serverlistcounttracker.cpp
1 //------------------------------------------------------------------------------
2 // serverlistcounttracker.cpp
3 //------------------------------------------------------------------------------
4 //
5 // This library is free software; you can redistribute it and/or
6 // modify it under the terms of the GNU Lesser General Public
7 // License as published by the Free Software Foundation; either
8 // version 2.1 of the License, or (at your option) any later version.
9 //
10 // This library 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 GNU
13 // Lesser General Public License for more details.
14 //
15 // You should have received a copy of the GNU Lesser General Public
16 // License along with this library; 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 #include <QSet>
30 
31 DClass<ServerListCountTracker>
32 {
33 public:
34  const EnginePlugin *plugin;
35  QSet<ServerPtr> countedServers;
36 
37  ServerListCount count;
38  bool hasRegisterBeenCalled;
39 
40  bool isPassingPluginFilter(const ServerPtr &server) const
41  {
42  return plugin == nullptr || server->plugin() == plugin;
43  }
44 };
45 DPointered(ServerListCountTracker)
46 
48  : QObject(parent)
49 {
50  d->plugin = nullptr;
51  d->hasRegisterBeenCalled = false;
52 }
53 
54 const ServerListCount &ServerListCountTracker::count() const
55 {
56  return d->count;
57 }
58 
59 void ServerListCountTracker::setPluginFilter(const EnginePlugin *plugin)
60 {
61  assert(!d->hasRegisterBeenCalled && "don't change filter after server has already been registered");
62  d->plugin = plugin;
63 }
64 
65 void ServerListCountTracker::deregisterServer(ServerPtr server)
66 {
67  if (d->isPassingPluginFilter(server))
68  {
69  d->countedServers.remove(server);
70  server->disconnect(this);
71  d->count.discountServer(server);
72  if (server->isRefreshing())
73  {
74  --d->count.numRefreshing;
75  }
76  else
77  {
78  d->count.discountPlayers(server);
79  }
80  emit updated();
81  }
82 }
83 
84 void ServerListCountTracker::registerServer(ServerPtr server)
85 {
86  d->hasRegisterBeenCalled = true;
87  if (d->isPassingPluginFilter(server))
88  {
89  this->connect(server.data(), SIGNAL(begunRefreshing(ServerPtr)),
90  SLOT(onServerBegunRefreshing(ServerPtr)));
91  this->connect(server.data(), SIGNAL(updated(ServerPtr,int)),
92  SLOT(onServerUpdated(ServerPtr)));
93 
94  d->count.countServer(server);
95  if (server->isRefreshing())
96  {
97  ++d->count.numRefreshing;
98  }
99  else
100  {
101  d->countedServers.insert(server);
102  d->count.countPlayers(server);
103  }
104  emit updated();
105  }
106 }
107 
108 void ServerListCountTracker::onServerBegunRefreshing(ServerPtr server)
109 {
110  d->countedServers.remove(server);
111  d->count.discountPlayers(server);
112  ++d->count.numRefreshing;
113  emit updated();
114 }
115 
116 void ServerListCountTracker::onServerUpdated(ServerPtr server)
117 {
118  if (d->countedServers.contains(server))
119  return;
120  d->countedServers.insert(server);
121  d->count.countPlayers(server);
122  --d->count.numRefreshing;
123  emit updated();
124 }
125 
127 
128 ServerListCount::ServerListCount()
129 {
130  numBots = 0;
131  numHumanPlayers = 0;
132  numPlayers = 0;
133 
134  numCustomServers = 0;
135  numGenericServers = 0;
136  numLanServers = 0;
137  numServers = 0;
138  numRefreshing = 0;
139 }
140 
141 void ServerListCount::countPlayers(const ServerPtr &server)
142 {
143  const PlayersList &players = server->players();
144 
145  numBots += players.numBots();
146  numHumanPlayers += players.numClientsWithoutBots();
147  numPlayers += players.numClients();
148 }
149 
150 void ServerListCount::discountPlayers(const ServerPtr &server)
151 {
152  const PlayersList &players = server->players();
153 
154  numBots -= players.numBots();
155  numHumanPlayers -= players.numClientsWithoutBots();
156  numPlayers -= players.numClients();
157 }
158 
159 void ServerListCount::countServer(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 void ServerListCount::discountServer(const ServerPtr &server)
168 {
169  --numServers;
170  numGenericServers -= !server->isSpecial() ? 1 : 0;
171  numLanServers -= server->isLan() ? 1 : 0;
172  numCustomServers -= server->isCustom() ? 1 : 0;
173 }
174 
175 int ServerListCount::refreshedPercent() const
176 {
177  if (numRefreshing == 0 || numServers == 0)
178  {
179  return 100;
180  }
181  else
182  {
183  float refreshingFactor = static_cast<float>(numRefreshing) /
184  static_cast<float>(numServers);
185  return static_cast<int>(floor(100.0 - 100.0 * refreshingFactor));
186  }
187 }
188 
189 ServerListCount &ServerListCount::operator+=(const ServerListCount &other)
190 {
191  numBots += other.numBots;
192  numHumanPlayers += other.numHumanPlayers;
193  numPlayers += other.numPlayers;
194 
195  numCustomServers += other.numCustomServers;
196  numGenericServers += other.numGenericServers;
197  numLanServers += other.numLanServers;
198  numServers += other.numServers;
199  numRefreshing += other.numRefreshing;
200  return *this;
201 }