mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-04-27 07:48:01 -07:00
Move game state and event handling out of tab_game and into separate classes (#6090)
* Move game state and event handling out of tab_game and into separate classes. Took 6 hours 38 minutes Took 23 seconds * Meta Info Took 14 hours 36 minutes * Properly respond to game started again. Took 49 minutes * Hook up the message log widgets to game events again. Took 33 minutes Took 7 seconds * Lint. Took 4 minutes * Hook up playerListWidget. Took 1 hour 2 minutes Took 10 seconds * Hook up playerListWidget properly. Took 1 hour 17 minutes * Fix regressions. Took 17 minutes Took 9 seconds * Log the local player joining too. Took 2 minutes * Connect some player signals unrelated to this refactor again. Took 5 minutes --------- Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
This commit is contained in:
parent
5c16f0d027
commit
b8e545bfa4
18 changed files with 1482 additions and 788 deletions
|
|
@ -207,8 +207,11 @@ set(cockatrice_SOURCES
|
|||
src/game/filters/filter_tree.cpp
|
||||
src/game/filters/filter_tree_model.cpp
|
||||
src/game/filters/syntax_help.cpp
|
||||
src/game/game_event_handler.cpp
|
||||
src/game/game_meta_info.cpp
|
||||
src/game/game_scene.cpp
|
||||
src/game/game_selector.cpp
|
||||
src/game/game_state.cpp
|
||||
src/game/game_view.cpp
|
||||
src/game/games_model.cpp
|
||||
src/game/hand_counter.cpp
|
||||
|
|
|
|||
|
|
@ -95,7 +95,8 @@ ReplayManager::ReplayManager(TabGame *parent, GameReplay *_replay)
|
|||
|
||||
void ReplayManager::replayNextEvent(Player::EventProcessingOptions options)
|
||||
{
|
||||
game->processGameEventContainer(replay->event_list(timelineWidget->getCurrentEvent()), nullptr, options);
|
||||
game->getGameEventHandler()->processGameEventContainer(replay->event_list(timelineWidget->getCurrentEvent()),
|
||||
nullptr, options);
|
||||
}
|
||||
|
||||
void ReplayManager::replayFinished()
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -2,17 +2,20 @@
|
|||
#define TAB_GAME_H
|
||||
|
||||
#include "../../client/tearoff_menu.h"
|
||||
#include "../../game/game_event_handler.h"
|
||||
#include "../../game/game_meta_info.h"
|
||||
#include "../../game/game_state.h"
|
||||
#include "../../game/player/player.h"
|
||||
#include "../replay_manager.h"
|
||||
#include "../ui/widgets/visual_deck_storage/visual_deck_storage_widget.h"
|
||||
#include "pb/event_leave.pb.h"
|
||||
#include "pb/serverinfo_game.pb.h"
|
||||
#include "tab.h"
|
||||
|
||||
#include <QCompleter>
|
||||
#include <QLoggingCategory>
|
||||
#include <QMap>
|
||||
|
||||
class ServerInfo_PlayerProperties;
|
||||
class TabbedDeckViewContainer;
|
||||
inline Q_LOGGING_CATEGORY(TabGameLog, "tab_game");
|
||||
|
||||
|
|
@ -24,7 +27,6 @@ class GameView;
|
|||
class GameScene;
|
||||
class ReplayManager;
|
||||
class CardInfoFrameWidget;
|
||||
class MessageLogWidget;
|
||||
class QTimer;
|
||||
class QSplitter;
|
||||
class QLabel;
|
||||
|
|
@ -35,25 +37,6 @@ class ZoneViewWidget;
|
|||
class PhasesToolbar;
|
||||
class PlayerListWidget;
|
||||
class ReplayTimelineWidget;
|
||||
class Response;
|
||||
class GameEventContainer;
|
||||
class GameEventContext;
|
||||
class GameCommand;
|
||||
class CommandContainer;
|
||||
class Event_GameJoined;
|
||||
class Event_GameStateChanged;
|
||||
class Event_PlayerPropertiesChanged;
|
||||
class Event_Join;
|
||||
class Event_Leave;
|
||||
class Event_GameHostChanged;
|
||||
class Event_GameClosed;
|
||||
class Event_GameStart;
|
||||
class Event_SetActivePlayer;
|
||||
class Event_SetActivePhase;
|
||||
class Event_Ping;
|
||||
class Event_GameSay;
|
||||
class Event_Kicked;
|
||||
class Event_ReverseTurn;
|
||||
class CardZone;
|
||||
class AbstractCardItem;
|
||||
class CardItem;
|
||||
|
|
@ -61,8 +44,6 @@ class DeckLoader;
|
|||
class QVBoxLayout;
|
||||
class QHBoxLayout;
|
||||
class GameReplay;
|
||||
class ServerInfo_User;
|
||||
class PendingCommand;
|
||||
class LineEditCompleter;
|
||||
class QDockWidget;
|
||||
class QStackedWidget;
|
||||
|
|
@ -71,26 +52,11 @@ class TabGame : public Tab
|
|||
{
|
||||
Q_OBJECT
|
||||
private:
|
||||
QTimer *gameTimer;
|
||||
int secondsElapsed;
|
||||
GameMetaInfo *gameMetaInfo;
|
||||
GameState *gameState;
|
||||
GameEventHandler *gameEventHandler;
|
||||
const UserListProxy *userListProxy;
|
||||
QList<AbstractClient *> clients;
|
||||
ServerInfo_Game gameInfo;
|
||||
QMap<int, QString> roomGameTypes;
|
||||
int hostId;
|
||||
int localPlayerId;
|
||||
const bool isLocalGame;
|
||||
bool spectator;
|
||||
bool judge;
|
||||
QMap<int, Player *> players;
|
||||
QMap<int, ServerInfo_User> spectators;
|
||||
bool gameStateKnown;
|
||||
bool resuming;
|
||||
QStringList phasesList;
|
||||
int currentPhase;
|
||||
int activePlayer;
|
||||
CardItem *activeCard;
|
||||
bool gameClosed;
|
||||
ReplayManager *replayManager;
|
||||
QStringList gameTypes;
|
||||
QCompleter *completer;
|
||||
|
|
@ -121,34 +87,22 @@ private:
|
|||
QList<QAction *> phaseActions;
|
||||
QAction *aCardMenu;
|
||||
|
||||
Player *addPlayer(int playerId, const ServerInfo_User &info);
|
||||
|
||||
bool isMainPlayerConceded() const;
|
||||
Player *addPlayer(Player *newPlayer);
|
||||
void addLocalPlayer(Player *newPlayer, int playerId);
|
||||
void processRemotePlayerDeckSelect(QString deckList, int playerId, QString playerName);
|
||||
void processMultipleRemotePlayerDeckSelect(QVector<QPair<int, QPair<QString, QString>>> playerIdDeckMap);
|
||||
void processLocalPlayerDeckSelect(Player *localPlayer, int playerId, ServerInfo_Player playerInfo);
|
||||
void loadDeckForLocalPlayer(Player *localPlayer, int playerId, ServerInfo_Player playerInfo);
|
||||
void processLocalPlayerReady(int playerId, ServerInfo_Player playerInfo);
|
||||
void createZoneForPlayer(Player *newPlayer, int playerId);
|
||||
|
||||
void startGame(bool resuming);
|
||||
void stopGame();
|
||||
void closeGame();
|
||||
bool leaveGame();
|
||||
|
||||
void eventSpectatorSay(const Event_GameSay &event, int eventPlayerId, const GameEventContext &context);
|
||||
void eventSpectatorLeave(const Event_Leave &event, int eventPlayerId, const GameEventContext &context);
|
||||
|
||||
void eventGameStateChanged(const Event_GameStateChanged &event, int eventPlayerId, const GameEventContext &context);
|
||||
void eventPlayerPropertiesChanged(const Event_PlayerPropertiesChanged &event,
|
||||
int eventPlayerId,
|
||||
const GameEventContext &context);
|
||||
void eventJoin(const Event_Join &event, int eventPlayerId, const GameEventContext &context);
|
||||
void eventLeave(const Event_Leave &event, int eventPlayerId, const GameEventContext &context);
|
||||
void eventKicked(const Event_Kicked &event, int eventPlayerId, const GameEventContext &context);
|
||||
void eventGameHostChanged(const Event_GameHostChanged &event, int eventPlayerId, const GameEventContext &context);
|
||||
void eventGameClosed(const Event_GameClosed &event, int eventPlayerId, const GameEventContext &context);
|
||||
Player *setActivePlayer(int id);
|
||||
void eventSetActivePlayer(const Event_SetActivePlayer &event, int eventPlayerId, const GameEventContext &context);
|
||||
void setActivePhase(int phase);
|
||||
void eventSetActivePhase(const Event_SetActivePhase &event, int eventPlayerId, const GameEventContext &context);
|
||||
void eventPing(const Event_Ping &event, int eventPlayerId, const GameEventContext &context);
|
||||
void eventReverseTurn(const Event_ReverseTurn &event, int eventPlayerId, const GameEventContext & /*context*/);
|
||||
void emitUserEvent();
|
||||
void createMenuItems();
|
||||
void createReplayMenuItems();
|
||||
void createViewMenuItems();
|
||||
|
|
@ -158,7 +112,6 @@ private:
|
|||
void createPlayAreaWidget(bool bReplay = false);
|
||||
void createDeckViewContainerWidget(bool bReplay = false);
|
||||
void createReplayDock(GameReplay *replay);
|
||||
QString getLeaveReason(Event_Leave::LeaveReason reason);
|
||||
signals:
|
||||
void gameClosing(TabGame *tab);
|
||||
void playerAdded(Player *player);
|
||||
|
|
@ -169,8 +122,15 @@ signals:
|
|||
void openDeckEditor(const DeckLoader *deck);
|
||||
void notIdle();
|
||||
|
||||
void playerConceded();
|
||||
void playerUnconceded();
|
||||
void phaseChanged(int phase);
|
||||
void gameLeft();
|
||||
void chatMessageSent(QString chatMessage);
|
||||
void turnAdvanced();
|
||||
void arrowDeletionRequested(int arrowId);
|
||||
|
||||
private slots:
|
||||
void incrementGameTime();
|
||||
void adminLockChanged(bool lock);
|
||||
void newCardAdded(AbstractCardItem *card);
|
||||
void setCardMenu(QMenu *menu);
|
||||
|
|
@ -184,17 +144,17 @@ private slots:
|
|||
void actPhaseAction();
|
||||
void actNextPhase();
|
||||
void actNextPhaseAction();
|
||||
void actNextTurn();
|
||||
void actReverseTurn();
|
||||
|
||||
void addMentionTag(const QString &value);
|
||||
void linkCardToChat(const QString &cardName);
|
||||
void commandFinished(const Response &response);
|
||||
|
||||
void refreshShortcuts();
|
||||
|
||||
void loadLayout();
|
||||
void actCompleterChanged();
|
||||
void notifyPlayerJoin(QString playerName);
|
||||
void notifyPlayerKicked();
|
||||
void processPlayerLeave(Player *leavingPlayer);
|
||||
void actResetLayout();
|
||||
void freeDocksSize();
|
||||
|
||||
|
|
@ -212,39 +172,36 @@ public:
|
|||
QList<AbstractClient *> &_clients,
|
||||
const Event_GameJoined &event,
|
||||
const QMap<int, QString> &_roomGameTypes);
|
||||
void connectToGameState();
|
||||
void connectToGameEventHandler();
|
||||
void connectMessageLogToGameEventHandler();
|
||||
void connectPlayerListToGameEventHandler();
|
||||
void loadReplay(GameReplay *replay);
|
||||
TabGame(TabSupervisor *_tabSupervisor, GameReplay *replay);
|
||||
~TabGame() override;
|
||||
void retranslateUi() override;
|
||||
void updatePlayerListDockTitle();
|
||||
bool closeRequest() override;
|
||||
const QMap<int, Player *> &getPlayers() const
|
||||
|
||||
GameMetaInfo *getGameMetaInfo()
|
||||
{
|
||||
return players;
|
||||
return gameMetaInfo;
|
||||
}
|
||||
|
||||
GameState *getGameState() const
|
||||
{
|
||||
return gameState;
|
||||
}
|
||||
|
||||
GameEventHandler *getGameEventHandler() const
|
||||
{
|
||||
return gameEventHandler;
|
||||
}
|
||||
|
||||
CardItem *getCard(int playerId, const QString &zoneName, int cardId) const;
|
||||
bool isHost() const
|
||||
{
|
||||
return hostId == localPlayerId;
|
||||
}
|
||||
bool getIsLocalGame() const
|
||||
{
|
||||
return isLocalGame;
|
||||
}
|
||||
int getGameId() const
|
||||
{
|
||||
return gameInfo.game_id();
|
||||
}
|
||||
|
||||
QString getTabText() const override;
|
||||
bool isSpectator() const
|
||||
{
|
||||
return spectator;
|
||||
}
|
||||
bool isSpectatorsOmniscient() const
|
||||
{
|
||||
return gameInfo.spectators_omniscient();
|
||||
}
|
||||
Player *getActiveLocalPlayer() const;
|
||||
|
||||
AbstractClient *getClientForPlayer(int playerId) const;
|
||||
|
||||
void setActiveCard(CardItem *card);
|
||||
|
|
@ -253,16 +210,16 @@ public:
|
|||
return activeCard;
|
||||
}
|
||||
|
||||
void processGameEventContainer(const GameEventContainer &cont,
|
||||
AbstractClient *client,
|
||||
Player::EventProcessingOptions options);
|
||||
PendingCommand *prepareGameCommand(const ::google::protobuf::Message &cmd);
|
||||
PendingCommand *prepareGameCommand(const QList<const ::google::protobuf::Message *> &cmdList);
|
||||
public slots:
|
||||
void sendGameCommand(PendingCommand *pend, int playerId = -1);
|
||||
void sendGameCommand(const ::google::protobuf::Message &command, int playerId = -1);
|
||||
void viewCardInfo(const CardRef &cardRef = {}) const;
|
||||
void resetChatAndPhase();
|
||||
void updateTimeElapsedLabel(QString newTime);
|
||||
void addPlayerToAutoCompleteList(QString playerName);
|
||||
void removePlayerFromAutoCompleteList(QString playerName);
|
||||
void removeSpectator(int spectatorId, ServerInfo_User spectator);
|
||||
void processLocalPlayerSideboardLocked(int playerId, bool sideboardLocked);
|
||||
void processLocalPlayerReadyStateChanged(int playerId, bool ready);
|
||||
void emitUserEvent();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -707,7 +707,7 @@ void TabSupervisor::gameLeft(TabGame *tab)
|
|||
if (tab == currentWidget())
|
||||
emit setMenu();
|
||||
|
||||
gameTabs.remove(tab->getGameId());
|
||||
gameTabs.remove(tab->getGameMetaInfo()->gameId());
|
||||
removeTab(indexOf(tab));
|
||||
|
||||
if (!localClients.isEmpty())
|
||||
|
|
@ -916,7 +916,7 @@ void TabSupervisor::processGameEventContainer(const GameEventContainer &cont)
|
|||
{
|
||||
TabGame *tab = gameTabs.value(cont.game_id());
|
||||
if (tab)
|
||||
tab->processGameEventContainer(cont, qobject_cast<AbstractClient *>(sender()), {});
|
||||
tab->getGameEventHandler()->processGameEventContainer(cont, qobject_cast<AbstractClient *>(sender()), {});
|
||||
else
|
||||
qCInfo(TabSupervisorLog) << "gameEvent: invalid gameId" << cont.game_id();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -259,10 +259,10 @@ void CardItem::deleteDragItem()
|
|||
|
||||
void CardItem::drawArrow(const QColor &arrowColor)
|
||||
{
|
||||
if (static_cast<TabGame *>(owner->parent())->isSpectator())
|
||||
if (static_cast<TabGame *>(owner->parent())->getGameState()->isSpectator())
|
||||
return;
|
||||
|
||||
Player *arrowOwner = static_cast<TabGame *>(owner->parent())->getActiveLocalPlayer();
|
||||
Player *arrowOwner = static_cast<TabGame *>(owner->parent())->getGameState()->getActiveLocalPlayer();
|
||||
ArrowDragItem *arrow = new ArrowDragItem(arrowOwner, this, arrowColor);
|
||||
scene()->addItem(arrow);
|
||||
arrow->grabMouse();
|
||||
|
|
@ -282,7 +282,7 @@ void CardItem::drawArrow(const QColor &arrowColor)
|
|||
|
||||
void CardItem::drawAttachArrow()
|
||||
{
|
||||
if (static_cast<TabGame *>(owner->parent())->isSpectator())
|
||||
if (static_cast<TabGame *>(owner->parent())->getGameState()->isSpectator())
|
||||
return;
|
||||
|
||||
auto *arrow = new ArrowAttachItem(this);
|
||||
|
|
|
|||
|
|
@ -157,7 +157,7 @@ void DeckViewContainer::switchToDeckSelectView()
|
|||
deckViewLayout->update();
|
||||
|
||||
setVisibility(loadLocalButton, true);
|
||||
setVisibility(loadRemoteButton, !parentGame->getIsLocalGame());
|
||||
setVisibility(loadRemoteButton, !parentGame->getGameState()->getIsLocalGame());
|
||||
setVisibility(loadFromClipboardButton, true);
|
||||
setVisibility(loadFromWebsiteButton, true);
|
||||
setVisibility(unloadDeckButton, false);
|
||||
|
|
@ -190,7 +190,7 @@ void DeckViewContainer::switchToDeckLoadedView()
|
|||
setVisibility(readyStartButton, true);
|
||||
setVisibility(sideboardLockButton, true);
|
||||
|
||||
if (parentGame->isHost()) {
|
||||
if (parentGame->getGameState()->isHost()) {
|
||||
setVisibility(forceStartGameButton, true);
|
||||
}
|
||||
}
|
||||
|
|
@ -287,9 +287,9 @@ void DeckViewContainer::loadDeckFromDeckLoader(const DeckLoader *deck)
|
|||
|
||||
Command_DeckSelect cmd;
|
||||
cmd.set_deck(deckString.toStdString());
|
||||
PendingCommand *pend = parentGame->prepareGameCommand(cmd);
|
||||
PendingCommand *pend = parentGame->getGameEventHandler()->prepareGameCommand(cmd);
|
||||
connect(pend, &PendingCommand::finished, this, &DeckViewContainer::deckSelectFinished);
|
||||
parentGame->sendGameCommand(pend, playerId);
|
||||
parentGame->getGameEventHandler()->sendGameCommand(pend, playerId);
|
||||
}
|
||||
|
||||
void DeckViewContainer::loadRemoteDeck()
|
||||
|
|
@ -298,9 +298,9 @@ void DeckViewContainer::loadRemoteDeck()
|
|||
if (dlg.exec()) {
|
||||
Command_DeckSelect cmd;
|
||||
cmd.set_deck_id(dlg.getDeckId());
|
||||
PendingCommand *pend = parentGame->prepareGameCommand(cmd);
|
||||
PendingCommand *pend = parentGame->getGameEventHandler()->prepareGameCommand(cmd);
|
||||
connect(pend, &PendingCommand::finished, this, &DeckViewContainer::deckSelectFinished);
|
||||
parentGame->sendGameCommand(pend, playerId);
|
||||
parentGame->getGameEventHandler()->sendGameCommand(pend, playerId);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -354,7 +354,7 @@ void DeckViewContainer::forceStart()
|
|||
Command_ReadyStart cmd;
|
||||
cmd.set_force_start(true);
|
||||
cmd.set_ready(true);
|
||||
parentGame->sendGameCommand(cmd, playerId);
|
||||
parentGame->getGameEventHandler()->sendGameCommand(cmd, playerId);
|
||||
}
|
||||
|
||||
void DeckViewContainer::sideboardLockButtonClicked()
|
||||
|
|
@ -362,7 +362,7 @@ void DeckViewContainer::sideboardLockButtonClicked()
|
|||
Command_SetSideboardLock cmd;
|
||||
cmd.set_locked(sideboardLockButton->getState());
|
||||
|
||||
parentGame->sendGameCommand(cmd, playerId);
|
||||
parentGame->getGameEventHandler()->sendGameCommand(cmd, playerId);
|
||||
}
|
||||
|
||||
void DeckViewContainer::sideboardPlanChanged()
|
||||
|
|
@ -371,7 +371,7 @@ void DeckViewContainer::sideboardPlanChanged()
|
|||
const QList<MoveCard_ToZone> &newPlan = deckView->getSideboardPlan();
|
||||
for (const auto &i : newPlan)
|
||||
cmd.add_move_list()->CopyFrom(i);
|
||||
parentGame->sendGameCommand(cmd, playerId);
|
||||
parentGame->getGameEventHandler()->sendGameCommand(cmd, playerId);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -381,7 +381,7 @@ void DeckViewContainer::sendReadyStartCommand(bool ready)
|
|||
{
|
||||
Command_ReadyStart cmd;
|
||||
cmd.set_ready(ready);
|
||||
parentGame->sendGameCommand(cmd, playerId);
|
||||
parentGame->getGameEventHandler()->sendGameCommand(cmd, playerId);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
517
cockatrice/src/game/game_event_handler.cpp
Normal file
517
cockatrice/src/game/game_event_handler.cpp
Normal file
|
|
@ -0,0 +1,517 @@
|
|||
#include "game_event_handler.h"
|
||||
|
||||
#include "../client/tabs/tab_game.h"
|
||||
#include "../server/abstract_client.h"
|
||||
#include "../server/message_log_widget.h"
|
||||
#include "../server/pending_command.h"
|
||||
#include "get_pb_extension.h"
|
||||
#include "pb/command_concede.pb.h"
|
||||
#include "pb/command_delete_arrow.pb.h"
|
||||
#include "pb/command_game_say.pb.h"
|
||||
#include "pb/command_leave_game.pb.h"
|
||||
#include "pb/command_next_turn.pb.h"
|
||||
#include "pb/command_reverse_turn.pb.h"
|
||||
#include "pb/command_set_active_phase.pb.h"
|
||||
#include "pb/context_connection_state_changed.pb.h"
|
||||
#include "pb/context_deck_select.pb.h"
|
||||
#include "pb/context_ping_changed.pb.h"
|
||||
#include "pb/event_game_closed.pb.h"
|
||||
#include "pb/event_game_host_changed.pb.h"
|
||||
#include "pb/event_game_say.pb.h"
|
||||
#include "pb/event_game_state_changed.pb.h"
|
||||
#include "pb/event_join.pb.h"
|
||||
#include "pb/event_kicked.pb.h"
|
||||
#include "pb/event_leave.pb.h"
|
||||
#include "pb/event_player_properties_changed.pb.h"
|
||||
#include "pb/event_reverse_turn.pb.h"
|
||||
#include "pb/event_set_active_phase.pb.h"
|
||||
#include "pb/event_set_active_player.pb.h"
|
||||
#include "pb/game_event_container.pb.h"
|
||||
|
||||
GameEventHandler::GameEventHandler(TabGame *_game) : game(_game), gameState(_game->getGameState())
|
||||
{
|
||||
}
|
||||
|
||||
void GameEventHandler::sendGameCommand(PendingCommand *pend, int playerId)
|
||||
{
|
||||
AbstractClient *client = game->getClientForPlayer(playerId);
|
||||
if (!client)
|
||||
return;
|
||||
|
||||
connect(pend, &PendingCommand::finished, this, &GameEventHandler::commandFinished);
|
||||
client->sendCommand(pend);
|
||||
}
|
||||
|
||||
void GameEventHandler::sendGameCommand(const google::protobuf::Message &command, int playerId)
|
||||
{
|
||||
AbstractClient *client = game->getClientForPlayer(playerId);
|
||||
if (!client)
|
||||
return;
|
||||
|
||||
PendingCommand *pend = prepareGameCommand(command);
|
||||
connect(pend, &PendingCommand::finished, this, &GameEventHandler::commandFinished);
|
||||
client->sendCommand(pend);
|
||||
}
|
||||
|
||||
void GameEventHandler::commandFinished(const Response &response)
|
||||
{
|
||||
if (response.response_code() == Response::RespChatFlood)
|
||||
emit gameFlooded();
|
||||
}
|
||||
|
||||
PendingCommand *GameEventHandler::prepareGameCommand(const ::google::protobuf::Message &cmd)
|
||||
{
|
||||
CommandContainer cont;
|
||||
cont.set_game_id(static_cast<google::protobuf::uint32>(game->getGameMetaInfo()->gameId()));
|
||||
GameCommand *c = cont.add_game_command();
|
||||
c->GetReflection()->MutableMessage(c, cmd.GetDescriptor()->FindExtensionByName("ext"))->CopyFrom(cmd);
|
||||
return new PendingCommand(cont);
|
||||
}
|
||||
|
||||
PendingCommand *GameEventHandler::prepareGameCommand(const QList<const ::google::protobuf::Message *> &cmdList)
|
||||
{
|
||||
CommandContainer cont;
|
||||
cont.set_game_id(static_cast<google::protobuf::uint32>(game->getGameMetaInfo()->gameId()));
|
||||
for (auto i : cmdList) {
|
||||
GameCommand *c = cont.add_game_command();
|
||||
c->GetReflection()->MutableMessage(c, i->GetDescriptor()->FindExtensionByName("ext"))->CopyFrom(*i);
|
||||
delete i;
|
||||
}
|
||||
return new PendingCommand(cont);
|
||||
}
|
||||
|
||||
void GameEventHandler::processGameEventContainer(const GameEventContainer &cont,
|
||||
AbstractClient *client,
|
||||
Player::EventProcessingOptions options)
|
||||
{
|
||||
const GameEventContext &context = cont.context();
|
||||
emit containerProcessingStarted(context);
|
||||
|
||||
const int eventListSize = cont.event_list_size();
|
||||
for (int i = 0; i < eventListSize; ++i) {
|
||||
const GameEvent &event = cont.event_list(i);
|
||||
const int playerId = event.player_id();
|
||||
const auto eventType = static_cast<GameEvent::GameEventType>(getPbExtension(event));
|
||||
|
||||
if (cont.has_forced_by_judge()) {
|
||||
auto id = cont.forced_by_judge();
|
||||
Player *judgep = gameState->getPlayers().value(id, nullptr);
|
||||
if (judgep) {
|
||||
emit setContextJudgeName(judgep->getName());
|
||||
} else if (gameState->getSpectators().contains(id)) {
|
||||
emit setContextJudgeName(QString::fromStdString(gameState->getSpectators().value(id).name()));
|
||||
}
|
||||
}
|
||||
|
||||
if (gameState->getSpectators().contains(playerId)) {
|
||||
switch (eventType) {
|
||||
case GameEvent::GAME_SAY:
|
||||
eventSpectatorSay(event.GetExtension(Event_GameSay::ext), playerId, context);
|
||||
break;
|
||||
case GameEvent::LEAVE:
|
||||
eventSpectatorLeave(event.GetExtension(Event_Leave::ext), playerId, context);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if ((gameState->getClients().size() > 1) && (playerId != -1))
|
||||
if (gameState->getClients().at(playerId) != client)
|
||||
continue;
|
||||
|
||||
switch (eventType) {
|
||||
case GameEvent::GAME_STATE_CHANGED:
|
||||
qInfo() << "Game state changed event";
|
||||
eventGameStateChanged(event.GetExtension(Event_GameStateChanged::ext), playerId, context);
|
||||
break;
|
||||
case GameEvent::PLAYER_PROPERTIES_CHANGED:
|
||||
qInfo() << "player prop event";
|
||||
eventPlayerPropertiesChanged(event.GetExtension(Event_PlayerPropertiesChanged::ext), playerId,
|
||||
context);
|
||||
break;
|
||||
case GameEvent::JOIN:
|
||||
qInfo() << "join event";
|
||||
eventJoin(event.GetExtension(Event_Join::ext), playerId, context);
|
||||
break;
|
||||
case GameEvent::LEAVE:
|
||||
qInfo() << "leave event";
|
||||
eventLeave(event.GetExtension(Event_Leave::ext), playerId, context);
|
||||
break;
|
||||
case GameEvent::KICKED:
|
||||
qInfo() << "kicked event";
|
||||
eventKicked(event.GetExtension(Event_Kicked::ext), playerId, context);
|
||||
break;
|
||||
case GameEvent::GAME_HOST_CHANGED:
|
||||
qInfo() << "host changed event";
|
||||
eventGameHostChanged(event.GetExtension(Event_GameHostChanged::ext), playerId, context);
|
||||
break;
|
||||
case GameEvent::GAME_CLOSED:
|
||||
qInfo() << "game closed event";
|
||||
eventGameClosed(event.GetExtension(Event_GameClosed::ext), playerId, context);
|
||||
break;
|
||||
case GameEvent::SET_ACTIVE_PLAYER:
|
||||
qInfo() << "set active player event";
|
||||
eventSetActivePlayer(event.GetExtension(Event_SetActivePlayer::ext), playerId, context);
|
||||
break;
|
||||
case GameEvent::SET_ACTIVE_PHASE:
|
||||
qInfo() << "set active phase";
|
||||
eventSetActivePhase(event.GetExtension(Event_SetActivePhase::ext), playerId, context);
|
||||
break;
|
||||
case GameEvent::REVERSE_TURN:
|
||||
qInfo() << "reverse turn event";
|
||||
eventReverseTurn(event.GetExtension(Event_ReverseTurn::ext), playerId, context);
|
||||
break;
|
||||
|
||||
default: {
|
||||
Player *player = gameState->getPlayers().value(playerId, 0);
|
||||
if (!player) {
|
||||
// qCWarning(GameEventHandlerLog) << "unhandled game event: invalid player id";
|
||||
break;
|
||||
}
|
||||
player->processGameEvent(eventType, event, context, options);
|
||||
game->emitUserEvent();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
emit containerProcessingDone();
|
||||
}
|
||||
|
||||
void GameEventHandler::handleNextTurn()
|
||||
{
|
||||
sendGameCommand(Command_NextTurn());
|
||||
}
|
||||
|
||||
void GameEventHandler::handleReverseTurn()
|
||||
{
|
||||
sendGameCommand(Command_ReverseTurn());
|
||||
}
|
||||
|
||||
void GameEventHandler::handlePlayerConceded()
|
||||
{
|
||||
sendGameCommand(Command_Concede());
|
||||
}
|
||||
|
||||
void GameEventHandler::handlePlayerUnconceded()
|
||||
{
|
||||
sendGameCommand(Command_Unconcede());
|
||||
}
|
||||
|
||||
void GameEventHandler::handleActivePhaseChanged(int phase)
|
||||
{
|
||||
Command_SetActivePhase cmd;
|
||||
cmd.set_phase(static_cast<google::protobuf::uint32>(phase));
|
||||
sendGameCommand(cmd);
|
||||
}
|
||||
|
||||
void GameEventHandler::handleGameLeft()
|
||||
{
|
||||
sendGameCommand(Command_LeaveGame());
|
||||
}
|
||||
|
||||
void GameEventHandler::handleChatMessageSent(const QString &chatMessage)
|
||||
{
|
||||
Command_GameSay cmd;
|
||||
cmd.set_message(chatMessage.toStdString());
|
||||
sendGameCommand(cmd);
|
||||
}
|
||||
|
||||
void GameEventHandler::handleArrowDeletion(int arrowId)
|
||||
{
|
||||
Command_DeleteArrow cmd;
|
||||
cmd.set_arrow_id(arrowId);
|
||||
sendGameCommand(cmd);
|
||||
}
|
||||
|
||||
void GameEventHandler::eventSpectatorSay(const Event_GameSay &event,
|
||||
int eventPlayerId,
|
||||
const GameEventContext & /*context*/)
|
||||
{
|
||||
const ServerInfo_User &userInfo = gameState->getSpectators().value(eventPlayerId);
|
||||
emit logSpectatorSay(userInfo, QString::fromStdString(event.message()));
|
||||
}
|
||||
|
||||
void GameEventHandler::eventSpectatorLeave(const Event_Leave &event,
|
||||
int eventPlayerId,
|
||||
const GameEventContext & /*context*/)
|
||||
{
|
||||
emit logSpectatorLeave(gameState->getSpectatorName(eventPlayerId), getLeaveReason(event.reason()));
|
||||
|
||||
emit spectatorLeft(eventPlayerId);
|
||||
|
||||
gameState->removeSpectator(eventPlayerId);
|
||||
|
||||
game->emitUserEvent();
|
||||
}
|
||||
|
||||
void GameEventHandler::eventGameStateChanged(const Event_GameStateChanged &event,
|
||||
int /*eventPlayerId*/,
|
||||
const GameEventContext & /*context*/)
|
||||
{
|
||||
const int playerListSize = event.player_list_size();
|
||||
|
||||
QVector<QPair<int, QPair<QString, QString>>> opponentDecksToDisplay;
|
||||
|
||||
for (int i = 0; i < playerListSize; ++i) {
|
||||
const ServerInfo_Player &playerInfo = event.player_list(i);
|
||||
const ServerInfo_PlayerProperties &prop = playerInfo.properties();
|
||||
const int playerId = prop.player_id();
|
||||
QString playerName = "@" + QString::fromStdString(prop.user_info().name());
|
||||
game->addPlayerToAutoCompleteList(playerName);
|
||||
if (prop.spectator()) {
|
||||
gameState->addSpectator(playerId, prop);
|
||||
} else {
|
||||
Player *player = gameState->getPlayers().value(playerId, 0);
|
||||
if (!player) {
|
||||
player = gameState->addPlayer(playerId, prop.user_info(), game);
|
||||
emit playerJoined(prop);
|
||||
emit logJoinPlayer(player);
|
||||
}
|
||||
player->processPlayerInfo(playerInfo);
|
||||
if (player->getLocal()) {
|
||||
emit localPlayerDeckSelected(player, playerId, playerInfo);
|
||||
} else {
|
||||
if (!game->getGameMetaInfo()->proto().share_decklists_on_load()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
opponentDecksToDisplay.append(
|
||||
qMakePair(playerId, qMakePair(playerName, QString::fromStdString(playerInfo.deck_list()))));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
processCardAttachmentsForPlayers(event);
|
||||
|
||||
emit remotePlayersDecksSelected(opponentDecksToDisplay);
|
||||
|
||||
gameState->setGameTime(event.seconds_elapsed());
|
||||
|
||||
if (event.game_started() && !game->getGameMetaInfo()->started()) {
|
||||
gameState->setResuming(!gameState->isGameStateKnown());
|
||||
game->getGameMetaInfo()->setStarted(event.game_started());
|
||||
if (gameState->isGameStateKnown())
|
||||
emit logGameStart();
|
||||
gameState->setActivePlayer(event.active_player_id());
|
||||
gameState->setCurrentPhase(event.active_phase());
|
||||
} else if (!event.game_started() && game->getGameMetaInfo()->started()) {
|
||||
gameState->setCurrentPhase(-1);
|
||||
gameState->setActivePlayer(-1);
|
||||
game->getGameMetaInfo()->setStarted(false);
|
||||
emit gameStopped();
|
||||
}
|
||||
gameState->setGameStateKnown(true);
|
||||
game->emitUserEvent();
|
||||
}
|
||||
|
||||
void GameEventHandler::processCardAttachmentsForPlayers(const Event_GameStateChanged &event)
|
||||
{
|
||||
for (int i = 0; i < event.player_list_size(); ++i) {
|
||||
const ServerInfo_Player &playerInfo = event.player_list(i);
|
||||
const ServerInfo_PlayerProperties &prop = playerInfo.properties();
|
||||
if (!prop.spectator()) {
|
||||
Player *player = gameState->getPlayers().value(prop.player_id(), 0);
|
||||
if (!player)
|
||||
continue;
|
||||
player->processCardAttachment(playerInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GameEventHandler::eventPlayerPropertiesChanged(const Event_PlayerPropertiesChanged &event,
|
||||
int eventPlayerId,
|
||||
const GameEventContext &context)
|
||||
{
|
||||
Player *player = gameState->getPlayers().value(eventPlayerId, 0);
|
||||
if (!player)
|
||||
return;
|
||||
const ServerInfo_PlayerProperties &prop = event.player_properties();
|
||||
emit playerPropertiesChanged(prop, eventPlayerId);
|
||||
|
||||
const auto contextType = static_cast<GameEventContext::ContextType>(getPbExtension(context));
|
||||
switch (contextType) {
|
||||
case GameEventContext::READY_START: {
|
||||
bool ready = prop.ready_start();
|
||||
if (player->getLocal())
|
||||
emit localPlayerReadyStateChanged(player->getId(), ready);
|
||||
if (ready) {
|
||||
emit logReadyStart(player);
|
||||
} else {
|
||||
emit logNotReadyStart(player);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case GameEventContext::CONCEDE: {
|
||||
emit playerConceded(player);
|
||||
player->setConceded(true);
|
||||
|
||||
QMapIterator<int, Player *> playerIterator(gameState->getPlayers());
|
||||
while (playerIterator.hasNext())
|
||||
playerIterator.next().value()->updateZones();
|
||||
|
||||
break;
|
||||
}
|
||||
case GameEventContext::UNCONCEDE: {
|
||||
emit playerUnconceded(player);
|
||||
player->setConceded(false);
|
||||
|
||||
QMapIterator<int, Player *> playerIterator(gameState->getPlayers());
|
||||
while (playerIterator.hasNext())
|
||||
playerIterator.next().value()->updateZones();
|
||||
|
||||
break;
|
||||
}
|
||||
case GameEventContext::DECK_SELECT: {
|
||||
Context_DeckSelect deckSelect = context.GetExtension(Context_DeckSelect::ext);
|
||||
emit logDeckSelect(player, QString::fromStdString(deckSelect.deck_hash()), deckSelect.sideboard_size());
|
||||
if (game->getGameMetaInfo()->proto().share_decklists_on_load() && deckSelect.has_deck_list() &&
|
||||
eventPlayerId != gameState->getLocalPlayerId()) {
|
||||
emit remotePlayerDeckSelected(QString::fromStdString(deckSelect.deck_list()), eventPlayerId,
|
||||
player->getName());
|
||||
}
|
||||
break;
|
||||
}
|
||||
case GameEventContext::SET_SIDEBOARD_LOCK: {
|
||||
if (player->getLocal()) {
|
||||
emit localPlayerSideboardLocked(player->getId(), prop.sideboard_locked());
|
||||
}
|
||||
emit logSideboardLockSet(player, prop.sideboard_locked());
|
||||
break;
|
||||
}
|
||||
case GameEventContext::CONNECTION_STATE_CHANGED: {
|
||||
emit logConnectionStateChanged(player, prop.ping_seconds() != -1);
|
||||
break;
|
||||
}
|
||||
default:;
|
||||
}
|
||||
}
|
||||
|
||||
void GameEventHandler::eventJoin(const Event_Join &event, int /*eventPlayerId*/, const GameEventContext & /*context*/)
|
||||
{
|
||||
const ServerInfo_PlayerProperties &playerInfo = event.player_properties();
|
||||
const int playerId = playerInfo.player_id();
|
||||
QString playerName = QString::fromStdString(playerInfo.user_info().name());
|
||||
game->addPlayerToAutoCompleteList(playerName);
|
||||
|
||||
if (gameState->getPlayers().contains(playerId))
|
||||
return;
|
||||
|
||||
if (playerInfo.spectator()) {
|
||||
gameState->addSpectator(playerId, playerInfo);
|
||||
emit logJoinSpectator(playerName);
|
||||
emit spectatorJoined(playerInfo);
|
||||
} else {
|
||||
Player *newPlayer = gameState->addPlayer(playerId, playerInfo.user_info(), game);
|
||||
emit logJoinPlayer(newPlayer);
|
||||
emit playerJoined(playerInfo);
|
||||
}
|
||||
|
||||
game->emitUserEvent();
|
||||
}
|
||||
|
||||
QString GameEventHandler::getLeaveReason(Event_Leave::LeaveReason reason)
|
||||
{
|
||||
switch (reason) {
|
||||
case Event_Leave::USER_KICKED:
|
||||
return tr("kicked by game host or moderator");
|
||||
break;
|
||||
case Event_Leave::USER_LEFT:
|
||||
return tr("player left the game");
|
||||
break;
|
||||
case Event_Leave::USER_DISCONNECTED:
|
||||
return tr("player disconnected from server");
|
||||
break;
|
||||
case Event_Leave::OTHER:
|
||||
default:
|
||||
return tr("reason unknown");
|
||||
break;
|
||||
}
|
||||
}
|
||||
void GameEventHandler::eventLeave(const Event_Leave &event, int eventPlayerId, const GameEventContext & /*context*/)
|
||||
{
|
||||
Player *player = gameState->getPlayers().value(eventPlayerId, 0);
|
||||
if (!player)
|
||||
return;
|
||||
|
||||
emit playerLeft(eventPlayerId);
|
||||
|
||||
emit logLeave(player, getLeaveReason(event.reason()));
|
||||
|
||||
gameState->removePlayer(eventPlayerId);
|
||||
|
||||
player->clear();
|
||||
player->deleteLater();
|
||||
|
||||
// Rearrange all remaining zones so that attachment relationship updates take place
|
||||
QMapIterator<int, Player *> playerIterator(gameState->getPlayers());
|
||||
while (playerIterator.hasNext())
|
||||
playerIterator.next().value()->updateZones();
|
||||
|
||||
game->emitUserEvent();
|
||||
}
|
||||
|
||||
void GameEventHandler::eventKicked(const Event_Kicked & /*event*/,
|
||||
int /*eventPlayerId*/,
|
||||
const GameEventContext & /*context*/)
|
||||
{
|
||||
emit gameClosed();
|
||||
|
||||
emit logKicked();
|
||||
|
||||
emit playerKicked();
|
||||
|
||||
game->emitUserEvent();
|
||||
}
|
||||
|
||||
void GameEventHandler::eventReverseTurn(const Event_ReverseTurn &event,
|
||||
int eventPlayerId,
|
||||
const GameEventContext & /*context*/)
|
||||
{
|
||||
Player *player = gameState->getPlayers().value(eventPlayerId, 0);
|
||||
if (!player)
|
||||
return;
|
||||
|
||||
emit logTurnReversed(player, event.reversed());
|
||||
}
|
||||
|
||||
void GameEventHandler::eventGameHostChanged(const Event_GameHostChanged & /*event*/,
|
||||
int eventPlayerId,
|
||||
const GameEventContext & /*context*/)
|
||||
{
|
||||
gameState->setHostId(eventPlayerId);
|
||||
}
|
||||
|
||||
void GameEventHandler::eventGameClosed(const Event_GameClosed & /*event*/,
|
||||
int /*eventPlayerId*/,
|
||||
const GameEventContext & /*context*/)
|
||||
{
|
||||
game->getGameMetaInfo()->setStarted(false);
|
||||
gameState->setGameClosed(true);
|
||||
emit gameClosed();
|
||||
emit logGameClosed();
|
||||
game->emitUserEvent();
|
||||
}
|
||||
|
||||
void GameEventHandler::eventSetActivePlayer(const Event_SetActivePlayer &event,
|
||||
int /*eventPlayerId*/,
|
||||
const GameEventContext & /*context*/)
|
||||
{
|
||||
gameState->setActivePlayer(event.active_player_id());
|
||||
Player *player = gameState->getPlayer(event.active_player_id());
|
||||
if (!player)
|
||||
return;
|
||||
emit logActivePlayer(player);
|
||||
game->emitUserEvent();
|
||||
}
|
||||
|
||||
void GameEventHandler::eventSetActivePhase(const Event_SetActivePhase &event,
|
||||
int /*eventPlayerId*/,
|
||||
const GameEventContext & /*context*/)
|
||||
{
|
||||
const int phase = event.phase();
|
||||
if (gameState->getCurrentPhase() != phase) {
|
||||
emit logActivePhaseChanged(phase);
|
||||
}
|
||||
gameState->setCurrentPhase(phase);
|
||||
game->emitUserEvent();
|
||||
}
|
||||
125
cockatrice/src/game/game_event_handler.h
Normal file
125
cockatrice/src/game/game_event_handler.h
Normal file
|
|
@ -0,0 +1,125 @@
|
|||
#ifndef COCKATRICE_GAME_EVENT_HANDLER_H
|
||||
#define COCKATRICE_GAME_EVENT_HANDLER_H
|
||||
|
||||
#include "pb/event_leave.pb.h"
|
||||
#include "pb/serverinfo_player.pb.h"
|
||||
#include "player/player.h"
|
||||
|
||||
#include <QObject>
|
||||
|
||||
class AbstractClient;
|
||||
class TabGame;
|
||||
class Response;
|
||||
class GameEventContainer;
|
||||
class GameEventContext;
|
||||
class GameCommand;
|
||||
class GameState;
|
||||
class MessageLogWidget;
|
||||
class CommandContainer;
|
||||
class Event_GameJoined;
|
||||
class Event_GameStateChanged;
|
||||
class Event_PlayerPropertiesChanged;
|
||||
class Event_Join;
|
||||
class Event_Leave;
|
||||
class Event_GameHostChanged;
|
||||
class Event_GameClosed;
|
||||
class Event_GameStart;
|
||||
class Event_SetActivePlayer;
|
||||
class Event_SetActivePhase;
|
||||
class Event_Ping;
|
||||
class Event_GameSay;
|
||||
class Event_Kicked;
|
||||
class Event_ReverseTurn;
|
||||
class PendingCommand;
|
||||
|
||||
class GameEventHandler : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private:
|
||||
TabGame *game;
|
||||
GameState *gameState;
|
||||
|
||||
public:
|
||||
GameEventHandler(TabGame *game);
|
||||
|
||||
void handleNextTurn();
|
||||
void handleReverseTurn();
|
||||
|
||||
void handlePlayerConceded();
|
||||
void handlePlayerUnconceded();
|
||||
void handleActivePhaseChanged(int phase);
|
||||
void handleGameLeft();
|
||||
void handleChatMessageSent(const QString &chatMessage);
|
||||
void handleArrowDeletion(int arrowId);
|
||||
|
||||
void eventSpectatorSay(const Event_GameSay &event, int eventPlayerId, const GameEventContext &context);
|
||||
void eventSpectatorLeave(const Event_Leave &event, int eventPlayerId, const GameEventContext &context);
|
||||
|
||||
void eventGameStateChanged(const Event_GameStateChanged &event, int eventPlayerId, const GameEventContext &context);
|
||||
void processCardAttachmentsForPlayers(const Event_GameStateChanged &event);
|
||||
void eventPlayerPropertiesChanged(const Event_PlayerPropertiesChanged &event,
|
||||
int eventPlayerId,
|
||||
const GameEventContext &context);
|
||||
void eventJoin(const Event_Join &event, int eventPlayerId, const GameEventContext &context);
|
||||
void eventLeave(const Event_Leave &event, int eventPlayerId, const GameEventContext &context);
|
||||
QString getLeaveReason(Event_Leave::LeaveReason reason);
|
||||
void eventKicked(const Event_Kicked &event, int eventPlayerId, const GameEventContext &context);
|
||||
void eventGameHostChanged(const Event_GameHostChanged &event, int eventPlayerId, const GameEventContext &context);
|
||||
void eventGameClosed(const Event_GameClosed &event, int eventPlayerId, const GameEventContext &context);
|
||||
|
||||
void eventSetActivePlayer(const Event_SetActivePlayer &event, int eventPlayerId, const GameEventContext &context);
|
||||
void eventSetActivePhase(const Event_SetActivePhase &event, int eventPlayerId, const GameEventContext &context);
|
||||
void eventPing(const Event_Ping &event, int eventPlayerId, const GameEventContext &context);
|
||||
void eventReverseTurn(const Event_ReverseTurn &event, int eventPlayerId, const GameEventContext & /*context*/);
|
||||
|
||||
void commandFinished(const Response &response);
|
||||
|
||||
void processGameEventContainer(const GameEventContainer &cont,
|
||||
AbstractClient *client,
|
||||
Player::EventProcessingOptions options);
|
||||
PendingCommand *prepareGameCommand(const ::google::protobuf::Message &cmd);
|
||||
PendingCommand *prepareGameCommand(const QList<const ::google::protobuf::Message *> &cmdList);
|
||||
public slots:
|
||||
void sendGameCommand(PendingCommand *pend, int playerId = -1);
|
||||
void sendGameCommand(const ::google::protobuf::Message &command, int playerId = -1);
|
||||
|
||||
signals:
|
||||
void localPlayerDeckSelected(Player *localPlayer, int playerId, ServerInfo_Player playerInfo);
|
||||
void remotePlayerDeckSelected(QString deckList, int playerId, QString playerName);
|
||||
void remotePlayersDecksSelected(QVector<QPair<int, QPair<QString, QString>>> opponentDecks);
|
||||
void localPlayerSideboardLocked(int playerId, bool sideboardLocked);
|
||||
void localPlayerReadyStateChanged(int playerId, bool ready);
|
||||
void gameStopped();
|
||||
void gameClosed();
|
||||
void playerPropertiesChanged(const ServerInfo_PlayerProperties &prop, int playerId);
|
||||
void playerJoined(const ServerInfo_PlayerProperties &playerInfo);
|
||||
void playerLeft(int leavingPlayerId);
|
||||
void playerKicked();
|
||||
void spectatorJoined(const ServerInfo_PlayerProperties &spectatorInfo);
|
||||
void spectatorLeft(int leavingSpectatorId);
|
||||
void gameFlooded();
|
||||
void containerProcessingStarted(GameEventContext context);
|
||||
void setContextJudgeName(QString judgeName);
|
||||
void containerProcessingDone();
|
||||
void logSpectatorSay(ServerInfo_User userInfo, QString message);
|
||||
void logSpectatorLeave(QString name, QString reason);
|
||||
void logGameStart();
|
||||
void logReadyStart(Player *player);
|
||||
void logNotReadyStart(Player *player);
|
||||
void playerConceded(Player *player);
|
||||
void playerUnconceded(Player *player);
|
||||
void logDeckSelect(Player *player, QString deckHash, int sideboardSize);
|
||||
void logSideboardLockSet(Player *player, bool sideboardLocked);
|
||||
void logConnectionStateChanged(Player *player, bool connected);
|
||||
void logJoinSpectator(QString spectatorName);
|
||||
void logJoinPlayer(Player *player);
|
||||
void logLeave(Player *player, QString reason);
|
||||
void logKicked();
|
||||
void logTurnReversed(Player *player, bool reversed);
|
||||
void logGameClosed();
|
||||
void logActivePlayer(Player *activePlayer);
|
||||
void logActivePhaseChanged(int activePhase);
|
||||
};
|
||||
|
||||
#endif // COCKATRICE_GAME_EVENT_HANDLER_H
|
||||
1
cockatrice/src/game/game_meta_info.cpp
Normal file
1
cockatrice/src/game/game_meta_info.cpp
Normal file
|
|
@ -0,0 +1 @@
|
|||
#include "game_meta_info.h"
|
||||
107
cockatrice/src/game/game_meta_info.h
Normal file
107
cockatrice/src/game/game_meta_info.h
Normal 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
|
||||
44
cockatrice/src/game/game_state.cpp
Normal file
44
cockatrice/src/game/game_state.cpp
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
#include "game_state.h"
|
||||
|
||||
GameState::GameState(int _secondsElapsed,
|
||||
int _hostId,
|
||||
int _localPlayerId,
|
||||
bool _isLocalGame,
|
||||
const QList<AbstractClient *> _clients,
|
||||
bool _spectator,
|
||||
bool _judge,
|
||||
bool _gameStateKnown,
|
||||
bool _resuming,
|
||||
int _currentPhase,
|
||||
bool _gameClosed)
|
||||
: secondsElapsed(_secondsElapsed), hostId(_hostId), localPlayerId(_localPlayerId), isLocalGame(_isLocalGame),
|
||||
clients(_clients), spectator(_spectator), judge(_judge), gameStateKnown(_gameStateKnown), resuming(_resuming),
|
||||
currentPhase(_currentPhase), gameClosed(_gameClosed)
|
||||
{
|
||||
}
|
||||
|
||||
void GameState::incrementGameTime()
|
||||
{
|
||||
setGameTime(++secondsElapsed);
|
||||
}
|
||||
|
||||
void GameState::setGameTime(int _secondsElapsed)
|
||||
{
|
||||
int seconds = _secondsElapsed;
|
||||
int minutes = seconds / 60;
|
||||
seconds -= minutes * 60;
|
||||
int hours = minutes / 60;
|
||||
minutes -= hours * 60;
|
||||
|
||||
emit updateTimeElapsedLabel(QString::number(hours).rightJustified(2, '0') + ":" +
|
||||
QString::number(minutes).rightJustified(2, '0') + ":" +
|
||||
QString::number(seconds).rightJustified(2, '0'));
|
||||
}
|
||||
|
||||
void GameState::startGameTimer()
|
||||
{
|
||||
gameTimer = new QTimer(this);
|
||||
gameTimer->setInterval(1000);
|
||||
connect(gameTimer, &QTimer::timeout, this, &GameState::incrementGameTime);
|
||||
gameTimer->start();
|
||||
}
|
||||
255
cockatrice/src/game/game_state.h
Normal file
255
cockatrice/src/game/game_state.h
Normal file
|
|
@ -0,0 +1,255 @@
|
|||
#ifndef COCKATRICE_GAME_STATE_H
|
||||
#define COCKATRICE_GAME_STATE_H
|
||||
|
||||
#include "../client/tabs/tab_game.h"
|
||||
#include "../server/abstract_client.h"
|
||||
#include "pb/serverinfo_game.pb.h"
|
||||
#include "pb/serverinfo_playerproperties.pb.h"
|
||||
|
||||
#include <QObject>
|
||||
|
||||
class ServerInfo_PlayerProperties;
|
||||
class ServerInfo_User;
|
||||
|
||||
class GameState : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit GameState(int secondsElapsed,
|
||||
int hostId,
|
||||
int localPlayerId,
|
||||
bool isLocalGame,
|
||||
QList<AbstractClient *> clients,
|
||||
bool spectator,
|
||||
bool judge,
|
||||
bool gameStateKnown,
|
||||
bool resuming,
|
||||
int currentPhase,
|
||||
bool gameClosed);
|
||||
|
||||
const QMap<int, Player *> &getPlayers() const
|
||||
{
|
||||
return players;
|
||||
}
|
||||
|
||||
int getPlayerCount() const
|
||||
{
|
||||
return players.size();
|
||||
}
|
||||
|
||||
const QMap<int, ServerInfo_User> &getSpectators() const
|
||||
{
|
||||
return spectators;
|
||||
}
|
||||
|
||||
ServerInfo_User getSpectator(int playerId) const
|
||||
{
|
||||
return spectators.value(playerId);
|
||||
}
|
||||
|
||||
QString getSpectatorName(int spectatorId) const
|
||||
{
|
||||
return QString::fromStdString(spectators.value(spectatorId).name());
|
||||
}
|
||||
|
||||
void addSpectator(int spectatorId, const ServerInfo_PlayerProperties &prop)
|
||||
{
|
||||
if (!spectators.contains(spectatorId)) {
|
||||
spectators.insert(spectatorId, prop.user_info());
|
||||
emit spectatorAdded(prop);
|
||||
}
|
||||
}
|
||||
|
||||
void removeSpectator(int spectatorId)
|
||||
{
|
||||
ServerInfo_User spectatorInfo = spectators.value(spectatorId);
|
||||
spectators.remove(spectatorId);
|
||||
emit spectatorRemoved(spectatorId, spectatorInfo);
|
||||
}
|
||||
|
||||
bool isHost() const
|
||||
{
|
||||
return hostId == localPlayerId;
|
||||
}
|
||||
|
||||
void setHostId(int _hostId)
|
||||
{
|
||||
hostId = _hostId;
|
||||
}
|
||||
|
||||
bool isJudge() const
|
||||
{
|
||||
return judge;
|
||||
}
|
||||
|
||||
int getLocalPlayerId() const
|
||||
{
|
||||
return localPlayerId;
|
||||
}
|
||||
|
||||
QList<AbstractClient *> getClients() const
|
||||
{
|
||||
return clients;
|
||||
}
|
||||
|
||||
bool isLocalPlayer(int playerId) const
|
||||
{
|
||||
return clients.size() > 1 || playerId == getLocalPlayerId();
|
||||
}
|
||||
|
||||
Player *addPlayer(int playerId, const ServerInfo_User &info, TabGame *game)
|
||||
{
|
||||
auto *newPlayer = new Player(info, playerId, isLocalPlayer(playerId), isJudge(), game);
|
||||
// TODO
|
||||
// connect(newPlayer, &Player::openDeckEditor, game, &TabGame::openDeckEditor);
|
||||
players.insert(playerId, newPlayer);
|
||||
emit playerAdded(newPlayer);
|
||||
return newPlayer;
|
||||
}
|
||||
|
||||
void removePlayer(int playerId)
|
||||
{
|
||||
Player *player = getPlayer(playerId);
|
||||
if (!player) {
|
||||
return;
|
||||
}
|
||||
players.remove(playerId);
|
||||
emit playerRemoved(player);
|
||||
}
|
||||
|
||||
Player *getPlayer(int playerId)
|
||||
{
|
||||
Player *player = players.value(playerId, 0);
|
||||
if (!player)
|
||||
return nullptr;
|
||||
return player;
|
||||
}
|
||||
|
||||
Player *getActiveLocalPlayer() const
|
||||
{
|
||||
Player *active = players.value(activePlayer, 0);
|
||||
if (active)
|
||||
if (active->getLocal())
|
||||
return active;
|
||||
|
||||
QMapIterator<int, Player *> playerIterator(players);
|
||||
while (playerIterator.hasNext()) {
|
||||
Player *temp = playerIterator.next().value();
|
||||
if (temp->getLocal())
|
||||
return temp;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void setActivePlayer(int activePlayerId)
|
||||
{
|
||||
activePlayer = activePlayerId;
|
||||
emit activePlayerChanged(activePlayer);
|
||||
}
|
||||
|
||||
bool getIsLocalGame() const
|
||||
{
|
||||
return isLocalGame;
|
||||
}
|
||||
|
||||
bool isSpectator() const
|
||||
{
|
||||
return spectator;
|
||||
}
|
||||
|
||||
bool isResuming() const
|
||||
{
|
||||
return resuming;
|
||||
}
|
||||
|
||||
void setResuming(bool _resuming)
|
||||
{
|
||||
resuming = _resuming;
|
||||
}
|
||||
|
||||
bool isGameStateKnown()
|
||||
{
|
||||
return gameStateKnown;
|
||||
}
|
||||
|
||||
int getCurrentPhase() const
|
||||
{
|
||||
return currentPhase;
|
||||
}
|
||||
|
||||
void setCurrentPhase(int phase)
|
||||
{
|
||||
currentPhase = phase;
|
||||
emit activePhaseChanged(phase);
|
||||
}
|
||||
|
||||
bool isMainPlayerConceded() const
|
||||
{
|
||||
Player *player = players.value(localPlayerId, nullptr);
|
||||
return player && player->getConceded();
|
||||
}
|
||||
|
||||
void setGameClosed(bool closed)
|
||||
{
|
||||
gameClosed = closed;
|
||||
}
|
||||
|
||||
bool isGameClosed() const
|
||||
{
|
||||
return gameClosed;
|
||||
}
|
||||
|
||||
void onStartedChanged(bool _started)
|
||||
{
|
||||
if (_started) {
|
||||
startGameTimer();
|
||||
emit gameStarted(_started);
|
||||
} else {
|
||||
emit gameStopped();
|
||||
}
|
||||
}
|
||||
|
||||
void startGameTimer();
|
||||
|
||||
void setGameStateKnown(bool known)
|
||||
{
|
||||
gameStateKnown = known;
|
||||
}
|
||||
|
||||
signals:
|
||||
void updateTimeElapsedLabel(QString newTime);
|
||||
void playerAdded(Player *player);
|
||||
void playerRemoved(Player *player);
|
||||
void spectatorAdded(ServerInfo_PlayerProperties spectator);
|
||||
void spectatorRemoved(int spectatorId, ServerInfo_User spectator);
|
||||
void gameStarted(bool resuming);
|
||||
void gameStopped();
|
||||
void activePhaseChanged(int activePhase);
|
||||
void activePlayerChanged(int playerId);
|
||||
|
||||
public slots:
|
||||
void incrementGameTime();
|
||||
void setGameTime(int _secondsElapsed);
|
||||
|
||||
private:
|
||||
QTimer *gameTimer;
|
||||
int secondsElapsed;
|
||||
int hostId;
|
||||
int localPlayerId;
|
||||
const bool isLocalGame;
|
||||
QMap<int, Player *> players;
|
||||
QMap<int, ServerInfo_User> spectators;
|
||||
QList<AbstractClient *> clients;
|
||||
bool spectator;
|
||||
bool judge;
|
||||
bool gameStateKnown;
|
||||
bool resuming;
|
||||
QStringList phasesList;
|
||||
int currentPhase;
|
||||
int activePlayer;
|
||||
bool gameClosed;
|
||||
};
|
||||
|
||||
#endif // COCKATRICE_GAME_STATE_H
|
||||
|
|
@ -150,16 +150,19 @@ Player::Player(const ServerInfo_User &info, int _id, bool _local, bool _judge, T
|
|||
|
||||
stack = addZone(new StackZone(this, (int)table->boundingRect().height(), this));
|
||||
|
||||
hand = addZone(new HandZone(this, _local || _judge || (_parent->isSpectator() && _parent->isSpectatorsOmniscient()),
|
||||
(int)table->boundingRect().height(), this));
|
||||
hand = addZone(
|
||||
new HandZone(this,
|
||||
_local || _judge ||
|
||||
(_parent->getGameState()->isSpectator() && _parent->getGameMetaInfo()->spectatorsOmniscient()),
|
||||
(int)table->boundingRect().height(), this));
|
||||
connect(hand, &HandZone::cardCountChanged, handCounter, &HandCounter::updateNumber);
|
||||
connect(handCounter, &HandCounter::showContextMenu, hand, &HandZone::showContextMenu);
|
||||
|
||||
updateBoundingRect();
|
||||
|
||||
if (local || judge) {
|
||||
connect(_parent, &TabGame::playerAdded, this, &Player::addPlayer);
|
||||
connect(_parent, &TabGame::playerRemoved, this, &Player::removePlayer);
|
||||
connect(_parent->getGameState(), &GameState::playerAdded, this, &Player::addPlayer);
|
||||
connect(_parent->getGameState(), &GameState::playerRemoved, this, &Player::removePlayer);
|
||||
}
|
||||
|
||||
if (local || judge) {
|
||||
|
|
@ -558,7 +561,7 @@ Player::Player(const ServerInfo_User &info, int _id, bool _local, bool _judge, T
|
|||
connect(tempSetCounter, &QAction::triggered, this, &Player::actCardCounterTrigger);
|
||||
}
|
||||
|
||||
const QList<Player *> &players = game->getPlayers().values();
|
||||
const QList<Player *> &players = game->getGameState()->getPlayers().values();
|
||||
for (const auto player : players) {
|
||||
addPlayer(player);
|
||||
}
|
||||
|
|
@ -1015,7 +1018,7 @@ void Player::setShortcutsActive()
|
|||
|
||||
// Don't enable always-active shortcuts in local games, since it causes keyboard shortcuts to work inconsistently
|
||||
// when there are more than 1 player.
|
||||
if (!game->getIsLocalGame()) {
|
||||
if (!game->getGameState()->getIsLocalGame()) {
|
||||
// unattach action is only active in card menu if the active card is attached.
|
||||
// make unattach shortcut always active so that it consistently works when multiple cards are selected.
|
||||
game->addAction(aUnattach);
|
||||
|
|
@ -2341,7 +2344,7 @@ void Player::eventDelCounter(const Event_DelCounter &event)
|
|||
|
||||
void Player::eventDumpZone(const Event_DumpZone &event)
|
||||
{
|
||||
Player *zoneOwner = game->getPlayers().value(event.zone_owner_id(), 0);
|
||||
Player *zoneOwner = game->getGameState()->getPlayers().value(event.zone_owner_id(), 0);
|
||||
if (!zoneOwner) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -2354,13 +2357,13 @@ void Player::eventDumpZone(const Event_DumpZone &event)
|
|||
|
||||
void Player::eventMoveCard(const Event_MoveCard &event, const GameEventContext &context)
|
||||
{
|
||||
Player *startPlayer = game->getPlayers().value(event.start_player_id());
|
||||
Player *startPlayer = game->getGameState()->getPlayers().value(event.start_player_id());
|
||||
if (!startPlayer) {
|
||||
return;
|
||||
}
|
||||
QString startZoneString = QString::fromStdString(event.start_zone());
|
||||
CardZone *startZone = startPlayer->getZones().value(startZoneString, 0);
|
||||
Player *targetPlayer = game->getPlayers().value(event.target_player_id());
|
||||
Player *targetPlayer = game->getGameState()->getPlayers().value(event.target_player_id());
|
||||
if (!targetPlayer) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -2433,7 +2436,7 @@ void Player::eventMoveCard(const Event_MoveCard &event, const GameEventContext &
|
|||
|
||||
// Look at all arrows from and to the card.
|
||||
// If the card was moved to another zone, delete the arrows, otherwise update them.
|
||||
QMapIterator<int, Player *> playerIterator(game->getPlayers());
|
||||
QMapIterator<int, Player *> playerIterator(game->getGameState()->getPlayers());
|
||||
while (playerIterator.hasNext()) {
|
||||
Player *p = playerIterator.next().value();
|
||||
|
||||
|
|
@ -2507,7 +2510,7 @@ void Player::eventDestroyCard(const Event_DestroyCard &event)
|
|||
|
||||
void Player::eventAttachCard(const Event_AttachCard &event)
|
||||
{
|
||||
const QMap<int, Player *> &playerList = game->getPlayers();
|
||||
const QMap<int, Player *> &playerList = game->getGameState()->getPlayers();
|
||||
Player *targetPlayer = nullptr;
|
||||
CardZone *targetZone = nullptr;
|
||||
CardItem *targetCard = nullptr;
|
||||
|
|
@ -2586,7 +2589,7 @@ void Player::eventRevealCards(const Event_RevealCards &event, EventProcessingOpt
|
|||
}
|
||||
Player *otherPlayer = nullptr;
|
||||
if (event.has_other_player_id()) {
|
||||
otherPlayer = game->getPlayers().value(event.other_player_id());
|
||||
otherPlayer = game->getGameState()->getPlayers().value(event.other_player_id());
|
||||
if (!otherPlayer) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -2790,7 +2793,9 @@ void Player::processPlayerInfo(const ServerInfo_Player &info)
|
|||
|
||||
switch (zoneInfo.type()) {
|
||||
case ServerInfo_Zone::PrivateZone:
|
||||
contentsKnown = local || judge || (game->isSpectator() && game->isSpectatorsOmniscient());
|
||||
contentsKnown =
|
||||
local || judge ||
|
||||
(game->getGameState()->isSpectator() && game->getGameMetaInfo()->spectatorsOmniscient());
|
||||
break;
|
||||
|
||||
case ServerInfo_Zone::PublicZone:
|
||||
|
|
@ -3084,7 +3089,7 @@ void Player::incrementAllCardCounters()
|
|||
|
||||
ArrowItem *Player::addArrow(const ServerInfo_Arrow &arrow)
|
||||
{
|
||||
const QMap<int, Player *> &playerList = game->getPlayers();
|
||||
const QMap<int, Player *> &playerList = game->getGameState()->getPlayers();
|
||||
Player *startPlayer = playerList.value(arrow.start_player_id(), 0);
|
||||
Player *targetPlayer = playerList.value(arrow.target_player_id(), 0);
|
||||
if (!startPlayer || !targetPlayer) {
|
||||
|
|
@ -3178,9 +3183,9 @@ PendingCommand *Player::prepareGameCommand(const google::protobuf::Message &cmd)
|
|||
GameCommand *c = base.add_game_command();
|
||||
base.set_target_id(id);
|
||||
c->GetReflection()->MutableMessage(c, cmd.GetDescriptor()->FindExtensionByName("ext"))->CopyFrom(cmd);
|
||||
return game->prepareGameCommand(base);
|
||||
return game->getGameEventHandler()->prepareGameCommand(base);
|
||||
} else {
|
||||
return game->prepareGameCommand(cmd);
|
||||
return game->getGameEventHandler()->prepareGameCommand(cmd);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -3196,9 +3201,9 @@ PendingCommand *Player::prepareGameCommand(const QList<const ::google::protobuf:
|
|||
->CopyFrom(*cmdList[i]);
|
||||
delete cmdList[i];
|
||||
}
|
||||
return game->prepareGameCommand(base);
|
||||
return game->getGameEventHandler()->prepareGameCommand(base);
|
||||
} else {
|
||||
return game->prepareGameCommand(cmdList);
|
||||
return game->getGameEventHandler()->prepareGameCommand(cmdList);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -3209,15 +3214,15 @@ void Player::sendGameCommand(const google::protobuf::Message &command)
|
|||
GameCommand *c = base.add_game_command();
|
||||
base.set_target_id(id);
|
||||
c->GetReflection()->MutableMessage(c, command.GetDescriptor()->FindExtensionByName("ext"))->CopyFrom(command);
|
||||
game->sendGameCommand(base, id);
|
||||
game->getGameEventHandler()->sendGameCommand(base, id);
|
||||
} else {
|
||||
game->sendGameCommand(command, id);
|
||||
game->getGameEventHandler()->sendGameCommand(command, id);
|
||||
}
|
||||
}
|
||||
|
||||
void Player::sendGameCommand(PendingCommand *pend)
|
||||
{
|
||||
game->sendGameCommand(pend, id);
|
||||
game->getGameEventHandler()->sendGameCommand(pend, id);
|
||||
}
|
||||
|
||||
bool Player::clearCardsToDelete()
|
||||
|
|
@ -3284,7 +3289,7 @@ void Player::actMoveCardXCardsFromTop()
|
|||
if (local) {
|
||||
sendGameCommand(prepareGameCommand(commandList));
|
||||
} else {
|
||||
game->sendGameCommand(prepareGameCommand(commandList));
|
||||
game->getGameEventHandler()->sendGameCommand(prepareGameCommand(commandList));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -3470,7 +3475,7 @@ void Player::cardMenuAction()
|
|||
if (local) {
|
||||
sendGameCommand(prepareGameCommand(commandList));
|
||||
} else {
|
||||
game->sendGameCommand(prepareGameCommand(commandList));
|
||||
game->getGameEventHandler()->sendGameCommand(prepareGameCommand(commandList));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -3505,7 +3510,7 @@ void Player::actIncPT(int deltaP, int deltaT)
|
|||
}
|
||||
}
|
||||
|
||||
game->sendGameCommand(prepareGameCommand(commandList), playerid);
|
||||
game->getGameEventHandler()->sendGameCommand(prepareGameCommand(commandList), playerid);
|
||||
}
|
||||
|
||||
void Player::actResetPT()
|
||||
|
|
@ -3538,7 +3543,7 @@ void Player::actResetPT()
|
|||
}
|
||||
|
||||
if (!commandList.empty()) {
|
||||
game->sendGameCommand(prepareGameCommand(commandList), playerid);
|
||||
game->getGameEventHandler()->sendGameCommand(prepareGameCommand(commandList), playerid);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -3632,7 +3637,7 @@ void Player::actSetPT()
|
|||
}
|
||||
}
|
||||
|
||||
game->sendGameCommand(prepareGameCommand(commandList), playerid);
|
||||
game->getGameEventHandler()->sendGameCommand(prepareGameCommand(commandList), playerid);
|
||||
}
|
||||
|
||||
void Player::actDrawArrow()
|
||||
|
|
@ -4045,6 +4050,7 @@ QMenu *Player::createCardMenu(const CardItem *card)
|
|||
|
||||
QMenu *revealMenu = cardMenu->addMenu(tr("Re&veal to..."));
|
||||
initContextualPlayersMenu(revealMenu);
|
||||
|
||||
connect(revealMenu, &QMenu::triggered, this, &Player::actReveal);
|
||||
|
||||
cardMenu->addSeparator();
|
||||
|
|
@ -4243,7 +4249,7 @@ QMenu *Player::updateCardMenu(const CardItem *card)
|
|||
|
||||
// If is spectator (as spectators don't need card menus), return
|
||||
// only update the menu if the card is actually selected
|
||||
if ((game->isSpectator() && !judge) || game->getActiveCard() != card) {
|
||||
if ((game->getGameState()->isSpectator() && !judge) || game->getActiveCard() != card) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
#ifndef PLAYERLISTWIDGET_H
|
||||
#define PLAYERLISTWIDGET_H
|
||||
|
||||
#include "player.h"
|
||||
|
||||
#include <QIcon>
|
||||
#include <QMap>
|
||||
#include <QStyledItemDelegate>
|
||||
|
|
@ -47,12 +49,14 @@ signals:
|
|||
public:
|
||||
PlayerListWidget(TabSupervisor *_tabSupervisor, AbstractClient *_client, TabGame *_game, QWidget *parent = nullptr);
|
||||
void retranslateUi();
|
||||
void addPlayer(const ServerInfo_PlayerProperties &player);
|
||||
void removePlayer(int playerId);
|
||||
void setActivePlayer(int playerId);
|
||||
void updatePlayerProperties(const ServerInfo_PlayerProperties &prop, int playerId = -1);
|
||||
void setGameStarted(bool _gameStarted, bool resuming);
|
||||
void showContextMenu(const QPoint &pos, const QModelIndex &index);
|
||||
|
||||
public slots:
|
||||
void addPlayer(const ServerInfo_PlayerProperties &player);
|
||||
void removePlayer(int playerId);
|
||||
void updatePlayerProperties(const ServerInfo_PlayerProperties &prop, int playerId = -1);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -391,6 +391,11 @@ void MessageLogWidget::logGameStart()
|
|||
appendHtmlServerMessage(tr("The game has started."));
|
||||
}
|
||||
|
||||
void MessageLogWidget::logGameFlooded()
|
||||
{
|
||||
appendMessage(tr("You are flooding the game. Please wait a couple of seconds."));
|
||||
}
|
||||
|
||||
void MessageLogWidget::logJoin(Player *player)
|
||||
{
|
||||
soundEngine->playSound("player_join");
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@ public slots:
|
|||
void logFlipCard(Player *player, QString cardName, bool faceDown);
|
||||
void logGameClosed();
|
||||
void logGameStart();
|
||||
void logGameFlooded();
|
||||
void logJoin(Player *player);
|
||||
void logJoinSpectator(QString name);
|
||||
void logKicked();
|
||||
|
|
|
|||
|
|
@ -380,7 +380,7 @@ void UserContextMenu::showContextMenu(const QPoint &pos,
|
|||
aRemoveMessages = new QAction(tr("Remove this user's messages"), this);
|
||||
menu->addAction(aRemoveMessages);
|
||||
}
|
||||
if (game && (game->isHost() || !tabSupervisor->getAdminLocked())) {
|
||||
if (game && (game->getGameState()->isHost() || !tabSupervisor->getAdminLocked())) {
|
||||
menu->addSeparator();
|
||||
menu->addAction(aKick);
|
||||
}
|
||||
|
|
@ -476,7 +476,7 @@ void UserContextMenu::showContextMenu(const QPoint &pos,
|
|||
Command_KickFromGame cmd;
|
||||
cmd.set_player_id(playerId);
|
||||
|
||||
game->sendGameCommand(cmd);
|
||||
game->getGameEventHandler()->sendGameCommand(cmd);
|
||||
} else if (actionClicked == aBan) {
|
||||
Command_GetUserInfo cmd;
|
||||
cmd.set_user_name(userName.toStdString());
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue