diff --git a/lib/CModHandler.cpp b/lib/CModHandler.cpp index 2a291f7c0..218259aa8 100644 --- a/lib/CModHandler.cpp +++ b/lib/CModHandler.cpp @@ -551,6 +551,12 @@ static JsonNode loadModSettings(std::string path) return JsonNode(); } +JsonNode addMeta(JsonNode config, std::string meta) +{ + config.setMeta(meta); + return std::move(config); +} + CModInfo::CModInfo(std::string identifier,const JsonNode & local, const JsonNode & config): identifier(identifier), name(config["name"].String()), @@ -558,7 +564,7 @@ CModInfo::CModInfo(std::string identifier,const JsonNode & local, const JsonNode dependencies(config["depends"].convertTo<std::set<std::string> >()), conflicts(config["conflicts"].convertTo<std::set<std::string> >()), validation(PENDING), - config(config) + config(addMeta(config, identifier)) { loadLocalData(local); } @@ -577,6 +583,7 @@ JsonNode CModInfo::saveLocalData() void CModInfo::updateChecksum(ui32 newChecksum) { + // comment-out next line to force validation of all mods ignoring checksum if (newChecksum != checksum) { checksum = newChecksum; diff --git a/lib/JsonDetail.cpp b/lib/JsonDetail.cpp index 94932861f..0baec2745 100644 --- a/lib/JsonDetail.cpp +++ b/lib/JsonDetail.cpp @@ -11,7 +11,10 @@ #include "StdInc.h" #include "JsonDetail.h" +#include "VCMI_Lib.h" #include "CGeneralTextHandler.h" +#include "CModHandler.h" + #include "filesystem/Filesystem.h" #include "ScopeGuard.h" @@ -879,52 +882,71 @@ namespace namespace Formats { - #define TEST_FILE(prefix, file, type) \ - if (CResourceHandler::get()->existsResource(ResourceID(prefix + file, type))) \ + bool testFilePresence(std::string scope, ResourceID resource) + { + std::set<std::string> allowedScopes; + if (scope != "core" && scope != "") // all real mods may have dependencies + { + //NOTE: recursive dependencies are not allowed at the moment - update code if this changes + allowedScopes = VLC->modh->getModData(scope).dependencies; + allowedScopes.insert("core"); // all mods can use H3 files + } + allowedScopes.insert(scope); // mods can use their own files + + for (auto & entry : allowedScopes) + { + if (CResourceHandler::get(entry)->existsResource(resource)) + return true; + } + return false; + } + + #define TEST_FILE(scope, prefix, file, type) \ + if (testFilePresence(scope, ResourceID(prefix + file, type))) \ return "" - std::string testAnimation(std::string path) + std::string testAnimation(std::string path, std::string scope) { - TEST_FILE("Sprites/", path, EResType::ANIMATION); - TEST_FILE("Sprites/", path, EResType::TEXT); + TEST_FILE(scope, "Sprites/", path, EResType::ANIMATION); + TEST_FILE(scope, "Sprites/", path, EResType::TEXT); return "Animation file \"" + path + "\" was not found"; } std::string textFile(const JsonNode & node) { - TEST_FILE("", node.String(), EResType::TEXT); + TEST_FILE(node.meta, "", node.String(), EResType::TEXT); return "Text file \"" + node.String() + "\" was not found"; } std::string musicFile(const JsonNode & node) { - TEST_FILE("", node.String(), EResType::MUSIC); + TEST_FILE(node.meta, "", node.String(), EResType::MUSIC); return "Music file \"" + node.String() + "\" was not found"; } std::string soundFile(const JsonNode & node) { - TEST_FILE("Sounds/", node.String(), EResType::SOUND); + TEST_FILE(node.meta, "Sounds/", node.String(), EResType::SOUND); return "Sound file \"" + node.String() + "\" was not found"; } std::string defFile(const JsonNode & node) { - TEST_FILE("Sprites/", node.String(), EResType::ANIMATION); + TEST_FILE(node.meta, "Sprites/", node.String(), EResType::ANIMATION); return "Def file \"" + node.String() + "\" was not found"; } std::string animationFile(const JsonNode & node) { - return testAnimation(node.String()); + return testAnimation(node.String(), node.meta); } std::string imageFile(const JsonNode & node) { - TEST_FILE("Data/", node.String(), EResType::IMAGE); - TEST_FILE("Sprites/", node.String(), EResType::IMAGE); + TEST_FILE(node.meta, "Data/", node.String(), EResType::IMAGE); + TEST_FILE(node.meta, "Sprites/", node.String(), EResType::IMAGE); if (node.String().find(':') != std::string::npos) - return testAnimation(node.String().substr(0, node.String().find(':'))); + return testAnimation(node.String().substr(0, node.String().find(':')), node.meta); return "Image file \"" + node.String() + "\" was not found"; } diff --git a/lib/filesystem/Filesystem.cpp b/lib/filesystem/Filesystem.cpp index 4236e30a4..78ed3966e 100644 --- a/lib/filesystem/Filesystem.cpp +++ b/lib/filesystem/Filesystem.cpp @@ -153,8 +153,7 @@ void CResourceHandler::initialize() ISimpleResourceLoader * CResourceHandler::get() { - assert(resourceLoader); - return resourceLoader; + return get(""); } ISimpleResourceLoader * CResourceHandler::get(std::string identifier) @@ -175,6 +174,7 @@ void CResourceHandler::load(const std::string &fsConfigURI) const JsonNode fsConfig((char*)fsConfigData.first.get(), fsConfigData.second); resourceLoader = new CFilesystemList(); + knownLoaders[""] = resourceLoader; addFilesystem("core", createFileSystem("", fsConfig["filesystem"])); // hardcoded system-specific path, may not be inside any of data directories @@ -184,6 +184,7 @@ void CResourceHandler::load(const std::string &fsConfigURI) void CResourceHandler::addFilesystem(const std::string & identifier, ISimpleResourceLoader * loader) { + assert(knownLoaders.count(identifier) == 0); resourceLoader->addLoader(loader, false); knownLoaders[identifier] = loader; }