renamed servernetwork to ISL (inter-server link), join/leave is working
This commit is contained in:
parent
dda78661ea
commit
5963c2239c
9 changed files with 155 additions and 78 deletions
|
@ -102,6 +102,7 @@ SET(PROTO_FILES
|
||||||
game_event_context.proto
|
game_event_context.proto
|
||||||
game_event.proto
|
game_event.proto
|
||||||
game_replay.proto
|
game_replay.proto
|
||||||
|
isl_message.proto
|
||||||
moderator_commands.proto
|
moderator_commands.proto
|
||||||
move_card_to_zone.proto
|
move_card_to_zone.proto
|
||||||
response_deck_download.proto
|
response_deck_download.proto
|
||||||
|
@ -133,7 +134,6 @@ SET(PROTO_FILES
|
||||||
serverinfo_room.proto
|
serverinfo_room.proto
|
||||||
serverinfo_user.proto
|
serverinfo_user.proto
|
||||||
serverinfo_zone.proto
|
serverinfo_zone.proto
|
||||||
servernetwork_message.proto
|
|
||||||
server_message.proto
|
server_message.proto
|
||||||
session_commands.proto
|
session_commands.proto
|
||||||
session_event.proto
|
session_event.proto
|
||||||
|
|
|
@ -4,7 +4,7 @@ import "commands.proto";
|
||||||
import "game_event_container.proto";
|
import "game_event_container.proto";
|
||||||
import "room_event.proto";
|
import "room_event.proto";
|
||||||
|
|
||||||
message ServerNetworkMessage {
|
message IslMessage {
|
||||||
enum MessageType {
|
enum MessageType {
|
||||||
RESPONSE = 0;
|
RESPONSE = 0;
|
||||||
SESSION_EVENT = 1;
|
SESSION_EVENT = 1;
|
|
@ -25,6 +25,8 @@
|
||||||
#include "pb/event_user_joined.pb.h"
|
#include "pb/event_user_joined.pb.h"
|
||||||
#include "pb/event_user_left.pb.h"
|
#include "pb/event_user_left.pb.h"
|
||||||
#include "pb/event_list_rooms.pb.h"
|
#include "pb/event_list_rooms.pb.h"
|
||||||
|
#include "pb/session_event.pb.h"
|
||||||
|
#include "pb/isl_message.pb.h"
|
||||||
#include <QCoreApplication>
|
#include <QCoreApplication>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
|
||||||
|
@ -98,6 +100,9 @@ AuthenticationResult Server::loginUser(Server_ProtocolHandler *session, QString
|
||||||
for (int i = 0; i < clients.size(); ++i)
|
for (int i = 0; i < clients.size(); ++i)
|
||||||
if (clients[i]->getAcceptsUserListChanges())
|
if (clients[i]->getAcceptsUserListChanges())
|
||||||
clients[i]->sendProtocolItem(*se);
|
clients[i]->sendProtocolItem(*se);
|
||||||
|
serverMutex.unlock();
|
||||||
|
|
||||||
|
sendIslMessage(*se);
|
||||||
delete se;
|
delete se;
|
||||||
|
|
||||||
return authState;
|
return authState;
|
||||||
|
@ -121,6 +126,7 @@ void Server::removeClient(Server_ProtocolHandler *client)
|
||||||
for (int i = 0; i < clients.size(); ++i)
|
for (int i = 0; i < clients.size(); ++i)
|
||||||
if (clients[i]->getAcceptsUserListChanges())
|
if (clients[i]->getAcceptsUserListChanges())
|
||||||
clients[i]->sendProtocolItem(*se);
|
clients[i]->sendProtocolItem(*se);
|
||||||
|
sendIslMessage(*se);
|
||||||
delete se;
|
delete se;
|
||||||
|
|
||||||
users.remove(QString::fromStdString(data->name()));
|
users.remove(QString::fromStdString(data->name()));
|
||||||
|
@ -177,3 +183,12 @@ int Server::getGamesCount() const
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Server::sendIslMessage(const SessionEvent &item, int serverId)
|
||||||
|
{
|
||||||
|
IslMessage msg;
|
||||||
|
msg.set_message_type(IslMessage::SESSION_EVENT);
|
||||||
|
msg.mutable_session_event()->CopyFrom(item);
|
||||||
|
|
||||||
|
doSendIslMessage(msg, serverId);
|
||||||
|
}
|
||||||
|
|
|
@ -11,6 +11,8 @@ class Server_Game;
|
||||||
class Server_Room;
|
class Server_Room;
|
||||||
class Server_ProtocolHandler;
|
class Server_ProtocolHandler;
|
||||||
class GameReplay;
|
class GameReplay;
|
||||||
|
class IslMessage;
|
||||||
|
class SessionEvent;
|
||||||
|
|
||||||
enum AuthenticationResult { NotLoggedIn = 0, PasswordRight = 1, UnknownUser = 2, WouldOverwriteOldSession = 3, UserIsBanned = 4 };
|
enum AuthenticationResult { NotLoggedIn = 0, PasswordRight = 1, UnknownUser = 2, WouldOverwriteOldSession = 3, UserIsBanned = 4 };
|
||||||
|
|
||||||
|
@ -50,6 +52,8 @@ public:
|
||||||
virtual bool isInIgnoreList(const QString &whoseList, const QString &who) { return false; }
|
virtual bool isInIgnoreList(const QString &whoseList, const QString &who) { return false; }
|
||||||
|
|
||||||
virtual void storeGameInformation(int secondsElapsed, const QSet<QString> &allPlayersEver, const QSet<QString> &allSpectatorsEver, const QList<GameReplay *> &replays) { }
|
virtual void storeGameInformation(int secondsElapsed, const QSet<QString> &allPlayersEver, const QSet<QString> &allSpectatorsEver, const QList<GameReplay *> &replays) { }
|
||||||
|
|
||||||
|
void sendIslMessage(const SessionEvent &item, int serverId = -1);
|
||||||
protected:
|
protected:
|
||||||
void prepareDestroy();
|
void prepareDestroy();
|
||||||
QList<Server_ProtocolHandler *> clients;
|
QList<Server_ProtocolHandler *> clients;
|
||||||
|
@ -70,6 +74,8 @@ protected:
|
||||||
virtual void lockSessionTables() { }
|
virtual void lockSessionTables() { }
|
||||||
virtual void unlockSessionTables() { }
|
virtual void unlockSessionTables() { }
|
||||||
virtual bool userSessionExists(const QString &userName) { return false; }
|
virtual bool userSessionExists(const QString &userName) { return false; }
|
||||||
|
|
||||||
|
virtual void doSendIslMessage(const IslMessage &msg, int serverId) { }
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -9,7 +9,7 @@ SET(servatrice_SOURCES
|
||||||
src/server_logger.cpp
|
src/server_logger.cpp
|
||||||
src/serversocketinterface.cpp
|
src/serversocketinterface.cpp
|
||||||
src/serversocketthread.cpp
|
src/serversocketthread.cpp
|
||||||
src/networkserverinterface.cpp
|
src/isl_interface.cpp
|
||||||
${CMAKE_CURRENT_BINARY_DIR}/version_string.cpp
|
${CMAKE_CURRENT_BINARY_DIR}/version_string.cpp
|
||||||
)
|
)
|
||||||
SET(servatrice_HEADERS
|
SET(servatrice_HEADERS
|
||||||
|
@ -17,7 +17,7 @@ SET(servatrice_HEADERS
|
||||||
src/server_logger.h
|
src/server_logger.h
|
||||||
src/serversocketinterface.h
|
src/serversocketinterface.h
|
||||||
src/serversocketthread.h
|
src/serversocketthread.h
|
||||||
src/networkserverinterface.h
|
src/isl_interface.h
|
||||||
)
|
)
|
||||||
|
|
||||||
SET(QT_DONTUSE_QTGUI)
|
SET(QT_DONTUSE_QTGUI)
|
||||||
|
|
|
@ -1,50 +1,49 @@
|
||||||
#include "networkserverinterface.h"
|
#include "isl_interface.h"
|
||||||
#include <QSslSocket>
|
#include <QSslSocket>
|
||||||
#include "server_logger.h"
|
#include "server_logger.h"
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "server_protocolhandler.h"
|
#include "server_protocolhandler.h"
|
||||||
#include "server_room.h"
|
#include "server_room.h"
|
||||||
|
|
||||||
#include "pb/servernetwork_message.pb.h"
|
#include "pb/isl_message.pb.h"
|
||||||
#include "pb/event_server_complete_list.pb.h"
|
#include "pb/event_server_complete_list.pb.h"
|
||||||
#include <google/protobuf/descriptor.h>
|
#include <google/protobuf/descriptor.h>
|
||||||
|
|
||||||
void NetworkServerInterface::sharedCtor(const QSslCertificate &cert, const QSslKey &privateKey)
|
void IslInterface::sharedCtor(const QSslCertificate &cert, const QSslKey &privateKey)
|
||||||
{
|
{
|
||||||
socket = new QSslSocket(this);
|
socket = new QSslSocket(this);
|
||||||
socket->setLocalCertificate(cert);
|
socket->setLocalCertificate(cert);
|
||||||
socket->setPrivateKey(privateKey);
|
socket->setPrivateKey(privateKey);
|
||||||
|
|
||||||
connect(socket, SIGNAL(readyRead()), this, SLOT(readClient()));
|
connect(socket, SIGNAL(readyRead()), this, SLOT(readClient()));
|
||||||
connect(socket, SIGNAL(disconnected()), this, SLOT(deleteLater()));
|
|
||||||
connect(socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(catchSocketError(QAbstractSocket::SocketError)));
|
connect(socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(catchSocketError(QAbstractSocket::SocketError)));
|
||||||
connect(this, SIGNAL(outputBufferChanged()), this, SLOT(flushOutputBuffer()), Qt::QueuedConnection);
|
connect(this, SIGNAL(outputBufferChanged()), this, SLOT(flushOutputBuffer()), Qt::QueuedConnection);
|
||||||
}
|
}
|
||||||
|
|
||||||
NetworkServerInterface::NetworkServerInterface(int _socketDescriptor, const QSslCertificate &cert, const QSslKey &privateKey, Servatrice *_server)
|
IslInterface::IslInterface(int _socketDescriptor, const QSslCertificate &cert, const QSslKey &privateKey, Servatrice *_server)
|
||||||
: QObject(), socketDescriptor(_socketDescriptor), server(_server), messageInProgress(false)
|
: QObject(), socketDescriptor(_socketDescriptor), server(_server), messageInProgress(false)
|
||||||
{
|
{
|
||||||
sharedCtor(cert, privateKey);
|
sharedCtor(cert, privateKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
NetworkServerInterface::NetworkServerInterface(const QString &_peerHostName, const QString &_peerAddress, int _peerPort, const QSslCertificate &_peerCert, const QSslCertificate &cert, const QSslKey &privateKey, Servatrice *_server)
|
IslInterface::IslInterface(int _serverId, const QString &_peerHostName, const QString &_peerAddress, int _peerPort, const QSslCertificate &_peerCert, const QSslCertificate &cert, const QSslKey &privateKey, Servatrice *_server)
|
||||||
: QObject(), peerHostName(_peerHostName), peerAddress(_peerAddress), peerPort(_peerPort), peerCert(_peerCert), server(_server), messageInProgress(false)
|
: QObject(), serverId(_serverId), peerHostName(_peerHostName), peerAddress(_peerAddress), peerPort(_peerPort), peerCert(_peerCert), server(_server), messageInProgress(false)
|
||||||
{
|
{
|
||||||
sharedCtor(cert, privateKey);
|
sharedCtor(cert, privateKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
NetworkServerInterface::~NetworkServerInterface()
|
IslInterface::~IslInterface()
|
||||||
{
|
{
|
||||||
logger->logMessage("[SN] session ended", this);
|
logger->logMessage("[ISL] session ended", this);
|
||||||
|
|
||||||
flushOutputBuffer();
|
flushOutputBuffer();
|
||||||
}
|
}
|
||||||
|
|
||||||
void NetworkServerInterface::initServer()
|
void IslInterface::initServer()
|
||||||
{
|
{
|
||||||
socket->setSocketDescriptor(socketDescriptor);
|
socket->setSocketDescriptor(socketDescriptor);
|
||||||
|
|
||||||
logger->logMessage(QString("[SN] incoming connection: %1").arg(socket->peerAddress().toString()));
|
logger->logMessage(QString("[ISL] incoming connection: %1").arg(socket->peerAddress().toString()));
|
||||||
|
|
||||||
QList<ServerProperties> serverList = server->getServerList();
|
QList<ServerProperties> serverList = server->getServerList();
|
||||||
int listIndex = -1;
|
int listIndex = -1;
|
||||||
|
@ -54,7 +53,7 @@ void NetworkServerInterface::initServer()
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (listIndex == -1) {
|
if (listIndex == -1) {
|
||||||
logger->logMessage(QString("[SN] address %1 unknown, terminating connection").arg(socket->peerAddress().toString()));
|
logger->logMessage(QString("[ISL] address %1 unknown, terminating connection").arg(socket->peerAddress().toString()));
|
||||||
deleteLater();
|
deleteLater();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -63,20 +62,21 @@ void NetworkServerInterface::initServer()
|
||||||
if (!socket->waitForEncrypted(5000)) {
|
if (!socket->waitForEncrypted(5000)) {
|
||||||
QList<QSslError> sslErrors(socket->sslErrors());
|
QList<QSslError> sslErrors(socket->sslErrors());
|
||||||
if (sslErrors.isEmpty())
|
if (sslErrors.isEmpty())
|
||||||
qDebug() << "[SN] SSL handshake timeout, terminating connection";
|
qDebug() << "[ISL] SSL handshake timeout, terminating connection";
|
||||||
else
|
else
|
||||||
qDebug() << "[SN] SSL errors:" << sslErrors;
|
qDebug() << "[ISL] SSL errors:" << sslErrors;
|
||||||
deleteLater();
|
deleteLater();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (serverList[listIndex].cert == socket->peerCertificate())
|
if (serverList[listIndex].cert == socket->peerCertificate())
|
||||||
logger->logMessage(QString("[SN] Peer authenticated as " + serverList[listIndex].hostname));
|
logger->logMessage(QString("[ISL] Peer authenticated as " + serverList[listIndex].hostname));
|
||||||
else {
|
else {
|
||||||
logger->logMessage(QString("[SN] Authentication failed, terminating connection"));
|
logger->logMessage(QString("[ISL] Authentication failed, terminating connection"));
|
||||||
deleteLater();
|
deleteLater();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
serverId = serverList[listIndex].id;
|
||||||
|
|
||||||
Event_ServerCompleteList event;
|
Event_ServerCompleteList event;
|
||||||
event.set_server_id(server->getServerId());
|
event.set_server_id(server->getServerId());
|
||||||
|
@ -93,13 +93,20 @@ void NetworkServerInterface::initServer()
|
||||||
event.add_room_list()->CopyFrom(room->getInfo(true, true, false));
|
event.add_room_list()->CopyFrom(room->getInfo(true, true, false));
|
||||||
}
|
}
|
||||||
|
|
||||||
ServerNetworkMessage message;
|
IslMessage message;
|
||||||
message.set_message_type(ServerNetworkMessage::SESSION_EVENT);
|
message.set_message_type(IslMessage::SESSION_EVENT);
|
||||||
SessionEvent *sessionEvent = message.mutable_session_event();
|
SessionEvent *sessionEvent = message.mutable_session_event();
|
||||||
sessionEvent->GetReflection()->MutableMessage(sessionEvent, event.GetDescriptor()->FindExtensionByName("ext"))->CopyFrom(event);
|
sessionEvent->GetReflection()->MutableMessage(sessionEvent, event.GetDescriptor()->FindExtensionByName("ext"))->CopyFrom(event);
|
||||||
transmitMessage(message);
|
|
||||||
|
|
||||||
server->addNetworkServerInterface(this);
|
server->islLock.lockForWrite();
|
||||||
|
if (server->islConnectionExists(serverId)) {
|
||||||
|
qDebug() << "[ISL] Duplicate connection to #" << serverId << "terminating connection";
|
||||||
|
deleteLater();
|
||||||
|
} else {
|
||||||
|
transmitMessage(message);
|
||||||
|
server->addIslInterface(serverId, this);
|
||||||
|
}
|
||||||
|
server->islLock.unlock();
|
||||||
|
|
||||||
roomIterator.toFront();
|
roomIterator.toFront();
|
||||||
while (roomIterator.hasNext())
|
while (roomIterator.hasNext())
|
||||||
|
@ -107,33 +114,42 @@ void NetworkServerInterface::initServer()
|
||||||
server->serverMutex.unlock();
|
server->serverMutex.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
void NetworkServerInterface::initClient()
|
void IslInterface::initClient()
|
||||||
{
|
{
|
||||||
QList<QSslError> expectedErrors;
|
QList<QSslError> expectedErrors;
|
||||||
expectedErrors.append(QSslError(QSslError::SelfSignedCertificate, peerCert));
|
expectedErrors.append(QSslError(QSslError::SelfSignedCertificate, peerCert));
|
||||||
socket->ignoreSslErrors(expectedErrors);
|
socket->ignoreSslErrors(expectedErrors);
|
||||||
|
|
||||||
qDebug() << "[SN] Connecting to " << peerAddress << ":" << peerPort;
|
qDebug() << "[ISL] Connecting to #" << serverId << ":" << peerAddress << ":" << peerPort;
|
||||||
|
|
||||||
socket->connectToHostEncrypted(peerAddress, peerPort, peerHostName);
|
socket->connectToHostEncrypted(peerAddress, peerPort, peerHostName);
|
||||||
if (!socket->waitForConnected(5000)) {
|
if (!socket->waitForConnected(5000)) {
|
||||||
qDebug() << "[SN] Socket error:" << socket->errorString();
|
qDebug() << "[ISL] Socket error:" << socket->errorString();
|
||||||
deleteLater();
|
deleteLater();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!socket->waitForEncrypted(5000)) {
|
if (!socket->waitForEncrypted(5000)) {
|
||||||
QList<QSslError> sslErrors(socket->sslErrors());
|
QList<QSslError> sslErrors(socket->sslErrors());
|
||||||
if (sslErrors.isEmpty())
|
if (sslErrors.isEmpty())
|
||||||
qDebug() << "[SN] SSL handshake timeout, terminating connection";
|
qDebug() << "[ISL] SSL handshake timeout, terminating connection";
|
||||||
else
|
else
|
||||||
qDebug() << "[SN] SSL errors:" << sslErrors;
|
qDebug() << "[ISL] SSL errors:" << sslErrors;
|
||||||
deleteLater();
|
deleteLater();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
server->addNetworkServerInterface(this);
|
|
||||||
|
server->islLock.lockForWrite();
|
||||||
|
if (server->islConnectionExists(serverId)) {
|
||||||
|
qDebug() << "[ISL] Duplicate connection to #" << serverId << "terminating connection";
|
||||||
|
deleteLater();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
server->addIslInterface(serverId, this);
|
||||||
|
server->islLock.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
void NetworkServerInterface::flushOutputBuffer()
|
void IslInterface::flushOutputBuffer()
|
||||||
{
|
{
|
||||||
QMutexLocker locker(&outputBufferMutex);
|
QMutexLocker locker(&outputBufferMutex);
|
||||||
if (outputBuffer.isEmpty())
|
if (outputBuffer.isEmpty())
|
||||||
|
@ -144,7 +160,7 @@ void NetworkServerInterface::flushOutputBuffer()
|
||||||
outputBuffer.clear();
|
outputBuffer.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void NetworkServerInterface::readClient()
|
void IslInterface::readClient()
|
||||||
{
|
{
|
||||||
QByteArray data = socket->readAll();
|
QByteArray data = socket->readAll();
|
||||||
server->incRxBytes(data.size());
|
server->incRxBytes(data.size());
|
||||||
|
@ -165,7 +181,7 @@ void NetworkServerInterface::readClient()
|
||||||
if (inputBuffer.size() < messageLength)
|
if (inputBuffer.size() < messageLength)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ServerNetworkMessage newMessage;
|
IslMessage newMessage;
|
||||||
newMessage.ParseFromArray(inputBuffer.data(), messageLength);
|
newMessage.ParseFromArray(inputBuffer.data(), messageLength);
|
||||||
inputBuffer.remove(0, messageLength);
|
inputBuffer.remove(0, messageLength);
|
||||||
messageInProgress = false;
|
messageInProgress = false;
|
||||||
|
@ -174,14 +190,18 @@ void NetworkServerInterface::readClient()
|
||||||
} while (!inputBuffer.isEmpty());
|
} while (!inputBuffer.isEmpty());
|
||||||
}
|
}
|
||||||
|
|
||||||
void NetworkServerInterface::catchSocketError(QAbstractSocket::SocketError socketError)
|
void IslInterface::catchSocketError(QAbstractSocket::SocketError socketError)
|
||||||
{
|
{
|
||||||
qDebug() << "[SN] Socket error:" << socketError;
|
qDebug() << "[ISL] Socket error:" << socketError;
|
||||||
|
|
||||||
|
server->islLock.lockForWrite();
|
||||||
|
server->removeIslInterface(serverId);
|
||||||
|
server->islLock.unlock();
|
||||||
|
|
||||||
deleteLater();
|
deleteLater();
|
||||||
}
|
}
|
||||||
|
|
||||||
void NetworkServerInterface::transmitMessage(const ServerNetworkMessage &item)
|
void IslInterface::transmitMessage(const IslMessage &item)
|
||||||
{
|
{
|
||||||
QByteArray buf;
|
QByteArray buf;
|
||||||
unsigned int size = item.ByteSize();
|
unsigned int size = item.ByteSize();
|
||||||
|
@ -198,7 +218,7 @@ void NetworkServerInterface::transmitMessage(const ServerNetworkMessage &item)
|
||||||
emit outputBufferChanged();
|
emit outputBufferChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
void NetworkServerInterface::processMessage(const ServerNetworkMessage &item)
|
void IslInterface::processMessage(const IslMessage &item)
|
||||||
{
|
{
|
||||||
qDebug() << QString::fromStdString(item.DebugString());
|
qDebug() << QString::fromStdString(item.DebugString());
|
||||||
}
|
}
|
|
@ -1,16 +1,16 @@
|
||||||
#ifndef NETWORKSERVERINTERFACE_H
|
#ifndef ISL_INTERFACE_H
|
||||||
#define NETWORKSERVERINTERFACE_H
|
#define ISL_INTERFACE_H
|
||||||
|
|
||||||
#include "servatrice.h"
|
#include "servatrice.h"
|
||||||
#include <QSslCertificate>
|
#include <QSslCertificate>
|
||||||
#include <QSslKey>
|
|
||||||
#include <QWaitCondition>
|
#include <QWaitCondition>
|
||||||
|
|
||||||
class Servatrice;
|
class Servatrice;
|
||||||
class QSslSocket;
|
class QSslSocket;
|
||||||
class ServerNetworkMessage;
|
class QSslKey;
|
||||||
|
class IslMessage;
|
||||||
|
|
||||||
class NetworkServerInterface : public QObject {
|
class IslInterface : public QObject {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
private slots:
|
private slots:
|
||||||
void readClient();
|
void readClient();
|
||||||
|
@ -19,6 +19,7 @@ private slots:
|
||||||
signals:
|
signals:
|
||||||
void outputBufferChanged();
|
void outputBufferChanged();
|
||||||
private:
|
private:
|
||||||
|
int serverId;
|
||||||
int socketDescriptor;
|
int socketDescriptor;
|
||||||
QString peerHostName, peerAddress;
|
QString peerHostName, peerAddress;
|
||||||
int peerPort;
|
int peerPort;
|
||||||
|
@ -32,17 +33,17 @@ private:
|
||||||
bool messageInProgress;
|
bool messageInProgress;
|
||||||
int messageLength;
|
int messageLength;
|
||||||
|
|
||||||
void processMessage(const ServerNetworkMessage &item);
|
void processMessage(const IslMessage &item);
|
||||||
void sharedCtor(const QSslCertificate &cert, const QSslKey &privateKey);
|
void sharedCtor(const QSslCertificate &cert, const QSslKey &privateKey);
|
||||||
public slots:
|
public slots:
|
||||||
void initServer();
|
void initServer();
|
||||||
void initClient();
|
void initClient();
|
||||||
public:
|
public:
|
||||||
NetworkServerInterface(int socketDescriptor, const QSslCertificate &cert, const QSslKey &privateKey, Servatrice *_server);
|
IslInterface(int socketDescriptor, const QSslCertificate &cert, const QSslKey &privateKey, Servatrice *_server);
|
||||||
NetworkServerInterface(const QString &peerHostName, const QString &peerAddress, int peerPort, const QSslCertificate &peerCert, const QSslCertificate &cert, const QSslKey &privateKey, Servatrice *_server);
|
IslInterface(int _serverId, const QString &peerHostName, const QString &peerAddress, int peerPort, const QSslCertificate &peerCert, const QSslCertificate &cert, const QSslKey &privateKey, Servatrice *_server);
|
||||||
~NetworkServerInterface();
|
~IslInterface();
|
||||||
|
|
||||||
void transmitMessage(const ServerNetworkMessage &item);
|
void transmitMessage(const IslMessage &item);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -25,7 +25,7 @@
|
||||||
#include "server_room.h"
|
#include "server_room.h"
|
||||||
#include "serversocketinterface.h"
|
#include "serversocketinterface.h"
|
||||||
#include "serversocketthread.h"
|
#include "serversocketthread.h"
|
||||||
#include "networkserverinterface.h"
|
#include "isl_interface.h"
|
||||||
#include "server_logger.h"
|
#include "server_logger.h"
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "passwordhasher.h"
|
#include "passwordhasher.h"
|
||||||
|
@ -48,12 +48,12 @@ void Servatrice_GameServer::incomingConnection(int socketDescriptor)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Servatrice_NetworkServer::incomingConnection(int socketDescriptor)
|
void Servatrice_IslServer::incomingConnection(int socketDescriptor)
|
||||||
{
|
{
|
||||||
QThread *thread = new QThread;
|
QThread *thread = new QThread;
|
||||||
connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
|
connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
|
||||||
|
|
||||||
NetworkServerInterface *interface = new NetworkServerInterface(socketDescriptor, cert, privateKey, server);
|
IslInterface *interface = new IslInterface(socketDescriptor, cert, privateKey, server);
|
||||||
interface->moveToThread(thread);
|
interface->moveToThread(thread);
|
||||||
connect(interface, SIGNAL(destroyed()), thread, SLOT(quit()));
|
connect(interface, SIGNAL(destroyed()), thread, SLOT(quit()));
|
||||||
|
|
||||||
|
@ -122,7 +122,7 @@ Servatrice::Servatrice(QSettings *_settings, QObject *parent)
|
||||||
maxGamesPerUser = settings->value("security/max_games_per_user").toInt();
|
maxGamesPerUser = settings->value("security/max_games_per_user").toInt();
|
||||||
|
|
||||||
try { if (settings->value("servernetwork/active", 0).toInt()) {
|
try { if (settings->value("servernetwork/active", 0).toInt()) {
|
||||||
qDebug() << "Connecting to server network.";
|
qDebug() << "Connecting to ISL network.";
|
||||||
const QString certFileName = settings->value("servernetwork/ssl_cert").toString();
|
const QString certFileName = settings->value("servernetwork/ssl_cert").toString();
|
||||||
const QString keyFileName = settings->value("servernetwork/ssl_key").toString();
|
const QString keyFileName = settings->value("servernetwork/ssl_key").toString();
|
||||||
qDebug() << "Loading certificate...";
|
qDebug() << "Loading certificate...";
|
||||||
|
@ -140,15 +140,6 @@ Servatrice::Servatrice(QSettings *_settings, QObject *parent)
|
||||||
if (key.isNull())
|
if (key.isNull())
|
||||||
throw QString("Invalid private key.");
|
throw QString("Invalid private key.");
|
||||||
|
|
||||||
const int networkPort = settings->value("servernetwork/port", 14747).toInt();
|
|
||||||
qDebug() << "Starting network server on port" << networkPort;
|
|
||||||
|
|
||||||
networkServer = new Servatrice_NetworkServer(this, cert, key, this);
|
|
||||||
if (networkServer->listen(QHostAddress::Any, networkPort))
|
|
||||||
qDebug() << "Network server listening.";
|
|
||||||
else
|
|
||||||
throw QString("networkServer->listen(): Error.");
|
|
||||||
|
|
||||||
QMutableListIterator<ServerProperties> serverIterator(serverList);
|
QMutableListIterator<ServerProperties> serverIterator(serverList);
|
||||||
while (serverIterator.hasNext()) {
|
while (serverIterator.hasNext()) {
|
||||||
const ServerProperties &prop = serverIterator.next();
|
const ServerProperties &prop = serverIterator.next();
|
||||||
|
@ -160,7 +151,7 @@ Servatrice::Servatrice(QSettings *_settings, QObject *parent)
|
||||||
QThread *thread = new QThread;
|
QThread *thread = new QThread;
|
||||||
connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
|
connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
|
||||||
|
|
||||||
NetworkServerInterface *interface = new NetworkServerInterface(prop.hostname, prop.address.toString(), prop.controlPort, prop.cert, cert, key, this);
|
IslInterface *interface = new IslInterface(prop.id, prop.hostname, prop.address.toString(), prop.controlPort, prop.cert, cert, key, this);
|
||||||
interface->moveToThread(thread);
|
interface->moveToThread(thread);
|
||||||
connect(interface, SIGNAL(destroyed()), thread, SLOT(quit()));
|
connect(interface, SIGNAL(destroyed()), thread, SLOT(quit()));
|
||||||
|
|
||||||
|
@ -168,6 +159,15 @@ Servatrice::Servatrice(QSettings *_settings, QObject *parent)
|
||||||
QMetaObject::invokeMethod(interface, "initClient", Qt::BlockingQueuedConnection);
|
QMetaObject::invokeMethod(interface, "initClient", Qt::BlockingQueuedConnection);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const int networkPort = settings->value("servernetwork/port", 14747).toInt();
|
||||||
|
qDebug() << "Starting ISL server on port" << networkPort;
|
||||||
|
|
||||||
|
islServer = new Servatrice_IslServer(this, cert, key, this);
|
||||||
|
if (islServer->listen(QHostAddress::Any, networkPort))
|
||||||
|
qDebug() << "ISL server listening.";
|
||||||
|
else
|
||||||
|
throw QString("islServer->listen(): Error.");
|
||||||
|
|
||||||
} } catch (QString error) {
|
} } catch (QString error) {
|
||||||
qDebug() << "ERROR --" << error;
|
qDebug() << "ERROR --" << error;
|
||||||
}
|
}
|
||||||
|
@ -556,8 +556,9 @@ int Servatrice::startSession(const QString &userName, const QString &address)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
QSqlQuery query;
|
QSqlQuery query;
|
||||||
query.prepare("insert into " + dbPrefix + "_sessions (user_name, ip_address, start_time) values(:user_name, :ip_address, NOW())");
|
query.prepare("insert into " + dbPrefix + "_sessions (user_name, id_server, ip_address, start_time) values(:user_name, :id_server, :ip_address, NOW())");
|
||||||
query.bindValue(":user_name", userName);
|
query.bindValue(":user_name", userName);
|
||||||
|
query.bindValue(":id_server", serverId);
|
||||||
query.bindValue(":ip_address", address);
|
query.bindValue(":ip_address", address);
|
||||||
if (execSqlQuery(query))
|
if (execSqlQuery(query))
|
||||||
return query.lastInsertId().toInt();
|
return query.lastInsertId().toInt();
|
||||||
|
@ -574,7 +575,7 @@ void Servatrice::endSession(int sessionId)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
QSqlQuery query;
|
QSqlQuery query;
|
||||||
query.exec("lock tables " + dbPrefix + "_sessions read");
|
query.exec("lock tables " + dbPrefix + "_sessions write");
|
||||||
query.prepare("update " + dbPrefix + "_sessions set end_time=NOW() where id = :id_session");
|
query.prepare("update " + dbPrefix + "_sessions set end_time=NOW() where id = :id_session");
|
||||||
query.bindValue(":id_session", sessionId);
|
query.bindValue(":id_session", sessionId);
|
||||||
execSqlQuery(query);
|
execSqlQuery(query);
|
||||||
|
@ -839,13 +840,42 @@ void Servatrice::shutdownTimeout()
|
||||||
deleteLater();
|
deleteLater();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Servatrice::addNetworkServerInterface(NetworkServerInterface *interface)
|
bool Servatrice::islConnectionExists(int serverId) const
|
||||||
{
|
{
|
||||||
networkServerInterfaces.append(interface);
|
// Only call with islLock locked at least for reading
|
||||||
|
|
||||||
|
return islInterfaces.contains(serverId);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Servatrice::removeNetworkServerInterface(NetworkServerInterface *interface)
|
void Servatrice::addIslInterface(int serverId, IslInterface *interface)
|
||||||
{
|
{
|
||||||
// XXX we probably need to delete everything that belonged to it...
|
// Only call with islLock locked for writing
|
||||||
networkServerInterfaces.removeAt(networkServerInterfaces.indexOf(interface));
|
|
||||||
|
islInterfaces.insert(serverId, interface);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Servatrice::removeIslInterface(int serverId)
|
||||||
|
{
|
||||||
|
// Only call with islLock locked for writing
|
||||||
|
|
||||||
|
// XXX we probably need to delete everything that belonged to it...
|
||||||
|
islInterfaces.remove(serverId);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Servatrice::doSendIslMessage(const IslMessage &msg, int serverId)
|
||||||
|
{
|
||||||
|
QReadLocker locker(&islLock);
|
||||||
|
|
||||||
|
qDebug() << "hallo";
|
||||||
|
if (serverId == -1) {
|
||||||
|
QMapIterator<int, IslInterface *> islIterator(islInterfaces);
|
||||||
|
while (islIterator.hasNext()) {
|
||||||
|
qDebug() << "welt";
|
||||||
|
islIterator.next().value()->transmitMessage(msg);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
IslInterface *interface = islInterfaces.value(serverId);
|
||||||
|
if (interface)
|
||||||
|
interface->transmitMessage(msg);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
#include <QSslCertificate>
|
#include <QSslCertificate>
|
||||||
#include <QSslKey>
|
#include <QSslKey>
|
||||||
#include <QHostAddress>
|
#include <QHostAddress>
|
||||||
|
#include <QReadWriteLock>
|
||||||
#include "server.h"
|
#include "server.h"
|
||||||
|
|
||||||
class QSqlDatabase;
|
class QSqlDatabase;
|
||||||
|
@ -35,7 +36,7 @@ class QTimer;
|
||||||
class GameReplay;
|
class GameReplay;
|
||||||
class Servatrice;
|
class Servatrice;
|
||||||
class ServerSocketInterface;
|
class ServerSocketInterface;
|
||||||
class NetworkServerInterface;
|
class IslInterface;
|
||||||
|
|
||||||
class Servatrice_GameServer : public QTcpServer {
|
class Servatrice_GameServer : public QTcpServer {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
@ -49,14 +50,14 @@ protected:
|
||||||
void incomingConnection(int socketDescriptor);
|
void incomingConnection(int socketDescriptor);
|
||||||
};
|
};
|
||||||
|
|
||||||
class Servatrice_NetworkServer : public QTcpServer {
|
class Servatrice_IslServer : public QTcpServer {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
private:
|
private:
|
||||||
Servatrice *server;
|
Servatrice *server;
|
||||||
QSslCertificate cert;
|
QSslCertificate cert;
|
||||||
QSslKey privateKey;
|
QSslKey privateKey;
|
||||||
public:
|
public:
|
||||||
Servatrice_NetworkServer(Servatrice *_server, const QSslCertificate &_cert, const QSslKey &_privateKey, QObject *parent = 0)
|
Servatrice_IslServer(Servatrice *_server, const QSslCertificate &_cert, const QSslKey &_privateKey, QObject *parent = 0)
|
||||||
: QTcpServer(parent), server(_server), cert(_cert), privateKey(_privateKey) { }
|
: QTcpServer(parent), server(_server), cert(_cert), privateKey(_privateKey) { }
|
||||||
protected:
|
protected:
|
||||||
void incomingConnection(int socketDescriptor);
|
void incomingConnection(int socketDescriptor);
|
||||||
|
@ -115,8 +116,10 @@ public:
|
||||||
int getUserIdInDB(const QString &name);
|
int getUserIdInDB(const QString &name);
|
||||||
void storeGameInformation(int secondsElapsed, const QSet<QString> &allPlayersEver, const QSet<QString> &allSpectatorsEver, const QList<GameReplay *> &replays);
|
void storeGameInformation(int secondsElapsed, const QSet<QString> &allPlayersEver, const QSet<QString> &allSpectatorsEver, const QList<GameReplay *> &replays);
|
||||||
|
|
||||||
void addNetworkServerInterface(NetworkServerInterface *interface);
|
bool islConnectionExists(int serverId) const;
|
||||||
void removeNetworkServerInterface(NetworkServerInterface *interface);
|
void addIslInterface(int serverId, IslInterface *interface);
|
||||||
|
void removeIslInterface(int serverId);
|
||||||
|
QReadWriteLock islLock;
|
||||||
|
|
||||||
QList<ServerProperties> getServerList() const;
|
QList<ServerProperties> getServerList() const;
|
||||||
protected:
|
protected:
|
||||||
|
@ -129,6 +132,8 @@ protected:
|
||||||
void lockSessionTables();
|
void lockSessionTables();
|
||||||
void unlockSessionTables();
|
void unlockSessionTables();
|
||||||
bool userSessionExists(const QString &userName);
|
bool userSessionExists(const QString &userName);
|
||||||
|
|
||||||
|
void doSendIslMessage(const IslMessage &msg, int serverId);
|
||||||
private:
|
private:
|
||||||
enum AuthenticationMethod { AuthenticationNone, AuthenticationSql };
|
enum AuthenticationMethod { AuthenticationNone, AuthenticationSql };
|
||||||
enum DatabaseType { DatabaseNone, DatabaseMySql };
|
enum DatabaseType { DatabaseNone, DatabaseMySql };
|
||||||
|
@ -136,7 +141,7 @@ private:
|
||||||
DatabaseType databaseType;
|
DatabaseType databaseType;
|
||||||
QTimer *pingClock, *statusUpdateClock;
|
QTimer *pingClock, *statusUpdateClock;
|
||||||
Servatrice_GameServer *gameServer;
|
Servatrice_GameServer *gameServer;
|
||||||
Servatrice_NetworkServer *networkServer;
|
Servatrice_IslServer *islServer;
|
||||||
QString serverName;
|
QString serverName;
|
||||||
QString loginMessage;
|
QString loginMessage;
|
||||||
QString dbPrefix;
|
QString dbPrefix;
|
||||||
|
@ -158,7 +163,7 @@ private:
|
||||||
QList<ServerProperties> serverList;
|
QList<ServerProperties> serverList;
|
||||||
void updateServerList();
|
void updateServerList();
|
||||||
|
|
||||||
QList<NetworkServerInterface *> networkServerInterfaces;
|
QMap<int, IslInterface *> islInterfaces;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue