additional network level parallelization
ai target acquisition parallelization better pooled enumerator thread safety
This commit is contained in:
parent
f892ad28a3
commit
131c41aa9a
5 changed files with 404 additions and 215 deletions
|
|
@ -2,6 +2,10 @@ using System;
|
|||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
#if Framework_4_0
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
#endif
|
||||
using Server;
|
||||
using Server.Items;
|
||||
using Server.Targeting;
|
||||
|
|
@ -2490,6 +2494,7 @@ namespace Server.Mobiles
|
|||
|
||||
IPooledEnumerable eable = map.GetMobilesInRange(m_Mobile.Location, iRange);
|
||||
|
||||
#if !Framework_4_0
|
||||
foreach (Mobile m in eable)
|
||||
{
|
||||
if (m.Deleted || m.Blessed)
|
||||
|
|
@ -2582,6 +2587,105 @@ namespace Server.Mobiles
|
|||
val = theirVal;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if Framework_4_0
|
||||
object valLock = new object();
|
||||
|
||||
Parallel.ForEach( eable.Cast<Mobile>(), m => {
|
||||
if (m.Deleted || m.Blessed)
|
||||
return;
|
||||
|
||||
// Let's not target ourselves...
|
||||
if (m == m_Mobile || m is BaseFamiliar)
|
||||
return;
|
||||
|
||||
// Dead targets are invalid.
|
||||
if (!m.Alive || m.IsDeadBondedPet)
|
||||
return;
|
||||
|
||||
// Staff members cannot be targeted.
|
||||
if (m.AccessLevel > AccessLevel.Player)
|
||||
return;
|
||||
|
||||
// Does it have to be a player?
|
||||
if (bPlayerOnly && !m.Player)
|
||||
return;
|
||||
|
||||
// Can't acquire a target we can't see.
|
||||
if (!m_Mobile.CanSee(m))
|
||||
return;
|
||||
|
||||
if (Core.AOS && m is BaseCreature && (m as BaseCreature).Summoned && !(m as BaseCreature).Controlled)
|
||||
return;
|
||||
|
||||
if (m_Mobile.Summoned && m_Mobile.SummonMaster != null)
|
||||
{
|
||||
// If this is a summon, it can't target its controller.
|
||||
if (m == m_Mobile.SummonMaster)
|
||||
return;
|
||||
|
||||
// It also must abide by harmful spell rules.
|
||||
if (!Server.Spells.SpellHelper.ValidIndirectTarget(m_Mobile.SummonMaster, m))
|
||||
return;
|
||||
|
||||
// Animated creatures cannot attack players directly.
|
||||
if (m is PlayerMobile && m_Mobile.IsAnimatedDead)
|
||||
return;
|
||||
}
|
||||
|
||||
// If we only want faction friends, make sure it's one.
|
||||
if (bFacFriend && !m_Mobile.IsFriend(m))
|
||||
return;
|
||||
|
||||
//Ignore anyone under EtherealVoyage
|
||||
if (TransformationSpellHelper.UnderTransformation(m, typeof(EtherealVoyageSpell)))
|
||||
return;
|
||||
|
||||
// Ignore players with activated honor
|
||||
if (m is PlayerMobile && ((PlayerMobile)m).HonorActive && !(m_Mobile.Combatant == m))
|
||||
return;
|
||||
|
||||
if (acqType == FightMode.Aggressor || acqType == FightMode.Evil)
|
||||
{
|
||||
bool bValid = IsHostile(m);
|
||||
|
||||
if (!bValid)
|
||||
bValid = (m_Mobile.GetFactionAllegiance(m) == BaseCreature.Allegiance.Enemy || m_Mobile.GetEthicAllegiance(m) == BaseCreature.Allegiance.Enemy);
|
||||
|
||||
if (acqType == FightMode.Evil && !bValid)
|
||||
{
|
||||
if (m is BaseCreature && ((BaseCreature)m).Controlled && ((BaseCreature)m).ControlMaster != null)
|
||||
bValid = (((BaseCreature)m).ControlMaster.Karma < 0);
|
||||
else
|
||||
bValid = (m.Karma < 0);
|
||||
}
|
||||
|
||||
if (!bValid)
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Same goes for faction enemies.
|
||||
if (bFacFoe && !m_Mobile.IsEnemy(m))
|
||||
return;
|
||||
|
||||
// If it's an enemy factioned mobile, make sure we can be harmful to it.
|
||||
if (bFacFoe && !bFacFriend && !m_Mobile.CanBeHarmful(m, false))
|
||||
return;
|
||||
}
|
||||
|
||||
theirVal = m_Mobile.GetFightModeRanking(m, acqType, bPlayerOnly);
|
||||
|
||||
lock (valLock) {
|
||||
if (theirVal > val && m_Mobile.InLOS(m))
|
||||
{
|
||||
newFocusMob = m;
|
||||
val = theirVal;
|
||||
}
|
||||
}
|
||||
});
|
||||
#endif
|
||||
|
||||
eable.Free();
|
||||
|
||||
|
|
|
|||
|
|
@ -5645,7 +5645,7 @@ namespace Server.Mobiles
|
|||
return base.CanBeDamaged();
|
||||
}
|
||||
|
||||
public virtual bool PlayerRangeSensitive{ get{ return (this.CurrentWayPoint == null); } } //If they are following a waypoint, they'll continue to follow it even if players aren't around
|
||||
public virtual bool PlayerRangeSensitive{ get{ return (this.CurrentWayPoint != null); } } //If they are following a waypoint, they'll continue to follow it even if players aren't around
|
||||
|
||||
/* until we are sure about who should be getting deleted, move them instead */
|
||||
/* On OSI, they despawn */
|
||||
|
|
|
|||
282
Server/Map.cs
282
Server/Map.cs
|
|
@ -1098,9 +1098,24 @@ namespace Server
|
|||
{
|
||||
private IPooledEnumerator m_Enumerator;
|
||||
|
||||
private static Queue<PooledEnumerable> m_InstancePool = new Queue<PooledEnumerable>();
|
||||
|
||||
public static PooledEnumerable Instantiate( IPooledEnumerator etor )
|
||||
{
|
||||
PooledEnumerable e = new PooledEnumerable( etor );
|
||||
PooledEnumerable e = null;
|
||||
|
||||
lock (m_InstancePool) {
|
||||
if ( m_InstancePool.Count > 0 ) {
|
||||
e = m_InstancePool.Dequeue();
|
||||
e.m_Enumerator = etor;
|
||||
}
|
||||
}
|
||||
|
||||
if (e == null )
|
||||
e = new PooledEnumerable( etor );
|
||||
|
||||
etor.Enumerable = e;
|
||||
|
||||
return e;
|
||||
}
|
||||
|
||||
|
|
@ -1112,18 +1127,20 @@ namespace Server
|
|||
public IEnumerator GetEnumerator()
|
||||
{
|
||||
if ( m_Enumerator == null )
|
||||
throw new ObjectDisposedException("PooledEnumerable", "GetEnumerator() called after Free()");
|
||||
throw new ObjectDisposedException( "PooledEnumerable", "GetEnumerator() called after Free()" );
|
||||
|
||||
return m_Enumerator;
|
||||
}
|
||||
|
||||
public void Free()
|
||||
{
|
||||
if ( m_Enumerator != null )
|
||||
{
|
||||
m_Enumerator.Free();
|
||||
m_Enumerator = null;
|
||||
if ( m_Enumerator != null ) {
|
||||
m_Enumerator.Free();
|
||||
m_Enumerator = null;
|
||||
}
|
||||
|
||||
lock (m_InstancePool)
|
||||
m_InstancePool.Enqueue( this );
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
|
|
@ -1141,7 +1158,7 @@ namespace Server
|
|||
Clients
|
||||
}
|
||||
|
||||
private class TypedEnumerator : IPooledEnumerator, IDisposable
|
||||
private class TypedEnumerator : IPooledEnumerator
|
||||
{
|
||||
private IPooledEnumerable m_Enumerable;
|
||||
|
||||
|
|
@ -1157,10 +1174,28 @@ namespace Server
|
|||
private SectorEnumeratorType m_Type;
|
||||
private object m_Current;
|
||||
|
||||
public static TypedEnumerator Instantiate( Map map, Rectangle2D bounds, SectorEnumeratorType type ) {
|
||||
TypedEnumerator e = new TypedEnumerator(map, bounds, type);
|
||||
private static Queue<TypedEnumerator> m_InstancePool = new Queue<TypedEnumerator>();
|
||||
|
||||
public static TypedEnumerator Instantiate( Map map, Rectangle2D bounds, SectorEnumeratorType type )
|
||||
{
|
||||
TypedEnumerator e = null;
|
||||
|
||||
lock (m_InstancePool) {
|
||||
if ( m_InstancePool.Count > 0 ) {
|
||||
e = m_InstancePool.Dequeue();
|
||||
|
||||
e.m_Map = map;
|
||||
e.m_Bounds = bounds;
|
||||
e.m_Type = type;
|
||||
}
|
||||
}
|
||||
|
||||
if (e == null) {
|
||||
e = new TypedEnumerator( map, bounds, type );
|
||||
}
|
||||
|
||||
e.Reset();
|
||||
|
||||
return e;
|
||||
}
|
||||
|
||||
|
|
@ -1169,13 +1204,15 @@ namespace Server
|
|||
if ( m_Map == null )
|
||||
return;
|
||||
|
||||
if ( m_Enumerator != null )
|
||||
{
|
||||
m_Map = null;
|
||||
|
||||
if ( m_Enumerator != null) {
|
||||
m_Enumerator.Free();
|
||||
m_Enumerator = null;
|
||||
}
|
||||
|
||||
m_Map = null;
|
||||
lock (m_InstancePool)
|
||||
m_InstancePool.Enqueue( this );
|
||||
}
|
||||
|
||||
public TypedEnumerator( Map map, Rectangle2D bounds, SectorEnumeratorType type )
|
||||
|
|
@ -1185,86 +1222,55 @@ namespace Server
|
|||
m_Type = type;
|
||||
}
|
||||
|
||||
public object Current {
|
||||
get { return m_Current; }
|
||||
}
|
||||
public object Current { get { return m_Current; } }
|
||||
|
||||
public bool MoveNext()
|
||||
{
|
||||
while ( true )
|
||||
{
|
||||
if (m_Enumerator == null)
|
||||
{
|
||||
Console.WriteLine("hmm m_Enumerator null??");
|
||||
return false;
|
||||
while ( m_Enumerator.MoveNext() ) {
|
||||
object o;
|
||||
|
||||
try {
|
||||
o = m_Enumerator.Current;
|
||||
} catch {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( m_Enumerator.MoveNext() )
|
||||
{
|
||||
object o;
|
||||
if ( o is Mobile ) {
|
||||
Mobile m = (Mobile) o;
|
||||
|
||||
try
|
||||
{
|
||||
o = m_Enumerator.Current;
|
||||
}
|
||||
catch
|
||||
{
|
||||
Console.WriteLine("typed Enum current null");
|
||||
continue;
|
||||
if ( !m.Deleted && m_Bounds.Contains( m.Location ) ) {
|
||||
m_Current = o;
|
||||
return true;
|
||||
}
|
||||
} else if ( o is Item ) {
|
||||
Item item = (Item) o;
|
||||
|
||||
if ( o is Mobile )
|
||||
{
|
||||
Mobile m = (Mobile) o;
|
||||
|
||||
if ( !m.Deleted && m_Bounds.Contains( m.Location ) )
|
||||
{
|
||||
m_Current = o;
|
||||
return true;
|
||||
}
|
||||
if ( !item.Deleted && item.Parent == null && m_Bounds.Contains( item.Location ) ) {
|
||||
m_Current = o;
|
||||
return true;
|
||||
}
|
||||
else if ( o is Item )
|
||||
{
|
||||
Item item = (Item) o;
|
||||
} else if ( o is NetState ) {
|
||||
Mobile m = ( (NetState) o ).Mobile;
|
||||
|
||||
if ( !item.Deleted && item.Parent == null && m_Bounds.Contains( item.Location ) )
|
||||
{
|
||||
m_Current = o;
|
||||
return true;
|
||||
}
|
||||
if ( m != null && !m.Deleted && m_Bounds.Contains( m.Location ) ) {
|
||||
m_Current = o;
|
||||
return true;
|
||||
}
|
||||
else if ( o is NetState )
|
||||
{
|
||||
Mobile m = ( (NetState) o ).Mobile;
|
||||
|
||||
if ( m != null && !m.Deleted && m_Bounds.Contains( m.Location ) )
|
||||
{
|
||||
m_Current = o;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_Current = null;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
m_Current = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
m_Current = null;
|
||||
m_Enumerator = SectorEnumerator.Instantiate( m_Map, m_Bounds, m_Type );
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Free();
|
||||
m_Enumerator = SectorEnumerator.Instantiate( m_Map, m_Bounds, m_Type );//new SectorEnumerator( m_Map, m_Origin, m_Type, m_Range );
|
||||
}
|
||||
}
|
||||
|
||||
private class MultiTileEnumerator : IPooledEnumerator, IDisposable
|
||||
private class MultiTileEnumerator : IPooledEnumerator
|
||||
{
|
||||
private IPooledEnumerable m_Enumerable;
|
||||
|
||||
|
|
@ -1279,11 +1285,27 @@ namespace Server
|
|||
private object m_Current;
|
||||
private int m_Index;
|
||||
|
||||
private static Queue<MultiTileEnumerator> m_InstancePool = new Queue<MultiTileEnumerator>();
|
||||
|
||||
public static MultiTileEnumerator Instantiate( Sector sector, Point2D loc )
|
||||
{
|
||||
MultiTileEnumerator e = new MultiTileEnumerator( sector, loc );
|
||||
MultiTileEnumerator e = null;
|
||||
|
||||
lock (m_InstancePool) {
|
||||
if ( m_InstancePool.Count > 0 ) {
|
||||
e = m_InstancePool.Dequeue();
|
||||
|
||||
e.m_List = sector.Multis;
|
||||
e.m_Location = loc;
|
||||
}
|
||||
}
|
||||
|
||||
if (e == null) {
|
||||
e = new MultiTileEnumerator( sector, loc );
|
||||
}
|
||||
|
||||
e.Reset();
|
||||
|
||||
return e;
|
||||
}
|
||||
|
||||
|
|
@ -1293,11 +1315,7 @@ namespace Server
|
|||
m_Location = loc;
|
||||
}
|
||||
|
||||
public object Current {
|
||||
get {
|
||||
return m_Current;
|
||||
}
|
||||
}
|
||||
public object Current { get { return m_Current; } }
|
||||
|
||||
public bool MoveNext()
|
||||
{
|
||||
|
|
@ -1342,7 +1360,10 @@ namespace Server
|
|||
if ( m_List == null )
|
||||
return;
|
||||
|
||||
m_List = null;
|
||||
lock (m_InstancePool) {
|
||||
m_InstancePool.Enqueue( this );
|
||||
m_List = null;
|
||||
}
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
|
|
@ -1350,14 +1371,9 @@ namespace Server
|
|||
m_Current = null;
|
||||
m_Index = -1;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Free();
|
||||
}
|
||||
}
|
||||
|
||||
private class ObjectEnumerator : IPooledEnumerator, IDisposable
|
||||
private class ObjectEnumerator : IPooledEnumerator
|
||||
{
|
||||
private IPooledEnumerable m_Enumerable;
|
||||
|
||||
|
|
@ -1373,11 +1389,27 @@ namespace Server
|
|||
private int m_Stage; // 0 = items, 1 = mobiles
|
||||
private object m_Current;
|
||||
|
||||
private static Queue<ObjectEnumerator> m_InstancePool = new Queue<ObjectEnumerator>();
|
||||
|
||||
public static ObjectEnumerator Instantiate( Map map, Rectangle2D bounds )
|
||||
{
|
||||
ObjectEnumerator e = new ObjectEnumerator(map, bounds);
|
||||
ObjectEnumerator e = null;
|
||||
|
||||
lock (m_InstancePool) {
|
||||
if ( m_InstancePool.Count > 0 ) {
|
||||
e = m_InstancePool.Dequeue();
|
||||
|
||||
e.m_Map = map;
|
||||
e.m_Bounds = bounds;
|
||||
}
|
||||
}
|
||||
|
||||
if (e == null) {
|
||||
e = new ObjectEnumerator( map, bounds );
|
||||
}
|
||||
|
||||
e.Reset();
|
||||
|
||||
return e;
|
||||
}
|
||||
|
||||
|
|
@ -1388,11 +1420,13 @@ namespace Server
|
|||
|
||||
m_Map = null;
|
||||
|
||||
if ( m_Enumerator != null )
|
||||
{
|
||||
if ( m_Enumerator != null ) {
|
||||
m_Enumerator.Free();
|
||||
m_Enumerator = null;
|
||||
}
|
||||
|
||||
lock (m_InstancePool)
|
||||
m_InstancePool.Enqueue( this );
|
||||
}
|
||||
|
||||
private ObjectEnumerator( Map map, Rectangle2D bounds )
|
||||
|
|
@ -1417,7 +1451,6 @@ namespace Server
|
|||
}
|
||||
catch
|
||||
{
|
||||
Console.WriteLine("OBJ Enum current null");
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -1474,14 +1507,9 @@ namespace Server
|
|||
|
||||
m_Enumerator = SectorEnumerator.Instantiate( m_Map, m_Bounds, SectorEnumeratorType.Items );
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Free();
|
||||
}
|
||||
}
|
||||
|
||||
private class SectorEnumerator : IPooledEnumerator, IDisposable
|
||||
private class SectorEnumerator : IPooledEnumerator
|
||||
{
|
||||
private IPooledEnumerable m_Enumerable;
|
||||
|
||||
|
|
@ -1503,10 +1531,26 @@ namespace Server
|
|||
|
||||
private static Queue<SectorEnumerator> m_InstancePool = new Queue<SectorEnumerator>();
|
||||
|
||||
public static SectorEnumerator Instantiate( Map map, Rectangle2D bounds, SectorEnumeratorType type ) {
|
||||
SectorEnumerator e = new SectorEnumerator(map, bounds, type);
|
||||
public static SectorEnumerator Instantiate( Map map, Rectangle2D bounds, SectorEnumeratorType type )
|
||||
{
|
||||
SectorEnumerator e = null;
|
||||
|
||||
lock (m_InstancePool) {
|
||||
if ( m_InstancePool.Count > 0 ) {
|
||||
e = m_InstancePool.Dequeue();
|
||||
|
||||
e.m_Map = map;
|
||||
e.m_Bounds = bounds;
|
||||
e.m_Type = type;
|
||||
}
|
||||
}
|
||||
|
||||
if (e == null) {
|
||||
e = new SectorEnumerator( map, bounds, type );
|
||||
}
|
||||
|
||||
e.Reset();
|
||||
|
||||
return e;
|
||||
}
|
||||
|
||||
|
|
@ -1515,7 +1559,13 @@ namespace Server
|
|||
if ( m_Map == null )
|
||||
return;
|
||||
|
||||
//m_Map = null;
|
||||
m_Map = null;
|
||||
|
||||
if ( m_Enumerable != null )
|
||||
m_Enumerable.Free();
|
||||
|
||||
lock (m_InstancePool)
|
||||
m_InstancePool.Enqueue( this );
|
||||
}
|
||||
|
||||
private SectorEnumerator( Map map, Rectangle2D bounds, SectorEnumeratorType type )
|
||||
|
|
@ -1540,8 +1590,32 @@ namespace Server
|
|||
}
|
||||
}
|
||||
|
||||
public object Current {
|
||||
get { return m_CurrentList[m_CurrentIndex]; }
|
||||
public object Current
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_CurrentList[m_CurrentIndex];
|
||||
/*try
|
||||
{
|
||||
return m_CurrentList[m_CurrentIndex];
|
||||
}
|
||||
catch
|
||||
{
|
||||
Console.WriteLine( "Warning: Object removed during enumeration. May not be recoverable" );
|
||||
|
||||
m_CurrentIndex = -1;
|
||||
m_CurrentList = GetListForSector( m_Map.InternalGetSector( m_xSector, m_ySector ) );
|
||||
|
||||
if ( MoveNext() )
|
||||
{
|
||||
return Current;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception( "Object disposed during enumeration. Was not recoverable." );
|
||||
}
|
||||
}*/
|
||||
}
|
||||
}
|
||||
|
||||
public bool MoveNext()
|
||||
|
|
@ -1550,9 +1624,6 @@ namespace Server
|
|||
{
|
||||
++m_CurrentIndex;
|
||||
|
||||
if (m_CurrentList == null)
|
||||
return false; // So much fail with PooledEnumerables ><
|
||||
|
||||
if ( m_CurrentIndex == m_CurrentList.Count )
|
||||
{
|
||||
++m_ySector;
|
||||
|
|
@ -1565,8 +1636,6 @@ namespace Server
|
|||
if ( m_xSector > m_xSectorEnd )
|
||||
{
|
||||
m_CurrentIndex = -1;
|
||||
m_CurrentList = null;
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
@ -1595,11 +1664,6 @@ namespace Server
|
|||
m_CurrentIndex = -1;
|
||||
m_CurrentList = GetListForSector( m_Map.InternalGetSector( m_xSector, m_ySector ) );
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Free();
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
|
|
|||
221
Server/Mobile.cs
221
Server/Mobile.cs
|
|
@ -4016,29 +4016,31 @@ namespace Server
|
|||
|
||||
if( m_Map != null )
|
||||
{
|
||||
Packet animPacket = null;//new DeathAnimation( this, c );
|
||||
Packet remPacket = null;//this.RemovePacket;
|
||||
Packet animPacket = null;
|
||||
object pLock = new object();
|
||||
|
||||
IPooledEnumerable eable = m_Map.GetClientsInRange( m_Location );
|
||||
|
||||
foreach( NetState state in eable )
|
||||
{
|
||||
if( state != m_NetState )
|
||||
{
|
||||
if( animPacket == null )
|
||||
animPacket = Packet.Acquire( new DeathAnimation( this, c ) );
|
||||
#if Framework_4_0
|
||||
Parallel.ForEach( eable.Cast<NetState>(), state => {
|
||||
#else
|
||||
foreach( NetState state in eable ) {
|
||||
#endif
|
||||
if( state != m_NetState ) {
|
||||
lock (pLock)
|
||||
if (animPacket == null)
|
||||
animPacket = Packet.Acquire( new DeathAnimation( this, c ) );;
|
||||
|
||||
state.Send( animPacket );
|
||||
|
||||
if( !state.Mobile.CanSee( this ) )
|
||||
{
|
||||
if( remPacket == null )
|
||||
remPacket = this.RemovePacket;
|
||||
|
||||
state.Send( remPacket );
|
||||
if( !state.Mobile.CanSee( this ) ) {
|
||||
state.Send( this.RemovePacket );
|
||||
}
|
||||
}
|
||||
}
|
||||
#if Framework_4_0
|
||||
);
|
||||
#endif
|
||||
|
||||
Packet.Release( animPacket );
|
||||
|
||||
|
|
@ -5363,31 +5365,33 @@ namespace Server
|
|||
|
||||
Packet pNew = null;
|
||||
Packet pOld = null;
|
||||
object pLock1 = new object();
|
||||
object pLock2 = new object();
|
||||
|
||||
foreach( NetState ns in eable )
|
||||
{
|
||||
if( ns.Mobile.CanSee( this ) )
|
||||
{
|
||||
Packet p;
|
||||
#if Framework_4_0
|
||||
Parallel.ForEach( eable.Cast<NetState>(), ns => {
|
||||
#else
|
||||
foreach( NetState ns in eable ) {
|
||||
#endif
|
||||
if( ns.Mobile.CanSee( this ) ) {
|
||||
if( ns.DamagePacket ) {
|
||||
lock (pLock1)
|
||||
if( pNew == null )
|
||||
pNew = Packet.Acquire( new DamagePacket( this, amount ) );
|
||||
|
||||
if( ns.DamagePacket )
|
||||
{
|
||||
if( pNew == null )
|
||||
pNew = Packet.Acquire( new DamagePacket( this, amount ) );
|
||||
ns.Send( pNew );
|
||||
} else {
|
||||
lock (pLock2)
|
||||
if( pOld == null )
|
||||
pOld = Packet.Acquire( new DamagePacketOld( this, amount ) );
|
||||
|
||||
p = pNew;
|
||||
ns.Send( pOld );
|
||||
}
|
||||
else
|
||||
{
|
||||
if( pOld == null )
|
||||
pOld = Packet.Acquire( new DamagePacketOld( this, amount ) );
|
||||
|
||||
p = pOld;
|
||||
}
|
||||
|
||||
ns.Send( p );
|
||||
}
|
||||
}
|
||||
#if Framework_4_0
|
||||
);
|
||||
#endif
|
||||
|
||||
Packet.Release( pNew );
|
||||
Packet.Release( pOld );
|
||||
|
|
@ -6360,20 +6364,22 @@ namespace Server
|
|||
|
||||
if( m_Map != null )
|
||||
{
|
||||
Packet p = null;
|
||||
Packet p = Packet.Acquire(new PlaySound(soundID, this));
|
||||
|
||||
IPooledEnumerable eable = m_Map.GetClientsInRange( m_Location );
|
||||
|
||||
foreach( NetState state in eable )
|
||||
{
|
||||
if( state.Mobile.CanSee( this ) )
|
||||
{
|
||||
if( p == null )
|
||||
p = Packet.Acquire( new PlaySound( soundID, this ) );
|
||||
|
||||
#if Framework_4_0
|
||||
Parallel.ForEach( eable.Cast<NetState>(), state => {
|
||||
#else
|
||||
foreach( NetState state in eable ) {
|
||||
#endif
|
||||
if( state.Mobile.CanSee( this ) ) {
|
||||
state.Send( p );
|
||||
}
|
||||
}
|
||||
#if Framework_4_0
|
||||
);
|
||||
#endif
|
||||
|
||||
Packet.Release( p );
|
||||
|
||||
|
|
@ -6631,20 +6637,19 @@ namespace Server
|
|||
{
|
||||
if( m_Map != null )
|
||||
{
|
||||
Packet p = null;
|
||||
|
||||
IPooledEnumerable eable = m_Map.GetClientsInRange( m_Location );
|
||||
|
||||
foreach( NetState state in eable )
|
||||
{
|
||||
#if Framework_4_0
|
||||
Parallel.ForEach( eable.Cast<NetState>(), state => {
|
||||
#else
|
||||
foreach( NetState state in eable ) {
|
||||
#endif
|
||||
if( state != m_NetState && (everyone || !state.Mobile.CanSee( this )) )
|
||||
{
|
||||
if( p == null )
|
||||
p = this.RemovePacket;
|
||||
|
||||
state.Send( p );
|
||||
}
|
||||
state.Send( this.RemovePacket );
|
||||
}
|
||||
#if Framework_4_0
|
||||
);
|
||||
#endif
|
||||
|
||||
eable.Free();
|
||||
}
|
||||
|
|
@ -10655,25 +10660,27 @@ namespace Server
|
|||
{
|
||||
Packet p = null;
|
||||
|
||||
if( ascii )
|
||||
p = new AsciiMessage( m_Serial, Body, type, hue, 3, Name, text );
|
||||
else
|
||||
p = new UnicodeMessage( m_Serial, Body, type, hue, 3, m_Language, Name, text );
|
||||
|
||||
p.Acquire();
|
||||
|
||||
IPooledEnumerable eable = m_Map.GetClientsInRange( m_Location );
|
||||
|
||||
foreach( NetState state in eable )
|
||||
{
|
||||
if( state.Mobile.CanSee( this ) && (noLineOfSight || state.Mobile.InLOS( this )) )
|
||||
{
|
||||
if( p == null )
|
||||
{
|
||||
if( ascii )
|
||||
p = new AsciiMessage( m_Serial, Body, type, hue, 3, Name, text );
|
||||
else
|
||||
p = new UnicodeMessage( m_Serial, Body, type, hue, 3, m_Language, Name, text );
|
||||
|
||||
p.Acquire();
|
||||
}
|
||||
|
||||
#if Framework_4_0
|
||||
Parallel.ForEach( eable.Cast<NetState>(), state => {
|
||||
#else
|
||||
foreach( NetState state in eable ) {
|
||||
#endif
|
||||
if( state.Mobile.CanSee( this ) && (noLineOfSight || state.Mobile.InLOS( this )) ) {
|
||||
state.Send( p );
|
||||
}
|
||||
}
|
||||
#if Framework_4_0
|
||||
);
|
||||
#endif
|
||||
|
||||
Packet.Release( p );
|
||||
|
||||
|
|
@ -10695,20 +10702,22 @@ namespace Server
|
|||
{
|
||||
if( m_Map != null )
|
||||
{
|
||||
Packet p = null;
|
||||
Packet p = Packet.Acquire( new MessageLocalized( m_Serial, Body, type, hue, 3, number, Name, args ) );
|
||||
|
||||
IPooledEnumerable eable = m_Map.GetClientsInRange( m_Location );
|
||||
|
||||
foreach( NetState state in eable )
|
||||
{
|
||||
if( state.Mobile.CanSee( this ) && (noLineOfSight || state.Mobile.InLOS( this )) )
|
||||
{
|
||||
if( p == null )
|
||||
p = Packet.Acquire( new MessageLocalized( m_Serial, Body, type, hue, 3, number, Name, args ) );
|
||||
|
||||
#if Framework_4_0
|
||||
Parallel.ForEach( eable.Cast<NetState>(), state => {
|
||||
#else
|
||||
foreach( NetState state in eable ) {
|
||||
#endif
|
||||
if( state.Mobile.CanSee( this ) && (noLineOfSight || state.Mobile.InLOS( this )) ) {
|
||||
state.Send( p );
|
||||
}
|
||||
}
|
||||
#if Framework_4_0
|
||||
);
|
||||
#endif
|
||||
|
||||
Packet.Release( p );
|
||||
|
||||
|
|
@ -10725,20 +10734,22 @@ namespace Server
|
|||
{
|
||||
if( m_Map != null )
|
||||
{
|
||||
Packet p = null;
|
||||
Packet p = Packet.Acquire( new MessageLocalizedAffix( m_Serial, Body, type, hue, 3, number, Name, affixType, affix, args ) );
|
||||
|
||||
IPooledEnumerable eable = m_Map.GetClientsInRange( m_Location );
|
||||
|
||||
foreach( NetState state in eable )
|
||||
{
|
||||
if( state.Mobile.CanSee( this ) && (noLineOfSight || state.Mobile.InLOS( this )) )
|
||||
{
|
||||
if( p == null )
|
||||
p = Packet.Acquire( new MessageLocalizedAffix( m_Serial, Body, type, hue, 3, number, Name, affixType, affix, args ) );
|
||||
|
||||
#if Framework_4_0
|
||||
Parallel.ForEach( eable.Cast<NetState>(), state => {
|
||||
#else
|
||||
foreach( NetState state in eable ) {
|
||||
#endif
|
||||
if( state.Mobile.CanSee( this ) && (noLineOfSight || state.Mobile.InLOS( this )) ) {
|
||||
state.Send( p );
|
||||
}
|
||||
}
|
||||
#if Framework_4_0
|
||||
);
|
||||
#endif
|
||||
|
||||
Packet.Release( p );
|
||||
|
||||
|
|
@ -10805,20 +10816,22 @@ namespace Server
|
|||
{
|
||||
if( m_Map != null )
|
||||
{
|
||||
Packet p = null;
|
||||
Packet p = Packet.Acquire( new MessageLocalized( m_Serial, Body, type, hue, 3, number, Name, args ) );
|
||||
|
||||
IPooledEnumerable eable = m_Map.GetClientsInRange( m_Location );
|
||||
|
||||
foreach( NetState state in eable )
|
||||
{
|
||||
if( state != m_NetState && state.Mobile.CanSee( this ) )
|
||||
{
|
||||
if( p == null )
|
||||
p = Packet.Acquire( new MessageLocalized( m_Serial, Body, type, hue, 3, number, Name, args ) );
|
||||
|
||||
#if Framework_4_0
|
||||
Parallel.ForEach( eable.Cast<NetState>(), state => {
|
||||
#else
|
||||
foreach( NetState state in eable ) {
|
||||
#endif
|
||||
if( state != m_NetState && state.Mobile.CanSee( this ) ) {
|
||||
state.Send( p );
|
||||
}
|
||||
}
|
||||
#if Framework_4_0
|
||||
);
|
||||
#endif
|
||||
|
||||
Packet.Release( p );
|
||||
|
||||
|
|
@ -10832,25 +10845,27 @@ namespace Server
|
|||
{
|
||||
Packet p = null;
|
||||
|
||||
if( ascii )
|
||||
p = new AsciiMessage( m_Serial, Body, type, hue, 3, Name, text );
|
||||
else
|
||||
p = new UnicodeMessage( m_Serial, Body, type, hue, 3, Language, Name, text );
|
||||
|
||||
p.Acquire();
|
||||
|
||||
IPooledEnumerable eable = m_Map.GetClientsInRange( m_Location );
|
||||
|
||||
foreach( NetState state in eable )
|
||||
{
|
||||
if( state != m_NetState && state.Mobile.CanSee( this ) )
|
||||
{
|
||||
if( p == null )
|
||||
{
|
||||
if( ascii )
|
||||
p = new AsciiMessage( m_Serial, Body, type, hue, 3, Name, text );
|
||||
else
|
||||
p = new UnicodeMessage( m_Serial, Body, type, hue, 3, Language, Name, text );
|
||||
|
||||
p.Acquire();
|
||||
}
|
||||
|
||||
#if Framework_4_0
|
||||
Parallel.ForEach( eable.Cast<NetState>(), state => {
|
||||
#else
|
||||
foreach( NetState state in eable ) {
|
||||
#endif
|
||||
if( state != m_NetState && state.Mobile.CanSee( this ) ) {
|
||||
state.Send( p );
|
||||
}
|
||||
}
|
||||
#if Framework_4_0
|
||||
);
|
||||
#endif
|
||||
|
||||
Packet.Release( p );
|
||||
|
||||
|
|
|
|||
|
|
@ -1125,8 +1125,10 @@ namespace Server.Network {
|
|||
TraceException( ex );
|
||||
}
|
||||
|
||||
if ( m_RecvBuffer != null )
|
||||
m_ReceiveBufferPool.ReleaseBuffer( m_RecvBuffer );
|
||||
if ( m_RecvBuffer != null ) {
|
||||
lock (m_ReceiveBufferPool)
|
||||
m_ReceiveBufferPool.ReleaseBuffer( m_RecvBuffer );
|
||||
}
|
||||
|
||||
m_Socket = null;
|
||||
|
||||
|
|
@ -1158,9 +1160,13 @@ namespace Server.Network {
|
|||
|
||||
public static void CheckAllAlive() {
|
||||
try {
|
||||
#if Framework_4_0
|
||||
Parallel.ForEach( m_Instances, ns => ns.CheckAlive() );
|
||||
#else
|
||||
for ( int i = 0; i < m_Instances.Count; ++i ) {
|
||||
m_Instances[i].CheckAlive();
|
||||
}
|
||||
#endif
|
||||
} catch ( Exception ex ) {
|
||||
TraceException( ex );
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue