std::vector<ModSpec> flattenMods(std::map<std::string, ModSpec> mods) { std::vector<ModSpec> result; for(std::map<std::string,ModSpec>::iterator it = mods.begin(); it != mods.end(); ++it) { ModSpec mod = (*it).second; if(mod.is_modpack) { std::vector<ModSpec> content = flattenMods(mod.modpack_content); result.reserve(result.size() + content.size()); result.insert(result.end(),content.begin(),content.end()); } else //not a modpack { result.push_back(mod); } } return result; }
void ModConfiguration::addModsInPath(std::string path) { addMods(flattenMods(getModsInPath(path))); }
ModConfiguration::ModConfiguration(std::string worldpath) { SubgameSpec gamespec = findWorldSubgame(worldpath); // Add common mods std::map<std::string, ModSpec> common_mods; 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 common_mods.insert(std::make_pair(modname, 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); } addMods(flattenMods(common_mods)); // Add all game mods and all world mods addModsInPath(gamespec.gamemods_path); addModsInPath(worldpath + DIR_DELIM + "worldmods"); // check world.mt file for mods explicitely declared to be // loaded or not by a load_mod_<modname> = ... line. std::string worldmt = worldpath+DIR_DELIM+"world.mt"; Settings worldmt_settings; worldmt_settings.readConfigFile(worldmt.c_str()); std::vector<std::string> names = worldmt_settings.getNames(); std::set<std::string> exclude_mod_names; for(std::vector<std::string>::iterator it = names.begin(); it != names.end(); ++it) { std::string name = *it; // for backwards compatibility: exclude only mods which are // explicitely excluded. if mod is not mentioned at all, it is // enabled. So by default, all installed mods are enabled. if (name.compare(0,9,"load_mod_") == 0 && !worldmt_settings.getBool(name)) { exclude_mod_names.insert(name.substr(9)); } } // Collect all mods in gamespec.addon_mods_paths, // excluding those in the set exclude_mod_names std::vector<ModSpec> addon_mods; for(std::set<std::string>::const_iterator it_path = gamespec.addon_mods_paths.begin(); it_path != gamespec.addon_mods_paths.end(); ++it_path) { std::vector<ModSpec> addon_mods_in_path = flattenMods(getModsInPath(*it_path)); for(std::vector<ModSpec>::iterator it = addon_mods_in_path.begin(); it != addon_mods_in_path.end(); ++it) { ModSpec& mod = *it; if(exclude_mod_names.count(mod.name) == 0) addon_mods.push_back(mod); } } addMods(addon_mods); // report on name conflicts if(!m_name_conflicts.empty()){ std::string s = "Unresolved name conflicts for mods "; for(std::set<std::string>::const_iterator it = m_name_conflicts.begin(); it != m_name_conflicts.end(); ++it) { if(it != m_name_conflicts.begin()) s += ", "; s += std::string("\"") + (*it) + "\""; } s += "."; throw ModError(s); } // get the mods in order resolveDependencies(); }
ModConfiguration::ModConfiguration(std::string worldpath) { SubgameSpec gamespec = findWorldSubgame(worldpath); // Add all game mods and all world mods addModsInPath(gamespec.gamemods_path); addModsInPath(worldpath + DIR_DELIM + "worldmods"); // check world.mt file for mods explicitely declared to be // loaded or not by a load_mod_<modname> = ... line. std::string worldmt = worldpath+DIR_DELIM+"world.mt"; Settings worldmt_settings; worldmt_settings.readConfigFile(worldmt.c_str()); std::vector<std::string> names = worldmt_settings.getNames(); std::set<std::string> include_mod_names; for(std::vector<std::string>::iterator it = names.begin(); it != names.end(); ++it) { std::string name = *it; // for backwards compatibility: exclude only mods which are // explicitely excluded. if mod is not mentioned at all, it is // enabled. So by default, all installed mods are enabled. if (name.compare(0,9,"load_mod_") == 0 && worldmt_settings.getBool(name)) { include_mod_names.insert(name.substr(9)); } } // Collect all mods that are also in include_mod_names std::vector<ModSpec> addon_mods; for(std::set<std::string>::const_iterator it_path = gamespec.addon_mods_paths.begin(); it_path != gamespec.addon_mods_paths.end(); ++it_path) { std::vector<ModSpec> addon_mods_in_path = flattenMods(getModsInPath(*it_path)); for(std::vector<ModSpec>::iterator it = addon_mods_in_path.begin(); it != addon_mods_in_path.end(); ++it) { ModSpec& mod = *it; if(include_mod_names.count(mod.name) != 0) addon_mods.push_back(mod); else worldmt_settings.setBool("load_mod_" + mod.name, false); } } worldmt_settings.updateConfigFile(worldmt.c_str()); addMods(addon_mods); // report on name conflicts if(!m_name_conflicts.empty()){ std::string s = "Unresolved name conflicts for mods "; for(std::set<std::string>::const_iterator it = m_name_conflicts.begin(); it != m_name_conflicts.end(); ++it) { if(it != m_name_conflicts.begin()) s += ", "; s += std::string("\"") + (*it) + "\""; } s += "."; throw ModError(s); } // get the mods in order resolveDependencies(); }