mirror of
https://github.com/alliedmodders/hl2sdk.git
synced 2025-09-19 12:06:07 +08:00
First version of the SOurce SDK 2013
This commit is contained in:
325
game/shared/predictableid.cpp
Normal file
325
game/shared/predictableid.cpp
Normal file
@ -0,0 +1,325 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "checksum_crc.h"
|
||||
#include "tier1/strtools.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
#if !defined( NO_ENTITY_PREDICTION )
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Helper class for resetting instance numbers, etc.
|
||||
//-----------------------------------------------------------------------------
|
||||
class CPredictableIdHelper
|
||||
{
|
||||
public:
|
||||
CPredictableIdHelper()
|
||||
{
|
||||
Reset( -1 );
|
||||
}
|
||||
|
||||
void Reset( int command )
|
||||
{
|
||||
m_nCurrentCommand = command;
|
||||
m_nCount = 0;
|
||||
memset( m_Entries, 0, sizeof( m_Entries ) );
|
||||
}
|
||||
|
||||
int AddEntry( int command, int hash )
|
||||
{
|
||||
// Clear list if command number changes
|
||||
if ( command != m_nCurrentCommand )
|
||||
{
|
||||
Reset( command );
|
||||
}
|
||||
|
||||
entry *e = FindOrAddEntry( hash );
|
||||
if ( !e )
|
||||
return 0;
|
||||
e->count++;
|
||||
return e->count-1;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
enum
|
||||
{
|
||||
MAX_ENTRIES = 256,
|
||||
};
|
||||
|
||||
struct entry
|
||||
{
|
||||
int hash;
|
||||
int count;
|
||||
};
|
||||
|
||||
entry *FindOrAddEntry( int hash )
|
||||
{
|
||||
int i;
|
||||
for ( i = 0; i < m_nCount; i++ )
|
||||
{
|
||||
entry *e = &m_Entries[ i ];
|
||||
if ( e->hash == hash )
|
||||
return e;
|
||||
}
|
||||
|
||||
if ( m_nCount >= MAX_ENTRIES )
|
||||
{
|
||||
// assert( 0 );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
entry *e = &m_Entries[ m_nCount++ ];
|
||||
e->hash = hash;
|
||||
e->count = 0;
|
||||
return e;
|
||||
}
|
||||
|
||||
int m_nCurrentCommand;
|
||||
int m_nCount;
|
||||
entry m_Entries[ MAX_ENTRIES ];
|
||||
};
|
||||
|
||||
static CPredictableIdHelper g_Helper;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
CPredictableId::CPredictableId( void )
|
||||
{
|
||||
memset( &m_PredictableID, 0, sizeof( m_PredictableID ) );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CPredictableId::ResetInstanceCounters( void )
|
||||
{
|
||||
g_Helper.Reset( -1 );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Is the Id being used
|
||||
// Output : Returns true on success, false on failure.
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CPredictableId::IsActive( void ) const
|
||||
{
|
||||
if ( *(const int *)&m_PredictableID == 0 )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : playerIndex -
|
||||
//-----------------------------------------------------------------------------
|
||||
void CPredictableId::SetPlayer( int playerIndex )
|
||||
{
|
||||
m_PredictableID.player = (unsigned int)playerIndex;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Output : int
|
||||
//-----------------------------------------------------------------------------
|
||||
int CPredictableId::GetPlayer( void ) const
|
||||
{
|
||||
return (int)m_PredictableID.player;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Output : int
|
||||
//-----------------------------------------------------------------------------
|
||||
int CPredictableId::GetCommandNumber( void ) const
|
||||
{
|
||||
return (int)m_PredictableID.command;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : commandNumber -
|
||||
//-----------------------------------------------------------------------------
|
||||
void CPredictableId::SetCommandNumber( int commandNumber )
|
||||
{
|
||||
m_PredictableID.command = (unsigned int)commandNumber;
|
||||
}
|
||||
|
||||
/*
|
||||
bool CPredictableId::IsCommandNumberEqual( int testNumber ) const
|
||||
{
|
||||
if ( ( testNumber & ((1<<10) - 1) ) == m_PredictableID.command )
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
*/
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : *classname -
|
||||
// *module -
|
||||
// line -
|
||||
// Output : static int
|
||||
//-----------------------------------------------------------------------------
|
||||
static int ClassFileLineHash( const char *classname, const char *module, int line )
|
||||
{
|
||||
CRC32_t retval;
|
||||
|
||||
CRC32_Init( &retval );
|
||||
|
||||
char tempbuffer[ 512 ];
|
||||
|
||||
// ACK, have to go lower case due to issues with .dsp having different cases of drive
|
||||
// letters, etc.!!!
|
||||
Q_strncpy( tempbuffer, classname, sizeof( tempbuffer ) );
|
||||
Q_strlower( tempbuffer );
|
||||
CRC32_ProcessBuffer( &retval, (void *)tempbuffer, Q_strlen( tempbuffer ) );
|
||||
|
||||
Q_strncpy( tempbuffer, module, sizeof( tempbuffer ) );
|
||||
Q_strlower( tempbuffer );
|
||||
CRC32_ProcessBuffer( &retval, (void *)tempbuffer, Q_strlen( tempbuffer ) );
|
||||
|
||||
CRC32_ProcessBuffer( &retval, (void *)&line, sizeof( int ) );
|
||||
|
||||
CRC32_Final( &retval );
|
||||
|
||||
return (int)retval;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Create a predictable id of the specified parameter set
|
||||
// Input : player -
|
||||
// command -
|
||||
// *classname -
|
||||
// *module -
|
||||
// line -
|
||||
//-----------------------------------------------------------------------------
|
||||
void CPredictableId::Init( int player, int command, const char *classname, const char *module, int line )
|
||||
{
|
||||
SetPlayer( player );
|
||||
SetCommandNumber( command );
|
||||
|
||||
m_PredictableID.hash = ClassFileLineHash( classname, module, line );
|
||||
|
||||
// Use helper to determine instance number this command
|
||||
int instance = g_Helper.AddEntry( command, m_PredictableID.hash );
|
||||
|
||||
// Set appropriate instance number
|
||||
SetInstanceNumber( instance );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Output : int
|
||||
//-----------------------------------------------------------------------------
|
||||
int CPredictableId::GetHash( void ) const
|
||||
{
|
||||
return (int)m_PredictableID.hash;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : counter -
|
||||
//-----------------------------------------------------------------------------
|
||||
void CPredictableId::SetInstanceNumber( int counter )
|
||||
{
|
||||
m_PredictableID.instance = (unsigned int)counter;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Output : int
|
||||
//-----------------------------------------------------------------------------
|
||||
int CPredictableId::GetInstanceNumber( void ) const
|
||||
{
|
||||
return (int)m_PredictableID.instance;
|
||||
}
|
||||
|
||||
// Client only
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : ack -
|
||||
//-----------------------------------------------------------------------------
|
||||
void CPredictableId::SetAcknowledged( bool ack )
|
||||
{
|
||||
m_PredictableID.ack = ack ? 1 : 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Output : Returns true on success, false on failure.
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CPredictableId::GetAcknowledged( void ) const
|
||||
{
|
||||
return m_PredictableID.ack ? true : false;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Output : int
|
||||
//-----------------------------------------------------------------------------
|
||||
int CPredictableId::GetRaw( void ) const
|
||||
{
|
||||
return *(int *)&m_PredictableID;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : raw -
|
||||
//-----------------------------------------------------------------------------
|
||||
void CPredictableId::SetRaw( int raw )
|
||||
{
|
||||
*(int *)&m_PredictableID = raw;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Determine if one id is == another, ignores Acknowledged state
|
||||
// Input : other -
|
||||
// Output : bool CPredictableId::operator
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CPredictableId::operator ==( const CPredictableId& other ) const
|
||||
{
|
||||
if ( this == &other )
|
||||
return true;
|
||||
|
||||
if ( GetPlayer() != other.GetPlayer() )
|
||||
return false;
|
||||
if ( GetCommandNumber() != other.GetCommandNumber() )
|
||||
return false;
|
||||
if ( GetHash() != other.GetHash() )
|
||||
return false;
|
||||
if ( GetInstanceNumber() != other.GetInstanceNumber() )
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CPredictableId::operator !=( const CPredictableId& other ) const
|
||||
{
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Output : char const
|
||||
//-----------------------------------------------------------------------------
|
||||
const char *CPredictableId::Describe( void ) const
|
||||
{
|
||||
static char desc[ 128 ];
|
||||
|
||||
Q_snprintf( desc, sizeof( desc ), "pl(%i) cmd(%i) hash(%i) inst(%i) ack(%s)",
|
||||
GetPlayer(),
|
||||
GetCommandNumber(),
|
||||
GetHash(),
|
||||
GetInstanceNumber() ,
|
||||
GetAcknowledged() ? "true" : "false" );
|
||||
|
||||
return desc;
|
||||
}
|
||||
#endif
|
Reference in New Issue
Block a user