From 7a469fb481d9bdb62923868f1acdff65d9058e6e Mon Sep 17 00:00:00 2001 From: Alibek Omarov Date: Sun, 21 Jul 2024 11:01:18 +0300 Subject: [PATCH] engine: always use original player hulls for pmove trace, because mods can write invalid data in pmove->player_{mins,maxs} --- engine/client/cl_game.c | 27 +++++++++++++++++++++------ engine/client/cl_pmove.c | 4 ++-- engine/common/common.h | 5 +++++ engine/common/pm_trace.c | 28 ++++++++++++++-------------- engine/server/sv_phys.c | 4 ++-- engine/server/sv_pmove.c | 2 +- 6 files changed, 45 insertions(+), 25 deletions(-) diff --git a/engine/client/cl_game.c b/engine/client/cl_game.c index df2dc0bf..aaab8f83 100644 --- a/engine/client/cl_game.c +++ b/engine/client/cl_game.c @@ -2435,8 +2435,8 @@ static void GAME_EXPORT pfnLocalPlayerBounds( int hull, float *mins, float *maxs { if( hull >= 0 && hull < 4 ) { - if( mins ) VectorCopy( clgame.pmove->player_mins[hull], mins ); - if( maxs ) VectorCopy( clgame.pmove->player_maxs[hull], maxs ); + if( mins ) VectorCopy( host.player_mins[hull], mins ); + if( maxs ) VectorCopy( host.player_maxs[hull], maxs ); } } @@ -2504,9 +2504,17 @@ CL_PushTraceBounds */ static void GAME_EXPORT CL_PushTraceBounds( int hullnum, const float *mins, const float *maxs ) { + if( !host.trace_bounds_pushed ) + { + memcpy( host.player_mins_backup, host.player_mins, sizeof( host.player_mins_backup )); + memcpy( host.player_maxs_backup, host.player_maxs, sizeof( host.player_maxs_backup )); + + host.trace_bounds_pushed = true; + } + hullnum = bound( 0, hullnum, 3 ); - VectorCopy( mins, clgame.pmove->player_mins[hullnum] ); - VectorCopy( maxs, clgame.pmove->player_maxs[hullnum] ); + VectorCopy( mins, host.player_mins[hullnum] ); + VectorCopy( maxs, host.player_maxs[hullnum] ); } /* @@ -2517,8 +2525,15 @@ CL_PopTraceBounds */ static void GAME_EXPORT CL_PopTraceBounds( void ) { - memcpy( clgame.pmove->player_mins, host.player_mins, sizeof( host.player_mins )); - memcpy( clgame.pmove->player_maxs, host.player_maxs, sizeof( host.player_maxs )); + if( !host.trace_bounds_pushed ) + { + Con_Reportf( S_ERROR "%s called without push!\n", __func__ ); + return; + } + + host.trace_bounds_pushed = false; + memcpy( host.player_mins, host.player_mins_backup, sizeof( host.player_mins )); + memcpy( host.player_maxs, host.player_maxs_backup, sizeof( host.player_maxs )); } /* diff --git a/engine/client/cl_pmove.c b/engine/client/cl_pmove.c index e84b648f..e6f36ba7 100644 --- a/engine/client/cl_pmove.c +++ b/engine/client/cl_pmove.c @@ -544,8 +544,8 @@ void GAME_EXPORT CL_SetSolidPlayers( int playernum ) // some fields needs to be override from cls.predicted_players VectorCopy( player->origin, pe->origin ); VectorCopy( player->angles, pe->angles ); - VectorCopy( clgame.pmove->player_mins[player->usehull], pe->mins ); - VectorCopy( clgame.pmove->player_maxs[player->usehull], pe->maxs ); + VectorCopy( host.player_mins[player->usehull], pe->mins ); + VectorCopy( host.player_maxs[player->usehull], pe->maxs ); pe->movetype = player->movetype; pe->solid = player->solid; } diff --git a/engine/common/common.h b/engine/common/common.h index 4f0322fc..ba55a194 100644 --- a/engine/common/common.h +++ b/engine/common/common.h @@ -314,6 +314,11 @@ typedef struct host_parm_s vec3_t player_mins[MAX_MAP_HULLS]; // 4 hulls allowed vec3_t player_maxs[MAX_MAP_HULLS]; // 4 hulls allowed + // for CL_{Push,Pop}TraceBounds + vec3_t player_mins_backup[MAX_MAP_HULLS]; + vec3_t player_maxs_backup[MAX_MAP_HULLS]; + qboolean trace_bounds_pushed; + qboolean allow_console; // allow console in dev-mode or multiplayer game qboolean allow_console_init; // initial value to allow the console qboolean key_overstrike; // key overstrike mode diff --git a/engine/common/pm_trace.c b/engine/common/pm_trace.c index 26d411e7..7b8653ee 100644 --- a/engine/common/pm_trace.c +++ b/engine/common/pm_trace.c @@ -186,7 +186,7 @@ hull_t *PM_HullForBsp( physent_t *pe, playermove_t *pmove, float *offset ) Assert( hull != NULL ); // calculate an offset value to center the origin - VectorSubtract( hull->clip_mins, pmove->player_mins[pmove->usehull], offset ); + VectorSubtract( hull->clip_mins, host.player_mins[pmove->usehull], offset ); VectorAdd( offset, pe->origin, offset ); return hull; @@ -203,7 +203,7 @@ static hull_t *PM_HullForStudio( physent_t *pe, playermove_t *pmove, int *numhit { vec3_t size; - VectorSubtract( pmove->player_maxs[pmove->usehull], pmove->player_mins[pmove->usehull], size ); + VectorSubtract( host.player_maxs[pmove->usehull], host.player_mins[pmove->usehull], size ); VectorScale( size, 0.5f, size ); return Mod_HullForStudio( pe->studiomodel, pe->frame, pe->sequence, pe->angles, pe->origin, size, pe->controller, pe->blending, numhitboxes, NULL ); @@ -379,8 +379,8 @@ pmtrace_t PM_PlayerTraceExt( playermove_t *pmove, vec3_t start, vec3_t end, int if( pe->solid == SOLID_CUSTOM ) { - VectorCopy( pmove->player_mins[pmove->usehull], mins ); - VectorCopy( pmove->player_maxs[pmove->usehull], maxs ); + VectorCopy( host.player_mins[pmove->usehull], mins ); + VectorCopy( host.player_maxs[pmove->usehull], maxs ); VectorClear( offset ); } else if( pe->model ) @@ -401,8 +401,8 @@ pmtrace_t PM_PlayerTraceExt( playermove_t *pmove, vec3_t start, vec3_t end, int } else { - VectorSubtract( pe->mins, pmove->player_maxs[pmove->usehull], mins ); - VectorSubtract( pe->maxs, pmove->player_mins[pmove->usehull], maxs ); + VectorSubtract( pe->mins, host.player_maxs[pmove->usehull], mins ); + VectorSubtract( pe->maxs, host.player_mins[pmove->usehull], maxs ); hull = PM_HullForBox( mins, maxs ); VectorCopy( pe->origin, offset ); @@ -410,8 +410,8 @@ pmtrace_t PM_PlayerTraceExt( playermove_t *pmove, vec3_t start, vec3_t end, int } else { - VectorSubtract( pe->mins, pmove->player_maxs[pmove->usehull], mins ); - VectorSubtract( pe->maxs, pmove->player_mins[pmove->usehull], maxs ); + VectorSubtract( pe->mins, host.player_maxs[pmove->usehull], mins ); + VectorSubtract( pe->maxs, host.player_mins[pmove->usehull], maxs ); hull = PM_HullForBox( mins, maxs ); VectorCopy( pe->origin, offset ); @@ -442,7 +442,7 @@ pmtrace_t PM_PlayerTraceExt( playermove_t *pmove, vec3_t start, vec3_t end, int if( transform_bbox ) { - World_TransformAABB( matrix, pmove->player_mins[pmove->usehull], pmove->player_maxs[pmove->usehull], mins, maxs ); + World_TransformAABB( matrix, host.player_mins[pmove->usehull], host.player_maxs[pmove->usehull], mins, maxs ); VectorSubtract( hull->clip_mins, mins, offset ); // calc new local offset for( j = 0; j < 3; j++ ) @@ -569,8 +569,8 @@ int PM_TestPlayerPosition( playermove_t *pmove, vec3_t pos, pmtrace_t *ptrace, p if( pe->solid == SOLID_CUSTOM ) { - VectorCopy( pmove->player_mins[pmove->usehull], mins ); - VectorCopy( pmove->player_maxs[pmove->usehull], maxs ); + VectorCopy( host.player_mins[pmove->usehull], mins ); + VectorCopy( host.player_maxs[pmove->usehull], maxs ); VectorClear( offset ); } else if( pe->model ) @@ -584,8 +584,8 @@ int PM_TestPlayerPosition( playermove_t *pmove, vec3_t pos, pmtrace_t *ptrace, p } else { - VectorSubtract( pe->mins, pmove->player_maxs[pmove->usehull], mins ); - VectorSubtract( pe->maxs, pmove->player_mins[pmove->usehull], maxs ); + VectorSubtract( pe->mins, host.player_maxs[pmove->usehull], mins ); + VectorSubtract( pe->maxs, host.player_mins[pmove->usehull], maxs ); hull = PM_HullForBox( mins, maxs ); VectorCopy( pe->origin, offset ); @@ -611,7 +611,7 @@ int PM_TestPlayerPosition( playermove_t *pmove, vec3_t pos, pmtrace_t *ptrace, p if( transform_bbox ) { - World_TransformAABB( matrix, pmove->player_mins[pmove->usehull], pmove->player_maxs[pmove->usehull], mins, maxs ); + World_TransformAABB( matrix, host.player_mins[pmove->usehull], host.player_maxs[pmove->usehull], mins, maxs ); VectorSubtract( hull->clip_mins, mins, offset ); // calc new local offset for( j = 0; j < 3; j++ ) diff --git a/engine/server/sv_phys.c b/engine/server/sv_phys.c index d0b0510e..83e1353d 100644 --- a/engine/server/sv_phys.c +++ b/engine/server/sv_phys.c @@ -199,8 +199,8 @@ static qboolean SV_TestEntityPosition( edict_t *ent, edict_t *blocker ) { // to avoid falling through tracktrain update client mins\maxs here if( FBitSet( ent->v.flags, FL_DUCKING )) - SV_SetMinMaxSize( ent, svgame.pmove->player_mins[1], svgame.pmove->player_maxs[1], true ); - else SV_SetMinMaxSize( ent, svgame.pmove->player_mins[0], svgame.pmove->player_maxs[0], true ); + SV_SetMinMaxSize( ent, host.player_mins[1], host.player_maxs[1], true ); + else SV_SetMinMaxSize( ent, host.player_mins[0], host.player_maxs[0], true ); } trace = SV_Move( ent->v.origin, ent->v.mins, ent->v.maxs, ent->v.origin, MOVE_NORMAL, ent, monsterClip ); diff --git a/engine/server/sv_pmove.c b/engine/server/sv_pmove.c index 23ca6625..925bcf04 100644 --- a/engine/server/sv_pmove.c +++ b/engine/server/sv_pmove.c @@ -671,7 +671,7 @@ static void SV_FinishPMove( playermove_t *pmove, sv_client_t *cl ) clent->v.angles[YAW] = clent->v.v_angle[YAW]; } - SV_SetMinMaxSize( clent, pmove->player_mins[pmove->usehull], pmove->player_maxs[pmove->usehull], false ); + SV_SetMinMaxSize( clent, host.player_mins[pmove->usehull], host.player_maxs[pmove->usehull], false ); // all next calls ignore footstep sounds pmove->runfuncs = false;