aboutsummaryrefslogtreecommitdiff
path: root/src/UdpTasks/BeaconServer/Receive/replyquery.cpp
blob: 7df6549effa480c6d31999b4bea3765b79da484c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
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;
}