[ServerGame] Refactor out spectator/judge bools into RoleInfo (#7761)

This commit is contained in:
RickyRister 2026-11-02 00:37:05 -07:00 • committed by GitHub
parent a1a8a59f4a
commit 62e590d300
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
12 changed files with 89 additions and 68 deletions

View file

@ -8,6 +8,7 @@ set(HEADERS
game/server_cardzone.h game/server_cardzone.h
game/server_counter.h game/server_counter.h
game/game_config.h game/game_config.h
game/role_info.h
game/server_deck_validation_strategy.h game/server_deck_validation_strategy.h
game/server_game.h game/server_game.h
game/server_game_lifecycle_strategy.h game/server_game_lifecycle_strategy.h

View file

@ -0,0 +1,13 @@
#ifndef COCKATRICE_ROLE_INFO_H
#define COCKATRICE_ROLE_INFO_H
/**
* @brief Represents information about a participant's roles.
*/
struct RoleInfo
{
bool isJudge = false; ///< Whether the participant joined as a judge
bool isSpectator = false; ///< Whether the participant joined as a spectator
};
#endif // COCKATRICE_ROLE_INFO_H

View file

@ -61,10 +61,10 @@
Server_AbstractParticipant::Server_AbstractParticipant(Server_Game *_game, Server_AbstractParticipant::Server_AbstractParticipant(Server_Game *_game,
int _playerId, int _playerId,
const ServerInfo_User &_userInfo, const ServerInfo_User &_userInfo,
bool _judge, const RoleInfo &_roleInfo,
Server_AbstractUserInterface *_userInterface) Server_AbstractUserInterface *_userInterface)
: ServerInfo_User_Container(_userInfo), game(_game), userInterface(_userInterface), pingTime(0), : ServerInfo_User_Container(_userInfo), game(_game), userInterface(_userInterface), pingTime(0),
playerId(_playerId), judge(_judge) playerId(_playerId), roleInfo(_roleInfo)
{ {
} }
@ -98,8 +98,8 @@ void Server_AbstractParticipant::getProperties(ServerInfo_PlayerProperties &resu
if (withUserInfo) { if (withUserInfo) {
copyUserInfo(*(result.mutable_user_info()), true); copyUserInfo(*(result.mutable_user_info()), true);
} }
result.set_spectator(spectator); result.set_spectator(isSpectator());
result.set_judge(judge); result.set_judge(isJudge());
result.set_ping_seconds(pingTime); result.set_ping_seconds(pingTime);
getPlayerProperties(result); getPlayerProperties(result);
} }
@ -176,7 +176,7 @@ Response::ResponseCode Server_AbstractParticipant::cmdUnconcede(const Command_Un
Response::ResponseCode Response::ResponseCode
Server_AbstractParticipant::cmdJudge(const Command_Judge &cmd, ResponseContainer &rc, GameEventStorage &ges) Server_AbstractParticipant::cmdJudge(const Command_Judge &cmd, ResponseContainer &rc, GameEventStorage &ges)
{ {
if (!judge) { if (!isJudge()) {
return Response::RespFunctionNotAllowed; return Response::RespFunctionNotAllowed;
} }
@ -204,7 +204,7 @@ Response::ResponseCode Server_AbstractParticipant::cmdReadyStart(const Command_R
Response::ResponseCode Response::ResponseCode
Server_AbstractParticipant::cmdGameSay(const Command_GameSay &cmd, ResponseContainer & /*rc*/, GameEventStorage &ges) Server_AbstractParticipant::cmdGameSay(const Command_GameSay &cmd, ResponseContainer & /*rc*/, GameEventStorage &ges)
{ {
if (spectator) { if (isSpectator()) {
/* Spectators can only talk if: /* Spectators can only talk if:
* (a) the game creator allows it * (a) the game creator allows it
* (b) the spectator is a moderator/administrator * (b) the spectator is a moderator/administrator
@ -365,7 +365,7 @@ Response::ResponseCode Server_AbstractParticipant::cmdNextTurn(const Command_Nex
return Response::RespGameNotStarted; return Response::RespGameNotStarted;
} }
if (!judge) { if (!isJudge()) {
return Response::RespFunctionNotAllowed; return Response::RespFunctionNotAllowed;
} }
@ -381,7 +381,7 @@ Response::ResponseCode Server_AbstractParticipant::cmdSetActivePhase(const Comma
return Response::RespGameNotStarted; return Response::RespGameNotStarted;
} }
if (!judge) { if (!isJudge()) {
return Response::RespFunctionNotAllowed; return Response::RespFunctionNotAllowed;
} }
@ -415,8 +415,8 @@ Response::ResponseCode Server_AbstractParticipant::cmdReverseTurn(const Command_
ResponseContainer & /*rc*/, ResponseContainer & /*rc*/,
GameEventStorage &ges) GameEventStorage &ges)
{ {
if (!judge) { if (!isJudge()) {
if (spectator) { if (isSpectator()) {
return Response::RespFunctionNotAllowed; return Response::RespFunctionNotAllowed;
} }
@ -577,7 +577,7 @@ void Server_AbstractParticipant::setUserInterface(Server_AbstractUserInterface *
void Server_AbstractParticipant::disconnectClient() void Server_AbstractParticipant::disconnectClient()
{ {
bool isRegistered = userInfo->user_level() & ServerInfo_User::IsRegistered; bool isRegistered = userInfo->user_level() & ServerInfo_User::IsRegistered;
if (!isRegistered || spectator) { if (!isRegistered || isSpectator()) {
game->removeParticipant(this, Event_Leave::USER_DISCONNECTED); game->removeParticipant(this, Event_Leave::USER_DISCONNECTED);
} else { } else {
setUserInterface(nullptr); setUserInterface(nullptr);

View file

@ -2,6 +2,7 @@
#define ABSTRACT_PARTICIPANT_H #define ABSTRACT_PARTICIPANT_H
#include "../serverinfo_user_container.h" #include "../serverinfo_user_container.h"
#include "role_info.h"
#include "server_arrowtarget.h" #include "server_arrowtarget.h"
#include <QMutex> #include <QMutex>
@ -61,8 +62,7 @@ protected:
Server_AbstractUserInterface *userInterface; Server_AbstractUserInterface *userInterface;
int pingTime; int pingTime;
int playerId; int playerId;
bool spectator; RoleInfo roleInfo;
bool judge;
virtual void getPlayerProperties(ServerInfo_PlayerProperties &result); virtual void getPlayerProperties(ServerInfo_PlayerProperties &result);
mutable QMutex playerMutex; mutable QMutex playerMutex;
@ -70,7 +70,7 @@ public:
Server_AbstractParticipant(Server_Game *_game, Server_AbstractParticipant(Server_Game *_game,
int _playerId, int _playerId,
const ServerInfo_User &_userInfo, const ServerInfo_User &_userInfo,
bool _judge, const RoleInfo &_roleInfo,
Server_AbstractUserInterface *_handler); Server_AbstractUserInterface *_handler);
~Server_AbstractParticipant() override; ~Server_AbstractParticipant() override;
virtual void prepareDestroy() virtual void prepareDestroy()
@ -91,11 +91,11 @@ public:
} }
bool isSpectator() const bool isSpectator() const
{ {
return spectator; return roleInfo.isSpectator;
} }
bool isJudge() const bool isJudge() const
{ {
return judge; return roleInfo.isJudge;
} }
Server_Game *getGame() const Server_Game *getGame() const
{ {

View file

@ -81,10 +81,9 @@ Server_AbstractPlayer::Server_AbstractPlayer(Server_Game *_game,
const ServerInfo_User &_userInfo, const ServerInfo_User &_userInfo,
bool _judge, bool _judge,
Server_AbstractUserInterface *_userInterface) Server_AbstractUserInterface *_userInterface)
: Server_AbstractParticipant(_game, _playerId, _userInfo, _judge, _userInterface), conceded(false), deck(nullptr), : Server_AbstractParticipant(_game, _playerId, _userInfo, {.isJudge = _judge}, _userInterface), conceded(false),
sideboardLocked(true), readyStart(false), nextCardId(0) deck(nullptr), sideboardLocked(true), readyStart(false), nextCardId(0)
{ {
spectator = false;
} }
Server_AbstractPlayer::~Server_AbstractPlayer() = default; Server_AbstractPlayer::~Server_AbstractPlayer() = default;
@ -295,7 +294,7 @@ Response::ResponseCode Server_AbstractPlayer::moveCard(GameEventStorage &ges,
{ {
// Disallow controller change to other zones than the table. // Disallow controller change to other zones than the table.
if (((targetzone->getType() != ServerInfo_Zone::PublicZone) || !targetzone->hasCoords()) && if (((targetzone->getType() != ServerInfo_Zone::PublicZone) || !targetzone->hasCoords()) &&
(startzone->getPlayer() != targetzone->getPlayer()) && !judge) { (startzone->getPlayer() != targetzone->getPlayer()) && !isJudge()) {
return Response::RespContextError; return Response::RespContextError;
} }
@ -808,7 +807,7 @@ Server_AbstractPlayer::cmdMoveCard(const Command_MoveCard &cmd, ResponseContaine
return Response::RespNameNotFound; return Response::RespNameNotFound;
} }
if ((startPlayer != this) && (!startZone->getPlayersWithWritePermission().contains(playerId)) && !judge) { if ((startPlayer != this) && (!startZone->getPlayersWithWritePermission().contains(playerId)) && !isJudge()) {
return Response::RespContextError; return Response::RespContextError;
} }
@ -821,7 +820,7 @@ Server_AbstractPlayer::cmdMoveCard(const Command_MoveCard &cmd, ResponseContaine
return Response::RespNameNotFound; return Response::RespNameNotFound;
} }
if ((startPlayer != this) && (targetPlayer != this) && !judge) { if ((startPlayer != this) && (targetPlayer != this) && !isJudge()) {
return Response::RespContextError; return Response::RespContextError;
} }
@ -1598,7 +1597,7 @@ Server_AbstractPlayer::cmdRevealCards(const Command_RevealCards &cmd, ResponseCo
zone->addWritePermission(cmd.player_id()); zone->addWritePermission(cmd.player_id());
} }
if (judge) { if (isJudge()) {
ges.setOverwriteOwnership(true); ges.setOverwriteOwnership(true);
} }

View file

@ -41,6 +41,7 @@
#include "libcockatrice/protocol/pb/serverinfo_replay_match.pb.h" #include "libcockatrice/protocol/pb/serverinfo_replay_match.pb.h"
#include "libcockatrice/protocol/pb/serverinfo_user.pb.h" #include "libcockatrice/protocol/pb/serverinfo_user.pb.h"
#include "libcockatrice/protocol/pb/session_event.pb.h" #include "libcockatrice/protocol/pb/session_event.pb.h"
#include "role_info.h"
#include "server_abstract_player.h" #include "server_abstract_player.h"
#include "server_abstractuserinterface.h" #include "server_abstractuserinterface.h"
#include "server_arrow.h" #include "server_arrow.h"
@ -479,9 +480,8 @@ void Server_Game::stopGameIfFinished()
Response::ResponseCode Server_Game::checkJoin(ServerInfo_User *user, Response::ResponseCode Server_Game::checkJoin(ServerInfo_User *user,
const QString &_password, const QString &_password,
bool spectator, const RoleInfo &roleInfo,
bool overrideRestrictions, bool overrideRestrictions)
bool asJudge)
{ {
Server_DatabaseInterface *databaseInterface = room->getServer()->getDatabaseInterface(); Server_DatabaseInterface *databaseInterface = room->getServer()->getDatabaseInterface();
for (auto *participant : participants.values()) { for (auto *participant : participants.values()) {
@ -490,11 +490,11 @@ Response::ResponseCode Server_Game::checkJoin(ServerInfo_User *user,
} }
} }
if (asJudge && !(user->user_level() & ServerInfo_User::IsJudge)) { if (roleInfo.isJudge && !(user->user_level() & ServerInfo_User::IsJudge)) {
return Response::RespUserLevelTooLow; return Response::RespUserLevelTooLow;
} }
if (!(overrideRestrictions && (user->user_level() & (ServerInfo_User::IsModerator | ServerInfo_User::IsJudge)))) { if (!(overrideRestrictions && (user->user_level() & (ServerInfo_User::IsModerator | ServerInfo_User::IsJudge)))) {
if ((_password != password) && !(spectator && !spectatorsNeedPassword)) { if ((_password != password) && !(roleInfo.isSpectator && !spectatorsNeedPassword)) {
return Response::RespWrongPassword; return Response::RespWrongPassword;
} }
if (!(user->user_level() & ServerInfo_User::IsRegistered) && onlyRegistered) { if (!(user->user_level() & ServerInfo_User::IsRegistered) && onlyRegistered) {
@ -510,13 +510,13 @@ Response::ResponseCode Server_Game::checkJoin(ServerInfo_User *user,
QString::fromStdString(user->name()))) { QString::fromStdString(user->name()))) {
return Response::RespInIgnoreList; return Response::RespInIgnoreList;
} }
if (spectator) { if (roleInfo.isSpectator) {
if (!spectatorsAllowed) { if (!spectatorsAllowed) {
return Response::RespSpectatorsNotAllowed; return Response::RespSpectatorsNotAllowed;
} }
} }
} }
if (!spectator && (gameStarted || (getPlayerCount() >= getMaxPlayers()))) { if (!roleInfo.isSpectator && (gameStarted || (getPlayerCount() >= getMaxPlayers()))) {
return Response::RespGameFull; return Response::RespGameFull;
} }
@ -537,19 +537,18 @@ bool Server_Game::containsUser(const QString &userName) const
void Server_Game::addPlayer(Server_AbstractUserInterface *userInterface, void Server_Game::addPlayer(Server_AbstractUserInterface *userInterface,
ResponseContainer &rc, ResponseContainer &rc,
bool spectator, const RoleInfo &roleInfo,
bool judge,
bool broadcastUpdate) bool broadcastUpdate)
{ {
QMutexLocker locker(&gameMutex); QMutexLocker locker(&gameMutex);
Server_AbstractParticipant *newParticipant; Server_AbstractParticipant *newParticipant;
if (spectator) { if (roleInfo.isSpectator) {
newParticipant = new Server_Spectator(this, nextPlayerId++, userInterface->copyUserInfo(true, true, true), newParticipant = new Server_Spectator(this, nextPlayerId++, userInterface->copyUserInfo(true, true, true),
judge, userInterface); roleInfo.isJudge, userInterface);
} else { } else {
newParticipant = new Server_Player(this, nextPlayerId++, userInterface->copyUserInfo(true, true, true), judge, newParticipant = new Server_Player(this, nextPlayerId++, userInterface->copyUserInfo(true, true, true),
userInterface); roleInfo.isJudge, userInterface);
} }
newParticipant->moveToThread(thread()); newParticipant->moveToThread(thread());
@ -560,7 +559,7 @@ void Server_Game::addPlayer(Server_AbstractUserInterface *userInterface,
const QString playerName = QString::fromStdString(newParticipant->getUserInfo()->name()); const QString playerName = QString::fromStdString(newParticipant->getUserInfo()->name());
participants.insert(newParticipant->getPlayerId(), newParticipant); participants.insert(newParticipant->getPlayerId(), newParticipant);
if (spectator) { if (roleInfo.isSpectator) {
allSpectatorsEver.insert(playerName); allSpectatorsEver.insert(playerName);
} else { } else {
allPlayersEver.insert(playerName); allPlayersEver.insert(playerName);
@ -579,7 +578,7 @@ void Server_Game::addPlayer(Server_AbstractUserInterface *userInterface,
emit gameInfoChanged(gameInfo); emit gameInfoChanged(gameInfo);
} }
if ((newParticipant->getUserInfo()->user_level() & ServerInfo_User::IsRegistered) && !spectator) { if ((newParticipant->getUserInfo()->user_level() & ServerInfo_User::IsRegistered) && !roleInfo.isSpectator) {
room->getServer()->addPersistentPlayer(playerName, room->getId(), gameId, newParticipant->getPlayerId()); room->getServer()->addPersistentPlayer(playerName, room->getId(), gameId, newParticipant->getPlayerId());
} }
@ -871,6 +870,13 @@ void Server_Game::createGameJoinedEvent(Server_AbstractParticipant *joiningParti
} }
} }
bool Server_Game::canSeePrivateEventsFor(const Server_AbstractParticipant *participant, int privatePlayerId) const
{
return participant->getPlayerId() == privatePlayerId // same player
|| participant->isJudge() // judges see everything
|| (participant->isSpectator() && spectatorsSeeEverything); // spectators see everything
}
void Server_Game::sendGameEventContainer(GameEventContainer *cont, void Server_Game::sendGameEventContainer(GameEventContainer *cont,
GameEventStorageItem::EventRecipients recipients, GameEventStorageItem::EventRecipients recipients,
int privatePlayerId) int privatePlayerId)
@ -879,8 +885,7 @@ void Server_Game::sendGameEventContainer(GameEventContainer *cont,
cont->set_game_id(gameId); cont->set_game_id(gameId);
for (auto *participant : participants.values()) { for (auto *participant : participants.values()) {
const bool playerPrivate = (participant->getPlayerId() == privatePlayerId) || participant->isJudge() || const bool playerPrivate = canSeePrivateEventsFor(participant, privatePlayerId);
(participant->isSpectator() && spectatorsSeeEverything);
if ((recipients.testFlag(GameEventStorageItem::SendToPrivate) && playerPrivate) || if ((recipients.testFlag(GameEventStorageItem::SendToPrivate) && playerPrivate) ||
(recipients.testFlag(GameEventStorageItem::SendToOthers) && !playerPrivate)) { (recipients.testFlag(GameEventStorageItem::SendToOthers) && !playerPrivate)) {
participant->sendGameEvent(*cont); participant->sendGameEvent(*cont);

View file

@ -62,6 +62,7 @@ class Message;
} // namespace protobuf } // namespace protobuf
} // namespace google } // namespace google
struct GameConfig; struct GameConfig;
struct RoleInfo;
class Server_Game : public QObject class Server_Game : public QObject
{ {
@ -109,6 +110,7 @@ private:
bool omniscient, bool omniscient,
bool withUserInfo); bool withUserInfo);
void storeGameInformation(); void storeGameInformation();
bool canSeePrivateEventsFor(const Server_AbstractParticipant *participant, int privatePlayerId) const;
signals: signals:
void sigStartGameIfReady(bool override); void sigStartGameIfReady(bool override);
void gameInfoChanged(ServerInfo_Game gameInfo); void gameInfoChanged(ServerInfo_Game gameInfo);
@ -188,12 +190,11 @@ public:
return shareDecklistsOnLoad; return shareDecklistsOnLoad;
} }
Response::ResponseCode Response::ResponseCode
checkJoin(ServerInfo_User *user, const QString &_password, bool spectator, bool overrideRestrictions, bool asJudge); checkJoin(ServerInfo_User *user, const QString &_password, const RoleInfo &roleInfo, bool overrideRestrictions);
bool containsUser(const QString &userName) const; bool containsUser(const QString &userName) const;
void addPlayer(Server_AbstractUserInterface *userInterface, void addPlayer(Server_AbstractUserInterface *userInterface,
ResponseContainer &rc, ResponseContainer &rc,
bool spectator, const RoleInfo &roleInfo,
bool judge,
bool broadcastUpdate = true); bool broadcastUpdate = true);
void removeParticipant(Server_AbstractParticipant *participant, Event_Leave::LeaveReason reason); void removeParticipant(Server_AbstractParticipant *participant, Event_Leave::LeaveReason reason);
void removeArrowsRelatedToPlayer(GameEventStorage &ges, Server_AbstractPlayer *player); void removeArrowsRelatedToPlayer(GameEventStorage &ges, Server_AbstractPlayer *player);

View file

@ -573,7 +573,7 @@ Server_Player::cmdNextTurn(const Command_NextTurn & /*cmd*/, ResponseContainer &
return Response::RespGameNotStarted; return Response::RespGameNotStarted;
} }
if (conceded && !judge) { if (conceded && !isJudge()) {
return Response::RespContextError; return Response::RespContextError;
} }
@ -589,7 +589,7 @@ Response::ResponseCode Server_Player::cmdSetActivePhase(const Command_SetActiveP
return Response::RespGameNotStarted; return Response::RespGameNotStarted;
} }
if (!judge) { if (!isJudge()) {
if (conceded) { if (conceded) {
return Response::RespContextError; return Response::RespContextError;
} }
@ -623,7 +623,7 @@ 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 (!judge && conceded) { if (!isJudge() && conceded) {
return Response::RespContextError; return Response::RespContextError;
} }
return Server_AbstractParticipant::cmdReverseTurn(cmd, rc, ges); return Server_AbstractParticipant::cmdReverseTurn(cmd, rc, ges);

View file

@ -11,7 +11,6 @@ Server_Spectator::Server_Spectator(Server_Game *_game,
const ServerInfo_User &_userInfo, const ServerInfo_User &_userInfo,
bool _judge, bool _judge,
Server_AbstractUserInterface *_userInterface) Server_AbstractUserInterface *_userInterface)
: Server_AbstractParticipant(_game, _playerId, _userInfo, _judge, _userInterface) : Server_AbstractParticipant(_game, _playerId, _userInfo, {.isJudge = _judge, .isSpectator = true}, _userInterface)
{ {
spectator = true;
} }

View file

@ -1141,7 +1141,8 @@ Server_ProtocolHandler::cmdCreateGame(const Command_CreateGame &cmd, Server_Room
auto *game = new Server_Game(config, room); auto *game = new Server_Game(config, room);
game->addPlayer(this, rc, asSpectator, asJudge, false); RoleInfo roleInfo{.isJudge = asJudge, .isSpectator = asSpectator};
game->addPlayer(this, rc, roleInfo, false);
room->addGame(game); room->addGame(game);
return Response::RespOk; return Response::RespOk;

View file

@ -1,5 +1,6 @@
#include "server_room.h" #include "server_room.h"
#include "game/role_info.h"
#include "game/server_game.h" #include "game/server_game.h"
#include "libcockatrice/protocol/pb/response.pb.h" #include "libcockatrice/protocol/pb/response.pb.h"
#include "libcockatrice/protocol/pb/room_event.pb.h" #include "libcockatrice/protocol/pb/room_event.pb.h"
@ -372,11 +373,11 @@ Response::ResponseCode Server_Room::processJoinGameCommand(const Command_JoinGam
QMutexLocker gameLocker(&game->gameMutex); QMutexLocker gameLocker(&game->gameMutex);
Response::ResponseCode result = RoleInfo roleInfo{.isJudge = cmd.join_as_judge(), .isSpectator = cmd.spectator()};
game->checkJoin(userInterface->getUserInfo(), QString::fromStdString(cmd.password()), cmd.spectator(), Response::ResponseCode result = game->checkJoin(
cmd.override_restrictions(), cmd.join_as_judge()); userInterface->getUserInfo(), QString::fromStdString(cmd.password()), roleInfo, cmd.override_restrictions());
if (result == Response::RespOk) { if (result == Response::RespOk) {
game->addPlayer(userInterface, rc, cmd.spectator(), cmd.join_as_judge()); game->addPlayer(userInterface, rc, roleInfo);
} }
return result; return result;

View file

@ -4,6 +4,7 @@
*/ */
#include "game/game_config.h" #include "game/game_config.h"
#include "game/role_info.h"
#include "game/server_game.h" #include "game/server_game.h"
#include "libcockatrice/protocol/pb/response.pb.h" #include "libcockatrice/protocol/pb/response.pb.h"
#include "server.h" #include "server.h"
@ -119,13 +120,13 @@ TEST_F(GameJoinOverrideTest, StaffBypassPasswordRestriction)
game = makeGame(true, false, false, true); game = makeGame(true, false, false, true);
// A plain user cannot override the password even with the override flag set. // A plain user cannot override the password even with the override flag set.
EXPECT_EQ(game->checkJoin(&plainUser, "wrong", false, true, false), Response::RespWrongPassword); EXPECT_EQ(game->checkJoin(&plainUser, "wrong", {}, true), Response::RespWrongPassword);
// Moderators and judges may enter any game regardless of the password. // Moderators and judges may enter any game regardless of the password.
EXPECT_EQ(game->checkJoin(&moderator, "wrong", false, true, false), Response::RespOk); EXPECT_EQ(game->checkJoin(&moderator, "wrong", {}, true), Response::RespOk);
EXPECT_EQ(game->checkJoin(&judge, "wrong", false, true, false), Response::RespOk); EXPECT_EQ(game->checkJoin(&judge, "wrong", {}, true), Response::RespOk);
// Without the override flag judges are still subject to the password. // Without the override flag judges are still subject to the password.
EXPECT_EQ(game->checkJoin(&judge, "wrong", false, false, true), Response::RespWrongPassword); EXPECT_EQ(game->checkJoin(&judge, "wrong", {.isJudge = true}, false), Response::RespWrongPassword);
EXPECT_EQ(game->checkJoin(&judge, "secret", false, false, true), Response::RespOk); EXPECT_EQ(game->checkJoin(&judge, "secret", {.isJudge = true}, false), Response::RespOk);
} }
TEST_F(GameJoinOverrideTest, StaffBypassRegisteredOnlyRestriction) TEST_F(GameJoinOverrideTest, StaffBypassRegisteredOnlyRestriction)
@ -133,9 +134,9 @@ TEST_F(GameJoinOverrideTest, StaffBypassRegisteredOnlyRestriction)
game = makeGame(false, true, false, true); game = makeGame(false, true, false, true);
// Without the override flag the only-registered restriction still applies. // Without the override flag the only-registered restriction still applies.
EXPECT_EQ(game->checkJoin(&unregisteredJudge, QString(), false, false, false), Response::RespUserLevelTooLow); EXPECT_EQ(game->checkJoin(&unregisteredJudge, QString(), {}, false), Response::RespUserLevelTooLow);
// An unregistered judge may enter when overriding restrictions. // An unregistered judge may enter when overriding restrictions.
EXPECT_EQ(game->checkJoin(&unregisteredJudge, QString(), false, true, false), Response::RespOk); EXPECT_EQ(game->checkJoin(&unregisteredJudge, QString(), {}, true), Response::RespOk);
} }
TEST_F(GameJoinOverrideTest, StaffBypassBuddiesOnlyRestriction) TEST_F(GameJoinOverrideTest, StaffBypassBuddiesOnlyRestriction)
@ -143,10 +144,10 @@ TEST_F(GameJoinOverrideTest, StaffBypassBuddiesOnlyRestriction)
game = makeGame(false, false, true, true); game = makeGame(false, false, true, true);
// A plain user who is not on the creator's buddy list gets rejected. // A plain user who is not on the creator's buddy list gets rejected.
EXPECT_EQ(game->checkJoin(&plainUser, QString(), false, true, false), Response::RespOnlyBuddies); EXPECT_EQ(game->checkJoin(&plainUser, QString(), {}, true), Response::RespOnlyBuddies);
// Moderators and judges bypass the buddies-only restriction. // Moderators and judges bypass the buddies-only restriction.
EXPECT_EQ(game->checkJoin(&moderator, QString(), false, true, false), Response::RespOk); EXPECT_EQ(game->checkJoin(&moderator, QString(), {}, true), Response::RespOk);
EXPECT_EQ(game->checkJoin(&judge, QString(), false, true, false), Response::RespOk); EXPECT_EQ(game->checkJoin(&judge, QString(), {}, true), Response::RespOk);
} }
TEST_F(GameJoinOverrideTest, StaffBypassSpectatorsNotAllowedRestriction) TEST_F(GameJoinOverrideTest, StaffBypassSpectatorsNotAllowedRestriction)
@ -154,11 +155,11 @@ TEST_F(GameJoinOverrideTest, StaffBypassSpectatorsNotAllowedRestriction)
game = makeGame(false, false, false, false); game = makeGame(false, false, false, false);
// A plain user cannot spectate when the game disallows spectators. // A plain user cannot spectate when the game disallows spectators.
EXPECT_EQ(game->checkJoin(&plainUser, QString(), true, false, false), Response::RespSpectatorsNotAllowed); EXPECT_EQ(game->checkJoin(&plainUser, QString(), {.isSpectator = true}, false), Response::RespSpectatorsNotAllowed);
// Moderators and judges may spectate any game regardless of the password // Moderators and judges may spectate any game regardless of the password
// and the spectator restriction. // and the spectator restriction.
EXPECT_EQ(game->checkJoin(&moderator, "wrong", true, true, false), Response::RespOk); EXPECT_EQ(game->checkJoin(&moderator, "wrong", {.isSpectator = true}, true), Response::RespOk);
EXPECT_EQ(game->checkJoin(&judge, "wrong", true, true, false), Response::RespOk); EXPECT_EQ(game->checkJoin(&judge, "wrong", {.isSpectator = true}, true), Response::RespOk);
} }
TEST_F(GameJoinOverrideTest, JudgeOverrideDoesNotGrantJudgeJoinToPlainUser) TEST_F(GameJoinOverrideTest, JudgeOverrideDoesNotGrantJudgeJoinToPlainUser)
@ -166,8 +167,8 @@ TEST_F(GameJoinOverrideTest, JudgeOverrideDoesNotGrantJudgeJoinToPlainUser)
game = makeGame(false, false, false, true); game = makeGame(false, false, false, true);
// joining with join_as_judge still requires the judge flag even when overriding. // joining with join_as_judge still requires the judge flag even when overriding.
EXPECT_EQ(game->checkJoin(&plainUser, QString(), false, true, true), Response::RespUserLevelTooLow); EXPECT_EQ(game->checkJoin(&plainUser, QString(), {.isJudge = true}, true), Response::RespUserLevelTooLow);
EXPECT_EQ(game->checkJoin(&judge, QString(), false, true, true), Response::RespOk); EXPECT_EQ(game->checkJoin(&judge, QString(), {.isJudge = true}, true), Response::RespOk);
} }
} // namespace } // namespace