BF2MC-Matchmaker
webserver/client.cpp
1 #include <unistd.h>
2 #include <iostream>
3 #include <iomanip>
4 #include <fstream>
5 #include <regex>
6 #include <thread>
7 
8 #include <settings.h>
9 #include <logger.h>
10 #include <server.h>
11 #include <gpcm/client.h>
12 #include <globals.h>
13 #include <database.h>
14 #include <util.h>
15 #include <atomizes.hpp>
16 #include <service/file_system.h>
17 
18 #include <webserver/client.h>
19 
20 typedef void (Webserver::Client::*RequestActionFunc)(const atomizes::HTTPMessage&, const std::string&, const Util::Url::Variables&);
21 
22 static std::map<std::string, RequestActionFunc> mRequestActions =
23 {
24  // www.easports.com
25  // News
26  { "/gamescripts/bfmc/ps2/en/PS2news_de_DE.txt", &Webserver::Client::requestFile },
27  { "/gamescripts/bfmc/ps2/en/PS2news_en_GB.txt", &Webserver::Client::requestFile },
28  { "/gamescripts/bfmc/ps2/en/PS2news_en_US.txt", &Webserver::Client::requestFile },
29  { "/gamescripts/bfmc/ps2/en/PS2news_es_ES.txt", &Webserver::Client::requestFile },
30  { "/gamescripts/bfmc/ps2/en/PS2news_fr_FR.txt", &Webserver::Client::requestFile },
31  { "/gamescripts/bfmc/ps2/en/PS2news_it_IT.txt", &Webserver::Client::requestFile },
32  { "/gamescripts/bfmc/ps2/en/PS2news_jp.txt", &Webserver::Client::requestFile },
33  { "/gamescripts/bfmc/ps2/en/PS2news_nl.txt", &Webserver::Client::requestFile },
34  { "/gamescripts/bfmc/ps2/en/PS2news_sv.txt", &Webserver::Client::requestFile },
35 
36  // GameSpy Licenses
37  { "/gamescripts/bfmc/ps2/GameSpy/gs.de", &Webserver::Client::requestFile },
38  { "/gamescripts/bfmc/ps2/GameSpy/gs.en", &Webserver::Client::requestFile },
39  { "/gamescripts/bfmc/ps2/GameSpy/gs.es", &Webserver::Client::requestFile },
40  { "/gamescripts/bfmc/ps2/GameSpy/gs.fr", &Webserver::Client::requestFile },
41  { "/gamescripts/bfmc/ps2/GameSpy/gs.gb", &Webserver::Client::requestFile },
42  { "/gamescripts/bfmc/ps2/GameSpy/gs.it", &Webserver::Client::requestFile },
43  { "/gamescripts/bfmc/ps2/GameSpy/gs.jp", &Webserver::Client::requestFile },
44  { "/gamescripts/bfmc/ps2/GameSpy/gs.nl", &Webserver::Client::requestFile },
45  { "/gamescripts/bfmc/ps2/GameSpy/gs.roa", &Webserver::Client::requestFile },
46  { "/gamescripts/bfmc/ps2/GameSpy/gs.sv", &Webserver::Client::requestFile },
47  { "/gamescripts/bfmc/ps2/GameSpy/gs.uk", &Webserver::Client::requestFile },
48  { "/gamescripts/bfmc/ps2/GameSpy/gs.us", &Webserver::Client::requestFile },
49 
50  // EA Licenses
51  { "/gamescripts/bfmc/ps2/Ea/Ea.de", &Webserver::Client::requestFile },
52  { "/gamescripts/bfmc/ps2/Ea/Ea.en", &Webserver::Client::requestFile },
53  { "/gamescripts/bfmc/ps2/Ea/Ea.es", &Webserver::Client::requestFile },
54  { "/gamescripts/bfmc/ps2/Ea/Ea.fr", &Webserver::Client::requestFile },
55  { "/gamescripts/bfmc/ps2/Ea/Ea.gb", &Webserver::Client::requestFile },
56  { "/gamescripts/bfmc/ps2/Ea/Ea.it", &Webserver::Client::requestFile },
57  { "/gamescripts/bfmc/ps2/Ea/Ea.jp", &Webserver::Client::requestFile },
58  { "/gamescripts/bfmc/ps2/Ea/Ea.nl", &Webserver::Client::requestFile },
59  { "/gamescripts/bfmc/ps2/Ea/Ea.roa", &Webserver::Client::requestFile },
60  { "/gamescripts/bfmc/ps2/Ea/Ea.sv", &Webserver::Client::requestFile },
61  { "/gamescripts/bfmc/ps2/Ea/Ea.uk", &Webserver::Client::requestFile },
62  { "/gamescripts/bfmc/ps2/Ea/Ea.us", &Webserver::Client::requestFile },
63 
64  // PunkBuster Licenses
65  { "/gamescripts/bfmc/ps2/PunkBuster/pb.de", &Webserver::Client::requestFile },
66  { "/gamescripts/bfmc/ps2/PunkBuster/pb.en", &Webserver::Client::requestFile },
67  { "/gamescripts/bfmc/ps2/PunkBuster/pb.es", &Webserver::Client::requestFile },
68  { "/gamescripts/bfmc/ps2/PunkBuster/pb.fr", &Webserver::Client::requestFile },
69  { "/gamescripts/bfmc/ps2/PunkBuster/pb.gb", &Webserver::Client::requestFile },
70  { "/gamescripts/bfmc/ps2/PunkBuster/pb.it", &Webserver::Client::requestFile },
71  { "/gamescripts/bfmc/ps2/PunkBuster/pb.jp", &Webserver::Client::requestFile },
72  { "/gamescripts/bfmc/ps2/PunkBuster/pb.nl", &Webserver::Client::requestFile },
73  { "/gamescripts/bfmc/ps2/PunkBuster/pb.roa", &Webserver::Client::requestFile },
74  { "/gamescripts/bfmc/ps2/PunkBuster/pb.sv", &Webserver::Client::requestFile },
75  { "/gamescripts/bfmc/ps2/PunkBuster/pb.uk", &Webserver::Client::requestFile },
76  { "/gamescripts/bfmc/ps2/PunkBuster/pb.us", &Webserver::Client::requestFile },
77 
78  // Settings
79  { "/gamescripts/bfmc/ps2/Settings/GameModes.txt", &Webserver::Client::requestFile },
80  { "/gamescripts/bfmc/ps2/Settings/QuickMatchOptions.txt", &Webserver::Client::requestFile },
81  { "/gamescripts/bfmc/ps2/Settings/PlayLists.txt", &Webserver::Client::requestFile },
82  { "/gamescripts/bfmc/ps2/Settings/ClanMatchOptions.txt", &Webserver::Client::requestFile },
83 
84  // Locale
85  { "/gamescripts/bfmc/ps2/Locale/language.hdt", &Webserver::Client::requestFile },
86  { "/gamescripts/bfmc/ps2/Locale/brittish.pus", &Webserver::Client::requestFile },
87  { "/gamescripts/bfmc/ps2/Locale/dutch.pus", &Webserver::Client::requestFile },
88  { "/gamescripts/bfmc/ps2/Locale/english.pus", &Webserver::Client::requestFile },
89  { "/gamescripts/bfmc/ps2/Locale/french.pus", &Webserver::Client::requestFile },
90  { "/gamescripts/bfmc/ps2/Locale/german.pus", &Webserver::Client::requestFile },
91  { "/gamescripts/bfmc/ps2/Locale/italian.pus", &Webserver::Client::requestFile },
92  { "/gamescripts/bfmc/ps2/Locale/japanese.pus", &Webserver::Client::requestFile },
93  { "/gamescripts/bfmc/ps2/Locale/spanish.pus", &Webserver::Client::requestFile },
94  { "/gamescripts/bfmc/ps2/Locale/swedish.pus", &Webserver::Client::requestFile },
95 
96  // Advertisements
97  { "/gamescripts/bfmc/ps2/Ads/advert.de.sux", &Webserver::Client::requestFile },
98  { "/gamescripts/bfmc/ps2/Ads/advert.de.txt", &Webserver::Client::requestFile },
99  { "/gamescripts/bfmc/ps2/Ads/advert.en.sux", &Webserver::Client::requestFile },
100  { "/gamescripts/bfmc/ps2/Ads/advert.en.txt", &Webserver::Client::requestFile },
101  { "/gamescripts/bfmc/ps2/Ads/advert.es.sux", &Webserver::Client::requestFile },
102  { "/gamescripts/bfmc/ps2/Ads/advert.es.txt", &Webserver::Client::requestFile },
103  { "/gamescripts/bfmc/ps2/Ads/advert.fr.sux", &Webserver::Client::requestFile },
104  { "/gamescripts/bfmc/ps2/Ads/advert.fr.txt", &Webserver::Client::requestFile },
105  { "/gamescripts/bfmc/ps2/Ads/advert.gb.sux", &Webserver::Client::requestFile },
106  { "/gamescripts/bfmc/ps2/Ads/advert.it.txt", &Webserver::Client::requestFile },
107  { "/gamescripts/bfmc/ps2/Ads/advert.jp.sux", &Webserver::Client::requestFile },
108  { "/gamescripts/bfmc/ps2/Ads/advert.jp.txt", &Webserver::Client::requestFile },
109  { "/gamescripts/bfmc/ps2/Ads/advert.nl.sux", &Webserver::Client::requestFile },
110  { "/gamescripts/bfmc/ps2/Ads/advert.nl.txt", &Webserver::Client::requestFile },
111  { "/gamescripts/bfmc/ps2/Ads/advert.roa.sux", &Webserver::Client::requestFile },
112  { "/gamescripts/bfmc/ps2/Ads/advert.roa.txt", &Webserver::Client::requestFile },
113  { "/gamescripts/bfmc/ps2/Ads/advert.sv.sux", &Webserver::Client::requestFile },
114  { "/gamescripts/bfmc/ps2/Ads/advert.sv.txt", &Webserver::Client::requestFile },
115  { "/gamescripts/bfmc/ps2/Ads/advert.uk.sux", &Webserver::Client::requestFile },
116  { "/gamescripts/bfmc/ps2/Ads/advert.uk.txt", &Webserver::Client::requestFile },
117  { "/gamescripts/bfmc/ps2/Ads/advert.us.sux", &Webserver::Client::requestFile },
118  { "/gamescripts/bfmc/ps2/Ads/advert.us.txt", &Webserver::Client::requestFile },
119 
120  // bfmc.gamespy.com
121  // Stats
122  { "/BFMC/Stats/getplayerinfo.aspx", &Webserver::Client::requestGetPlayerInfo }, // Done
123  { "/BFMC/Stats/stats.aspx", &Webserver::Client::requestStats }, // Done
124 
125  // Clan
126  { "/BFMC/Clans/claninfo.aspx", &Webserver::Client::requestClanInfo }, // Done
127  { "/BFMC/Clans/clanmembers.aspx", &Webserver::Client::requestClanMembers }, // Done
128  { "/BFMC/Clans/leaderboard.aspx", &Webserver::Client::requestLeaderboard }, // Done
129  { "/BFMC/Clans/createclan.aspx", &Webserver::Client::requestCreateClan }, // Done
130  { "/BFMC/Clans/updateclan.aspx", &Webserver::Client::requestUpdateClan }, // Done
131  { "/BFMC/Clans/disband.aspx", &Webserver::Client::requestDisband }, // Done
132  { "/BFMC/Clans/changerank.aspx", &Webserver::Client::requestChangeRank }, // Done
133  { "/BFMC/Clans/addmember.aspx", &Webserver::Client::requestAddMember }, // Done
134  { "/BFMC/Clans/deletemember.aspx", &Webserver::Client::requestDeleteMember }, // Done
135  { "/BFMC/Clans/clanmessage.aspx", &Webserver::Client::requestClanMessage }, // Done
136 
137  // I like memes :D
139  { "/index.html", &Webserver::Client::requestMeme },
140  { "/favicon.ico", &Webserver::Client::requestEmpty },
141 
142  // API
143  { "/API/servers/live", &Webserver::Client::requestAPIServersLive },
144  { "/API/game", &Webserver::Client::requestAPIGame },
145  { "/API/games", &Webserver::Client::requestAPIGames },
146  { "/API/player", &Webserver::Client::requestAPIPlayer },
147  { "/API/clan", &Webserver::Client::requestAPIClan },
148  { "/API/leaderboard", &Webserver::Client::requestAPILeaderboard },
149  { "/API/leaderboard/clan", &Webserver::Client::requestAPILeaderboardClan },
150  { "/API/clan/simulation", &Webserver::Client::requestAPIClanSimulation },
151  { "/API/admin/clients", &Webserver::Client::requestAPIAdminClients },
152  { "/API/admin/kick", &Webserver::Client::requestAPIAdminKick },
153  { "/API/admin/message", &Webserver::Client::requestAPIAdminMessage },
154  { "/API/admin/playerstats/recalc", &Webserver::Client::requestAPIAdminPlayerStatsRecalc },
155 };
156 
157 Webserver::Client::Client(int socket, struct sockaddr_in address)
158 {
159  this->_socket = socket;
160  this->_address = address;
161  this->UpdateLastRecievedTime();
162 }
163 
165 {
166  this->Disconnect();
167 }
168 
170 {
171  std::vector<char> buffer(4096, 0);
172  atomizes::HTTPMessageParser http_parser;
173  atomizes::HTTPMessage http_request;
174 
175  // Read socket
176  int recv_size = read(this->_socket, &(buffer[0]), 4096);
177 
178  // If error or no data is recieved we end the connection
179  if(recv_size <= 0)
180  {
181  this->Disconnect();
182 
183  return;
184  }
185 
186  // Resize buffer
187  buffer.resize(recv_size);
188 
189  this->UpdateLastRecievedTime();
190 
191  // Parse buffer to http header
192  http_parser.Parse(&http_request, &(buffer[0]));
193 
194  // Trigger onRequest event
195  this->onRequest(http_request);
196 
197  this->Disconnect();
198 }
199 
201 {
202  this->Close();
203  g_webserver_server->onClientDisconnect(*this);
204 }
205 
206 void Webserver::Client::Send(const atomizes::HTTPMessage &http_response) const
207 {
208  this->Net::Socket::Send(http_response.ToString());
209 }
210 
211 void Webserver::Client::Send(const Json::Value &value) const
212 {
213  // Create a JSON writer
214  Json::StreamWriterBuilder writer;
215  std::string jsonString = Json::writeString(writer, value);
216 
217  // Create http response
218  atomizes::HTTPMessage http_response = this->_defaultResponseHeader();
219  http_response.SetStatusCode(200);
220  http_response.SetMessageBody(jsonString);
221 
222  //Logger::debug("json = " + jsonString);
223 
224  // Send http response
225  this->Send(http_response);
226 }
227 
228 // Events
229 
230 void Webserver::Client::onRequest(const atomizes::HTTPMessage &http_request)
231 {
232  if(http_request.GetMethod() == atomizes::MessageMethod::GET)
233  {
234  std::string url_base;
235  Util::Url::Variables url_variables;
236 
237  this->_LogTransaction("-->", http_request.GetPath());
238 
239  // Split url into url base and variables
240  Util::Url::GetElements(http_request.GetPath(), url_base, url_variables);
241 
242  auto it = mRequestActions.find(url_base);
243  if (it != mRequestActions.end())
244  {
245  // Get Function address
246  RequestActionFunc func = it->second;
247 
248  // Execute action function with class object.
249  (this->*(func))(http_request, url_base, url_variables);
250  }
251  else
252  {
253  Logger::warning("action \"" + url_base + "\" not implemented!", Server::Type::Webserver);
254  }
255  }
256 }
257 
258 void Webserver::Client::requestFile(const atomizes::HTTPMessage& http_request, const std::string& url_base,
259  const Util::Url::Variables& url_variables)
260 {
261  this->_SendFile("../data" + url_base);
262 }
263 
264 void Webserver::Client::requestEmpty(const atomizes::HTTPMessage& http_request, const std::string& url_base,
265  const Util::Url::Variables& url_variables)
266 {
267  atomizes::HTTPMessage http_response = this->_defaultResponseHeader();
268 
269  http_response.SetStatusCode(200);
270  http_response.SetMessageBody("\r\n");
271 
272  this->Send(http_response);
273 
274  this->_LogTransaction("<--", "HTTP/1.1 200 OK");
275 }
276 
277 void Webserver::Client::requestMeme(const atomizes::HTTPMessage& http_request, const std::string& url_base,
278  const Util::Url::Variables& url_variables)
279 {
280  this->_SendFile("../data/meme/index.html");
281 }
282 
283 // Private functions
284 
285 void Webserver::Client::_LogTransaction(const std::string& direction, const std::string& response) const
286 {
287  std::shared_lock<std::shared_mutex> guard(g_settings_mutex); // settings lock (read)
288 
289  //if ((g_logger_mode & Logger::Mode::Development) == 0)
290  //{
291  // return;
292  //}
293 
294  bool show_console = (g_settings["webserver"]["show_requests"].asBool() && direction == "-->") ||
295  (g_settings["webserver"]["show_responses"].asBool() && direction == "<--");
296 
297  Logger::info(this->GetAddress() + " " + direction + " " + response,
298  Server::Type::Webserver, show_console);
299 }
300 
301 atomizes::HTTPMessage Webserver::Client::_defaultResponseHeader(bool isPlainText) const
302 {
303  atomizes::HTTPMessage http_response;
304 
305  http_response.SetHeader("Server", "BF2MC-Matchmaker");
306  http_response.SetHeader("Accept-Ranges", "bytes");
307 
308  if(isPlainText)
309  http_response.SetHeader("Content-Type", "text/plain");
310 
311  return http_response;
312 }
313 
314 bool Webserver::Client::_readFile(const std::string& file_name, std::string& data) const
315 {
316  bool finished = false;
317 
318  // Load file from memory
319  if(g_file_system->GetFile(file_name, data))
320  {
321  // Debug
322  //Logger::debug("file_name = " + file_name);
323  //Logger::debug("file size = " + std::to_string(data.size()));
324 
325  return true;
326  }
327 
328  std::ifstream input;
329 
330  try
331  {
332  input.open(file_name, std::ifstream::in | std::ifstream::binary);
333 
334  if(input.is_open())
335  {
336  data.append((std::istreambuf_iterator<char>(input)), std::istreambuf_iterator<char>());
337 
338  input.close();
339 
340  return true;
341  }
342  }
343  catch(...)
344  {
345  Logger::error(file_name);
346  }
347 
348  //Logger::debug(std::to_string(data.size()));
349 
350  return false;
351 }
352 
353 void Webserver::Client::_SendFile(const std::string& file_name) const
354 {
355  std::string data;
356  atomizes::HTTPMessage http_response = this->_defaultResponseHeader(false);
357 
358  if(this->_readFile(file_name, data) && data.size() != 0)
359  {
360  http_response.SetStatusCode(200);
361  http_response.SetMessageBody(data);
362  }
363  else
364  { // fix: Prevent to hang the http connection
365  http_response.SetStatusCode(404);
366  http_response.SetMessageBody("\r\n");
367  }
368 
369  this->Send(http_response);
370 
371  this->_LogTransaction("<--", "HTTP/1.1 200 OK");
372 }
373 
374 void Webserver::Client::_GetSessionPlayerAndClan(const Util::Url::Variables& url_variables, Battlefield::Clan& clan, Battlefield::Player& player) const
375 {
376  GPCM::Session session;
377 
378  auto it = url_variables.find("authtoken");
379  if (it != url_variables.end())
380  {
381  std::string authtoken = it->second;
382 
383  session = GPCM::Client::findSessionByAuthtoken(authtoken);
384  }
385 
386  if(session.profileid != -1)
387  {
388  // Set player profileid
389  player.SetProfileId(session.profileid);
390 
391  // Get clan information based of player profileid
392  g_database->queryClanByProfileId(clan, player);
393  }
394 }
395 
397  const Util::Url::Variables &url_variables, bool is_update)
398 {
399  for(const auto &url_variable : url_variables)
400  {
401  std::string key = url_variable.first;
402  std::string value = Util::Url::Decode(url_variable.second);
403 
404  if(key == "authtoken")
405  continue;
406 
407  if(!Util::isAscii(value) || (key == "name" && is_update))
408  {
409  return false;
410  }
411 
412  auto it = Battlefield::Clan::SetterMap.find(key);
413  if(it == Battlefield::Clan::SetterMap.end() || (clan.*(it->second))(value))
414  {
415  return false;
416  }
417  }
418 
419  return true;
420 }
421 
422 // Static functions
423 
425 {
426  Logger::info("Heartbeat started", Server::Webserver);
427 
428  while(true)
429  {
430  std::this_thread::sleep_for (std::chrono::seconds(60));
431 
432  auto target_time = std::chrono::system_clock::now() - std::chrono::minutes(1);
433 
434  for(std::shared_ptr<Net::Socket> client : g_webserver_server->GetClients())
435  {
436  auto last_recieved = client.get()->GetLastRecievedTime();
437 
438  if (last_recieved <= target_time)
439  {
440  client.get()->Close();
441  }
442  }
443  }
444 }
445 
Represents a clan in the Battlefield game.
Definition: clan.h:54
Represents a player with extended statistics.
Definition: player.h:38
bool queryClanByProfileId(Battlefield::Clan &clan, const Battlefield::Player &player)
Queries a clan by a player's profile ID.
static GPCM::Session findSessionByAuthtoken(const std::string &authtoken)
Finds a session by authentication token.
void Send(const std::string &msg) const
Sends a message over the socket.
Definition: socket.cpp:80
void UpdateLastRecievedTime()
Updates the last received time to the current system time.
Definition: socket.cpp:112
struct sockaddr_in _address
Definition: socket.h:18
int _socket
Definition: socket.h:17
std::vector< std::shared_ptr< Net::Socket > > GetClients()
Get the vector of client sockets connected to this server.
Definition: server.cpp:86
@ Webserver
Definition: server.h:20
void onClientDisconnect(const Net::Socket &client)
Called when a client disconnects from the server.
Definition: server.cpp:336
bool GetFile(const std::string &file_path, std::string &data)
Retrieves the data of a file from the File_System.
Definition: file_system.cpp:59
void requestAPIAdminKick(const atomizes::HTTPMessage &http_request, const std::string &url_base, const Util::Url::Variables &url_variables)
Handle a request to kick a client through the API.
Definition: api_admin.cpp:146
void requestAPIClanSimulation(const atomizes::HTTPMessage &http_request, const std::string &url_base, const Util::Url::Variables &url_variables)
Handle a request for clan simulation through the API.
Definition: api.cpp:530
void requestLeaderboard(const atomizes::HTTPMessage &http_request, const std::string &url_base, const Util::Url::Variables &url_variables)
Handle a request to get the leaderboard.
static void Heartbeat()
Heartbeat function to manage client connections.
void requestMeme(const atomizes::HTTPMessage &http_request, const std::string &url_base, const Util::Url::Variables &url_variables)
Handle a request for a meme.
void requestStats(const atomizes::HTTPMessage &http_request, const std::string &url_base, const Util::Url::Variables &url_variables)
Handle a request for player statistics.
Definition: status.cpp:78
void requestAPIAdminMessage(const atomizes::HTTPMessage &http_request, const std::string &url_base, const Util::Url::Variables &url_variables)
Handle a request to send a message to a client through the API.
Definition: api_admin.cpp:188
void requestAPIPlayer(const atomizes::HTTPMessage &http_request, const std::string &url_base, const Util::Url::Variables &url_variables)
Handle a request for a specific player through the API.
Definition: api.cpp:226
Client(int socket, struct sockaddr_in address)
Constructor for Webserver Client.
atomizes::HTTPMessage _defaultResponseHeader(bool isPlainText=true) const
Generate the default HTTP response header.
void onRequest(const atomizes::HTTPMessage &http_request)
Process incoming HTTP request.
void _GetSessionPlayerAndClan(const Util::Url::Variables &url_variables, Battlefield::Clan &clan, Battlefield::Player &player) const
Extract session, player, and clan information from URL variables.
void Disconnect()
Disconnect the client.
void requestAPILeaderboardClan(const atomizes::HTTPMessage &http_request, const std::string &url_base, const Util::Url::Variables &url_variables)
Handle a request for the clan leaderboard through the API.
Definition: api.cpp:480
void requestClanInfo(const atomizes::HTTPMessage &http_request, const std::string &url_base, const Util::Url::Variables &url_variables)
Handle a request to get clan information.
void requestAddMember(const atomizes::HTTPMessage &http_request, const std::string &url_base, const Util::Url::Variables &url_variables)
Handle a request to add a member to a clan.
void requestChangeRank(const atomizes::HTTPMessage &http_request, const std::string &url_base, const Util::Url::Variables &url_variables)
Handle a request to change a member's rank in a clan.
void requestClanMembers(const atomizes::HTTPMessage &http_request, const std::string &url_base, const Util::Url::Variables &url_variables)
Handle a request to get clan members.
void requestAPIAdminClients(const atomizes::HTTPMessage &http_request, const std::string &url_base, const Util::Url::Variables &url_variables)
Handle a request for admin clients through the API.
Definition: api_admin.cpp:16
void requestEmpty(const atomizes::HTTPMessage &http_request, const std::string &url_base, const Util::Url::Variables &url_variables)
Handle a request for a empty response.
void requestFile(const atomizes::HTTPMessage &http_request, const std::string &url_base, const Util::Url::Variables &url_variables)
Handle a request for a specific file.
void requestUpdateClan(const atomizes::HTTPMessage &http_request, const std::string &url_base, const Util::Url::Variables &url_variables)
Handle a request to update a clan.
void requestClanMessage(const atomizes::HTTPMessage &http_request, const std::string &url_base, const Util::Url::Variables &url_variables)
Handle a request for clan messages.
void Send(const atomizes::HTTPMessage &http_response) const
Send an HTTP response.
void requestAPIServersLive(const atomizes::HTTPMessage &http_request, const std::string &url_base, const Util::Url::Variables &url_variables)
Handle a request for live servers through the API.
Definition: api.cpp:15
void requestDeleteMember(const atomizes::HTTPMessage &http_request, const std::string &url_base, const Util::Url::Variables &url_variables)
Handle a request to delete a member from a clan.
void requestAPIGame(const atomizes::HTTPMessage &http_request, const std::string &url_base, const Util::Url::Variables &url_variables)
Handle a request for a specific game through the API.
Definition: api.cpp:111
void _LogTransaction(const std::string &direction, const std::string &response) const
Log a transaction.
void Listen()
Start listening for incoming requests.
void _SendFile(const std::string &file_name) const
Send a file as an HTTP response.
void requestCreateClan(const atomizes::HTTPMessage &http_request, const std::string &url_base, const Util::Url::Variables &url_variables)
Handle a request to create a new clan.
bool _readFile(const std::string &file_name, std::string &data) const
Read a file and store its contents in a string.
bool _updateClanInformation(Battlefield::Clan &clan, const Util::Url::Variables &url_variables, bool is_update=false)
Update clan information based on URL variables.
void requestDisband(const atomizes::HTTPMessage &http_request, const std::string &url_base, const Util::Url::Variables &url_variables)
Handle a request to disband a clan.
~Client()
Destructor for Webserver Client.
void requestAPIClan(const atomizes::HTTPMessage &http_request, const std::string &url_base, const Util::Url::Variables &url_variables)
Handle a request for a specific clan through the API.
Definition: api.cpp:316
void requestAPILeaderboard(const atomizes::HTTPMessage &http_request, const std::string &url_base, const Util::Url::Variables &url_variables)
Handle a request for the leaderboard through the API.
Definition: api.cpp:368
void requestGetPlayerInfo(const atomizes::HTTPMessage &http_request, const std::string &url_base, const Util::Url::Variables &url_variables)
Handle a request to get player information.
Definition: status.cpp:20
void requestAPIGames(const atomizes::HTTPMessage &http_request, const std::string &url_base, const Util::Url::Variables &url_variables)
Handle a request for multiple games through the API.
Definition: api.cpp:199
void requestAPIAdminPlayerStatsRecalc(const atomizes::HTTPMessage &http_request, const std::string &url_base, const Util::Url::Variables &url_variables)
Handles the API request to recalculate player statistics.
Definition: api_admin.cpp:241
Represents a session with a GPCM client.
Definition: gpcm/client.h:19