diff --git a/cockatrice/src/game/board/card_item.h b/cockatrice/src/game/board/card_item.h index acb2e5e04..65c870afb 100644 --- a/cockatrice/src/game/board/card_item.h +++ b/cockatrice/src/game/board/card_item.h @@ -3,7 +3,7 @@ #include "../zones/logic/card_zone_logic.h" #include "abstract_card_item.h" -#include "server_card.h" +#include "server/game/server_card.h" class CardDatabase; class CardDragItem; diff --git a/cockatrice/src/server/local_server.cpp b/cockatrice/src/server/local_server.cpp index c40247c72..74ee8601d 100644 --- a/cockatrice/src/server/local_server.cpp +++ b/cockatrice/src/server/local_server.cpp @@ -1,7 +1,7 @@ #include "local_server.h" #include "local_server_interface.h" -#include "server_room.h" +#include "server/server_room.h" LocalServer::LocalServer(QObject *parent) : Server(parent) { diff --git a/cockatrice/src/server/local_server.h b/cockatrice/src/server/local_server.h index 5f7d480dc..93dbeb827 100644 --- a/cockatrice/src/server/local_server.h +++ b/cockatrice/src/server/local_server.h @@ -1,8 +1,8 @@ #ifndef LOCALSERVER_H #define LOCALSERVER_H -#include "server.h" -#include "server_database_interface.h" +#include "server/server.h" +#include "server/server_database_interface.h" class LocalServerInterface; diff --git a/cockatrice/src/server/local_server_interface.h b/cockatrice/src/server/local_server_interface.h index 8e997ae30..ebfc49719 100644 --- a/cockatrice/src/server/local_server_interface.h +++ b/cockatrice/src/server/local_server_interface.h @@ -1,7 +1,7 @@ #ifndef LOCALSERVERINTERFACE_H #define LOCALSERVERINTERFACE_H -#include "server_protocolhandler.h" +#include "server/server_protocolhandler.h" class LocalServer; diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index 50d136f4f..cf2f15db1 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -17,20 +17,22 @@ set(common_SOURCES passwordhasher.cpp rng_abstract.cpp rng_sfmt.cpp - server.cpp - server_abstractuserinterface.cpp - server_arrow.cpp - server_arrowtarget.h - server_card.cpp - server_cardzone.cpp - server_counter.cpp - server_database_interface.cpp - server_game.cpp - server_player.cpp - server_protocolhandler.cpp - server_remoteuserinterface.cpp - server_response_containers.cpp - server_room.cpp + server/game/server_abstract_participant.cpp + server/game/server_arrow.cpp + server/game/server_arrowtarget.cpp + server/game/server_card.cpp + server/game/server_cardzone.cpp + server/game/server_counter.cpp + server/game/server_game.cpp + server/game/server_player.cpp + server/game/server_spectator.cpp + server/server.cpp + server/server_abstractuserinterface.cpp + server/server_database_interface.cpp + server/server_protocolhandler.cpp + server/server_remoteuserinterface.cpp + server/server_response_containers.cpp + server/server_room.cpp serverinfo_user_container.cpp sfmt/SFMT.c ) diff --git a/common/server/game/server_abstract_participant.cpp b/common/server/game/server_abstract_participant.cpp new file mode 100644 index 000000000..1ef765d8b --- /dev/null +++ b/common/server/game/server_abstract_participant.cpp @@ -0,0 +1,612 @@ +#include "server_abstract_participant.h" + +#include "../../color.h" +#include "../../deck_list.h" +#include "../../deck_list_card_node.h" +#include "../../get_pb_extension.h" +#include "../../rng_abstract.h" +#include "../../trice_limits.h" +#include "../server.h" +#include "../server_abstractuserinterface.h" +#include "../server_database_interface.h" +#include "../server_room.h" +#include "pb/command_attach_card.pb.h" +#include "pb/command_change_zone_properties.pb.h" +#include "pb/command_concede.pb.h" +#include "pb/command_create_arrow.pb.h" +#include "pb/command_create_counter.pb.h" +#include "pb/command_create_token.pb.h" +#include "pb/command_deck_select.pb.h" +#include "pb/command_del_counter.pb.h" +#include "pb/command_delete_arrow.pb.h" +#include "pb/command_draw_cards.pb.h" +#include "pb/command_dump_zone.pb.h" +#include "pb/command_flip_card.pb.h" +#include "pb/command_game_say.pb.h" +#include "pb/command_inc_card_counter.pb.h" +#include "pb/command_inc_counter.pb.h" +#include "pb/command_kick_from_game.pb.h" +#include "pb/command_leave_game.pb.h" +#include "pb/command_move_card.pb.h" +#include "pb/command_mulligan.pb.h" +#include "pb/command_next_turn.pb.h" +#include "pb/command_ready_start.pb.h" +#include "pb/command_reveal_cards.pb.h" +#include "pb/command_reverse_turn.pb.h" +#include "pb/command_roll_die.pb.h" +#include "pb/command_set_active_phase.pb.h" +#include "pb/command_set_card_attr.pb.h" +#include "pb/command_set_card_counter.pb.h" +#include "pb/command_set_counter.pb.h" +#include "pb/command_set_sideboard_lock.pb.h" +#include "pb/command_set_sideboard_plan.pb.h" +#include "pb/command_shuffle.pb.h" +#include "pb/command_undo_draw.pb.h" +#include "pb/context_concede.pb.h" +#include "pb/context_connection_state_changed.pb.h" +#include "pb/context_deck_select.pb.h" +#include "pb/context_move_card.pb.h" +#include "pb/context_mulligan.pb.h" +#include "pb/context_ready_start.pb.h" +#include "pb/context_set_sideboard_lock.pb.h" +#include "pb/context_undo_draw.pb.h" +#include "pb/event_attach_card.pb.h" +#include "pb/event_change_zone_properties.pb.h" +#include "pb/event_create_arrow.pb.h" +#include "pb/event_create_counter.pb.h" +#include "pb/event_create_token.pb.h" +#include "pb/event_del_counter.pb.h" +#include "pb/event_delete_arrow.pb.h" +#include "pb/event_destroy_card.pb.h" +#include "pb/event_draw_cards.pb.h" +#include "pb/event_dump_zone.pb.h" +#include "pb/event_flip_card.pb.h" +#include "pb/event_game_say.pb.h" +#include "pb/event_move_card.pb.h" +#include "pb/event_player_properties_changed.pb.h" +#include "pb/event_reveal_cards.pb.h" +#include "pb/event_reverse_turn.pb.h" +#include "pb/event_roll_die.pb.h" +#include "pb/event_set_card_attr.pb.h" +#include "pb/event_set_card_counter.pb.h" +#include "pb/event_set_counter.pb.h" +#include "pb/event_shuffle.pb.h" +#include "pb/response.pb.h" +#include "pb/response_deck_download.pb.h" +#include "pb/response_dump_zone.pb.h" +#include "pb/serverinfo_player.pb.h" +#include "pb/serverinfo_user.pb.h" +#include "server_arrow.h" +#include "server_card.h" +#include "server_cardzone.h" +#include "server_counter.h" +#include "server_game.h" +#include "server_player.h" + +#include +#include +#include + +Server_AbstractParticipant::Server_AbstractParticipant(Server_Game *_game, + int _playerId, + const ServerInfo_User &_userInfo, + bool _judge, + Server_AbstractUserInterface *_userInterface) + : ServerInfo_User_Container(_userInfo), game(_game), userInterface(_userInterface), pingTime(0), + playerId(_playerId), judge(_judge) +{ +} + +Server_AbstractParticipant::~Server_AbstractParticipant() = default; + +void Server_AbstractParticipant::removeFromGame() +{ + QMutexLocker locker(&playerMutex); + if (userInterface) { + userInterface->playerRemovedFromGame(game); + } +} + +bool Server_AbstractParticipant::updatePingTime() // returns true if ping time changed +{ + QMutexLocker locker(&playerMutex); + + int oldPingTime = pingTime; + if (userInterface) { + pingTime = userInterface->getLastCommandTime(); + } else { + pingTime = -1; + } + + return pingTime != oldPingTime; +} + +void Server_AbstractParticipant::getProperties(ServerInfo_PlayerProperties &result, bool withUserInfo) +{ + result.set_player_id(playerId); + if (withUserInfo) { + copyUserInfo(*(result.mutable_user_info()), true); + } + result.set_spectator(spectator); + result.set_judge(judge); + result.set_ping_seconds(pingTime); + getPlayerProperties(result); +} + +void Server_AbstractParticipant::getPlayerProperties(ServerInfo_PlayerProperties & /*result*/) +{ +} + +Response::ResponseCode Server_AbstractParticipant::cmdLeaveGame(const Command_LeaveGame & /*cmd*/, + ResponseContainer & /*rc*/, + GameEventStorage & /*ges*/) +{ + game->removeParticipant(this, Event_Leave::USER_LEFT); + return Response::RespOk; +} + +Response::ResponseCode Server_AbstractParticipant::cmdKickFromGame(const Command_KickFromGame &cmd, + ResponseContainer & /*rc*/, + GameEventStorage & /*ges*/) +{ + if ((game->getHostId() != playerId) && !(userInfo->user_level() & ServerInfo_User::IsModerator)) { + return Response::RespFunctionNotAllowed; + } + + if (!game->kickParticipant(cmd.player_id())) { + return Response::RespNameNotFound; + } + + return Response::RespOk; +} + +Response::ResponseCode Server_AbstractParticipant::cmdDeckSelect(const Command_DeckSelect & /*cmd*/, + ResponseContainer & /*rc*/, + GameEventStorage & /*ges*/) +{ + return Response::RespFunctionNotAllowed; +} + +Response::ResponseCode Server_AbstractParticipant::cmdSetSideboardPlan(const Command_SetSideboardPlan & /*cmd*/, + ResponseContainer & /*rc*/, + GameEventStorage & /*ges*/) +{ + return Response::RespFunctionNotAllowed; +} + +Response::ResponseCode Server_AbstractParticipant::cmdSetSideboardLock(const Command_SetSideboardLock & /*cmd*/, + ResponseContainer & /*rc*/, + GameEventStorage & /*ges*/) +{ + return Response::RespFunctionNotAllowed; +} + +Response::ResponseCode Server_AbstractParticipant::cmdConcede(const Command_Concede & /*cmd*/, + ResponseContainer & /*rc*/, + GameEventStorage & /*ges*/) +{ + return Response::RespFunctionNotAllowed; +} + +Response::ResponseCode Server_AbstractParticipant::cmdUnconcede(const Command_Unconcede & /*cmd*/, + ResponseContainer & /*rc*/, + GameEventStorage & /*ges*/) +{ + return Response::RespFunctionNotAllowed; +} + +Response::ResponseCode +Server_AbstractParticipant::cmdJudge(const Command_Judge &cmd, ResponseContainer &rc, GameEventStorage &ges) +{ + if (!judge) { + return Response::RespFunctionNotAllowed; + } + + Server_Player *player = this->game->getPlayer(cmd.target_id()); + + ges.setForcedByJudge(playerId); + if (player == nullptr) { + return Response::RespContextError; + } + + for (int i = 0; i < cmd.game_command_size(); ++i) { + player->processGameCommand(cmd.game_command(i), rc, ges); + } + + return Response::RespOk; +} + +Response::ResponseCode Server_AbstractParticipant::cmdReadyStart(const Command_ReadyStart & /*cmd*/, + ResponseContainer & /*rc*/, + GameEventStorage & /*ges*/) +{ + return Response::RespFunctionNotAllowed; +} + +Response::ResponseCode +Server_AbstractParticipant::cmdGameSay(const Command_GameSay &cmd, ResponseContainer & /*rc*/, GameEventStorage &ges) +{ + if (spectator) { + /* Spectators can only talk if: + * (a) the game creator allows it + * (b) the spectator is a moderator/administrator + * (c) the spectator is a judge + */ + bool isModOrJudge = (userInfo->user_level() & (ServerInfo_User::IsModerator | ServerInfo_User::IsJudge)); + if (!isModOrJudge && !game->getSpectatorsCanTalk()) { + return Response::RespFunctionNotAllowed; + } + } + + if (!userInterface->addSaidMessageSize(static_cast(cmd.message().size()))) { + return Response::RespChatFlood; + } + Event_GameSay event; + event.set_message(cmd.message()); + ges.enqueueGameEvent(event, playerId); + + game->getRoom()->getServer()->getDatabaseInterface()->logMessage( + userInfo->id(), QString::fromStdString(userInfo->name()), QString::fromStdString(userInfo->address()), + textFromStdString(cmd.message()), Server_DatabaseInterface::MessageTargetGame, game->getGameId(), + game->getDescription()); + + return Response::RespOk; +} + +Response::ResponseCode Server_AbstractParticipant::cmdShuffle(const Command_Shuffle & /*cmd*/, + ResponseContainer & /*rc*/, + GameEventStorage & /*ges*/) +{ + return Response::RespFunctionNotAllowed; +} + +Response::ResponseCode Server_AbstractParticipant::cmdMulligan(const Command_Mulligan & /*cmd*/, + ResponseContainer & /*rc*/, + GameEventStorage & /*ges*/) +{ + return Response::RespFunctionNotAllowed; +} + +Response::ResponseCode Server_AbstractParticipant::cmdRollDie(const Command_RollDie & /*cmd*/, + ResponseContainer & /*rc*/, + GameEventStorage & /*ges*/) const +{ + return Response::RespFunctionNotAllowed; +} + +Response::ResponseCode Server_AbstractParticipant::cmdDrawCards(const Command_DrawCards & /*cmd*/, + ResponseContainer & /*rc*/, + GameEventStorage & /*ges*/) +{ + return Response::RespFunctionNotAllowed; +} + +Response::ResponseCode Server_AbstractParticipant::cmdUndoDraw(const Command_UndoDraw & /*cmd*/, + ResponseContainer & /*rc*/, + GameEventStorage & /*ges*/) +{ + return Response::RespFunctionNotAllowed; +} + +Response::ResponseCode Server_AbstractParticipant::cmdMoveCard(const Command_MoveCard & /*cmd*/, + ResponseContainer & /*rc*/, + GameEventStorage & /*ges*/) +{ + return Response::RespFunctionNotAllowed; +} + +Response::ResponseCode Server_AbstractParticipant::cmdFlipCard(const Command_FlipCard & /*cmd*/, + ResponseContainer & /*rc*/, + GameEventStorage & /*ges*/) +{ + return Response::RespFunctionNotAllowed; +} + +Response::ResponseCode Server_AbstractParticipant::cmdAttachCard(const Command_AttachCard & /*cmd*/, + ResponseContainer & /*rc*/, + GameEventStorage & /*ges*/) +{ + return Response::RespFunctionNotAllowed; +} + +Response::ResponseCode Server_AbstractParticipant::cmdCreateToken(const Command_CreateToken & /*cmd*/, + ResponseContainer & /*rc*/, + GameEventStorage & /*ges*/) +{ + return Response::RespFunctionNotAllowed; +} + +Response::ResponseCode Server_AbstractParticipant::cmdCreateArrow(const Command_CreateArrow & /*cmd*/, + ResponseContainer & /*rc*/, + GameEventStorage & /*ges*/) +{ + return Response::RespFunctionNotAllowed; +} + +Response::ResponseCode Server_AbstractParticipant::cmdDeleteArrow(const Command_DeleteArrow & /*cmd*/, + ResponseContainer & /*rc*/, + GameEventStorage & /*ges*/) +{ + return Response::RespFunctionNotAllowed; +} + +Response::ResponseCode Server_AbstractParticipant::cmdSetCardAttr(const Command_SetCardAttr & /*cmd*/, + ResponseContainer & /*rc*/, + GameEventStorage & /*ges*/) +{ + return Response::RespFunctionNotAllowed; +} + +Response::ResponseCode Server_AbstractParticipant::cmdSetCardCounter(const Command_SetCardCounter & /*cmd*/, + ResponseContainer & /*rc*/, + GameEventStorage & /*ges*/) +{ + return Response::RespFunctionNotAllowed; +} + +Response::ResponseCode Server_AbstractParticipant::cmdIncCardCounter(const Command_IncCardCounter & /*cmd*/, + ResponseContainer & /*rc*/, + GameEventStorage & /*ges*/) +{ + return Response::RespFunctionNotAllowed; +} + +Response::ResponseCode Server_AbstractParticipant::cmdIncCounter(const Command_IncCounter & /*cmd*/, + ResponseContainer & /*rc*/, + GameEventStorage & /*ges*/) +{ + return Response::RespFunctionNotAllowed; +} + +Response::ResponseCode Server_AbstractParticipant::cmdCreateCounter(const Command_CreateCounter & /*cmd*/, + ResponseContainer & /*rc*/, + GameEventStorage & /*ges*/) +{ + return Response::RespFunctionNotAllowed; +} + +Response::ResponseCode Server_AbstractParticipant::cmdSetCounter(const Command_SetCounter & /*cmd*/, + ResponseContainer & /*rc*/, + GameEventStorage & /*ges*/) +{ + return Response::RespFunctionNotAllowed; +} + +Response::ResponseCode Server_AbstractParticipant::cmdDelCounter(const Command_DelCounter & /*cmd*/, + ResponseContainer & /*rc*/, + GameEventStorage & /*ges*/) +{ + return Response::RespFunctionNotAllowed; +} + +Response::ResponseCode Server_AbstractParticipant::cmdNextTurn(const Command_NextTurn & /*cmd*/, + ResponseContainer & /*rc*/, + GameEventStorage & /*ges*/) +{ + if (!game->getGameStarted()) { + return Response::RespGameNotStarted; + } + + if (!judge) { + return Response::RespFunctionNotAllowed; + } + + game->nextTurn(); + return Response::RespOk; +} + +Response::ResponseCode Server_AbstractParticipant::cmdSetActivePhase(const Command_SetActivePhase &cmd, + ResponseContainer & /*rc*/, + GameEventStorage & /*ges*/) +{ + if (!game->getGameStarted()) { + return Response::RespGameNotStarted; + } + + if (!judge) { + return Response::RespFunctionNotAllowed; + } + + game->setActivePhase(cmd.phase()); + + return Response::RespOk; +} + +Response::ResponseCode Server_AbstractParticipant::cmdDumpZone(const Command_DumpZone & /*cmd*/, + ResponseContainer & /*rc*/, + GameEventStorage & /*ges*/) +{ + return Response::RespFunctionNotAllowed; +} + +Response::ResponseCode Server_AbstractParticipant::cmdRevealCards(const Command_RevealCards & /*cmd*/, + ResponseContainer & /*rc*/, + GameEventStorage & /*ges*/) +{ + return Response::RespFunctionNotAllowed; +} + +Response::ResponseCode Server_AbstractParticipant::cmdChangeZoneProperties(const Command_ChangeZoneProperties & /*cmd*/, + ResponseContainer & /*rc*/, + GameEventStorage & /*ges*/) +{ + return Response::RespFunctionNotAllowed; +} + +Response::ResponseCode Server_AbstractParticipant::cmdReverseTurn(const Command_ReverseTurn & /*cmd*/, + ResponseContainer & /*rc*/, + GameEventStorage &ges) +{ + if (!judge) { + if (spectator) { + return Response::RespFunctionNotAllowed; + } + + if (!game->getGameStarted()) { + return Response::RespGameNotStarted; + } + } + + bool reversedTurn = game->reverseTurnOrder(); + + Event_ReverseTurn event; + event.set_reversed(reversedTurn); + ges.enqueueGameEvent(event, playerId); + + return Response::RespOk; +} + +Response::ResponseCode +Server_AbstractParticipant::processGameCommand(const GameCommand &command, ResponseContainer &rc, GameEventStorage &ges) +{ + switch ((GameCommand::GameCommandType)getPbExtension(command)) { + case GameCommand::KICK_FROM_GAME: + return cmdKickFromGame(command.GetExtension(Command_KickFromGame::ext), rc, ges); + break; + case GameCommand::LEAVE_GAME: + return cmdLeaveGame(command.GetExtension(Command_LeaveGame::ext), rc, ges); + break; + case GameCommand::GAME_SAY: + return cmdGameSay(command.GetExtension(Command_GameSay::ext), rc, ges); + break; + case GameCommand::SHUFFLE: + return cmdShuffle(command.GetExtension(Command_Shuffle::ext), rc, ges); + break; + case GameCommand::MULLIGAN: + return cmdMulligan(command.GetExtension(Command_Mulligan::ext), rc, ges); + break; + case GameCommand::ROLL_DIE: + return cmdRollDie(command.GetExtension(Command_RollDie::ext), rc, ges); + break; + case GameCommand::DRAW_CARDS: + return cmdDrawCards(command.GetExtension(Command_DrawCards::ext), rc, ges); + break; + case GameCommand::UNDO_DRAW: + return cmdUndoDraw(command.GetExtension(Command_UndoDraw::ext), rc, ges); + break; + case GameCommand::FLIP_CARD: + return cmdFlipCard(command.GetExtension(Command_FlipCard::ext), rc, ges); + break; + case GameCommand::ATTACH_CARD: + return cmdAttachCard(command.GetExtension(Command_AttachCard::ext), rc, ges); + break; + case GameCommand::CREATE_TOKEN: + return cmdCreateToken(command.GetExtension(Command_CreateToken::ext), rc, ges); + break; + case GameCommand::CREATE_ARROW: + return cmdCreateArrow(command.GetExtension(Command_CreateArrow::ext), rc, ges); + break; + case GameCommand::DELETE_ARROW: + return cmdDeleteArrow(command.GetExtension(Command_DeleteArrow::ext), rc, ges); + break; + case GameCommand::SET_CARD_ATTR: + return cmdSetCardAttr(command.GetExtension(Command_SetCardAttr::ext), rc, ges); + break; + case GameCommand::SET_CARD_COUNTER: + return cmdSetCardCounter(command.GetExtension(Command_SetCardCounter::ext), rc, ges); + break; + case GameCommand::INC_CARD_COUNTER: + return cmdIncCardCounter(command.GetExtension(Command_IncCardCounter::ext), rc, ges); + break; + case GameCommand::READY_START: + return cmdReadyStart(command.GetExtension(Command_ReadyStart::ext), rc, ges); + break; + case GameCommand::CONCEDE: + return cmdConcede(command.GetExtension(Command_Concede::ext), rc, ges); + break; + case GameCommand::INC_COUNTER: + return cmdIncCounter(command.GetExtension(Command_IncCounter::ext), rc, ges); + break; + case GameCommand::CREATE_COUNTER: + return cmdCreateCounter(command.GetExtension(Command_CreateCounter::ext), rc, ges); + break; + case GameCommand::SET_COUNTER: + return cmdSetCounter(command.GetExtension(Command_SetCounter::ext), rc, ges); + break; + case GameCommand::DEL_COUNTER: + return cmdDelCounter(command.GetExtension(Command_DelCounter::ext), rc, ges); + break; + case GameCommand::NEXT_TURN: + return cmdNextTurn(command.GetExtension(Command_NextTurn::ext), rc, ges); + break; + case GameCommand::SET_ACTIVE_PHASE: + return cmdSetActivePhase(command.GetExtension(Command_SetActivePhase::ext), rc, ges); + break; + case GameCommand::DUMP_ZONE: + return cmdDumpZone(command.GetExtension(Command_DumpZone::ext), rc, ges); + break; + case GameCommand::REVEAL_CARDS: + return cmdRevealCards(command.GetExtension(Command_RevealCards::ext), rc, ges); + break; + case GameCommand::MOVE_CARD: + return cmdMoveCard(command.GetExtension(Command_MoveCard::ext), rc, ges); + break; + case GameCommand::SET_SIDEBOARD_PLAN: + return cmdSetSideboardPlan(command.GetExtension(Command_SetSideboardPlan::ext), rc, ges); + break; + case GameCommand::DECK_SELECT: + return cmdDeckSelect(command.GetExtension(Command_DeckSelect::ext), rc, ges); + break; + case GameCommand::SET_SIDEBOARD_LOCK: + return cmdSetSideboardLock(command.GetExtension(Command_SetSideboardLock::ext), rc, ges); + break; + case GameCommand::CHANGE_ZONE_PROPERTIES: + return cmdChangeZoneProperties(command.GetExtension(Command_ChangeZoneProperties::ext), rc, ges); + break; + case GameCommand::UNCONCEDE: + return cmdUnconcede(command.GetExtension(Command_Unconcede::ext), rc, ges); + break; + case GameCommand::JUDGE: + return cmdJudge(command.GetExtension(Command_Judge::ext), rc, ges); + break; + case GameCommand::REVERSE_TURN: + return cmdReverseTurn(command.GetExtension(Command_ReverseTurn::ext), rc, ges); + break; + default: + return Response::RespInvalidCommand; + } +} + +void Server_AbstractParticipant::sendGameEvent(const GameEventContainer &cont) +{ + QMutexLocker locker(&playerMutex); + + if (userInterface) { + userInterface->sendProtocolItem(cont); + } +} + +void Server_AbstractParticipant::setUserInterface(Server_AbstractUserInterface *_userInterface) +{ + playerMutex.lock(); + userInterface = _userInterface; + playerMutex.unlock(); + + pingTime = _userInterface ? 0 : -1; + + Event_PlayerPropertiesChanged event; + event.mutable_player_properties()->set_ping_seconds(pingTime); + + GameEventStorage ges; + ges.setGameEventContext(Context_ConnectionStateChanged()); + ges.enqueueGameEvent(event, playerId); + ges.sendToGame(game); +} + +void Server_AbstractParticipant::disconnectClient() +{ + bool isRegistered = userInfo->user_level() & ServerInfo_User::IsRegistered; + if (!isRegistered || spectator) { + game->removeParticipant(this, Event_Leave::USER_DISCONNECTED); + } else { + setUserInterface(nullptr); + } +} + +void Server_AbstractParticipant::getInfo(ServerInfo_Player *info, + Server_AbstractParticipant * /*recipient*/, + bool /* omniscient */, + bool withUserInfo) +{ + getProperties(*info->mutable_properties(), withUserInfo); +} diff --git a/common/server/game/server_abstract_participant.h b/common/server/game/server_abstract_participant.h new file mode 100644 index 000000000..dcae09741 --- /dev/null +++ b/common/server/game/server_abstract_participant.h @@ -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 + +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 diff --git a/common/server_arrow.cpp b/common/server/game/server_arrow.cpp similarity index 100% rename from common/server_arrow.cpp rename to common/server/game/server_arrow.cpp diff --git a/common/server_arrow.h b/common/server/game/server_arrow.h similarity index 100% rename from common/server_arrow.h rename to common/server/game/server_arrow.h diff --git a/common/server_arrowtarget.cpp b/common/server/game/server_arrowtarget.cpp similarity index 100% rename from common/server_arrowtarget.cpp rename to common/server/game/server_arrowtarget.cpp diff --git a/common/server_arrowtarget.h b/common/server/game/server_arrowtarget.h similarity index 100% rename from common/server_arrowtarget.h rename to common/server/game/server_arrowtarget.h diff --git a/common/server_card.cpp b/common/server/game/server_card.cpp similarity index 100% rename from common/server_card.cpp rename to common/server/game/server_card.cpp diff --git a/common/server_card.h b/common/server/game/server_card.h similarity index 99% rename from common/server_card.h rename to common/server/game/server_card.h index d96b9d056..a24be2046 100644 --- a/common/server_card.h +++ b/common/server/game/server_card.h @@ -20,7 +20,7 @@ #ifndef SERVER_CARD_H #define SERVER_CARD_H -#include "card_ref.h" +#include "../../card_ref.h" #include "pb/card_attributes.pb.h" #include "pb/serverinfo_card.pb.h" #include "server_arrowtarget.h" diff --git a/common/server_cardzone.cpp b/common/server/game/server_cardzone.cpp similarity index 96% rename from common/server_cardzone.cpp rename to common/server/game/server_cardzone.cpp index 88b61622f..44b946fa0 100644 --- a/common/server_cardzone.cpp +++ b/common/server/game/server_cardzone.cpp @@ -19,8 +19,8 @@ ***************************************************************************/ #include "server_cardzone.h" +#include "../rng_abstract.h" #include "pb/command_move_card.pb.h" -#include "rng_abstract.h" #include "server_card.h" #include "server_player.h" @@ -318,7 +318,7 @@ void Server_CardZone::addWritePermission(int playerId) playersWithWritePermission.insert(playerId); } -void Server_CardZone::getInfo(ServerInfo_Zone *info, Server_Player *playerWhosAsking, bool omniscient) +void Server_CardZone::getInfo(ServerInfo_Zone *info, Server_AbstractParticipant *recipient, bool omniscient) { info->set_name(name.toStdString()); info->set_type(type); @@ -327,10 +327,10 @@ void Server_CardZone::getInfo(ServerInfo_Zone *info, Server_Player *playerWhosAs info->set_always_reveal_top_card(alwaysRevealTopCard); info->set_always_look_at_top_card(alwaysLookAtTopCard); - const auto selfPlayerAsking = playerWhosAsking == player || omniscient; - const auto zonesSelfCanSee = type != ServerInfo_Zone::HiddenZone; - const auto otherPlayerAsking = playerWhosAsking != player; - const auto zonesOthersCanSee = type == ServerInfo_Zone::PublicZone; + const bool selfPlayerAsking = recipient == player || omniscient; + const bool zonesSelfCanSee = type != ServerInfo_Zone::HiddenZone; + const bool otherPlayerAsking = recipient != player; + const bool zonesOthersCanSee = type == ServerInfo_Zone::PublicZone; if ((selfPlayerAsking && zonesSelfCanSee) || (otherPlayerAsking && zonesOthersCanSee)) { QListIterator cardIterator(cards); while (cardIterator.hasNext()) diff --git a/common/server_cardzone.h b/common/server/game/server_cardzone.h similarity index 97% rename from common/server_cardzone.h rename to common/server/game/server_cardzone.h index 51aefbafd..4c7318f08 100644 --- a/common/server_cardzone.h +++ b/common/server/game/server_cardzone.h @@ -29,6 +29,7 @@ class Server_Card; class Server_Player; +class Server_AbstractParticipant; class Server_Game; class GameEventStorage; @@ -87,7 +88,7 @@ public: { return player; } - void getInfo(ServerInfo_Zone *info, Server_Player *playerWhosAsking, bool omniscient); + 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; diff --git a/common/server_counter.cpp b/common/server/game/server_counter.cpp similarity index 100% rename from common/server_counter.cpp rename to common/server/game/server_counter.cpp diff --git a/common/server_counter.h b/common/server/game/server_counter.h similarity index 100% rename from common/server_counter.h rename to common/server/game/server_counter.h diff --git a/common/server_game.cpp b/common/server/game/server_game.cpp similarity index 76% rename from common/server_game.cpp rename to common/server/game/server_game.cpp index e129f9f76..eb064d878 100644 --- a/common/server_game.cpp +++ b/common/server/game/server_game.cpp @@ -19,7 +19,11 @@ ***************************************************************************/ #include "server_game.h" -#include "deck_list.h" +#include "../../deck_list.h" +#include "../server.h" +#include "../server_database_interface.h" +#include "../server_protocolhandler.h" +#include "../server_room.h" #include "pb/context_connection_state_changed.pb.h" #include "pb/context_deck_select.pb.h" #include "pb/context_ping_changed.pb.h" @@ -37,14 +41,11 @@ #include "pb/event_set_active_player.pb.h" #include "pb/game_replay.pb.h" #include "pb/serverinfo_playerping.pb.h" -#include "server.h" #include "server_arrow.h" #include "server_card.h" #include "server_cardzone.h" -#include "server_database_interface.h" #include "server_player.h" -#include "server_protocolhandler.h" -#include "server_room.h" +#include "server_spectator.h" #include #include @@ -101,10 +102,10 @@ Server_Game::~Server_Game() gameClosed = true; sendGameEventContainer(prepareGameEvent(Event_GameClosed(), -1)); - for (auto *anyPlayer : players.values()) { - anyPlayer->prepareDestroy(); + for (auto *participant : participants.values()) { + participant->prepareDestroy(); } - players.clear(); + participants.clear(); room->removeGame(this); delete creatorInfo; @@ -189,36 +190,23 @@ void Server_Game::pingClockTimeout() bool allPlayersInactive = true; int playerCount = 0; - for (auto *anyPlayer : players) { - if (anyPlayer == nullptr) + for (auto *participant : participants) { + if (participant == nullptr) continue; - if (!anyPlayer->getSpectator()) { + if (!participant->getSpectator()) { ++playerCount; } - int oldPingTime = anyPlayer->getPingTime(); - int newPingTime; - { - QMutexLocker playerMutexLocker(&anyPlayer->playerMutex); - if (anyPlayer->getUserInterface()) { - newPingTime = anyPlayer->getUserInterface()->getLastCommandTime(); - } else { - newPingTime = -1; - } - } - - if ((newPingTime != -1) && (!anyPlayer->getSpectator() || anyPlayer->getPlayerId() == hostId)) { - allPlayersInactive = false; - } - - if ((abs(oldPingTime - newPingTime) > 1) || ((newPingTime == -1) && (oldPingTime != -1)) || - ((newPingTime != -1) && (oldPingTime == -1))) { - anyPlayer->setPingTime(newPingTime); - + if (participant->updatePingTime()) { Event_PlayerPropertiesChanged event; - event.mutable_player_properties()->set_ping_seconds(newPingTime); - ges.enqueueGameEvent(event, anyPlayer->getPlayerId()); + event.mutable_player_properties()->set_ping_seconds(participant->getPingTime()); + ges.enqueueGameEvent(event, participant->getPlayerId()); + } + + if ((participant->getPingTime() != -1) && + (!participant->getSpectator() || participant->getPlayerId() == hostId)) { + allPlayersInactive = false; } } ges.sendToGame(this); @@ -233,16 +221,32 @@ void Server_Game::pingClockTimeout() } } +QMap Server_Game::getPlayers() const // copies pointers to new map +{ + QMap players; + QMutexLocker locker(&gameMutex); + for (int id : participants.keys()) { + auto *participant = participants[id]; + if (!participant->getSpectator()) { + players[id] = static_cast(participant); + } + } + return players; +} + +Server_Player *Server_Game::getPlayer(int id) const +{ + auto *participant = participants.value(id); + if (!participant->getSpectator()) { + return static_cast(participant); + } else { + return nullptr; + } +} + int Server_Game::getPlayerCount() const { - QMutexLocker locker(&gameMutex); - - int result = 0; - for (Server_Player *anyPlayer : players.values()) { - if (!anyPlayer->getSpectator()) - ++result; - } - return result; + return participants.size() - getSpectatorCount(); } int Server_Game::getSpectatorCount() const @@ -250,15 +254,15 @@ int Server_Game::getSpectatorCount() const QMutexLocker locker(&gameMutex); int result = 0; - for (Server_Player *anyPlayer : players.values()) { - if (anyPlayer->getSpectator()) + for (Server_AbstractParticipant *participant : participants.values()) { + if (participant->getSpectator()) ++result; } return result; } void Server_Game::createGameStateChangedEvent(Event_GameStateChanged *event, - Server_Player *playerWhosAsking, + Server_AbstractParticipant *recipient, bool omniscient, bool withUserInfo) { @@ -270,8 +274,8 @@ void Server_Game::createGameStateChangedEvent(Event_GameStateChanged *event, } else event->set_game_started(false); - for (Server_Player *anyPlayer : players.values()) { - anyPlayer->getInfo(event->add_player_list(), playerWhosAsking, omniscient, withUserInfo); + for (Server_AbstractParticipant *participant : participants.values()) { + participant->getInfo(event->add_player_list(), recipient, omniscient, withUserInfo); } } @@ -294,21 +298,21 @@ void Server_Game::sendGameStateToPlayers() createGameStateChangedEvent(&spectatorNormalEvent, nullptr, false, false); // send game state info to clients according to their role in the game - for (Server_Player *anyPlayer : players.values()) { + for (auto *participant : participants.values()) { GameEventContainer *gec; - if (anyPlayer->getSpectator()) { - if (spectatorsSeeEverything || anyPlayer->getJudge()) { + if (participant->getSpectator()) { + if (spectatorsSeeEverything || participant->getJudge()) { gec = prepareGameEvent(omniscientEvent, -1); } else { gec = prepareGameEvent(spectatorNormalEvent, -1); } } else { Event_GameStateChanged event; - createGameStateChangedEvent(&event, anyPlayer, false, false); + createGameStateChangedEvent(&event, participant, false, false); gec = prepareGameEvent(event, -1); } - anyPlayer->sendGameEvent(*gec); + participant->sendGameEvent(*gec); delete gec; } } @@ -322,28 +326,27 @@ void Server_Game::doStartGameIfReady(bool forceStartGame) return; } - for (Server_Player *anyPlayer : players.values()) { - if (!anyPlayer->getReadyStart() && !anyPlayer->getSpectator()) { + auto players = getPlayers(); + for (auto *player : players.values()) { + if (!player->getReadyStart()) { if (forceStartGame) { // Player is not ready to start, so kick them // TODO: Move them to Spectators instead - kickPlayer(anyPlayer->getPlayerId()); + kickParticipant(player->getPlayerId()); } else { return; } } } - for (Server_Player *anyPlayer : players.values()) { - if (!anyPlayer->getSpectator()) { - anyPlayer->setupZones(); - } + for (Server_Player *player : players.values()) { + player->setupZones(); } gameStarted = true; - for (Server_Player *anyPlayer : players.values()) { - anyPlayer->setConceded(false); - anyPlayer->setReadyStart(false); + for (auto *player : players.values()) { + player->setConceded(false); + player->setReadyStart(false); } if (firstGameStarted) { @@ -392,8 +395,9 @@ void Server_Game::stopGameIfFinished() QMutexLocker locker(&gameMutex); int playing = 0; - for (Server_Player *anyPlayer : players.values()) { - if (!anyPlayer->getConceded() && !anyPlayer->getSpectator()) + auto players = getPlayers(); + for (auto *player : players.values()) { + if (!player->getConceded()) ++playing; } if (playing > 1) @@ -401,9 +405,9 @@ void Server_Game::stopGameIfFinished() gameStarted = false; - for (Server_Player *anyPlayer : players.values()) { - anyPlayer->clearZones(); - anyPlayer->setConceded(false); + for (auto *player : players.values()) { + player->clearZones(); + player->setConceded(false); } sendGameStateToPlayers(); @@ -424,8 +428,8 @@ Response::ResponseCode Server_Game::checkJoin(ServerInfo_User *user, bool asJudge) { Server_DatabaseInterface *databaseInterface = room->getServer()->getDatabaseInterface(); - for (Server_Player *anyPlayer : players.values()) { - if (anyPlayer->getUserInfo()->name() == user->name()) + for (auto *participant : participants.values()) { + if (participant->getUserInfo()->name() == user->name()) return Response::RespContextError; } @@ -459,8 +463,8 @@ bool Server_Game::containsUser(const QString &userName) const { QMutexLocker locker(&gameMutex); - for (Server_Player *anyPlayer : players.values()) { - if (anyPlayer->getUserInfo()->name() == userName.toStdString()) + for (auto *participant : participants.values()) { + if (participant->getUserInfo()->name() == userName.toStdString()) return true; } return false; @@ -474,17 +478,23 @@ void Server_Game::addPlayer(Server_AbstractUserInterface *userInterface, { QMutexLocker locker(&gameMutex); - Server_Player *newPlayer = new Server_Player(this, nextPlayerId++, userInterface->copyUserInfo(true, true, true), - spectator, judge, userInterface); + Server_AbstractParticipant *newParticipant; + if (spectator) { + newParticipant = new Server_Spectator(this, nextPlayerId++, userInterface->copyUserInfo(true, true, true), + judge, userInterface); + } else { + newParticipant = new Server_Player(this, nextPlayerId++, userInterface->copyUserInfo(true, true, true), judge, + userInterface); + } - newPlayer->moveToThread(thread()); + newParticipant->moveToThread(thread()); Event_Join joinEvent; - newPlayer->getProperties(*joinEvent.mutable_player_properties(), true); + newParticipant->getProperties(*joinEvent.mutable_player_properties(), true); sendGameEventContainer(prepareGameEvent(joinEvent, -1)); - const QString playerName = QString::fromStdString(newPlayer->getUserInfo()->name()); - players.insert(newPlayer->getPlayerId(), newPlayer); + const QString playerName = QString::fromStdString(newParticipant->getUserInfo()->name()); + participants.insert(newParticipant->getPlayerId(), newParticipant); if (spectator) { allSpectatorsEver.insert(playerName); } else { @@ -492,8 +502,8 @@ void Server_Game::addPlayer(Server_AbstractUserInterface *userInterface, // if the original creator of the game joins, give them host status back // FIXME: transferring host to spectators has side effects - if (newPlayer->getUserInfo()->name() == creatorInfo->name()) { - hostId = newPlayer->getPlayerId(); + if (newParticipant->getUserInfo()->name() == creatorInfo->name()) { + hostId = newParticipant->getPlayerId(); sendGameEventContainer(prepareGameEvent(Event_GameHostChanged(), hostId)); } } @@ -507,41 +517,42 @@ void Server_Game::addPlayer(Server_AbstractUserInterface *userInterface, emit gameInfoChanged(gameInfo); } - if ((newPlayer->getUserInfo()->user_level() & ServerInfo_User::IsRegistered) && !spectator) - room->getServer()->addPersistentPlayer(playerName, room->getId(), gameId, newPlayer->getPlayerId()); + if ((newParticipant->getUserInfo()->user_level() & ServerInfo_User::IsRegistered) && !spectator) + room->getServer()->addPersistentPlayer(playerName, room->getId(), gameId, newParticipant->getPlayerId()); - userInterface->playerAddedToGame(gameId, room->getId(), newPlayer->getPlayerId()); + userInterface->playerAddedToGame(gameId, room->getId(), newParticipant->getPlayerId()); - createGameJoinedEvent(newPlayer, rc, false); + createGameJoinedEvent(newParticipant, rc, false); } -void Server_Game::removePlayer(Server_Player *player, Event_Leave::LeaveReason reason) +void Server_Game::removeParticipant(Server_AbstractParticipant *participant, Event_Leave::LeaveReason reason) { - room->getServer()->removePersistentPlayer(QString::fromStdString(player->getUserInfo()->name()), room->getId(), - gameId, player->getPlayerId()); - players.remove(player->getPlayerId()); + room->getServer()->removePersistentPlayer(QString::fromStdString(participant->getUserInfo()->name()), room->getId(), + gameId, participant->getPlayerId()); + participants.remove(participant->getPlayerId()); + bool spectator = participant->getSpectator(); GameEventStorage ges; - removeArrowsRelatedToPlayer(ges, player); - unattachCards(ges, player); + if (!spectator) { + auto *player = static_cast(participant); + removeArrowsRelatedToPlayer(ges, player); + unattachCards(ges, player); + } Event_Leave event; event.set_reason(reason); - ges.enqueueGameEvent(event, player->getPlayerId()); + ges.enqueueGameEvent(event, participant->getPlayerId()); ges.sendToGame(this); - bool playerActive = activePlayer == player->getPlayerId(); - bool playerHost = hostId == player->getPlayerId(); - bool spectator = player->getSpectator(); - player->prepareDestroy(); + bool playerActive = activePlayer == participant->getPlayerId(); + bool playerHost = hostId == participant->getPlayerId(); + participant->prepareDestroy(); if (playerHost) { int newHostId = -1; - for (Server_Player *otherPlayer : players.values()) { - if (!otherPlayer->getSpectator()) { - newHostId = otherPlayer->getPlayerId(); - break; - } + for (auto *otherPlayer : getPlayers().values()) { + newHostId = otherPlayer->getPlayerId(); + break; } if (newHostId != -1) { hostId = newHostId; @@ -573,28 +584,28 @@ void Server_Game::removeArrowsRelatedToPlayer(GameEventStorage &ges, Server_Play // Remove all arrows of other players pointing to the player being removed or to one of his cards. // Also remove all arrows starting at one of his cards. This is necessary since players can create // arrows that start at another person's cards. - for (Server_Player *anyPlayer : players.values()) { + for (Server_Player *anyPlayer : getPlayers().values()) { QList arrows = anyPlayer->getArrows().values(); QList toDelete; for (int i = 0; i < arrows.size(); ++i) { - Server_Arrow *a = arrows[i]; - Server_Card *targetCard = qobject_cast(a->getTargetItem()); + Server_Arrow *arrow = arrows[i]; + Server_Card *targetCard = qobject_cast(arrow->getTargetItem()); if (targetCard) { if (targetCard->getZone() != nullptr && targetCard->getZone()->getPlayer() == player) - toDelete.append(a); - } else if (static_cast(a->getTargetItem()) == player) - toDelete.append(a); + toDelete.append(arrow); + } else if (static_cast(arrow->getTargetItem()) == player) + toDelete.append(arrow); // Don't use else here! It has to happen regardless of whether targetCard == 0. - if (a->getStartCard()->getZone() != nullptr && a->getStartCard()->getZone()->getPlayer() == player) - toDelete.append(a); + if (arrow->getStartCard()->getZone() != nullptr && arrow->getStartCard()->getZone()->getPlayer() == player) + toDelete.append(arrow); } for (int i = 0; i < toDelete.size(); ++i) { Event_DeleteArrow event; event.set_arrow_id(toDelete[i]->getId()); - ges.enqueueGameEvent(event, anyPlayer->getPlayerId()); + ges.enqueueGameEvent(event, player->getPlayerId()); - anyPlayer->deleteArrow(toDelete[i]->getId()); + player->deleteArrow(toDelete[i]->getId()); } } } @@ -621,19 +632,19 @@ void Server_Game::unattachCards(GameEventStorage &ges, Server_Player *player) } } -bool Server_Game::kickPlayer(int playerId) +bool Server_Game::kickParticipant(int playerId) { QMutexLocker locker(&gameMutex); - Server_Player *playerToKick = players.value(playerId); - if (!playerToKick) + auto *participant = participants.value(playerId); + if (!participant) return false; GameEventContainer *gec = prepareGameEvent(Event_Kicked(), -1); - playerToKick->sendGameEvent(*gec); + participant->sendGameEvent(*gec); delete gec; - removePlayer(playerToKick, Event_Leave::USER_KICKED); + removeParticipant(participant, Event_Leave::USER_KICKED); return true; } @@ -655,16 +666,16 @@ void Server_Game::setActivePhase(int _activePhase) { QMutexLocker locker(&gameMutex); - for (Server_Player *anyPlayer : players.values()) { - QList toDelete = anyPlayer->getArrows().values(); + for (auto *player : getPlayers().values()) { + QList toDelete = player->getArrows().values(); for (int i = 0; i < toDelete.size(); ++i) { Server_Arrow *a = toDelete[i]; Event_DeleteArrow event; event.set_arrow_id(a->getId()); - sendGameEventContainer(prepareGameEvent(event, anyPlayer->getPlayerId())); + sendGameEventContainer(prepareGameEvent(event, player->getPlayerId())); - anyPlayer->deleteArrow(a->getId()); + player->deleteArrow(a->getId()); } } @@ -679,15 +690,17 @@ void Server_Game::nextTurn() { QMutexLocker locker(&gameMutex); - if (players.isEmpty()) { + if (participants.isEmpty()) { qWarning() << "Server_Game::nextTurn was called while players is empty; gameId = " << gameId; return; } + auto players = getPlayers(); const QList keys = players.keys(); int listPos = -1; - if (activePlayer != -1) + if (activePlayer != -1) { listPos = keys.indexOf(activePlayer); + } do { if (turnOrderReversed) { --listPos; @@ -700,19 +713,21 @@ void Server_Game::nextTurn() listPos = 0; } } - } while (players.value(keys[listPos])->getSpectator() || players.value(keys[listPos])->getConceded()); + } while (players.value(keys[listPos])->getConceded()); setActivePlayer(keys[listPos]); } -void Server_Game::createGameJoinedEvent(Server_Player *joiningPlayer, ResponseContainer &rc, bool resuming) +void Server_Game::createGameJoinedEvent(Server_AbstractParticipant *joiningParticipant, + ResponseContainer &rc, + bool resuming) { Event_GameJoined event1; getInfo(*event1.mutable_game_info()); event1.set_host_id(hostId); - event1.set_player_id(joiningPlayer->getPlayerId()); - event1.set_spectator(joiningPlayer->getSpectator()); - event1.set_judge(joiningPlayer->getJudge()); + event1.set_player_id(joiningParticipant->getPlayerId()); + event1.set_spectator(joiningParticipant->getSpectator()); + event1.set_judge(joiningParticipant->getJudge()); event1.set_resuming(resuming); if (resuming) { const QStringList &allGameTypes = room->getGameTypes(); @@ -730,10 +745,9 @@ void Server_Game::createGameJoinedEvent(Server_Player *joiningPlayer, ResponseCo event2.set_active_player_id(activePlayer); event2.set_active_phase(activePhase); - for (auto *anyPlayer : players.values()) { - anyPlayer->getInfo(event2.add_player_list(), joiningPlayer, - (joiningPlayer->getSpectator() && (spectatorsSeeEverything || joiningPlayer->getJudge())), - true); + bool omniscient = joiningParticipant->getSpectator() && (spectatorsSeeEverything || joiningParticipant->getJudge()); + for (auto *participant : participants.values()) { + participant->getInfo(event2.add_player_list(), joiningParticipant, omniscient, true); } rc.enqueuePostResponseItem(ServerMessage::GAME_EVENT_CONTAINER, prepareGameEvent(event2, -1)); @@ -746,12 +760,13 @@ void Server_Game::sendGameEventContainer(GameEventContainer *cont, QMutexLocker locker(&gameMutex); cont->set_game_id(gameId); - for (Server_Player *anyPlayer : players.values()) { - const bool playerPrivate = (anyPlayer->getPlayerId() == privatePlayerId) || - (anyPlayer->getSpectator() && (spectatorsSeeEverything || anyPlayer->getJudge())); + for (auto *participant : participants.values()) { + const bool playerPrivate = + (participant->getPlayerId() == privatePlayerId) || + (participant->getSpectator() && (spectatorsSeeEverything || participant->getJudge())); if ((recipients.testFlag(GameEventStorageItem::SendToPrivate) && playerPrivate) || (recipients.testFlag(GameEventStorageItem::SendToOthers) && !playerPrivate)) - anyPlayer->sendGameEvent(*cont); + participant->sendGameEvent(*cont); } if (recipients.testFlag(GameEventStorageItem::SendToPrivate)) { cont->set_seconds_elapsed(secondsElapsed - startTimeOfThisGame); diff --git a/common/server_game.h b/common/server/game/server_game.h similarity index 91% rename from common/server_game.h rename to common/server/game/server_game.h index 226a14149..6bb162763 100644 --- a/common/server_game.h +++ b/common/server/game/server_game.h @@ -20,10 +20,10 @@ #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 "server_response_containers.h" #include #include @@ -37,8 +37,8 @@ class GameEventContainer; class GameReplay; class Server_Room; class Server_Player; +class Server_AbstractParticipant; class ServerInfo_User; -class ServerInfo_Player; class ServerInfo_Game; class Server_AbstractUserInterface; class Event_GameStateChanged; @@ -51,7 +51,7 @@ private: int nextPlayerId; int hostId; ServerInfo_User *creatorInfo; - QMap players; + QMap participants; QSet allPlayersEver, allSpectatorsEver; bool gameStarted; bool gameClosed; @@ -78,7 +78,7 @@ private: GameReplay *currentReplay; void createGameStateChangedEvent(Event_GameStateChanged *event, - Server_Player *playerWhosAsking, + Server_AbstractParticipant *recipient, bool omniscient, bool withUserInfo); void storeGameInformation(); @@ -130,9 +130,11 @@ public: } int getPlayerCount() const; int getSpectatorCount() const; - const QMap &getPlayers() const + QMap getPlayers() const; + Server_Player *getPlayer(int id) const; + const QMap &getParticipants() const { - return players; + return participants; } int getGameId() const { @@ -182,10 +184,10 @@ public: bool spectator, bool judge, bool broadcastUpdate = true); - void removePlayer(Server_Player *player, Event_Leave::LeaveReason reason); + void removeParticipant(Server_AbstractParticipant *participant, Event_Leave::LeaveReason reason); void removeArrowsRelatedToPlayer(GameEventStorage &ges, Server_Player *player); void unattachCards(GameEventStorage &ges, Server_Player *player); - bool kickPlayer(int playerId); + bool kickParticipant(int playerId); void startGameIfReady(bool forceStartGame); void stopGameIfFinished(); int getActivePlayer() const @@ -208,7 +210,7 @@ public: return turnOrderReversed = !turnOrderReversed; } - void createGameJoinedEvent(Server_Player *player, ResponseContainer &rc, bool resuming); + void createGameJoinedEvent(Server_AbstractParticipant *participant, ResponseContainer &rc, bool resuming); GameEventContainer * prepareGameEvent(const ::google::protobuf::Message &gameEvent, int playerId, GameEventContext *context = 0); diff --git a/common/server_player.cpp b/common/server/game/server_player.cpp similarity index 84% rename from common/server_player.cpp rename to common/server/game/server_player.cpp index b49f3c0e7..b8b9b7cd5 100644 --- a/common/server_player.cpp +++ b/common/server/game/server_player.cpp @@ -1,9 +1,15 @@ #include "server_player.h" -#include "color.h" -#include "deck_list.h" -#include "deck_list_card_node.h" -#include "get_pb_extension.h" +#include "../../color.h" +#include "../../deck_list.h" +#include "../../deck_list_card_node.h" +#include "../../get_pb_extension.h" +#include "../../rng_abstract.h" +#include "../../trice_limits.h" +#include "../server.h" +#include "../server_abstractuserinterface.h" +#include "../server_database_interface.h" +#include "../server_room.h" #include "pb/command_attach_card.pb.h" #include "pb/command_change_zone_properties.pb.h" #include "pb/command_concede.pb.h" @@ -70,17 +76,11 @@ #include "pb/response_dump_zone.pb.h" #include "pb/serverinfo_player.pb.h" #include "pb/serverinfo_user.pb.h" -#include "rng_abstract.h" -#include "server.h" -#include "server_abstractuserinterface.h" #include "server_arrow.h" #include "server_card.h" #include "server_cardzone.h" #include "server_counter.h" -#include "server_database_interface.h" #include "server_game.h" -#include "server_room.h" -#include "trice_limits.h" #include #include @@ -108,13 +108,12 @@ struct MoveCardStruct Server_Player::Server_Player(Server_Game *_game, int _playerId, const ServerInfo_User &_userInfo, - bool _spectator, bool _judge, Server_AbstractUserInterface *_userInterface) - : ServerInfo_User_Container(_userInfo), game(_game), userInterface(_userInterface), deck(nullptr), pingTime(0), - playerId(_playerId), spectator(_spectator), judge(_judge), nextCardId(0), readyStart(false), conceded(false), - sideboardLocked(true) + : Server_AbstractParticipant(_game, _playerId, _userInfo, _judge, _userInterface), deck(nullptr), nextCardId(0), + readyStart(false), conceded(false), sideboardLocked(true) { + spectator = false; } Server_Player::~Server_Player() = default; @@ -124,12 +123,7 @@ void Server_Player::prepareDestroy() delete deck; deck = nullptr; - playerMutex.lock(); - if (userInterface) { - userInterface->playerRemovedFromGame(game); - } - playerMutex.unlock(); - + removeFromGame(); clearZones(); deleteLater(); @@ -269,25 +263,6 @@ void Server_Player::clearZones() lastDrawList.clear(); } -void Server_Player::getProperties(ServerInfo_PlayerProperties &result, bool withUserInfo) -{ - result.set_player_id(playerId); - if (withUserInfo) { - copyUserInfo(*(result.mutable_user_info()), true); - } - result.set_spectator(spectator); - if (!spectator) { - result.set_conceded(conceded); - result.set_sideboard_locked(sideboardLocked); - result.set_ready_start(readyStart); - } - result.set_judge(judge); - if (deck) { - result.set_deck_hash(deck->getDeckHash().toStdString()); - } - result.set_ping_seconds(pingTime); -} - void Server_Player::addZone(Server_CardZone *zone) { zones.insert(zone->getName(), zone); @@ -541,8 +516,7 @@ Response::ResponseCode Server_Player::moveCard(GameEventStorage &ges, if (startzone != targetzone) { // Delete all arrows from and to the card - const QList &players = game->getPlayers().values(); - for (auto player : players) { + for (auto *player : game->getPlayers().values()) { QList arrowsToDelete; for (Server_Arrow *arrow : player->getArrows()) { if ((arrow->getStartCard() == card) || (arrow->getTargetItem() == card)) @@ -781,34 +755,9 @@ Response::ResponseCode Server_Player::setCardAttrHelper(GameEventStorage &ges, return Response::RespOk; } -Response::ResponseCode -Server_Player::cmdLeaveGame(const Command_LeaveGame & /*cmd*/, ResponseContainer & /*rc*/, GameEventStorage & /*ges*/) -{ - game->removePlayer(this, Event_Leave::USER_LEFT); - return Response::RespOk; -} - -Response::ResponseCode -Server_Player::cmdKickFromGame(const Command_KickFromGame &cmd, ResponseContainer & /*rc*/, GameEventStorage & /*ges*/) -{ - if ((game->getHostId() != playerId) && !(userInfo->user_level() & ServerInfo_User::IsModerator)) { - return Response::RespFunctionNotAllowed; - } - - if (!game->kickPlayer(cmd.player_id())) { - return Response::RespNameNotFound; - } - - return Response::RespOk; -} - Response::ResponseCode Server_Player::cmdDeckSelect(const Command_DeckSelect &cmd, ResponseContainer &rc, GameEventStorage &ges) { - if (spectator) { - return Response::RespFunctionNotAllowed; - } - DeckList *newDeck; if (cmd.has_deck_id()) { try { @@ -853,9 +802,6 @@ Response::ResponseCode Server_Player::cmdSetSideboardPlan(const Command_SetSideb ResponseContainer & /*rc*/, GameEventStorage & /*ges*/) { - if (spectator) { - return Response::RespFunctionNotAllowed; - } if (readyStart) { return Response::RespContextError; } @@ -879,9 +825,6 @@ Response::ResponseCode Server_Player::cmdSetSideboardLock(const Command_SetSideb ResponseContainer & /*rc*/, GameEventStorage &ges) { - if (spectator) { - return Response::RespFunctionNotAllowed; - } if (readyStart) { return Response::RespContextError; } @@ -908,9 +851,6 @@ Response::ResponseCode Server_Player::cmdSetSideboardLock(const Command_SetSideb Response::ResponseCode Server_Player::cmdConcede(const Command_Concede & /*cmd*/, ResponseContainer & /*rc*/, GameEventStorage &ges) { - if (spectator) { - return Response::RespFunctionNotAllowed; - } if (!game->getGameStarted()) { return Response::RespGameNotStarted; } @@ -939,7 +879,7 @@ Server_Player::cmdConcede(const Command_Concede & /*cmd*/, ResponseContainer & / CardToMove cardToMove; cardToMove.set_card_id(card->getId()); - for (const auto &player : game->getPlayers()) { + for (const auto *player : game->getPlayers()) { if (player == nullptr || player->getUserInfo() == nullptr) { continue; } @@ -984,9 +924,6 @@ Server_Player::cmdConcede(const Command_Concede & /*cmd*/, ResponseContainer & / Response::ResponseCode Server_Player::cmdUnconcede(const Command_Unconcede & /*cmd*/, ResponseContainer & /*rc*/, GameEventStorage &ges) { - if (spectator) { - return Response::RespFunctionNotAllowed; - } if (!game->getGameStarted()) { return Response::RespGameNotStarted; } @@ -1008,31 +945,9 @@ Server_Player::cmdUnconcede(const Command_Unconcede & /*cmd*/, ResponseContainer return Response::RespOk; } -Response::ResponseCode Server_Player::cmdJudge(const Command_Judge &cmd, ResponseContainer &rc, GameEventStorage &ges) -{ - if (!judge) - return Response::RespFunctionNotAllowed; - - Server_Player *player = this->game->getPlayers().value(cmd.target_id()); - - ges.setForcedByJudge(playerId); - if (player == nullptr) - return Response::RespContextError; - - for (int i = 0; i < cmd.game_command_size(); ++i) { - player->processGameCommand(cmd.game_command(i), rc, ges); - } - - return Response::RespOk; -} - Response::ResponseCode Server_Player::cmdReadyStart(const Command_ReadyStart &cmd, ResponseContainer & /*rc*/, GameEventStorage &ges) { - if (spectator) { - return Response::RespFunctionNotAllowed; - } - if (!deck || game->getGameStarted()) { return Response::RespContextError; } @@ -1060,43 +975,9 @@ Server_Player::cmdReadyStart(const Command_ReadyStart &cmd, ResponseContainer & return Response::RespOk; } -Response::ResponseCode -Server_Player::cmdGameSay(const Command_GameSay &cmd, ResponseContainer & /*rc*/, GameEventStorage &ges) -{ - if (spectator) { - /* Spectators can only talk if: - * (a) the game creator allows it - * (b) the spectator is a moderator/administrator - * (c) the spectator is a judge - */ - bool isModOrJudge = (userInfo->user_level() & (ServerInfo_User::IsModerator | ServerInfo_User::IsJudge)); - if (!isModOrJudge && !game->getSpectatorsCanTalk()) { - return Response::RespFunctionNotAllowed; - } - } - - if (!userInterface->addSaidMessageSize(static_cast(cmd.message().size()))) { - return Response::RespChatFlood; - } - Event_GameSay event; - event.set_message(cmd.message()); - ges.enqueueGameEvent(event, playerId); - - game->getRoom()->getServer()->getDatabaseInterface()->logMessage( - userInfo->id(), QString::fromStdString(userInfo->name()), QString::fromStdString(userInfo->address()), - textFromStdString(cmd.message()), Server_DatabaseInterface::MessageTargetGame, game->getGameId(), - game->getDescription()); - - return Response::RespOk; -} - Response::ResponseCode Server_Player::cmdShuffle(const Command_Shuffle &cmd, ResponseContainer & /*rc*/, GameEventStorage &ges) { - if (spectator) { - return Response::RespFunctionNotAllowed; - } - if (!game->getGameStarted()) { return Response::RespGameNotStarted; } @@ -1129,10 +1010,6 @@ Server_Player::cmdShuffle(const Command_Shuffle &cmd, ResponseContainer & /*rc*/ Response::ResponseCode Server_Player::cmdMulligan(const Command_Mulligan &cmd, ResponseContainer & /*rc*/, GameEventStorage &ges) { - if (spectator) { - return Response::RespFunctionNotAllowed; - } - if (!game->getGameStarted()) { return Response::RespGameNotStarted; } @@ -1170,9 +1047,6 @@ Server_Player::cmdMulligan(const Command_Mulligan &cmd, ResponseContainer & /*rc Response::ResponseCode Server_Player::cmdRollDie(const Command_RollDie &cmd, ResponseContainer & /*rc*/, GameEventStorage &ges) const { - if (spectator) { - return Response::RespFunctionNotAllowed; - } if (conceded) { return Response::RespContextError; } @@ -1199,10 +1073,6 @@ Server_Player::cmdRollDie(const Command_RollDie &cmd, ResponseContainer & /*rc*/ Response::ResponseCode Server_Player::cmdDrawCards(const Command_DrawCards &cmd, ResponseContainer & /*rc*/, GameEventStorage &ges) { - if (spectator) { - return Response::RespFunctionNotAllowed; - } - if (!game->getGameStarted()) { return Response::RespGameNotStarted; } @@ -1216,10 +1086,6 @@ Server_Player::cmdDrawCards(const Command_DrawCards &cmd, ResponseContainer & /* Response::ResponseCode Server_Player::cmdUndoDraw(const Command_UndoDraw & /*cmd*/, ResponseContainer & /*rc*/, GameEventStorage &ges) { - if (spectator) { - return Response::RespFunctionNotAllowed; - } - if (!game->getGameStarted()) { return Response::RespGameNotStarted; } @@ -1244,10 +1110,6 @@ Server_Player::cmdUndoDraw(const Command_UndoDraw & /*cmd*/, ResponseContainer & Response::ResponseCode Server_Player::cmdMoveCard(const Command_MoveCard &cmd, ResponseContainer & /*rc*/, GameEventStorage &ges) { - if (spectator) { - return Response::RespFunctionNotAllowed; - } - if (!game->getGameStarted()) { return Response::RespGameNotStarted; } @@ -1255,7 +1117,7 @@ Server_Player::cmdMoveCard(const Command_MoveCard &cmd, ResponseContainer & /*rc return Response::RespContextError; } - Server_Player *startPlayer = game->getPlayers().value(cmd.has_start_player_id() ? cmd.start_player_id() : playerId); + Server_Player *startPlayer = game->getPlayer(cmd.has_start_player_id() ? cmd.start_player_id() : playerId); if (!startPlayer) { return Response::RespNameNotFound; } @@ -1268,7 +1130,7 @@ Server_Player::cmdMoveCard(const Command_MoveCard &cmd, ResponseContainer & /*rc return Response::RespContextError; } - Server_Player *targetPlayer = game->getPlayers().value(cmd.target_player_id()); + Server_Player *targetPlayer = game->getPlayer(cmd.target_player_id()); if (!targetPlayer) { return Response::RespNameNotFound; } @@ -1292,10 +1154,6 @@ Server_Player::cmdMoveCard(const Command_MoveCard &cmd, ResponseContainer & /*rc Response::ResponseCode Server_Player::cmdFlipCard(const Command_FlipCard &cmd, ResponseContainer & /*rc*/, GameEventStorage &ges) { - if (spectator) { - return Response::RespFunctionNotAllowed; - } - if (!game->getGameStarted()) { return Response::RespGameNotStarted; } @@ -1344,10 +1202,6 @@ Server_Player::cmdFlipCard(const Command_FlipCard &cmd, ResponseContainer & /*rc Response::ResponseCode Server_Player::cmdAttachCard(const Command_AttachCard &cmd, ResponseContainer & /*rc*/, GameEventStorage &ges) { - if (spectator) { - return Response::RespFunctionNotAllowed; - } - if (!game->getGameStarted()) { return Response::RespGameNotStarted; } @@ -1370,7 +1224,7 @@ Server_Player::cmdAttachCard(const Command_AttachCard &cmd, ResponseContainer & Server_Card *targetCard = nullptr; if (cmd.has_target_player_id()) { - targetPlayer = game->getPlayers().value(cmd.target_player_id()); + targetPlayer = game->getPlayer(cmd.target_player_id()); if (!targetPlayer) { return Response::RespNameNotFound; } @@ -1404,10 +1258,8 @@ Server_Player::cmdAttachCard(const Command_AttachCard &cmd, ResponseContainer & return Response::RespContextError; } - QMapIterator playerIterator(game->getPlayers()); - while (playerIterator.hasNext()) { - Server_Player *p = playerIterator.next().value(); - QList _arrows = p->getArrows().values(); + for (auto *player : game->getPlayers()) { + QList _arrows = player->getArrows().values(); QList toDelete; for (auto a : _arrows) { auto *tCard = qobject_cast(a->getTargetItem()); @@ -1418,8 +1270,8 @@ Server_Player::cmdAttachCard(const Command_AttachCard &cmd, ResponseContainer & for (auto &i : toDelete) { Event_DeleteArrow event; event.set_arrow_id(i->getId()); - ges.enqueueGameEvent(event, p->getPlayerId()); - p->deleteArrow(i->getId()); + ges.enqueueGameEvent(event, player->getPlayerId()); + player->deleteArrow(i->getId()); } } @@ -1458,10 +1310,6 @@ Server_Player::cmdAttachCard(const Command_AttachCard &cmd, ResponseContainer & Response::ResponseCode Server_Player::cmdCreateToken(const Command_CreateToken &cmd, ResponseContainer &rc, GameEventStorage &ges) { - if (spectator) { - return Response::RespFunctionNotAllowed; - } - if (!game->getGameStarted()) { return Response::RespGameNotStarted; } @@ -1609,8 +1457,7 @@ Server_Player::cmdCreateToken(const Command_CreateToken &cmd, ResponseContainer } // Copy Arrows - const QList &players = game->getPlayers().values(); - for (auto player : players) { + for (auto *player : game->getPlayers().values()) { QList changedArrowIds; for (Server_Arrow *arrow : player->getArrows()) { bool sendGameEvent = false; @@ -1698,10 +1545,6 @@ void Server_Player::sendCreateTokenEvents(Server_CardZone *zone, Response::ResponseCode Server_Player::cmdCreateArrow(const Command_CreateArrow &cmd, ResponseContainer & /*rc*/, GameEventStorage &ges) { - if (spectator) { - return Response::RespFunctionNotAllowed; - } - if (!game->getGameStarted()) { return Response::RespGameNotStarted; } @@ -1709,8 +1552,8 @@ Server_Player::cmdCreateArrow(const Command_CreateArrow &cmd, ResponseContainer return Response::RespContextError; } - Server_Player *startPlayer = game->getPlayers().value(cmd.start_player_id()); - Server_Player *targetPlayer = game->getPlayers().value(cmd.target_player_id()); + Server_Player *startPlayer = game->getPlayer(cmd.start_player_id()); + Server_Player *targetPlayer = game->getPlayer(cmd.target_player_id()); if (!startPlayer || !targetPlayer) { return Response::RespNameNotFound; } @@ -1778,10 +1621,6 @@ Server_Player::cmdCreateArrow(const Command_CreateArrow &cmd, ResponseContainer Response::ResponseCode Server_Player::cmdDeleteArrow(const Command_DeleteArrow &cmd, ResponseContainer & /*rc*/, GameEventStorage &ges) { - if (spectator) { - return Response::RespFunctionNotAllowed; - } - if (!game->getGameStarted()) { return Response::RespGameNotStarted; } @@ -1803,10 +1642,6 @@ Server_Player::cmdDeleteArrow(const Command_DeleteArrow &cmd, ResponseContainer Response::ResponseCode Server_Player::cmdSetCardAttr(const Command_SetCardAttr &cmd, ResponseContainer & /*rc*/, GameEventStorage &ges) { - if (spectator) { - return Response::RespFunctionNotAllowed; - } - if (!game->getGameStarted()) { return Response::RespGameNotStarted; } @@ -1821,10 +1656,6 @@ Server_Player::cmdSetCardAttr(const Command_SetCardAttr &cmd, ResponseContainer Response::ResponseCode Server_Player::cmdSetCardCounter(const Command_SetCardCounter &cmd, ResponseContainer & /*rc*/, GameEventStorage &ges) { - if (spectator) { - return Response::RespFunctionNotAllowed; - } - if (!game->getGameStarted()) { return Response::RespGameNotStarted; } @@ -1857,10 +1688,6 @@ Server_Player::cmdSetCardCounter(const Command_SetCardCounter &cmd, ResponseCont Response::ResponseCode Server_Player::cmdIncCardCounter(const Command_IncCardCounter &cmd, ResponseContainer & /*rc*/, GameEventStorage &ges) { - if (spectator) { - return Response::RespFunctionNotAllowed; - } - if (!game->getGameStarted()) { return Response::RespGameNotStarted; } @@ -1897,10 +1724,6 @@ Server_Player::cmdIncCardCounter(const Command_IncCardCounter &cmd, ResponseCont Response::ResponseCode Server_Player::cmdIncCounter(const Command_IncCounter &cmd, ResponseContainer & /*rc*/, GameEventStorage &ges) { - if (spectator) { - return Response::RespFunctionNotAllowed; - } - if (!game->getGameStarted()) { return Response::RespGameNotStarted; } @@ -1926,10 +1749,6 @@ Server_Player::cmdIncCounter(const Command_IncCounter &cmd, ResponseContainer & Response::ResponseCode Server_Player::cmdCreateCounter(const Command_CreateCounter &cmd, ResponseContainer & /*rc*/, GameEventStorage &ges) { - if (spectator) { - return Response::RespFunctionNotAllowed; - } - if (!game->getGameStarted()) { return Response::RespGameNotStarted; } @@ -1956,10 +1775,6 @@ Server_Player::cmdCreateCounter(const Command_CreateCounter &cmd, ResponseContai Response::ResponseCode Server_Player::cmdSetCounter(const Command_SetCounter &cmd, ResponseContainer & /*rc*/, GameEventStorage &ges) { - if (spectator) { - return Response::RespFunctionNotAllowed; - } - if (!game->getGameStarted()) { return Response::RespGameNotStarted; } @@ -1985,10 +1800,6 @@ Server_Player::cmdSetCounter(const Command_SetCounter &cmd, ResponseContainer & Response::ResponseCode Server_Player::cmdDelCounter(const Command_DelCounter &cmd, ResponseContainer & /*rc*/, GameEventStorage &ges) { - if (spectator) { - return Response::RespFunctionNotAllowed; - } - if (!game->getGameStarted()) { return Response::RespGameNotStarted; } @@ -2017,14 +1828,8 @@ Server_Player::cmdNextTurn(const Command_NextTurn & /*cmd*/, ResponseContainer & return Response::RespGameNotStarted; } - if (!judge) { - if (spectator) { - return Response::RespFunctionNotAllowed; - } - - if (conceded) { - return Response::RespContextError; - } + if (conceded && !judge) { + return Response::RespContextError; } game->nextTurn(); @@ -2040,10 +1845,6 @@ Response::ResponseCode Server_Player::cmdSetActivePhase(const Command_SetActiveP } if (!judge) { - if (spectator) { - return Response::RespFunctionNotAllowed; - } - if (conceded) { return Response::RespContextError; } @@ -2065,7 +1866,7 @@ Server_Player::cmdDumpZone(const Command_DumpZone &cmd, ResponseContainer &rc, G return Response::RespGameNotStarted; } - Server_Player *otherPlayer = game->getPlayers().value(cmd.player_id()); + Server_Player *otherPlayer = game->getPlayer(cmd.player_id()); if (!otherPlayer) { return Response::RespNameNotFound; } @@ -2141,10 +1942,6 @@ Server_Player::cmdDumpZone(const Command_DumpZone &cmd, ResponseContainer &rc, G Response::ResponseCode Server_Player::cmdRevealCards(const Command_RevealCards &cmd, ResponseContainer & /*rc*/, GameEventStorage &ges) { - if (spectator) { - return Response::RespFunctionNotAllowed; - } - if (!game->getGameStarted()) { return Response::RespGameNotStarted; } @@ -2153,7 +1950,7 @@ Server_Player::cmdRevealCards(const Command_RevealCards &cmd, ResponseContainer } if (cmd.has_player_id()) { - Server_Player *otherPlayer = game->getPlayers().value(cmd.player_id()); + Server_Player *otherPlayer = game->getPlayer(cmd.player_id()); if (!otherPlayer) return Response::RespNameNotFound; } @@ -2252,9 +2049,9 @@ Server_Player::cmdRevealCards(const Command_RevealCards &cmd, ResponseContainer ges.enqueueGameEvent(eventOthers, playerId, GameEventStorageItem::SendToOthers); } else { if (cmd.grant_write_access()) { - const QList &playerIds = game->getPlayers().keys(); - for (int _playerId : playerIds) { - zone->addWritePermission(_playerId); + const QList &participantIds = game->getParticipants().keys(); + for (int anyParticipantId : participantIds) { + zone->addWritePermission(anyParticipantId); } } @@ -2304,182 +2101,22 @@ Response::ResponseCode Server_Player::cmdChangeZoneProperties(const Command_Chan } Response::ResponseCode -Server_Player::cmdReverseTurn(const Command_ReverseTurn & /*cmd*/, ResponseContainer & /*rc*/, GameEventStorage &ges) +Server_Player::cmdReverseTurn(const Command_ReverseTurn &cmd, ResponseContainer &rc, GameEventStorage &ges) { - if (spectator) { - return Response::RespFunctionNotAllowed; - } - if (!game->getGameStarted()) { - return Response::RespGameNotStarted; - } - - if (conceded) { + if (!judge && conceded) { return Response::RespContextError; } - - bool reversedTurn = game->reverseTurnOrder(); - - Event_ReverseTurn event; - event.set_reversed(reversedTurn); - ges.enqueueGameEvent(event, playerId); - - return Response::RespOk; -} - -Response::ResponseCode -Server_Player::processGameCommand(const GameCommand &command, ResponseContainer &rc, GameEventStorage &ges) -{ - switch ((GameCommand::GameCommandType)getPbExtension(command)) { - case GameCommand::KICK_FROM_GAME: - return cmdKickFromGame(command.GetExtension(Command_KickFromGame::ext), rc, ges); - break; - case GameCommand::LEAVE_GAME: - return cmdLeaveGame(command.GetExtension(Command_LeaveGame::ext), rc, ges); - break; - case GameCommand::GAME_SAY: - return cmdGameSay(command.GetExtension(Command_GameSay::ext), rc, ges); - break; - case GameCommand::SHUFFLE: - return cmdShuffle(command.GetExtension(Command_Shuffle::ext), rc, ges); - break; - case GameCommand::MULLIGAN: - return cmdMulligan(command.GetExtension(Command_Mulligan::ext), rc, ges); - break; - case GameCommand::ROLL_DIE: - return cmdRollDie(command.GetExtension(Command_RollDie::ext), rc, ges); - break; - case GameCommand::DRAW_CARDS: - return cmdDrawCards(command.GetExtension(Command_DrawCards::ext), rc, ges); - break; - case GameCommand::UNDO_DRAW: - return cmdUndoDraw(command.GetExtension(Command_UndoDraw::ext), rc, ges); - break; - case GameCommand::FLIP_CARD: - return cmdFlipCard(command.GetExtension(Command_FlipCard::ext), rc, ges); - break; - case GameCommand::ATTACH_CARD: - return cmdAttachCard(command.GetExtension(Command_AttachCard::ext), rc, ges); - break; - case GameCommand::CREATE_TOKEN: - return cmdCreateToken(command.GetExtension(Command_CreateToken::ext), rc, ges); - break; - case GameCommand::CREATE_ARROW: - return cmdCreateArrow(command.GetExtension(Command_CreateArrow::ext), rc, ges); - break; - case GameCommand::DELETE_ARROW: - return cmdDeleteArrow(command.GetExtension(Command_DeleteArrow::ext), rc, ges); - break; - case GameCommand::SET_CARD_ATTR: - return cmdSetCardAttr(command.GetExtension(Command_SetCardAttr::ext), rc, ges); - break; - case GameCommand::SET_CARD_COUNTER: - return cmdSetCardCounter(command.GetExtension(Command_SetCardCounter::ext), rc, ges); - break; - case GameCommand::INC_CARD_COUNTER: - return cmdIncCardCounter(command.GetExtension(Command_IncCardCounter::ext), rc, ges); - break; - case GameCommand::READY_START: - return cmdReadyStart(command.GetExtension(Command_ReadyStart::ext), rc, ges); - break; - case GameCommand::CONCEDE: - return cmdConcede(command.GetExtension(Command_Concede::ext), rc, ges); - break; - case GameCommand::INC_COUNTER: - return cmdIncCounter(command.GetExtension(Command_IncCounter::ext), rc, ges); - break; - case GameCommand::CREATE_COUNTER: - return cmdCreateCounter(command.GetExtension(Command_CreateCounter::ext), rc, ges); - break; - case GameCommand::SET_COUNTER: - return cmdSetCounter(command.GetExtension(Command_SetCounter::ext), rc, ges); - break; - case GameCommand::DEL_COUNTER: - return cmdDelCounter(command.GetExtension(Command_DelCounter::ext), rc, ges); - break; - case GameCommand::NEXT_TURN: - return cmdNextTurn(command.GetExtension(Command_NextTurn::ext), rc, ges); - break; - case GameCommand::SET_ACTIVE_PHASE: - return cmdSetActivePhase(command.GetExtension(Command_SetActivePhase::ext), rc, ges); - break; - case GameCommand::DUMP_ZONE: - return cmdDumpZone(command.GetExtension(Command_DumpZone::ext), rc, ges); - break; - case GameCommand::REVEAL_CARDS: - return cmdRevealCards(command.GetExtension(Command_RevealCards::ext), rc, ges); - break; - case GameCommand::MOVE_CARD: - return cmdMoveCard(command.GetExtension(Command_MoveCard::ext), rc, ges); - break; - case GameCommand::SET_SIDEBOARD_PLAN: - return cmdSetSideboardPlan(command.GetExtension(Command_SetSideboardPlan::ext), rc, ges); - break; - case GameCommand::DECK_SELECT: - return cmdDeckSelect(command.GetExtension(Command_DeckSelect::ext), rc, ges); - break; - case GameCommand::SET_SIDEBOARD_LOCK: - return cmdSetSideboardLock(command.GetExtension(Command_SetSideboardLock::ext), rc, ges); - break; - case GameCommand::CHANGE_ZONE_PROPERTIES: - return cmdChangeZoneProperties(command.GetExtension(Command_ChangeZoneProperties::ext), rc, ges); - break; - case GameCommand::UNCONCEDE: - return cmdUnconcede(command.GetExtension(Command_Unconcede::ext), rc, ges); - break; - case GameCommand::JUDGE: - return cmdJudge(command.GetExtension(Command_Judge::ext), rc, ges); - break; - case GameCommand::REVERSE_TURN: - return cmdReverseTurn(command.GetExtension(Command_ReverseTurn::ext), rc, ges); - break; - default: - return Response::RespInvalidCommand; - } -} - -void Server_Player::sendGameEvent(const GameEventContainer &cont) -{ - QMutexLocker locker(&playerMutex); - - if (userInterface) { - userInterface->sendProtocolItem(cont); - } -} - -void Server_Player::setUserInterface(Server_AbstractUserInterface *_userInterface) -{ - playerMutex.lock(); - userInterface = _userInterface; - playerMutex.unlock(); - - pingTime = _userInterface ? 0 : -1; - - Event_PlayerPropertiesChanged event; - event.mutable_player_properties()->set_ping_seconds(pingTime); - - GameEventStorage ges; - ges.setGameEventContext(Context_ConnectionStateChanged()); - ges.enqueueGameEvent(event, playerId); - ges.sendToGame(game); -} - -void Server_Player::disconnectClient() -{ - if (!(userInfo->user_level() & ServerInfo_User::IsRegistered) || spectator) { - game->removePlayer(this, Event_Leave::USER_DISCONNECTED); - } else { - setUserInterface(nullptr); - } + return Server_AbstractParticipant::cmdReverseTurn(cmd, rc, ges); } void Server_Player::getInfo(ServerInfo_Player *info, - Server_Player *playerWhosAsking, + Server_AbstractParticipant *recipient, bool omniscient, bool withUserInfo) { getProperties(*info->mutable_properties(), withUserInfo); - if (playerWhosAsking == this) { + if (recipient == this) { if (deck) { info->set_deck_list(deck->writeToString_Native().toStdString()); } @@ -2494,6 +2131,16 @@ void Server_Player::getInfo(ServerInfo_Player *info, } for (Server_CardZone *zone : zones) { - zone->getInfo(info->add_zone_list(), playerWhosAsking, omniscient); + zone->getInfo(info->add_zone_list(), recipient, omniscient); + } +} + +void Server_Player::getPlayerProperties(ServerInfo_PlayerProperties &result) +{ + result.set_conceded(conceded); + result.set_sideboard_locked(sideboardLocked); + result.set_ready_start(readyStart); + if (deck) { + result.set_deck_hash(deck->getDeckHash().toStdString()); } } diff --git a/common/server/game/server_player.h b/common/server/game/server_player.h new file mode 100644 index 000000000..fc3e69ee8 --- /dev/null +++ b/common/server/game/server_player.h @@ -0,0 +1,178 @@ +#ifndef PLAYER_H +#define PLAYER_H + +#include "../../serverinfo_user_container.h" +#include "server_abstract_participant.h" + +#include +#include +#include + +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 zones; + QMap counters; + QMap arrows; + QList 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 &getZones() const + { + return zones; + } + const QMap &getCounters() const + { + return counters; + } + const QMap &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 &_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 diff --git a/common/server/game/server_spectator.cpp b/common/server/game/server_spectator.cpp new file mode 100644 index 000000000..bc873e386 --- /dev/null +++ b/common/server/game/server_spectator.cpp @@ -0,0 +1,11 @@ +#include "server_spectator.h" + +Server_Spectator::Server_Spectator(Server_Game *_game, + int _playerId, + const ServerInfo_User &_userInfo, + bool _judge, + Server_AbstractUserInterface *_userInterface) + : Server_AbstractParticipant(_game, _playerId, _userInfo, _judge, _userInterface) +{ + spectator = true; +} diff --git a/common/server/game/server_spectator.h b/common/server/game/server_spectator.h new file mode 100644 index 000000000..4d3928a63 --- /dev/null +++ b/common/server/game/server_spectator.h @@ -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 diff --git a/common/server.cpp b/common/server/server.cpp similarity index 97% rename from common/server.cpp rename to common/server/server.cpp index 4b0120ea1..a80c9ee8f 100644 --- a/common/server.cpp +++ b/common/server/server.cpp @@ -19,18 +19,17 @@ ***************************************************************************/ #include "server.h" -#include "debug_pb_message.h" -#include "featureset.h" +#include "../debug_pb_message.h" +#include "../featureset.h" +#include "game/server_game.h" +#include "game/server_player.h" #include "pb/event_connection_closed.pb.h" #include "pb/event_list_rooms.pb.h" #include "pb/event_user_joined.pb.h" #include "pb/event_user_left.pb.h" #include "pb/isl_message.pb.h" #include "pb/session_event.pb.h" -#include "server_counter.h" #include "server_database_interface.h" -#include "server_game.h" -#include "server_player.h" #include "server_protocolhandler.h" #include "server_remoteuserinterface.h" #include "server_room.h" @@ -330,11 +329,11 @@ void Server::externalUserLeft(const QString &userName) continue; QMutexLocker gameLocker(&game->gameMutex); - Server_Player *player = game->getPlayers().value(userGamesIterator.value().second); - if (!player) + auto *participant = game->getParticipants().value(userGamesIterator.value().second); + if (!participant) continue; - player->disconnectClient(); + participant->disconnectClient(); } roomsLock.unlock(); @@ -481,8 +480,8 @@ void Server::externalGameCommandContainerReceived(const CommandContainer &cont, } QMutexLocker gameLocker(&game->gameMutex); - Server_Player *player = game->getPlayers().value(playerId); - if (!player) { + auto *participant = game->getParticipants().value(playerId); + if (!participant) { qDebug() << "externalGameCommandContainerReceived: player id=" << playerId << "not found"; throw Response::RespNotInRoom; } @@ -492,7 +491,7 @@ void Server::externalGameCommandContainerReceived(const CommandContainer &cont, const GameCommand &sc = cont.game_command(i); qDebug() << "[ISL]" << getSafeDebugString(sc); - Response::ResponseCode resp = player->processGameCommand(sc, responseContainer, ges); + Response::ResponseCode resp = participant->processGameCommand(sc, responseContainer, ges); if (resp != Response::RespOk) finalResponseCode = resp; @@ -500,9 +499,7 @@ void Server::externalGameCommandContainerReceived(const CommandContainer &cont, ges.sendToGame(game); if (finalResponseCode != Response::RespNothing) { - player->playerMutex.lock(); - player->getUserInterface()->sendResponseContainer(responseContainer, finalResponseCode); - player->playerMutex.unlock(); + participant->getUserInterface()->sendResponseContainer(responseContainer, finalResponseCode); } } catch (Response::ResponseCode code) { Response response; diff --git a/common/server.h b/common/server/server.h similarity index 100% rename from common/server.h rename to common/server/server.h diff --git a/common/server_abstractuserinterface.cpp b/common/server/server_abstractuserinterface.cpp similarity index 91% rename from common/server_abstractuserinterface.cpp rename to common/server/server_abstractuserinterface.cpp index f40e64f8c..5016a8867 100644 --- a/common/server_abstractuserinterface.cpp +++ b/common/server/server_abstractuserinterface.cpp @@ -1,10 +1,10 @@ #include "server_abstractuserinterface.h" +#include "game/server_game.h" +#include "game/server_player.h" #include "pb/event_game_joined.pb.h" #include "pb/event_game_state_changed.pb.h" #include "server.h" -#include "server_game.h" -#include "server_player.h" #include "server_player_reference.h" #include "server_response_containers.h" #include "server_room.h" @@ -103,14 +103,14 @@ void Server_AbstractUserInterface::joinPersistentGames(ResponseContainer &rc) continue; QMutexLocker gameLocker(&game->gameMutex); - Server_Player *player = game->getPlayers().value(pr.getPlayerId()); - if (!player) + auto *participant = game->getParticipants().value(pr.getPlayerId()); + if (!participant) continue; - player->setUserInterface(this); - playerAddedToGame(game->getGameId(), room->getId(), player->getPlayerId()); + participant->setUserInterface(this); + playerAddedToGame(game->getGameId(), room->getId(), participant->getPlayerId()); - game->createGameJoinedEvent(player, rc, true); + game->createGameJoinedEvent(participant, rc, true); } server->roomsLock.unlock(); } diff --git a/common/server_abstractuserinterface.h b/common/server/server_abstractuserinterface.h similarity index 97% rename from common/server_abstractuserinterface.h rename to common/server/server_abstractuserinterface.h index 763bcc567..c65d8a5c4 100644 --- a/common/server_abstractuserinterface.h +++ b/common/server/server_abstractuserinterface.h @@ -1,9 +1,9 @@ #ifndef SERVER_ABSTRACTUSERINTERFACE #define SERVER_ABSTRACTUSERINTERFACE +#include "../serverinfo_user_container.h" #include "pb/response.pb.h" #include "pb/server_message.pb.h" -#include "serverinfo_user_container.h" #include #include diff --git a/common/server_database_interface.cpp b/common/server/server_database_interface.cpp similarity index 100% rename from common/server_database_interface.cpp rename to common/server/server_database_interface.cpp diff --git a/common/server_database_interface.h b/common/server/server_database_interface.h similarity index 100% rename from common/server_database_interface.h rename to common/server/server_database_interface.h diff --git a/common/server_player_reference.h b/common/server/server_player_reference.h similarity index 100% rename from common/server_player_reference.h rename to common/server/server_player_reference.h diff --git a/common/server_protocolhandler.cpp b/common/server/server_protocolhandler.cpp similarity index 98% rename from common/server_protocolhandler.cpp rename to common/server/server_protocolhandler.cpp index 8fa3dc414..c06ee7624 100644 --- a/common/server_protocolhandler.cpp +++ b/common/server/server_protocolhandler.cpp @@ -1,8 +1,11 @@ #include "server_protocolhandler.h" -#include "debug_pb_message.h" -#include "featureset.h" -#include "get_pb_extension.h" +#include "../debug_pb_message.h" +#include "../featureset.h" +#include "../get_pb_extension.h" +#include "../trice_limits.h" +#include "game/server_game.h" +#include "game/server_player.h" #include "pb/commands.pb.h" #include "pb/event_game_joined.pb.h" #include "pb/event_list_rooms.pb.h" @@ -18,10 +21,7 @@ #include "pb/response_login.pb.h" #include "pb/serverinfo_user.pb.h" #include "server_database_interface.h" -#include "server_game.h" -#include "server_player.h" #include "server_room.h" -#include "trice_limits.h" #include #include @@ -73,14 +73,14 @@ void Server_ProtocolHandler::prepareDestroy() continue; } game->gameMutex.lock(); - Server_Player *p = game->getPlayers().value(gameIterator.value().second); - if (!p) { + auto *participant = game->getParticipants().value(gameIterator.value().second); + if (!participant) { game->gameMutex.unlock(); room->gamesLock.unlock(); continue; } - p->disconnectClient(); + participant->disconnectClient(); game->gameMutex.unlock(); room->gamesLock.unlock(); @@ -257,8 +257,8 @@ Response::ResponseCode Server_ProtocolHandler::processGameCommandContainer(const } QMutexLocker gameLocker(&game->gameMutex); - Server_Player *player = game->getPlayers().value(roomIdAndPlayerId.second); - if (!player) + auto *participant = game->getParticipants().value(roomIdAndPlayerId.second); + if (!participant) return Response::RespNotInRoom; resetIdleTimer(); @@ -289,7 +289,7 @@ Response::ResponseCode Server_ProtocolHandler::processGameCommandContainer(const } } - Response::ResponseCode resp = player->processGameCommand(sc, rc, ges); + Response::ResponseCode resp = participant->processGameCommand(sc, rc, ges); if (resp != Response::RespOk) finalResponseCode = resp; diff --git a/common/server_protocolhandler.h b/common/server/server_protocolhandler.h similarity index 100% rename from common/server_protocolhandler.h rename to common/server/server_protocolhandler.h diff --git a/common/server_remoteuserinterface.cpp b/common/server/server_remoteuserinterface.cpp similarity index 100% rename from common/server_remoteuserinterface.cpp rename to common/server/server_remoteuserinterface.cpp diff --git a/common/server_remoteuserinterface.h b/common/server/server_remoteuserinterface.h similarity index 100% rename from common/server_remoteuserinterface.h rename to common/server/server_remoteuserinterface.h diff --git a/common/server_response_containers.cpp b/common/server/server_response_containers.cpp similarity index 99% rename from common/server_response_containers.cpp rename to common/server/server_response_containers.cpp index 03ce4d853..9b07bdb91 100644 --- a/common/server_response_containers.cpp +++ b/common/server/server_response_containers.cpp @@ -1,6 +1,6 @@ #include "server_response_containers.h" -#include "server_game.h" +#include "game/server_game.h" #include diff --git a/common/server_response_containers.h b/common/server/server_response_containers.h similarity index 100% rename from common/server_response_containers.h rename to common/server/server_response_containers.h diff --git a/common/server_room.cpp b/common/server/server_room.cpp similarity index 99% rename from common/server_room.cpp rename to common/server/server_room.cpp index 654666edf..badb37642 100644 --- a/common/server_room.cpp +++ b/common/server/server_room.cpp @@ -1,5 +1,7 @@ #include "server_room.h" +#include "../trice_limits.h" +#include "game/server_game.h" #include "pb/commands.pb.h" #include "pb/event_join_room.pb.h" #include "pb/event_leave_room.pb.h" @@ -9,9 +11,7 @@ #include "pb/room_commands.pb.h" #include "pb/serverinfo_chat_message.pb.h" #include "pb/serverinfo_room.pb.h" -#include "server_game.h" #include "server_protocolhandler.h" -#include "trice_limits.h" #include #include diff --git a/common/server_room.h b/common/server/server_room.h similarity index 98% rename from common/server_room.h rename to common/server/server_room.h index 7c804a461..7e256dc15 100644 --- a/common/server_room.h +++ b/common/server/server_room.h @@ -1,9 +1,9 @@ #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 "serverinfo_user_container.h" #include #include diff --git a/common/server_player.h b/common/server_player.h deleted file mode 100644 index 45736957d..000000000 --- a/common/server_player.h +++ /dev/null @@ -1,248 +0,0 @@ -#ifndef PLAYER_H -#define PLAYER_H - -#include "pb/card_attributes.pb.h" -#include "pb/response.pb.h" -#include "server_arrowtarget.h" -#include "serverinfo_user_container.h" - -#include -#include -#include -#include - -class DeckList; -class Server_Game; -class Server_CardZone; -class Server_Counter; -class Server_Arrow; -class Server_Card; -class Server_AbstractUserInterface; -class ServerInfo_User; -class ServerInfo_Player; -class ServerInfo_PlayerProperties; -class CommandContainer; -class CardToMove; -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_Player : public Server_ArrowTarget, public ServerInfo_User_Container -{ - Q_OBJECT -private: - class MoveCardCompareFunctor; - Server_Game *game; - Server_AbstractUserInterface *userInterface; - DeckList *deck; - QMap zones; - QMap counters; - QMap arrows; - QList lastDrawList; - int pingTime; - int playerId; - bool spectator; - bool judge; - 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); - -public: - mutable QMutex playerMutex; - Server_Player(Server_Game *_game, - int _playerId, - const ServerInfo_User &_userInfo, - bool _spectator, - bool _judge, - Server_AbstractUserInterface *_handler); - ~Server_Player() override; - void prepareDestroy(); - const DeckList *getDeckList() const - { - return deck; - } - Server_AbstractUserInterface *getUserInterface() const - { - return userInterface; - } - void setUserInterface(Server_AbstractUserInterface *_userInterface); - void disconnectClient(); - - bool getReadyStart() const - { - return readyStart; - } - void setReadyStart(bool _readyStart) - { - readyStart = _readyStart; - } - int getPlayerId() const - { - return playerId; - } - bool getSpectator() const - { - return spectator; - } - bool getJudge() const - { - return judge; - } - bool getConceded() const - { - return conceded; - } - void setConceded(bool _conceded) - { - conceded = _conceded; - } - - Server_Game *getGame() const - { - return game; - } - const QMap &getZones() const - { - return zones; - } - const QMap &getCounters() const - { - return counters; - } - const QMap &getArrows() const - { - return arrows; - } - - int getPingTime() const - { - return pingTime; - } - void setPingTime(int _pingTime) - { - pingTime = _pingTime; - } - void getProperties(ServerInfo_PlayerProperties &result, bool withUserInfo); - - 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 &_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 cmdLeaveGame(const Command_LeaveGame &cmd, ResponseContainer &rc, GameEventStorage &ges); - Response::ResponseCode - cmdKickFromGame(const Command_KickFromGame &cmd, ResponseContainer &rc, GameEventStorage &ges); - Response::ResponseCode cmdConcede(const Command_Concede &cmd, ResponseContainer &rc, GameEventStorage &ges); - Response::ResponseCode cmdUnconcede(const Command_Unconcede &cmd, ResponseContainer &rc, GameEventStorage &ges); - Response::ResponseCode cmdJudge(const Command_Judge &cmd, ResponseContainer &rc, GameEventStorage &ges); - Response::ResponseCode cmdReadyStart(const Command_ReadyStart &cmd, ResponseContainer &rc, GameEventStorage &ges); - Response::ResponseCode cmdDeckSelect(const Command_DeckSelect &cmd, ResponseContainer &rc, GameEventStorage &ges); - Response::ResponseCode - cmdSetSideboardPlan(const Command_SetSideboardPlan &cmd, ResponseContainer &rc, GameEventStorage &ges); - Response::ResponseCode - cmdSetSideboardLock(const Command_SetSideboardLock &cmd, ResponseContainer &rc, GameEventStorage &ges); - Response::ResponseCode cmdGameSay(const Command_GameSay &cmd, ResponseContainer &rc, GameEventStorage &ges); - Response::ResponseCode cmdShuffle(const Command_Shuffle &cmd, ResponseContainer &rc, GameEventStorage &ges); - Response::ResponseCode cmdMulligan(const Command_Mulligan &cmd, ResponseContainer &rc, GameEventStorage &ges); - Response::ResponseCode cmdRollDie(const Command_RollDie &cmd, ResponseContainer &rc, GameEventStorage &ges) const; - Response::ResponseCode cmdDrawCards(const Command_DrawCards &cmd, ResponseContainer &rc, GameEventStorage &ges); - Response::ResponseCode cmdUndoDraw(const Command_UndoDraw &cmd, ResponseContainer &rc, GameEventStorage &ges); - Response::ResponseCode cmdMoveCard(const Command_MoveCard &cmd, ResponseContainer &rc, GameEventStorage &ges); - Response::ResponseCode cmdFlipCard(const Command_FlipCard &cmd, ResponseContainer &rc, GameEventStorage &ges); - Response::ResponseCode cmdAttachCard(const Command_AttachCard &cmd, ResponseContainer &rc, GameEventStorage &ges); - Response::ResponseCode cmdCreateToken(const Command_CreateToken &cmd, ResponseContainer &rc, GameEventStorage &ges); - Response::ResponseCode cmdCreateArrow(const Command_CreateArrow &cmd, ResponseContainer &rc, GameEventStorage &ges); - Response::ResponseCode cmdDeleteArrow(const Command_DeleteArrow &cmd, ResponseContainer &rc, GameEventStorage &ges); - Response::ResponseCode cmdSetCardAttr(const Command_SetCardAttr &cmd, ResponseContainer &rc, GameEventStorage &ges); - Response::ResponseCode - cmdSetCardCounter(const Command_SetCardCounter &cmd, ResponseContainer &rc, GameEventStorage &ges); - Response::ResponseCode - cmdIncCardCounter(const Command_IncCardCounter &cmd, ResponseContainer &rc, GameEventStorage &ges); - Response::ResponseCode cmdIncCounter(const Command_IncCounter &cmd, ResponseContainer &rc, GameEventStorage &ges); - Response::ResponseCode - cmdCreateCounter(const Command_CreateCounter &cmd, ResponseContainer &rc, GameEventStorage &ges); - Response::ResponseCode cmdSetCounter(const Command_SetCounter &cmd, ResponseContainer &rc, GameEventStorage &ges); - Response::ResponseCode cmdDelCounter(const Command_DelCounter &cmd, ResponseContainer &rc, GameEventStorage &ges); - Response::ResponseCode cmdNextTurn(const Command_NextTurn &cmd, ResponseContainer &rc, GameEventStorage &ges); - Response::ResponseCode - cmdSetActivePhase(const Command_SetActivePhase &cmd, ResponseContainer &rc, GameEventStorage &ges); - Response::ResponseCode cmdDumpZone(const Command_DumpZone &cmd, ResponseContainer &rc, GameEventStorage &ges); - Response::ResponseCode cmdRevealCards(const Command_RevealCards &cmd, ResponseContainer &rc, GameEventStorage &ges); - Response::ResponseCode - cmdReverseTurn(const Command_ReverseTurn & /*cmd*/, ResponseContainer & /*rc*/, GameEventStorage &ges); - 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); - - void getInfo(ServerInfo_Player *info, Server_Player *playerWhosAsking, bool omniscient, bool withUserInfo); -}; - -#endif diff --git a/servatrice/src/isl_interface.cpp b/servatrice/src/isl_interface.cpp index 351c608c5..0c13bcd0f 100644 --- a/servatrice/src/isl_interface.cpp +++ b/servatrice/src/isl_interface.cpp @@ -14,9 +14,9 @@ #include "pb/event_user_left.pb.h" #include "pb/event_user_message.pb.h" #include "pb/isl_message.pb.h" +#include "server/server_protocolhandler.h" +#include "server/server_room.h" #include "server_logger.h" -#include "server_protocolhandler.h" -#include "server_room.h" #include #include diff --git a/servatrice/src/servatrice.cpp b/servatrice/src/servatrice.cpp index 99a8f7c41..e1288a627 100644 --- a/servatrice/src/servatrice.cpp +++ b/servatrice/src/servatrice.cpp @@ -29,8 +29,8 @@ #include "pb/event_server_shutdown.pb.h" #include "servatrice_connection_pool.h" #include "servatrice_database_interface.h" +#include "server/server_room.h" #include "server_logger.h" -#include "server_room.h" #include "serversocketinterface.h" #include "settingscache.h" #include "smtpclient.h" diff --git a/servatrice/src/servatrice.h b/servatrice/src/servatrice.h index 8dbaf492f..c68327c60 100644 --- a/servatrice/src/servatrice.h +++ b/servatrice/src/servatrice.h @@ -20,7 +20,7 @@ #ifndef SERVATRICE_H #define SERVATRICE_H -#include "server.h" +#include "server/server.h" #include #include @@ -284,4 +284,4 @@ public: QList getServerList() const; }; -#endif \ No newline at end of file +#endif diff --git a/servatrice/src/servatrice_database_interface.h b/servatrice/src/servatrice_database_interface.h index e3846cdd4..9eb492953 100644 --- a/servatrice/src/servatrice_database_interface.h +++ b/servatrice/src/servatrice_database_interface.h @@ -1,8 +1,8 @@ #ifndef SERVATRICE_DATABASE_INTERFACE_H #define SERVATRICE_DATABASE_INTERFACE_H -#include "server.h" -#include "server_database_interface.h" +#include "server/server.h" +#include "server/server_database_interface.h" #include #include diff --git a/servatrice/src/serversocketinterface.cpp b/servatrice/src/serversocketinterface.cpp index 5f765574f..9b08ee330 100644 --- a/servatrice/src/serversocketinterface.cpp +++ b/servatrice/src/serversocketinterface.cpp @@ -65,10 +65,10 @@ #include "pb/serverinfo_user.pb.h" #include "servatrice.h" #include "servatrice_database_interface.h" +#include "server/game/server_player.h" +#include "server/server_response_containers.h" +#include "server/server_room.h" #include "server_logger.h" -#include "server_player.h" -#include "server_response_containers.h" -#include "server_room.h" #include "settingscache.h" #include "trice_limits.h" #include "version_string.h" diff --git a/servatrice/src/serversocketinterface.h b/servatrice/src/serversocketinterface.h index 54a852fd7..9f15e62b8 100644 --- a/servatrice/src/serversocketinterface.h +++ b/servatrice/src/serversocketinterface.h @@ -20,7 +20,7 @@ #ifndef SERVERSOCKETINTERFACE_H #define SERVERSOCKETINTERFACE_H -#include "server_protocolhandler.h" +#include "server/server_protocolhandler.h" #include #include