More work on rejoin. This is still broken because the player id is not yet updated on client side, and the server still does not activate the rejoining player.
This commit is contained in:
@@ -1500,28 +1500,49 @@ ClientStateWaitStart::InternalHandlePacket(boost::shared_ptr<ClientThread> clien
|
||||
|
||||
StartData startData;
|
||||
startData.startDealerPlayerId = netGameStart->startDealerPlayerId;
|
||||
if (netGameStart->gameStartMode.present != gameStartMode_PR_gameStartModeInitial)
|
||||
if (netGameStart->gameStartMode.present == gameStartMode_PR_gameStartModeInitial)
|
||||
{
|
||||
GameStartModeInitial_t *netStartModeInitial = &netGameStart->gameStartMode.choice.gameStartModeInitial;
|
||||
startData.numberOfPlayers = netStartModeInitial->playerSeats.list.count;
|
||||
client->SetStartData(startData);
|
||||
|
||||
// Set player numbers using the game start data slots.
|
||||
NonZeroId_t **playerIds = netStartModeInitial->playerSeats.list.array;
|
||||
unsigned numPlayers = netStartModeInitial->playerSeats.list.count;
|
||||
// Request player info for players if needed.
|
||||
if (numPlayers && playerIds && *playerIds) {
|
||||
for (unsigned i = 0; i < numPlayers; i++) {
|
||||
unsigned playerId = *playerIds[i];
|
||||
boost::shared_ptr<PlayerData> tmpPlayer = client->GetPlayerDataByUniqueId(playerId);
|
||||
if (!tmpPlayer.get())
|
||||
throw ClientException(__FILE__, __LINE__, ERR_NET_UNKNOWN_PLAYER_ID, 0);
|
||||
tmpPlayer->SetNumber(i);
|
||||
}
|
||||
} else
|
||||
throw ClientException(__FILE__, __LINE__, ERR_NET_INVALID_PLAYER_COUNT, 0);
|
||||
} else if (netGameStart->gameStartMode.present == gameStartMode_PR_gameStartModeRejoin) {
|
||||
GameStartModeRejoin_t *netStartModeRejoin = &netGameStart->gameStartMode.choice.gameStartModeRejoin;
|
||||
startData.numberOfPlayers = netStartModeRejoin->rejoinPlayerData.list.count;
|
||||
client->SetStartData(startData);
|
||||
|
||||
// Set player numbers using the game start data slots.
|
||||
RejoinPlayerData_t **playerInfos = netStartModeRejoin->rejoinPlayerData.list.array;
|
||||
unsigned numPlayers = netStartModeRejoin->rejoinPlayerData.list.count;
|
||||
// Request player info for players if needed.
|
||||
if (numPlayers && playerInfos && *playerInfos) {
|
||||
for (unsigned i = 0; i < numPlayers; i++) {
|
||||
RejoinPlayerData_t *playerData = playerInfos[i];
|
||||
boost::shared_ptr<PlayerData> tmpPlayer = client->GetPlayerDataByUniqueId(playerData->playerId);
|
||||
if (!tmpPlayer.get())
|
||||
throw ClientException(__FILE__, __LINE__, ERR_NET_UNKNOWN_PLAYER_ID, 0);
|
||||
tmpPlayer->SetNumber(i);
|
||||
// TODO set money
|
||||
}
|
||||
} else
|
||||
throw ClientException(__FILE__, __LINE__, ERR_NET_INVALID_PLAYER_COUNT, 0);
|
||||
} else {
|
||||
throw ClientException(__FILE__, __LINE__, ERR_NET_INTERNAL_GAME_ERROR, 0);
|
||||
|
||||
GameStartModeInitial_t *netStartModeInitial = &netGameStart->gameStartMode.choice.gameStartModeInitial;
|
||||
startData.numberOfPlayers = netStartModeInitial->playerSeats.list.count;
|
||||
client->SetStartData(startData);
|
||||
|
||||
// Set player numbers using the game start data slots.
|
||||
NonZeroId_t **playerIds = netStartModeInitial->playerSeats.list.array;
|
||||
unsigned numPlayers = netStartModeInitial->playerSeats.list.count;
|
||||
// Request player info for players if needed.
|
||||
if (numPlayers && playerIds && *playerIds) {
|
||||
for (unsigned i = 0; i < numPlayers; i++) {
|
||||
unsigned playerId = *playerIds[i];
|
||||
boost::shared_ptr<PlayerData> tmpPlayer = client->GetPlayerDataByUniqueId(playerId);
|
||||
if (!tmpPlayer.get())
|
||||
throw ClientException(__FILE__, __LINE__, ERR_NET_UNKNOWN_PLAYER_ID, 0);
|
||||
tmpPlayer->SetNumber(i);
|
||||
}
|
||||
} else
|
||||
throw ClientException(__FILE__, __LINE__, ERR_NET_INVALID_PLAYER_COUNT, 0);
|
||||
|
||||
}
|
||||
client->InitGame();
|
||||
client->GetCallback().SignalNetClientGameInfo(MSG_NET_GAME_CLIENT_START);
|
||||
client->SetState(ClientStateWaitHand::Instance());
|
||||
|
||||
@@ -627,6 +627,22 @@ ServerGame::SetPlayerAutoLeaveOnFinish(unsigned playerId)
|
||||
m_autoLeavePlayerList.push_back(playerId);
|
||||
}
|
||||
|
||||
void
|
||||
ServerGame::AddRejoinPlayer(unsigned playerId)
|
||||
{
|
||||
boost::mutex::scoped_lock lock(m_rejoinPlayerListMutex);
|
||||
m_rejoinPlayerList.push_back(playerId);
|
||||
}
|
||||
|
||||
PlayerIdList
|
||||
ServerGame::GetAndResetRejoinPlayers()
|
||||
{
|
||||
boost::mutex::scoped_lock lock(m_rejoinPlayerListMutex);
|
||||
PlayerIdList tmpList(m_rejoinPlayerList);
|
||||
m_rejoinPlayerList.clear();
|
||||
return tmpList;
|
||||
}
|
||||
|
||||
void
|
||||
ServerGame::AddComputerPlayer(boost::shared_ptr<PlayerData> player)
|
||||
{
|
||||
|
||||
@@ -357,6 +357,20 @@ AbstractServerGameStateReceiving::ProcessPacket(boost::shared_ptr<ServerGame> se
|
||||
}
|
||||
}
|
||||
|
||||
boost::shared_ptr<NetPacket>
|
||||
AbstractServerGameStateReceiving::CreateNetPacketPlayerJoined(unsigned gameId, const PlayerData &playerData)
|
||||
{
|
||||
boost::shared_ptr<NetPacket> packet(new NetPacket(NetPacket::Alloc));
|
||||
packet->GetMsg()->present = PokerTHMessage_PR_gamePlayerMessage;
|
||||
GamePlayerMessage_t *netGamePlayer = &packet->GetMsg()->choice.gamePlayerMessage;
|
||||
netGamePlayer->gameId = gameId;
|
||||
netGamePlayer->gamePlayerNotification.present = gamePlayerNotification_PR_gamePlayerJoined;
|
||||
GamePlayerJoined_t *playerJoined = &netGamePlayer->gamePlayerNotification.choice.gamePlayerJoined;
|
||||
playerJoined->playerId = playerData.GetUniqueId();
|
||||
playerJoined->isGameAdmin = playerData.IsGameAdmin();
|
||||
return packet;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
ServerGameStateInit ServerGameStateInit::s_state;
|
||||
@@ -429,7 +443,7 @@ ServerGameStateInit::HandleNewSession(boost::shared_ptr<ServerGame> server, boos
|
||||
server->GetLobbyThread().GetSender().Send(session, packet);
|
||||
|
||||
// Send notifications for connected players to client.
|
||||
PlayerDataList tmpPlayerList = server->GetFullPlayerDataList();
|
||||
PlayerDataList tmpPlayerList(server->GetFullPlayerDataList());
|
||||
PlayerDataList::iterator player_i = tmpPlayerList.begin();
|
||||
PlayerDataList::iterator player_end = tmpPlayerList.end();
|
||||
while (player_i != player_end) {
|
||||
@@ -624,20 +638,6 @@ ServerGameStateInit::InternalProcessPacket(boost::shared_ptr<ServerGame> server,
|
||||
}
|
||||
}
|
||||
|
||||
boost::shared_ptr<NetPacket>
|
||||
ServerGameStateInit::CreateNetPacketPlayerJoined(unsigned gameId, const PlayerData &playerData)
|
||||
{
|
||||
boost::shared_ptr<NetPacket> packet(new NetPacket(NetPacket::Alloc));
|
||||
packet->GetMsg()->present = PokerTHMessage_PR_gamePlayerMessage;
|
||||
GamePlayerMessage_t *netGamePlayer = &packet->GetMsg()->choice.gamePlayerMessage;
|
||||
netGamePlayer->gameId = gameId;
|
||||
netGamePlayer->gamePlayerNotification.present = gamePlayerNotification_PR_gamePlayerJoined;
|
||||
GamePlayerJoined_t *playerJoined = &netGamePlayer->gamePlayerNotification.choice.gamePlayerJoined;
|
||||
playerJoined->playerId = playerData.GetUniqueId();
|
||||
playerJoined->isGameAdmin = playerData.IsGameAdmin();
|
||||
return packet;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
ServerGameStateStartGame ServerGameStateStartGame::s_state;
|
||||
@@ -753,8 +753,65 @@ AbstractServerGameStateRunning::~AbstractServerGameStateRunning()
|
||||
void
|
||||
AbstractServerGameStateRunning::HandleNewSession(boost::shared_ptr<ServerGame> server, boost::shared_ptr<SessionData> session)
|
||||
{
|
||||
// Do not accept new sessions in this state.
|
||||
server->MoveSessionToLobby(session, NTF_NET_REMOVED_ALREADY_RUNNING);
|
||||
|
||||
// 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());
|
||||
|
||||
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.
|
||||
{
|
||||
boost::shared_ptr<NetPacket> packet(new NetPacket(NetPacket::Alloc));
|
||||
packet->GetMsg()->present = PokerTHMessage_PR_startEventMessage;
|
||||
StartEventMessage_t *netStartEvent = &packet->GetMsg()->choice.startEventMessage;
|
||||
netStartEvent->gameId = server->GetId();
|
||||
netStartEvent->fillWithComputerPlayers = false;
|
||||
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@@ -963,7 +1020,7 @@ ServerGameStateHand::EngineLoop(boost::shared_ptr<ServerGame> server)
|
||||
// Remove disconnected players. This is the one and only place to do this.
|
||||
server->RemoveDisconnectedPlayers();
|
||||
|
||||
// Update rankings of all remaining players.
|
||||
// Update rankings of all remaining players
|
||||
server->UpdateRankingMap();
|
||||
|
||||
// Start next hand - if enough players are left.
|
||||
@@ -1079,6 +1136,41 @@ ServerGameStateHand::StartNewHand(boost::shared_ptr<ServerGame> server)
|
||||
// Initialize hand.
|
||||
Game &curGame = server->GetGame();
|
||||
curGame.initHand();
|
||||
// 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) {
|
||||
boost::shared_ptr<NetPacket> packet(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;
|
||||
|
||||
// Send player data to client.
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
// HACK: Skip GUI notification run
|
||||
curGame.getCurrentHand()->getFlop()->skipFirstRunGui();
|
||||
|
||||
@@ -1314,13 +1314,7 @@ ServerLobbyThread::HandleNetPacketRejoinGame(boost::shared_ptr<SessionData> sess
|
||||
|
||||
if (pos != m_gameMap.end()) {
|
||||
boost::shared_ptr<ServerGame> game = pos->second;
|
||||
// Verify that the user is allowed to rejoin.
|
||||
boost::shared_ptr<PlayerInterface> tmpPlayer = game->GetPlayerInterfaceFromGame(session->GetPlayerData()->GetName());
|
||||
if (tmpPlayer && tmpPlayer->getMyGuid() == session->GetPlayerData()->GetOldGuid()) {
|
||||
MoveSessionToGame(game, session, autoLeave);
|
||||
} else {
|
||||
SendJoinGameFailed(session, rejoinGame.gameId, NTF_NET_JOIN_REJOIN_FAILED);
|
||||
}
|
||||
MoveSessionToGame(game, session, autoLeave);
|
||||
} else {
|
||||
SendJoinGameFailed(session, rejoinGame.gameId, NTF_NET_JOIN_GAME_INVALID);
|
||||
}
|
||||
|
||||
@@ -87,6 +87,9 @@ public:
|
||||
|
||||
void SetPlayerAutoLeaveOnFinish(unsigned playerId);
|
||||
|
||||
void AddRejoinPlayer(unsigned playerId);
|
||||
PlayerIdList GetAndResetRejoinPlayers();
|
||||
|
||||
unsigned GetSmallDelaySec() const;
|
||||
|
||||
// should be protected, but is needed in function.
|
||||
@@ -173,6 +176,9 @@ private:
|
||||
PlayerIdList m_autoLeavePlayerList;
|
||||
mutable boost::mutex m_autoLeavePlayerListMutex;
|
||||
|
||||
PlayerIdList m_rejoinPlayerList;
|
||||
mutable boost::mutex m_rejoinPlayerListMutex;
|
||||
|
||||
PlayerIdList m_reportedAvatarList;
|
||||
|
||||
RankingMap m_rankingMap;
|
||||
|
||||
@@ -64,6 +64,8 @@ public:
|
||||
// Calls InternalProcess if packet has not been processed.
|
||||
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);
|
||||
|
||||
protected:
|
||||
|
||||
virtual void InternalProcessPacket(boost::shared_ptr<ServerGame> server, boost::shared_ptr<SessionData> session, boost::shared_ptr<NetPacket> packet) = 0;
|
||||
@@ -98,8 +100,6 @@ protected:
|
||||
|
||||
virtual void InternalProcessPacket(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);
|
||||
|
||||
private:
|
||||
static ServerGameStateInit s_state;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user