changed a lot of thread locking code in the server, rooms are working with ISL now
This commit is contained in:
parent
572e4eaafa
commit
c23af44749
16 changed files with 449 additions and 221 deletions
|
@ -16,4 +16,5 @@ message ServerInfo_Game {
|
||||||
optional bool spectators_need_password = 13;
|
optional bool spectators_need_password = 13;
|
||||||
optional uint32 spectators_count = 14;
|
optional uint32 spectators_count = 14;
|
||||||
optional uint32 start_time = 15;
|
optional uint32 start_time = 15;
|
||||||
|
optional sint32 server_id = 16 [default = -1];
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,10 +32,11 @@
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
|
||||||
Server::Server(QObject *parent)
|
Server::Server(QObject *parent)
|
||||||
: QObject(parent), serverMutex(QMutex::Recursive), nextGameId(0), nextReplayId(0)
|
: QObject(parent), nextGameId(0), nextReplayId(0)
|
||||||
{
|
{
|
||||||
qRegisterMetaType<ServerInfo_Game>("ServerInfo_Game");
|
qRegisterMetaType<ServerInfo_Game>("ServerInfo_Game");
|
||||||
qRegisterMetaType<ServerInfo_Room>("ServerInfo_Room");
|
qRegisterMetaType<ServerInfo_Room>("ServerInfo_Room");
|
||||||
|
qRegisterMetaType<ServerInfo_User>("ServerInfo_User");
|
||||||
}
|
}
|
||||||
|
|
||||||
Server::~Server()
|
Server::~Server()
|
||||||
|
@ -44,22 +45,26 @@ Server::~Server()
|
||||||
|
|
||||||
void Server::prepareDestroy()
|
void Server::prepareDestroy()
|
||||||
{
|
{
|
||||||
QMutexLocker locker(&serverMutex);
|
roomsLock.lockForWrite();
|
||||||
|
|
||||||
while (!clients.isEmpty())
|
|
||||||
delete clients.takeFirst();
|
|
||||||
|
|
||||||
QMapIterator<int, Server_Room *> roomIterator(rooms);
|
QMapIterator<int, Server_Room *> roomIterator(rooms);
|
||||||
while (roomIterator.hasNext())
|
while (roomIterator.hasNext())
|
||||||
delete roomIterator.next().value();
|
delete roomIterator.next().value();
|
||||||
|
rooms.clear();
|
||||||
|
roomsLock.unlock();
|
||||||
|
|
||||||
|
clientsLock.lockForWrite();
|
||||||
|
while (!clients.isEmpty())
|
||||||
|
delete clients.takeFirst();
|
||||||
|
clientsLock.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
AuthenticationResult Server::loginUser(Server_ProtocolHandler *session, QString &name, const QString &password, QString &reasonStr)
|
AuthenticationResult Server::loginUser(Server_ProtocolHandler *session, QString &name, const QString &password, QString &reasonStr)
|
||||||
{
|
{
|
||||||
QMutexLocker locker(&serverMutex);
|
|
||||||
if (name.size() > 35)
|
if (name.size() > 35)
|
||||||
name = name.left(35);
|
name = name.left(35);
|
||||||
|
|
||||||
|
QWriteLocker locker(&clientsLock);
|
||||||
|
|
||||||
AuthenticationResult authState = checkUserPassword(session, name, password, reasonStr);
|
AuthenticationResult authState = checkUserPassword(session, name, password, reasonStr);
|
||||||
if ((authState == NotLoggedIn) || (authState == UserIsBanned))
|
if ((authState == NotLoggedIn) || (authState == UserIsBanned))
|
||||||
return authState;
|
return authState;
|
||||||
|
@ -113,13 +118,13 @@ AuthenticationResult Server::loginUser(Server_ProtocolHandler *session, QString
|
||||||
|
|
||||||
void Server::addClient(Server_ProtocolHandler *client)
|
void Server::addClient(Server_ProtocolHandler *client)
|
||||||
{
|
{
|
||||||
QMutexLocker locker(&serverMutex);
|
QWriteLocker locker(&clientsLock);
|
||||||
clients << client;
|
clients << client;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Server::removeClient(Server_ProtocolHandler *client)
|
void Server::removeClient(Server_ProtocolHandler *client)
|
||||||
{
|
{
|
||||||
QMutexLocker locker(&serverMutex);
|
QWriteLocker locker(&clientsLock);
|
||||||
clients.removeAt(clients.indexOf(client));
|
clients.removeAt(clients.indexOf(client));
|
||||||
ServerInfo_User *data = client->getUserInfo();
|
ServerInfo_User *data = client->getUserInfo();
|
||||||
if (data) {
|
if (data) {
|
||||||
|
@ -142,34 +147,90 @@ void Server::removeClient(Server_ProtocolHandler *client)
|
||||||
qDebug() << "Server::removeClient:" << clients.size() << "clients; " << users.size() << "users left";
|
qDebug() << "Server::removeClient:" << clients.size() << "clients; " << users.size() << "users left";
|
||||||
}
|
}
|
||||||
|
|
||||||
void Server::externalUserJoined(ServerInfo_User userInfo)
|
void Server::externalUserJoined(const ServerInfo_User &userInfo)
|
||||||
{
|
{
|
||||||
// This function is always called from the main thread via signal/slot.
|
// This function is always called from the main thread via signal/slot.
|
||||||
QMutexLocker locker(&serverMutex);
|
QWriteLocker locker(&clientsLock);
|
||||||
|
|
||||||
externalUsers.insert(QString::fromStdString(userInfo.name()), new Server_RemoteUserInterface(this, ServerInfo_User_Container(userInfo)));
|
externalUsers.insert(QString::fromStdString(userInfo.name()), new Server_RemoteUserInterface(this, ServerInfo_User_Container(userInfo)));
|
||||||
|
|
||||||
Event_UserJoined event;
|
Event_UserJoined event;
|
||||||
event.mutable_user_info()->CopyFrom(userInfo);
|
event.mutable_user_info()->CopyFrom(userInfo);
|
||||||
|
|
||||||
SessionEvent *se = Server_ProtocolHandler::prepareSessionEvent(event);
|
SessionEvent *se = Server_ProtocolHandler::prepareSessionEvent(event);
|
||||||
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);
|
||||||
|
delete se;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Server::externalUserLeft(QString userName)
|
void Server::externalUserLeft(const QString &userName)
|
||||||
{
|
{
|
||||||
// This function is always called from the main thread via signal/slot.
|
// This function is always called from the main thread via signal/slot.
|
||||||
QMutexLocker locker(&serverMutex);
|
QWriteLocker locker(&clientsLock);
|
||||||
|
|
||||||
delete externalUsers.take(userName);
|
delete externalUsers.take(userName);
|
||||||
|
|
||||||
Event_UserLeft event;
|
Event_UserLeft event;
|
||||||
event.set_name(userName.toStdString());
|
event.set_name(userName.toStdString());
|
||||||
|
|
||||||
SessionEvent *se = Server_ProtocolHandler::prepareSessionEvent(event);
|
SessionEvent *se = Server_ProtocolHandler::prepareSessionEvent(event);
|
||||||
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);
|
||||||
|
delete se;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Server::externalRoomUserJoined(int roomId, const ServerInfo_User &userInfo)
|
||||||
|
{
|
||||||
|
// This function is always called from the main thread via signal/slot.
|
||||||
|
QReadLocker locker(&roomsLock);
|
||||||
|
|
||||||
|
Server_Room *room = rooms.value(roomId);
|
||||||
|
if (!room) {
|
||||||
|
qDebug() << "externalRoomUserJoined: room id=" << roomId << "not found";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
room->addExternalUser(userInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Server::externalRoomUserLeft(int roomId, const QString &userName)
|
||||||
|
{
|
||||||
|
// This function is always called from the main thread via signal/slot.
|
||||||
|
QReadLocker locker(&roomsLock);
|
||||||
|
|
||||||
|
Server_Room *room = rooms.value(roomId);
|
||||||
|
if (!room) {
|
||||||
|
qDebug() << "externalRoomUserLeft: room id=" << roomId << "not found";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
room->removeExternalUser(userName);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Server::externalRoomSay(int roomId, const QString &userName, const QString &message)
|
||||||
|
{
|
||||||
|
// This function is always called from the main thread via signal/slot.
|
||||||
|
QReadLocker locker(&roomsLock);
|
||||||
|
|
||||||
|
Server_Room *room = rooms.value(roomId);
|
||||||
|
if (!room) {
|
||||||
|
qDebug() << "externalRoomSay: room id=" << roomId << "not found";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
room->say(userName, message, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Server::externalRoomGameListChanged(int roomId, const ServerInfo_Game &gameInfo)
|
||||||
|
{
|
||||||
|
// This function is always called from the main thread via signal/slot.
|
||||||
|
QReadLocker locker(&roomsLock);
|
||||||
|
|
||||||
|
Server_Room *room = rooms.value(roomId);
|
||||||
|
if (!room) {
|
||||||
|
qDebug() << "externalRoomGameListChanged: room id=" << roomId << "not found";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
room->updateExternalGameList(gameInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Server::broadcastRoomUpdate(const ServerInfo_Room &roomInfo, bool sendToIsl)
|
void Server::broadcastRoomUpdate(const ServerInfo_Room &roomInfo, bool sendToIsl)
|
||||||
|
@ -179,11 +240,11 @@ void Server::broadcastRoomUpdate(const ServerInfo_Room &roomInfo, bool sendToIsl
|
||||||
|
|
||||||
SessionEvent *se = Server_ProtocolHandler::prepareSessionEvent(event);
|
SessionEvent *se = Server_ProtocolHandler::prepareSessionEvent(event);
|
||||||
|
|
||||||
serverMutex.lock();
|
clientsLock.lockForRead();
|
||||||
for (int i = 0; i < clients.size(); ++i)
|
for (int i = 0; i < clients.size(); ++i)
|
||||||
if (clients[i]->getAcceptsRoomListChanges())
|
if (clients[i]->getAcceptsRoomListChanges())
|
||||||
clients[i]->sendProtocolItem(*se);
|
clients[i]->sendProtocolItem(*se);
|
||||||
serverMutex.unlock();
|
clientsLock.unlock();
|
||||||
|
|
||||||
if (sendToIsl)
|
if (sendToIsl)
|
||||||
sendIslMessage(*se);
|
sendIslMessage(*se);
|
||||||
|
@ -193,25 +254,26 @@ void Server::broadcastRoomUpdate(const ServerInfo_Room &roomInfo, bool sendToIsl
|
||||||
|
|
||||||
void Server::addRoom(Server_Room *newRoom)
|
void Server::addRoom(Server_Room *newRoom)
|
||||||
{
|
{
|
||||||
QMutexLocker locker(&serverMutex);
|
QWriteLocker locker(&roomsLock);
|
||||||
|
qDebug() << "Adding room: ID=" << newRoom->getId() << "name=" << newRoom->getName();
|
||||||
rooms.insert(newRoom->getId(), newRoom);
|
rooms.insert(newRoom->getId(), newRoom);
|
||||||
connect(newRoom, SIGNAL(roomInfoChanged(ServerInfo_Room)), this, SLOT(broadcastRoomUpdate(const ServerInfo_Room &)), Qt::QueuedConnection);
|
connect(newRoom, SIGNAL(roomInfoChanged(ServerInfo_Room)), this, SLOT(broadcastRoomUpdate(const ServerInfo_Room &)), Qt::QueuedConnection);
|
||||||
}
|
}
|
||||||
|
|
||||||
int Server::getUsersCount() const
|
int Server::getUsersCount() const
|
||||||
{
|
{
|
||||||
QMutexLocker locker(&serverMutex);
|
QReadLocker locker(&clientsLock);
|
||||||
return users.size();
|
return users.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
int Server::getGamesCount() const
|
int Server::getGamesCount() const
|
||||||
{
|
{
|
||||||
int result = 0;
|
int result = 0;
|
||||||
QMutexLocker locker(&serverMutex);
|
QReadLocker locker(&roomsLock);
|
||||||
QMapIterator<int, Server_Room *> roomIterator(rooms);
|
QMapIterator<int, Server_Room *> roomIterator(rooms);
|
||||||
while (roomIterator.hasNext()) {
|
while (roomIterator.hasNext()) {
|
||||||
Server_Room *room = roomIterator.next().value();
|
Server_Room *room = roomIterator.next().value();
|
||||||
QMutexLocker roomLocker(&room->roomMutex);
|
QMutexLocker roomLocker(&room->gamesMutex);
|
||||||
result += room->getGames().size();
|
result += room->getGames().size();
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
|
|
@ -5,8 +5,11 @@
|
||||||
#include <QStringList>
|
#include <QStringList>
|
||||||
#include <QMap>
|
#include <QMap>
|
||||||
#include <QMutex>
|
#include <QMutex>
|
||||||
|
#include <QReadWriteLock>
|
||||||
|
#include <QMetaType>
|
||||||
#include "pb/serverinfo_user.pb.h"
|
#include "pb/serverinfo_user.pb.h"
|
||||||
#include "pb/serverinfo_room.pb.h"
|
#include "pb/serverinfo_room.pb.h"
|
||||||
|
#include "pb/serverinfo_game.pb.h"
|
||||||
|
|
||||||
class Server_Game;
|
class Server_Game;
|
||||||
class Server_Room;
|
class Server_Room;
|
||||||
|
@ -29,7 +32,7 @@ signals:
|
||||||
private slots:
|
private slots:
|
||||||
void broadcastRoomUpdate(const ServerInfo_Room &roomInfo, bool sendToIsl = false);
|
void broadcastRoomUpdate(const ServerInfo_Room &roomInfo, bool sendToIsl = false);
|
||||||
public:
|
public:
|
||||||
mutable QMutex serverMutex;
|
mutable QReadWriteLock clientsLock, roomsLock;
|
||||||
Server(QObject *parent = 0);
|
Server(QObject *parent = 0);
|
||||||
~Server();
|
~Server();
|
||||||
AuthenticationResult loginUser(Server_ProtocolHandler *session, QString &name, const QString &password, QString &reason);
|
AuthenticationResult loginUser(Server_ProtocolHandler *session, QString &name, const QString &password, QString &reason);
|
||||||
|
@ -67,9 +70,12 @@ public:
|
||||||
void removeExternalUser(const QString &userName);
|
void removeExternalUser(const QString &userName);
|
||||||
const QMap<QString, Server_AbstractUserInterface *> &getExternalUsers() const { return externalUsers; }
|
const QMap<QString, Server_AbstractUserInterface *> &getExternalUsers() const { return externalUsers; }
|
||||||
protected slots:
|
protected slots:
|
||||||
void externalUserJoined(ServerInfo_User userInfo);
|
void externalUserJoined(const ServerInfo_User &userInfo);
|
||||||
void externalUserLeft(QString userName);
|
void externalUserLeft(const QString &userName);
|
||||||
void externalRoomUpdated(ServerInfo_Room roomInfo);
|
void externalRoomUserJoined(int roomId, const ServerInfo_User &userInfo);
|
||||||
|
void externalRoomUserLeft(int roomId, const QString &userName);
|
||||||
|
void externalRoomSay(int roomId, const QString &userName, const QString &message);
|
||||||
|
void externalRoomGameListChanged(int roomId, const ServerInfo_Game &gameInfo);
|
||||||
protected:
|
protected:
|
||||||
void prepareDestroy();
|
void prepareDestroy();
|
||||||
QList<Server_ProtocolHandler *> clients;
|
QList<Server_ProtocolHandler *> clients;
|
||||||
|
@ -95,4 +101,8 @@ protected:
|
||||||
virtual void doSendIslMessage(const IslMessage &msg, int serverId) { }
|
virtual void doSendIslMessage(const IslMessage &msg, int serverId) { }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Q_DECLARE_METATYPE(ServerInfo_User)
|
||||||
|
Q_DECLARE_METATYPE(ServerInfo_Room)
|
||||||
|
Q_DECLARE_METATYPE(ServerInfo_Game)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -65,7 +65,7 @@ Server_Game::Server_Game(Server_ProtocolHandler *_creator, int _gameId, const QS
|
||||||
|
|
||||||
Server_Game::~Server_Game()
|
Server_Game::~Server_Game()
|
||||||
{
|
{
|
||||||
room->roomMutex.lock();
|
room->gamesMutex.lock();
|
||||||
gameMutex.lock();
|
gameMutex.lock();
|
||||||
|
|
||||||
sendGameEventContainer(prepareGameEvent(Event_GameClosed(), -1));
|
sendGameEventContainer(prepareGameEvent(Event_GameClosed(), -1));
|
||||||
|
@ -80,7 +80,7 @@ Server_Game::~Server_Game()
|
||||||
creatorInfo = 0;
|
creatorInfo = 0;
|
||||||
|
|
||||||
gameMutex.unlock();
|
gameMutex.unlock();
|
||||||
room->roomMutex.unlock();
|
room->gamesMutex.unlock();
|
||||||
|
|
||||||
currentReplay->set_duration_seconds(secondsElapsed - startTimeOfThisGame);
|
currentReplay->set_duration_seconds(secondsElapsed - startTimeOfThisGame);
|
||||||
replayList.append(currentReplay);
|
replayList.append(currentReplay);
|
||||||
|
@ -371,7 +371,6 @@ Server_Player *Server_Game::addPlayer(Server_ProtocolHandler *handler, bool spec
|
||||||
|
|
||||||
void Server_Game::removePlayer(Server_Player *player)
|
void Server_Game::removePlayer(Server_Player *player)
|
||||||
{
|
{
|
||||||
QMutexLocker roomLocker(&room->roomMutex);
|
|
||||||
QMutexLocker locker(&gameMutex);
|
QMutexLocker locker(&gameMutex);
|
||||||
|
|
||||||
players.remove(player->getPlayerId());
|
players.remove(player->getPlayerId());
|
||||||
|
@ -461,7 +460,6 @@ void Server_Game::unattachCards(GameEventStorage &ges, Server_Player *player)
|
||||||
|
|
||||||
bool Server_Game::kickPlayer(int playerId)
|
bool Server_Game::kickPlayer(int playerId)
|
||||||
{
|
{
|
||||||
QMutexLocker roomLocker(&room->roomMutex);
|
|
||||||
QMutexLocker locker(&gameMutex);
|
QMutexLocker locker(&gameMutex);
|
||||||
|
|
||||||
Server_Player *playerToKick = players.value(playerId);
|
Server_Player *playerToKick = players.value(playerId);
|
||||||
|
|
|
@ -89,7 +89,7 @@
|
||||||
#include <google/protobuf/descriptor.h>
|
#include <google/protobuf/descriptor.h>
|
||||||
|
|
||||||
Server_ProtocolHandler::Server_ProtocolHandler(Server *_server, QObject *parent)
|
Server_ProtocolHandler::Server_ProtocolHandler(Server *_server, QObject *parent)
|
||||||
: QObject(parent), Server_AbstractUserInterface(_server), authState(NotLoggedIn), acceptsUserListChanges(false), acceptsRoomListChanges(false), sessionId(-1), timeRunning(0), lastDataReceived(0), gameListMutex(QMutex::Recursive)
|
: QObject(parent), Server_AbstractUserInterface(_server), authState(NotLoggedIn), acceptsUserListChanges(false), acceptsRoomListChanges(false), sessionId(-1), timeRunning(0), lastDataReceived(0)
|
||||||
{
|
{
|
||||||
connect(server, SIGNAL(pingClockTimeout()), this, SLOT(pingClockTimeout()));
|
connect(server, SIGNAL(pingClockTimeout()), this, SLOT(pingClockTimeout()));
|
||||||
}
|
}
|
||||||
|
@ -103,7 +103,6 @@ Server_ProtocolHandler::~Server_ProtocolHandler()
|
||||||
// finalization.
|
// finalization.
|
||||||
void Server_ProtocolHandler::prepareDestroy()
|
void Server_ProtocolHandler::prepareDestroy()
|
||||||
{
|
{
|
||||||
QMutexLocker locker(&server->serverMutex);
|
|
||||||
qDebug("Server_ProtocolHandler::prepareDestroy");
|
qDebug("Server_ProtocolHandler::prepareDestroy");
|
||||||
|
|
||||||
server->removeClient(this);
|
server->removeClient(this);
|
||||||
|
@ -113,20 +112,40 @@ void Server_ProtocolHandler::prepareDestroy()
|
||||||
roomIterator.next().value()->removeClient(this);
|
roomIterator.next().value()->removeClient(this);
|
||||||
|
|
||||||
gameListMutex.lock();
|
gameListMutex.lock();
|
||||||
QMapIterator<int, QPair<Server_Game *, Server_Player *> > gameIterator(games);
|
QMap<int, QPair<int, int> > tempGames(games);
|
||||||
|
gameListMutex.unlock();
|
||||||
|
|
||||||
|
server->roomsLock.lockForRead();
|
||||||
|
QMapIterator<int, QPair<int, int> > gameIterator(tempGames);
|
||||||
while (gameIterator.hasNext()) {
|
while (gameIterator.hasNext()) {
|
||||||
gameIterator.next();
|
gameIterator.next();
|
||||||
Server_Game *g = gameIterator.value().first;
|
|
||||||
Server_Player *p = gameIterator.value().second;
|
|
||||||
|
|
||||||
|
Server_Room *r = server->getRooms().value(gameIterator.value().first);
|
||||||
|
if (!r)
|
||||||
|
continue;
|
||||||
|
r->gamesMutex.lock();
|
||||||
|
Server_Game *g = r->getGames().value(gameIterator.key());
|
||||||
|
if (!g) {
|
||||||
|
r->gamesMutex.unlock();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
g->gameMutex.lock();
|
g->gameMutex.lock();
|
||||||
|
Server_Player *p = g->getPlayer(gameIterator.value().second);
|
||||||
|
if (!p) {
|
||||||
|
g->gameMutex.unlock();
|
||||||
|
r->gamesMutex.unlock();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if ((authState == UnknownUser) || p->getSpectator())
|
if ((authState == UnknownUser) || p->getSpectator())
|
||||||
g->removePlayer(p);
|
g->removePlayer(p);
|
||||||
else
|
else
|
||||||
p->setProtocolHandler(0);
|
p->setProtocolHandler(0);
|
||||||
|
|
||||||
g->gameMutex.unlock();
|
g->gameMutex.unlock();
|
||||||
|
r->gamesMutex.unlock();
|
||||||
}
|
}
|
||||||
gameListMutex.unlock();
|
server->roomsLock.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Server_ProtocolHandler::playerRemovedFromGame(Server_Game *game)
|
void Server_ProtocolHandler::playerRemovedFromGame(Server_Game *game)
|
||||||
|
@ -214,12 +233,11 @@ Response::ResponseCode Server_ProtocolHandler::processRoomCommandContainer(const
|
||||||
if (authState == NotLoggedIn)
|
if (authState == NotLoggedIn)
|
||||||
return Response::RespLoginNeeded;
|
return Response::RespLoginNeeded;
|
||||||
|
|
||||||
|
QReadLocker locker(&server->roomsLock);
|
||||||
Server_Room *room = rooms.value(cont.room_id(), 0);
|
Server_Room *room = rooms.value(cont.room_id(), 0);
|
||||||
if (!room)
|
if (!room)
|
||||||
return Response::RespNotInRoom;
|
return Response::RespNotInRoom;
|
||||||
|
|
||||||
QMutexLocker locker(&room->roomMutex);
|
|
||||||
|
|
||||||
Response::ResponseCode finalResponseCode = Response::RespOk;
|
Response::ResponseCode finalResponseCode = Response::RespOk;
|
||||||
for (int i = cont.room_command_size() - 1; i >= 0; --i) {
|
for (int i = cont.room_command_size() - 1; i >= 0; --i) {
|
||||||
Response::ResponseCode resp = Response::RespInvalidCommand;
|
Response::ResponseCode resp = Response::RespInvalidCommand;
|
||||||
|
@ -245,16 +263,34 @@ Response::ResponseCode Server_ProtocolHandler::processGameCommandContainer(const
|
||||||
|
|
||||||
gameListMutex.lock();
|
gameListMutex.lock();
|
||||||
if (!games.contains(cont.game_id())) {
|
if (!games.contains(cont.game_id())) {
|
||||||
qDebug() << "invalid game";
|
gameListMutex.unlock();
|
||||||
return Response::RespNotInRoom;
|
return Response::RespNotInRoom;
|
||||||
}
|
}
|
||||||
QPair<Server_Game *, Server_Player *> gamePair = games.value(cont.game_id());
|
const QPair<int, int> roomIdAndPlayerId = games.value(cont.game_id());
|
||||||
Server_Game *game = gamePair.first;
|
|
||||||
Server_Player *player = gamePair.second;
|
|
||||||
|
|
||||||
QMutexLocker locker(&game->gameMutex);
|
|
||||||
gameListMutex.unlock();
|
gameListMutex.unlock();
|
||||||
|
|
||||||
|
server->roomsLock.lockForRead();
|
||||||
|
Server_Room *room = server->getRooms().value(roomIdAndPlayerId.first);
|
||||||
|
if (!room) {
|
||||||
|
server->roomsLock.unlock();
|
||||||
|
return Response::RespNotInRoom;
|
||||||
|
}
|
||||||
|
room->gamesMutex.lock();
|
||||||
|
Server_Game *game = room->getGames().value(cont.game_id());
|
||||||
|
if (!game) {
|
||||||
|
room->gamesMutex.unlock();
|
||||||
|
server->roomsLock.unlock();
|
||||||
|
return Response::RespNotInRoom;
|
||||||
|
}
|
||||||
|
game->gameMutex.lock();
|
||||||
|
Server_Player *player = game->getPlayer(roomIdAndPlayerId.second);
|
||||||
|
if (!player) {
|
||||||
|
game->gameMutex.unlock();
|
||||||
|
room->gamesMutex.unlock();
|
||||||
|
server->roomsLock.unlock();
|
||||||
|
return Response::RespNotInRoom;
|
||||||
|
}
|
||||||
|
|
||||||
GameEventStorage ges;
|
GameEventStorage ges;
|
||||||
Response::ResponseCode finalResponseCode = Response::RespOk;
|
Response::ResponseCode finalResponseCode = Response::RespOk;
|
||||||
for (int i = cont.game_command_size() - 1; i >= 0; --i) {
|
for (int i = cont.game_command_size() - 1; i >= 0; --i) {
|
||||||
|
@ -298,6 +334,11 @@ Response::ResponseCode Server_ProtocolHandler::processGameCommandContainer(const
|
||||||
finalResponseCode = resp;
|
finalResponseCode = resp;
|
||||||
}
|
}
|
||||||
ges.sendToGame(game);
|
ges.sendToGame(game);
|
||||||
|
|
||||||
|
game->gameMutex.unlock();
|
||||||
|
room->gamesMutex.unlock();
|
||||||
|
server->roomsLock.unlock();
|
||||||
|
|
||||||
return finalResponseCode;
|
return finalResponseCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -400,13 +441,6 @@ void Server_ProtocolHandler::pingClockTimeout()
|
||||||
++timeRunning;
|
++timeRunning;
|
||||||
}
|
}
|
||||||
|
|
||||||
QPair<Server_Game *, Server_Player *> Server_ProtocolHandler::getGame(int gameId) const
|
|
||||||
{
|
|
||||||
if (games.contains(gameId))
|
|
||||||
return games.value(gameId);
|
|
||||||
return QPair<Server_Game *, Server_Player *>(0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
Response::ResponseCode Server_ProtocolHandler::cmdPing(const Command_Ping & /*cmd*/, ResponseContainer & /*rc*/)
|
Response::ResponseCode Server_ProtocolHandler::cmdPing(const Command_Ping & /*cmd*/, ResponseContainer & /*rc*/)
|
||||||
{
|
{
|
||||||
return Response::RespOk;
|
return Response::RespOk;
|
||||||
|
@ -449,13 +483,13 @@ Response::ResponseCode Server_ProtocolHandler::cmdLogin(const Command_Login &cmd
|
||||||
re->add_ignore_list()->CopyFrom(ignoreIterator.next().value());
|
re->add_ignore_list()->CopyFrom(ignoreIterator.next().value());
|
||||||
}
|
}
|
||||||
|
|
||||||
server->serverMutex.lock();
|
server->roomsLock.lockForRead();
|
||||||
|
|
||||||
QMapIterator<int, Server_Room *> roomIterator(server->getRooms());
|
QMapIterator<int, Server_Room *> roomIterator(server->getRooms());
|
||||||
QMutexLocker gameListLocker(&gameListMutex);
|
gameListMutex.lock();
|
||||||
while (roomIterator.hasNext()) {
|
while (roomIterator.hasNext()) {
|
||||||
Server_Room *room = roomIterator.next().value();
|
Server_Room *room = roomIterator.next().value();
|
||||||
room->roomMutex.lock();
|
room->gamesMutex.lock();
|
||||||
QMapIterator<int, Server_Game *> gameIterator(room->getGames());
|
QMapIterator<int, Server_Game *> gameIterator(room->getGames());
|
||||||
while (gameIterator.hasNext()) {
|
while (gameIterator.hasNext()) {
|
||||||
Server_Game *game = gameIterator.next().value();
|
Server_Game *game = gameIterator.next().value();
|
||||||
|
@ -464,7 +498,7 @@ Response::ResponseCode Server_ProtocolHandler::cmdLogin(const Command_Login &cmd
|
||||||
for (int j = 0; j < gamePlayers.size(); ++j)
|
for (int j = 0; j < gamePlayers.size(); ++j)
|
||||||
if (gamePlayers[j]->getUserInfo()->name() == userInfo->name()) {
|
if (gamePlayers[j]->getUserInfo()->name() == userInfo->name()) {
|
||||||
gamePlayers[j]->setProtocolHandler(this);
|
gamePlayers[j]->setProtocolHandler(this);
|
||||||
games.insert(game->getGameId(), QPair<Server_Game *, Server_Player *>(game, gamePlayers[j]));
|
games.insert(game->getGameId(), QPair<int, int>(room->getId(), gamePlayers[j]->getPlayerId()));
|
||||||
|
|
||||||
Event_GameJoined event1;
|
Event_GameJoined event1;
|
||||||
event1.set_game_id(game->getGameId());
|
event1.set_game_id(game->getGameId());
|
||||||
|
@ -478,7 +512,7 @@ Response::ResponseCode Server_ProtocolHandler::cmdLogin(const Command_Login &cmd
|
||||||
rc.enqueuePostResponseItem(ServerMessage::SESSION_EVENT, prepareSessionEvent(event1));
|
rc.enqueuePostResponseItem(ServerMessage::SESSION_EVENT, prepareSessionEvent(event1));
|
||||||
|
|
||||||
Event_GameStateChanged event2;
|
Event_GameStateChanged event2;
|
||||||
QListIterator<ServerInfo_Player> gameStateIterator(game->getGameState(gamePlayers[j]));
|
QListIterator<ServerInfo_Player> gameStateIterator(game->getGameState(gamePlayers[j], gamePlayers[j]->getSpectator() && game->getSpectatorsSeeEverything(), true));
|
||||||
while (gameStateIterator.hasNext())
|
while (gameStateIterator.hasNext())
|
||||||
event2.add_player_list()->CopyFrom(gameStateIterator.next());
|
event2.add_player_list()->CopyFrom(gameStateIterator.next());
|
||||||
event2.set_seconds_elapsed(game->getSecondsElapsed());
|
event2.set_seconds_elapsed(game->getSecondsElapsed());
|
||||||
|
@ -490,9 +524,10 @@ Response::ResponseCode Server_ProtocolHandler::cmdLogin(const Command_Login &cmd
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
room->roomMutex.unlock();
|
room->gamesMutex.unlock();
|
||||||
}
|
}
|
||||||
server->serverMutex.unlock();
|
gameListMutex.unlock();
|
||||||
|
server->roomsLock.unlock();
|
||||||
|
|
||||||
rc.setResponseExtension(re);
|
rc.setResponseExtension(re);
|
||||||
return Response::RespOk;
|
return Response::RespOk;
|
||||||
|
@ -503,7 +538,7 @@ Response::ResponseCode Server_ProtocolHandler::cmdMessage(const Command_Message
|
||||||
if (authState == NotLoggedIn)
|
if (authState == NotLoggedIn)
|
||||||
return Response::RespLoginNeeded;
|
return Response::RespLoginNeeded;
|
||||||
|
|
||||||
QMutexLocker locker(&server->serverMutex);
|
QReadLocker locker(&server->clientsLock);
|
||||||
|
|
||||||
QString receiver = QString::fromStdString(cmd.user_name());
|
QString receiver = QString::fromStdString(cmd.user_name());
|
||||||
Server_AbstractUserInterface *userInterface = server->getUsers().value(receiver);
|
Server_AbstractUserInterface *userInterface = server->getUsers().value(receiver);
|
||||||
|
@ -532,22 +567,24 @@ Response::ResponseCode Server_ProtocolHandler::cmdGetGamesOfUser(const Command_G
|
||||||
if (authState == NotLoggedIn)
|
if (authState == NotLoggedIn)
|
||||||
return Response::RespLoginNeeded;
|
return Response::RespLoginNeeded;
|
||||||
|
|
||||||
server->serverMutex.lock();
|
server->clientsLock.lockForRead();
|
||||||
if (!server->getUsers().contains(QString::fromStdString(cmd.user_name())))
|
if (!server->getUsers().contains(QString::fromStdString(cmd.user_name())))
|
||||||
return Response::RespNameNotFound;
|
return Response::RespNameNotFound;
|
||||||
|
server->clientsLock.unlock();
|
||||||
|
|
||||||
Response_GetGamesOfUser *re = new Response_GetGamesOfUser;
|
Response_GetGamesOfUser *re = new Response_GetGamesOfUser;
|
||||||
|
server->roomsLock.lockForRead();
|
||||||
QMapIterator<int, Server_Room *> roomIterator(server->getRooms());
|
QMapIterator<int, Server_Room *> roomIterator(server->getRooms());
|
||||||
while (roomIterator.hasNext()) {
|
while (roomIterator.hasNext()) {
|
||||||
Server_Room *room = roomIterator.next().value();
|
Server_Room *room = roomIterator.next().value();
|
||||||
room->roomMutex.lock();
|
room->gamesMutex.lock();
|
||||||
re->add_room_list()->CopyFrom(room->getInfo(false, true));
|
re->add_room_list()->CopyFrom(room->getInfo(false, true));
|
||||||
QListIterator<ServerInfo_Game> gameIterator(room->getGamesOfUser(QString::fromStdString(cmd.user_name())));
|
QListIterator<ServerInfo_Game> gameIterator(room->getGamesOfUser(QString::fromStdString(cmd.user_name())));
|
||||||
while (gameIterator.hasNext())
|
while (gameIterator.hasNext())
|
||||||
re->add_game_list()->CopyFrom(gameIterator.next());
|
re->add_game_list()->CopyFrom(gameIterator.next());
|
||||||
room->roomMutex.unlock();
|
room->gamesMutex.unlock();
|
||||||
}
|
}
|
||||||
server->serverMutex.unlock();
|
server->roomsLock.unlock();
|
||||||
|
|
||||||
rc.setResponseExtension(re);
|
rc.setResponseExtension(re);
|
||||||
return Response::RespOk;
|
return Response::RespOk;
|
||||||
|
@ -564,7 +601,7 @@ Response::ResponseCode Server_ProtocolHandler::cmdGetUserInfo(const Command_GetU
|
||||||
re->mutable_user_info()->CopyFrom(*userInfo);
|
re->mutable_user_info()->CopyFrom(*userInfo);
|
||||||
else {
|
else {
|
||||||
|
|
||||||
QMutexLocker locker(&server->serverMutex);
|
QReadLocker locker(&server->clientsLock);
|
||||||
|
|
||||||
ServerInfo_User_Container *infoSource;
|
ServerInfo_User_Container *infoSource;
|
||||||
if (server->getUsers().contains(userName))
|
if (server->getUsers().contains(userName))
|
||||||
|
@ -604,12 +641,11 @@ Response::ResponseCode Server_ProtocolHandler::cmdJoinRoom(const Command_JoinRoo
|
||||||
if (rooms.contains(cmd.room_id()))
|
if (rooms.contains(cmd.room_id()))
|
||||||
return Response::RespContextError;
|
return Response::RespContextError;
|
||||||
|
|
||||||
|
QReadLocker serverLocker(&server->roomsLock);
|
||||||
Server_Room *r = server->getRooms().value(cmd.room_id(), 0);
|
Server_Room *r = server->getRooms().value(cmd.room_id(), 0);
|
||||||
if (!r)
|
if (!r)
|
||||||
return Response::RespNameNotFound;
|
return Response::RespNameNotFound;
|
||||||
|
|
||||||
QMutexLocker serverLocker(&server->serverMutex);
|
|
||||||
QMutexLocker roomLocker(&r->roomMutex);
|
|
||||||
r->addClient(this);
|
r->addClient(this);
|
||||||
rooms.insert(r->getId(), r);
|
rooms.insert(r->getId(), r);
|
||||||
|
|
||||||
|
@ -630,14 +666,14 @@ Response::ResponseCode Server_ProtocolHandler::cmdListUsers(const Command_ListUs
|
||||||
return Response::RespLoginNeeded;
|
return Response::RespLoginNeeded;
|
||||||
|
|
||||||
Response_ListUsers *re = new Response_ListUsers;
|
Response_ListUsers *re = new Response_ListUsers;
|
||||||
server->serverMutex.lock();
|
server->clientsLock.lockForRead();
|
||||||
QMapIterator<QString, Server_ProtocolHandler *> userIterator = server->getUsers();
|
QMapIterator<QString, Server_ProtocolHandler *> userIterator = server->getUsers();
|
||||||
while (userIterator.hasNext())
|
while (userIterator.hasNext())
|
||||||
re->add_user_list()->CopyFrom(userIterator.next().value()->copyUserInfo(false));
|
re->add_user_list()->CopyFrom(userIterator.next().value()->copyUserInfo(false));
|
||||||
QMapIterator<QString, Server_AbstractUserInterface *> extIterator = server->getExternalUsers();
|
QMapIterator<QString, Server_AbstractUserInterface *> extIterator = server->getExternalUsers();
|
||||||
while (extIterator.hasNext())
|
while (extIterator.hasNext())
|
||||||
re->add_user_list()->CopyFrom(extIterator.next().value()->copyUserInfo(false));
|
re->add_user_list()->CopyFrom(extIterator.next().value()->copyUserInfo(false));
|
||||||
server->serverMutex.unlock();
|
server->clientsLock.unlock();
|
||||||
|
|
||||||
acceptsUserListChanges = true;
|
acceptsUserListChanges = true;
|
||||||
|
|
||||||
|
@ -675,7 +711,7 @@ Response::ResponseCode Server_ProtocolHandler::cmdRoomSay(const Command_RoomSay
|
||||||
}
|
}
|
||||||
msg.replace(QChar('\n'), QChar(' '));
|
msg.replace(QChar('\n'), QChar(' '));
|
||||||
|
|
||||||
room->say(this, msg);
|
room->say(QString::fromStdString(userInfo->name()), msg);
|
||||||
return Response::RespOk;
|
return Response::RespOk;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -683,7 +719,9 @@ Response::ResponseCode Server_ProtocolHandler::cmdCreateGame(const Command_Creat
|
||||||
{
|
{
|
||||||
if (authState == NotLoggedIn)
|
if (authState == NotLoggedIn)
|
||||||
return Response::RespLoginNeeded;
|
return Response::RespLoginNeeded;
|
||||||
|
|
||||||
|
QMutexLocker roomLocker(&room->gamesMutex);
|
||||||
|
|
||||||
if (server->getMaxGamesPerUser() > 0)
|
if (server->getMaxGamesPerUser() > 0)
|
||||||
if (room->getGamesCreatedByUser(QString::fromStdString(userInfo->name())) >= server->getMaxGamesPerUser())
|
if (room->getGamesCreatedByUser(QString::fromStdString(userInfo->name())) >= server->getMaxGamesPerUser())
|
||||||
return Response::RespContextError;
|
return Response::RespContextError;
|
||||||
|
@ -699,13 +737,14 @@ Response::ResponseCode Server_ProtocolHandler::cmdCreateGame(const Command_Creat
|
||||||
Server_Game *game = new Server_Game(this, server->getNextGameId(), description, QString::fromStdString(cmd.password()), cmd.max_players(), gameTypes, cmd.only_buddies(), cmd.only_registered(), cmd.spectators_allowed(), cmd.spectators_need_password(), cmd.spectators_can_talk(), cmd.spectators_see_everything(), room);
|
Server_Game *game = new Server_Game(this, server->getNextGameId(), description, QString::fromStdString(cmd.password()), cmd.max_players(), gameTypes, cmd.only_buddies(), cmd.only_registered(), cmd.spectators_allowed(), cmd.spectators_need_password(), cmd.spectators_can_talk(), cmd.spectators_see_everything(), room);
|
||||||
game->moveToThread(room->thread());
|
game->moveToThread(room->thread());
|
||||||
|
|
||||||
QMutexLocker gameListLocker(&gameListMutex);
|
|
||||||
game->gameMutex.lock();
|
game->gameMutex.lock();
|
||||||
room->addGame(game);
|
room->addGame(game);
|
||||||
|
|
||||||
Server_Player *creator = game->getPlayers().values().first();
|
Server_Player *creator = game->getPlayers().values().first();
|
||||||
|
|
||||||
games.insert(game->getGameId(), QPair<Server_Game *, Server_Player *>(game, creator));
|
gameListMutex.lock();
|
||||||
|
games.insert(game->getGameId(), QPair<int, int>(room->getId(), creator->getPlayerId()));
|
||||||
|
gameListMutex.unlock();
|
||||||
|
|
||||||
Event_GameJoined event1;
|
Event_GameJoined event1;
|
||||||
event1.set_game_id(game->getGameId());
|
event1.set_game_id(game->getGameId());
|
||||||
|
@ -738,21 +777,25 @@ Response::ResponseCode Server_ProtocolHandler::cmdJoinGame(const Command_JoinGam
|
||||||
if (authState == NotLoggedIn)
|
if (authState == NotLoggedIn)
|
||||||
return Response::RespLoginNeeded;
|
return Response::RespLoginNeeded;
|
||||||
|
|
||||||
QMutexLocker gameListLocker(&gameListMutex);
|
QMutexLocker locker(&gameListMutex);
|
||||||
|
|
||||||
if (games.contains(cmd.game_id()))
|
if (games.contains(cmd.game_id()))
|
||||||
return Response::RespContextError;
|
return Response::RespContextError;
|
||||||
|
|
||||||
|
room->gamesMutex.lock();
|
||||||
Server_Game *g = room->getGames().value(cmd.game_id());
|
Server_Game *g = room->getGames().value(cmd.game_id());
|
||||||
if (!g)
|
if (!g) {
|
||||||
|
room->gamesMutex.unlock();
|
||||||
return Response::RespNameNotFound;
|
return Response::RespNameNotFound;
|
||||||
|
}
|
||||||
|
|
||||||
QMutexLocker locker(&g->gameMutex);
|
g->gameMutex.lock();
|
||||||
|
|
||||||
Response::ResponseCode result = g->checkJoin(userInfo, QString::fromStdString(cmd.password()), cmd.spectator(), cmd.override_restrictions());
|
Response::ResponseCode result = g->checkJoin(userInfo, QString::fromStdString(cmd.password()), cmd.spectator(), cmd.override_restrictions());
|
||||||
if (result == Response::RespOk) {
|
if (result == Response::RespOk) {
|
||||||
Server_Player *player = g->addPlayer(this, cmd.spectator());
|
Server_Player *player = g->addPlayer(this, cmd.spectator());
|
||||||
games.insert(cmd.game_id(), QPair<Server_Game *, Server_Player *>(g, player));
|
|
||||||
|
games.insert(cmd.game_id(), QPair<int, int>(room->getId(), player->getPlayerId()));
|
||||||
|
|
||||||
Event_GameJoined event1;
|
Event_GameJoined event1;
|
||||||
event1.set_game_id(g->getGameId());
|
event1.set_game_id(g->getGameId());
|
||||||
|
@ -775,6 +818,10 @@ Response::ResponseCode Server_ProtocolHandler::cmdJoinGame(const Command_JoinGam
|
||||||
event2.set_active_phase(g->getActivePhase());
|
event2.set_active_phase(g->getActivePhase());
|
||||||
rc.enqueuePostResponseItem(ServerMessage::GAME_EVENT_CONTAINER, g->prepareGameEvent(event2, -1));
|
rc.enqueuePostResponseItem(ServerMessage::GAME_EVENT_CONTAINER, g->prepareGameEvent(event2, -1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
g->gameMutex.unlock();
|
||||||
|
room->gamesMutex.unlock();
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -88,11 +88,9 @@ class Command_ShutdownServer;
|
||||||
class Server_ProtocolHandler : public QObject, public Server_AbstractUserInterface {
|
class Server_ProtocolHandler : public QObject, public Server_AbstractUserInterface {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
protected:
|
protected:
|
||||||
QMap<int, QPair<Server_Game *, Server_Player *> > games;
|
QMap<int, QPair<int, int> > games; // gameId -> (roomId, playerId)
|
||||||
QMap<int, Server_Room *> rooms;
|
QMap<int, Server_Room *> rooms;
|
||||||
|
|
||||||
QPair<Server_Game *, Server_Player *> getGame(int gameId) const;
|
|
||||||
|
|
||||||
AuthenticationResult authState;
|
AuthenticationResult authState;
|
||||||
bool acceptsUserListChanges;
|
bool acceptsUserListChanges;
|
||||||
bool acceptsRoomListChanges;
|
bool acceptsRoomListChanges;
|
||||||
|
@ -100,6 +98,8 @@ protected:
|
||||||
void prepareDestroy();
|
void prepareDestroy();
|
||||||
int sessionId;
|
int sessionId;
|
||||||
private:
|
private:
|
||||||
|
QMutex gameListMutex;
|
||||||
|
|
||||||
QList<int> messageSizeOverTime, messageCountOverTime;
|
QList<int> messageSizeOverTime, messageCountOverTime;
|
||||||
int timeRunning, lastDataReceived;
|
int timeRunning, lastDataReceived;
|
||||||
QTimer *pingClock;
|
QTimer *pingClock;
|
||||||
|
@ -175,8 +175,6 @@ private slots:
|
||||||
signals:
|
signals:
|
||||||
void logDebugMessage(const QString &message, Server_ProtocolHandler *session);
|
void logDebugMessage(const QString &message, Server_ProtocolHandler *session);
|
||||||
public:
|
public:
|
||||||
QMutex gameListMutex;
|
|
||||||
|
|
||||||
Server_ProtocolHandler(Server *_server, QObject *parent = 0);
|
Server_ProtocolHandler(Server *_server, QObject *parent = 0);
|
||||||
~Server_ProtocolHandler();
|
~Server_ProtocolHandler();
|
||||||
void playerRemovedFromGame(Server_Game *game);
|
void playerRemovedFromGame(Server_Game *game);
|
||||||
|
|
|
@ -10,22 +10,25 @@
|
||||||
#include <google/protobuf/descriptor.h>
|
#include <google/protobuf/descriptor.h>
|
||||||
|
|
||||||
Server_Room::Server_Room(int _id, const QString &_name, const QString &_description, bool _autoJoin, const QString &_joinMessage, const QStringList &_gameTypes, Server *parent)
|
Server_Room::Server_Room(int _id, const QString &_name, const QString &_description, bool _autoJoin, const QString &_joinMessage, const QStringList &_gameTypes, Server *parent)
|
||||||
: QObject(parent), id(_id), name(_name), description(_description), autoJoin(_autoJoin), joinMessage(_joinMessage), gameTypes(_gameTypes), roomMutex(QMutex::Recursive)
|
: QObject(parent), id(_id), name(_name), description(_description), autoJoin(_autoJoin), joinMessage(_joinMessage), gameTypes(_gameTypes), gamesMutex(QMutex::Recursive)
|
||||||
{
|
{
|
||||||
connect(this, SIGNAL(gameListChanged(ServerInfo_Game)), this, SLOT(broadcastGameListUpdate(ServerInfo_Game)), Qt::QueuedConnection);
|
connect(this, SIGNAL(gameListChanged(ServerInfo_Game)), this, SLOT(broadcastGameListUpdate(ServerInfo_Game)), Qt::QueuedConnection);
|
||||||
}
|
}
|
||||||
|
|
||||||
Server_Room::~Server_Room()
|
Server_Room::~Server_Room()
|
||||||
{
|
{
|
||||||
QMutexLocker locker(&roomMutex);
|
|
||||||
qDebug("Server_Room destructor");
|
qDebug("Server_Room destructor");
|
||||||
|
|
||||||
|
gamesMutex.lock();
|
||||||
const QList<Server_Game *> gameList = games.values();
|
const QList<Server_Game *> gameList = games.values();
|
||||||
for (int i = 0; i < gameList.size(); ++i)
|
for (int i = 0; i < gameList.size(); ++i)
|
||||||
delete gameList[i];
|
delete gameList[i];
|
||||||
games.clear();
|
games.clear();
|
||||||
|
gamesMutex.unlock();
|
||||||
|
|
||||||
|
usersLock.lockForWrite();
|
||||||
userList.clear();
|
userList.clear();
|
||||||
|
usersLock.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
Server *Server_Room::getServer() const
|
Server *Server_Room::getServer() const
|
||||||
|
@ -35,12 +38,8 @@ Server *Server_Room::getServer() const
|
||||||
|
|
||||||
ServerInfo_Room Server_Room::getInfo(bool complete, bool showGameTypes, bool updating, bool includeExternalData) const
|
ServerInfo_Room Server_Room::getInfo(bool complete, bool showGameTypes, bool updating, bool includeExternalData) const
|
||||||
{
|
{
|
||||||
QMutexLocker locker(&roomMutex);
|
|
||||||
|
|
||||||
ServerInfo_Room result;
|
ServerInfo_Room result;
|
||||||
result.set_room_id(id);
|
result.set_room_id(id);
|
||||||
result.set_game_count(games.size() + externalGames.size());
|
|
||||||
result.set_player_count(userList.size() + externalUsers.size());
|
|
||||||
|
|
||||||
if (!updating) {
|
if (!updating) {
|
||||||
result.set_name(name.toStdString());
|
result.set_name(name.toStdString());
|
||||||
|
@ -48,6 +47,8 @@ ServerInfo_Room Server_Room::getInfo(bool complete, bool showGameTypes, bool upd
|
||||||
result.set_auto_join(autoJoin);
|
result.set_auto_join(autoJoin);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gamesMutex.lock();
|
||||||
|
result.set_game_count(games.size() + externalGames.size());
|
||||||
if (complete) {
|
if (complete) {
|
||||||
QMapIterator<int, Server_Game *> gameIterator(games);
|
QMapIterator<int, Server_Game *> gameIterator(games);
|
||||||
while (gameIterator.hasNext())
|
while (gameIterator.hasNext())
|
||||||
|
@ -57,7 +58,12 @@ ServerInfo_Room Server_Room::getInfo(bool complete, bool showGameTypes, bool upd
|
||||||
while (externalGameIterator.hasNext())
|
while (externalGameIterator.hasNext())
|
||||||
result.add_game_list()->CopyFrom(externalGameIterator.next().value());
|
result.add_game_list()->CopyFrom(externalGameIterator.next().value());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
gamesMutex.unlock();
|
||||||
|
|
||||||
|
usersLock.lockForRead();
|
||||||
|
result.set_player_count(userList.size() + externalUsers.size());
|
||||||
|
if (complete) {
|
||||||
for (int i = 0; i < userList.size(); ++i)
|
for (int i = 0; i < userList.size(); ++i)
|
||||||
result.add_user_list()->CopyFrom(userList[i]->copyUserInfo(false));
|
result.add_user_list()->CopyFrom(userList[i]->copyUserInfo(false));
|
||||||
if (includeExternalData) {
|
if (includeExternalData) {
|
||||||
|
@ -66,6 +72,8 @@ ServerInfo_Room Server_Room::getInfo(bool complete, bool showGameTypes, bool upd
|
||||||
result.add_user_list()->CopyFrom(externalUserIterator.next().value().copyUserInfo(false));
|
result.add_user_list()->CopyFrom(externalUserIterator.next().value().copyUserInfo(false));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
usersLock.unlock();
|
||||||
|
|
||||||
if (complete || showGameTypes)
|
if (complete || showGameTypes)
|
||||||
for (int i = 0; i < gameTypes.size(); ++i) {
|
for (int i = 0; i < gameTypes.size(); ++i) {
|
||||||
ServerInfo_GameType *gameTypeInfo = result.add_gametype_list();
|
ServerInfo_GameType *gameTypeInfo = result.add_gametype_list();
|
||||||
|
@ -90,18 +98,18 @@ void Server_Room::addClient(Server_ProtocolHandler *client)
|
||||||
event.mutable_user_info()->CopyFrom(client->copyUserInfo(false));
|
event.mutable_user_info()->CopyFrom(client->copyUserInfo(false));
|
||||||
sendRoomEvent(prepareRoomEvent(event));
|
sendRoomEvent(prepareRoomEvent(event));
|
||||||
|
|
||||||
roomMutex.lock();
|
usersLock.lockForWrite();
|
||||||
userList.append(client);
|
userList.append(client);
|
||||||
roomMutex.unlock();
|
usersLock.unlock();
|
||||||
|
|
||||||
emit roomInfoChanged(getInfo(false, false, true));
|
emit roomInfoChanged(getInfo(false, false, true));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Server_Room::removeClient(Server_ProtocolHandler *client)
|
void Server_Room::removeClient(Server_ProtocolHandler *client)
|
||||||
{
|
{
|
||||||
roomMutex.lock();
|
usersLock.lockForWrite();
|
||||||
userList.removeAt(userList.indexOf(client));
|
userList.removeAt(userList.indexOf(client));
|
||||||
roomMutex.unlock();
|
usersLock.unlock();
|
||||||
|
|
||||||
Event_LeaveRoom event;
|
Event_LeaveRoom event;
|
||||||
event.set_name(client->getUserInfo()->name());
|
event.set_name(client->getUserInfo()->name());
|
||||||
|
@ -112,23 +120,25 @@ void Server_Room::removeClient(Server_ProtocolHandler *client)
|
||||||
|
|
||||||
void Server_Room::addExternalUser(const ServerInfo_User &userInfo)
|
void Server_Room::addExternalUser(const ServerInfo_User &userInfo)
|
||||||
{
|
{
|
||||||
|
// This function is always called from the Server thread with server->roomsMutex locked.
|
||||||
ServerInfo_User_Container userInfoContainer(userInfo);
|
ServerInfo_User_Container userInfoContainer(userInfo);
|
||||||
Event_JoinRoom event;
|
Event_JoinRoom event;
|
||||||
event.mutable_user_info()->CopyFrom(userInfoContainer.copyUserInfo(false));
|
event.mutable_user_info()->CopyFrom(userInfoContainer.copyUserInfo(false));
|
||||||
sendRoomEvent(prepareRoomEvent(event), false);
|
sendRoomEvent(prepareRoomEvent(event), false);
|
||||||
|
|
||||||
roomMutex.lock();
|
usersLock.lockForWrite();
|
||||||
externalUsers.insert(QString::fromStdString(userInfo.name()), userInfoContainer);
|
externalUsers.insert(QString::fromStdString(userInfo.name()), userInfoContainer);
|
||||||
roomMutex.unlock();
|
usersLock.unlock();
|
||||||
|
|
||||||
emit roomInfoChanged(getInfo(false, false, true));
|
emit roomInfoChanged(getInfo(false, false, true));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Server_Room::removeExternalUser(const QString &name)
|
void Server_Room::removeExternalUser(const QString &name)
|
||||||
{
|
{
|
||||||
roomMutex.lock();
|
// This function is always called from the Server thread with server->roomsMutex locked.
|
||||||
|
usersLock.lockForWrite();
|
||||||
externalUsers.remove(name);
|
externalUsers.remove(name);
|
||||||
roomMutex.unlock();
|
usersLock.unlock();
|
||||||
|
|
||||||
Event_LeaveRoom event;
|
Event_LeaveRoom event;
|
||||||
event.set_name(name.toStdString());
|
event.set_name(name.toStdString());
|
||||||
|
@ -137,20 +147,34 @@ void Server_Room::removeExternalUser(const QString &name)
|
||||||
emit roomInfoChanged(getInfo(false, false, true));
|
emit roomInfoChanged(getInfo(false, false, true));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Server_Room::say(Server_ProtocolHandler *client, const QString &s)
|
void Server_Room::updateExternalGameList(const ServerInfo_Game &gameInfo)
|
||||||
|
{
|
||||||
|
// This function is always called from the Server thread with server->roomsMutex locked.
|
||||||
|
gamesMutex.lock();
|
||||||
|
if (!gameInfo.has_player_count() && externalGames.contains(gameInfo.game_id()))
|
||||||
|
externalGames.remove(gameInfo.game_id());
|
||||||
|
else
|
||||||
|
externalGames.insert(gameInfo.game_id(), gameInfo);
|
||||||
|
gamesMutex.unlock();
|
||||||
|
|
||||||
|
broadcastGameListUpdate(gameInfo, false);
|
||||||
|
emit roomInfoChanged(getInfo(false, false, true));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Server_Room::say(const QString &userName, const QString &s, bool sendToIsl)
|
||||||
{
|
{
|
||||||
Event_RoomSay event;
|
Event_RoomSay event;
|
||||||
event.set_name(client->getUserInfo()->name());
|
event.set_name(userName.toStdString());
|
||||||
event.set_message(s.toStdString());
|
event.set_message(s.toStdString());
|
||||||
sendRoomEvent(prepareRoomEvent(event));
|
sendRoomEvent(prepareRoomEvent(event), sendToIsl);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Server_Room::sendRoomEvent(RoomEvent *event, bool sendToIsl)
|
void Server_Room::sendRoomEvent(RoomEvent *event, bool sendToIsl)
|
||||||
{
|
{
|
||||||
roomMutex.lock();
|
usersLock.lockForRead();
|
||||||
for (int i = 0; i < userList.size(); ++i)
|
for (int i = 0; i < userList.size(); ++i)
|
||||||
userList[i]->sendProtocolItem(*event);
|
userList[i]->sendProtocolItem(*event);
|
||||||
roomMutex.unlock();
|
usersLock.unlock();
|
||||||
|
|
||||||
if (sendToIsl)
|
if (sendToIsl)
|
||||||
static_cast<Server *>(parent())->sendIslMessage(*event);
|
static_cast<Server *>(parent())->sendIslMessage(*event);
|
||||||
|
@ -158,16 +182,16 @@ void Server_Room::sendRoomEvent(RoomEvent *event, bool sendToIsl)
|
||||||
delete event;
|
delete event;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Server_Room::broadcastGameListUpdate(ServerInfo_Game gameInfo)
|
void Server_Room::broadcastGameListUpdate(ServerInfo_Game gameInfo, bool sendToIsl)
|
||||||
{
|
{
|
||||||
Event_ListGames event;
|
Event_ListGames event;
|
||||||
event.add_game_list()->CopyFrom(gameInfo);
|
event.add_game_list()->CopyFrom(gameInfo);
|
||||||
sendRoomEvent(prepareRoomEvent(event));
|
sendRoomEvent(prepareRoomEvent(event), sendToIsl);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Server_Room::addGame(Server_Game *game)
|
void Server_Room::addGame(Server_Game *game)
|
||||||
{
|
{
|
||||||
// Lock roomMutex and gameMutex before calling this
|
// Lock gamesMutex and gameMutex before calling this
|
||||||
|
|
||||||
connect(game, SIGNAL(gameInfoChanged(ServerInfo_Game)), this, SLOT(broadcastGameListUpdate(ServerInfo_Game)));
|
connect(game, SIGNAL(gameInfoChanged(ServerInfo_Game)), this, SLOT(broadcastGameListUpdate(ServerInfo_Game)));
|
||||||
games.insert(game->getGameId(), game);
|
games.insert(game->getGameId(), game);
|
||||||
|
@ -177,7 +201,7 @@ void Server_Room::addGame(Server_Game *game)
|
||||||
|
|
||||||
void Server_Room::removeGame(Server_Game *game)
|
void Server_Room::removeGame(Server_Game *game)
|
||||||
{
|
{
|
||||||
// No need to lock roomMutex or gameMutex. This method is only
|
// No need to lock gamesMutex or gameMutex. This method is only
|
||||||
// called from ~Server_Game, which locks both mutexes anyway beforehand.
|
// called from ~Server_Game, which locks both mutexes anyway beforehand.
|
||||||
|
|
||||||
disconnect(game, 0, this, 0);
|
disconnect(game, 0, this, 0);
|
||||||
|
@ -189,7 +213,7 @@ void Server_Room::removeGame(Server_Game *game)
|
||||||
|
|
||||||
int Server_Room::getGamesCreatedByUser(const QString &userName) const
|
int Server_Room::getGamesCreatedByUser(const QString &userName) const
|
||||||
{
|
{
|
||||||
QMutexLocker locker(&roomMutex);
|
QMutexLocker locker(&gamesMutex);
|
||||||
|
|
||||||
QMapIterator<int, Server_Game *> gamesIterator(games);
|
QMapIterator<int, Server_Game *> gamesIterator(games);
|
||||||
int result = 0;
|
int result = 0;
|
||||||
|
@ -201,6 +225,8 @@ int Server_Room::getGamesCreatedByUser(const QString &userName) const
|
||||||
|
|
||||||
QList<ServerInfo_Game> Server_Room::getGamesOfUser(const QString &userName) const
|
QList<ServerInfo_Game> Server_Room::getGamesOfUser(const QString &userName) const
|
||||||
{
|
{
|
||||||
|
QMutexLocker locker(&gamesMutex);
|
||||||
|
|
||||||
QList<ServerInfo_Game> result;
|
QList<ServerInfo_Game> result;
|
||||||
QMapIterator<int, Server_Game *> gamesIterator(games);
|
QMapIterator<int, Server_Game *> gamesIterator(games);
|
||||||
while (gamesIterator.hasNext()) {
|
while (gamesIterator.hasNext()) {
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QStringList>
|
#include <QStringList>
|
||||||
#include <QMutex>
|
#include <QMutex>
|
||||||
#include <QMetaType>
|
#include <QReadWriteLock>
|
||||||
#include "pb/serverinfo_room.pb.h"
|
#include "pb/serverinfo_room.pb.h"
|
||||||
#include "serverinfo_user_container.h"
|
#include "serverinfo_user_container.h"
|
||||||
|
|
||||||
|
@ -35,9 +35,10 @@ private:
|
||||||
QList<Server_ProtocolHandler *> userList;
|
QList<Server_ProtocolHandler *> userList;
|
||||||
QMap<QString, ServerInfo_User_Container> externalUsers;
|
QMap<QString, ServerInfo_User_Container> externalUsers;
|
||||||
private slots:
|
private slots:
|
||||||
void broadcastGameListUpdate(ServerInfo_Game gameInfo);
|
void broadcastGameListUpdate(ServerInfo_Game gameInfo, bool sendToIsl = true);
|
||||||
public:
|
public:
|
||||||
mutable QMutex roomMutex;
|
mutable QReadWriteLock usersLock;
|
||||||
|
mutable QMutex gamesMutex;
|
||||||
Server_Room(int _id, const QString &_name, const QString &_description, bool _autoJoin, const QString &_joinMessage, const QStringList &_gameTypes, Server *parent);
|
Server_Room(int _id, const QString &_name, const QString &_description, bool _autoJoin, const QString &_joinMessage, const QStringList &_gameTypes, Server *parent);
|
||||||
~Server_Room();
|
~Server_Room();
|
||||||
int getId() const { return id; }
|
int getId() const { return id; }
|
||||||
|
@ -57,8 +58,10 @@ public:
|
||||||
|
|
||||||
void addExternalUser(const ServerInfo_User &userInfo);
|
void addExternalUser(const ServerInfo_User &userInfo);
|
||||||
void removeExternalUser(const QString &name);
|
void removeExternalUser(const QString &name);
|
||||||
|
const QMap<QString, ServerInfo_User_Container> &getExternalUsers() const { return externalUsers; }
|
||||||
|
void updateExternalGameList(const ServerInfo_Game &gameInfo);
|
||||||
|
|
||||||
void say(Server_ProtocolHandler *client, const QString &s);
|
void say(const QString &userName, const QString &s, bool sendToIsl = true);
|
||||||
|
|
||||||
void addGame(Server_Game *game);
|
void addGame(Server_Game *game);
|
||||||
void removeGame(Server_Game *game);
|
void removeGame(Server_Game *game);
|
||||||
|
@ -67,7 +70,4 @@ public:
|
||||||
RoomEvent *prepareRoomEvent(const ::google::protobuf::Message &roomEvent);
|
RoomEvent *prepareRoomEvent(const ::google::protobuf::Message &roomEvent);
|
||||||
};
|
};
|
||||||
|
|
||||||
Q_DECLARE_METATYPE(ServerInfo_Game)
|
|
||||||
Q_DECLARE_METATYPE(ServerInfo_Room)
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -11,6 +11,10 @@
|
||||||
#include "pb/event_user_message.pb.h"
|
#include "pb/event_user_message.pb.h"
|
||||||
#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_join_room.pb.h"
|
||||||
|
#include "pb/event_leave_room.pb.h"
|
||||||
|
#include "pb/event_room_say.pb.h"
|
||||||
|
#include "pb/event_list_games.pb.h"
|
||||||
#include <google/protobuf/descriptor.h>
|
#include <google/protobuf/descriptor.h>
|
||||||
|
|
||||||
void IslInterface::sharedCtor(const QSslCertificate &cert, const QSslKey &privateKey)
|
void IslInterface::sharedCtor(const QSslCertificate &cert, const QSslKey &privateKey)
|
||||||
|
@ -19,7 +23,7 @@ void IslInterface::sharedCtor(const QSslCertificate &cert, const QSslKey &privat
|
||||||
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()), Qt::QueuedConnection);
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
@ -42,18 +46,31 @@ IslInterface::~IslInterface()
|
||||||
|
|
||||||
flushOutputBuffer();
|
flushOutputBuffer();
|
||||||
|
|
||||||
QStringList usersToDelete;
|
// As these signals are connected with Qt::QueuedConnection implicitly,
|
||||||
server->serverMutex.lock();
|
// we don't need to worry about them modifying the lists while we're iterating.
|
||||||
QMapIterator<QString, Server_AbstractUserInterface *> extUsers = server->getExternalUsers();
|
server->clientsLock.lockForRead();
|
||||||
|
QMapIterator<QString, Server_AbstractUserInterface *> extUsers(server->getExternalUsers());
|
||||||
while (extUsers.hasNext()) {
|
while (extUsers.hasNext()) {
|
||||||
extUsers.next();
|
extUsers.next();
|
||||||
if (extUsers.value()->getUserInfo()->server_id() == serverId)
|
if (extUsers.value()->getUserInfo()->server_id() == serverId)
|
||||||
usersToDelete.append(extUsers.key());
|
emit externalUserLeft(extUsers.key());
|
||||||
}
|
}
|
||||||
server->serverMutex.unlock();
|
server->clientsLock.unlock();
|
||||||
|
|
||||||
for (int i = 0; i < usersToDelete.size(); ++i)
|
server->roomsLock.lockForRead();
|
||||||
emit externalUserLeft(usersToDelete[i]);
|
QMapIterator<int, Server_Room *> roomIterator(server->getRooms());
|
||||||
|
while (roomIterator.hasNext()) {
|
||||||
|
Server_Room *room = roomIterator.next().value();
|
||||||
|
room->usersLock.lockForRead();
|
||||||
|
QMapIterator<QString, ServerInfo_User_Container> roomUsers(room->getExternalUsers());
|
||||||
|
while (roomUsers.hasNext()) {
|
||||||
|
roomUsers.next();
|
||||||
|
if (roomUsers.value().getUserInfo()->server_id() == serverId)
|
||||||
|
emit externalRoomUserLeft(room->getId(), roomUsers.key());
|
||||||
|
}
|
||||||
|
room->usersLock.unlock();
|
||||||
|
}
|
||||||
|
server->roomsLock.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
void IslInterface::initServer()
|
void IslInterface::initServer()
|
||||||
|
@ -98,15 +115,18 @@ void IslInterface::initServer()
|
||||||
Event_ServerCompleteList event;
|
Event_ServerCompleteList event;
|
||||||
event.set_server_id(server->getServerId());
|
event.set_server_id(server->getServerId());
|
||||||
|
|
||||||
server->serverMutex.lock();
|
server->clientsLock.lockForRead();
|
||||||
QMapIterator<QString, Server_ProtocolHandler *> userIterator(server->getUsers());
|
QMapIterator<QString, Server_ProtocolHandler *> userIterator(server->getUsers());
|
||||||
while (userIterator.hasNext())
|
while (userIterator.hasNext())
|
||||||
event.add_user_list()->CopyFrom(userIterator.next().value()->copyUserInfo(true, true));
|
event.add_user_list()->CopyFrom(userIterator.next().value()->copyUserInfo(true, true));
|
||||||
|
server->clientsLock.unlock();
|
||||||
|
|
||||||
|
server->roomsLock.lockForRead();
|
||||||
QMapIterator<int, Server_Room *> roomIterator(server->getRooms());
|
QMapIterator<int, Server_Room *> roomIterator(server->getRooms());
|
||||||
while (roomIterator.hasNext()) {
|
while (roomIterator.hasNext()) {
|
||||||
Server_Room *room = roomIterator.next().value();
|
Server_Room *room = roomIterator.next().value();
|
||||||
room->roomMutex.lock();
|
room->usersLock.lockForRead();
|
||||||
|
room->gamesMutex.lock();
|
||||||
event.add_room_list()->CopyFrom(room->getInfo(true, true, false, false));
|
event.add_room_list()->CopyFrom(room->getInfo(true, true, false, false));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -126,9 +146,12 @@ void IslInterface::initServer()
|
||||||
server->islLock.unlock();
|
server->islLock.unlock();
|
||||||
|
|
||||||
roomIterator.toFront();
|
roomIterator.toFront();
|
||||||
while (roomIterator.hasNext())
|
while (roomIterator.hasNext()) {
|
||||||
roomIterator.next().value()->roomMutex.unlock();
|
roomIterator.next();
|
||||||
server->serverMutex.unlock();
|
roomIterator.value()->gamesMutex.unlock();
|
||||||
|
roomIterator.value()->usersLock.unlock();
|
||||||
|
}
|
||||||
|
server->roomsLock.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
void IslInterface::initClient()
|
void IslInterface::initClient()
|
||||||
|
@ -161,7 +184,7 @@ void IslInterface::initClient()
|
||||||
deleteLater();
|
deleteLater();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
server->addIslInterface(serverId, this);
|
server->addIslInterface(serverId, this);
|
||||||
server->islLock.unlock();
|
server->islLock.unlock();
|
||||||
}
|
}
|
||||||
|
@ -242,11 +265,24 @@ void IslInterface::sessionEvent_ServerCompleteList(const Event_ServerCompleteLis
|
||||||
temp.set_server_id(serverId);
|
temp.set_server_id(serverId);
|
||||||
emit externalUserJoined(temp);
|
emit externalUserJoined(temp);
|
||||||
}
|
}
|
||||||
|
for (int i = 0; i < event.room_list_size(); ++i) {
|
||||||
|
const ServerInfo_Room &room = event.room_list(i);
|
||||||
|
for (int j = 0; j < room.user_list_size(); ++j) {
|
||||||
|
ServerInfo_User userInfo(room.user_list(j));
|
||||||
|
userInfo.set_server_id(serverId);
|
||||||
|
emit externalRoomUserJoined(room.room_id(), userInfo);
|
||||||
|
}
|
||||||
|
for (int j = 0; j < room.game_list_size(); ++j) {
|
||||||
|
ServerInfo_Game gameInfo(room.game_list(j));
|
||||||
|
gameInfo.set_server_id(serverId);
|
||||||
|
emit externalRoomGameListChanged(room.room_id(), gameInfo);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void IslInterface::sessionEvent_UserMessage(const SessionEvent &sessionEvent, const Event_UserMessage &event)
|
void IslInterface::sessionEvent_UserMessage(const SessionEvent &sessionEvent, const Event_UserMessage &event)
|
||||||
{
|
{
|
||||||
QMutexLocker locker(&server->serverMutex);
|
QReadLocker locker(&server->clientsLock);
|
||||||
|
|
||||||
Server_ProtocolHandler *userInterface = server->getUsers().value(QString::fromStdString(event.receiver_name()));
|
Server_ProtocolHandler *userInterface = server->getUsers().value(QString::fromStdString(event.receiver_name()));
|
||||||
if (userInterface)
|
if (userInterface)
|
||||||
|
@ -255,7 +291,9 @@ void IslInterface::sessionEvent_UserMessage(const SessionEvent &sessionEvent, co
|
||||||
|
|
||||||
void IslInterface::sessionEvent_UserJoined(const Event_UserJoined &event)
|
void IslInterface::sessionEvent_UserJoined(const Event_UserJoined &event)
|
||||||
{
|
{
|
||||||
emit externalUserJoined(event.user_info());
|
ServerInfo_User userInfo(event.user_info());
|
||||||
|
userInfo.set_server_id(serverId);
|
||||||
|
emit externalUserJoined(userInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
void IslInterface::sessionEvent_UserLeft(const Event_UserLeft &event)
|
void IslInterface::sessionEvent_UserLeft(const Event_UserLeft &event)
|
||||||
|
@ -263,6 +301,32 @@ void IslInterface::sessionEvent_UserLeft(const Event_UserLeft &event)
|
||||||
emit externalUserLeft(QString::fromStdString(event.name()));
|
emit externalUserLeft(QString::fromStdString(event.name()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void IslInterface::roomEvent_UserJoined(int roomId, const Event_JoinRoom &event)
|
||||||
|
{
|
||||||
|
ServerInfo_User userInfo(event.user_info());
|
||||||
|
userInfo.set_server_id(serverId);
|
||||||
|
emit externalRoomUserJoined(roomId, userInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
void IslInterface::roomEvent_UserLeft(int roomId, const Event_LeaveRoom &event)
|
||||||
|
{
|
||||||
|
emit externalRoomUserLeft(roomId, QString::fromStdString(event.name()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void IslInterface::roomEvent_Say(int roomId, const Event_RoomSay &event)
|
||||||
|
{
|
||||||
|
emit externalRoomSay(roomId, QString::fromStdString(event.name()), QString::fromStdString(event.message()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void IslInterface::roomEvent_ListGames(int roomId, const Event_ListGames &event)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < event.game_list_size(); ++i) {
|
||||||
|
ServerInfo_Game gameInfo(event.game_list(i));
|
||||||
|
gameInfo.set_server_id(serverId);
|
||||||
|
emit externalRoomGameListChanged(roomId, gameInfo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void IslInterface::processSessionEvent(const SessionEvent &event)
|
void IslInterface::processSessionEvent(const SessionEvent &event)
|
||||||
{
|
{
|
||||||
switch (getPbExtension(event)) {
|
switch (getPbExtension(event)) {
|
||||||
|
@ -274,6 +338,17 @@ void IslInterface::processSessionEvent(const SessionEvent &event)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void IslInterface::processRoomEvent(const RoomEvent &event)
|
||||||
|
{
|
||||||
|
switch (getPbExtension(event)) {
|
||||||
|
case RoomEvent::JOIN_ROOM: roomEvent_UserJoined(event.room_id(), event.GetExtension(Event_JoinRoom::ext)); break;
|
||||||
|
case RoomEvent::LEAVE_ROOM: roomEvent_UserLeft(event.room_id(), event.GetExtension(Event_LeaveRoom::ext)); break;
|
||||||
|
case RoomEvent::ROOM_SAY: roomEvent_Say(event.room_id(), event.GetExtension(Event_RoomSay::ext)); break;
|
||||||
|
case RoomEvent::LIST_GAMES: roomEvent_ListGames(event.room_id(), event.GetExtension(Event_ListGames::ext)); break;
|
||||||
|
default: ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void IslInterface::processMessage(const IslMessage &item)
|
void IslInterface::processMessage(const IslMessage &item)
|
||||||
{
|
{
|
||||||
qDebug() << QString::fromStdString(item.DebugString());
|
qDebug() << QString::fromStdString(item.DebugString());
|
||||||
|
@ -290,6 +365,7 @@ void IslInterface::processMessage(const IslMessage &item)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case IslMessage::ROOM_EVENT: {
|
case IslMessage::ROOM_EVENT: {
|
||||||
|
processRoomEvent(item.room_event()); break;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: ;
|
default: ;
|
||||||
|
|
|
@ -5,6 +5,8 @@
|
||||||
#include <QSslCertificate>
|
#include <QSslCertificate>
|
||||||
#include <QWaitCondition>
|
#include <QWaitCondition>
|
||||||
#include "pb/serverinfo_user.pb.h"
|
#include "pb/serverinfo_user.pb.h"
|
||||||
|
#include "pb/serverinfo_room.pb.h"
|
||||||
|
#include "pb/serverinfo_game.pb.h"
|
||||||
|
|
||||||
class Servatrice;
|
class Servatrice;
|
||||||
class QSslSocket;
|
class QSslSocket;
|
||||||
|
@ -15,6 +17,10 @@ class Event_ServerCompleteList;
|
||||||
class Event_UserMessage;
|
class Event_UserMessage;
|
||||||
class Event_UserJoined;
|
class Event_UserJoined;
|
||||||
class Event_UserLeft;
|
class Event_UserLeft;
|
||||||
|
class Event_JoinRoom;
|
||||||
|
class Event_LeaveRoom;
|
||||||
|
class Event_RoomSay;
|
||||||
|
class Event_ListGames;
|
||||||
|
|
||||||
class IslInterface : public QObject {
|
class IslInterface : public QObject {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
@ -26,7 +32,11 @@ signals:
|
||||||
void outputBufferChanged();
|
void outputBufferChanged();
|
||||||
|
|
||||||
void externalUserJoined(ServerInfo_User userInfo);
|
void externalUserJoined(ServerInfo_User userInfo);
|
||||||
void externalUserLeft(QString name);
|
void externalUserLeft(QString userName);
|
||||||
|
void externalRoomUserJoined(int roomId, ServerInfo_User userInfo);
|
||||||
|
void externalRoomUserLeft(int roomId, QString userName);
|
||||||
|
void externalRoomSay(int roomId, QString userName, QString message);
|
||||||
|
void externalRoomGameListChanged(int roomId, ServerInfo_Game gameInfo);
|
||||||
private:
|
private:
|
||||||
int serverId;
|
int serverId;
|
||||||
int socketDescriptor;
|
int socketDescriptor;
|
||||||
|
@ -47,7 +57,13 @@ private:
|
||||||
void sessionEvent_UserJoined(const Event_UserJoined &event);
|
void sessionEvent_UserJoined(const Event_UserJoined &event);
|
||||||
void sessionEvent_UserLeft(const Event_UserLeft &event);
|
void sessionEvent_UserLeft(const Event_UserLeft &event);
|
||||||
|
|
||||||
|
void roomEvent_UserJoined(int roomId, const Event_JoinRoom &event);
|
||||||
|
void roomEvent_UserLeft(int roomId, const Event_LeaveRoom &event);
|
||||||
|
void roomEvent_Say(int roomId, const Event_RoomSay &event);
|
||||||
|
void roomEvent_ListGames(int roomId, const Event_ListGames &event);
|
||||||
|
|
||||||
void processSessionEvent(const SessionEvent &event);
|
void processSessionEvent(const SessionEvent &event);
|
||||||
|
void processRoomEvent(const RoomEvent &event);
|
||||||
|
|
||||||
void processMessage(const IslMessage &item);
|
void processMessage(const IslMessage &item);
|
||||||
void sharedCtor(const QSslCertificate &cert, const QSslKey &privateKey);
|
void sharedCtor(const QSslCertificate &cert, const QSslKey &privateKey);
|
||||||
|
|
|
@ -35,7 +35,7 @@
|
||||||
|
|
||||||
RNG_Abstract *rng;
|
RNG_Abstract *rng;
|
||||||
ServerLogger *logger;
|
ServerLogger *logger;
|
||||||
ServerLoggerThread *loggerThread;
|
QThread *loggerThread;
|
||||||
|
|
||||||
void testRNG()
|
void testRNG()
|
||||||
{
|
{
|
||||||
|
@ -100,7 +100,11 @@ void sigSegvHandler(int sig)
|
||||||
logger->logMessage("CRASH: SIGSEGV");
|
logger->logMessage("CRASH: SIGSEGV");
|
||||||
else if (sig == SIGABRT)
|
else if (sig == SIGABRT)
|
||||||
logger->logMessage("CRASH: SIGABRT");
|
logger->logMessage("CRASH: SIGABRT");
|
||||||
|
|
||||||
|
logger->deleteLater();
|
||||||
|
loggerThread->wait();
|
||||||
delete loggerThread;
|
delete loggerThread;
|
||||||
|
|
||||||
raise(sig);
|
raise(sig);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -121,10 +125,13 @@ int main(int argc, char *argv[])
|
||||||
|
|
||||||
QSettings *settings = new QSettings("servatrice.ini", QSettings::IniFormat);
|
QSettings *settings = new QSettings("servatrice.ini", QSettings::IniFormat);
|
||||||
|
|
||||||
loggerThread = new ServerLoggerThread(settings->value("server/logfile").toString());
|
loggerThread = new QThread;
|
||||||
|
logger = new ServerLogger;
|
||||||
|
logger->moveToThread(loggerThread);
|
||||||
|
QObject::connect(logger, SIGNAL(destroyed()), loggerThread, SLOT(quit()));
|
||||||
|
|
||||||
loggerThread->start();
|
loggerThread->start();
|
||||||
loggerThread->waitForInit();
|
QMetaObject::invokeMethod(logger, "startLog", Qt::BlockingQueuedConnection, Q_ARG(QString, settings->value("server/logfile").toString()));
|
||||||
logger = loggerThread->getLogger();
|
|
||||||
|
|
||||||
qInstallMsgHandler(myMessageOutput2);
|
qInstallMsgHandler(myMessageOutput2);
|
||||||
#ifdef Q_OS_UNIX
|
#ifdef Q_OS_UNIX
|
||||||
|
@ -166,6 +173,9 @@ int main(int argc, char *argv[])
|
||||||
|
|
||||||
delete rng;
|
delete rng;
|
||||||
delete settings;
|
delete settings;
|
||||||
|
|
||||||
|
logger->deleteLater();
|
||||||
|
loggerThread->wait();
|
||||||
delete loggerThread;
|
delete loggerThread;
|
||||||
|
|
||||||
return retval;
|
return retval;
|
||||||
|
|
|
@ -87,30 +87,55 @@ Servatrice::Servatrice(QSettings *_settings, QObject *parent)
|
||||||
updateServerList();
|
updateServerList();
|
||||||
clearSessionTables();
|
clearSessionTables();
|
||||||
|
|
||||||
int size = settings->beginReadArray("rooms");
|
const QString roomMethod = settings->value("rooms/method").toString();
|
||||||
for (int i = 0; i < size; ++i) {
|
if (roomMethod == "sql") {
|
||||||
settings->setArrayIndex(i);
|
QSqlQuery query;
|
||||||
|
query.prepare("select id, name, descr, auto_join, join_message from " + dbPrefix + "_rooms order by id asc");
|
||||||
QStringList gameTypes;
|
execSqlQuery(query);
|
||||||
int size2 = settings->beginReadArray("game_types");
|
while (query.next()) {
|
||||||
for (int j = 0; j < size2; ++j) {
|
QSqlQuery query2;
|
||||||
settings->setArrayIndex(j);
|
query2.prepare("select name from " + dbPrefix + "_rooms_gametypes where id_room = :id_room");
|
||||||
gameTypes.append(settings->value("name").toString());
|
query2.bindValue(":id_room", query.value(0).toInt());
|
||||||
|
execSqlQuery(query2);
|
||||||
|
QStringList gameTypes;
|
||||||
|
while (query2.next())
|
||||||
|
gameTypes.append(query2.value(0).toString());
|
||||||
|
|
||||||
|
addRoom(new Server_Room(query.value(0).toInt(),
|
||||||
|
query.value(1).toString(),
|
||||||
|
query.value(2).toString(),
|
||||||
|
query.value(3).toInt(),
|
||||||
|
query.value(4).toString(),
|
||||||
|
gameTypes,
|
||||||
|
this
|
||||||
|
));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
int size = settings->beginReadArray("rooms/roomlist");
|
||||||
|
for (int i = 0; i < size; ++i) {
|
||||||
|
settings->setArrayIndex(i);
|
||||||
|
|
||||||
|
QStringList gameTypes;
|
||||||
|
int size2 = settings->beginReadArray("game_types");
|
||||||
|
for (int j = 0; j < size2; ++j) {
|
||||||
|
settings->setArrayIndex(j);
|
||||||
|
gameTypes.append(settings->value("name").toString());
|
||||||
|
}
|
||||||
|
settings->endArray();
|
||||||
|
|
||||||
|
Server_Room *newRoom = new Server_Room(
|
||||||
|
i,
|
||||||
|
settings->value("name").toString(),
|
||||||
|
settings->value("description").toString(),
|
||||||
|
settings->value("autojoin").toBool(),
|
||||||
|
settings->value("joinmessage").toString(),
|
||||||
|
gameTypes,
|
||||||
|
this
|
||||||
|
);
|
||||||
|
addRoom(newRoom);
|
||||||
}
|
}
|
||||||
settings->endArray();
|
settings->endArray();
|
||||||
|
|
||||||
Server_Room *newRoom = new Server_Room(
|
|
||||||
i,
|
|
||||||
settings->value("name").toString(),
|
|
||||||
settings->value("description").toString(),
|
|
||||||
settings->value("autojoin").toBool(),
|
|
||||||
settings->value("joinmessage").toString(),
|
|
||||||
gameTypes,
|
|
||||||
this
|
|
||||||
);
|
|
||||||
addRoom(newRoom);
|
|
||||||
}
|
}
|
||||||
settings->endArray();
|
|
||||||
|
|
||||||
updateLoginMessage();
|
updateLoginMessage();
|
||||||
|
|
||||||
|
@ -499,8 +524,8 @@ ServerInfo_User Servatrice::getUserData(const QString &name, bool withId)
|
||||||
|
|
||||||
int Servatrice::getUsersWithAddress(const QHostAddress &address) const
|
int Servatrice::getUsersWithAddress(const QHostAddress &address) const
|
||||||
{
|
{
|
||||||
QMutexLocker locker(&serverMutex);
|
|
||||||
int result = 0;
|
int result = 0;
|
||||||
|
QReadLocker locker(&clientsLock);
|
||||||
for (int i = 0; i < clients.size(); ++i)
|
for (int i = 0; i < clients.size(); ++i)
|
||||||
if (static_cast<ServerSocketInterface *>(clients[i])->getPeerAddress() == address)
|
if (static_cast<ServerSocketInterface *>(clients[i])->getPeerAddress() == address)
|
||||||
++result;
|
++result;
|
||||||
|
@ -509,8 +534,8 @@ int Servatrice::getUsersWithAddress(const QHostAddress &address) const
|
||||||
|
|
||||||
QList<ServerSocketInterface *> Servatrice::getUsersWithAddressAsList(const QHostAddress &address) const
|
QList<ServerSocketInterface *> Servatrice::getUsersWithAddressAsList(const QHostAddress &address) const
|
||||||
{
|
{
|
||||||
QMutexLocker locker(&serverMutex);
|
|
||||||
QList<ServerSocketInterface *> result;
|
QList<ServerSocketInterface *> result;
|
||||||
|
QReadLocker locker(&clientsLock);
|
||||||
for (int i = 0; i < clients.size(); ++i)
|
for (int i = 0; i < clients.size(); ++i)
|
||||||
if (static_cast<ServerSocketInterface *>(clients[i])->getPeerAddress() == address)
|
if (static_cast<ServerSocketInterface *>(clients[i])->getPeerAddress() == address)
|
||||||
result.append(static_cast<ServerSocketInterface *>(clients[i]));
|
result.append(static_cast<ServerSocketInterface *>(clients[i]));
|
||||||
|
@ -519,6 +544,8 @@ QList<ServerSocketInterface *> Servatrice::getUsersWithAddressAsList(const QHost
|
||||||
|
|
||||||
void Servatrice::clearSessionTables()
|
void Servatrice::clearSessionTables()
|
||||||
{
|
{
|
||||||
|
qDebug() << "Clearing previous sessions...";
|
||||||
|
|
||||||
lockSessionTables();
|
lockSessionTables();
|
||||||
QSqlQuery query;
|
QSqlQuery query;
|
||||||
query.prepare("update " + dbPrefix + "_sessions set end_time=now() where end_time is null and id_server = :id_server");
|
query.prepare("update " + dbPrefix + "_sessions set end_time=now() where end_time is null and id_server = :id_server");
|
||||||
|
@ -740,13 +767,13 @@ void Servatrice::storeGameInformation(int secondsElapsed, const QSet<QString> &a
|
||||||
|
|
||||||
SessionEvent *sessionEvent = Server_ProtocolHandler::prepareSessionEvent(replayEvent);
|
SessionEvent *sessionEvent = Server_ProtocolHandler::prepareSessionEvent(replayEvent);
|
||||||
allUsersIterator.toFront();
|
allUsersIterator.toFront();
|
||||||
serverMutex.lock();
|
clientsLock.lockForRead();
|
||||||
while (allUsersIterator.hasNext()) {
|
while (allUsersIterator.hasNext()) {
|
||||||
Server_ProtocolHandler *userHandler = users.value(allUsersIterator.next());
|
Server_ProtocolHandler *userHandler = users.value(allUsersIterator.next());
|
||||||
if (userHandler)
|
if (userHandler)
|
||||||
userHandler->sendProtocolItem(*sessionEvent);
|
userHandler->sendProtocolItem(*sessionEvent);
|
||||||
}
|
}
|
||||||
serverMutex.unlock();
|
clientsLock.unlock();
|
||||||
delete sessionEvent;
|
delete sessionEvent;
|
||||||
|
|
||||||
QMutexLocker locker(&dbMutex);
|
QMutexLocker locker(&dbMutex);
|
||||||
|
@ -790,8 +817,6 @@ void Servatrice::storeGameInformation(int secondsElapsed, const QSet<QString> &a
|
||||||
|
|
||||||
void Servatrice::scheduleShutdown(const QString &reason, int minutes)
|
void Servatrice::scheduleShutdown(const QString &reason, int minutes)
|
||||||
{
|
{
|
||||||
QMutexLocker locker(&serverMutex);
|
|
||||||
|
|
||||||
shutdownReason = reason;
|
shutdownReason = reason;
|
||||||
shutdownMinutes = minutes + 1;
|
shutdownMinutes = minutes + 1;
|
||||||
if (minutes > 0) {
|
if (minutes > 0) {
|
||||||
|
@ -818,8 +843,6 @@ void Servatrice::incRxBytes(quint64 num)
|
||||||
|
|
||||||
void Servatrice::shutdownTimeout()
|
void Servatrice::shutdownTimeout()
|
||||||
{
|
{
|
||||||
QMutexLocker locker(&serverMutex);
|
|
||||||
|
|
||||||
--shutdownMinutes;
|
--shutdownMinutes;
|
||||||
|
|
||||||
SessionEvent *se;
|
SessionEvent *se;
|
||||||
|
@ -833,9 +856,11 @@ void Servatrice::shutdownTimeout()
|
||||||
event.set_reason(Event_ConnectionClosed::SERVER_SHUTDOWN);
|
event.set_reason(Event_ConnectionClosed::SERVER_SHUTDOWN);
|
||||||
se = Server_ProtocolHandler::prepareSessionEvent(event);
|
se = Server_ProtocolHandler::prepareSessionEvent(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
clientsLock.lockForRead();
|
||||||
for (int i = 0; i < clients.size(); ++i)
|
for (int i = 0; i < clients.size(); ++i)
|
||||||
clients[i]->sendProtocolItem(*se);
|
clients[i]->sendProtocolItem(*se);
|
||||||
|
clientsLock.unlock();
|
||||||
delete se;
|
delete se;
|
||||||
|
|
||||||
if (!shutdownMinutes)
|
if (!shutdownMinutes)
|
||||||
|
@ -856,7 +881,10 @@ void Servatrice::addIslInterface(int serverId, IslInterface *interface)
|
||||||
islInterfaces.insert(serverId, interface);
|
islInterfaces.insert(serverId, interface);
|
||||||
connect(interface, SIGNAL(externalUserJoined(ServerInfo_User)), this, SLOT(externalUserJoined(ServerInfo_User)));
|
connect(interface, SIGNAL(externalUserJoined(ServerInfo_User)), this, SLOT(externalUserJoined(ServerInfo_User)));
|
||||||
connect(interface, SIGNAL(externalUserLeft(QString)), this, SLOT(externalUserLeft(QString)));
|
connect(interface, SIGNAL(externalUserLeft(QString)), this, SLOT(externalUserLeft(QString)));
|
||||||
connect(interface, SIGNAL(externalRoomUpdated(ServerInfo_Room)), this, SLOT(externalRoomUpdated(const ServerInfo_Room &)));
|
connect(interface, SIGNAL(externalRoomUserJoined(int, ServerInfo_User)), this, SLOT(externalRoomUserJoined(int, ServerInfo_User)));
|
||||||
|
connect(interface, SIGNAL(externalRoomUserLeft(int, QString)), this, SLOT(externalRoomUserLeft(int, QString)));
|
||||||
|
connect(interface, SIGNAL(externalRoomSay(int, QString, QString)), this, SLOT(externalRoomSay(int, QString, QString)));
|
||||||
|
connect(interface, SIGNAL(externalRoomGameListChanged(int, ServerInfo_Game)), this, SLOT(externalRoomGameListChanged(int, ServerInfo_Game)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Servatrice::removeIslInterface(int serverId)
|
void Servatrice::removeIslInterface(int serverId)
|
||||||
|
|
|
@ -26,7 +26,6 @@
|
||||||
#include <QSslKey>
|
#include <QSslKey>
|
||||||
#include <QHostAddress>
|
#include <QHostAddress>
|
||||||
#include <QReadWriteLock>
|
#include <QReadWriteLock>
|
||||||
#include <QMetaType>
|
|
||||||
#include "server.h"
|
#include "server.h"
|
||||||
|
|
||||||
class QSqlDatabase;
|
class QSqlDatabase;
|
||||||
|
@ -167,6 +166,4 @@ private:
|
||||||
QMap<int, IslInterface *> islInterfaces;
|
QMap<int, IslInterface *> islInterfaces;
|
||||||
};
|
};
|
||||||
|
|
||||||
Q_DECLARE_METATYPE(ServerInfo_User)
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -8,8 +8,17 @@
|
||||||
# include <sys/socket.h>
|
# include <sys/socket.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ServerLogger::ServerLogger(const QString &logFileName, QObject *parent)
|
ServerLogger::ServerLogger(QObject *parent)
|
||||||
: QObject(parent), flushRunning(false)
|
: QObject(parent), flushRunning(false)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
ServerLogger::~ServerLogger()
|
||||||
|
{
|
||||||
|
flushBuffer();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ServerLogger::startLog(const QString &logFileName)
|
||||||
{
|
{
|
||||||
if (!logFileName.isEmpty()) {
|
if (!logFileName.isEmpty()) {
|
||||||
logFile = new QFile("server.log", this);
|
logFile = new QFile("server.log", this);
|
||||||
|
@ -26,11 +35,6 @@ ServerLogger::ServerLogger(const QString &logFileName, QObject *parent)
|
||||||
connect(this, SIGNAL(sigFlushBuffer()), this, SLOT(flushBuffer()), Qt::QueuedConnection);
|
connect(this, SIGNAL(sigFlushBuffer()), this, SLOT(flushBuffer()), Qt::QueuedConnection);
|
||||||
}
|
}
|
||||||
|
|
||||||
ServerLogger::~ServerLogger()
|
|
||||||
{
|
|
||||||
flushBuffer();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ServerLogger::logMessage(QString message, void *caller)
|
void ServerLogger::logMessage(QString message, void *caller)
|
||||||
{
|
{
|
||||||
if (!logFile)
|
if (!logFile)
|
||||||
|
@ -98,34 +102,3 @@ void ServerLogger::handleSigHup()
|
||||||
|
|
||||||
QFile *ServerLogger::logFile;
|
QFile *ServerLogger::logFile;
|
||||||
int ServerLogger::sigHupFD[2];
|
int ServerLogger::sigHupFD[2];
|
||||||
|
|
||||||
ServerLoggerThread::ServerLoggerThread(const QString &_fileName, QObject *parent)
|
|
||||||
: QThread(parent), fileName(_fileName)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
ServerLoggerThread::~ServerLoggerThread()
|
|
||||||
{
|
|
||||||
quit();
|
|
||||||
wait();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ServerLoggerThread::run()
|
|
||||||
{
|
|
||||||
logger = new ServerLogger(fileName);
|
|
||||||
|
|
||||||
usleep(100);
|
|
||||||
initWaitCondition.wakeAll();
|
|
||||||
|
|
||||||
exec();
|
|
||||||
|
|
||||||
delete logger;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ServerLoggerThread::waitForInit()
|
|
||||||
{
|
|
||||||
QMutex mutex;
|
|
||||||
mutex.lock();
|
|
||||||
initWaitCondition.wait(&mutex);
|
|
||||||
mutex.unlock();
|
|
||||||
}
|
|
||||||
|
|
|
@ -14,10 +14,11 @@ class Server_ProtocolHandler;
|
||||||
class ServerLogger : public QObject {
|
class ServerLogger : public QObject {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
ServerLogger(const QString &logFileName, QObject *parent = 0);
|
ServerLogger(QObject *parent = 0);
|
||||||
~ServerLogger();
|
~ServerLogger();
|
||||||
static void hupSignalHandler(int unused);
|
static void hupSignalHandler(int unused);
|
||||||
public slots:
|
public slots:
|
||||||
|
void startLog(const QString &logFileName);
|
||||||
void logMessage(QString message, void *caller = 0);
|
void logMessage(QString message, void *caller = 0);
|
||||||
private slots:
|
private slots:
|
||||||
void handleSigHup();
|
void handleSigHup();
|
||||||
|
@ -33,19 +34,4 @@ private:
|
||||||
QMutex bufferMutex;
|
QMutex bufferMutex;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ServerLoggerThread : public QThread {
|
|
||||||
Q_OBJECT
|
|
||||||
private:
|
|
||||||
QString fileName;
|
|
||||||
ServerLogger *logger;
|
|
||||||
QWaitCondition initWaitCondition;
|
|
||||||
protected:
|
|
||||||
void run();
|
|
||||||
public:
|
|
||||||
ServerLoggerThread(const QString &_fileName, QObject *parent = 0);
|
|
||||||
~ServerLoggerThread();
|
|
||||||
ServerLogger *getLogger() const { return logger; }
|
|
||||||
void waitForInit();
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -642,6 +642,6 @@ Response::ResponseCode ServerSocketInterface::cmdUpdateServerMessage(const Comma
|
||||||
|
|
||||||
Response::ResponseCode ServerSocketInterface::cmdShutdownServer(const Command_ShutdownServer &cmd, ResponseContainer & /*rc*/)
|
Response::ResponseCode ServerSocketInterface::cmdShutdownServer(const Command_ShutdownServer &cmd, ResponseContainer & /*rc*/)
|
||||||
{
|
{
|
||||||
servatrice->scheduleShutdown(QString::fromStdString(cmd.reason()), cmd.minutes());
|
QMetaObject::invokeMethod(server, "scheduleShutdown", Q_ARG(QString, QString::fromStdString(cmd.reason())), Q_ARG(int, cmd.minutes()));
|
||||||
return Response::RespOk;
|
return Response::RespOk;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue