More work on server redesign. Network mode still broken.

This commit is contained in:
lotodore
2007-08-20 15:30:22 +00:00
parent 7a1c1188b8
commit 9d63df9218
16 changed files with 1143 additions and 666 deletions
+6 -1
View File
@@ -114,7 +114,12 @@ Game::~Game()
}
HandInterface * Game::getCurrentHand()
HandInterface *Game::getCurrentHand()
{
return actualHand;
}
const HandInterface *Game::getCurrentHand() const
{
return actualHand;
}
+1
View File
@@ -48,6 +48,7 @@ public:
void startHand();
HandInterface *getCurrentHand();
const HandInterface *getCurrentHand() const;
std::vector<boost::shared_ptr<PlayerInterface> > getPlayerArray() {return playerArray;}
+1 -2
View File
@@ -42,8 +42,7 @@ ServerAcceptThread::~ServerAcceptThread()
}
void
ServerAcceptThread::Init(unsigned serverPort, bool ipv6, bool sctp, const std::string &pwd,
const GameData &gameData)
ServerAcceptThread::Init(unsigned serverPort, bool ipv6, bool sctp, const std::string &pwd)
{
if (IsRunning())
return; // TODO: throw exception
@@ -17,8 +17,8 @@
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#include <net/serverrecvstate.h>
#include <net/serverrecvthread.h>
#include <net/servergamestate.h>
#include <net/servergamethread.h>
#include <net/receiverhelper.h>
#include <net/senderthread.h>
#include <net/netpacket.h>
@@ -50,14 +50,13 @@ using namespace std;
// Helper functions
// TODO: these are hacks.
static void SendPlayerAction(ServerRecvThread &server, boost::shared_ptr<PlayerInterface> player)
static void SendPlayerAction(ServerGameThread &server, boost::shared_ptr<PlayerInterface> player)
{
Game &curGame = server.GetGame();
assert(player);
boost::shared_ptr<NetPacket> notifyActionDone(new NetPacketPlayersActionDone);
NetPacketPlayersActionDone::Data actionDoneData;
actionDoneData.gameState = static_cast<GameState>(curGame.getCurrentHand()->getActualRound());
actionDoneData.gameState = server.GetCurRound();
actionDoneData.playerId = player->getMyUniqueID();
actionDoneData.playerAction = static_cast<PlayerAction>(player->getMyAction());
actionDoneData.totalPlayerBet = player->getMySet();
@@ -66,7 +65,7 @@ static void SendPlayerAction(ServerRecvThread &server, boost::shared_ptr<PlayerI
server.SendToAllPlayers(notifyActionDone);
}
static void SendNewRoundCards(ServerRecvThread &server, Game &curGame, int state)
static void SendNewRoundCards(ServerGameThread &server, Game &curGame, int state)
{
// TODO: no switch needed here if game states are polymorphic
switch(state) {
@@ -112,39 +111,34 @@ static void SendNewRoundCards(ServerRecvThread &server, Game &curGame, int state
//-----------------------------------------------------------------------------
ServerRecvState::~ServerRecvState()
ServerGameState::~ServerGameState()
{
}
//-----------------------------------------------------------------------------
AbstractServerRecvStateReceiving::AbstractServerRecvStateReceiving()
AbstractServerGameStateReceiving::AbstractServerGameStateReceiving()
{
}
AbstractServerRecvStateReceiving::~AbstractServerRecvStateReceiving()
AbstractServerGameStateReceiving::~AbstractServerGameStateReceiving()
{
}
int
AbstractServerRecvStateReceiving::Process(ServerRecvThread &server)
AbstractServerGameStateReceiving::Process(ServerGameThread &server)
{
// This is the receive loop for the server.
int retVal = MSG_SOCK_INTERNAL_PENDING;
SOCKET recvSock = server.Select();
SessionWrapper session = server.GetSessionManager().Select(RECV_TIMEOUT_MSEC);
if (recvSock != INVALID_SOCKET)
if (session.sessionData.get())
{
// If data is available, find the corresponding session.
SessionWrapper session = server.GetSession(recvSock);
// The session must exist.
assert(session.sessionData.get());
boost::shared_ptr<NetPacket> packet;
try
{
// Receive the packet.
packet = server.GetReceiver().Recv(recvSock);
packet = server.GetReceiver().Recv(session.sessionData->GetSocket());
} catch (const NetException &)
{
server.CloseSessionDelayed(session);
@@ -184,16 +178,16 @@ AbstractServerRecvStateReceiving::Process(ServerRecvThread &server)
//-----------------------------------------------------------------------------
AbstractServerRecvStateTimer::AbstractServerRecvStateTimer()
AbstractServerGameStateTimer::AbstractServerGameStateTimer()
{
}
AbstractServerRecvStateTimer::~AbstractServerRecvStateTimer()
AbstractServerGameStateTimer::~AbstractServerGameStateTimer()
{
}
void
AbstractServerRecvStateTimer::Init()
AbstractServerGameStateTimer::Init()
{
m_timer.reset();
m_timer.start();
@@ -201,139 +195,74 @@ AbstractServerRecvStateTimer::Init()
//-----------------------------------------------------------------------------
boost::thread_specific_ptr<ServerRecvStateInit> ServerRecvStateInit::Ptr;
boost::thread_specific_ptr<ServerGameStateInit> ServerGameStateInit::Ptr;
ServerRecvStateInit &
ServerRecvStateInit::Instance()
ServerGameStateInit &
ServerGameStateInit::Instance()
{
if (!Ptr.get())
Ptr.reset(new ServerRecvStateInit);
Ptr.reset(new ServerGameStateInit);
return *Ptr;
}
ServerRecvStateInit::ServerRecvStateInit()
ServerGameStateInit::ServerGameStateInit()
: m_curUniquePlayerId(0)
{
}
ServerRecvStateInit::~ServerRecvStateInit()
ServerGameStateInit::~ServerGameStateInit()
{
}
void
ServerRecvStateInit::HandleNewConnection(ServerRecvThread &server, boost::shared_ptr<ConnectData> connData)
ServerGameStateInit::HandleNewSession(ServerGameThread &server, SessionWrapper session)
{
// Create a random session id.
// This id can be used to reconnect to the server if the connection was lost.
unsigned sessionId;
RandomBytes((unsigned char *)&sessionId, sizeof(sessionId)); // TODO: check for collisions.
// Create a new session.
boost::shared_ptr<SessionData> sessionData(new SessionData(connData->ReleaseSocket(), sessionId));
server.AddSession(sessionData);
}
int
ServerRecvStateInit::InternalProcess(ServerRecvThread &server, SessionWrapper session, boost::shared_ptr<NetPacket> packet)
{
int retVal = MSG_SOCK_INIT_DONE;
if (packet->ToNetPacketJoinGame())
if (session.sessionData.get() && session.playerData.get())
{
// Session should be in initial state.
if (session.sessionData->GetState() != SessionData::Init)
{
server.SessionError(session, ERR_SOCK_INVALID_STATE);
return retVal;
}
const NetPacketJoinGame *tmpPacket = packet->ToNetPacketJoinGame();
NetPacketJoinGame::Data joinGameData;
tmpPacket->GetData(joinGameData);
// Check the protocol version.
if (joinGameData.versionMajor != NET_VERSION_MAJOR)
{
server.SessionError(session, ERR_NET_VERSION_NOT_SUPPORTED);
return retVal;
}
size_t curNumPlayers = server.GetCurNumberOfPlayers();
// Check the number of players.
if (curNumPlayers >= (size_t)server.GetGameData().maxNumberOfPlayers)
{
server.SessionError(session, ERR_NET_SERVER_FULL);
return retVal;
}
// Check the server password.
if (!server.CheckPassword(joinGameData.password))
else
{
server.SessionError(session, ERR_NET_INVALID_PASSWORD);
return retVal;
if (curNumPlayers == 0)
{
// First player is admin.
session.playerData->SetRights(PLAYER_RIGHTS_ADMIN);
}
else
{
// Send notifications for connected players to client.
PlayerDataList tmpPlayerList = server.GetSessionManager().GetPlayerDataList();
PlayerDataList::iterator player_i = tmpPlayerList.begin();
PlayerDataList::iterator player_end = tmpPlayerList.end();
while (player_i != player_end)
{
server.GetSender().Send(session.sessionData->GetSocket(), CreateNetPacketPlayerJoined(*(*player_i)));
++player_i;
}
// Send "Player Joined" to other fully connected clients.
server.SendToAllPlayers(CreateNetPacketPlayerJoined(*session.playerData));
}
// Session is now in game state.
session.sessionData->SetState(SessionData::Game);
// Accept session.
server.GetSessionManager().AddSession(session);
}
// Check whether the player name is correct.
// Partly, this is also done in netpacket.
// However, some disallowed names are checked only here.
if (joinGameData.playerName.empty() || joinGameData.playerName.size() > MAX_NAME_SIZE
|| joinGameData.playerName.substr(0, sizeof(SERVER_COMPUTER_PLAYER_NAME) - 1) == SERVER_COMPUTER_PLAYER_NAME)
{
server.SessionError(session, ERR_NET_INVALID_PLAYER_NAME);
return retVal;
}
// Check whether this player is already connected.
if (server.IsPlayerConnected(joinGameData.playerName))
{
server.SessionError(session, ERR_NET_PLAYER_NAME_IN_USE);
return retVal;
}
// Create player data object.
// TODO HACK first player is admin
PlayerRights rights = PLAYER_RIGHTS_NORMAL;
if (server.GetCurNumberOfPlayers() == 0)
rights = PLAYER_RIGHTS_ADMIN;
boost::shared_ptr<PlayerData> tmpPlayerData(
new PlayerData(m_curUniquePlayerId++, 0, PLAYER_TYPE_HUMAN, rights));
tmpPlayerData->SetName(joinGameData.playerName);
tmpPlayerData->SetNetSessionData(session.sessionData);
// Send ACK to client.
boost::shared_ptr<NetPacket> answer(new NetPacketJoinGameAck);
NetPacketJoinGameAck::Data joinGameAckData;
joinGameAckData.sessionId = session.sessionData->GetId(); // TODO: currently unused.
joinGameAckData.yourPlayerUniqueId = tmpPlayerData->GetUniqueId();
joinGameAckData.gameData = server.GetGameData();
joinGameAckData.ptype = tmpPlayerData->GetType();
joinGameAckData.prights = tmpPlayerData->GetRights();
static_cast<NetPacketJoinGameAck *>(answer.get())->SetData(joinGameAckData);
server.GetSender().Send(session.sessionData->GetSocket(), answer);
// Send notifications for connected players to client.
PlayerDataList tmpPlayerList = server.GetPlayerDataList();
PlayerDataList::iterator player_i = tmpPlayerList.begin();
PlayerDataList::iterator player_end = tmpPlayerList.end();
while (player_i != player_end)
{
server.GetSender().Send(session.sessionData->GetSocket(), CreateNetPacketPlayerJoined(*(*player_i)));
++player_i;
}
// Send "Player Joined" to other fully connected clients.
server.SendToAllPlayers(CreateNetPacketPlayerJoined(*tmpPlayerData));
// Set player data for session.
server.SetSessionPlayerData(session.sessionData, tmpPlayerData);
// Session is now established.
session.sessionData->SetState(SessionData::Established);
}
else if (packet->ToNetPacketStartEvent())
}
int
ServerGameStateInit::InternalProcess(ServerGameThread &server, SessionWrapper session, boost::shared_ptr<NetPacket> packet)
{
int retVal = MSG_SOCK_INIT_DONE;
if (packet->ToNetPacketStartEvent())
{
server.ResetComputerPlayerList();
int remainingSlots = server.GetGameData().maxNumberOfPlayers - server.GetCurNumberOfPlayers();
@@ -370,7 +299,7 @@ ServerRecvStateInit::InternalProcess(ServerRecvThread &server, SessionWrapper se
}
boost::shared_ptr<NetPacket>
ServerRecvStateInit::CreateNetPacketPlayerJoined(const PlayerData &playerData)
ServerGameStateInit::CreateNetPacketPlayerJoined(const PlayerData &playerData)
{
boost::shared_ptr<NetPacket> thisPlayerJoined(new NetPacketPlayerJoined);
NetPacketPlayerJoined::Data thisPlayerJoinedData;
@@ -384,44 +313,44 @@ ServerRecvStateInit::CreateNetPacketPlayerJoined(const PlayerData &playerData)
//-----------------------------------------------------------------------------
AbstractServerRecvStateRunning::AbstractServerRecvStateRunning()
AbstractServerGameStateRunning::AbstractServerGameStateRunning()
{
}
AbstractServerRecvStateRunning::~AbstractServerRecvStateRunning()
AbstractServerGameStateRunning::~AbstractServerGameStateRunning()
{
}
void
AbstractServerRecvStateRunning::HandleNewConnection(ServerRecvThread &server, boost::shared_ptr<ConnectData> connData)
AbstractServerGameStateRunning::HandleNewSession(ServerGameThread &server, SessionWrapper session)
{
// Do not accept new connections in this state.
server.RejectNewConnection(connData);
// Do not accept new sessions in this state.
server.RejectSession(session);
}
//-----------------------------------------------------------------------------
boost::thread_specific_ptr<ServerRecvStateStartGame> ServerRecvStateStartGame::Ptr;
boost::thread_specific_ptr<ServerGameStateStartGame> ServerGameStateStartGame::Ptr;
ServerRecvStateStartGame &
ServerRecvStateStartGame::Instance()
ServerGameStateStartGame &
ServerGameStateStartGame::Instance()
{
if (!Ptr.get())
Ptr.reset(new ServerRecvStateStartGame);
Ptr.reset(new ServerGameStateStartGame);
return *Ptr;
}
ServerRecvStateStartGame::ServerRecvStateStartGame()
ServerGameStateStartGame::ServerGameStateStartGame()
{
}
ServerRecvStateStartGame::~ServerRecvStateStartGame()
ServerGameStateStartGame::~ServerGameStateStartGame()
{
}
int
ServerRecvStateStartGame::Process(ServerRecvThread &server)
ServerGameStateStartGame::Process(ServerGameThread &server)
{
boost::shared_ptr<NetPacket> answer(new NetPacketGameStart);
@@ -430,7 +359,7 @@ ServerRecvStateStartGame::Process(ServerRecvThread &server)
// Send player order to clients.
// Assume player list is sorted by number.
PlayerDataList tmpPlayerList = server.GetPlayerDataList();
PlayerDataList tmpPlayerList = server.GetSessionManager().GetPlayerDataList();
PlayerDataList::iterator player_i = tmpPlayerList.begin();
PlayerDataList::iterator player_end = tmpPlayerList.end();
while (player_i != player_end)
@@ -445,34 +374,34 @@ ServerRecvStateStartGame::Process(ServerRecvThread &server)
static_cast<NetPacketGameStart *>(answer.get())->SetData(gameStartData);
server.SendToAllPlayers(answer);
server.SetState(ServerRecvStateStartHand::Instance());
server.SetState(ServerGameStateStartHand::Instance());
return MSG_NET_GAME_SERVER_START;
}
//-----------------------------------------------------------------------------
boost::thread_specific_ptr<ServerRecvStateStartHand> ServerRecvStateStartHand::Ptr;
boost::thread_specific_ptr<ServerGameStateStartHand> ServerGameStateStartHand::Ptr;
ServerRecvStateStartHand &
ServerRecvStateStartHand::Instance()
ServerGameStateStartHand &
ServerGameStateStartHand::Instance()
{
if (!Ptr.get())
Ptr.reset(new ServerRecvStateStartHand);
Ptr.reset(new ServerGameStateStartHand);
return *Ptr;
}
ServerRecvStateStartHand::ServerRecvStateStartHand()
ServerGameStateStartHand::ServerGameStateStartHand()
{
}
ServerRecvStateStartHand::~ServerRecvStateStartHand()
ServerGameStateStartHand::~ServerGameStateStartHand()
{
}
int
ServerRecvStateStartHand::Process(ServerRecvThread &server)
ServerGameStateStartHand::Process(ServerGameThread &server)
{
boost::shared_ptr<NetPacket> answer(new NetPacketHandStart);
@@ -542,34 +471,34 @@ ServerRecvStateStartHand::Process(ServerRecvThread &server)
}
}
server.SetState(ServerRecvStateStartRound::Instance());
server.SetState(ServerGameStateStartRound::Instance());
return MSG_NET_GAME_SERVER_HAND_START;
}
//-----------------------------------------------------------------------------
boost::thread_specific_ptr<ServerRecvStateStartRound> ServerRecvStateStartRound::Ptr;
boost::thread_specific_ptr<ServerGameStateStartRound> ServerGameStateStartRound::Ptr;
ServerRecvStateStartRound &
ServerRecvStateStartRound::Instance()
ServerGameStateStartRound &
ServerGameStateStartRound::Instance()
{
if (!Ptr.get())
Ptr.reset(new ServerRecvStateStartRound);
Ptr.reset(new ServerGameStateStartRound);
return *Ptr;
}
ServerRecvStateStartRound::ServerRecvStateStartRound()
ServerGameStateStartRound::ServerGameStateStartRound()
{
}
ServerRecvStateStartRound::~ServerRecvStateStartRound()
ServerGameStateStartRound::~ServerGameStateStartRound()
{
}
int
ServerRecvStateStartRound::Process(ServerRecvThread &server)
ServerGameStateStartRound::Process(ServerGameThread &server)
{
int retVal = MSG_SOCK_INTERNAL_PENDING;
Game &curGame = server.GetGame();
@@ -616,14 +545,14 @@ ServerRecvStateStartRound::Process(ServerRecvThread &server)
server.SendToAllPlayers(allIn);
curGame.getCurrentHand()->setCardsShown(true);
server.SetState(ServerRecvStateShowCardsDelay::Instance());
server.SetState(ServerGameStateShowCardsDelay::Instance());
retVal = MSG_NET_GAME_SERVER_CARDS_DELAY;
}
else
{
SendNewRoundCards(server, curGame, newRound);
server.SetState(ServerRecvStateDealCardsDelay::Instance());
server.SetState(ServerGameStateDealCardsDelay::Instance());
retVal = MSG_NET_GAME_SERVER_CARDS_DELAY;
}
}
@@ -646,7 +575,7 @@ ServerRecvStateStartRound::Process(ServerRecvThread &server)
server.SendToAllPlayers(notification);
server.SetState(ServerRecvStateWaitPlayerAction::Instance());
server.SetState(ServerGameStateWaitPlayerAction::Instance());
retVal = MSG_NET_GAME_SERVER_ROUND;
}
@@ -722,12 +651,12 @@ ServerRecvStateStartRound::Process(ServerRecvThread &server)
if (playersPositiveCashCounter == 1)
{
// View a dialog for a new game - delayed.
server.SetState(ServerRecvStateNextGameDelay::Instance());
server.SetState(ServerGameStateNextGameDelay::Instance());
retVal = MSG_NET_GAME_SERVER_END;
}
else
{
server.SetState(ServerRecvStateNextHandDelay::Instance());
server.SetState(ServerGameStateNextHandDelay::Instance());
retVal = MSG_NET_GAME_SERVER_HAND_END;
}
}
@@ -736,7 +665,7 @@ ServerRecvStateStartRound::Process(ServerRecvThread &server)
}
std::list<boost::shared_ptr<PlayerInterface> >
ServerRecvStateStartRound::GetActivePlayers(Game &curGame)
ServerGameStateStartRound::GetActivePlayers(Game &curGame)
{
std::list<boost::shared_ptr<PlayerInterface> > activePlayers;
for (int i = 0; i < curGame.getStartQuantityPlayers() ; i++)
@@ -752,27 +681,27 @@ ServerRecvStateStartRound::GetActivePlayers(Game &curGame)
//-----------------------------------------------------------------------------
boost::thread_specific_ptr<ServerRecvStateWaitPlayerAction> ServerRecvStateWaitPlayerAction::Ptr;
boost::thread_specific_ptr<ServerGameStateWaitPlayerAction> ServerGameStateWaitPlayerAction::Ptr;
ServerRecvStateWaitPlayerAction &
ServerRecvStateWaitPlayerAction::Instance()
ServerGameStateWaitPlayerAction &
ServerGameStateWaitPlayerAction::Instance()
{
if (!Ptr.get())
Ptr.reset(new ServerRecvStateWaitPlayerAction);
Ptr.reset(new ServerGameStateWaitPlayerAction);
return *Ptr;
}
ServerRecvStateWaitPlayerAction::ServerRecvStateWaitPlayerAction()
ServerGameStateWaitPlayerAction::ServerGameStateWaitPlayerAction()
{
}
ServerRecvStateWaitPlayerAction::~ServerRecvStateWaitPlayerAction()
ServerGameStateWaitPlayerAction::~ServerGameStateWaitPlayerAction()
{
}
int
ServerRecvStateWaitPlayerAction::Process(ServerRecvThread &server)
ServerGameStateWaitPlayerAction::Process(ServerGameThread &server)
{
int retVal;
@@ -783,15 +712,15 @@ ServerRecvStateWaitPlayerAction::Process(ServerRecvThread &server)
// If the player is computer controlled, let the engine act.
if (tmpPlayer->getMyType() == PLAYER_TYPE_COMPUTER)
{
server.SetState(ServerRecvStateComputerAction::Instance());
server.SetState(ServerGameStateComputerAction::Instance());
retVal = MSG_SOCK_INTERNAL_PENDING;
}
// If the player we are waiting for left, continue without him.
else if (!server.IsPlayerConnected(tmpPlayer->getMyName()))
else if (!server.GetSessionManager().IsPlayerConnected(tmpPlayer->getMyName()))
{
PerformPlayerAction(server, tmpPlayer, PLAYER_ACTION_FOLD, 0);
server.SetState(ServerRecvStateStartRound::Instance());
server.SetState(ServerGameStateStartRound::Instance());
retVal = MSG_NET_GAME_SERVER_ACTION;
}
else if (GetTimer().elapsed().total_seconds() >= server.GetGameData().playerActionTimeoutSec + SERVER_PLAYER_TIMEOUT_ADD_DELAY_SEC)
@@ -802,17 +731,17 @@ ServerRecvStateWaitPlayerAction::Process(ServerRecvThread &server)
else
PerformPlayerAction(server, tmpPlayer, PLAYER_ACTION_FOLD, 0);
server.SetState(ServerRecvStateStartRound::Instance());
server.SetState(ServerGameStateStartRound::Instance());
retVal = MSG_NET_GAME_SERVER_ACTION;
}
else
retVal = AbstractServerRecvStateReceiving::Process(server);
retVal = AbstractServerGameStateReceiving::Process(server);
return retVal;
}
int
ServerRecvStateWaitPlayerAction::InternalProcess(ServerRecvThread &server, SessionWrapper session, boost::shared_ptr<NetPacket> packet)
ServerGameStateWaitPlayerAction::InternalProcess(ServerGameThread &server, SessionWrapper session, boost::shared_ptr<NetPacket> packet)
{
int retVal = MSG_SOCK_INTERNAL_PENDING;
@@ -829,7 +758,7 @@ ServerRecvStateWaitPlayerAction::InternalProcess(ServerRecvThread &server, Sessi
PerformPlayerAction(server, tmpPlayer, actionData.playerAction, actionData.playerBet);
server.SetState(ServerRecvStateStartRound::Instance());
server.SetState(ServerGameStateStartRound::Instance());
retVal = MSG_NET_GAME_SERVER_ACTION;
}
@@ -837,7 +766,7 @@ ServerRecvStateWaitPlayerAction::InternalProcess(ServerRecvThread &server, Sessi
}
void
ServerRecvStateWaitPlayerAction::PerformPlayerAction(ServerRecvThread &server, boost::shared_ptr<PlayerInterface> player, PlayerAction action, int bet)
ServerGameStateWaitPlayerAction::PerformPlayerAction(ServerGameThread &server, boost::shared_ptr<PlayerInterface> player, PlayerAction action, int bet)
{
Game &curGame = server.GetGame();
assert(player);
@@ -858,29 +787,29 @@ ServerRecvStateWaitPlayerAction::PerformPlayerAction(ServerRecvThread &server, b
//-----------------------------------------------------------------------------
boost::thread_specific_ptr<ServerRecvStateComputerAction> ServerRecvStateComputerAction::Ptr;
boost::thread_specific_ptr<ServerGameStateComputerAction> ServerGameStateComputerAction::Ptr;
ServerRecvStateComputerAction &
ServerRecvStateComputerAction::Instance()
ServerGameStateComputerAction &
ServerGameStateComputerAction::Instance()
{
if (!Ptr.get())
Ptr.reset(new ServerRecvStateComputerAction);
Ptr.reset(new ServerGameStateComputerAction);
return *Ptr;
}
ServerRecvStateComputerAction::ServerRecvStateComputerAction()
ServerGameStateComputerAction::ServerGameStateComputerAction()
{
}
ServerRecvStateComputerAction::~ServerRecvStateComputerAction()
ServerGameStateComputerAction::~ServerGameStateComputerAction()
{
}
int
ServerRecvStateComputerAction::Process(ServerRecvThread &server)
ServerGameStateComputerAction::Process(ServerGameThread &server)
{
int retVal = AbstractServerRecvStateReceiving::Process(server);
int retVal = AbstractServerGameStateReceiving::Process(server);
if (GetTimer().elapsed().total_seconds() >= SERVER_COMPUTER_ACTION_DELAY_SEC)
{
@@ -889,7 +818,7 @@ ServerRecvStateComputerAction::Process(ServerRecvThread &server)
tmpPlayer->action();
SendPlayerAction(server, tmpPlayer);
server.SetState(ServerRecvStateStartRound::Instance());
server.SetState(ServerGameStateStartRound::Instance());
retVal = MSG_NET_GAME_SERVER_ACTION;
}
@@ -897,36 +826,36 @@ ServerRecvStateComputerAction::Process(ServerRecvThread &server)
}
int
ServerRecvStateComputerAction::InternalProcess(ServerRecvThread &server, SessionWrapper session, boost::shared_ptr<NetPacket> packet)
ServerGameStateComputerAction::InternalProcess(ServerGameThread &server, SessionWrapper session, boost::shared_ptr<NetPacket> packet)
{
return MSG_SOCK_INTERNAL_PENDING;
}
//-----------------------------------------------------------------------------
boost::thread_specific_ptr<ServerRecvStateDealCardsDelay> ServerRecvStateDealCardsDelay::Ptr;
boost::thread_specific_ptr<ServerGameStateDealCardsDelay> ServerGameStateDealCardsDelay::Ptr;
ServerRecvStateDealCardsDelay &
ServerRecvStateDealCardsDelay::Instance()
ServerGameStateDealCardsDelay &
ServerGameStateDealCardsDelay::Instance()
{
if (!Ptr.get())
Ptr.reset(new ServerRecvStateDealCardsDelay);
Ptr.reset(new ServerGameStateDealCardsDelay);
return *Ptr;
}
ServerRecvStateDealCardsDelay::ServerRecvStateDealCardsDelay()
ServerGameStateDealCardsDelay::ServerGameStateDealCardsDelay()
{
}
ServerRecvStateDealCardsDelay::~ServerRecvStateDealCardsDelay()
ServerGameStateDealCardsDelay::~ServerGameStateDealCardsDelay()
{
}
int
ServerRecvStateDealCardsDelay::Process(ServerRecvThread &server)
ServerGameStateDealCardsDelay::Process(ServerGameThread &server)
{
int retVal = AbstractServerRecvStateReceiving::Process(server);
int retVal = AbstractServerGameStateReceiving::Process(server);
Game &curGame = server.GetGame();
@@ -946,49 +875,49 @@ ServerRecvStateDealCardsDelay::Process(ServerRecvThread &server)
break;
}
if (!delay || GetTimer().elapsed().total_seconds() >= delay)
server.SetState(ServerRecvStateStartRound::Instance());
server.SetState(ServerGameStateStartRound::Instance());
return retVal;
}
int
ServerRecvStateDealCardsDelay::InternalProcess(ServerRecvThread &server, SessionWrapper session, boost::shared_ptr<NetPacket> packet)
ServerGameStateDealCardsDelay::InternalProcess(ServerGameThread &server, SessionWrapper session, boost::shared_ptr<NetPacket> packet)
{
return MSG_SOCK_INTERNAL_PENDING;
}
//-----------------------------------------------------------------------------
boost::thread_specific_ptr<ServerRecvStateShowCardsDelay> ServerRecvStateShowCardsDelay::Ptr;
boost::thread_specific_ptr<ServerGameStateShowCardsDelay> ServerGameStateShowCardsDelay::Ptr;
ServerRecvStateShowCardsDelay &
ServerRecvStateShowCardsDelay::Instance()
ServerGameStateShowCardsDelay &
ServerGameStateShowCardsDelay::Instance()
{
if (!Ptr.get())
Ptr.reset(new ServerRecvStateShowCardsDelay);
Ptr.reset(new ServerGameStateShowCardsDelay);
return *Ptr;
}
ServerRecvStateShowCardsDelay::ServerRecvStateShowCardsDelay()
ServerGameStateShowCardsDelay::ServerGameStateShowCardsDelay()
{
}
ServerRecvStateShowCardsDelay::~ServerRecvStateShowCardsDelay()
ServerGameStateShowCardsDelay::~ServerGameStateShowCardsDelay()
{
}
int
ServerRecvStateShowCardsDelay::Process(ServerRecvThread &server)
ServerGameStateShowCardsDelay::Process(ServerGameThread &server)
{
int retVal = AbstractServerRecvStateReceiving::Process(server);
int retVal = AbstractServerGameStateReceiving::Process(server);
if (GetTimer().elapsed().total_seconds() >= SERVER_SHOW_CARDS_DELAY_SEC)
{
Game &curGame = server.GetGame();
SendNewRoundCards(server, curGame, curGame.getCurrentHand()->getActualRound());
server.SetState(ServerRecvStateDealCardsDelay::Instance());
server.SetState(ServerGameStateDealCardsDelay::Instance());
retVal = MSG_NET_GAME_SERVER_CARDS_DELAY;
}
@@ -996,74 +925,74 @@ ServerRecvStateShowCardsDelay::Process(ServerRecvThread &server)
}
int
ServerRecvStateShowCardsDelay::InternalProcess(ServerRecvThread &server, SessionWrapper session, boost::shared_ptr<NetPacket> packet)
ServerGameStateShowCardsDelay::InternalProcess(ServerGameThread &server, SessionWrapper session, boost::shared_ptr<NetPacket> packet)
{
return MSG_SOCK_INTERNAL_PENDING;
}
//-----------------------------------------------------------------------------
boost::thread_specific_ptr<ServerRecvStateNextHandDelay> ServerRecvStateNextHandDelay::Ptr;
boost::thread_specific_ptr<ServerGameStateNextHandDelay> ServerGameStateNextHandDelay::Ptr;
ServerRecvStateNextHandDelay &
ServerRecvStateNextHandDelay::Instance()
ServerGameStateNextHandDelay &
ServerGameStateNextHandDelay::Instance()
{
if (!Ptr.get())
Ptr.reset(new ServerRecvStateNextHandDelay);
Ptr.reset(new ServerGameStateNextHandDelay);
return *Ptr;
}
ServerRecvStateNextHandDelay::ServerRecvStateNextHandDelay()
ServerGameStateNextHandDelay::ServerGameStateNextHandDelay()
{
}
ServerRecvStateNextHandDelay::~ServerRecvStateNextHandDelay()
ServerGameStateNextHandDelay::~ServerGameStateNextHandDelay()
{
}
int
ServerRecvStateNextHandDelay::Process(ServerRecvThread &server)
ServerGameStateNextHandDelay::Process(ServerGameThread &server)
{
int retVal = AbstractServerRecvStateReceiving::Process(server);
int retVal = AbstractServerGameStateReceiving::Process(server);
if (GetTimer().elapsed().total_seconds() >= SERVER_DELAY_NEXT_HAND_SEC)
server.SetState(ServerRecvStateStartHand::Instance());
server.SetState(ServerGameStateStartHand::Instance());
return retVal;
}
int
ServerRecvStateNextHandDelay::InternalProcess(ServerRecvThread &server, SessionWrapper session, boost::shared_ptr<NetPacket> packet)
ServerGameStateNextHandDelay::InternalProcess(ServerGameThread &server, SessionWrapper session, boost::shared_ptr<NetPacket> packet)
{
return MSG_SOCK_INTERNAL_PENDING;
}
//-----------------------------------------------------------------------------
boost::thread_specific_ptr<ServerRecvStateNextGameDelay> ServerRecvStateNextGameDelay::Ptr;
boost::thread_specific_ptr<ServerGameStateNextGameDelay> ServerGameStateNextGameDelay::Ptr;
ServerRecvStateNextGameDelay &
ServerRecvStateNextGameDelay::Instance()
ServerGameStateNextGameDelay &
ServerGameStateNextGameDelay::Instance()
{
if (!Ptr.get())
Ptr.reset(new ServerRecvStateNextGameDelay);
Ptr.reset(new ServerGameStateNextGameDelay);
return *Ptr;
}
ServerRecvStateNextGameDelay::ServerRecvStateNextGameDelay()
ServerGameStateNextGameDelay::ServerGameStateNextGameDelay()
{
}
ServerRecvStateNextGameDelay::~ServerRecvStateNextGameDelay()
ServerGameStateNextGameDelay::~ServerGameStateNextGameDelay()
{
}
int
ServerRecvStateNextGameDelay::Process(ServerRecvThread &server)
ServerGameStateNextGameDelay::Process(ServerGameThread &server)
{
int retVal = AbstractServerRecvStateReceiving::Process(server);
int retVal = AbstractServerGameStateReceiving::Process(server);
if (GetTimer().elapsed().total_seconds() >= SERVER_DELAY_NEXT_GAME_SEC)
{
@@ -1085,41 +1014,41 @@ ServerRecvStateNextGameDelay::Process(ServerRecvThread &server)
server.SendToAllPlayers(endGame);
// Wait for the start of a new game.
server.SetState(ServerRecvStateInit::Instance());
server.SetState(ServerGameStateInit::Instance());
}
return retVal;
}
int
ServerRecvStateNextGameDelay::InternalProcess(ServerRecvThread &server, SessionWrapper session, boost::shared_ptr<NetPacket> packet)
ServerGameStateNextGameDelay::InternalProcess(ServerGameThread &server, SessionWrapper session, boost::shared_ptr<NetPacket> packet)
{
return MSG_SOCK_INTERNAL_PENDING;
}
//-----------------------------------------------------------------------------
boost::thread_specific_ptr<ServerRecvStateFinal> ServerRecvStateFinal::Ptr;
boost::thread_specific_ptr<ServerGameStateFinal> ServerGameStateFinal::Ptr;
ServerRecvStateFinal &
ServerRecvStateFinal::Instance()
ServerGameStateFinal &
ServerGameStateFinal::Instance()
{
if (!Ptr.get())
Ptr.reset(new ServerRecvStateFinal);
Ptr.reset(new ServerGameStateFinal);
return *Ptr;
}
ServerRecvStateFinal::ServerRecvStateFinal()
ServerGameStateFinal::ServerGameStateFinal()
{
}
ServerRecvStateFinal::~ServerRecvStateFinal()
ServerGameStateFinal::~ServerGameStateFinal()
{
}
int
ServerRecvStateFinal::InternalProcess(ServerRecvThread &server, SessionWrapper session, boost::shared_ptr<NetPacket> packet)
ServerGameStateFinal::InternalProcess(ServerGameThread &server, SessionWrapper session, boost::shared_ptr<NetPacket> packet)
{
return MSG_SOCK_INTERNAL_PENDING;
}
+371
View File
@@ -0,0 +1,371 @@
/***************************************************************************
* Copyright (C) 2007 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 *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#include <net/servergamethread.h>
#include <net/servergamestate.h>
#include <net/serverlobbythread.h>
#include <net/serverexception.h>
#include <net/senderthread.h>
#include <net/sendercallback.h>
#include <net/receiverhelper.h>
#include <net/socket_msg.h>
#include <game.h>
#include <localenginefactory.h>
#include <tools.h>
using namespace std;
class ServerSenderCallback : public SenderCallback
{
public:
ServerSenderCallback(ServerGameThread &server) : m_server(server) {}
virtual ~ServerSenderCallback() {}
virtual void SignalNetError(SOCKET sock, int errorID, int osErrorID)
{
// We just ignore send errors for now, on server side.
// A serious send error should trigger a read error or a read
// returning 0 afterwards, and we will handle this error.
}
private:
ServerGameThread &m_server;
};
ServerGameThread::ServerGameThread(ServerLobbyThread &lobbyThread, GuiInterface &gui, ConfigFile *playerConfig)
: m_lobbyThread(lobbyThread), m_gui(gui), m_gameId(0), m_playerConfig(playerConfig), m_curState(NULL)
{
m_senderCallback.reset(new ServerSenderCallback(*this));
m_sender.reset(new SenderThread(GetSenderCallback()));
m_receiver.reset(new ReceiverHelper);
}
ServerGameThread::~ServerGameThread()
{
}
void
ServerGameThread::Init(const string &pwd, const GameData &gameData)
{
m_password = pwd;
m_gameData = gameData;
}
void
ServerGameThread::AddSession(SessionWrapper session)
{
GetState().HandleNewSession(*this, session);
}
GameState
ServerGameThread::GetCurRound() const
{
return static_cast<GameState>(GetGame().getCurrentHand()->getActualRound());
}
void
ServerGameThread::SendToAllPlayers(boost::shared_ptr<NetPacket> packet)
{
GetSessionManager().SendToAllSessions(GetSender(), packet);
}
void
ServerGameThread::Main()
{
SetState(SERVER_INITIAL_STATE::Instance());
GetSender().Run();
try
{
while (!ShouldTerminate())
{
// Process current state.
GetState().Process(*this);
}
} catch (const NetException &e)
{
GetCallback().SignalNetServerError(e.GetErrorId(), e.GetOsErrorCode());
}
GetSender().SignalTermination();
GetSender().Join(SENDER_THREAD_TERMINATE_TIMEOUT);
}
void
ServerGameThread::InternalStartGame()
{
// Set order of players.
AssignPlayerNumbers();
// Initialize the game.
GuiInterface &gui = GetGui();
PlayerDataList playerData = GetSessionManager().GetPlayerDataList();
// Create EngineFactory
boost::shared_ptr<EngineFactory> factory(new LocalEngineFactory(m_playerConfig)); // LocalEngine erstellen
// Set start data.
StartData startData;
startData.numberOfPlayers = playerData.size();
int tmpDealerPos = 0;
Tools::getRandNumber(0, startData.numberOfPlayers-1, 1, &tmpDealerPos, 0);
// The Player Id is not continuous. Therefore, the start dealer position
// needs to be converted to a player Id, and cannot be directly generated
// as player Id.
PlayerDataList::const_iterator player_i = playerData.begin();
PlayerDataList::const_iterator player_end = playerData.end();
bool randDealerFound = false;
while (player_i != player_end)
{
if ((*player_i)->GetNumber() == tmpDealerPos)
{
// Get ID of the dealer.
startData.startDealerPlayerId = static_cast<unsigned>((*player_i)->GetUniqueId());
randDealerFound = true;
break;
}
++player_i;
}
assert(randDealerFound); // TODO: Throw exception.
SetStartData(startData);
m_game.reset(new Game(&gui, factory, playerData, GetGameData(), GetStartData(), GetNextGameId()));
}
void
ServerGameThread::InternalKickPlayer(unsigned playerId)
{
// SessionWrapper tmpSession = GetSessionByUniquePlayerId(uniqueId);
// SessionError(tmpSession, ERR_NET_PLAYER_KICKED);
}
void
ServerGameThread::AddComputerPlayer(boost::shared_ptr<PlayerData> player)
{
m_computerPlayers.push_back(player);
}
void
ServerGameThread::ResetComputerPlayerList()
{
m_computerPlayers.clear();
}
void
ServerGameThread::SessionError(SessionWrapper session, int errorCode)
{
if (session.sessionData.get())
{
SendError(session.sessionData->GetSocket(), errorCode);
CloseSessionDelayed(session);
}
}
void
ServerGameThread::CloseSessionDelayed(SessionWrapper session)
{
GetSessionManager().RemoveSession(session.sessionData->GetSocket());
boost::shared_ptr<PlayerData> tmpPlayerData = session.playerData;
if (tmpPlayerData.get() && !tmpPlayerData->GetName().empty())
{
// Send "Player Left" to clients.
boost::shared_ptr<NetPacket> thisPlayerLeft(new NetPacketPlayerLeft);
NetPacketPlayerLeft::Data thisPlayerLeftData;
thisPlayerLeftData.playerId = tmpPlayerData->GetUniqueId();
static_cast<NetPacketPlayerLeft *>(thisPlayerLeft.get())->SetData(thisPlayerLeftData);
GetSessionManager().SendToAllSessions(GetSender(), thisPlayerLeft);
GetCallback().SignalNetServerPlayerLeft(tmpPlayerData->GetName());
}
GetLobbyThread().CloseSessionDelayed(session);
}
void
ServerGameThread::SendError(SOCKET s, int errorCode)
{
boost::shared_ptr<NetPacket> packet(new NetPacketError);
NetPacketError::Data errorData;
errorData.errorCode = errorCode;
static_cast<NetPacketError *>(packet.get())->SetData(errorData);
GetSender().Send(s, packet);
}
void
ServerGameThread::RejectSession(SessionWrapper session)
{
// TODO
}
void
ServerGameThread::RemoveDisconnectedPlayers()
{
// This should only be called between hands.
if (m_game.get())
{
for (int i = 0; i < m_game->getStartQuantityPlayers(); i++)
{
boost::shared_ptr<PlayerInterface> tmpPlayer = m_game->getPlayerArray()[i];
if (!GetSessionManager().IsPlayerConnected(tmpPlayer->getMyUniqueID()) && tmpPlayer->getMyType() == PLAYER_TYPE_HUMAN)
{
tmpPlayer->setMyCash(0);
tmpPlayer->setMyActiveStatus(false);
tmpPlayer->setNetSessionData(boost::shared_ptr<SessionData>());
}
}
}
}
size_t
ServerGameThread::GetCurNumberOfPlayers() const
{
return GetSessionManager().GetPlayerDataList().size();
}
void
ServerGameThread::AssignPlayerNumbers()
{
int playerNumber = 0;
PlayerDataList playerList = GetSessionManager().GetPlayerDataList();
PlayerDataList::iterator player_i = playerList.begin();
PlayerDataList::iterator player_end = playerList.end();
while (player_i != player_end)
{
(*player_i)->SetNumber(playerNumber);
++playerNumber;
++player_i;
}
}
unsigned
ServerGameThread::GetNextGameId()
{
return m_gameId++;
}
SessionManager &
ServerGameThread::GetSessionManager()
{
return m_sessionManager;
}
const SessionManager &
ServerGameThread::GetSessionManager() const
{
return m_sessionManager;
}
ServerLobbyThread &
ServerGameThread::GetLobbyThread()
{
return m_lobbyThread;
}
ServerCallback &
ServerGameThread::GetCallback()
{
return m_gui;
}
ServerGameState &
ServerGameThread::GetState()
{
assert(m_curState);
return *m_curState;
}
void
ServerGameThread::SetState(ServerGameState &newState)
{
newState.Init();
m_curState = &newState;
}
SenderThread &
ServerGameThread::GetSender()
{
assert(m_sender.get());
return *m_sender;
}
ReceiverHelper &
ServerGameThread::GetReceiver()
{
assert(m_receiver.get());
return *m_receiver;
}
Game &
ServerGameThread::GetGame()
{
assert(m_game.get());
return *m_game;
}
const Game &
ServerGameThread::GetGame() const
{
assert(m_game.get());
return *m_game;
}
const GameData &
ServerGameThread::GetGameData() const
{
return m_gameData;
}
const StartData &
ServerGameThread::GetStartData() const
{
return m_startData;
}
void
ServerGameThread::SetStartData(const StartData &startData)
{
m_startData = startData;
}
bool
ServerGameThread::CheckPassword(const string &password) const
{
return (password == m_password);
}
ServerSenderCallback &
ServerGameThread::GetSenderCallback()
{
assert(m_senderCallback.get());
return *m_senderCallback;
}
GuiInterface &
ServerGameThread::GetGui()
{
return m_gui;
}
+16 -38
View File
@@ -79,6 +79,19 @@ ServerLobbyThread::AddConnection(boost::shared_ptr<ConnectData> data)
m_connectQueue.push_back(data);
}
void
ServerLobbyThread::CloseSessionDelayed(SessionWrapper session)
{
m_sessionManager.RemoveSession(session.sessionData->GetSocket());
boost::microsec_timer closeTimer;
closeTimer.start();
CloseSessionList::value_type closeSessionData(closeTimer, session.sessionData);
boost::mutex::scoped_lock lock(m_closeSessionListMutex);
m_closeSessionList.push_back(closeSessionData);
}
u_int32_t
ServerLobbyThread::GetNextUniquePlayerId()
{
@@ -198,7 +211,7 @@ ServerLobbyThread::HandleNetPacketInit(SessionWrapper session, const NetPacketIn
}
// Check whether this player is already connected.
if (IsPlayerConnected(initData.playerName))
if (m_sessionManager.IsPlayerConnected(initData.playerName))
{
SessionError(session, ERR_NET_PLAYER_NAME_IN_USE);
return;
@@ -247,6 +260,8 @@ ServerLobbyThread::HandleNetPacketJoinGame(SessionWrapper session, const NetPack
void
ServerLobbyThread::CloseSessionLoop()
{
boost::mutex::scoped_lock lock(m_closeSessionListMutex);
CloseSessionList::iterator i = m_closeSessionList.begin();
CloseSessionList::iterator end = m_closeSessionList.end();
@@ -302,30 +317,6 @@ ServerLobbyThread::SessionError(SessionWrapper session, int errorCode)
}
}
void
ServerLobbyThread::CloseSessionDelayed(SessionWrapper session)
{
m_sessionManager.RemoveSession(session.sessionData->GetSocket());
boost::shared_ptr<PlayerData> tmpPlayerData = session.playerData;
if (tmpPlayerData.get() && !tmpPlayerData->GetName().empty())
{
// Send "Player Left" to clients.
boost::shared_ptr<NetPacket> thisPlayerLeft(new NetPacketPlayerLeft);
NetPacketPlayerLeft::Data thisPlayerLeftData;
thisPlayerLeftData.playerId = tmpPlayerData->GetUniqueId();
static_cast<NetPacketPlayerLeft *>(thisPlayerLeft.get())->SetData(thisPlayerLeftData);
m_sessionManager.SendToAllSessions(GetSender(), thisPlayerLeft);
GetCallback().SignalNetServerPlayerLeft(tmpPlayerData->GetName());
}
boost::microsec_timer closeTimer;
closeTimer.start();
CloseSessionList::value_type closeSessionData(closeTimer, session.sessionData);
m_closeSessionList.push_back(closeSessionData);
}
void
ServerLobbyThread::SendError(SOCKET s, int errorCode)
{
@@ -336,19 +327,6 @@ ServerLobbyThread::SendError(SOCKET s, int errorCode)
GetSender().Send(s, packet);
}
bool
ServerLobbyThread::IsPlayerConnected(const string &playerName) const
{
bool retVal = false;
SessionWrapper tmpSession = m_sessionManager.GetSessionByPlayerName(playerName);
if (tmpSession.sessionData.get() && tmpSession.playerData.get())
retVal = true;
return retVal;
}
ServerCallback &
ServerLobbyThread::GetCallback()
{
+59 -3
View File
@@ -36,18 +36,24 @@ SessionManager::~SessionManager()
void
SessionManager::AddSession(boost::shared_ptr<SessionData> sessionData)
{
AddSession(SessionWrapper(sessionData, boost::shared_ptr<PlayerData>()));
}
void
SessionManager::AddSession(SessionWrapper session)
{
boost::mutex::scoped_lock lock(m_sessionMapMutex);
SessionMap::iterator pos = m_sessionMap.lower_bound(sessionData->GetSocket());
SessionMap::iterator pos = m_sessionMap.lower_bound(session.sessionData->GetSocket());
// If pos points to a pair whose key is equivalent to the socket, this handle
// already exists within the list.
if (pos != m_sessionMap.end() && sessionData->GetSocket() == pos->first)
if (pos != m_sessionMap.end() && session.sessionData->GetSocket() == pos->first)
{
throw ServerException(ERR_SOCK_CONN_EXISTS, 0);
}
m_sessionMap.insert(pos, SessionMap::value_type(sessionData->GetSocket(), SessionWrapper(sessionData, boost::shared_ptr<PlayerData>())));
m_sessionMap.insert(pos, SessionMap::value_type(session.sessionData->GetSocket(), session));
}
void
@@ -182,6 +188,56 @@ SessionManager::GetSessionByUniquePlayerId(unsigned uniqueId) const
return tmpSession;
}
PlayerDataList
SessionManager::GetPlayerDataList() const
{
PlayerDataList playerList;
boost::mutex::scoped_lock lock(m_sessionMapMutex);
SessionMap::const_iterator session_i = m_sessionMap.begin();
SessionMap::const_iterator session_end = m_sessionMap.end();
while (session_i != session_end)
{
// Get all players which are fully connected.
if (session_i->second.sessionData->GetState() == SessionData::Established)
{
boost::shared_ptr<PlayerData> tmpPlayer(session_i->second.playerData);
assert(tmpPlayer.get());
assert(!tmpPlayer->GetName().empty());
playerList.push_back(tmpPlayer);
}
++session_i;
}
return playerList;
}
bool
SessionManager::IsPlayerConnected(const string &playerName) const
{
bool retVal = false;
SessionWrapper tmpSession = GetSessionByPlayerName(playerName);
if (tmpSession.sessionData.get() && tmpSession.playerData.get())
retVal = true;
return retVal;
}
bool
SessionManager::IsPlayerConnected(unsigned uniqueId) const
{
bool retVal = false;
SessionWrapper tmpSession = GetSessionByUniquePlayerId(uniqueId);
if (tmpSession.sessionData.get() && tmpSession.playerData.get())
retVal = true;
return retVal;
}
void
SessionManager::Clear()
{
+1 -2
View File
@@ -41,8 +41,7 @@ public:
virtual ~ServerAcceptThread();
// Set the parameters.
void Init(unsigned serverPort, bool ipv6, bool sctp, const std::string &pwd,
const GameData &gameData);
void Init(unsigned serverPort, bool ipv6, bool sctp, const std::string &pwd);
ServerCallback &GetCallback();
GuiInterface &GetGui();
+380
View File
@@ -0,0 +1,380 @@
/***************************************************************************
* Copyright (C) 2007 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 *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
/* State of network server. */
#ifndef _SERVERGAMESTATE_H_
#define _SERVERGAMESTATE_H_
#include <net/servergamethread.h>
#include <playerdata.h>
#include <core/boost/timer.hpp>
#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable : 4250)
#endif
#define SERVER_INITIAL_STATE ServerGameStateInit
#define SERVER_START_GAME_STATE ServerGameStateStartGame
class Game;
class PlayerInterface;
class ServerCallback;
class ServerGameState
{
public:
virtual ~ServerGameState();
// Initialize after switching to this state.
virtual void Init() = 0;
// Handling of a new TCP connection.
virtual void HandleNewSession(ServerGameThread &server, SessionWrapper session) = 0;
// Main processing function of the current state.
virtual int Process(ServerGameThread &server) = 0;
};
// Abstract State: Receiving.
class AbstractServerGameStateReceiving : virtual public ServerGameState
{
public:
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);
protected:
AbstractServerGameStateReceiving();
virtual int InternalProcess(ServerGameThread &server, SessionWrapper session, boost::shared_ptr<NetPacket> packet) = 0;
};
// Abstract State: Timer.
class AbstractServerGameStateTimer : virtual public ServerGameState
{
public:
virtual ~AbstractServerGameStateTimer();
virtual void Init();
const boost::microsec_timer &GetTimer() const {return m_timer;}
protected:
AbstractServerGameStateTimer();
private:
boost::microsec_timer m_timer;
};
// Abstract State: Game is running.
class AbstractServerGameStateRunning : virtual public ServerGameState
{
public:
virtual ~AbstractServerGameStateRunning();
// Reject new connections.
virtual void HandleNewSession(ServerGameThread &server, SessionWrapper session);
protected:
AbstractServerGameStateRunning();
};
// State: Initialization.
class ServerGameStateInit : public AbstractServerGameStateReceiving
{
public:
// Access the state singleton.
static ServerGameStateInit &Instance();
virtual ~ServerGameStateInit();
virtual void Init() {}
//
virtual void HandleNewSession(ServerGameThread &server, SessionWrapper session);
protected:
// Protected constructor - this is a singleton.
ServerGameStateInit();
virtual int InternalProcess(ServerGameThread &server, SessionWrapper session, boost::shared_ptr<NetPacket> packet);
static boost::shared_ptr<NetPacket> CreateNetPacketPlayerJoined(const PlayerData &playerData);
private:
u_int32_t m_curUniquePlayerId;
static boost::thread_specific_ptr<ServerGameStateInit> Ptr;
};
// State: Start server game.
class ServerGameStateStartGame : public AbstractServerGameStateRunning
{
public:
// Access the state singleton.
static ServerGameStateStartGame &Instance();
virtual ~ServerGameStateStartGame();
virtual void Init() {}
//
virtual int Process(ServerGameThread &server);
protected:
// Protected constructor - this is a singleton.
ServerGameStateStartGame();
private:
static boost::thread_specific_ptr<ServerGameStateStartGame> Ptr;
};
// State: Start new hand.
class ServerGameStateStartHand : public AbstractServerGameStateRunning
{
public:
// Access the state singleton.
static ServerGameStateStartHand &Instance();
virtual ~ServerGameStateStartHand();
virtual void Init() {}
//
virtual int Process(ServerGameThread &server);
protected:
// Protected constructor - this is a singleton.
ServerGameStateStartHand();
private:
static boost::thread_specific_ptr<ServerGameStateStartHand> Ptr;
};
// State: Start new round.
class ServerGameStateStartRound : public AbstractServerGameStateRunning
{
public:
// Access the state singleton.
static ServerGameStateStartRound &Instance();
virtual ~ServerGameStateStartRound();
virtual void Init() {}
//
virtual int Process(ServerGameThread &server);
protected:
// Protected constructor - this is a singleton.
ServerGameStateStartRound();
static std::list<boost::shared_ptr<PlayerInterface> > GetActivePlayers(Game &curGame);
private:
static boost::thread_specific_ptr<ServerGameStateStartRound> Ptr;
};
// State: Wait for a player action.
class ServerGameStateWaitPlayerAction : public AbstractServerGameStateReceiving, public AbstractServerGameStateRunning, public AbstractServerGameStateTimer
{
public:
// Access the state singleton.
static ServerGameStateWaitPlayerAction &Instance();
virtual ~ServerGameStateWaitPlayerAction();
// Handle leaving players.
virtual int Process(ServerGameThread &server);
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);
private:
static boost::thread_specific_ptr<ServerGameStateWaitPlayerAction> Ptr;
};
// 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 boost::thread_specific_ptr<ServerGameStateComputerAction> Ptr;
};
// 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 boost::thread_specific_ptr<ServerGameStateDealCardsDelay> Ptr;
};
// 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 boost::thread_specific_ptr<ServerGameStateShowCardsDelay> Ptr;
};
// 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 boost::thread_specific_ptr<ServerGameStateNextHandDelay> Ptr;
};
// 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 boost::thread_specific_ptr<ServerGameStateNextGameDelay> Ptr;
};
// State: Final.
class ServerGameStateFinal : public AbstractServerGameStateReceiving, public AbstractServerGameStateRunning
{
public:
// Access the state singleton.
static ServerGameStateFinal &Instance();
virtual ~ServerGameStateFinal();
virtual void Init() {}
protected:
// Protected constructor - this is a singleton.
ServerGameStateFinal();
virtual int InternalProcess(ServerGameThread &server, SessionWrapper session, boost::shared_ptr<NetPacket> packet);
private:
static boost::thread_specific_ptr<ServerGameStateFinal> Ptr;
};
#ifdef _MSC_VER
#pragma warning(pop)
#endif
#endif
+132
View File
@@ -0,0 +1,132 @@
/***************************************************************************
* Copyright (C) 2007 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 *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
/* Network server game thread. */
#ifndef _SERVERGAMETHREAD_H_
#define _SERVERGAMETHREAD_H_
#include <net/sessionmanager.h>
#include <gui/guiinterface.h>
#include <gamedata.h>
#define GAME_THREAD_TERMINATE_TIMEOUT 200
class SenderThread;
class ReceiverHelper;
class ServerLobbyThread;
class ServerSenderCallback;
class ServerGameState;
class ConfigFile;
struct GameData;
class Game;
class ServerGameThread : public Thread
{
public:
ServerGameThread(ServerLobbyThread &lobbyThread, GuiInterface &gui, ConfigFile *playerConfig);
virtual ~ServerGameThread();
void Init(const std::string &pwd, const GameData &gameData);
void AddSession(SessionWrapper session);
ServerCallback &GetCallback();
GameState GetCurRound() const;
void SendToAllPlayers(boost::shared_ptr<NetPacket> packet);
protected:
// Main function of the thread.
virtual void Main();
void InternalStartGame();
void InternalKickPlayer(unsigned playerId);
void AddComputerPlayer(boost::shared_ptr<PlayerData> player);
void ResetComputerPlayerList();
void SessionError(SessionWrapper session, int errorCode);
void CloseSessionDelayed(SessionWrapper session);
void SendError(SOCKET s, int errorCode);
void RejectSession(SessionWrapper session);
void RemoveDisconnectedPlayers();
size_t GetCurNumberOfPlayers() const;
void AssignPlayerNumbers();
unsigned GetNextGameId();
SessionManager &GetSessionManager();
const SessionManager &GetSessionManager() const;
ServerLobbyThread &GetLobbyThread();
ServerGameState &GetState();
void SetState(ServerGameState &newState);
SenderThread &GetSender();
ReceiverHelper &GetReceiver();
Game &GetGame();
const Game &GetGame() const;
const GameData &GetGameData() const;
const StartData &GetStartData() const;
void SetStartData(const StartData &startData);
bool CheckPassword(const std::string &password) const;
ServerSenderCallback &GetSenderCallback();
GuiInterface &GetGui();
private:
SessionManager m_sessionManager;
PlayerDataList m_computerPlayers;
ServerLobbyThread &m_lobbyThread;
std::auto_ptr<ReceiverHelper> m_receiver;
std::auto_ptr<SenderThread> m_sender;
std::auto_ptr<ServerSenderCallback> m_senderCallback;
GuiInterface &m_gui;
GameData m_gameData;
StartData m_startData;
std::auto_ptr<Game> m_game;
unsigned m_gameId;
std::string m_password;
ConfigFile *m_playerConfig;
ServerGameState *m_curState;
friend class AbstractServerGameStateReceiving;
friend class AbstractServerGameStateRunning;
friend class ServerGameStateInit;
friend class ServerGameStateStartGame;
friend class ServerGameStateStartHand;
friend class ServerGameStateStartRound;
friend class ServerGameStateWaitPlayerAction;
friend class ServerGameStateComputerAction;
friend class ServerGameStateDealCardsDelay;
friend class ServerGameStateShowCardsDelay;
friend class ServerGameStateNextHandDelay;
friend class ServerGameStateNextGameDelay;
};
#endif
+2 -3
View File
@@ -50,6 +50,7 @@ public:
void Init(const std::string &pwd);
void AddConnection(boost::shared_ptr<ConnectData> data);
void CloseSessionDelayed(SessionWrapper session);
u_int32_t GetNextUniquePlayerId();
ServerCallback &GetCallback();
@@ -77,11 +78,8 @@ protected:
void CleanupSessionMap();
void SessionError(SessionWrapper session, int errorCode);
void CloseSessionDelayed(SessionWrapper session);
void SendError(SOCKET s, int errorCode);
bool IsPlayerConnected(const std::string &playerName) const;
SenderThread &GetSender();
ReceiverHelper &GetReceiver();
@@ -98,6 +96,7 @@ private:
SessionManager m_sessionManager;
CloseSessionList m_closeSessionList;
mutable boost::mutex m_closeSessionListMutex;
std::auto_ptr<ReceiverHelper> m_receiver;
std::auto_ptr<SenderThread> m_sender;
-378
View File
@@ -1,378 +0,0 @@
/***************************************************************************
* Copyright (C) 2007 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 *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
/* State of network server. */
#ifndef _SERVERRECVSTATE_H_
#define _SERVERRECVSTATE_H_
#include <net/serverrecvthread.h>
#include <playerdata.h>
#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable : 4250)
#endif
#define SERVER_INITIAL_STATE ServerRecvStateInit
#define SERVER_START_GAME_STATE ServerRecvStateStartGame
class Game;
class PlayerInterface;
class ServerCallback;
class ServerRecvState
{
public:
virtual ~ServerRecvState();
// Initialize after switching to this state.
virtual void Init() = 0;
// Handling of a new TCP connection.
virtual void HandleNewConnection(ServerRecvThread &server, boost::shared_ptr<ConnectData> connData) = 0;
// Main processing function of the current state.
virtual int Process(ServerRecvThread &server) = 0;
};
// Abstract State: Receiving.
class AbstractServerRecvStateReceiving : virtual public ServerRecvState
{
public:
virtual ~AbstractServerRecvStateReceiving();
// Globally handle packets which are allowed in all running states.
// Calls InternalProcess if packet has not been processed.
virtual int Process(ServerRecvThread &server);
protected:
AbstractServerRecvStateReceiving();
virtual int InternalProcess(ServerRecvThread &server, SessionWrapper session, boost::shared_ptr<NetPacket> packet) = 0;
};
// Abstract State: Timer.
class AbstractServerRecvStateTimer : virtual public ServerRecvState
{
public:
virtual ~AbstractServerRecvStateTimer();
virtual void Init();
const boost::microsec_timer &GetTimer() const {return m_timer;}
protected:
AbstractServerRecvStateTimer();
private:
boost::microsec_timer m_timer;
};
// Abstract State: Game is running.
class AbstractServerRecvStateRunning : virtual public ServerRecvState
{
public:
virtual ~AbstractServerRecvStateRunning();
// Reject new connections.
virtual void HandleNewConnection(ServerRecvThread &server, boost::shared_ptr<ConnectData> data);
protected:
AbstractServerRecvStateRunning();
};
// State: Initialization.
class ServerRecvStateInit : public AbstractServerRecvStateReceiving
{
public:
// Access the state singleton.
static ServerRecvStateInit &Instance();
virtual ~ServerRecvStateInit();
virtual void Init() {}
//
virtual void HandleNewConnection(ServerRecvThread &server, boost::shared_ptr<ConnectData> data);
protected:
// Protected constructor - this is a singleton.
ServerRecvStateInit();
virtual int InternalProcess(ServerRecvThread &server, SessionWrapper session, boost::shared_ptr<NetPacket> packet);
static boost::shared_ptr<NetPacket> CreateNetPacketPlayerJoined(const PlayerData &playerData);
private:
u_int32_t m_curUniquePlayerId;
static boost::thread_specific_ptr<ServerRecvStateInit> Ptr;
};
// State: Start server game.
class ServerRecvStateStartGame : public AbstractServerRecvStateRunning
{
public:
// Access the state singleton.
static ServerRecvStateStartGame &Instance();
virtual ~ServerRecvStateStartGame();
virtual void Init() {}
//
virtual int Process(ServerRecvThread &server);
protected:
// Protected constructor - this is a singleton.
ServerRecvStateStartGame();
private:
static boost::thread_specific_ptr<ServerRecvStateStartGame> Ptr;
};
// State: Start new hand.
class ServerRecvStateStartHand : public AbstractServerRecvStateRunning
{
public:
// Access the state singleton.
static ServerRecvStateStartHand &Instance();
virtual ~ServerRecvStateStartHand();
virtual void Init() {}
//
virtual int Process(ServerRecvThread &server);
protected:
// Protected constructor - this is a singleton.
ServerRecvStateStartHand();
private:
static boost::thread_specific_ptr<ServerRecvStateStartHand> Ptr;
};
// State: Start new round.
class ServerRecvStateStartRound : public AbstractServerRecvStateRunning
{
public:
// Access the state singleton.
static ServerRecvStateStartRound &Instance();
virtual ~ServerRecvStateStartRound();
virtual void Init() {}
//
virtual int Process(ServerRecvThread &server);
protected:
// Protected constructor - this is a singleton.
ServerRecvStateStartRound();
static std::list<boost::shared_ptr<PlayerInterface> > GetActivePlayers(Game &curGame);
private:
static boost::thread_specific_ptr<ServerRecvStateStartRound> Ptr;
};
// State: Wait for a player action.
class ServerRecvStateWaitPlayerAction : public AbstractServerRecvStateReceiving, public AbstractServerRecvStateRunning, public AbstractServerRecvStateTimer
{
public:
// Access the state singleton.
static ServerRecvStateWaitPlayerAction &Instance();
virtual ~ServerRecvStateWaitPlayerAction();
// Handle leaving players.
virtual int Process(ServerRecvThread &server);
protected:
// Protected constructor - this is a singleton.
ServerRecvStateWaitPlayerAction();
virtual int InternalProcess(ServerRecvThread &server, SessionWrapper session, boost::shared_ptr<NetPacket> packet);
static void PerformPlayerAction(ServerRecvThread &server, boost::shared_ptr<PlayerInterface> player, PlayerAction action, int bet);
private:
static boost::thread_specific_ptr<ServerRecvStateWaitPlayerAction> Ptr;
};
// State: Delay and computer action
class ServerRecvStateComputerAction : public AbstractServerRecvStateReceiving, public AbstractServerRecvStateRunning, public AbstractServerRecvStateTimer
{
public:
// Access the state singleton.
static ServerRecvStateComputerAction &Instance();
virtual ~ServerRecvStateComputerAction();
// Overwrite default processing
virtual int Process(ServerRecvThread &server);
protected:
// Protected constructor - this is a singleton.
ServerRecvStateComputerAction();
virtual int InternalProcess(ServerRecvThread &server, SessionWrapper session, boost::shared_ptr<NetPacket> packet);
private:
static boost::thread_specific_ptr<ServerRecvStateComputerAction> Ptr;
};
// State: Delay after dealing cards
class ServerRecvStateDealCardsDelay : public AbstractServerRecvStateReceiving, public AbstractServerRecvStateRunning, public AbstractServerRecvStateTimer
{
public:
// Access the state singleton.
static ServerRecvStateDealCardsDelay &Instance();
virtual ~ServerRecvStateDealCardsDelay();
// Overwrite default processing
virtual int Process(ServerRecvThread &server);
protected:
// Protected constructor - this is a singleton.
ServerRecvStateDealCardsDelay();
virtual int InternalProcess(ServerRecvThread &server, SessionWrapper session, boost::shared_ptr<NetPacket> packet);
private:
static boost::thread_specific_ptr<ServerRecvStateDealCardsDelay> Ptr;
};
// State: Delay after showing cards (all in)
class ServerRecvStateShowCardsDelay : public AbstractServerRecvStateReceiving, public AbstractServerRecvStateRunning, public AbstractServerRecvStateTimer
{
public:
// Access the state singleton.
static ServerRecvStateShowCardsDelay &Instance();
virtual ~ServerRecvStateShowCardsDelay();
// Overwrite default processing
virtual int Process(ServerRecvThread &server);
protected:
// Protected constructor - this is a singleton.
ServerRecvStateShowCardsDelay();
virtual int InternalProcess(ServerRecvThread &server, SessionWrapper session, boost::shared_ptr<NetPacket> packet);
private:
static boost::thread_specific_ptr<ServerRecvStateShowCardsDelay> Ptr;
};
// State: Delay before next hand.
class ServerRecvStateNextHandDelay : public AbstractServerRecvStateReceiving, public AbstractServerRecvStateRunning, public AbstractServerRecvStateTimer
{
public:
// Access the state singleton.
static ServerRecvStateNextHandDelay &Instance();
virtual ~ServerRecvStateNextHandDelay();
// Overwrite default processing
virtual int Process(ServerRecvThread &server);
protected:
// Protected constructor - this is a singleton.
ServerRecvStateNextHandDelay();
virtual int InternalProcess(ServerRecvThread &server, SessionWrapper session, boost::shared_ptr<NetPacket> packet);
private:
static boost::thread_specific_ptr<ServerRecvStateNextHandDelay> Ptr;
};
// State: Delay before next hand.
class ServerRecvStateNextGameDelay : public AbstractServerRecvStateReceiving, public AbstractServerRecvStateRunning, public AbstractServerRecvStateTimer
{
public:
// Access the state singleton.
static ServerRecvStateNextGameDelay &Instance();
virtual ~ServerRecvStateNextGameDelay();
// Overwrite default processing
virtual int Process(ServerRecvThread &server);
protected:
// Protected constructor - this is a singleton.
ServerRecvStateNextGameDelay();
virtual int InternalProcess(ServerRecvThread &server, SessionWrapper session, boost::shared_ptr<NetPacket> packet);
private:
static boost::thread_specific_ptr<ServerRecvStateNextGameDelay> Ptr;
};
// State: Final.
class ServerRecvStateFinal : public AbstractServerRecvStateReceiving, public AbstractServerRecvStateRunning
{
public:
// Access the state singleton.
static ServerRecvStateFinal &Instance();
virtual ~ServerRecvStateFinal();
virtual void Init() {}
protected:
// Protected constructor - this is a singleton.
ServerRecvStateFinal();
virtual int InternalProcess(ServerRecvThread &server, SessionWrapper session, boost::shared_ptr<NetPacket> packet);
private:
static boost::thread_specific_ptr<ServerRecvStateFinal> Ptr;
};
#ifdef _MSC_VER
#pragma warning(pop)
#endif
#endif
+1 -1
View File
@@ -29,7 +29,7 @@
class SessionData
{
public:
enum State { Init, Established };
enum State { Init, Established, Game };
SessionData(SOCKET sockfd, unsigned id);
~SessionData();
+6 -1
View File
@@ -46,7 +46,8 @@ public:
SessionManager();
virtual ~SessionManager();
void AddSession(boost::shared_ptr<SessionData> sessionData); // new Sessions have no player data
void AddSession(boost::shared_ptr<SessionData> sessionData); // new Sessions without player data
void AddSession(SessionWrapper session);
void SetSessionPlayerData(SOCKET session, boost::shared_ptr<PlayerData> playerData);
void RemoveSession(SOCKET session);
@@ -54,6 +55,10 @@ public:
SessionWrapper GetSessionByPlayerName(const std::string playerName) const;
SessionWrapper GetSessionByUniquePlayerId(unsigned uniqueId) const;
PlayerDataList GetPlayerDataList() const;
bool IsPlayerConnected(const std::string &playerName) const;
bool IsPlayerConnected(unsigned uniqueId) const;
void Clear();
unsigned GetRawSessionCount();
+2
View File
@@ -62,6 +62,8 @@ public:
{return m_type;}
PlayerRights GetRights() const
{return m_rights;}
void SetRights(PlayerRights rights)
{m_rights = rights;}
unsigned GetUniqueId() const
{return m_uniqueId;}
int GetNumber() const
+1 -2
View File
@@ -169,8 +169,7 @@ void Session::startNetworkServer(const GameData &gameData)
myConfig->readConfigInt("ServerPort"),
myConfig->readConfigInt("ServerUseIpv6") == 1,
myConfig->readConfigInt("ServerUseSctp") == 1,
myConfig->readConfigString("ServerPassword"),
gameData);
myConfig->readConfigString("ServerPassword"));
myNetServer->Run();
}