Files
link/patches
colby 81d3553492 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>
2026-07-10 15:46:07 -05:00
..

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.