X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=src%2Faddon%2Faddon.cpp;h=26884229b0536a24a20a0e8daf1574541018ab42;hb=9af7ca781183b7d57410e5cd3b8bc7f8128ed1b0;hp=377116140fb82e60bebc68d44651a7fac2de3594;hpb=79f870896e74b27bd093dca36b90e5ea3182ce92;p=supertux.git diff --git a/src/addon/addon.cpp b/src/addon/addon.cpp index 377116140..26884229b 100644 --- a/src/addon/addon.cpp +++ b/src/addon/addon.cpp @@ -1,12 +1,11 @@ -// $Id$ -// // SuperTux - Add-on // Copyright (C) 2007 Christoph Sommer +// 2014 Ingo Ruhnke // -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -14,122 +13,163 @@ // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA -// 02111-1307, USA. -// +// along with this program. If not, see . -#include -#include -#include -#include -#include "lisp/lisp.hpp" -#include "lisp/writer.hpp" -#include "lisp/parser.hpp" #include "addon/addon.hpp" -#include "addon/addon_manager.hpp" -#include "log.hpp" -#include "addon/md5.hpp" -std::string -Addon::get_md5() const -{ - if (!installed) { - if (stored_md5 == "") log_warning << "Add-on not installed and no stored MD5 available" << std::endl; - return stored_md5; - } +#include +#include +#include - if (calculated_md5 != "") return calculated_md5; +#include "lisp/parser.hpp" +#include "util/reader.hpp" +#include "util/writer.hpp" +#include "util/log.hpp" - if (installed_physfs_filename == "") throw std::runtime_error("Tried to calculate MD5 of Add-on with unknown filename"); +namespace { - // TODO: this does not work as expected for some files -- IFileStream seems to not always behave like an ifstream. - //IFileStream ifs(installed_physfs_filename); - //std::string md5 = MD5(ifs).hex_digest(); +static const char* s_allowed_characters = "-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; - MD5 md5; - PHYSFS_file* file; - file = PHYSFS_openRead(installed_physfs_filename.c_str()); - unsigned char buffer[1024]; - while (true) { - PHYSFS_sint64 len = PHYSFS_read(file, buffer, 1, sizeof(buffer)); - if (len <= 0) break; - md5.update(buffer, len); +Addon::Type addon_type_from_string(const std::string& type) +{ + if (type == "world") + { + return Addon::WORLD; + } + else if (type == "worldmap") + { + return Addon::WORLDMAP; + } + else if (type == "levelset") + { + return Addon::LEVELSET; + } + else + { + throw std::runtime_error("not a valid Addon::Type: " + type); } - PHYSFS_close(file); - - calculated_md5 = md5.hex_digest(); - log_debug << "MD5 of " << title << ": " << calculated_md5 << std::endl; - - return calculated_md5; } -void -Addon::parse(const lisp::Lisp& lisp) +} // namespace + +std::unique_ptr +Addon::parse(const Reader& lisp) { - try { - lisp.get("kind", kind); - lisp.get("title", title); - lisp.get("author", author); - lisp.get("license", license); - lisp.get("http-url", http_url); - lisp.get("file", suggested_filename); - lisp.get("md5", stored_md5); - } catch(std::exception& e) { + std::unique_ptr addon(new Addon); + + try + { + if (!lisp.get("id", addon->m_id)) + { + throw std::runtime_error("(id ...) field missing from addon description"); + } + + if (addon->m_id.empty()) + { + throw std::runtime_error("addon id is empty"); + } + + if (addon->m_id.find_first_not_of(s_allowed_characters) != std::string::npos) + { + throw std::runtime_error("addon id contains illegal characters: " + addon->m_id); + } + + lisp.get("version", addon->m_version); + + std::string type; + lisp.get("type", type); + addon->m_type = addon_type_from_string(type); + + lisp.get("title", addon->m_title); + lisp.get("author", addon->m_author); + lisp.get("license", addon->m_license); + lisp.get("url", addon->m_url); + lisp.get("md5", addon->m_md5); + + return addon; + } + catch(const std::exception& err) + { std::stringstream msg; - msg << "Problem when parsing addoninfo: " << e.what(); + msg << "Problem when parsing addoninfo: " << err.what(); throw std::runtime_error(msg.str()); } } -void -Addon::parse(std::string fname) +std::unique_ptr +Addon::parse(const std::string& fname) { - try { + try + { lisp::Parser parser; const lisp::Lisp* root = parser.parse(fname); const lisp::Lisp* addon = root->get_lisp("supertux-addoninfo"); - if(!addon) throw std::runtime_error("file is not a supertux-addoninfo file."); - parse(*addon); - } catch(std::exception& e) { + if(!addon) + { + throw std::runtime_error("file is not a supertux-addoninfo file."); + } + else + { + return parse(*addon); + } + } + catch(const std::exception& err) + { std::stringstream msg; - msg << "Problem when reading addoninfo '" << fname << "': " << e.what(); + msg << "Problem when reading addoninfo '" << fname << "': " << err.what(); throw std::runtime_error(msg.str()); } } -void -Addon::write(lisp::Writer& writer) const +Addon::Addon() : + m_id(), + m_version(0), + m_type(), + m_title(), + m_author(), + m_license(), + m_url(), + m_md5(), + m_install_filename(), + m_enabled(false) +{} + +std::string +Addon::get_filename() const { - writer.start_list("supertux-addoninfo"); - if (kind != "") writer.write_string("kind", kind); - if (title != "") writer.write_string("title", title); - if (author != "") writer.write_string("author", author); - if (license != "") writer.write_string("license", license); - if (http_url != "") writer.write_string("http-url", http_url); - if (suggested_filename != "") writer.write_string("file", suggested_filename); - if (stored_md5 != "") writer.write_string("md5", stored_md5); - writer.end_list("supertux-addoninfo"); + return get_id() + ".zip"; } -void -Addon::write(std::string fname) const +std::string +Addon::get_install_filename() const { - lisp::Writer writer(fname); - write(writer); + return m_install_filename; } -bool -Addon::operator==(Addon addon2) const +bool +Addon::is_installed() const { - std::string s1 = this->get_md5(); - std::string s2 = addon2.get_md5(); + return !m_install_filename.empty(); +} - if ((s1 != "") && (s2 != "")) return (s1 == s2); +bool +Addon::is_enabled() const +{ + return m_enabled; +} - if (this->title != addon2.title) return false; - if (this->author != addon2.author) return false; - if (this->kind != addon2.kind) return false; - return true; +void +Addon::set_install_filename(const std::string& absolute_filename, const std::string& md5) +{ + m_install_filename = absolute_filename; + m_md5 = md5; } +void +Addon::set_enabled(bool v) +{ + m_enabled = v; +} + + +/* EOF */