From 4bf9ceff6d88b57cc4f2802b5101722a4df1f16f Mon Sep 17 00:00:00 2001 From: lotodore Date: Fri, 12 Dec 2008 22:38:35 +0000 Subject: [PATCH] Deny ask kick if the player is not/no longer present. --- docs/net_protocol.txt | 1 + src/game_defs.h | 1 + src/net/common/netpacket.cpp | 7 ++++ src/net/common/servergamethread.cpp | 64 ++++++++++++++++++----------- src/net/servergamethread.h | 1 + 5 files changed, 50 insertions(+), 24 deletions(-) diff --git a/docs/net_protocol.txt b/docs/net_protocol.txt index 5d4ed3b4..a9328192 100644 --- a/docs/net_protocol.txt +++ b/docs/net_protocol.txt @@ -830,6 +830,7 @@ Deny Reason: 0x0001: Kick not possible due to number of players. 0x0002: Another kick cannot be requested at this time. 0x0003: Kick request is already in progress. + 0x0004: Invalid player ID. 0xFFFF: Other reason. diff --git a/src/game_defs.h b/src/game_defs.h index ba6a9748..31b67067 100644 --- a/src/game_defs.h +++ b/src/game_defs.h @@ -72,6 +72,7 @@ enum DenyKickPlayerReason KICK_DENIED_TOO_FEW_PLAYERS, KICK_DENIED_TEMPORARY, KICK_DENIED_OTHER_IN_PROGRESS, + KICK_DENIED_INVALID_PLAYER_ID, KICK_DENIED_OTHER_REASON }; diff --git a/src/net/common/netpacket.cpp b/src/net/common/netpacket.cpp index d0818b4f..9d556f56 100644 --- a/src/net/common/netpacket.cpp +++ b/src/net/common/netpacket.cpp @@ -125,6 +125,7 @@ using namespace std; #define NET_ASK_KICK_DENIED_TOO_FEW_PLAYERS 0x0001 #define NET_ASK_KICK_DENIED_TEMPORARY 0x0002 #define NET_ASK_KICK_DENIED_OTHER_IN_PROGRESS 0x0003 +#define NET_ASK_KICK_DENIED_INVALID_PLAYER_ID 0x0004 #define NET_ASK_KICK_DENIED_OTHER_REASON 0xFFFF // Vote types @@ -4526,6 +4527,9 @@ NetPacketAskKickPlayerDenied::SetData(const NetPacketAskKickPlayerDenied::Data & case KICK_DENIED_OTHER_IN_PROGRESS: tmpData->denyReason = htons(NET_ASK_KICK_DENIED_OTHER_IN_PROGRESS); break; + case KICK_DENIED_INVALID_PLAYER_ID: + tmpData->denyReason = htons(NET_ASK_KICK_DENIED_INVALID_PLAYER_ID); + break; default: tmpData->denyReason = htons(NET_ASK_KICK_DENIED_OTHER_REASON); break; @@ -4555,6 +4559,9 @@ NetPacketAskKickPlayerDenied::GetData(NetPacketAskKickPlayerDenied::Data &outDat case NET_ASK_KICK_DENIED_OTHER_IN_PROGRESS: outData.denyReason = KICK_DENIED_OTHER_IN_PROGRESS; break; + case NET_ASK_KICK_DENIED_INVALID_PLAYER_ID: + outData.denyReason = KICK_DENIED_INVALID_PLAYER_ID; + break; default: outData.denyReason = KICK_DENIED_OTHER_REASON; break; diff --git a/src/net/common/servergamethread.cpp b/src/net/common/servergamethread.cpp index 893b4e2d..27f8756d 100644 --- a/src/net/common/servergamethread.cpp +++ b/src/net/common/servergamethread.cpp @@ -220,7 +220,7 @@ ServerGameThread::VoteKickAction() abortPetition = true; } // 3. The kick has become invalid because the player to be kicked left. - else if (find(playerIds.begin(), playerIds.end(), m_voteKickData->kickPlayerId) == playerIds.end()) + else if (!IsValidPlayer(m_voteKickData->kickPlayerId)) { reason = PETITION_END_PLAYER_LEFT; abortPetition = true; @@ -327,34 +327,40 @@ ServerGameThread::InternalAskVoteKick(SessionWrapper byWhom, unsigned playerIdWh size_t numPlayers = GetSessionManager().GetPlayerIdList().size(); if (numPlayers > 2) { - // Lock the vote kick data. - boost::mutex::scoped_lock lock(m_voteKickDataMutex); - if (!m_voteKickData) + // Check whether the player to be kicked exists. + if (IsValidPlayer(playerIdWho)) { - // Initiate a vote kick. - unsigned playerIdByWhom = byWhom.playerData->GetUniqueId(); - m_voteKickData.reset(new VoteKickData); - m_voteKickData->petitionId = m_curPetitionId++; - m_voteKickData->kickPlayerId = playerIdWho; - m_voteKickData->numVotesToKick = static_cast(ceil(numPlayers / 3. * 2.)); - m_voteKickData->timeLimitSec = timeoutSec + SERVER_KICK_TIMEOUT_ADD_DELAY_SEC; - // Consider first vote. - m_voteKickData->numVotesInFavourOfKicking = 1; - m_voteKickData->votedPlayerIds.push_back(playerIdByWhom); + // Lock the vote kick data. + boost::mutex::scoped_lock lock(m_voteKickDataMutex); + if (!m_voteKickData) + { + // Initiate a vote kick. + unsigned playerIdByWhom = byWhom.playerData->GetUniqueId(); + m_voteKickData.reset(new VoteKickData); + m_voteKickData->petitionId = m_curPetitionId++; + m_voteKickData->kickPlayerId = playerIdWho; + m_voteKickData->numVotesToKick = static_cast(ceil(numPlayers / 3. * 2.)); + m_voteKickData->timeLimitSec = timeoutSec + SERVER_KICK_TIMEOUT_ADD_DELAY_SEC; + // Consider first vote. + m_voteKickData->numVotesInFavourOfKicking = 1; + m_voteKickData->votedPlayerIds.push_back(playerIdByWhom); - boost::shared_ptr startPetition(new NetPacketStartKickPlayerPetition); - NetPacketStartKickPlayerPetition::Data startPetitionData; - startPetitionData.petitionId = m_voteKickData->petitionId; - startPetitionData.proposingPlayerId = playerIdByWhom; - startPetitionData.kickPlayerId = m_voteKickData->kickPlayerId; - startPetitionData.kickTimeoutSec = timeoutSec; - startPetitionData.numVotesNeededToKick = m_voteKickData->numVotesToKick; + boost::shared_ptr startPetition(new NetPacketStartKickPlayerPetition); + NetPacketStartKickPlayerPetition::Data startPetitionData; + startPetitionData.petitionId = m_voteKickData->petitionId; + startPetitionData.proposingPlayerId = playerIdByWhom; + startPetitionData.kickPlayerId = m_voteKickData->kickPlayerId; + startPetitionData.kickTimeoutSec = timeoutSec; + startPetitionData.numVotesNeededToKick = m_voteKickData->numVotesToKick; - static_cast(startPetition.get())->SetData(startPetitionData); - SendToAllPlayers(startPetition, SessionData::Game); + static_cast(startPetition.get())->SetData(startPetitionData); + SendToAllPlayers(startPetition, SessionData::Game); + } + else + InternalDenyAskVoteKick(byWhom, playerIdWho, KICK_DENIED_OTHER_IN_PROGRESS); } else - InternalDenyAskVoteKick(byWhom, playerIdWho, KICK_DENIED_OTHER_IN_PROGRESS); + InternalDenyAskVoteKick(byWhom, playerIdWho, KICK_DENIED_INVALID_PLAYER_ID); } else InternalDenyAskVoteKick(byWhom, playerIdWho, KICK_DENIED_TOO_FEW_PLAYERS); @@ -693,6 +699,16 @@ ServerGameThread::AssignPlayerNumbers() } } +bool +ServerGameThread::IsValidPlayer(unsigned playerId) const +{ + bool retVal = false; + const PlayerIdList list(GetPlayerIdList()); + if (find(list.begin(), list.end(), playerId) != list.end()) + retVal = true; + return retVal; +} + SessionManager & ServerGameThread::GetSessionManager() { diff --git a/src/net/servergamethread.h b/src/net/servergamethread.h index e4bf8cfd..0a688a3c 100644 --- a/src/net/servergamethread.h +++ b/src/net/servergamethread.h @@ -109,6 +109,7 @@ protected: void RemoveDisconnectedPlayers(); size_t GetCurNumberOfPlayers() const; void AssignPlayerNumbers(); + bool IsValidPlayer(unsigned playerId) const; ServerLobbyThread &GetLobbyThread();