Author: shadowmaster
Date: Sun Jun  8 22:06:28 2008
New Revision: 27050

URL: http://svn.gna.org/viewcvs/wesnoth?rev=27050&view=rev
Log:
https://mail.gna.org/public/wesnoth-dev/2008-06/msg00002.html
- Adding new source code files before making them usable by cmake, scons
  and autotools

Added:
    trunk/src/addon_checks.cpp
    trunk/src/addon_checks.hpp
    trunk/src/addon_management.cpp
    trunk/src/addon_management.hpp

Added: trunk/src/addon_checks.cpp
URL: 
http://svn.gna.org/viewcvs/wesnoth/trunk/src/addon_checks.cpp?rev=27050&view=auto
==============================================================================
--- trunk/src/addon_checks.cpp (added)
+++ trunk/src/addon_checks.cpp Sun Jun  8 22:06:28 2008
@@ -1,0 +1,106 @@
+/* $Id$ */
+/*
+   Copyright (C) 2003 - 2008 by David White <[EMAIL PROTECTED]>
+                 2008 by Ignacio R. Morelle <[EMAIL PROTECTED]>
+   Part of the Battle for Wesnoth Project http://www.wesnoth.org/
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License version 2
+   or at your option any later version.
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY.
+
+   See the COPYING file for more details.
+*/
+
+#include "global.hpp"
+#include "addon_checks.hpp"
+#include "config.hpp"
+#include <algorithm>
+
+static bool two_dots(char a, char b)
+{
+       return a == '.' && b == '.';
+}
+
+bool addon_name_legal(const std::string& name)
+{
+       if(name == "" || strlen(name.c_str()) == 0 || name == "." ||
+          std::find(name.begin(),name.end(),'/') != name.end() ||
+          std::find(name.begin(),name.end(),'\\') != name.end() ||
+          std::find(name.begin(),name.end(),':') != name.end() ||
+          std::adjacent_find(name.begin(),name.end(),two_dots) != name.end()) {
+               return false;
+       } else {
+               return true;
+       }
+}
+
+bool check_names_legal(const config& dir)
+{
+       const config::child_list& files = dir.get_children("file");
+       for(config::child_list::const_iterator i = files.begin(); i != 
files.end(); ++i) {
+                       if (!addon_name_legal((**i)["name"])) return false;
+       }
+       const config::child_list& dirs = dir.get_children("dir");
+       {
+               for(config::child_list::const_iterator i = dirs.begin(); i != 
dirs.end(); ++i) {
+                               if (!addon_name_legal((**i)["name"])) return 
false;
+                               if (!check_names_legal(**i)) return false;
+               }
+       }
+       return true;
+}
+
+ADDON_TYPE get_addon_type(const std::string& str)
+{
+       if (str.empty())
+               return ADDON_UNKNOWN;
+       else if (str == "campaign")
+               return ADDON_SP_CAMPAIGN;
+       else if (str == "scenario")
+               return ADDON_SP_SCENARIO;
+       else if (str == "era" || str == "era_mp")
+               return ADDON_MP_ERA;
+       else if (str == "faction" || str == "faction_mp")
+               return ADDON_MP_FACTION;
+       else if (str == "maps_mp" || str == "maps" || str == "map_pack" || str 
== "map_pack_mp")
+               return ADDON_MP_MAPS;
+       else if (str == "scenario_mp")
+               return ADDON_MP_SCENARIO;
+       else if (str == "campaign_mp")
+               return ADDON_MP_CAMPAIGN;
+       else if (str == "media")
+               return ADDON_MEDIA;
+//     else if (str == "mod")
+//             return ADDON_MOD;
+//     else if (str == "gui")
+//             return ADDON_GUI;
+       else
+               return ADDON_UNKNOWN;
+}
+
+std::vector<config *> find_scripts(const config &cfg, std::string extension)
+{
+       std::vector<config *> python_scripts;
+       const config::child_list& dirs = cfg.get_children("dir");
+       config::child_list::const_iterator i;
+       for(i = dirs.begin(); i != dirs.end(); ++i) {
+               const config::child_list& files = (**i).get_children("file");
+               config::child_list::const_iterator j;
+               for(j = files.begin(); j != files.end(); ++j) {
+                       std::string filename = (**j)["name"].str();
+                       if (filename.length() > extension.length()) {
+                               if (filename.substr(filename.length() - 
extension.length()) ==
+                                       extension) {
+                                       python_scripts.push_back(*j);
+                               }
+                       }
+               }
+               // Recursively look for files in sub directories.
+               std::vector<config *> childs = find_scripts(**i, extension);
+               python_scripts.insert(python_scripts.end(),
+                       childs.begin(), childs.end());
+       }
+       return python_scripts;
+}

Added: trunk/src/addon_checks.hpp
URL: 
http://svn.gna.org/viewcvs/wesnoth/trunk/src/addon_checks.hpp?rev=27050&view=auto
==============================================================================
--- trunk/src/addon_checks.hpp (added)
+++ trunk/src/addon_checks.hpp Sun Jun  8 22:06:28 2008
@@ -1,0 +1,68 @@
+/* $Id$ */
+/*
+   Copyright (C) 2003 - 2008 by David White <[EMAIL PROTECTED]>
+                 2008 by Ignacio R. Morelle <[EMAIL PROTECTED]>
+   Part of the Battle for Wesnoth Project http://www.wesnoth.org/
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License version 2
+   or at your option any later version.
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY.
+
+   See the COPYING file for more details.
+*/
+
+#ifndef ADDON_CHECKS_HPP_INCLUDED
+#define ADDON_CHECKS_HPP_INCLUDED
+
+#include <vector>
+#include <string>
+
+class config;
+
+//! Values used for the directory scans
+enum ADDON_GROUP {
+       ADDON_SINGLEPLAYER,     //!< (userdir)/data/campaigns
+       ADDON_MULTIPLAYER,      //!< (userdir)/data/multiplayer
+       ADDON_ALL                       //!< all of the above.
+};
+
+//! Values used for add-on classification; UI-only
+//! at the moment, in the future it could be used for
+//! directory allocation too, removing the need for
+//! the ADDON_GROUP constants (TODO).
+enum ADDON_TYPE {
+       ADDON_UNKNOWN,          //!< a.k.a. anything.
+       ADDON_SP_CAMPAIGN,      //!< Single-player campaign.
+       ADDON_SP_SCENARIO,      //!< Single-player scenario.
+       ADDON_MP_CAMPAIGN,      //!< Multiplayer campaign.
+       ADDON_MP_SCENARIO,      //!< Multiplayer scenario.
+       ADDON_MP_MAPS,          //!< Multiplayer plain (no WML) map pack.
+       ADDON_MP_ERA,           //!< Multiplayer era.
+       ADDON_MP_FACTION,       //!< Multiplayer faction.
+       // NOTE: following two still require proper engine support
+       //ADDON_MOD,                    // Modification of the game for SP 
and/or MP.
+       //ADDON_GUI,                    // GUI add-ons/themes.
+       ADDON_MEDIA                     //!< Miscellaneous content/media (unit 
packs, terrain packs, music packs, etc.).
+};
+
+ADDON_TYPE get_addon_type(const std::string& str);
+
+inline ADDON_GROUP is_addon_sp_or_mp(ADDON_TYPE t)
+{
+       return (t == ADDON_MP_CAMPAIGN ||
+               t == ADDON_MP_SCENARIO ||
+               t == ADDON_MP_ERA ||
+               t == ADDON_MP_MAPS ||
+               t == ADDON_MP_FACTION) ? ADDON_MULTIPLAYER : ADDON_SINGLEPLAYER;
+}
+
+//! Checks whether an add-on name is legal or not.
+bool addon_name_legal(const std::string& name);
+//! Probes an add-on archive for illegal names.
+bool check_names_legal(const config& dir);
+//! Return a vector of detected scripts.
+std::vector<config *> find_scripts(const config &cfg, std::string extension);
+
+#endif /* !ADDON_CHECKS_HPP_INCLUDED */

Added: trunk/src/addon_management.cpp
URL: 
http://svn.gna.org/viewcvs/wesnoth/trunk/src/addon_management.cpp?rev=27050&view=auto
==============================================================================
--- trunk/src/addon_management.cpp (added)
+++ trunk/src/addon_management.cpp Sun Jun  8 22:06:28 2008
@@ -1,0 +1,313 @@
+/* $Id$ */
+/*
+   Copyright (C) 2003 - 2008 by David White <[EMAIL PROTECTED]>
+                 2008 by Ignacio R. Morelle <[EMAIL PROTECTED]>
+   Part of the Battle for Wesnoth Project http://www.wesnoth.org/
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License version 2
+   or at your option any later version.
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY.
+
+   See the COPYING file for more details.
+*/
+
+#include "global.hpp"
+
+#include "config.hpp"
+#include "filesystem.hpp"
+#include "addon_management.hpp"
+#include "serialization/parser.hpp"
+#include "serialization/string_utils.hpp"
+
+#include <algorithm>
+#include <cstring>
+
+namespace {
+       std::string get_addon_type_parent(ADDON_GROUP addon_type)
+       {
+               switch (addon_type)
+               {
+                       case ADDON_MULTIPLAYER:
+                               return get_addon_campaigns_dir();
+                       case ADDON_SINGLEPLAYER:
+                       default:
+                               return get_addon_campaigns_dir();
+               }
+       }
+
+       void setup_addon_dirs()
+       {
+               make_directory(get_user_data_dir() + "/data");
+               make_directory(get_addon_campaigns_dir());
+               make_directory(get_mp_addons_dir());
+       }
+}
+
+void get_addon_info(const std::string& addon_name, ADDON_GROUP addon_type, 
config& cfg)
+{
+       const std::string parentd = get_addon_type_parent(addon_type);
+
+       // Cope with old-style or new-style file organization 
+       std::string exterior = parentd + "/" + addon_name + ".pbl";
+       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 set_addon_info(const std::string& addon_name, ADDON_GROUP addon_type, 
const config& cfg)
+{
+       const std::string parentd = get_addon_type_parent(addon_type);
+
+       scoped_ostream stream = ostream_file(parentd + "/" + addon_name + 
".pbl");
+       write(*stream, cfg);
+}
+
+void remove_local_addon(const std::string& addon, ADDON_GROUP addon_type)
+{
+       const std::string addon_dir = get_addon_type_parent(addon_type) + "/" + 
addon;
+
+       delete_directory(addon_dir);
+       if (file_exists(addon_dir + ".cfg"))
+               delete_directory(addon_dir + ".cfg");
+}
+
+std::vector< addon_list_item > enumerate_all_available_addons()
+{
+       const std::vector< std::string > mp_addons_v = 
available_addons(ADDON_MULTIPLAYER);
+       const std::vector< std::string > sp_addons_v = 
available_addons(ADDON_SINGLEPLAYER);
+       std::vector< addon_list_item > result;
+
+       std::vector< std::string >::const_iterator i;
+
+       for (i = mp_addons_v.begin(); i != mp_addons_v.end(); ++i) {
+               result.push_back(std::make_pair(*i, ADDON_MULTIPLAYER));
+       }
+       for (i = sp_addons_v.begin(); i != sp_addons_v.end(); ++i) {
+               result.push_back(std::make_pair(*i, ADDON_SINGLEPLAYER));
+       }
+
+       return result;
+}
+
+std::vector<std::string> available_addons(ADDON_GROUP addons_type)
+{
+       std::vector<std::string> res;
+       std::vector<std::string> files, dirs;
+       const std::string parentd = get_addon_type_parent(addons_type);
+       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);
+               }
+       }
+
+       return res;
+}
+
+std::vector<std::string> installed_addons(ADDON_GROUP addons_type)
+{
+       std::vector<std::string> res;
+       const std::string parentd = get_addon_type_parent(addons_type);
+       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;
+}
+
+namespace {
+       const char escape_char = 1;
+}
+
+static bool needs_escaping(char c) { return c == 0 || c == escape_char; }
+
+static std::string encode_binary(const std::string& str)
+{
+       std::string res;
+       res.resize(str.size());
+       size_t n = 0;
+       for(std::string::const_iterator j = str.begin(); j != str.end(); ++j) {
+               if(needs_escaping(*j)) {
+                       res.resize(res.size()+1);
+                       res[n++] = escape_char;
+                       res[n++] = *j + 1;
+               } else {
+                       res[n++] = *j;
+               }
+       }
+
+       return res;
+}
+
+static std::string unencode_binary(const std::string& str)
+{
+       std::string res;
+       res.resize(str.size());
+
+       size_t n = 0;
+       for(std::string::const_iterator j = str.begin(); j != str.end(); ++j) {
+               if(*j == escape_char && j+1 != str.end()) {
+                       ++j;
+                       res[n++] = *j - 1;
+                       res.resize(res.size()-1);
+               } else {
+                       res[n++] = *j;
+               }
+       }
+
+       return res;
+}
+
+static std::pair<std::vector<std::string>, std::vector<std::string> > 
read_ignore_patterns(const std::string& addon_name, ADDON_GROUP addon_type)
+{
+       const std::string parentd = get_addon_type_parent(addon_type);
+
+       std::pair<std::vector<std::string>, std::vector<std::string> > patterns;
+       std::string exterior = parentd + "/" + addon_name + ".ign";
+       std::string interior = parentd + "/" + addon_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");
+               /* 
+                * Prevent certain potential security compromises.
+                * The idea is to stop bad guys from uploading things
+                * that could become trojans if an unsuspecting user
+                * downloads them.
+                */
+               patterns.first.push_back("*.exe");
+               patterns.first.push_back("*.bat");
+               patterns.first.push_back("*.cmd");
+               patterns.first.push_back("*.com");
+               patterns.first.push_back("*.scr");
+               patterns.first.push_back("*.sh");
+               patterns.first.push_back("*.js");
+               patterns.first.push_back("*.vbs");
+               patterns.first.push_back("*.o");
+               /* Remove junk created by certain file manager ;) */
+               patterns.first.push_back("Thumbs.db");
+               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, std::pair<std::vector<std::string>, std::vector<std::string> >& 
ignore_patterns)
+{
+       cfg["name"] = dirname;
+       const std::string dir = path + '/' + dirname;
+
+       std::vector<std::string> files, dirs;
+       get_files_in_dir(dir,&files,&dirs);
+       for(std::vector<std::string>::const_iterator i = files.begin(); i != 
files.end(); ++i) {
+               bool valid = true;
+               for(std::vector<std::string>::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<std::string>::const_iterator j = dirs.begin(); j != 
dirs.end(); ++j) {
+               bool valid = true;
+               for(std::vector<std::string>::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_addon(const std::string& addon_name, ADDON_GROUP addon_type, 
config& cfg)
+{
+       const std::string parentd = get_addon_type_parent(addon_type);
+
+       std::pair<std::vector<std::string>, std::vector<std::string> > 
ignore_patterns;
+       // External .cfg may not exist; newer campaigns have a _main.cfg
+       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, addon_type);
+       archive_dir(parentd, addon_name, cfg.add_child("dir"), ignore_patterns);
+}
+
+static void unarchive_file(const std::string& path, const config& cfg)
+{
+       write_file(path + '/' + cfg["name"].str(), 
unencode_binary(cfg["contents"]));
+}
+
+static void unarchive_dir(const std::string& path, const config& cfg)
+{
+       std::string dir;
+       if (cfg["name"].empty())
+               dir = path;
+       else
+               dir = path + '/' + cfg["name"].str();
+
+       make_directory(dir);
+
+       const config::child_list& dirs = cfg.get_children("dir");
+       for(config::child_list::const_iterator i = dirs.begin(); i != 
dirs.end(); ++i) {
+               unarchive_dir(dir,**i);
+       }
+
+       const config::child_list& files = cfg.get_children("file");
+       for(config::child_list::const_iterator j = files.begin(); j != 
files.end(); ++j) {
+               unarchive_file(dir,**j);
+       }
+}
+
+void unarchive_addon(const config& cfg)
+{
+       ADDON_GROUP addon_type = is_addon_sp_or_mp(get_addon_type(cfg["type"]));
+       const std::string parentd = get_addon_type_parent(addon_type);
+       setup_addon_dirs();
+       unarchive_dir(parentd, cfg);
+}

Added: trunk/src/addon_management.hpp
URL: 
http://svn.gna.org/viewcvs/wesnoth/trunk/src/addon_management.hpp?rev=27050&view=auto
==============================================================================
--- trunk/src/addon_management.hpp (added)
+++ trunk/src/addon_management.hpp Sun Jun  8 22:06:28 2008
@@ -1,0 +1,59 @@
+/* $Id$ */
+/*
+   Copyright (C) 2003 - 2008 by David White <[EMAIL PROTECTED]>
+                 2008 by Ignacio R. Morelle <[EMAIL PROTECTED]>
+   Part of the Battle for Wesnoth Project http://www.wesnoth.org/
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License version 2
+   or at your option any later version.
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY.
+
+   See the COPYING file for more details.
+*/
+
+#ifndef ADDON_MANAGEMENT_HPP_INCLUDED
+#define ADDON_MANAGEMENT_HPP_INCLUDED
+
+class config;
+
+#include "addon_checks.hpp"
+
+#include <string>
+#include <vector>
+#include <utility>
+
+typedef std::pair< std::string, ADDON_GROUP > addon_list_item;
+
+void remove_local_addon(const std::string& addon, ADDON_GROUP addon_type);
+
+//! Gets the publish information for an add-on
+//! @param addon_name The add-on's main directory/file name.
+//! @param addon_type The type of add-on for locating it in the directory tree.
+//! @param cfg A config object to store the add-on's properties.
+void get_addon_info(const std::string& addon_name, ADDON_GROUP addon_type, 
class config& cfg);
+
+//! Sets the publish information for an add-on
+//! @param addon_name The add-on's main directory/file name.
+//! @param addon_type The type of add-on for locating it in the directory tree.
+//! @param cfg A config object from which the add-on's properties are copied.
+void set_addon_info(const std::string& addon_name, ADDON_GROUP addon_type, 
const class config& cfg);
+
+//! Returns a list of local add-ons that can be published.
+//! @param addon_type The type of add-on for locating it in the directory tree.
+std::vector<std::string> available_addons(ADDON_GROUP addons_type);
+
+//! Returns a list of all kinds of local add-ons that can be published.
+std::vector< addon_list_item > enumerate_all_available_addons();
+
+//! Retrieves the names of all installed add-ons of a kind.
+//! @param addon_type The type of add-on for locating it in the directory tree.
+std::vector<std::string> installed_addons(ADDON_GROUP addons_type);
+
+//! Archives an add-on into a config object for campaignd transactions.
+void archive_addon(const std::string& addon_name, ADDON_GROUP addon_type, 
class config& cfg);
+//! Unarchives an add-on from campaignd's retrieved config object.
+void unarchive_addon(const class config& cfg);
+
+#endif /* !ADDON_MANAGEMENT_HPP_INCLUDED */


_______________________________________________
Wesnoth-commits mailing list
[email protected]
https://mail.gna.org/listinfo/wesnoth-commits

Reply via email to