Updated the SDK with the latest code from the TF and HL2 branches.

This commit is contained in:
Michael Sartain
2014-10-02 08:25:55 -07:00
parent 56accfdb9c
commit 55ed12f8d1
767 changed files with 119642 additions and 122204 deletions
+161 -74
View File
@@ -10,6 +10,7 @@
#include "eiface.h"
#include "team.h"
#include "gameinterface.h"
#include "fmtstr.h"
#ifdef TF_DLL
#include "tf/tf_gamerules.h"
@@ -39,15 +40,105 @@ CVoteController *g_voteController = NULL;
ConVar sv_vote_timer_duration("sv_vote_timer_duration", "15", FCVAR_DEVELOPMENTONLY, "How long to allow voting on an issue");
ConVar sv_vote_command_delay("sv_vote_command_delay", "2", FCVAR_DEVELOPMENTONLY, "How long after a vote passes until the action happens", false, 0, true, 4.5);
ConVar sv_allow_votes("sv_allow_votes", "1", 0, "Allow voting?");
ConVar sv_vote_failure_timer("sv_vote_failure_timer", "300", 0, "A vote that fails cannot be re-submitted for this long");
ConVar sv_allow_votes("sv_allow_votes", "1", FCVAR_NONE, "Allow voting?");
ConVar sv_vote_failure_timer( "sv_vote_failure_timer", "300", FCVAR_NONE, "A vote that fails cannot be re-submitted for this long" );
#ifdef TF_DLL
ConVar sv_vote_failure_timer_mvm( "sv_vote_failure_timer_mvm", "120", 0, "A vote that fails in MvM cannot be re-submitted for this long" );
ConVar sv_vote_failure_timer_mvm( "sv_vote_failure_timer_mvm", "120", FCVAR_NONE, "A vote that fails in MvM cannot be re-submitted for this long" );
#endif // TF_DLL
ConVar sv_vote_creation_timer("sv_vote_creation_timer", "120", FCVAR_DEVELOPMENTONLY, "How often someone can individually call a vote.");
ConVar sv_vote_quorum_ratio( "sv_vote_quorum_ratio", "0.6", 1, "The minimum ratio of players needed to vote on an issue to resolve it.", true, 0.1, true, 1.0 );
ConVar sv_vote_allow_spectators( "sv_vote_allow_spectators", "0", 0, "Allow spectators to vote?" );
ConVar sv_vote_ui_hide_disabled_issues( "sv_vote_ui_hide_disabled_issues", "1", 0, "Suppress listing of disabled issues in the vote setup screen." );
ConVar sv_vote_quorum_ratio( "sv_vote_quorum_ratio", "0.6", FCVAR_HIDDEN, "The minimum ratio of players needed to vote on an issue to resolve it.", true, 0.1, true, 1.0 );
ConVar sv_vote_allow_spectators( "sv_vote_allow_spectators", "0", FCVAR_NONE, "Allow spectators to vote?" );
ConVar sv_vote_ui_hide_disabled_issues( "sv_vote_ui_hide_disabled_issues", "1", FCVAR_NONE, "Suppress listing of disabled issues in the vote setup screen." );
static const int k_nKickWatchListMaxDuration = 300;
//-----------------------------------------------------------------------------
// Purpose: Game system to detect maps without cameras in them, and move on
//-----------------------------------------------------------------------------
class CVoteControllerSystem : public CAutoGameSystemPerFrame
{
public:
CVoteControllerSystem( char const *name ) : CAutoGameSystemPerFrame( name )
{
SetDefLessFunc( m_mapKickWatchList );
m_flNextKickCheckTime = 0.f;
}
virtual void LevelInitPreEntity()
{
}
virtual void FrameUpdatePostEntityThink( void )
{
// Executing the vote controller command needs to happen in the PostEntityThink as it can restart levels and
// blast entities, etc. If you're doing this during a regular think, this can cause entities thinking after
// you in Physics_RunThinkFunctions() to get grumpy and crash.
if ( g_voteController )
{
// Vote passed - execute the command
if ( g_voteController->m_executeCommandTimer.HasStarted() && g_voteController->m_executeCommandTimer.IsElapsed() )
{
g_voteController->m_executeCommandTimer.Invalidate();
g_voteController->m_potentialIssues[g_voteController->m_iActiveIssueIndex]->ExecuteCommand();
}
// Kick watch
if ( m_flNextKickCheckTime < gpGlobals->curtime )
{
FOR_EACH_MAP( m_mapKickWatchList, i )
{
if ( gpGlobals->curtime > m_mapKickWatchList[i] )
{
m_mapKickWatchList.RemoveAt( i );
break; // Constantly called code - resume on next pass
}
CBasePlayer *pTarget = NULL;
CSteamID steamIDPlayer;
for ( int j = 1; j <= gpGlobals->maxClients; j++ )
{
CBasePlayer *pPlayer = UTIL_PlayerByIndex( j );
if ( !pPlayer )
continue;
if ( pPlayer->GetSteamID( &steamIDPlayer ) == false )
continue;
if ( steamIDPlayer == m_mapKickWatchList.Key( i ) )
{
pTarget = pPlayer;
break;
}
}
if ( pTarget )
{
// Welcome back
engine->ServerCommand( CFmtStr( "kickid %d %s;", pTarget->GetUserID(), "Kicked by server." ) );
}
}
m_flNextKickCheckTime = gpGlobals->curtime + 0.2f;
}
}
}
void AddPlayerToKickWatchList( CSteamID steamID, float flDuration )
{
flDuration = clamp( flDuration, 1.f, (float)k_nKickWatchListMaxDuration );
if ( m_mapKickWatchList.Find( steamID ) == m_mapKickWatchList.InvalidIndex() )
{
m_mapKickWatchList.Insert( steamID, ( gpGlobals->curtime + flDuration ) );
}
}
private:
CUtlMap< CSteamID, float > m_mapKickWatchList;
float m_flNextKickCheckTime;
};
CVoteControllerSystem VoteControllerSystem( "CVoteControllerSystem" );
//-----------------------------------------------------------------------------
// Purpose:
@@ -101,7 +192,7 @@ CON_COMMAND( callvote, "Start a vote on an issue." )
{
if ( pVoteCaller->GetTeamNumber() == TEAM_SPECTATOR )
{
g_voteController->SendVoteFailedMessage( VOTE_FAILED_SPECTATOR, pVoteCaller );
g_voteController->SendVoteCreationFailedMessage( VOTE_FAILED_SPECTATOR, pVoteCaller );
return;
}
}
@@ -111,7 +202,7 @@ CON_COMMAND( callvote, "Start a vote on an issue." )
int nCooldown = 0;
if ( !g_voteController->CanEntityCallVote( pVoteCaller, nCooldown ) )
{
g_voteController->SendVoteFailedMessage( VOTE_FAILED_RATE_EXCEEDED, pVoteCaller, nCooldown );
g_voteController->SendVoteCreationFailedMessage( VOTE_FAILED_RATE_EXCEEDED, pVoteCaller, nCooldown );
return;
}
#endif
@@ -381,7 +472,7 @@ bool CVoteController::CreateVote( int iEntIndex, const char *pszTypeString, cons
{
if ( !bDedicatedServer )
{
SendVoteFailedMessage( nErrorCode, pVoteCaller, nTime );
SendVoteCreationFailedMessage( nErrorCode, pVoteCaller, nTime );
}
}
}
@@ -391,35 +482,43 @@ bool CVoteController::CreateVote( int iEntIndex, const char *pszTypeString, cons
}
//-----------------------------------------------------------------------------
// Purpose: Sent to everyone, unless we pass a player pointer
// Purpose: The vote failed to start - let the caller know why
//-----------------------------------------------------------------------------
void CVoteController::SendVoteFailedMessage( vote_create_failed_t nReason, CBasePlayer *pVoteCaller, int nTime )
void CVoteController::SendVoteCreationFailedMessage( vote_create_failed_t nReason, CBasePlayer *pVoteCaller, int nTime /*= -1*/ )
{
// driller: need to merge all failure case stuff into a single path
if ( pVoteCaller )
{
CSingleUserRecipientFilter user( pVoteCaller );
user.MakeReliable();
Assert( pVoteCaller );
if ( !pVoteCaller )
return;
UserMessageBegin( user, "CallVoteFailed" );
WRITE_BYTE( nReason );
WRITE_SHORT( nTime );
MessageEnd();
}
else
{
UTIL_LogPrintf("Vote failed \"%s %s\" \n",
m_potentialIssues[m_iActiveIssueIndex]->GetTypeString(),
m_potentialIssues[m_iActiveIssueIndex]->GetDetailsString() );
CSingleUserRecipientFilter user( pVoteCaller );
user.MakeReliable();
CBroadcastRecipientFilter filter;
filter.MakeReliable();
UserMessageBegin( user, "CallVoteFailed" );
WRITE_BYTE( nReason );
WRITE_SHORT( nTime );
MessageEnd();
}
UserMessageBegin( filter, "VoteFailed" );
WRITE_BYTE( m_iOnlyTeamToVote );
WRITE_BYTE( nReason );
MessageEnd();
}
//-----------------------------------------------------------------------------
// Purpose: The vote was called, but failed to pass - let everyone know why
//-----------------------------------------------------------------------------
void CVoteController::SendVoteFailedToPassMessage( vote_create_failed_t nReason )
{
Assert( m_potentialIssues[m_iActiveIssueIndex] );
// See if we have a player target.
CBasePlayer *pVoteTarget = m_potentialIssues[m_iActiveIssueIndex]->m_hPlayerTarget;
bool bFakeClient = ( pVoteTarget && ( pVoteTarget->IsFakeClient() || pVoteTarget->IsHLTV() || pVoteTarget->IsReplay() ) );
UTIL_LogPrintf( "Vote failed \"%s %s\" with code %i (proxy: %i) \n", m_potentialIssues[m_iActiveIssueIndex]->GetTypeString(), m_potentialIssues[m_iActiveIssueIndex]->GetDetailsString(), (int)nReason, bFakeClient );
CBroadcastRecipientFilter filter;
filter.MakeReliable();
UserMessageBegin( filter, "VoteFailed" );
WRITE_BYTE( m_iOnlyTeamToVote );
WRITE_BYTE( nReason );
MessageEnd();
}
//-----------------------------------------------------------------------------
@@ -577,7 +676,7 @@ void CVoteController::VoteControllerThink( void )
// Option1 is Yes
if ( nWinningVoteOption != VOTE_OPTION1 )
{
SendVoteFailedMessage( VOTE_FAILED_YES_MUST_EXCEED_NO );
SendVoteFailedToPassMessage( VOTE_FAILED_YES_MUST_EXCEED_NO );
bVotePassed = false;
}
}
@@ -592,7 +691,7 @@ void CVoteController::VoteControllerThink( void )
}
else
{
SendVoteFailedMessage( VOTE_FAILED_QUORUM_FAILURE );
SendVoteFailedToPassMessage( VOTE_FAILED_QUORUM_FAILURE );
bVotePassed = false;
}
@@ -601,9 +700,11 @@ void CVoteController::VoteControllerThink( void )
m_executeCommandTimer.Start( sv_vote_command_delay.GetFloat() );
m_resetVoteTimer.Start( 5.0 );
UTIL_LogPrintf("Vote succeeded \"%s %s\"\n",
m_potentialIssues[m_iActiveIssueIndex]->GetTypeString(),
m_potentialIssues[m_iActiveIssueIndex]->GetDetailsString() );
// Target is not always a player (changelevel, etc)
CBasePlayer *pVoteTarget = m_potentialIssues[m_iActiveIssueIndex]->m_hPlayerTarget;
bool bFakeClient = ( pVoteTarget && ( pVoteTarget->IsFakeClient() || pVoteTarget->IsHLTV() || pVoteTarget->IsReplay() ) );
UTIL_LogPrintf( "Vote succeeded \"%s %s\" (proxy: %i) \n", m_potentialIssues[m_iActiveIssueIndex]->GetTypeString(), m_potentialIssues[m_iActiveIssueIndex]->GetDetailsString(), bFakeClient );
CBroadcastRecipientFilter filter;
filter.MakeReliable();
@@ -821,6 +922,14 @@ bool CVoteController::CanEntityCallVote( CBasePlayer *pPlayer, int &nCooldown )
return true;
};
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CVoteController::AddPlayerToKickWatchList( CSteamID steamID, float flDuration )
{
VoteControllerSystem.AddPlayerToKickWatchList( steamID, flDuration );
}
//-----------------------------------------------------------------------------
// Purpose: BaseIssue
//-----------------------------------------------------------------------------
@@ -831,6 +940,7 @@ CBaseIssue::CBaseIssue( const char *pszTypeString )
m_iNumYesVotes = 0;
m_iNumNoVotes = 0;
m_iNumPotentialVotes = 0;
m_flNextCallTime = -1.f;
ASSERT( g_voteController );
g_voteController->RegisterIssue( this );
@@ -943,9 +1053,18 @@ bool CBaseIssue::CanCallVote( int iEntIndex, const char *pszDetails, vote_create
return true;
// Bogus player
if( iEntIndex == -1 )
if ( iEntIndex == -1 )
return false;
// Note: Issue timers reset on level change because the class is created/destroyed during transitions.
// It'd be nice to refactor the basic framework of the system to get rid of side-effects like this.
if ( m_flNextCallTime != -1.f && gpGlobals->curtime < m_flNextCallTime )
{
nFailCode = VOTE_FAILED_ON_COOLDOWN;
nTime = m_flNextCallTime - gpGlobals->curtime;
return false;
}
#ifdef TF_DLL
if ( TFGameRules() && TFGameRules()->IsInWaitingForPlayers() && !TFGameRules()->IsInTournamentMode() )
{
@@ -955,14 +1074,14 @@ bool CBaseIssue::CanCallVote( int iEntIndex, const char *pszDetails, vote_create
#endif // TF_DLL
CBaseEntity *pVoteCaller = UTIL_EntityByIndex( iEntIndex );
if( pVoteCaller && !CanTeamCallVote( GetVoterTeam( pVoteCaller ) ) )
if ( pVoteCaller && !CanTeamCallVote( GetVoterTeam( pVoteCaller ) ) )
{
nFailCode = VOTE_FAILED_TEAM_CANT_CALL;
return false;
}
// Did this fail recently?
for( int iIndex = 0; iIndex < m_FailedVotes.Count(); iIndex++ )
for ( int iIndex = 0; iIndex < m_FailedVotes.Count(); iIndex++ )
{
FailedVote *pCurrentFailure = m_FailedVotes[iIndex];
int nTimeRemaining = pCurrentFailure->flLockoutTime - gpGlobals->curtime;
@@ -988,7 +1107,7 @@ bool CBaseIssue::CanCallVote( int iEntIndex, const char *pszDetails, vote_create
if ( bFailed )
{
nFailCode = VOTE_FAILED_FAILED_RECENTLY;
nFailCode = VOTE_FAILED_ON_COOLDOWN;
nTime = nTimeRemaining;
return false;
}
@@ -1065,36 +1184,4 @@ bool CBaseIssue::GetVoteOptions( CUtlVector <const char*> &vecNames )
return true;
}
//-----------------------------------------------------------------------------
// Purpose: Game system to detect maps without cameras in them, and move on
//-----------------------------------------------------------------------------
class CVoteControllerSystem : public CAutoGameSystemPerFrame
{
public:
CVoteControllerSystem( char const *name ) : CAutoGameSystemPerFrame( name )
{
}
virtual void LevelInitPreEntity()
{
}
virtual void FrameUpdatePostEntityThink( void )
{
// Executing the vote controller command needs to happen in the PostEntityThink as it can restart levels and
// blast entities, etc. If you're doing this during a regular think, this can cause entities thinking after
// you in Physics_RunThinkFunctions() to get grumpy and crash.
if( g_voteController )
{
// Vote passed - execute the command
if( g_voteController->m_executeCommandTimer.HasStarted() && g_voteController->m_executeCommandTimer.IsElapsed() )
{
g_voteController->m_executeCommandTimer.Invalidate();
g_voteController->m_potentialIssues[ g_voteController->m_iActiveIssueIndex ]->ExecuteCommand();
}
}
}
};
CVoteControllerSystem VoteControllerSystem( "CVoteControllerSystem" );