From 51945f002b8ad272e60149666fbbe1b22c37cba3 Mon Sep 17 00:00:00 2001 From: Alibek Omarov Date: Thu, 23 May 2024 02:06:54 +0300 Subject: [PATCH] engine: server: check for invoker entity when filtering out host client during entities thinking --- engine/server/sv_game.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/engine/server/sv_game.c b/engine/server/sv_game.c index 4eda05e1d5..cc19324f80 100644 --- a/engine/server/sv_game.c +++ b/engine/server/sv_game.c @@ -4182,7 +4182,16 @@ void GAME_EXPORT SV_PlaybackEventFull( int flags, const edict_t *pInvoker, word continue; } - if( FBitSet( flags, FEV_NOTHOST ) && cl == sv.current_client && FBitSet( cl->flags, FCL_LOCAL_WEAPONS )) + // a1ba: GoldSrc never cleans up host_client pointer (similar to sv.current_client) + // so it's always points at some client and in singleplayer this check always succeedes + // in Xash, however, sv.current_client might be reset and set to NULL + // this is especially dangerous when weapons play events in Think functions + // + // IMHO, it doesn't make sense to me to compare it against current client when we have + // invoker edict pointer but to preserve behaviour check for them both + // + // if it breaks some mods, probably sv.current_client semantics must be reworked to match GoldSrc + if( FBitSet( flags, FEV_NOTHOST ) && ( cl == sv.current_client || cl->edict == pInvoker ) && FBitSet( cl->flags, FCL_LOCAL_WEAPONS )) continue; // will be played on client side if( FBitSet( flags, FEV_HOSTONLY ) && cl->edict != pInvoker )