diff --git a/public/basehandle.h b/public/basehandle.h index 492a20b3..f0dfa831 100644 --- a/public/basehandle.h +++ b/public/basehandle.h @@ -1,4 +1,4 @@ -//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============// +//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============// // // Purpose: // @@ -92,10 +92,10 @@ inline CBaseHandle::CBaseHandle( int iEntry, int iSerialNumber ) inline void CBaseHandle::Init( int iEntry, int iSerialNumber ) { - Assert( iEntry >= 0 && iEntry < NUM_ENT_ENTRIES ); + Assert( iEntry >= 0 && (iEntry & ENT_ENTRY_MASK) == iEntry); Assert( iSerialNumber >= 0 && iSerialNumber < (1 << NUM_SERIAL_NUM_BITS) ); - m_Index = iEntry | (iSerialNumber << NUM_ENT_ENTRY_BITS); + m_Index = iEntry | (iSerialNumber << NUM_SERIAL_NUM_SHIFT_BITS); } inline void CBaseHandle::Term() @@ -110,12 +110,26 @@ inline bool CBaseHandle::IsValid() const inline int CBaseHandle::GetEntryIndex() const { + // There is a hack here: due to a bug in the original implementation of the + // entity handle system, an attempt to look up an invalid entity index in + // certain cirumstances might fall through to the the mask operation below. + // This would mask an invalid index to be in fact a lookup of entity number + // NUM_ENT_ENTRIES, so invalid ent indexes end up actually looking up the + // last slot in the entities array. Since this slot is always empty, the + // lookup returns NULL and the expected behavior occurs through this unexpected + // route. + // A lot of code actually depends on this behavior, and the bug was only exposed + // after a change to NUM_SERIAL_NUM_BITS increased the number of allowable + // static props in the world. So the if-stanza below detects this case and + // retains the prior (bug-submarining) behavior. + if ( !IsValid() ) + return NUM_ENT_ENTRIES-1; return m_Index & ENT_ENTRY_MASK; } inline int CBaseHandle::GetSerialNumber() const { - return m_Index >> NUM_ENT_ENTRY_BITS; + return m_Index >> NUM_SERIAL_NUM_SHIFT_BITS; } inline int CBaseHandle::ToInt() const diff --git a/public/const.h b/public/const.h index fc1d2191..3a22a20d 100644 --- a/public/const.h +++ b/public/const.h @@ -1,4 +1,4 @@ -//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============// +//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============// // // Purpose: // @@ -69,7 +69,7 @@ #define INVALID_EHANDLE_INDEX 0xFFFFFFFF #define NUM_SERIAL_NUM_BITS (32 - NUM_ENT_ENTRY_BITS) - +#define NUM_SERIAL_NUM_SHIFT_BITS 16 // Networked ehandles use less bits to encode the serial number. #define NUM_NETWORKED_EHANDLE_SERIAL_NUMBER_BITS 10