diff --git a/Scripts/Commands/Handlers.cs b/Scripts/Commands/Handlers.cs index f98710d10..50ce98614 100644 --- a/Scripts/Commands/Handlers.cs +++ b/Scripts/Commands/Handlers.cs @@ -1,10 +1,10 @@ using System; using System.IO; -using Server; using System.Text; using System.Collections; using System.Collections.Generic; using System.Net; +using Server; using Server.Accounting; using Server.Mobiles; using Server.Items; @@ -17,7 +17,6 @@ using Server.Targeting; using Server.Targets; using Server.Gumps; using Server.Commands.Generic; -using Server.Diagnostics; namespace Server.Commands { @@ -27,8 +26,6 @@ namespace Server.Commands { CommandSystem.Prefix = "["; - Properties.Register(); - Register( "Go", AccessLevel.Counselor, new CommandEventHandler( Go_OnCommand ) ); Register( "DropHolding", AccessLevel.Counselor, new CommandEventHandler( DropHolding_OnCommand ) ); @@ -71,14 +68,6 @@ namespace Server.Commands Register( "ViewEquip", AccessLevel.GameMaster, new CommandEventHandler( ViewEquip_OnCommand ) ); - Register( "DumpTimers", AccessLevel.Administrator, new CommandEventHandler( DumpTimers_OnCommand ) ); - Register( "CountObjects", AccessLevel.Administrator, new CommandEventHandler( CountObjects_OnCommand ) ); - Register( "ProfileWorld", AccessLevel.Administrator, new CommandEventHandler( ProfileWorld_OnCommand ) ); - Register( "TraceInternal", AccessLevel.Administrator, new CommandEventHandler( TraceInternal_OnCommand ) ); - Register( "TraceExpanded", AccessLevel.Administrator, new CommandEventHandler( TraceExpanded_OnCommand ) ); - Register( "WriteProfiles", AccessLevel.Administrator, new CommandEventHandler( WriteProfiles_OnCommand ) ); - Register( "SetProfiles", AccessLevel.Administrator, new CommandEventHandler( SetProfiles_OnCommand ) ); - Register( "Light", AccessLevel.Counselor, new CommandEventHandler( Light_OnCommand ) ); Register( "Stats", AccessLevel.Counselor, new CommandEventHandler( Stats_OnCommand ) ); @@ -473,382 +462,6 @@ namespace Server.Commands } } - [Usage( "WriteProfiles" )] - [Description( "Generates a log files containing performance diagnostic information." )] - public static void WriteProfiles_OnCommand( CommandEventArgs e ) - { - try - { - using ( StreamWriter sw = new StreamWriter( "profiles.log", true ) ) - { - sw.WriteLine( "# Dump on {0:f}", DateTime.Now ); - sw.WriteLine( "# Core profiling for " + Core.ProfileTime ); - - sw.WriteLine( "# Packet send" ); - BaseProfile.WriteAll( sw, PacketSendProfile.Profiles ); - sw.WriteLine(); - - sw.WriteLine( "# Packet receive" ); - BaseProfile.WriteAll( sw, PacketReceiveProfile.Profiles ); - sw.WriteLine(); - - sw.WriteLine( "# Timer" ); - BaseProfile.WriteAll( sw, TimerProfile.Profiles ); - sw.WriteLine(); - - sw.WriteLine( "# Gump response" ); - BaseProfile.WriteAll( sw, GumpProfile.Profiles ); - sw.WriteLine(); - - sw.WriteLine( "# Target response" ); - BaseProfile.WriteAll( sw, TargetProfile.Profiles ); - sw.WriteLine(); - } - } - catch - { - } - } - - [Usage( "SetProfiles [true | false]" )] - [Description( "Enables, disables, or toggles the state of core packet and timer profiling." )] - public static void SetProfiles_OnCommand( CommandEventArgs e ) - { - if ( e.Length == 1 ) - Core.Profiling = e.GetBoolean( 0 ); - else - Core.Profiling = !Core.Profiling; - - e.Mobile.SendMessage( "Profiling has been {0}.", Core.Profiling ? "enabled" : "disabled" ); - } - - [Usage( "DumpTimers" )] - [Description( "Generates a log file of all currently executing timers. Used for tracing timer leaks." )] - public static void DumpTimers_OnCommand( CommandEventArgs e ) - { - try - { - using ( StreamWriter sw = new StreamWriter( "timerdump.log", true ) ) - Timer.DumpInfo( sw ); - } - catch - { - } - } - - private class CountSorter : IComparer - { - public int Compare( object x, object y ) - { - DictionaryEntry a = (DictionaryEntry)x; - DictionaryEntry b = (DictionaryEntry)y; - - int aCount = GetCount( a.Value ); - int bCount = GetCount( b.Value ); - - int v = -aCount.CompareTo( bCount ); - - if ( v == 0 ) - { - Type aType = (Type)a.Key; - Type bType = (Type)b.Key; - - v = aType.FullName.CompareTo( bType.FullName ); - } - - return v; - } - - private int GetCount( object obj ) - { - if ( obj is int ) - return (int) obj; - - if ( obj is int[] ) - { - int[] list = (int[]) obj; - - int total = 0; - - for ( int i = 0; i < list.Length; ++i ) - total += list[i]; - - return total; - } - - return 0; - } - } - - [Usage( "CountObjects" )] - [Description( "Generates a log file detailing all item and mobile types in the world." )] - public static void CountObjects_OnCommand( CommandEventArgs e ) - { - using ( StreamWriter op = new StreamWriter( "objects.log" ) ) - { - Hashtable table = new Hashtable(); - - foreach ( Item item in World.Items.Values ) - { - Type type = item.GetType(); - - object o = (object)table[type]; - - if ( o == null ) - table[type] = 1; - else - table[type] = 1 + (int)o; - } - - ArrayList items = new ArrayList( table ); - - table.Clear(); - - foreach ( Mobile m in World.Mobiles.Values ) - { - Type type = m.GetType(); - - object o = (object)table[type]; - - if ( o == null ) - table[type] = 1; - else - table[type] = 1 + (int)o; - } - - ArrayList mobiles = new ArrayList( table ); - - items.Sort( new CountSorter() ); - mobiles.Sort( new CountSorter() ); - - op.WriteLine( "# Object count table generated on {0}", DateTime.Now ); - op.WriteLine(); - op.WriteLine(); - - op.WriteLine( "# Items:" ); - - foreach ( DictionaryEntry de in items ) - op.WriteLine( "{0}\t{1:F2}%\t{2}", de.Value, (100 * (int)de.Value) / (double)World.Items.Count, de.Key ); - - op.WriteLine(); - op.WriteLine(); - - op.WriteLine( "#Mobiles:" ); - - foreach ( DictionaryEntry de in mobiles ) - op.WriteLine( "{0}\t{1:F2}%\t{2}", de.Value, (100 * (int)de.Value) / (double)World.Mobiles.Count, de.Key ); - } - - e.Mobile.SendMessage( "Object table has been generated. See the file : /objects.log" ); - } - - [Usage( "TraceExpanded" )] - [Description( "Generates a log file describing all items using expanded memory." )] - public static void TraceExpanded_OnCommand( CommandEventArgs e ) - { - Hashtable typeTable = new Hashtable(); - - foreach ( Item item in World.Items.Values ) - { - ExpandFlag flags = item.GetExpandFlags(); - - if ( ( flags & ~(ExpandFlag.TempFlag | ExpandFlag.SaveFlag) ) == 0 ) - continue; - - Type itemType = item.GetType(); - - do - { - int[] countTable = typeTable[itemType] as int[]; - - if ( countTable == null ) - typeTable[itemType] = countTable = new int[8]; - - if ( ( flags & ExpandFlag.Name ) != 0 ) - ++countTable[0]; - - if ( ( flags & ExpandFlag.Items ) != 0 ) - ++countTable[1]; - - if ( ( flags & ExpandFlag.Bounce ) != 0 ) - ++countTable[2]; - - if ( ( flags & ExpandFlag.Holder ) != 0 ) - ++countTable[3]; - - if ( ( flags & ExpandFlag.Blessed ) != 0 ) - ++countTable[4]; - - /*if ( ( flags & ExpandFlag.TempFlag ) != 0 ) - ++countTable[5]; - - if ( ( flags & ExpandFlag.SaveFlag ) != 0 ) - ++countTable[6];*/ - - if ( ( flags & ExpandFlag.Weight ) != 0 ) - ++countTable[7]; - - itemType = itemType.BaseType; - } while ( itemType != typeof( object ) ); - } - - try - { - using ( StreamWriter op = new StreamWriter( "expandedItems.log", true ) ) - { - string[] names = new string[] - { - "Name", - "Items", - "Bounce", - "Holder", - "Blessed", - "TempFlag", - "SaveFlag", - "Weight" - }; - - ArrayList list = new ArrayList( typeTable ); - - list.Sort( new CountSorter() ); - - foreach ( DictionaryEntry de in list ) - { - Type itemType = de.Key as Type; - int[] countTable = de.Value as int[]; - - op.WriteLine( "# {0}", itemType.FullName ); - - for ( int i = 0; i < countTable.Length; ++i ) - { - if ( countTable[i] > 0 ) - op.WriteLine( "{0}\t{1:N0}", names[i], countTable[i] ); - } - - op.WriteLine(); - } - } - } - catch - { - } - } - - [Usage( "TraceInternal" )] - [Description( "Generates a log file describing all items in the 'internal' map." )] - public static void TraceInternal_OnCommand( CommandEventArgs e ) - { - int totalCount = 0; - Hashtable table = new Hashtable(); - - foreach ( Item item in World.Items.Values ) - { - if ( item.Parent != null || item.Map != Map.Internal ) - continue; - - ++totalCount; - - Type type = item.GetType(); - int[] parms = (int[])table[type]; - - if ( parms == null ) - table[type] = parms = new int[]{ 0, 0 }; - - parms[0]++; - parms[1] += item.Amount; - } - - using ( StreamWriter op = new StreamWriter( "internal.log" ) ) - { - op.WriteLine( "# {0} items found", totalCount ); - op.WriteLine( "# {0} different types", table.Count ); - op.WriteLine(); - op.WriteLine(); - op.WriteLine( "Type\t\tCount\t\tAmount\t\tAvg. Amount" ); - - foreach ( DictionaryEntry de in table ) - { - Type type = (Type)de.Key; - int[] parms = (int[])de.Value; - - op.WriteLine( "{0}\t\t{1}\t\t{2}\t\t{3:F2}", type.Name, parms[0], parms[1], (double)parms[1] / parms[0] ); - } - } - } - - [Usage( "ProfileWorld" )] - [Description( "Prints the amount of data serialized for every object type in your world file." )] - public static void ProfileWorld_OnCommand( CommandEventArgs e ) - { - ProfileWorld( "items", "worldprofile_items.log" ); - ProfileWorld( "mobiles", "worldprofile_mobiles.log" ); - } - - public static void ProfileWorld( string type, string opFile ) - { - try - { - ArrayList types = new ArrayList(); - - using ( BinaryReader bin = new BinaryReader( new FileStream( String.Format( "Saves/{0}/{0}.tdb", type ), FileMode.Open, FileAccess.Read, FileShare.Read ) ) ) - { - int count = bin.ReadInt32(); - - for ( int i = 0; i < count; ++i ) - types.Add( ScriptCompiler.FindTypeByFullName( bin.ReadString() ) ); - } - - long total = 0; - - Hashtable table = new Hashtable(); - - using ( BinaryReader bin = new BinaryReader( new FileStream( String.Format( "Saves/{0}/{0}.idx", type ), FileMode.Open, FileAccess.Read, FileShare.Read ) ) ) - { - int count = bin.ReadInt32(); - - for ( int i = 0; i < count; ++i ) - { - int typeID = bin.ReadInt32(); - int serial = bin.ReadInt32(); - long pos = bin.ReadInt64(); - int length = bin.ReadInt32(); - Type objType = (Type)types[typeID]; - - while ( objType != null && objType != typeof( object ) ) - { - object obj = table[objType]; - - if ( obj == null ) - table[objType] = length; - else - table[objType] = length + (int)obj; - - objType = objType.BaseType; - total += length; - } - } - } - - ArrayList list = new ArrayList( table ); - - list.Sort( new CountSorter() ); - - using ( StreamWriter op = new StreamWriter( opFile ) ) - { - op.WriteLine( "# Profile of world {0}", type ); - op.WriteLine( "# Generated on {0}", DateTime.Now ); - op.WriteLine(); - op.WriteLine(); - - foreach ( DictionaryEntry de in list ) - op.WriteLine( "{0}\t{1:F2}%\t{2}", de.Value, (100 * (int)de.Value) / (double)total, de.Key ); - } - } - catch - { - } - } - [Usage( "ViewEquip" )] [Description( "Lists equipment of a targeted mobile. From the list you can move, delete, or open props." )] public static void ViewEquip_OnCommand( CommandEventArgs e ) diff --git a/Scripts/Commands/Profiling.cs b/Scripts/Commands/Profiling.cs new file mode 100644 index 000000000..554efef09 --- /dev/null +++ b/Scripts/Commands/Profiling.cs @@ -0,0 +1,400 @@ +using System; +using System.IO; +using System.Text; +using System.Collections; +using System.Collections.Generic; +using Server; +using Server.Diagnostics; + +namespace Server.Commands +{ + public class Profiling + { + public static void Initialize() + { + CommandSystem.Register( "DumpTimers", AccessLevel.Administrator, new CommandEventHandler( DumpTimers_OnCommand ) ); + CommandSystem.Register( "CountObjects", AccessLevel.Administrator, new CommandEventHandler( CountObjects_OnCommand ) ); + CommandSystem.Register( "ProfileWorld", AccessLevel.Administrator, new CommandEventHandler( ProfileWorld_OnCommand ) ); + CommandSystem.Register( "TraceInternal", AccessLevel.Administrator, new CommandEventHandler( TraceInternal_OnCommand ) ); + CommandSystem.Register( "TraceExpanded", AccessLevel.Administrator, new CommandEventHandler( TraceExpanded_OnCommand ) ); + CommandSystem.Register( "WriteProfiles", AccessLevel.Administrator, new CommandEventHandler( WriteProfiles_OnCommand ) ); + CommandSystem.Register( "SetProfiles", AccessLevel.Administrator, new CommandEventHandler( SetProfiles_OnCommand ) ); + } + + [Usage( "WriteProfiles" )] + [Description( "Generates a log files containing performance diagnostic information." )] + public static void WriteProfiles_OnCommand( CommandEventArgs e ) + { + try + { + using ( StreamWriter sw = new StreamWriter( "profiles.log", true ) ) + { + sw.WriteLine( "# Dump on {0:f}", DateTime.Now ); + sw.WriteLine( "# Core profiling for " + Core.ProfileTime ); + + sw.WriteLine( "# Packet send" ); + BaseProfile.WriteAll( sw, PacketSendProfile.Profiles ); + sw.WriteLine(); + + sw.WriteLine( "# Packet receive" ); + BaseProfile.WriteAll( sw, PacketReceiveProfile.Profiles ); + sw.WriteLine(); + + sw.WriteLine( "# Timer" ); + BaseProfile.WriteAll( sw, TimerProfile.Profiles ); + sw.WriteLine(); + + sw.WriteLine( "# Gump response" ); + BaseProfile.WriteAll( sw, GumpProfile.Profiles ); + sw.WriteLine(); + + sw.WriteLine( "# Target response" ); + BaseProfile.WriteAll( sw, TargetProfile.Profiles ); + sw.WriteLine(); + } + } + catch + { + } + } + + [Usage( "SetProfiles [true | false]" )] + [Description( "Enables, disables, or toggles the state of core packet and timer profiling." )] + public static void SetProfiles_OnCommand( CommandEventArgs e ) + { + if ( e.Length == 1 ) + Core.Profiling = e.GetBoolean( 0 ); + else + Core.Profiling = !Core.Profiling; + + e.Mobile.SendMessage( "Profiling has been {0}.", Core.Profiling ? "enabled" : "disabled" ); + } + + [Usage( "DumpTimers" )] + [Description( "Generates a log file of all currently executing timers. Used for tracing timer leaks." )] + public static void DumpTimers_OnCommand( CommandEventArgs e ) + { + try + { + using ( StreamWriter sw = new StreamWriter( "timerdump.log", true ) ) + Timer.DumpInfo( sw ); + } + catch + { + } + } + + private class CountSorter : IComparer + { + public int Compare( object x, object y ) + { + DictionaryEntry a = (DictionaryEntry)x; + DictionaryEntry b = (DictionaryEntry)y; + + int aCount = GetCount( a.Value ); + int bCount = GetCount( b.Value ); + + int v = -aCount.CompareTo( bCount ); + + if ( v == 0 ) + { + Type aType = (Type)a.Key; + Type bType = (Type)b.Key; + + v = aType.FullName.CompareTo( bType.FullName ); + } + + return v; + } + + private int GetCount( object obj ) + { + if ( obj is int ) + return (int) obj; + + if ( obj is int[] ) + { + int[] list = (int[]) obj; + + int total = 0; + + for ( int i = 0; i < list.Length; ++i ) + total += list[i]; + + return total; + } + + return 0; + } + } + + [Usage( "CountObjects" )] + [Description( "Generates a log file detailing all item and mobile types in the world." )] + public static void CountObjects_OnCommand( CommandEventArgs e ) + { + using ( StreamWriter op = new StreamWriter( "objects.log" ) ) + { + Hashtable table = new Hashtable(); + + foreach ( Item item in World.Items.Values ) + { + Type type = item.GetType(); + + object o = (object)table[type]; + + if ( o == null ) + table[type] = 1; + else + table[type] = 1 + (int)o; + } + + ArrayList items = new ArrayList( table ); + + table.Clear(); + + foreach ( Mobile m in World.Mobiles.Values ) + { + Type type = m.GetType(); + + object o = (object)table[type]; + + if ( o == null ) + table[type] = 1; + else + table[type] = 1 + (int)o; + } + + ArrayList mobiles = new ArrayList( table ); + + items.Sort( new CountSorter() ); + mobiles.Sort( new CountSorter() ); + + op.WriteLine( "# Object count table generated on {0}", DateTime.Now ); + op.WriteLine(); + op.WriteLine(); + + op.WriteLine( "# Items:" ); + + foreach ( DictionaryEntry de in items ) + op.WriteLine( "{0}\t{1:F2}%\t{2}", de.Value, (100 * (int)de.Value) / (double)World.Items.Count, de.Key ); + + op.WriteLine(); + op.WriteLine(); + + op.WriteLine( "#Mobiles:" ); + + foreach ( DictionaryEntry de in mobiles ) + op.WriteLine( "{0}\t{1:F2}%\t{2}", de.Value, (100 * (int)de.Value) / (double)World.Mobiles.Count, de.Key ); + } + + e.Mobile.SendMessage( "Object table has been generated. See the file : /objects.log" ); + } + + [Usage( "TraceExpanded" )] + [Description( "Generates a log file describing all items using expanded memory." )] + public static void TraceExpanded_OnCommand( CommandEventArgs e ) + { + Hashtable typeTable = new Hashtable(); + + foreach ( Item item in World.Items.Values ) + { + ExpandFlag flags = item.GetExpandFlags(); + + if ( ( flags & ~(ExpandFlag.TempFlag | ExpandFlag.SaveFlag) ) == 0 ) + continue; + + Type itemType = item.GetType(); + + do + { + int[] countTable = typeTable[itemType] as int[]; + + if ( countTable == null ) + typeTable[itemType] = countTable = new int[8]; + + if ( ( flags & ExpandFlag.Name ) != 0 ) + ++countTable[0]; + + if ( ( flags & ExpandFlag.Items ) != 0 ) + ++countTable[1]; + + if ( ( flags & ExpandFlag.Bounce ) != 0 ) + ++countTable[2]; + + if ( ( flags & ExpandFlag.Holder ) != 0 ) + ++countTable[3]; + + if ( ( flags & ExpandFlag.Blessed ) != 0 ) + ++countTable[4]; + + /*if ( ( flags & ExpandFlag.TempFlag ) != 0 ) + ++countTable[5]; + + if ( ( flags & ExpandFlag.SaveFlag ) != 0 ) + ++countTable[6];*/ + + if ( ( flags & ExpandFlag.Weight ) != 0 ) + ++countTable[7]; + + itemType = itemType.BaseType; + } while ( itemType != typeof( object ) ); + } + + try + { + using ( StreamWriter op = new StreamWriter( "expandedItems.log", true ) ) + { + string[] names = new string[] + { + "Name", + "Items", + "Bounce", + "Holder", + "Blessed", + "TempFlag", + "SaveFlag", + "Weight" + }; + + ArrayList list = new ArrayList( typeTable ); + + list.Sort( new CountSorter() ); + + foreach ( DictionaryEntry de in list ) + { + Type itemType = de.Key as Type; + int[] countTable = de.Value as int[]; + + op.WriteLine( "# {0}", itemType.FullName ); + + for ( int i = 0; i < countTable.Length; ++i ) + { + if ( countTable[i] > 0 ) + op.WriteLine( "{0}\t{1:N0}", names[i], countTable[i] ); + } + + op.WriteLine(); + } + } + } + catch + { + } + } + + [Usage( "TraceInternal" )] + [Description( "Generates a log file describing all items in the 'internal' map." )] + public static void TraceInternal_OnCommand( CommandEventArgs e ) + { + int totalCount = 0; + Hashtable table = new Hashtable(); + + foreach ( Item item in World.Items.Values ) + { + if ( item.Parent != null || item.Map != Map.Internal ) + continue; + + ++totalCount; + + Type type = item.GetType(); + int[] parms = (int[])table[type]; + + if ( parms == null ) + table[type] = parms = new int[]{ 0, 0 }; + + parms[0]++; + parms[1] += item.Amount; + } + + using ( StreamWriter op = new StreamWriter( "internal.log" ) ) + { + op.WriteLine( "# {0} items found", totalCount ); + op.WriteLine( "# {0} different types", table.Count ); + op.WriteLine(); + op.WriteLine(); + op.WriteLine( "Type\t\tCount\t\tAmount\t\tAvg. Amount" ); + + foreach ( DictionaryEntry de in table ) + { + Type type = (Type)de.Key; + int[] parms = (int[])de.Value; + + op.WriteLine( "{0}\t\t{1}\t\t{2}\t\t{3:F2}", type.Name, parms[0], parms[1], (double)parms[1] / parms[0] ); + } + } + } + + [Usage( "ProfileWorld" )] + [Description( "Prints the amount of data serialized for every object type in your world file." )] + public static void ProfileWorld_OnCommand( CommandEventArgs e ) + { + ProfileWorld( "items", "worldprofile_items.log" ); + ProfileWorld( "mobiles", "worldprofile_mobiles.log" ); + } + + public static void ProfileWorld( string type, string opFile ) + { + try + { + ArrayList types = new ArrayList(); + + using ( BinaryReader bin = new BinaryReader( new FileStream( String.Format( "Saves/{0}/{0}.tdb", type ), FileMode.Open, FileAccess.Read, FileShare.Read ) ) ) + { + int count = bin.ReadInt32(); + + for ( int i = 0; i < count; ++i ) + types.Add( ScriptCompiler.FindTypeByFullName( bin.ReadString() ) ); + } + + long total = 0; + + Hashtable table = new Hashtable(); + + using ( BinaryReader bin = new BinaryReader( new FileStream( String.Format( "Saves/{0}/{0}.idx", type ), FileMode.Open, FileAccess.Read, FileShare.Read ) ) ) + { + int count = bin.ReadInt32(); + + for ( int i = 0; i < count; ++i ) + { + int typeID = bin.ReadInt32(); + int serial = bin.ReadInt32(); + long pos = bin.ReadInt64(); + int length = bin.ReadInt32(); + Type objType = (Type)types[typeID]; + + while ( objType != null && objType != typeof( object ) ) + { + object obj = table[objType]; + + if ( obj == null ) + table[objType] = length; + else + table[objType] = length + (int)obj; + + objType = objType.BaseType; + total += length; + } + } + } + + ArrayList list = new ArrayList( table ); + + list.Sort( new CountSorter() ); + + using ( StreamWriter op = new StreamWriter( opFile ) ) + { + op.WriteLine( "# Profile of world {0}", type ); + op.WriteLine( "# Generated on {0}", DateTime.Now ); + op.WriteLine(); + op.WriteLine(); + + foreach ( DictionaryEntry de in list ) + op.WriteLine( "{0}\t{1:F2}%\t{2}", de.Value, (100 * (int)de.Value) / (double)total, de.Key ); + } + } + catch + { + } + } + } +} \ No newline at end of file diff --git a/Scripts/Commands/Properties.cs b/Scripts/Commands/Properties.cs index 1ab9766fe..0ce755899 100644 --- a/Scripts/Commands/Properties.cs +++ b/Scripts/Commands/Properties.cs @@ -20,7 +20,7 @@ namespace Server.Commands public class Properties { - public static void Register() + public static void Initialize() { CommandSystem.Register( "Props", AccessLevel.Counselor, new CommandEventHandler( Props_OnCommand ) ); } diff --git a/Server/Skills.cs b/Server/Skills.cs index b81cc8117..afb3a7229 100644 --- a/Server/Skills.cs +++ b/Server/Skills.cs @@ -91,7 +91,10 @@ namespace Server Chivalry = 51, Bushido = 52, Ninjitsu = 53, - Spellweaving = 54 + Spellweaving = 54, + Mysticism = 55, + Imbuing = 56, + Throwing = 57 } [PropertyObject] @@ -612,61 +615,64 @@ namespace Server private static SkillInfo[] m_Table = new SkillInfo[55] { - new SkillInfo( 0, "Alchemy", 0.0, 5.0, 5.0, "Alchemist", null, 0.0, 0.5, 0.5, 1.0 ), - new SkillInfo( 1, "Anatomy", 0.0, 0.0, 0.0, "Healer", null, 0.15, 0.15, 0.7, 1.0 ), - new SkillInfo( 2, "Animal Lore", 0.0, 0.0, 0.0, "Ranger", null, 0.0, 0.0, 1.0, 1.0 ), - new SkillInfo( 3, "Item Identification", 0.0, 0.0, 0.0, "Merchant", null, 0.0, 0.0, 1.0, 1.0 ), - new SkillInfo( 4, "Arms Lore", 0.0, 0.0, 0.0, "Warrior", null, 0.75, 0.15, 0.1, 1.0 ), - new SkillInfo( 5, "Parrying", 7.5, 2.5, 0.0, "Warrior", null, 0.75, 0.25, 0.0, 1.0 ), - new SkillInfo( 6, "Begging", 0.0, 0.0, 0.0, "Beggar", null, 0.0, 0.0, 0.0, 1.0 ), - new SkillInfo( 7, "Blacksmithy", 10.0, 0.0, 0.0, "Smith", null, 1.0, 0.0, 0.0, 1.0 ), - new SkillInfo( 8, "Bowcraft/Fletching", 6.0, 16.0, 0.0, "Bowyer", null, 0.6, 1.6, 0.0, 1.0 ), - new SkillInfo( 9, "Peacemaking", 0.0, 0.0, 0.0, "Bard", null, 0.0, 0.0, 0.0, 1.0 ), - new SkillInfo( 10, "Camping", 20.0, 15.0, 15.0, "Ranger", null, 2.0, 1.5, 1.5, 1.0 ), - new SkillInfo( 11, "Carpentry", 20.0, 5.0, 0.0, "Carpenter", null, 2.0, 0.5, 0.0, 1.0 ), - new SkillInfo( 12, "Cartography", 0.0, 7.5, 7.5, "Cartographer", null, 0.0, 0.75, 0.75, 1.0 ), - new SkillInfo( 13, "Cooking", 0.0, 20.0, 30.0, "Chef", null, 0.0, 2.0, 3.0, 1.0 ), - new SkillInfo( 14, "Detecting Hidden", 0.0, 0.0, 0.0, "Scout", null, 0.0, 0.4, 0.6, 1.0 ), - new SkillInfo( 15, "Discordance", 0.0, 2.5, 2.5, "Bard", null, 0.0, 0.25, 0.25, 1.0 ), - new SkillInfo( 16, "Evaluating Intelligence", 0.0, 0.0, 0.0, "Scholar", null, 0.0, 0.0, 1.0, 1.0 ), - new SkillInfo( 17, "Healing", 6.0, 6.0, 8.0, "Healer", null, 0.6, 0.6, 0.8, 1.0 ), - new SkillInfo( 18, "Fishing", 0.0, 0.0, 0.0, "Fisherman", null, 0.5, 0.5, 0.0, 1.0 ), - new SkillInfo( 19, "Forensic Evaluation", 0.0, 0.0, 0.0, "Detective", null, 0.0, 0.2, 0.8, 1.0 ), - new SkillInfo( 20, "Herding", 16.25, 6.25, 2.5, "Shepherd", null, 1.625, 0.625, 0.25, 1.0 ), - new SkillInfo( 21, "Hiding", 0.0, 0.0, 0.0, "Rogue", null, 0.0, 0.8, 0.2, 1.0 ), - new SkillInfo( 22, "Provocation", 0.0, 4.5, 0.5, "Bard", null, 0.0, 0.45, 0.05, 1.0 ), - new SkillInfo( 23, "Inscription", 0.0, 2.0, 8.0, "Scribe", null, 0.0, 0.2, 0.8, 1.0 ), - new SkillInfo( 24, "Lockpicking", 0.0, 25.0, 0.0, "Rogue", null, 0.0, 2.0, 0.0, 1.0 ), - new SkillInfo( 25, "Magery", 0.0, 0.0, 15.0, "Mage", null, 0.0, 0.0, 1.5, 1.0 ), - new SkillInfo( 26, "Resisting Spells", 0.0, 0.0, 0.0, "Mage", null, 0.25, 0.25, 0.5, 1.0 ), - new SkillInfo( 27, "Tactics", 0.0, 0.0, 0.0, "Warrior", null, 0.0, 0.0, 0.0, 1.0 ), - new SkillInfo( 28, "Snooping", 0.0, 25.0, 0.0, "Pickpocket", null, 0.0, 2.5, 0.0, 1.0 ), - new SkillInfo( 29, "Musicianship", 0.0, 0.0, 0.0, "Bard", null, 0.0, 0.8, 0.2, 1.0 ), - new SkillInfo( 30, "Poisoning", 0.0, 4.0, 16.0, "Assassin", null, 0.0, 0.4, 1.6, 1.0 ), - new SkillInfo( 31, "Archery", 2.5, 7.5, 0.0, "Archer", null, 0.25, 0.75, 0.0, 1.0 ), - new SkillInfo( 32, "Spirit Speak", 0.0, 0.0, 0.0, "Medium", null, 0.0, 0.0, 1.0, 1.0 ), - new SkillInfo( 33, "Stealing", 0.0, 10.0, 0.0, "Rogue", null, 0.0, 1.0, 0.0, 1.0 ), - new SkillInfo( 34, "Tailoring", 3.75, 16.25, 5.0, "Tailor", null, 0.38, 1.63, 0.5, 1.0 ), - new SkillInfo( 35, "Animal Taming", 14.0, 2.0, 4.0, "Tamer", null, 1.4, 0.2, 0.4, 1.0 ), - new SkillInfo( 36, "Taste Identification", 0.0, 0.0, 0.0, "Chef", null, 0.2, 0.0, 0.8, 1.0 ), - new SkillInfo( 37, "Tinkering", 5.0, 2.0, 3.0, "Tinker", null, 0.5, 0.2, 0.3, 1.0 ), - new SkillInfo( 38, "Tracking", 0.0, 12.5, 12.5, "Ranger", null, 0.0, 1.25, 1.25, 1.0 ), - new SkillInfo( 39, "Veterinary", 8.0, 4.0, 8.0, "Veterinarian", null, 0.8, 0.4, 0.8, 1.0 ), - new SkillInfo( 40, "Swordsmanship", 7.5, 2.5, 0.0, "Swordsman", null, 0.75, 0.25, 0.0, 1.0 ), - new SkillInfo( 41, "Mace Fighting", 9.0, 1.0, 0.0, "Armsman", null, 0.9, 0.1, 0.0, 1.0 ), - new SkillInfo( 42, "Fencing", 4.5, 5.5, 0.0, "Fencer", null, 0.45, 0.55, 0.0, 1.0 ), - new SkillInfo( 43, "Wrestling", 9.0, 1.0, 0.0, "Wrestler", null, 0.9, 0.1, 0.0, 1.0 ), - new SkillInfo( 44, "Lumberjacking", 20.0, 0.0, 0.0, "Lumberjack", null, 2.0, 0.0, 0.0, 1.0 ), - new SkillInfo( 45, "Mining", 20.0, 0.0, 0.0, "Miner", null, 2.0, 0.0, 0.0, 1.0 ), - new SkillInfo( 46, "Meditation", 0.0, 0.0, 0.0, "Stoic", null, 0.0, 0.0, 0.0, 1.0 ), - new SkillInfo( 47, "Stealth", 0.0, 0.0, 0.0, "Rogue", null, 0.0, 0.0, 0.0, 1.0 ), - new SkillInfo( 48, "Remove Trap", 0.0, 0.0, 0.0, "Rogue", null, 0.0, 0.0, 0.0, 1.0 ), - new SkillInfo( 49, "Necromancy", 0.0, 0.0, 0.0, "Necromancer", null, 0.0, 0.0, 0.0, 1.0 ), - new SkillInfo( 50, "Focus", 0.0, 0.0, 0.0, "Stoic", null, 0.0, 0.0, 0.0, 1.0 ), - new SkillInfo( 51, "Chivalry", 0.0, 0.0, 0.0, "Paladin", null, 0.0, 0.0, 0.0, 1.0 ), - new SkillInfo( 52, "Bushido", 0.0, 0.0, 0.0, "Samurai", null, 0.0, 0.0, 0.0, 1.0 ), - new SkillInfo( 53, "Ninjitsu", 0.0, 0.0, 0.0, "Ninja", null, 0.0, 0.0, 0.0, 1.0 ), - new SkillInfo( 54, "Spellweaving", 0.0, 0.0, 0.0, "Arcanist", null, 0.0, 0.0, 0.0, 1.0 ), + new SkillInfo( 0, "Alchemy", 0.0, 5.0, 5.0, "Alchemist", null, 0.0, 0.5, 0.5, 1.0 ), + new SkillInfo( 1, "Anatomy", 0.0, 0.0, 0.0, "Healer", null, 0.15, 0.15, 0.7, 1.0 ), + new SkillInfo( 2, "Animal Lore", 0.0, 0.0, 0.0, "Ranger", null, 0.0, 0.0, 1.0, 1.0 ), + new SkillInfo( 3, "Item Identification", 0.0, 0.0, 0.0, "Merchant", null, 0.0, 0.0, 1.0, 1.0 ), + new SkillInfo( 4, "Arms Lore", 0.0, 0.0, 0.0, "Warrior", null, 0.75, 0.15, 0.1, 1.0 ), + new SkillInfo( 5, "Parrying", 7.5, 2.5, 0.0, "Warrior", null, 0.75, 0.25, 0.0, 1.0 ), + new SkillInfo( 6, "Begging", 0.0, 0.0, 0.0, "Beggar", null, 0.0, 0.0, 0.0, 1.0 ), + new SkillInfo( 7, "Blacksmithy", 10.0, 0.0, 0.0, "Smith", null, 1.0, 0.0, 0.0, 1.0 ), + new SkillInfo( 8, "Bowcraft/Fletching", 6.0, 16.0, 0.0, "Bowyer", null, 0.6, 1.6, 0.0, 1.0 ), + new SkillInfo( 9, "Peacemaking", 0.0, 0.0, 0.0, "Bard", null, 0.0, 0.0, 0.0, 1.0 ), + new SkillInfo( 10, "Camping", 20.0, 15.0, 15.0, "Ranger", null, 2.0, 1.5, 1.5, 1.0 ), + new SkillInfo( 11, "Carpentry", 20.0, 5.0, 0.0, "Carpenter", null, 2.0, 0.5, 0.0, 1.0 ), + new SkillInfo( 12, "Cartography", 0.0, 7.5, 7.5, "Cartographer", null, 0.0, 0.75, 0.75, 1.0 ), + new SkillInfo( 13, "Cooking", 0.0, 20.0, 30.0, "Chef", null, 0.0, 2.0, 3.0, 1.0 ), + new SkillInfo( 14, "Detecting Hidden", 0.0, 0.0, 0.0, "Scout", null, 0.0, 0.4, 0.6, 1.0 ), + new SkillInfo( 15, "Discordance", 0.0, 2.5, 2.5, "Bard", null, 0.0, 0.25, 0.25, 1.0 ), + new SkillInfo( 16, "Evaluating Intelligence", 0.0, 0.0, 0.0, "Scholar", null, 0.0, 0.0, 1.0, 1.0 ), + new SkillInfo( 17, "Healing", 6.0, 6.0, 8.0, "Healer", null, 0.6, 0.6, 0.8, 1.0 ), + new SkillInfo( 18, "Fishing", 0.0, 0.0, 0.0, "Fisherman", null, 0.5, 0.5, 0.0, 1.0 ), + new SkillInfo( 19, "Forensic Evaluation", 0.0, 0.0, 0.0, "Detective", null, 0.0, 0.2, 0.8, 1.0 ), + new SkillInfo( 20, "Herding", 16.25, 6.25, 2.5, "Shepherd", null, 1.625, 0.625, 0.25, 1.0 ), + new SkillInfo( 21, "Hiding", 0.0, 0.0, 0.0, "Rogue", null, 0.0, 0.8, 0.2, 1.0 ), + new SkillInfo( 22, "Provocation", 0.0, 4.5, 0.5, "Bard", null, 0.0, 0.45, 0.05, 1.0 ), + new SkillInfo( 23, "Inscription", 0.0, 2.0, 8.0, "Scribe", null, 0.0, 0.2, 0.8, 1.0 ), + new SkillInfo( 24, "Lockpicking", 0.0, 25.0, 0.0, "Rogue", null, 0.0, 2.0, 0.0, 1.0 ), + new SkillInfo( 25, "Magery", 0.0, 0.0, 15.0, "Mage", null, 0.0, 0.0, 1.5, 1.0 ), + new SkillInfo( 26, "Resisting Spells", 0.0, 0.0, 0.0, "Mage", null, 0.25, 0.25, 0.5, 1.0 ), + new SkillInfo( 27, "Tactics", 0.0, 0.0, 0.0, "Warrior", null, 0.0, 0.0, 0.0, 1.0 ), + new SkillInfo( 28, "Snooping", 0.0, 25.0, 0.0, "Pickpocket", null, 0.0, 2.5, 0.0, 1.0 ), + new SkillInfo( 29, "Musicianship", 0.0, 0.0, 0.0, "Bard", null, 0.0, 0.8, 0.2, 1.0 ), + new SkillInfo( 30, "Poisoning", 0.0, 4.0, 16.0, "Assassin", null, 0.0, 0.4, 1.6, 1.0 ), + new SkillInfo( 31, "Archery", 2.5, 7.5, 0.0, "Archer", null, 0.25, 0.75, 0.0, 1.0 ), + new SkillInfo( 32, "Spirit Speak", 0.0, 0.0, 0.0, "Medium", null, 0.0, 0.0, 1.0, 1.0 ), + new SkillInfo( 33, "Stealing", 0.0, 10.0, 0.0, "Rogue", null, 0.0, 1.0, 0.0, 1.0 ), + new SkillInfo( 34, "Tailoring", 3.75, 16.25, 5.0, "Tailor", null, 0.38, 1.63, 0.5, 1.0 ), + new SkillInfo( 35, "Animal Taming", 14.0, 2.0, 4.0, "Tamer", null, 1.4, 0.2, 0.4, 1.0 ), + new SkillInfo( 36, "Taste Identification", 0.0, 0.0, 0.0, "Chef", null, 0.2, 0.0, 0.8, 1.0 ), + new SkillInfo( 37, "Tinkering", 5.0, 2.0, 3.0, "Tinker", null, 0.5, 0.2, 0.3, 1.0 ), + new SkillInfo( 38, "Tracking", 0.0, 12.5, 12.5, "Ranger", null, 0.0, 1.25, 1.25, 1.0 ), + new SkillInfo( 39, "Veterinary", 8.0, 4.0, 8.0, "Veterinarian", null, 0.8, 0.4, 0.8, 1.0 ), + new SkillInfo( 40, "Swordsmanship", 7.5, 2.5, 0.0, "Swordsman", null, 0.75, 0.25, 0.0, 1.0 ), + new SkillInfo( 41, "Mace Fighting", 9.0, 1.0, 0.0, "Armsman", null, 0.9, 0.1, 0.0, 1.0 ), + new SkillInfo( 42, "Fencing", 4.5, 5.5, 0.0, "Fencer", null, 0.45, 0.55, 0.0, 1.0 ), + new SkillInfo( 43, "Wrestling", 9.0, 1.0, 0.0, "Wrestler", null, 0.9, 0.1, 0.0, 1.0 ), + new SkillInfo( 44, "Lumberjacking", 20.0, 0.0, 0.0, "Lumberjack", null, 2.0, 0.0, 0.0, 1.0 ), + new SkillInfo( 45, "Mining", 20.0, 0.0, 0.0, "Miner", null, 2.0, 0.0, 0.0, 1.0 ), + new SkillInfo( 46, "Meditation", 0.0, 0.0, 0.0, "Stoic", null, 0.0, 0.0, 0.0, 1.0 ), + new SkillInfo( 47, "Stealth", 0.0, 0.0, 0.0, "Rogue", null, 0.0, 0.0, 0.0, 1.0 ), + new SkillInfo( 48, "Remove Trap", 0.0, 0.0, 0.0, "Rogue", null, 0.0, 0.0, 0.0, 1.0 ), + new SkillInfo( 49, "Necromancy", 0.0, 0.0, 0.0, "Necromancer", null, 0.0, 0.0, 0.0, 1.0 ), + new SkillInfo( 50, "Focus", 0.0, 0.0, 0.0, "Stoic", null, 0.0, 0.0, 0.0, 1.0 ), + new SkillInfo( 51, "Chivalry", 0.0, 0.0, 0.0, "Paladin", null, 0.0, 0.0, 0.0, 1.0 ), + new SkillInfo( 52, "Bushido", 0.0, 0.0, 0.0, "Samurai", null, 0.0, 0.0, 0.0, 1.0 ), + new SkillInfo( 53, "Ninjitsu", 0.0, 0.0, 0.0, "Ninja", null, 0.0, 0.0, 0.0, 1.0 ), + new SkillInfo( 54, "Spellweaving", 0.0, 0.0, 0.0, "Arcanist", null, 0.0, 0.0, 0.0, 1.0 ), + new SkillInfo( 55, "Mysticism", 0.0, 0.0, 0.0, "Mystic", null, 0.0, 0.0, 0.0, 1.0 ), + new SkillInfo( 56, "Imbuing", 0.0, 0.0, 0.0, "Artificer", null, 0.0, 0.0, 0.0, 1.0 ), + new SkillInfo( 57, "Throwing", 0.0, 0.0, 0.0, "Bladeweaving", null, 0.0, 0.0, 0.0, 1.0 ), }; public static SkillInfo[] Table @@ -856,6 +862,15 @@ namespace Server [CommandProperty( AccessLevel.Counselor )] public Skill Spellweaving { get { return this[SkillName.Spellweaving]; } set { } } + [CommandProperty( AccessLevel.Counselor )] + public Skill Mysticism { get { return this[SkillName.Mysticism]; } set { } } + + [CommandProperty( AccessLevel.Counselor )] + public Skill Imbuing { get { return this[SkillName.Imbuing]; } set { } } + + [CommandProperty( AccessLevel.Counselor )] + public Skill Throwing { get { return this[SkillName.Throwing]; } set { } } + #endregion [CommandProperty( AccessLevel.Counselor, AccessLevel.GameMaster )]