aboutsummaryrefslogtreecommitdiff
path: root/src/TcpTasks/SyncClient/onsyncread.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/TcpTasks/SyncClient/onsyncread.cpp')
-rw-r--r--src/TcpTasks/SyncClient/onsyncread.cpp111
1 files changed, 111 insertions, 0 deletions
diff --git a/src/TcpTasks/SyncClient/onsyncread.cpp b/src/TcpTasks/SyncClient/onsyncread.cpp
new file mode 100644
index 0000000..c0f0b73
--- /dev/null
+++ b/src/TcpTasks/SyncClient/onsyncread.cpp
@@ -0,0 +1,111 @@
+#include "syncclient.h"
+
+void SyncClient::onSyncRead()
+{
+ // reset timeout after receiving (any) data
+ _timeOut.start();
+
+ // read from tcp connection and append to buffer
+ QByteArray receiveBuffer = _tcpSocket.readAll();
+ _rxBuffer.append( receiveBuffer );
+
+ // prevent large heaps of text -- log only relevant message, not masterserver data
+ if ( receiveBuffer.length() > 30 )
+ {
+ // log size of data
+ _coreObject->Log.logEvent("tcp", QStringLiteral("%1 sent %2 characters")
+ .arg(_clientLabel, QString::number(receiveBuffer.length()) ) );
+ }
+ else
+ {
+ // log message
+ _coreObject->Log.logEvent("tcp", QStringLiteral("%1 sent '%2'")
+ .arg(_clientLabel, receiveBuffer.data()) );
+ }
+
+ // remote masterserver opens with secure challenge
+ if ( _rxBuffer.contains("secure") )
+ {
+ // parse to hash
+ QMultiHash<QString, QString> receiveData = parseGameSpy0Buffer(_rxBuffer.toLatin1());
+
+ // generate response
+ QStringList response = replyQuery(receiveData);
+
+ // return response
+ _tcpSocket.write(response.join("").toLatin1());
+
+ // sync request
+ QString request = QStringLiteral("\\sync\\%1\\msid\\%2")
+ .arg(_coreObject->Settings.SyncerSettings.syncGames,
+ _coreObject->masterserverIdentity);
+ _tcpSocket.write(request.toLatin1());
+
+ // all relevant information received. clear buffer for next interaction
+ _rxBuffer = "";
+ return;
+ }
+
+ if ( _rxBuffer.contains("final") )
+ {
+ // parse to hash: receivedData format is {gamename} => {string of addresses}
+ QMultiHash<QString, QString> receiveData = parseGameSpy0Buffer(_rxBuffer.toLatin1());
+ receiveData.remove("final"); // prevent "final" from registering as gamename
+
+ // count number of addresses for logging
+ int totalServerCount = 0;
+
+ // use transaction for SQLite
+ QSqlDatabase::database().transaction();
+
+ // parse to list of list of <ServerInfo>
+ QHashIterator<QString,QString> receiveDataIterator(receiveData);
+ while ( receiveDataIterator.hasNext() )
+ {
+ // {gamename} => {string of addresses}
+ receiveDataIterator.next();
+ QString gamename = receiveDataIterator.key();
+ QString addressBufferList = receiveDataIterator.value();
+
+ // split address list in single addresses
+ QStringListIterator listIterator( addressBufferList.split(" ", QString::SkipEmptyParts) );
+ while ( listIterator.hasNext() )
+ {
+ // address (ip:port)
+ QString addr = listIterator.next();
+
+ // older Qt5 masterservers sync in ::ffff:127.0.0.1 format, trim the '::ffff:'
+ addr.remove("::ffff:");
+
+ // (address cont.)
+ QStringList address = addr.split(':');
+ unsigned short remotePort = address.takeLast().toUShort();
+ QString remoteAddr = address.join(":"); // IPv4 has only 1 element, IPv6 has 4 that need joining with ':'
+
+ // valid address?
+ if ( ! QHostAddress(remoteAddr).isNull() and remotePort > 0 )
+ {
+ // if it does not exist in the db, insert
+ if ( ! updateSyncedServer(remoteAddr, remotePort) )
+ {
+ // add
+ insertServer(remoteAddr, remotePort, gamename, false);
+ }
+ }
+ totalServerCount++;
+ } // has next address
+ } // has next game
+
+ // commit SQLite
+ QSqlDatabase::database().commit();
+
+ // report in log
+ _coreObject->Log.logEvent("sync", QStringLiteral("received %1 servers in %2 games from %3")
+ .arg( QString::number(totalServerCount),
+ QString::number(receiveData.count()),
+ _clientLabel)
+ );
+ } // if final
+
+ // else keep appending data until \\final\\ is received
+}