twhl-community / halflife-updated

Half-Life SDK updated to compile under VS2019 and 2022. Check README.md for more information.
Other
382 stars 146 forks source link

Handgrenade explosion can cause a crash when damaging entities through thin walls #186

Closed FreeSlave closed 1 year ago

FreeSlave commented 1 year ago

Add this entity (e.g. to dlls/monsters.cpp)

class CMonsterTest : public CBaseEntity
{
public:
    void Spawn( void );
};
LINK_ENTITY_TO_CLASS( monster_test, CMonsterTest );

void CMonsterTest :: Spawn ( void )
{
    pev->solid = SOLID_SLIDEBOX;
    pev->movetype = MOVETYPE_STEP;

    UTIL_SetSize( pev, Vector( 0, 0, 0 ), Vector( 0, 0, 0 ) );
    SetBits (pev->flags, FL_MONSTER);
}

Load this map explotest.zip. Take a handgrenade and throw one at the box.

For me this produces a crash with following backtrace going into the engine:

#0  0xf6409970 in SV_SingleClipMoveToEntity (ent=0xed9a708c, start=0xffffc530, mins=0xffffc290, maxs=0xffffc29c, end=0xffffc370, trace=0xffffc1e8) at ../engine/world.c:965
#1  0xf640a146 in SV_ClipMoveToEntity (end=<optimized out>, maxs=0xffffc29c, mins=0xffffc290, start=<optimized out>, ent=0xed9a708c) at ../engine/world.c:1089
#2  SV_ClipToLinks (node=0xf6e5b3c0 <sv_areanodes>, clip=0xffffc270) at ../engine/world.c:1230
#3  0xf640ad33 in SV_Move (start=0xffffc530, mins=0xf6596744 <vec3_origin>, maxs=0xf6596744 <vec3_origin>, end=0xffffc4bc, type=0, passedict=0xed9a76d4, monsterClipBrush=false)
    at ../engine/world.c:1461
#4  0xf63cb068 in PF_traceline_Shared (ent=<optimized out>, nomonsters=0, v2=0xffffc4bc, v1=0xffffc530) at ../engine/pr_cmds.c:494
#5  PF_traceline_DLL (v1=0xffffc530, v2=0xffffc4bc, fNoMonsters=0, pentToSkip=0xed9a76d4, ptr=0xffffc4d4) at ../engine/pr_cmds.c:504
#6  0xeff4672e in RadiusDamage(Vector, entvars_s*, entvars_s*, float, float, int, int) () at /home/roman/.local/share/Steam/steamapps/common/Half-Life/hlupdated/dlls/hl.so
#7  0xeff46acd in CBaseMonster::RadiusDamage(entvars_s*, entvars_s*, float, int, int) () at /home/roman/.local/share/Steam/steamapps/common/Half-Life/hlupdated/dlls/hl.so
#8  0xeff713cd in CGrenade::Explode(TraceResult*, int) () at /home/roman/.local/share/Steam/steamapps/common/Half-Life/hlupdated/dlls/hl.so
#9  0xeff717cb in CGrenade::Detonate() () at /home/roman/.local/share/Steam/steamapps/common/Half-Life/hlupdated/dlls/hl.so
#10 0xf63fdedb in SV_RunThink (ent=0xed9a76d4) at ../engine/sv_phys.c:153
#11 SV_Physics_Toss (ent=0xed9a76d4) at ../engine/sv_phys.c:1539
#12 0xf63ff6e8 in SV_Physics () at ../engine/sv_phys.c:2054
#13 0xf63f7236 in SV_Frame () at ../engine/sv_main.c:9355
#14 0xf63b67c6 in _Host_Frame (time=0.0166408736) at ../engine/host.c:1430
#15 0xf63b6c52 in Host_Frame (time=0.0166408736, iState=1, stateInfo=0xffffc8bc) at ../engine/host.c:1548
#16 0xf63e3b04 in CEngine::Frame() (this=0xf65fdaa0 <g_Engine>) at ../engine/sys_engine.cpp:245
#17 0xf63e158b in RunListenServer(void*, char*, char*, char*, IBaseInterface* (*)(char const*, int*), IBaseInterface* (*)(char const*, int*))
    (instance=0x0, basedir=0x804b220 <szBaseDir> "/home/roman/.local/share/Steam/steamapps/common/Half-Life", cmdline=0x8053660 "/home/roman/.local/share/Steam/steamapps/common/Half-Life/hl_linux -game hlupdated", postRestartCmdLineArgs=0x804d360 <main::szNewCommandParams> "", launcherFactory=0x8049350 <CreateInterfaceLocal(char const*, int*)>, filesystemFactory=
    0xf761ed40 <CreateInterface(char const*, int*)>) at ../engine/sys_dll2.cpp:955
#18 0x08048d67 in main(int, char const**) (argc=3, argv=0xffffcaf4) at ../launcher/launcher.cpp:439

If I revert this commit https://github.com/SamVanheer/halflife-updated/commit/078e78766f3782563df5bd262ae0b17168a43b6b the crash doesn't happen.

SamVanheer commented 1 year ago

This crash occurs because you made an entity solid without giving it a model. Take a look here: https://github.com/id-Software/Quake/blob/bf4ac424ce754894ac8f1dae6a3981954bc9852d/QW/server/world.c#L727-L728

If the entity is SOLID_NOT then it's ignored. Otherwise it will be passed along the chain until it gets to SV_SingleClipMoveToEntity which does this:

if ( sv.models[ent->v.modelindex]->type == 3 )
{
  v7 = SV_HullForStudioModel(ent, mins, maxs, offset, &numhulls);
}
else
{
  v7 = SV_HullForEntity(ent, mins, maxs, offset);
  numhulls = 1;
}

Since you have no model it uses the model at index 0 which is null, that's where the crash occurs.

The crash doesn't occur when that change you linked to is reverted because the explosion is placed outside the map, so the explosion can't "see" the entity and can't hit it.

FreeSlave commented 1 year ago

Thanks for clarification. I set invisible sprite as model and it works okay now. Closing issue.