diff --git a/sp/src/game/shared/mapbase/vscript_singletons.cpp b/sp/src/game/shared/mapbase/vscript_singletons.cpp
index 81459ebfcf8..5a039709242 100644
--- a/sp/src/game/shared/mapbase/vscript_singletons.cpp
+++ b/sp/src/game/shared/mapbase/vscript_singletons.cpp
@@ -74,22 +74,36 @@ extern ISaveRestoreOps* GetStdStringDataOps();
#ifdef GAME_DLL
#define UTLVECTOR_DATAOPS( fieldType, dataType )\
CUtlVectorDataopsInstantiator< fieldType >::GetDataOps( (CUtlVector< dataType >*)0 )
- #define IS_EHANDLE_UTLVECTOR( td )\
- td->pSaveRestoreOps == UTLVECTOR_DATAOPS( FIELD_EHANDLE, CHandle< CBaseEntity > ) ||\
- td->pSaveRestoreOps == UTLVECTOR_DATAOPS( FIELD_EHANDLE, CHandle< CBaseFlex > ) ||\
- td->pSaveRestoreOps == UTLVECTOR_DATAOPS( FIELD_EHANDLE, CHandle< CBaseAnimating > ) ||\
- td->pSaveRestoreOps == UTLVECTOR_DATAOPS( FIELD_EHANDLE, CHandle< CBaseCombatWeapon > ) ||\
- td->pSaveRestoreOps == UTLVECTOR_DATAOPS( FIELD_EHANDLE, CHandle< CBasePlayer > ) ||\
- td->pSaveRestoreOps == UTLVECTOR_DATAOPS( FIELD_EHANDLE, CHandle< CAI_BaseNPC > ) ||\
- td->pSaveRestoreOps == UTLVECTOR_DATAOPS( FIELD_EHANDLE, CHandle< CSceneEntity > ) ||\
- td->pSaveRestoreOps == UTLVECTOR_DATAOPS( FIELD_EHANDLE, CHandle< CSceneListManager > ) ||\
- td->pSaveRestoreOps == UTLVECTOR_DATAOPS( FIELD_EHANDLE, CHandle< CRagdollBoogie > ) ||\
- td->pSaveRestoreOps == UTLVECTOR_DATAOPS( FIELD_EHANDLE, CHandle< CFish > ) ||\
- td->pSaveRestoreOps == UTLVECTOR_DATAOPS( FIELD_EHANDLE, CHandle< CVGuiScreen > )
class CSceneListManager;
class CRagdollBoogie;
class CFish;
+
+ bool IS_EHANDLE_UTLVECTOR( const typedescription_t *td )
+ {
+ // Different entity handles are compiled as unique types, thus return unique SaveRestoreOps
+ return ( td->pSaveRestoreOps == UTLVECTOR_DATAOPS( FIELD_EHANDLE, CHandle< CBaseEntity > ) ||
+ // CSceneEntity::m_hActorList
+ td->pSaveRestoreOps == UTLVECTOR_DATAOPS( FIELD_EHANDLE, CHandle< CBaseFlex > ) ||
+ // CTriggerSoundscape::m_spectators
+ td->pSaveRestoreOps == UTLVECTOR_DATAOPS( FIELD_EHANDLE, CHandle< CBasePlayer > ) ||
+ // CAI_GoalEntity::m_actors
+ td->pSaveRestoreOps == UTLVECTOR_DATAOPS( FIELD_EHANDLE, CHandle< CAI_BaseNPC > ) ||
+ // CAntlionTemplateMaker::m_Children
+ //td->pSaveRestoreOps == UTLVECTOR_DATAOPS( FIELD_EHANDLE, CHandle< CNPC_Antlion > ) ||
+ // CPointRagdollBoogie::m_Boogies
+ td->pSaveRestoreOps == UTLVECTOR_DATAOPS( FIELD_EHANDLE, CHandle< CRagdollBoogie > ) ||
+ // CFishPool::m_fishes
+ td->pSaveRestoreOps == UTLVECTOR_DATAOPS( FIELD_EHANDLE, CHandle< CFish > ) ||
+ // CBaseViewModel::m_hScreens
+ td->pSaveRestoreOps == UTLVECTOR_DATAOPS( FIELD_EHANDLE, CHandle< CVGuiScreen > ) ||
+ // CSceneManager::{m_ActiveScenes, m_hNotifySceneCompletion}
+ td->pSaveRestoreOps == UTLVECTOR_DATAOPS( FIELD_EHANDLE, CHandle< CSceneEntity > ) ||
+ // CSceneManager::m_hListManagers, CSceneListManager::m_hListManagers
+ td->pSaveRestoreOps == UTLVECTOR_DATAOPS( FIELD_EHANDLE, CHandle< CSceneListManager > )
+ );
+ }
+
#ifdef _DEBUG
class CStringTableSaveRestoreOps;
extern CStringTableSaveRestoreOps g_VguiScreenStringOps;
@@ -160,7 +174,7 @@ class CScriptNetPropManager
return 8;
if ( proxy == RecvProxy_Int32ToInt16 )
return 16;
- if ( proxy == RecvProxy_Int32ToInt32 )
+ if ( proxy == RecvProxy_Int32ToInt32 || proxy == RecvProxy_IntToColor32 )
return 32;
return 0;
@@ -218,7 +232,14 @@ class CScriptNetPropManager
#define MASK_INT_SIZE( _size ) ( ( 1 << (_size - 1) ) | ( (1 << (_size - 1)) - 1 ) )
#define MASK_NEAREST_BYTE( _bits ) ( ( (1 << ALIGN_TO_NEAREST_BYTE(_bits)) - 1 ) & ~((1 << _bits) - 1) )
#define ALIGN_TO_NEAREST_BYTE( _bits ) ( (_bits + 7) & ~7 )
- #define VARINFO_ARRAYSIZE_BITS 12
+ #define VARINFO_ELEMSIZE_BITS 8
+ #define VARINFO_ARRAYSIZE_BITS 16
+ #define VARINFO_ELEMSIZE_MAX ( ( 1 << VARINFO_ELEMSIZE_BITS ) - 1 )
+ #define VARINFO_ARRAYSIZE_MAX ( ( 1 << VARINFO_ARRAYSIZE_BITS ) - 1 )
+
+ // Else either clamp 'arraysize' assignments to 0x7fffffff
+ // or change unsigned boundary checks
+ COMPILE_TIME_ASSERT( VARINFO_ARRAYSIZE_BITS < 32 );
struct varinfo_t
{
@@ -232,13 +253,15 @@ class CScriptNetPropManager
enum types datatype : 16;
- // element size in bytes
- unsigned int elemsize : 8;
unsigned int arraysize : VARINFO_ARRAYSIZE_BITS;
+ // element size in bytes
+ unsigned int elemsize : VARINFO_ELEMSIZE_BITS;
// Following are only used in integer netprops to handle unsigned and size casting
- bool isUnsigned : 1;
- bool isNotNetworked : 1;
+ unsigned int isUnsigned : 1;
+ unsigned int isNotNetworked : 1;
+
+ unsigned int isGameRules : 1;
int GetOffset( int index )
{
@@ -258,7 +281,7 @@ class CScriptNetPropManager
CUtlVector< int > m_EntMap;
CUtlVector< vardict_t > m_VarDicts;
- varinfo_t* CacheNew( CBaseEntity *pEnt, const char *szProp )
+ varinfo_t *CacheNew( CBaseEntity *pEnt, const char *szProp, bool bNetworked )
{
int idx = m_EntMap.Find( GetClassID( pEnt ) );
if ( idx == m_EntMap.InvalidIndex() )
@@ -276,6 +299,13 @@ class CScriptNetPropManager
varinfo_t *pInfo = &dict.Element( idx );
V_memset( pInfo, 0, sizeof( varinfo_t ) );
+
+ pInfo->isNotNetworked = !bNetworked;
+
+ // see Recv/SendProxy_HL2GameRules
+ if ( bNetworked && dynamic_cast< CGameRulesProxy* >( pEnt ) )
+ pInfo->isGameRules = 1;
+
return pInfo;
}
@@ -458,7 +488,7 @@ class CScriptNetPropManager
// Searches NetTable first to handle overwritten member network variables - see
// CPlayerResource::m_iHealth and CBaseEntity::m_iHealth
- varinfo_t *GetVarInfo( CBaseEntity *pEnt, const char *szProp, int index )
+ varinfo_t *GetVarInfo( CBaseEntity *pEnt, const char *szProp, int index, bool bDontWarnOnMissing = false )
{
int offset = 0;
NetTable *pTable = GetNetTable( GetNetworkClass( pEnt ) );
@@ -467,9 +497,10 @@ class CScriptNetPropManager
{
#define SetVarInfo()\
- varinfo_t *pInfo = CacheNew( pEnt, szProp );\
- pInfo->isNotNetworked = 0;\
+ varinfo_t *pInfo = CacheNew( pEnt, szProp, true );\
+ Assert( pProp->GetElementStride() <= VARINFO_ELEMSIZE_MAX );\
pInfo->elemsize = pProp->GetElementStride();\
+ Assert( pProp->GetNumElements() > 0 && pProp->GetNumElements() <= VARINFO_ARRAYSIZE_MAX );\
pInfo->arraysize = pProp->GetNumElements();\
pInfo->offset = offset;
@@ -613,8 +644,9 @@ class CScriptNetPropManager
{
if ( IsEHandle( pProp ) )
{
- varinfo_t *pInfo = CacheNew( pEnt, szProp );
+ varinfo_t *pInfo = CacheNew( pEnt, szProp, true );
pInfo->elemsize = sizeof(int);
+ Assert( pArray->GetNumProps() > 0 && pArray->GetNumProps() <= VARINFO_ARRAYSIZE_MAX );
pInfo->arraysize = pArray->GetNumProps();
pInfo->offset = offset;
pInfo->datatype = types::_EHANDLE;
@@ -629,7 +661,7 @@ class CScriptNetPropManager
if ( size == 0 )
break;
#endif
- varinfo_t *pInfo = CacheNew( pEnt, szProp );
+ varinfo_t *pInfo = CacheNew( pEnt, szProp, true );
if ( pArray->GetNumProps() > 1 )
{
@@ -641,6 +673,7 @@ class CScriptNetPropManager
pInfo->elemsize = 0;
}
+ Assert( pArray->GetNumProps() > 0 && pArray->GetNumProps() <= VARINFO_ARRAYSIZE_MAX );
pInfo->arraysize = pArray->GetNumProps();
pInfo->offset = offset;
pInfo->mask = MASK_INT_SIZE( size );
@@ -650,8 +683,9 @@ class CScriptNetPropManager
}
case DPT_Float:
{
- varinfo_t *pInfo = CacheNew( pEnt, szProp );
+ varinfo_t *pInfo = CacheNew( pEnt, szProp, true );
pInfo->elemsize = sizeof(float);
+ Assert( pArray->GetNumProps() > 0 && pArray->GetNumProps() <= VARINFO_ARRAYSIZE_MAX );
pInfo->arraysize = pArray->GetNumProps();
pInfo->offset = offset;
pInfo->datatype = types::_FLOAT;
@@ -659,8 +693,9 @@ class CScriptNetPropManager
}
case DPT_Vector:
{
- varinfo_t *pInfo = CacheNew( pEnt, szProp );
+ varinfo_t *pInfo = CacheNew( pEnt, szProp, true );
pInfo->elemsize = sizeof(float)*3;
+ Assert( pArray->GetNumProps() > 0 && pArray->GetNumProps() <= VARINFO_ARRAYSIZE_MAX );
pInfo->arraysize = pArray->GetNumProps();
pInfo->offset = offset;
pInfo->datatype = types::_VEC3;
@@ -668,8 +703,9 @@ class CScriptNetPropManager
}
case DPT_VectorXY:
{
- varinfo_t *pInfo = CacheNew( pEnt, szProp );
+ varinfo_t *pInfo = CacheNew( pEnt, szProp, true );
pInfo->elemsize = sizeof(float)*2;
+ Assert( pArray->GetNumProps() > 0 && pArray->GetNumProps() <= VARINFO_ARRAYSIZE_MAX );
pInfo->arraysize = pArray->GetNumProps();
pInfo->offset = offset;
pInfo->datatype = types::_VEC2;
@@ -793,9 +829,10 @@ class CScriptNetPropManager
}
#define SetVarInfo()\
- varinfo_t *pInfo = CacheNew( pEnt, szProp );\
- pInfo->isNotNetworked = 1;\
+ varinfo_t *pInfo = CacheNew( pEnt, szProp, false );\
+ Assert( pField->fieldSizeInBytes / pField->fieldSize <= VARINFO_ELEMSIZE_MAX );\
pInfo->elemsize = pField->fieldSizeInBytes / pField->fieldSize;\
+ Assert( pField->fieldSize > 0 && pField->fieldSize <= VARINFO_ARRAYSIZE_MAX );\
pInfo->arraysize = pField->fieldSize;\
pInfo->offset = offset;
@@ -812,7 +849,6 @@ class CScriptNetPropManager
{
SetVarInfo();
pInfo->isUnsigned = ( pField->flags & SPROP_UNSIGNED ) != 0;
- pInfo->isNotNetworked = 1;
switch ( pField->fieldType )
{
case FIELD_INTEGER:
@@ -904,26 +940,26 @@ class CScriptNetPropManager
else if ( IS_EHANDLE_UTLVECTOR( pField ) )
{
SetVarInfo();
- pInfo->arraysize = ( 1 << VARINFO_ARRAYSIZE_BITS ) - 1; // dynamic, check on get
+ pInfo->arraysize = VARINFO_ARRAYSIZE_MAX;
pInfo->datatype = types::_DAR_EHANDLE;
}
else if ( pField->pSaveRestoreOps == UTLVECTOR_DATAOPS( FIELD_CLASSPTR, CBaseEntity* ) )
{
SetVarInfo();
- pInfo->arraysize = ( 1 << VARINFO_ARRAYSIZE_BITS ) - 1; // dynamic, check on get
+ pInfo->arraysize = VARINFO_ARRAYSIZE_MAX;
pInfo->datatype = types::_DAR_CLASSPTR;
}
else if ( pField->pSaveRestoreOps == UTLVECTOR_DATAOPS( FIELD_INTEGER, int ) )
{
SetVarInfo();
- pInfo->arraysize = ( 1 << VARINFO_ARRAYSIZE_BITS ) - 1; // dynamic, check on get
+ pInfo->arraysize = VARINFO_ARRAYSIZE_MAX;
pInfo->datatype = types::_DAR_INT;
}
else if ( pField->pSaveRestoreOps == UTLVECTOR_DATAOPS( FIELD_FLOAT, float ) ||
pField->pSaveRestoreOps == UTLVECTOR_DATAOPS( FIELD_TIME, float ) )
{
SetVarInfo();
- pInfo->arraysize = ( 1 << VARINFO_ARRAYSIZE_BITS ) - 1; // dynamic, check on get
+ pInfo->arraysize = VARINFO_ARRAYSIZE_MAX;
pInfo->datatype = types::_DAR_FLOAT;
}
// Only used by CAI_PlayerAlly::m_PendingConcept
@@ -956,9 +992,21 @@ class CScriptNetPropManager
}
}
#endif
+
+ if ( !bDontWarnOnMissing )
+ Warning( "NetProp field (%s)->'%s' does not exist!\n", pEnt->GetClassname(), szProp );
+
return NULL;
}
+ char *GetBase( CBaseEntity *pEnt, const varinfo_t *pInfo )
+ {
+ if ( pInfo->isGameRules )
+ return (char*)GameRules();
+
+ return (char*)pEnt;
+ }
+
public:
// FIXME: Cannot get datatable/arrays at the moment
bool HasProp( HSCRIPT hEnt, const char *szProp )
@@ -970,7 +1018,7 @@ class CScriptNetPropManager
varinfo_t *pInfo = CacheFetch( pEnt, szProp );
if ( !pInfo )
{
- pInfo = GetVarInfo( pEnt, szProp, INDEX_GET_TYPE );
+ pInfo = GetVarInfo( pEnt, szProp, INDEX_GET_TYPE, true );
if ( !pInfo )
return false;
@@ -1044,33 +1092,36 @@ class CScriptNetPropManager
if ( !pInfo )
return -1;
}
+
#ifdef GAME_DLL
+ char *pBase = GetBase( pEnt, pInfo );
+
switch ( pInfo->datatype )
{
case types::_DAR_EHANDLE:
{
- CUtlVector< EHANDLE > &vec = *(CUtlVector< EHANDLE >*)((char*)pEnt + pInfo->offset);
+ CUtlVector< EHANDLE > &vec = *(CUtlVector< EHANDLE >*)(pBase + pInfo->offset);
if ( !vec.Base() )
return -1;
return vec.Count();
}
case types::_DAR_CLASSPTR:
{
- CUtlVector< CBaseEntity* > &vec = *(CUtlVector< CBaseEntity* >*)((char*)pEnt + pInfo->offset);
+ CUtlVector< CBaseEntity* > &vec = *(CUtlVector< CBaseEntity* >*)(pBase + pInfo->offset);
if ( !vec.Base() )
return -1;
return vec.Count();
}
case types::_DAR_INT:
{
- CUtlVector< int > &vec = *(CUtlVector< int >*)((char*)pEnt + pInfo->offset);
+ CUtlVector< int > &vec = *(CUtlVector< int >*)(pBase + pInfo->offset);
if ( !vec.Base() )
return -1;
return vec.Count();
}
case types::_DAR_FLOAT:
{
- CUtlVector< float > &vec = *(CUtlVector< float >*)((char*)pEnt + pInfo->offset);
+ CUtlVector< float > &vec = *(CUtlVector< float >*)(pBase + pInfo->offset);
if ( !vec.Base() )
return -1;
return vec.Count();
@@ -1096,7 +1147,7 @@ class CScriptNetPropManager
return -1;
}
- if ( index < 0 || (unsigned int)index >= pInfo->arraysize )
+ if ( (unsigned int)index >= pInfo->arraysize )
return -1;
if ( pInfo->isNotNetworked )
@@ -1132,10 +1183,12 @@ class CScriptNetPropManager
}
else
{
+ char *pBase = GetBase( pEnt, pInfo );
+
switch ( pInfo->datatype )
{
case types::_INT32:
- return (*(int*)((char*)pEnt + pInfo->GetOffset( index ))) & pInfo->mask;
+ return (*(int*)(pBase + pInfo->GetOffset( index ))) & pInfo->mask;
}
}
@@ -1157,7 +1210,7 @@ class CScriptNetPropManager
return;
}
- if ( index < 0 || (unsigned int)index >= pInfo->arraysize )
+ if ( (unsigned int)index >= pInfo->arraysize )
return;
if ( pInfo->isNotNetworked )
@@ -1215,11 +1268,13 @@ class CScriptNetPropManager
}
else
{
+ char *pBase = GetBase( pEnt, pInfo );
+
switch ( pInfo->datatype )
{
case types::_INT32:
{
- int *dest = (int*)((char*)pEnt + pInfo->GetOffset( index ));
+ int *dest = (int*)(pBase + pInfo->GetOffset( index ));
*dest = (*dest & ~pInfo->mask) | (value & pInfo->mask);
NetworkStateChanged( pEnt, pInfo->GetOffset( index ) );
break;
@@ -1248,19 +1303,21 @@ class CScriptNetPropManager
if ( pInfo->datatype == types::_VEC3 )
arraysize *= 3;
- if ( index < 0 || (unsigned int)index >= arraysize )
+ if ( (unsigned int)index >= arraysize )
return -1;
+ char *pBase = GetBase( pEnt, pInfo );
+
switch ( pInfo->datatype )
{
case types::_FLOAT:
- return *(float*)((char*)pEnt + pInfo->GetOffset( index ));
+ return *(float*)(pBase + pInfo->GetOffset( index ));
case types::_VEC3:
- return ((float*)((char*)pEnt + pInfo->GetOffset( index / 3 )))[ index % 3 ];
+ return ((float*)(pBase + pInfo->GetOffset( index / 3 )))[ index % 3 ];
#ifdef GAME_DLL
case types::_DAR_FLOAT:
{
- CUtlVector< float > &vec = *(CUtlVector< float >*)((char*)pEnt + pInfo->offset);
+ CUtlVector< float > &vec = *(CUtlVector< float >*)(pBase + pInfo->offset);
if ( !vec.Base() )
return -1;
if ( index >= vec.Count() )
@@ -1293,23 +1350,25 @@ class CScriptNetPropManager
if ( pInfo->datatype == types::_VEC3 )
arraysize *= 3;
- if ( index < 0 || (unsigned int)index >= arraysize )
+ if ( (unsigned int)index >= arraysize )
return;
+ char *pBase = GetBase( pEnt, pInfo );
+
switch ( pInfo->datatype )
{
case types::_FLOAT:
- *(float*)((char*)pEnt + pInfo->GetOffset( index )) = value;
+ *(float*)(pBase + pInfo->GetOffset( index )) = value;
NetworkStateChanged( pEnt, pInfo->GetOffset( index ) );
break;
case types::_VEC3:
- ((float*)((char*)pEnt + pInfo->GetOffset( index / 3 )))[ index % 3 ] = value;
+ ((float*)(pBase + pInfo->GetOffset( index / 3 )))[ index % 3 ] = value;
NetworkStateChanged( pEnt, pInfo->GetOffset( index / 3 ) );
break;
#ifdef GAME_DLL
case types::_DAR_FLOAT:
{
- CUtlVector< float > &vec = *(CUtlVector< float >*)((char*)pEnt + pInfo->offset);
+ CUtlVector< float > &vec = *(CUtlVector< float >*)(pBase + pInfo->offset);
if ( !vec.Base() )
return;
if ( index >= vec.Count() )
@@ -1337,30 +1396,32 @@ class CScriptNetPropManager
return NULL;
}
- if ( index < 0 || (unsigned int)index >= pInfo->arraysize )
+ if ( (unsigned int)index >= pInfo->arraysize )
return NULL;
+ char *pBase = GetBase( pEnt, pInfo );
+
switch ( pInfo->datatype )
{
case types::_EHANDLE:
{
- EHANDLE &iEHandle = *(EHANDLE*)((char*)pEnt + pInfo->GetOffset( index ));
+ EHANDLE &iEHandle = *(EHANDLE*)(pBase + pInfo->GetOffset( index ));
return ToHScript( iEHandle );
}
#ifdef GAME_DLL
case types::_CLASSPTR:
{
- CBaseEntity* ptr = *(CBaseEntity**)((char*)pEnt + pInfo->GetOffset( index ));
+ CBaseEntity *ptr = *(CBaseEntity**)(pBase + pInfo->GetOffset( index ));
return ToHScript( ptr );
}
case types::_EDICT:
{
- edict_t* ptr = *(edict_t**)((char*)pEnt + pInfo->GetOffset( index ));
+ edict_t *ptr = *(edict_t**)(pBase + pInfo->GetOffset( index ));
return ToHScript( GetContainingEntity( ptr ) );
}
case types::_DAR_EHANDLE:
{
- CUtlVector< EHANDLE > &vec = *(CUtlVector< EHANDLE >*)((char*)pEnt + pInfo->offset);
+ CUtlVector< EHANDLE > &vec = *(CUtlVector< EHANDLE >*)(pBase + pInfo->offset);
if ( !vec.Base() )
return NULL;
if ( index >= vec.Count() )
@@ -1369,7 +1430,7 @@ class CScriptNetPropManager
}
case types::_DAR_CLASSPTR:
{
- CUtlVector< CBaseEntity* > &vec = *(CUtlVector< CBaseEntity* >*)((char*)pEnt + pInfo->offset);
+ CUtlVector< CBaseEntity* > &vec = *(CUtlVector< CBaseEntity* >*)(pBase + pInfo->offset);
if ( !vec.Base() )
return NULL;
if ( index >= vec.Count() )
@@ -1379,7 +1440,7 @@ class CScriptNetPropManager
#endif
case types::_PHYS:
{
- IPhysicsObject* ptr = *(IPhysicsObject**)((char*)pEnt + pInfo->GetOffset( index ));
+ IPhysicsObject *ptr = *(IPhysicsObject**)(pBase + pInfo->GetOffset( index ));
return ptr ? g_pScriptVM->RegisterInstance( ptr ) : NULL;
}
}
@@ -1402,30 +1463,32 @@ class CScriptNetPropManager
return;
}
- if ( index < 0 || (unsigned int)index >= pInfo->arraysize )
+ if ( (unsigned int)index >= pInfo->arraysize )
return;
+ char *pBase = GetBase( pEnt, pInfo );
+
switch ( pInfo->datatype )
{
case types::_EHANDLE:
- *(EHANDLE*)((char*)pEnt + pInfo->GetOffset( index )) = ToEnt( value );
+ *(EHANDLE*)(pBase + pInfo->GetOffset( index )) = ToEnt( value );
NetworkStateChanged( pEnt, pInfo->GetOffset( index ) );
break;
#ifdef GAME_DLL
case types::_CLASSPTR:
- *(CBaseEntity**)((char*)pEnt + pInfo->GetOffset( index )) = ToEnt( value );
+ *(CBaseEntity**)(pBase + pInfo->GetOffset( index )) = ToEnt( value );
NetworkStateChanged( pEnt, pInfo->GetOffset( index ) );
break;
case types::_EDICT:
{
CBaseEntity* ptr = ToEnt( value );
- *(edict_t**)((char*)pEnt + pInfo->GetOffset( index )) = ptr ? ptr->edict() : NULL;
+ *(edict_t**)(pBase + pInfo->GetOffset( index )) = ptr ? ptr->edict() : NULL;
NetworkStateChanged( pEnt, pInfo->GetOffset( index ) );
break;
}
case types::_DAR_EHANDLE:
{
- CUtlVector< EHANDLE > &vec = *(CUtlVector< EHANDLE >*)((char*)pEnt + pInfo->offset);
+ CUtlVector< EHANDLE > &vec = *(CUtlVector< EHANDLE >*)(pBase + pInfo->offset);
if ( !vec.Base() )
return;
if ( index >= vec.Count() )
@@ -1436,7 +1499,7 @@ class CScriptNetPropManager
}
case types::_DAR_CLASSPTR:
{
- CUtlVector< CBaseEntity* > &vec = *(CUtlVector< CBaseEntity* >*)((char*)pEnt + pInfo->offset);
+ CUtlVector< CBaseEntity* > &vec = *(CUtlVector< CBaseEntity* >*)(pBase + pInfo->offset);
if ( !vec.Base() )
return;
if ( index >= vec.Count() )
@@ -1464,13 +1527,15 @@ class CScriptNetPropManager
return vec3_invalid;
}
- if ( index < 0 || (unsigned int)index >= pInfo->arraysize )
+ if ( (unsigned int)index >= pInfo->arraysize )
return vec3_invalid;
+ char *pBase = GetBase( pEnt, pInfo );
+
switch ( pInfo->datatype )
{
case types::_VEC3:
- return *(Vector*)((char*)pEnt + pInfo->GetOffset( index ));
+ return *(Vector*)(pBase + pInfo->GetOffset( index ));
}
return vec3_invalid;
@@ -1491,13 +1556,15 @@ class CScriptNetPropManager
return;
}
- if ( index < 0 || (unsigned int)index >= pInfo->arraysize )
+ if ( (unsigned int)index >= pInfo->arraysize )
return;
+ char *pBase = GetBase( pEnt, pInfo );
+
switch ( pInfo->datatype )
{
case types::_VEC3:
- *(Vector*)((char*)pEnt + pInfo->GetOffset( index )) = value;
+ *(Vector*)(pBase + pInfo->GetOffset( index )) = value;
NetworkStateChanged( pEnt, pInfo->GetOffset( index ) );
break;
}
@@ -1518,21 +1585,23 @@ class CScriptNetPropManager
return NULL;
}
- if ( index < 0 || (unsigned int)index >= pInfo->arraysize )
+ if ( (unsigned int)index >= pInfo->arraysize )
return NULL;
+ char *pBase = GetBase( pEnt, pInfo );
+
switch ( pInfo->datatype )
{
case types::_CSTRING:
- return (const char*)((char*)pEnt + pInfo->GetOffset( index ));
+ return (const char*)(pBase + pInfo->GetOffset( index ));
case types::_STRING_T: // Identical to _CSTRING on client
- return STRING( *(string_t*)((char*)pEnt + pInfo->GetOffset( index )) );
+ return STRING( *(string_t*)(pBase + pInfo->GetOffset( index )) );
case types::_INT8:
{
if ( !pInfo->stringsize )
return NULL;
- char * const pVar = ((char*)pEnt + pInfo->GetOffset( index ));
+ char * const pVar = pBase + pInfo->GetOffset( index );
// Is this null terminated?
int i = 0;
@@ -1550,7 +1619,7 @@ class CScriptNetPropManager
}
#ifdef GAME_DLL
case types::_STDSTRING:
- return ( (std::string*)((char*)pEnt + pInfo->GetOffset( index )) )->c_str();
+ return ( (std::string*)(pBase + pInfo->GetOffset( index )) )->c_str();
#endif
}
@@ -1572,9 +1641,11 @@ class CScriptNetPropManager
return;
}
- if ( index < 0 || (unsigned int)index >= pInfo->arraysize )
+ if ( (unsigned int)index >= pInfo->arraysize )
return;
+ char *pBase = GetBase( pEnt, pInfo );
+
switch ( pInfo->datatype )
{
case types::_CSTRING:
@@ -1582,7 +1653,7 @@ class CScriptNetPropManager
{
if ( pInfo->stringsize )
{
- V_strncpy( (char*)pEnt + pInfo->GetOffset( index ), value, pInfo->stringsize );
+ V_strncpy( pBase + pInfo->GetOffset( index ), value, pInfo->stringsize );
NetworkStateChanged( pEnt, pInfo->GetOffset( index ) );
break;
}
@@ -1596,9 +1667,9 @@ class CScriptNetPropManager
if ( src == NULL_STRING )
src = AllocPooledString( value );
#ifdef GAME_DLL
- *(string_t*)((char*)pEnt + pInfo->GetOffset( index )) = src;
+ *(string_t*)(pBase + pInfo->GetOffset( index )) = src;
#else
- V_strcpy( (char*)pEnt + pInfo->GetOffset( index ), src );
+ V_strcpy( pBase + pInfo->GetOffset( index ), src );
#endif
NetworkStateChanged( pEnt, pInfo->GetOffset( index ) );
break;
@@ -1606,7 +1677,7 @@ class CScriptNetPropManager
#ifdef GAME_DLL
case types::_STDSTRING:
{
- ( (std::string*)((char*)pEnt + pInfo->GetOffset( index )) )->assign( value, V_strlen(value) );
+ ( (std::string*)(pBase + pInfo->GetOffset( index )) )->assign( value, V_strlen(value) );
NetworkStateChanged( pEnt, pInfo->GetOffset( index ) );
break;
}
@@ -1884,7 +1955,6 @@ class CScriptNetPropManager
case DPT_DataTable:
{
NetTable* pArray = pProp->GetDataTable();
- Assert( pArray->GetNumProps() );
if ( V_strcmp( pProp->GetName(), pArray->GetName() ) != 0 )
{
@@ -1893,6 +1963,8 @@ class CScriptNetPropManager
break;
}
+ Assert( pArray->GetNumProps() > 0 && pArray->GetNumProps() <= VARINFO_ARRAYSIZE_MAX );
+
// Double check that each element is the same size
// Array indexing ints gets element size from this
int diff1 = pArray->GetProp(1)->GetOffset() - pArray->GetProp(0)->GetOffset();
@@ -1925,6 +1997,9 @@ class CScriptNetPropManager
NetProp *pArray = pProp->GetArrayProp();
pVar += pArray->GetOffset();
+ Assert( pProp->GetNumElements() > 0 && pProp->GetNumElements() <= VARINFO_ARRAYSIZE_MAX );
+ Assert( pProp->GetElementStride() <= VARINFO_ELEMSIZE_MAX );
+
int numElements = pProp->GetNumElements();
int elementStride = pProp->GetElementStride();
@@ -2210,13 +2285,17 @@ class CScriptNetPropManager
Print("null");
return;
}
+
+ Assert( vec.Count() >= 0 && vec.Count() <= VARINFO_ARRAYSIZE_MAX );
Print("\n%s[", m_indent.Get());
Indent1();
+
FOR_EACH_VEC( vec, i )
{
Print("\n%s", m_indent.Get());
PrintEntity( vec[i] );
}
+
Indent0();
Print("\n%s]", m_indent.Get());
}
@@ -2228,13 +2307,17 @@ class CScriptNetPropManager
Print("null");
return;
}
+
+ Assert( vec.Count() >= 0 && vec.Count() <= VARINFO_ARRAYSIZE_MAX );
Print("\n%s[", m_indent.Get());
Indent1();
+
FOR_EACH_VEC( vec, i )
{
Print("\n%s", m_indent.Get());
Print( "%i", vec[i] );
}
+
Indent0();
Print("\n%s]", m_indent.Get());
}
@@ -2247,13 +2330,17 @@ class CScriptNetPropManager
Print("null");
return;
}
+
+ Assert( vec.Count() >= 0 && vec.Count() <= VARINFO_ARRAYSIZE_MAX );
Print("\n%s[", m_indent.Get());
Indent1();
+
FOR_EACH_VEC( vec, i )
{
Print("\n%s", m_indent.Get());
Print( "%f", vec[i] );
}
+
Indent0();
Print("\n%s]", m_indent.Get());
}
@@ -2265,13 +2352,17 @@ class CScriptNetPropManager
Print("null");
return;
}
+
+ Assert( vec.Count() >= 0 && vec.Count() <= VARINFO_ARRAYSIZE_MAX );
Print("\n%s[", m_indent.Get());
Indent1();
+
FOR_EACH_VEC( vec, i )
{
Print("\n%s", m_indent.Get());
PrintString( vec[i] );
}
+
Indent0();
Print("\n%s]", m_indent.Get());
}
@@ -2283,13 +2374,17 @@ class CScriptNetPropManager
Print("null");
return;
}
+
+ Assert( vec.Count() >= 0 && vec.Count() <= VARINFO_ARRAYSIZE_MAX );
Print("\n%s[", m_indent.Get());
Indent1();
+
FOR_EACH_VEC( vec, i )
{
Print("\n%s", m_indent.Get());
PrintEntity( vec[i] );
}
+
Indent0();
Print("\n%s]", m_indent.Get());
}
@@ -2444,6 +2539,9 @@ class CScriptNetPropManager
}
else
{
+ Assert( td->fieldSize > 0 && td->fieldSize <= VARINFO_ARRAYSIZE_MAX );
+ Assert( td->fieldSizeInBytes / td->fieldSize <= VARINFO_ELEMSIZE_MAX );
+
Print(" <");
PrintFieldType( pVar, td );
Print(" array> #%d", td->fieldSize);
@@ -2492,9 +2590,11 @@ class CScriptNetPropManager
m_output.SetBufferType( true, false );
IndentStart();
+ void *pNetBase = dynamic_cast< CGameRulesProxy* >( pEnt ) ? (void*)GameRules() : (void*)pEnt;
+
Print( "\n" );
Print( "(%s)\n", GetNetTable( GetNetworkClass(pEnt) )->GetName() );
- DumpNetTable_r( pEnt, GetNetTable( GetNetworkClass(pEnt) ) );
+ DumpNetTable_r( pNetBase, GetNetTable( GetNetworkClass(pEnt) ) );
Print( "\n\n" );
Print( "\n" );