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)
Response readResponse(const QByteArray &data)
Calls readMasterResponse and handles packet caching.
unsigned short port() const
Network port of the master server.
bool sendRequest(QUdpSocket *socket)
Sends request packet through socket.
Message object used to pass messages throughout the Doomseeker's system.
void registerNewServer(ServerPtr server)
Registers new server with this MasterClient.
void masterHost(QString &host, unsigned short &port) const
void message(const QString &title, const QString &content, bool isError)
bool isTimeouted() const
Indicates that the server has timeouted recently.
virtual Response readMasterResponse(const QByteArray &data)=0
Called to read and analyze the response from the MasterServer.
QHostAddress address() const
Address of the master server.
static const unsigned BANNED_FROM_MASTERSERVER
Information indicating that current player is banned from given server.
virtual void refreshStarts()
void messageImportant(const Message &message)
Signal used to forward important message to Doomseeker.
void timeoutRefresh()
Times the refreshing process out.
virtual void timeoutRefreshEx()
Reimplement this for clean up purposes.
virtual const EnginePlugin * plugin() const =0
QString masterBanHelp() const
[Virtual] Help message displayed to the user when ban is detected.
static const unsigned CUSTOM_ERROR
Programmer-defined error message.
bool isAddressSame(const QHostAddress &address, unsigned short port) const
Returns true if the passed address:port is the same as this master server's.
QString contents() const
Customized displayable contents of this Message.
Abstract base for all MasterClients.
QString engineName() const
Extracts engine name from pluginInfo() if available.
virtual QByteArray createServerListRequest()=0
Produce contents of server list request packet that is sent to the master server. ...