23 #include "masterclient.h"
26 #include "plugins/engineplugin.h"
27 #include "serverapi/message.h"
28 #include "serverapi/server.h"
29 #include "serverapi/playerslist.h"
30 #include "datapaths.h"
32 #include <QDataStream>
33 #include <QErrorMessage>
36 #include <QMessageBox>
47 QList<ServerPtr> servers;
51 bool isCacheOpenForReading()
const
53 return cache != NULL && cache->isReadable();
56 bool isCacheOpenForWriting()
const
58 return cache != NULL && cache->isWritable();
66 POLYMORPHIC_DEFINE_CONST(QString,
MasterClient, masterBanHelp, (), ());
68 MasterClient::MasterClient()
74 set_masterBanHelp(&MasterClient::masterBanHelp_default);
77 MasterClient::~MasterClient()
87 void MasterClient::clearServers()
94 return (d->address == address && d->port == port);
97 void MasterClient::emitBannedMessage()
101 if (!helpMsg.trimmed().isEmpty())
104 msg.
contents(), helpMsg.trimmed()));
112 foreach (ServerPtr server, d->servers)
114 server->disconnect();
125 return plugin()->data()->name;
138 QString MasterClient::masterBanHelp_default()
const
143 void MasterClient::notifyResponse(Response response)
149 case RESPONSE_BANNED:
156 "master because not enough time has past."),
true);
165 tr(
"Could not fetch a new server list. The protocol you are using is too old. "
166 "An update may be available."),
true);
171 int MasterClient::numPlayers()
const
174 foreach(ServerPtr server, d->servers)
178 players += server->players().numClients();
184 int MasterClient::numServers()
const
186 return d->servers.size();
189 ServerPtr MasterClient::operator[](
int index)
const
191 return d->servers[index];
194 bool MasterClient::preparePacketCache(
bool write)
196 if (write ? !d->isCacheOpenForWriting() : !d->isCacheOpenForReading())
205 QString cacheFile = gDefaultDataPaths->programsDataDirectoryPath() +
"/"
206 + QString(
plugin()->data()->name).replace(
' ',
"");
207 d->cache =
new QFile(cacheFile);
214 if(!d->cache->open(write ? QIODevice::WriteOnly|QIODevice::Truncate : QIODevice::ReadOnly))
216 resetPacketCaching();
220 else if (!write && d->isCacheOpenForReading())
226 return d->cache != NULL;
229 void MasterClient::pushPacketToCache(
const QByteArray &data)
231 if(!preparePacketCache(
true))
236 QDataStream strm(d->cache);
237 strm << static_cast<quint16>(data.size());
244 if (response == RESPONSE_GOOD || response == RESPONSE_PENDING)
246 pushPacketToCache(data);
251 void MasterClient::readPacketCache()
253 if(!preparePacketCache(
false))
260 QDataStream strm(d->cache);
270 gLog << tr(
"Reloading master server results from cache for %1!").arg(
plugin()->data()->name);
271 bool hasGood =
false;
277 QByteArray data(size,
'\0');
281 if (response == RESPONSE_GOOD)
285 if(response != RESPONSE_GOOD && response != RESPONSE_PENDING)
306 server->setSelf(server.toWeakRef());
307 d->servers << server;
310 void MasterClient::resetPacketCaching()
323 resetPacketCaching();
328 if(d->address.isNull())
333 if(request.isEmpty())
335 socket->writeDatagram(request, d->address, d->port);
339 const QList<ServerPtr> &MasterClient::servers()
const
349 void MasterClient::setTimeouted(
bool b)
361 emit
message(tr(
"Master server timeout"), tr(
"Connection timeout (%1:%2).")
362 .arg(d->address.toString()).arg(d->port),
true);
373 void MasterClient::updateAddress()
379 QHostInfo info = QHostInfo::fromName(host);
380 if(info.addresses().size() == 0)
383 d->address = info.addresses().first();
384 if (d->address.protocol() != QAbstractSocket::IPv4Protocol)
386 foreach(
const QHostAddress &addr, info.addresses())
388 if(addr.protocol() == QAbstractSocket::IPv4Protocol)
Response readResponse(const QByteArray &data)
Calls readMasterResponse and handles packet caching.
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.
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. ...