From 51526948c014bbf40b595f0a5413c0ff934cfc59 Mon Sep 17 00:00:00 2001 From: Alibek Omarov Date: Fri, 20 May 2022 18:09:52 +0300 Subject: [PATCH] engine: server: make PEntityOfEntIndex bug-compatible with GoldSrc Add new undocumented GoldSrc eiface function, PEntityOfEntIndexAllEntities, a bug-free version of PEntityOfEntIndex Ref: https://github.com/ValveSoftware/halflife/issues/2272 --- engine/common/common.h | 1 - engine/eiface.h | 3 +++ engine/server/server.h | 1 - engine/server/sv_game.c | 49 ++++++++++++++++++++++++++--------------- 4 files changed, 34 insertions(+), 20 deletions(-) diff --git a/engine/common/common.h b/engine/common/common.h index 3b6d3277..f96eda0d 100644 --- a/engine/common/common.h +++ b/engine/common/common.h @@ -756,7 +756,6 @@ void pfnDrawSetTextColor( float r, float g, float b ); void pfnDrawConsoleStringLen( const char *pText, int *length, int *height ); void *Cache_Check( poolhandle_t mempool, struct cache_user_s *c ); void COM_TrimSpace( const char *source, char *dest ); -edict_t* pfnPEntityOfEntIndex( int iEntIndex ); void pfnGetModelBounds( model_t *mod, float *mins, float *maxs ); void pfnCVarDirectSet( cvar_t *var, const char *szValue ); int COM_CheckParm( char *parm, char **ppnext ); diff --git a/engine/eiface.h b/engine/eiface.h index 87b21130..e18cdedb 100644 --- a/engine/eiface.h +++ b/engine/eiface.h @@ -278,6 +278,9 @@ typedef struct enginefuncs_s void (*pfnQueryClientCvarValue)( const edict_t *player, const char *cvarName ); void (*pfnQueryClientCvarValue2)( const edict_t *player, const char *cvarName, int requestID ); int (*pfnCheckParm)( char *parm, char **ppnext ); + + // added in 8279 + edict_t* (*pfnPEntityOfEntIndexAllEntities)( int iEntIndex ); } enginefuncs_t; // ONLY ADD NEW FUNCTIONS TO THE END OF THIS STRUCT. INTERFACE VERSION IS FROZEN AT 138 diff --git a/engine/server/server.h b/engine/server/server.h index 2bfd8b18..4775397f 100644 --- a/engine/server/server.h +++ b/engine/server/server.h @@ -628,7 +628,6 @@ void SV_StartSound( edict_t *ent, int chan, const char *sample, float vol, float edict_t *SV_FindGlobalEntity( string_t classname, string_t globalname ); qboolean SV_CreateStaticEntity( struct sizebuf_s *msg, int index ); void SV_SendUserReg( sizebuf_t *msg, sv_user_message_t *user ); -edict_t* pfnPEntityOfEntIndex( int iEntIndex ); int pfnIndexOfEdict( const edict_t *pEdict ); void pfnWriteBytes( const byte *bytes, int count ); void SV_UpdateBaseVelocity( edict_t *ent ); diff --git a/engine/server/sv_game.c b/engine/server/sv_game.c index c3f25eb0..35626d83 100644 --- a/engine/server/sv_game.c +++ b/engine/server/sv_game.c @@ -60,6 +60,21 @@ qboolean SV_CheckEdict( const edict_t *e, const char *file, const int line ) } #endif +static edict_t *SV_PEntityOfEntIndex( const int iEntIndex, const qboolean allentities ) +{ + edict_t *pEdict = EDICT_NUM( iEntIndex ); + qboolean player = allentities ? iEntIndex <= svs.maxclients : iEntIndex < svs.maxclients; + + if( !SV_IsValidEdict( pEdict )) + return NULL; + + if( !player && !pEdict->pvPrivateData ) + return NULL; + + return pEdict; +} + + /* ============= EntvarsDescription @@ -586,7 +601,7 @@ void SV_RestartAmbientSounds( void ) continue; S_StopSound( si->entnum, si->channel, si->name ); - SV_StartSound( pfnPEntityOfEntIndex( si->entnum ), CHAN_STATIC, si->name, si->volume, si->attenuation, 0, si->pitch ); + SV_StartSound( SV_PEntityOfEntIndex( si->entnum, true ), CHAN_STATIC, si->name, si->volume, si->attenuation, 0, si->pitch ); } #if !XASH_DEDICATED // TODO: ??? @@ -640,10 +655,10 @@ void SV_RestartDecals( void ) for( i = 0; i < host.numdecals; i++ ) { entry = &host.decalList[i]; - modelIndex = pfnPEntityOfEntIndex( entry->entityIndex )->v.modelindex; + modelIndex = SV_PEntityOfEntIndex( entry->entityIndex, true )->v.modelindex; // game override - if( SV_RestoreCustomDecal( entry, pfnPEntityOfEntIndex( entry->entityIndex ), false )) + if( SV_RestoreCustomDecal( entry, SV_PEntityOfEntIndex( entry->entityIndex, true ), false )) continue; decalIndex = pfnDecalIndex( entry->name ); @@ -3350,24 +3365,21 @@ pfnPEntityOfEntIndex ============= */ -edict_t *pfnPEntityOfEntIndex( int iEntIndex ) +static edict_t *pfnPEntityOfEntIndex( int iEntIndex ) { - if( iEntIndex >= 0 && iEntIndex < GI->max_edicts ) - { - edict_t *pEdict = EDICT_NUM( iEntIndex ); - - if( !iEntIndex || FBitSet( host.features, ENGINE_QUAKE_COMPATIBLE )) - return pEdict; // just get access to array - - if( SV_IsValidEdict( pEdict ) && pEdict->pvPrivateData ) - return pEdict; + // have to be bug-compatible with GoldSrc in this function + return SV_PEntityOfEntIndex( iEntIndex, false ); +} - // g-cont: world and clients can be acessed even without private data! - if( SV_IsValidEdict( pEdict ) && SV_IsPlayerIndex( iEntIndex )) - return pEdict; - } +/* +============= +pfnPEntityOfEntIndexAllEntities - return NULL; +============= +*/ +static edict_t *pfnPEntityOfEntIndexAllEntities( int iEntIndex ) +{ + return SV_PEntityOfEntIndex( iEntIndex, true ); } /* @@ -4740,6 +4752,7 @@ static enginefuncs_t gEngfuncs = pfnQueryClientCvarValue, pfnQueryClientCvarValue2, COM_CheckParm, + pfnPEntityOfEntIndexAllEntities, }; /*