From e981d1b4774887bf7a9ed3ae045f5b8d07c055c6 Mon Sep 17 00:00:00 2001 From: def Date: Wed, 23 Dec 2020 10:00:38 +0100 Subject: [PATCH] Fix veto vote, simplified logic Also allow IPs to change their vote when multiple players are connected, with 1 player it always worked. Reported by Lenah on Discord --- src/game/server/gamecontext.cpp | 67 +++++++++++++++++++-------------- 1 file changed, 38 insertions(+), 29 deletions(-) diff --git a/src/game/server/gamecontext.cpp b/src/game/server/gamecontext.cpp index 070a2ed7d..f83ef4f1e 100644 --- a/src/game/server/gamecontext.cpp +++ b/src/game/server/gamecontext.cpp @@ -820,11 +820,12 @@ void CGameContext::OnTick() } } - bool aVoteChecked[MAX_CLIENTS] = {0}; + // remember checked players, only the first player with a specific ip will be handled + bool aVoteChecked[MAX_CLIENTS] = {false}; int64 Now = Server()->Tick(); for(int i = 0; i < MAX_CLIENTS; i++) { - if(!m_apPlayers[i]) + if(!m_apPlayers[i] || aVoteChecked[i]) continue; if((IsKickVote() || IsSpecVote()) && (m_apPlayers[i]->GetTeam() == TEAM_SPECTATORS || @@ -851,41 +852,49 @@ void CGameContext::OnTick() int ActVotePos = m_apPlayers[i]->m_VotePos; // only allow IPs to vote once, but keep veto ability - if(!aVoteChecked[i]) + // check for more players with the same ip (only use the vote of the one who voted first) + for(int j = i + 1; j < MAX_CLIENTS; j++) { - // check for more players with the same ip (only use the vote of the one who voted first) - for(int j = i + 1; j < MAX_CLIENTS; ++j) - { - if(!m_apPlayers[j] || aVoteChecked[j] || str_comp(aaBuf[j], aaBuf[i])) - continue; + if(!m_apPlayers[j] || aVoteChecked[j] || str_comp(aaBuf[j], aaBuf[i]) != 0) + continue; - aVoteChecked[j] = true; - if(m_apPlayers[j]->m_Vote && (!ActVote || ActVotePos > m_apPlayers[j]->m_VotePos)) - { - ActVote = m_apPlayers[j]->m_Vote; - ActVotePos = m_apPlayers[j]->m_VotePos; - } + // count the latest vote by this ip + if(ActVotePos < m_apPlayers[j]->m_VotePos) + { + ActVote = m_apPlayers[j]->m_Vote; + ActVotePos = m_apPlayers[j]->m_VotePos; } - Total++; - if(ActVote > 0) - Yes++; - else if(ActVote < 0) - No++; + aVoteChecked[j] = true; } + Total++; + if(ActVote > 0) + Yes++; + else if(ActVote < 0) + No++; + // veto right for players who have been active on server for long and who're not afk - if(!IsKickVote() && !IsSpecVote() && m_apPlayers[i] && - !m_apPlayers[i]->m_Afk && m_apPlayers[i]->GetTeam() != TEAM_SPECTATORS && - g_Config.m_SvVoteVetoTime && - ((Server()->Tick() - m_apPlayers[i]->m_JoinTick) / (Server()->TickSpeed() * 60) > g_Config.m_SvVoteVetoTime || - (m_apPlayers[i]->GetCharacter() && m_apPlayers[i]->GetCharacter()->m_DDRaceState == DDRACE_STARTED && - (Server()->Tick() - m_apPlayers[i]->GetCharacter()->m_StartTime) / (Server()->TickSpeed() * 60) > g_Config.m_SvVoteVetoTime))) + if(!IsKickVote() && !IsSpecVote() && g_Config.m_SvVoteVetoTime) { - if(ActVote == 0) - Veto = true; - else if(ActVote < 0) - VetoStop = true; + // look through all players with same IP again + for(int j = i + 1; j < MAX_CLIENTS; j++) + { + if(!m_apPlayers[j] || str_comp(aaBuf[j], aaBuf[i]) != 0) + continue; + + if(m_apPlayers[j] && !m_apPlayers[j]->m_Afk && m_apPlayers[j]->GetTeam() != TEAM_SPECTATORS && + ((Server()->Tick() - m_apPlayers[j]->m_JoinTick) / (Server()->TickSpeed() * 60) > g_Config.m_SvVoteVetoTime || + (m_apPlayers[j]->GetCharacter() && m_apPlayers[j]->GetCharacter()->m_DDRaceState == DDRACE_STARTED && + (Server()->Tick() - m_apPlayers[j]->GetCharacter()->m_StartTime) / (Server()->TickSpeed() * 60) > g_Config.m_SvVoteVetoTime))) + { + if(ActVote == 0) + Veto = true; + else if(ActVote < 0) + VetoStop = true; + break; + } + } } }