diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
index eccf7a6977..efab6ed5ff 100644
--- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
@@ -211,16 +211,20 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
lock (sp.AttachmentsSyncLock)
{
- foreach (SceneObjectGroup grp in sp.GetAttachments())
+ foreach (SceneObjectGroup so in sp.GetAttachments())
{
- grp.Scene.DeleteSceneObject(grp, false);
+ // We can only remove the script instances from the script engine after we've retrieved their xml state
+ // when we update the attachment item.
+ m_scene.DeleteSceneObject(so, false, false);
if (saveChanged || saveAllScripted)
{
- grp.IsAttachment = false;
- grp.AbsolutePosition = grp.RootPart.AttachedPos;
- UpdateKnownItem(sp, grp, saveAllScripted);
+ so.IsAttachment = false;
+ so.AbsolutePosition = so.RootPart.AttachedPos;
+ UpdateKnownItem(sp, so, saveAllScripted);
}
+
+ so.RemoveScriptInstances(true);
}
sp.ClearAttachments();
@@ -682,7 +686,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
m_scene.EventManager.TriggerOnAttach(so.LocalId, so.FromItemID, UUID.Zero);
sp.RemoveAttachment(so);
- m_scene.DeleteSceneObject(so, false);
+
+ // We can only remove the script instances from the script engine after we've retrieved their xml state
+ // when we update the attachment item.
+ m_scene.DeleteSceneObject(so, false, false);
// Prepare sog for storage
so.AttachedAvatar = UUID.Zero;
@@ -691,6 +698,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
so.AbsolutePosition = so.RootPart.AttachedPos;
UpdateKnownItem(sp, so, true);
+ so.RemoveScriptInstances(true);
}
private SceneObjectGroup RezSingleAttachmentFromInventoryInternal(
diff --git a/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs b/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs
index 1c9bdce832..8d6284739b 100644
--- a/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs
+++ b/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs
@@ -92,7 +92,7 @@ namespace OpenSim.Region.Framework.Interfaces
void ResumeScripts();
///
- /// Stop all the scripts in this entity.
+ /// Stop and remove all the scripts in this entity from the scene.
///
///
/// Should be true if these scripts are being removed because the scene
@@ -100,6 +100,11 @@ namespace OpenSim.Region.Framework.Interfaces
///
void RemoveScriptInstances(bool sceneObjectBeingDeleted);
+ ///
+ /// Stop all the scripts in this entity.
+ ///
+ void StopScriptInstances();
+
///
/// Start a script which is in this entity's inventory.
///
@@ -129,7 +134,7 @@ namespace OpenSim.Region.Framework.Interfaces
bool CreateScriptInstance(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource);
///
- /// Stop a script which is in this prim's inventory.
+ /// Stop and remove a script which is in this prim's inventory from the scene.
///
///
///
@@ -138,6 +143,12 @@ namespace OpenSim.Region.Framework.Interfaces
///
void RemoveScriptInstance(UUID itemId, bool sceneObjectBeingDeleted);
+ ///
+ /// Stop a script which is in this prim's inventory.
+ ///
+ ///
+ void StopScriptInstance(UUID itemId);
+
///
/// Add an item to this entity's inventory. If an item with the same name already exists, then an alternative
/// name is chosen.
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index ec911a52d4..25223b95b3 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -2183,13 +2183,30 @@ namespace OpenSim.Region.Framework.Scenes
///
/// Synchronously delete the given object from the scene.
///
+ ///
+ /// Scripts are also removed.
+ ///
/// Object Id
/// Suppress broadcasting changes to other clients.
public void DeleteSceneObject(SceneObjectGroup group, bool silent)
+ {
+ DeleteSceneObject(group, silent, true);
+ }
+
+ ///
+ /// Synchronously delete the given object from the scene.
+ ///
+ /// Object Id
+ /// Suppress broadcasting changes to other clients.
+ /// If true, then scripts are removed. If false, then they are only stopped.
+ public void DeleteSceneObject(SceneObjectGroup group, bool silent, bool removeScripts)
{
// m_log.DebugFormat("[SCENE]: Deleting scene object {0} {1}", group.Name, group.UUID);
- group.RemoveScriptInstances(true);
+ if (removeScripts)
+ group.RemoveScriptInstances(true);
+ else
+ group.StopScriptInstances();
SceneObjectPart[] partList = group.Parts;
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs
index 2866b546eb..ddf5da0ba4 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs
@@ -79,7 +79,7 @@ namespace OpenSim.Region.Framework.Scenes
}
///
- /// Stop the scripts contained in all the prims in this group
+ /// Stop and remove the scripts contained in all the prims in this group
///
///
/// Should be true if these scripts are being removed because the scene
@@ -92,6 +92,14 @@ namespace OpenSim.Region.Framework.Scenes
parts[i].Inventory.RemoveScriptInstances(sceneObjectBeingDeleted);
}
+ ///
+ /// Stop the scripts contained in all the prims in this group
+ ///
+ public void StopScriptInstances()
+ {
+ Array.ForEach(m_parts.GetArray(), p => p.Inventory.StopScriptInstances());
+ }
+
///
/// Add an inventory item from a user's inventory to a prim in this scene object.
///
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
index 866311a298..cf2ed1a802 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
@@ -280,7 +280,7 @@ namespace OpenSim.Region.Framework.Scenes
}
///
- /// Stop all the scripts in this prim.
+ /// Stop and remove all the scripts in this prim.
///
///
/// Should be true if these scripts are being removed because the scene
@@ -293,6 +293,14 @@ namespace OpenSim.Region.Framework.Scenes
RemoveScriptInstance(item.ItemID, sceneObjectBeingDeleted);
}
+ ///
+ /// Stop all the scripts in this prim.
+ ///
+ public void StopScriptInstances()
+ {
+ GetInventoryItems(InventoryType.LSL).ForEach(i => StopScriptInstance(i));
+ }
+
///
/// Start a script which is in this prim's inventory.
///
@@ -443,7 +451,7 @@ namespace OpenSim.Region.Framework.Scenes
}
///
- /// Stop a script which is in this prim's inventory.
+ /// Stop and remove a script which is in this prim's inventory.
///
///
///
@@ -470,7 +478,7 @@ namespace OpenSim.Region.Framework.Scenes
}
else
{
- m_log.ErrorFormat(
+ m_log.WarnFormat(
"[PRIM INVENTORY]: " +
"Couldn't stop script with ID {0} since it couldn't be found for prim {1}, {2} at {3} in {4}",
itemId, m_part.Name, m_part.UUID,
@@ -478,6 +486,51 @@ namespace OpenSim.Region.Framework.Scenes
}
}
+ ///
+ /// Stop a script which is in this prim's inventory.
+ ///
+ ///
+ ///
+ /// Should be true if this script is being removed because the scene
+ /// object is being deleted. This will prevent spurious updates to the client.
+ ///
+ public void StopScriptInstance(UUID itemId)
+ {
+ TaskInventoryItem scriptItem;
+
+ lock (m_items)
+ m_items.TryGetValue(itemId, out scriptItem);
+
+ if (scriptItem != null)
+ {
+ StopScriptInstance(scriptItem);
+ }
+ else
+ {
+ m_log.WarnFormat(
+ "[PRIM INVENTORY]: " +
+ "Couldn't stop script with ID {0} since it couldn't be found for prim {1}, {2} at {3} in {4}",
+ itemId, m_part.Name, m_part.UUID,
+ m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName);
+ }
+ }
+
+ ///
+ /// Stop a script which is in this prim's inventory.
+ ///
+ ///
+ ///
+ /// Should be true if this script is being removed because the scene
+ /// object is being deleted. This will prevent spurious updates to the client.
+ ///
+ public void StopScriptInstance(TaskInventoryItem item)
+ {
+ m_part.ParentGroup.Scene.EventManager.TriggerStopScript(m_part.LocalId, item.ItemID);
+
+ // At the moment, even stopped scripts are counted as active, which is probably wrong.
+// m_part.ParentGroup.AddActiveScriptCount(-1);
+ }
+
///
/// Check if the inventory holds an item with a given name.
///