From 05ac6d3209afb640926995d252e8513ef3003819 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Fri, 11 Jan 2013 01:46:36 +0000 Subject: [PATCH 1/2] Save attachments on detach/exit if a contained script state has been changed. This involves making Attachments module listen for start/stop script changes. It also involves removing the script from the region on detach in the same manner as every other DeleteSceneObject() call rather than simply stopping it This is necessary tue to the bad assymetry of start and stop script triggers but it appears to be the correct behaviour anyway, as detached objects are completely gone from the sim. Not just in a state where their scripts have been stopped. --- .../Avatar/Attachments/AttachmentsModule.cs | 18 +++++++++++++++++- .../Region/Framework/Scenes/EventManager.cs | 3 +++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index 58ed554e10..f9c2142b8f 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs @@ -75,10 +75,26 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments m_scene.RegisterModuleInterface(this); if (Enabled) + { m_scene.EventManager.OnNewClient += SubscribeToClientEvents; + m_scene.EventManager.OnStartScript += HandleScriptStateChange; + m_scene.EventManager.OnStopScript += HandleScriptStateChange; + } // TODO: Should probably be subscribing to CloseClient too, but this doesn't yet give us IClientAPI } + + /// + /// Listen for client triggered running state changes so that we can persist the script's object if necessary. + /// + /// + /// + private void HandleScriptStateChange(uint localID, UUID itemID) + { + SceneObjectGroup sog = m_scene.GetGroupByPrim(localID); + if (sog != null && sog.IsAttachment) + sog.HasGroupChanged = true; + } public void RemoveRegion(Scene scene) { @@ -743,7 +759,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments // Remove the object from the scene so no more updates // are sent. Doing this before the below changes will ensure // updates can't cause "HUD artefacts" - m_scene.DeleteSceneObject(so, false, false); + m_scene.DeleteSceneObject(so, false); // Prepare sog for storage so.AttachedAvatar = UUID.Zero; diff --git a/OpenSim/Region/Framework/Scenes/EventManager.cs b/OpenSim/Region/Framework/Scenes/EventManager.cs index 6b08e0f8fe..902ded1f03 100644 --- a/OpenSim/Region/Framework/Scenes/EventManager.cs +++ b/OpenSim/Region/Framework/Scenes/EventManager.cs @@ -339,6 +339,8 @@ namespace OpenSim.Region.Framework.Scenes /// in /// via , /// via + /// XXX: This is only triggered when it is the client that starts the script, not in other situations where + /// a script is started, unlike OnStopScript! /// public event StartScript OnStartScript; @@ -352,6 +354,7 @@ namespace OpenSim.Region.Framework.Scenes /// in , /// , /// + /// XXX: This is triggered when a sciprt is stopped for any reason, unlike OnStartScript! /// public event StopScript OnStopScript; From 660d36a5b026e8b6862b9a575e9578d6ae1599a2 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Fri, 11 Jan 2013 02:28:43 +0000 Subject: [PATCH 2/2] Implement a workaround solution for saving manual script state changes by the user before logout instead of wrongly removing the script early. This workaround relies on the fact that a closing client goes inactive before the attachments derez calls happen. This reverts the change to remove scripts too early instead of stopping them, since the the two step stop then remove is necessary to execute the detach event. --- .../Avatar/Attachments/AttachmentsModule.cs | 24 +++++++++++++++---- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index f9c2142b8f..8a3eeaad97 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs @@ -77,8 +77,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments if (Enabled) { m_scene.EventManager.OnNewClient += SubscribeToClientEvents; - m_scene.EventManager.OnStartScript += HandleScriptStateChange; - m_scene.EventManager.OnStopScript += HandleScriptStateChange; + m_scene.EventManager.OnStartScript += (localID, itemID) => HandleScriptStateChange(localID, true); + m_scene.EventManager.OnStopScript += (localID, itemID) => HandleScriptStateChange(localID, false); } // TODO: Should probably be subscribing to CloseClient too, but this doesn't yet give us IClientAPI @@ -89,11 +89,25 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments /// /// /// - private void HandleScriptStateChange(uint localID, UUID itemID) + private void HandleScriptStateChange(uint localID, bool started) { SceneObjectGroup sog = m_scene.GetGroupByPrim(localID); if (sog != null && sog.IsAttachment) - sog.HasGroupChanged = true; + { + if (!started) + { + // FIXME: This is a convoluted way for working out whether the script state has changed to stop + // because it has been manually stopped or because the stop was called in UpdateDetachedObject() below + // This needs to be handled in a less tangled way. + ScenePresence sp = m_scene.GetScenePresence(sog.AttachedAvatar); + if (sp.ControllingClient.IsActive) + sog.HasGroupChanged = true; + } + else + { + sog.HasGroupChanged = true; + } + } } public void RemoveRegion(Scene scene) @@ -759,7 +773,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments // Remove the object from the scene so no more updates // are sent. Doing this before the below changes will ensure // updates can't cause "HUD artefacts" - m_scene.DeleteSceneObject(so, false); + m_scene.DeleteSceneObject(so, false, false); // Prepare sog for storage so.AttachedAvatar = UUID.Zero;