void VoteMenuHandler::OnClientDisconnected(int client) { if (!IsVoteInProgress()) { return; } /* Wipe out their vote if they had one */ int item; if ((item = m_ClientVotes[client]) >= 0) { assert((unsigned)item < m_Items); assert(m_Votes[item] > 0); m_Votes[item]--; m_ClientVotes[client] = -1; } }
void ClientVoteMgr::CastVote(bool bVote) { if (!IsVoteInProgress() || m_bHasVoted) { return; } CAutoMessage cMsg; cMsg.Writeuint8( MID_VOTE ); cMsg.WriteBits( eVote_Cast, FNumBitsExclusive<kNumVoteActions>::k_nValue ); cMsg.Writeuint8( m_CurrentVote.m_nVoteID ); cMsg.Writebool( bVote ); g_pLTClient->SendToServer( cMsg.Read(), MESSAGE_GUARANTEED ); m_bHasVoted = true; g_pHUDMgr->QueueUpdate(kHUDVote); }
bool VoteMenuHandler::InitializeVoting(IBaseMenu *menu, IMenuHandler *handler, unsigned int time, unsigned int flags) { if (IsVoteInProgress()) { return false; } InternalReset(); /* Mark all clients as not voting */ for (int i=1; i<=gpGlobals->maxClients; i++) { m_ClientVotes[i] = -2; } m_Items = menu->GetItemCount(); if (m_Votes.size() < (size_t)m_Items) { /* Only clear the items we need to... */ size_t size = m_Votes.size(); for (size_t i=0; i<size; i++) { m_Votes[i] = 0; } m_Votes.resize(m_Items, 0); } else { for (unsigned int i=0; i<m_Items; i++) { m_Votes[i] = 0; } } m_pCurMenu = menu; m_VoteTime = time; m_VoteFlags = flags; m_pHandler = handler; m_pHandler->OnMenuStart(m_pCurMenu); return true; }
void ServerVoteMgr::HandleVoteCast(HCLIENT hVoterClient, ILTMessage_Read* pMsg) { if (!IsVoteInProgress()) { return; } uint32 nVoteID = pMsg->Readuint8(); bool bVote = pMsg->Readbool(); if (nVoteID != m_CurrentVote.m_nVoteID) { return; } VoterList::iterator iterVoter; // Check if they are eligible. if( !IsClientEligible( hVoterClient, iterVoter )) return; // Check if they already voted. if( IsClientVoteYes( hVoterClient, iterVoter ) || IsClientVoteNo( hVoterClient, iterVoter )) return; if (bVote) { m_lstVoterCastYes.push_back( hVoterClient ); m_CurrentVote.m_nYesVotes++; } else { m_lstVoterCastNo.push_back( hVoterClient ); m_CurrentVote.m_nNoVotes++; } // Check the status of the vote. CheckVoteStatus( ); }
void ClientVoteMgr::CallVoteNext(VoteType eVoteType) { if (IsVoteInProgress()) { g_pTransmission->Show("ScreenVote_VoteInProgress"); return; } if (IsVoteDelayed()) { wchar_t szMsg[256]; szMsg[0] = '\0'; FormatString("ScreenVote_VoteDelayed",szMsg,LTARRAYSIZE(szMsg),(uint32)m_VoteDelayTimer.GetTimeLeft()); g_pTransmission->Show(szMsg); return; } CAutoMessage cMsg; cMsg.Writeuint8( MID_VOTE ); cMsg.WriteBits( eVote_Start, FNumBitsExclusive<kNumVoteActions>::k_nValue ); cMsg.WriteBits( eVoteType, FNumBitsExclusive<kNumVoteTypes>::k_nValue ); g_pLTClient->SendToServer( cMsg.Read(), MESSAGE_GUARANTEED ); }
void ClientVoteMgr::HandleMsgVote(ILTMessage_Read* pMsg) { VoteAction eVoteAction = (VoteAction)pMsg->ReadBits( FNumBitsExclusive<kNumVoteActions>::k_nValue ); uint32 nLocalID = 0; g_pLTClient->GetLocalClientID (&nLocalID); switch(eVoteAction) { case eVote_Start: HandleVoteStart(pMsg); break; case eVote_Cast: if (IsVoteInProgress()) { uint32 nVoteID = pMsg->Readuint8(); if (nVoteID == m_CurrentVote.m_nVoteID) { m_CurrentVote.m_nYesVotes = pMsg->Readuint8(); m_CurrentVote.m_nNoVotes = pMsg->Readuint8(); m_CurrentVote.m_nVotesNeeded = pMsg->Readuint8(); } g_pHUDMgr->QueueUpdate(kHUDVote); } break; case eVote_Pass: if (nLocalID == m_CurrentVote.m_nCallerID) { //start a timer to prevent us from spamming votes double fTimeOut = (double)(GameModeMgr::Instance().m_ServerSettings.m_nVoteDelay); m_VoteDelayTimer.Start(fTimeOut); } HandleVotePass(); break; case eVote_Fail: g_pTransmission->Show("Vote_Failed"); g_pGameMsgs->AddMessage("Vote_Failed"); if (nLocalID == m_CurrentVote.m_nCallerID) { //start a timer to prevent us from spamming votes double fTimeOut = (double)(GameModeMgr::Instance().m_ServerSettings.m_nVoteDelay); m_VoteDelayTimer.Start(fTimeOut); } ClearVote(); break; case eVote_Expire: g_pTransmission->Show("Vote_TimedOut"); g_pGameMsgs->AddMessage("Vote_TimedOut"); if (nLocalID == m_CurrentVote.m_nCallerID) { //start a timer to prevent us from spamming votes double fTimeOut = (double)(GameModeMgr::Instance().m_ServerSettings.m_nVoteDelay); m_VoteDelayTimer.Start(fTimeOut); } ClearVote(); break; case eVote_Cancel_Players: g_pTransmission->Show("Vote_NotEnoughPlayers"); g_pGameMsgs->AddMessage("Vote_NotEnoughPlayers"); m_VoteDelayTimer.Stop(); ClearVote(); break; case eVote_Cancel_InProgress: g_pTransmission->Show("ScreenVote_VoteInProgress"); g_pGameMsgs->AddMessage("ScreenVote_VoteInProgress"); m_VoteDelayTimer.Stop(); break; } }
void ServerVoteMgr::HandleVoteStart(HCLIENT hSender, ILTMessage_Read* pMsg) { if (!hSender) { return; } if (IsVoteInProgress()) { // Tell the player why their vote didn't start SendCancelVoteInProgress( hSender ); return; } VoteType eVoteType = (VoteType)pMsg->ReadBits( FNumBitsExclusive<kNumVoteTypes>::k_nValue ); //check to see if we have a real client uint32 nCallerID = g_pLTServer->GetClientID( hSender ); HCLIENT hCallerClient = g_pLTServer->GetClientHandle( nCallerID ); if( !hCallerClient ) return; GameClientData* pCallerGameClientData = ServerConnectionMgr::Instance().GetGameClientData( hCallerClient ); if( !pCallerGameClientData ) return; //check to see if the client has a live player... if (!GameModeMgr::Instance( ).m_grbAllowDeadVoting) { CPlayerObj* pPlayerObj = ( CPlayerObj* )g_pLTServer->HandleToObject( pCallerGameClientData->GetPlayer( )); if( !pPlayerObj || !pPlayerObj->IsAlive( )) { return; } }; // Make sure we start fresh. ClearVote( ); switch(eVoteType) { case eVote_Kick: case eVote_TeamKick: case eVote_Ban: { uint32 nTargetID = pMsg->Readuint32(); HCLIENT hTargetClient = g_pLTServer->GetClientHandle( nTargetID ); if( !hTargetClient ) return; GameClientData* pTargetGameClientData = ServerConnectionMgr::Instance().GetGameClientData( hTargetClient ); if( !pTargetGameClientData ) return; // Iterate through all the clients and see if anyone is ready to vote. ServerConnectionMgr::GameClientDataList& gameClientDataList = ServerConnectionMgr::Instance( ).GetGameClientDataList( ); ServerConnectionMgr::GameClientDataList::iterator iter = gameClientDataList.begin( ); for( ; iter != gameClientDataList.end( ); iter++ ) { GameClientData* pGameClientData = *iter; if( !pGameClientData->GetClient( )) continue; // Skip clients that aren't ready to play yet. if( pGameClientData->GetClientConnectionState() != eClientConnectionState_InWorld ) continue; // Client must have reached the inworld state. if( !pGameClientData->IsClientInWorld( )) continue; // Restrict elibible voters if it's a team kick. if( eVoteType == eVote_TeamKick ) { if( pCallerGameClientData->GetLastTeamId() != pGameClientData->GetLastTeamId( )) continue; } // Add to the eligible voter list. m_lstEligibleVoter.push_back( pGameClientData->GetClient( )); } // Check if we have a quorum of voters. uint32 nQuorum = ( eVoteType == eVote_TeamKick ) ? GameModeMgr::Instance().m_ServerSettings.m_nMinPlayersForTeamVote : GameModeMgr::Instance().m_ServerSettings.m_nMinPlayersForVote; //figure out how many votes are needed to pass uint8 nVotesNeeded = ((m_lstEligibleVoter.size() + 2) / 2); //the "+ 2" is here to ensure a majority not just half //if we have less than the "minimum" number of players, the vote must pass unanimously if( m_lstEligibleVoter.size( ) < nQuorum ) { nVotesNeeded = m_lstEligibleVoter.size( ); } // Put the caller on the list of voters already cast. m_lstVoterCastYes.push_back( pCallerGameClientData->GetClient( )); float fDuration = GameModeMgr::Instance().m_ServerSettings.m_nVoteLifetime; m_VoteTimer.Start(fDuration); m_CurrentVote.m_eVoteType = eVoteType; m_CurrentVote.m_nVoteID = m_CurrentVote.m_nVoteID++; //increment vote ID so that each vote is more or less unique... will wrap after 256 votes m_CurrentVote.m_nTargetID = nTargetID; m_CurrentVote.m_nCallerID = nCallerID; m_CurrentVote.m_nNoVotes = 0; m_CurrentVote.m_nYesVotes = 1; m_CurrentVote.m_nVotesNeeded = nVotesNeeded; CAutoMessage cMsg; cMsg.Writeuint8( MID_VOTE ); cMsg.WriteBits( eVote_Start, FNumBitsExclusive<kNumVoteActions>::k_nValue ); cMsg.Writeuint8( m_CurrentVote.m_nVoteID ); cMsg.WriteBits( eVoteType, FNumBitsExclusive<kNumVoteTypes>::k_nValue ); cMsg.Writeuint32( nCallerID ); cMsg.Writeuint32( nTargetID ); cMsg.Writeuint8( m_CurrentVote.m_nVotesNeeded ); cMsg.Writedouble( m_VoteTimer.GetTimeLeft( )); // Send the vote start info to the eligible voters. SendToEligibleVoters( *cMsg.Read( )); // Check if we've already achieved necessary votes. CheckVoteStatus(); } break; case eVote_NextRound: case eVote_NextMap: { // Iterate through all the clients and see if anyone is ready to vote. ServerConnectionMgr::GameClientDataList& gameClientDataList = ServerConnectionMgr::Instance( ).GetGameClientDataList( ); ServerConnectionMgr::GameClientDataList::iterator iter = gameClientDataList.begin( ); for( ; iter != gameClientDataList.end( ); iter++ ) { GameClientData* pGameClientData = *iter; if( !pGameClientData->GetClient( )) continue; // Skip clients that aren't ready to play yet. if( pGameClientData->GetClientConnectionState() != eClientConnectionState_InWorld ) continue; // Client must have reached the inworld state. if( !pGameClientData->IsClientInWorld( )) continue; // Add to the eligible voter list. m_lstEligibleVoter.push_back( pGameClientData->GetClient( )); } // Check if we have a quorum of voters. uint32 nQuorum = GameModeMgr::Instance().m_ServerSettings.m_nMinPlayersForVote; //figure out how many votes are needed to pass uint8 nVotesNeeded = ((m_lstEligibleVoter.size() + 2) / 2); //the "+ 2" is here to ensure a majority not just half //if we have less than the "minimum" number of players, the vote must pass unanimously if( m_lstEligibleVoter.size( ) < nQuorum ) { nVotesNeeded = m_lstEligibleVoter.size( ); } // Put the caller on the list of voters already cast. m_lstVoterCastYes.push_back( pCallerGameClientData->GetClient( )); float fDuration = GameModeMgr::Instance().m_ServerSettings.m_nVoteLifetime; m_VoteTimer.Start(fDuration); m_CurrentVote.m_eVoteType = eVoteType; m_CurrentVote.m_nVoteID = m_CurrentVote.m_nVoteID++; //increment vote ID so that each vote is more or less unique... will wrap after 256 votes m_CurrentVote.m_nTargetID = 0; m_CurrentVote.m_nCallerID = nCallerID; m_CurrentVote.m_nNoVotes = 0; m_CurrentVote.m_nYesVotes = 1; m_CurrentVote.m_nVotesNeeded = nVotesNeeded; CAutoMessage cMsg; cMsg.Writeuint8( MID_VOTE ); cMsg.WriteBits( eVote_Start, FNumBitsExclusive<kNumVoteActions>::k_nValue ); cMsg.Writeuint8( m_CurrentVote.m_nVoteID ); cMsg.WriteBits( eVoteType, FNumBitsExclusive<kNumVoteTypes>::k_nValue ); cMsg.Writeuint32( nCallerID ); cMsg.Writeuint32( 0 ); cMsg.Writeuint8( m_CurrentVote.m_nVotesNeeded ); cMsg.Writedouble( m_VoteTimer.GetTimeLeft( )); // Send the vote start info to the eligible voters. SendToEligibleVoters( *cMsg.Read( )); // Check if we've already achieved necessary votes. CheckVoteStatus(); } break; case eVote_SelectMap: { uint32 nMapIndex = pMsg->Readuint32(); uint32 nCallerID = g_pLTServer->GetClientID( hSender ); HCLIENT hCallerClient = g_pLTServer->GetClientHandle( nCallerID ); if( !hCallerClient ) return; GameClientData* pCallerGameClientData = ServerConnectionMgr::Instance().GetGameClientData( hCallerClient ); if( !pCallerGameClientData ) return; // Iterate through all the clients and see if anyone is ready to vote. ServerConnectionMgr::GameClientDataList& gameClientDataList = ServerConnectionMgr::Instance( ).GetGameClientDataList( ); ServerConnectionMgr::GameClientDataList::iterator iter = gameClientDataList.begin( ); for( ; iter != gameClientDataList.end( ); iter++ ) { GameClientData* pGameClientData = *iter; if( !pGameClientData->GetClient( )) continue; // Skip clients that aren't ready to play yet. if( pGameClientData->GetClientConnectionState() != eClientConnectionState_InWorld ) continue; // Client must have reached the inworld state. if( !pGameClientData->IsClientInWorld( )) continue; // Add to the eligible voter list. m_lstEligibleVoter.push_back( pGameClientData->GetClient( )); } // Check if we have a quorum of voters. uint32 nQuorum = GameModeMgr::Instance().m_ServerSettings.m_nMinPlayersForVote; //figure out how many votes are needed to pass uint8 nVotesNeeded = ((m_lstEligibleVoter.size() + 2) / 2); //the "+ 2" is here to ensure a majority not just half //if we have less than the "minimum" number of players, the vote must pass unanimously if( m_lstEligibleVoter.size( ) < nQuorum ) { nVotesNeeded = m_lstEligibleVoter.size( ); } // Put the caller on the list of voters already cast. m_lstVoterCastYes.push_back( pCallerGameClientData->GetClient( )); float fDuration = GameModeMgr::Instance().m_ServerSettings.m_nVoteLifetime; m_VoteTimer.Start(fDuration); m_CurrentVote.m_eVoteType = eVoteType; m_CurrentVote.m_nVoteID = m_CurrentVote.m_nVoteID++; //increment vote ID so that each vote is more or less unique... will wrap after 256 votes m_CurrentVote.m_nTargetID = nMapIndex; m_CurrentVote.m_nCallerID = nCallerID; m_CurrentVote.m_nNoVotes = 0; m_CurrentVote.m_nYesVotes = 1; m_CurrentVote.m_nVotesNeeded = nVotesNeeded; CAutoMessage cMsg; cMsg.Writeuint8( MID_VOTE ); cMsg.WriteBits( eVote_Start, FNumBitsExclusive<kNumVoteActions>::k_nValue ); cMsg.Writeuint8( m_CurrentVote.m_nVoteID ); cMsg.WriteBits( eVoteType, FNumBitsExclusive<kNumVoteTypes>::k_nValue ); cMsg.Writeuint32( nCallerID ); cMsg.Writeuint32( nMapIndex ); cMsg.Writeuint8( m_CurrentVote.m_nVotesNeeded ); cMsg.Writedouble( m_VoteTimer.GetTimeLeft( )); // Send the vote start info to the eligible voters. SendToEligibleVoters( *cMsg.Read( )); // Check if we've already achieved necessary votes. CheckVoteStatus(); } break; } }