From 91b62abf7b2a7db7648dbe5eb101dfaa13c0e859 Mon Sep 17 00:00:00 2001 From: lotodore Date: Wed, 2 Apr 2008 21:41:39 +0000 Subject: [PATCH] Fixed nasty synchronization bug when players leave during start of a game. Fixed netpacket error which occured occasionally during game start when only one player was left, the last player will be removed from the game now, but stay in the lobby. Added new stat to IRC bot. --- src/net/common/netpacket.cpp | 7 ++++ src/net/common/servergamestate.cpp | 59 +++++++++++++++++++---------- src/net/common/servergamethread.cpp | 2 + src/net/common/servermanager.cpp | 6 +++ src/net/socket_msg.h | 1 + 5 files changed, 54 insertions(+), 21 deletions(-) diff --git a/src/net/common/netpacket.cpp b/src/net/common/netpacket.cpp index 06c5568c..d90f7266 100644 --- a/src/net/common/netpacket.cpp +++ b/src/net/common/netpacket.cpp @@ -100,6 +100,7 @@ using namespace std; #define NET_REMOVED_GAME_ALREADY_RUNNING 0x0002 #define NET_REMOVED_KICKED 0x0003 #define NET_REMOVED_TIMEOUT 0x0004 +#define NET_REMOVED_START_FAILED 0x0005 #define NET_REMOVED_OTHER_REASON 0xFFFF // Reasons for timeout warning @@ -4281,6 +4282,9 @@ NetPacketRemovedFromGame::SetData(const NetPacketRemovedFromGame::Data &inData) case NTF_NET_REMOVED_TIMEOUT : tmpData->removeReason = htons(NET_REMOVED_TIMEOUT); break; + case NTF_NET_REMOVED_START_FAILED : + tmpData->removeReason = htons(NET_REMOVED_START_FAILED); + break; default : tmpData->removeReason = htons(NET_REMOVED_OTHER_REASON); break; @@ -4313,6 +4317,9 @@ NetPacketRemovedFromGame::GetData(NetPacketRemovedFromGame::Data &outData) const case NET_REMOVED_TIMEOUT : outData.removeReason = NTF_NET_REMOVED_TIMEOUT; break; + case NET_REMOVED_START_FAILED : + outData.removeReason = NTF_NET_REMOVED_START_FAILED; + break; default : outData.removeReason = NTF_NET_INTERNAL; break; diff --git a/src/net/common/servergamestate.cpp b/src/net/common/servergamestate.cpp index 1a04e0f0..8dd5adf0 100644 --- a/src/net/common/servergamestate.cpp +++ b/src/net/common/servergamestate.cpp @@ -458,6 +458,7 @@ ServerGameStateWaitAck::Process(ServerGameThread &server) if (server.GetStateTimer().elapsed().total_seconds() >= SERVER_START_GAME_TIMEOUT_SEC) { // On timeout: start anyway. + server.GetSessionManager().ResetAllReadyFlags(); server.SetState(SERVER_START_GAME_STATE::Instance()); retVal = MSG_SOCK_INIT_DONE; } @@ -509,33 +510,49 @@ ServerGameStateStartGame::~ServerGameStateStartGame() int ServerGameStateStartGame::Process(ServerGameThread &server) { - server.InternalStartGame(); + int retVal = MSG_SOCK_INTERNAL_PENDING; - boost::shared_ptr answer(new NetPacketGameStart); - - NetPacketGameStart::Data gameStartData; - gameStartData.startData = server.GetStartData(); - - // Send player order to clients. - // Assume player list is sorted by number. PlayerDataList tmpPlayerList = server.GetFullPlayerDataList(); - PlayerDataList::iterator player_i = tmpPlayerList.begin(); - PlayerDataList::iterator player_end = tmpPlayerList.end(); - while (player_i != player_end) + if (tmpPlayerList.size() <= 1) { - NetPacketGameStart::PlayerSlot tmpPlayerSlot; - tmpPlayerSlot.playerId = (*player_i)->GetUniqueId(); - gameStartData.playerSlots.push_back(tmpPlayerSlot); + if (!tmpPlayerList.empty()) + { + boost::shared_ptr tmpPlayer(tmpPlayerList.front()); + SessionWrapper tmpSession = server.GetSessionManager().GetSessionByUniquePlayerId(tmpPlayer->GetUniqueId()); + if (tmpSession.sessionData.get()) + server.MoveSessionToLobby(tmpSession, NTF_NET_REMOVED_START_FAILED); + } + } + else + { + server.InternalStartGame(); - ++player_i; + boost::shared_ptr answer(new NetPacketGameStart); + + NetPacketGameStart::Data gameStartData; + gameStartData.startData = server.GetStartData(); + + // Send player order to clients. + // Assume player list is sorted by number. + PlayerDataList::iterator player_i = tmpPlayerList.begin(); + PlayerDataList::iterator player_end = tmpPlayerList.end(); + while (player_i != player_end) + { + NetPacketGameStart::PlayerSlot tmpPlayerSlot; + tmpPlayerSlot.playerId = (*player_i)->GetUniqueId(); + gameStartData.playerSlots.push_back(tmpPlayerSlot); + + ++player_i; + } + + static_cast(answer.get())->SetData(gameStartData); + + server.SendToAllPlayers(answer, SessionData::Game); + server.SetState(ServerGameStateStartHand::Instance()); + retVal = MSG_NET_GAME_SERVER_START; } - static_cast(answer.get())->SetData(gameStartData); - - server.SendToAllPlayers(answer, SessionData::Game); - server.SetState(ServerGameStateStartHand::Instance()); - - return MSG_NET_GAME_SERVER_START; + return retVal; } //----------------------------------------------------------------------------- diff --git a/src/net/common/servergamethread.cpp b/src/net/common/servergamethread.cpp index b538156d..10cc7617 100644 --- a/src/net/common/servergamethread.cpp +++ b/src/net/common/servergamethread.cpp @@ -404,6 +404,8 @@ void ServerGameThread::MoveSessionToLobby(SessionWrapper session, int reason) { GracefulRemoveSession(session); + // Reset ready flag - just in case it is set, player may leave at any time. + session.sessionData->ResetReadyFlag(); GetLobbyThread().ReAddSession(session, reason); } diff --git a/src/net/common/servermanager.cpp b/src/net/common/servermanager.cpp index 2fbc7d88..9ceb358a 100644 --- a/src/net/common/servermanager.cpp +++ b/src/net/common/servermanager.cpp @@ -124,6 +124,12 @@ ServerManager::SignalIrcChatMsg(const std::string &nickName, const std::string & << "Players currently on Server.. " << tmpStats.numberOfPlayersOnServer; m_ircThread->SendChatMessage(statStream.str()); } + { + ostringstream statStream; + statStream + << "Games currently open......... " << tmpStats.numberOfGamesOpen; + m_ircThread->SendChatMessage(statStream.str()); + } { ostringstream statStream; statStream diff --git a/src/net/socket_msg.h b/src/net/socket_msg.h index 454d2eb5..1421b23a 100644 --- a/src/net/socket_msg.h +++ b/src/net/socket_msg.h @@ -91,6 +91,7 @@ #define NTF_NET_REMOVED_ALREADY_RUNNING 204 #define NTF_NET_REMOVED_KICKED 205 #define NTF_NET_REMOVED_TIMEOUT 206 +#define NTF_NET_REMOVED_START_FAILED 207 // Notifications - join failed #define NTF_NET_JOIN_GAME_FULL 210