I just did some more research and I happened to find something quite interesting.
Originally, from the SDK:
PHP Code:
bool PassServerEntityFilter( const IHandleEntity *pTouch, const IHandleEntity *pPass )
{
if ( !pPass )
return true;
if ( pTouch == pPass )
return false;
const CBaseEntity *pEntTouch = EntityFromEntityHandle( pTouch );
const CBaseEntity *pEntPass = EntityFromEntityHandle( pPass );
if ( !pEntTouch || !pEntPass )
return true;
// don't clip against own missiles
if ( pEntTouch->GetOwnerEntity() == pEntPass )
return false;
// don't clip against owner
if ( pEntPass->GetOwnerEntity() == pEntTouch )
return false;
return true;
}
By simply looking at this, it would seem that returning true will allow the entity from passing through the other. Otherwise, block it from happening.
Translating this into a plugin will result to:
PHP Code:
public MRESReturn PassServerEntityFilter(DHookReturn hReturn, DHookParam hParams)
{
int pTouch = hParams.Get(1);
int pPass = hParams.Get(2);
if (!pPass)
{
hReturn.Value = false;
return MRES_Supercede;
}
if (pTouch != pPass)
{
// From what I've gathered from Ghidra's decompiler, it would seem that either one of these
// entity handle pointers can be null when passed as a parameter onto an SDKCall since the
// result will always be true but only on Linux. Windows, however, does not allow this and
// will most likely result in a crash.
if (IsStaticProp(pTouch) || IsStaticProp(pPass))
{
// This should be false but let's just hope it will prevent entities from phasing through
// walls and falling into an endless void then crashing the server after some time :p
hReturn.Value = true;
return MRES_Supercede;
}
int pEntTouch = GetBaseEntity(pTouch);
int pEntPass = GetBaseEntity(pPass);
if (pEntTouch != -1 && pEntPass != -1)
{
// Windows: 0x20c -> 524
// Linux: 0x220 -> 544
// Both offsets point to "m_hOwnerEntity" property
if (GetEntPropEnt(pEntTouch, Prop_Data, "m_hOwnerEntity") == pEntPass || GetEntPropEnt(pEntPass, Prop_Data, "m_hOwnerEntity") == pEntTouch)
{
hReturn.Value = true;
return MRES_Supercede;
}
// ...
}
else
{
hReturn.Value = false;
}
}
else
{
hReturn.Value = true;
}
return MRES_Supercede;
}
After detouring the function, the logic is somehow inverted for some unknown reason. At least that's what I concluded from how I've seen plugins change the result through the forward.
It really was quite a head scratcher while analyzing this thoroughly. Of course, you can correct me if I made any mistakes. That would help me understand it better and ease the headache I got from this alone.