diff --git a/OpenSim/Framework/WebUtil.cs b/OpenSim/Framework/WebUtil.cs
index 51d87bdf2d..2bbf785661 100644
--- a/OpenSim/Framework/WebUtil.cs
+++ b/OpenSim/Framework/WebUtil.cs
@@ -1062,11 +1062,10 @@ namespace OpenSim.Framework
if (WebUtil.DebugLevel >= 5)
WebUtil.LogOutgoingDetail("SEND", reqnum, System.Text.Encoding.UTF8.GetString(data));
- Stream requestStream = null;
try
{
- requestStream = request.GetRequestStream();
- requestStream.Write(data, 0, length);
+ using(Stream requestStream = request.GetRequestStream())
+ requestStream.Write(data,0,length);
}
catch (Exception e)
{
@@ -1076,9 +1075,6 @@ namespace OpenSim.Framework
}
finally
{
- if (requestStream != null)
- requestStream.Dispose();
-
// capture how much time was spent writing
tickdata = Util.EnvironmentTickCountSubtract(tickstart);
}
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
index 8d07bae155..37937123b4 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
@@ -346,12 +346,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
private bool m_VelocityInterpolate = false;
private const uint MaxTransferBytesPerPacket = 600;
- ///
- /// List used in construction of data blocks for an object update packet. This is to stop us having to
- /// continually recreate it.
- ///
- protected List m_fullUpdateDataBlocksBuilder;
-
///
/// Maintain a record of all the objects killed. This allows us to stop an update being sent from the
/// thread servicing the m_primFullUpdates queue after a kill. If this happens the object persists as an
@@ -511,7 +505,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
m_scene = scene;
m_entityUpdates = new PriorityQueue(m_scene.Entities.Count);
m_entityProps = new PriorityQueue(m_scene.Entities.Count);
- m_fullUpdateDataBlocksBuilder = new List();
m_killRecord = new List();
// m_attachmentsSent = new HashSet();
@@ -594,13 +587,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
OutPacket(disable, ThrottleOutPacketType.Unknown);
}
- // Shutdown the image manager
- ImageManager.Close();
// Fire the callback for this connection closing
if (OnConnectionClosed != null)
OnConnectionClosed(this);
+
// Flush all of the packets out of the UDP server for this client
if (m_udpServer != null)
m_udpServer.Flush(m_udpClient);
@@ -615,8 +607,20 @@ namespace OpenSim.Region.ClientStack.LindenUDP
// Disable UDP handling for this client
m_udpClient.Shutdown();
-
-
+
+ m_udpClient.OnQueueEmpty -= HandleQueueEmpty;
+ m_udpClient.HasUpdates -= HandleHasUpdates;
+ m_udpClient.OnPacketStats -= PopulateStats;
+
+ // Shutdown the image manager
+ ImageManager.Close();
+ ImageManager = null;
+
+ m_entityUpdates = null;
+ m_entityProps = null;
+ m_killRecord.Clear();
+ GroupsInView.Clear();
+ m_scene = null;
//m_log.InfoFormat("[CLIENTVIEW] Memory pre GC {0}", System.GC.GetTotalMemory(false));
//GC.Collect();
//m_log.InfoFormat("[CLIENTVIEW] Memory post GC {0}", System.GC.GetTotalMemory(true));
@@ -814,7 +818,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
public void ProcessSpecificPacketAsync(object state)
{
AsyncPacketProcess packetObject = (AsyncPacketProcess)state;
-
+
try
{
packetObject.result = packetObject.Method(packetObject.ClientView, packetObject.Pack);
@@ -4095,19 +4099,18 @@ namespace OpenSim.Region.ClientStack.LindenUDP
ResendPrimUpdate(update);
}
+ private List objectUpdateBlocks = new List();
+ private List compressedUpdateBlocks = new List();
+ private List terseUpdateBlocks = new List();
+ private List terseAgentUpdateBlocks = new List();
+
private void ProcessEntityUpdates(int maxUpdatesBytes)
{
- OpenSim.Framework.Lazy> objectUpdateBlocks = new OpenSim.Framework.Lazy>();
- OpenSim.Framework.Lazy> compressedUpdateBlocks = new OpenSim.Framework.Lazy>();
- OpenSim.Framework.Lazy> terseUpdateBlocks = new OpenSim.Framework.Lazy>();
- OpenSim.Framework.Lazy> terseAgentUpdateBlocks = new OpenSim.Framework.Lazy>();
-
OpenSim.Framework.Lazy> objectUpdates = new OpenSim.Framework.Lazy>();
OpenSim.Framework.Lazy> compressedUpdates = new OpenSim.Framework.Lazy>();
OpenSim.Framework.Lazy> terseUpdates = new OpenSim.Framework.Lazy>();
OpenSim.Framework.Lazy> terseAgentUpdates = new OpenSim.Framework.Lazy>();
-
// Check to see if this is a flush
if (maxUpdatesBytes <= 0)
{
@@ -4328,7 +4331,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
ablock = CreateAvatarUpdateBlock((ScenePresence)update.Entity);
else
ablock = CreatePrimUpdateBlock((SceneObjectPart)update.Entity, this.m_agentId);
- objectUpdateBlocks.Value.Add(ablock);
+ objectUpdateBlocks.Add(ablock);
objectUpdates.Value.Add(update);
maxUpdatesBytes -= ablock.Length;
@@ -4337,7 +4340,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
{
ObjectUpdateCompressedPacket.ObjectDataBlock ablock =
CreateCompressedUpdateBlock((SceneObjectPart)update.Entity, updateFlags);
- compressedUpdateBlocks.Value.Add(ablock);
+ compressedUpdateBlocks.Add(ablock);
compressedUpdates.Value.Add(update);
maxUpdatesBytes -= ablock.Length;
}
@@ -4348,14 +4351,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
{
// ALL presence updates go into a special list
ablock = CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures));
- terseAgentUpdateBlocks.Value.Add(ablock);
+ terseAgentUpdateBlocks.Add(ablock);
terseAgentUpdates.Value.Add(update);
}
else
{
// Everything else goes here
ablock = CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures));
- terseUpdateBlocks.Value.Add(ablock);
+ terseUpdateBlocks.Add(ablock);
terseUpdates.Value.Add(update);
}
maxUpdatesBytes -= ablock.Length;
@@ -4366,74 +4369,69 @@ namespace OpenSim.Region.ClientStack.LindenUDP
#region Packet Sending
-// const float TIME_DILATION = 1.0f;
ushort timeDilation;
-// if(updatesThisCall > 0)
-// timeDilation = Utils.FloatToUInt16(avgTimeDilation/updatesThisCall, 0.0f, 1.0f);
-// else
-// timeDilation = ushort.MaxValue; // 1.0;
timeDilation = Utils.FloatToUInt16(m_scene.TimeDilation, 0.0f, 1.0f);
- if (terseAgentUpdateBlocks.IsValueCreated)
+ if (terseAgentUpdateBlocks.Count > 0)
{
- List blocks = terseAgentUpdateBlocks.Value;
-
ImprovedTerseObjectUpdatePacket packet
= (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ImprovedTerseObjectUpdate);
packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
packet.RegionData.TimeDilation = timeDilation;
- packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count];
+ packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[terseAgentUpdateBlocks.Count];
- for (int i = 0; i < blocks.Count; i++)
- packet.ObjectData[i] = blocks[i];
+ for (int i = 0; i < terseAgentUpdateBlocks.Count; i++)
+ packet.ObjectData[i] = terseAgentUpdateBlocks[i];
+
+ terseAgentUpdateBlocks.Clear();
OutPacket(packet, ThrottleOutPacketType.Unknown, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(terseAgentUpdates.Value, oPacket); });
}
- if (objectUpdateBlocks.IsValueCreated)
+ if (objectUpdateBlocks.Count > 0)
{
- List blocks = objectUpdateBlocks.Value;
-
ObjectUpdatePacket packet = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate);
packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
packet.RegionData.TimeDilation = timeDilation;
- packet.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[blocks.Count];
+ packet.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[objectUpdateBlocks.Count];
- for (int i = 0; i < blocks.Count; i++)
- packet.ObjectData[i] = blocks[i];
+ for (int i = 0; i < objectUpdateBlocks.Count; i++)
+ packet.ObjectData[i] = objectUpdateBlocks[i];
+
+ objectUpdateBlocks.Clear();
OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(objectUpdates.Value, oPacket); });
}
- if (compressedUpdateBlocks.IsValueCreated)
+ if (compressedUpdateBlocks.Count > 0)
{
- List blocks = compressedUpdateBlocks.Value;
-
ObjectUpdateCompressedPacket packet = (ObjectUpdateCompressedPacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdateCompressed);
packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
packet.RegionData.TimeDilation = timeDilation;
- packet.ObjectData = new ObjectUpdateCompressedPacket.ObjectDataBlock[blocks.Count];
+ packet.ObjectData = new ObjectUpdateCompressedPacket.ObjectDataBlock[compressedUpdateBlocks.Count];
- for (int i = 0; i < blocks.Count; i++)
- packet.ObjectData[i] = blocks[i];
+ for (int i = 0; i < compressedUpdateBlocks.Count; i++)
+ packet.ObjectData[i] = compressedUpdateBlocks[i];
+
+ compressedUpdateBlocks.Clear();
OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(compressedUpdates.Value, oPacket); });
}
- if (terseUpdateBlocks.IsValueCreated)
+ if (terseUpdateBlocks.Count > 0)
{
- List blocks = terseUpdateBlocks.Value;
-
ImprovedTerseObjectUpdatePacket packet
= (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(
PacketType.ImprovedTerseObjectUpdate);
packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
packet.RegionData.TimeDilation = timeDilation;
- packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count];
+ packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[terseUpdateBlocks.Count];
- for (int i = 0; i < blocks.Count; i++)
- packet.ObjectData[i] = blocks[i];
+ for (int i = 0; i < terseUpdateBlocks.Count; i++)
+ packet.ObjectData[i] = terseUpdateBlocks[i];
+
+ terseUpdateBlocks.Clear();
OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(terseUpdates.Value, oPacket); });
}
@@ -4828,21 +4826,20 @@ namespace OpenSim.Region.ClientStack.LindenUDP
m_entityProps.Enqueue(priority, new ObjectPropertyUpdate(entity,0,false,true));
}
+ List objectFamilyBlocks = new
+ List();
+ List objectPropertiesBlocks =
+ new List();
+ List needPhysics = new List();
+
private void ProcessEntityPropertyRequests(int maxUpdateBytes)
{
- OpenSim.Framework.Lazy> objectFamilyBlocks =
- new OpenSim.Framework.Lazy>();
+// OpenSim.Framework.Lazy> familyUpdates =
+// new OpenSim.Framework.Lazy>();
- OpenSim.Framework.Lazy> objectPropertiesBlocks =
- new OpenSim.Framework.Lazy>();
-
- OpenSim.Framework.Lazy> familyUpdates =
- new OpenSim.Framework.Lazy>();
-
- OpenSim.Framework.Lazy> propertyUpdates =
- new OpenSim.Framework.Lazy>();
+// OpenSim.Framework.Lazy> propertyUpdates =
+// new OpenSim.Framework.Lazy>();
- List needPhysics = new List();
EntityUpdate iupdate;
Int32 timeinqueue; // this is just debugging code & can be dropped later
@@ -4860,8 +4857,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
{
SceneObjectPart sop = (SceneObjectPart)update.Entity;
ObjectPropertiesFamilyPacket.ObjectDataBlock objPropDB = CreateObjectPropertiesFamilyBlock(sop,update.Flags);
- objectFamilyBlocks.Value.Add(objPropDB);
- familyUpdates.Value.Add(update);
+ objectFamilyBlocks.Add(objPropDB);
+// familyUpdates.Value.Add(update);
maxUpdateBytes -= objPropDB.Length;
}
}
@@ -4873,23 +4870,22 @@ namespace OpenSim.Region.ClientStack.LindenUDP
SceneObjectPart sop = (SceneObjectPart)update.Entity;
needPhysics.Add(sop);
ObjectPropertiesPacket.ObjectDataBlock objPropDB = CreateObjectPropertiesBlock(sop);
- objectPropertiesBlocks.Value.Add(objPropDB);
- propertyUpdates.Value.Add(update);
+ objectPropertiesBlocks.Add(objPropDB);
+// propertyUpdates.Value.Add(update);
maxUpdateBytes -= objPropDB.Length;
}
}
}
- if (objectPropertiesBlocks.IsValueCreated)
+ if (objectPropertiesBlocks.Count > 0)
{
- List blocks = objectPropertiesBlocks.Value;
- List updates = propertyUpdates.Value;
-
ObjectPropertiesPacket packet = (ObjectPropertiesPacket)PacketPool.Instance.GetPacket(PacketType.ObjectProperties);
- packet.ObjectData = new ObjectPropertiesPacket.ObjectDataBlock[blocks.Count];
- for (int i = 0; i < blocks.Count; i++)
- packet.ObjectData[i] = blocks[i];
+ packet.ObjectData = new ObjectPropertiesPacket.ObjectDataBlock[objectPropertiesBlocks.Count];
+ for (int i = 0; i < objectPropertiesBlocks.Count; i++)
+ packet.ObjectData[i] = objectPropertiesBlocks[i];
+
+ objectPropertiesBlocks.Clear();
packet.Header.Zerocoded = true;
// Pass in the delegate so that if this packet needs to be resent, we send the current properties
@@ -4898,7 +4894,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
//OutPacket(packet, ThrottleOutPacketType.Task, true,
// delegate(OutgoingPacket oPacket)
// {
- // ResendPropertyUpdates(updates, oPacket);
+ // ResendPropertyUpdates(propertyUpdates.Value, oPacket);
// });
OutPacket(packet, ThrottleOutPacketType.Task, true);
@@ -4909,23 +4905,21 @@ namespace OpenSim.Region.ClientStack.LindenUDP
// Int32 fpcnt = 0;
// Int32 fbcnt = 0;
- if (objectFamilyBlocks.IsValueCreated)
- {
- List blocks = objectFamilyBlocks.Value;
-
+ if (objectFamilyBlocks.Count > 0)
+ {
// one packet per object block... uggh...
- for (int i = 0; i < blocks.Count; i++)
+ for (int i = 0; i < objectFamilyBlocks.Count; i++)
{
ObjectPropertiesFamilyPacket packet =
(ObjectPropertiesFamilyPacket)PacketPool.Instance.GetPacket(PacketType.ObjectPropertiesFamily);
- packet.ObjectData = blocks[i];
+ packet.ObjectData = objectFamilyBlocks[i];
packet.Header.Zerocoded = true;
// Pass in the delegate so that if this packet needs to be resent, we send the current properties
// of the object rather than the properties when the packet was created
- List updates = new List();
- updates.Add(familyUpdates.Value[i]);
+// List updates = new List();
+// updates.Add(familyUpdates.Value[i]);
// HACK : Remove intelligent resending until it's fixed in core
//OutPacket(packet, ThrottleOutPacketType.Task, true,
// delegate(OutgoingPacket oPacket)
@@ -4937,6 +4931,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
// fpcnt++;
// fbcnt++;
}
+ objectFamilyBlocks.Clear();
}
if(needPhysics.Count > 0)
@@ -4962,6 +4957,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
eq.Enqueue(BuildEvent("ObjectPhysicsProperties", llsdBody),AgentId);
}
+ needPhysics.Clear();
}
// m_log.WarnFormat("[PACKETCOUNTS] queued {0} property packets with {1} blocks",ppcnt,pbcnt);
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs
index d59b7614ed..e85cee2524 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs
@@ -120,13 +120,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
/// Circuit code that this client is connected on
public readonly uint CircuitCode;
/// Sequence numbers of packets we've received (for duplicate checking)
- public readonly IncomingPacketHistoryCollection PacketArchive = new IncomingPacketHistoryCollection(200);
+ public IncomingPacketHistoryCollection PacketArchive = new IncomingPacketHistoryCollection(200);
/// Packets we have sent that need to be ACKed by the client
- public readonly UnackedPacketCollection NeedAcks = new UnackedPacketCollection();
+ public UnackedPacketCollection NeedAcks = new UnackedPacketCollection();
/// ACKs that are queued up, waiting to be sent to the client
- public readonly DoubleLocklessQueue PendingAcks = new DoubleLocklessQueue();
+ public DoubleLocklessQueue PendingAcks = new DoubleLocklessQueue();
/// Current packet sequence number
public int CurrentSequence;
@@ -170,7 +170,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
private double m_nextOnQueueEmpty = 0;
/// Throttle bucket for this agent's connection
- private readonly AdaptiveTokenBucket m_throttleClient;
+ private AdaptiveTokenBucket m_throttleClient;
public AdaptiveTokenBucket FlowThrottle
{
get { return m_throttleClient; }
@@ -179,10 +179,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
/// Throttle buckets for each packet category
private readonly TokenBucket[] m_throttleCategories;
/// Outgoing queues for throttled packets
- private readonly DoubleLocklessQueue[] m_packetOutboxes = new DoubleLocklessQueue[THROTTLE_CATEGORY_COUNT];
+ private DoubleLocklessQueue[] m_packetOutboxes = new DoubleLocklessQueue[THROTTLE_CATEGORY_COUNT];
/// A container that can hold one packet for each outbox, used to store
/// dequeued packets that are being held for throttling
- private readonly OutgoingPacket[] m_nextPackets = new OutgoingPacket[THROTTLE_CATEGORY_COUNT];
+ private OutgoingPacket[] m_nextPackets = new OutgoingPacket[THROTTLE_CATEGORY_COUNT];
/// A reference to the LLUDPServer that is managing this client
private readonly LLUDPServer m_udpServer;
@@ -288,14 +288,22 @@ namespace OpenSim.Region.ClientStack.LindenUDP
for (int i = 0; i < THROTTLE_CATEGORY_COUNT; i++)
{
m_packetOutboxes[i].Clear();
+ m_throttleCategories[i] = null;
m_nextPackets[i] = null;
}
// pull the throttle out of the scene throttle
m_throttleClient.Parent.UnregisterRequest(m_throttleClient);
+ m_throttleClient = null;
OnPacketStats = null;
OnQueueEmpty = null;
- }
+ PendingAcks.Clear();
+ NeedAcks.Clear();
+ NeedAcks = null;
+ PendingAcks = null;
+ m_nextPackets = null;
+ m_packetOutboxes = null;
+ }
///
/// Gets information about this client connection
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/UnackedPacketCollection.cs b/OpenSim/Region/ClientStack/Linden/UDP/UnackedPacketCollection.cs
index b546a99603..c9d5697b23 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/UnackedPacketCollection.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/UnackedPacketCollection.cs
@@ -74,6 +74,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
/// Holds information about pending removals
private LocklessQueue m_pendingRemoves = new LocklessQueue();
+
+ public void Clear()
+ {
+ m_packets.Clear();
+ m_pendingAdds = null;
+ m_pendingAcknowledgements = null;
+ m_pendingRemoves = null;
+ }
+
///
/// Add an unacked packet to the collection
///
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index f73d54e249..2cfdd946f9 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -1104,7 +1104,7 @@ namespace OpenSim.Region.Framework.Scenes
AdjustKnownSeeds();
- RegisterToEvents();
+ RegisterToClientEvents();
SetDirectionVectors();
Appearance = appearance;
@@ -1171,7 +1171,7 @@ namespace OpenSim.Region.Framework.Scenes
}
}
- public void RegisterToEvents()
+ public void RegisterToClientEvents()
{
ControllingClient.OnCompleteMovementToRegion += CompleteMovement;
ControllingClient.OnAgentUpdate += HandleAgentUpdate;
@@ -1189,6 +1189,22 @@ namespace OpenSim.Region.Framework.Scenes
// ControllingClient.OnChildAgentStatus += new StatusChange(this.ChildStatusChange);
// ControllingClient.OnStopMovement += new GenericCall2(this.StopMovement);
}
+
+ public void RemoveClientEvents()
+ {
+ ControllingClient.OnCompleteMovementToRegion -= CompleteMovement;
+ ControllingClient.OnAgentUpdate -= HandleAgentUpdate;
+ ControllingClient.OnAgentCameraUpdate -= HandleAgentCamerasUpdate;
+ ControllingClient.OnAgentRequestSit -= HandleAgentRequestSit;
+ ControllingClient.OnAgentSit -= HandleAgentSit;
+ ControllingClient.OnSetAlwaysRun -= HandleSetAlwaysRun;
+ ControllingClient.OnStartAnim -= HandleStartAnim;
+ ControllingClient.OnStopAnim -= HandleStopAnim;
+ ControllingClient.OnChangeAnim -= avnHandleChangeAnim;
+ ControllingClient.OnForceReleaseControls -= HandleForceReleaseControls;
+ ControllingClient.OnAutoPilotGo -= MoveToTarget;
+ ControllingClient.OnUpdateThrottles -= RaiseUpdateThrottles;
+ }
private void SetDirectionVectors()
{
@@ -5016,12 +5032,16 @@ namespace OpenSim.Region.Framework.Scenes
RemoveFromPhysicalScene();
m_scene.EventManager.OnRegionHeartbeatEnd -= RegionHeartbeatEnd;
+ RemoveClientEvents();
// if (Animator != null)
// Animator.Close();
Animator = null;
+ scriptedcontrols.Clear();
+ ControllingClient = null;
LifecycleState = ScenePresenceState.Removed;
+ IsDeleted = true;
}
public void AddAttachment(SceneObjectGroup gobj)