- 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.
This commit is contained in:
eos 2012-03-21 22:25:44 +00:00
parent 65536e1667
commit 9f0a67e5d7
20 changed files with 191 additions and 101 deletions

View file

@ -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

7
Data/Assemblies_4_0.cfg Normal file
View file

@ -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

View file

@ -354,3 +354,8 @@
253 0x2773
245 0x281B
169 0x281C
#ML Mobiles
276 0x2D95
277 0x2D96

View file

@ -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 )

View file

@ -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 )

View file

@ -33,31 +33,6 @@ namespace Server.Items
writer.WriteEncodedInt( 1 ); // version
}
private static List<ArcaneCircleAddon> m_ToFix;
public static void Configure()
{
m_ToFix = new List<ArcaneCircleAddon>();
}
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<ArcaneCircleAddon>.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 );
}
}
}
}

View file

@ -465,7 +465,7 @@ namespace Server.Items
}
if ( version < 3 )
m_Recount.Add( this );
ValidationQueue<Aquarium>.Add( this );
}
private void RecountLiveCreatures()
@ -480,20 +480,9 @@ namespace Server.Items
}
}
private static List<Aquarium> m_Recount;
public static void Configure()
public void Validate()
{
m_Recount = new List<Aquarium>();
}
public static void Initialize()
{
foreach ( Aquarium aquarium in m_Recount )
aquarium.RecountLiveCreatures();
m_Recount.Clear();
m_Recount = null;
RecountLiveCreatures();
}
#region Members

View file

@ -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<BulletinMessage>.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 )

View file

@ -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;

View file

@ -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<T>
{
private static List<T> m_Queue;
static ValidationQueue()
{
m_Queue = new List<T>();
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;
}
}
}

View file

@ -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;
}

View file

@ -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 );
}

View file

@ -123,26 +123,13 @@ namespace Server.Mobiles
int version = reader.ReadInt();
m_ToRemove.Add( this );
ValidationQueue<BaseFamiliar>.Add( this );
}
private static List<BaseFamiliar> m_ToRemove;
public static void Configure()
public void Validate()
{
m_ToRemove = new List<BaseFamiliar>();
}
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

View file

@ -264,23 +264,12 @@ namespace Server.Mobiles
int version = reader.ReadInt();
if ( reader.ReadBool() )
m_ToRevert.Add( this );
ValidationQueue<Changeling>.Add( this );
}
private static List<Changeling> m_ToRevert;
public static void Configure()
public void Validate()
{
m_ToRevert = new List<Changeling>();
}
public static void Initialize()
{
foreach ( Changeling c in m_ToRevert )
c.Revert();
m_ToRevert.Clear();
m_ToRevert = null;
Revert();
}
private class ClonedItem : Item

View file

@ -450,16 +450,18 @@ namespace Server.Mobiles
totalDamage = 0;
foreach (KeyValuePair<Mobile, int> kvp in m_DamageEntries)
foreach (KeyValuePair<Mobile, int> 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 )

View file

@ -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.

View file

@ -22,7 +22,7 @@ using System;
namespace Server.Accounting
{
public interface IAccount
public interface IAccount : IComparable<IAccount>
{
string Username { get; set; }
AccessLevel AccessLevel { get; set; }

View file

@ -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<Item>();
}
return cont.m_Items;
}
CompactInfo info = AcquireCompactInfo();
info.m_Items = new List<Item>();
if ( info.m_Items == null )
info.m_Items = new List<Item>();
return info.m_Items;
}

View file

@ -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 )

View file

@ -55,7 +55,11 @@ namespace Server
{
List<string> list = new List<string>();
#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 ) )
{