diff --git a/libcockatrice_network/libcockatrice/network/server/remote/game/server_game.cpp b/libcockatrice_network/libcockatrice/network/server/remote/game/server_game.cpp index 0098be19d..16c012806 100644 --- a/libcockatrice_network/libcockatrice/network/server/remote/game/server_game.cpp +++ b/libcockatrice_network/libcockatrice/network/server/remote/game/server_game.cpp @@ -812,6 +812,15 @@ void Server_Game::createGameJoinedEvent(Server_AbstractParticipant *joiningParti } rc.enqueuePostResponseItem(ServerMessage::GAME_EVENT_CONTAINER, prepareGameEvent(event2, -1)); + + // A tournament's bracket/phase/standings live in Event_TournamentState, which + // normally only flows on mutation. Without a copy here a late joiner would sit + // on an empty bracket until the next round advances, so replay the current + // state as part of the join snapshot. + if (tournament) { + rc.enqueuePostResponseItem(ServerMessage::GAME_EVENT_CONTAINER, + prepareGameEvent(tournament->buildStateEvent(), -1)); + } } void Server_Game::sendGameEventContainer(GameEventContainer *cont, diff --git a/libcockatrice_network/libcockatrice/network/server/remote/game/server_tournament.cpp b/libcockatrice_network/libcockatrice/network/server/remote/game/server_tournament.cpp index 527f2e728..65529072f 100644 --- a/libcockatrice_network/libcockatrice/network/server/remote/game/server_tournament.cpp +++ b/libcockatrice_network/libcockatrice/network/server/remote/game/server_tournament.cpp @@ -635,7 +635,7 @@ void Server_Tournament::checkAndAdvanceRound(GameEventStorage &ges) } } -void Server_Tournament::broadcastTournamentState(GameEventStorage &ges) +Event_TournamentState Server_Tournament::buildStateEvent() const { QMutexLocker locker(&tournamentMutex); @@ -682,5 +682,10 @@ void Server_Tournament::broadcastTournamentState(GameEventStorage &ges) p->set_player2_match_wins(pairing.player2MatchWins); } - ges.enqueueGameEvent(state, -1); + return state; +} + +void Server_Tournament::broadcastTournamentState(GameEventStorage &ges) +{ + ges.enqueueGameEvent(buildStateEvent(), -1); } diff --git a/libcockatrice_network/libcockatrice/network/server/remote/game/server_tournament.h b/libcockatrice_network/libcockatrice/network/server/remote/game/server_tournament.h index aeb3ea732..438490e84 100644 --- a/libcockatrice_network/libcockatrice/network/server/remote/game/server_tournament.h +++ b/libcockatrice_network/libcockatrice/network/server/remote/game/server_tournament.h @@ -36,6 +36,8 @@ public: void recordMatchResult(int playerId1, int playerId2, int winnerId, GameEventStorage &ges); bool recordMatchResultByGameId(int gameId, int winnerId, GameEventStorage &ges); void broadcastTournamentState(GameEventStorage &ges); + // Current tournament state message, for replaying to a participant joining late. + Event_TournamentState buildStateEvent() const; bool isStarted() const {