reduced game selector minimum height; server race conditions fixed

This commit is contained in:
Max-Wilhelm Bruker 2011-04-17 15:46:47 +02:00
parent 7ae0e31964
commit 2d8b12a576
9 changed files with 40 additions and 45 deletions

View file

@ -9,7 +9,7 @@ LocalServerInterface::LocalServerInterface(LocalServer *_server)
LocalServerInterface::~LocalServerInterface() LocalServerInterface::~LocalServerInterface()
{ {
server->removeClient(this); prepareDestroy();
} }
void LocalServerInterface::sendProtocolItem(ProtocolItem *item, bool deleteItem) void LocalServerInterface::sendProtocolItem(ProtocolItem *item, bool deleteItem)

View file

@ -49,7 +49,7 @@ GameSelector::GameSelector(AbstractClient *_client, TabRoom *_room, QWidget *par
setLayout(mainLayout); setLayout(mainLayout);
setMinimumWidth((qreal) (gameListView->columnWidth(0) * gameListModel->columnCount()) / 1.5); setMinimumWidth((qreal) (gameListView->columnWidth(0) * gameListModel->columnCount()) / 1.5);
setMinimumHeight(400); setMinimumHeight(200);
connect(showFullGamesCheckBox, SIGNAL(stateChanged(int)), this, SLOT(showFullGamesChanged(int))); connect(showFullGamesCheckBox, SIGNAL(stateChanged(int)), this, SLOT(showFullGamesChanged(int)));
connect(createButton, SIGNAL(clicked()), this, SLOT(actCreate())); connect(createButton, SIGNAL(clicked()), this, SLOT(actCreate()));

View file

@ -28,12 +28,12 @@
#include <QTimer> #include <QTimer>
#include <QDebug> #include <QDebug>
Server_Game::Server_Game(Server_ProtocolHandler *_creator, int _gameId, 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_Room *parent) Server_Game::Server_Game(Server_ProtocolHandler *_creator, int _gameId, 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_Room *_room)
: QObject(parent), creatorInfo(new ServerInfo_User(_creator->getUserInfo())), gameStarted(false), gameId(_gameId), description(_description), password(_password), maxPlayers(_maxPlayers), gameTypes(_gameTypes), activePlayer(-1), activePhase(-1), onlyBuddies(_onlyBuddies), onlyRegistered(_onlyRegistered), spectatorsAllowed(_spectatorsAllowed), spectatorsNeedPassword(_spectatorsNeedPassword), spectatorsCanTalk(_spectatorsCanTalk), spectatorsSeeEverything(_spectatorsSeeEverything), inactivityCounter(0), secondsElapsed(0), gameMutex(QMutex::Recursive) : QObject(), room(_room), creatorInfo(new ServerInfo_User(_creator->getUserInfo())), gameStarted(false), gameId(_gameId), description(_description), password(_password), maxPlayers(_maxPlayers), gameTypes(_gameTypes), activePlayer(-1), activePhase(-1), onlyBuddies(_onlyBuddies), onlyRegistered(_onlyRegistered), spectatorsAllowed(_spectatorsAllowed), spectatorsNeedPassword(_spectatorsNeedPassword), spectatorsCanTalk(_spectatorsCanTalk), spectatorsSeeEverything(_spectatorsSeeEverything), inactivityCounter(0), secondsElapsed(0), gameMutex(QMutex::Recursive)
{ {
addPlayer(_creator, false, false); addPlayer(_creator, false, false);
if (parent->getServer()->getGameShouldPing()) { if (room->getServer()->getGameShouldPing()) {
pingClock = new QTimer(this); pingClock = new QTimer(this);
connect(pingClock, SIGNAL(timeout()), this, SLOT(pingClockTimeout())); connect(pingClock, SIGNAL(timeout()), this, SLOT(pingClockTimeout()));
pingClock->start(1000); pingClock->start(1000);
@ -79,7 +79,7 @@ void Server_Game::pingClockTimeout()
} }
sendGameEvent(new Event_Ping(secondsElapsed, pingList)); sendGameEvent(new Event_Ping(secondsElapsed, pingList));
const int maxTime = static_cast<Server_Room *>(parent())->getServer()->getMaxGameInactivityTime(); const int maxTime = room->getServer()->getMaxGameInactivityTime();
if (allPlayersInactive) { if (allPlayersInactive) {
if (((++inactivityCounter >= maxTime) && (maxTime > 0)) || (playerCount < maxPlayers)) if (((++inactivityCounter >= maxTime) && (maxTime > 0)) || (playerCount < maxPlayers))
deleteLater(); deleteLater();
@ -193,9 +193,9 @@ ResponseCode Server_Game::checkJoin(ServerInfo_User *user, const QString &_passw
if (!(user->getUserLevel() & ServerInfo_User::IsRegistered) && onlyRegistered) if (!(user->getUserLevel() & ServerInfo_User::IsRegistered) && onlyRegistered)
return RespUserLevelTooLow; return RespUserLevelTooLow;
if (onlyBuddies) if (onlyBuddies)
if (!static_cast<Server_Room *>(parent())->getServer()->getBuddyList(creatorInfo->getName()).contains(user->getName())) if (!room->getServer()->getBuddyList(creatorInfo->getName()).contains(user->getName()))
return RespOnlyBuddies; return RespOnlyBuddies;
if (static_cast<Server_Room *>(parent())->getServer()->getIgnoreList(creatorInfo->getName()).contains(user->getName())) if (room->getServer()->getIgnoreList(creatorInfo->getName()).contains(user->getName()))
return RespInIgnoreList; return RespInIgnoreList;
if (spectator) { if (spectator) {
if (!spectatorsAllowed) if (!spectatorsAllowed)
@ -218,7 +218,7 @@ Server_Player *Server_Game::addPlayer(Server_ProtocolHandler *handler, bool spec
players.insert(playerId, newPlayer); players.insert(playerId, newPlayer);
if (broadcastUpdate) if (broadcastUpdate)
qobject_cast<Server_Room *>(parent())->broadcastGameListUpdate(this); room->broadcastGameListUpdate(this);
return newPlayer; return newPlayer;
} }
@ -242,7 +242,7 @@ void Server_Game::removePlayer(Server_Player *player)
if (gameStarted && playerActive) if (gameStarted && playerActive)
nextTurn(); nextTurn();
} }
qobject_cast<Server_Room *>(parent())->broadcastGameListUpdate(this); room->broadcastGameListUpdate(this);
} }
void Server_Game::removeArrowsToPlayer(Server_Player *player) void Server_Game::removeArrowsToPlayer(Server_Player *player)

View file

@ -34,6 +34,7 @@ class ServerInfo_User;
class Server_Game : public QObject { class Server_Game : public QObject {
Q_OBJECT Q_OBJECT
private: private:
Server_Room *room;
ServerInfo_User *creatorInfo; ServerInfo_User *creatorInfo;
QMap<int, Server_Player *> players; QMap<int, Server_Player *> players;
bool gameStarted; bool gameStarted;

View file

@ -17,11 +17,20 @@ Server_ProtocolHandler::Server_ProtocolHandler(Server *_server, QObject *parent)
: QObject(parent), server(_server), authState(PasswordWrong), acceptsUserListChanges(false), acceptsRoomListChanges(false), userInfo(0), timeRunning(0), lastDataReceived(0) : QObject(parent), server(_server), authState(PasswordWrong), acceptsUserListChanges(false), acceptsRoomListChanges(false), userInfo(0), timeRunning(0), lastDataReceived(0)
{ {
connect(server, SIGNAL(pingClockTimeout()), this, SLOT(pingClockTimeout())); connect(server, SIGNAL(pingClockTimeout()), this, SLOT(pingClockTimeout()));
connect(this, SIGNAL(sigGameCreated(Server_Game *)), this, SLOT(processSigGameCreated(Server_Game *)), Qt::QueuedConnection);
} }
Server_ProtocolHandler::~Server_ProtocolHandler() Server_ProtocolHandler::~Server_ProtocolHandler()
{ {
}
// This is essentially the destructor, but it needs to be called from the
// child's destructor with the server mutex locked. Otherwise, the mutex
// could get unlocked while the object is not finished being destroyed,
// leading to calls to pure virtual functions.
void Server_ProtocolHandler::prepareDestroy()
{
server->removeClient(this);
QMapIterator<int, Server_Room *> roomIterator(rooms); QMapIterator<int, Server_Room *> roomIterator(rooms);
while (roomIterator.hasNext()) while (roomIterator.hasNext())
roomIterator.next().value()->removeClient(this); roomIterator.next().value()->removeClient(this);
@ -423,24 +432,17 @@ ResponseCode Server_ProtocolHandler::cmdCreateGame(Command_CreateGame *cmd, Comm
for (int i = 0; i < gameTypeList.size(); ++i) for (int i = 0; i < gameTypeList.size(); ++i)
gameTypes.append(gameTypeList[i]->getData()); gameTypes.append(gameTypeList[i]->getData());
room->createGame(cmd->getDescription(), cmd->getPassword(), cmd->getMaxPlayers(), gameTypes, cmd->getOnlyBuddies(), cmd->getOnlyRegistered(), cmd->getSpectatorsAllowed(), cmd->getSpectatorsNeedPassword(), cmd->getSpectatorsCanTalk(), cmd->getSpectatorsSeeEverything(), this); Server_Game *game = room->createGame(cmd->getDescription(), cmd->getPassword(), cmd->getMaxPlayers(), gameTypes, cmd->getOnlyBuddies(), cmd->getOnlyRegistered(), cmd->getSpectatorsAllowed(), cmd->getSpectatorsNeedPassword(), cmd->getSpectatorsCanTalk(), cmd->getSpectatorsSeeEverything(), this);
return RespOk;
}
void Server_ProtocolHandler::gameCreated(Server_Game *game)
{
emit sigGameCreated(game);
}
void Server_ProtocolHandler::processSigGameCreated(Server_Game *game)
{
QMutexLocker locker(&game->gameMutex);
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)); games.insert(game->getGameId(), QPair<Server_Game *, Server_Player *>(game, creator));
sendProtocolItem(new Event_GameJoined(game->getGameId(), game->getDescription(), creator->getPlayerId(), false, game->getSpectatorsCanTalk(), game->getSpectatorsSeeEverything(), false)); sendProtocolItem(new Event_GameJoined(game->getGameId(), game->getDescription(), creator->getPlayerId(), false, game->getSpectatorsCanTalk(), game->getSpectatorsSeeEverything(), false));
sendProtocolItem(GameEventContainer::makeNew(new Event_GameStateChanged(game->getGameStarted(), game->getActivePlayer(), game->getActivePhase(), game->getGameState(creator)), game->getGameId())); sendProtocolItem(GameEventContainer::makeNew(new Event_GameStateChanged(game->getGameStarted(), game->getActivePlayer(), game->getActivePhase(), game->getGameState(creator)), game->getGameId()));
game->gameMutex.unlock();
return RespOk;
} }
ResponseCode Server_ProtocolHandler::cmdJoinGame(Command_JoinGame *cmd, CommandContainer * /*cont*/, Server_Room *room) ResponseCode Server_ProtocolHandler::cmdJoinGame(Command_JoinGame *cmd, CommandContainer * /*cont*/, Server_Room *room)
@ -455,6 +457,8 @@ ResponseCode Server_ProtocolHandler::cmdJoinGame(Command_JoinGame *cmd, CommandC
if (!g) if (!g)
return RespNameNotFound; return RespNameNotFound;
QMutexLocker locker(&g->gameMutex);
ResponseCode result = g->checkJoin(userInfo, cmd->getPassword(), cmd->getSpectator()); ResponseCode result = g->checkJoin(userInfo, cmd->getPassword(), cmd->getSpectator());
if (result == RespOk) { if (result == RespOk) {
Server_Player *player = g->addPlayer(this, cmd->getSpectator()); Server_Player *player = g->addPlayer(this, cmd->getSpectator());

View file

@ -28,6 +28,8 @@ protected:
bool acceptsRoomListChanges; bool acceptsRoomListChanges;
ServerInfo_User *userInfo; ServerInfo_User *userInfo;
QMap<QString, ServerInfo_User *> buddyList, ignoreList; QMap<QString, ServerInfo_User *> buddyList, ignoreList;
void prepareDestroy();
private: private:
QList<ProtocolItem *> itemQueue; QList<ProtocolItem *> itemQueue;
QList<int> messageSizeOverTime, messageCountOverTime; QList<int> messageSizeOverTime, messageCountOverTime;
@ -91,11 +93,7 @@ private:
ResponseCode processCommandHelper(Command *command, CommandContainer *cont); ResponseCode processCommandHelper(Command *command, CommandContainer *cont);
private slots: private slots:
void pingClockTimeout(); void pingClockTimeout();
void processSigGameCreated(Server_Game *game);
signals:
void sigGameCreated(Server_Game *game);
public: public:
mutable QMutex protocolHandlerMutex;
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);
@ -107,7 +105,6 @@ public:
const QMap<QString, ServerInfo_User *> &getBuddyList() const { return buddyList; } const QMap<QString, ServerInfo_User *> &getBuddyList() const { return buddyList; }
const QMap<QString, ServerInfo_User *> &getIgnoreList() const { return ignoreList; } const QMap<QString, ServerInfo_User *> &getIgnoreList() const { return ignoreList; }
void gameCreated(Server_Game *game);
int getLastCommandTime() const { return timeRunning - lastDataReceived; } int getLastCommandTime() const { return timeRunning - lastDataReceived; }
void processCommandContainer(CommandContainer *cont); void processCommandContainer(CommandContainer *cont);
virtual void sendProtocolItem(ProtocolItem *item, bool deleteItem = true) = 0; virtual void sendProtocolItem(ProtocolItem *item, bool deleteItem = true) = 0;

View file

@ -6,7 +6,6 @@
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), roomMutex(QMutex::Recursive)
{ {
connect(this, SIGNAL(sigCreateGame(const QString &, const QString &, int, const QList<int> &, bool, bool, bool, bool, bool, bool, Server_ProtocolHandler *)), this, SLOT(doCreateGame(const QString &, const QString &, int, const QList<int> &, bool, bool, bool, bool, bool, bool, Server_ProtocolHandler *)));
} }
Server *Server_Room::getServer() const Server *Server_Room::getServer() const
@ -79,24 +78,24 @@ void Server_Room::broadcastGameListUpdate(Server_Game *game)
delete event; delete event;
} }
void Server_Room::doCreateGame(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) 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)
{ {
QMutexLocker locker(&roomMutex); QMutexLocker locker(&roomMutex);
Server_Game *newGame = new Server_Game(creator, static_cast<Server *>(parent())->getNextGameId(), description, password, maxPlayers, gameTypes, onlyBuddies, onlyRegistered, spectatorsAllowed, spectatorsNeedPassword, spectatorsCanTalk, spectatorsSeeEverything, 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());
newGame->setParent(this);
// This mutex needs to be unlocked by the caller.
newGame->gameMutex.lock();
games.insert(newGame->getGameId(), newGame); games.insert(newGame->getGameId(), newGame);
connect(newGame, SIGNAL(gameClosing()), this, SLOT(removeGame())); connect(newGame, SIGNAL(gameClosing()), this, SLOT(removeGame()));
broadcastGameListUpdate(newGame); broadcastGameListUpdate(newGame);
creator->gameCreated(newGame);
emit gameCreated(newGame); emit gameCreated(newGame);
emit roomInfoChanged(); emit roomInfoChanged();
}
void 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) return newGame;
{
emit sigCreateGame(description, password, maxPlayers, gameTypes, onlyBuddies, onlyRegistered, spectatorsAllowed, spectatorsNeedPassword, spectatorsCanTalk, spectatorsSeeEverything, creator);
} }
void Server_Room::removeGame() void Server_Room::removeGame()

View file

@ -20,8 +20,6 @@ signals:
void roomInfoChanged(); void roomInfoChanged();
void gameCreated(Server_Game *game); void gameCreated(Server_Game *game);
void gameClosing(int gameId); void gameClosing(int gameId);
void sigCreateGame(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);
private: private:
int id; int id;
QString name; QString name;
@ -31,7 +29,6 @@ private:
QStringList gameTypes; QStringList gameTypes;
QMap<int, Server_Game *> games; QMap<int, Server_Game *> games;
private slots: private slots:
void doCreateGame(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 removeGame(); void removeGame();
public: public:
mutable QMutex roomMutex; mutable QMutex roomMutex;
@ -49,7 +46,7 @@ public:
void removeClient(Server_ProtocolHandler *client); void removeClient(Server_ProtocolHandler *client);
void say(Server_ProtocolHandler *client, const QString &s); void say(Server_ProtocolHandler *client, const QString &s);
void broadcastGameListUpdate(Server_Game *game); void broadcastGameListUpdate(Server_Game *game);
void 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); 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 sendRoomEvent(RoomEvent *event); void sendRoomEvent(RoomEvent *event);
}; };

View file

@ -69,8 +69,7 @@ ServerSocketInterface::~ServerSocketInterface()
delete socket; delete socket;
socket = 0; socket = 0;
// This call has to stay here so that the mutex is not freed prematurely. prepareDestroy();
server->removeClient(this);
} }
void ServerSocketInterface::processProtocolItem(ProtocolItem *item) void ServerSocketInterface::processProtocolItem(ProtocolItem *item)
@ -94,8 +93,6 @@ void ServerSocketInterface::flushXmlBuffer()
void ServerSocketInterface::readClient() void ServerSocketInterface::readClient()
{ {
QMutexLocker locker(&protocolHandlerMutex);
QByteArray data = socket->readAll(); QByteArray data = socket->readAll();
logger->logMessage(QString(data)); logger->logMessage(QString(data));
xmlReader->addData(data); xmlReader->addData(data);