Full Version : Crash Help Please
xmlspawner >>Scripting Support >>Crash Help Please


<< Prev | Next >>

Erica- 04-28-2007
heres the crash
<

ArteGordon- 04-29-2007
looks like you added a new vendor that has invalid items in the inventory.
Look in any new SBvendor scripts in the InternalBuyInfo class for things like

CODE
Server Crash Report
===================

RunUO Version 2.0, Build 2671.42452
Operating System: Microsoft Windows NT 6.0.6000.0
.NET Framework: 2.0.50727.312
Time: 4/28/2007 8:05:28 PM
Mobiles: 4592
Items: 195749
Exception:
System.MissingMethodException: Cannot create an abstract class.
  at System.RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean publicOnly, Boolean noCheck, Boolean& canBeCached, RuntimeMethodHandle& ctor, Boolean& bNeedSecurityCheck)
  at System.RuntimeType.CreateInstanceSlow(Boolean publicOnly, Boolean fillCache)
  at System.RuntimeType.CreateInstanceImpl(Boolean publicOnly, Boolean skipVisibilityChecks, Boolean fillCache)
  at System.Activator.CreateInstance(Type type, Boolean nonPublic)
  at System.Activator.CreateInstance(Type type)
  at Server.Mobiles.GenericBuyInfo.GetEntity() in c:\Program Files\RunUO 2.0 SVN 173\Scripts\Mobiles\Vendors\GenericBuy.cs:line 268
  at Server.Mobiles.GenericBuyInfo.GetDisplayEntity() in c:\Program Files\RunUO 2.0 SVN 173\Scripts\Mobiles\Vendors\GenericBuy.cs:line 150
  at Server.Mobiles.BaseVendor.VendorBuy(Mobile from) in c:\Program Files\RunUO 2.0 SVN 173\Scripts\Mobiles\Vendors\BaseVendor2.cs:line 689
  at Server.ContextMenus.VendorBuyEntry.OnClick() in c:\Program Files\RunUO 2.0 SVN 173\Scripts\Mobiles\Vendors\BaseVendor2.cs:line 1548
  at Server.Network.PacketHandlers.ContextMenuResponse(NetState state, PacketReader pvSrc)
  at Server.Network.PacketHandlers.ExtendedCommand(NetState state, PacketReader pvSrc)
  at Server.Network.MessagePump.HandleReceive(NetState ns)
  at Server.Network.MessagePump.Slice()
  at Server.Core.Main(String[] args)

Clients:
- Count: 1
+ ::ffff:69.245.225.176: (account = fallonova) (mobile = 0xC0B 'Sylvie')
heres script[CODE]using System;
using System.Collections;
using System.Collections.Generic;
using Server.Items;
using Server.Network;
using Server.ContextMenus;
using Server.Mobiles;
using Server.Misc;
using Server.Engines.BulkOrders;
using Server.Regions;
using Server.Factions;

namespace Server.Mobiles
{
public enum VendorShoeType
{
 None,
 Shoes,
 Boots,
 Sandals,
 ThighBoots
}

public abstract class BaseVendor : BaseCreature, IVendor
{
 private const int MaxSell = 500;

 protected abstract ArrayList SBInfos{ get; }

 private ArrayList m_ArmorBuyInfo = new ArrayList();
 private ArrayList m_ArmorSellInfo = new ArrayList();

 private DateTime m_LastRestock;

 public override bool CanTeach{ get{ return true; } }

 public override bool PlayerRangeSensitive{ get{ return true; } }

 public virtual bool IsActiveVendor{ get{ return true; } }
 public virtual bool IsActiveBuyer{ get{ return IsActiveVendor; } } // response to vendor SELL
 public virtual bool IsActiveSeller{ get{ return IsActiveVendor; } } // repsonse to vendor BUY

 public virtual NpcGuild NpcGuild{ get{ return NpcGuild.None; } }

 public virtual bool IsInvulnerable{ get{ return true; } }

 public override bool ShowFameTitle{ get{ return false; } }

 public virtual bool IsValidBulkOrder( Item item )
 {
  return false;
 }

 public virtual Item CreateBulkOrder( Mobile from, bool fromContextMenu )
 {
  return null;
 }

 public virtual bool SupportsBulkOrders( Mobile from )
 {
  return false;
 }

 public virtual TimeSpan GetNextBulkOrder( Mobile from )
 {
  return TimeSpan.Zero;
 }

 public virtual void OnSuccessfulBulkOrderRecieve( Mobile from )
 {
 }

 #region Faction
 public virtual int GetPriceScalar()
 {
  Town town = Town.FromRegion( this.Region );

  if ( town != null )
   return (100 + town.Tax);

  return 100;
 }

 public void UpdateBuyInfo()
 {
  int priceScalar = GetPriceScalar();
 
  IBuyItemInfo[] buyinfo = (IBuyItemInfo[])m_ArmorBuyInfo.ToArray( typeof( IBuyItemInfo ) );

  if ( buyinfo != null )
  {
   foreach ( IBuyItemInfo info in buyinfo )
    info.PriceScalar = priceScalar;
  }
 }
 #endregion

 private class BulkOrderInfoEntry : ContextMenuEntry
 {
  private Mobile m_From;
  private BaseVendor m_Vendor;

  public BulkOrderInfoEntry( Mobile from, BaseVendor vendor ) : base( 6152, 6 )
  {
   m_From = from;
   m_Vendor = vendor;
  }

  public override void OnClick()
  {
   if ( m_Vendor.SupportsBulkOrders( m_From ) )
   {
    TimeSpan ts = m_Vendor.GetNextBulkOrder( m_From );

    int totalSeconds = (int)ts.TotalSeconds;
    int totalHours = (totalSeconds + 3599) / 3600;
    int totalMinutes = (totalSeconds + 59) / 60;

    if ( ((Core.SE ) ? totalMinutes == 0 : totalHours == 0) )
    {
     m_From.SendLocalizedMessage( 1049038 ); // You can get an order now.

     if ( Core.AOS )
     {
      Item bulkOrder = m_Vendor.CreateBulkOrder( m_From, true );

      if ( bulkOrder is LargeBOD )
       m_From.SendGump( new LargeBODAcceptGump( m_From, (LargeBOD)bulkOrder ) );
      else if ( bulkOrder is SmallBOD )
       m_From.SendGump( new SmallBODAcceptGump( m_From, (SmallBOD)bulkOrder ) );
     }
    }
    else
    {
     int oldSpeechHue = m_Vendor.SpeechHue;
     m_Vendor.SpeechHue = 0x3B2;
     
     if( Core.SE )
      m_Vendor.SayTo( m_From, 1072058, totalMinutes.ToString() ); // An offer may be available in about ~1_minutes~ minutes.
     else
      m_Vendor.SayTo( m_From, 1049039, totalHours.ToString() ); // An offer may be available in about ~1_hours~ hours.

     m_Vendor.SpeechHue = oldSpeechHue;
    }
   }
  }
 }

 public BaseVendor( string title ) : base( AIType.AI_Vendor, FightMode.None, 2, 1, 0.5, 2 )
 {
  LoadSBInfo();

  this.Title = title;
  InitBody();
  InitOutfit();

  Container pack;
  //these packs MUST exist, or the client will crash when the packets are sent
  pack = new Backpack();
  pack.Layer = Layer.ShopBuy;
  pack.Movable = false;
  pack.Visible = false;
  AddItem( pack );

  pack = new Backpack();
  pack.Layer = Layer.ShopResale;
  pack.Movable = false;
  pack.Visible = false;
  AddItem( pack );

  m_LastRestock = DateTime.Now;
 }
 
 public BaseVendor( Serial serial ) : base( serial )
 {
 }

 public DateTime LastRestock
 {
  get
  {
   return m_LastRestock;
  }
  set
  {
   m_LastRestock = value;
  }
 }

 public virtual TimeSpan RestockDelay
 {
  get
  {
   return TimeSpan.FromHours( 1 );
  }
 }

 public Container BuyPack
 {
  get
  {
   Container pack = FindItemOnLayer( Layer.ShopBuy ) as Container;

   if ( pack == null )
   {
    pack = new Backpack();
    pack.Layer = Layer.ShopBuy;
    pack.Visible = false;
    AddItem( pack );
   }

   return pack;
  }
 }

 public abstract void InitSBInfo();

 public virtual bool IsTokunoVendor{ get{ return ( Map == Map.Tokuno ); } }

 protected void LoadSBInfo()
 {
  m_LastRestock = DateTime.Now;

  for ( int i = 0; i < m_ArmorBuyInfo.Count; ++i )
  {
   GenericBuyInfo buy = m_ArmorBuyInfo[i] as GenericBuyInfo;

   if ( buy != null )
    buy.DeleteDisplayEntity();
  }

  SBInfos.Clear();

  InitSBInfo();

  m_ArmorBuyInfo.Clear();
  m_ArmorSellInfo.Clear();

  for ( int i = 0; i < SBInfos.Count; i++ )
  {
   SBInfo sbInfo = (SBInfo)SBInfos[i];
   m_ArmorBuyInfo.AddRange( sbInfo.BuyInfo );
   m_ArmorSellInfo.Add( sbInfo.SellInfo );
  }
 }

 public virtual bool GetGender()
 {
  return Utility.RandomBool();
 }

 public virtual void InitBody()
 {
  InitStats( 100, 100, 25 );

  SpeechHue = Utility.RandomDyedHue();
  Hue = Utility.RandomSkinHue();

  if ( IsInvulnerable && !Core.AOS )
   NameHue = 0x35;

  if ( Female = GetGender() )
  {
   Body = 0x191;
   Name = NameList.RandomName( "female" );
  }
  else
  {
   Body = 0x190;
   Name = NameList.RandomName( "male" );
  }
 }

 public virtual int GetRandomHue()
 {
  switch ( Utility.Random( 5 ) )
  {
   default:
   case 0: return Utility.RandomBlueHue();
   case 1: return Utility.RandomGreenHue();
   case 2: return Utility.RandomRedHue();
   case 3: return Utility.RandomYellowHue();
   case 4: return Utility.RandomNeutralHue();
  }
 }

 public virtual int GetShoeHue()
 {
  if ( 0.1 > Utility.RandomDouble() )
   return 0;

  return Utility.RandomNeutralHue();
 }

 public virtual VendorShoeType ShoeType
 {
  get{ return VendorShoeType.Shoes; }
 }

 public virtual int RandomBrightHue()
 {
  if ( 0.1 > Utility.RandomDouble() )
   return Utility.RandomList( 0x62, 0x71 );

  return Utility.RandomList( 0x03, 0x0D, 0x13, 0x1C, 0x21, 0x30, 0x37, 0x3A, 0x44, 0x59 );
 }

 public virtual void CheckMorph()
 {
  if ( CheckGargoyle() )
   return;

  if ( CheckNecromancer() )
   return;
                 //17APR2007 Added Elven Vendor for Heartwood *** START 1/2 ***
                 if (CheckElvenVendor())
                      return;
                 //17APR2007 Added Elven Vendor for Heartwood *** END 1/2 ***

  CheckTokuno();
 }
           //17APR2007 Added Elven Vendor for Heartwood *** START 2/2***
           public virtual bool CheckElvenVendor()
           {
              Map map = this.Map;

              if (!Region.IsPartOf("Heartwood"))
                   return false;
              if ( Body != 605 && Body != 606 )
             
              TurnToElvenVendor();

              return true;
           }

           public virtual void TurnToElvenVendor()
           {
               List<Item> deleteList = new List<Item>();
          for (int i = 0; i < Items.Count; ++i)
          {
              if (Items[i] is BaseClothing )
              deleteList.Add( Items[i] );
          }

          for (int i = 0; i < deleteList.Count; ++i)
                 deleteList[i].Delete();


           if ( Female = GetGender() )
           {
               Body = 606;
               Name = NameList.RandomName("female");
               Female = true;
               Race = Race.Elf;
               Hue = Utility.RandomList( 1154, 371, 798, 803, 283, 723, 993, 2119, 55, 471 );
           }
           else
           {
               Body = 605;
               Name = NameList.RandomName("male");
               Female = false;
               Race = Race.Elf;
               Hue = Utility.RandomList( 1154, 371, 798, 803, 283, 723, 993, 2119, 55, 471  );
           }
           Item hair = new Item( Utility.RandomList( 0x2FD1, 0x2FCF, 0x2FC0, 0x2FC2, 0x2FBF, 0X2FCE ) );
           hair.Hue = Utility.RandomList( 1153, 1175, 1260, 1266, 55, 471, 2119, 993, 723, 283, 803, 708 );


           hair.Layer = Layer.Hair;
           hair.Movable = false;
           AddItem( hair );
           switch (Utility.Random(6))
           {
               case 0: //WoodLand Set
                  {
                       
     AddItem( new Server.Items.WoodlandArms() );
          AddItem( new Server.Items.WoodlandChest() );
     AddItem( new Server.Items.WoodlandGloves() );
     AddItem( new Server.Items.WoodlandGorget() );
          AddItem( new Server.Items.WoodlandLegs() );
     AddItem( new Server.Items.VultureHelm() );
          AddItem( new Server.Items.WoodlandBelt(GetRandomHue() ) );
                    AddItem( new Server.Items.ElvenBoots(GetRandomHue() ) );

                    break;
    }
      case 1: //DarkShirt & Pants & Boots
         {
     AddItem( new Server.Items.ElvenDarkShirt(GetRandomHue() ) );
     AddItem( new Server.Items.ElvenPants(GetRandomHue() ) );
     AddItem( new Server.Items.ElvenBoots(GetRandomHue() ) );
     break;
    }
      case 2: //Shirt & Pants & Boots
    {
     AddItem( new Server.Items.ElvenShirt(GetRandomHue() ) );
     AddItem( new Server.Items.ElvenPants(GetRandomHue() ) );
     AddItem( new Server.Items.ElvenBoots(GetRandomHue() ) );
     break;
    }
      case 3: //Leaf Set
         {
     AddItem( new Server.Items.LeafChest() );
     AddItem( new Server.Items.LeafArms() );
     AddItem( new Server.Items.ElvenBoots(GetRandomHue() ) );
     AddItem( new Server.Items.LeafGloves() );
     AddItem( new Server.Items.LeafGorget() );
     AddItem( new Server.Items.LeafLegs() );

                   break;
    }
                case 4: //Hide Set
         {
     AddItem( new Server.Items.HideChest() );
     AddItem( new Server.Items.HideGloves() );
     AddItem( new Server.Items.HidePauldrons() );
     AddItem( new Server.Items.HideGorget() );
     AddItem( new Server.Items.HidePants() );
     AddItem( new Server.Items.ElvenBoots(GetRandomHue() ) );
     

                   break;
    }

                case 5: //Robe & Boots
    {
      if (Female)
      {
        AddItem( new Server.Items.FemaleElvenRobe(GetRandomHue() ) );
   AddItem( new Server.Items.ElvenBoots(GetRandomHue() ) );
   break;
      }
      else
      {
   AddItem( new Server.Items.MaleElvenRobe(GetRandomHue() ) );
   AddItem( new Server.Items.ElvenBoots(GetRandomHue() ) );
   break;
      }
  }
    }
           }
           //17APR2007 Added Elven Vendor for Heartwood *** END  2/2 ***

 public virtual bool CheckTokuno()
 {
  if ( this.Map != Map.Tokuno )
   return false;

  NameList n;

  if ( Female )
   n = NameList.GetNameList( "tokuno female" );
  else
   n = NameList.GetNameList( "tokuno male" );

  if ( !n.ContainsName( this.Name ) )
   TurnToTokuno();

  return true;
 }

 public virtual void TurnToTokuno()
 {
  if ( Female )
   this.Name = NameList.RandomName( "tokuno female" );
  else
   this.Name = NameList.RandomName( "tokuno male" );
 }

 public virtual bool CheckGargoyle()
 {
  Map map = this.Map;

  if ( map != Map.Ilshenar )
   return false;

  if ( !Region.IsPartOf( "Gargoyle City" ) )
   return false;

  if ( Body != 0x2F6 || (Hue & 0x8000) == 0 )
   TurnToGargoyle();

  return true;
 }

 public virtual bool CheckNecromancer()
 {
  Map map = this.Map;

  if ( map != Map.Malas )
   return false;

  if ( !Region.IsPartOf( "Umbra" ) )
   return false;

  if ( Hue != 0x83E8 )
   TurnToNecromancer();

  return true;
 }

 public override void OnAfterSpawn()
 {
  CheckMorph();
 }

 protected override void OnMapChange( Map oldMap )
 {
  base.OnMapChange( oldMap );

  CheckMorph();

  LoadSBInfo();
 }

 public virtual int GetRandomNecromancerHue()
 {
  switch ( Utility.Random( 20 ) )
  {
   case 0: return 0;
   case 1: return 0x4E9;
   default: return Utility.RandomList( 0x485, 0x497 );
  }
 }

 public virtual void TurnToNecromancer()
 {
  for ( int i = 0; i < this.Items.Count; ++i )
  {
   Item item = this.Items[i];

   if ( item is Hair || item is Beard )
    item.Hue = 0;
   else if ( item is BaseClothing || item is BaseWeapon || item is BaseArmor || item is BaseTool )
    item.Hue = GetRandomNecromancerHue();
  }

  HairHue = 0;
  FacialHairHue = 0;

  Hue = 0x83E8;
 }

 public virtual void TurnToGargoyle()
 {
  for ( int i = 0; i < this.Items.Count; ++i )
  {
   Item item = this.Items[i];

   if ( item is BaseClothing || item is Hair || item is Beard )
    item.Delete();
  }

  HairItemID = 0;
  FacialHairItemID = 0;

  Body = 0x2F6;
  Hue = RandomBrightHue() | 0x8000;
  Name = NameList.RandomName( "gargoyle vendor" );

  CapitalizeTitle();
 }

 public virtual void CapitalizeTitle()
 {
  string title = this.Title;

  if ( title == null )
   return;

  string[] split = title.Split( ' ' );

  for ( int i = 0; i < split.Length; ++i )
  {
   if ( Insensitive.Equals( split[i], "the" ) )
    continue;

   if ( split[i].Length > 1 )
    split[i] = Char.ToUpper( split[i][0] ) + split[i].Substring( 1 );
   else if ( split[i].Length > 0 )
    split[i] = Char.ToUpper( split[i][0] ).ToString();
  }

  this.Title = String.Join( " ", split );
 }

 public virtual int GetHairHue()
 {
  return Utility.RandomHairHue();
 }

 public virtual void InitOutfit()
 {
  switch ( Utility.Random( 3 ) )
  {
   case 0: AddItem( new FancyShirt( GetRandomHue() ) ); break;
   case 1: AddItem( new Doublet( GetRandomHue() ) ); break;
   case 2: AddItem( new Shirt( GetRandomHue() ) ); break;
  }

  switch ( ShoeType )
  {
   case VendorShoeType.Shoes: AddItem( new Shoes( GetShoeHue() ) ); break;
   case VendorShoeType.Boots: AddItem( new Boots( GetShoeHue() ) ); break;
   case VendorShoeType.Sandals: AddItem( new Sandals( GetShoeHue() ) ); break;
   case VendorShoeType.ThighBoots: AddItem( new ThighBoots( GetShoeHue() ) ); break;
  }

  int hairHue = GetHairHue();

  Utility.AssignRandomHair( this, hairHue );
  Utility.AssignRandomFacialHair( this, hairHue );

  if ( Female )
  {
   switch ( Utility.Random( 6 ) )
   {
    case 0: AddItem( new ShortPants( GetRandomHue() ) ); break;
    case 1:
    case 2: AddItem( new Kilt( GetRandomHue() ) ); break;
    case 3:
    case 4:
    case 5: AddItem( new Skirt( GetRandomHue() ) ); break;
   }
  }
  else
  {
   switch ( Utility.Random( 2 ) )
   {
    case 0: AddItem( new LongPants( GetRandomHue() ) ); break;
    case 1: AddItem( new ShortPants( GetRandomHue() ) ); break;
   }
  }

  PackGold( 100, 200 );
 }

 public virtual void Restock()
 {
  m_LastRestock = DateTime.Now;

  IBuyItemInfo[] buyInfo = this.GetBuyInfo();

  foreach ( IBuyItemInfo bii in buyInfo )
   bii.OnRestock();
 }

 private static TimeSpan InventoryDecayTime = TimeSpan.FromHours( 1.0 );

 public virtual void VendorBuy( Mobile from )
 {
  if ( !IsActiveSeller )
   return;

  if ( !from.CheckAlive() )
   return;

  if ( !CheckVendorAccess( from ) )
  {
   Say( 501522 ); // I shall not treat with scum like thee!
   return;
  }

  if ( DateTime.Now - m_LastRestock > RestockDelay )
   Restock();

  UpdateBuyInfo();

  int count = 0;
  ArrayList list;
  IBuyItemInfo[] buyInfo = this.GetBuyInfo();
  IShopSellInfo[] sellInfo = this.GetSellInfo();

  list = new ArrayList( buyInfo.Length );
  Container cont = this.BuyPack;

  List<ObjectPropertyList> opls = null;

  for (int idx=0;idx<buyInfo.Length;idx++)
  {
   IBuyItemInfo buyItem = (IBuyItemInfo)buyInfo[idx];

   if ( buyItem.Amount <= 0 || list.Count >= 250 )
    continue;

   // NOTE: Only GBI supported; if you use another implementation of IBuyItemInfo, this will crash
   GenericBuyInfo gbi = (GenericBuyInfo) buyItem;
   IEntity disp = gbi.GetDisplayEntity();

   list.Add( new BuyItemState( buyItem.Name, cont.Serial, disp == null ? (Serial) 0x7FC0FFEE : disp.Serial, buyItem.Price, buyItem.Amount, buyItem.ItemID, buyItem.Hue ) );
   count++;

   if ( ObjectPropertyList.Enabled ) {
    if ( opls == null ) {
     opls = new List<ObjectPropertyList>();
    }

    if ( disp is Item ) {
     opls.Add( ( ( Item ) disp ).PropertyList );
    } else if ( disp is Mobile ) {
     opls.Add( ( ( Mobile ) disp ).PropertyList );
    }
   }
  }

  List<Item> playerItems = cont.Items;

  for ( int i = playerItems.Count - 1; i >= 0; --i )
  {
   if ( i >= playerItems.Count )
    continue;

   Item item = playerItems[i];

   if ( (item.LastMoved + InventoryDecayTime) <= DateTime.Now )
    item.Delete();
  }

  for ( int i = 0; i < playerItems.Count; ++i )
  {
   Item item = playerItems[i];

   int price = 0;
   string name = null;

   foreach( IShopSellInfo ssi in sellInfo )
   {
    if ( ssi.IsSellable( item ) )
    {
     price = ssi.GetBuyPriceFor( item );
     name = ssi.GetNameFor( item );
     break;
    }
   }

   if ( name != null && list.Count < 250 )
   {
    list.Add( new BuyItemState( name, cont.Serial, item.Serial, price, item.Amount, item.ItemID, item.Hue ) );
    count++;

    if ( ObjectPropertyList.Enabled ) {
     if ( opls == null ) {
      opls = new List<ObjectPropertyList>();
     }

     opls.Add( item.PropertyList );
    }
   }
  }

  //one (not all) of the packets uses a byte to describe number of items in the list.  Osi = dumb.
  //if ( list.Count > 255 )
  // Console.WriteLine( "Vendor Warning: Vendor {0} has more than 255 buy items, may cause client errors!", this );

  if ( list.Count > 0 )
  {
   list.Sort( new BuyItemStateComparer() );

   SendPacksTo( from );
   
   from.Send( new VendorBuyContent( list ) );
   from.Send( new VendorBuyList( this, list ) );
   from.Send( new DisplayBuyList( this ) );
   from.Send( new MobileStatusExtended( from ) );//make sure their gold amount is sent

   if ( ObjectPropertyList.Enabled && opls != null ) {
    for ( int i = 0; i < opls.Count; ++i ) {
     from.Send( opls[i] );
    }
   }

   SayTo( from, 500186 ); // Greetings.  Have a look around.
  }
 }

 public virtual void SendPacksTo( Mobile from )
 {
  Item pack = FindItemOnLayer( Layer.ShopBuy );

  if ( pack == null )
  {
   pack = new Backpack();
   pack.Layer = Layer.ShopBuy;
   pack.Movable = false;
   pack.Visible = false;
   AddItem( pack );
  }

  from.Send( new EquipUpdate( pack ) );

  pack = FindItemOnLayer( Layer.ShopSell );

  if ( pack != null )
   from.Send( new EquipUpdate( pack ) );

  pack = FindItemOnLayer( Layer.ShopResale );

  if ( pack == null )
  {
   pack = new Backpack();
   pack.Layer = Layer.ShopResale;
   pack.Movable = false;
   pack.Visible = false;
   AddItem( pack );
  }

  from.Send( new EquipUpdate( pack ) );
 }

 public virtual void VendorSell( Mobile from )
 {
  if ( !IsActiveBuyer )
   return;

  if ( !from.CheckAlive() )
   return;

  if ( !CheckVendorAccess( from ) )
  {
   Say( 501522 ); // I shall not treat with scum like thee!
   return;
  }

  Container pack = from.Backpack;

  if ( pack != null )
  {
   IShopSellInfo[] info = GetSellInfo();

   Hashtable table = new Hashtable();

   foreach ( IShopSellInfo ssi in info )
   {
    Item[] items = pack.FindItemsByType( ssi.Types );

    foreach ( Item item in items )
    {
     if ( item is Container && ((Container)item).Items.Count != 0 )
      continue;

     if ( item.IsStandardLoot() && item.Movable && ssi.IsSellable( item ) )
      table[item] = new SellItemState( item, ssi.GetSellPriceFor( item ), ssi.GetNameFor( item ) );
    }
   }

   if ( table.Count > 0 )
   {
    SendPacksTo( from );

    from.Send( new VendorSellList( this, table ) );
   }
   else
   {
    Say( true, "You have nothing I would be interested in." );
   }
  }
 }

 public override bool OnDragDrop( Mobile from, Item dropped )
 {
  if ( dropped is SmallBOD || dropped is LargeBOD )
  {
   if ( !IsValidBulkOrder( dropped ) || !SupportsBulkOrders( from ) )
   {
    SayTo( from, 1045130 ); // That order is for some other shopkeeper.
    return false;
   }
   else if ( (dropped is SmallBOD && !((SmallBOD)dropped).Complete) || (dropped is LargeBOD && !((LargeBOD)dropped).Complete) )
   {
    SayTo( from, 1045131 ); // You have not completed the order yet.
    return false;
   }

   Item reward;
   int gold, fame;

   if ( dropped is SmallBOD )
    ((SmallBOD)dropped).GetRewards( out reward, out gold, out fame );
   else
    ((LargeBOD)dropped).GetRewards( out reward, out gold, out fame );

   from.SendSound( 0x3D );

   SayTo( from, 1045132 ); // Thank you so much!  Here is a reward for your effort.

   if ( reward != null )
    from.AddToBackpack( reward );

   if ( gold > 1000 )
    from.AddToBackpack( new BankCheck( gold ) );
   else if ( gold > 0 )
    from.AddToBackpack( new Gold( gold ) );

   Titles.AwardFame( from, fame, true );

   OnSuccessfulBulkOrderRecieve( from );

   dropped.Delete();
   return true;
  }

  return base.OnDragDrop( from, dropped );
 }

 private GenericBuyInfo LookupDisplayObject( object obj )
 {
  IBuyItemInfo[] buyInfo = this.GetBuyInfo();

  for ( int i = 0; i < buyInfo.Length; ++i ) {
   GenericBuyInfo gbi = (GenericBuyInfo)buyInfo[i];

   if ( gbi.GetDisplayEntity() == obj )
    return gbi;
  }

  return null;
 }

 private void ProcessSinglePurchase( BuyItemResponse buy, IBuyItemInfo bii, ArrayList validBuy, ref int controlSlots, ref bool fullPurchase, ref int totalCost )
 {
  int amount = buy.Amount;

  if ( amount > bii.Amount )
   amount = bii.Amount;

  if ( amount <= 0 )
   return;

  int slots = bii.ControlSlots * amount;

  if ( controlSlots >= slots )
  {
   controlSlots -= slots;
  }
  else
  {
   fullPurchase = false;
   return;
  }

  totalCost += bii.Price * amount;
  validBuy.Add( buy );
 }

 private void ProcessValidPurchase( int amount, IBuyItemInfo bii, Mobile buyer, Container cont )
 {
  if ( amount > bii.Amount )
   amount = bii.Amount;

  if ( amount < 1 )
   return;

  bii.Amount -= amount;

  IEntity o = bii.GetEntity();

  if ( o is Item )
  {
   Item item = (Item)o;

   if ( item.Stackable )
   {
    item.Amount = amount;

    if ( cont == null || !cont.TryDropItem( buyer, item, false ) )
     item.MoveToWorld( buyer.Location, buyer.Map );
   }
   else
   {
    item.Amount = 1;

    if ( cont == null || !cont.TryDropItem( buyer, item, false ) )
     item.MoveToWorld( buyer.Location, buyer.Map );

    for (int i=1;i<amount;i++)
    {
     item = bii.GetEntity() as Item;

     if ( item != null )
     {
      item.Amount = 1;

      if ( cont == null || !cont.TryDropItem( buyer, item, false ) )
       item.MoveToWorld( buyer.Location, buyer.Map );
     }
    }
   }
  }
  else if ( o is Mobile )
  {
   Mobile m = (Mobile)o;

   m.Direction = (Direction)Utility.Random( 8 );
   m.MoveToWorld( buyer.Location, buyer.Map );
   m.PlaySound( m.GetIdleSound() );

   if ( m is BaseCreature )
    ((BaseCreature)m).SetControlMaster( buyer );

   for ( int i = 1; i < amount; ++i )
   {
    m = bii.GetEntity() as Mobile;

    if ( m != null )
    {
     m.Direction = (Direction)Utility.Random( 8 );
     m.MoveToWorld( buyer.Location, buyer.Map );

     if ( m is BaseCreature )
      ((BaseCreature)m).SetControlMaster( buyer );
    }
   }
  }
 }

 public virtual bool OnBuyItems( Mobile buyer, ArrayList list )
 {
  if ( !IsActiveSeller )
   return false;

  if ( !buyer.CheckAlive() )
   return false;

  if ( !CheckVendorAccess( buyer ) )
  {
   Say( 501522 ); // I shall not treat with scum like thee!
   return false;
  }

  UpdateBuyInfo();

  IBuyItemInfo[] buyInfo = this.GetBuyInfo();
  IShopSellInfo[] info = GetSellInfo();
  int totalCost = 0;
  ArrayList validBuy = new ArrayList( list.Count );
  Container cont;
  bool bought = false;
  bool fromBank = false;
  bool fullPurchase = true;
  int controlSlots = buyer.FollowersMax - buyer.Followers;

  foreach ( BuyItemResponse buy in list )
  {
   Serial ser = buy.Serial;
   int amount = buy.Amount;

   if ( ser.IsItem )
   {
    Item item = World.FindItem( ser );

    if ( item == null )
     continue;

    GenericBuyInfo gbi = LookupDisplayObject( item );

    if ( gbi != null )
    {
     ProcessSinglePurchase( buy, gbi, validBuy, ref controlSlots, ref fullPurchase, ref totalCost );
    }
    else if ( item.RootParent == this )
    {
     if ( amount > item.Amount )
      amount = item.Amount;

     if ( amount <= 0 )
      continue;

     foreach ( IShopSellInfo ssi in info )
     {
      if ( ssi.IsSellable( item ) )
      {
       if ( ssi.IsResellable( item ) )
       {
        totalCost += ssi.GetBuyPriceFor( item ) * amount;
        validBuy.Add( buy );
        break;
       }
      }
     }
    }
   }
   else if ( ser.IsMobile )
   {
    Mobile mob = World.FindMobile( ser );

    if ( mob == null )
     continue;

    GenericBuyInfo gbi = LookupDisplayObject( mob );

    if ( gbi != null )
     ProcessSinglePurchase( buy, gbi, validBuy, ref controlSlots, ref fullPurchase, ref totalCost );
   }
  }//foreach

  if ( fullPurchase && validBuy.Count == 0 )
   SayTo( buyer, 500190 ); // Thou hast bought nothing!
  else if ( validBuy.Count == 0 )
   SayTo( buyer, 500187 ); // Your order cannot be fulfilled, please try again.

  if ( validBuy.Count == 0 )
   return false;

  bought = ( buyer.AccessLevel >= AccessLevel.GameMaster );

  cont = buyer.Backpack;
  if ( !bought && cont != null )
  {
   if ( cont.ConsumeTotal( typeof( Gold ), totalCost ) )
    bought = true;
   else if ( totalCost < 2000 )
    SayTo( buyer, 500192 );//Begging thy pardon, but thou casnt afford that.
  }

  if ( !bought && totalCost >= 2000 )
  {
   cont = buyer.FindBankNoCreate();
   if ( cont != null && cont.ConsumeTotal( typeof( Gold ), totalCost ) )
   {
    bought = true;
    fromBank = true;
   }
   else
   {
    SayTo( buyer, 500191 ); //Begging thy pardon, but thy bank account lacks these funds.
   }
  }

  if ( !bought )
   return false;
  else
   buyer.PlaySound( 0x32 );

  cont = buyer.Backpack;
  if ( cont == null )
   cont = buyer.BankBox;

  foreach ( BuyItemResponse buy in validBuy )
  {
   Serial ser = buy.Serial;
   int amount = buy.Amount;

   if ( amount < 1 )
    continue;

   if ( ser.IsItem )
   {
    Item item = World.FindItem( ser );

    if ( item == null )
     continue;

    GenericBuyInfo gbi = LookupDisplayObject( item );

    if ( gbi != null )
    {
     ProcessValidPurchase( amount, gbi, buyer, cont );
    }
    else
    {
     if ( amount > item.Amount )
      amount = item.Amount;

     foreach ( IShopSellInfo ssi in info )
     {
      if ( ssi.IsSellable( item ) )
      {
       if ( ssi.IsResellable( item ) )
       {
        Item buyItem;
        if ( amount >= item.Amount )
        {
         buyItem = item;
        }
        else
        {
         buyItem = Mobile.LiftItemDupe( item, item.Amount - amount );

         if ( buyItem == null )
          buyItem = item;
        }

        if ( cont == null || !cont.TryDropItem( buyer, buyItem, false ) )
         buyItem.MoveToWorld( buyer.Location, buyer.Map );

        break;
       }
      }
     }
    }
   }
   else if ( ser.IsMobile )
   {
    Mobile mob = World.FindMobile( ser );

    if ( mob == null )
     continue;

    GenericBuyInfo gbi = LookupDisplayObject( mob );

    if ( gbi != null )
     ProcessValidPurchase( amount, gbi, buyer, cont );
   }
  }//foreach

  if ( fullPurchase )
  {
   if ( buyer.AccessLevel >= AccessLevel.GameMaster )
    SayTo( buyer, true, "I would not presume to charge thee anything.  Here are the goods you requested." );
   else if ( fromBank )
    SayTo( buyer, true, "The total of thy purchase is {0} gold, which has been withdrawn from your bank account.  My thanks for the patronage.", totalCost );
   else
    SayTo( buyer, true, "The total of thy purchase is {0} gold.  My thanks for the patronage.", totalCost );
  }
  else
  {
   if ( buyer.AccessLevel >= AccessLevel.GameMaster )
    SayTo( buyer, true, "I would not presume to charge thee anything.  Unfortunately, I could not sell you all the goods you requested." );
   else if ( fromBank )
    SayTo( buyer, true, "The total of thy purchase is {0} gold, which has been withdrawn from your bank account.  My thanks for the patronage.  Unfortunately, I could not sell you all the goods you requested.", totalCost );
   else
    SayTo( buyer, true, "The total of thy purchase is {0} gold.  My thanks for the patronage.  Unfortunately, I could not sell you all the goods you requested.", totalCost );
  }

  return true;
 }

 public virtual bool CheckVendorAccess( Mobile from )
 {
  GuardedRegion reg = (GuardedRegion) this.Region.GetRegion( typeof( GuardedRegion ) );

  if ( reg != null && !reg.CheckVendorAccess( this, from ) )
   return false;

  if ( this.Region != from.Region )
  {
   reg = (GuardedRegion) from.Region.GetRegion( typeof( GuardedRegion ) );

   if ( reg != null && !reg.CheckVendorAccess( this, from ) )
    return false;
  }

  return true;
 }

 public virtual bool OnSellItems( Mobile seller, ArrayList list )
 {
  if ( !IsActiveBuyer )
   return false;

  if ( !seller.CheckAlive() )
   return false;

  if ( !CheckVendorAccess( seller ) )
  {
   Say( 501522 ); // I shall not treat with scum like thee!
   return false;
  }

  seller.PlaySound( 0x32 );

  IShopSellInfo[] info = GetSellInfo();
  IBuyItemInfo[] buyInfo = this.GetBuyInfo();
  int GiveGold = 0;
  int Sold = 0;
  Container cont;
  ArrayList delete = new ArrayList();
  ArrayList drop = new ArrayList();

  foreach ( SellItemResponse resp in list )
  {
   if ( resp.Item.RootParent != seller || resp.Amount <= 0 || !resp.Item.IsStandardLoot() || !resp.Item.Movable || (resp.Item is Container && ((Container)resp.Item).Items.Count != 0) )
    continue;

   foreach( IShopSellInfo ssi in info )
   {
    if ( ssi.IsSellable( resp.Item ) )
    {
     Sold++;
     break;
    }
   }
  }

  if ( Sold > MaxSell )
  {
   SayTo( seller, true, "You may only sell {0} items at a time!", MaxSell );
   return false;
  }
  else if ( Sold == 0 )
  {
   return true;
  }

  foreach ( SellItemResponse resp in list )
  {
   if ( resp.Item.RootParent != seller || resp.Amount <= 0 || !resp.Item.IsStandardLoot() || !resp.Item.Movable || (resp.Item is Container && ((Container)resp.Item).Items.Count != 0) )
    continue;

   foreach( IShopSellInfo ssi in info )
   {
    if ( ssi.IsSellable( resp.Item ) )
    {
     int amount = resp.Amount;

     if ( amount > resp.Item.Amount )
      amount = resp.Item.Amount;

     if ( ssi.IsResellable( resp.Item ) )
     {
      bool found = false;

      foreach ( IBuyItemInfo bii in buyInfo )
      {
       if ( bii.Restock( resp.Item, amount ) )
       {
        resp.Item.Consume( amount );
        found = true;

        break;
       }
      }

      if ( !found )
      {
       cont = this.BuyPack;

       if ( amount < resp.Item.Amount )
       {
        Item item = Mobile.LiftItemDupe( resp.Item, resp.Item.Amount - amount );

        if ( item != null )
        {
         item.SetLastMoved();
         cont.DropItem( item );
        }
        else
        {
         resp.Item.SetLastMoved();
         cont.DropItem( resp.Item );
        }
       }
       else
       {
        resp.Item.SetLastMoved();
        cont.DropItem( resp.Item );
       }
      }
     }
     else
     {
      if ( amount < resp.Item.Amount )
       resp.Item.Amount -= amount;
      else
       resp.Item.Delete();
     }

     GiveGold += ssi.GetSellPriceFor( resp.Item )*amount;
     break;
    }
   }
  }

  if ( GiveGold > 0 )
  {
   while ( GiveGold > 60000 )
   {
    seller.AddToBackpack( new Gold( 60000 ) );
    GiveGold -= 60000;
   }

   seller.AddToBackpack( new Gold( GiveGold ) );

   seller.PlaySound( 0x0037 );//Gold dropping sound

   if ( SupportsBulkOrders( seller ) )
   {
    Item bulkOrder = CreateBulkOrder( seller, false );

    if ( bulkOrder is LargeBOD )
     seller.SendGump( new LargeBODAcceptGump( seller, (LargeBOD)bulkOrder ) );
    else if ( bulkOrder is SmallBOD )
     seller.SendGump( new SmallBODAcceptGump( seller, (SmallBOD)bulkOrder ) );
   }
  }
  //no cliloc for this?
  //SayTo( seller, true, "Thank you! I bought {0} item{1}. Here is your {2}gp.", Sold, (Sold > 1 ? "s" : ""), GiveGold );
 
  return true;
 }

 public override void Serialize( GenericWriter writer )
 {
  base.Serialize( writer );

  writer.Write( (int) 1 ); // version

  ArrayList sbInfos = this.SBInfos;

  for ( int i = 0; sbInfos != null && i < sbInfos.Count; ++i )
  {
   SBInfo sbInfo = (SBInfo)sbInfos[i];
   ArrayList buyInfo = sbInfo.BuyInfo;

   for ( int j = 0; buyInfo != null && j < buyInfo.Count; ++j )
   {
    GenericBuyInfo gbi = (GenericBuyInfo)buyInfo[j];

    int maxAmount = gbi.MaxAmount;
    int doubled = 0;

    switch ( maxAmount )
    {
     case  40: doubled = 1; break;
     case  80: doubled = 2; break;
     case 160: doubled = 3; break;
     case 320: doubled = 4; break;
     case 640: doubled = 5; break;
     case 999: doubled = 6; break;
    }

    if ( doubled > 0 )
    {
     writer.WriteEncodedInt( 1 + ((j * sbInfos.Count) + i) );
     writer.WriteEncodedInt( doubled );
    }
   }
  }

  writer.WriteEncodedInt( 0 );
 }

 public override void Deserialize( GenericReader reader )
 {
  base.Deserialize( reader );

  int version = reader.ReadInt();

  LoadSBInfo();

  ArrayList sbInfos = this.SBInfos;

  switch ( version )
  {
   case 1:
   {
    int index;

    while ( (index = reader.ReadEncodedInt()) > 0 )
    {
     int doubled = reader.ReadEncodedInt();

     if ( sbInfos != null )
     {
      index -= 1;
      int sbInfoIndex = index % sbInfos.Count;
      int buyInfoIndex = index / sbInfos.Count;

      if ( sbInfoIndex >= 0 && sbInfoIndex < sbInfos.Count )
      {
       SBInfo sbInfo = (SBInfo)sbInfos[sbInfoIndex];
       ArrayList buyInfo = sbInfo.BuyInfo;

       if ( buyInfo != null && buyInfoIndex >= 0 && buyInfoIndex < buyInfo.Count )
       {
        GenericBuyInfo gbi = (GenericBuyInfo)buyInfo[buyInfoIndex];

        int amount = 20;

        switch ( doubled )
        {
         case 1: amount =  40; break;
         case 2: amount =  80; break;
         case 3: amount = 160; break;
         case 4: amount = 320; break;
         case 5: amount = 640; break;
         case 6: amount = 999; break;
        }

        gbi.Amount = gbi.MaxAmount = amount;
       }
      }
     }
    }

    break;
   }
  }

  if ( IsParagon )
   IsParagon = false;

  if ( Core.AOS && NameHue == 0x35 )
   NameHue = -1;

  Timer.DelayCall( TimeSpan.Zero, new TimerCallback( CheckMorph ) );
 }

 public override void AddCustomContextEntries( Mobile from, List<ContextMenuEntry> list )
 {
  if ( from.Alive && IsActiveVendor )
  {
   if ( IsActiveSeller )
    list.Add( new VendorBuyEntry( from, this ) );

   if ( IsActiveBuyer )
    list.Add( new VendorSellEntry( from, this ) );

   if ( SupportsBulkOrders( from ) )
    list.Add( new BulkOrderInfoEntry( from, this ) );
  }

  base.AddCustomContextEntries( from, list );
 }

 public virtual IShopSellInfo[] GetSellInfo()
 {
  return (IShopSellInfo[])m_ArmorSellInfo.ToArray( typeof( IShopSellInfo ) );
 }

 public virtual IBuyItemInfo[] GetBuyInfo()
 {
  return (IBuyItemInfo[])m_ArmorBuyInfo.ToArray( typeof( IBuyItemInfo ) );
 }

 public override bool CanBeDamaged()
 {
  return !IsInvulnerable;
 }
}
}

namespace Server.ContextMenus
{
public class VendorBuyEntry : ContextMenuEntry
{
 private BaseVendor m_Vendor;

 public VendorBuyEntry( Mobile from, BaseVendor vendor ) : base( 6103, 8 )
 {
  m_Vendor = vendor;
  Enabled = vendor.CheckVendorAccess( from );
 }

 public override void OnClick()
 {
  m_Vendor.VendorBuy( this.Owner.From );
 }
}

public class VendorSellEntry : ContextMenuEntry
{
 private BaseVendor m_Vendor;

 public VendorSellEntry( Mobile from, BaseVendor vendor ) : base( 6104, 8 )
 {
  m_Vendor = vendor;
  Enabled = vendor.CheckVendorAccess( from );
 }

 public override void OnClick()
 {
  m_Vendor.VendorSell( this.Owner.From );
 }
}
}

namespace Server
{
public interface IShopSellInfo
{
 //get display name for an item
 string GetNameFor( Item item );

 //get price for an item which the player is selling
 int GetSellPriceFor( Item item );

 //get price for an item which the player is buying
 int GetBuyPriceFor( Item item );

 //can we sell this item
CODE

Add( new GenericBuyInfo( "1041280", typeof( InteriorDecorator ), 10001, 20, 0xFC1, 0 ) );


the type such as InteriorDecorator must be a valid constructable class. You have some type specified that is an abstract class and that is causing the crash.