From 24f8525fadb1e7ab777cc67d1a83ec65fb4e06a4 Mon Sep 17 00:00:00 2001 From: Alibek Omarov Date: Wed, 22 Jul 2026 20:13:14 +0500 Subject: [PATCH] engine: server: refactoring. --- engine/server/server.h | 19 +++++ engine/server/sv_game.c | 20 +---- engine/server/sv_phys.c | 179 +++++++++++++++++---------------------- engine/server/sv_pmove.c | 11 +-- engine/server/sv_world.c | 25 ++---- 5 files changed, 112 insertions(+), 142 deletions(-) diff --git a/engine/server/server.h b/engine/server/server.h index cb7469ed..21f6f3fc 100644 --- a/engine/server/server.h +++ b/engine/server/server.h @@ -705,4 +705,23 @@ int SV_LightForEntity( edict_t *pEdict ); // void SV_SourceQuery_HandleConnnectionlessPacket( const char *c, netadr_t from, sizebuf_t *msg ); +static inline qboolean SV_CheckGroupOp( int op, int groupinfo, int mask ) +{ + if( op == GROUP_OP_AND && !FBitSet( groupinfo, mask )) + return false; + + if( op == GROUP_OP_NAND && FBitSet( groupinfo, mask )) + return false; + + return true; +} + +static inline qboolean SV_CheckGroupTrace( const edict_t *e1, const edict_t *e2 ) +{ + if( e1->v.groupinfo && e2->v.groupinfo ) + return SV_CheckGroupOp( svs.groupop, e1->v.groupinfo, e2->v.groupinfo ); + + return true; +} + #endif//SERVER_H diff --git a/engine/server/sv_game.c b/engine/server/sv_game.c index c080b4ab..b711dd3a 100644 --- a/engine/server/sv_game.c +++ b/engine/server/sv_game.c @@ -435,14 +435,8 @@ static int SV_Multicast( int dest, const vec3_t origin, const edict_t *ent, qboo if( filter && cl == sv.current_client && FBitSet( sv.current_client->flags, FCL_PREDICT_MOVEMENT )) continue; - if( SV_IsValidEdict( ent ) && ent->v.groupinfo && cl->edict->v.groupinfo ) - { - if( svs.groupop == GROUP_OP_AND && !FBitSet( cl->edict->v.groupinfo, ent->v.groupinfo )) - continue; - - if( svs.groupop == GROUP_OP_NAND && FBitSet( cl->edict->v.groupinfo, ent->v.groupinfo )) - continue; - } + if( SV_IsValidEdict( ent ) && !SV_CheckGroupTrace( ent, cl->edict )) + continue; if( !SV_CheckClientVisiblity( cl, mask )) continue; @@ -4123,14 +4117,8 @@ void GAME_EXPORT SV_PlaybackEventFull( int flags, const edict_t *pInvoker, word if( cl->state != cs_spawned || !cl->edict || FBitSet( cl->flags, FCL_FAKECLIENT )) continue; - if( SV_IsValidEdict( pInvoker ) && pInvoker->v.groupinfo && cl->edict->v.groupinfo ) - { - if( svs.groupop == GROUP_OP_AND && !FBitSet( cl->edict->v.groupinfo, pInvoker->v.groupinfo )) - continue; - - if( svs.groupop == GROUP_OP_NAND && FBitSet( cl->edict->v.groupinfo, pInvoker->v.groupinfo )) - continue; - } + if( SV_IsValidEdict( pInvoker ) && !SV_CheckGroupTrace( pInvoker, cl->edict )) + continue; if( SV_IsValidEdict( pInvoker )) { diff --git a/engine/server/sv_phys.c b/engine/server/sv_phys.c index f43d967d..bfd679b9 100644 --- a/engine/server/sv_phys.c +++ b/engine/server/sv_phys.c @@ -60,6 +60,47 @@ Utility functions =============================================================================== */ +/* +================ +SV_CheckVelocity +================ +*/ +void SV_CheckVelocity( edict_t *ent ) +{ + float wishspd; + float maxspd; + + // bound velocity + for( int i = 0; i < 3; i++ ) + { + if( IS_NAN( ent->v.velocity[i] )) + { + if( sv_check_errors.value ) + Con_Printf( "Got a NaN velocity on %s\n", SV_GetString( ent->v.classname )); + ent->v.velocity[i] = 0.0f; + } + + if( IS_NAN( ent->v.origin[i] )) + { + if( sv_check_errors.value ) + Con_Printf( "Got a NaN origin on %s\n", SV_GetString( ent->v.classname )); + ent->v.origin[i] = 0.0f; + } + } + + wishspd = DotProduct( ent->v.velocity, ent->v.velocity ); + maxspd = sv_maxvelocity.value * sv_maxvelocity.value * 1.73f; // half-diagonal + + if( wishspd > maxspd ) + { + wishspd = sqrt( wishspd ); + if( sv_check_errors.value ) + Con_Printf( "Got a velocity too high on %s ( %.2f > %.2f )\n", SV_GetString( ent->v.classname ), wishspd, sqrt( maxspd )); + wishspd = sv_maxvelocity.value / wishspd; + VectorScale( ent->v.velocity, wishspd, ent->v.velocity ); + } +} + /* ================ SV_CheckAllEnts @@ -110,47 +151,6 @@ static void SV_CheckAllEnts( void ) } } -/* -================ -SV_CheckVelocity -================ -*/ -void SV_CheckVelocity( edict_t *ent ) -{ - float wishspd; - float maxspd; - - // bound velocity - for( int i = 0; i < 3; i++ ) - { - if( IS_NAN( ent->v.velocity[i] )) - { - if( sv_check_errors.value ) - Con_Printf( "Got a NaN velocity on %s\n", SV_GetString( ent->v.classname )); - ent->v.velocity[i] = 0.0f; - } - - if( IS_NAN( ent->v.origin[i] )) - { - if( sv_check_errors.value ) - Con_Printf( "Got a NaN origin on %s\n", SV_GetString( ent->v.classname )); - ent->v.origin[i] = 0.0f; - } - } - - wishspd = DotProduct( ent->v.velocity, ent->v.velocity ); - maxspd = sv_maxvelocity.value * sv_maxvelocity.value * 1.73f; // half-diagonal - - if( wishspd > maxspd ) - { - wishspd = sqrt( wishspd ); - if( sv_check_errors.value ) - Con_Printf( "Got a velocity too high on %s ( %.2f > %.2f )\n", SV_GetString( ent->v.classname ), wishspd, sqrt( maxspd )); - wishspd = sv_maxvelocity.value / wishspd; - VectorScale( ent->v.velocity, wishspd, ent->v.velocity ); - } -} - /* ================ SV_UpdateBaseVelocity @@ -158,26 +158,20 @@ SV_UpdateBaseVelocity */ void SV_UpdateBaseVelocity( edict_t *ent ) { - if( ent->v.flags & FL_ONGROUND ) - { - edict_t *groundentity = ent->v.groundentity; + if( !FBitSet( ent->v.flags, FL_ONGROUND )) + return; - if( SV_IsValidEdict( groundentity )) - { - // On conveyor belt that's moving? - if( groundentity->v.flags & FL_CONVEYOR ) - { - vec3_t new_basevel; + const edict_t *groundentity = ent->v.groundentity; - VectorScale( groundentity->v.movedir, groundentity->v.speed, new_basevel ); - if( ent->v.flags & FL_BASEVELOCITY ) - VectorAdd( new_basevel, ent->v.basevelocity, new_basevel ); + if( !SV_IsValidEdict( groundentity ) || !FBitSet( groundentity->v.flags, FL_CONVEYOR )) + return; - ent->v.flags |= FL_BASEVELOCITY; - VectorCopy( new_basevel, ent->v.basevelocity ); - } - } - } + if( FBitSet( ent->v.flags, FL_BASEVELOCITY )) + VectorMA( ent->v.basevelocity, groundentity->v.speed, groundentity->v.movedir, ent->v.basevelocity ); + else + VectorScale( groundentity->v.movedir, groundentity->v.speed, ent->v.basevelocity ); + + ent->v.flags |= FL_BASEVELOCITY; } /* @@ -189,18 +183,15 @@ returns true if the entity is in solid currently */ static qboolean SV_TestEntityPosition( edict_t *ent, edict_t *blocker ) { - qboolean monsterClip = FBitSet( ent->v.flags, FL_MONSTERCLIP ) ? true : false; - trace_t trace; - if( FBitSet( ent->v.flags, FL_CLIENT|FL_FAKECLIENT )) { // to avoid falling through tracktrain update client mins\maxs here - if( FBitSet( ent->v.flags, FL_DUCKING )) - 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 ); + int hull = FBitSet( ent->v.flags, FL_DUCKING ) ? 1 : 0; + SV_SetMinMaxSize( ent, host.player_mins[hull], host.player_maxs[hull], true ); } - trace = SV_Move( ent->v.origin, ent->v.mins, ent->v.maxs, ent->v.origin, MOVE_NORMAL, ent, monsterClip ); + qboolean monsterClip = FBitSet( ent->v.flags, FL_MONSTERCLIP ) ? true : false; + trace_t trace = SV_Move( ent->v.origin, ent->v.mins, ent->v.maxs, ent->v.origin, MOVE_NORMAL, ent, monsterClip ); if( SV_IsValidEdict( blocker ) && SV_IsValidEdict( trace.ent )) { @@ -212,6 +203,25 @@ static qboolean SV_TestEntityPosition( edict_t *ent, edict_t *blocker ) return trace.startsolid; } +static qboolean SV_TryThink( edict_t *ent, double frametime, double time ) +{ + float thinktime = ent->v.nextthink; + if( thinktime <= 0.0f || thinktime > ( time + frametime )) + return false; + + // don't let things stay in the past. + // it is possible to start that way + // by a trigger with a local time. + if( thinktime < time ) + thinktime = time; + + ent->v.nextthink = 0.0f; + svgame.globals->time = thinktime; + svgame.dllFuncs.pfnThink( ent ); + + return true; +} + /* ============= SV_RunThink @@ -224,21 +234,10 @@ Returns false if the entity removed itself. */ static qboolean SV_RunThink( edict_t *ent ) { - float thinktime; - if( !FBitSet( ent->v.flags, FL_KILLME )) { - thinktime = ent->v.nextthink; - if( thinktime <= 0.0f || thinktime > (sv.time + sv.frametime)) + if( !SV_TryThink( ent, sv.frametime, sv.time )) return true; - - if( thinktime < sv.time ) - thinktime = sv.time; // don't let things stay in the past. - // it is possible to start that way - // by a trigger with a local time. - ent->v.nextthink = 0.0f; - svgame.globals->time = thinktime; - svgame.dllFuncs.pfnThink( ent ); } if( FBitSet( ent->v.flags, FL_KILLME )) @@ -259,25 +258,13 @@ Returns false if the entity removed itself. */ qboolean SV_PlayerRunThink( edict_t *ent, float frametime, double time ) { - float thinktime; - if( svgame.physFuncs.SV_PlayerThink ) return svgame.physFuncs.SV_PlayerThink( ent, frametime, time ); if( !FBitSet( ent->v.flags, FL_KILLME|FL_DORMANT )) { - thinktime = ent->v.nextthink; - if( thinktime <= 0.0f || thinktime > (time + frametime)) + if( !SV_TryThink( ent, frametime, time )) return true; - - if( thinktime < time ) - thinktime = time; // don't let things stay in the past. - // it is possible to start that way - // by a trigger with a local time. - - ent->v.nextthink = 0.0f; - svgame.globals->time = thinktime; - svgame.dllFuncs.pfnThink( ent ); } if( FBitSet( ent->v.flags, FL_KILLME )) @@ -297,17 +284,11 @@ void SV_Impact( edict_t *e1, edict_t *e2, trace_t *trace ) { svgame.globals->time = sv.time; - if(( e1->v.flags|e2->v.flags ) & FL_KILLME ) + if( FBitSet( e1->v.flags|e2->v.flags, FL_KILLME )) return; - if( e1->v.groupinfo && e2->v.groupinfo ) - { - if( svs.groupop == GROUP_OP_AND && !FBitSet( e1->v.groupinfo, e2->v.groupinfo )) - return; - - if( svs.groupop == GROUP_OP_NAND && FBitSet( e1->v.groupinfo, e2->v.groupinfo )) - return; - } + if( !SV_CheckGroupTrace( e1, e2 )) + return; if( e1->v.solid != SOLID_NOT ) { diff --git a/engine/server/sv_pmove.c b/engine/server/sv_pmove.c index e3c5fe10..d3989319 100644 --- a/engine/server/sv_pmove.c +++ b/engine/server/sv_pmove.c @@ -205,10 +205,7 @@ static void SV_AddLinksToPmove( areanode_t *node, const vec3_t pmove_mins, const if( check->v.groupinfo != 0 ) { - if( svs.groupop == GROUP_OP_AND && !FBitSet( check->v.groupinfo, pl->v.groupinfo )) - continue; - - if( svs.groupop == GROUP_OP_NAND && FBitSet( check->v.groupinfo, pl->v.groupinfo )) + if( !SV_CheckGroupOp( svs.groupop, check->v.groupinfo, pl->v.groupinfo )) continue; } @@ -977,9 +974,9 @@ void SV_RunCmd( sv_client_t *cl, usercmd_t *ucmd, int random_seed ) // touch other objects for( int i = 0; i < svgame.pmove->numtouch; i++ ) { - pmtrace_t *pmtrace = &svgame.pmove->touchindex[i]; - edict_t *touch = SV_EdictNum( svgame.pmove->physents[pmtrace->ent].info ); - trace_t trace; + pmtrace_t *pmtrace = &svgame.pmove->touchindex[i]; + edict_t *touch = SV_EdictNum( svgame.pmove->physents[pmtrace->ent].info ); + trace_t trace; VectorCopy( pmtrace->deltavelocity, clent->v.velocity ); PM_ConvertTrace( &trace, pmtrace, touch ); diff --git a/engine/server/sv_world.c b/engine/server/sv_world.c index b110852a..44052a13 100644 --- a/engine/server/sv_world.c +++ b/engine/server/sv_world.c @@ -522,14 +522,8 @@ static void SV_TouchLinks( edict_t *ent, areanode_t *node ) if( touch == ent || touch->v.solid != SOLID_TRIGGER ) // disabled ? continue; - if( touch->v.groupinfo && ent->v.groupinfo ) - { - if( svs.groupop == GROUP_OP_AND && !FBitSet( touch->v.groupinfo, ent->v.groupinfo )) - continue; - - if( svs.groupop == GROUP_OP_NAND && FBitSet( touch->v.groupinfo, ent->v.groupinfo )) - continue; - } + if( !SV_CheckGroupTrace( touch, ent )) + continue; if( !BoundsIntersect( ent->v.absmin, ent->v.absmax, touch->v.absmin, touch->v.absmax )) continue; @@ -725,10 +719,7 @@ static void SV_WaterLinks( const vec3_t origin, int *pCont, areanode_t *node ) if( touch->v.groupinfo ) { - if( svs.groupop == GROUP_OP_AND && !FBitSet( touch->v.groupinfo, svs.groupmask )) - continue; - - if( svs.groupop == GROUP_OP_NAND && FBitSet( touch->v.groupinfo, svs.groupmask )) + if( !SV_CheckGroupOp( svs.groupop, touch->v.groupinfo, svs.groupmask )) continue; } @@ -1101,14 +1092,8 @@ static qboolean SV_ClipToEntity( edict_t *touch, moveclip_t *clip ) trace_t trace; model_t *mod; - if( touch->v.groupinfo && SV_IsValidEdict( clip->passedict ) && clip->passedict->v.groupinfo != 0 ) - { - if( svs.groupop == GROUP_OP_AND && !FBitSet( touch->v.groupinfo, clip->passedict->v.groupinfo )) - return true; - - if( svs.groupop == GROUP_OP_NAND && FBitSet( touch->v.groupinfo, clip->passedict->v.groupinfo )) - return true; - } + if( SV_IsValidEdict( clip->passedict ) && !SV_CheckGroupTrace( touch, clip->passedict )) + return true; if( touch == clip->passedict || touch->v.solid == SOLID_NOT ) return true;