More work on server redesign. Network mode still broken.
This commit is contained in:
+6
-1
@@ -114,7 +114,12 @@ Game::~Game()
|
||||
|
||||
}
|
||||
|
||||
HandInterface * Game::getCurrentHand()
|
||||
HandInterface *Game::getCurrentHand()
|
||||
{
|
||||
return actualHand;
|
||||
}
|
||||
|
||||
const HandInterface *Game::getCurrentHand() const
|
||||
{
|
||||
return actualHand;
|
||||
}
|
||||
|
||||
@@ -48,6 +48,7 @@ public:
|
||||
void startHand();
|
||||
|
||||
HandInterface *getCurrentHand();
|
||||
const HandInterface *getCurrentHand() const;
|
||||
|
||||
std::vector<boost::shared_ptr<PlayerInterface> > getPlayerArray() {return playerArray;}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
{
|
||||
|
||||
@@ -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()
|
||||
{
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
@@ -29,7 +29,7 @@
|
||||
class SessionData
|
||||
{
|
||||
public:
|
||||
enum State { Init, Established };
|
||||
enum State { Init, Established, Game };
|
||||
|
||||
SessionData(SOCKET sockfd, unsigned id);
|
||||
~SessionData();
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user