Allow Judges to see all information, regardless of room settings (#5053)

This commit is contained in:
Zach H 2024-06-16 19:12:37 -04:00 committed by GitHub
parent e2ab8db958
commit b7fbc12ac0
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 42 additions and 23 deletions

View file

@ -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); 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); (int)table->boundingRect().height(), this);
connect(hand, SIGNAL(cardCountChanged()), handCounter, SLOT(updateNumber())); connect(hand, SIGNAL(cardCountChanged()), handCounter, SLOT(updateNumber()));
connect(handCounter, SIGNAL(showContextMenu(const QPoint &)), hand, SLOT(showContextMenu(const QPoint &))); connect(handCounter, SIGNAL(showContextMenu(const QPoint &)), hand, SLOT(showContextMenu(const QPoint &)));

View file

@ -323,11 +323,15 @@ void Server_CardZone::getInfo(ServerInfo_Zone *info, Server_Player *playerWhosAs
info->set_name(name.toStdString()); info->set_name(name.toStdString());
info->set_type(type); info->set_type(type);
info->set_with_coords(has_coords); info->set_with_coords(has_coords);
info->set_card_count(cards.size()); info->set_card_count(static_cast<int>(cards.size()));
info->set_always_reveal_top_card(alwaysRevealTopCard); info->set_always_reveal_top_card(alwaysRevealTopCard);
info->set_always_look_at_top_card(alwaysLookAtTopCard); 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<Server_Card *> cardIterator(cards); QListIterator<Server_Card *> cardIterator(cards);
while (cardIterator.hasNext()) while (cardIterator.hasNext())
cardIterator.next()->getInfo(info->add_card_list()); cardIterator.next()->getInfo(info->add_card_list());

View file

@ -276,7 +276,7 @@ void Server_Game::sendGameStateToPlayers()
{ {
// game state information for replay and omniscient spectators // game state information for replay and omniscient spectators
Event_GameStateChanged omniscientEvent; Event_GameStateChanged omniscientEvent;
createGameStateChangedEvent(&omniscientEvent, 0, true, false); createGameStateChangedEvent(&omniscientEvent, nullptr, true, false);
GameEventContainer *replayCont = prepareGameEvent(omniscientEvent, -1); GameEventContainer *replayCont = prepareGameEvent(omniscientEvent, -1);
replayCont->set_seconds_elapsed(secondsElapsed - startTimeOfThisGame); 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 // 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 // the data we used for the replay. All spectators are equal, so we don't need to make a createGameStateChangedEvent
// call for each one. // call for each one.
Event_GameStateChanged spectatorEvent; Event_GameStateChanged spectatorNormalEvent;
if (spectatorsSeeEverything) createGameStateChangedEvent(&spectatorNormalEvent, nullptr, false, false);
spectatorEvent = omniscientEvent;
else
createGameStateChangedEvent(&spectatorEvent, 0, false, false);
// send game state info to clients according to their role in the game // send game state info to clients according to their role in the game
for (Server_Player *player : players.values()) { for (Server_Player *player : players.values()) {
GameEventContainer *gec; GameEventContainer *gec;
if (player->getSpectator()) if (player->getSpectator()) {
gec = prepareGameEvent(spectatorEvent, -1); if (spectatorsSeeEverything || player->getJudge()) {
else { gec = prepareGameEvent(omniscientEvent, -1);
} else {
gec = prepareGameEvent(spectatorNormalEvent, -1);
}
} else {
Event_GameStateChanged event; Event_GameStateChanged event;
createGameStateChangedEvent(&event, player, false, false); createGameStateChangedEvent(&event, player, false, false);
@ -341,7 +342,7 @@ void Server_Game::doStartGameIfReady()
gameInfo->set_started(false); gameInfo->set_started(false);
Event_GameStateChanged omniscientEvent; Event_GameStateChanged omniscientEvent;
createGameStateChangedEvent(&omniscientEvent, 0, true, true); createGameStateChangedEvent(&omniscientEvent, nullptr, true, true);
GameEventContainer *replayCont = prepareGameEvent(omniscientEvent, -1); GameEventContainer *replayCont = prepareGameEvent(omniscientEvent, -1);
replayCont->set_seconds_elapsed(0); replayCont->set_seconds_elapsed(0);
@ -711,7 +712,8 @@ void Server_Game::createGameJoinedEvent(Server_Player *player, ResponseContainer
event2.set_active_phase(activePhase); event2.set_active_phase(activePhase);
for (auto *_player : players.values()) { 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)); rc.enqueuePostResponseItem(ServerMessage::GAME_EVENT_CONTAINER, prepareGameEvent(event2, -1));
@ -725,8 +727,8 @@ void Server_Game::sendGameEventContainer(GameEventContainer *cont,
cont->set_game_id(gameId); cont->set_game_id(gameId);
for (Server_Player *player : players.values()) { for (Server_Player *player : players.values()) {
const bool playerPrivate = const bool playerPrivate = (player->getPlayerId() == privatePlayerId) ||
(player->getPlayerId() == privatePlayerId) || (player->getSpectator() && spectatorsSeeEverything); (player->getSpectator() && (spectatorsSeeEverything || player->getJudge()));
if ((recipients.testFlag(GameEventStorageItem::SendToPrivate) && playerPrivate) || if ((recipients.testFlag(GameEventStorageItem::SendToPrivate) && playerPrivate) ||
(recipients.testFlag(GameEventStorageItem::SendToOthers) && !playerPrivate)) (recipients.testFlag(GameEventStorageItem::SendToOthers) && !playerPrivate))
player->sendGameEvent(*cont); player->sendGameEvent(*cont);

View file

@ -2085,6 +2085,10 @@ Server_Player::cmdRevealCards(const Command_RevealCards &cmd, ResponseContainer
zone->addWritePermission(cmd.player_id()); zone->addWritePermission(cmd.player_id());
} }
if (getJudge()) {
ges.setOverwriteOwnership(true);
}
ges.enqueueGameEvent(eventPrivate, playerId, GameEventStorageItem::SendToPrivate, cmd.player_id()); ges.enqueueGameEvent(eventPrivate, playerId, GameEventStorageItem::SendToPrivate, cmd.player_id());
ges.enqueueGameEvent(eventOthers, playerId, GameEventStorageItem::SendToOthers); ges.enqueueGameEvent(eventOthers, playerId, GameEventStorageItem::SendToOthers);
} else { } else {

View file

@ -53,17 +53,21 @@ void GameEventStorage::sendToGame(Server_Game *game)
if (gameEventList.isEmpty()) if (gameEventList.isEmpty())
return; return;
GameEventContainer *contPrivate = new GameEventContainer; auto *contPrivate = new GameEventContainer;
GameEventContainer *contOthers = new GameEventContainer; auto *contOthers = new GameEventContainer;
int id = privatePlayerId; int id = privatePlayerId;
if (forcedByJudge != -1) { if (forcedByJudge != -1) {
contPrivate->set_forced_by_judge(forcedByJudge); contPrivate->set_forced_by_judge(forcedByJudge);
contOthers->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(); for (const auto &i : gameEventList) {
const GameEventStorageItem::EventRecipients recipients = gameEventList[i]->getRecipients(); const GameEvent &event = i->getGameEvent();
const GameEventStorageItem::EventRecipients recipients = i->getRecipients();
if (recipients.testFlag(GameEventStorageItem::SendToPrivate)) if (recipients.testFlag(GameEventStorageItem::SendToPrivate))
contPrivate->add_event_list()->CopyFrom(event); contPrivate->add_event_list()->CopyFrom(event);
if (recipients.testFlag(GameEventStorageItem::SendToOthers)) if (recipients.testFlag(GameEventStorageItem::SendToOthers))

View file

@ -50,6 +50,7 @@ private:
QList<GameEventStorageItem *> gameEventList; QList<GameEventStorageItem *> gameEventList;
int privatePlayerId; int privatePlayerId;
int forcedByJudge = -1; int forcedByJudge = -1;
bool overwriteOwnership = false;
public: public:
GameEventStorage(); GameEventStorage();
@ -72,6 +73,10 @@ public:
{ {
forcedByJudge = playerId; forcedByJudge = playerId;
} }
void setOverwriteOwnership(bool shouldOverwriteOwnership)
{
overwriteOwnership = shouldOverwriteOwnership;
}
void enqueueGameEvent(const ::google::protobuf::Message &event, void enqueueGameEvent(const ::google::protobuf::Message &event,
int playerId, int playerId,