Meta Info

Took 14 hours 36 minutes
This commit is contained in:
Lukas Brübach 2025-09-04 13:05:28 +02:00
parent 467d90e236
commit 0d9969b365
11 changed files with 238 additions and 149 deletions

View file

@ -208,6 +208,7 @@ set(cockatrice_SOURCES
src/game/filters/filter_tree_model.cpp src/game/filters/filter_tree_model.cpp
src/game/filters/syntax_help.cpp src/game/filters/syntax_help.cpp
src/game/game_event_handler.cpp src/game/game_event_handler.cpp
src/game/game_meta_info.cpp
src/game/game_scene.cpp src/game/game_scene.cpp
src/game/game_selector.cpp src/game/game_selector.cpp
src/game/game_state.cpp src/game/game_state.cpp

View file

@ -50,12 +50,19 @@ TabGame::TabGame(TabSupervisor *_tabSupervisor, GameReplay *_replay)
{ {
// THIS CTOR IS USED ON REPLAY // THIS CTOR IS USED ON REPLAY
gameMetaInfo = new GameMetaInfo();
gameState = new GameState(0, -1, -1, _tabSupervisor->getIsLocalGame(), QList<AbstractClient *>(), true, false, gameState = new GameState(0, -1, -1, _tabSupervisor->getIsLocalGame(), QList<AbstractClient *>(), true, false,
false, false, -1, false); false, false, -1, false);
connect(gameState, &GameState::playerAdded, this, &TabGame::addPlayer); connect(gameState, &GameState::playerAdded, this, &TabGame::addPlayer);
connect(gameState, &GameState::spectatorAdded, this, &TabGame::addSpectator); connect(gameState, &GameState::spectatorAdded, this, &TabGame::addSpectator);
connect(gameState, &GameState::gameStarted, this, &TabGame::startGame); connect(gameState, &GameState::gameStarted, this, &TabGame::startGame);
gameEventHandler = new GameEventHandler(this);
connect(this, &TabGame::gameLeft, gameEventHandler, &GameEventHandler::handleGameLeft);
connect(gameEventHandler, &GameEventHandler::localPlayerDeckSelected, this, &TabGame::processLocalPlayerDeckSelect);
connect(gameEventHandler, &GameEventHandler::gameStopped, this, &TabGame::stopGame);
connect(gameEventHandler, &GameEventHandler::gameClosed, this, &TabGame::closeGame);
createCardInfoDock(true); createCardInfoDock(true);
createPlayerListDock(true); createPlayerListDock(true);
createMessageDock(true); createMessageDock(true);
@ -63,12 +70,6 @@ TabGame::TabGame(TabSupervisor *_tabSupervisor, GameReplay *_replay)
createDeckViewContainerWidget(true); createDeckViewContainerWidget(true);
createReplayDock(_replay); createReplayDock(_replay);
gameEventHandler = new GameEventHandler(this, messageLog);
connect(this, &TabGame::gameLeft, gameEventHandler, &GameEventHandler::handleGameLeft);
connect(gameEventHandler, &GameEventHandler::localPlayerDeckSelected, this, &TabGame::processLocalPlayerDeckSelect);
connect(gameEventHandler, &GameEventHandler::gameStopped, this, &TabGame::stopGame);
connect(gameEventHandler, &GameEventHandler::gameClosed, this, &TabGame::closeGame);
addDockWidget(Qt::RightDockWidgetArea, cardInfoDock); addDockWidget(Qt::RightDockWidgetArea, cardInfoDock);
addDockWidget(Qt::RightDockWidgetArea, playerListDock); addDockWidget(Qt::RightDockWidgetArea, playerListDock);
addDockWidget(Qt::RightDockWidgetArea, messageLayoutDock); addDockWidget(Qt::RightDockWidgetArea, messageLayoutDock);
@ -85,7 +86,7 @@ TabGame::TabGame(TabSupervisor *_tabSupervisor, GameReplay *_replay)
connect(&SettingsCache::instance().shortcuts(), &ShortcutsSettings::shortCutChanged, this, connect(&SettingsCache::instance().shortcuts(), &ShortcutsSettings::shortCutChanged, this,
&TabGame::refreshShortcuts); &TabGame::refreshShortcuts);
refreshShortcuts(); refreshShortcuts();
messageLog->logReplayStarted(gameState->getGameId()); messageLog->logReplayStarted(gameMetaInfo->gameId());
QTimer::singleShot(0, this, &TabGame::loadLayout); QTimer::singleShot(0, this, &TabGame::loadLayout);
} }
@ -97,15 +98,24 @@ TabGame::TabGame(TabSupervisor *_tabSupervisor,
: Tab(_tabSupervisor), userListProxy(_tabSupervisor->getUserListManager()), activeCard(nullptr) : Tab(_tabSupervisor), userListProxy(_tabSupervisor->getUserListManager()), activeCard(nullptr)
{ {
gameMetaInfo = new GameMetaInfo();
gameMetaInfo->setFromProto(event.game_info());
gameMetaInfo->setRoomGameTypes(_roomGameTypes);
gameState = new GameState(0, event.host_id(), event.player_id(), _tabSupervisor->getIsLocalGame(), _clients, gameState = new GameState(0, event.host_id(), event.player_id(), _tabSupervisor->getIsLocalGame(), _clients,
event.spectator(), event.judge(), false, event.resuming(), -1, false); event.spectator(), event.judge(), false, event.resuming(), -1, false);
gameState->setGameInfo(event.game_info());
gameState->setRoomGameTypes(_roomGameTypes);
// THIS CTOR IS USED ON GAMES // THIS CTOR IS USED ON GAMES
gameState->setStarted(false); gameMetaInfo->setStarted(false);
connect(gameState, &GameState::playerAdded, this, &TabGame::addPlayer); connect(gameState, &GameState::playerAdded, this, &TabGame::addPlayer);
connect(gameState, &GameState::spectatorAdded, this, &TabGame::addSpectator); connect(gameState, &GameState::spectatorAdded, this, &TabGame::addSpectator);
connect(gameState, &GameState::gameStarted, this, &TabGame::startGame);
gameEventHandler = new GameEventHandler(this);
connect(this, &TabGame::gameLeft, gameEventHandler, &GameEventHandler::handleGameLeft);
connect(gameEventHandler, &GameEventHandler::localPlayerDeckSelected, this, &TabGame::processLocalPlayerDeckSelect);
connect(gameEventHandler, &GameEventHandler::gameStopped, this, &TabGame::stopGame);
connect(gameEventHandler, &GameEventHandler::gameClosed, this, &TabGame::closeGame);
createCardInfoDock(); createCardInfoDock();
createPlayerListDock(); createPlayerListDock();
@ -114,14 +124,6 @@ TabGame::TabGame(TabSupervisor *_tabSupervisor,
createDeckViewContainerWidget(); createDeckViewContainerWidget();
createReplayDock(nullptr); createReplayDock(nullptr);
connect(gameState, &GameState::gameStarted, this, &TabGame::startGame);
gameEventHandler = new GameEventHandler(this, messageLog);
connect(this, &TabGame::gameLeft, gameEventHandler, &GameEventHandler::handleGameLeft);
connect(gameEventHandler, &GameEventHandler::localPlayerDeckSelected, this, &TabGame::processLocalPlayerDeckSelect);
connect(gameEventHandler, &GameEventHandler::gameStopped, this, &TabGame::stopGame);
connect(gameEventHandler, &GameEventHandler::gameClosed, this, &TabGame::closeGame);
addDockWidget(Qt::RightDockWidgetArea, cardInfoDock); addDockWidget(Qt::RightDockWidgetArea, cardInfoDock);
addDockWidget(Qt::RightDockWidgetArea, playerListDock); addDockWidget(Qt::RightDockWidgetArea, playerListDock);
addDockWidget(Qt::RightDockWidgetArea, messageLayoutDock); addDockWidget(Qt::RightDockWidgetArea, messageLayoutDock);
@ -141,16 +143,16 @@ TabGame::TabGame(TabSupervisor *_tabSupervisor,
refreshShortcuts(); refreshShortcuts();
// append game to rooms game list for others to see // append game to rooms game list for others to see
for (int i = gameState->getGameTypesSize() - 1; i >= 0; i--) for (int i = gameMetaInfo->gameTypesSize() - 1; i >= 0; i--)
gameTypes.append(gameState->findRoomGameType(i)); gameTypes.append(gameMetaInfo->findRoomGameType(i));
QTimer::singleShot(0, this, &TabGame::loadLayout); QTimer::singleShot(0, this, &TabGame::loadLayout);
} }
void TabGame::loadReplay(GameReplay *replay) void TabGame::loadReplay(GameReplay *replay)
{ {
gameState->setGameInfo(replay->game_info()); gameMetaInfo->setFromProto(replay->game_info());
gameState->setSpectatorsOmniscient(true); gameMetaInfo->setSpectatorsOmniscient(true);
} }
void TabGame::addMentionTag(const QString &value) void TabGame::addMentionTag(const QString &value)
@ -189,8 +191,8 @@ TabGame::~TabGame()
void TabGame::updatePlayerListDockTitle() void TabGame::updatePlayerListDockTitle()
{ {
QString tabText = QString tabText =
" | " + (replayManager->replay ? tr("Replay") : tr("Game")) + " #" + QString::number(gameState->getGameId()); " | " + (replayManager->replay ? tr("Replay") : tr("Game")) + " #" + QString::number(gameMetaInfo->gameId());
QString userCountInfo = QString(" %1/%2").arg(gameState->getPlayerCount()).arg(gameState->getMaxPlayerCount()); QString userCountInfo = QString(" %1/%2").arg(gameState->getPlayerCount()).arg(gameMetaInfo->maxPlayers());
playerListDock->setWindowTitle(tr("Player List") + userCountInfo + playerListDock->setWindowTitle(tr("Player List") + userCountInfo +
(playerListDock->isWindow() ? tabText : QString())); (playerListDock->isWindow() ? tabText : QString()));
} }
@ -198,7 +200,7 @@ void TabGame::updatePlayerListDockTitle()
void TabGame::retranslateUi() void TabGame::retranslateUi()
{ {
QString tabText = QString tabText =
" | " + (replayManager->replay ? tr("Replay") : tr("Game")) + " #" + QString::number(gameState->getGameId()); " | " + (replayManager->replay ? tr("Replay") : tr("Game")) + " #" + QString::number(gameMetaInfo->gameId());
updatePlayerListDockTitle(); updatePlayerListDockTitle();
cardInfoDock->setWindowTitle(tr("Card Info") + (cardInfoDock->isWindow() ? tabText : QString())); cardInfoDock->setWindowTitle(tr("Card Info") + (cardInfoDock->isWindow() ? tabText : QString()));
@ -397,14 +399,14 @@ void TabGame::updateTimeElapsedLabel(const QString newTime)
void TabGame::adminLockChanged(bool lock) void TabGame::adminLockChanged(bool lock)
{ {
bool v = !(gameState->isSpectator() && !gameState->canSpectatorsChat() && lock); bool v = !(gameState->isSpectator() && !gameMetaInfo->spectatorsCanChat() && lock);
sayLabel->setVisible(v); sayLabel->setVisible(v);
sayEdit->setVisible(v); sayEdit->setVisible(v);
} }
void TabGame::actGameInfo() void TabGame::actGameInfo()
{ {
DlgCreateGame dlg(gameState->getGameInfo(), gameState->getRoomGameTypes(), this); DlgCreateGame dlg(gameMetaInfo->proto(), gameMetaInfo->getRoomGameTypes(), this);
dlg.exec(); dlg.exec();
} }
@ -561,7 +563,7 @@ void TabGame::actCompleterChanged()
void TabGame::notifyPlayerJoin(QString playerName) void TabGame::notifyPlayerJoin(QString playerName)
{ {
if (trayIcon) { if (trayIcon) {
QString gameId(QString::number(gameState->getGameId())); QString gameId(QString::number(gameMetaInfo->gameId()));
trayIcon->showMessage(tr("A player has joined game #%1").arg(gameId), trayIcon->showMessage(tr("A player has joined game #%1").arg(gameId),
tr("%1 has joined the game").arg(playerName)); tr("%1 has joined the game").arg(playerName));
} }
@ -746,7 +748,7 @@ void TabGame::startGame(bool _resuming)
} }
playerListWidget->setGameStarted(true, gameState->isResuming()); playerListWidget->setGameStarted(true, gameState->isResuming());
gameState->setStarted(true); gameMetaInfo->setStarted(true);
static_cast<GameScene *>(gameView->scene())->rearrange(); static_cast<GameScene *>(gameView->scene())->rearrange();
} }
@ -836,8 +838,8 @@ QString TabGame::getTabText() const
gameTypeInfo.append("..."); gameTypeInfo.append("...");
} }
QString gameDesc(gameState->getGameDescription()); QString gameDesc(gameMetaInfo->description());
QString gameId(QString::number(gameState->getGameId())); QString gameId(QString::number(gameMetaInfo->gameId()));
QString tabText; QString tabText;
if (replayManager->replay) if (replayManager->replay)
@ -1282,7 +1284,7 @@ void TabGame::createMessageDock(bool bReplay)
* (c) the spectator is a judge * (c) the spectator is a judge
*/ */
bool isModOrJudge = !tabSupervisor->getAdminLocked() || gameState->isJudge(); bool isModOrJudge = !tabSupervisor->getAdminLocked() || gameState->isJudge();
if (!isModOrJudge && !gameState->canSpectatorsChat()) { if (!isModOrJudge && !gameMetaInfo->spectatorsCanChat()) {
sayLabel->hide(); sayLabel->hide();
sayEdit->hide(); sayEdit->hide();
} }

View file

@ -3,6 +3,7 @@
#include "../../client/tearoff_menu.h" #include "../../client/tearoff_menu.h"
#include "../../game/game_event_handler.h" #include "../../game/game_event_handler.h"
#include "../../game/game_meta_info.h"
#include "../../game/game_state.h" #include "../../game/game_state.h"
#include "../../game/player/player.h" #include "../../game/player/player.h"
#include "../replay_manager.h" #include "../replay_manager.h"
@ -51,6 +52,7 @@ class TabGame : public Tab
{ {
Q_OBJECT Q_OBJECT
private: private:
GameMetaInfo *gameMetaInfo;
GameState *gameState; GameState *gameState;
GameEventHandler *gameEventHandler; GameEventHandler *gameEventHandler;
const UserListProxy *userListProxy; const UserListProxy *userListProxy;
@ -178,6 +180,11 @@ public:
void updatePlayerListDockTitle(); void updatePlayerListDockTitle();
bool closeRequest() override; bool closeRequest() override;
GameMetaInfo *getGameMetaInfo()
{
return gameMetaInfo;
}
GameState *getGameState() const GameState *getGameState() const
{ {
return gameState; return gameState;

View file

@ -707,7 +707,7 @@ void TabSupervisor::gameLeft(TabGame *tab)
if (tab == currentWidget()) if (tab == currentWidget())
emit setMenu(); emit setMenu();
gameTabs.remove(tab->getGameState()->getGameId()); gameTabs.remove(tab->getGameMetaInfo()->gameId());
removeTab(indexOf(tab)); removeTab(indexOf(tab));
if (!localClients.isEmpty()) if (!localClients.isEmpty())

View file

@ -28,8 +28,7 @@
#include "pb/event_set_active_player.pb.h" #include "pb/event_set_active_player.pb.h"
#include "pb/game_event_container.pb.h" #include "pb/game_event_container.pb.h"
GameEventHandler::GameEventHandler(TabGame *_game, MessageLogWidget *_messageLog) GameEventHandler::GameEventHandler(TabGame *_game) : game(_game), gameState(_game->getGameState())
: game(_game), gameState(_game->getGameState()), messageLog(_messageLog)
{ {
} }
@ -57,13 +56,14 @@ void GameEventHandler::sendGameCommand(const google::protobuf::Message &command,
void GameEventHandler::commandFinished(const Response &response) void GameEventHandler::commandFinished(const Response &response)
{ {
if (response.response_code() == Response::RespChatFlood) if (response.response_code() == Response::RespChatFlood)
messageLog->appendMessage(tr("You are flooding the game. Please wait a couple of seconds.")); emit gameFlooded();
// messageLog->appendMessage(tr("You are flooding the game. Please wait a couple of seconds."));
} }
PendingCommand *GameEventHandler::prepareGameCommand(const ::google::protobuf::Message &cmd) PendingCommand *GameEventHandler::prepareGameCommand(const ::google::protobuf::Message &cmd)
{ {
CommandContainer cont; CommandContainer cont;
cont.set_game_id(static_cast<google::protobuf::uint32>(game->getGameState()->getGameId())); cont.set_game_id(static_cast<google::protobuf::uint32>(game->getGameMetaInfo()->gameId()));
GameCommand *c = cont.add_game_command(); GameCommand *c = cont.add_game_command();
c->GetReflection()->MutableMessage(c, cmd.GetDescriptor()->FindExtensionByName("ext"))->CopyFrom(cmd); c->GetReflection()->MutableMessage(c, cmd.GetDescriptor()->FindExtensionByName("ext"))->CopyFrom(cmd);
return new PendingCommand(cont); return new PendingCommand(cont);
@ -72,7 +72,7 @@ PendingCommand *GameEventHandler::prepareGameCommand(const ::google::protobuf::M
PendingCommand *GameEventHandler::prepareGameCommand(const QList<const ::google::protobuf::Message *> &cmdList) PendingCommand *GameEventHandler::prepareGameCommand(const QList<const ::google::protobuf::Message *> &cmdList)
{ {
CommandContainer cont; CommandContainer cont;
cont.set_game_id(static_cast<google::protobuf::uint32>(game->getGameState()->getGameId())); cont.set_game_id(static_cast<google::protobuf::uint32>(game->getGameMetaInfo()->gameId()));
for (auto i : cmdList) { for (auto i : cmdList) {
GameCommand *c = cont.add_game_command(); GameCommand *c = cont.add_game_command();
c->GetReflection()->MutableMessage(c, i->GetDescriptor()->FindExtensionByName("ext"))->CopyFrom(*i); c->GetReflection()->MutableMessage(c, i->GetDescriptor()->FindExtensionByName("ext"))->CopyFrom(*i);
@ -86,7 +86,8 @@ void GameEventHandler::processGameEventContainer(const GameEventContainer &cont,
Player::EventProcessingOptions options) Player::EventProcessingOptions options)
{ {
const GameEventContext &context = cont.context(); const GameEventContext &context = cont.context();
messageLog->containerProcessingStarted(context); emit containerProcessingStarted(context);
// messageLog->containerProcessingStarted(context);
const int eventListSize = cont.event_list_size(); const int eventListSize = cont.event_list_size();
for (int i = 0; i < eventListSize; ++i) { for (int i = 0; i < eventListSize; ++i) {
const GameEvent &event = cont.event_list(i); const GameEvent &event = cont.event_list(i);
@ -97,9 +98,11 @@ void GameEventHandler::processGameEventContainer(const GameEventContainer &cont,
auto id = cont.forced_by_judge(); auto id = cont.forced_by_judge();
Player *judgep = gameState->getPlayers().value(id, nullptr); Player *judgep = gameState->getPlayers().value(id, nullptr);
if (judgep) { if (judgep) {
messageLog->setContextJudgeName(judgep->getName()); emit setContextJudgeName();
// messageLog->setContextJudgeName(judgep->getName());
} else if (gameState->getSpectators().contains(id)) { } else if (gameState->getSpectators().contains(id)) {
messageLog->setContextJudgeName(QString::fromStdString(gameState->getSpectators().value(id).name())); emit setContextJudgeName();
// messageLog->setContextJudgeName(QString::fromStdString(gameState->getSpectators().value(id).name()));
} }
} }
@ -164,7 +167,8 @@ void GameEventHandler::processGameEventContainer(const GameEventContainer &cont,
} }
} }
} }
messageLog->containerProcessingDone(); emit containerProcessingDone();
// messageLog->containerProcessingDone();
} }
void GameEventHandler::handleNextTurn() void GameEventHandler::handleNextTurn()
@ -218,14 +222,15 @@ void GameEventHandler::eventSpectatorSay(const Event_GameSay &event,
const GameEventContext & /*context*/) const GameEventContext & /*context*/)
{ {
const ServerInfo_User &userInfo = gameState->getSpectators().value(eventPlayerId); const ServerInfo_User &userInfo = gameState->getSpectators().value(eventPlayerId);
messageLog->logSpectatorSay(userInfo, QString::fromStdString(event.message())); emit logSpectatorSay(userInfo, QString::fromStdString(event.message()));
// messageLog->logSpectatorSay(userInfo, QString::fromStdString(event.message()));
} }
void GameEventHandler::eventSpectatorLeave(const Event_Leave &event, void GameEventHandler::eventSpectatorLeave(const Event_Leave &event,
int eventPlayerId, int eventPlayerId,
const GameEventContext & /*context*/) const GameEventContext & /*context*/)
{ {
messageLog->logLeaveSpectator(gameState->getSpectatorName(eventPlayerId), getLeaveReason(event.reason())); emit logSpectatorLeave(gameState->getSpectatorName(eventPlayerId), getLeaveReason(event.reason()));
gameState->removeSpectator(eventPlayerId); gameState->removeSpectator(eventPlayerId);
@ -257,7 +262,7 @@ void GameEventHandler::eventGameStateChanged(const Event_GameStateChanged &event
if (player->getLocal()) { if (player->getLocal()) {
emit localPlayerDeckSelected(player, playerId, playerInfo); emit localPlayerDeckSelected(player, playerId, playerInfo);
} else { } else {
if (!gameState->getGameInfo().share_decklists_on_load()) { if (!game->getGameMetaInfo()->proto().share_decklists_on_load()) {
continue; continue;
} }
@ -273,17 +278,18 @@ void GameEventHandler::eventGameStateChanged(const Event_GameStateChanged &event
gameState->setGameTime(event.seconds_elapsed()); gameState->setGameTime(event.seconds_elapsed());
if (event.game_started() && !gameState->getGameInfo().started()) { if (event.game_started() && !game->getGameMetaInfo()->started()) {
gameState->setResuming(!gameState->isGameStateKnown()); gameState->setResuming(!gameState->isGameStateKnown());
gameState->setStarted(event.game_started()); game->getGameMetaInfo()->setStarted(event.game_started());
if (gameState->isGameStateKnown()) if (gameState->isGameStateKnown())
messageLog->logGameStart(); emit logGameStart();
// messageLog->logGameStart();
gameState->setActivePlayer(event.active_player_id()); gameState->setActivePlayer(event.active_player_id());
gameState->setCurrentPhase(event.active_phase()); gameState->setCurrentPhase(event.active_phase());
} else if (!event.game_started() && gameState->getGameInfo().started()) { } else if (!event.game_started() && game->getGameMetaInfo()->started()) {
gameState->setCurrentPhase(-1); gameState->setCurrentPhase(-1);
gameState->setActivePlayer(-1); gameState->setActivePlayer(-1);
gameState->setStarted(false); game->getGameMetaInfo()->setStarted(false);
emit gameStopped(); emit gameStopped();
} }
gameState->setGameStateKnown(true); gameState->setGameStateKnown(true);
@ -320,14 +326,19 @@ void GameEventHandler::eventPlayerPropertiesChanged(const Event_PlayerProperties
bool ready = prop.ready_start(); bool ready = prop.ready_start();
if (player->getLocal()) if (player->getLocal())
emit localPlayerReadyStateChanged(player->getId(), ready); emit localPlayerReadyStateChanged(player->getId(), ready);
if (ready) if (ready) {
messageLog->logReadyStart(player); emit logReadyStart();
else // messageLog->logReadyStart(player);
messageLog->logNotReadyStart(player); } else {
emit logNotReadyStart();
// emit logNotReadyStart(player);
// messageLog->logNotReadyStart(player);
}
break; break;
} }
case GameEventContext::CONCEDE: { case GameEventContext::CONCEDE: {
messageLog->logConcede(player); emit playerConceded();
// messageLog->logConcede(player);
player->setConceded(true); player->setConceded(true);
QMapIterator<int, Player *> playerIterator(gameState->getPlayers()); QMapIterator<int, Player *> playerIterator(gameState->getPlayers());
@ -337,7 +348,8 @@ void GameEventHandler::eventPlayerPropertiesChanged(const Event_PlayerProperties
break; break;
} }
case GameEventContext::UNCONCEDE: { case GameEventContext::UNCONCEDE: {
messageLog->logUnconcede(player); emit playerUnconceded();
// messageLog->logUnconcede(player);
player->setConceded(false); player->setConceded(false);
QMapIterator<int, Player *> playerIterator(gameState->getPlayers()); QMapIterator<int, Player *> playerIterator(gameState->getPlayers());
@ -348,9 +360,10 @@ void GameEventHandler::eventPlayerPropertiesChanged(const Event_PlayerProperties
} }
case GameEventContext::DECK_SELECT: { case GameEventContext::DECK_SELECT: {
Context_DeckSelect deckSelect = context.GetExtension(Context_DeckSelect::ext); Context_DeckSelect deckSelect = context.GetExtension(Context_DeckSelect::ext);
messageLog->logDeckSelect(player, QString::fromStdString(deckSelect.deck_hash()), emit logDeckSelect();
deckSelect.sideboard_size()); /*messageLog->logDeckSelect(player, QString::fromStdString(deckSelect.deck_hash()),
if (gameState->getGameInfo().share_decklists_on_load() && deckSelect.has_deck_list() && deckSelect.sideboard_size());*/
if (game->getGameMetaInfo()->proto().share_decklists_on_load() && deckSelect.has_deck_list() &&
eventPlayerId != gameState->getLocalPlayerId()) { eventPlayerId != gameState->getLocalPlayerId()) {
emit remotePlayerDeckSelected(QString::fromStdString(deckSelect.deck_list()), eventPlayerId, emit remotePlayerDeckSelected(QString::fromStdString(deckSelect.deck_list()), eventPlayerId,
player->getName()); player->getName());
@ -361,11 +374,13 @@ void GameEventHandler::eventPlayerPropertiesChanged(const Event_PlayerProperties
if (player->getLocal()) { if (player->getLocal()) {
emit localPlayerSideboardLocked(player->getId(), prop.sideboard_locked()); emit localPlayerSideboardLocked(player->getId(), prop.sideboard_locked());
} }
messageLog->logSetSideboardLock(player, prop.sideboard_locked()); emit logSideboardLockSet();
// messageLog->logSetSideboardLock(player, prop.sideboard_locked());
break; break;
} }
case GameEventContext::CONNECTION_STATE_CHANGED: { case GameEventContext::CONNECTION_STATE_CHANGED: {
messageLog->logConnectionStateChanged(player, prop.ping_seconds() != -1); // messageLog->logConnectionStateChanged(player, prop.ping_seconds() != -1);
emit logConnectionStateChanged();
break; break;
} }
default:; default:;
@ -384,10 +399,11 @@ void GameEventHandler::eventJoin(const Event_Join &event, int /*eventPlayerId*/,
if (playerInfo.spectator()) { if (playerInfo.spectator()) {
gameState->addSpectator(playerId, playerInfo); gameState->addSpectator(playerId, playerInfo);
messageLog->logJoinSpectator(playerName); // messageLog->logJoinSpectator(playerName);
emit logJoinSpectator();
} else { } else {
Player *newPlayer = gameState->addPlayer(playerId, playerInfo.user_info(), game); Player *newPlayer = gameState->addPlayer(playerId, playerInfo.user_info(), game);
messageLog->logJoin(newPlayer); emit logJoinPlayer(newPlayer);
} }
// playerListWidget->addPlayer(playerInfo); // playerListWidget->addPlayer(playerInfo);
game->emitUserEvent(); game->emitUserEvent();
@ -419,7 +435,7 @@ void GameEventHandler::eventLeave(const Event_Leave &event, int eventPlayerId, c
emit playerLeft(player); emit playerLeft(player);
messageLog->logLeave(player, getLeaveReason(event.reason())); emit logLeave(player, getLeaveReason(event.reason()));
gameState->removePlayer(eventPlayerId); gameState->removePlayer(eventPlayerId);
@ -440,7 +456,9 @@ void GameEventHandler::eventKicked(const Event_Kicked & /*event*/,
{ {
emit gameClosed(); emit gameClosed();
messageLog->logKicked(); emit logKicked();
// messageLog->logKicked();
emit playerKicked(); emit playerKicked();
@ -455,7 +473,7 @@ void GameEventHandler::eventReverseTurn(const Event_ReverseTurn &event,
if (!player) if (!player)
return; return;
messageLog->logReverseTurn(player, event.reversed()); emit logTurnReversed(player, event.reversed());
} }
void GameEventHandler::eventGameHostChanged(const Event_GameHostChanged & /*event*/, void GameEventHandler::eventGameHostChanged(const Event_GameHostChanged & /*event*/,
@ -469,10 +487,11 @@ void GameEventHandler::eventGameClosed(const Event_GameClosed & /*event*/,
int /*eventPlayerId*/, int /*eventPlayerId*/,
const GameEventContext & /*context*/) const GameEventContext & /*context*/)
{ {
gameState->setStarted(false); game->getGameMetaInfo()->setStarted(false);
gameState->setGameClosed(true); gameState->setGameClosed(true);
emit gameClosed(); emit gameClosed();
messageLog->logGameClosed(); emit logGameClosed();
// messageLog->logGameClosed();
game->emitUserEvent(); game->emitUserEvent();
} }
@ -484,7 +503,8 @@ void GameEventHandler::eventSetActivePlayer(const Event_SetActivePlayer &event,
Player *player = gameState->getPlayer(event.active_player_id()); Player *player = gameState->getPlayer(event.active_player_id());
if (!player) if (!player)
return; return;
messageLog->logSetActivePlayer(player); emit logActivePlayer();
// messageLog->logSetActivePlayer(player);
game->emitUserEvent(); game->emitUserEvent();
} }
@ -493,8 +513,10 @@ void GameEventHandler::eventSetActivePhase(const Event_SetActivePhase &event,
const GameEventContext & /*context*/) const GameEventContext & /*context*/)
{ {
const int phase = event.phase(); const int phase = event.phase();
if (gameState->getCurrentPhase() != phase) if (gameState->getCurrentPhase() != phase) {
messageLog->logSetActivePhase(phase); emit logActivePhaseChanged();
}
// messageLog->logSetActivePhase(phase);
gameState->setCurrentPhase(phase); gameState->setCurrentPhase(phase);
game->emitUserEvent(); game->emitUserEvent();
} }

View file

@ -39,10 +39,9 @@ class GameEventHandler : public QObject
private: private:
TabGame *game; TabGame *game;
GameState *gameState; GameState *gameState;
MessageLogWidget *messageLog;
public: public:
GameEventHandler(TabGame *game, MessageLogWidget *messageLog); GameEventHandler(TabGame *game);
void handleNextTurn(); void handleNextTurn();
void handleReverseTurn(); void handleReverseTurn();
@ -95,6 +94,28 @@ signals:
void gameClosed(); void gameClosed();
void playerLeft(Player *leavingPlayer); void playerLeft(Player *leavingPlayer);
void playerKicked(); void playerKicked();
void gameFlooded();
void containerProcessingStarted(GameEventContext context);
void setContextJudgeName();
void containerProcessingDone();
void logSpectatorSay(ServerInfo_User userInfo, QString message);
void logSpectatorLeave(QString name, QString reason);
void logGameStart();
void logReadyStart();
void logNotReadyStart();
void playerConceded();
void playerUnconceded();
void logDeckSelect();
void logSideboardLockSet();
void logConnectionStateChanged();
void logJoinSpectator();
void logJoinPlayer(Player *player);
void logLeave(Player *player, QString reason);
void logKicked();
void logTurnReversed(Player *player, bool reversed);
void logGameClosed();
void logActivePlayer();
void logActivePhaseChanged();
}; };
#endif // COCKATRICE_GAME_EVENT_HANDLER_H #endif // COCKATRICE_GAME_EVENT_HANDLER_H

View file

@ -0,0 +1 @@
#include "game_meta_info.h"

View file

@ -0,0 +1,107 @@
#ifndef GAME_META_INFO_H
#define GAME_META_INFO_H
#include "pb/serverinfo_game.pb.h"
#include <QMap>
#include <QObject>
// Translation layer class to expose protobuf safely and hook it up to Qt Signals.
// This class de-couples the domain object (i.e. the GameMetaInfo) from the network object.
// If the network object changes, only this class needs to be adjusted.
class GameMetaInfo : public QObject
{
Q_OBJECT
public:
explicit GameMetaInfo(QObject *parent = nullptr) : QObject(parent)
{
}
QMap<int, QString> roomGameTypes;
// Populate from protobuf (e.g., after network message)
void setFromProto(const ServerInfo_Game &gi)
{
gameInfo_.CopyFrom(gi);
}
const ServerInfo_Game &proto() const
{
return gameInfo_;
}
// High-level getters that avoid exposing protobuf directly
int gameId() const
{
return gameInfo_.game_id();
}
int maxPlayers() const
{
return gameInfo_.max_players();
}
QString description() const
{
return QString::fromStdString(gameInfo_.description());
}
bool started() const
{
return gameInfo_.started();
}
bool spectatorsOmniscient() const
{
return gameInfo_.spectators_omniscient();
}
bool spectatorsCanChat() const
{
return gameInfo_.spectators_can_chat();
}
int gameTypesSize() const
{
return gameInfo_.game_types_size();
}
int gameTypeIdAt(int index) const
{
return gameInfo_.game_types(index);
}
QMap<int, QString> getRoomGameTypes() const
{
return roomGameTypes;
}
void setRoomGameTypes(QMap<int, QString> _roomGameTypes)
{
roomGameTypes = _roomGameTypes;
}
QString findRoomGameType(int index)
{
return roomGameTypes.find(gameInfo_.game_types(index)).value();
}
public slots:
void setStarted(bool s)
{
if (gameInfo_.started() == s)
return;
gameInfo_.set_started(s);
emit startedChanged(s);
}
void setSpectatorsOmniscient(bool v)
{
if (gameInfo_.spectators_omniscient() == v)
return;
gameInfo_.set_spectators_omniscient(v);
emit spectatorsOmniscienceChanged(v);
}
signals:
void startedChanged(bool started);
void spectatorsOmniscienceChanged(bool omniscient);
private:
ServerInfo_Game gameInfo_;
};
#endif // GAME_META_INFO_H

View file

@ -5,7 +5,6 @@
#include "../server/abstract_client.h" #include "../server/abstract_client.h"
#include "pb/serverinfo_game.pb.h" #include "pb/serverinfo_game.pb.h"
#include "pb/serverinfo_playerproperties.pb.h" #include "pb/serverinfo_playerproperties.pb.h"
#include "player/player.h"
#include <QObject> #include <QObject>
@ -39,11 +38,6 @@ public:
return players.size(); return players.size();
} }
int getMaxPlayerCount() const
{
return gameInfo.max_players();
}
const QMap<int, ServerInfo_User> &getSpectators() const const QMap<int, ServerInfo_User> &getSpectators() const
{ {
return spectators; return spectators;
@ -159,46 +153,16 @@ public:
return isLocalGame; return isLocalGame;
} }
int getGameId() const
{
return gameInfo.game_id();
}
QString getGameDescription() const
{
return gameInfo.description().c_str();
}
bool isSpectator() const bool isSpectator() const
{ {
return spectator; return spectator;
} }
bool isSpectatorsOmniscient() const
{
return gameInfo.spectators_omniscient();
}
bool canSpectatorsChat() const
{
return gameInfo.spectators_can_chat();
}
bool isResuming() const bool isResuming() const
{ {
return resuming; return resuming;
} }
void setStarted(bool _started)
{
gameInfo.set_started(_started);
if (_started) {
emit gameStarted(resuming);
} else {
emit gameStopped();
}
}
void setResuming(bool _resuming) void setResuming(bool _resuming)
{ {
resuming = _resuming; resuming = _resuming;
@ -237,41 +201,6 @@ public:
void startGameTimer(); void startGameTimer();
ServerInfo_Game getGameInfo() const
{
return gameInfo;
}
void setGameInfo(ServerInfo_Game _gameInfo)
{
gameInfo.CopyFrom(_gameInfo);
}
QMap<int, QString> getRoomGameTypes() const
{
return roomGameTypes;
}
void setRoomGameTypes(QMap<int, QString> _roomGameTypes)
{
roomGameTypes = _roomGameTypes;
}
int getGameTypesSize() const
{
return gameInfo.game_types_size();
}
QString findRoomGameType(int index)
{
return roomGameTypes.find(gameInfo.game_types(index)).value();
}
void setSpectatorsOmniscient(bool spectatorsOmniscient)
{
gameInfo.set_spectators_omniscient(spectatorsOmniscient);
}
void setGameStateKnown(bool known) void setGameStateKnown(bool known)
{ {
gameStateKnown = known; gameStateKnown = known;
@ -293,8 +222,6 @@ public slots:
private: private:
QTimer *gameTimer; QTimer *gameTimer;
int secondsElapsed; int secondsElapsed;
ServerInfo_Game gameInfo;
QMap<int, QString> roomGameTypes;
int hostId; int hostId;
int localPlayerId; int localPlayerId;
const bool isLocalGame; const bool isLocalGame;

View file

@ -153,7 +153,7 @@ Player::Player(const ServerInfo_User &info, int _id, bool _local, bool _judge, T
hand = addZone( hand = addZone(
new HandZone(this, new HandZone(this,
_local || _judge || _local || _judge ||
(_parent->getGameState()->isSpectator() && _parent->getGameState()->isSpectatorsOmniscient()), (_parent->getGameState()->isSpectator() && _parent->getGameMetaInfo()->spectatorsOmniscient()),
(int)table->boundingRect().height(), this)); (int)table->boundingRect().height(), this));
connect(hand, &HandZone::cardCountChanged, handCounter, &HandCounter::updateNumber); connect(hand, &HandZone::cardCountChanged, handCounter, &HandCounter::updateNumber);
connect(handCounter, &HandCounter::showContextMenu, hand, &HandZone::showContextMenu); connect(handCounter, &HandCounter::showContextMenu, hand, &HandZone::showContextMenu);
@ -2787,7 +2787,7 @@ void Player::processPlayerInfo(const ServerInfo_Player &info)
case ServerInfo_Zone::PrivateZone: case ServerInfo_Zone::PrivateZone:
contentsKnown = contentsKnown =
local || judge || local || judge ||
(game->getGameState()->isSpectator() && game->getGameState()->isSpectatorsOmniscient()); (game->getGameState()->isSpectator() && game->getGameMetaInfo()->spectatorsOmniscient());
break; break;
case ServerInfo_Zone::PublicZone: case ServerInfo_Zone::PublicZone:

View file

@ -800,7 +800,8 @@ void MessageLogWidget::connectToPlayer(Player *player)
connect(player, &Player::logAttachCard, this, &MessageLogWidget::logAttachCard); connect(player, &Player::logAttachCard, this, &MessageLogWidget::logAttachCard);
connect(player, &Player::logUnattachCard, this, &MessageLogWidget::logUnattachCard); connect(player, &Player::logUnattachCard, this, &MessageLogWidget::logUnattachCard);
connect(player, &Player::logDumpZone, this, &MessageLogWidget::logDumpZone); connect(player, &Player::logDumpZone, this, &MessageLogWidget::logDumpZone);
connect(player, &Player::logDrawCards, this, &MessageLogWidget::logDrawCards); // TODO: Reconnect this
// connect(player, &Player::AlogDrawCards, this, &MessageLogWidget::logDrawCards);
connect(player, &Player::logUndoDraw, this, &MessageLogWidget::logUndoDraw); connect(player, &Player::logUndoDraw, this, &MessageLogWidget::logUndoDraw);
connect(player, &Player::logRevealCards, this, &MessageLogWidget::logRevealCards); connect(player, &Player::logRevealCards, this, &MessageLogWidget::logRevealCards);
connect(player, &Player::logAlwaysRevealTopCard, this, &MessageLogWidget::logAlwaysRevealTopCard); connect(player, &Player::logAlwaysRevealTopCard, this, &MessageLogWidget::logAlwaysRevealTopCard);