From 7e8320bada32b642058487b84af2c8355fc18292 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Wed, 17 Sep 2008 22:00:56 +0000 Subject: 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. --- .../ScriptEngine/Interfaces/IScriptInstance.cs | 1 + .../Shared/Api/Implementation/LSL_Api.cs | 8 +++ .../ScriptEngine/Shared/Instance/ScriptInstance.cs | 60 ++++++++++++++++++++-- OpenSim/Region/ScriptEngine/XEngine/XEngine.cs | 1 + 4 files changed, 67 insertions(+), 3 deletions(-) (limited to 'OpenSim/Region/ScriptEngine') diff --git a/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs b/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs index a05edbd..0c807a8 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 20b52b7..2b19ae1 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 da55858..dd1bfaa 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 3b48362..466a879 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; -- cgit v1.1