using System; using Server.Accounting; using Server.Items; using Server.Mobiles; namespace Server.Custom { /// /// Fires PlayerVendorSale with real seeded-vendor data to prove the full chain: the /// EventSink event added by the Phase 7 patch, its args, the subscriber, and the vendor.sale /// JSON. It does NOT exercise the gump call site (that needs a live buyer with a NetState) — /// the hook line is placed at the committed-sale point in PlayerVendorBuyGump.OnResponse and /// is verified by a real in-game purchase. /// /// Test scaffolding. Never deployed. Read-only (invokes an event; changes no world state). /// public static class BridgeVendorSaleProbe { public static void Initialize() { if (Config.Get("Bridge.VendorSaleProbeOnStart", false)) EventSink.ServerStarted += () => Timer.DelayCall(TimeSpan.FromSeconds(4.0), Run); } private static void Run() { try { var vendors = PlayerVendor.PlayerVendors; if (vendors == null || vendors.Count == 0) { Console.WriteLine("[VendorSaleProbe] no player vendors; seed the world first"); return; } // A real seeded vendor, its owner, and one of its actual priced items. PlayerVendor vendor = null; Item item = null; int price = 0; foreach (var v in vendors) { if (v == null || v.Deleted || v.Owner == null || v.Backpack == null) continue; foreach (var it in v.Backpack.Items) { var vi = v.GetVendorItem(it); if (vi != null) { vendor = v; item = it; price = vi.Price; break; } } if (vendor != null) break; } if (vendor == null) { Console.WriteLine("[VendorSaleProbe] no vendor with a priced item found"); return; } // A buyer on a DIFFERENT account than the owner, so buyerAcct != ownerAcct. Mobile buyer = null; foreach (Account a in Accounting.Accounts.GetAccounts()) { if (!a.Username.StartsWith("seed_", StringComparison.Ordinal)) continue; var pm = a[0] as PlayerMobile; if (pm != null && pm != vendor.Owner && !(vendor.Owner != null && vendor.Owner.Account == a)) { buyer = pm; break; } } int commission = 0; if (vendor.IsCommission) commission = (int)(price * (vendor.CommissionPerc / 100)); Console.WriteLine("[VendorSaleProbe] firing PlayerVendorSale: buyer={0} owner={1} item={2} price={3} commission={4}", buyer == null ? "?" : buyer.Name, vendor.Owner == null ? "?" : vendor.Owner.Name, item.GetType().Name, price, commission); EventSink.InvokePlayerVendorSale( new PlayerVendorSaleEventArgs(buyer, vendor, vendor.Owner, item, price, commission)); Console.WriteLine("[VendorSaleProbe] done; watch for vendor.sale"); } catch (Exception ex) { Console.WriteLine("[VendorSaleProbe] FAILED: " + ex); } } } }