BF2MC-Matchmaker
api.cpp
1 #include <atomizes.hpp>
2 #include <json/json.h>
3 #include <random>
4 #include <chrono>
5 
6 #include <logger.h>
7 #include <globals.h>
8 #include <settings.h>
9 #include <database.h>
10 #include <gpcm/client.h>
11 #include <battlefield/gamestat.h>
12 
13 #include <webserver/client.h>
14 
15 void Webserver::Client::requestAPIServersLive(const atomizes::HTTPMessage& http_request, const std::string& url_base,
16  const Util::Url::Variables& url_variables)
17 {
18  Json::Value json_game_servers(Json::arrayValue);
19  Battlefield::GameServers game_servers;
20 
21  // Get game servers from database
22  g_database->queryGameServers(game_servers);
23 
24  for(Battlefield::GameServer game_server : game_servers)
25  {
26  Json::Value json_game_server;
27 
28  // Get game server players from database
29  g_database->queryGameServerPlayers(game_server);
30 
31  // Game Server information
32  json_game_server["id"] = game_server.GetId();
33  json_game_server["flag"] = game_server.GetFlag();
34  json_game_server["natneg"] = game_server.GetNatNeg();
35  json_game_server["gamename"] = game_server.GetGameName();
36  json_game_server["hostname"] = game_server.GetHostName();
37  json_game_server["gamever"] = game_server.GetGameVersion();
38  json_game_server["cl"] = game_server.GetClientVersion();
39  json_game_server["rv"] = game_server.GetRV();
40  json_game_server["map"] = game_server.GetMap();
41  json_game_server["mc"] = game_server.GetMapCycling();
42  json_game_server["mapname"] = game_server.GetMapName();
43  json_game_server["gc"] = game_server.GetGC();
44  json_game_server["gametype"] = game_server.GetGameType();
45  json_game_server["numplayers"] = game_server.GetNumPlayers();
46  json_game_server["maxplayers"] = game_server.GetMaxPlayers();
47  json_game_server["numteams"] = game_server.GetNumTeams();
48  json_game_server["gamemode"] = game_server.GetGameMode();
49  json_game_server["teamplay"] = game_server.GetTeamplay();
50  json_game_server["fraglimit"] = game_server.GetFlagLimit();
51  json_game_server["teamfraglimit"] = game_server.GetTeamFragLimit();
52  json_game_server["timelimit"] = game_server.GetTimeLimit();
53  json_game_server["timeelapsed"] = game_server.GetTimeElapsed();
54  json_game_server["password"] = game_server.GetPassword();
55  json_game_server["nr"] = game_server.GetMinRank();
56  json_game_server["xr"] = game_server.GetMaxRank();
57  json_game_server["ff"] = game_server.GetFriendlyFire();
58  json_game_server["sr"] = game_server.GetStatsTracking();
59  json_game_server["rc"] = game_server.GetReconfigurable();
60  json_game_server["ni"] = game_server.GetMinIpRange();
61  json_game_server["xi"] = game_server.GetMaxIpRange();
62  json_game_server["qm"] = game_server.GetQM();
63  json_game_server["region"] = game_server.GetRegion();
64  json_game_server["c0"] = game_server.GetClan1Id();
65  json_game_server["c1"] = game_server.GetClan2Id();
66  json_game_server["n0"] = game_server.GetClan1Name();
67  json_game_server["n1"] = game_server.GetClan2Name();
68  json_game_server["c0c"] = game_server.GetClan1Claimed();
69  json_game_server["c1c"] = game_server.GetClan2Claimed();
70  json_game_server["team0"] = game_server.GetTeam1Name();
71  json_game_server["team1"] = game_server.GetTeam2Name();
72  json_game_server["score0"] = game_server.GetTeam1Score();
73  json_game_server["score1"] = game_server.GetTeam2Score();
74  json_game_server["updated_at"] = game_server.GetUpdatedAt();
75  json_game_server["verified"] = game_server.isVerified();
76  json_game_server["is_alive"] = game_server.IsAlive();
77 
78  // Secret
79  //json_game_server["ip"] = game_server.GetIp();
80  //json_game_server["port"] = game_server.GetPort();
81  //json_game_server["localip0"] = game_server.GetLocalIp();
82  //json_game_server["localport"] = game_server.GetLocalPort();
83  //json_game_server["hostport"] = game_server.GetHostPort();
84 
85  // Game server player information
86  Json::Value json_players(Json::arrayValue);
87  for(const Battlefield::GameServerPlayer gsplayer : game_server.GetPlayers())
88  {
89  Json::Value json_player;
90 
91  json_player["name"] = gsplayer.GetName();
92  json_player["score"] = gsplayer.GetScore();
93  json_player["skill"] = gsplayer.GetSkill();
94  json_player["ping"] = gsplayer.GetPing();
95  json_player["team"] = gsplayer.GetTeam();
96  json_player["deaths"] = gsplayer.GetDeaths();
97  json_player["profileid"] = gsplayer.GetProfileId();
98 
99  json_players.append(json_player);
100  }
101  json_game_server["players"] = json_players;
102 
103  json_game_servers.append(json_game_server);
104  }
105 
106  this->Send(json_game_servers);
107 
108  this->_LogTransaction("<--", "HTTP/1.1 200 OK");
109 }
110 
111 void Webserver::Client::requestAPIGame(const atomizes::HTTPMessage& http_request, const std::string& url_base,
112  const Util::Url::Variables& url_variables)
113 {
114  Json::Value json_game_stat;
115  Battlefield::GameStat game_stat;
116 
117  // Get Game Stats
118  auto it = url_variables.find("id");
119  if (it != url_variables.end())
120  {
121  game_stat.SetId(it->second);
122 
123  // Get Game Stat information from database
124  g_database->queryGameStatById(game_stat);
125  }
126 
127  // Get Game stat player information from database
128  g_database->queryGameStatPlayers(game_stat);
129 
130  // Game Stat information
131  json_game_stat["id"] = game_stat.GetId();
132  json_game_stat["gametype"] = game_stat.GetGameType();
133  json_game_stat["gamver"] = game_stat.GetGameVersion();
134  json_game_stat["hostname"] = game_stat.GetHostName();
135  json_game_stat["mapid"] = game_stat.GetMapId();
136  json_game_stat["numplayers"] = game_stat.GetNumPlayers();
137  json_game_stat["pplayers"] = game_stat.GetPPlayers();
138  json_game_stat["tplayed"] = game_stat.GetTimePlayed();
139  json_game_stat["clanid_t0"] = game_stat.GetTeam1ClanId();
140  json_game_stat["clanid_t1"] = game_stat.GetTeam2ClanId();
141  json_game_stat["country_t0"] = game_stat.GetTeam1Country();
142  json_game_stat["country_t1"] = game_stat.GetTeam2Country();
143  json_game_stat["victory_t0"] = game_stat.GetTeam1Victory();
144  json_game_stat["victory_t1"] = game_stat.GetTeam2Victory();
145  json_game_stat["created_at"] = game_stat.GetCreatedAt();
146 
147  // Game server player information
148  Json::Value json_players(Json::arrayValue);
149  for(const Battlefield::GameStatPlayer gsplayer : game_stat.GetPlayers())
150  {
151  Json::Value json_player;
152 
153  json_player["id"] = gsplayer.GetId();
154  json_player["auth"] = gsplayer.GetAuth();
155  json_player["pid"] = gsplayer.GetProfileId();
156  json_player["team"] = gsplayer.GetTeam();
157  json_player["score"] = gsplayer.GetScore();
158  json_player["rank"] = gsplayer.GetRank();
159  json_player["pph"] = gsplayer.GetPPH();
160  json_player["kills"] = gsplayer.GetKills();
161  json_player["deaths"] = gsplayer.GetDeaths();
162  json_player["suicides"] = gsplayer.GetSuicides();
163  json_player["time"] = gsplayer.GetTime();
164  json_player["lavd"] = gsplayer.GetLAVsDestroyed();
165  json_player["mavd"] = gsplayer.GetMAVsDestroyed();
166  json_player["havd"] = gsplayer.GetHAVsDestroyed();
167  json_player["hed"] = gsplayer.GetHelicoptersDestroyed();
168  json_player["pld"] = gsplayer.GetPlanesDestroyed();
169  json_player["bod"] = gsplayer.GetBoatsDestroyed();
170  json_player["k1"] = gsplayer.GetKillsAssualtKit();
171  json_player["s1"] = gsplayer.GetSpawnsAssualtKit();
172  json_player["k2"] = gsplayer.GetKillsSniperKit();
173  json_player["s2"] = gsplayer.GetSpawnsSniperKit();
174  json_player["k3"] = gsplayer.GetKillsSpecialOpKit();
175  json_player["s3"] = gsplayer.GetSpawnsSpecialOpKit();
176  json_player["k4"] = gsplayer.GetKillsCombatEngineerKit();
177  json_player["s4"] = gsplayer.GetSpawnsCombatEngineerKit();
178  json_player["k5"] = gsplayer.GetKillsSupportKit();
179  json_player["s5"] = gsplayer.GetSpawnsSupportKit();
180  json_player["tk"] = gsplayer.GetTeamKills();
181  json_player["medals"] = gsplayer.GetMedals();
182  json_player["ttb"] = gsplayer.GetTotalTopPlayer();
183  json_player["mv"] = gsplayer.GetTotalVictories();
184  json_player["ngp"] = gsplayer.GetTotalGameSessions();
185  json_player["cflags"] = gsplayer.GetCapturedFlags();
186  json_player["nflags"] = gsplayer.GetNeutralizedFlags();
187  json_player["sflags"] = gsplayer.GetSavedFlags();
188  json_player["disable"] = gsplayer.IsDisabled();
189 
190  json_players.append(json_player);
191  }
192  json_game_stat["players"] = json_players;
193 
194  this->Send(json_game_stat);
195 
196  this->_LogTransaction("<--", "HTTP/1.1 200 OK");
197 }
198 
199 void Webserver::Client::requestAPIGames(const atomizes::HTTPMessage& http_request, const std::string& url_base,
200  const Util::Url::Variables& url_variables)
201 {
202  Json::Value json_game_stats(Json::arrayValue);
203  Battlefield::GameStats game_stats;
204 
205  // Get Game Stats
206  auto it = url_variables.find("date");
207  if (it != url_variables.end() && Util::isAscii(it->second))
208  {
209  std::string date = it->second;
210 
211  // Get Game Stat information from database
212  g_database->queryGameStatsByDate(game_stats, date);
213  }
214 
215  for(Battlefield::GameStat game_stat : game_stats)
216  {
217  json_game_stats.append(game_stat.GetId());
218  }
219 
220 
221  this->Send(json_game_stats);
222 
223  this->_LogTransaction("<--", "HTTP/1.1 200 OK");
224 }
225 
226 void Webserver::Client::requestAPIPlayer(const atomizes::HTTPMessage& http_request, const std::string& url_base,
227  const Util::Url::Variables& url_variables)
228 {
229  Json::Value json_player;
230  Battlefield::Player player;
231  Battlefield::Clan clan;
232 
233  // Get player profileid
234  auto it = url_variables.find("profileid");
235  if (it != url_variables.end() && player.SetProfileId(it->second))
236  {
237  // Get player information from database
238  g_database->queryPlayerByProfileId(player);
239  }
240 
241  it = url_variables.find("uniquenick");
242  if (it != url_variables.end() && Util::isAscii(it->second))
243  {
244  player.SetUniquenick(it->second);
245 
246  // Get player information from database
247  g_database->queryPlayerByUniquenick(player);
248  }
249 
250  // Get player Stats information from database
251  g_database->queryPlayerStatsByProfileId(player);
252 
253  // Get player Stats information from database
254  g_database->queryClanByProfileId(clan, player);
255 
256  // Player information
257  json_player["profileid"] = player.GetProfileId();
258  json_player["userid"] = player.GetUserId();
259  json_player["nick"] = player.GetNick();
260  json_player["uniquenick"] = player.GetUniquenick();
261  json_player["last_login"] = player.GetLastLogin();
262  json_player["created_at"] = player.GetCreatedAt();
263 
264  // Secret
265  //json_player["email"] = player.GetEmail();
266  //json_player["password"] = player.GetPassword();
267  //json_player["last_login_ip"] = player.GetLastLoginIp();
268 
269  // Player stats informaton
270  json_player["score"] = player.GetScore();
271  json_player["ran"] = player.GetRank();
272  json_player["pph"] = player.GetPPH();
273  json_player["kills"] = player.GetKills();
274  json_player["deaths"] = player.GetDeaths();
275  json_player["suicides"] = player.GetSuicides();
276  json_player["time"] = player.GetTime();
277  json_player["vehicles"] = player.GetVehiclesDestroyed();
278  json_player["lavd"] = player.GetLAVsDestroyed();
279  json_player["mavd"] = player.GetMAVsDestroyed();
280  json_player["havd"] = player.GetHAVsDestroyed();
281  json_player["hed"] = player.GetHelicoptersDestroyed();
282  json_player["pld"] = player.GetPlanesDestroyed();
283  json_player["bod"] = player.GetBoatsDestroyed();
284  json_player["k1"] = player.GetKillsAssualtKit();
285  json_player["s1"] = player.GetSpawnsAssualtKit();
286  json_player["k2"] = player.GetKillsSniperKit();
287  json_player["s2"] = player.GetSpawnsSniperKit();
288  json_player["k3"] = player.GetKillsSpecialOpKit();
289  json_player["s3"] = player.GetSpawnsSpecialOpKit();
290  json_player["k4"] = player.GetKillsCombatEngineerKit();
291  json_player["s4"] = player.GetSpawnsCombatEngineerKit();
292  json_player["k5"] = player.GetKillsSupportKit();
293  json_player["s5"] = player.GetSpawnsSupportKit();
294  json_player["tk"] = player.GetTeamKills();
295  json_player["medals"] = player.GetMedals();
296  json_player["ttb"] = player.GetTotalTopPlayer();
297  json_player["mv"] = player.GetTotalVictories();
298  json_player["ngp"] = player.GetTotalGameSessions();
299  json_player["cflags"] = player.GetCapturedFlags();
300  json_player["nflags"] = player.GetNeutralizedFlags();
301  json_player["sflags"] = player.GetSavedFlags();
302 
303  Json::Value json_clan;
304 
305  json_clan["clanid"] = clan.GetClanId();
306  json_clan["name"] = clan.GetName();
307  json_clan["tag"] = clan.GetTag();
308 
309  json_player["clan"] = json_clan;
310 
311  this->Send(json_player);
312 
313  this->_LogTransaction("<--", "HTTP/1.1 200 OK");
314 }
315 
316 void Webserver::Client::requestAPIClan(const atomizes::HTTPMessage& http_request, const std::string& url_base,
317  const Util::Url::Variables& url_variables)
318 {
319  Json::Value json_clan;
320  Battlefield::Clan clan;
321 
322  // Get player profileid
323  auto it = url_variables.find("clanid");
324  if (it != url_variables.end() || !clan.SetClanId(it->second))
325  {
326  return;
327  }
328 
329  // Get clan information from database
330  g_database->queryClanByClanId(clan);
331 
332  // Get clan ranks information from database
333  g_database->queryClanRanksByClanId(clan);
334 
335  // Clan information
336  json_clan["clanid"] = clan.GetClanId();
337  json_clan["name"] = clan.GetName();
338  json_clan["tag"] = clan.GetTag();
339  json_clan["homepage"] = clan.GetHomepage();
340  json_clan["info"] = clan.GetInfo();
341  json_clan["region"] = clan.GetRegion();
342  json_clan["created_at"] = clan.GetCreatedAt();
343 
344  // Secret
345  //json_clan["rating"] = clan.GetRating();
346  //json_clan["wins"] = clan.GetWins();
347  //json_clan["losses"] = clan.GetLosses();
348  //json_clan["draws"] = clan.GetDraws();
349 
350  // Clan ranks information
351  Json::Value json_members(Json::arrayValue);
352  for (const auto& pair : clan.GetRanks())
353  {
354  Json::Value json_member;
355 
356  json_member["profileid"] = pair.first;
357  json_member["rank"] = static_cast<uint8_t>(pair.second);
358 
359  json_members.append(json_member);
360  }
361  json_clan["members"] = json_members;
362 
363  this->Send(json_clan);
364 
365  this->_LogTransaction("<--", "HTTP/1.1 200 OK");
366 }
367 
368 void Webserver::Client::requestAPILeaderboard(const atomizes::HTTPMessage& http_request, const std::string& url_base,
369  const Util::Url::Variables& url_variables)
370 {
371  Json::Value json_leaderboard(Json::arrayValue);
372  std::string sort = "";
373  uint32_t limit = 10;
374  uint32_t offset = 0;
375 
376  auto it = url_variables.find("limit");
377  if (it != url_variables.end())
378  {
379  if(it->second == "25") limit = 25;
380  else if(it->second == "50") limit = 50;
381  else if(it->second == "75") limit = 75;
382  else if(it->second == "100") limit = 100;
383  }
384 
385  it = url_variables.find("offset");
386  if (it != url_variables.end())
387  {
388  try
389  {
390  offset = std::stoul(it->second);
391  }
392  catch(...) {}
393  }
394 
395  // Get leaderboard from Database
396  Battlefield::RankPlayers rank_players;
397  it = url_variables.find("sort");
398  if (it != url_variables.end())
399  {
400  sort = it->second;
401 
402  if(sort == "rank") g_database->queryLeaderboardRank(rank_players, limit, offset);
403  else if(sort == "score") g_database->queryLeaderboardType(rank_players, "score", limit, offset);
404  else if(sort == "pph") g_database->queryLeaderboardType(rank_players, "pph", limit, offset);
405  else if(sort == "k1") g_database->queryLeaderboardType(rank_players, "k1", limit, offset);
406  else if(sort == "k2") g_database->queryLeaderboardType(rank_players, "k2", limit, offset);
407  else if(sort == "k3") g_database->queryLeaderboardType(rank_players, "k3", limit, offset);
408  else if(sort == "k4") g_database->queryLeaderboardType(rank_players, "k4", limit, offset);
409  else if(sort == "k5") g_database->queryLeaderboardType(rank_players, "k5", limit, offset);
410  else if(sort == "kills") g_database->queryLeaderboardType(rank_players, "kills", limit, offset);
411  else if(sort == "lavd") g_database->queryLeaderboardType(rank_players, "lavd", limit, offset);
412  else if(sort == "mavd") g_database->queryLeaderboardType(rank_players, "mavd", limit, offset);
413  else if(sort == "havd") g_database->queryLeaderboardType(rank_players, "havd", limit, offset);
414  else if(sort == "hed") g_database->queryLeaderboardType(rank_players, "hed", limit, offset);
415  else if(sort == "bod") g_database->queryLeaderboardType(rank_players, "bod", limit, offset);
416  else if(sort == "vehicles") g_database->queryLeaderboardType(rank_players, "vehicles", limit, offset);
417  else if(sort == "ratio_k1") g_database->queryLeaderboardRatio(rank_players, "k1", "s1", limit, offset);
418  else if(sort == "ratio_k2") g_database->queryLeaderboardRatio(rank_players, "k2", "s2", limit, offset);
419  else if(sort == "ratio_k3") g_database->queryLeaderboardRatio(rank_players, "k3", "s3", limit, offset);
420  else if(sort == "ratio_k4") g_database->queryLeaderboardRatio(rank_players, "k4", "s4", limit, offset);
421  else if(sort == "ratio_k5") g_database->queryLeaderboardRatio(rank_players, "k5", "s5", limit, offset);
422  else if(sort == "ratio_kd") g_database->queryLeaderboardRatio(rank_players, "kills", "deaths", limit, offset);
423  }
424 
425  // Write leaderboard
426  for (const auto& pair : rank_players)
427  {
428  Json::Value json_player;
429 
430  json_player["position"] = pair.first;
431  json_player["profileid"] = pair.second.GetProfileId();
432  json_player["uniquenick"] = pair.second.GetUniquenick();
433 
434  if(sort == "rank")
435  {
436  json_player["rank"] = pair.second.GetRank();
437  }
438  else
439  {
440  // to-do: optimization to get full list in one query
441  Battlefield::Player player;
442 
443  player.SetProfileId(pair.second.GetProfileId());
444 
445  g_database->queryPlayerByProfileId(player);
446 
447  json_player["rank"] = player.GetRank();
448  }
449 
450  if(sort == "pph" || sort == "rank") json_player["pph"] = pair.second.GetPPH();
451  if(sort == "score" || sort == "rank") json_player["score"] = pair.second.GetScore();
452 
453  if(sort == "k1") json_player["k1"] = pair.second.GetKillsAssualtKit();
454  else if(sort == "k2") json_player["k2"] = pair.second.GetKillsSniperKit();
455  else if(sort == "k3") json_player["k3"] = pair.second.GetKillsSpecialOpKit();
456  else if(sort == "k4") json_player["k4"] = pair.second.GetKillsCombatEngineerKit();
457  else if(sort == "k5") json_player["k5"] = pair.second.GetKillsSupportKit();
458  else if(sort == "kills") json_player["kills"] = pair.second.GetKills();
459  else if(sort == "lavd") json_player["lavd"] = pair.second.GetLAVsDestroyed();
460  else if(sort == "mavd") json_player["mavd"] = pair.second.GetMAVsDestroyed();
461  else if(sort == "havd") json_player["havd"] = pair.second.GetHAVsDestroyed();
462  else if(sort == "hed") json_player["hed"] = pair.second.GetHelicoptersDestroyed();
463  else if(sort == "bod") json_player["bod"] = pair.second.GetBoatsDestroyed();
464  else if(sort == "vehicles") json_player["vehicles"] = pair.second.GetVehiclesDestroyed();
465  else if(sort == "ratio_k1") json_player["ratio"] = pair.second.GetRatioAssualtKit();
466  else if(sort == "ratio_k2") json_player["ratio"] = pair.second.GetRatioSniperKit();
467  else if(sort == "ratio_k3") json_player["ratio"] = pair.second.GetRatioSpecialOpKit();
468  else if(sort == "ratio_k4") json_player["ratio"] = pair.second.GetRatioCombatEngineerKit();
469  else if(sort == "ratio_k5") json_player["ratio"] = pair.second.GetRatioSupportKit();
470  else if(sort == "ratio_kd") json_player["ratio"] = pair.second.GetRatio();
471 
472  json_leaderboard.append(json_player);
473  }
474 
475  this->Send(json_leaderboard);
476 
477  this->_LogTransaction("<--", "HTTP/1.1 200 OK");
478 }
479 
480 void Webserver::Client::requestAPILeaderboardClan(const atomizes::HTTPMessage& http_request, const std::string& url_base,
481  const Util::Url::Variables& url_variables)
482 {
483  Json::Value json_leaderboard(Json::arrayValue);
484  uint32_t limit = 10;
485  uint32_t offset = 0;
486 
487  auto it = url_variables.find("limit");
488  if (it != url_variables.end())
489  {
490  if(it->second == "25") limit = 25;
491  else if(it->second == "50") limit = 50;
492  else if(it->second == "75") limit = 75;
493  else if(it->second == "100") limit = 100;
494  }
495 
496  it = url_variables.find("offset");
497  if (it != url_variables.end())
498  {
499  try
500  {
501  offset = std::stoul(it->second);
502  }
503  catch(...) {}
504  }
505 
506  Battlefield::RankClans rank_clans;
507  g_database->queryLeaderboardClan(rank_clans, limit, offset);
508 
509  for (const auto& pair : rank_clans)
510  {
511  Json::Value json_clan;
512 
513  json_clan["position"] = pair.first;
514  json_clan["clanid"] = pair.second.GetClanId();
515  json_clan["name"] = pair.second.GetName();
516  json_clan["tag"] = pair.second.GetTag();
517  json_clan["score"] = pair.second.GetScore();
518  json_clan["wins"] = pair.second.GetWins();
519  json_clan["losses"] = pair.second.GetLosses();
520  json_clan["draws"] = pair.second.GetDraws();
521 
522  json_leaderboard.append(json_clan);
523  }
524 
525  this->Send(json_leaderboard);
526 
527  this->_LogTransaction("<--", "HTTP/1.1 200 OK");
528 };
529 
530 void Webserver::Client::requestAPIClanSimulation(const atomizes::HTTPMessage& http_request, const std::string& url_base,
531  const Util::Url::Variables& url_variables)
532 {
533  Battlefield::Clans clans;
534  Json::Value json_results;
535 
536  // Get total_clans
537  uint32_t total_clans = 2;
538  auto it = url_variables.find("total_clans");
539  if (it != url_variables.end())
540  {
541  try
542  {
543  total_clans = std::stoul(it->second);
544  }
545  catch(...) {}
546 
547  if(total_clans > 20)
548  total_clans = 2;
549  }
550 
551  // Get total_clans
552  uint32_t total_fights = 1;
553  it = url_variables.find("total_fights");
554  if (it != url_variables.end())
555  {
556  try
557  {
558  total_fights = std::stoul(it->second);
559  }
560  catch(...) {}
561 
562  if(total_fights > 10000)
563  total_fights = 2;
564  }
565 
566  // Random generator
567  unsigned seed = std::chrono::system_clock::now().time_since_epoch().count();
568  std::default_random_engine generator(seed);
569 
570  // Create random integer functions with ranges
571  std::uniform_int_distribution<int> gen_random_clan_id(1, total_clans);
572  std::uniform_int_distribution<int> gen_random_team_win(0, 1);
573  std::uniform_int_distribution<int> gen_random_victory(1, 3);
574 
575  // Generate random clans
576  for(int i = 1; i <= total_clans; i++)
577  {
578  Battlefield::Clan clan;
579 
580  clan.SetClanId(i);
581 
582  std::string clan_name(1, static_cast<char>(0x40 + i));
583  clan_name = "Clan " + clan_name;
584  clan.SetName(clan_name);
585 
586  clans.push_back(clan);
587  }
588 
589  //clans[0].SetScore(1000);
590 
591  // Battle random clans
592  Json::Value json_fights(Json::arrayValue);
593  Battlefield::GameStats game_stats;
594 
595  for(int i = 0; i < total_fights; i++)
596  {
597  Json::Value json_fight;
598 
599  // Generate random game_stat
600  Battlefield::GameStat game_stat;
601 
602  // Pick first random clan
603  int clanid_t0 = gen_random_clan_id(generator);
604 
605  // Pick second random clan
606  int clanid_t1;
607  do
608  {
609  clanid_t1 = gen_random_clan_id(generator);
610  }
611  while(clanid_t1 == clanid_t0); // Clan cant fight themselfs
612 
613  // set clan id's
614  game_stat.SetTeam1ClanId(clanid_t0);
615  game_stat.SetTeam2ClanId(clanid_t1);
616 
617  int team_win = gen_random_team_win(generator);
618  int victory = gen_random_victory(generator);
619 
620  if(team_win == 0)
621  {
622  game_stat.SetTeam1Victory(victory);
623 
624  if(victory == 3) // If its draw
625  game_stat.SetTeam2Victory(3);
626  }
627  else
628  {
629  game_stat.SetTeam2Victory(victory);
630 
631  if(victory == 3) // If its draw
632  game_stat.SetTeam1Victory(3);
633  }
634  game_stats.push_back(game_stat);
635 
636  // Create json game stat
637  json_fight["clanid_t0"] = game_stat.GetTeam1ClanId();
638  json_fight["clanid_t1"] = game_stat.GetTeam2ClanId();
639  json_fight["victory_t0"] = game_stat.GetTeam1Victory();
640  json_fight["victory_t1"] = game_stat.GetTeam2Victory();
641 
642  json_fights.append(json_fight);
643  }
644  json_results["fights"] = json_fights;
645 
646  // After all clan fight have been fought we can update the clan
647  for(const Battlefield::GameStat& game_stat : game_stats)
648  {
649  Battlefield::Clan* clan1 = &(clans[game_stat.GetTeam1ClanId() - 1]);
650  Battlefield::Clan* clan2 = &(clans[game_stat.GetTeam2ClanId() - 1]);
651 
652  Battlefield::GameStat::VictoryState clan1victory = game_stat.GetTeam1VictoryEnum();
653  Battlefield::GameStat::VictoryState clan2victory = game_stat.GetTeam2VictoryEnum();
654 
656  double R1 = 1.0;
657  double R2 = 1.0;
658 
659  switch(clan1victory)
660  {
662  K *= 2;
663  R1 = 1.0;
664  clan1->SetWins(clan1->GetWins() + 1);
665  break;
667  K *= 4;
668  R1 = 1.0;
669  clan1->SetWins(clan1->GetWins() + 1);
670  break;
672  R1 = 0.0;
673  clan1->SetLosses(clan1->GetLosses() + 1);
674  break;
676  R1 = 1.0;
677  clan1->SetDraws(clan1->GetDraws() + 1);
678  break;
679  }
680 
681  switch(clan2victory)
682  {
684  K *= 2;
685  R2 = 1.0;
686  clan2->SetWins(clan2->GetWins() + 1);
687  break;
689  K *= 4;
690  R2 = 1.0;
691  clan2->SetWins(clan2->GetWins() + 1);
692  break;
694  R2 = 0.0;
695  clan2->SetLosses(clan2->GetLosses() + 1);
696  break;
698  R2 = 1.0;
699  clan2->SetDraws(clan2->GetDraws() + 1);
700  break;
701  }
702 
703  // Calculate the difference between two clan score
704  double diff1 = static_cast<int64_t>(clan2->GetScore()) - static_cast<int64_t>(clan1->GetScore());
705  double diff2 = static_cast<int64_t>(clan1->GetScore()) - static_cast<int64_t>(clan2->GetScore());
706 
707  // Calculate the procentage between difference of clan score.
708  double P1 = (1.0 / (1.0 + std::pow(10, diff1 / Battlefield::Clan::ELO_MAX_RANGE)));
709  double P2 = (1.0 / (1.0 + std::pow(10, diff2 / Battlefield::Clan::ELO_MAX_RANGE)));
710 
711  // Calculate how much score will be added and substracted
712  double score1 = K * (R1 - P1);
713  double score2 = K * (R2 - P2);
714 
715  // Debug
716  //Logger::debug("clan1 = " + std::to_string(clan1->GetScore()));
717  //Logger::debug("clan2 = " + std::to_string(clan2->GetScore()));
718  //Logger::debug("R1 = " + std::to_string(R1));
719  //Logger::debug("R2 = " + std::to_string(R2));
720  //Logger::debug("P1 = " + std::to_string(P1));
721  //Logger::debug("P2 = " + std::to_string(P2));
722  //Logger::debug("score1 = " + std::to_string(score1));
723  //Logger::debug("score2 = " + std::to_string(score2));
724 
725  clan1->SetScore(std::max(0, static_cast<int>(std::floor(score1) + clan1->GetScore())));
726  clan2->SetScore(std::max(0, static_cast<int>(std::floor(score2) + clan2->GetScore())));
727  }
728 
729  // Show clans results
730  Json::Value json_clans(Json::arrayValue);
731  for(const Battlefield::Clan& clan : clans)
732  {
733  Json::Value json_clan;
734 
735  json_clan["id"] = clan.GetClanId();
736  json_clan["name"] = clan.GetName();
737  json_clan["score"] = clan.GetScore();
738  json_clan["wins"] = clan.GetWins();
739  json_clan["losses"] = clan.GetLosses();
740  json_clan["draws"] = clan.GetDraws();
741 
742  json_clans.append(json_clan);
743  }
744  json_results["clans"] = json_clans;
745 
746  this->Send(json_results);
747 
748  this->_LogTransaction("<--", "HTTP/1.1 200 OK");
749 }
750 
Represents a clan in the Battlefield game.
Definition: clan.h:54
static const int ELO_MAX_RANGE
The maximum range for clan battles.
Definition: clan.h:115
static const int ELO_WEIGHT
The Elo score weight for clan battles.
Definition: clan.h:107
Represents a player in a game server.
Definition: gameserver.h:385
Class representing game server information.
Definition: gameserver.h:63
Represents a player's statistics in a game.
Definition: gamestat.h:146
Represents game statistics.
Definition: gamestat.h:37
VictoryState
Enumerates the victory states for a game.
Definition: gamestat.h:43
Represents a player with extended statistics.
Definition: player.h:38
bool queryGameStatById(Battlefield::GameStat &game_stat)
Queries a game statistic by its ID.
Definition: game_stat.cpp:158
bool queryGameServerPlayers(Battlefield::GameServer &game_server)
Queries the players connected to a game server.
bool queryGameServers(Battlefield::GameServers &game_servers)
Queries all game servers from the database.
bool queryPlayerByProfileId(Battlefield::Player &player)
Queries a player by their profile ID.
bool queryClanByClanId(Battlefield::Clan &clan)
Queries a clan by its clan ID.
bool queryGameStatsByDate(Battlefield::GameStats &game_stats, const std::string &date)
Queries game statistics by date.
Definition: game_stat.cpp:10
bool queryLeaderboardRatio(Battlefield::RankPlayers &rank_players, const std::string &k, const std::string &s, uint32_t limit=10, uint32_t offset=0)
Queries the leaderboard rank of players by kills-to-spawns ratio.
bool queryClanRanksByClanId(Battlefield::Clan &clan)
Queries the ranks of a clan by its clan ID.
Definition: clan_rank.cpp:10
bool queryGameStatPlayers(Battlefield::GameStat &game_stat)
Queries the players associated with a game statistic.
bool queryPlayerByUniquenick(Battlefield::Player &player)
Queries a player by their unique nickname.
bool queryLeaderboardClan(Battlefield::RankClans &rank_clans, uint32_t limit=10, uint32_t offset=0)
Queries clan leaderboard.
bool queryPlayerStatsByProfileId(Battlefield::Player &player)
Queries the statistics of a player by their profile ID.
Definition: player_stat.cpp:10
bool queryLeaderboardRank(Battlefield::RankPlayers &rank_players, uint32_t limit=10, uint32_t offset=0)
Queries the leaderboard rank of players.
bool queryClanByProfileId(Battlefield::Clan &clan, const Battlefield::Player &player)
Queries a clan by a player's profile ID.
bool queryLeaderboardType(Battlefield::RankPlayers &rank_players, const std::string &type, uint32_t limit=10, uint32_t offset=0)
Queries the leaderboard rank of players by player stat type.
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 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
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 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 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 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 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