serverlistcounttracker.cpp
1 //------------------------------------------------------------------------------
2 // serverlistcounttracker.cpp
3 //------------------------------------------------------------------------------
4 //
5 // This program is free software; you can redistribute it and/or
6 // modify it under the terms of the GNU General Public License
7 // as published by the Free Software Foundation; either version 2
8 // of the License, or (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 General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software
17 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18 // 02110-1301, USA.
19 //
20 //------------------------------------------------------------------------------
21 // Copyright (C) 2015 "Zalewa" <zalewapl@gmail.com>
22 //------------------------------------------------------------------------------
23 #include "serverlistcounttracker.h"
24 
25 #include "serverapi/playerslist.h"
26 #include "serverapi/server.h"
27 #include <cassert>
28 #include <cmath>
29 
30 DClass<ServerListCountTracker>
31 {
32 public:
33  const EnginePlugin *plugin;
34 
35  ServerListCount count;
36  bool hasRegisterBeenCalled;
37 
38  bool isPassingPluginFilter(const ServerPtr &server) const
39  {
40  return plugin == NULL || server->plugin() == plugin;
41  }
42 };
43 DPointered(ServerListCountTracker)
44 
46 : QObject(parent)
47 {
48  d->plugin = NULL;
49  d->hasRegisterBeenCalled = false;
50 }
51 
52 const ServerListCount &ServerListCountTracker::count() const
53 {
54  return d->count;
55 }
56 
57 void ServerListCountTracker::setPluginFilter(const EnginePlugin *plugin)
58 {
59  assert(!d->hasRegisterBeenCalled && "don't change filter after server has already been registered");
60  d->plugin = plugin;
61 }
62 
63 void ServerListCountTracker::deregisterServer(ServerPtr server)
64 {
65  if (d->isPassingPluginFilter(server))
66  {
67  server->disconnect(this);
68  d->count.discountServer(server);
69  if (server->isRefreshing())
70  {
71  --d->count.numRefreshing;
72  }
73  else
74  {
75  d->count.discountPlayers(server);
76  }
77  emit updated();
78  }
79 }
80 
81 void ServerListCountTracker::registerServer(ServerPtr server)
82 {
83  d->hasRegisterBeenCalled = true;
84  if (d->isPassingPluginFilter(server))
85  {
86  this->connect(server.data(), SIGNAL(begunRefreshing(ServerPtr)),
87  SLOT(onServerBegunRefreshing(ServerPtr)));
88  this->connect(server.data(), SIGNAL(updated(ServerPtr, int)),
89  SLOT(onServerUpdated(ServerPtr)));
90 
91  d->count.countServer(server);
92  if (server->isRefreshing())
93  {
94  ++d->count.numRefreshing;
95  }
96  else
97  {
98  d->count.countPlayers(server);
99  }
100  emit updated();
101  }
102 }
103 
104 void ServerListCountTracker::onServerBegunRefreshing(ServerPtr server)
105 {
106  d->count.discountPlayers(server);
107  ++d->count.numRefreshing;
108  emit updated();
109 }
110 
111 void ServerListCountTracker::onServerUpdated(ServerPtr server)
112 {
113  d->count.countPlayers(server);
114  --d->count.numRefreshing;
115  emit updated();
116 }
117 
119 
120 ServerListCount::ServerListCount()
121 {
122  numBots = 0;
123  numHumanPlayers = 0;
124  numPlayers = 0;
125 
126  numCustomServers = 0;
127  numGenericServers = 0;
128  numLanServers = 0;
129  numServers = 0;
130  numRefreshing = 0;
131 }
132 
133 void ServerListCount::countPlayers(const ServerPtr &server)
134 {
135  const PlayersList &players = server->players();
136 
137  numBots += players.numBots();
138  numHumanPlayers += players.numClientsWithoutBots();
139  numPlayers += players.numClients();
140 }
141 
142 void ServerListCount::discountPlayers(const ServerPtr &server)
143 {
144  const PlayersList &players = server->players();
145 
146  numBots -= players.numBots();
147  numHumanPlayers -= players.numClientsWithoutBots();
148  numPlayers -= players.numClients();
149 }
150 
151 void ServerListCount::countServer(const ServerPtr &server)
152 {
153  ++numServers;
154  numGenericServers += !server->isSpecial() ? 1 : 0;
155  numLanServers += server->isLan() ? 1 : 0;
156  numCustomServers += server->isCustom() ? 1 : 0;
157 }
158 
159 void ServerListCount::discountServer(const ServerPtr &server)
160 {
161  --numServers;
162  numGenericServers -= !server->isSpecial() ? 1 : 0;
163  numLanServers -= server->isLan() ? 1 : 0;
164  numCustomServers -= server->isCustom() ? 1 : 0;
165 }
166 
167 int ServerListCount::refreshedPercent() const
168 {
169  if (numRefreshing == 0 || numServers == 0)
170  {
171  return 100;
172  }
173  else
174  {
175  float refreshingFactor = static_cast<float>(numRefreshing) /
176  static_cast<float>(numServers);
177  return static_cast<int>(floor(100.0 - 100.0 * refreshingFactor));
178  }
179 }
180 
181 ServerListCount& ServerListCount::operator+=(const ServerListCount &other)
182 {
183  numBots += other.numBots;
184  numHumanPlayers += other.numHumanPlayers;
185  numPlayers += other.numPlayers;
186 
187  numCustomServers += other.numCustomServers;
188  numGenericServers += other.numGenericServers;
189  numLanServers += other.numLanServers;
190  numServers += other.numServers;
191  numRefreshing += other.numRefreshing;
192  return *this;
193 }
int numClients() const
Overall number of people and bots on the server.