diff --git a/docs/LOOT Metadata Syntax.html b/docs/LOOT Metadata Syntax.html index 1d8c0880..f91788fc 100644 --- a/docs/LOOT Metadata Syntax.html +++ b/docs/LOOT Metadata Syntax.html @@ -322,6 +322,24 @@ nav: 0 urllocation list✗An unordered list of locations for this plugin. If the same version can be found at multiple locations, only one location should be recorded. This metadata is not currently used by LOOT. dirtydirty info list✗An unordered list of dirty info structures for this plugin. +

Each plugin must have only one matching non-regex entry. If multiple non-regex entries exist with the same name value, all but the first will be ignored. A plugin may match any number of regex entries though, and their metadata will be merged, with later entries being merged into earlier entries as detailed in the table below. Merging only takes place if both entries have their enabled value set to true (which is the default if unspecified). + + + + +
Key NameMerge Behaviour (merging B into A) +
nameNot merged. +
enabledReplaced but must be `true` anyway. +
priorityReplaced by B's value. +
afterMerged. If A and B both contain an entry with the same name value, B's copy is skipped. +
reqMerged. If A and B both contain an entry with the same name value, B's copy is skipped. +
incMerged. If A and B both contain an entry with the same name value, B's copy is skipped. +
msgMerged. If A and B both contain an entry with the same content string (if there are multiple content strings, the first is checked), then B's copy is skipped. +
tagMerged. If A and B both contain an entry with the same name value, B's copy is skipped, unless one is suggesting the tag for addition and the other is suggesting it for removal, in which case both entries are kept. +
urlCurrently skipped by the parser, so neither A nor B will contain any entries anyway. +
dirtyMerged. If A and B both contain an entry with the same crc value, B's copy is skipped. +
+

Example: name: 'Oscuro''s_Oblivion_Overhaul.esm' req: diff --git a/src/backend/game.cpp b/src/backend/game.cpp index 335acc4f..83780ce2 100644 --- a/src/backend/game.cpp +++ b/src/backend/game.cpp @@ -180,18 +180,24 @@ namespace loot { return pluginList; } + // Merges multiple matching regex entries if any are found. Plugin MetadataList::FindPlugin(const Plugin& plugin) const { + Plugin match(plugin.Name()); + auto it = plugins.find(plugin); if (it != plugins.end()) - return *it; + match = *it; + // Now we want to also match possibly multiple regex entries. it = find(regexPlugins.begin(), regexPlugins.end(), plugin); + while (it != regexPlugins.end()) { + match.MergeMetadata(*it); - if (it != regexPlugins.end()) - return *it; - else - return Plugin(plugin.Name()); + it = find(++it, regexPlugins.end(), plugin); + } + + return match; } void MetadataList::AddPlugin(const Plugin& plugin) { @@ -201,6 +207,8 @@ namespace loot { plugins.insert(plugin); } + // Doesn't erase matching regex entries, because they might also + // be required for other plugins. void MetadataList::ErasePlugin(const Plugin& plugin) { auto it = plugins.find(plugin); @@ -208,12 +216,6 @@ namespace loot { plugins.erase(it); return; } - - it = find(regexPlugins.begin(), regexPlugins.end(), plugin); - - if (it != regexPlugins.end()) { - regexPlugins.erase(it); - } } // Masterlist member functions diff --git a/src/backend/game.h b/src/backend/game.h index 9d282fcf..f32e9bbc 100644 --- a/src/backend/game.h +++ b/src/backend/game.h @@ -20,7 +20,7 @@ You should have received a copy of the GNU General Public License along with LOOT. If not, see . -*/ + */ #ifndef __LOOT_GAME__ #define __LOOT_GAME__ @@ -41,7 +41,6 @@ #include namespace loot { - class Game; /* Each Game object should store the config details specific to that game. @@ -52,7 +51,7 @@ namespace loot { global message lists. Each game should have functions to load this plugin and masterlist / userlist data. Plugin data should be loaded as header-only and as full data. - */ + */ class MetadataList { public: @@ -63,8 +62,13 @@ namespace loot { bool operator == (const MetadataList& rhs) const; //Compares content. std::list Plugins() const; + + // Merges multiple matching regex entries if any are found. Plugin FindPlugin(const Plugin& plugin) const; void AddPlugin(const Plugin& plugin); + + // Doesn't erase matching regex entries, because they might also + // be required for other plugins. void ErasePlugin(const Plugin& plugin); std::list messages; @@ -96,8 +100,8 @@ namespace loot { Game(const unsigned int baseGameCode, const std::string& lootFolder = ""); Game& SetDetails(const std::string& name, const std::string& masterFile, - const std::string& repositoryURL, const std::string& repositoryBranch, - const std::string& path, const std::string& registry); + const std::string& repositoryURL, const std::string& repositoryBranch, + const std::string& path, const std::string& registry); Game& SetPath(const std::string& path); //Used by API. Game& Init();