1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-06-21 00:19:29 +02:00

Fix: Crash on startup when mod dependency is not found

This commit is contained in:
Dmitry Orlov
2022-03-21 01:33:04 +03:00
committed by Andrii Danylchenko
parent 4defbc314a
commit d98f240164
3 changed files with 28 additions and 16 deletions

View File

@ -200,20 +200,25 @@ void CIdentifierStorage::registerObject(std::string scope, std::string type, std
std::vector<CIdentifierStorage::ObjectData> CIdentifierStorage::getPossibleIdentifiers(const ObjectCallback & request) std::vector<CIdentifierStorage::ObjectData> CIdentifierStorage::getPossibleIdentifiers(const ObjectCallback & request)
{ {
std::set<std::string> allowedScopes; std::set<std::string> allowedScopes;
bool isValidScope = true;
if (request.remoteScope.empty()) if (request.remoteScope.empty())
{ {
// normally ID's from all required mods, own mod and virtual "core" mod are allowed // normally ID's from all required mods, own mod and virtual "core" mod are allowed
if (request.localScope != "core" && request.localScope != "") if(request.localScope != "core" && !request.localScope.empty())
allowedScopes = VLC->modh->getModData(request.localScope).dependencies; {
allowedScopes = VLC->modh->getModDependencies(request.localScope, isValidScope);
if(!isValidScope)
return std::vector<ObjectData>();
}
allowedScopes.insert(request.localScope); allowedScopes.insert(request.localScope);
allowedScopes.insert("core"); allowedScopes.insert("core");
} }
else else
{ {
//...unless destination mod was specified explicitly //...unless destination mod was specified explicitly
//note: getModData does not work for "core" by design //note: getModDependencies does not work for "core" by design
//for map format support core mod has access to any mod //for map format support core mod has access to any mod
//TODO: better solution for access from map? //TODO: better solution for access from map?
@ -224,7 +229,11 @@ std::vector<CIdentifierStorage::ObjectData> CIdentifierStorage::getPossibleIdent
else else
{ {
// allow only available to all core mod or dependencies // allow only available to all core mod or dependencies
auto myDeps = VLC->modh->getModData(request.localScope).dependencies; auto myDeps = VLC->modh->getModDependencies(request.localScope, isValidScope);
if(!isValidScope)
return std::vector<ObjectData>();
if(request.remoteScope == "core" || request.remoteScope == request.localScope || myDeps.count(request.remoteScope)) if(request.remoteScope == "core" || request.remoteScope == request.localScope || myDeps.count(request.remoteScope))
allowedScopes.insert(request.remoteScope); allowedScopes.insert(request.remoteScope);
} }
@ -931,18 +940,16 @@ void CModHandler::loadModFilesystems()
} }
} }
CModInfo & CModHandler::getModData(TModID modId) std::set<TModID> CModHandler::getModDependencies(TModID modId, bool & isModFound)
{ {
auto it = allMods.find(modId); auto it = allMods.find(modId);
isModFound = (it != allMods.end());
if(it == allMods.end()) if(isModFound)
{ return it->second.dependencies;
throw std::runtime_error("Mod not found '" + modId+"'");
} logMod->error("Mod not found: '%s'", modId);
else return std::set<TModID>();
{
return it->second;
}
} }
void CModHandler::initializeConfig() void CModHandler::initializeConfig()

View File

@ -266,7 +266,7 @@ public:
void loadMods(bool onlyEssential = false); void loadMods(bool onlyEssential = false);
void loadModFilesystems(); void loadModFilesystems();
CModInfo & getModData(TModID modId); std::set<TModID> getModDependencies(TModID modId, bool & isModFound);
/// returns list of all (active) mods /// returns list of all (active) mods
std::vector<std::string> getAllMods(); std::vector<std::string> getAllMods();

View File

@ -997,10 +997,15 @@ namespace
bool testFilePresence(std::string scope, ResourceID resource) bool testFilePresence(std::string scope, ResourceID resource)
{ {
std::set<std::string> allowedScopes; std::set<std::string> allowedScopes;
if (scope != "core" && scope != "") // all real mods may have dependencies if(scope != "core" && !scope.empty()) // all real mods may have dependencies
{ {
//NOTE: recursive dependencies are not allowed at the moment - update code if this changes //NOTE: recursive dependencies are not allowed at the moment - update code if this changes
allowedScopes = VLC->modh->getModData(scope).dependencies; bool found = true;
allowedScopes = VLC->modh->getModDependencies(scope, found);
if(!found)
return false;
allowedScopes.insert("core"); // all mods can use H3 files allowedScopes.insert("core"); // all mods can use H3 files
} }
allowedScopes.insert(scope); // mods can use their own files allowedScopes.insert(scope); // mods can use their own files