aboutsummaryrefslogtreecommitdiff
path: root/src/UdpTasks/BeaconServer/Receive/replyquery.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/UdpTasks/BeaconServer/Receive/replyquery.cpp')
-rw-r--r--src/UdpTasks/BeaconServer/Receive/replyquery.cpp113
1 files changed, 113 insertions, 0 deletions
diff --git a/src/UdpTasks/BeaconServer/Receive/replyquery.cpp b/src/UdpTasks/BeaconServer/Receive/replyquery.cpp
new file mode 100644
index 0000000..7df6549
--- /dev/null
+++ b/src/UdpTasks/BeaconServer/Receive/replyquery.cpp
@@ -0,0 +1,113 @@
+#include "../beaconserver.h"
+
+QStringList BeaconServer::replyQuery(const QMultiHash<QString, QString> &query)
+{
+ // initialise output
+ QStringList queryResponse;
+
+ // gamespy uses incrementing query ids in the messages
+ _queryId = ( (_queryId > 99) ? 1 : _queryId + 1 );
+ int querySubId = 1;
+
+ // secure response
+ if ( query.contains("secure") and _coreObject->SupportedGames.contains( TYPE_GAMENAME))
+ {
+ // sanity checks and cast to byte array
+ QByteArray secure = query.value("secure", "").toLatin1();
+ QByteArray cipher = _coreObject->SupportedGames.value(TYPE_GAMENAME).cipher.toLatin1();
+ int enctype = query.value("enctype", "0").toInt();
+ QString validate = returnValidate(cipher, secure, enctype);
+
+ queryResponse.append(
+ QStringLiteral("\\validate\\%1\\queryid\\%2.%3")
+ .arg(validate, QString::number(_queryId), QString::number(querySubId++))
+ );
+ }
+
+ // basic
+ if ( query.contains("basic") or query.contains("status") )
+ {
+ queryResponse.append(
+ QStringLiteral("\\gamename\\%1"
+ "\\gamever\\%2"
+ "\\location\\0"
+ "\\queryid\\%3.%4")
+ .arg(TYPE_GAMENAME, SHORT_VER, QString::number(_queryId), QString::number(querySubId++))
+ );
+ }
+
+ // info
+ if ( query.contains("info") or query.contains("status") )
+ {
+ // cast server statistics as player info
+ QString selectStats = "SELECT SUM(num_direct) AS serv_direct, "
+ "SUM(num_total) AS serv_total "
+ "FROM gameinfo ";
+ QSqlQuery statQuery;
+ statQuery.prepare(selectStats);
+ if ( ! statQuery.exec() )
+ reportQuery(statQuery); // do NOT return/die!
+
+ // get values
+ int serv_direct = -1;
+ int serv_total = -1;
+ if ( statQuery.next() )
+ {
+ serv_direct = statQuery.value("serv_direct").toInt();
+ serv_total = statQuery.value("serv_total").toInt();
+ }
+
+ queryResponse.append(
+ QStringLiteral("\\hostname\\%1"
+ "\\hostport\\%2"
+ "\\gametype\\%3"
+ "\\mapname\\333networks"
+ "\\numplayers\\%4"
+ "\\maxplayers\\%5"
+ "\\gamemode\\openplaying"
+ "\\queryid\\%6.%7")
+ .arg( _coreObject->Settings.PublicInformationSettings.hostname,
+ QString::number(_coreObject->Settings.ListenServerSettings.listenPort),
+ "Masterserver", // replace with "bare masterserver" or "integrated beacon/website checker", based on the settings
+ QString::number(serv_direct),
+ QString::number(serv_total),
+ QString::number(_queryId), QString::number(querySubId++))
+ );
+ }
+
+ // rules
+ if ( query.contains("rules") or query.contains("status") )
+ {
+ // compile information about the specific software
+ QString mutators;
+ mutators.append( QStringLiteral("buildtype: %1, buildtime: %2, Qt version: %3, author: %4")
+ .arg(BUILD_TYPE,
+ BUILD_TIME,
+ qVersion(),
+ BUILD_AUTHOR) );
+
+ queryResponse.append(
+ QStringLiteral("\\mutators\\%1"
+ "\\AdminName\\%2"
+ "\\AdminEMail\\%3"
+ "\\queryid\\%4.%5")
+ .arg( mutators,
+ _coreObject->Settings.PublicInformationSettings.adminName,
+ _coreObject->Settings.PublicInformationSettings.contact,
+ QString::number(_queryId), QString::number(querySubId++))
+ );
+ }
+
+ // echo: reply with echo_reply
+ if (query.contains("echo"))
+ {
+ queryResponse.append(QStringLiteral("\\echo_reply\\%1\\queryid\\%2.%3")
+ .arg(query.value("echo"), QString::number(_queryId), QString::number(querySubId++))
+ );
+ }
+
+ // end query with final
+ queryResponse.append("\\final\\");
+
+ return queryResponse;
+}