docs(rust): phase 10 as built — protocol 7 and the raid alert
PLAN.md §25.5-25.8: what shipped, the walk that met the criterion on the Oxide rig, the four things the rig found (every generic notice never said which server; attackerId null for a spawned player; a disband roster gone before the disband was read; in-app `subscribers` being everyone), and what is not proven. PROTOCOL.md §13 specifies protocol 7. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01E14m6SuuY6i1vASFeGDBeY
This commit is contained in:
@@ -50,7 +50,7 @@ it is listening without one.
|
||||
|
||||
## 2. Versioning
|
||||
|
||||
The wire version is a single integer — **6** as of first-party clans (§12) — declared in
|
||||
The wire version is a single integer — **7** as of the raid frame (§13) — declared in
|
||||
**four** places that must agree:
|
||||
|
||||
| Where | Repo |
|
||||
@@ -337,6 +337,7 @@ arrives with the phase that needs it, and each is a version bump:
|
||||
- ~~the permission mirror (phase 7)~~ — **protocol 4, §10**
|
||||
- ~~plugin configuration edited from the site (phase 7b)~~ — **protocol 5, §11**
|
||||
- ~~clans, for core's Team provider (phase 9)~~ — **protocol 6, §12**
|
||||
- ~~who lives in a raided base, for the raid alert (phase 10)~~ — **protocol 7, §13**
|
||||
- leases, budgets and the event actions (phases 12-13)
|
||||
- the map image over the asset-bridge shape (phase 14)
|
||||
|
||||
@@ -451,7 +452,7 @@ Every kind protocol 2 defines, and the hook behind it. **`class` is not a field
|
||||
| `player.death` | `OnPlayerDeath` | **presence** | victim, attacker, attackerType, weapon, distance, grid |
|
||||
| `player.chat` | `OnPlayerChat` | **presence** | steamId, name, channel, message |
|
||||
| `player.tally` | *aggregate* — see §8.6 | **presence** | steamId, gathered{}, npcKills, structures |
|
||||
| `entity.destroyed` | `OnEntityDeath` on owned building blocks | **staff** | ownerId, prefab, grid, attacker |
|
||||
| `entity.destroyed` | `OnEntityDeath` on owned building blocks — **and doors, external walls and the cupboard from protocol 7 (§13)** | **staff** | ownerId, prefab, grid, attacker; from protocol 7 also `structure`, `buildingId`, `authorized` |
|
||||
| `player.reported` | `OnPlayerReported` | **staff** | reporter, target, subject, message, type |
|
||||
| `player.banned` / `player.unbanned` | `OnUserBanned` / `OnUserUnbanned` | **staff** | id, name, **ip**, reason |
|
||||
| `player.login.attempt` | `CanUserLogin` *(observed, never answered)* | **staff** | id, name, **ip** |
|
||||
@@ -1196,3 +1197,59 @@ matches a call to a method by its argument types, so neither call reaches it.
|
||||
the bridge's own `rg.hooks` count for `OnClanDisbanded` stayed at the one real disband, with nothing
|
||||
logged. A loosely typed signature (`object, object`) would have filed the plugin's clans as the
|
||||
game's.
|
||||
|
||||
## 13. Protocol 7 — the raid frame names who lives there
|
||||
|
||||
Added in phase 10 ([`PLAN.md`](../modules/rust/PLAN.md) §25). The raid alert goes to the people whose
|
||||
base it was (D59), and protocol 2's `entity.destroyed` could not say who that is: it named the
|
||||
block's **placer** (`ownerId`), which is not the base's owner in any sense a Rust player recognises,
|
||||
and it fired only for `BuildingBlock` — which a door is not. **No new kind and no new route;** one
|
||||
frame widens, and `clan.disbanded` gains its roster.
|
||||
|
||||
### 13.1 `entity.destroyed`, widened
|
||||
|
||||
It now fires, still only when a real (non-NPC) player did it and `OwnerID` is non-zero, for four
|
||||
kinds of entity. The kind travels as `structure`:
|
||||
|
||||
| `structure` | Game type | Notes |
|
||||
|---|---|---|
|
||||
| `block` | `BuildingBlock` | as before; the only kind the `structures` tally counts, so that column keeps its meaning |
|
||||
| `door` | `Door` (an `AnimatedBuildingBlock`, a *sibling* of `BuildingBlock`) | external gates are doors too |
|
||||
| `wall` | `SimpleBuildingBlock` | external walls |
|
||||
| `cupboard` | `BuildingPrivlidge` | the tool cupboard itself; `OnEntityDeath` runs before the kill, so it still reports its own list |
|
||||
|
||||
Two fields are added when the entity resolves to a cupboard (`DecayEntity.GetBuildingPrivilege()`,
|
||||
which goes through the building, or the cupboard itself):
|
||||
|
||||
| Field | Meaning |
|
||||
|---|---|
|
||||
| `buildingId` | the cupboard's network id, as a string — the base's identity, and the raid alert's cooldown subject |
|
||||
| `authorized` | `[{ steamId, online }]` from the cupboard's `authorizedPlayers`, **bounded at 64**; `authorizedTruncated: true` when cut |
|
||||
|
||||
**Both are ABSENT when there is no cupboard**, which is a different answer from an empty list, and
|
||||
the website alerts nobody in that case (D67). `recentGroupMembers` — which also sits on the cupboard
|
||||
— is **not** authorisation: it counts code-lock users toward group upkeep, and it is not sent.
|
||||
|
||||
`attackerId` is now derived from the player's `userID` rather than `UserIDString`, which the game
|
||||
fills in only for a connected player, a loaded sleeper or an engine bot. The website skips the alert
|
||||
when the attacker is on the cupboard (a self-demolish, a teammate), and a null would defeat that.
|
||||
|
||||
The class is unchanged: **staff**. A structure's grid is where somebody lives, and the frame now also
|
||||
names who. It reaches a player only through the raid alert, which is ceilinged `owner` and sent one
|
||||
person at a time.
|
||||
|
||||
### 13.2 `clan.disbanded` carries `members`
|
||||
|
||||
The Steam ids of the clan it ended. The website tells a disbanded clan's members, and by the time it
|
||||
reads the frame the next `clans` board may already have removed the roster from its store — the board
|
||||
is re-sent seconds after the event, and after an outage it is applied before the backlog. The game
|
||||
deletes the clan and walks `Members` to drop each membership, but never empties the list, so it is
|
||||
whole when the hook fires. Bounded by the clan's own member limit.
|
||||
|
||||
### 13.3 The sidecar
|
||||
|
||||
`PROTOCOL_VERSION` becomes 7 and nothing else changes: both frames are `event`s, stored and served as
|
||||
they arrive (§8.1). The bump exists because a website that alerts on `authorized` must not pair with
|
||||
a protocol-6 plugin that never sends it — against one it would read every raid as a base with no
|
||||
cupboard and alert nobody while looking healthy.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user