|
@@ -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);
|
|
|
- }
|
|
|
+ if (data.second.modData.isNull())
|
|
|
+ {
|
|
|
+ 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;
|
|
|
+ for(auto & otherMod : modData)
|
|
|
+ {
|
|
|
+ if (otherMod.first == data.first)
|
|
|
+ continue;
|
|
|
|
|
|
- if (otherMod.second.modData.isNull())
|
|
|
- continue;
|
|
|
+ if (otherMod.second.modData.isNull())
|
|
|
+ continue;
|
|
|
|
|
|
- for(auto & otherObject : otherMod.second.modData.Struct())
|
|
|
- {
|
|
|
- if (data.second.modData.Struct().count(otherObject.first))
|
|
|
+ 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 (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 & conflictModData : conflictModData.Struct())
|
|
|
+ conflictingMods.insert(conflictModData.first);
|
|
|
|
|
|
- for (auto const & modID : conflictingMods)
|
|
|
- resolvedConflicts.merge(VLC->modh->getModDependencies(modID));
|
|
|
+ for (auto const & modID : conflictingMods)
|
|
|
+ resolvedConflicts.merge(VLC->modh->getModDependencies(modID));
|
|
|
|
|
|
- vstd::erase_if(conflictingMods, [&resolvedConflicts](const std::string & entry){ return resolvedConflicts.count(entry);});
|
|
|
+ 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
|
|
|
+ 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;
|
|
|
+ bool allEqual = true;
|
|
|
|
|
|
- for (auto const & modID : conflictingMods)
|
|
|
- {
|
|
|
- if (conflictModData[modID] != conflictModData[*conflictingMods.begin()])
|
|
|
+ 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
|
|
|
+ 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);
|
|
|
+ logMod->warn("Potential confict in '%s'", conflictPath);
|
|
|
|
|
|
- for (auto const & modID : conflictingMods)
|
|
|
- logMod->warn("Mod '%s' - value set to %s", modID, conflictModData[modID].toCompactString());
|
|
|
+ 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
|