1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-11-27 22:49:25 +02:00

Added an option to configure validation level in launcher

This commit is contained in:
Ivan Savenko
2024-10-06 19:21:18 +00:00
parent 3e3f842fbe
commit 66fdad145c
8 changed files with 1200 additions and 1034 deletions

View File

@@ -17,6 +17,7 @@
#include "../BattleFieldHandler.h"
#include "../CArtHandler.h"
#include "../CCreatureHandler.h"
#include "../CConfigHandler.h"
#include "../entities/faction/CTownHandler.h"
#include "../texts/CGeneralTextHandler.h"
#include "../CHeroHandler.h"
@@ -79,7 +80,7 @@ bool ContentTypeHandler::preloadModData(const std::string & modName, const std::
logMod->trace("Patching object %s (%s) from %s", objectName, remoteName, modName);
JsonNode & remoteConf = modData[remoteName].patches[objectName];
if (!remoteConf.isNull())
if (!remoteConf.isNull() && settings["mods"]["validation"].String() != "off")
JsonUtils::detectConflicts(conflictList, remoteConf, entry.second, objectName);
JsonUtils::merge(remoteConf, entry.second);
@@ -162,67 +163,70 @@ void ContentTypeHandler::loadCustom()
void ContentTypeHandler::afterLoadFinalization()
{
for (auto const & data : modData)
if (settings["mods"]["validation"].String() != "off")
{
if (data.second.modData.isNull())
for (auto const & data : modData)
{
for (auto node : data.second.patches.Struct())
logMod->warn("Mod '%s' have added patch for object '%s' from mod '%s', but this mod was not loaded or has no new objects.", node.second.getModScope(), node.first, data.first);
}
for(auto & otherMod : modData)
{
if (otherMod.first == data.first)
continue;
if (otherMod.second.modData.isNull())
continue;
for(auto & otherObject : otherMod.second.modData.Struct())
if (data.second.modData.isNull())
{
if (data.second.modData.Struct().count(otherObject.first))
for (auto node : data.second.patches.Struct())
logMod->warn("Mod '%s' have added patch for object '%s' from mod '%s', but this mod was not loaded or has no new objects.", node.second.getModScope(), node.first, data.first);
}
for(auto & otherMod : modData)
{
if (otherMod.first == data.first)
continue;
if (otherMod.second.modData.isNull())
continue;
for(auto & otherObject : otherMod.second.modData.Struct())
{
logMod->warn("Mod '%s' have added object with name '%s' that is also available in mod '%s'", data.first, otherObject.first, otherMod.first);
logMod->warn("Two objects with same name were loaded. Please use form '%s:%s' if mod '%s' needs to modify this object instead", otherMod.first, otherObject.first, data.first);
if (data.second.modData.Struct().count(otherObject.first))
{
logMod->warn("Mod '%s' have added object with name '%s' that is also available in mod '%s'", data.first, otherObject.first, otherMod.first);
logMod->warn("Two objects with same name were loaded. Please use form '%s:%s' if mod '%s' needs to modify this object instead", otherMod.first, otherObject.first, data.first);
}
}
}
}
}
for (const auto& [conflictPath, conflictModData] : conflictList.Struct())
{
std::set<std::string> conflictingMods;
std::set<std::string> resolvedConflicts;
for (auto const & conflictModData : conflictModData.Struct())
conflictingMods.insert(conflictModData.first);
for (auto const & modID : conflictingMods)
resolvedConflicts.merge(VLC->modh->getModDependencies(modID));
vstd::erase_if(conflictingMods, [&resolvedConflicts](const std::string & entry){ return resolvedConflicts.count(entry);});
if (conflictingMods.size() < 2)
continue; // all conflicts were resolved - either via compatibility patch (mod that depends on 2 conflicting mods) or simple mod that depends on another one
bool allEqual = true;
for (auto const & modID : conflictingMods)
for (const auto& [conflictPath, conflictModData] : conflictList.Struct())
{
if (conflictModData[modID] != conflictModData[*conflictingMods.begin()])
std::set<std::string> conflictingMods;
std::set<std::string> resolvedConflicts;
for (auto const & conflictModData : conflictModData.Struct())
conflictingMods.insert(conflictModData.first);
for (auto const & modID : conflictingMods)
resolvedConflicts.merge(VLC->modh->getModDependencies(modID));
vstd::erase_if(conflictingMods, [&resolvedConflicts](const std::string & entry){ return resolvedConflicts.count(entry);});
if (conflictingMods.size() < 2)
continue; // all conflicts were resolved - either via compatibility patch (mod that depends on 2 conflicting mods) or simple mod that depends on another one
bool allEqual = true;
for (auto const & modID : conflictingMods)
{
allEqual = false;
break;
if (conflictModData[modID] != conflictModData[*conflictingMods.begin()])
{
allEqual = false;
break;
}
}
if (allEqual)
continue; // conflict still present, but all mods use the same value for conflicting entry - permit it
logMod->warn("Potential confict in '%s'", conflictPath);
for (auto const & modID : conflictingMods)
logMod->warn("Mod '%s' - value set to %s", modID, conflictModData[modID].toCompactString());
}
if (allEqual)
continue; // conflict still present, but all mods use the same value for conflicting entry - permit it
logMod->warn("Potential confict in '%s'", conflictPath);
for (auto const & modID : conflictingMods)
logMod->warn("Mod '%s' - value set to %s", modID, conflictModData[modID].toCompactString());
}
handler->afterLoadFinalization();
@@ -288,7 +292,7 @@ void CContentHandler::afterLoadFinalization()
void CContentHandler::preloadData(CModInfo & mod)
{
bool validate = (mod.validation != CModInfo::PASSED);
bool validate = validateMod(mod);
// print message in format [<8-symbols checksum>] <modname>
auto & info = mod.getVerificationInfo();
@@ -305,7 +309,7 @@ void CContentHandler::preloadData(CModInfo & mod)
void CContentHandler::load(CModInfo & mod)
{
bool validate = (mod.validation != CModInfo::PASSED);
bool validate = validateMod(mod);
if (!loadMod(mod.identifier, validate))
mod.validation = CModInfo::FAILED;
@@ -326,4 +330,18 @@ const ContentTypeHandler & CContentHandler::operator[](const std::string & name)
return handlers.at(name);
}
bool CContentHandler::validateMod(const CModInfo & mod) const
{
if (settings["mods"]["validation"].String() == "full")
return true;
if (mod.validation == CModInfo::PASSED)
return false;
if (settings["mods"]["validation"].String() == "off")
return false;
return true;
}
VCMI_LIB_NAMESPACE_END