diff --git a/libcockatrice_network/libcockatrice/network/server/remote/game/server_abstract_participant.cpp b/libcockatrice_network/libcockatrice/network/server/remote/game/server_abstract_participant.cpp index a6280ffa1..a6313e312 100644 --- a/libcockatrice_network/libcockatrice/network/server/remote/game/server_abstract_participant.cpp +++ b/libcockatrice_network/libcockatrice/network/server/remote/game/server_abstract_participant.cpp @@ -41,6 +41,7 @@ #include #include #include +#include #include #include #include @@ -536,6 +537,15 @@ Server_AbstractParticipant::processGameCommand(const GameCommand &command, Respo case GameCommand::SET_PLAYMAT: return cmdSetPlaymat(command.GetExtension(Command_SetPlaymat::ext), rc, ges); break; + case GameCommand::REPORT_MATCH_RESULT: + return cmdReportMatchResult(command.GetExtension(Command_ReportMatchResult::ext), rc, ges); + break; + case GameCommand::ADVANCE_TOURNAMENT: + return cmdAdvanceTournament(command.GetExtension(Command_AdvanceTournament::ext), rc, ges); + break; + case GameCommand::TOURNAMENT_SETTINGS_SELECT: + return cmdTournamentSettingsSelect(command.GetExtension(Command_TournamentSettingsSelect::ext), rc, ges); + break; default: return Response::RespInvalidCommand; } @@ -584,3 +594,25 @@ void Server_AbstractParticipant::getInfo(ServerInfo_Player *info, { getProperties(*info->mutable_properties(), withUserInfo); } + +Response::ResponseCode Server_AbstractParticipant::cmdReportMatchResult(const Command_ReportMatchResult & /*cmd*/, + ResponseContainer & /*rc*/, + GameEventStorage & /*ges*/) +{ + return Response::RespContextError; +} + +Response::ResponseCode Server_AbstractParticipant::cmdAdvanceTournament(const Command_AdvanceTournament & /*cmd*/, + ResponseContainer & /*rc*/, + GameEventStorage & /*ges*/) +{ + return Response::RespContextError; +} + +Response::ResponseCode +Server_AbstractParticipant::cmdTournamentSettingsSelect(const Command_TournamentSettingsSelect & /*cmd*/, + ResponseContainer & /*rc*/, + GameEventStorage & /*ges*/) +{ + return Response::RespContextError; +} diff --git a/libcockatrice_network/libcockatrice/network/server/remote/game/server_abstract_participant.h b/libcockatrice_network/libcockatrice/network/server/remote/game/server_abstract_participant.h index c78ae78c1..b41ecbb20 100644 --- a/libcockatrice_network/libcockatrice/network/server/remote/game/server_abstract_participant.h +++ b/libcockatrice_network/libcockatrice/network/server/remote/game/server_abstract_participant.h @@ -53,6 +53,9 @@ class Command_DeckSelect; class Command_SetSideboardLock; class Command_ChangeZoneProperties; class Command_SetPlaymat; +class Command_ReportMatchResult; +class Command_AdvanceTournament; +class Command_TournamentSettingsSelect; class Server_AbstractParticipant : public Server_ArrowTarget, public ServerInfo_User_Container { @@ -175,6 +178,13 @@ public: cmdReverseTurn(const Command_ReverseTurn & /*cmd*/, ResponseContainer & /*rc*/, GameEventStorage &ges); virtual Response::ResponseCode cmdChangeZoneProperties(const Command_ChangeZoneProperties &cmd, ResponseContainer &rc, GameEventStorage &ges); + virtual Response::ResponseCode + cmdReportMatchResult(const Command_ReportMatchResult &cmd, ResponseContainer &rc, GameEventStorage &ges); + virtual Response::ResponseCode + cmdAdvanceTournament(const Command_AdvanceTournament &cmd, ResponseContainer &rc, GameEventStorage &ges); + virtual Response::ResponseCode cmdTournamentSettingsSelect(const Command_TournamentSettingsSelect &cmd, + ResponseContainer &rc, + GameEventStorage &ges); Response::ResponseCode processGameCommand(const GameCommand &command, ResponseContainer &rc, GameEventStorage &ges); void sendGameEvent(const GameEventContainer &event); diff --git a/libcockatrice_network/libcockatrice/network/server/remote/game/server_abstract_player.cpp b/libcockatrice_network/libcockatrice/network/server/remote/game/server_abstract_player.cpp index 957a89792..a9d486a4d 100644 --- a/libcockatrice_network/libcockatrice/network/server/remote/game/server_abstract_player.cpp +++ b/libcockatrice_network/libcockatrice/network/server/remote/game/server_abstract_player.cpp @@ -1663,3 +1663,9 @@ void Server_AbstractPlayer::getPlayerProperties(ServerInfo_PlayerProperties &res playmatParams->set_zoom(playmat.params.zoom); } } + +void Server_AbstractPlayer::setDeck(DeckList *_deck) +{ + delete deck; + deck = _deck; +} diff --git a/libcockatrice_network/libcockatrice/network/server/remote/game/server_abstract_player.h b/libcockatrice_network/libcockatrice/network/server/remote/game/server_abstract_player.h index 85fbc0557..312f62d0e 100644 --- a/libcockatrice_network/libcockatrice/network/server/remote/game/server_abstract_player.h +++ b/libcockatrice_network/libcockatrice/network/server/remote/game/server_abstract_player.h @@ -47,6 +47,7 @@ public: { return deck; } + void setDeck(DeckList *_deck); bool getReadyStart() const { return readyStart; diff --git a/libcockatrice_network/libcockatrice/network/server/remote/server_room.cpp b/libcockatrice_network/libcockatrice/network/server/remote/server_room.cpp index 1f29e62fb..f6880e9ff 100644 --- a/libcockatrice_network/libcockatrice/network/server/remote/server_room.cpp +++ b/libcockatrice_network/libcockatrice/network/server/remote/server_room.cpp @@ -363,6 +363,18 @@ void Server_Room::broadcastGameListUpdate(const ServerInfo_Game &gameInfo, bool sendRoomEvent(prepareRoomEvent(event), sendToIsl); } +Server_AbstractUserInterface *Server_Room::getUserInterfaceByName(const QString &name) const +{ + usersLock.lockForRead(); + auto it = users.constFind(name); + Server_AbstractUserInterface *result = nullptr; + if (it != users.constEnd()) { + result = it.value(); + } + usersLock.unlock(); + return result; +} + void Server_Room::addGame(Server_Game *game) { ServerInfo_Room roomInfo; diff --git a/libcockatrice_network/libcockatrice/network/server/remote/server_room.h b/libcockatrice_network/libcockatrice/network/server/remote/server_room.h index 3d9988f20..02b865ebc 100644 --- a/libcockatrice_network/libcockatrice/network/server/remote/server_room.h +++ b/libcockatrice_network/libcockatrice/network/server/remote/server_room.h @@ -135,6 +135,8 @@ public: void addGame(Server_Game *game); void removeGame(Server_Game *game); + Server_AbstractUserInterface *getUserInterfaceByName(const QString &name) const; + void sendRoomEvent(RoomEvent *event, bool sendToIsl = true); RoomEvent *prepareRoomEvent(const ::google::protobuf::Message &roomEvent); }; diff --git a/libcockatrice_protocol/libcockatrice/protocol/pb/CMakeLists.txt b/libcockatrice_protocol/libcockatrice/protocol/pb/CMakeLists.txt index 3a193ae3c..6708b06cb 100644 --- a/libcockatrice_protocol/libcockatrice/protocol/pb/CMakeLists.txt +++ b/libcockatrice_protocol/libcockatrice/protocol/pb/CMakeLists.txt @@ -60,6 +60,7 @@ set(PROTO_FILES command_set_sideboard_lock.proto command_set_sideboard_plan.proto command_shuffle.proto + command_tournament.proto command_undo_draw.proto commands.proto context_concede.proto @@ -118,6 +119,7 @@ set(PROTO_FILES event_set_card_counter.proto event_set_counter.proto event_shuffle.proto + event_tournament_state.proto event_user_joined.proto event_user_left.proto event_user_message.proto diff --git a/libcockatrice_protocol/libcockatrice/protocol/pb/command_tournament.proto b/libcockatrice_protocol/libcockatrice/protocol/pb/command_tournament.proto new file mode 100644 index 000000000..ee958f587 --- /dev/null +++ b/libcockatrice_protocol/libcockatrice/protocol/pb/command_tournament.proto @@ -0,0 +1,26 @@ +syntax = "proto2"; +import "game_commands.proto"; +import "event_tournament_state.proto"; + +message Command_ReportMatchResult { + extend GameCommand { + optional Command_ReportMatchResult ext = 1037; + } + + optional sint32 game_id = 1 [default = -1]; + optional sint32 winner_id = 2 [default = -1]; +} + +message Command_AdvanceTournament { + extend GameCommand { + optional Command_AdvanceTournament ext = 1038; + } +} + +message Command_TournamentSettingsSelect { + extend GameCommand { + optional Command_TournamentSettingsSelect ext = 1039; + } + + optional TournamentSettings settings = 1; +} diff --git a/libcockatrice_protocol/libcockatrice/protocol/pb/event_game_state_changed.proto b/libcockatrice_protocol/libcockatrice/protocol/pb/event_game_state_changed.proto index 5c8aee3fe..c085e6a59 100644 --- a/libcockatrice_protocol/libcockatrice/protocol/pb/event_game_state_changed.proto +++ b/libcockatrice_protocol/libcockatrice/protocol/pb/event_game_state_changed.proto @@ -24,4 +24,10 @@ message Event_GameStateChanged { // the amount of seconds since the game started optional uint32 seconds_elapsed = 5; + + // whether this game is a tournament game + optional bool is_tournament = 9; + + // for tournament sub-games: the ID of the parent tournament game (-1 if not a sub-game) + optional sint32 parent_game_id = 10 [default = -1]; } diff --git a/libcockatrice_protocol/libcockatrice/protocol/pb/event_tournament_state.proto b/libcockatrice_protocol/libcockatrice/protocol/pb/event_tournament_state.proto new file mode 100644 index 000000000..5fb003f50 --- /dev/null +++ b/libcockatrice_protocol/libcockatrice/protocol/pb/event_tournament_state.proto @@ -0,0 +1,43 @@ +syntax = "proto2"; +import "game_event.proto"; + +message TournamentPlayer { + optional sint32 player_id = 1; + optional string player_name = 2; + optional uint32 wins = 3; + optional uint32 losses = 4; + optional uint32 draws = 5; + optional bool deck_submitted = 6; +} + +message TournamentPairing { + optional sint32 player1_id = 1; + optional sint32 player2_id = 2 [default = -1]; + optional sint32 game_id = 3; + optional sint32 winner_id = 4 [default = -1]; + optional sint32 player1_match_wins = 5 [default = 0]; + optional sint32 player2_match_wins = 6 [default = 0]; +} + +message TournamentSettings { + optional uint32 games_per_match = 1 [default = 1]; +} + +message Event_TournamentState { + extend GameEvent { + optional Event_TournamentState ext = 2027; + } + + enum TournamentPhase { + PHASE_DECK_BUILDING = 0; + PHASE_PLAYING = 1; + PHASE_FINISHED = 2; + } + + optional TournamentPhase phase = 1; + optional uint32 current_round = 2; + optional uint32 total_rounds = 3; + repeated TournamentPlayer players = 4; + repeated TournamentPairing pairings = 5; + optional TournamentSettings settings = 6; +} diff --git a/libcockatrice_protocol/libcockatrice/protocol/pb/game_commands.proto b/libcockatrice_protocol/libcockatrice/protocol/pb/game_commands.proto index 2e5b88978..68a79eb6b 100644 --- a/libcockatrice_protocol/libcockatrice/protocol/pb/game_commands.proto +++ b/libcockatrice_protocol/libcockatrice/protocol/pb/game_commands.proto @@ -180,6 +180,15 @@ message GameCommand { /// Server: Server_Player::cmdSetPlaymat /// Client: reflected via player properties changed event SET_PLAYMAT = 1035; + + /// Report the result of a tournament match sub-game. + REPORT_MATCH_RESULT = 1037; + + /// Advance the tournament to the next round. + ADVANCE_TOURNAMENT = 1038; + + /// Select tournament settings. + TOURNAMENT_SETTINGS_SELECT = 1039; } extensions 100 to max; diff --git a/libcockatrice_protocol/libcockatrice/protocol/pb/game_event.proto b/libcockatrice_protocol/libcockatrice/protocol/pb/game_event.proto index 7d3147701..b952bfdef 100644 --- a/libcockatrice_protocol/libcockatrice/protocol/pb/game_event.proto +++ b/libcockatrice_protocol/libcockatrice/protocol/pb/game_event.proto @@ -34,6 +34,7 @@ message GameEvent { CHANGE_ZONE_PROPERTIES = 2020; REVERSE_TURN = 2021; GAME_LOG_NOTICE = 2022; + TOURNAMENT_STATE = 2027; } optional sint32 player_id = 1 [default = -1]; extensions 100 to max; diff --git a/libcockatrice_protocol/libcockatrice/protocol/pb/room_commands.proto b/libcockatrice_protocol/libcockatrice/protocol/pb/room_commands.proto index a8c90ec6c..bf4d5310f 100644 --- a/libcockatrice_protocol/libcockatrice/protocol/pb/room_commands.proto +++ b/libcockatrice_protocol/libcockatrice/protocol/pb/room_commands.proto @@ -69,6 +69,12 @@ message Command_CreateGame { // share decklists with all players when selected optional bool share_decklists_on_load = 14; + + // number of games per match in tournament mode (e.g. 3 for best of 3) + optional uint32 games_per_match = 15 [default = 1]; + + // whether this is a tournament game + optional bool is_tournament = 16; } message Command_JoinGame { diff --git a/libcockatrice_protocol/libcockatrice/protocol/pb/serverinfo_game.proto b/libcockatrice_protocol/libcockatrice/protocol/pb/serverinfo_game.proto index 9989ae18a..4ac004cf4 100644 --- a/libcockatrice_protocol/libcockatrice/protocol/pb/serverinfo_game.proto +++ b/libcockatrice_protocol/libcockatrice/protocol/pb/serverinfo_game.proto @@ -65,4 +65,7 @@ message ServerInfo_Game { // the current host of the game, which may differ from the creator after a host transfer optional ServerInfo_User host_info = 53; + + // whether this game is a tournament game + optional bool is_tournament = 54; }