3 Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU Lesser General Public License as published by
7 the Free Software Foundation; either version 2.1 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public License along
16 with this program; if not, write to the Free Software Foundation, Inc.,
17 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22 #include "irrlichttypes.h"
28 #include <json/json.h>
29 #include <unordered_set>
30 #include "util/basic_macros.h"
34 class ModMetadataDatabase;
36 #define MODNAME_ALLOWED_CHARS "abcdefghijklmnopqrstuvwxyz0123456789_"
47 std::unordered_set<std::string> depends;
48 std::unordered_set<std::string> optdepends;
49 std::unordered_set<std::string> unsatisfied_depends;
51 bool part_of_modpack = false;
52 bool is_modpack = false;
55 * A constructed canonical path to represent this mod's location.
56 * This intended to be used as an identifier for a modpath that tolerates file movement,
57 * and cannot be used to read the mod files.
59 * Note that `mymod` is the directory name, not the mod name specified in mod.conf.
65 * (^ this would have name=mymod in mod.conf)
66 * - mods/modpack1/mymod
67 * - games/mygame/mods/mymod
70 std::string virtual_path;
72 // For logging purposes
73 std::vector<const char *> deprecation_msgs;
76 std::map<std::string, ModSpec> modpack_content;
82 ModSpec(const std::string &name, const std::string &path, bool part_of_modpack, const std::string &virtual_path) :
83 name(name), path(path), part_of_modpack(part_of_modpack), virtual_path(virtual_path)
87 void checkAndLog() const;
90 // Retrieves depends, optdepends, is_modpack and modpack_content
91 void parseModContents(ModSpec &mod);
94 * Gets a list of all mods and modpacks in path
96 * @param Path to search, should be absolute
97 * @param part_of_modpack Is this searching within a modpack?
98 * @param virtual_path Virtual path for this directory, see comment in ModSpec
99 * @returns map of mods
101 std::map<std::string, ModSpec> getModsInPath(const std::string &path,
102 const std::string &virtual_path, bool part_of_modpack = false);
104 // replaces modpack Modspecs with their content
105 std::vector<ModSpec> flattenMods(const std::map<std::string, ModSpec> &mods);
107 // a ModConfiguration is a subset of installed mods, expected to have
108 // all dependencies fullfilled, so it can be used as a list of mods to
109 // load when the game starts.
110 class ModConfiguration
113 // checks if all dependencies are fullfilled.
114 bool isConsistent() const { return m_unsatisfied_mods.empty(); }
116 const std::vector<ModSpec> &getMods() const { return m_sorted_mods; }
118 const std::vector<ModSpec> &getUnsatisfiedMods() const
120 return m_unsatisfied_mods;
123 void printUnsatisfiedModsError() const;
126 ModConfiguration(const std::string &worldpath);
129 * adds all mods in the given path. used for games, modpacks
130 * and world-specific mods (worldmods-folders)
132 * @param path To search, should be absolute
133 * @param virtual_path Virtual path for this directory, see comment in ModSpec
135 void addModsInPath(const std::string &path, const std::string &virtual_path);
137 // adds all mods in the set.
138 void addMods(const std::vector<ModSpec> &new_mods);
141 * @param settings_path Path to world.mt
142 * @param modPaths Map from virtual name to mod path
144 void addModsFromConfig(const std::string &settings_path,
145 const std::unordered_map<std::string, std::string> &modPaths);
147 void checkConflictsAndDeps();
150 // list of mods sorted such that they can be loaded in the
151 // given order with all dependencies being fullfilled. I.e.,
152 // every mod in this list has only dependencies on mods which
153 // appear earlier in the vector.
154 std::vector<ModSpec> m_sorted_mods;
157 // move mods from m_unsatisfied_mods to m_sorted_mods
158 // in an order that satisfies dependencies
159 void resolveDependencies();
161 // mods with unmet dependencies. Before dependencies are resolved,
162 // this is where all mods are stored. Afterwards this contains
163 // only the ones with really unsatisfied dependencies.
164 std::vector<ModSpec> m_unsatisfied_mods;
166 // set of mod names for which an unresolved name conflict
167 // exists. A name conflict happens when two or more mods
168 // at the same level have the same name but different paths.
169 // Levels (mods in higher levels override mods in lower levels):
170 // 1. game mod in modpack; 2. game mod;
171 // 3. world mod in modpack; 4. world mod;
172 // 5. addon mod in modpack; 6. addon mod.
173 std::unordered_set<std::string> m_name_conflicts;
175 // Deleted default constructor
176 ModConfiguration() = default;
180 class ClientModConfiguration : public ModConfiguration
183 ClientModConfiguration(const std::string &path);
187 class ModMetadata : public Metadata
190 ModMetadata() = delete;
191 ModMetadata(const std::string &mod_name, ModMetadataDatabase *database);
192 ~ModMetadata() = default;
194 virtual void clear();
196 const std::string &getModName() const { return m_mod_name; }
198 virtual bool setString(const std::string &name, const std::string &var);
201 std::string m_mod_name;
202 ModMetadataDatabase *m_database;