From 9f0a67e5d79ca31a944ab1471a66368e812f1957 Mon Sep 17 00:00:00 2001 From: eos Date: Wed, 21 Mar 2012 22:25:44 +0000 Subject: [PATCH] - Added a new Assemblies.cfg file (Assemblies_4_0.cfg) specific for .NET 4.0, which includes System.Core.dll by default. - Fixed cu sidhe and reptalon trade statuettes. - Made IAccount comparable, to be able to sort by account in-game. - Fixed item leak in ChampionSpawn and Harrower. - Added ChampionSpawn and Harrower leaked item types to Cleanup. - Added a helper for handling validation after deserialization, and converted classes using that technique to the new system. - Fixed bulletin board item leak, and the core bug that caused it. Leaked items will be cleaned up on server boot. - Fixed bulletin board message content packet to compensate for a client bug. - Monster AI is now deactivated on the internal map, like it is on inactive sectors. - Monster AI activity is now checked on map changes as well, not just location changes. - Corrected hiding requirement needed to train stealth from an NPC for Core.ML. - Fixed a SendLocalizedMessage overload calling itself. --- Data/Assemblies.cfg | 3 - Data/Assemblies_4_0.cfg | 7 +++ Data/shrink.cfg | 5 ++ Scripts/Accounting/Account.cs | 8 +++ Scripts/Engines/CannedEvil/ChampionSpawn.cs | 6 +- Scripts/Items/Addons/ArcaneCircleAddon.cs | 39 +++++-------- Scripts/Items/Aquarium/Aquarium.cs | 17 +----- Scripts/Items/Misc/BulletinBoards.cs | 30 ++++++++-- Scripts/Misc/Cleanup.cs | 23 +++++++- Scripts/Misc/ValidationQueue.cs | 57 +++++++++++++++++++ Scripts/Mobiles/AI/BaseAI.cs | 2 + Scripts/Mobiles/BaseCreature.cs | 23 ++++++-- Scripts/Mobiles/Familiars/BaseFamiliar.cs | 21 ++----- .../Monsters/ML/Twisted Weald/Changeling.cs | 17 +----- Scripts/Mobiles/Special/Harrower.cs | 8 ++- Scripts/Skills/Stealth.cs | 12 ++-- Server/IAccount.cs | 2 +- Server/Item.cs | 6 +- Server/Mobile.cs | 2 +- Server/ScriptCompiler.cs | 4 ++ 20 files changed, 191 insertions(+), 101 deletions(-) create mode 100644 Data/Assemblies_4_0.cfg create mode 100644 Scripts/Misc/ValidationQueue.cs diff --git a/Data/Assemblies.cfg b/Data/Assemblies.cfg index a350fe9df..af921f9c2 100644 --- a/Data/Assemblies.cfg +++ b/Data/Assemblies.cfg @@ -1,9 +1,6 @@ System.dll -#Uncomment the following line for full C# 4.0 support. -#System.Core.dll System.Web.dll System.Xml.dll System.Data.dll System.Drawing.dll System.Windows.Forms.dll - diff --git a/Data/Assemblies_4_0.cfg b/Data/Assemblies_4_0.cfg new file mode 100644 index 000000000..b38b50d2d --- /dev/null +++ b/Data/Assemblies_4_0.cfg @@ -0,0 +1,7 @@ +System.dll +System.Core.dll +System.Web.dll +System.Xml.dll +System.Data.dll +System.Drawing.dll +System.Windows.Forms.dll diff --git a/Data/shrink.cfg b/Data/shrink.cfg index 46ae209b1..eac18e938 100644 --- a/Data/shrink.cfg +++ b/Data/shrink.cfg @@ -354,3 +354,8 @@ 253 0x2773 245 0x281B 169 0x281C + +#ML Mobiles + +276 0x2D95 +277 0x2D96 diff --git a/Scripts/Accounting/Account.cs b/Scripts/Accounting/Account.cs index ce9be7c38..c4895aa5e 100644 --- a/Scripts/Accounting/Account.cs +++ b/Scripts/Accounting/Account.cs @@ -1188,6 +1188,14 @@ namespace Server.Accounting return m_Username.CompareTo( other.m_Username ); } + public int CompareTo( IAccount other ) + { + if ( other == null ) + return -1; + + return m_Username.CompareTo( other.Username ); + } + public int CompareTo( object obj ) { if ( obj is Account ) diff --git a/Scripts/Engines/CannedEvil/ChampionSpawn.cs b/Scripts/Engines/CannedEvil/ChampionSpawn.cs index 05ebb5790..316ac9dd5 100644 --- a/Scripts/Engines/CannedEvil/ChampionSpawn.cs +++ b/Scripts/Engines/CannedEvil/ChampionSpawn.cs @@ -1060,12 +1060,14 @@ namespace Server.Engines.CannedEvil { totalDamage += kvp.Value; - if( totalDamage > randomDamage ) + if( totalDamage >= randomDamage ) { GiveArtifact( kvp.Key, artifact ); - break; + return; } } + + artifact.Delete(); } public void GiveArtifact( Mobile to, Item artifact ) diff --git a/Scripts/Items/Addons/ArcaneCircleAddon.cs b/Scripts/Items/Addons/ArcaneCircleAddon.cs index 128c0e61f..e88704ce1 100644 --- a/Scripts/Items/Addons/ArcaneCircleAddon.cs +++ b/Scripts/Items/Addons/ArcaneCircleAddon.cs @@ -33,31 +33,6 @@ namespace Server.Items writer.WriteEncodedInt( 1 ); // version } - private static List m_ToFix; - - public static void Configure() - { - m_ToFix = new List(); - } - - public static void Initialize() - { - foreach ( ArcaneCircleAddon ac in m_ToFix ) - { - foreach ( AddonComponent c in ac.Components ) - { - if ( c.ItemID == 0x3083 ) - { - c.Offset = new Point3D( -1, -1, 0 ); - c.MoveToWorld( new Point3D( ac.X + c.Offset.X, ac.Y + c.Offset.Y, ac.Z + c.Offset.Z ), ac.Map ); - } - } - } - - m_ToFix.Clear(); - m_ToFix = null; - } - public override void Deserialize( GenericReader reader ) { base.Deserialize( reader ); @@ -65,7 +40,19 @@ namespace Server.Items int version = reader.ReadEncodedInt(); if ( version == 0 ) - m_ToFix.Add( this ); + ValidationQueue.Add( this ); + } + + public void Validate() + { + foreach ( AddonComponent c in Components ) + { + if ( c.ItemID == 0x3083 ) + { + c.Offset = new Point3D( -1, -1, 0 ); + c.MoveToWorld( new Point3D( X + c.Offset.X, Y + c.Offset.Y, Z + c.Offset.Z ), Map ); + } + } } } diff --git a/Scripts/Items/Aquarium/Aquarium.cs b/Scripts/Items/Aquarium/Aquarium.cs index ef1a2dc17..1f69e1762 100644 --- a/Scripts/Items/Aquarium/Aquarium.cs +++ b/Scripts/Items/Aquarium/Aquarium.cs @@ -465,7 +465,7 @@ namespace Server.Items } if ( version < 3 ) - m_Recount.Add( this ); + ValidationQueue.Add( this ); } private void RecountLiveCreatures() @@ -480,20 +480,9 @@ namespace Server.Items } } - private static List m_Recount; - - public static void Configure() + public void Validate() { - m_Recount = new List(); - } - - public static void Initialize() - { - foreach ( Aquarium aquarium in m_Recount ) - aquarium.RecountLiveCreatures(); - - m_Recount.Clear(); - m_Recount = null; + RecountLiveCreatures(); } #region Members diff --git a/Scripts/Items/Misc/BulletinBoards.cs b/Scripts/Items/Misc/BulletinBoards.cs index 965c7a5b0..be4cf55ea 100644 --- a/Scripts/Items/Misc/BulletinBoards.cs +++ b/Scripts/Items/Misc/BulletinBoards.cs @@ -403,7 +403,7 @@ namespace Server.Items { base.Serialize( writer ); - writer.Write( (int) 0 ); // version + writer.Write( (int) 1 ); // version writer.Write( (Mobile) m_Poster ); writer.Write( (string) m_Subject ); @@ -437,6 +437,7 @@ namespace Server.Items switch ( version ) { + case 1: case 0: { m_Poster = reader.ReadMobile(); @@ -465,10 +466,19 @@ namespace Server.Items if ( hasThread && m_Thread == null ) Delete(); + if ( version == 0 ) + ValidationQueue.Add( this ); + break; } } } + + public void Validate() + { + if ( !( Parent is BulletinBoard && ((BulletinBoard)Parent).Items.Contains( this ) ) ) + Delete(); + } } public class BBDisplayBoard : Packet @@ -593,20 +603,30 @@ namespace Server.Items m_Stream.Write( (byte) len ); for ( int i = 0; i < len; ++i ) - WriteString( msg.Lines[i] ); + WriteString( msg.Lines[i], true ); } public void WriteString( string v ) + { + WriteString( v, false ); + } + + public void WriteString( string v, bool padding ) { byte[] buffer = Utility.UTF8.GetBytes( v ); - int len = buffer.Length + 1; + int tail = padding ? 2 : 1; + int len = buffer.Length + tail; if ( len > 255 ) len = 255; m_Stream.Write( (byte) len ); - m_Stream.Write( buffer, 0, len-1 ); - m_Stream.Write( (byte) 0 ); + m_Stream.Write( buffer, 0, len - tail ); + + if ( padding ) + m_Stream.Write( (short) 0 ); // padding compensates for a client bug + else + m_Stream.Write( (byte) 0 ); } public string SafeString( string v ) diff --git a/Scripts/Misc/Cleanup.cs b/Scripts/Misc/Cleanup.cs index 1b69026fe..292da49a2 100644 --- a/Scripts/Misc/Cleanup.cs +++ b/Scripts/Misc/Cleanup.cs @@ -141,8 +141,27 @@ namespace Server.Misc || item is TreasureMap || item is MessageInABottle || item is BaseArmor || item is BaseWeapon || item is BaseClothing - || (item is BaseJewel && Core.AOS) - || (item is BasePotion && Core.ML)) + || ( item is BaseJewel && Core.AOS ) + || ( item is BasePotion && Core.ML ) + #region Champion artifacts + || item is SkullPole + || item is EvilIdolSkull + || item is MonsterStatuette + || item is Pier + || item is ArtifactLargeVase + || item is ArtifactVase + || item is MinotaurStatueDeed + || item is SwampTile + || item is WallBlood + || item is TatteredAncientMummyWrapping + || item is LavaTile + || item is DemonSkull + || item is Web + || item is WaterTile + || item is WindSpirit + || item is DirtPatch + || item is Futon ) + #endregion return true; return false; diff --git a/Scripts/Misc/ValidationQueue.cs b/Scripts/Misc/ValidationQueue.cs new file mode 100644 index 000000000..bca24285d --- /dev/null +++ b/Scripts/Misc/ValidationQueue.cs @@ -0,0 +1,57 @@ +using System; +using System.Collections.Generic; +using System.Reflection; +using Server; + +namespace Server +{ + public delegate void ValidationEventHandler(); + + public static class ValidationQueue + { + public static event ValidationEventHandler StartValidation; + + public static void Initialize() + { + if ( StartValidation != null ) + StartValidation(); + + StartValidation = null; + } + } + + public static class ValidationQueue + { + private static List m_Queue; + + static ValidationQueue() + { + m_Queue = new List(); + ValidationQueue.StartValidation += new ValidationEventHandler( ValidateAll ); + } + + public static void Add( T obj ) + { + m_Queue.Add( obj ); + } + + private static void ValidateAll() + { + Type type = typeof( T ); + + if ( type != null ) + { + MethodInfo m = type.GetMethod( "Validate", BindingFlags.Instance | BindingFlags.Public ); + + if ( m != null ) + { + for ( int i = 0; i < m_Queue.Count; ++i ) + m.Invoke( m_Queue[i], null ); + } + } + + m_Queue.Clear(); + m_Queue = null; + } + } +} diff --git a/Scripts/Mobiles/AI/BaseAI.cs b/Scripts/Mobiles/AI/BaseAI.cs index 1ebadaaea..2ae4c35bc 100644 --- a/Scripts/Mobiles/AI/BaseAI.cs +++ b/Scripts/Mobiles/AI/BaseAI.cs @@ -2704,6 +2704,7 @@ namespace Server.Mobiles } else if( m_Owner.m_Mobile.Map == null || m_Owner.m_Mobile.Map == Map.Internal ) { + m_Owner.Deactivate(); return; } else if( m_Owner.m_Mobile.PlayerRangeSensitive )//have to check this in the timer.... @@ -2725,6 +2726,7 @@ namespace Server.Mobiles } else if( m_Owner.m_Mobile.Map == null || m_Owner.m_Mobile.Map == Map.Internal ) { + m_Owner.Deactivate(); return; } diff --git a/Scripts/Mobiles/BaseCreature.cs b/Scripts/Mobiles/BaseCreature.cs index 6b6e62d73..1d20d22b7 100644 --- a/Scripts/Mobiles/BaseCreature.cs +++ b/Scripts/Mobiles/BaseCreature.cs @@ -11,6 +11,7 @@ using Server.ContextMenus; using Server.Engines.Quests; using Server.Engines.PartySystem; using Server.Factions; +using Server.SkillHandlers; using Server.Spells.Bushido; using Server.Spells.Spellweaving; using Server.Spells.Necromancy; @@ -2948,7 +2949,7 @@ namespace Server.Mobiles if ( !CanTeach ) return false; - if( skill == SkillName.Stealth && from.Skills[SkillName.Hiding].Base < ((Core.SE) ? 50.0 : 80.0) ) + if( skill == SkillName.Stealth && from.Skills[SkillName.Hiding].Base < Stealth.HidingRequirement ) return false; if ( skill == SkillName.RemoveTrap && (from.Skills[SkillName.Lockpicking].Base < 50.0 || from.Skills[SkillName.DetectHidden].Base < 50.0) ) @@ -3382,12 +3383,24 @@ namespace Server.Mobiles return true; // entered idle state } + private void CheckAIActive() + { + Map map = Map; + + if ( PlayerRangeSensitive && m_AI != null && map != null && map.GetSector( Location ).Active ) + m_AI.Activate(); + } + + protected override void OnMapChange( Map oldMap ) + { + CheckAIActive(); + + base.OnMapChange( oldMap ); + } + protected override void OnLocationChange( Point3D oldLocation ) { - Map map = this.Map; - - if ( PlayerRangeSensitive && m_AI != null && map != null && map.GetSector( this.Location ).Active ) - m_AI.Activate(); + CheckAIActive(); base.OnLocationChange( oldLocation ); } diff --git a/Scripts/Mobiles/Familiars/BaseFamiliar.cs b/Scripts/Mobiles/Familiars/BaseFamiliar.cs index 028944efc..a250165d7 100644 --- a/Scripts/Mobiles/Familiars/BaseFamiliar.cs +++ b/Scripts/Mobiles/Familiars/BaseFamiliar.cs @@ -123,26 +123,13 @@ namespace Server.Mobiles int version = reader.ReadInt(); - m_ToRemove.Add( this ); + ValidationQueue.Add( this ); } - private static List m_ToRemove; - - public static void Configure() + public void Validate() { - m_ToRemove = new List(); - } - - public static void Initialize() - { - foreach( BaseFamiliar f in m_ToRemove ) - { - f.DropPackContents(); - f.Delete(); - } - - m_ToRemove.Clear(); - m_ToRemove = null; + DropPackContents(); + Delete(); } private class ReleaseEntry : ContextMenuEntry diff --git a/Scripts/Mobiles/Monsters/ML/Twisted Weald/Changeling.cs b/Scripts/Mobiles/Monsters/ML/Twisted Weald/Changeling.cs index 746262144..c2e5af1fa 100644 --- a/Scripts/Mobiles/Monsters/ML/Twisted Weald/Changeling.cs +++ b/Scripts/Mobiles/Monsters/ML/Twisted Weald/Changeling.cs @@ -264,23 +264,12 @@ namespace Server.Mobiles int version = reader.ReadInt(); if ( reader.ReadBool() ) - m_ToRevert.Add( this ); + ValidationQueue.Add( this ); } - private static List m_ToRevert; - - public static void Configure() + public void Validate() { - m_ToRevert = new List(); - } - - public static void Initialize() - { - foreach ( Changeling c in m_ToRevert ) - c.Revert(); - - m_ToRevert.Clear(); - m_ToRevert = null; + Revert(); } private class ClonedItem : Item diff --git a/Scripts/Mobiles/Special/Harrower.cs b/Scripts/Mobiles/Special/Harrower.cs index 66cea06e5..9292432be 100644 --- a/Scripts/Mobiles/Special/Harrower.cs +++ b/Scripts/Mobiles/Special/Harrower.cs @@ -450,16 +450,18 @@ namespace Server.Mobiles totalDamage = 0; - foreach (KeyValuePair kvp in m_DamageEntries) + foreach (KeyValuePair kvp in validEntries) { totalDamage += kvp.Value; - if( totalDamage > randomDamage ) + if( totalDamage >= randomDamage ) { GiveArtifact( kvp.Key, artifact ); - break; + return; } } + + artifact.Delete(); } public void GiveArtifact( Mobile to, Item artifact ) diff --git a/Scripts/Skills/Stealth.cs b/Scripts/Skills/Stealth.cs index 884844849..27342b79a 100644 --- a/Scripts/Skills/Stealth.cs +++ b/Scripts/Skills/Stealth.cs @@ -11,7 +11,9 @@ namespace Server.SkillHandlers SkillInfo.Table[(int)SkillName.Stealth].Callback = new SkillUseCallback( OnUse ); } - public static int[,] ArmorTable{ get { return m_ArmorTable; } } + public static double HidingRequirement { get { return ( Core.ML ? 30.0 : ( Core.SE ? 50.0 : 80.0 ) ); } } + + public static int[,] ArmorTable { get { return m_ArmorTable; } } private static int[,] m_ArmorTable = new int[,] { // Gorget Gloves Helmet Arms Legs Chest Shield @@ -32,7 +34,7 @@ namespace Server.SkillHandlers { if( !Core.AOS ) return (int)m.ArmorRating; - + int ar = 0; for( int i = 0; i < m.Items.Count; i++ ) @@ -61,7 +63,7 @@ namespace Server.SkillHandlers { m.SendLocalizedMessage( 502725 ); // You must hide first } - else if ( m.Skills[SkillName.Hiding].Base < ((Core.ML) ? 30.0 : (Core.SE) ? 50.0 : 80.0) ) + else if ( m.Skills[SkillName.Hiding].Base < HidingRequirement ) { m.SendLocalizedMessage( 502726 ); // You are not hidden well enough. Become better at hiding. m.RevealingAction(); @@ -75,7 +77,7 @@ namespace Server.SkillHandlers { int armorRating = GetArmorRating( m ); - if( armorRating >= (Core.AOS ? 42 : 26) ) //I have a hunch '42' was chosen cause someone's a fan of DNA + if( armorRating >= (Core.AOS ? 42 : 26) ) //I have a hunch '42' was chosen cause someone's a fan of DNA { m.SendLocalizedMessage( 502727 ); // You could not hope to move quietly wearing this much armor. m.RevealingAction(); @@ -92,7 +94,7 @@ namespace Server.SkillHandlers PlayerMobile pm = m as PlayerMobile; // IsStealthing should be moved to Server.Mobiles if( pm != null ) - pm.IsStealthing = true; + pm.IsStealthing = true; m.SendLocalizedMessage( 502730 ); // You begin to move quietly. diff --git a/Server/IAccount.cs b/Server/IAccount.cs index 27cc15b71..1919dcf7b 100644 --- a/Server/IAccount.cs +++ b/Server/IAccount.cs @@ -22,7 +22,7 @@ using System; namespace Server.Accounting { - public interface IAccount + public interface IAccount : IComparable { string Username { get; set; } AccessLevel AccessLevel { get; set; } diff --git a/Server/Item.cs b/Server/Item.cs index 95f41021c..16d709070 100644 --- a/Server/Item.cs +++ b/Server/Item.cs @@ -812,16 +812,16 @@ namespace Server { Container cont = this as Container; - if ( cont.m_Items == null ) { + if ( cont.m_Items == null ) cont.m_Items = new List(); - } return cont.m_Items; } CompactInfo info = AcquireCompactInfo(); - info.m_Items = new List(); + if ( info.m_Items == null ) + info.m_Items = new List(); return info.m_Items; } diff --git a/Server/Mobile.cs b/Server/Mobile.cs index ed299867c..35795eaff 100644 --- a/Server/Mobile.cs +++ b/Server/Mobile.cs @@ -10696,7 +10696,7 @@ namespace Server public void SendLocalizedMessage( int number, bool append, string affix, string args ) { - SendLocalizedMessage( number, append, affix, args ); + SendLocalizedMessage( number, append, affix, args, 0x3B2 ); } public void SendLocalizedMessage( int number, bool append, string affix, string args, int hue ) diff --git a/Server/ScriptCompiler.cs b/Server/ScriptCompiler.cs index d9667b111..e97251b27 100644 --- a/Server/ScriptCompiler.cs +++ b/Server/ScriptCompiler.cs @@ -55,7 +55,11 @@ namespace Server { List list = new List(); +#if Framework_4_0 + string path = Path.Combine( Core.BaseDirectory, "Data/Assemblies_4_0.cfg" ); +#else string path = Path.Combine( Core.BaseDirectory, "Data/Assemblies.cfg" ); +#endif if( File.Exists( path ) ) {