diff --git a/Server/Main.cs b/Server/Main.cs index bc6442156..f69ca09a4 100644 --- a/Server/Main.cs +++ b/Server/Main.cs @@ -28,6 +28,10 @@ using System.Reflection; using System.Runtime.InteropServices; using System.Text; using System.Threading; +#if Framework_4_0 +using System.Threading.Tasks; +#endif + using Server; using Server.Accounting; using Server.Gumps; @@ -586,80 +590,95 @@ namespace Server VerifySerialization( ScriptCompiler.Assemblies[a] ); } + private static readonly Type[] m_SerialTypeArray = new Type[1] { typeof(Serial) }; + + private static void VerifyType( Type t ) + { + bool isItem = t.IsSubclassOf(typeof(Item)); + + if (isItem || t.IsSubclassOf(typeof(Mobile))) + { + if (isItem) + { + //++m_ItemCount; + Interlocked.Increment(ref m_ItemCount); + } + else + { + //++m_MobileCount; + Interlocked.Increment(ref m_MobileCount); + } + + StringBuilder warningSb = null; + + try + { + /* + if( isItem && t.IsPublic && !t.IsAbstract ) + { + ConstructorInfo cInfo = t.GetConstructor( Type.EmptyTypes ); + + if( cInfo == null ) + { + if (warningSb == null) + warningSb = new StringBuilder(); + + warningSb.AppendLine(" - No zero paramater constructor"); + } + }*/ + + if (t.GetConstructor(m_SerialTypeArray) == null) + { + if (warningSb == null) + warningSb = new StringBuilder(); + + warningSb.AppendLine(" - No serialization constructor"); + } + + if (t.GetMethod("Serialize", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly) == null) + { + if (warningSb == null) + warningSb = new StringBuilder(); + + warningSb.AppendLine(" - No Serialize() method"); + } + + if (t.GetMethod("Deserialize", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly) == null) + { + if (warningSb == null) + warningSb = new StringBuilder(); + + warningSb.AppendLine(" - No Deserialize() method"); + } + + if (warningSb != null && warningSb.Length > 0) + { + Console.WriteLine("Warning: {0}\n{1}", t, warningSb.ToString()); + } + } + catch + { + Console.WriteLine("Warning: Exception in serialization verification of type {0}", t); + } + } + } + private static void VerifySerialization( Assembly a ) { if( a == null ) return; - Type[] ctorTypes = new Type[] { typeof( Serial ) }; - - foreach( Type t in a.GetTypes() ) - { - bool isItem = t.IsSubclassOf( typeof( Item ) ); - - if( isItem || t.IsSubclassOf( typeof( Mobile ) ) ) +#if Framework_4_0 + Parallel.ForEach(a.GetTypes(), t => { - if( isItem ) - ++m_ItemCount; - else - ++m_MobileCount; - - bool warned = false; - - try - { - - /* - if( isItem && t.IsPublic && !t.IsAbstract ) - { - ConstructorInfo cInfo = t.GetConstructor( Type.EmptyTypes ); - if( cInfo == null ) - { - if( !warned ) - Console.WriteLine( "Warning: {0}", t ); - - warned = true; - Console.WriteLine( " - No zero paramater constructor" ); - } - } - */ - - if( t.GetConstructor( ctorTypes ) == null ) - { - if( !warned ) - Console.WriteLine( "Warning: {0}", t ); - - warned = true; - Console.WriteLine( " - No serialization constructor" ); - } - - if( t.GetMethod( "Serialize", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly ) == null ) - { - if( !warned ) - Console.WriteLine( "Warning: {0}", t ); - - warned = true; - Console.WriteLine( " - No Serialize() method" ); - } - - if( t.GetMethod( "Deserialize", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly ) == null ) - { - if( !warned ) - Console.WriteLine( "Warning: {0}", t ); - - warned = true; - Console.WriteLine( " - No Deserialize() method" ); - } - - if( warned ) - Console.WriteLine(); - } - catch - { - Console.WriteLine( "Warning: Exception in serialization verification of type {0}", t ); - } - } + VerifyType(t); + }); +#else + foreach (Type t in a.GetTypes()) + { + VerifyType(t); } +#endif } } diff --git a/Server/ScriptCompiler.cs b/Server/ScriptCompiler.cs index 5f9ca202c..9c6d9c6c1 100644 --- a/Server/ScriptCompiler.cs +++ b/Server/ScriptCompiler.cs @@ -29,6 +29,7 @@ using System.Reflection; using System.Security.Cryptography; using Microsoft.CSharp; using Microsoft.VisualBasic; +using System.Diagnostics; namespace Server { @@ -583,8 +584,14 @@ namespace Server m_Assemblies = assemblies.ToArray(); Console.Write( "Scripts: Verifying..." ); + + Stopwatch watch = Stopwatch.StartNew(); + Core.VerifySerialization(); - Console.WriteLine( "done ({0} items, {1} mobiles)", Core.ScriptItems, Core.ScriptMobiles ); + + watch.Stop(); + + Console.WriteLine("done ({0} items, {1} mobiles) ({2:F2} seconds)", Core.ScriptItems, Core.ScriptMobiles, watch.Elapsed.TotalSeconds); return true; } diff --git a/Server/World.cs b/Server/World.cs index 44907116a..0e360e74e 100644 --- a/Server/World.cs +++ b/Server/World.cs @@ -286,6 +286,62 @@ namespace Server { get { return m_LoadingType; } } + private static readonly Type[] m_SerialTypeArray = new Type[1] { typeof(Serial) }; + + //TODO, when fully migrated to .NET 4.0: + //private static List> ReadTypes( BinaryReader tdbReader ) + private static List ReadTypes( BinaryReader tdbReader ) + { + int count = tdbReader.ReadInt32(); + + List types = new List(count); + + for (int i = 0; i < count; ++i) + { + string typeName = tdbReader.ReadString(); + + Type t = ScriptCompiler.FindTypeByFullName(typeName); + + if (t == null) + { + Console.WriteLine("failed"); + + if (!Core.Service) + { + Console.WriteLine("Error: Type '{0}' was not found. Delete all of those types? (y/n)", typeName); + + if (Console.ReadKey(true).Key == ConsoleKey.Y) + { + types.Add(null); + Console.Write("World: Loading..."); + continue; + } + + Console.WriteLine("Types will not be deleted. An exception will be thrown."); + } + else + { + Console.WriteLine("Error: Type '{0}' was not found.", typeName); + } + + throw new Exception(String.Format("Bad type '{0}'", typeName)); + } + + ConstructorInfo ctor = t.GetConstructor(m_SerialTypeArray); + + if (ctor != null) + { + types.Add(new object[] { ctor, typeName }); + } + else + { + throw new Exception(String.Format("Type '{0}' does not have a serialization constructor", t)); + } + } + + return types; + } + public static void Load() { if ( m_Loaded ) return; @@ -305,7 +361,6 @@ namespace Server { int mobileCount = 0, itemCount = 0, guildCount = 0; object[] ctorArgs = new object[1]; - Type[] ctorTypes = new Type[1] { typeof( Serial ) }; List items = new List(); List mobiles = new List(); @@ -318,43 +373,7 @@ namespace Server { using ( FileStream tdb = new FileStream( MobileTypesPath, FileMode.Open, FileAccess.Read, FileShare.Read ) ) { BinaryReader tdbReader = new BinaryReader( tdb ); - int count = tdbReader.ReadInt32(); - - ArrayList types = new ArrayList( count ); - - for ( int i = 0; i < count; ++i ) { - string typeName = tdbReader.ReadString(); - - Type t = ScriptCompiler.FindTypeByFullName( typeName ); - - if ( t == null ) { - Console.WriteLine( "failed" ); - - if ( !Core.Service ) { - Console.WriteLine( "Error: Type '{0}' was not found. Delete all of those types? (y/n)", typeName ); - - if ( Console.ReadKey( true ).Key == ConsoleKey.Y ) { - types.Add( null ); - Console.Write( "World: Loading..." ); - continue; - } - - Console.WriteLine( "Types will not be deleted. An exception will be thrown." ); - } else { - Console.WriteLine( "Error: Type '{0}' was not found.", typeName ); - } - - throw new Exception( String.Format( "Bad type '{0}'", typeName ) ); - } - - ConstructorInfo ctor = t.GetConstructor( ctorTypes ); - - if ( ctor != null ) { - types.Add( new object[] { ctor, null } ); - } else { - throw new Exception( String.Format( "Type '{0}' does not have a serialization constructor", t ) ); - } - } + List types = ReadTypes( tdbReader ); mobileCount = idxReader.ReadInt32(); @@ -366,7 +385,7 @@ namespace Server { long pos = idxReader.ReadInt64(); int length = idxReader.ReadInt32(); - object[] objs = ( object[] ) types[typeID]; + object[] objs = types[typeID]; if ( objs == null ) continue; @@ -403,44 +422,7 @@ namespace Server { using ( FileStream tdb = new FileStream( ItemTypesPath, FileMode.Open, FileAccess.Read, FileShare.Read ) ) { BinaryReader tdbReader = new BinaryReader( tdb ); - int count = tdbReader.ReadInt32(); - - ArrayList types = new ArrayList( count ); - - for ( int i = 0; i < count; ++i ) { - string typeName = tdbReader.ReadString(); - - Type t = ScriptCompiler.FindTypeByFullName( typeName ); - - if ( t == null ) { - Console.WriteLine( "failed" ); - - - if ( !Core.Service ) { - Console.WriteLine( "Error: Type '{0}' was not found. Delete all of those types? (y/n)", typeName ); - - if ( Console.ReadKey( true ).Key == ConsoleKey.Y ) { - types.Add( null ); - Console.Write( "World: Loading..." ); - continue; - } - - Console.WriteLine( "Types will not be deleted. An exception will be thrown." ); - } else { - Console.WriteLine( "Error: Type '{0}' was not found.", typeName ); - } - - throw new Exception( String.Format( "Bad type '{0}'", typeName ) ); - } - - ConstructorInfo ctor = t.GetConstructor( ctorTypes ); - - if ( ctor != null ) { - types.Add( new object[] { ctor, typeName } ); - } else { - throw new Exception( String.Format( "Type '{0}' does not have a serialization constructor", t ) ); - } - } + List types = ReadTypes( tdbReader ); itemCount = idxReader.ReadInt32(); @@ -452,7 +434,7 @@ namespace Server { long pos = idxReader.ReadInt64(); int length = idxReader.ReadInt32(); - object[] objs = ( object[] ) types[typeID]; + object[] objs = types[typeID]; if ( objs == null ) continue;