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
This commit is contained in:
Alibek Omarov 2022-05-20 18:09:52 +03:00 committed by a1batross
parent 10ec32e264
commit 51526948c0
4 changed files with 34 additions and 20 deletions

View File

@ -756,7 +756,6 @@ void pfnDrawSetTextColor( float r, float g, float b );
void pfnDrawConsoleStringLen( const char *pText, int *length, int *height ); void pfnDrawConsoleStringLen( const char *pText, int *length, int *height );
void *Cache_Check( poolhandle_t mempool, struct cache_user_s *c ); void *Cache_Check( poolhandle_t mempool, struct cache_user_s *c );
void COM_TrimSpace( const char *source, char *dest ); void COM_TrimSpace( const char *source, char *dest );
edict_t* pfnPEntityOfEntIndex( int iEntIndex );
void pfnGetModelBounds( model_t *mod, float *mins, float *maxs ); void pfnGetModelBounds( model_t *mod, float *mins, float *maxs );
void pfnCVarDirectSet( cvar_t *var, const char *szValue ); void pfnCVarDirectSet( cvar_t *var, const char *szValue );
int COM_CheckParm( char *parm, char **ppnext ); int COM_CheckParm( char *parm, char **ppnext );

View File

@ -278,6 +278,9 @@ typedef struct enginefuncs_s
void (*pfnQueryClientCvarValue)( const edict_t *player, const char *cvarName ); void (*pfnQueryClientCvarValue)( const edict_t *player, const char *cvarName );
void (*pfnQueryClientCvarValue2)( const edict_t *player, const char *cvarName, int requestID ); void (*pfnQueryClientCvarValue2)( const edict_t *player, const char *cvarName, int requestID );
int (*pfnCheckParm)( char *parm, char **ppnext ); int (*pfnCheckParm)( char *parm, char **ppnext );
// added in 8279
edict_t* (*pfnPEntityOfEntIndexAllEntities)( int iEntIndex );
} enginefuncs_t; } enginefuncs_t;
// ONLY ADD NEW FUNCTIONS TO THE END OF THIS STRUCT. INTERFACE VERSION IS FROZEN AT 138 // ONLY ADD NEW FUNCTIONS TO THE END OF THIS STRUCT. INTERFACE VERSION IS FROZEN AT 138

View File

@ -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 ); edict_t *SV_FindGlobalEntity( string_t classname, string_t globalname );
qboolean SV_CreateStaticEntity( struct sizebuf_s *msg, int index ); qboolean SV_CreateStaticEntity( struct sizebuf_s *msg, int index );
void SV_SendUserReg( sizebuf_t *msg, sv_user_message_t *user ); void SV_SendUserReg( sizebuf_t *msg, sv_user_message_t *user );
edict_t* pfnPEntityOfEntIndex( int iEntIndex );
int pfnIndexOfEdict( const edict_t *pEdict ); int pfnIndexOfEdict( const edict_t *pEdict );
void pfnWriteBytes( const byte *bytes, int count ); void pfnWriteBytes( const byte *bytes, int count );
void SV_UpdateBaseVelocity( edict_t *ent ); void SV_UpdateBaseVelocity( edict_t *ent );

View File

@ -60,6 +60,21 @@ qboolean SV_CheckEdict( const edict_t *e, const char *file, const int line )
} }
#endif #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 EntvarsDescription
@ -586,7 +601,7 @@ void SV_RestartAmbientSounds( void )
continue; continue;
S_StopSound( si->entnum, si->channel, si->name ); 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: ??? #if !XASH_DEDICATED // TODO: ???
@ -640,10 +655,10 @@ void SV_RestartDecals( void )
for( i = 0; i < host.numdecals; i++ ) for( i = 0; i < host.numdecals; i++ )
{ {
entry = &host.decalList[i]; entry = &host.decalList[i];
modelIndex = pfnPEntityOfEntIndex( entry->entityIndex )->v.modelindex; modelIndex = SV_PEntityOfEntIndex( entry->entityIndex, true )->v.modelindex;
// game override // game override
if( SV_RestoreCustomDecal( entry, pfnPEntityOfEntIndex( entry->entityIndex ), false )) if( SV_RestoreCustomDecal( entry, SV_PEntityOfEntIndex( entry->entityIndex, true ), false ))
continue; continue;
decalIndex = pfnDecalIndex( entry->name ); 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 ) // have to be bug-compatible with GoldSrc in this function
{ return SV_PEntityOfEntIndex( iEntIndex, false );
edict_t *pEdict = EDICT_NUM( iEntIndex ); }
if( !iEntIndex || FBitSet( host.features, ENGINE_QUAKE_COMPATIBLE )) /*
return pEdict; // just get access to array =============
pfnPEntityOfEntIndexAllEntities
if( SV_IsValidEdict( pEdict ) && pEdict->pvPrivateData ) =============
return pEdict; */
static edict_t *pfnPEntityOfEntIndexAllEntities( int iEntIndex )
// g-cont: world and clients can be acessed even without private data! {
if( SV_IsValidEdict( pEdict ) && SV_IsPlayerIndex( iEntIndex )) return SV_PEntityOfEntIndex( iEntIndex, true );
return pEdict;
}
return NULL;
} }
/* /*
@ -4740,6 +4752,7 @@ static enginefuncs_t gEngfuncs =
pfnQueryClientCvarValue, pfnQueryClientCvarValue,
pfnQueryClientCvarValue2, pfnQueryClientCvarValue2,
COM_CheckParm, COM_CheckParm,
pfnPEntityOfEntIndexAllEntities,
}; };
/* /*