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_REMOVE_PLAYER_INTERVAL_MSEC 1000
#define SERVER_KICK_TIMEOUT_ADD_DELAY_SEC 2
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)
: 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_curState(NULL), 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)
m_gameNum(1), m_curPetitionId(1)
{
LOG_VERBOSE("Game object " << GetId() << " created.");
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()
{
GetLobbyThread().GetTimerManager().UnregisterTimer(m_removePlayerTimerId);
GetLobbyThread().GetTimerManager().UnregisterTimer(m_voteKickTimerId);
LOG_VERBOSE("Game object " << GetId() << " destructed.");
}
@@ -70,9 +83,8 @@ ServerGameThread::GetName() const
void
ServerGameThread::AddSession(SessionWrapper session)
{
// Must be thread safe.
boost::mutex::scoped_lock lock(m_sessionQueueMutex);
m_sessionQueue.push_back(session);
if (session.sessionData)
GetState().HandleNewSession(session);
}
void
@@ -82,6 +94,13 @@ ServerGameThread::RemovePlayer(unsigned playerId, unsigned 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
ServerGameThread::GetCurRound() const
{
@@ -111,50 +130,15 @@ ServerGameThread::RemoveAllSessions()
GetSessionManager().ForEach(boost::bind(&ServerLobbyThread::RemoveSessionFromGame, boost::ref(lobbyThread), _1));
}
void
ServerGameThread::Main()
{
LOG_VERBOSE("Game thread " << GetId() << " started.");
// TODO terminate game.
// TODO Handle game termination!
// ResetComputerPlayerList();
// GetLobbyThread().RemoveGame(GetId());
SetState(SERVER_INITIAL_STATE::Instance());
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.");
}
// LOG_VERBOSE("Game thread " << GetId() << " terminating.");
void
ServerGameThread::RemovePlayerLoop()
ServerGameThread::TimerRemovePlayer()
{
boost::mutex::scoped_lock lock(m_removePlayerListMutex);
@@ -173,16 +157,7 @@ ServerGameThread::RemovePlayerLoop()
}
void
ServerGameThread::VoteKickLoop()
{
// 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()
ServerGameThread::TimerVoteKick()
{
// Check whether someone should be kicked, or whether a vote kick should be aborted.
// 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());
newAdmin->SetRights(PLAYER_RIGHTS_ADMIN);
// Notify game state on admin change
GetState().NotifyGameAdminChanged(*this);
GetState().NotifyGameAdminChanged();
// Send "Game Admin Changed" to clients.
boost::shared_ptr<NetPacket> adminChanged(new NetPacketGameAdminChanged);
NetPacketGameAdminChanged::Data adminChangedData;
@@ -743,33 +718,9 @@ ServerGameThread::GetState()
}
void
ServerGameThread::SetState(ServerGameState &newState)
ServerGameThread::SetState(boost::shared_ptr<ServerGameState> newState)
{
newState.Init(*this);
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;
m_curState = newState;
}
ReceiverHelper &
+27 -19
View File
@@ -444,6 +444,12 @@ ServerLobbyThread::RemoveGame(unsigned id)
m_removeGameList.push_back(id);
}
TimerManager &
ServerLobbyThread::GetTimerManager()
{
return m_timerManager;
}
AvatarManager &
ServerLobbyThread::GetAvatarManager()
{
@@ -564,12 +570,22 @@ ServerLobbyThread::RegisterTimers()
void
ServerLobbyThread::HandleRead(SessionId sessionId, const boost::system::error_code& error, size_t bytesRead)
{
// Find the session.
SessionWrapper session = m_sessionManager.GetSessionById(sessionId);
if (!session.sessionData)
session = m_gameSessionManager.GetSessionById(sessionId);
if (session.sessionData)
{
// Retrieve current game, if applicable.
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)
{
@@ -581,10 +597,11 @@ ServerLobbyThread::HandleRead(SessionId sessionId, const boost::system::error_co
{
boost::shared_ptr<NetPacket> packet = buf.receivedPackets.front();
buf.receivedPackets.pop_front();
// if (game)
// game->HandlePacket(session, packet);
// else
if (game)
game->HandlePacket(session, packet);
else
HandlePacket(session, packet);
// TODO state may have changed between.
}
session.sessionData->GetAsioSocket()->async_read_some(
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
{
// 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)
game->ErrorRemoveSession(session);
else
@@ -949,9 +958,6 @@ ServerLobbyThread::HandleNetPacketCreateGame(SessionWrapper session, const NetPa
// Add game to list of games.
InternalAddGame(game);
// Start the game.
game->Run();
}
void
@@ -1055,15 +1061,16 @@ ServerLobbyThread::TimerRemoveGame()
RemoveGameList::iterator end = m_removeGameList.end();
// Synchronously remove games which have been closed.
// TODO deprecated
while (i != end)
{
GameMap::iterator pos = m_gameMap.find(*i);
if (pos != m_gameMap.end())
{
boost::shared_ptr<ServerGameThread> tmpGame = pos->second;
tmpGame->SignalTermination();
if (!tmpGame->Join(GAME_THREAD_TERMINATE_TIMEOUT))
throw ServerException(__FILE__, __LINE__, ERR_NET_GAME_TERMINATION_FAILED, 0);
// tmpGame->SignalTermination();
// if (!tmpGame->Join(GAME_THREAD_TERMINATE_TIMEOUT))
// throw ServerException(__FILE__, __LINE__, ERR_NET_GAME_TERMINATION_FAILED, 0);
InternalRemoveGame(tmpGame);
}
++i;
@@ -1241,13 +1248,14 @@ ServerLobbyThread::InternalResubscribeMsg(SessionWrapper session)
void
ServerLobbyThread::TerminateGames()
{
// TODO deprecated
GameMap::iterator i = m_gameMap.begin();
GameMap::iterator end = m_gameMap.end();
while (i != end)
{
i->second->SignalTermination();
i->second->Join(GAME_THREAD_TERMINATE_TIMEOUT);
//i->second->SignalTermination();
//i->second->Join(GAME_THREAD_TERMINATE_TIMEOUT);
++i;
}
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 *
* it under the terms of the GNU General Public License as published by *
@@ -16,7 +16,7 @@
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
/* State of network server. */
/* State of a network game. */
#ifndef _SERVERGAMESTATE_H_
#define _SERVERGAMESTATE_H_
@@ -40,353 +40,130 @@ class ServerCallback;
class ServerGameState
{
public:
ServerGameState(ServerGameThread &serverGame) : m_serverGame(serverGame) {}
virtual ~ServerGameState();
// Initialize after switching to this state.
virtual void Init(ServerGameThread &server) = 0;
virtual void NotifyGameAdminChanged(ServerGameThread &server) = 0;
virtual void NotifyGameAdminChanged() = 0;
// 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.
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.
class AbstractServerGameStateReceiving : virtual public ServerGameState
class AbstractServerGameStateReceiving : public ServerGameState
{
public:
AbstractServerGameStateReceiving(ServerGameThread &serverGame);
virtual ~AbstractServerGameStateReceiving();
// Globally handle packets which are allowed in all running states.
// Calls InternalProcess if packet has not been processed.
virtual int Process(ServerGameThread &server);
virtual int ProcessPacket(SessionWrapper session, boost::shared_ptr<NetPacket> packet);
protected:
AbstractServerGameStateReceiving();
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);
virtual int InternalProcessPacket(SessionWrapper session, boost::shared_ptr<NetPacket> packet) = 0;
};
// State: Initialization.
class ServerGameStateInit : public AbstractServerGameStateReceiving, public AbstractServerGameStateTimer
class ServerGameStateInit : public AbstractServerGameStateReceiving
{
public:
// Access the state singleton.
static ServerGameStateInit &Instance();
ServerGameStateInit(ServerGameThread &serverGame);
virtual ~ServerGameStateInit();
virtual void NotifyGameAdminChanged(ServerGameThread &server);
virtual void NotifyGameAdminChanged();
//
virtual int Process(ServerGameThread &server);
virtual void HandleNewSession(ServerGameThread &server, SessionWrapper session);
virtual void HandleNewSession(SessionWrapper session);
protected:
// Protected constructor - this is a singleton.
ServerGameStateInit();
void RegisterAdminTimers();
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);
private:
static ServerGameStateInit m_state;
unsigned m_adminWarningTimerId;
unsigned m_adminTimeoutTimerId;
bool m_timerRegistered;
};
// Wait for Ack of start event.
class ServerGameStateWaitAck : public AbstractServerGameStateReceiving, public AbstractServerGameStateRunning, public AbstractServerGameStateTimer
// Wait for Ack of start event and start game.
class ServerGameStateStartGame : public AbstractServerGameStateReceiving
{
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 void Init(ServerGameThread & /*server*/) {}
//
virtual int Process(ServerGameThread &server);
virtual void NotifyGameAdminChanged() {}
virtual void HandleNewSession(SessionWrapper session);
protected:
// Protected constructor - this is a singleton.
ServerGameStateStartGame();
virtual int InternalProcessPacket(SessionWrapper session, boost::shared_ptr<NetPacket> packet);
void TimerTimeout();
void DoStart();
private:
static ServerGameStateStartGame m_state;
unsigned m_timeoutTimerId;
};
// State: Start new hand.
class ServerGameStateStartHand : public AbstractServerGameStateRunning
// State: Within hand.
class ServerGameStateHand : public AbstractServerGameStateReceiving
{
public:
// Access the state singleton.
static ServerGameStateStartHand &Instance();
ServerGameStateHand(ServerGameThread &serverGame);
virtual ~ServerGameStateHand();
virtual ~ServerGameStateStartHand();
virtual void Init(ServerGameThread & /*server*/) {}
//
virtual int Process(ServerGameThread &server);
virtual void NotifyGameAdminChanged() {}
virtual void HandleNewSession(SessionWrapper session);
protected:
// Protected constructor - this is a singleton.
ServerGameStateStartHand();
virtual int InternalProcessPacket(SessionWrapper session, boost::shared_ptr<NetPacket> packet);
void TimerLoop();
void TimerShowCards();
void TimerComputerAction();
void TimerNextHand();
void TimerNextGame();
int GetDealCardsDelaySec();
private:
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;
unsigned m_loopTimerId;
};
// State: Wait for a player action.
class ServerGameStateWaitPlayerAction : public AbstractServerGameStateReceiving, public AbstractServerGameStateRunning, public AbstractServerGameStateTimer
class ServerGameStateWaitPlayerAction : public AbstractServerGameStateReceiving
{
public:
// Access the state singleton.
static ServerGameStateWaitPlayerAction &Instance();
ServerGameStateWaitPlayerAction(ServerGameThread &serverGame);
virtual ~ServerGameStateWaitPlayerAction();
// Handle leaving players.
virtual int Process(ServerGameThread &server);
virtual void NotifyGameAdminChanged() {}
virtual void HandleNewSession(SessionWrapper session);
protected:
// Protected constructor - this is a singleton.
ServerGameStateWaitPlayerAction();
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);
virtual int InternalProcessPacket(SessionWrapper session, boost::shared_ptr<NetPacket> packet);
void TimerTimeout();
private:
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;
unsigned m_timeoutTimerId;
};
#ifdef _MSC_VER
+11 -25
View File
@@ -39,7 +39,7 @@ class ConfigFile;
struct GameData;
class Game;
class ServerGameThread : public Thread
class ServerGameThread
{
public:
ServerGameThread(
@@ -52,6 +52,8 @@ public:
void AddSession(SessionWrapper session);
void RemovePlayer(unsigned playerId, unsigned errorCode);
void HandlePacket(SessionWrapper session, boost::shared_ptr<NetPacket> packet);
ServerCallback &GetCallback();
GameState GetCurRound() const;
@@ -79,11 +81,8 @@ protected:
typedef std::deque<SessionWrapper> SessionQueue;
// Main function of the thread.
virtual void Main();
void RemovePlayerLoop();
void VoteKickLoop();
void VoteKickAction();
void TimerRemovePlayer();
void TimerVoteKick();
void InternalStartGame();
void ResetGame();
@@ -115,12 +114,7 @@ protected:
ServerLobbyThread &GetLobbyThread();
ServerGameState &GetState();
void SetState(ServerGameState &newState);
const boost::timers::portable::microsec_timer &GetStateTimer() const;
boost::timers::portable::microsec_timer &GetStateTimer();
unsigned GetStateTimerFlag() const;
void SetStateTimerFlag(unsigned flag);
void SetState(boost::shared_ptr<ServerGameState> newState);
ReceiverHelper &GetReceiver();
@@ -159,34 +153,26 @@ private:
const GameData m_gameData;
StartData m_startData;
boost::shared_ptr<Game> m_game;
boost::shared_ptr<ServerGameState> m_curState;
const u_int32_t m_id;
const std::string m_name;
const std::string m_password;
ConfigFile *m_playerConfig;
ServerGameState *m_curState;
unsigned m_gameNum;
unsigned m_curPetitionId;
boost::timers::portable::microsec_timer m_stateTimer;
unsigned m_stateTimerFlag;
unsigned m_removePlayerTimerId;
unsigned m_voteKickTimerId;
boost::timers::portable::microsec_timer m_voteKickActionTimer;
friend class ServerLobbyThread;
friend class AbstractServerGameStateReceiving;
friend class AbstractServerGameStateRunning;
friend class AbstractServerGameStateTimer;
friend class ServerGameStateInit;
friend class ServerGameStateWaitAck;
friend class ServerGameStateStartGame;
friend class ServerGameStateStartHand;
friend class ServerGameStateStartRound;
friend class ServerGameStateHand;
friend class ServerGameStateWaitPlayerAction;
friend class ServerGameStateComputerAction;
friend class ServerGameStateDealCardsDelay;
friend class ServerGameStateShowCardsDelay;
friend class ServerGameStateNextHandDelay;
friend class ServerGameStateNextGameDelay;
};
#endif
+1
View File
@@ -90,6 +90,7 @@ public:
u_int32_t GetNextGameId();
ServerCallback &GetCallback();
TimerManager &GetTimerManager();
AvatarManager &GetAvatarManager();
ServerStats GetStats() const;