diff --git a/OpenSim/Region/Environment/Scenes/Scene.Inventory.cs b/OpenSim/Region/Environment/Scenes/Scene.Inventory.cs index cdd69430cd..7836937459 100644 --- a/OpenSim/Region/Environment/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Environment/Scenes/Scene.Inventory.cs @@ -879,12 +879,13 @@ namespace OpenSim.Region.Environment.Scenes SceneObjectGroup group = part.ParentGroup; if (group != null) { - int type = group.RemoveInventoryItem(localID, itemID); - part.GetProperties(remoteClient); - if (type == 10) + TaskInventoryItem item = group.GetInventoryItem(localID, itemID); + if (item.Type == 10) { EventManager.TriggerRemoveScript(localID, itemID); } + group.RemoveInventoryItem(localID, itemID); + part.GetProperties(remoteClient); } else { diff --git a/OpenSim/Region/Environment/Scenes/Scene.cs b/OpenSim/Region/Environment/Scenes/Scene.cs index 78c8c62b4f..8ee217958b 100644 --- a/OpenSim/Region/Environment/Scenes/Scene.cs +++ b/OpenSim/Region/Environment/Scenes/Scene.cs @@ -1742,6 +1742,8 @@ namespace OpenSim.Region.Environment.Scenes { //SceneObjectPart rootPart = group.GetChildPart(group.UUID); + group.RemoveScriptInstances(); + foreach (SceneObjectPart part in group.Children.Values) { if (part.PhysActor != null) diff --git a/OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs index 514f6d8f51..5670492b8b 100644 --- a/OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs @@ -958,7 +958,7 @@ namespace OpenSim.Region.Environment.Scenes { foreach (SceneObjectPart part in m_parts.Values) { - part.RemoveScriptInstances(); +// part.RemoveScriptInstances(); List avatars = Scene.GetScenePresences(); for (int i = 0; i < avatars.Count; i++) diff --git a/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs b/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs index a05edbd1b3..0c807a8bb9 100644 --- a/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs +++ b/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs @@ -93,6 +93,7 @@ namespace OpenSim.Region.ScriptEngine.Interfaces DetectParams GetDetectParams(int idx); UUID GetDetectID(int idx); void SaveState(string assembly); + void DestroyScriptInstance(); IScriptApi GetApi(string name); } diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 20b52b74cc..2b19ae12ea 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -2553,6 +2553,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (agentID == UUID.Zero || perm == 0) // Releasing permissions { + llReleaseControls(); + m_host.TaskInventory[invItemID].PermsGranter=UUID.Zero; m_host.TaskInventory[invItemID].PermsMask=0; @@ -2564,6 +2566,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return; } + if ( m_host.TaskInventory[invItemID].PermsGranter != agentID || (perm & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0) + llReleaseControls(); + m_host.AddScriptLPS(1); if (m_host.ParentGroup.RootPart.IsAttachment && agent == m_host.ParentGroup.RootPart.AttachedAvatar) @@ -2648,6 +2653,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api client.OnScriptAnswer-=handleScriptAnswer; m_waitingForScriptAnswer=false; + if((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0) + llReleaseControls(); + m_host.TaskInventory[invItemID].PermsMask=answer; m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( "run_time_permissions", new Object[] { diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs index da55858a71..dd1bfaa2ad 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs @@ -77,6 +77,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance private int m_MaxScriptQueue; private bool m_SaveState = true; private bool m_ShuttingDown = false; + private int m_ControlEventsInQueue = 0; + private int m_LastControlLevel = 0; private Dictionary m_Apis = new Dictionary(); @@ -320,6 +322,29 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance } } + private void ReleaseControls() + { + SceneObjectPart part=m_Engine.World.GetSceneObjectPart(m_LocalID); + if (part != null && part.TaskInventory.ContainsKey(m_ItemID)) + { + UUID permsGranter = part.TaskInventory[m_ItemID].PermsGranter; + int permsMask = part.TaskInventory[m_ItemID].PermsMask; + + if ((permsMask & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) != 0) + { + + ScenePresence presence = m_Engine.World.GetScenePresence(permsGranter); + if (presence != null) + presence.UnRegisterControlEventsToScript(m_LocalID, m_ItemID); + } + } + } + + public void DestroyScriptInstance() + { + ReleaseControls(); + } + public void RemoveState() { string savedState = Path.Combine(Path.GetDirectoryName(m_Assembly), @@ -439,7 +464,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance if (m_EventQueue.Count >= m_MaxScriptQueue) return; - m_EventQueue.Enqueue(data); if (data.EventName == "timer") { if (m_TimerQueued) @@ -447,8 +471,31 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance m_TimerQueued = true; } - if (!m_RunEvents) - return; + if (data.EventName == "control") + { + int held = ((LSL_Types.LSLInteger)data.Params[1]).value; + int changed= ((LSL_Types.LSLInteger)data.Params[2]).value; + + // If the last message was a 0 (nothing held) + // and this one is also nothing held, drop it + // + if (m_LastControlLevel == held && held == 0) + return; + + // If there is one or more queued, then queue + // only changed ones, else queue unconditionally + // + if (m_ControlEventsInQueue > 0) + { + if (m_LastControlLevel == held) + return; + } + + m_LastControlLevel = held; + m_ControlEventsInQueue++; + } + + m_EventQueue.Enqueue(data); if (m_CurrentResult == null) { @@ -475,6 +522,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance } if (data.EventName == "timer") m_TimerQueued = false; + if (data.EventName == "control") + { + if (m_ControlEventsInQueue > 0) + m_ControlEventsInQueue--; + } } //m_log.DebugFormat("[XENGINE]: Processing event {0} for {1}", data.EventName, this); @@ -616,6 +668,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance bool running = Running; RemoveState(); + ReleaseControls(); Stop(0); SceneObjectPart part=m_Engine.World.GetSceneObjectPart(m_LocalID); @@ -641,6 +694,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance // bool running = Running; RemoveState(); + ReleaseControls(); m_Script.ResetVars(); SceneObjectPart part=m_Engine.World.GetSceneObjectPart(m_LocalID); diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs index 3b48362dfa..466a879de8 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs @@ -565,6 +565,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine } instance.RemoveState(); + instance.DestroyScriptInstance(); instance = null; diff --git a/prebuild.xml b/prebuild.xml index 324d7c7fb4..0da4bb24f1 100644 --- a/prebuild.xml +++ b/prebuild.xml @@ -1830,6 +1830,7 @@ +