From 7e8320bada32b642058487b84af2c8355fc18292 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Wed, 17 Sep 2008 22:00:56 +0000 Subject: [PATCH] Kan-Ed fix series. Fix llTakeControls to behave as documented. XEngine fixes: prevent queue overruns, prevent spamming when no key is down. Release controls when conflicting permissions are requested or permissions are refused later. Release when prim or script are deleted. Fixes Scene script instance deletion semantics. --- .../Environment/Scenes/Scene.Inventory.cs | 7 ++- OpenSim/Region/Environment/Scenes/Scene.cs | 2 + .../Environment/Scenes/SceneObjectGroup.cs | 2 +- .../Interfaces/IScriptInstance.cs | 1 + .../Shared/Api/Implementation/LSL_Api.cs | 8 +++ .../Shared/Instance/ScriptInstance.cs | 60 ++++++++++++++++++- .../Region/ScriptEngine/XEngine/XEngine.cs | 1 + prebuild.xml | 1 + 8 files changed, 75 insertions(+), 7 deletions(-) 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 @@ +