From 8e4152bc8179a51aa6a9c5a8dec0ceb34002f3ee Mon Sep 17 00:00:00 2001 From: Ivan Savenko Date: Mon, 30 Sep 2024 19:26:22 +0000 Subject: [PATCH] It is now possible to define objects directly in mod.json instead of using path to file with object definition --- config/schemas/mod.json | 80 +++++++++++++-------------- lib/json/JsonUtils.cpp | 21 +++++++ lib/json/JsonUtils.h | 2 + lib/modding/CModHandler.cpp | 21 +------ lib/modding/ContentTypeHandler.cpp | 4 +- lib/modding/ContentTypeHandler.h | 2 +- lib/texts/TextLocalizationContainer.h | 1 - 7 files changed, 69 insertions(+), 62 deletions(-) diff --git a/config/schemas/mod.json b/config/schemas/mod.json index 5c09ef74c..76d174c28 100644 --- a/config/schemas/mod.json +++ b/config/schemas/mod.json @@ -5,6 +5,17 @@ "description" : "Format used to define main mod file (mod.json) in VCMI", "required" : [ "name", "description", "modType", "version", "author", "contact" ], "definitions" : { + "fileListOrObject" : { + "oneOf" : [ + { + "type" : "array", + "items" : { "type" : "string", "format" : "textFile" } + }, + { + "type" : "object" + } + ] + }, "localizable" : { "type" : "object", "additionalProperties" : false, @@ -35,9 +46,8 @@ "description" : "If set to true, vcmi will skip validation of current translation json files" }, "translations" : { - "type" : "array", "description" : "List of files with translations for this language", - "items" : { "type" : "string", "format" : "textFile" } + "$ref" : "#/definitions/fileListOrObject" } } } @@ -122,9 +132,17 @@ "description" : "If set to true, mod will not be enabled automatically on install" }, "settings" : { - "type" : "object", "description" : "List of changed game settings by mod", - "$ref" : "gameSettings.json" + "oneOf" : [ + { + "type" : "object", + "$ref" : "gameSettings.json" + }, + { + "type" : "array", + "items" : { "type" : "string", "format" : "textFile" } + }, + ] }, "filesystem" : { "type" : "object", @@ -206,94 +224,76 @@ "$ref" : "#/definitions/localizable" }, "translations" : { - "type" : "array", "description" : "List of files with translations for this language", - "items" : { "type" : "string", "format" : "textFile" } + "$ref" : "#/definitions/fileListOrObject" }, "factions" : { - "type" : "array", "description" : "List of configuration files for towns/factions", - "items" : { "type" : "string", "format" : "textFile" } + "$ref" : "#/definitions/fileListOrObject" }, "heroClasses" : { - "type" : "array", "description" : "List of configuration files for hero classes", - "items" : { "type" : "string", "format" : "textFile" } + "$ref" : "#/definitions/fileListOrObject" }, "heroes" : { - "type" : "array", "description" : "List of configuration files for heroes", - "items" : { "type" : "string", "format" : "textFile" } + "$ref" : "#/definitions/fileListOrObject" }, "skills" : { - "type" : "array", "description" : "List of configuration files for skills", - "items" : { "type" : "string", "format" : "textFile" } + "$ref" : "#/definitions/fileListOrObject" }, "creatures" : { - "type" : "array", "description" : "List of configuration files for creatures", - "items" : { "type" : "string", "format" : "textFile" } + "$ref" : "#/definitions/fileListOrObject" }, "artifacts" : { - "type" : "array", "description" : "List of configuration files for artifacts", - "items" : { "type" : "string", "format" : "textFile" } + "$ref" : "#/definitions/fileListOrObject" }, "spells" : { - "type" : "array", "description" : "List of configuration files for spells", - "items" : { "type" : "string", "format" : "textFile" } + "$ref" : "#/definitions/fileListOrObject" }, "objects" : { - "type" : "array", "description" : "List of configuration files for objects", - "items" : { "type" : "string", "format" : "textFile" } + "$ref" : "#/definitions/fileListOrObject" }, "biomes" : { - "type" : "array", "description" : "List of configuration files for biomes", - "items" : { "type" : "string", "format" : "textFile" } + "$ref" : "#/definitions/fileListOrObject" }, "bonuses" : { - "type" : "array", "description" : "List of configuration files for bonuses", - "items" : { "type" : "string", "format" : "textFile" } + "$ref" : "#/definitions/fileListOrObject" }, "terrains" : { - "type" : "array", "description" : "List of configuration files for terrains", - "items" : { "type" : "string", "format" : "textFile" } + "$ref" : "#/definitions/fileListOrObject" }, "roads" : { - "type" : "array", "description" : "List of configuration files for roads", - "items" : { "type" : "string", "format" : "textFile" } + "$ref" : "#/definitions/fileListOrObject" }, "rivers" : { - "type" : "array", "description" : "List of configuration files for rivers", - "items" : { "type" : "string", "format" : "textFile" } + "$ref" : "#/definitions/fileListOrObject" }, "battlefields" : { - "type" : "array", "description" : "List of configuration files for battlefields", - "items" : { "type" : "string", "format" : "textFile" } + "$ref" : "#/definitions/fileListOrObject" }, "obstacles" : { - "type" : "array", "description" : "List of configuration files for obstacles", - "items" : { "type" : "string", "format" : "textFile" } + "$ref" : "#/definitions/fileListOrObject" }, "templates" : { - "type" : "array", "description" : "List of configuration files for RMG templates", - "items" : { "type" : "string", "format" : "textFile" } + "$ref" : "#/definitions/fileListOrObject" }, "scripts" : { - "type" : "array", "description" : "List of configuration files for scripts", - "items" : { "type" : "string", "format" : "textFile" } + "$ref" : "#/definitions/fileListOrObject" } } } diff --git a/lib/json/JsonUtils.cpp b/lib/json/JsonUtils.cpp index f1680e11f..e1cd47678 100644 --- a/lib/json/JsonUtils.cpp +++ b/lib/json/JsonUtils.cpp @@ -230,6 +230,27 @@ void JsonUtils::inherit(JsonNode & descendant, const JsonNode & base) std::swap(descendant, inheritedNode); } +JsonNode JsonUtils::assembleFromFiles(const JsonNode & files, bool & isValid) +{ + if (files.isVector()) + { + auto configList = files.convertTo >(); + JsonNode result = JsonUtils::assembleFromFiles(configList, isValid); + + return result; + } + else + { + return files; + } +} + +JsonNode JsonUtils::assembleFromFiles(const JsonNode & files) +{ + bool isValid = false; + return assembleFromFiles(files, isValid); +} + JsonNode JsonUtils::assembleFromFiles(const std::vector & files) { bool isValid = false; diff --git a/lib/json/JsonUtils.h b/lib/json/JsonUtils.h index 954ee0b16..dcf03d30e 100644 --- a/lib/json/JsonUtils.h +++ b/lib/json/JsonUtils.h @@ -44,6 +44,8 @@ namespace JsonUtils * @brief generate one Json structure from multiple files * @param files - list of filenames with parts of json structure */ + DLL_LINKAGE JsonNode assembleFromFiles(const JsonNode & files); + DLL_LINKAGE JsonNode assembleFromFiles(const JsonNode & files, bool & isValid); DLL_LINKAGE JsonNode assembleFromFiles(const std::vector & files); DLL_LINKAGE JsonNode assembleFromFiles(const std::vector & files, bool & isValid); diff --git a/lib/modding/CModHandler.cpp b/lib/modding/CModHandler.cpp index e2d44cbd3..8dbf84eda 100644 --- a/lib/modding/CModHandler.cpp +++ b/lib/modding/CModHandler.cpp @@ -384,7 +384,7 @@ std::set CModHandler::getModDependencies(const TModID & modId, bool & is void CModHandler::initializeConfig() { - VLC->settingsHandler->loadBase(coreMod->config["settings"]); + VLC->settingsHandler->loadBase(JsonUtils::assembleFromFiles(coreMod->config["settings"])); for(const TModID & modName : activeMods) { @@ -401,21 +401,6 @@ CModVersion CModHandler::getModVersion(TModID modName) const return {}; } -static JsonNode loadReferencesList(const JsonNode & source) -{ - if (source.isVector()) - { - auto configList = source.convertTo >(); - JsonNode result = JsonUtils::assembleFromFiles(configList); - - return result; - } - else - { - return source; - } -} - void CModHandler::loadTranslation(const TModID & modName) { const auto & mod = allMods[modName]; @@ -423,8 +408,8 @@ void CModHandler::loadTranslation(const TModID & modName) std::string preferredLanguage = VLC->generaltexth->getPreferredLanguage(); std::string modBaseLanguage = allMods[modName].baseLanguage; - JsonNode baseTranslation = loadReferencesList(mod.config["translations"]); - JsonNode extraTranslation = loadReferencesList(mod.config[preferredLanguage]["translations"]); + JsonNode baseTranslation = JsonUtils::assembleFromFiles(mod.config["translations"]); + JsonNode extraTranslation = JsonUtils::assembleFromFiles(mod.config[preferredLanguage]["translations"]); VLC->generaltexth->loadTranslationOverrides(modName, baseTranslation); VLC->generaltexth->loadTranslationOverrides(modName, extraTranslation); diff --git a/lib/modding/ContentTypeHandler.cpp b/lib/modding/ContentTypeHandler.cpp index 83ae46c1b..d5dfb8461 100644 --- a/lib/modding/ContentTypeHandler.cpp +++ b/lib/modding/ContentTypeHandler.cpp @@ -50,7 +50,7 @@ ContentTypeHandler::ContentTypeHandler(IHandlerBase * handler, const std::string } } -bool ContentTypeHandler::preloadModData(const std::string & modName, const std::vector & fileList, bool validate) +bool ContentTypeHandler::preloadModData(const std::string & modName, const JsonNode & fileList, bool validate) { bool result = false; JsonNode data = JsonUtils::assembleFromFiles(fileList, result); @@ -216,7 +216,7 @@ bool CContentHandler::preloadModData(const std::string & modName, JsonNode modCo bool result = true; for(auto & handler : handlers) { - result &= handler.second.preloadModData(modName, modConfig[handler.first].convertTo >(), validate); + result &= handler.second.preloadModData(modName, modConfig[handler.first], validate); } return result; } diff --git a/lib/modding/ContentTypeHandler.h b/lib/modding/ContentTypeHandler.h index 7093c12d5..60b29d689 100644 --- a/lib/modding/ContentTypeHandler.h +++ b/lib/modding/ContentTypeHandler.h @@ -39,7 +39,7 @@ public: /// local version of methods in ContentHandler /// returns true if loading was successful - bool preloadModData(const std::string & modName, const std::vector & fileList, bool validate); + bool preloadModData(const std::string & modName, const JsonNode & fileList, bool validate); bool loadMod(const std::string & modName, bool validate); void loadCustom(); void afterLoadFinalization(); diff --git a/lib/texts/TextLocalizationContainer.h b/lib/texts/TextLocalizationContainer.h index e3047c516..cde8e070e 100644 --- a/lib/texts/TextLocalizationContainer.h +++ b/lib/texts/TextLocalizationContainer.h @@ -36,7 +36,6 @@ protected: void serialize(Handler & h) { h & translatedText; - //h & baseLanguage; h & identifierModContext; h & baseStringModContext; }