[Server] Add game lifecycle strategy hook (#7130)

Took 30 minutes

Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
This commit is contained in:
BruebachL
2026-08-23 10:26:14 +02:00
committed by GitHub
parent 6b5105eecc
commit da924c2bd6
4 changed files with 59 additions and 1 deletions

View File

@@ -13,6 +13,7 @@ set(HEADERS
game/game_config.h
game/server_deck_validation_strategy.h
game/server_game.h
game/server_game_lifecycle_strategy.h
game/server_player.h
game/server_spectator.h
server.h

View File

@@ -63,7 +63,7 @@ Server_Game::Server_Game(const GameConfig &config, Server_Room *_room)
startingLifeTotal(config.startingLifeTotal), shareDecklistsOnLoad(config.shareDecklistsOnLoad),
inactivityCounter(0), startTimeOfThisGame(0), secondsElapsed(0), firstGameStarted(false),
turnOrderReversed(false), startTime(QDateTime::currentDateTime()), pingClock(nullptr),
deckValidationStrategy(new Server_DefaultDeckValidationStrategy), gameMutex()
lifecycleStrategy(new Server_DefaultLifecycleStrategy), gameMutex()
{
currentReplay = new GameReplay;
currentReplay->set_replay_id(room->getServer()->getDatabaseInterface()->getNextReplayId());
@@ -329,6 +329,11 @@ void Server_Game::doStartGameIfReady(bool forceStartGame)
}
players = getPlayers(); // players could have been kicked, get new list of players
if (lifecycleStrategy->onGameStarting(this) == Server_GameLifecycleStrategy::StartAction::Handled) {
locker.unlock();
return;
}
for (Server_AbstractPlayer *player : players.values()) {
player->setupZones();
}

View File

@@ -23,6 +23,7 @@
#include "../server_response_containers.h"
#include "game_config.h"
#include "server_deck_validation_strategy.h"
#include "server_game_lifecycle_strategy.h"
#include <QDateTime>
#include <QMap>
@@ -83,6 +84,8 @@ private:
QScopedPointer<Server_DeckValidationStrategy> deckValidationStrategy;
QScopedPointer<Server_GameLifecycleStrategy> lifecycleStrategy;
void createGameStateChangedEvent(Event_GameStateChanged *event,
Server_AbstractParticipant *recipient,
bool omniscient,
@@ -220,6 +223,12 @@ public:
}
/** @brief Replace the deck validation strategy; takes ownership of @p strategy. */
void setDeckValidationStrategy(Server_DeckValidationStrategy *strategy);
/** @brief Get the current game lifecycle strategy (non-owning). */
Server_GameLifecycleStrategy *getLifecycleStrategy() const
{
return lifecycleStrategy.data();
}
};
#endif

View File

@@ -0,0 +1,43 @@
#ifndef SERVER_GAME_LIFECYCLE_STRATEGY_H
#define SERVER_GAME_LIFECYCLE_STRATEGY_H
class Server_Game;
/**
* @brief Strategy hook invoked around a game's lifecycle transitions.
*
* Subclasses can intercept the game start to perform custom setup (e.g. draft or
* tournament initialization); the default implementation never intercepts.
*/
class Server_GameLifecycleStrategy
{
public:
virtual ~Server_GameLifecycleStrategy() = default;
/** @brief How the game start should proceed after this hook returns. */
enum class StartAction
{
ProceedNormal, ///< Continue with the normal game start flow.
Handled, ///< The strategy handled the start; abort the normal flow.
};
/**
* @brief Called when a game is about to start.
* @return How the start flow should proceed.
*/
virtual StartAction onGameStarting(Server_Game *game) = 0;
};
/**
* @brief Default lifecycle strategy that never intercepts the game start.
*/
class Server_DefaultLifecycleStrategy : public Server_GameLifecycleStrategy
{
public:
StartAction onGameStarting(Server_Game *) override
{
return StartAction::ProceedNormal;
}
};
#endif