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