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

Merge pull request #4712 from IvanSavenko/detect_conflict

Detection of potential conflicts between mods
This commit is contained in:
Ivan Savenko
2024-10-07 17:57:52 +03:00
committed by GitHub
11 changed files with 1260 additions and 991 deletions

View File

@@ -17,6 +17,7 @@
#include "ModIncompatibility.h"
#include "../CCreatureHandler.h"
#include "../CConfigHandler.h"
#include "../CStopWatch.h"
#include "../GameSettings.h"
#include "../ScriptHandler.h"
@@ -331,10 +332,38 @@ void CModHandler::loadModFilesystems()
coreMod->updateChecksum(calculateModChecksum(ModScope::scopeBuiltin(), CResourceHandler::get(ModScope::scopeBuiltin())));
std::map<std::string, ISimpleResourceLoader *> modFilesystems;
for(std::string & modName : activeMods)
modFilesystems[modName] = genModFilesystem(modName, allMods[modName].config);
for(std::string & modName : activeMods)
CResourceHandler::addFilesystem("data", modName, modFilesystems[modName]);
if (settings["mods"]["validation"].String() == "full")
{
CModInfo & mod = allMods[modName];
CResourceHandler::addFilesystem("data", modName, genModFilesystem(modName, mod.config));
for(std::string & leftModName : activeMods)
{
for(std::string & rightModName : activeMods)
{
if (leftModName == rightModName)
continue;
if (getModDependencies(leftModName).count(rightModName) || getModDependencies(rightModName).count(leftModName))
continue;
const auto & filter = [](const ResourcePath &path){return path.getType() != EResType::DIRECTORY;};
std::unordered_set<ResourcePath> leftResources = modFilesystems[leftModName]->getFilteredFiles(filter);
std::unordered_set<ResourcePath> rightResources = modFilesystems[rightModName]->getFilteredFiles(filter);
for (auto const & leftFile : leftResources)
{
if (rightResources.count(leftFile))
logMod->warn("Potential confict detected between '%s' and '%s': both mods add file '%s'", leftModName, rightModName, leftFile.getOriginalName());
}
}
}
}
}
@@ -370,6 +399,12 @@ std::string CModHandler::getModLanguage(const TModID& modId) const
return allMods.at(modId).baseLanguage;
}
std::set<TModID> CModHandler::getModDependencies(const TModID & modId) const
{
bool isModFound;
return getModDependencies(modId, isModFound);
}
std::set<TModID> CModHandler::getModDependencies(const TModID & modId, bool & isModFound) const
{
auto it = allMods.find(modId);