diff --git a/cockatrice/src/remoteclient.cpp b/cockatrice/src/remoteclient.cpp index 04d88837..4f48c474 100644 --- a/cockatrice/src/remoteclient.cpp +++ b/cockatrice/src/remoteclient.cpp @@ -9,10 +9,10 @@ #include "pb/server_message.pb.h" #include "pb/event_server_identification.pb.h" -static const unsigned int protocolVersion = 13; +static const unsigned int protocolVersion = 14; RemoteClient::RemoteClient(QObject *parent) - : AbstractClient(parent), timeRunning(0), lastDataReceived(0), messageInProgress(false), messageLength(0) + : AbstractClient(parent), timeRunning(0), lastDataReceived(0), messageInProgress(false), handshakeStarted(false), messageLength(0) { timer = new QTimer(this); timer->setInterval(1000); @@ -47,6 +47,11 @@ void RemoteClient::slotConnected() { timeRunning = lastDataReceived = 0; timer->start(); + + // dirty hack to be compatible with v14 server + sendCommandContainer(CommandContainer()); + // end of hack + setStatus(StatusAwaitingWelcome); } @@ -54,7 +59,7 @@ void RemoteClient::processServerIdentificationEvent(const Event_ServerIdentifica { if (event.protocol_version() != protocolVersion) { emit protocolVersionMismatch(protocolVersion, event.protocol_version()); - setStatus(StatusDisconnected); + setStatus(StatusDisconnecting); return; } setStatus(StatusLoggingIn); @@ -105,12 +110,22 @@ void RemoteClient::readData() do { if (!messageInProgress) { if (inputBuffer.size() >= 4) { - messageLength = (((quint32) (unsigned char) inputBuffer[0]) << 24) - + (((quint32) (unsigned char) inputBuffer[1]) << 16) - + (((quint32) (unsigned char) inputBuffer[2]) << 8) - + ((quint32) (unsigned char) inputBuffer[3]); - inputBuffer.remove(0, 4); - messageInProgress = true; + // dirty hack to be compatible with v14 server that sends 60 bytes of garbage at the beginning + if (!handshakeStarted) { + handshakeStarted = true; + if (inputBuffer.startsWith("start(); } else { QTcpSocket *socket = new QTcpSocket; + ServerSocketInterface *ssi = new ServerSocketInterface(server, socket); socket->setSocketDescriptor(socketDescriptor); socket->setSocketOption(QAbstractSocket::LowDelayOption, 1); - ServerSocketInterface *ssi = new ServerSocketInterface(server, socket); logger->logMessage(QString("incoming connection: %1").arg(socket->peerAddress().toString()), ssi); + ssi->initSessionDeprecated(); } } diff --git a/servatrice/src/serversocketinterface.cpp b/servatrice/src/serversocketinterface.cpp index 7cc05630..6080b65c 100644 --- a/servatrice/src/serversocketinterface.cpp +++ b/servatrice/src/serversocketinterface.cpp @@ -57,40 +57,14 @@ #include #include -static const int protocolVersion = 13; +static const int protocolVersion = 14; ServerSocketInterface::ServerSocketInterface(Servatrice *_server, QTcpSocket *_socket, QObject *parent) - : Server_ProtocolHandler(_server, parent), servatrice(_server), socket(_socket), messageInProgress(false) + : Server_ProtocolHandler(_server, parent), servatrice(_server), socket(_socket), messageInProgress(false), handshakeStarted(false) { - bool success = true; - connect(socket, SIGNAL(readyRead()), this, SLOT(readClient())); connect(socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(catchSocketError(QAbstractSocket::SocketError))); connect(this, SIGNAL(outputBufferChanged()), this, SLOT(flushOutputBuffer()), Qt::QueuedConnection); - - Event_ServerIdentification identEvent; - identEvent.set_server_name(servatrice->getServerName().toStdString()); - identEvent.set_server_version(VERSION_STRING); - identEvent.set_protocol_version(protocolVersion); - SessionEvent *identSe = prepareSessionEvent(identEvent); - sendProtocolItem(*identSe); - delete identSe; - - int maxUsers = _server->getMaxUsersPerAddress(); - if ((maxUsers > 0) && (_server->getUsersWithAddress(socket->peerAddress()) >= maxUsers)) { - Event_ConnectionClosed event; - event.set_reason(Event_ConnectionClosed::TOO_MANY_CONNECTIONS); - SessionEvent *se = prepareSessionEvent(event); - sendProtocolItem(*se); - delete se; - - success = false; - } - - server->addClient(this); - - if (!success) - prepareDestroy(); } ServerSocketInterface::~ServerSocketInterface() @@ -102,6 +76,42 @@ ServerSocketInterface::~ServerSocketInterface() socket = 0; } +void ServerSocketInterface::initSessionDeprecated() +{ + // dirty hack to make v13 client display the correct error message + + outputBufferMutex.lock(); + outputBuffer = ""; + outputBufferMutex.unlock(); + + emit outputBufferChanged(); +} + +bool ServerSocketInterface::initSession() +{ + Event_ServerIdentification identEvent; + identEvent.set_server_name(servatrice->getServerName().toStdString()); + identEvent.set_server_version(VERSION_STRING); + identEvent.set_protocol_version(protocolVersion); + SessionEvent *identSe = prepareSessionEvent(identEvent); + sendProtocolItem(*identSe); + delete identSe; + + int maxUsers = servatrice->getMaxUsersPerAddress(); + if ((maxUsers > 0) && (servatrice->getUsersWithAddress(socket->peerAddress()) >= maxUsers)) { + Event_ConnectionClosed event; + event.set_reason(Event_ConnectionClosed::TOO_MANY_CONNECTIONS); + SessionEvent *se = prepareSessionEvent(event); + sendProtocolItem(*se); + delete se; + + return false; + } + + server->addClient(this); + return true; +} + void ServerSocketInterface::flushOutputBuffer() { QMutexLocker locker(&outputBufferMutex); @@ -139,7 +149,15 @@ void ServerSocketInterface::readClient() inputBuffer.remove(0, messageLength); messageInProgress = false; - processCommandContainer(newCommandContainer); + // dirty hack to make v13 client display the correct error message + if (handshakeStarted) + processCommandContainer(newCommandContainer); + else if (!newCommandContainer.has_cmd_id()) { + handshakeStarted = true; + if (!initSession()) + prepareDestroy(); + } + // end of hack } while (!inputBuffer.isEmpty()); } diff --git a/servatrice/src/serversocketinterface.h b/servatrice/src/serversocketinterface.h index 40b7e406..ed4b526c 100644 --- a/servatrice/src/serversocketinterface.h +++ b/servatrice/src/serversocketinterface.h @@ -63,6 +63,7 @@ private: QByteArray inputBuffer, outputBuffer; bool messageInProgress; + bool handshakeStarted; int messageLength; Response::ResponseCode cmdAddToList(const Command_AddToList &cmd, ResponseContainer &rc); @@ -92,6 +93,8 @@ private: public: ServerSocketInterface(Servatrice *_server, QTcpSocket *_socket, QObject *parent = 0); ~ServerSocketInterface(); + void initSessionDeprecated(); + bool initSession(); QHostAddress getPeerAddress() const { return socket->peerAddress(); } QString getAddress() const { return socket->peerAddress().toString(); }