From e8eda4f1899d6b7a9ad1c005db93ebb91bad24e8 Mon Sep 17 00:00:00 2001 From: lotodore Date: Sat, 4 Sep 2010 20:08:40 +0000 Subject: [PATCH] Delay auto-start of games when they are full. --- src/net/common/servergame.cpp | 14 ++++- src/net/common/servergamestate.cpp | 93 ++++++++++++++++++++---------- src/net/servergame.h | 6 +- src/net/servergamestate.h | 10 ++++ 4 files changed, 88 insertions(+), 35 deletions(-) diff --git a/src/net/common/servergame.cpp b/src/net/common/servergame.cpp index 3af4f720..13840dcd 100644 --- a/src/net/common/servergame.cpp +++ b/src/net/common/servergame.cpp @@ -50,7 +50,8 @@ ServerGame::ServerGame(boost::shared_ptr lobbyThread, u_int32 : m_adminPlayerId(adminPlayerId), m_lobbyThread(lobbyThread), m_gui(gui), m_gameData(gameData), m_curState(NULL), m_id(id), m_dbId(DB_ID_INVALID), m_name(name), m_password(pwd), m_playerConfig(playerConfig), m_gameNum(1), m_curPetitionId(1), - m_voteKickTimer(lobbyThread->GetIOService()), m_stateTimer(lobbyThread->GetIOService()) + m_voteKickTimer(lobbyThread->GetIOService()), m_stateTimer1(lobbyThread->GetIOService()), + m_stateTimer2(lobbyThread->GetIOService()) { LOG_VERBOSE("Game object " << GetId() << " created."); @@ -758,6 +759,7 @@ ServerGame::RemovePlayerData(boost::shared_ptr player, int reason) } GetSessionManager().SendToAllSessions(GetLobbyThread().GetSender(), thisPlayerLeft, SessionData::Game); + GetState().NotifySessionRemoved(shared_from_this()); GetLobbyThread().NotifyPlayerLeftGame(GetId(), player->GetUniqueId()); } @@ -891,9 +893,15 @@ ServerGame::SetState(ServerGameState &newState) } boost::asio::deadline_timer & -ServerGame::GetStateTimer() +ServerGame::GetStateTimer1() { - return m_stateTimer; + return m_stateTimer1; +} + +boost::asio::deadline_timer & +ServerGame::GetStateTimer2() +{ + return m_stateTimer2; } ReceiverHelper & diff --git a/src/net/common/servergamestate.cpp b/src/net/common/servergamestate.cpp index daa15de0..82bb3681 100644 --- a/src/net/common/servergamestate.cpp +++ b/src/net/common/servergamestate.cpp @@ -62,6 +62,7 @@ using namespace std; #endif #define SERVER_START_GAME_TIMEOUT_SEC 10 +#define SERVER_AUTOSTART_GAME_DELAY_SEC 6 #define SERVER_GAME_ADMIN_WARNING_REMAINING_SEC 60 #define SERVER_GAME_ADMIN_TIMEOUT_SEC 300 // 5 min, MUST be > SERVER_GAME_ADMIN_WARNING_REMAINING_SEC #define SERVER_VOTE_KICK_TIMEOUT_SEC 30 @@ -329,6 +330,7 @@ void ServerGameStateInit::Exit(boost::shared_ptr server) { UnregisterAdminTimer(server); + UnregisterAutoStartTimer(server); } void @@ -338,6 +340,12 @@ ServerGameStateInit::NotifyGameAdminChanged(boost::shared_ptr server RegisterAdminTimer(server); } +void +ServerGameStateInit::NotifySessionRemoved(boost::shared_ptr server) +{ + UnregisterAutoStartTimer(server); +} + void ServerGameStateInit::HandleNewSession(boost::shared_ptr server, SessionWrapper session) { @@ -391,7 +399,7 @@ ServerGameStateInit::HandleNewSession(boost::shared_ptr server, Sess if (server->GetCurNumberOfPlayers() == (size_t)tmpGameData.maxNumberOfPlayers) { // Automatically start the game if it is full. - SendStartEvent(*server, false); + RegisterAutoStartTimer(server); } } } @@ -400,9 +408,9 @@ ServerGameStateInit::HandleNewSession(boost::shared_ptr server, Sess void ServerGameStateInit::RegisterAdminTimer(boost::shared_ptr server) { - server->GetStateTimer().expires_from_now( + server->GetStateTimer1().expires_from_now( boost::posix_time::seconds(SERVER_GAME_ADMIN_TIMEOUT_SEC - SERVER_GAME_ADMIN_WARNING_REMAINING_SEC)); - server->GetStateTimer().async_wait( + server->GetStateTimer1().async_wait( boost::bind( &ServerGameStateInit::TimerAdminWarning, this, boost::asio::placeholders::error, server)); } @@ -410,7 +418,32 @@ ServerGameStateInit::RegisterAdminTimer(boost::shared_ptr server) void ServerGameStateInit::UnregisterAdminTimer(boost::shared_ptr server) { - server->GetStateTimer().cancel(); + server->GetStateTimer1().cancel(); +} + +void +ServerGameStateInit::RegisterAutoStartTimer(boost::shared_ptr server) +{ + server->GetStateTimer2().expires_from_now( + boost::posix_time::seconds(SERVER_AUTOSTART_GAME_DELAY_SEC)); + server->GetStateTimer2().async_wait( + boost::bind( + &ServerGameStateInit::TimerAutoStart, this, boost::asio::placeholders::error, server)); +} + +void +ServerGameStateInit::UnregisterAutoStartTimer(boost::shared_ptr server) +{ + server->GetStateTimer2().cancel(); +} + +void +ServerGameStateInit::TimerAutoStart(const boost::system::error_code &ec, boost::shared_ptr server) +{ + if (!ec && &server->GetState() == this) + { + SendStartEvent(*server, false); + } } void @@ -431,9 +464,9 @@ ServerGameStateInit::TimerAdminWarning(const boost::system::error_code &ec, boos server->GetLobbyThread().GetSender().Send(session.sessionData, packet); } // Start timeout timer. - server->GetStateTimer().expires_from_now( + server->GetStateTimer1().expires_from_now( boost::posix_time::seconds(SERVER_GAME_ADMIN_WARNING_REMAINING_SEC)); - server->GetStateTimer().async_wait( + server->GetStateTimer1().async_wait( boost::bind( &ServerGameStateInit::TimerAdminTimeout, this, boost::asio::placeholders::error, server)); } @@ -590,9 +623,9 @@ ServerGameStateStartGame::~ServerGameStateStartGame() void ServerGameStateStartGame::Enter(boost::shared_ptr server) { - server->GetStateTimer().expires_from_now( + server->GetStateTimer1().expires_from_now( boost::posix_time::seconds(SERVER_START_GAME_TIMEOUT_SEC)); - server->GetStateTimer().async_wait( + server->GetStateTimer1().async_wait( boost::bind( &ServerGameStateStartGame::TimerTimeout, this, boost::asio::placeholders::error, server)); } @@ -600,7 +633,7 @@ ServerGameStateStartGame::Enter(boost::shared_ptr server) void ServerGameStateStartGame::Exit(boost::shared_ptr server) { - server->GetStateTimer().cancel(); + server->GetStateTimer1().cancel(); } void @@ -704,9 +737,9 @@ ServerGameStateHand::~ServerGameStateHand() void ServerGameStateHand::Enter(boost::shared_ptr server) { - server->GetStateTimer().expires_from_now( + server->GetStateTimer1().expires_from_now( boost::posix_time::milliseconds(SERVER_LOOP_DELAY_MSEC)); - server->GetStateTimer().async_wait( + server->GetStateTimer1().async_wait( boost::bind( &ServerGameStateHand::TimerLoop, this, boost::asio::placeholders::error, server)); } @@ -714,7 +747,7 @@ ServerGameStateHand::Enter(boost::shared_ptr server) void ServerGameStateHand::Exit(boost::shared_ptr server) { - server->GetStateTimer().cancel(); + server->GetStateTimer1().cancel(); } void @@ -797,9 +830,9 @@ ServerGameStateHand::EngineLoop(boost::shared_ptr server) server->SendToAllPlayers(allIn, SessionData::Game); curGame.getCurrentHand()->setCardsShown(true); - server->GetStateTimer().expires_from_now( + server->GetStateTimer1().expires_from_now( boost::posix_time::seconds(SERVER_SHOW_CARDS_DELAY_SEC)); - server->GetStateTimer().async_wait( + server->GetStateTimer1().async_wait( boost::bind( &ServerGameStateHand::TimerShowCards, this, boost::asio::placeholders::error, server)); } @@ -807,9 +840,9 @@ ServerGameStateHand::EngineLoop(boost::shared_ptr server) { SendNewRoundCards(*server, curGame, newRound); - server->GetStateTimer().expires_from_now( + server->GetStateTimer1().expires_from_now( boost::posix_time::seconds(GetDealCardsDelaySec(*server))); - server->GetStateTimer().async_wait( + server->GetStateTimer1().async_wait( boost::bind( &ServerGameStateHand::TimerLoop, this, boost::asio::placeholders::error, server)); } @@ -839,9 +872,9 @@ ServerGameStateHand::EngineLoop(boost::shared_ptr server) // If the player is computer controlled, let the engine act. if (curPlayer->getMyType() == PLAYER_TYPE_COMPUTER) { - server->GetStateTimer().expires_from_now( + server->GetStateTimer1().expires_from_now( boost::posix_time::seconds(SERVER_COMPUTER_ACTION_DELAY_SEC)); - server->GetStateTimer().async_wait( + server->GetStateTimer1().async_wait( boost::bind( &ServerGameStateHand::TimerComputerAction, this, boost::asio::placeholders::error, server)); } @@ -850,9 +883,9 @@ ServerGameStateHand::EngineLoop(boost::shared_ptr server) { PerformPlayerAction(*server, curPlayer, PLAYER_ACTION_FOLD, 0); - server->GetStateTimer().expires_from_now( + server->GetStateTimer1().expires_from_now( boost::posix_time::milliseconds(SERVER_LOOP_DELAY_MSEC)); - server->GetStateTimer().async_wait( + server->GetStateTimer1().async_wait( boost::bind( &ServerGameStateHand::TimerLoop, this, boost::asio::placeholders::error, server)); } @@ -937,9 +970,9 @@ ServerGameStateHand::EngineLoop(boost::shared_ptr server) server->InternalEndGame(); // View a dialog for a new game - delayed. - server->GetStateTimer().expires_from_now( + server->GetStateTimer1().expires_from_now( boost::posix_time::seconds(SERVER_DELAY_NEXT_GAME_SEC)); - server->GetStateTimer().async_wait( + server->GetStateTimer1().async_wait( boost::bind( &ServerGameStateHand::TimerNextGame, this, boost::asio::placeholders::error, server, winnerPlayer->getMyUniqueID())); } @@ -959,9 +992,9 @@ ServerGameStateHand::TimerShowCards(const boost::system::error_code &ec, boost:: Game &curGame = server->GetGame(); SendNewRoundCards(*server, curGame, curGame.getCurrentHand()->getCurrentRound()); - server->GetStateTimer().expires_from_now( + server->GetStateTimer1().expires_from_now( boost::posix_time::seconds(GetDealCardsDelaySec(*server))); - server->GetStateTimer().async_wait( + server->GetStateTimer1().async_wait( boost::bind( &ServerGameStateHand::TimerLoop, this, boost::asio::placeholders::error, server)); } @@ -1200,8 +1233,8 @@ ServerGameStateWaitPlayerAction::Enter(boost::shared_ptr server) int timeoutSec = server->GetGameData().playerActionTimeoutSec + SERVER_PLAYER_TIMEOUT_ADD_DELAY_SEC; #endif - server->GetStateTimer().expires_from_now(boost::posix_time::seconds(timeoutSec)); - server->GetStateTimer().async_wait( + server->GetStateTimer1().expires_from_now(boost::posix_time::seconds(timeoutSec)); + server->GetStateTimer1().async_wait( boost::bind( &ServerGameStateWaitPlayerAction::TimerTimeout, this, boost::asio::placeholders::error, server)); } @@ -1209,7 +1242,7 @@ ServerGameStateWaitPlayerAction::Enter(boost::shared_ptr server) void ServerGameStateWaitPlayerAction::Exit(boost::shared_ptr server) { - server->GetStateTimer().cancel(); + server->GetStateTimer1().cancel(); } void @@ -1346,10 +1379,10 @@ ServerGameStateWaitNextHand::Enter(boost::shared_ptr server) int timeoutSec = server->GetGameData().delayBetweenHandsSec; #endif - server->GetStateTimer().expires_from_now( + server->GetStateTimer1().expires_from_now( boost::posix_time::seconds(timeoutSec)); - server->GetStateTimer().async_wait( + server->GetStateTimer1().async_wait( boost::bind( &ServerGameStateWaitNextHand::TimerTimeout, this, boost::asio::placeholders::error, server)); } @@ -1357,7 +1390,7 @@ ServerGameStateWaitNextHand::Enter(boost::shared_ptr server) void ServerGameStateWaitNextHand::Exit(boost::shared_ptr server) { - server->GetStateTimer().cancel(); + server->GetStateTimer1().cancel(); } void diff --git a/src/net/servergame.h b/src/net/servergame.h index 2834aa29..0c59d143 100644 --- a/src/net/servergame.h +++ b/src/net/servergame.h @@ -139,7 +139,8 @@ protected: ServerGameState &GetState(); void SetState(ServerGameState &newState); - boost::asio::deadline_timer &GetStateTimer(); + boost::asio::deadline_timer &GetStateTimer1(); + boost::asio::deadline_timer &GetStateTimer2(); ReceiverHelper &GetReceiver(); @@ -188,7 +189,8 @@ private: unsigned m_gameNum; unsigned m_curPetitionId; boost::asio::deadline_timer m_voteKickTimer; - boost::asio::deadline_timer m_stateTimer; + boost::asio::deadline_timer m_stateTimer1; + boost::asio::deadline_timer m_stateTimer2; friend class ServerLobbyThread; friend class AbstractServerGameStateReceiving; diff --git a/src/net/servergamestate.h b/src/net/servergamestate.h index 35d8e4d1..e0ae7b1f 100644 --- a/src/net/servergamestate.h +++ b/src/net/servergamestate.h @@ -45,6 +45,7 @@ public: virtual void Exit(boost::shared_ptr server) = 0; virtual void NotifyGameAdminChanged(boost::shared_ptr server) = 0; + virtual void NotifySessionRemoved(boost::shared_ptr server) = 0; // Handling of a new session. virtual void HandleNewSession(boost::shared_ptr server, SessionWrapper session) = 0; @@ -79,6 +80,7 @@ public: virtual ~ServerGameStateInit(); virtual void NotifyGameAdminChanged(boost::shared_ptr server); + virtual void NotifySessionRemoved(boost::shared_ptr server); virtual void HandleNewSession(boost::shared_ptr server, SessionWrapper session); @@ -87,6 +89,9 @@ protected: void RegisterAdminTimer(boost::shared_ptr server); void UnregisterAdminTimer(boost::shared_ptr server); + void RegisterAutoStartTimer(boost::shared_ptr server); + void UnregisterAutoStartTimer(boost::shared_ptr server); + void TimerAutoStart(const boost::system::error_code &ec, boost::shared_ptr server); void TimerAdminWarning(const boost::system::error_code &ec, boost::shared_ptr server); void TimerAdminTimeout(const boost::system::error_code &ec, boost::shared_ptr server); void SendStartEvent(ServerGame &server, bool fillWithComputerPlayers); @@ -110,6 +115,7 @@ public: virtual ~ServerGameStateStartGame(); virtual void NotifyGameAdminChanged(boost::shared_ptr /*server*/) {} + virtual void NotifySessionRemoved(boost::shared_ptr /*server*/) {} virtual void HandleNewSession(boost::shared_ptr server, SessionWrapper session); protected: @@ -134,6 +140,7 @@ public: virtual ~ServerGameStateHand(); virtual void NotifyGameAdminChanged(boost::shared_ptr /*server*/) {} + virtual void NotifySessionRemoved(boost::shared_ptr /*server*/) {} virtual void HandleNewSession(boost::shared_ptr server, SessionWrapper session); protected: @@ -167,6 +174,7 @@ public: virtual ~ServerGameStateWaitPlayerAction(); virtual void NotifyGameAdminChanged(boost::shared_ptr /*server*/) {} + virtual void NotifySessionRemoved(boost::shared_ptr /*server*/) {} virtual void HandleNewSession(boost::shared_ptr server, SessionWrapper session); protected: @@ -190,6 +198,7 @@ public: virtual ~ServerGameStateWaitNextHand(); virtual void NotifyGameAdminChanged(boost::shared_ptr /*server*/) {} + virtual void NotifySessionRemoved(boost::shared_ptr /*server*/) {} virtual void HandleNewSession(boost::shared_ptr server, SessionWrapper session); protected: @@ -212,6 +221,7 @@ public: virtual void Exit(boost::shared_ptr /*server*/) {} virtual void NotifyGameAdminChanged(boost::shared_ptr /*server*/) {} + virtual void NotifySessionRemoved(boost::shared_ptr /*server*/) {} // Handling of a new session. virtual void HandleNewSession(boost::shared_ptr /*server*/, SessionWrapper /*session*/) {}