/* GNU General Public License version 3 notice Copyright (C) 2012 Mihawk . All rights reserved. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see < http://www.gnu.org/licenses/ >. */ #ifndef SERVERQUERY_H #define SERVERQUERY_H #include #include class QUdpSocket; // Player info struct struct Player { int id; QString team; QString name; QString skin; int frags; int time; int ping; int topColor; int bottomColor; bool spectator; }; typedef QList PlayerList; // Server info struct struct ServerRule { QString rule; QString value; }; typedef QList ServerRules; /** This class gathers information for a given server and returns the information in lists of information. @author Mihawk @file ServerQuery.h */ class ServerQuery : public QObject { Q_OBJECT public: // Error codes enum Error { NoError, TimedOutError, EmptyResponseError, InvalidResponseError, InvalidInfoStringError, InvalidPlayerInfoError, SendError, HostLookupError, ConnectionError, UnknownError }; /** Constructor. @param parent The parent object if possible */ explicit ServerQuery(QObject *parent = 0); /** Destructor. */ ~ServerQuery(); /** Sets the address we are going to gather information from. @param address The server address @param port The server port @return True on success else false */ bool setAddress(const QString &address, quint16 port = 27500); bool setAddress(const QHostAddress &address, quint16 port = 27500); /** Returns the address and port of the server we are querying. */ const QHostAddress& address() const; quint16 port() const; /** Start a new query on the server, this function is non-blocking run() must be called for updates on the current query. @param pingServer Whether we should gather ping information too (this blocks the query) @return True on success, false otherwise */ bool query(bool pingServer = false); /** Must be called when a query is active. */ void run(); /** Returns whether a query is active or not. @return True if we are now in the middle of a query process, false otherwise */ bool isActive() const; /** Returns the player list connected to this server we just gathered info with all their information. @return The player list */ PlayerList playerList() const; /** Returns all the information gathered from the server. @return The server rules (as we call it) */ ServerRules serverRules() const; /** Searches and returns a given rule value from the Server rules list we gathered. @param ruleName The rule to look for @return The rule's value */ QString serverRuleValue(const QString& ruleName) const; signals: /** Emitted when an error occured during the information gathering process. @param err Error code */ void error(ServerQuery::Error err); /** Emitted when the information gathering process finished successfully. */ void finished(); private slots: /** Parses the server information response from server internally. */ void parseServerInfo(); /** Called when an error occured on the socket level. @param err Error code */ void socketError(QAbstractSocket::SocketError err); private: QUdpSocket* mySocket; // The socket used to do the query QHostAddress myAddress; // The address of the server quint16 myPort; // The port of the server PlayerList myPlayers; // The parsed player list ServerRules myRules; // The parsed server information list quint16 myPing; // The ping from us to the server bool myIsProxyFlag; // Indicates whether this server is a proxy bool myActiveFlag; // Indicates whether we are in the middle of a query process /** Pings the server we are gathering information from. Note: This function blocks code until its finished. FIXME: Make this function non-blocking too. @param count Number of times we should ping the server @param timeout How long to wait for a server reply @return The average ping */ int ping(int count = 3, int timeout = 1000); // Tables used for namefun conversion static char ourReadableCharsTable[256]; static bool ourReadableCharsTableInitialized; /** Initializes namefun conversion tables. */ static void fillReadableCharsTable(); public: /** Converts namefun text to normal text. @param name The text/name to convert */ static QString convertNameFun(const QString &name); }; #endif // SERVERQUERY_H