using System;
using System.Reflection;
using Server.Accounting;
using Server.Items;
using Server.Mobiles;
namespace Server.Custom
{
///
/// Spawns a reachable, houseless player vendor next to the `tester` character (wttest) and
/// gives tester gold, so the PlayerVendorSale core patch can be exercised by a real in-game
/// purchase. The buyer must be a non-GM — IsOwner() treats any GameMaster+ as the owner of
/// every player vendor, so an Owner-level character can never buy.
///
/// Owner is a seed_000 character, so buyer (wttest) and owner (seed_000) are different
/// accounts — a clean cheat-detection example.
///
/// Test scaffolding. Never deployed. Spawns a mobile and hands out gold; run only on the
/// throwaway seeded world.
///
public static class BridgeVendorTestProbe
{
private static readonly MethodInfo SetVendorItem = typeof(PlayerVendor).GetMethod(
"SetVendorItem",
BindingFlags.Instance | BindingFlags.NonPublic,
null,
new[] { typeof(Item), typeof(int), typeof(string) },
null);
public static void Initialize()
{
if (Config.Get("Bridge.VendorTestOnStart", false))
EventSink.ServerStarted += () => Timer.DelayCall(TimeSpan.FromSeconds(3.0), Run);
}
private static void Run()
{
try
{
var ownerAcct = Accounting.Accounts.GetAccount("seed_000") as Account;
var owner = ownerAcct == null ? null : ownerAcct[0];
var buyerAcct = Accounting.Accounts.GetAccount("wttest") as Account;
var buyer = buyerAcct == null ? null : buyerAcct[0] as PlayerMobile;
if (owner == null || buyer == null)
{
Console.WriteLine("[VendorTest] need seed_000 owner and wttest/tester; not found");
return;
}
// Remove any prior test vendor (e.g. one orphaned on the Internal map).
if (PlayerVendor.PlayerVendors != null)
{
var doomed = new System.Collections.Generic.List();
foreach (var v in PlayerVendor.PlayerVendors)
if (v != null && !v.Deleted && v.ShopName == "Bridge Test Shop")
doomed.Add(v);
foreach (var v in doomed)
v.Delete();
}
// A confirmed-walkable spot where tester was already standing this session, so the
// vendor is on solid ground and reachable. Then force tester's logout location right
// next to it, so tester logs in beside the vendor regardless of where it was.
var map = Map.Trammel;
var loc = new Point3D(3533, 2546, 20); // vendor
buyer.LogoutMap = map;
buyer.LogoutLocation = new Point3D(3532, 2546, 20); // tester appears here
var vendor = new PlayerVendor(owner, null)
{
Name = "test vendor",
ShopName = "Bridge Test Shop"
};
vendor.MoveToWorld(loc, map);
var blade = new Longsword();
vendor.Backpack.DropItem(blade);
if (SetVendorItem != null)
SetVendorItem.Invoke(vendor, new object[] { blade, 100, "a test blade" });
// Make sure tester can afford it.
if (buyer.Backpack != null)
buyer.Backpack.DropItem(new Gold(1000));
Console.WriteLine(
"[VendorTest] spawned '{0}' (owner {1}/seed_000) next to {2}/wttest at {3} on {4}; test blade = 100 gold; gave tester 1000 gold",
vendor.ShopName, owner.Name, buyer.Name, loc, map);
}
catch (Exception ex)
{
Console.WriteLine("[VendorTest] FAILED: " + ex);
}
}
}
}