Turn things in common into separate libs.

Took 2 hours 27 minutes
This commit is contained in:
Lukas Brübach 2025-10-04 15:10:20 +02:00
parent 53d80efab8
commit 01378b8314
389 changed files with 336 additions and 233 deletions

View file

@ -0,0 +1,183 @@
#ifndef ABSTRACT_PARTICIPANT_H
#define ABSTRACT_PARTICIPANT_H
#include "../serverinfo_user_container.h"
#include "pb/card_attributes.pb.h"
#include "pb/response.pb.h"
#include "server_arrowtarget.h"
#include <QMutex>
class Server_Game;
class Server_AbstractUserInterface;
class ServerInfo_User;
class ServerInfo_Player;
class ServerInfo_PlayerProperties;
class GameEventContainer;
class GameEventStorage;
class ResponseContainer;
class GameCommand;
class Command_KickFromGame;
class Command_LeaveGame;
class Command_GameSay;
class Command_Shuffle;
class Command_Mulligan;
class Command_RollDie;
class Command_DrawCards;
class Command_UndoDraw;
class Command_FlipCard;
class Command_AttachCard;
class Command_CreateToken;
class Command_CreateArrow;
class Command_DeleteArrow;
class Command_SetCardAttr;
class Command_SetCardCounter;
class Command_IncCardCounter;
class Command_ReadyStart;
class Command_Concede;
class Command_Unconcede;
class Command_Judge;
class Command_IncCounter;
class Command_CreateCounter;
class Command_SetCounter;
class Command_DelCounter;
class Command_NextTurn;
class Command_SetActivePhase;
class Command_DumpZone;
class Command_RevealCards;
class Command_ReverseTurn;
class Command_MoveCard;
class Command_SetSideboardPlan;
class Command_DeckSelect;
class Command_SetSideboardLock;
class Command_ChangeZoneProperties;
class Server_AbstractParticipant : public Server_ArrowTarget, public ServerInfo_User_Container
{
Q_OBJECT
protected:
Server_Game *game;
Server_AbstractUserInterface *userInterface;
int pingTime;
int playerId;
bool spectator;
bool judge;
virtual void getPlayerProperties(ServerInfo_PlayerProperties &result);
mutable QMutex playerMutex;
public:
Server_AbstractParticipant(Server_Game *_game,
int _playerId,
const ServerInfo_User &_userInfo,
bool _judge,
Server_AbstractUserInterface *_handler);
~Server_AbstractParticipant() override;
virtual void prepareDestroy()
{
removeFromGame();
};
void removeFromGame();
Server_AbstractUserInterface *getUserInterface() const
{
return userInterface;
}
void setUserInterface(Server_AbstractUserInterface *_userInterface);
void disconnectClient();
int getPlayerId() const
{
return playerId;
}
bool getSpectator() const
{
return spectator;
}
bool getJudge() const
{
return judge;
}
Server_Game *getGame() const
{
return game;
}
int getPingTime() const
{
return pingTime;
}
bool updatePingTime();
void getProperties(ServerInfo_PlayerProperties &result, bool withUserInfo);
virtual Response::ResponseCode
cmdLeaveGame(const Command_LeaveGame &cmd, ResponseContainer &rc, GameEventStorage &ges);
virtual Response::ResponseCode
cmdKickFromGame(const Command_KickFromGame &cmd, ResponseContainer &rc, GameEventStorage &ges);
virtual Response::ResponseCode cmdConcede(const Command_Concede &cmd, ResponseContainer &rc, GameEventStorage &ges);
virtual Response::ResponseCode
cmdUnconcede(const Command_Unconcede &cmd, ResponseContainer &rc, GameEventStorage &ges);
virtual Response::ResponseCode cmdJudge(const Command_Judge &cmd, ResponseContainer &rc, GameEventStorage &ges);
virtual Response::ResponseCode
cmdReadyStart(const Command_ReadyStart &cmd, ResponseContainer &rc, GameEventStorage &ges);
virtual Response::ResponseCode
cmdDeckSelect(const Command_DeckSelect &cmd, ResponseContainer &rc, GameEventStorage &ges);
virtual Response::ResponseCode
cmdSetSideboardPlan(const Command_SetSideboardPlan &cmd, ResponseContainer &rc, GameEventStorage &ges);
virtual Response::ResponseCode
cmdSetSideboardLock(const Command_SetSideboardLock &cmd, ResponseContainer &rc, GameEventStorage &ges);
virtual Response::ResponseCode cmdGameSay(const Command_GameSay &cmd, ResponseContainer &rc, GameEventStorage &ges);
virtual Response::ResponseCode cmdShuffle(const Command_Shuffle &cmd, ResponseContainer &rc, GameEventStorage &ges);
virtual Response::ResponseCode
cmdMulligan(const Command_Mulligan &cmd, ResponseContainer &rc, GameEventStorage &ges);
virtual Response::ResponseCode
cmdRollDie(const Command_RollDie &cmd, ResponseContainer &rc, GameEventStorage &ges) const;
virtual Response::ResponseCode
cmdDrawCards(const Command_DrawCards &cmd, ResponseContainer &rc, GameEventStorage &ges);
virtual Response::ResponseCode
cmdUndoDraw(const Command_UndoDraw &cmd, ResponseContainer &rc, GameEventStorage &ges);
virtual Response::ResponseCode
cmdMoveCard(const Command_MoveCard &cmd, ResponseContainer &rc, GameEventStorage &ges);
virtual Response::ResponseCode
cmdFlipCard(const Command_FlipCard &cmd, ResponseContainer &rc, GameEventStorage &ges);
virtual Response::ResponseCode
cmdAttachCard(const Command_AttachCard &cmd, ResponseContainer &rc, GameEventStorage &ges);
virtual Response::ResponseCode
cmdCreateToken(const Command_CreateToken &cmd, ResponseContainer &rc, GameEventStorage &ges);
virtual Response::ResponseCode
cmdCreateArrow(const Command_CreateArrow &cmd, ResponseContainer &rc, GameEventStorage &ges);
virtual Response::ResponseCode
cmdDeleteArrow(const Command_DeleteArrow &cmd, ResponseContainer &rc, GameEventStorage &ges);
virtual Response::ResponseCode
cmdSetCardAttr(const Command_SetCardAttr &cmd, ResponseContainer &rc, GameEventStorage &ges);
virtual Response::ResponseCode
cmdSetCardCounter(const Command_SetCardCounter &cmd, ResponseContainer &rc, GameEventStorage &ges);
virtual Response::ResponseCode
cmdIncCardCounter(const Command_IncCardCounter &cmd, ResponseContainer &rc, GameEventStorage &ges);
virtual Response::ResponseCode
cmdIncCounter(const Command_IncCounter &cmd, ResponseContainer &rc, GameEventStorage &ges);
virtual Response::ResponseCode
cmdCreateCounter(const Command_CreateCounter &cmd, ResponseContainer &rc, GameEventStorage &ges);
virtual Response::ResponseCode
cmdSetCounter(const Command_SetCounter &cmd, ResponseContainer &rc, GameEventStorage &ges);
virtual Response::ResponseCode
cmdDelCounter(const Command_DelCounter &cmd, ResponseContainer &rc, GameEventStorage &ges);
virtual Response::ResponseCode
cmdNextTurn(const Command_NextTurn &cmd, ResponseContainer &rc, GameEventStorage &ges);
virtual Response::ResponseCode
cmdSetActivePhase(const Command_SetActivePhase &cmd, ResponseContainer &rc, GameEventStorage &ges);
virtual Response::ResponseCode
cmdDumpZone(const Command_DumpZone &cmd, ResponseContainer &rc, GameEventStorage &ges);
virtual Response::ResponseCode
cmdRevealCards(const Command_RevealCards &cmd, ResponseContainer &rc, GameEventStorage &ges);
virtual Response::ResponseCode
cmdReverseTurn(const Command_ReverseTurn & /*cmd*/, ResponseContainer & /*rc*/, GameEventStorage &ges);
virtual Response::ResponseCode
cmdChangeZoneProperties(const Command_ChangeZoneProperties &cmd, ResponseContainer &rc, GameEventStorage &ges);
Response::ResponseCode processGameCommand(const GameCommand &command, ResponseContainer &rc, GameEventStorage &ges);
void sendGameEvent(const GameEventContainer &event);
virtual void
getInfo(ServerInfo_Player *info, Server_AbstractParticipant *recipient, bool omniscient, bool withUserInfo);
};
#endif

View file

@ -0,0 +1,52 @@
#ifndef SERVER_ARROW_H
#define SERVER_ARROW_H
#include "pb/color.pb.h"
class Server_Card;
class Server_ArrowTarget;
class ServerInfo_Arrow;
class Server_Arrow
{
private:
int id;
Server_Card *startCard;
Server_ArrowTarget *targetItem;
color arrowColor;
public:
Server_Arrow(int _id, Server_Card *_startCard, Server_ArrowTarget *_targetItem, const color &_arrowColor);
int getId() const
{
return id;
}
void setId(int _id)
{
id = _id;
}
Server_Card *getStartCard() const
{
return startCard;
}
void setStartCard(Server_Card *startCard_)
{
startCard = startCard_;
}
Server_ArrowTarget *getTargetItem() const
{
return targetItem;
}
void setTargetItem(Server_ArrowTarget *targetItem_)
{
targetItem = targetItem_;
}
const color &getColor() const
{
return arrowColor;
}
void getInfo(ServerInfo_Arrow *info);
};
#endif

View file

@ -0,0 +1,11 @@
#ifndef SERVER_ARROWTARGET_H
#define SERVER_ARROWTARGET_H
#include <QObject>
class Server_ArrowTarget : public QObject
{
Q_OBJECT
};
#endif

View file

@ -0,0 +1,227 @@
/***************************************************************************
* Copyright (C) 2008 by Max-Wilhelm Bruker *
* brukie@laptop *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#ifndef SERVER_CARD_H
#define SERVER_CARD_H
#include "pb/card_attributes.pb.h"
#include "pb/serverinfo_card.pb.h"
#include "server_arrowtarget.h"
#include "utility/card_ref.h"
#include <QMap>
#include <QString>
class Server_CardZone;
class Event_SetCardCounter;
class Event_SetCardAttr;
class Server_Card : public Server_ArrowTarget
{
Q_OBJECT
private:
Server_CardZone *zone;
int id;
int coord_x, coord_y;
CardRef cardRef;
QMap<int, int> counters;
bool tapped;
bool attacking;
bool facedown;
QString color;
QString ptString;
QString annotation;
bool destroyOnZoneChange;
bool doesntUntap;
Server_Card *parentCard;
QList<Server_Card *> attachedCards;
Server_Card *stashedCard;
public:
Server_Card(const CardRef &cardRef, int _id, int _coord_x, int _coord_y, Server_CardZone *_zone = nullptr);
~Server_Card() override;
Server_CardZone *getZone() const
{
return zone;
}
void setZone(Server_CardZone *_zone)
{
zone = _zone;
}
int getId() const
{
return id;
}
CardRef getCardRef() const
{
return cardRef;
}
QString getProviderId() const
{
return cardRef.providerId;
}
int getX() const
{
return coord_x;
}
int getY() const
{
return coord_y;
}
QString getName() const
{
return cardRef.name;
}
const QMap<int, int> &getCounters() const
{
return counters;
}
int getCounter(int counter_id) const
{
return counters.value(counter_id, 0);
}
bool getTapped() const
{
return tapped;
}
bool getAttacking() const
{
return attacking;
}
bool getFaceDown() const
{
return facedown;
}
QString getColor() const
{
return color;
}
QString getPT() const
{
return ptString;
}
QString getAnnotation() const
{
return annotation;
}
bool getDoesntUntap() const
{
return doesntUntap;
}
bool getDestroyOnZoneChange() const
{
return destroyOnZoneChange;
}
Server_Card *getParentCard() const
{
return parentCard;
}
const QList<Server_Card *> &getAttachedCards() const
{
return attachedCards;
}
void setId(int _id)
{
id = _id;
}
void setCoords(int x, int y)
{
coord_x = x;
coord_y = y;
}
void setCardRef(const CardRef &_cardRef)
{
cardRef = _cardRef;
}
void setCounter(int _id, int value, Event_SetCardCounter *event = nullptr);
void setTapped(bool _tapped)
{
tapped = _tapped;
}
void setAttacking(bool _attacking)
{
attacking = _attacking;
}
void setFaceDown(bool _facedown)
{
facedown = _facedown;
}
void setColor(const QString &_color)
{
color = _color;
}
void setPT(const QString &_pt)
{
ptString = _pt;
}
void setAnnotation(const QString &_annotation)
{
annotation = _annotation;
}
void setDestroyOnZoneChange(bool _destroy)
{
destroyOnZoneChange = _destroy;
}
void setDoesntUntap(bool _doesntUntap)
{
doesntUntap = _doesntUntap;
}
void setParentCard(Server_Card *_parentCard);
void addAttachedCard(Server_Card *card)
{
attachedCards.append(card);
}
void removeAttachedCard(Server_Card *card)
{
attachedCards.removeOne(card);
}
void setStashedCard(Server_Card *card)
{
// setStashedCard should only be called on creation of a new card, so
// there should never be an already existing stashed card.
Q_ASSERT(!stashedCard);
// Stashed cards can't themselves have stashed cards, and tokens can't
// be stashed.
if (card->stashedCard || card->getDestroyOnZoneChange()) {
stashedCard = card->takeStashedCard();
card->deleteLater();
} else {
stashedCard = card;
}
}
Server_Card *takeStashedCard()
{
Server_Card *oldStashedCard = stashedCard;
stashedCard = nullptr;
return oldStashedCard;
}
void resetState(bool keepAnnotations = false);
QString setAttribute(CardAttribute attribute, const QString &avalue, bool allCards);
QString setAttribute(CardAttribute attribute, const QString &avalue, Event_SetCardAttr *event = nullptr);
void getInfo(ServerInfo_Card *info);
};
#endif

View file

@ -0,0 +1,125 @@
/***************************************************************************
* Copyright (C) 2008 by Max-Wilhelm Bruker *
* brukie@laptop *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#ifndef SERVER_CARDZONE_H
#define SERVER_CARDZONE_H
#include "pb/serverinfo_zone.pb.h"
#include <QList>
#include <QMap>
#include <QSet>
#include <QString>
class Server_Card;
class Server_Player;
class Server_AbstractParticipant;
class Server_Game;
class GameEventStorage;
class Server_CardZone
{
private:
Server_Player *player;
QString name;
bool has_coords; // having coords means this zone has x and y coordinates
ServerInfo_Zone::ZoneType type;
int cardsBeingLookedAt;
QSet<int> playersWithWritePermission;
bool alwaysRevealTopCard;
bool alwaysLookAtTopCard;
QList<Server_Card *> cards;
QMap<int, QMap<int, Server_Card *>> coordinateMap; // y -> (x -> card)
QMap<int, QMultiMap<QString, int>> freePilesMap; // y -> (cardName -> x)
QMap<int, int> freeSpaceMap; // y -> x
void removeCardFromCoordMap(Server_Card *card, int oldX, int oldY);
void insertCardIntoCoordMap(Server_Card *card, int x, int y);
public:
Server_CardZone(Server_Player *_player, const QString &_name, bool _has_coords, ServerInfo_Zone::ZoneType _type);
~Server_CardZone();
const QList<Server_Card *> &getCards() const
{
return cards;
}
int removeCard(Server_Card *card);
int removeCard(Server_Card *card, bool &wasLookedAt);
Server_Card *getCard(int id, int *position = nullptr, bool remove = false);
int getCardsBeingLookedAt() const
{
return cardsBeingLookedAt;
}
void setCardsBeingLookedAt(int _cardsBeingLookedAt)
{
cardsBeingLookedAt = qMax(0, _cardsBeingLookedAt);
}
bool isCardAtPosLookedAt(int pos) const;
bool hasCoords() const
{
return has_coords;
}
ServerInfo_Zone::ZoneType getType() const
{
return type;
}
QString getName() const
{
return name;
}
Server_Player *getPlayer() const
{
return player;
}
void getInfo(ServerInfo_Zone *info, Server_AbstractParticipant *recipient, bool omniscient);
int getFreeGridColumn(int x, int y, const QString &cardName, bool dontStackSameName) const;
bool isColumnEmpty(int x, int y) const;
bool isColumnStacked(int x, int y) const;
void fixFreeSpaces(GameEventStorage &ges);
void moveCardInRow(GameEventStorage &ges, Server_Card *card, int x, int y);
void insertCard(Server_Card *card, int x, int y);
void updateCardCoordinates(Server_Card *card, int oldX, int oldY);
void shuffle(int start = 0, int end = -1);
void clear();
void addWritePermission(int playerId);
const QSet<int> &getPlayersWithWritePermission() const
{
return playersWithWritePermission;
}
bool getAlwaysRevealTopCard() const
{
return alwaysRevealTopCard;
}
void setAlwaysRevealTopCard(bool _alwaysRevealTopCard)
{
alwaysRevealTopCard = _alwaysRevealTopCard;
}
bool getAlwaysLookAtTopCard() const
{
return alwaysLookAtTopCard;
}
void setAlwaysLookAtTopCard(bool _alwaysLookAtTopCard)
{
alwaysLookAtTopCard = _alwaysLookAtTopCard;
}
};
#endif

View file

@ -0,0 +1,71 @@
/***************************************************************************
* Copyright (C) 2008 by Max-Wilhelm Bruker *
* brukie@laptop *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#ifndef SERVER_COUNTER_H
#define SERVER_COUNTER_H
#include "pb/color.pb.h"
#include <QString>
class ServerInfo_Counter;
class Server_Counter
{
protected:
int id;
QString name;
color counterColor;
int radius;
int count;
public:
Server_Counter(int _id, const QString &_name, const color &_counterColor, int _radius, int _count = 0);
~Server_Counter()
{
}
int getId() const
{
return id;
}
QString getName() const
{
return name;
}
const color &getColor() const
{
return counterColor;
}
int getRadius() const
{
return radius;
}
int getCount() const
{
return count;
}
void setCount(int _count)
{
count = _count;
}
void getInfo(ServerInfo_Counter *info);
};
#endif

View file

@ -0,0 +1,226 @@
/***************************************************************************
* Copyright (C) 2008 by Max-Wilhelm Bruker *
* brukie@laptop *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#ifndef SERVERGAME_H
#define SERVERGAME_H
#include "../server_response_containers.h"
#include "pb/event_leave.pb.h"
#include "pb/response.pb.h"
#include "pb/serverinfo_game.pb.h"
#include <QDateTime>
#include <QMap>
#include <QMutex>
#include <QObject>
#include <QSet>
#include <QStringList>
class QTimer;
class GameEventContainer;
class GameReplay;
class Server_Room;
class Server_Player;
class Server_AbstractParticipant;
class ServerInfo_User;
class ServerInfo_Game;
class Server_AbstractUserInterface;
class Event_GameStateChanged;
class Server_Game : public QObject
{
Q_OBJECT
private:
Server_Room *room;
int nextPlayerId;
int hostId;
ServerInfo_User *creatorInfo;
QMap<int, Server_AbstractParticipant *> participants;
QSet<QString> allPlayersEver, allSpectatorsEver;
bool gameStarted;
bool gameClosed;
int gameId;
QString description;
QString password;
int maxPlayers;
QList<int> gameTypes;
int activePlayer, activePhase;
bool onlyBuddies, onlyRegistered;
bool spectatorsAllowed;
bool spectatorsNeedPassword;
bool spectatorsCanTalk;
bool spectatorsSeeEverything;
int startingLifeTotal;
bool shareDecklistsOnLoad;
int inactivityCounter;
int startTimeOfThisGame, secondsElapsed;
bool firstGameStarted;
bool turnOrderReversed;
QDateTime startTime;
QTimer *pingClock;
QList<GameReplay *> replayList;
GameReplay *currentReplay;
void createGameStateChangedEvent(Event_GameStateChanged *event,
Server_AbstractParticipant *recipient,
bool omniscient,
bool withUserInfo);
void storeGameInformation();
signals:
void sigStartGameIfReady(bool override);
void gameInfoChanged(ServerInfo_Game gameInfo);
private slots:
void pingClockTimeout();
void doStartGameIfReady(bool forceStartGame = false);
public:
#if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0))
mutable QRecursiveMutex gameMutex;
#else
mutable QMutex gameMutex;
#endif
Server_Game(const ServerInfo_User &_creatorInfo,
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,
int _startingLifeTotal,
bool _shareDecklistsOnLoad,
Server_Room *parent);
~Server_Game() override;
Server_Room *getRoom() const
{
return room;
}
void getInfo(ServerInfo_Game &result) const;
int getHostId() const
{
return hostId;
}
ServerInfo_User *getCreatorInfo() const
{
return creatorInfo;
}
bool getGameStarted() const
{
return gameStarted;
}
int getPlayerCount() const;
int getSpectatorCount() const;
QMap<int, Server_Player *> getPlayers() const;
Server_Player *getPlayer(int id) const;
const QMap<int, Server_AbstractParticipant *> &getParticipants() const
{
return participants;
}
int getGameId() const
{
return gameId;
}
QString getDescription() const
{
return description;
}
QString getPassword() const
{
return password;
}
int getMaxPlayers() const
{
return maxPlayers;
}
bool getSpectatorsAllowed() const
{
return spectatorsAllowed;
}
bool getSpectatorsNeedPassword() const
{
return spectatorsNeedPassword;
}
bool getSpectatorsCanTalk() const
{
return spectatorsCanTalk;
}
bool getSpectatorsSeeEverything() const
{
return spectatorsSeeEverything;
}
int getStartingLifeTotal() const
{
return startingLifeTotal;
}
bool getShareDecklistsOnLoad() const
{
return shareDecklistsOnLoad;
}
Response::ResponseCode
checkJoin(ServerInfo_User *user, const QString &_password, bool spectator, bool overrideRestrictions, bool asJudge);
bool containsUser(const QString &userName) const;
void addPlayer(Server_AbstractUserInterface *userInterface,
ResponseContainer &rc,
bool spectator,
bool judge,
bool broadcastUpdate = true);
void removeParticipant(Server_AbstractParticipant *participant, Event_Leave::LeaveReason reason);
void removeArrowsRelatedToPlayer(GameEventStorage &ges, Server_Player *player);
void unattachCards(GameEventStorage &ges, Server_Player *player);
bool kickParticipant(int playerId);
void startGameIfReady(bool forceStartGame);
void stopGameIfFinished();
int getActivePlayer() const
{
return activePlayer;
}
int getActivePhase() const
{
return activePhase;
}
void setActivePlayer(int _activePlayer);
void setActivePhase(int _activePhase);
void nextTurn();
int getSecondsElapsed() const
{
return secondsElapsed;
}
bool reverseTurnOrder()
{
return turnOrderReversed = !turnOrderReversed;
}
void createGameJoinedEvent(Server_AbstractParticipant *participant, ResponseContainer &rc, bool resuming);
GameEventContainer *
prepareGameEvent(const ::google::protobuf::Message &gameEvent, int playerId, GameEventContext *context = 0);
GameEventContext prepareGameEventContext(const ::google::protobuf::Message &gameEventContext);
void sendGameStateToPlayers();
void sendGameEventContainer(GameEventContainer *cont,
GameEventStorageItem::EventRecipients recipients = GameEventStorageItem::SendToPrivate |
GameEventStorageItem::SendToOthers,
int privatePlayerId = -1);
};
#endif

View file

@ -0,0 +1,178 @@
#ifndef PLAYER_H
#define PLAYER_H
#include "../serverinfo_user_container.h"
#include "server_abstract_participant.h"
#include <QList>
#include <QMap>
#include <QString>
class DeckList;
class Server_CardZone;
class Server_Counter;
class Server_Arrow;
class Server_Card;
class CardToMove;
class Server_Player : public Server_AbstractParticipant
{
Q_OBJECT
private:
class MoveCardCompareFunctor;
DeckList *deck;
QMap<QString, Server_CardZone *> zones;
QMap<int, Server_Counter *> counters;
QMap<int, Server_Arrow *> arrows;
QList<int> lastDrawList;
int nextCardId;
bool readyStart;
bool conceded;
bool sideboardLocked;
void revealTopCardIfNeeded(Server_CardZone *zone, GameEventStorage &ges);
void sendCreateTokenEvents(Server_CardZone *zone, Server_Card *card, int xCoord, int yCoord, GameEventStorage &ges);
void getPlayerProperties(ServerInfo_PlayerProperties &result) override;
public:
Server_Player(Server_Game *_game,
int _playerId,
const ServerInfo_User &_userInfo,
bool _judge,
Server_AbstractUserInterface *_handler);
~Server_Player() override;
void prepareDestroy() override;
const DeckList *getDeckList() const
{
return deck;
}
bool getReadyStart() const
{
return readyStart;
}
void setReadyStart(bool _readyStart)
{
readyStart = _readyStart;
}
bool getConceded() const
{
return conceded;
}
void setConceded(bool _conceded)
{
conceded = _conceded;
}
const QMap<QString, Server_CardZone *> &getZones() const
{
return zones;
}
const QMap<int, Server_Counter *> &getCounters() const
{
return counters;
}
const QMap<int, Server_Arrow *> &getArrows() const
{
return arrows;
}
int newCardId();
int newCounterId() const;
int newArrowId() const;
void addZone(Server_CardZone *zone);
void addArrow(Server_Arrow *arrow);
void updateArrowId(int id);
bool deleteArrow(int arrowId);
void addCounter(Server_Counter *counter);
void clearZones();
void setupZones();
Response::ResponseCode drawCards(GameEventStorage &ges, int number);
Response::ResponseCode moveCard(GameEventStorage &ges,
Server_CardZone *startzone,
const QList<const CardToMove *> &_cards,
Server_CardZone *targetzone,
int xCoord,
int yCoord,
bool fixFreeSpaces = true,
bool undoingDraw = false,
bool isReversed = false);
void unattachCard(GameEventStorage &ges, Server_Card *card);
Response::ResponseCode setCardAttrHelper(GameEventStorage &ges,
int targetPlayerId,
const QString &zone,
int cardId,
CardAttribute attribute,
const QString &attrValue,
Server_Card *unzonedCard = nullptr);
Response::ResponseCode
cmdConcede(const Command_Concede &cmd, ResponseContainer &rc, GameEventStorage &ges) override;
Response::ResponseCode
cmdUnconcede(const Command_Unconcede &cmd, ResponseContainer &rc, GameEventStorage &ges) override;
Response::ResponseCode
cmdReadyStart(const Command_ReadyStart &cmd, ResponseContainer &rc, GameEventStorage &ges) override;
Response::ResponseCode
cmdDeckSelect(const Command_DeckSelect &cmd, ResponseContainer &rc, GameEventStorage &ges) override;
Response::ResponseCode
cmdSetSideboardPlan(const Command_SetSideboardPlan &cmd, ResponseContainer &rc, GameEventStorage &ges) override;
Response::ResponseCode
cmdSetSideboardLock(const Command_SetSideboardLock &cmd, ResponseContainer &rc, GameEventStorage &ges) override;
Response::ResponseCode
cmdShuffle(const Command_Shuffle &cmd, ResponseContainer &rc, GameEventStorage &ges) override;
Response::ResponseCode
cmdMulligan(const Command_Mulligan &cmd, ResponseContainer &rc, GameEventStorage &ges) override;
Response::ResponseCode
cmdRollDie(const Command_RollDie &cmd, ResponseContainer &rc, GameEventStorage &ges) const override;
Response::ResponseCode
cmdDrawCards(const Command_DrawCards &cmd, ResponseContainer &rc, GameEventStorage &ges) override;
Response::ResponseCode
cmdUndoDraw(const Command_UndoDraw &cmd, ResponseContainer &rc, GameEventStorage &ges) override;
Response::ResponseCode
cmdMoveCard(const Command_MoveCard &cmd, ResponseContainer &rc, GameEventStorage &ges) override;
Response::ResponseCode
cmdFlipCard(const Command_FlipCard &cmd, ResponseContainer &rc, GameEventStorage &ges) override;
Response::ResponseCode
cmdAttachCard(const Command_AttachCard &cmd, ResponseContainer &rc, GameEventStorage &ges) override;
Response::ResponseCode
cmdCreateToken(const Command_CreateToken &cmd, ResponseContainer &rc, GameEventStorage &ges) override;
Response::ResponseCode
cmdCreateArrow(const Command_CreateArrow &cmd, ResponseContainer &rc, GameEventStorage &ges) override;
Response::ResponseCode
cmdDeleteArrow(const Command_DeleteArrow &cmd, ResponseContainer &rc, GameEventStorage &ges) override;
Response::ResponseCode
cmdSetCardAttr(const Command_SetCardAttr &cmd, ResponseContainer &rc, GameEventStorage &ges) override;
Response::ResponseCode
cmdSetCardCounter(const Command_SetCardCounter &cmd, ResponseContainer &rc, GameEventStorage &ges) override;
Response::ResponseCode
cmdIncCardCounter(const Command_IncCardCounter &cmd, ResponseContainer &rc, GameEventStorage &ges) override;
Response::ResponseCode
cmdIncCounter(const Command_IncCounter &cmd, ResponseContainer &rc, GameEventStorage &ges) override;
Response::ResponseCode
cmdCreateCounter(const Command_CreateCounter &cmd, ResponseContainer &rc, GameEventStorage &ges) override;
Response::ResponseCode
cmdSetCounter(const Command_SetCounter &cmd, ResponseContainer &rc, GameEventStorage &ges) override;
Response::ResponseCode
cmdDelCounter(const Command_DelCounter &cmd, ResponseContainer &rc, GameEventStorage &ges) override;
Response::ResponseCode
cmdNextTurn(const Command_NextTurn &cmd, ResponseContainer &rc, GameEventStorage &ges) override;
Response::ResponseCode
cmdSetActivePhase(const Command_SetActivePhase &cmd, ResponseContainer &rc, GameEventStorage &ges) override;
Response::ResponseCode
cmdDumpZone(const Command_DumpZone &cmd, ResponseContainer &rc, GameEventStorage &ges) override;
Response::ResponseCode
cmdRevealCards(const Command_RevealCards &cmd, ResponseContainer &rc, GameEventStorage &ges) override;
Response::ResponseCode
cmdReverseTurn(const Command_ReverseTurn & /*cmd*/, ResponseContainer & /*rc*/, GameEventStorage &ges) override;
Response::ResponseCode cmdChangeZoneProperties(const Command_ChangeZoneProperties &cmd,
ResponseContainer &rc,
GameEventStorage &ges) override;
void getInfo(ServerInfo_Player *info,
Server_AbstractParticipant *playerWhosAsking,
bool omniscient,
bool withUserInfo) override;
};
#endif

View file

@ -0,0 +1,17 @@
#ifndef SPECTATOR_H
#define SPECTATOR_H
#include "server_abstract_participant.h"
class Server_Spectator : public Server_AbstractParticipant
{
Q_OBJECT
public:
Server_Spectator(Server_Game *_game,
int _playerId,
const ServerInfo_User &_userInfo,
bool _judge,
Server_AbstractUserInterface *_handler);
};
#endif

View file

@ -0,0 +1,16 @@
#ifndef ROOM_MESSAGE_TYPE_H
#define ROOM_MESSAGE_TYPE_H
#ifdef Q_OS_MACOS
// avoid collision from Mac OS X's ConditionalMacros.h
// https://github.com/protocolbuffers/protobuf/issues/119
#undef TYPE_BOOL
#endif
#include "pb/event_room_say.pb.h"
#include <QFlags>
Q_DECLARE_FLAGS(RoomMessageTypeFlags, Event_RoomSay::RoomMessageType)
Q_DECLARE_OPERATORS_FOR_FLAGS(RoomMessageTypeFlags)
#endif

View file

@ -0,0 +1,253 @@
#ifndef SERVER_H
#define SERVER_H
#include "pb/commands.pb.h"
#include "pb/serverinfo_ban.pb.h"
#include "pb/serverinfo_chat_message.pb.h"
#include "pb/serverinfo_user.pb.h"
#include "pb/serverinfo_warning.pb.h"
#include "server_player_reference.h"
#include <QMap>
#include <QMultiMap>
#include <QMutex>
#include <QObject>
#include <QReadWriteLock>
#include <QStringList>
class Server_DatabaseInterface;
class Server_Game;
class Server_Room;
class Server_ProtocolHandler;
class Server_AbstractUserInterface;
class GameReplay;
class IslMessage;
class SessionEvent;
class RoomEvent;
class DeckList;
class ServerInfo_Game;
class ServerInfo_Room;
class Response;
class GameEventContainer;
class CommandContainer;
class Command_JoinGame;
enum AuthenticationResult
{
NotLoggedIn,
PasswordRight,
UnknownUser,
WouldOverwriteOldSession,
UserIsBanned,
UsernameInvalid,
RegistrationRequired,
UserIsInactive,
ClientIdRequired
};
class Server : public QObject
{
Q_OBJECT
signals:
void pingClockTimeout();
void sigSendIslMessage(const IslMessage &message, int serverId);
void endSession(qint64 sessionId);
private slots:
void broadcastRoomUpdate(const ServerInfo_Room &roomInfo, bool sendToIsl = false);
public:
mutable QReadWriteLock clientsLock, roomsLock; // locking order: roomsLock before clientsLock
explicit Server(QObject *parent = nullptr);
~Server() override = default;
AuthenticationResult loginUser(Server_ProtocolHandler *session,
QString &name,
const QString &password,
bool passwordNeedsHash,
QString &reason,
int &secondsLeft,
QString &clientid,
QString &clientVersion,
QString &connectionType);
const QMap<int, Server_Room *> &getRooms()
{
return rooms;
}
Server_AbstractUserInterface *findUser(const QString &userName) const;
const QMap<QString, Server_ProtocolHandler *> &getUsers() const
{
return users;
}
const QMap<qint64, Server_ProtocolHandler *> &getUsersBySessionId() const
{
return usersBySessionId;
}
virtual QMap<QString, bool> getServerRequiredFeatureList() const
{
return QMap<QString, bool>();
}
void addClient(Server_ProtocolHandler *player);
void removeClient(Server_ProtocolHandler *player);
QList<QString> getOnlineModeratorList() const;
virtual QString getLoginMessage() const
{
return QString();
}
virtual QString getRequiredFeatures() const
{
return QString();
}
virtual bool permitUnregisteredUsers() const
{
return true;
}
virtual bool getGameShouldPing() const
{
return false;
}
virtual bool getClientIDRequiredEnabled() const
{
return false;
}
virtual bool getRegOnlyServerEnabled() const
{
return false;
}
virtual bool getMaxUserLimitEnabled() const
{
return false;
}
virtual bool getEnableLogQuery() const
{
return false;
}
virtual bool getStoreReplaysEnabled() const
{
return true;
}
virtual int getIdleClientTimeout() const
{
return 0;
}
virtual int getClientKeepAlive() const
{
return 0;
}
virtual int getMaxGameInactivityTime() const
{
return 9999999;
}
virtual int getMaxPlayerInactivityTime() const
{
return 9999999;
}
virtual int getMessageCountingInterval() const
{
return 0;
}
virtual int getMaxMessageCountPerInterval() const
{
return 0;
}
virtual int getMaxMessageSizePerInterval() const
{
return 0;
}
virtual int getMaxGamesPerUser() const
{
return -1;
}
virtual int getCommandCountingInterval() const
{
return 0;
}
virtual int getMaxCommandCountPerInterval() const
{
return 0;
}
virtual int getMaxUserTotal() const
{
return 9999999;
}
virtual int getServerID() const
{
return 0;
}
virtual bool permitCreateGameAsJudge() const
{
return false;
}
Server_DatabaseInterface *getDatabaseInterface() const;
int getNextLocalGameId()
{
QMutexLocker locker(&nextLocalGameIdMutex);
return ++nextLocalGameId;
}
void sendIsl_Response(const Response &item, int serverId = -1, qint64 sessionId = -1);
void sendIsl_SessionEvent(const SessionEvent &item, int serverId = -1, qint64 sessionId = -1);
void sendIsl_GameEventContainer(const GameEventContainer &item, int serverId = -1, qint64 sessionId = -1);
void sendIsl_RoomEvent(const RoomEvent &item, int serverId = -1, qint64 sessionId = -1);
void sendIsl_GameCommand(const CommandContainer &item, int serverId, qint64 sessionId, int roomId, int playerId);
void sendIsl_RoomCommand(const CommandContainer &item, int serverId, qint64 sessionId, int roomId);
const QMap<QString, Server_AbstractUserInterface *> &getExternalUsers() const
{
return externalUsers;
}
void addPersistentPlayer(const QString &userName, int roomId, int gameId, int playerId);
void removePersistentPlayer(const QString &userName, int roomId, int gameId, int playerId);
QList<PlayerReference> getPersistentPlayerReferences(const QString &userName) const;
int getUsersCount() const;
int getGamesCount() const;
int getTCPUserCount() const
{
return tcpUserCount;
}
int getWebSocketUserCount() const
{
return webSocketUserCount;
}
private:
QMultiMap<QString, PlayerReference> persistentPlayers;
mutable QReadWriteLock persistentPlayersLock;
int nextLocalGameId, tcpUserCount, webSocketUserCount;
QMutex nextLocalGameIdMutex;
protected slots:
void externalUserJoined(const ServerInfo_User &userInfo);
void externalUserLeft(const QString &userName);
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 externalRoomRemoveMessages(int roomId, const QString &userName, int amount);
void externalRoomGameListChanged(int roomId, const ServerInfo_Game &gameInfo);
void
externalJoinGameCommandReceived(const Command_JoinGame &cmd, int cmdId, int roomId, int serverId, qint64 sessionId);
void
externalGameCommandContainerReceived(const CommandContainer &cont, int playerId, int serverId, qint64 sessionId);
void externalGameEventContainerReceived(const GameEventContainer &cont, qint64 sessionId);
void externalResponseReceived(const Response &resp, qint64 sessionId);
virtual void doSendIslMessage(const IslMessage & /* msg */, int /* serverId */)
{
}
protected:
void prepareDestroy();
void setDatabaseInterface(Server_DatabaseInterface *_databaseInterface);
QList<Server_ProtocolHandler *> clients;
QMap<qint64, Server_ProtocolHandler *> usersBySessionId;
QMap<QString, Server_ProtocolHandler *> users;
QMap<qint64, Server_AbstractUserInterface *> externalUsersBySessionId;
QMap<QString, Server_AbstractUserInterface *> externalUsers;
QMap<int, Server_Room *> rooms;
QMap<QThread *, Server_DatabaseInterface *> databaseInterfaces;
void addRoom(Server_Room *newRoom);
};
#endif

View file

@ -0,0 +1,63 @@
#ifndef SERVER_ABSTRACTUSERINTERFACE
#define SERVER_ABSTRACTUSERINTERFACE
#include "pb/response.pb.h"
#include "pb/server_message.pb.h"
#include "serverinfo_user_container.h"
#include <QMap>
#include <QMutex>
#include <QPair>
class SessionEvent;
class GameEventContainer;
class RoomEvent;
class ResponseContainer;
class Server;
class Server_Game;
class Server_AbstractUserInterface : public ServerInfo_User_Container
{
private:
mutable QMutex gameListMutex;
QMap<int, QPair<int, int>> games; // gameId -> (roomId, playerId)
protected:
Server *server;
public:
explicit Server_AbstractUserInterface(Server *_server) : server(_server)
{
}
Server_AbstractUserInterface(Server *_server, const ServerInfo_User_Container &other)
: ServerInfo_User_Container(other), server(_server)
{
}
~Server_AbstractUserInterface() override
{
}
virtual int getLastCommandTime() const = 0;
virtual bool addSaidMessageSize(int size) = 0;
void playerRemovedFromGame(Server_Game *game);
void playerAddedToGame(int gameId, int roomId, int playerId);
void joinPersistentGames(ResponseContainer &rc);
QMap<int, QPair<int, int>> getGames() const
{
QMutexLocker locker(&gameListMutex);
return games;
}
virtual void sendProtocolItem(const Response &item) = 0;
virtual void sendProtocolItem(const SessionEvent &item) = 0;
virtual void sendProtocolItem(const GameEventContainer &item) = 0;
virtual void sendProtocolItem(const RoomEvent &item) = 0;
void sendProtocolItemByType(ServerMessage::MessageType type, const ::google::protobuf::Message &item);
static SessionEvent *prepareSessionEvent(const ::google::protobuf::Message &sessionEvent);
void sendResponseContainer(const ResponseContainer &responseContainer, Response::ResponseCode responseCode);
};
#endif

View file

@ -0,0 +1,175 @@
#ifndef SERVER_DATABASE_INTERFACE_H
#define SERVER_DATABASE_INTERFACE_H
#include "server.h"
#include <QObject>
class Server_DatabaseInterface : public QObject
{
Q_OBJECT
public:
explicit Server_DatabaseInterface(QObject *parent = nullptr) : QObject(parent)
{
}
virtual AuthenticationResult checkUserPassword(Server_ProtocolHandler *handler,
const QString &user,
const QString &password,
const QString &clientId,
QString &reasonStr,
int &secondsLeft,
bool passwordNeedsHash) = 0;
virtual bool checkUserIsBanned(const QString & /* ipAddress */,
const QString & /* userName */,
const QString & /* clientId */,
QString & /* banReason */,
int & /* banSecondsRemaining */)
{
return false;
}
virtual bool activeUserExists(const QString & /* user */)
{
return false;
}
virtual bool userExists(const QString & /* user */)
{
return false;
}
virtual QString getUserSalt(const QString & /* user */)
{
return {};
}
virtual QMap<QString, ServerInfo_User> getBuddyList(const QString & /* name */)
{
return QMap<QString, ServerInfo_User>();
}
virtual QMap<QString, ServerInfo_User> getIgnoreList(const QString & /* name */)
{
return QMap<QString, ServerInfo_User>();
}
virtual bool isInBuddyList(const QString & /* whoseList */, const QString & /* who */)
{
return false;
}
virtual bool isInIgnoreList(const QString & /* whoseList */, const QString & /* who */)
{
return false;
}
virtual ServerInfo_User getUserData(const QString &name, bool withId = false) = 0;
virtual void storeGameInformation(const QString & /* roomName */,
const QStringList & /* roomGameTypes */,
const ServerInfo_Game & /* gameInfo */,
const QSet<QString> & /* allPlayersEver */,
const QSet<QString> & /* allSpectatorsEver */,
const QList<GameReplay *> & /* replayList */)
{
}
virtual DeckList *getDeckFromDatabase(int /* deckId */, int /* userId */)
{
return 0;
}
virtual bool removeForgotPassword(const QString & /* user */)
{
return false;
}
virtual qint64 startSession(const QString & /* userName */,
const QString & /* address */,
const QString & /* clientId */,
const QString & /* connectionType */)
{
return 0;
}
virtual bool usernameIsValid(const QString & /*userName */, QString & /* error */)
{
return true;
};
public slots:
virtual void endSession(qint64 /* sessionId */)
{
}
public:
virtual int getNextGameId() = 0;
virtual int getNextReplayId() = 0;
virtual int getActiveUserCount(QString connectionType = QString()) = 0;
virtual void clearSessionTables()
{
}
virtual void lockSessionTables()
{
}
virtual void unlockSessionTables()
{
}
virtual bool userSessionExists(const QString & /* userName */)
{
return false;
}
virtual bool getRequireRegistration()
{
return false;
}
virtual bool registerUser(const QString & /* userName */,
const QString & /* realName */,
const QString & /* password */,
bool /* passwordNeedsHash */,
const QString & /* emailAddress */,
const QString & /* country */,
bool /* active = false */)
{
return false;
}
virtual bool activateUser(const QString & /* userName */, const QString & /* token */)
{
return false;
}
virtual void updateUsersClientID(const QString & /* userName */, const QString & /* userClientID */)
{
}
virtual void updateUsersLastLoginData(const QString & /* userName */, const QString & /* clientVersion */)
{
}
enum LogMessage_TargetType
{
MessageTargetRoom,
MessageTargetGame,
MessageTargetChat,
MessageTargetIslRoom
};
virtual void logMessage(const int /* senderId */,
const QString & /* senderName */,
const QString & /* senderIp */,
const QString & /* logMessage */,
LogMessage_TargetType /* targetType */,
const int /* targetId */,
const QString & /* targetName */){};
virtual bool checkUserIsBanned(Server_ProtocolHandler * /* session */,
QString & /* banReason */,
int & /* banSecondsRemaining */)
{
return false;
};
virtual int checkNumberOfUserAccounts(const QString & /* email */)
{
return 0;
};
virtual bool
changeUserPassword(const QString & /* user */, const QString & /* password */, bool /* passwordNeedsHash */)
{
return false;
};
virtual bool changeUserPassword(const QString & /* user */,
const QString & /* oldPassword */,
bool /* oldPasswordNeedsHash */,
const QString & /* newPassword */,
bool /* newPasswordNeedsHash */)
{
return false;
};
};
#endif

View file

@ -0,0 +1,33 @@
#ifndef SERVER_PLAYER_REFERENCE_H
#define SERVER_PLAYER_REFERENCE_H
class PlayerReference
{
private:
int roomId;
int gameId;
int playerId;
public:
PlayerReference(int _roomId, int _gameId, int _playerId) : roomId(_roomId), gameId(_gameId), playerId(_playerId)
{
}
int getRoomId() const
{
return roomId;
}
int getGameId() const
{
return gameId;
}
int getPlayerId() const
{
return playerId;
}
bool operator==(const PlayerReference &other)
{
return ((roomId == other.roomId) && (gameId == other.gameId) && (playerId == other.playerId));
}
};
#endif

View file

@ -0,0 +1,141 @@
#ifndef SERVER_PROTOCOLHANDLER_H
#define SERVER_PROTOCOLHANDLER_H
#include "pb/response.pb.h"
#include "pb/server_message.pb.h"
#include "server.h"
#include "server_abstractuserinterface.h"
#include <QObject>
#include <QPair>
class Features;
class Server_DatabaseInterface;
class Server_Player;
class ServerInfo_User;
class Server_Room;
class QTimer;
class FeatureSet;
class ServerMessage;
class Response;
class SessionEvent;
class GameEventContainer;
class RoomEvent;
class ResponseContainer;
class CommandContainer;
class SessionCommand;
class ModeratorCommand;
class AdminCommand;
class Command_Ping;
class Command_Login;
class Command_Register;
class Command_Message;
class Command_ListUsers;
class Command_GetGamesOfUser;
class Command_GetUserInfo;
class Command_ListRooms;
class Command_JoinRoom;
class Command_LeaveRoom;
class Command_RoomSay;
class Command_CreateGame;
class Command_JoinGame;
class Server_ProtocolHandler : public QObject, public Server_AbstractUserInterface
{
Q_OBJECT
protected:
QMap<int, Server_Room *> rooms;
bool deleted;
Server_DatabaseInterface *databaseInterface;
AuthenticationResult authState;
bool usingRealPassword;
bool acceptsUserListChanges;
bool acceptsRoomListChanges;
bool idleClientWarningSent;
virtual void logDebugMessage(const QString & /* message */)
{
}
private:
QList<int> messageSizeOverTime, messageCountOverTime, commandCountOverTime;
int timeRunning, lastDataReceived, lastActionReceived;
virtual void transmitProtocolItem(const ServerMessage &item) = 0;
Response::ResponseCode cmdPing(const Command_Ping &cmd, ResponseContainer &rc);
Response::ResponseCode cmdLogin(const Command_Login &cmd, ResponseContainer &rc);
Response::ResponseCode cmdMessage(const Command_Message &cmd, ResponseContainer &rc);
Response::ResponseCode cmdGetGamesOfUser(const Command_GetGamesOfUser &cmd, ResponseContainer &rc);
Response::ResponseCode cmdGetUserInfo(const Command_GetUserInfo &cmd, ResponseContainer &rc);
Response::ResponseCode cmdListRooms(const Command_ListRooms &cmd, ResponseContainer &rc);
Response::ResponseCode cmdJoinRoom(const Command_JoinRoom &cmd, ResponseContainer &rc);
Response::ResponseCode cmdListUsers(const Command_ListUsers &cmd, ResponseContainer &rc);
Response::ResponseCode cmdLeaveRoom(const Command_LeaveRoom &cmd, Server_Room *room, ResponseContainer &rc);
Response::ResponseCode cmdRoomSay(const Command_RoomSay &cmd, Server_Room *room, ResponseContainer &rc);
Response::ResponseCode cmdCreateGame(const Command_CreateGame &cmd, Server_Room *room, ResponseContainer &rc);
Response::ResponseCode cmdJoinGame(const Command_JoinGame &cmd, Server_Room *room, ResponseContainer &rc);
Response::ResponseCode processSessionCommandContainer(const CommandContainer &cont, ResponseContainer &rc);
virtual Response::ResponseCode
processExtendedSessionCommand(int /* cmdType */, const SessionCommand & /* cmd */, ResponseContainer & /* rc */)
{
return Response::RespFunctionNotAllowed;
}
Response::ResponseCode processRoomCommandContainer(const CommandContainer &cont, ResponseContainer &rc);
Response::ResponseCode processGameCommandContainer(const CommandContainer &cont, ResponseContainer &rc);
Response::ResponseCode processModeratorCommandContainer(const CommandContainer &cont, ResponseContainer &rc);
virtual Response::ResponseCode
processExtendedModeratorCommand(int /* cmdType */, const ModeratorCommand & /* cmd */, ResponseContainer & /* rc */)
{
return Response::RespFunctionNotAllowed;
}
Response::ResponseCode processAdminCommandContainer(const CommandContainer &cont, ResponseContainer &rc);
virtual Response::ResponseCode
processExtendedAdminCommand(int /* cmdType */, const AdminCommand & /* cmd */, ResponseContainer & /* rc */)
{
return Response::RespFunctionNotAllowed;
}
void resetIdleTimer();
private slots:
void pingClockTimeout();
public slots:
void prepareDestroy();
public:
Server_ProtocolHandler(Server *_server, Server_DatabaseInterface *_databaseInterface, QObject *parent = 0);
~Server_ProtocolHandler();
bool getAcceptsUserListChanges() const
{
return acceptsUserListChanges;
}
bool getAcceptsRoomListChanges() const
{
return acceptsRoomListChanges;
}
virtual QString getAddress() const = 0;
virtual QString getConnectionType() const = 0;
Server_DatabaseInterface *getDatabaseInterface() const
{
return databaseInterface;
}
int getLastCommandTime() const
{
return timeRunning - lastDataReceived;
}
bool addSaidMessageSize(int size);
void processCommandContainer(const CommandContainer &cont);
void sendProtocolItem(const Response &item);
void sendProtocolItem(const SessionEvent &item);
void sendProtocolItem(const GameEventContainer &item);
void sendProtocolItem(const RoomEvent &item);
};
#endif

View file

@ -0,0 +1,29 @@
#ifndef SERVER_REMOTEUSERINTERFACE_H
#define SERVER_REMOTEUSERINTERFACE_H
#include "server_abstractuserinterface.h"
class Server_RemoteUserInterface : public Server_AbstractUserInterface
{
public:
Server_RemoteUserInterface(Server *_server, const ServerInfo_User_Container &_userInfoContainer)
: Server_AbstractUserInterface(_server, _userInfoContainer)
{
}
int getLastCommandTime() const
{
return 0;
}
bool addSaidMessageSize(int /*size*/)
{
return true;
}
void sendProtocolItem(const Response &item);
void sendProtocolItem(const SessionEvent &item);
void sendProtocolItem(const GameEventContainer &item);
void sendProtocolItem(const RoomEvent &item);
};
#endif

View file

@ -0,0 +1,130 @@
#ifndef SERVER_RESPONSE_CONTAINERS_H
#define SERVER_RESPONSE_CONTAINERS_H
#include "pb/server_message.pb.h"
#include <QList>
#include <QPair>
namespace google
{
namespace protobuf
{
class Message;
}
} // namespace google
class Server_Game;
class GameEventStorageItem
{
public:
enum EventRecipient
{
SendToPrivate = 0x01,
SendToOthers = 0x02
};
Q_DECLARE_FLAGS(EventRecipients, EventRecipient)
private:
GameEvent *event;
EventRecipients recipients;
public:
GameEventStorageItem(const ::google::protobuf::Message &_event, int _playerId, EventRecipients _recipients);
~GameEventStorageItem();
const GameEvent &getGameEvent() const
{
return *event;
}
EventRecipients getRecipients() const
{
return recipients;
}
};
Q_DECLARE_OPERATORS_FOR_FLAGS(GameEventStorageItem::EventRecipients)
class GameEventStorage
{
private:
::google::protobuf::Message *gameEventContext;
QList<GameEventStorageItem *> gameEventList;
int privatePlayerId;
int forcedByJudge = -1;
bool overwriteOwnership = false;
public:
GameEventStorage();
~GameEventStorage();
void setGameEventContext(const ::google::protobuf::Message &_gameEventContext);
::google::protobuf::Message *getGameEventContext() const
{
return gameEventContext;
}
const QList<GameEventStorageItem *> &getGameEventList() const
{
return gameEventList;
}
int getPrivatePlayerId() const
{
return privatePlayerId;
}
void setForcedByJudge(int playerId)
{
forcedByJudge = playerId;
}
void setOverwriteOwnership(bool shouldOverwriteOwnership)
{
overwriteOwnership = shouldOverwriteOwnership;
}
void enqueueGameEvent(const ::google::protobuf::Message &event,
int playerId,
GameEventStorageItem::EventRecipients recipients = GameEventStorageItem::SendToPrivate |
GameEventStorageItem::SendToOthers,
int _privatePlayerId = -1);
void sendToGame(Server_Game *game);
};
class ResponseContainer
{
private:
int cmdId;
::google::protobuf::Message *responseExtension;
QList<QPair<ServerMessage::MessageType, ::google::protobuf::Message *>> preResponseQueue, postResponseQueue;
public:
ResponseContainer(int _cmdId);
~ResponseContainer();
int getCmdId() const
{
return cmdId;
}
void setResponseExtension(::google::protobuf::Message *_responseExtension)
{
responseExtension = _responseExtension;
}
::google::protobuf::Message *getResponseExtension() const
{
return responseExtension;
}
void enqueuePreResponseItem(ServerMessage::MessageType type, ::google::protobuf::Message *item)
{
preResponseQueue.append(qMakePair(type, item));
}
void enqueuePostResponseItem(ServerMessage::MessageType type, ::google::protobuf::Message *item)
{
postResponseQueue.append(qMakePair(type, item));
}
const QList<QPair<ServerMessage::MessageType, ::google::protobuf::Message *>> &getPreResponseQueue() const
{
return preResponseQueue;
}
const QList<QPair<ServerMessage::MessageType, ::google::protobuf::Message *>> &getPostResponseQueue() const
{
return postResponseQueue;
}
};
#endif

View file

@ -0,0 +1,144 @@
#ifndef SERVER_ROOM_H
#define SERVER_ROOM_H
#include "../serverinfo_user_container.h"
#include "pb/response.pb.h"
#include "pb/serverinfo_chat_message.pb.h"
#include <QList>
#include <QMap>
#include <QMutex>
#include <QObject>
#include <QReadWriteLock>
#include <QStringList>
class Server_DatabaseInterface;
class Server_ProtocolHandler;
class RoomEvent;
class ServerInfo_User;
class ServerInfo_Room;
class ServerInfo_Game;
class Server_Game;
class Server;
class Command_JoinGame;
class ResponseContainer;
class Server_AbstractUserInterface;
class Server_Room : public QObject
{
Q_OBJECT
signals:
void roomInfoChanged(const ServerInfo_Room &roomInfo);
void gameListChanged(const ServerInfo_Game &gameInfo);
private:
int id;
int chatHistorySize;
QString name;
QString description;
QString permissionLevel;
QString privilegeLevel;
bool autoJoin;
QString joinMessage;
QStringList gameTypes;
QMap<int, Server_Game *> games;
QMap<int, ServerInfo_Game> externalGames;
QMap<QString, Server_ProtocolHandler *> users;
QMap<QString, ServerInfo_User_Container> externalUsers;
QList<ServerInfo_ChatMessage> chatHistory;
private slots:
void broadcastGameListUpdate(const ServerInfo_Game &gameInfo, bool sendToIsl = true);
public:
mutable QReadWriteLock usersLock;
mutable QReadWriteLock gamesLock;
mutable QReadWriteLock historyLock;
Server_Room(int _id,
int _chatHistorySize,
const QString &_name,
const QString &_description,
const QString &_permissionLevel,
const QString &_privilegeLevel,
bool _autoJoin,
const QString &_joinMessage,
const QStringList &_gameTypes,
Server *parent);
~Server_Room() override;
int getId() const
{
return id;
}
QString getName() const
{
return name;
}
QString getDescription() const
{
return description;
}
QString getRoomPermission() const
{
return permissionLevel;
}
QString getRoomPrivilege() const
{
return privilegeLevel;
}
bool getAutoJoin() const
{
return autoJoin;
}
bool userMayJoin(const ServerInfo_User &userInfo);
QString getJoinMessage() const
{
return joinMessage;
}
const QStringList &getGameTypes() const
{
return gameTypes;
}
const QMap<int, Server_Game *> &getGames() const
{
return games;
}
const QMap<int, ServerInfo_Game> &getExternalGames() const
{
return externalGames;
}
Server *getServer() const;
const ServerInfo_Room &
getInfo(ServerInfo_Room &result, bool complete, bool showGameTypes = false, bool includeExternalData = true) const;
int getGamesCreatedByUser(const QString &name) const;
QList<ServerInfo_Game> getGamesOfUser(const QString &name) const;
QList<ServerInfo_ChatMessage> &getChatHistory()
{
return chatHistory;
}
void addClient(Server_ProtocolHandler *client);
void removeClient(Server_ProtocolHandler *client);
void addExternalUser(const ServerInfo_User &userInfo);
void removeExternalUser(const QString &_name);
const QMap<QString, ServerInfo_User_Container> &getExternalUsers() const
{
return externalUsers;
}
void updateExternalGameList(const ServerInfo_Game &gameInfo);
Response::ResponseCode processJoinGameCommand(const Command_JoinGame &cmd,
ResponseContainer &rc,
Server_AbstractUserInterface *userInterface);
void say(const QString &userName, const QString &s, bool sendToIsl = true);
void removeSaidMessages(const QString &userName, int amount, bool sendToIsl = true);
void addGame(Server_Game *game);
void removeGame(Server_Game *game);
void sendRoomEvent(RoomEvent *event, bool sendToIsl = true);
RoomEvent *prepareRoomEvent(const ::google::protobuf::Message &roomEvent);
};
#endif

View file

@ -0,0 +1,27 @@
#ifndef SERVERINFO_USER_CONTAINER
#define SERVERINFO_USER_CONTAINER
class ServerInfo_User;
class ServerInfo_User_Container
{
protected:
ServerInfo_User *userInfo;
public:
explicit ServerInfo_User_Container(ServerInfo_User *_userInfo = nullptr);
explicit ServerInfo_User_Container(const ServerInfo_User &_userInfo);
ServerInfo_User_Container(const ServerInfo_User_Container &other);
ServerInfo_User_Container &operator=(const ServerInfo_User_Container &other) = default;
virtual ~ServerInfo_User_Container();
ServerInfo_User *getUserInfo() const
{
return userInfo;
}
void setUserInfo(const ServerInfo_User &_userInfo);
ServerInfo_User &
copyUserInfo(ServerInfo_User &result, bool complete, bool internalInfo = false, bool sessionInfo = false) const;
ServerInfo_User copyUserInfo(bool complete, bool internalInfo = false, bool sessionInfo = false) const;
};
#endif

View file

@ -0,0 +1,16 @@
#ifndef USER_LEVEL_H
#define USER_LEVEL_H
#ifdef Q_OS_MACOS
// avoid collision from Mac OS X's ConditionalMacros.h
// https://github.com/protocolbuffers/protobuf/issues/119
#undef TYPE_BOOL
#endif
#include "pb/serverinfo_user.pb.h"
#include <QFlags>
Q_DECLARE_FLAGS(UserLevelFlags, ServerInfo_User::UserLevelFlag)
Q_DECLARE_OPERATORS_FOR_FLAGS(UserLevelFlags)
#endif