Almost complete rewrite of server game state due to porting the network engine to asio. Server is still broken in a lot of ways. A game is no longer run in a separate thread (but this change is still incomplete).

This commit is contained in:
lotodore
2009-05-30 22:20:40 +00:00
parent 1ac6d2cd23
commit 08ed5e0496
6 changed files with 759 additions and 1271 deletions
File diff suppressed because it is too large Load Diff
+35 -84
View File
@@ -33,6 +33,7 @@
#define SERVER_CHECK_VOTE_KICK_INTERVAL_MSEC 500 #define SERVER_CHECK_VOTE_KICK_INTERVAL_MSEC 500
#define SERVER_REMOVE_PLAYER_INTERVAL_MSEC 1000
#define SERVER_KICK_TIMEOUT_ADD_DELAY_SEC 2 #define SERVER_KICK_TIMEOUT_ADD_DELAY_SEC 2
using namespace std; using namespace std;
@@ -41,17 +42,29 @@ using namespace std;
ServerGameThread::ServerGameThread(ServerLobbyThread &lobbyThread, u_int32_t id, const string &name, const string &pwd, const GameData &gameData, unsigned adminPlayerId, GuiInterface &gui, ConfigFile *playerConfig) ServerGameThread::ServerGameThread(ServerLobbyThread &lobbyThread, u_int32_t id, const string &name, const string &pwd, const GameData &gameData, unsigned adminPlayerId, GuiInterface &gui, ConfigFile *playerConfig)
: m_adminPlayerId(adminPlayerId), m_lobbyThread(lobbyThread), m_gui(gui), : m_adminPlayerId(adminPlayerId), m_lobbyThread(lobbyThread), m_gui(gui),
m_gameData(gameData), m_id(id), m_name(name), m_password(pwd), m_playerConfig(playerConfig), m_gameData(gameData), m_id(id), m_name(name), m_password(pwd), m_playerConfig(playerConfig),
m_curState(NULL), m_gameNum(1), m_curPetitionId(1), m_gameNum(1), m_curPetitionId(1)
m_stateTimer(boost::posix_time::time_duration(0, 0, 0), boost::timers::portable::microsec_timer::manual_start),
m_stateTimerFlag(0)
{ {
LOG_VERBOSE("Game object " << GetId() << " created."); LOG_VERBOSE("Game object " << GetId() << " created.");
m_receiver.reset(new ReceiverHelper); m_receiver.reset(new ReceiverHelper);
m_removePlayerTimerId = GetLobbyThread().GetTimerManager().RegisterTimer(
SERVER_REMOVE_PLAYER_INTERVAL_MSEC,
boost::bind(&ServerGameThread::TimerRemovePlayer, this),
true);
m_voteKickTimerId = GetLobbyThread().GetTimerManager().RegisterTimer(
SERVER_CHECK_VOTE_KICK_INTERVAL_MSEC,
boost::bind(&ServerGameThread::TimerVoteKick, this),
true);
SetState(boost::shared_ptr<ServerGameState>(new SERVER_INITIAL_STATE(*this)));
} }
ServerGameThread::~ServerGameThread() ServerGameThread::~ServerGameThread()
{ {
GetLobbyThread().GetTimerManager().UnregisterTimer(m_removePlayerTimerId);
GetLobbyThread().GetTimerManager().UnregisterTimer(m_voteKickTimerId);
LOG_VERBOSE("Game object " << GetId() << " destructed."); LOG_VERBOSE("Game object " << GetId() << " destructed.");
} }
@@ -70,9 +83,8 @@ ServerGameThread::GetName() const
void void
ServerGameThread::AddSession(SessionWrapper session) ServerGameThread::AddSession(SessionWrapper session)
{ {
// Must be thread safe. if (session.sessionData)
boost::mutex::scoped_lock lock(m_sessionQueueMutex); GetState().HandleNewSession(session);
m_sessionQueue.push_back(session);
} }
void void
@@ -82,6 +94,13 @@ ServerGameThread::RemovePlayer(unsigned playerId, unsigned errorCode)
m_removePlayerList.push_back(RemovePlayerList::value_type(playerId, errorCode)); m_removePlayerList.push_back(RemovePlayerList::value_type(playerId, errorCode));
} }
void
ServerGameThread::HandlePacket(SessionWrapper session, boost::shared_ptr<NetPacket> packet)
{
if (session.sessionData && packet)
GetState().ProcessPacket(session, packet);
}
GameState GameState
ServerGameThread::GetCurRound() const ServerGameThread::GetCurRound() const
{ {
@@ -111,50 +130,15 @@ ServerGameThread::RemoveAllSessions()
GetSessionManager().ForEach(boost::bind(&ServerLobbyThread::RemoveSessionFromGame, boost::ref(lobbyThread), _1)); GetSessionManager().ForEach(boost::bind(&ServerLobbyThread::RemoveSessionFromGame, boost::ref(lobbyThread), _1));
} }
void // TODO terminate game.
ServerGameThread::Main() // TODO Handle game termination!
{ // ResetComputerPlayerList();
LOG_VERBOSE("Game thread " << GetId() << " started."); // GetLobbyThread().RemoveGame(GetId());
SetState(SERVER_INITIAL_STATE::Instance()); // LOG_VERBOSE("Game thread " << GetId() << " terminating.");
try
{
do
{
{
// Handle one new session at a time.
SessionWrapper tmpSession;
{
boost::mutex::scoped_lock lock(m_sessionQueueMutex);
if (!m_sessionQueue.empty())
{
tmpSession = m_sessionQueue.front();
m_sessionQueue.pop_front();
}
}
if (tmpSession.sessionData.get())
GetState().HandleNewSession(*this, tmpSession);
}
// Process current state.
GetState().Process(*this);
RemovePlayerLoop();
VoteKickLoop();
} while (!ShouldTerminate() && GetSessionManager().HasSessions());
} catch (const PokerTHException &e)
{
GetCallback().SignalNetServerError(e.GetErrorId(), e.GetOsErrorCode());
LOG_ERROR(e.what());
}
ResetComputerPlayerList();
GetLobbyThread().RemoveGame(GetId());
LOG_VERBOSE("Game thread " << GetId() << " terminating.");
}
void void
ServerGameThread::RemovePlayerLoop() ServerGameThread::TimerRemovePlayer()
{ {
boost::mutex::scoped_lock lock(m_removePlayerListMutex); boost::mutex::scoped_lock lock(m_removePlayerListMutex);
@@ -173,16 +157,7 @@ ServerGameThread::RemovePlayerLoop()
} }
void void
ServerGameThread::VoteKickLoop() ServerGameThread::TimerVoteKick()
{
// Do not call the vote kick action all the time.
// Check the timer.
if (m_voteKickActionTimer.elapsed().total_milliseconds() >= SERVER_CHECK_VOTE_KICK_INTERVAL_MSEC)
VoteKickAction();
}
void
ServerGameThread::VoteKickAction()
{ {
// Check whether someone should be kicked, or whether a vote kick should be aborted. // Check whether someone should be kicked, or whether a vote kick should be aborted.
// Only one vote kick can be active at a time. // Only one vote kick can be active at a time.
@@ -605,7 +580,7 @@ ServerGameThread::RemovePlayerData(boost::shared_ptr<PlayerData> player, int rea
SetAdminPlayerId(newAdmin->GetUniqueId()); SetAdminPlayerId(newAdmin->GetUniqueId());
newAdmin->SetRights(PLAYER_RIGHTS_ADMIN); newAdmin->SetRights(PLAYER_RIGHTS_ADMIN);
// Notify game state on admin change // Notify game state on admin change
GetState().NotifyGameAdminChanged(*this); GetState().NotifyGameAdminChanged();
// Send "Game Admin Changed" to clients. // Send "Game Admin Changed" to clients.
boost::shared_ptr<NetPacket> adminChanged(new NetPacketGameAdminChanged); boost::shared_ptr<NetPacket> adminChanged(new NetPacketGameAdminChanged);
NetPacketGameAdminChanged::Data adminChangedData; NetPacketGameAdminChanged::Data adminChangedData;
@@ -743,33 +718,9 @@ ServerGameThread::GetState()
} }
void void
ServerGameThread::SetState(ServerGameState &newState) ServerGameThread::SetState(boost::shared_ptr<ServerGameState> newState)
{ {
newState.Init(*this); m_curState = newState;
m_curState = &newState;
}
const boost::timers::portable::microsec_timer &
ServerGameThread::GetStateTimer() const
{
return m_stateTimer;
}
boost::timers::portable::microsec_timer &
ServerGameThread::GetStateTimer()
{
return m_stateTimer;
}
unsigned
ServerGameThread::GetStateTimerFlag() const
{
return m_stateTimerFlag;
}
void
ServerGameThread::SetStateTimerFlag(unsigned flag)
{
m_stateTimerFlag = flag;
} }
ReceiverHelper & ReceiverHelper &
+27 -19
View File
@@ -444,6 +444,12 @@ ServerLobbyThread::RemoveGame(unsigned id)
m_removeGameList.push_back(id); m_removeGameList.push_back(id);
} }
TimerManager &
ServerLobbyThread::GetTimerManager()
{
return m_timerManager;
}
AvatarManager & AvatarManager &
ServerLobbyThread::GetAvatarManager() ServerLobbyThread::GetAvatarManager()
{ {
@@ -564,12 +570,22 @@ ServerLobbyThread::RegisterTimers()
void void
ServerLobbyThread::HandleRead(SessionId sessionId, const boost::system::error_code& error, size_t bytesRead) ServerLobbyThread::HandleRead(SessionId sessionId, const boost::system::error_code& error, size_t bytesRead)
{ {
// Find the session.
SessionWrapper session = m_sessionManager.GetSessionById(sessionId); SessionWrapper session = m_sessionManager.GetSessionById(sessionId);
if (!session.sessionData) if (!session.sessionData)
session = m_gameSessionManager.GetSessionById(sessionId); session = m_gameSessionManager.GetSessionById(sessionId);
if (session.sessionData) if (session.sessionData)
{ {
// Retrieve current game, if applicable.
unsigned gameId = session.sessionData->GetGameId(); unsigned gameId = session.sessionData->GetGameId();
boost::shared_ptr<ServerGameThread> game;
if (gameId)
{
GameMap::iterator pos = m_gameMap.find(gameId);
if (pos != m_gameMap.end())
game = pos->second;
}
if (!error) if (!error)
{ {
@@ -581,10 +597,11 @@ ServerLobbyThread::HandleRead(SessionId sessionId, const boost::system::error_co
{ {
boost::shared_ptr<NetPacket> packet = buf.receivedPackets.front(); boost::shared_ptr<NetPacket> packet = buf.receivedPackets.front();
buf.receivedPackets.pop_front(); buf.receivedPackets.pop_front();
// if (game) if (game)
// game->HandlePacket(session, packet); game->HandlePacket(session, packet);
// else else
HandlePacket(session, packet); HandlePacket(session, packet);
// TODO state may have changed between.
} }
session.sessionData->GetAsioSocket()->async_read_some( session.sessionData->GetAsioSocket()->async_read_some(
boost::asio::buffer(buf.recvBuf + buf.recvBufUsed, RECV_BUF_SIZE - buf.recvBufUsed), boost::asio::buffer(buf.recvBuf + buf.recvBufUsed, RECV_BUF_SIZE - buf.recvBufUsed),
@@ -598,14 +615,6 @@ ServerLobbyThread::HandleRead(SessionId sessionId, const boost::system::error_co
else else
{ {
// On error: Close this session. // On error: Close this session.
boost::shared_ptr<ServerGameThread> game;
if (gameId)
{
GameMap::iterator pos = m_gameMap.find(gameId);
if (pos != m_gameMap.end())
game = pos->second;
}
if (game) if (game)
game->ErrorRemoveSession(session); game->ErrorRemoveSession(session);
else else
@@ -949,9 +958,6 @@ ServerLobbyThread::HandleNetPacketCreateGame(SessionWrapper session, const NetPa
// Add game to list of games. // Add game to list of games.
InternalAddGame(game); InternalAddGame(game);
// Start the game.
game->Run();
} }
void void
@@ -1055,15 +1061,16 @@ ServerLobbyThread::TimerRemoveGame()
RemoveGameList::iterator end = m_removeGameList.end(); RemoveGameList::iterator end = m_removeGameList.end();
// Synchronously remove games which have been closed. // Synchronously remove games which have been closed.
// TODO deprecated
while (i != end) while (i != end)
{ {
GameMap::iterator pos = m_gameMap.find(*i); GameMap::iterator pos = m_gameMap.find(*i);
if (pos != m_gameMap.end()) if (pos != m_gameMap.end())
{ {
boost::shared_ptr<ServerGameThread> tmpGame = pos->second; boost::shared_ptr<ServerGameThread> tmpGame = pos->second;
tmpGame->SignalTermination(); // tmpGame->SignalTermination();
if (!tmpGame->Join(GAME_THREAD_TERMINATE_TIMEOUT)) // if (!tmpGame->Join(GAME_THREAD_TERMINATE_TIMEOUT))
throw ServerException(__FILE__, __LINE__, ERR_NET_GAME_TERMINATION_FAILED, 0); // throw ServerException(__FILE__, __LINE__, ERR_NET_GAME_TERMINATION_FAILED, 0);
InternalRemoveGame(tmpGame); InternalRemoveGame(tmpGame);
} }
++i; ++i;
@@ -1241,13 +1248,14 @@ ServerLobbyThread::InternalResubscribeMsg(SessionWrapper session)
void void
ServerLobbyThread::TerminateGames() ServerLobbyThread::TerminateGames()
{ {
// TODO deprecated
GameMap::iterator i = m_gameMap.begin(); GameMap::iterator i = m_gameMap.begin();
GameMap::iterator end = m_gameMap.end(); GameMap::iterator end = m_gameMap.end();
while (i != end) while (i != end)
{ {
i->second->SignalTermination(); //i->second->SignalTermination();
i->second->Join(GAME_THREAD_TERMINATE_TIMEOUT); //i->second->Join(GAME_THREAD_TERMINATE_TIMEOUT);
++i; ++i;
} }
m_gameMap.clear(); m_gameMap.clear();
+58 -281
View File
@@ -1,5 +1,5 @@
/*************************************************************************** /***************************************************************************
* Copyright (C) 2007 by Lothar May * * Copyright (C) 2007-2009 by Lothar May *
* * * *
* This program is free software; you can redistribute it and/or modify * * This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by * * it under the terms of the GNU General Public License as published by *
@@ -16,7 +16,7 @@
* Free Software Foundation, Inc., * * Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/ ***************************************************************************/
/* State of network server. */ /* State of a network game. */
#ifndef _SERVERGAMESTATE_H_ #ifndef _SERVERGAMESTATE_H_
#define _SERVERGAMESTATE_H_ #define _SERVERGAMESTATE_H_
@@ -40,353 +40,130 @@ class ServerCallback;
class ServerGameState class ServerGameState
{ {
public: public:
ServerGameState(ServerGameThread &serverGame) : m_serverGame(serverGame) {}
virtual ~ServerGameState(); virtual ~ServerGameState();
// Initialize after switching to this state. virtual void NotifyGameAdminChanged() = 0;
virtual void Init(ServerGameThread &server) = 0;
virtual void NotifyGameAdminChanged(ServerGameThread &server) = 0;
// Handling of a new session. // Handling of a new session.
virtual void HandleNewSession(ServerGameThread &server, SessionWrapper session) = 0; virtual void HandleNewSession(SessionWrapper session) = 0;
// Main processing function of the current state. // Main processing function of the current state.
virtual int Process(ServerGameThread &server) = 0; virtual int ProcessPacket(SessionWrapper session, boost::shared_ptr<NetPacket> packet) = 0;
protected:
ServerGameThread &GetServerGame() {return m_serverGame;}
private:
ServerGameThread &m_serverGame;
}; };
// Abstract State: Receiving. // Abstract State: Receiving.
class AbstractServerGameStateReceiving : virtual public ServerGameState class AbstractServerGameStateReceiving : public ServerGameState
{ {
public: public:
AbstractServerGameStateReceiving(ServerGameThread &serverGame);
virtual ~AbstractServerGameStateReceiving(); virtual ~AbstractServerGameStateReceiving();
// Globally handle packets which are allowed in all running states. // Globally handle packets which are allowed in all running states.
// Calls InternalProcess if packet has not been processed. // Calls InternalProcess if packet has not been processed.
virtual int Process(ServerGameThread &server); virtual int ProcessPacket(SessionWrapper session, boost::shared_ptr<NetPacket> packet);
protected: protected:
AbstractServerGameStateReceiving(); virtual int InternalProcessPacket(SessionWrapper session, boost::shared_ptr<NetPacket> packet) = 0;
virtual int InternalProcess(ServerGameThread &server, SessionWrapper session, boost::shared_ptr<NetPacket> packet) = 0;
};
// Abstract State: Game is running.
class AbstractServerGameStateRunning : virtual public ServerGameState
{
public:
virtual ~AbstractServerGameStateRunning();
virtual void NotifyGameAdminChanged(ServerGameThread &/*server*/) {}
// Reject new connections.
virtual void HandleNewSession(ServerGameThread &server, SessionWrapper session);
protected:
AbstractServerGameStateRunning();
};
// Abstract State: Timer.
class AbstractServerGameStateTimer : virtual public ServerGameState
{
public:
virtual ~AbstractServerGameStateTimer();
virtual void Init(ServerGameThread &server);
}; };
// State: Initialization. // State: Initialization.
class ServerGameStateInit : public AbstractServerGameStateReceiving, public AbstractServerGameStateTimer class ServerGameStateInit : public AbstractServerGameStateReceiving
{ {
public: public:
// Access the state singleton. ServerGameStateInit(ServerGameThread &serverGame);
static ServerGameStateInit &Instance();
virtual ~ServerGameStateInit(); virtual ~ServerGameStateInit();
virtual void NotifyGameAdminChanged(ServerGameThread &server); virtual void NotifyGameAdminChanged();
// virtual void HandleNewSession(SessionWrapper session);
virtual int Process(ServerGameThread &server);
virtual void HandleNewSession(ServerGameThread &server, SessionWrapper session);
protected: protected:
// Protected constructor - this is a singleton. void RegisterAdminTimers();
ServerGameStateInit(); void UnregisterAdminTimers();
void TimerAdminWarning();
void TimerAdminTimeout();
virtual int InternalProcess(ServerGameThread &server, SessionWrapper session, boost::shared_ptr<NetPacket> packet); virtual int InternalProcessPacket(SessionWrapper session, boost::shared_ptr<NetPacket> packet);
static boost::shared_ptr<NetPacket> CreateNetPacketPlayerJoined(const PlayerData &playerData); static boost::shared_ptr<NetPacket> CreateNetPacketPlayerJoined(const PlayerData &playerData);
private: private:
static ServerGameStateInit m_state; unsigned m_adminWarningTimerId;
unsigned m_adminTimeoutTimerId;
bool m_timerRegistered;
}; };
// Wait for Ack of start event. // Wait for Ack of start event and start game.
class ServerGameStateWaitAck : public AbstractServerGameStateReceiving, public AbstractServerGameStateRunning, public AbstractServerGameStateTimer class ServerGameStateStartGame : public AbstractServerGameStateReceiving
{ {
public: public:
// Access the state singleton.
static ServerGameStateWaitAck &Instance();
virtual ~ServerGameStateWaitAck();
// Timeout if waiting takes too long.
virtual int Process(ServerGameThread &server);
protected:
// Protected constructor - this is a singleton.
ServerGameStateWaitAck();
virtual int InternalProcess(ServerGameThread &server, SessionWrapper session, boost::shared_ptr<NetPacket> packet);
private:
static ServerGameStateWaitAck m_state;
};
// State: Start server game.
class ServerGameStateStartGame : public AbstractServerGameStateRunning
{
public:
// Access the state singleton.
static ServerGameStateStartGame &Instance();
ServerGameStateStartGame(ServerGameThread &serverGame);
virtual ~ServerGameStateStartGame(); virtual ~ServerGameStateStartGame();
virtual void Init(ServerGameThread & /*server*/) {} virtual void NotifyGameAdminChanged() {}
virtual void HandleNewSession(SessionWrapper session);
//
virtual int Process(ServerGameThread &server);
protected: protected:
// Protected constructor - this is a singleton. virtual int InternalProcessPacket(SessionWrapper session, boost::shared_ptr<NetPacket> packet);
ServerGameStateStartGame(); void TimerTimeout();
void DoStart();
private: private:
unsigned m_timeoutTimerId;
static ServerGameStateStartGame m_state;
}; };
// State: Start new hand. // State: Within hand.
class ServerGameStateStartHand : public AbstractServerGameStateRunning class ServerGameStateHand : public AbstractServerGameStateReceiving
{ {
public: public:
// Access the state singleton. ServerGameStateHand(ServerGameThread &serverGame);
static ServerGameStateStartHand &Instance(); virtual ~ServerGameStateHand();
virtual ~ServerGameStateStartHand(); virtual void NotifyGameAdminChanged() {}
virtual void HandleNewSession(SessionWrapper session);
virtual void Init(ServerGameThread & /*server*/) {}
//
virtual int Process(ServerGameThread &server);
protected: protected:
virtual int InternalProcessPacket(SessionWrapper session, boost::shared_ptr<NetPacket> packet);
// Protected constructor - this is a singleton. void TimerLoop();
ServerGameStateStartHand(); void TimerShowCards();
void TimerComputerAction();
void TimerNextHand();
void TimerNextGame();
int GetDealCardsDelaySec();
private: private:
unsigned m_loopTimerId;
static ServerGameStateStartHand m_state;
};
// State: Start new round.
class ServerGameStateStartRound : public AbstractServerGameStateRunning
{
public:
// Access the state singleton.
static ServerGameStateStartRound &Instance();
virtual ~ServerGameStateStartRound();
virtual void Init(ServerGameThread & /*server*/) {}
//
virtual int Process(ServerGameThread &server);
protected:
// Protected constructor - this is a singleton.
ServerGameStateStartRound();
private:
static ServerGameStateStartRound m_state;
}; };
// State: Wait for a player action. // State: Wait for a player action.
class ServerGameStateWaitPlayerAction : public AbstractServerGameStateReceiving, public AbstractServerGameStateRunning, public AbstractServerGameStateTimer class ServerGameStateWaitPlayerAction : public AbstractServerGameStateReceiving
{ {
public: public:
// Access the state singleton. ServerGameStateWaitPlayerAction(ServerGameThread &serverGame);
static ServerGameStateWaitPlayerAction &Instance();
virtual ~ServerGameStateWaitPlayerAction(); virtual ~ServerGameStateWaitPlayerAction();
// Handle leaving players. virtual void NotifyGameAdminChanged() {}
virtual int Process(ServerGameThread &server); virtual void HandleNewSession(SessionWrapper session);
protected: protected:
// Protected constructor - this is a singleton. virtual int InternalProcessPacket(SessionWrapper session, boost::shared_ptr<NetPacket> packet);
ServerGameStateWaitPlayerAction(); void TimerTimeout();
virtual int InternalProcess(ServerGameThread &server, SessionWrapper session, boost::shared_ptr<NetPacket> packet);
static void PerformPlayerAction(ServerGameThread &server, boost::shared_ptr<PlayerInterface> player, PlayerAction action, int bet);
private: private:
unsigned m_timeoutTimerId;
static ServerGameStateWaitPlayerAction m_state;
};
// State: Delay and computer action
class ServerGameStateComputerAction : public AbstractServerGameStateReceiving, public AbstractServerGameStateRunning, public AbstractServerGameStateTimer
{
public:
// Access the state singleton.
static ServerGameStateComputerAction &Instance();
virtual ~ServerGameStateComputerAction();
// Overwrite default processing
virtual int Process(ServerGameThread &server);
protected:
// Protected constructor - this is a singleton.
ServerGameStateComputerAction();
virtual int InternalProcess(ServerGameThread &server, SessionWrapper session, boost::shared_ptr<NetPacket> packet);
private:
static ServerGameStateComputerAction m_state;
};
// State: Delay after dealing cards
class ServerGameStateDealCardsDelay : public AbstractServerGameStateReceiving, public AbstractServerGameStateRunning, public AbstractServerGameStateTimer
{
public:
// Access the state singleton.
static ServerGameStateDealCardsDelay &Instance();
virtual ~ServerGameStateDealCardsDelay();
// Overwrite default processing
virtual int Process(ServerGameThread &server);
protected:
// Protected constructor - this is a singleton.
ServerGameStateDealCardsDelay();
virtual int InternalProcess(ServerGameThread &server, SessionWrapper session, boost::shared_ptr<NetPacket> packet);
private:
static ServerGameStateDealCardsDelay m_state;
};
// State: Delay after showing cards (all in)
class ServerGameStateShowCardsDelay : public AbstractServerGameStateReceiving, public AbstractServerGameStateRunning, public AbstractServerGameStateTimer
{
public:
// Access the state singleton.
static ServerGameStateShowCardsDelay &Instance();
virtual ~ServerGameStateShowCardsDelay();
// Overwrite default processing
virtual int Process(ServerGameThread &server);
protected:
// Protected constructor - this is a singleton.
ServerGameStateShowCardsDelay();
virtual int InternalProcess(ServerGameThread &server, SessionWrapper session, boost::shared_ptr<NetPacket> packet);
private:
static ServerGameStateShowCardsDelay m_state;
};
// State: Delay before next hand.
class ServerGameStateNextHandDelay : public AbstractServerGameStateReceiving, public AbstractServerGameStateRunning, public AbstractServerGameStateTimer
{
public:
// Access the state singleton.
static ServerGameStateNextHandDelay &Instance();
virtual ~ServerGameStateNextHandDelay();
// Overwrite default processing
virtual int Process(ServerGameThread &server);
protected:
// Protected constructor - this is a singleton.
ServerGameStateNextHandDelay();
virtual int InternalProcess(ServerGameThread &server, SessionWrapper session, boost::shared_ptr<NetPacket> packet);
private:
static ServerGameStateNextHandDelay m_state;
};
// State: Delay before next hand.
class ServerGameStateNextGameDelay : public AbstractServerGameStateReceiving, public AbstractServerGameStateRunning, public AbstractServerGameStateTimer
{
public:
// Access the state singleton.
static ServerGameStateNextGameDelay &Instance();
virtual ~ServerGameStateNextGameDelay();
// Overwrite default processing
virtual int Process(ServerGameThread &server);
protected:
// Protected constructor - this is a singleton.
ServerGameStateNextGameDelay();
virtual int InternalProcess(ServerGameThread &server, SessionWrapper session, boost::shared_ptr<NetPacket> packet);
private:
static ServerGameStateNextGameDelay m_state;
};
// State: Final.
class ServerGameStateFinal : public AbstractServerGameStateReceiving, public AbstractServerGameStateRunning
{
public:
// Access the state singleton.
static ServerGameStateFinal &Instance();
virtual ~ServerGameStateFinal();
virtual void Init(ServerGameThread & /*server*/) {}
protected:
// Protected constructor - this is a singleton.
ServerGameStateFinal();
virtual int InternalProcess(ServerGameThread &server, SessionWrapper session, boost::shared_ptr<NetPacket> packet);
private:
static ServerGameStateFinal m_state;
}; };
#ifdef _MSC_VER #ifdef _MSC_VER
+11 -25
View File
@@ -39,7 +39,7 @@ class ConfigFile;
struct GameData; struct GameData;
class Game; class Game;
class ServerGameThread : public Thread class ServerGameThread
{ {
public: public:
ServerGameThread( ServerGameThread(
@@ -52,6 +52,8 @@ public:
void AddSession(SessionWrapper session); void AddSession(SessionWrapper session);
void RemovePlayer(unsigned playerId, unsigned errorCode); void RemovePlayer(unsigned playerId, unsigned errorCode);
void HandlePacket(SessionWrapper session, boost::shared_ptr<NetPacket> packet);
ServerCallback &GetCallback(); ServerCallback &GetCallback();
GameState GetCurRound() const; GameState GetCurRound() const;
@@ -79,11 +81,8 @@ protected:
typedef std::deque<SessionWrapper> SessionQueue; typedef std::deque<SessionWrapper> SessionQueue;
// Main function of the thread. void TimerRemovePlayer();
virtual void Main(); void TimerVoteKick();
void RemovePlayerLoop();
void VoteKickLoop();
void VoteKickAction();
void InternalStartGame(); void InternalStartGame();
void ResetGame(); void ResetGame();
@@ -115,12 +114,7 @@ protected:
ServerLobbyThread &GetLobbyThread(); ServerLobbyThread &GetLobbyThread();
ServerGameState &GetState(); ServerGameState &GetState();
void SetState(ServerGameState &newState); void SetState(boost::shared_ptr<ServerGameState> newState);
const boost::timers::portable::microsec_timer &GetStateTimer() const;
boost::timers::portable::microsec_timer &GetStateTimer();
unsigned GetStateTimerFlag() const;
void SetStateTimerFlag(unsigned flag);
ReceiverHelper &GetReceiver(); ReceiverHelper &GetReceiver();
@@ -159,34 +153,26 @@ private:
const GameData m_gameData; const GameData m_gameData;
StartData m_startData; StartData m_startData;
boost::shared_ptr<Game> m_game; boost::shared_ptr<Game> m_game;
boost::shared_ptr<ServerGameState> m_curState;
const u_int32_t m_id; const u_int32_t m_id;
const std::string m_name; const std::string m_name;
const std::string m_password; const std::string m_password;
ConfigFile *m_playerConfig; ConfigFile *m_playerConfig;
ServerGameState *m_curState;
unsigned m_gameNum; unsigned m_gameNum;
unsigned m_curPetitionId; unsigned m_curPetitionId;
unsigned m_removePlayerTimerId;
boost::timers::portable::microsec_timer m_stateTimer; unsigned m_voteKickTimerId;
unsigned m_stateTimerFlag;
boost::timers::portable::microsec_timer m_voteKickActionTimer; boost::timers::portable::microsec_timer m_voteKickActionTimer;
friend class ServerLobbyThread; friend class ServerLobbyThread;
friend class AbstractServerGameStateReceiving; friend class AbstractServerGameStateReceiving;
friend class AbstractServerGameStateRunning;
friend class AbstractServerGameStateTimer;
friend class ServerGameStateInit; friend class ServerGameStateInit;
friend class ServerGameStateWaitAck; friend class ServerGameStateWaitAck;
friend class ServerGameStateStartGame; friend class ServerGameStateStartGame;
friend class ServerGameStateStartHand; friend class ServerGameStateHand;
friend class ServerGameStateStartRound;
friend class ServerGameStateWaitPlayerAction; friend class ServerGameStateWaitPlayerAction;
friend class ServerGameStateComputerAction;
friend class ServerGameStateDealCardsDelay;
friend class ServerGameStateShowCardsDelay;
friend class ServerGameStateNextHandDelay;
friend class ServerGameStateNextGameDelay;
}; };
#endif #endif
+1
View File
@@ -90,6 +90,7 @@ public:
u_int32_t GetNextGameId(); u_int32_t GetNextGameId();
ServerCallback &GetCallback(); ServerCallback &GetCallback();
TimerManager &GetTimerManager();
AvatarManager &GetAvatarManager(); AvatarManager &GetAvatarManager();
ServerStats GetStats() const; ServerStats GetStats() const;