more ISL code, mutex fixes
This commit is contained in:
parent
0ae18d7b2e
commit
572e4eaafa
9 changed files with 107 additions and 48 deletions
|
@ -34,6 +34,8 @@
|
|||
Server::Server(QObject *parent)
|
||||
: QObject(parent), serverMutex(QMutex::Recursive), nextGameId(0), nextReplayId(0)
|
||||
{
|
||||
qRegisterMetaType<ServerInfo_Game>("ServerInfo_Game");
|
||||
qRegisterMetaType<ServerInfo_Room>("ServerInfo_Room");
|
||||
}
|
||||
|
||||
Server::~Server()
|
||||
|
@ -170,22 +172,22 @@ void Server::externalUserLeft(QString userName)
|
|||
clients[i]->sendProtocolItem(*se);
|
||||
}
|
||||
|
||||
void Server::broadcastRoomUpdate()
|
||||
void Server::broadcastRoomUpdate(const ServerInfo_Room &roomInfo, bool sendToIsl)
|
||||
{
|
||||
QMutexLocker locker(&serverMutex);
|
||||
Server_Room *room = static_cast<Server_Room *>(sender());
|
||||
Event_ListRooms event;
|
||||
|
||||
ServerInfo_Room *roomInfo = event.add_room_list();
|
||||
room->roomMutex.lock();
|
||||
roomInfo->CopyFrom(room->getInfo(false, false, true));
|
||||
room->roomMutex.unlock();
|
||||
event.add_room_list()->CopyFrom(roomInfo);
|
||||
|
||||
SessionEvent *se = Server_ProtocolHandler::prepareSessionEvent(event);
|
||||
|
||||
serverMutex.lock();
|
||||
for (int i = 0; i < clients.size(); ++i)
|
||||
if (clients[i]->getAcceptsRoomListChanges())
|
||||
clients[i]->sendProtocolItem(*se);
|
||||
serverMutex.unlock();
|
||||
|
||||
if (sendToIsl)
|
||||
sendIslMessage(*se);
|
||||
|
||||
delete se;
|
||||
}
|
||||
|
||||
|
@ -193,7 +195,7 @@ void Server::addRoom(Server_Room *newRoom)
|
|||
{
|
||||
QMutexLocker locker(&serverMutex);
|
||||
rooms.insert(newRoom->getId(), newRoom);
|
||||
connect(newRoom, SIGNAL(roomInfoChanged()), this, SLOT(broadcastRoomUpdate()));
|
||||
connect(newRoom, SIGNAL(roomInfoChanged(ServerInfo_Room)), this, SLOT(broadcastRoomUpdate(const ServerInfo_Room &)), Qt::QueuedConnection);
|
||||
}
|
||||
|
||||
int Server::getUsersCount() const
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include <QMap>
|
||||
#include <QMutex>
|
||||
#include "pb/serverinfo_user.pb.h"
|
||||
#include "pb/serverinfo_room.pb.h"
|
||||
|
||||
class Server_Game;
|
||||
class Server_Room;
|
||||
|
@ -26,7 +27,7 @@ class Server : public QObject
|
|||
signals:
|
||||
void pingClockTimeout();
|
||||
private slots:
|
||||
void broadcastRoomUpdate();
|
||||
void broadcastRoomUpdate(const ServerInfo_Room &roomInfo, bool sendToIsl = false);
|
||||
public:
|
||||
mutable QMutex serverMutex;
|
||||
Server(QObject *parent = 0);
|
||||
|
@ -68,6 +69,7 @@ public:
|
|||
protected slots:
|
||||
void externalUserJoined(ServerInfo_User userInfo);
|
||||
void externalUserLeft(QString userName);
|
||||
void externalRoomUpdated(ServerInfo_Room roomInfo);
|
||||
protected:
|
||||
void prepareDestroy();
|
||||
QList<Server_ProtocolHandler *> clients;
|
||||
|
|
|
@ -271,7 +271,7 @@ void Server_Game::doStartGameIfReady()
|
|||
nextTurn();
|
||||
|
||||
locker.unlock();
|
||||
room->broadcastGameListUpdate(this);
|
||||
emit gameInfoChanged(getInfo());
|
||||
}
|
||||
|
||||
void Server_Game::startGameIfReady()
|
||||
|
@ -364,7 +364,7 @@ Server_Player *Server_Game::addPlayer(Server_ProtocolHandler *handler, bool spec
|
|||
}
|
||||
|
||||
if (broadcastUpdate)
|
||||
room->broadcastGameListUpdate(this);
|
||||
emit gameInfoChanged(getInfo());
|
||||
|
||||
return newPlayer;
|
||||
}
|
||||
|
@ -409,7 +409,7 @@ void Server_Game::removePlayer(Server_Player *player)
|
|||
if (gameStarted && playerActive)
|
||||
nextTurn();
|
||||
}
|
||||
room->broadcastGameListUpdate(this);
|
||||
emit gameInfoChanged(getInfo());
|
||||
}
|
||||
|
||||
void Server_Game::removeArrowsToPlayer(GameEventStorage &ges, Server_Player *player)
|
||||
|
|
|
@ -67,6 +67,7 @@ private:
|
|||
GameReplay *currentReplay;
|
||||
signals:
|
||||
void sigStartGameIfReady();
|
||||
void gameInfoChanged(ServerInfo_Game gameInfo);
|
||||
private slots:
|
||||
void pingClockTimeout();
|
||||
void doStartGameIfReady();
|
||||
|
|
|
@ -695,11 +695,16 @@ Response::ResponseCode Server_ProtocolHandler::cmdCreateGame(const Command_Creat
|
|||
QString description = QString::fromStdString(cmd.description());
|
||||
if (description.size() > 60)
|
||||
description = description.left(60);
|
||||
Server_Game *game = room->createGame(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(), this);
|
||||
|
||||
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());
|
||||
|
||||
QMutexLocker gameListLocker(&gameListMutex);
|
||||
game->gameMutex.lock();
|
||||
room->addGame(game);
|
||||
|
||||
Server_Player *creator = game->getPlayers().values().first();
|
||||
|
||||
QMutexLocker gameListLocker(&gameListMutex);
|
||||
games.insert(game->getGameId(), QPair<Server_Game *, Server_Player *>(game, creator));
|
||||
|
||||
Event_GameJoined event1;
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
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)
|
||||
{
|
||||
connect(this, SIGNAL(gameListChanged(ServerInfo_Game)), this, SLOT(broadcastGameListUpdate(ServerInfo_Game)), Qt::QueuedConnection);
|
||||
}
|
||||
|
||||
Server_Room::~Server_Room()
|
||||
|
@ -32,14 +33,14 @@ Server *Server_Room::getServer() const
|
|||
return static_cast<Server *>(parent());
|
||||
}
|
||||
|
||||
ServerInfo_Room Server_Room::getInfo(bool complete, bool showGameTypes, bool updating) const
|
||||
ServerInfo_Room Server_Room::getInfo(bool complete, bool showGameTypes, bool updating, bool includeExternalData) const
|
||||
{
|
||||
QMutexLocker locker(&roomMutex);
|
||||
|
||||
ServerInfo_Room result;
|
||||
result.set_room_id(id);
|
||||
result.set_game_count(games.size());
|
||||
result.set_player_count(userList.size());
|
||||
result.set_game_count(games.size() + externalGames.size());
|
||||
result.set_player_count(userList.size() + externalUsers.size());
|
||||
|
||||
if (!updating) {
|
||||
result.set_name(name.toStdString());
|
||||
|
@ -51,9 +52,19 @@ ServerInfo_Room Server_Room::getInfo(bool complete, bool showGameTypes, bool upd
|
|||
QMapIterator<int, Server_Game *> gameIterator(games);
|
||||
while (gameIterator.hasNext())
|
||||
result.add_game_list()->CopyFrom(gameIterator.next().value()->getInfo());
|
||||
if (includeExternalData) {
|
||||
QMapIterator<int, ServerInfo_Game> externalGameIterator(externalGames);
|
||||
while (externalGameIterator.hasNext())
|
||||
result.add_game_list()->CopyFrom(externalGameIterator.next().value());
|
||||
}
|
||||
|
||||
for (int i = 0; i < userList.size(); ++i)
|
||||
result.add_user_list()->CopyFrom(userList[i]->copyUserInfo(false));
|
||||
if (includeExternalData) {
|
||||
QMapIterator<QString, ServerInfo_User_Container> externalUserIterator(externalUsers);
|
||||
while (externalUserIterator.hasNext())
|
||||
result.add_user_list()->CopyFrom(externalUserIterator.next().value().copyUserInfo(false));
|
||||
}
|
||||
}
|
||||
if (complete || showGameTypes)
|
||||
for (int i = 0; i < gameTypes.size(); ++i) {
|
||||
|
@ -83,7 +94,7 @@ void Server_Room::addClient(Server_ProtocolHandler *client)
|
|||
userList.append(client);
|
||||
roomMutex.unlock();
|
||||
|
||||
emit roomInfoChanged();
|
||||
emit roomInfoChanged(getInfo(false, false, true));
|
||||
}
|
||||
|
||||
void Server_Room::removeClient(Server_ProtocolHandler *client)
|
||||
|
@ -96,7 +107,34 @@ void Server_Room::removeClient(Server_ProtocolHandler *client)
|
|||
event.set_name(client->getUserInfo()->name());
|
||||
sendRoomEvent(prepareRoomEvent(event));
|
||||
|
||||
emit roomInfoChanged();
|
||||
emit roomInfoChanged(getInfo(false, false, true));
|
||||
}
|
||||
|
||||
void Server_Room::addExternalUser(const ServerInfo_User &userInfo)
|
||||
{
|
||||
ServerInfo_User_Container userInfoContainer(userInfo);
|
||||
Event_JoinRoom event;
|
||||
event.mutable_user_info()->CopyFrom(userInfoContainer.copyUserInfo(false));
|
||||
sendRoomEvent(prepareRoomEvent(event), false);
|
||||
|
||||
roomMutex.lock();
|
||||
externalUsers.insert(QString::fromStdString(userInfo.name()), userInfoContainer);
|
||||
roomMutex.unlock();
|
||||
|
||||
emit roomInfoChanged(getInfo(false, false, true));
|
||||
}
|
||||
|
||||
void Server_Room::removeExternalUser(const QString &name)
|
||||
{
|
||||
roomMutex.lock();
|
||||
externalUsers.remove(name);
|
||||
roomMutex.unlock();
|
||||
|
||||
Event_LeaveRoom event;
|
||||
event.set_name(name.toStdString());
|
||||
sendRoomEvent(prepareRoomEvent(event), false);
|
||||
|
||||
emit roomInfoChanged(getInfo(false, false, true));
|
||||
}
|
||||
|
||||
void Server_Room::say(Server_ProtocolHandler *client, const QString &s)
|
||||
|
@ -107,39 +145,34 @@ void Server_Room::say(Server_ProtocolHandler *client, const QString &s)
|
|||
sendRoomEvent(prepareRoomEvent(event));
|
||||
}
|
||||
|
||||
void Server_Room::sendRoomEvent(RoomEvent *event)
|
||||
void Server_Room::sendRoomEvent(RoomEvent *event, bool sendToIsl)
|
||||
{
|
||||
QMutexLocker locker(&roomMutex);
|
||||
|
||||
roomMutex.lock();
|
||||
for (int i = 0; i < userList.size(); ++i)
|
||||
userList[i]->sendProtocolItem(*event);
|
||||
roomMutex.unlock();
|
||||
|
||||
if (sendToIsl)
|
||||
static_cast<Server *>(parent())->sendIslMessage(*event);
|
||||
|
||||
delete event;
|
||||
}
|
||||
|
||||
void Server_Room::broadcastGameListUpdate(Server_Game *game)
|
||||
void Server_Room::broadcastGameListUpdate(ServerInfo_Game gameInfo)
|
||||
{
|
||||
QMutexLocker locker(&roomMutex);
|
||||
|
||||
Event_ListGames event;
|
||||
event.add_game_list()->CopyFrom(game->getInfo());
|
||||
event.add_game_list()->CopyFrom(gameInfo);
|
||||
sendRoomEvent(prepareRoomEvent(event));
|
||||
}
|
||||
|
||||
Server_Game *Server_Room::createGame(const QString &description, const QString &password, int maxPlayers, const QList<int> &gameTypes, bool onlyBuddies, bool onlyRegistered, bool spectatorsAllowed, bool spectatorsNeedPassword, bool spectatorsCanTalk, bool spectatorsSeeEverything, Server_ProtocolHandler *creator)
|
||||
void Server_Room::addGame(Server_Game *game)
|
||||
{
|
||||
QMutexLocker locker(&roomMutex);
|
||||
// Lock roomMutex and gameMutex before calling this
|
||||
|
||||
Server_Game *newGame = new Server_Game(creator, static_cast<Server *>(parent())->getNextGameId(), description, password, maxPlayers, gameTypes, onlyBuddies, onlyRegistered, spectatorsAllowed, spectatorsNeedPassword, spectatorsCanTalk, spectatorsSeeEverything, this);
|
||||
newGame->moveToThread(thread());
|
||||
// This mutex needs to be unlocked by the caller.
|
||||
newGame->gameMutex.lock();
|
||||
games.insert(newGame->getGameId(), newGame);
|
||||
|
||||
broadcastGameListUpdate(newGame);
|
||||
|
||||
emit roomInfoChanged();
|
||||
|
||||
return newGame;
|
||||
connect(game, SIGNAL(gameInfoChanged(ServerInfo_Game)), this, SLOT(broadcastGameListUpdate(ServerInfo_Game)));
|
||||
games.insert(game->getGameId(), game);
|
||||
emit gameListChanged(game->getInfo());
|
||||
emit roomInfoChanged(getInfo(false, false, true));
|
||||
}
|
||||
|
||||
void Server_Room::removeGame(Server_Game *game)
|
||||
|
@ -147,10 +180,11 @@ void Server_Room::removeGame(Server_Game *game)
|
|||
// No need to lock roomMutex or gameMutex. This method is only
|
||||
// called from ~Server_Game, which locks both mutexes anyway beforehand.
|
||||
|
||||
broadcastGameListUpdate(game);
|
||||
disconnect(game, 0, this, 0);
|
||||
emit gameListChanged(game->getInfo());
|
||||
games.remove(game->getGameId());
|
||||
|
||||
emit roomInfoChanged();
|
||||
emit roomInfoChanged(getInfo(false, false, true));
|
||||
}
|
||||
|
||||
int Server_Room::getGamesCreatedByUser(const QString &userName) const
|
||||
|
|
|
@ -6,7 +6,9 @@
|
|||
#include <QObject>
|
||||
#include <QStringList>
|
||||
#include <QMutex>
|
||||
#include <QMetaType>
|
||||
#include "pb/serverinfo_room.pb.h"
|
||||
#include "serverinfo_user_container.h"
|
||||
|
||||
class Server_ProtocolHandler;
|
||||
class RoomEvent;
|
||||
|
@ -19,7 +21,8 @@ class Server;
|
|||
class Server_Room : public QObject {
|
||||
Q_OBJECT
|
||||
signals:
|
||||
void roomInfoChanged();
|
||||
void roomInfoChanged(ServerInfo_Room roomInfo);
|
||||
void gameListChanged(ServerInfo_Game gameInfo);
|
||||
private:
|
||||
int id;
|
||||
QString name;
|
||||
|
@ -28,7 +31,11 @@ private:
|
|||
QString joinMessage;
|
||||
QStringList gameTypes;
|
||||
QMap<int, Server_Game *> games;
|
||||
QMap<int, ServerInfo_Game> externalGames;
|
||||
QList<Server_ProtocolHandler *> userList;
|
||||
QMap<QString, ServerInfo_User_Container> externalUsers;
|
||||
private slots:
|
||||
void broadcastGameListUpdate(ServerInfo_Game gameInfo);
|
||||
public:
|
||||
mutable QMutex roomMutex;
|
||||
Server_Room(int _id, const QString &_name, const QString &_description, bool _autoJoin, const QString &_joinMessage, const QStringList &_gameTypes, Server *parent);
|
||||
|
@ -41,19 +48,26 @@ public:
|
|||
const QStringList &getGameTypes() const { return gameTypes; }
|
||||
const QMap<int, Server_Game *> &getGames() const { return games; }
|
||||
Server *getServer() const;
|
||||
ServerInfo_Room getInfo(bool complete, bool showGameTypes = false, bool updating = false) const;
|
||||
ServerInfo_Room getInfo(bool complete, bool showGameTypes = false, bool updating = false, bool includeExternalData = true) const;
|
||||
int getGamesCreatedByUser(const QString &name) const;
|
||||
QList<ServerInfo_Game> getGamesOfUser(const QString &name) const;
|
||||
|
||||
void addClient(Server_ProtocolHandler *client);
|
||||
void removeClient(Server_ProtocolHandler *client);
|
||||
|
||||
void addExternalUser(const ServerInfo_User &userInfo);
|
||||
void removeExternalUser(const QString &name);
|
||||
|
||||
void say(Server_ProtocolHandler *client, const QString &s);
|
||||
void broadcastGameListUpdate(Server_Game *game);
|
||||
Server_Game *createGame(const QString &description, const QString &password, int maxPlayers, const QList<int> &_gameTypes, bool onlyBuddies, bool onlyRegistered, bool spectatorsAllowed, bool spectatorsNeedPassword, bool spectatorsCanTalk, bool spectatorsSeeEverything, Server_ProtocolHandler *creator);
|
||||
|
||||
void addGame(Server_Game *game);
|
||||
void removeGame(Server_Game *game);
|
||||
|
||||
void sendRoomEvent(RoomEvent *event);
|
||||
void sendRoomEvent(RoomEvent *event, bool sendToIsl = true);
|
||||
RoomEvent *prepareRoomEvent(const ::google::protobuf::Message &roomEvent);
|
||||
};
|
||||
|
||||
Q_DECLARE_METATYPE(ServerInfo_Game)
|
||||
Q_DECLARE_METATYPE(ServerInfo_Room)
|
||||
|
||||
#endif
|
||||
|
|
|
@ -107,7 +107,7 @@ void IslInterface::initServer()
|
|||
while (roomIterator.hasNext()) {
|
||||
Server_Room *room = roomIterator.next().value();
|
||||
room->roomMutex.lock();
|
||||
event.add_room_list()->CopyFrom(room->getInfo(true, true, false));
|
||||
event.add_room_list()->CopyFrom(room->getInfo(true, true, false, false));
|
||||
}
|
||||
|
||||
IslMessage message;
|
||||
|
|
|
@ -856,6 +856,7 @@ void Servatrice::addIslInterface(int serverId, IslInterface *interface)
|
|||
islInterfaces.insert(serverId, interface);
|
||||
connect(interface, SIGNAL(externalUserJoined(ServerInfo_User)), this, SLOT(externalUserJoined(ServerInfo_User)));
|
||||
connect(interface, SIGNAL(externalUserLeft(QString)), this, SLOT(externalUserLeft(QString)));
|
||||
connect(interface, SIGNAL(externalRoomUpdated(ServerInfo_Room)), this, SLOT(externalRoomUpdated(const ServerInfo_Room &)));
|
||||
}
|
||||
|
||||
void Servatrice::removeIslInterface(int serverId)
|
||||
|
|
Loading…
Reference in a new issue