More work on server side vote kick. Most error handling complete now. Client side still lacking.
This commit is contained in:
1 parent
e0c1662fa5
commit
89450a9a32
5 files changed
+50
-28
No files matched your search
@@ -829,7 +829,7 @@ Deny Reason:
|
|||||||
0x0000: Invalid state. Vote kick is only possible when the game is running.
|
0x0000: Invalid state. Vote kick is only possible when the game is running.
|
||||||
0x0001: Kick not possible due to number of players.
|
0x0001: Kick not possible due to number of players.
|
||||||
0x0002: Another kick cannot be requested at this time.
|
0x0002: Another kick cannot be requested at this time.
|
||||||
0x0003: Kick request is already in progress for this player.
|
0x0003: Kick request is already in progress.
|
||||||
0xFFFF: Other reason.
|
0xFFFF: Other reason.
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -98,7 +98,7 @@ struct VoteKickData
|
|||||||
int numVotesToKick;
|
int numVotesToKick;
|
||||||
int numVotesInFavourOfKicking;
|
int numVotesInFavourOfKicking;
|
||||||
int numVotesAgainstKicking;
|
int numVotesAgainstKicking;
|
||||||
unsigned timeLimitSec;
|
int timeLimitSec;
|
||||||
boost::timers::portable::microsec_timer voteTimer;
|
boost::timers::portable::microsec_timer voteTimer;
|
||||||
PlayerIdList votedPlayerIds;
|
PlayerIdList votedPlayerIds;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -213,7 +213,7 @@ AbstractServerGameStateReceiving::Process(ServerGameThread &server)
|
|||||||
NetPacketVoteKickPlayer::Data voteData;
|
NetPacketVoteKickPlayer::Data voteData;
|
||||||
packet->ToNetPacketVoteKickPlayer()->GetData(voteData);
|
packet->ToNetPacketVoteKickPlayer()->GetData(voteData);
|
||||||
|
|
||||||
server.InternalVoteKick(voteData.petitionId, voteData.vote);
|
server.InternalVoteKick(session, voteData.petitionId, voteData.vote);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Chat text is always allowed.
|
// Chat text is always allowed.
|
||||||
|
|||||||
@@ -176,7 +176,6 @@ ServerGameThread::VoteKickLoop()
|
|||||||
{
|
{
|
||||||
// Do not call the vote kick action all the time.
|
// Do not call the vote kick action all the time.
|
||||||
// Check the timer.
|
// Check the timer.
|
||||||
// The action will also be initiated after a player left.
|
|
||||||
if (m_voteKickActionTimer.elapsed().total_milliseconds() >= SERVER_CHECK_VOTE_KICK_INTERVAL_MSEC)
|
if (m_voteKickActionTimer.elapsed().total_milliseconds() >= SERVER_CHECK_VOTE_KICK_INTERVAL_MSEC)
|
||||||
VoteKickAction();
|
VoteKickAction();
|
||||||
}
|
}
|
||||||
@@ -189,8 +188,8 @@ ServerGameThread::VoteKickAction()
|
|||||||
boost::mutex::scoped_lock lock(m_voteKickDataMutex);
|
boost::mutex::scoped_lock lock(m_voteKickDataMutex);
|
||||||
if (m_voteKickData)
|
if (m_voteKickData)
|
||||||
{
|
{
|
||||||
|
// Prepare some values.
|
||||||
const PlayerIdList playerIds(GetPlayerIdList());
|
const PlayerIdList playerIds(GetPlayerIdList());
|
||||||
// 1. Several players left the game, so a kick is no longer possible.
|
|
||||||
int votesRequiredToKick = m_voteKickData->numVotesToKick - m_voteKickData->numVotesInFavourOfKicking;
|
int votesRequiredToKick = m_voteKickData->numVotesToKick - m_voteKickData->numVotesInFavourOfKicking;
|
||||||
int playersAllowedToVote = 0;
|
int playersAllowedToVote = 0;
|
||||||
// We need to count the number of players which are still allowed to vote.
|
// We need to count the number of players which are still allowed to vote.
|
||||||
@@ -203,20 +202,29 @@ ServerGameThread::VoteKickAction()
|
|||||||
++player_i;
|
++player_i;
|
||||||
}
|
}
|
||||||
bool abortPetition = false;
|
bool abortPetition = false;
|
||||||
EndPetitionReason reason = PETITION_END_ENOUGH_VOTES;
|
bool doKick = false;
|
||||||
|
EndPetitionReason reason;
|
||||||
|
|
||||||
if (votesRequiredToKick > playersAllowedToVote)
|
// 1. Enough votes to kick the player.
|
||||||
|
if (m_voteKickData->numVotesInFavourOfKicking >= m_voteKickData->numVotesToKick)
|
||||||
|
{
|
||||||
|
reason = PETITION_END_ENOUGH_VOTES;
|
||||||
|
abortPetition = true;
|
||||||
|
doKick = true;
|
||||||
|
}
|
||||||
|
// 2. Several players left the game, so a kick is no longer possible.
|
||||||
|
else if (votesRequiredToKick > playersAllowedToVote)
|
||||||
{
|
{
|
||||||
reason = PETITION_END_NOT_ENOUGH_PLAYERS;
|
reason = PETITION_END_NOT_ENOUGH_PLAYERS;
|
||||||
abortPetition = true;
|
abortPetition = true;
|
||||||
}
|
}
|
||||||
// 2. The kick has become invalid because the player to be kicked left.
|
// 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 (find(playerIds.begin(), playerIds.end(), m_voteKickData->kickPlayerId) == playerIds.end())
|
||||||
{
|
{
|
||||||
reason = PETITION_END_PLAYER_LEFT;
|
reason = PETITION_END_PLAYER_LEFT;
|
||||||
abortPetition = true;
|
abortPetition = true;
|
||||||
}
|
}
|
||||||
// 3. A kick request timed out (because not everyone voted).
|
// 4. A kick request timed out (because not everyone voted).
|
||||||
else if (m_voteKickData->voteTimer.elapsed().total_seconds() >= m_voteKickData->timeLimitSec)
|
else if (m_voteKickData->voteTimer.elapsed().total_seconds() >= m_voteKickData->timeLimitSec)
|
||||||
{
|
{
|
||||||
reason = PETITION_END_TIMEOUT;
|
reason = PETITION_END_TIMEOUT;
|
||||||
@@ -229,13 +237,16 @@ ServerGameThread::VoteKickAction()
|
|||||||
endPetitionData.petitionId = m_voteKickData->petitionId;
|
endPetitionData.petitionId = m_voteKickData->petitionId;
|
||||||
endPetitionData.numVotesAgainstKicking = m_voteKickData->numVotesAgainstKicking;
|
endPetitionData.numVotesAgainstKicking = m_voteKickData->numVotesAgainstKicking;
|
||||||
endPetitionData.numVotesInFavourOfKicking = m_voteKickData->numVotesInFavourOfKicking;
|
endPetitionData.numVotesInFavourOfKicking = m_voteKickData->numVotesInFavourOfKicking;
|
||||||
endPetitionData.playerKicked = false;
|
endPetitionData.playerKicked = doKick;
|
||||||
endPetitionData.endReason = reason;
|
endPetitionData.endReason = reason;
|
||||||
m_voteKickData.reset();
|
m_voteKickData.reset();
|
||||||
lock.unlock(); // Do not block the data longer than necessary.
|
|
||||||
|
|
||||||
static_cast<NetPacketEndKickPlayerPetition *>(endPetition.get())->SetData(endPetitionData);
|
static_cast<NetPacketEndKickPlayerPetition *>(endPetition.get())->SetData(endPetitionData);
|
||||||
SendToAllPlayers(endPetition, SessionData::Game);
|
SendToAllPlayers(endPetition, SessionData::Game);
|
||||||
|
|
||||||
|
// Perform kick.
|
||||||
|
if (doKick)
|
||||||
|
InternalKickPlayer(m_voteKickData->kickPlayerId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -329,17 +340,13 @@ ServerGameThread::InternalAskVoteKick(SessionWrapper byWhom, unsigned playerIdWh
|
|||||||
startPetitionData.kickPlayerId = m_voteKickData->kickPlayerId;
|
startPetitionData.kickPlayerId = m_voteKickData->kickPlayerId;
|
||||||
startPetitionData.kickTimeoutSec = m_voteKickData->timeLimitSec;
|
startPetitionData.kickTimeoutSec = m_voteKickData->timeLimitSec;
|
||||||
startPetitionData.numVotesNeededToKick = m_voteKickData->numVotesToKick;
|
startPetitionData.numVotesNeededToKick = m_voteKickData->numVotesToKick;
|
||||||
lock.unlock(); // Do not block the data longer than necessary.
|
|
||||||
|
|
||||||
static_cast<NetPacketStartKickPlayerPetition *>(startPetition.get())->SetData(startPetitionData);
|
static_cast<NetPacketStartKickPlayerPetition *>(startPetition.get())->SetData(startPetitionData);
|
||||||
SendToAllPlayers(startPetition, SessionData::Game);
|
SendToAllPlayers(startPetition, SessionData::Game);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
|
||||||
lock.unlock(); // Do not block the data longer than necessary.
|
|
||||||
InternalDenyAskVoteKick(byWhom, playerIdWho, KICK_DENIED_OTHER_IN_PROGRESS);
|
InternalDenyAskVoteKick(byWhom, playerIdWho, KICK_DENIED_OTHER_IN_PROGRESS);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else
|
else
|
||||||
InternalDenyAskVoteKick(byWhom, playerIdWho, KICK_DENIED_TOO_FEW_PLAYERS);
|
InternalDenyAskVoteKick(byWhom, playerIdWho, KICK_DENIED_TOO_FEW_PLAYERS);
|
||||||
}
|
}
|
||||||
@@ -359,29 +366,43 @@ ServerGameThread::InternalDenyAskVoteKick(SessionWrapper byWhom, unsigned player
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ServerGameThread::InternalVoteKick(unsigned petitionId, KickVote vote)
|
ServerGameThread::InternalVoteKick(SessionWrapper byWhom, unsigned petitionId, KickVote vote)
|
||||||
{
|
{
|
||||||
if (IsRunning())
|
if (IsRunning() && byWhom.playerData)
|
||||||
{
|
{
|
||||||
boost::mutex::scoped_lock lock(m_voteKickDataMutex);
|
boost::mutex::scoped_lock lock(m_voteKickDataMutex);
|
||||||
|
// Check whether this is the valid petition id.
|
||||||
if (m_voteKickData->petitionId == petitionId)
|
if (m_voteKickData->petitionId == petitionId)
|
||||||
{
|
{
|
||||||
|
// Check whether the player already voted.
|
||||||
|
unsigned playerId = byWhom.playerData->GetUniqueId();
|
||||||
|
if (find(m_voteKickData->votedPlayerIds.begin(), m_voteKickData->votedPlayerIds.end(), playerId) == m_voteKickData->votedPlayerIds.end())
|
||||||
|
{
|
||||||
|
m_voteKickData->votedPlayerIds.push_back(playerId);
|
||||||
if (vote == KICK_VOTE_IN_FAVOUR)
|
if (vote == KICK_VOTE_IN_FAVOUR)
|
||||||
{
|
|
||||||
m_voteKickData->numVotesInFavourOfKicking++;
|
m_voteKickData->numVotesInFavourOfKicking++;
|
||||||
if (m_voteKickData->numVotesInFavourOfKicking >= m_voteKickData->numVotesToKick)
|
|
||||||
{
|
|
||||||
// Perform kick.
|
|
||||||
InternalKickPlayer(m_voteKickData->kickPlayerId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
m_voteKickData->numVotesAgainstKicking++;
|
m_voteKickData->numVotesAgainstKicking++;
|
||||||
// TODO abort if no longer possible.
|
|
||||||
// TODO remove deprecated list entries.
|
|
||||||
// TODO error handling.
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
InternalDenyVoteKick(byWhom, petitionId, VOTE_DENIED_ALREADY_VOTED);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
InternalDenyVoteKick(byWhom, petitionId, VOTE_DENIED_INVALID_PETITION);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
InternalDenyVoteKick(byWhom, petitionId, VOTE_DENIED_IMPOSSIBLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ServerGameThread::InternalDenyVoteKick(SessionWrapper byWhom, unsigned petitionId, DenyVoteReason reason)
|
||||||
|
{
|
||||||
|
boost::shared_ptr<NetPacket> denyVote(new NetPacketVoteKickPlayerDenied);
|
||||||
|
NetPacketVoteKickPlayerDenied::Data denyVoteData;
|
||||||
|
denyVoteData.petitionId = petitionId;
|
||||||
|
denyVoteData.denyReason = reason;
|
||||||
|
static_cast<NetPacketVoteKickPlayerDenied *>(denyVote.get())->SetData(denyVoteData);
|
||||||
|
GetSender().Send(byWhom.sessionData, denyVote);
|
||||||
}
|
}
|
||||||
|
|
||||||
PlayerDataList
|
PlayerDataList
|
||||||
|
|||||||
@@ -90,7 +90,8 @@ protected:
|
|||||||
void InternalKickPlayer(unsigned playerId);
|
void InternalKickPlayer(unsigned playerId);
|
||||||
void InternalAskVoteKick(SessionWrapper byWhom, unsigned playerIdWho, unsigned timeoutSec);
|
void InternalAskVoteKick(SessionWrapper byWhom, unsigned playerIdWho, unsigned timeoutSec);
|
||||||
void InternalDenyAskVoteKick(SessionWrapper byWhom, unsigned playerIdWho, DenyKickPlayerReason reason);
|
void InternalDenyAskVoteKick(SessionWrapper byWhom, unsigned playerIdWho, DenyKickPlayerReason reason);
|
||||||
void InternalVoteKick(unsigned petitionId, KickVote vote);
|
void InternalVoteKick(SessionWrapper byWhom, unsigned petitionId, KickVote vote);
|
||||||
|
void InternalDenyVoteKick(SessionWrapper byWhom, unsigned petitionId, DenyVoteReason reason);
|
||||||
|
|
||||||
PlayerDataList GetFullPlayerDataList() const;
|
PlayerDataList GetFullPlayerDataList() const;
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user