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. --- .../Shared/Api/Implementation/LSL_Api.cs | 8 +++ .../ScriptEngine/Shared/Instance/ScriptInstance.cs | 60 ++++++++++++++++++++-- 2 files changed, 65 insertions(+), 3 deletions(-) (limited to 'OpenSim/Region/ScriptEngine/Shared') 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); -- cgit v1.1