diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/mods.cpp | 52 | ||||
-rw-r--r-- | src/server.cpp | 4 | ||||
-rw-r--r-- | src/subgame.cpp | 15 | ||||
-rw-r--r-- | src/subgame.h | 4 |
4 files changed, 68 insertions, 7 deletions
diff --git a/src/mods.cpp b/src/mods.cpp index ac2d9b17d..6a7ab79aa 100644 --- a/src/mods.cpp +++ b/src/mods.cpp @@ -23,6 +23,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "log.h" #include "subgame.h" #include "settings.h" +#include "strfnd.h" std::map<std::string, ModSpec> getModsInPath(std::string path) { @@ -188,11 +189,58 @@ void ModConfiguration::addMods(std::vector<ModSpec> new_mods) } } +// If failed, returned modspec has name=="" +static ModSpec findCommonMod(const std::string &modname) +{ + // Try to find in {$user,$share}/games/common/$modname + std::vector<std::string> find_paths; + find_paths.push_back(porting::path_user + DIR_DELIM + "games" + + DIR_DELIM + "common" + DIR_DELIM + "mods" + DIR_DELIM + modname); + find_paths.push_back(porting::path_share + DIR_DELIM + "games" + + DIR_DELIM + "common" + DIR_DELIM + "mods" + DIR_DELIM + modname); + for(u32 i=0; i<find_paths.size(); i++){ + const std::string &try_path = find_paths[i]; + if(fs::PathExists(try_path)) + return ModSpec(modname, try_path); + } + // Failed to find mod + return ModSpec(); +} + ModConfiguration::ModConfiguration(std::string worldpath) { + SubgameSpec gamespec = findWorldSubgame(worldpath); + + // Add common mods without dependency handling + std::vector<std::string> inexistent_common_mods; + Settings gameconf; + if(getGameConfig(gamespec.path, gameconf)){ + if(gameconf.exists("common_mods")){ + Strfnd f(gameconf.get("common_mods")); + while(!f.atend()){ + std::string modname = trim(f.next(",")); + if(modname.empty()) + continue; + ModSpec spec = findCommonMod(modname); + if(spec.name.empty()) + inexistent_common_mods.push_back(modname); + else + m_sorted_mods.push_back(spec); + } + } + } + if(!inexistent_common_mods.empty()){ + std::string s = "Required common mods "; + for(u32 i=0; i<inexistent_common_mods.size(); i++){ + if(i != 0) s += ", "; + s += std::string("\"") + inexistent_common_mods[i] + "\""; + } + s += " could not be found."; + throw ModError(s); + } + // Add all world mods and all game mods addModsInPath(worldpath + DIR_DELIM + "worldmods"); - SubgameSpec gamespec = findWorldSubgame(worldpath); addModsInPath(gamespec.gamemods_path); // check world.mt file for mods explicitely declared to be @@ -217,6 +265,6 @@ ModConfiguration::ModConfiguration(std::string worldpath) } for(std::set<std::string>::const_iterator i = gamespec.addon_mods_paths.begin(); - i != gamespec.addon_mods_paths.end(); ++i) + i != gamespec.addon_mods_paths.end(); ++i) addModsInPathFiltered((*i),exclude_mod_names); } diff --git a/src/server.cpp b/src/server.cpp index d699dc9d2..2dcab63b8 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -736,10 +736,10 @@ Server::Server( } // complain about mods declared to be loaded, but not found for(std::vector<ModSpec>::iterator it = m_mods.begin(); - it != m_mods.end(); ++it) + it != m_mods.end(); ++it) load_mod_names.erase((*it).name); for(std::list<ModSpec>::iterator it = unsatisfied_mods.begin(); - it != unsatisfied_mods.end(); ++it) + it != unsatisfied_mods.end(); ++it) load_mod_names.erase((*it).name); if(!load_mod_names.empty()) { diff --git a/src/subgame.cpp b/src/subgame.cpp index 3c8bf53c5..8678ae37f 100644 --- a/src/subgame.cpp +++ b/src/subgame.cpp @@ -24,12 +24,16 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "log.h" #include "util/string.h" -std::string getGameName(const std::string &game_path) +bool getGameConfig(const std::string &game_path, Settings &conf) { std::string conf_path = game_path + DIR_DELIM + "game.conf"; + return conf.readConfigFile(conf_path.c_str()); +} + +std::string getGameName(const std::string &game_path) +{ Settings conf; - bool succeeded = conf.readConfigFile(conf_path.c_str()); - if(!succeeded) + if(!getGameConfig(game_path, conf)) return ""; if(!conf.exists("name")) return ""; @@ -117,6 +121,11 @@ std::set<std::string> getAvailableGameIds() for(u32 j=0; j<dirlist.size(); j++){ if(!dirlist[j].dir) continue; + // If configuration file is not found or broken, ignore game + Settings conf; + if(!getGameConfig(*i + DIR_DELIM + dirlist[j].name, conf)) + continue; + // Add it to result const char *ends[] = {"_game", NULL}; std::string shorter = removeStringEnd(dirlist[j].name, ends); if(shorter != "") diff --git a/src/subgame.h b/src/subgame.h index 8561c1a52..996714be0 100644 --- a/src/subgame.h +++ b/src/subgame.h @@ -24,6 +24,8 @@ with this program; if not, write to the Free Software Foundation, Inc., #include <set> #include <vector> +class Settings; + #define WORLDNAME_BLACKLISTED_CHARS "/\\" struct SubgameSpec @@ -52,6 +54,8 @@ struct SubgameSpec } }; +bool getGameConfig(const std::string &game_path, Settings &conf); + std::string getGameName(const std::string &game_path); SubgameSpec findSubgame(const std::string &id); |