1 | // SuperTux - Add-on |
2 | // Copyright (C) 2007 Christoph Sommer <christoph.sommer@2007.expires.deltadevelopment.de> |
3 | // 2014 Ingo Ruhnke <grumbel@gmail.com> |
4 | // |
5 | // This program is free software: you can redistribute it and/or modify |
6 | // it under the terms of the GNU General Public License as published by |
7 | // the Free Software Foundation, either version 3 of the License, or |
8 | // (at your option) any later version. |
9 | // |
10 | // This program is distributed in the hope that it will be useful, |
11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of |
12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
13 | // GNU General Public License for more details. |
14 | // |
15 | // You should have received a copy of the GNU General Public License |
16 | // along with this program. If not, see <http://www.gnu.org/licenses/>. |
17 | |
18 | #include "addon/addon.hpp" |
19 | |
20 | #include <sstream> |
21 | |
22 | #include "util/reader.hpp" |
23 | #include "util/reader_document.hpp" |
24 | #include "util/reader_mapping.hpp" |
25 | |
26 | namespace { |
27 | |
28 | static const char* s_allowed_characters = "-_0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" ; |
29 | |
30 | Addon::Type addon_type_from_string(const std::string& type) |
31 | { |
32 | if (type == "world" ) |
33 | { |
34 | return Addon::WORLD; |
35 | } |
36 | else if (type == "worldmap" ) |
37 | { |
38 | return Addon::WORLDMAP; |
39 | } |
40 | else if (type == "levelset" ) |
41 | { |
42 | return Addon::LEVELSET; |
43 | } |
44 | else if (type == "languagepack" ) |
45 | { |
46 | return Addon::LANGUAGEPACK; |
47 | } |
48 | else |
49 | { |
50 | throw std::runtime_error("not a valid Addon::Type: " + type); |
51 | } |
52 | } |
53 | |
54 | } // namespace |
55 | |
56 | std::unique_ptr<Addon> |
57 | Addon::parse(const ReaderMapping& mapping) |
58 | { |
59 | std::unique_ptr<Addon> addon(new Addon); |
60 | |
61 | try |
62 | { |
63 | if (!mapping.get("id" , addon->m_id)) |
64 | { |
65 | throw std::runtime_error("(id ...) field missing from addon description" ); |
66 | } |
67 | |
68 | if (addon->m_id.empty()) |
69 | { |
70 | throw std::runtime_error("addon id is empty" ); |
71 | } |
72 | |
73 | if (addon->m_id.find_first_not_of(s_allowed_characters) != std::string::npos) |
74 | { |
75 | throw std::runtime_error("addon id contains illegal characters: " + addon->m_id); |
76 | } |
77 | |
78 | mapping.get("version" , addon->m_version); |
79 | |
80 | std::string type; |
81 | mapping.get("type" , type); |
82 | addon->m_type = addon_type_from_string(type); |
83 | |
84 | mapping.get("title" , addon->m_title); |
85 | mapping.get("author" , addon->m_author); |
86 | mapping.get("license" , addon->m_license); |
87 | mapping.get("url" , addon->m_url); |
88 | mapping.get("md5" , addon->m_md5); |
89 | mapping.get("format" , addon->m_format); |
90 | |
91 | return addon; |
92 | } |
93 | catch(const std::exception& err) |
94 | { |
95 | std::stringstream msg; |
96 | msg << "Problem when parsing addoninfo: " << err.what(); |
97 | throw std::runtime_error(msg.str()); |
98 | } |
99 | } |
100 | |
101 | std::unique_ptr<Addon> |
102 | Addon::parse(const std::string& fname) |
103 | { |
104 | try |
105 | { |
106 | register_translation_directory(fname); |
107 | auto doc = ReaderDocument::from_file(fname); |
108 | auto root = doc.get_root(); |
109 | if (root.get_name() != "supertux-addoninfo" ) |
110 | { |
111 | throw std::runtime_error("file is not a supertux-addoninfo file." ); |
112 | } |
113 | else |
114 | { |
115 | return parse(root.get_mapping()); |
116 | } |
117 | } |
118 | catch(const std::exception& err) |
119 | { |
120 | std::stringstream msg; |
121 | msg << "Problem when reading addoninfo '" << fname << "': " << err.what(); |
122 | throw std::runtime_error(msg.str()); |
123 | } |
124 | } |
125 | |
126 | Addon::Addon() : |
127 | m_id(), |
128 | m_version(0), |
129 | m_type(), |
130 | m_title(), |
131 | m_author(), |
132 | m_license(), |
133 | m_format(0), |
134 | m_url(), |
135 | m_md5(), |
136 | m_install_filename(), |
137 | m_enabled(false) |
138 | {} |
139 | |
140 | std::string |
141 | Addon::get_filename() const |
142 | { |
143 | return get_id() + ".zip" ; |
144 | } |
145 | |
146 | std::string |
147 | Addon::get_install_filename() const |
148 | { |
149 | return m_install_filename; |
150 | } |
151 | |
152 | bool |
153 | Addon::is_installed() const |
154 | { |
155 | return !m_install_filename.empty(); |
156 | } |
157 | |
158 | bool |
159 | Addon::is_enabled() const |
160 | { |
161 | return m_enabled; |
162 | } |
163 | |
164 | void |
165 | Addon::set_install_filename(const std::string& absolute_filename, const std::string& md5) |
166 | { |
167 | m_install_filename = absolute_filename; |
168 | m_md5 = md5; |
169 | } |
170 | |
171 | void |
172 | Addon::set_enabled(bool v) |
173 | { |
174 | m_enabled = v; |
175 | } |
176 | |
177 | |
178 | /* EOF */ |
179 | |