Phase 7: PlayerVendorSale core event + subscriber

The one non-drop-in piece. Player-vendor purchases raise no EventSink, so the
sale is invisible to subscription. Two git-format core patches add a
PlayerVendorSale event and raise it at the committed sale in
PlayerVendorBuyGump.OnResponse (right after HoldGold +=), where buyer, vendor
owner, item, price, and commission are all in scope. The subscriber
BridgeVendorSale emits vendor.sale.

All three are a coupled unit. The subscriber references PlayerVendorSaleEventArgs,
which does not exist until the EventSink patch is applied, so it lives in patches/
not overlay/ -- shipping it in overlay would break the build on any unpatched
install. patches/README.md documents applying the unit; both patches verified
with git apply --check against stock ServUO 57.4. This is the first phase that
rebuilds the core (ServUO.exe), not just Scripts.dll.

vendor.sale carries buyer and vendor-owner accounts, both present and distinct,
which is the pair that flags gold-laundering when they match -- richer than the
ownerless NPC ValidVendor* events, and on a committed sale rather than a
validation stage.

Verified with a probe firing the event on real seeded-vendor data: vendor.sale
emitted with buyerAcct=seed_001, ownerAcct=seed_000, Longsword, price 69819. The
probe proves the event, args, subscriber, and payload; the literal gump call site
firing on a real purchase needs a live buyer with a NetState and is confirmed by
an in-game buy. Evidence in docs/PLAN.md §17.

This completes every phase on the ServUO side. Phases 0-6 are drop-in (overlay/);
7 is patches/. Cheat signals are folded into existing streams (fastwalk, audit,
vendor.sale), not a separate phase. Remaining work is the Rust sidecar.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-10 15:46:07 -05:00
parent b8058094f0
commit 81d3553492
8 changed files with 315 additions and 13 deletions

View File

@@ -12,6 +12,7 @@ These two scripts produced the measured budget in `docs/PLAN.md` §1. They are k
| `BridgeSweepProbe.cs` | `Scripts/Custom/BridgeSweepProbe.cs` | Bumps one seeded house's decay stage after baseline so the decay sweep's transition detection can be observed without waiting a real IDOC stage. Flag: `SweepProbeOnStart`. Pair with short `*SweepSeconds` overrides. |
| `BridgeLinkProbe.cs` | `Scripts/Custom/BridgeLinkProbe.cs` | Triggers `[link` for seed_001 without a client, then saves so the `WebsiteUserId` tag reaches `accounts.xml`. Flag: `LinkProbeOnStart`. Pair with a sidecar that reads the code and sends `link.confirm`. |
| `BridgeCrierProbe.cs` | `Scripts/Custom/BridgeCrierProbe.cs` | Logs the global town-crier entry list every 3s so `towncrier.add` / `remove` can be seen landing in game state. Flag: `CrierProbeOnStart`. |
| `BridgeVendorSaleProbe.cs` | `Scripts/Custom/BridgeVendorSaleProbe.cs` | Fires `PlayerVendorSale` (Phase 7) with real seeded-vendor data so `vendor.sale` can be verified without a live buy. Requires the Phase 7 patches applied. Flag: `VendorSaleProbeOnStart`. |
## Deploy overwrites Bridge.cfg