1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-14 10:12:59 +02:00
vcmi/lib/modding/ModVerificationInfo.cpp
2024-12-01 16:00:09 +00:00

124 lines
3.1 KiB
C++

/*
* ModVerificationInfo.cpp, part of VCMI engine
*
* Authors: listed in file AUTHORS in main folder
*
* License: GNU General Public License v2.0 or later
* Full text of license available in license.txt file, in main folder
*
*/
#include "StdInc.h"
#include "ModVerificationInfo.h"
#include "CModHandler.h"
#include "ModDescription.h"
#include "ModIncompatibility.h"
#include "ModScope.h"
#include "../json/JsonNode.h"
#include "../VCMI_Lib.h"
VCMI_LIB_NAMESPACE_BEGIN
JsonNode ModVerificationInfo::jsonSerializeList(const ModCompatibilityInfo & input)
{
JsonNode output;
for(const auto & mod : input)
{
JsonNode modWriter;
modWriter["modId"].String() = mod.first;
modWriter["name"].String() = mod.second.name;
if (!mod.second.parent.empty())
modWriter["parent"].String() = mod.second.parent;
modWriter["version"].String() = mod.second.version.toString();
output.Vector().push_back(modWriter);
}
return output;
}
ModCompatibilityInfo ModVerificationInfo::jsonDeserializeList(const JsonNode & input)
{
ModCompatibilityInfo output;
for(const auto & mod : input.Vector())
{
ModVerificationInfo info;
info.version = CModVersion::fromString(mod["version"].String());
info.name = mod["name"].String();
info.parent = mod["parent"].String();
info.checksum = 0;
info.impactsGameplay = true;
if(!mod["modId"].isNull())
output[mod["modId"].String()] = info;
else
output[mod["name"].String()] = info;
}
return output;
}
ModListVerificationStatus ModVerificationInfo::verifyListAgainstLocalMods(const ModCompatibilityInfo & modList)
{
ModListVerificationStatus result;
for(const auto & m : VLC->modh->getActiveMods())
{
if(modList.count(m))
continue;
if (m == ModScope::scopeBuiltin())
continue;
if(VLC->modh->getModInfo(m).affectsGameplay())
result[m] = ModVerificationStatus::EXCESSIVE;
}
for(const auto & infoPair : modList)
{
auto & remoteModId = infoPair.first;
auto & remoteModInfo = infoPair.second;
if (remoteModId == ModScope::scopeBuiltin())
continue;
bool modAffectsGameplay = remoteModInfo.impactsGameplay;
//parent mod affects gameplay if child affects too
for(const auto & subInfoPair : modList)
modAffectsGameplay |= (subInfoPair.second.impactsGameplay && subInfoPair.second.parent == remoteModId);
if(!vstd::contains(VLC->modh->getAllMods(), remoteModId))
{
result[remoteModId] = ModVerificationStatus::NOT_INSTALLED;
continue;
}
const auto & localVersion = VLC->modh->getModInfo(remoteModId).getVersion();
modAffectsGameplay |= VLC->modh->getModInfo(remoteModId).affectsGameplay();
// skip it. Such mods should only be present in old saves or if mod changed and no longer affects gameplay
if (!modAffectsGameplay)
continue;
if (!vstd::contains(VLC->modh->getActiveMods(), remoteModId))
{
result[remoteModId] = ModVerificationStatus::DISABLED;
continue;
}
if(remoteModInfo.version != localVersion)
{
result[remoteModId] = ModVerificationStatus::VERSION_MISMATCH;
continue;
}
result[remoteModId] = ModVerificationStatus::FULL_MATCH;
}
return result;
}
VCMI_LIB_NAMESPACE_END