Esempio n. 1
0
void Widget::tcpProcessData(QByteArray data, QTcpSocket* socket)
{
    // Login request (forwarded)
    if (useRemoteLogin && tcpReceivedDatas->contains("commfunction=login&") && tcpReceivedDatas->contains("&version="))
    {
        logMessage("TCP: Remote login not implemented yet.");
        // We need to add the client with his IP/port/passhash to tcpPlayers if he isn't already there
        Player newPlayer;
        newPlayer.IP = socket->peerAddress().toIPv4Address();
        newPlayer.port = socket->peerPort();
        QString passhash = QString(*tcpReceivedDatas);
        passhash = passhash.mid(passhash.indexOf("passhash=")+9);
        passhash.truncate(passhash.indexOf('&'));
        newPlayer.passhash = passhash;
        logMessage("IP:"+newPlayer.IP+", passhash:"+newPlayer.passhash);

        // Then connect to the remote and forward the client's requests
        if (!remoteLoginSock.isOpen())
        {
            remoteLoginSock.connectToHost(remoteLoginIP, remoteLoginPort);
            remoteLoginSock.waitForConnected(remoteLoginTimeout);
            if (!remoteLoginSock.isOpen())
            {
                win.logMessage("TCP: Can't connect to remote login server : timed out.");
                return;
            }
        }
        // We just blindly send everything that we're going to remove from tcpReceivedDatas at the end of tcpProcessData
        QByteArray toSend = *tcpReceivedDatas;
        toSend.left(toSend.indexOf(data) + data.size());
        remoteLoginSock.write(toSend);
    }
    else if (useRemoteLogin && tcpReceivedDatas->contains("Server:")) // Login reply (forwarded)
    {
        logMessage("TCP: Remote login not implemented yet.");
        // First we need to find a player matching the received passhash in tcpPlayers
        // Use the player's IP/port to find a matching socket in tcpClientsList
        // The login headers are all the same, so we can just use loginHeader.bin and send back data
    }
    else if (tcpReceivedDatas->contains("commfunction=login&") && tcpReceivedDatas->contains("&version=")) // Login request
    {
        QString postData = QString(*tcpReceivedDatas);
        *tcpReceivedDatas = tcpReceivedDatas->right(postData.size()-postData.indexOf("version=")-8-4); // 4 : size of version number (ie:version=1344)
        logMessage("TCP: Login request received :");
        QFile file(QString(NETDATAPATH)+"/loginHeader.bin");
        QFile fileServersList(SERVERSLISTFILEPATH);
        QFile fileBadPassword(QString(NETDATAPATH)+"/loginWrongPassword.bin");
        QFile fileAlready(QString(NETDATAPATH)+"/loginAlreadyConnected.bin");
        QFile fileMaxRegistration(QString(NETDATAPATH)+"/loginMaxRegistered.bin");
        QFile fileMaxConnected(QString(NETDATAPATH)+"/loginMaxConnected.bin");
        if (!file.open(QIODevice::ReadOnly) || !fileBadPassword.open(QIODevice::ReadOnly)
        || !fileAlready.open(QIODevice::ReadOnly) || !fileMaxRegistration.open(QIODevice::ReadOnly)
        || !fileMaxConnected.open(QIODevice::ReadOnly) || !fileServersList.open(QIODevice::ReadOnly))
        {
            logStatusMessage("Error reading login data files");
            stopServer();
        }
        else
        {
            bool ok=true;
            postData = postData.right(postData.size()-postData.indexOf("username="******"passhash=")-9);
            QString passhash = postData;
            passhash.truncate(postData.indexOf('&'));
            logMessage(QString("IP : ")+socket->peerAddress().toString());
            logMessage(QString("Username : "******"Passhash : ")+passhash);

            // Add player to the players list
            Player* player = Player::findPlayer(tcpPlayers, username);
            if (player->name != username) // Not found, create a new player
            {
                // Check max registered number
                if (tcpPlayers.size() >= maxRegistered)
                {
                    logMessage("TCP: Registration failed, too many players registered");
                    socket->write(fileMaxRegistration.readAll());
                    ok = false;
                }
                else
                {
                    logMessage("TCP: Creating user "+username+" in database");
                    Player* newPlayer = new Player;
                    newPlayer->name = username;
                    newPlayer->passhash = passhash;
                    newPlayer->IP = socket->peerAddress().toString();
                    newPlayer->connected = false; // The connection checks are done by the game servers

                    tcpPlayers << newPlayer;
                    if (!Player::savePlayers(tcpPlayers))
                        ok = false;
                }
            }
            else // Found, compare passhashes, check if already connected
            {
                if (player->passhash != passhash) // Bad password
                {
                    logMessage("TCP: Login failed, wrong password");
                    socket->write(fileBadPassword.readAll());
                    ok=false;
                }
                /*
                else if (newPlayer.connected) // Already connected
                {
                    logMessage("TCP: Login failed, player already connected");
                    socket->write(fileAlready.readAll());
                    ok=false;
                }
                */
                else // Good password
                {
                    /*
                    // Check too many connected
                    int n=0;
                    for (int i=0;i<tcpPlayers.size();i++)
                        if (tcpPlayers[i].connected)
                            n++;
                    if (n>=maxConnected)
                    {
                        logMessage("TCP: Login failed, too much players connected");
                        socket->write(fileMaxConnected.readAll());
                        ok=false;
                    }
                    else
                    */
                    {
                        //player->reset();
                        player->IP = socket->peerAddress().toString();
                        player->lastPingTime = timestampNow();
                        player->connected = true;
                    }
                }
            }

            if (ok) // Send servers list
            {
                QByteArray customData = file.readAll();

                QByteArray data1 = QByteArray::fromHex("0D0A61757468726573706F6E73653A0A747275650A");
                QByteArray sesskey = QCryptographicHash::hash(QString(passhash + saltPassword).toLatin1(), QCryptographicHash::Md5).toHex();
                sesskey += passhash;
                QByteArray data2 = QByteArray::fromHex("0A310A");
                QByteArray serversList;
                QByteArray line;
                do {
                    line = fileServersList.readLine().trimmed();
                    serversList+=line;
                    serversList+=0x0A;
                } while (!line.isEmpty());
                serversList = serversList.trimmed();
                QByteArray data3 = QByteArray::fromHex("0D0A300D0A0D0A");
                int dataSize = data1.size() + sesskey.size() + data2.size() + serversList.size() - 2;
                QString dataSizeStr = QString().setNum(dataSize, 16);

                customData += dataSizeStr;
                customData += data1;
                customData += sesskey;
                customData += data2;
                customData += serversList;
                customData += data3;

                logMessage("TCP: Login successful, sending servers list");
                socket->write(customData);
                socket->close();
            }
        }
    }
    else if (data.contains("commfunction=removesession"))
    {
        logMessage("TCP: Session closed by client");
    }
    else // Unknown request, erase tcp buffer
    {
        // Display data
        logMessage("TCP: Unknown request received : ");
        logMessage(QString(data.data()));
    }
}
Esempio n. 2
0
void Widget::tcpProcessData(QByteArray data, QTcpSocket* socket)
{
    if (tcpReceivedDatas->contains("commfunction=login&") && tcpReceivedDatas->contains("&version=")) // Login request
    {
        QString postData = QString(*tcpReceivedDatas);
        *tcpReceivedDatas = tcpReceivedDatas->right(postData.size()-postData.indexOf("version=")-8-4); // 4 : size of version number (ie:version=1344)
        logMessage("TCP: Login request received :");
        QFile file(QString(NETDATAPATH)+"/loginHeader.bin");
        QFile fileServersList(SERVERSLISTFILEPATH);
        QFile fileBadPassword(QString(NETDATAPATH)+"/loginWrongPassword.bin");
        QFile fileAlready(QString(NETDATAPATH)+"/loginAlreadyConnected.bin");
        QFile fileMaxRegistration(QString(NETDATAPATH)+"/loginMaxRegistered.bin");
        QFile fileMaxConnected(QString(NETDATAPATH)+"/loginMaxConnected.bin");
        if (!file.open(QIODevice::ReadOnly) || !fileBadPassword.open(QIODevice::ReadOnly)
        || !fileAlready.open(QIODevice::ReadOnly) || !fileMaxRegistration.open(QIODevice::ReadOnly)
        || !fileMaxConnected.open(QIODevice::ReadOnly) || !fileServersList.open(QIODevice::ReadOnly))
        {
            logStatusMessage("Error reading login data files");
            stopServer();
        }
        else
        {
            bool ok=true;
            postData = postData.right(postData.size()-postData.indexOf("username="******"passhash=")-9);
            QString passhash = postData;
            passhash.truncate(postData.indexOf('&'));
            logMessage(QString("IP : ")+socket->peerAddress().toString());
            logMessage(QString("Username : "******"Passhash : ")+passhash);

            // Add player to the players list
            Player player = Player::findPlayer(tcpPlayers, username);
            if (player.name != username) // Not found, create a new player
            {
                // Check max registered number
                if (tcpPlayers.size() >= maxRegistered)
                {
                    logMessage("TCP: Registration failed, too much players registered");
                    socket->write(fileMaxRegistration.readAll());
                    ok = false;
                }
                else
                {
                    logMessage("TCP: Creating user in database");
                    Player newPlayer;
                    newPlayer.name = username;
                    newPlayer.passhash = passhash;
                    newPlayer.IP = socket->peerAddress().toString();
                    newPlayer.connected = false; // The connection checks are done by the game servers

                    tcpPlayers << newPlayer;
                    if (!Player::savePlayers(tcpPlayers))
                        ok = false;
                }
            }
            else // Found, compare passhashes, check if already connected
            {
                if (player.passhash != passhash) // Bad password
                {
                    logMessage("TCP: Login failed, wrong password");
                    socket->write(fileBadPassword.readAll());
                    ok=false;
                }
                /*
                else if (newPlayer.connected) // Already connected
                {
                    logMessage("TCP: Login failed, player already connected");
                    socket->write(fileAlready.readAll());
                    ok=false;
                }
                */
                else // Good password
                {
                    /*
                    // Check too many connected
                    int n=0;
                    for (int i=0;i<tcpPlayers.size();i++)
                        if (tcpPlayers[i].connected)
                            n++;
                    if (n>=maxConnected)
                    {
                        logMessage("TCP: Login failed, too much players connected");
                        socket->write(fileMaxConnected.readAll());
                        ok=false;
                    }
                    else
                    */
                    {
                        player.reset();
                        player.IP = socket->peerAddress().toString();
                        player.lastPingTime = timestampNow();
                        player.connected = true;
                    }
                }
            }

            if (ok) // Send servers list
            {
                QByteArray customData = file.readAll();

                QByteArray data1 = QByteArray::fromHex("0D0A61757468726573706F6E73653A0A747275650A");
                QByteArray sesskey = QCryptographicHash::hash(QString(passhash + saltPassword).toLatin1(), QCryptographicHash::Md5).toHex();
                sesskey += passhash;
                QByteArray data2 = QByteArray::fromHex("0A310A");
                QByteArray serversList;
                QByteArray line;
                do {
                    line = fileServersList.readLine().trimmed();
                    serversList+=line;
                    serversList+=0x0A;
                } while (!line.isEmpty());
                serversList = serversList.trimmed();
                QByteArray data3 = QByteArray::fromHex("0D0A300D0A0D0A");
                int dataSize = data1.size() + sesskey.size() + data2.size() + serversList.size() - 2;
                QString dataSizeStr = QString().setNum(dataSize, 16);

                customData += dataSizeStr;
                customData += data1;
                customData += sesskey;
                customData += data2;
                customData += serversList;
                customData += data3;

                logMessage("TCP: Login successful, sending servers list");
                socket->write(customData);
            }
        }
    }
    else if (data.contains("commfunction=removesession"))
    {
        logMessage("TCP: Session closed by client");
    }
    else // Unknown request, erase tcp buffer
    {
        // Display data
        logMessage("TCP: Unknow request received : ");
        logMessage(QString(data.data()));
    }

    // Delete the processed message from the buffer
    *tcpReceivedDatas = tcpReceivedDatas->right(tcpReceivedDatas->size() - tcpReceivedDatas->indexOf(data) - data.size());
}