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>
patches
Unified diffs against stock ServUO 57.4 for files the bridge must modify rather than add. Anything that can be shipped as a whole file belongs in overlay/ instead.
Apply from the server root:
git apply --check patches/<name>.patch # dry run
git apply patches/<name>.patch
Phase 7 — player-vendor sale (a coupled unit)
Player-vendor purchases raise no EventSink. ValidVendorPurchase / ValidVendorSell cover NPC vendors only. The commit point is PlayerVendorBuyGump.OnResponse, the only place where buyer, vendor owner, price, and commission are all in scope — exactly what cheat detection needs. See docs/PLAN.md §6.
This is the one non-drop-in piece. Apply all three together:
| Item | Target | What |
|---|---|---|
playervendor-sale-eventsink.patch |
Server/EventSink.cs |
Adds the PlayerVendorSale delegate, PlayerVendorSaleEventArgs { Buyer, Vendor, Owner, Item, Price, Commission }, the event field, and InvokePlayerVendorSale. |
playervendor-sale-gump.patch |
Scripts/Gumps/PlayerVendorGumps.cs |
One InvokePlayerVendorSale(...) call right after the committed HoldGold +=. |
BridgeVendorSale.cs |
copy to Scripts/Custom/Bridge/ |
The subscriber that emits vendor.sale. Not in overlay/ because it references PlayerVendorSaleEventArgs, which does not exist until the EventSink patch is applied — shipping it in overlay would break the build on any unpatched install. |
cd <servuo root>
git apply --check patches/playervendor-sale-eventsink.patch patches/playervendor-sale-gump.patch # dry run
git apply patches/playervendor-sale-eventsink.patch patches/playervendor-sale-gump.patch
cp patches/BridgeVendorSale.cs Scripts/Custom/Bridge/BridgeVendorSale.cs
Both patches are git-format and verified with git apply --check against stock ServUO 57.4. Modifying EventSink.cs means the core rebuilds, so ScriptCompiler's dynamic script build is not enough — rebuild the solution (dotnet build ServUO.sln) or the server binary.
Not applicable to a non-git shard? git apply works in a plain directory too. If patch is used instead, note the core files are CRLF; use patch --binary.
Note on Scripts.csproj
Phase 0 modifies an existing file but ships as a whole-file overlay (overlay/Scripts/Scripts.csproj) because the file is small, we own it operationally, and a copy is less fragile than a diff against a project file. Revisit if it starts drifting from upstream.
Note on shard repairs
The deletions and edits described in docs/SHARD_PREREQS.md are one-time repairs to a specific broken install, not part of the bridge. They are not shipped here.