feat(bridge): RaidableBases — raid.* events, raid.spawn, the raids helper (PLAN_REDESIGNS §11.4)
All checks were successful
PR Checks / plugin-checks (pull_request) Successful in 11s

PLAN_REDESIGNS §11.4 (D202-D208, D386-D390), protocol 14. Spec: docs
rust-link/PROTOCOL.md §20.12.

- RunicGatewayRaids.cs, the raids helper (D168, D204-D207, D387), shipped
  beside the bridge and released with it. Harmony patches on RaidableBases'
  spawn queue Add, OpenEvent and each base's BypassUseOwners(): a run's base
  is tagged at birth, its PvP/NPCs/despawn/lock set on a member-by-member copy
  of its profile (Setup, NPC and DespawnOptions copied again, so the shared
  profile is never touched), PvP also set on the base after OpenEvent; a spot
  checked (own look, then the plugin's area check with its reason, rocks and
  cliffs a warning; then the ocean level, D388, D389) and pasted; one base
  despawned; profiles reloaded under watch. Both editions, every member found
  by name. rgr.status.
- Hello's integrations.raidableBases: edition, the paid spawn call (looked
  for by name, D348), CopyPaste, the plugin's own difficulties (D386), the
  helper, and with it the grid and the profiles.
- raid.started / raid.completed / raid.ended / raid.purchased / raid.locked
  from the lifecycle hooks; the unload trap's completions (no owner, no
  raiders) are neither sent nor counted. The tally's raidsCompleted (Warlord).
- map.live's raids layer, kept by the hooks and seeded from GetAllEvents().
- raid.spawn: with the helper the base is a world registry entry, so
  world.revert / world.owned / world.expired serve it (never-started after
  15 min, raidablebases-unloaded); without it the paid call or rbevent, not
  the run's. raid.check for the editor's advice (D208, D391).
- RaidableBases' profiles in the configuration editor (D205): a virtual
  @data/RaidableBases/Profiles/ path, all-profiles-or-none writes, reloaded by
  the helper and rolled back when a profile does not load.

Compiled on both rigs (Rust 25902425, Oxide 2.0.7830, Carbon 2.0.262) and
driven on both rigs with the paid 3.2.2 and the tier-3 pack through a
throwaway plugin: the pick and spot routes with every setting, a repeat key,
revert, expiry, and a good and a broken profile edit.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01E14m6SuuY6i1vASFeGDBeY
This commit is contained in:
2026-10-16 19:29:02 -05:00
parent 594acb5351
commit e0d6c46850
4 changed files with 3336 additions and 12 deletions

View File

@@ -37,6 +37,7 @@ unauthenticated command channel on the network.
overlay/oxide/plugins/RunicGateway.cs → <server>/oxide/plugins/RunicGateway.cs
overlay/oxide/plugins/RunicGatewayZones.cs → <server>/oxide/plugins/RunicGatewayZones.cs
overlay/oxide/plugins/RunicGatewayDomes.cs → <server>/oxide/plugins/RunicGatewayDomes.cs
overlay/oxide/plugins/RunicGatewayRaids.cs → <server>/oxide/plugins/RunicGatewayRaids.cs
```
`RunicGatewayZones.cs` is the **ZoneManager helper** (docs/modules/rust/PLAN_FIXES.md D181, D182). ZoneManager
@@ -52,6 +53,17 @@ helper patches the first with Harmony and tells the bridge when ZoneDomes has st
domes back without drawing any twice. It is optional: without it the site offers no dome, and says which piece is
missing. `rgd.status` in the server console says whether it patched.
`RunicGatewayRaids.cs` is the **RaidableBases helper** (docs/modules/rust/PLAN_REDESIGNS.md §11.4, D204–D207,
D387). RaidableBases' API spawns nothing and despawns nothing, so an event's base cannot be the event's from the
outside. The helper reaches its internals by reflection and patches its spawn queue, `OpenEvent` and each base's
`BypassUseOwners()` with Harmony: it tags the base a run asked for at birth, applies that spawn's own PvP, NPCs,
despawn time and lock on a copy of its profile, places one at a spot after checking it, despawns that one base at
the run's end, and reloads RaidableBases' profiles when the site edits them. It serves both editions, free and
paid, and reads every difficulty, profile and base name from the installed plugin. It is optional: without it the
bridge still reports raid bases on the feed and the map, and a step can still ask RaidableBases for a base where it
picks, but that base despawns on its own timer, and the site says so. `rgr.status` in the server console says
whether it patched, which edition's spawn call it found, and whether the plugin's spawn grid is built.
Oxide compiles and loads it on the write, and writes `oxide/config/RunicGateway.json` on first load:
```json
@@ -134,6 +146,15 @@ kept when the event ends: Guarded Crate has no way to end one event alone. Witho
is refused, because the crate would land unguarded; and, as for Dangerous Treasures, a framework with
`consolePlugins=False` cannot place one.
nivex's `RaidableBases` is optional, free or paid, and needs `CopyPaste` to paste its bases. Where it is
loaded, a base appearing, being raided, bought or locked to a player reach the site's feed, its map's own
*Raid bases* layer and the *Warlord* title, and an event can spawn one (`raid.spawn`). With
`RunicGatewayRaids.cs` (above) the base is the event's: at a spot or where RaidableBases picks, with its own
settings, despawned when the event ends; and the site can edit RaidableBases' profiles from its configuration
page, reloading them under watch. For up to ten minutes after RaidableBases loads it builds its spawn grid and
refuses every spawn, and a spawn then is answered "not ready". Every difficulty, profile and base name is read
from the installed plugin.
nivex's `ZLevels Remastered` is optional, and the bridge only says whether it is loaded. Its levels are
never read or sent. Its XP boosts are its own permissions (`zlevelsremastered.vip1` to `vip3`), so an
event lends one as it lends any other permission, and it takes effect at once.