X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=src%2Fmods.h;h=50ada328ebed6c38e45ecb19b978b417c6985a49;hb=d6050bee5187d0d456e9d95406fc74ba163ea3aa;hp=9761a910329a87a94329ef1d290c2587e7e83505;hpb=6d0ea26c2d62c3774ff384cf1bfc2a3372b49a3b;p=minetest.git diff --git a/src/mods.h b/src/mods.h index 9761a9103..50ada328e 100644 --- a/src/mods.h +++ b/src/mods.h @@ -17,100 +17,56 @@ with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#ifndef MODS_HEADER -#define MODS_HEADER +#pragma once #include "irrlichttypes.h" -#include #include #include #include #include #include -#include +#include +#include +#include "config.h" +#include "metadata.h" -class ModError : public std::exception -{ -public: - ModError(const std::string &s) - { - m_s = "ModError: "; - m_s += s; - } - virtual ~ModError() throw() - {} - virtual const char * what() const throw() - { - return m_s.c_str(); - } - std::string m_s; -}; +#define MODNAME_ALLOWED_CHARS "abcdefghijklmnopqrstuvwxyz0123456789_" struct ModSpec { std::string name; std::string path; //if normal mod: - std::set depends; - std::set unsatisfied_depends; + std::unordered_set depends; + std::unordered_set optdepends; + std::unordered_set unsatisfied_depends; - bool is_modpack; + bool part_of_modpack = false; + bool is_modpack = false; // if modpack: std::map modpack_content; - ModSpec(const std::string name_="", const std::string path_="", - const std::set depends_=std::set()): + ModSpec(const std::string &name_="", const std::string &path_=""): name(name_), - path(path_), - depends(depends_), - unsatisfied_depends(depends_), - is_modpack(false), - modpack_content() + path(path_) {} }; +// Retrieves depends, optdepends, is_modpack and modpack_content +void parseModContents(ModSpec &mod); -std::map getModsInPath(std::string path); - -// expands modpack contents, but does not replace them. -std::map flattenModTree(std::map mods); +std::map getModsInPath(std::string path, bool part_of_modpack = false); // replaces modpack Modspecs with their content std::vector flattenMods(std::map mods); -// removes Mods mentioned in exclude_mod_names -std::vector filterMods(std::vector mods, - std::set exclude_mod_names); - // a ModConfiguration is a subset of installed mods, expected to have // all dependencies fullfilled, so it can be used as a list of mods to // load when the game starts. class ModConfiguration { public: - ModConfiguration(): - m_unsatisfied_mods(), - m_sorted_mods() - {} - - - ModConfiguration(std::string worldpath); - - // adds all mods in the given path. used for games, modpacks - // and world-specific mods (worldmods-folders) - void addModsInPath(std::string path) - { - addMods(flattenMods(getModsInPath(path))); - } - - // adds all mods in the given path whose name does not appear - // in the exclude_mods set. - void addModsInPathFiltered(std::string path, std::set exclude_mods); - - // adds all mods in the set. - void addMods(std::vector mods); - // checks if all dependencies are fullfilled. - bool isConsistent() + bool isConsistent() const { return m_unsatisfied_mods.empty(); } @@ -120,17 +76,34 @@ class ModConfiguration return m_sorted_mods; } - std::list getUnsatisfiedMods() + const std::vector &getUnsatisfiedMods() const { return m_unsatisfied_mods; } + void printUnsatisfiedModsError() const; + +protected: + ModConfiguration(const std::string &worldpath); + // adds all mods in the given path. used for games, modpacks + // and world-specific mods (worldmods-folders) + void addModsInPath(const std::string &path); + + // adds all mods in the set. + void addMods(const std::vector &new_mods); + + void addModsFromConfig(const std::string &settings_path, const std::set &mods); + + void checkConflictsAndDeps(); private: + // move mods from m_unsatisfied_mods to m_sorted_mods + // in an order that satisfies dependencies + void resolveDependencies(); - // mods with unmet dependencies. This is a list and not a - // vector because we want easy removal of elements at every - // position. - std::list m_unsatisfied_mods; + // mods with unmet dependencies. Before dependencies are resolved, + // this is where all mods are stored. Afterwards this contains + // only the ones with really unsatisfied dependencies. + std::vector m_unsatisfied_mods; // list of mods sorted such that they can be loaded in the // given order with all dependencies being fullfilled. I.e., @@ -138,8 +111,62 @@ class ModConfiguration // appear earlier in the vector. std::vector m_sorted_mods; + // set of mod names for which an unresolved name conflict + // exists. A name conflict happens when two or more mods + // at the same level have the same name but different paths. + // Levels (mods in higher levels override mods in lower levels): + // 1. game mod in modpack; 2. game mod; + // 3. world mod in modpack; 4. world mod; + // 5. addon mod in modpack; 6. addon mod. + std::unordered_set m_name_conflicts; + + // Deleted default constructor + ModConfiguration() = default; + }; +class ServerModConfiguration: public ModConfiguration +{ +public: + ServerModConfiguration(const std::string &worldpath); + +}; +#ifndef SERVER +class ClientModConfiguration: public ModConfiguration +{ +public: + ClientModConfiguration(const std::string &path); +}; #endif +struct ModLicenseInfo { + int id; + std::string shortinfo; + std::string url; +}; + +struct ModAuthorInfo { + int id; + std::string username; +}; + +class ModMetadata: public Metadata +{ +public: + ModMetadata(const std::string &mod_name); + ~ModMetadata() = default; + + virtual void clear(); + + bool save(const std::string &root_path); + bool load(const std::string &root_path); + + bool isModified() const { return m_modified; } + const std::string &getModName() const { return m_mod_name; } + + virtual bool setString(const std::string &name, const std::string &var); +private: + std::string m_mod_name; + bool m_modified = false; +};