Revert part of eb49009d023e6e3b5d59a97b8fb5fed5eee83296 (#5230)
[oweals/minetest.git] / src / mods.h
1 /*
2 Minetest
3 Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
4
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.
9
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.
14
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.
18 */
19
20 #ifndef MODS_HEADER
21 #define MODS_HEADER
22
23 #include "irrlichttypes.h"
24 #include <list>
25 #include <set>
26 #include <vector>
27 #include <string>
28 #include <map>
29 #include <json/json.h>
30 #include "config.h"
31 #include "metadata.h"
32
33 #define MODNAME_ALLOWED_CHARS "abcdefghijklmnopqrstuvwxyz0123456789_"
34
35 struct ModSpec
36 {
37         std::string name;
38         std::string path;
39         //if normal mod:
40         std::set<std::string> depends;
41         std::set<std::string> optdepends;
42         std::set<std::string> unsatisfied_depends;
43
44         bool part_of_modpack;
45         bool is_modpack;
46         // if modpack:
47         std::map<std::string,ModSpec> modpack_content;
48         ModSpec(const std::string &name_="", const std::string &path_=""):
49                 name(name_),
50                 path(path_),
51                 depends(),
52                 optdepends(),
53                 unsatisfied_depends(),
54                 part_of_modpack(false),
55                 is_modpack(false),
56                 modpack_content()
57         {}
58 };
59
60 // Retrieves depends, optdepends, is_modpack and modpack_content
61 void parseModContents(ModSpec &mod);
62
63 std::map<std::string,ModSpec> getModsInPath(std::string path, bool part_of_modpack = false);
64
65 // If failed, returned modspec has name==""
66 ModSpec findCommonMod(const std::string &modname);
67
68 // expands modpack contents, but does not replace them.
69 std::map<std::string, ModSpec> flattenModTree(std::map<std::string, ModSpec> mods);
70
71 // replaces modpack Modspecs with their content
72 std::vector<ModSpec> flattenMods(std::map<std::string,ModSpec> mods);
73
74 // a ModConfiguration is a subset of installed mods, expected to have
75 // all dependencies fullfilled, so it can be used as a list of mods to
76 // load when the game starts.
77 class ModConfiguration
78 {
79 public:
80         ModConfiguration():
81                 m_unsatisfied_mods(),
82                 m_sorted_mods(),
83                 m_name_conflicts()
84         {}
85
86
87         ModConfiguration(std::string worldpath);
88
89         // checks if all dependencies are fullfilled.
90         bool isConsistent()
91         {
92                 return m_unsatisfied_mods.empty();
93         }
94
95         std::vector<ModSpec> getMods()
96         {
97                 return m_sorted_mods;
98         }
99
100         std::vector<ModSpec> getUnsatisfiedMods()
101         {
102                 return m_unsatisfied_mods;
103         }
104
105 private:
106         // adds all mods in the given path. used for games, modpacks
107         // and world-specific mods (worldmods-folders)
108         void addModsInPath(std::string path);
109
110         // adds all mods in the set.
111         void addMods(std::vector<ModSpec> new_mods);
112
113         // move mods from m_unsatisfied_mods to m_sorted_mods
114         // in an order that satisfies dependencies
115         void resolveDependencies();
116
117         // mods with unmet dependencies. Before dependencies are resolved,
118         // this is where all mods are stored. Afterwards this contains
119         // only the ones with really unsatisfied dependencies.
120         std::vector<ModSpec> m_unsatisfied_mods;
121
122         // list of mods sorted such that they can be loaded in the
123         // given order with all dependencies being fullfilled. I.e.,
124         // every mod in this list has only dependencies on mods which
125         // appear earlier in the vector.
126         std::vector<ModSpec> m_sorted_mods;
127
128         // set of mod names for which an unresolved name conflict
129         // exists. A name conflict happens when two or more mods
130         // at the same level have the same name but different paths.
131         // Levels (mods in higher levels override mods in lower levels):
132         // 1. game mod in modpack; 2. game mod;
133         // 3. world mod in modpack; 4. world mod;
134         // 5. addon mod in modpack; 6. addon mod.
135         std::set<std::string> m_name_conflicts;
136
137 };
138
139 #if USE_CURL
140 Json::Value getModstoreUrl(std::string url);
141 #else
142 inline Json::Value getModstoreUrl(std::string url) {
143         return Json::Value();
144 }
145 #endif
146
147 struct ModLicenseInfo {
148         int id;
149         std::string shortinfo;
150         std::string url;
151 };
152
153 struct ModAuthorInfo {
154         int id;
155         std::string username;
156 };
157
158 struct ModStoreMod {
159         int id;
160         std::string title;
161         std::string basename;
162         ModAuthorInfo author;
163         float rating;
164         bool valid;
165 };
166
167 struct ModStoreCategoryInfo {
168         int id;
169         std::string name;
170 };
171
172 struct ModStoreVersionEntry {
173         int id;
174         std::string date;
175         std::string file;
176         bool approved;
177         //ugly version number
178         int mtversion;
179 };
180
181 struct ModStoreTitlePic {
182         int id;
183         std::string file;
184         std::string description;
185         int mod;
186 };
187
188 struct ModStoreModDetails {
189         /* version_set?? */
190         std::vector<ModStoreCategoryInfo> categories;
191         ModAuthorInfo author;
192         ModLicenseInfo license;
193         ModStoreTitlePic titlepic;
194         int id;
195         std::string title;
196         std::string basename;
197         std::string description;
198         std::string repository;
199         float rating;
200         std::vector<std::string> depends;
201         std::vector<std::string> softdeps;
202
203         std::string download_url;
204         std::string screenshot_url;
205         std::vector<ModStoreVersionEntry> versions;
206         bool valid;
207 };
208
209 class ModMetadata: public Metadata
210 {
211 public:
212         ModMetadata(const std::string &mod_name);
213         ~ModMetadata() {}
214
215         virtual void clear();
216
217         bool save(const std::string &root_path);
218         bool load(const std::string &root_path);
219
220         bool isModified() const { return m_modified; }
221         const std::string &getModName() const { return m_mod_name; }
222
223         virtual bool setString(const std::string &name, const std::string &var);
224 private:
225         std::string m_mod_name;
226         bool m_modified;
227 };
228
229 #endif