From 77e9863e9b0519c3a450b1df8b420051818e6004 Mon Sep 17 00:00:00 2001 From: wtclaude Date: Wed, 23 Sep 2026 13:37:05 -0500 Subject: [PATCH] fix(bridge): the raid frame's attackerId comes from userID UserIDString is filled in only when a player connects, loads as a sleeper, or is an engine bot. A player another plugin spawned has none, and the phase-10 walk's raid arrived with attackerId null. The website skips the raid alert when the attacker is authorised on the cupboard, so a null would quietly defeat that exclusion. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01E14m6SuuY6i1vASFeGDBeY --- overlay/oxide/plugins/RunicGateway.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/overlay/oxide/plugins/RunicGateway.cs b/overlay/oxide/plugins/RunicGateway.cs index 6c7560c..4083667 100644 --- a/overlay/oxide/plugins/RunicGateway.cs +++ b/overlay/oxide/plugins/RunicGateway.cs @@ -1446,7 +1446,12 @@ namespace Oxide.Plugins frame["ownerId"] = entity.OwnerID.ToString(); frame["prefab"] = entity.ShortPrefabName; frame["structure"] = structure; - frame["attackerId"] = attacker.UserIDString; + + // From `userID`, not `UserIDString`. The string is filled in when a player connects, + // loads as a sleeper, or is an engine bot — and at no other time, so a player another + // plugin spawned carries none. The website skips the raid alert when the attacker is + // authorised on the cupboard (PLAN.md D59), and a null here would quietly defeat that. + frame["attackerId"] = ((ulong)attacker.userID).ToString(); frame["attackerName"] = attacker.displayName; string grid = GridOf(entity);