diff --git a/docs/PROTOCOL_2.md b/docs/PROTOCOL_2.md index 2635c11..0a8c86c 100644 --- a/docs/PROTOCOL_2.md +++ b/docs/PROTOCOL_2.md @@ -1,6 +1,6 @@ # Protocol 2.0 — Provisioning & World-State Streams -**Status:** Part A **built** on branch `feat/protocol2-account-provisioning` (2026-07-17), compiles clean both sides. Part B is design. +**Status:** Parts A + B (phases 1–4) **built and smoke-tested live** on branch `feat/protocol2-account-provisioning` (2026-07-17) — booted ServUO + the real sidecar and exercised every endpoint (see §15). Part B phase 5 (Factions/VvV) deferred by owner decision. **Date:** 2026-07-17 **Codebase:** ServUO 57.4, `C:\Users\colby\Desktop\servuo`, net48 / x64, Expansion **EJ**. **Companion to** [`PLAN.md`](PLAN.md) (read/event plane), [`ADMIN_CONTROLS.md`](ADMIN_CONTROLS.md) (staff write plane), and [`INTEGRATION.md`](INTEGRATION.md) (website API). @@ -446,3 +446,34 @@ Key points, all grounded: | `docs/INTEGRATION.md` | **Extend.** `report.*` events + endpoints; note they supersede the stock FTP/HTML reports and `WebStatus`. | > **Recommendation:** fold this in as **Part B, Phase 6** (after the world-state streams), scoped to skill distribution + staff/page-queue history first. It is low-effort (public methods, existing sweep pattern) and directly answers "get the admin reports onto the site instead of a file" — by tapping the data the engine already computes and never letting it become a file at all. + +--- + +## 15. Smoke test — live run (2026-07-17) + +Deployed the overlay to the ServUO checkout, booted the shard and the real sidecar (protocol 2, `plugin_connected: true`), and exercised every new surface over REST against the live game. All green. + +**Part A — provisioning (through the real shard):** + +| Check | Result | +|-------|--------| +| `POST /accounts/create` (fresh IP) | **200** `account.ok`, account created + linked | +| duplicate name | **409** `account already exists` | +| per-IP cap | shard's real `AccountsPerIp=3` enforced: 3rd from one IP allowed, **4th → 429** `ip account limit reached` | +| loopback IP with `RequireIpForCreate` | **400** `client ip required` (fails closed) | +| `GET /link/{acct}` after create | **200**, linked to the website id | +| `DELETE /link/{acct}` | **200** `unlink`; lookup then **404** | + +**Part B — world-state boards (through the real shard):** + +| Endpoint | Result | +|----------|--------| +| `GET /houses` | **28 houses**, full owner/decay/co-owner/built-on data (shard → `house.update` → board → REST) | +| `GET /governors` | **9 cities**, `governor: null`/`electionPhase: none` on this unseeded world | +| `GET /guilds` | `[]` — no guilds on this world; the sweep ran without error | +| `GET /online` | `count: 0` — headless (no UO client), snapshot emitted and stored | +| `GET /char/{acct}/0` | full profile incl. the new `titles` block | + +**Not exercised (needs a live UO client, not a headless boot):** `presence.online` with real players, `region.enter`, real-time `guild.join`, and `char.vitals`. And `guild.join`/guild board content needs a guild to exist. These are inherent to a clientless smoke test — the board *plumbing* is proven by `/houses`, which uses the identical path. + +**One operational note surfaced:** the boot-time `Dynamic` script recompile **cannot replace `Scripts.dll` while the server is running**, because the Scripts build tries to copy the locked `ServUO.exe` and fails (the `PLAN.md §3` trap). The fix used here: build `Scripts/Scripts.csproj` once with the server **stopped**, then boot — the offline build produces a fresh `Scripts.dll` the boot then loads. Rely on this, not the in-process rebuild, when deploying new bridge code. The shard's world save was left untouched (hard-kill, no autosave), so the test accounts did not persist.