feat(bridge): protocol 13 with RunicNPC, edge → main (runicnpc 9e step 3, merge 2 of 3) #29
@@ -1,7 +1,7 @@
|
||||
// Runic Gateway Zones — a helper for ZoneManager, shipped beside the Runic Gateway bridge.
|
||||
// Copyright (C) Runic Gateway contributors. GPL-3.0-or-later.
|
||||
//
|
||||
// ONE JOB (docs/modules/rust/PLAN_FIXES.md F12, D168, D181, D182):
|
||||
// ITS FIRST JOB (docs/modules/rust/PLAN_FIXES.md F12, D168, D181, D182):
|
||||
//
|
||||
// ZoneManager counts a player as inside a zone only when the zone's trigger fires on ENTRY. A
|
||||
// zone created, updated or loaded around somebody who is already standing there never fires it,
|
||||
@@ -27,6 +27,17 @@
|
||||
// * **It fixes every zone on the server**, not only the bridge's. That is deliberate: the fault is
|
||||
// ZoneManager's, and it is the same fault for an arena another plugin made.
|
||||
//
|
||||
// A SECOND JOB (RunicNPC stage 9d walk, the org lead's call, 2026-10-07):
|
||||
//
|
||||
// ZoneManager subscribes the hooks that enforce its flags (`OnEntityTakeDamage` for PvpGod and the
|
||||
// other damage flags, `OnEntityBuilt` for NoBuild, and so on) only for the flags some zone had when
|
||||
// ZoneManager loaded, or when a flag is toggled by command. A zone made later through its API —
|
||||
// which is every zone an event opens — never re-subscribes them, so on a server with no such zone
|
||||
// already, an event's PvpGod or NoBuild zone enforces nothing: the 9d walk shot a player dead and
|
||||
// built a foundation inside one. The same postfix that sees every zone made therefore also has
|
||||
// ZoneManager run its own `UpdateHookSubscriptions` on the next tick. ZoneManager decides what to
|
||||
// subscribe; this only asks it to look.
|
||||
//
|
||||
// It is optional. The bridge never depends on it to load: without it — deleted, or loaded but
|
||||
// unable to find what it patches after a ZoneManager update — the bridge scores the zones it made
|
||||
// by `IsPositionInZone` instead (D182), and reports this helper's state at hello so the site can
|
||||
@@ -41,8 +52,8 @@ using UnityEngine;
|
||||
|
||||
namespace Oxide.Plugins
|
||||
{
|
||||
[Info("Runic Gateway Zones", "Runic Gateway", "0.1.0")]
|
||||
[Description("Helper for Runic Gateway: ZoneManager counts players already inside a zone when it is created, updated or loaded.")]
|
||||
[Info("Runic Gateway Zones", "Runic Gateway", "0.2.0")]
|
||||
[Description("Helper for Runic Gateway: ZoneManager counts players already inside a zone when it is created, updated or loaded, and enforces a new zone's flags.")]
|
||||
public class RunicGatewayZones : RustPlugin
|
||||
{
|
||||
private const string HarmonyId = "runicgateway.zones";
|
||||
@@ -61,6 +72,9 @@ namespace Oxide.Plugins
|
||||
private FieldInfo _definition;
|
||||
private PropertyInfo _id;
|
||||
|
||||
/// <summary>ZoneManager's private <c>UpdateHookSubscriptions</c>, or null when this ZoneManager has none (the second job is then off).</summary>
|
||||
private MethodInfo _updateHooks;
|
||||
|
||||
/// <summary>
|
||||
/// What the bridge reads through <see cref="State"/>: <c>patched</c>, <c>unsupported</c>
|
||||
/// (ZoneManager is here but not the shape this helper patches), or <c>no-zonemanager</c>.
|
||||
@@ -134,6 +148,7 @@ namespace Oxide.Plugins
|
||||
MethodInfo initialize = zoneType?.GetMethod("InitializeZone", any);
|
||||
|
||||
_getZone = zmType.GetMethod("GetZoneByID", any, null, new[] { typeof(string) }, null);
|
||||
_updateHooks = zmType.GetMethod("UpdateHookSubscriptions", any, null, Type.EmptyTypes, null);
|
||||
_definition = zoneType?.GetField("definition", any);
|
||||
_id = _definition?.FieldType.GetProperty("Id", any);
|
||||
_enter = zoneType == null
|
||||
@@ -169,10 +184,14 @@ namespace Oxide.Plugins
|
||||
|
||||
_state = "patched";
|
||||
_reason = null;
|
||||
Puts($"patched ZoneManager {_zoneManager.Version}: a zone takes in the players already inside it");
|
||||
Puts($"patched ZoneManager {_zoneManager.Version}: a zone takes in the players already inside it" +
|
||||
(_updateHooks != null ? ", and a new zone's flags are enforced" : ""));
|
||||
if (_updateHooks == null)
|
||||
PrintWarning($"this ZoneManager ({_zoneManager.Version}) has no UpdateHookSubscriptions: a zone made after it loaded may not enforce its flags until ZoneManager reloads");
|
||||
|
||||
// The zones ZoneManager loaded before this helper did were initialised unwatched —
|
||||
// which, at a server start, is all of them. Sweep them once now.
|
||||
RefreshHooks();
|
||||
SweepAll();
|
||||
}
|
||||
|
||||
@@ -258,10 +277,32 @@ namespace Oxide.Plugins
|
||||
var batch = new List<KeyValuePair<string, object>>(_pending);
|
||||
_pending.Clear();
|
||||
|
||||
// The second job first: the hooks that enforce the new zones' flags, then the players.
|
||||
RefreshHooks();
|
||||
|
||||
foreach (KeyValuePair<string, object> entry in batch)
|
||||
Sweep(entry.Key, entry.Value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Main thread. Has ZoneManager subscribe the hooks its zones' flags now need. ZoneManager
|
||||
/// only adds subscriptions here, and subscribing a hook twice is a no-op.
|
||||
/// </summary>
|
||||
private void RefreshHooks()
|
||||
{
|
||||
if (_updateHooks == null || _zoneManager == null)
|
||||
return;
|
||||
|
||||
try
|
||||
{
|
||||
_updateHooks.Invoke(_zoneManager, null);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
PrintWarning($"could not have ZoneManager refresh its hooks: {(ex.InnerException ?? ex).Message}");
|
||||
}
|
||||
}
|
||||
|
||||
private void SweepAll()
|
||||
{
|
||||
var ids = _zoneManager.Call("GetZoneIDs") as string[];
|
||||
@@ -328,7 +369,8 @@ namespace Oxide.Plugins
|
||||
if (arg.Connection != null && !arg.IsAdmin)
|
||||
return;
|
||||
|
||||
arg.ReplyWith($"Runic Gateway Zones {Version}: {_state}{(_reason != null ? $" ({_reason})" : "")}");
|
||||
arg.ReplyWith($"Runic Gateway Zones {Version}: {_state}{(_reason != null ? $" ({_reason})" : "")}" +
|
||||
$"; new zones' flags {(_updateHooks != null ? "enforced" : "NOT refreshed (no UpdateHookSubscriptions)")}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user