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())); } }
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()); }