feat(protocol2): house registry board (Part B ph.3)
Overlay BridgeHousing (new): a diff sweep over BaseHouse.AllHouses -> house.update / house.remove (owner, region, location, decay level, co-owners, friends, placement price), complementing the existing house.decay transition feed. HousingSweepSeconds (300s); wired into [bridge reload|sweepnow|status. Stock ServUO has no "for sale" flag, so this is an owner->houses registry; price is the placement value, not a listing. Sidecar: houses board table with upsert/delete/all; main routes house.update/ remove into it; GET /houses served from the store. Docs: INTEGRATION.md house.* events + /houses endpoint; PROTOCOL_2 ph.3 built. Verified: sidecar cargo check clean; overlay compiles in the full ServUO Scripts tree (0 errors, 0 warnings). Live run pending. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -296,6 +296,25 @@ Who's online and where. A population snapshot is polled (`PresenceSweepSeconds`,
|
|||||||
"who":{"serial":"0x1A2B","name":"Darrow","acct":"whitlocktech","player":true},"t":...}
|
"who":{"serial":"0x1A2B","name":"Darrow","acct":"whitlocktech","player":true},"t":...}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
#### Houses (Protocol 2.0)
|
||||||
|
|
||||||
|
The house registry — one row per house, complementing the `house.decay` *transition* feed (§ above). Polled (`HousingSweepSeconds`, default 300s) and diffed like the other boards.
|
||||||
|
|
||||||
|
| kind | fields | notes |
|
||||||
|
|------|--------|-------|
|
||||||
|
| `house.update` | `serial`, `name`, `owner` (actor or null), `coOwners`, `friends`, `region`, `map`, `x`,`y`,`z`, `decay`, `price`, `builtOn`, `lastRefreshed` | A house's owner/region/decay/co-owners changed, or first sight this connection. `decay` is the level name (e.g. `LikeNew`). `price` is the placement value — **stock ServUO has no "for sale" flag**, so this is not a listing. |
|
||||||
|
| `house.remove` | `serial` | The house was demolished or no longer exists. Drop the row. |
|
||||||
|
|
||||||
|
```json
|
||||||
|
{"kind":"house.update","serial":"0x40001234","name":"The Silver Anvil","decay":"LikeNew",
|
||||||
|
"price":432100,"map":"Felucca","x":1420,"y":1631,"z":0,"region":"Britain",
|
||||||
|
"owner":{"serial":"0x1A2B","name":"Darrow","acct":"whitlocktech","player":true},
|
||||||
|
"coOwners":2,"friends":5,"builtOn":"2026-01-02T00:00:00Z","lastRefreshed":"2026-07-10T00:00:00Z",
|
||||||
|
"t":1752489280000}
|
||||||
|
```
|
||||||
|
|
||||||
|
Render from `GET /houses` (§6) on connect, then keep live with these events.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 5. REST — read queries
|
## 5. REST — read queries
|
||||||
@@ -602,6 +621,18 @@ GET /online
|
|||||||
|
|
||||||
The current online population — total plus per-facet and per-region breakdowns. The latest `presence.online` snapshot (from SQLite, so it survives a sidecar restart); keep it live with the `presence.online` stream (§4). `count: 0` with empty maps if the shard hasn't reported yet. For the population time series, `GET /history?kind=presence.online`.
|
The current online population — total plus per-facet and per-region breakdowns. The latest `presence.online` snapshot (from SQLite, so it survives a sidecar restart); keep it live with the `presence.online` stream (§4). `count: 0` with empty maps if the shard hasn't reported yet. For the population time series, `GET /history?kind=presence.online`.
|
||||||
|
|
||||||
|
### House registry (Protocol 2.0)
|
||||||
|
|
||||||
|
```
|
||||||
|
GET /houses
|
||||||
|
→ { "houses": [ {"kind":"house.update","serial":"0x40001234","name":"The Silver Anvil",
|
||||||
|
"decay":"LikeNew","price":432100,"map":"Felucca","x":1420,"y":1631,"z":0,"region":"Britain",
|
||||||
|
"owner":{"serial":"0x1A2B","name":"Darrow","acct":"whitlocktech","player":true},
|
||||||
|
"coOwners":2,"friends":5,"builtOn":"...","lastRefreshed":"...","t":...}, ... ] }
|
||||||
|
```
|
||||||
|
|
||||||
|
Every house's latest snapshot — owner→houses map. Served from the sidecar's projection, kept current by the `house.*` stream (§4). Ordered by name. Survives a sidecar restart.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 7. Status codes
|
## 7. Status codes
|
||||||
|
|||||||
@@ -382,7 +382,7 @@ If the website mirrors rosters/links (it does — `store.record_link`), it must
|
|||||||
|
|
||||||
1. ~~**Guilds + governors.**~~ **Built (2026-07-17), compiles clean both sides.** `BridgeSocial.cs` (guild sweep + `JoinGuild` → `guild.update`/`guild.remove`/`guild.join`) and `BridgeGovernance.cs` (city sweep → `city.update`, gated on `CityLoyaltySystem.Enabled`), `GuildSweepSeconds` (60s) / `CitySweepSeconds` (300s) config, both wired into `[bridge reload|sweepnow|status`. Sidecar `guilds`/`governors` board tables + `GET /guilds`, `/governors` served from the store (the §12.2 snapshot rule). Shared `BridgeJson.Actor` writer (serial/name/acct/webId/player). **Deviation from the §10 sketch:** the wire uses full-state `guild.update`/`city.update` upserts (website derives "created"/"governor changed" from the board) rather than discrete `guild.created`/`city.governor` events — this avoids a reconnect re-emit looking like a storm of creations, matching the proven `champ.update` model. *Live end-to-end run still pending.*
|
1. ~~**Guilds + governors.**~~ **Built (2026-07-17), compiles clean both sides.** `BridgeSocial.cs` (guild sweep + `JoinGuild` → `guild.update`/`guild.remove`/`guild.join`) and `BridgeGovernance.cs` (city sweep → `city.update`, gated on `CityLoyaltySystem.Enabled`), `GuildSweepSeconds` (60s) / `CitySweepSeconds` (300s) config, both wired into `[bridge reload|sweepnow|status`. Sidecar `guilds`/`governors` board tables + `GET /guilds`, `/governors` served from the store (the §12.2 snapshot rule). Shared `BridgeJson.Actor` writer (serial/name/acct/webId/player). **Deviation from the §10 sketch:** the wire uses full-state `guild.update`/`city.update` upserts (website derives "created"/"governor changed" from the board) rather than discrete `guild.created`/`city.governor` events — this avoids a reconnect re-emit looking like a storm of creations, matching the proven `champ.update` model. *Live end-to-end run still pending.*
|
||||||
2. ~~**Presence.**~~ **Built (2026-07-17), compiles clean both sides.** `BridgePresence.cs`: a `presence.online` sweep (total + per-facet + per-region, emitted on change) and real-time `region.enter` (`EventSink.OnEnterRegion`, player-filtered). `PresenceSweepSeconds` (30s), wired into `[bridge`. `GET /online` serves the latest snapshot from the event store (population series via `/history?kind=presence.online`). *Live run pending.*
|
2. ~~**Presence.**~~ **Built (2026-07-17), compiles clean both sides.** `BridgePresence.cs`: a `presence.online` sweep (total + per-facet + per-region, emitted on change) and real-time `region.enter` (`EventSink.OnEnterRegion`, player-filtered). `PresenceSweepSeconds` (30s), wired into `[bridge`. `GET /online` serves the latest snapshot from the event store (population series via `/history?kind=presence.online`). *Live run pending.*
|
||||||
3. **Housing registry.** Extend the decay sweep to a full owner→houses list → `GET /houses`. (Selected from the §11 menu. Note: stock ServUO has no "for sale" flag on houses, so the registry is owner→houses; for-sale is dropped.)
|
3. ~~**Housing registry.**~~ **Built (2026-07-17), compiles clean both sides.** `BridgeHousing.cs`: a house sweep over `BaseHouse.AllHouses` → `house.update`/`house.remove` (owner, region, location, decay, co-owners, friends, price), complementing the existing `house.decay` transition feed. `HousingSweepSeconds` (300s), wired into `[bridge`. Sidecar `houses` board + `GET /houses`. (Stock ServUO has no "for sale" flag, so this is owner→houses; `price` is the placement value, not a listing.) *Live run pending.*
|
||||||
4. **Titles.** `char.profile` `titles` block (§10.3) — no new stream, folds into `BridgeProfile`.
|
4. **Titles.** `char.profile` `titles` block (§10.3) — no new stream, folds into `BridgeProfile`.
|
||||||
5. **Factions/VvV** — only after confirming which system the shard runs; stream just the enabled one.
|
5. **Factions/VvV** — only after confirming which system the shard runs; stream just the enabled one.
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user