From b7fbc12ac092f179c0735ba5aff608b9dcfca296 Mon Sep 17 00:00:00 2001 From: Zach H Date: Sun, 16 Jun 2024 19:12:37 -0400 Subject: [PATCH] Allow Judges to see all information, regardless of room settings (#5053) --- cockatrice/src/player.cpp | 2 +- common/server_cardzone.cpp | 10 +++++++--- common/server_game.cpp | 28 ++++++++++++++------------- common/server_player.cpp | 4 ++++ common/server_response_containers.cpp | 16 +++++++++------ common/server_response_containers.h | 5 +++++ 6 files changed, 42 insertions(+), 23 deletions(-) diff --git a/cockatrice/src/player.cpp b/cockatrice/src/player.cpp index 6e9e12843..3573ab240 100644 --- a/cockatrice/src/player.cpp +++ b/cockatrice/src/player.cpp @@ -152,7 +152,7 @@ Player::Player(const ServerInfo_User &info, int _id, bool _local, bool _judge, T stack = new StackZone(this, (int)table->boundingRect().height(), this); - hand = new HandZone(this, _local || (_parent->getSpectator() && _parent->getSpectatorsSeeEverything()), + hand = new HandZone(this, _local || _judge || (_parent->getSpectator() && _parent->getSpectatorsSeeEverything()), (int)table->boundingRect().height(), this); connect(hand, SIGNAL(cardCountChanged()), handCounter, SLOT(updateNumber())); connect(handCounter, SIGNAL(showContextMenu(const QPoint &)), hand, SLOT(showContextMenu(const QPoint &))); diff --git a/common/server_cardzone.cpp b/common/server_cardzone.cpp index f34e24e3d..88b61622f 100644 --- a/common/server_cardzone.cpp +++ b/common/server_cardzone.cpp @@ -323,11 +323,15 @@ void Server_CardZone::getInfo(ServerInfo_Zone *info, Server_Player *playerWhosAs info->set_name(name.toStdString()); info->set_type(type); info->set_with_coords(has_coords); - info->set_card_count(cards.size()); + info->set_card_count(static_cast(cards.size())); info->set_always_reveal_top_card(alwaysRevealTopCard); info->set_always_look_at_top_card(alwaysLookAtTopCard); - if ((((playerWhosAsking == player) || omniscient) && (type != ServerInfo_Zone::HiddenZone)) || - ((playerWhosAsking != player) && (type == ServerInfo_Zone::PublicZone))) { + + 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; + if ((selfPlayerAsking && zonesSelfCanSee) || (otherPlayerAsking && zonesOthersCanSee)) { QListIterator cardIterator(cards); while (cardIterator.hasNext()) cardIterator.next()->getInfo(info->add_card_list()); diff --git a/common/server_game.cpp b/common/server_game.cpp index f4f15c8e8..4add59011 100644 --- a/common/server_game.cpp +++ b/common/server_game.cpp @@ -276,7 +276,7 @@ void Server_Game::sendGameStateToPlayers() { // game state information for replay and omniscient spectators Event_GameStateChanged omniscientEvent; - createGameStateChangedEvent(&omniscientEvent, 0, true, false); + createGameStateChangedEvent(&omniscientEvent, nullptr, true, false); GameEventContainer *replayCont = prepareGameEvent(omniscientEvent, -1); replayCont->set_seconds_elapsed(secondsElapsed - startTimeOfThisGame); @@ -287,18 +287,19 @@ void Server_Game::sendGameStateToPlayers() // If spectators are not omniscient, we need an additional createGameStateChangedEvent call, otherwise we can use // the data we used for the replay. All spectators are equal, so we don't need to make a createGameStateChangedEvent // call for each one. - Event_GameStateChanged spectatorEvent; - if (spectatorsSeeEverything) - spectatorEvent = omniscientEvent; - else - createGameStateChangedEvent(&spectatorEvent, 0, false, false); + Event_GameStateChanged spectatorNormalEvent; + createGameStateChangedEvent(&spectatorNormalEvent, nullptr, false, false); // send game state info to clients according to their role in the game for (Server_Player *player : players.values()) { GameEventContainer *gec; - if (player->getSpectator()) - gec = prepareGameEvent(spectatorEvent, -1); - else { + if (player->getSpectator()) { + if (spectatorsSeeEverything || player->getJudge()) { + gec = prepareGameEvent(omniscientEvent, -1); + } else { + gec = prepareGameEvent(spectatorNormalEvent, -1); + } + } else { Event_GameStateChanged event; createGameStateChangedEvent(&event, player, false, false); @@ -341,7 +342,7 @@ void Server_Game::doStartGameIfReady() gameInfo->set_started(false); Event_GameStateChanged omniscientEvent; - createGameStateChangedEvent(&omniscientEvent, 0, true, true); + createGameStateChangedEvent(&omniscientEvent, nullptr, true, true); GameEventContainer *replayCont = prepareGameEvent(omniscientEvent, -1); replayCont->set_seconds_elapsed(0); @@ -711,7 +712,8 @@ void Server_Game::createGameJoinedEvent(Server_Player *player, ResponseContainer event2.set_active_phase(activePhase); for (auto *_player : players.values()) { - _player->getInfo(event2.add_player_list(), _player, _player->getSpectator() && spectatorsSeeEverything, true); + _player->getInfo(event2.add_player_list(), _player, + (_player->getSpectator() && (spectatorsSeeEverything || _player->getJudge())), true); } rc.enqueuePostResponseItem(ServerMessage::GAME_EVENT_CONTAINER, prepareGameEvent(event2, -1)); @@ -725,8 +727,8 @@ void Server_Game::sendGameEventContainer(GameEventContainer *cont, cont->set_game_id(gameId); for (Server_Player *player : players.values()) { - const bool playerPrivate = - (player->getPlayerId() == privatePlayerId) || (player->getSpectator() && spectatorsSeeEverything); + const bool playerPrivate = (player->getPlayerId() == privatePlayerId) || + (player->getSpectator() && (spectatorsSeeEverything || player->getJudge())); if ((recipients.testFlag(GameEventStorageItem::SendToPrivate) && playerPrivate) || (recipients.testFlag(GameEventStorageItem::SendToOthers) && !playerPrivate)) player->sendGameEvent(*cont); diff --git a/common/server_player.cpp b/common/server_player.cpp index d1a20acc9..31790b265 100644 --- a/common/server_player.cpp +++ b/common/server_player.cpp @@ -2085,6 +2085,10 @@ Server_Player::cmdRevealCards(const Command_RevealCards &cmd, ResponseContainer zone->addWritePermission(cmd.player_id()); } + if (getJudge()) { + ges.setOverwriteOwnership(true); + } + ges.enqueueGameEvent(eventPrivate, playerId, GameEventStorageItem::SendToPrivate, cmd.player_id()); ges.enqueueGameEvent(eventOthers, playerId, GameEventStorageItem::SendToOthers); } else { diff --git a/common/server_response_containers.cpp b/common/server_response_containers.cpp index 766721bb4..03ce4d853 100644 --- a/common/server_response_containers.cpp +++ b/common/server_response_containers.cpp @@ -53,17 +53,21 @@ void GameEventStorage::sendToGame(Server_Game *game) if (gameEventList.isEmpty()) return; - GameEventContainer *contPrivate = new GameEventContainer; - GameEventContainer *contOthers = new GameEventContainer; + auto *contPrivate = new GameEventContainer; + auto *contOthers = new GameEventContainer; int id = privatePlayerId; if (forcedByJudge != -1) { contPrivate->set_forced_by_judge(forcedByJudge); contOthers->set_forced_by_judge(forcedByJudge); - id = forcedByJudge; + if (overwriteOwnership) { + id = forcedByJudge; + setOverwriteOwnership(false); + } } - for (int i = 0; i < gameEventList.size(); ++i) { - const GameEvent &event = gameEventList[i]->getGameEvent(); - const GameEventStorageItem::EventRecipients recipients = gameEventList[i]->getRecipients(); + + for (const auto &i : gameEventList) { + const GameEvent &event = i->getGameEvent(); + const GameEventStorageItem::EventRecipients recipients = i->getRecipients(); if (recipients.testFlag(GameEventStorageItem::SendToPrivate)) contPrivate->add_event_list()->CopyFrom(event); if (recipients.testFlag(GameEventStorageItem::SendToOthers)) diff --git a/common/server_response_containers.h b/common/server_response_containers.h index 94f49f115..31e00c54e 100644 --- a/common/server_response_containers.h +++ b/common/server_response_containers.h @@ -50,6 +50,7 @@ private: QList gameEventList; int privatePlayerId; int forcedByJudge = -1; + bool overwriteOwnership = false; public: GameEventStorage(); @@ -72,6 +73,10 @@ public: { forcedByJudge = playerId; } + void setOverwriteOwnership(bool shouldOverwriteOwnership) + { + overwriteOwnership = shouldOverwriteOwnership; + } void enqueueGameEvent(const ::google::protobuf::Message &event, int playerId,