diff --git a/src/net/common/servergamestate.cpp b/src/net/common/servergamestate.cpp index 6e0b20b0..a5dfb397 100644 --- a/src/net/common/servergamestate.cpp +++ b/src/net/common/servergamestate.cpp @@ -226,7 +226,6 @@ ServerGameStateInit::Instance() } ServerGameStateInit::ServerGameStateInit() -: m_curUniquePlayerId(0) { } @@ -264,7 +263,7 @@ ServerGameStateInit::HandleNewSession(ServerGameThread &server, SessionWrapper s server.GetSender().Send(session.sessionData->GetSocket(), joinGameAck); // Send notifications for connected players to client. - PlayerDataList tmpPlayerList = server.GetSessionManager().GetPlayerDataList(); + PlayerDataList tmpPlayerList = server.GetFullPlayerDataList(); PlayerDataList::iterator player_i = tmpPlayerList.begin(); PlayerDataList::iterator player_end = tmpPlayerList.end(); while (player_i != player_end) @@ -295,20 +294,20 @@ ServerGameStateInit::InternalProcess(ServerGameThread &server, SessionWrapper se if (packet->ToNetPacketStartEvent()) { server.ResetComputerPlayerList(); -/* int remainingSlots = server.GetGameData().maxNumberOfPlayers - server.GetCurNumberOfPlayers(); + int remainingSlots = server.GetGameData().maxNumberOfPlayers - server.GetCurNumberOfPlayers(); for (int i = 1; i <= remainingSlots; i++) { boost::shared_ptr tmpPlayerData( - new PlayerData(m_curUniquePlayerId++, 0, PLAYER_TYPE_COMPUTER, PLAYER_RIGHTS_NORMAL)); + new PlayerData(server.GetLobbyThread().GetNextUniquePlayerId(), 0, PLAYER_TYPE_COMPUTER, PLAYER_RIGHTS_NORMAL)); ostringstream name; name << SERVER_COMPUTER_PLAYER_NAME << i; tmpPlayerData->SetName(name.str()); + server.AddComputerPlayer(tmpPlayerData); // Send "Player Joined" to other fully connected clients. - server.SendToAllPlayers(CreateNetPacketPlayerJoined(*tmpPlayerData)); - server.AddComputerPlayer(tmpPlayerData); - }*/ + server.SendToAllPlayers(CreateNetPacketPlayerJoined(*tmpPlayerData), SessionData::Game); + } server.InternalStartGame(); server.SetState(SERVER_START_GAME_STATE::Instance()); @@ -387,7 +386,7 @@ ServerGameStateStartGame::Process(ServerGameThread &server) // Send player order to clients. // Assume player list is sorted by number. - PlayerDataList tmpPlayerList = server.GetSessionManager().GetPlayerDataList(); + PlayerDataList tmpPlayerList = server.GetFullPlayerDataList(); PlayerDataList::iterator player_i = tmpPlayerList.begin(); PlayerDataList::iterator player_end = tmpPlayerList.end(); while (player_i != player_end) diff --git a/src/net/common/servergamethread.cpp b/src/net/common/servergamethread.cpp index ce4e39fc..b0c75427 100644 --- a/src/net/common/servergamethread.cpp +++ b/src/net/common/servergamethread.cpp @@ -146,7 +146,7 @@ ServerGameThread::InternalStartGame() // Initialize the game. GuiInterface &gui = GetGui(); - PlayerDataList playerData = GetSessionManager().GetPlayerDataList(); + PlayerDataList playerData = GetFullPlayerDataList(); // Create EngineFactory boost::shared_ptr factory(new LocalEngineFactory(m_playerConfig)); // LocalEngine erstellen @@ -185,22 +185,81 @@ ServerGameThread::InternalStartGame() void ServerGameThread::InternalKickPlayer(unsigned playerId) { -// TODO -// SessionWrapper tmpSession = GetSessionByUniquePlayerId(uniqueId); -// SessionError(tmpSession, ERR_NET_PLAYER_KICKED); + SessionWrapper tmpSession = GetSessionManager().GetSessionByUniquePlayerId(playerId); + SessionError(tmpSession, ERR_NET_PLAYER_KICKED); +} + +PlayerDataList +ServerGameThread::GetFullPlayerDataList() const +{ + PlayerDataList playerList(GetSessionManager().GetPlayerDataList()); + boost::mutex::scoped_lock lock(m_computerPlayerListMutex); + copy(m_computerPlayerList.begin(), m_computerPlayerList.end(), back_inserter(playerList)); + + return playerList; +} + +boost::shared_ptr +ServerGameThread::GetPlayerDataByUniqueId(unsigned playerId) const +{ + boost::shared_ptr tmpPlayer; + SessionWrapper session = GetSessionManager().GetSessionByUniquePlayerId(playerId); + if (session.playerData.get()) + { + tmpPlayer = session.playerData; + } + else + { + boost::mutex::scoped_lock lock(m_computerPlayerListMutex); + PlayerDataList::const_iterator i = m_computerPlayerList.begin(); + PlayerDataList::const_iterator end = m_computerPlayerList.end(); + while (i != end) + { + if ((*i)->GetUniqueId() == playerId) + { + tmpPlayer = *i; + break; + } + ++i; + } + } + return tmpPlayer; +} + +PlayerIdList +ServerGameThread::GetPlayerIdList() const +{ + PlayerIdList idList(GetSessionManager().GetPlayerIdList()); + boost::mutex::scoped_lock lock(m_computerPlayerListMutex); + PlayerDataList::const_iterator i = m_computerPlayerList.begin(); + PlayerDataList::const_iterator end = m_computerPlayerList.end(); + while (i != end) + { + idList.push_back((*i)->GetUniqueId()); + ++i; + } + + return idList; +} + +bool +ServerGameThread::IsPlayerConnected(const std::string &name) const +{ + return GetSessionManager().IsPlayerConnected(name); } void ServerGameThread::AddComputerPlayer(boost::shared_ptr player) { - // TODO - m_computerPlayers.push_back(player); + boost::mutex::scoped_lock lock(m_computerPlayerListMutex); + m_computerPlayerList.push_back(player); } void ServerGameThread::ResetComputerPlayerList() { - m_computerPlayers.clear(); + boost::mutex::scoped_lock lock(m_computerPlayerListMutex); + m_computerPlayerList.clear(); } void @@ -271,7 +330,7 @@ ServerGameThread::RemoveDisconnectedPlayers() size_t ServerGameThread::GetCurNumberOfPlayers() const { - return GetSessionManager().GetPlayerDataList().size(); + return GetFullPlayerDataList().size(); } void @@ -279,7 +338,7 @@ ServerGameThread::AssignPlayerNumbers() { int playerNumber = 0; - PlayerDataList playerList = GetSessionManager().GetPlayerDataList(); + PlayerDataList playerList = GetFullPlayerDataList(); PlayerDataList::iterator player_i = playerList.begin(); PlayerDataList::iterator player_end = playerList.end(); diff --git a/src/net/common/serverlobbythread.cpp b/src/net/common/serverlobbythread.cpp index 03aa7f5e..7136eb62 100644 --- a/src/net/common/serverlobbythread.cpp +++ b/src/net/common/serverlobbythread.cpp @@ -127,6 +127,7 @@ ServerLobbyThread::RemoveGame(unsigned id) u_int32_t ServerLobbyThread::GetNextUniquePlayerId() { + boost::mutex::scoped_lock lock(m_curUniquePlayerIdMutex); return m_curUniquePlayerId++; } @@ -300,28 +301,28 @@ ServerLobbyThread::HandleNetPacketRetrievePlayerInfo(SessionWrapper session, con tmpPacket.GetData(request); // Find player in lobby or in a game. - SessionWrapper tmpSession = m_sessionManager.GetSessionByUniquePlayerId(request.playerId); - if (!tmpSession.sessionData.get() || !tmpSession.playerData.get()) + boost::shared_ptr tmpPlayer = m_sessionManager.GetSessionByUniquePlayerId(request.playerId).playerData; + if (!tmpPlayer.get()) { GameMap::const_iterator game_i = m_gameMap.begin(); GameMap::const_iterator game_end = m_gameMap.end(); while (game_i != game_end) { - tmpSession = game_i->second->GetSessionManager().GetSessionByUniquePlayerId(request.playerId); - if (tmpSession.sessionData.get() && tmpSession.playerData.get()) + tmpPlayer = game_i->second->GetPlayerDataByUniqueId(request.playerId); + if (tmpPlayer.get()) break; ++game_i; } } - if (tmpSession.sessionData.get() && tmpSession.playerData.get()) + if (tmpPlayer.get()) { // Send player info to client. boost::shared_ptr info(new NetPacketPlayerInfo); NetPacketPlayerInfo::Data infoData; - infoData.playerId = tmpSession.playerData->GetUniqueId(); - infoData.playerInfo.ptype = tmpSession.playerData->GetType(); - infoData.playerInfo.playerName = tmpSession.playerData->GetName(); + infoData.playerId = tmpPlayer->GetUniqueId(); + infoData.playerInfo.ptype = tmpPlayer->GetType(); + infoData.playerInfo.playerName = tmpPlayer->GetName(); static_cast(info.get())->SetData(infoData); GetSender().Send(session.sessionData->GetSocket(), info); } @@ -560,7 +561,7 @@ ServerLobbyThread::IsPlayerConnected(const string &name) GameMap::const_iterator game_end = m_gameMap.end(); while (game_i != game_end) { - if (game_i->second->GetSessionManager().IsPlayerConnected(name)) + if (game_i->second->IsPlayerConnected(name)) { retVal = true; break; @@ -580,7 +581,7 @@ ServerLobbyThread::CreateNetPacketGameListNew(const ServerGameThread &game) packetData.gameInfo.mode = GAME_MODE_CREATED; packetData.gameInfo.name = game.GetName(); packetData.gameInfo.data = game.GetGameData(); - packetData.gameInfo.players = game.GetSessionManager().GetPlayerIdList(); + packetData.gameInfo.players = game.GetPlayerIdList(); static_cast(packet.get())->SetData(packetData); return packet; } diff --git a/src/net/servergamestate.h b/src/net/servergamestate.h index 23c7042d..c3be8edc 100644 --- a/src/net/servergamestate.h +++ b/src/net/servergamestate.h @@ -126,7 +126,6 @@ protected: private: - u_int32_t m_curUniquePlayerId; static boost::thread_specific_ptr Ptr; }; diff --git a/src/net/servergamethread.h b/src/net/servergamethread.h index b2d8a4b9..e885a8b5 100644 --- a/src/net/servergamethread.h +++ b/src/net/servergamethread.h @@ -60,8 +60,9 @@ public: bool CheckPassword(const std::string &password) const; const GameData &GetGameData() const; - const SessionManager &GetSessionManager() const; - SessionManager &GetSessionManager(); + boost::shared_ptr GetPlayerDataByUniqueId(unsigned playerId) const; + PlayerIdList GetPlayerIdList() const; + bool IsPlayerConnected(const std::string &name) const; protected: @@ -73,6 +74,8 @@ protected: void InternalStartGame(); void InternalKickPlayer(unsigned playerId); + PlayerDataList GetFullPlayerDataList() const; + void AddComputerPlayer(boost::shared_ptr player); void ResetComputerPlayerList(); @@ -104,13 +107,17 @@ protected: unsigned GetNextGameNum(); + const SessionManager &GetSessionManager() const; + SessionManager &GetSessionManager(); + private: SessionQueue m_sessionQueue; mutable boost::mutex m_sessionQueueMutex; SessionManager m_sessionManager; - PlayerDataList m_computerPlayers; + PlayerDataList m_computerPlayerList; + mutable boost::mutex m_computerPlayerListMutex; ServerLobbyThread &m_lobbyThread; std::auto_ptr m_receiver; diff --git a/src/net/serverlobbythread.h b/src/net/serverlobbythread.h index 89c349c1..073cd9e3 100644 --- a/src/net/serverlobbythread.h +++ b/src/net/serverlobbythread.h @@ -130,8 +130,10 @@ private: std::string m_password; ConfigFile *m_playerConfig; - u_int32_t m_curUniquePlayerId; u_int32_t m_curGameId; + + u_int32_t m_curUniquePlayerId; + mutable boost::mutex m_curUniquePlayerIdMutex; }; #endif