Fix compile on certain Linux configurations, reduce spawn point height
[oweals/minetest.git] / src / serverlist.cpp
1 /*
2 Minetest-c55
3 Copyright (C) 2011 celeron55, Perttu Ahola <celeron55@gmail.com>
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU Lesser General Public License as published by
7 the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public License along
16 with this program; if not, write to the Free Software Foundation, Inc.,
17 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19
20 #include <iostream>
21 #include <sstream>
22 #include <algorithm>
23
24 #include "main.h" // for g_settings
25 #include "settings.h"
26 #include "serverlist.h"
27 #include "filesys.h"
28 #include "porting.h"
29 #include "log.h"
30 #if USE_CURL
31 #include <curl/curl.h>
32 #endif
33
34 namespace ServerList
35 {
36 std::string getFilePath()
37 {
38         std::string serverlist_file = g_settings->get("serverlist_file");
39
40         std::string rel_path = std::string("client") + DIR_DELIM
41                 + "serverlist" + DIR_DELIM
42                 + serverlist_file;
43         std::string path = porting::path_share + DIR_DELIM + rel_path;
44         return path;
45 }
46
47 std::vector<ServerListSpec> getLocal()
48 {
49         std::string path = ServerList::getFilePath();
50         std::string liststring;
51         if(fs::PathExists(path))
52         {
53                 std::ifstream istream(path.c_str(), std::ios::binary);
54                 if(istream.is_open())
55                 {
56                         std::ostringstream ostream;
57                         ostream << istream.rdbuf();
58                         liststring = ostream.str();
59                         istream.close();
60                 }
61         }
62
63         return ServerList::deSerialize(liststring);
64 }
65
66
67 #if USE_CURL
68
69 static size_t WriteCallback(void *contents, size_t size, size_t nmemb, void *userp)
70 {
71     ((std::string*)userp)->append((char*)contents, size * nmemb);
72     return size * nmemb;
73 }
74
75
76 std::vector<ServerListSpec> getOnline()
77 {
78         std::string liststring;
79         CURL *curl;
80
81         curl = curl_easy_init();
82         if (curl)
83         {
84                 CURLcode res;
85
86                 curl_easy_setopt(curl, CURLOPT_URL, g_settings->get("serverlist_url").c_str());
87                 curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, ServerList::WriteCallback);
88                 curl_easy_setopt(curl, CURLOPT_WRITEDATA, &liststring);
89
90                 res = curl_easy_perform(curl);
91                 if (res != CURLE_OK)
92                         errorstream<<"Serverlist at url "<<g_settings->get("serverlist_url")<<" not found (internet connection?)"<<std::endl;
93                 curl_easy_cleanup(curl);
94         }
95
96         return ServerList::deSerialize(liststring);
97 }
98
99 #endif
100
101 /*
102         Delete a server fromt he local favorites list
103 */
104 bool deleteEntry (ServerListSpec server)
105 {
106         std::vector<ServerListSpec> serverlist = ServerList::getLocal();
107         for(unsigned i = 0; i < serverlist.size(); i++)
108         {
109                 if  (serverlist[i].address == server.address
110                 &&   serverlist[i].port    == server.port)
111                 {
112                         serverlist.erase(serverlist.begin() + i);
113                 }
114         }
115
116         std::string path = ServerList::getFilePath();
117         std::ofstream stream (path.c_str());
118         if (stream.is_open())
119         {
120                 stream<<ServerList::serialize(serverlist);
121                 return true;
122         }
123         return false;
124 }
125
126 /*
127         Insert a server to the local favorites list
128 */
129 bool insert (ServerListSpec server)
130 {
131         // Remove duplicates
132         ServerList::deleteEntry(server);
133
134         std::vector<ServerListSpec> serverlist = ServerList::getLocal();
135
136         // Insert new server at the top of the list
137         serverlist.insert(serverlist.begin(), server);
138
139         std::string path = ServerList::getFilePath();
140         std::ofstream stream (path.c_str());
141         if (stream.is_open())
142         {
143                 stream<<ServerList::serialize(serverlist);
144         }
145
146         return false;
147 }
148
149 std::vector<ServerListSpec> deSerialize(std::string liststring)
150 {
151         std::vector<ServerListSpec> serverlist;
152         std::istringstream stream(liststring);
153         std::string line;
154         while (std::getline(stream, line))
155         {
156                 std::transform(line.begin(), line.end(),line.begin(), ::toupper);
157                 if (line == "[SERVER]")
158                 {
159                         ServerListSpec thisserver;
160                         std::getline(stream, thisserver.name);
161                         std::getline(stream, thisserver.address);
162                         std::getline(stream, thisserver.port);
163                         std::getline(stream, thisserver.description);
164                         serverlist.push_back(thisserver);
165                 }
166         }
167         return serverlist;
168 }
169
170 std::string serialize(std::vector<ServerListSpec> serverlist)
171 {
172         std::string liststring;
173         for(std::vector<ServerListSpec>::iterator i = serverlist.begin(); i != serverlist.end(); i++)
174         {
175                 liststring += "[server]\n";
176                 liststring += i->name + "\n";
177                 liststring += i->address + "\n";
178                 liststring += i->port + "\n";
179                 liststring += i->description + "\n";
180                 liststring += "\n";
181         }
182         return liststring;
183 }
184
185 } //namespace ServerList