Polishing rejoin implementation.
This commit is contained in:
+127
-133
@@ -371,6 +371,53 @@ AbstractServerGameStateReceiving::CreateNetPacketPlayerJoined(unsigned gameId, c
|
||||
return packet;
|
||||
}
|
||||
|
||||
boost::shared_ptr<NetPacket>
|
||||
AbstractServerGameStateReceiving::CreateNetPacketJoinGameAck(const ServerGame &server, const PlayerData &playerData)
|
||||
{
|
||||
boost::shared_ptr<NetPacket> packet(new NetPacket(NetPacket::Alloc));
|
||||
packet->GetMsg()->present = PokerTHMessage_PR_joinGameReplyMessage;
|
||||
JoinGameReplyMessage_t *netJoinReply = &packet->GetMsg()->choice.joinGameReplyMessage;
|
||||
netJoinReply->gameId = server.GetId();
|
||||
netJoinReply->joinGameResult.present = joinGameResult_PR_joinGameAck;
|
||||
JoinGameAck_t *joinAck = &netJoinReply->joinGameResult.choice.joinGameAck;
|
||||
joinAck->areYouGameAdmin = static_cast<PlayerInfoRights>(playerData.IsGameAdmin());
|
||||
|
||||
NetPacket::SetGameData(server.GetGameData(), &joinAck->gameInfo);
|
||||
OCTET_STRING_fromBuf(
|
||||
&joinAck->gameInfo.gameName,
|
||||
server.GetName().c_str(),
|
||||
(int)server.GetName().length());
|
||||
return packet;
|
||||
}
|
||||
|
||||
void
|
||||
AbstractServerGameStateReceiving::AcceptNewSession(boost::shared_ptr<ServerGame> server, boost::shared_ptr<SessionData> session)
|
||||
{
|
||||
// Set game admin, if applicable.
|
||||
session->GetPlayerData()->SetGameAdmin(session->GetPlayerData()->GetUniqueId() == server->GetAdminPlayerId());
|
||||
|
||||
// Send ack to client.
|
||||
server->GetLobbyThread().GetSender().Send(session, CreateNetPacketJoinGameAck(*server, *session->GetPlayerData()));
|
||||
|
||||
// Send notifications for connected players to client.
|
||||
PlayerDataList tmpPlayerList(server->GetFullPlayerDataList());
|
||||
PlayerDataList::iterator player_i = tmpPlayerList.begin();
|
||||
PlayerDataList::iterator player_end = tmpPlayerList.end();
|
||||
while (player_i != player_end) {
|
||||
server->GetLobbyThread().GetSender().Send(session, CreateNetPacketPlayerJoined(server->GetId(), *(*player_i)));
|
||||
++player_i;
|
||||
}
|
||||
|
||||
// Send "Player Joined" to other fully connected clients.
|
||||
server->SendToAllPlayers(CreateNetPacketPlayerJoined(server->GetId(), *session->GetPlayerData()), SessionData::Game);
|
||||
|
||||
// Accept session.
|
||||
server->GetSessionManager().AddSession(session);
|
||||
|
||||
// Notify lobby.
|
||||
server->GetLobbyThread().NotifyPlayerJoinedGame(server->GetId(), session->GetPlayerData()->GetUniqueId());
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
ServerGameStateInit ServerGameStateInit::s_state;
|
||||
@@ -424,41 +471,8 @@ ServerGameStateInit::HandleNewSession(boost::shared_ptr<ServerGame> server, boos
|
||||
if (server->GetCurNumberOfPlayers() >= tmpGameData.maxNumberOfPlayers) {
|
||||
server->MoveSessionToLobby(session, NTF_NET_REMOVED_GAME_FULL);
|
||||
} else {
|
||||
session->GetPlayerData()->SetGameAdmin(session->GetPlayerData()->GetUniqueId() == server->GetAdminPlayerId());
|
||||
|
||||
// Send ack to client.
|
||||
boost::shared_ptr<NetPacket> packet(new NetPacket(NetPacket::Alloc));
|
||||
packet->GetMsg()->present = PokerTHMessage_PR_joinGameReplyMessage;
|
||||
JoinGameReplyMessage_t *netJoinReply = &packet->GetMsg()->choice.joinGameReplyMessage;
|
||||
netJoinReply->gameId = server->GetId();
|
||||
netJoinReply->joinGameResult.present = joinGameResult_PR_joinGameAck;
|
||||
JoinGameAck_t *joinAck = &netJoinReply->joinGameResult.choice.joinGameAck;
|
||||
joinAck->areYouGameAdmin = static_cast<PlayerInfoRights>(session->GetPlayerData()->IsGameAdmin());
|
||||
|
||||
NetPacket::SetGameData(server->GetGameData(), &joinAck->gameInfo);
|
||||
OCTET_STRING_fromBuf(
|
||||
&joinAck->gameInfo.gameName,
|
||||
server->GetName().c_str(),
|
||||
(int)server->GetName().length());
|
||||
server->GetLobbyThread().GetSender().Send(session, packet);
|
||||
|
||||
// Send notifications for connected players to client.
|
||||
PlayerDataList tmpPlayerList(server->GetFullPlayerDataList());
|
||||
PlayerDataList::iterator player_i = tmpPlayerList.begin();
|
||||
PlayerDataList::iterator player_end = tmpPlayerList.end();
|
||||
while (player_i != player_end) {
|
||||
server->GetLobbyThread().GetSender().Send(session, CreateNetPacketPlayerJoined(server->GetId(), *(*player_i)));
|
||||
++player_i;
|
||||
}
|
||||
|
||||
// Send "Player Joined" to other fully connected clients.
|
||||
server->SendToAllPlayers(CreateNetPacketPlayerJoined(server->GetId(), *session->GetPlayerData()), SessionData::Game);
|
||||
|
||||
// Accept session.
|
||||
server->GetSessionManager().AddSession(session);
|
||||
|
||||
// Notify lobby.
|
||||
server->GetLobbyThread().NotifyPlayerJoinedGame(server->GetId(), session->GetPlayerData()->GetUniqueId());
|
||||
AcceptNewSession(server, session);
|
||||
|
||||
if (server->GetCurNumberOfPlayers() == tmpGameData.maxNumberOfPlayers) {
|
||||
// Automatically start the game if it is full.
|
||||
@@ -755,50 +769,15 @@ AbstractServerGameStateRunning::HandleNewSession(boost::shared_ptr<ServerGame> s
|
||||
{
|
||||
|
||||
// Verify that the user is allowed to rejoin.
|
||||
boost::shared_ptr<PlayerInterface> tmpPlayer = server->GetPlayerInterfaceFromGame(session->GetPlayerData()->GetName());
|
||||
if (tmpPlayer && tmpPlayer->getMyGuid() == session->GetPlayerData()->GetOldGuid()) {
|
||||
// Perform rejoin at hand start.
|
||||
// Send ack to client.
|
||||
// TODO this code is partly copy & paste.
|
||||
{
|
||||
boost::shared_ptr<NetPacket> packet(new NetPacket(NetPacket::Alloc));
|
||||
packet->GetMsg()->present = PokerTHMessage_PR_joinGameReplyMessage;
|
||||
JoinGameReplyMessage_t *netJoinReply = &packet->GetMsg()->choice.joinGameReplyMessage;
|
||||
netJoinReply->gameId = server->GetId();
|
||||
netJoinReply->joinGameResult.present = joinGameResult_PR_joinGameAck;
|
||||
JoinGameAck_t *joinAck = &netJoinReply->joinGameResult.choice.joinGameAck;
|
||||
joinAck->areYouGameAdmin = static_cast<PlayerInfoRights>(session->GetPlayerData()->IsGameAdmin());
|
||||
if (session && session->GetPlayerData()) {
|
||||
boost::shared_ptr<PlayerInterface> tmpPlayer = server->GetPlayerInterfaceFromGame(session->GetPlayerData()->GetName());
|
||||
if (tmpPlayer && tmpPlayer->getMyGuid() == session->GetPlayerData()->GetOldGuid()) {
|
||||
// The player wants to rejoin.
|
||||
AcceptNewSession(server, session);
|
||||
// Remember: We need to initiate a rejoin when starting the next hand.
|
||||
server->AddRejoinPlayer(session->GetPlayerData()->GetUniqueId());
|
||||
|
||||
NetPacket::SetGameData(server->GetGameData(), &joinAck->gameInfo);
|
||||
OCTET_STRING_fromBuf(
|
||||
&joinAck->gameInfo.gameName,
|
||||
server->GetName().c_str(),
|
||||
(int)server->GetName().length());
|
||||
server->GetLobbyThread().GetSender().Send(session, packet);
|
||||
}
|
||||
|
||||
// Send notifications for connected players to client.
|
||||
PlayerDataList tmpPlayerList = server->GetFullPlayerDataList();
|
||||
PlayerDataList::iterator player_i = tmpPlayerList.begin();
|
||||
PlayerDataList::iterator player_end = tmpPlayerList.end();
|
||||
while (player_i != player_end) {
|
||||
server->GetLobbyThread().GetSender().Send(session, CreateNetPacketPlayerJoined(server->GetId(), *(*player_i)));
|
||||
++player_i;
|
||||
}
|
||||
|
||||
// Send "Player Joined" to other fully connected clients.
|
||||
server->SendToAllPlayers(CreateNetPacketPlayerJoined(server->GetId(), *session->GetPlayerData()), SessionData::Game);
|
||||
|
||||
// Accept session.
|
||||
server->GetSessionManager().AddSession(session);
|
||||
// Remember: We need to initiate a rejoin when starting the next hand.
|
||||
server->AddRejoinPlayer(session->GetPlayerData()->GetUniqueId());
|
||||
|
||||
// Notify lobby.
|
||||
server->GetLobbyThread().NotifyPlayerJoinedGame(server->GetId(), session->GetPlayerData()->GetUniqueId());
|
||||
|
||||
// Send start event right away.
|
||||
{
|
||||
// Send start event right away.
|
||||
boost::shared_ptr<NetPacket> packet(new NetPacket(NetPacket::Alloc));
|
||||
packet->GetMsg()->present = PokerTHMessage_PR_startEventMessage;
|
||||
StartEventMessage_t *netStartEvent = &packet->GetMsg()->choice.startEventMessage;
|
||||
@@ -807,10 +786,10 @@ AbstractServerGameStateRunning::HandleNewSession(boost::shared_ptr<ServerGame> s
|
||||
|
||||
// Wait for rejoining player to confirm start of game.
|
||||
server->GetLobbyThread().GetSender().Send(session, packet);
|
||||
} else {
|
||||
// Do not accept "new" sessions in this state, only rejoin is allowed.
|
||||
server->MoveSessionToLobby(session, NTF_NET_REMOVED_ALREADY_RUNNING);
|
||||
}
|
||||
} else {
|
||||
// Do not accept "new" sessions in this state, only rejoin is allowed.
|
||||
server->MoveSessionToLobby(session, NTF_NET_REMOVED_ALREADY_RUNNING);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1136,59 +1115,8 @@ ServerGameStateHand::StartNewHand(boost::shared_ptr<ServerGame> server)
|
||||
Game &curGame = server->GetGame();
|
||||
|
||||
// Initialize rejoining players.
|
||||
{
|
||||
PlayerIdList rejoinIdList(server->GetAndResetRejoinPlayers());
|
||||
PlayerIdList::iterator i = rejoinIdList.begin();
|
||||
PlayerIdList::iterator end = rejoinIdList.end();
|
||||
while (i != end) {
|
||||
boost::shared_ptr<SessionData> session(server->GetSessionManager().GetSessionByUniquePlayerId(*i));
|
||||
if (session) {
|
||||
// Set new player id.
|
||||
boost::shared_ptr<PlayerInterface> rejoinPlayer = curGame.getPlayerByName(session->GetPlayerData()->GetName());
|
||||
if (rejoinPlayer) {
|
||||
// Notify other clients about id change.
|
||||
boost::shared_ptr<NetPacket> packet(new NetPacket(NetPacket::Alloc));
|
||||
packet->GetMsg()->present = PokerTHMessage_PR_playerIdChangedMessage;
|
||||
PlayerIdChangedMessage_t *netIdChanged = &packet->GetMsg()->choice.playerIdChangedMessage;
|
||||
netIdChanged->oldPlayerId = rejoinPlayer->getMyUniqueID();
|
||||
netIdChanged->newPlayerId = session->GetPlayerData()->GetUniqueId();
|
||||
server->SendToAllButOnePlayers(packet, session->GetId(), SessionData::Game);
|
||||
|
||||
// Update the dealer, if necessary.
|
||||
curGame.replaceDealer(rejoinPlayer->getMyUniqueID(), session->GetPlayerData()->GetUniqueId());
|
||||
// Change the Id in the poker engine.
|
||||
rejoinPlayer->setMyUniqueID(session->GetPlayerData()->GetUniqueId());
|
||||
rejoinPlayer->setIsConnected(true);
|
||||
|
||||
// Send game start notification to rejoining client.
|
||||
packet.reset(new NetPacket(NetPacket::Alloc));
|
||||
packet->GetMsg()->present = PokerTHMessage_PR_gameStartMessage;
|
||||
GameStartMessage_t *netGameStart = &packet->GetMsg()->choice.gameStartMessage;
|
||||
netGameStart->gameId = server->GetId();
|
||||
netGameStart->startDealerPlayerId = curGame.getDealerPosition();
|
||||
netGameStart->gameStartMode.present = gameStartMode_PR_gameStartModeRejoin;
|
||||
GameStartModeRejoin_t *netStartModeRejoin = &netGameStart->gameStartMode.choice.gameStartModeRejoin;
|
||||
|
||||
netStartModeRejoin->handNum = curGame.getCurrentHandID();
|
||||
PlayerListIterator player_i = curGame.getSeatsList()->begin();
|
||||
PlayerListIterator player_end = curGame.getSeatsList()->end();
|
||||
while (player_i != player_end) {
|
||||
boost::shared_ptr<PlayerInterface> tmpPlayer = *player_i;
|
||||
if (tmpPlayer->getMyActiveStatus()) {
|
||||
RejoinPlayerData_t *playerSlot = (RejoinPlayerData_t *)calloc(1, sizeof(RejoinPlayerData_t));
|
||||
playerSlot->playerId = tmpPlayer->getMyUniqueID();
|
||||
playerSlot->playerMoney = tmpPlayer->getMyCash();
|
||||
ASN_SEQUENCE_ADD(&netStartModeRejoin->rejoinPlayerData.list, playerSlot);
|
||||
}
|
||||
++player_i;
|
||||
}
|
||||
|
||||
server->GetLobbyThread().GetSender().Send(session, packet);
|
||||
}
|
||||
}
|
||||
++i;
|
||||
}
|
||||
}
|
||||
// This has to be done before initialising the new hand, because there are side effects.
|
||||
InitRejoiningPlayers(server);
|
||||
|
||||
// Initialize hand.
|
||||
curGame.initHand();
|
||||
@@ -1305,6 +1233,72 @@ ServerGameStateHand::StartNewHand(boost::shared_ptr<ServerGame> server)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ServerGameStateHand::InitRejoiningPlayers(boost::shared_ptr<ServerGame> server)
|
||||
{
|
||||
PlayerIdList rejoinIdList(server->GetAndResetRejoinPlayers());
|
||||
PlayerIdList::iterator i = rejoinIdList.begin();
|
||||
PlayerIdList::iterator end = rejoinIdList.end();
|
||||
while (i != end) {
|
||||
boost::shared_ptr<SessionData> session(server->GetSessionManager().GetSessionByUniquePlayerId(*i));
|
||||
if (session && session->GetPlayerData()) {
|
||||
PerformRejoin(server, session);
|
||||
}
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ServerGameStateHand::PerformRejoin(boost::shared_ptr<ServerGame> server, boost::shared_ptr<SessionData> session)
|
||||
{
|
||||
Game &curGame = server->GetGame();
|
||||
// Set new player id.
|
||||
boost::shared_ptr<PlayerInterface> rejoinPlayer = curGame.getPlayerByName(session->GetPlayerData()->GetName());
|
||||
if (rejoinPlayer) {
|
||||
// Notify other clients about id change.
|
||||
boost::shared_ptr<NetPacket> packet(new NetPacket(NetPacket::Alloc));
|
||||
packet->GetMsg()->present = PokerTHMessage_PR_playerIdChangedMessage;
|
||||
PlayerIdChangedMessage_t *netIdChanged = &packet->GetMsg()->choice.playerIdChangedMessage;
|
||||
netIdChanged->oldPlayerId = rejoinPlayer->getMyUniqueID();
|
||||
netIdChanged->newPlayerId = session->GetPlayerData()->GetUniqueId();
|
||||
server->SendToAllButOnePlayers(packet, session->GetId(), SessionData::Game);
|
||||
|
||||
// Update the dealer, if necessary.
|
||||
curGame.replaceDealer(rejoinPlayer->getMyUniqueID(), session->GetPlayerData()->GetUniqueId());
|
||||
// Change the Id in the poker engine.
|
||||
rejoinPlayer->setMyUniqueID(session->GetPlayerData()->GetUniqueId());
|
||||
rejoinPlayer->setMyGuid(session->GetPlayerData()->GetGuid());
|
||||
rejoinPlayer->setIsConnected(true);
|
||||
|
||||
// Send game start notification to rejoining client.
|
||||
packet.reset(new NetPacket(NetPacket::Alloc));
|
||||
packet->GetMsg()->present = PokerTHMessage_PR_gameStartMessage;
|
||||
GameStartMessage_t *netGameStart = &packet->GetMsg()->choice.gameStartMessage;
|
||||
netGameStart->gameId = server->GetId();
|
||||
netGameStart->startDealerPlayerId = curGame.getDealerPosition();
|
||||
netGameStart->gameStartMode.present = gameStartMode_PR_gameStartModeRejoin;
|
||||
GameStartModeRejoin_t *netStartModeRejoin = &netGameStart->gameStartMode.choice.gameStartModeRejoin;
|
||||
|
||||
netStartModeRejoin->handNum = curGame.getCurrentHandID();
|
||||
PlayerListIterator player_i = curGame.getSeatsList()->begin();
|
||||
PlayerListIterator player_end = curGame.getSeatsList()->end();
|
||||
while (player_i != player_end) {
|
||||
boost::shared_ptr<PlayerInterface> tmpPlayer = *player_i;
|
||||
if (tmpPlayer->getMyActiveStatus()) {
|
||||
RejoinPlayerData_t *playerSlot = (RejoinPlayerData_t *)calloc(1, sizeof(RejoinPlayerData_t));
|
||||
playerSlot->playerId = tmpPlayer->getMyUniqueID();
|
||||
playerSlot->playerMoney = tmpPlayer->getMyCash();
|
||||
ASN_SEQUENCE_ADD(&netStartModeRejoin->rejoinPlayerData.list, playerSlot);
|
||||
}
|
||||
++player_i;
|
||||
}
|
||||
|
||||
server->GetLobbyThread().GetSender().Send(session, packet);
|
||||
} else {
|
||||
server->SessionError(session, ERR_SOCK_INVALID_STATE);
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
@@ -65,6 +65,9 @@ public:
|
||||
virtual void ProcessPacket(boost::shared_ptr<ServerGame> server, boost::shared_ptr<SessionData> session, boost::shared_ptr<NetPacket> packet);
|
||||
|
||||
static boost::shared_ptr<NetPacket> CreateNetPacketPlayerJoined(unsigned gameId, const PlayerData &playerData);
|
||||
static boost::shared_ptr<NetPacket> CreateNetPacketJoinGameAck(const ServerGame &server, const PlayerData &playerData);
|
||||
|
||||
static void AcceptNewSession(boost::shared_ptr<ServerGame> server, boost::shared_ptr<SessionData> session);
|
||||
|
||||
protected:
|
||||
|
||||
@@ -162,6 +165,8 @@ protected:
|
||||
void TimerNextGame(const boost::system::error_code &ec, boost::shared_ptr<ServerGame> server, unsigned winnerPlayerId);
|
||||
int GetDealCardsDelaySec(ServerGame &server);
|
||||
static void StartNewHand(boost::shared_ptr<ServerGame> server);
|
||||
static void InitRejoiningPlayers(boost::shared_ptr<ServerGame> server);
|
||||
static void PerformRejoin(boost::shared_ptr<ServerGame> server, boost::shared_ptr<SessionData> session);
|
||||
|
||||
private:
|
||||
static ServerGameStateHand s_state;
|
||||
|
||||
Reference in New Issue
Block a user