X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=src%2Faddon%2Faddon.cpp;h=26884229b0536a24a20a0e8daf1574541018ab42;hb=9a5a375c953da2f1c19f52f41c65aeac4c0f4158;hp=0bbe885b5c024f38d6733495b3929c169b2245f6;hpb=477ff26b2f06ee1743996a0feba8ebe0e6c28ba4;p=supertux.git diff --git a/src/addon/addon.cpp b/src/addon/addon.cpp index 0bbe885b5..26884229b 100644 --- a/src/addon/addon.cpp +++ b/src/addon/addon.cpp @@ -1,5 +1,6 @@ // 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 @@ -20,112 +21,155 @@ #include #include -#include "addon/md5.hpp" #include "lisp/parser.hpp" #include "util/reader.hpp" #include "util/writer.hpp" #include "util/log.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; - } - - if (calculated_md5 != "") return calculated_md5; +namespace { - if (installed_physfs_filename == "") throw std::runtime_error("Tried to calculate MD5 of Add-on with unknown filename"); +static const char* s_allowed_characters = "-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; - // 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(); - - 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 +} // 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("kind", kind); - if (title != "") writer.write("title", title); - if (author != "") writer.write("author", author); - if (license != "") writer.write("license", license); - if (http_url != "") writer.write("http-url", http_url); - if (suggested_filename != "") writer.write("file", suggested_filename); - if (stored_md5 != "") writer.write("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 */