23 #include "masterclient.h"
25 #include "datapaths.h"
27 #include "plugins/engineplugin.h"
28 #include "serverapi/message.h"
29 #include "serverapi/playerslist.h"
30 #include "serverapi/server.h"
32 #include <QDataStream>
33 #include <QErrorMessage>
36 #include <QMessageBox>
47 QList<ServerPtr> servers;
51 bool isCacheOpenForReading()
const
53 return cache !=
nullptr && cache->isReadable();
56 bool isCacheOpenForWriting()
const
58 return cache !=
nullptr && cache->isWritable();
66 POLYMORPHIC_DEFINE_CONST(QString,
MasterClient, masterBanHelp, (), ())
68 MasterClient::MasterClient()
74 set_masterBanHelp(&MasterClient::masterBanHelp_default);
77 MasterClient::~MasterClient()
81 if (d->cache !=
nullptr)
99 return d->address.toIPv4Address() == address.toIPv4Address() && d->port ==
port;
102 void MasterClient::emitBannedMessage()
106 if (!helpMsg.trimmed().isEmpty())
109 msg.
contents(), helpMsg.trimmed()));
126 return plugin()->data()->name;
139 QString MasterClient::masterBanHelp_default()
const
144 void MasterClient::notifyResponse(Response response)
150 case RESPONSE_BANNED:
157 "master because not enough time has passed."),
true);
166 tr(
"Could not fetch a new server list. The protocol you are using is too old. "
167 "An update may be available."),
true);
172 int MasterClient::numServers()
const
174 return d->servers.size();
177 ServerPtr MasterClient::operator[](
int index)
const
179 return d->servers[index];
187 bool MasterClient::preparePacketCache(
bool write)
189 if (write ? !d->isCacheOpenForWriting() : !d->isCacheOpenForReading())
196 if (d->cache ==
nullptr)
198 QString cacheFile = gDefaultDataPaths->cacheLocationPath() +
"/"
199 + QString(
plugin()->data()->name).replace(
' ',
"");
200 d->cache =
new QFile(cacheFile);
207 if (!d->cache->open(write ? QIODevice::WriteOnly | QIODevice::Truncate : QIODevice::ReadOnly))
209 resetPacketCaching();
213 else if (!write && d->isCacheOpenForReading())
219 return d->cache !=
nullptr;
222 void MasterClient::pushPacketToCache(
const QByteArray &data)
224 if (!preparePacketCache(
true))
229 QDataStream strm(d->cache);
230 strm << static_cast<quint16>(data.size());
237 if (response == RESPONSE_GOOD || response == RESPONSE_PENDING)
239 pushPacketToCache(data);
244 void MasterClient::readPacketCache()
246 if (!preparePacketCache(
false))
253 QDataStream strm(d->cache);
263 gLog << tr(
"Reloading master server results from cache for %1!").arg(
plugin()->data()->name);
264 bool hasGood =
false;
265 while (!strm.atEnd())
270 QByteArray data(size,
'\0');
274 if (response == RESPONSE_GOOD)
278 if (response != RESPONSE_GOOD && response != RESPONSE_PENDING)
299 server->setSelf(server.toWeakRef());
300 d->servers << server;
303 void MasterClient::resetPacketCaching()
305 if (d->cache !=
nullptr)
316 resetPacketCaching();
321 if (d->address.isNull())
326 if (request.isEmpty())
328 socket->writeDatagram(request, d->address, d->port);
332 const QList<ServerPtr> &MasterClient::servers()
const
342 void MasterClient::setTimeouted(
bool b)
354 emit
message(tr(
"Master server timeout"), tr(
"Connection timeout (%1:%2).")
355 .arg(d->address.toString()).arg(d->port),
true);
366 void MasterClient::updateAddress()
372 QHostInfo info = QHostInfo::fromName(host);
373 if (info.addresses().size() == 0)
376 d->address = info.addresses().first();
377 if (d->address.protocol() != QAbstractSocket::IPv4Protocol)
379 for (
const QHostAddress &addr : info.addresses())
381 if (addr.protocol() == QAbstractSocket::IPv4Protocol)