fixed issue #42: make 'client deprecated' message work for v13 client <-> v14 server
This commit is contained in:
parent
f7975d8ace
commit
b9087715bf
7 changed files with 81 additions and 47 deletions
|
@ -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("<?xm")) {
|
||||
messageInProgress = true;
|
||||
messageLength = 60;
|
||||
}
|
||||
} else {
|
||||
// end of hack
|
||||
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;
|
||||
}
|
||||
} else
|
||||
return;
|
||||
}
|
||||
|
@ -126,10 +141,10 @@ void RemoteClient::readData()
|
|||
messageInProgress = false;
|
||||
|
||||
processProtocolItem(newServerMessage);
|
||||
} while (!inputBuffer.isEmpty());
|
||||
|
||||
if (getStatus() == StatusDisconnecting) // use thread-safe getter
|
||||
doDisconnectFromServer();
|
||||
if (getStatus() == StatusDisconnecting) // use thread-safe getter
|
||||
doDisconnectFromServer();
|
||||
} while (!inputBuffer.isEmpty());
|
||||
}
|
||||
|
||||
void RemoteClient::sendCommandContainer(const CommandContainer &cont)
|
||||
|
|
|
@ -33,6 +33,7 @@ private:
|
|||
|
||||
QByteArray inputBuffer;
|
||||
bool messageInProgress;
|
||||
bool handshakeStarted;
|
||||
int messageLength;
|
||||
|
||||
QTimer *timer;
|
||||
|
|
|
@ -1,4 +0,0 @@
|
|||
[Dolphin]
|
||||
Timestamp=2012,3,4,11,22,24
|
||||
Version=2
|
||||
ViewMode=1
|
|
@ -5,7 +5,7 @@ import "moderator_commands.proto";
|
|||
import "admin_commands.proto";
|
||||
|
||||
message CommandContainer {
|
||||
required uint64 cmd_id = 1;
|
||||
optional uint64 cmd_id = 1;
|
||||
|
||||
optional uint32 game_id = 10;
|
||||
optional uint32 room_id = 20;
|
||||
|
|
|
@ -43,10 +43,11 @@ void Servatrice_GameServer::incomingConnection(int socketDescriptor)
|
|||
sst->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();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -57,40 +57,14 @@
|
|||
#include <string>
|
||||
#include <iostream>
|
||||
|
||||
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 = "<?xml version=\"1.0\"?><cockatrice_server_stream version=\"14\">";
|
||||
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());
|
||||
}
|
||||
|
||||
|
|
|
@ -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(); }
|
||||
|
||||
|
|
Loading…
Reference in a new issue