diff --git a/changelog b/changelog index 5ef6dd0fa4d..c4c7d0b4bb4 100644 --- a/changelog +++ b/changelog @@ -14,6 +14,8 @@ Version 1.3.11+svn: * user interface: * changed the default setting for the turn bell to on * removed the turn_cmd preference option + * Savegames now have a prefix indicating the campaign they are from if + the campaign WML declared an abbrev= tag. * WML engine: * New standard unit filter keys: - defense: chance to be hit on current terrain by normal weapons @@ -21,9 +23,9 @@ Version 1.3.11+svn: * the preprocessor now ignores filenames with '..' in them * miscellaneous and bug fixes: * fix a compilation bug on Windows (usleep not defined) - * UI: - * Savegames now have a prefix indicating the campaign they are from if - the campaign WML declared an abbrev= tag. + * addon interface : added support of ignore file (.ign) to configure what + shouldn't be uploaded on the addon server (it useful if you use a svn checkout + for example) Version 1.3.11: * campaigns diff --git a/src/publish_campaign.cpp b/src/publish_campaign.cpp index 845616363b7..afdaa81f620 100644 --- a/src/publish_campaign.cpp +++ b/src/publish_campaign.cpp @@ -167,13 +167,42 @@ static std::string unencode_binary(const std::string& str) return res; } +static std::pair, std::vector > read_ignore_patterns(const std::string& campaign_name) { + std::pair, std::vector > patterns; + std::string exterior = campaign_dir() + "/" + campaign_name + ".ign"; + std::string interior = campaign_dir() + "/" + campaign_name + "/_server.ign"; + std::string ign_file; + if (file_exists(interior)) { + ign_file = interior; + } else if (file_exists(exterior)) { + ign_file = exterior; + } else { /* default patterns */ + patterns.first.push_back("*~"); + patterns.first.push_back("*-bak"); + patterns.first.push_back("*.pbl"); + patterns.first.push_back("*.ign"); + return patterns; + } + std::istream *stream = istream_file(ign_file); + std::string line; + while (std::getline(*stream, line)) { + 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; +} + static void archive_file(const std::string& path, const std::string& fname, config& cfg) { cfg["name"] = fname; cfg["contents"] = encode_binary(read_file(path + '/' + fname)); } -static void archive_dir(const std::string& path, const std::string& dirname, config& cfg) +static void archive_dir(const std::string& path, const std::string& dirname, config& cfg, std::pair, std::vector >& ignore_patterns) { cfg["name"] = dirname; const std::string dir = path + '/' + dirname; @@ -181,23 +210,41 @@ static void archive_dir(const std::string& path, const std::string& dirname, con std::vector files, dirs; get_files_in_dir(dir,&files,&dirs); for(std::vector::const_iterator i = files.begin(); i != files.end(); ++i) { - if (ends_with(*i, "~")||ends_with(*i, "-bak")||(*i).find(".pbl")!=std::string::npos) - continue; - archive_file(dir,*i,cfg.add_child("file")); + bool valid = true; + for(std::vector::const_iterator p = ignore_patterns.first.begin(); p != ignore_patterns.first.end(); ++p) { + if (utils::wildcard_string_match(*i, *p)) { + valid = false; + break; + } + } + if (valid) { + archive_file(dir,*i,cfg.add_child("file")); + } } for(std::vector::const_iterator j = dirs.begin(); j != dirs.end(); ++j) { - archive_dir(dir,*j,cfg.add_child("dir")); + bool valid = true; + for(std::vector::const_iterator p = ignore_patterns.second.begin(); p != ignore_patterns.second.end(); ++p) { + if (utils::wildcard_string_match(*j, *p)) { + valid = false; + break; + } + } + if (valid) { + archive_dir(dir,*j,cfg.add_child("dir"),ignore_patterns); + } } } void archive_campaign(const std::string& campaign_name, config& cfg) { + std::pair, std::vector > ignore_patterns; // External .cfg may not exist; newer campaigns have a _main.cfg std::string external_cfg = campaign_name + ".cfg"; if (file_exists(campaign_dir() + "/" + external_cfg)) archive_file(campaign_dir(), external_cfg,cfg.add_child("file")); - archive_dir(campaign_dir(),campaign_name,cfg.add_child("dir")); + ignore_patterns = read_ignore_patterns(campaign_name); + archive_dir(campaign_dir(),campaign_name,cfg.add_child("dir"),ignore_patterns); } static void unarchive_file(const std::string& path, const config& cfg)