Players should now be able to leave a network game, the other players can continue the game (if it wasn't the server who left).
This commit is contained in:
@@ -385,6 +385,33 @@ AbstractClientStateReceiving::Process(ClientThread &client)
|
||||
if (tmpPlayer.get())
|
||||
client.GetCallback().SignalNetClientChatMsg(tmpPlayer->GetName(), chatData.text);
|
||||
}
|
||||
else if (tmpPacket->ToNetPacketPlayerLeft())
|
||||
{
|
||||
// A player left the game.
|
||||
NetPacketPlayerLeft::Data playerLeftData;
|
||||
tmpPacket->ToNetPacketPlayerLeft()->GetData(playerLeftData);
|
||||
|
||||
// Signal to GUI.
|
||||
client.RemovePlayerData(playerLeftData.playerId);
|
||||
|
||||
// If the game is running, deactivate player.
|
||||
boost::shared_ptr<Game> curGame = client.GetGame();
|
||||
if (curGame.get())
|
||||
{
|
||||
PlayerInterface *tmpPlayer = curGame->getPlayerByUniqueId(playerLeftData.playerId);
|
||||
if (!tmpPlayer)
|
||||
throw ClientException(ERR_NET_UNKNOWN_PLAYER_ID, 0);
|
||||
|
||||
// Reset his action and his cash.
|
||||
tmpPlayer->setMyAction(PLAYER_ACTION_FOLD);
|
||||
tmpPlayer->setMyCash(0);
|
||||
// Player is now inactive.
|
||||
tmpPlayer->setMyActiveStatus(false);
|
||||
|
||||
client.GetGui().refreshAction();
|
||||
client.GetGui().refreshCash();
|
||||
}
|
||||
}
|
||||
else
|
||||
retVal = InternalProcess(client, tmpPacket);
|
||||
}
|
||||
@@ -490,13 +517,6 @@ ClientStateWaitGame::InternalProcess(ClientThread &client, boost::shared_ptr<Net
|
||||
playerData->SetName(netPlayerData.playerName);
|
||||
client.AddPlayerData(playerData);
|
||||
}
|
||||
else if (packet->ToNetPacketPlayerLeft())
|
||||
{
|
||||
// Another player left the network game.
|
||||
NetPacketPlayerLeft::Data netPlayerData;
|
||||
packet->ToNetPacketPlayerLeft()->GetData(netPlayerData);
|
||||
client.RemovePlayerData(netPlayerData.playerId);
|
||||
}
|
||||
// TODO: handle error packet (kicked from server)
|
||||
|
||||
return retVal;
|
||||
|
||||
@@ -35,6 +35,34 @@ using namespace std;
|
||||
#define SERVER_WAIT_TIMEOUT_MSEC 50
|
||||
#define SERVER_NEXT_HAND_DELAY_SEC 10
|
||||
|
||||
// Helper functions
|
||||
|
||||
static PlayerInterface *GetCurrentPlayer(Game &curGame)
|
||||
{
|
||||
int curPlayerNum = 0;
|
||||
// TODO: no switch needed here if game states are polymorphic
|
||||
switch(curGame.getCurrentHand()->getActualRound()) {
|
||||
case GAME_STATE_PREFLOP: {
|
||||
curPlayerNum = curGame.getCurrentHand()->getPreflop()->getPlayersTurn();
|
||||
} break;
|
||||
case GAME_STATE_FLOP: {
|
||||
curPlayerNum = curGame.getCurrentHand()->getFlop()->getPlayersTurn();
|
||||
} break;
|
||||
case GAME_STATE_TURN: {
|
||||
curPlayerNum = curGame.getCurrentHand()->getTurn()->getPlayersTurn();
|
||||
} break;
|
||||
case GAME_STATE_RIVER: {
|
||||
curPlayerNum = curGame.getCurrentHand()->getRiver()->getPlayersTurn();
|
||||
} break;
|
||||
default: {
|
||||
//
|
||||
}
|
||||
}
|
||||
assert(curPlayerNum < curGame.getStartQuantityPlayers()); // TODO: throw exception
|
||||
return curGame.getPlayerArray()[curPlayerNum];
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
ServerRecvState::~ServerRecvState()
|
||||
{
|
||||
@@ -567,32 +595,6 @@ ServerRecvStateStartRound::GameRun(Game &curGame)
|
||||
}
|
||||
}
|
||||
|
||||
PlayerInterface *
|
||||
ServerRecvStateStartRound::GetCurrentPlayer(Game &curGame)
|
||||
{
|
||||
int curPlayerNum = 0;
|
||||
// TODO: no switch needed here if game states are polymorphic
|
||||
switch(curGame.getCurrentHand()->getActualRound()) {
|
||||
case GAME_STATE_PREFLOP: {
|
||||
curPlayerNum = curGame.getCurrentHand()->getPreflop()->getPlayersTurn();
|
||||
} break;
|
||||
case GAME_STATE_FLOP: {
|
||||
curPlayerNum = curGame.getCurrentHand()->getFlop()->getPlayersTurn();
|
||||
} break;
|
||||
case GAME_STATE_TURN: {
|
||||
curPlayerNum = curGame.getCurrentHand()->getTurn()->getPlayersTurn();
|
||||
} break;
|
||||
case GAME_STATE_RIVER: {
|
||||
curPlayerNum = curGame.getCurrentHand()->getRiver()->getPlayersTurn();
|
||||
} break;
|
||||
default: {
|
||||
//
|
||||
}
|
||||
}
|
||||
assert(curPlayerNum < curGame.getStartQuantityPlayers()); // TODO: throw exception
|
||||
return curGame.getPlayerArray()[curPlayerNum];
|
||||
}
|
||||
|
||||
void
|
||||
ServerRecvStateStartRound::SendNewRoundCards(ServerRecvThread &server, Game &curGame, int state)
|
||||
{
|
||||
@@ -655,6 +657,28 @@ ServerRecvStateWaitPlayerAction::~ServerRecvStateWaitPlayerAction()
|
||||
{
|
||||
}
|
||||
|
||||
int
|
||||
ServerRecvStateWaitPlayerAction::Process(ServerRecvThread &server)
|
||||
{
|
||||
int retVal;
|
||||
|
||||
// If the player we are waiting for left, continue without him.
|
||||
PlayerInterface *tmpPlayer = GetCurrentPlayer(server.GetGame());
|
||||
assert(tmpPlayer);
|
||||
if (!tmpPlayer->getMyActiveStatus())
|
||||
{
|
||||
assert(tmpPlayer->getMyAction() == PLAYER_ACTION_FOLD && tmpPlayer->getMyCash() == 0);
|
||||
PerformPlayerAction(server, tmpPlayer, PLAYER_ACTION_FOLD, 0);
|
||||
|
||||
server.SetState(ServerRecvStateStartRound::Instance());
|
||||
retVal = MSG_NET_GAME_SERVER_ACTION;
|
||||
}
|
||||
else
|
||||
retVal = ServerRecvStateReceiving::Process(server);
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
int
|
||||
ServerRecvStateWaitPlayerAction::InternalProcess(ServerRecvThread &server, SessionWrapper session, boost::shared_ptr<NetPacket> packet)
|
||||
{
|
||||
@@ -668,28 +692,10 @@ ServerRecvStateWaitPlayerAction::InternalProcess(ServerRecvThread &server, Sessi
|
||||
Game &curGame = server.GetGame();
|
||||
PlayerInterface *tmpPlayer = curGame.getPlayerByUniqueId(session.playerData->GetUniqueId());
|
||||
assert(tmpPlayer); // TODO throw exception
|
||||
// TODO: check whether this is the correct player
|
||||
// TODO: check game state
|
||||
|
||||
tmpPlayer->setMyAction(actionData.playerAction);
|
||||
// Only change the player bet if action is not fold/check
|
||||
if (actionData.playerAction != PLAYER_ACTION_FOLD && actionData.playerAction != PLAYER_ACTION_CHECK)
|
||||
{
|
||||
tmpPlayer->setMySet(actionData.playerBet);
|
||||
|
||||
if (tmpPlayer->getMySet() > GetHighestSet(curGame))
|
||||
SetHighestSet(curGame, tmpPlayer->getMySet());
|
||||
}
|
||||
|
||||
boost::shared_ptr<NetPacket> notifyActionDone(new NetPacketPlayersActionDone);
|
||||
NetPacketPlayersActionDone::Data actionDoneData;
|
||||
actionDoneData.gameState = static_cast<GameState>(curGame.getCurrentHand()->getActualRound());
|
||||
actionDoneData.playerId = session.playerData->GetUniqueId();
|
||||
actionDoneData.playerAction = actionData.playerAction;
|
||||
actionDoneData.totalPlayerBet = tmpPlayer->getMySet();
|
||||
actionDoneData.playerMoney = tmpPlayer->getMyCash();
|
||||
actionDoneData.potSize = curGame.getCurrentHand()->getBoard()->getPot();
|
||||
actionDoneData.curHandBets = curGame.getCurrentHand()->getBoard()->getSets();
|
||||
static_cast<NetPacketPlayersActionDone *>(notifyActionDone.get())->SetData(actionDoneData);
|
||||
server.SendToAllPlayers(notifyActionDone);
|
||||
PerformPlayerAction(server, tmpPlayer, actionData.playerAction, actionData.playerBet);
|
||||
|
||||
server.SetState(ServerRecvStateStartRound::Instance());
|
||||
retVal = MSG_NET_GAME_SERVER_ACTION;
|
||||
@@ -698,6 +704,34 @@ ServerRecvStateWaitPlayerAction::InternalProcess(ServerRecvThread &server, Sessi
|
||||
return retVal;
|
||||
}
|
||||
|
||||
void
|
||||
ServerRecvStateWaitPlayerAction::PerformPlayerAction(ServerRecvThread &server, PlayerInterface *player, PlayerAction action, int bet)
|
||||
{
|
||||
Game &curGame = server.GetGame();
|
||||
assert(player);
|
||||
player->setMyAction(action);
|
||||
// Only change the player bet if action is not fold/check
|
||||
if (action != PLAYER_ACTION_FOLD && action != PLAYER_ACTION_CHECK)
|
||||
{
|
||||
player->setMySet(bet);
|
||||
|
||||
if (player->getMySet() > GetHighestSet(curGame))
|
||||
SetHighestSet(curGame, player->getMySet());
|
||||
}
|
||||
|
||||
boost::shared_ptr<NetPacket> notifyActionDone(new NetPacketPlayersActionDone);
|
||||
NetPacketPlayersActionDone::Data actionDoneData;
|
||||
actionDoneData.gameState = static_cast<GameState>(curGame.getCurrentHand()->getActualRound());
|
||||
actionDoneData.playerId = player->getMyUniqueID();
|
||||
actionDoneData.playerAction = static_cast<PlayerAction>(player->getMyAction());
|
||||
actionDoneData.totalPlayerBet = player->getMySet();
|
||||
actionDoneData.playerMoney = player->getMyCash();
|
||||
actionDoneData.potSize = curGame.getCurrentHand()->getBoard()->getPot();
|
||||
actionDoneData.curHandBets = curGame.getCurrentHand()->getBoard()->getSets();
|
||||
static_cast<NetPacketPlayersActionDone *>(notifyActionDone.get())->SetData(actionDoneData);
|
||||
server.SendToAllPlayers(notifyActionDone);
|
||||
}
|
||||
|
||||
int
|
||||
ServerRecvStateWaitPlayerAction::GetHighestSet(Game &curGame)
|
||||
{
|
||||
|
||||
@@ -346,7 +346,17 @@ ServerRecvThread::CloseSessionDelayed(SessionWrapper session)
|
||||
boost::shared_ptr<PlayerData> tmpPlayerData = session.playerData;
|
||||
if (tmpPlayerData.get() && !tmpPlayerData->GetName().empty())
|
||||
{
|
||||
GetCallback().SignalNetServerPlayerLeft(tmpPlayerData->GetName());
|
||||
// Set player inactive.
|
||||
if (m_game.get())
|
||||
{
|
||||
PlayerInterface *player = GetGame().getPlayerByUniqueId(tmpPlayerData->GetUniqueId());
|
||||
if (player)
|
||||
{
|
||||
player->setMyAction(PLAYER_ACTION_FOLD);
|
||||
player->setMyCash(0);
|
||||
player->setMyActiveStatus(false);
|
||||
}
|
||||
}
|
||||
|
||||
// Send "Player Left" to clients.
|
||||
boost::shared_ptr<NetPacket> thisPlayerLeft(new NetPacketPlayerLeft);
|
||||
@@ -354,6 +364,8 @@ ServerRecvThread::CloseSessionDelayed(SessionWrapper session)
|
||||
thisPlayerLeftData.playerId = tmpPlayerData->GetUniqueId();
|
||||
static_cast<NetPacketPlayerLeft *>(thisPlayerLeft.get())->SetData(thisPlayerLeftData);
|
||||
SendToAllPlayers(thisPlayerLeft);
|
||||
|
||||
GetCallback().SignalNetServerPlayerLeft(tmpPlayerData->GetName());
|
||||
}
|
||||
|
||||
boost::microsec_timer closeTimer;
|
||||
|
||||
Reference in New Issue
Block a user