std::vector<std::string> available_addons() { std::vector<std::string> res; std::vector<std::string> files, dirs; const std::string parentd = get_addon_campaigns_dir(); get_files_in_dir(parentd,&files,&dirs); for(std::vector<std::string>::const_iterator i = dirs.begin(); i != dirs.end(); ++i) { const std::string external_cfg_file = *i + ".cfg"; const std::string internal_cfg_file = *i + "/_main.cfg"; const std::string external_pbl_file = *i + ".pbl"; const std::string internal_pbl_file = *i + "/_server.pbl"; if((std::find(files.begin(),files.end(),external_cfg_file) != files.end() || file_exists(parentd + "/" + internal_cfg_file)) && (std::find(files.begin(),files.end(),external_pbl_file) != files.end() || (file_exists(parentd + "/" + internal_pbl_file)))) { res.push_back(*i); } } for(std::vector<std::string>::const_iterator i = files.begin(); i != files.end(); ++i) { const size_t length = i->size() - 4; if (i->rfind(".cfg", length) != length) continue; const std::string name = i->substr(0, length); // Continue if there is a dir (which we already processed). if (std::find(dirs.begin(), dirs.end(), name) != dirs.end()) continue; if (std::find(files.begin(), files.end(), name + ".pbl") != files.end()) { res.push_back(name); } } return res; }
bool have_addon_pbl_info(const std::string& addon_name) { static const std::string parentd = get_addon_campaigns_dir(); return file_exists(parentd+"/"+addon_name+".pbl") || file_exists(parentd+"/"+addon_name+"/_server.pbl"); }
static std::pair<std::vector<std::string>, std::vector<std::string> > read_ignore_patterns(const std::string& addon_name) { const std::string parentd = get_addon_campaigns_dir(); const std::string exterior = parentd + "/" + addon_name + ".ign"; const std::string interior = parentd + "/" + addon_name + "/_server.ign"; std::pair<std::vector<std::string>, std::vector<std::string> > patterns; std::string ign_file; LOG_CFG << "searching for .ign file for '" << addon_name << "'...\n"; if (file_exists(interior)) { ign_file = interior; } else if (file_exists(exterior)) { ign_file = exterior; } else { LOG_CFG << "no .ign file found for '" << addon_name << "'\n" << "inserting default ignore patterns...\n"; append_default_ignore_patterns(patterns); return patterns; // just default patterns } LOG_CFG << "found .ign file: " << ign_file << '\n'; std::istream *stream = istream_file(ign_file); std::string line; while (std::getline(*stream, line)) { utils::strip(line); const size_t l = line.size(); if (line[l - 1] == '/') { // directory; we strip the last / patterns.second.push_back(line.substr(0, l - 1)); } else { // file patterns.first.push_back(line); } } return patterns; }
bool remove_local_addon(const std::string& addon, std::string* log) { bool ret = true; std::ostringstream messages; const std::string addon_dir = get_addon_campaigns_dir() + "/" + addon; LOG_CFG << "removing local add-on: " << addon << '\n'; if(file_exists(addon_dir) && !delete_directory(addon_dir)) { messages << "Failed to delete directory/file: " << addon_dir << '\n'; ret = false; } if(file_exists(addon_dir + ".cfg") && !delete_directory(addon_dir + ".cfg")) { messages << "Failed to delete directory/file: " << addon_dir << ".cfg\n"; ret = false; } if(log != NULL) { *log = messages.str(); } if(!ret) { ERR_CFG << "removal of add-on " << addon << " failed:\n" << messages.str(); } return ret; }
void set_addon_info(const std::string& addon_name, const config& cfg) { const std::string parentd = get_addon_campaigns_dir(); scoped_ostream stream = ostream_file(parentd + "/" + addon_name + ".pbl"); write(*stream, cfg); }
bool have_addon_in_vcs_tree(const std::string& addon_name) { static const std::string parentd = get_addon_campaigns_dir(); return file_exists(parentd+"/"+addon_name+"/.svn") || file_exists(parentd+"/"+addon_name+"/.git") || file_exists(parentd+"/"+addon_name+"/.hg"); }
void get_addon_info(const std::string& addon_name, config& cfg) { const std::string parentd = get_addon_campaigns_dir(); // Cope with old-style or new-style file organization const std::string exterior = parentd + "/" + addon_name + ".pbl"; const std::string interior = parentd + "/" + addon_name + "/_server.pbl"; const std::string pbl_file = (file_exists(exterior)? exterior : interior); scoped_istream stream = istream_file(pbl_file); read(cfg, *stream); }
void archive_addon(const std::string& addon_name, config& cfg) { const std::string parentd = get_addon_campaigns_dir(); std::pair<std::vector<std::string>, std::vector<std::string> > ignore_patterns; // External .cfg may not exist; newer campaigns have a _main.cfg const std::string external_cfg = addon_name + ".cfg"; if (file_exists(parentd + "/" + external_cfg)) { archive_file(parentd, external_cfg, cfg.add_child("file")); } ignore_patterns = read_ignore_patterns(addon_name); archive_dir(parentd, addon_name, cfg.add_child("dir"), ignore_patterns); }
std::vector<std::string> installed_addons() { std::vector<std::string> res; const std::string parentd = get_addon_campaigns_dir(); std::vector<std::string> files, dirs; get_files_in_dir(parentd,&files,&dirs); for(std::vector<std::string>::const_iterator i = dirs.begin(); i != dirs.end(); ++i) { const std::string external_cfg_file = *i + ".cfg"; const std::string internal_cfg_file = *i + "/_main.cfg"; if(std::find(files.begin(),files.end(),external_cfg_file) != files.end() || file_exists(parentd + "/" + internal_cfg_file)) { res.push_back(*i); } } return res; }
bool remove_local_addon(const std::string& addon) { bool ret = true; const std::string addon_dir = get_addon_campaigns_dir() + "/" + addon; LOG_CFG << "removing local add-on: " << addon << '\n'; if(file_exists(addon_dir) && !delete_directory(addon_dir, true)) { ERR_CFG << "Failed to delete directory/file: " << addon_dir << '\n'; ret = false; } if(file_exists(addon_dir + ".cfg") && !delete_directory(addon_dir + ".cfg", true)) { ERR_CFG << "Failed to delete directory/file: " << addon_dir << ".cfg" << std::endl; ret = false; } if(!ret) { ERR_CFG << "removal of add-on " << addon << " failed!" << std::endl; } return ret; }
void unarchive_addon(const config& cfg) { const std::string parentd = get_addon_campaigns_dir(); unarchive_dir(parentd, cfg); }
bool is_addon_installed(const std::string& addon_name) { const std::string namestem = get_addon_campaigns_dir() + "/" + addon_name; return file_exists(namestem + ".cfg") || file_exists(namestem + "/_main.cfg"); }
void game_config_manager::load_addons_cfg() { const std::string user_campaign_dir = get_addon_campaigns_dir(); std::vector<std::string> error_addons; std::vector<std::string> user_dirs; std::vector<std::string> user_files; std::vector<std::string> addons_to_load; get_files_in_dir(user_campaign_dir, &user_files, &user_dirs, ENTIRE_FILE_PATH); std::stringstream user_error_log; // Append the $user_campaign_dir/*.cfg files to addons_to_load. BOOST_FOREACH(const std::string& uc, user_files) { const std::string file = uc; const int size_minus_extension = file.size() - 4; if(file.substr(size_minus_extension, file.size()) == ".cfg") { bool ok = true; // Allowing it if the dir doesn't exist, // for the single-file add-on. if(file_exists(file.substr(0, size_minus_extension))) { // Unfortunately, we create the dir plus // _info.cfg ourselves on download. std::vector<std::string> dirs, files; get_files_in_dir(file.substr(0, size_minus_extension), &files, &dirs); if(dirs.size() > 0) { ok = false; } if(files.size() > 1) { ok = false; } if(files.size() == 1 && files[0] != "_info.cfg") { ok = false; } } if(!ok) { const int userdata_loc = file.find("data/add-ons") + 5; ERR_CONFIG << "error reading usermade add-on '" << file << "'\n"; error_addons.push_back(file); user_error_log << "The format '~" << file.substr(userdata_loc) << "' is only for single-file add-ons, use '~" << file.substr(userdata_loc, size_minus_extension - userdata_loc) << "/_main.cfg' instead.\n"; } else { addons_to_load.push_back(file); } } } // Append the $user_campaign_dir/*/_main.cfg files to addons_to_load. BOOST_FOREACH(const std::string& uc, user_dirs) { const std::string main_cfg = uc + "/_main.cfg"; if(file_exists(main_cfg)) { addons_to_load.push_back(main_cfg); } } // Load the addons. BOOST_FOREACH(const std::string& uc, addons_to_load) { const std::string toplevel = uc; try { config umc_cfg; cache_.get_config(toplevel, umc_cfg); game_config_.append(umc_cfg); } catch(config::error& err) { ERR_CONFIG << "error reading usermade add-on '" << uc << "'\n"; error_addons.push_back(uc); user_error_log << err.message << "\n"; } catch(preproc_config::error& err) { ERR_CONFIG << "error reading usermade add-on '" << uc << "'\n"; error_addons.push_back(uc); user_error_log << err.message << "\n"; } catch(io_exception&) { ERR_CONFIG << "error reading usermade add-on '" << uc << "'\n"; error_addons.push_back(uc); } } if(error_addons.empty() == false) { std::stringstream msg; msg << _n("The following add-on had errors and could not be loaded:", "The following add-ons had errors and could not be loaded:", error_addons.size()); BOOST_FOREACH(const std::string& error_addon, error_addons) { msg << "\n" << error_addon; } msg << '\n' << _("ERROR DETAILS:") << '\n' << user_error_log.str(); gui2::show_error_message(disp_.video(),msg.str()); }