Removed unneeded curl includes
[supertux.git] / src / addon / addon_list.cpp
1 //  SuperTux
2 //  Copyright (C) 2014 Ingo Ruhnke <grumbel@gmail.com>
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_list.hpp"
18
19 #include <memory>
20 #include <sstream>
21 #include <stdexcept>
22
23 #include "addon/addon.hpp"
24 #include "lisp/lisp.hpp"
25 #include "lisp/list_iterator.hpp"
26 #include "lisp/parser.hpp"
27 #include "util/log.hpp"
28
29 static const char* allowed_characters = "-.0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz";
30
31 std::vector<std::unique_ptr<Addon> >
32 AddonList::parse(const std::string& addoninfos)
33 {
34   std::vector<std::unique_ptr<Addon> > m_addons;
35
36   try
37   {
38     lisp::Parser parser;
39     std::stringstream addoninfos_stream(addoninfos);
40     const lisp::Lisp* root = parser.parse(addoninfos_stream, "supertux-addons");
41
42     const lisp::Lisp* addons_lisp = root->get_lisp("supertux-addons");
43     if(!addons_lisp)
44     {
45       throw std::runtime_error("Downloaded file is not an Add-on list");
46     }
47
48     lisp::ListIterator iter(addons_lisp);
49     while(iter.next())
50     {
51       const std::string& token = iter.item();
52       if(token != "supertux-addoninfo")
53       {
54         log_warning << "Unknown token '" << token << "' in Add-on list" << std::endl;
55         continue;
56       }
57       std::unique_ptr<Addon> addon(new Addon(m_addons.size()));
58       addon->parse(*(iter.lisp()));
59       addon->installed = false;
60       addon->loaded = false;
61
62       // make sure the list of known Add-ons does not already contain this one
63       bool exists = false;
64       for (auto i = m_addons.begin(); i != m_addons.end(); ++i) {
65         if (**i == *addon) {
66           exists = true;
67           break;
68         }
69       }
70
71       if (exists)
72       {
73         // do nothing
74       }
75       else if (addon->suggested_filename.find_first_not_of(allowed_characters) != std::string::npos)
76       {
77         // make sure the Add-on's file name does not contain weird characters
78         log_warning << "Add-on \"" << addon->title << "\" contains unsafe file name. Skipping." << std::endl;
79       }
80       else
81       {
82         m_addons.push_back(std::move(addon));
83       }
84     }
85
86     return m_addons;
87   }
88   catch(std::exception& e)
89   {
90     std::stringstream msg;
91     msg << "Problem when reading Add-on list: " << e.what();
92     throw std::runtime_error(msg.str());
93   }
94 }
95
96 /* EOF */