Hi! I’ve tracked down the cause of the Kicked: RPC Error in PlayerAttack issue in Vanish v2.0.5 when hitting sleeping players.
Problem
When a sleeper is hit, Vanish throws a NullReferenceException insideOnEntityTakeDamage(BaseCombatEntity entity, HitInfo info), which then bubbles up as an RPC error and kicks the attacker.
Root cause
entity.ToPlayer()(or equivalent) can return null in edge cases (sleepers / non-player entities in the damage pipeline).The current code calls
IsInvisible(victim)before checking ifvictimis null.Additionally, aggressively modifying
HitInfo(HitEntity = null, replacingdamageTypes) can break downstream assumptions and trigger RPC kicks.
Problematic order in current code:
BasePlayer attacker = info.InitiatorPlayer;
BasePlayer victim = entity.ToPlayer();
if (!IsInvisible(victim) && !IsInvisible(attacker)) return null;
if (attacker == null) return null;Required fix (exact patch)
Reorder null checks and handle victim safely, and avoid nulling HitEntity:
private object OnEntityTakeDamage(BaseCombatEntity entity, HitInfo info)
{
if (entity == null || info == null) return null;
var attacker = info.InitiatorPlayer;
if (attacker == null) return null;
var victim = entity as BasePlayer; // can be null in edge cases
if (!IsInvisible(attacker) && (victim == null || !IsInvisible(victim)))
return null;
if (IsInvisible(attacker) && HasPerm(attacker.UserIDString, PermDamage))
return null;
info.damageTypes?.ScaleAll(0f);
info.HitMaterial = 0;
info.DoHitEffects = false;
return true;
}
This completely stops the NRE and prevents RPC Error in PlayerAttack when hitting sleepers.
Thanks!