- //std::string html = "Blubb<a href=\"http://www.deltadevelopment.de/users/christoph/supertux/addons/coconut_fortress.zip\">Coconut Fortress</a>\nFoobar<a href=\"http://www.deltadevelopment.de/users/christoph/supertux/addons/in_the_spring.zip\">Another</a>Baz";
- static const std::string startToken = "href=\"";
- static const std::string endToken = "\"";
-
- // extract urls: for each startToken found...
- std::string::size_type n = 0;
- while ((n = html.find(startToken)) != std::string::npos) {
-
- // strip everything up to and including token
- html.erase(0, n + startToken.length());
-
- // find end token
- std::string::size_type n2 = html.find(endToken);
- if (n2 == std::string::npos) break;
-
- // extract url: it's the string inbetween
- std::string url = html.substr(0, n2);
-
- // strip everything up to and including endToken
- html.erase(0, n2 + endToken.length());
-
- // make absolute url
- url = std::string(baseUrl) + url;
-
- // make sure url looks like it points to an archive
- static const std::string archiveExt = ".zip";
- if (url.compare(url.length()-archiveExt.length(), archiveExt.length(), archiveExt) != 0) continue;
-
- // extract nice title
- std::string::size_type n = url.rfind('/') + 1;
- if (n == std::string::npos) n = 0;
- std::string title = url.substr(n, url.length() - n - archiveExt.length());
-
- // construct file name
- std::string fname = url.substr(n);
-
- // make sure it does not contain weird characters
- if (fname.find_first_not_of("match.quiz-proxy_gwenblvdjfks0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ") != std::string::npos) continue;
-
- Addon addon;
- addon.title = title;
- addon.fname = fname;
- addon.url = url;
- addon.isInstalled = false;
-
- addons.push_back(addon);
+ if (addoninfos == "") throw std::runtime_error("Add-on list download failed");
+
+ try {
+ lisp::Parser parser;
+ std::stringstream addoninfos_stream(addoninfos);
+ const lisp::Lisp* root = parser.parse(addoninfos_stream, "supertux-addons");
+
+ const lisp::Lisp* addons_lisp = root->get_lisp("supertux-addons");
+ if(!addons_lisp) throw std::runtime_error("file is not a supertux-addons file.");
+
+ lisp::ListIterator iter(addons_lisp);
+ while(iter.next()) {
+ const std::string& token = iter.item();
+ if(token == "supertux-addoninfo") {
+ Addon addon;
+ addon.parse(*(iter.lisp()));
+
+ // make sure the Add-on's file name does not contain weird characters
+ if (addon.file.find_first_not_of("match.quiz-proxy_gwenblvdjfks0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ") != std::string::npos) {
+ log_warning << "Add-on \"" << addon.title << "\" contains unsafe file name. Skipping." << std::endl;
+ continue;
+ }
+
+ addon.isInstalled = false;
+ addons.push_back(addon);
+ } else {
+ log_warning << "Unknown token '" << token << "' in supertux-addons file" << std::endl;
+ }
+ }
+ } catch(std::exception& e) {
+ std::stringstream msg;
+ msg << "Problem when reading addoninfo: " << e.what();
+ throw std::runtime_error(msg.str());