From 3358d70c5b174b2b9ac1216e9e43497279982805 Mon Sep 17 00:00:00 2001 From: Teravus Ovares Date: Sun, 20 Apr 2008 04:19:44 +0000 Subject: [PATCH] * Updates LSL2CS converter * All objects are not touchable by default now * When a script listens for one of the touch events in the state, an object becomes touchable. * All LSL scripts report which events they consume now ** This uses semi-complicated Regex to discover the events, stick them in a dictionary, and then write a method call into each script state's state_entry() event. ** Tedd may figure out a better way to do this in the future. For now, this works for LSL. --- .../Scenes/SceneObjectGroup.Inventory.cs | 2 + .../Environment/Scenes/SceneObjectGroup.cs | 135 ++++++++++++ .../Scenes/SceneObjectPart.Inventory.cs | 1 + .../Environment/Scenes/SceneObjectPart.cs | 14 +- .../Common/BuiltIn_Commands_BaseClass.cs | 4 + .../Common/LSL_BuiltIn_Commands.cs | 5 + .../Common/LSL_BuiltIn_Commands_Interface.cs | 1 + .../Compiler/LSL/LSL2CSConverter.cs | 200 +++++++++++++++++- 8 files changed, 358 insertions(+), 4 deletions(-) diff --git a/OpenSim/Region/Environment/Scenes/SceneObjectGroup.Inventory.cs b/OpenSim/Region/Environment/Scenes/SceneObjectGroup.Inventory.cs index 3f14fff00a..495b604aae 100644 --- a/OpenSim/Region/Environment/Scenes/SceneObjectGroup.Inventory.cs +++ b/OpenSim/Region/Environment/Scenes/SceneObjectGroup.Inventory.cs @@ -51,6 +51,7 @@ namespace OpenSim.Region.Environment.Scenes if (part != null) { part.StartScript(itemID); + } else { @@ -119,6 +120,7 @@ namespace OpenSim.Region.Environment.Scenes if (part != null) { part.StopScript(itemID); + RemoveScriptEvents(itemID); } else { diff --git a/OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs index 1f38e4f498..7abaaee2f3 100644 --- a/OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs @@ -41,6 +41,40 @@ using OpenSim.Region.Physics.Manager; namespace OpenSim.Region.Environment.Scenes { + + [Flags] + public enum scriptEvents : int + { + None = 0, + attach = 1, + collision = 15, + collision_end = 32, + collision_start = 64, + control = 128, + dataserver = 256, + email = 512, + http_response = 1024, + land_collision = 2048, + land_collision_end = 4096, + land_collision_start = 8192, + link_message = 16384, + listen = 32768, + money = 65536, + moving_end = 131072, + moving_start = 262144, + not_at_rot_target = 524288, + not_at_target = 1048576, + remote_data = 8388608, + run_time_permissions = 268435456, + state_entry = 1073741824, + state_exit = 2, + timer = 4, + touch = 8, + touch_end = 536870912, + touch_start = 2097152, + object_rez = 4194304 + } + public delegate void PrimCountTaintedDelegate(); public partial class SceneObjectGroup : EntityBase @@ -67,6 +101,9 @@ namespace OpenSim.Region.Environment.Scenes private LLVector3 lastPhysGroupPos; private LLQuaternion lastPhysGroupRot; + private Dictionary m_scriptEvents = new Dictionary(); + private scriptEvents m_aggregateScriptEvents = scriptEvents.None; + #region Properties /// @@ -2042,6 +2079,104 @@ namespace OpenSim.Region.Environment.Scenes d.AddActiveScripts(count); } + public void RemoveScriptEvents(LLUUID scriptid) + { + lock (m_scriptEvents) + { + if (m_scriptEvents.ContainsKey(scriptid)) + { + scriptEvents oldparts = scriptEvents.None; + oldparts = (scriptEvents)m_scriptEvents[scriptid]; + + // remove values from aggregated script events + m_aggregateScriptEvents &= ~oldparts; + m_scriptEvents.Remove(scriptid); + } + + } + aggregateScriptEvents(); + } + + public void SetScriptEvents(LLUUID scriptid, int events) + { + + scriptEvents oldparts = scriptEvents.None; + lock (m_scriptEvents) + { + if (m_scriptEvents.ContainsKey(scriptid)) + { + oldparts = (scriptEvents)m_scriptEvents[scriptid]; + + // remove values from aggregated script events + m_aggregateScriptEvents &= ~oldparts; + m_scriptEvents[scriptid] = (scriptEvents)events; + } + else + { + m_scriptEvents.Add(scriptid, (scriptEvents)events); + } + + } + + aggregateScriptEvents(); + } + public void aggregateScriptEvents() + { + // Aggregate script events + lock (m_scriptEvents) + { + foreach (scriptEvents s in m_scriptEvents.Values) + { + m_aggregateScriptEvents |= s; + } + } + uint objectflagupdate = m_rootPart.ObjectFlags; + + if ( + ((m_aggregateScriptEvents & scriptEvents.touch) != 0) || + ((m_aggregateScriptEvents & scriptEvents.touch_end) != 0) || + ((m_aggregateScriptEvents & scriptEvents.touch_start) != 0) + ) + { + objectflagupdate |= (uint)LLObject.ObjectFlags.Touch; + } + else + { + objectflagupdate &= ~(uint)LLObject.ObjectFlags.Touch; + } + + if ((m_aggregateScriptEvents & scriptEvents.money) != 0) + { + objectflagupdate |= (uint)LLObject.ObjectFlags.Money; + } + else + { + objectflagupdate &= ~(uint)LLObject.ObjectFlags.Money; + } + + if ( + ((m_aggregateScriptEvents & scriptEvents.collision) != 0) || + ((m_aggregateScriptEvents & scriptEvents.collision_end) != 0) || + ((m_aggregateScriptEvents & scriptEvents.collision_start) != 0) + ) + { + // subscribe to physics updates. + } + else + { + // unsubscribe to physics updates. + } + lock (m_parts) + { + foreach (SceneObjectPart part in m_parts.Values) + { + part.ObjectFlags = objectflagupdate; + } + } + ScheduleGroupForFullUpdate(); + + } + public override void SetText(string text, Vector3 color, double alpha) { Color = Color.FromArgb(0xff - (int) (alpha*0xff), diff --git a/OpenSim/Region/Environment/Scenes/SceneObjectPart.Inventory.cs b/OpenSim/Region/Environment/Scenes/SceneObjectPart.Inventory.cs index 16da516cbf..8ce71c494c 100644 --- a/OpenSim/Region/Environment/Scenes/SceneObjectPart.Inventory.cs +++ b/OpenSim/Region/Environment/Scenes/SceneObjectPart.Inventory.cs @@ -147,6 +147,7 @@ namespace OpenSim.Region.Environment.Scenes if (10 == item.Type) { StopScript(item.ItemID); + m_parentGroup.RemoveScriptEvents(item.ItemID); } } } diff --git a/OpenSim/Region/Environment/Scenes/SceneObjectPart.cs b/OpenSim/Region/Environment/Scenes/SceneObjectPart.cs index b42375f871..61d10c9587 100644 --- a/OpenSim/Region/Environment/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Environment/Scenes/SceneObjectPart.cs @@ -83,6 +83,7 @@ namespace OpenSim.Region.Environment.Scenes SCALE = 0x40 } + [Serializable] public partial class SceneObjectPart : IScriptHost, ISerializable { @@ -729,8 +730,7 @@ namespace OpenSim.Region.Environment.Scenes m_folderID = LLUUID.Random(); Flags = 0; - Flags |= LLObject.ObjectFlags.Touch | - LLObject.ObjectFlags.AllowInventoryDrop | + Flags |= LLObject.ObjectFlags.AllowInventoryDrop | LLObject.ObjectFlags.CreateSelected; @@ -774,7 +774,7 @@ namespace OpenSim.Region.Environment.Scenes // Since we don't store script state, this is only a 'temporary' objectflag now // If the object is scripted, the script will get loaded and this will be set again - ObjectFlags &= ~(uint)LLObject.ObjectFlags.Scripted; + ObjectFlags &= ~(uint)(LLObject.ObjectFlags.Scripted | LLObject.ObjectFlags.Touch); TrimPermissions(); // ApplyPhysics(); @@ -2312,6 +2312,14 @@ namespace OpenSim.Region.Environment.Scenes SetText( text ); } + public void setScriptEvents(LLUUID scriptID, int events) + { + if (m_parentGroup != null) + { + m_parentGroup.SetScriptEvents(scriptID, events); + } + } + protected SceneObjectPart(SerializationInfo info, StreamingContext context) { //System.Console.WriteLine("SceneObjectPart Deserialize BGN"); diff --git a/OpenSim/Region/ScriptEngine/Common/BuiltIn_Commands_BaseClass.cs b/OpenSim/Region/ScriptEngine/Common/BuiltIn_Commands_BaseClass.cs index cb4ca3917d..b6468c2b66 100644 --- a/OpenSim/Region/ScriptEngine/Common/BuiltIn_Commands_BaseClass.cs +++ b/OpenSim/Region/ScriptEngine/Common/BuiltIn_Commands_BaseClass.cs @@ -1990,6 +1990,10 @@ namespace OpenSim.Region.ScriptEngine.Common return m_LSL_Functions.osDrawImage(drawList, width, height, imageUrl); } + public void osSetStateEvents(int events) + { + m_LSL_Functions.osSetStateEvents(events); + } // diff --git a/OpenSim/Region/ScriptEngine/Common/LSL_BuiltIn_Commands.cs b/OpenSim/Region/ScriptEngine/Common/LSL_BuiltIn_Commands.cs index 26e56c7cb2..4192d40ade 100644 --- a/OpenSim/Region/ScriptEngine/Common/LSL_BuiltIn_Commands.cs +++ b/OpenSim/Region/ScriptEngine/Common/LSL_BuiltIn_Commands.cs @@ -5597,6 +5597,11 @@ namespace OpenSim.Region.ScriptEngine.Common return drawList; } + public void osSetStateEvents(int events) + { + m_host.setScriptEvents(m_itemID,events); + } + private void NotImplemented(string command) { if (throwErrorOnNotImplemented) diff --git a/OpenSim/Region/ScriptEngine/Common/LSL_BuiltIn_Commands_Interface.cs b/OpenSim/Region/ScriptEngine/Common/LSL_BuiltIn_Commands_Interface.cs index 4e632efccd..205e90836e 100644 --- a/OpenSim/Region/ScriptEngine/Common/LSL_BuiltIn_Commands_Interface.cs +++ b/OpenSim/Region/ScriptEngine/Common/LSL_BuiltIn_Commands_Interface.cs @@ -669,5 +669,6 @@ namespace OpenSim.Region.ScriptEngine.Common string osSetPenSize(string drawList, int penSize); string osSetPenColour(string drawList, string colour); string osDrawImage(string drawList, int width, int height, string imageUrl); + void osSetStateEvents(int events); } } diff --git a/OpenSim/Region/ScriptEngine/DotNetEngine/Compiler/LSL/LSL2CSConverter.cs b/OpenSim/Region/ScriptEngine/DotNetEngine/Compiler/LSL/LSL2CSConverter.cs index 9f753df65f..8d85b690d3 100644 --- a/OpenSim/Region/ScriptEngine/DotNetEngine/Compiler/LSL/LSL2CSConverter.cs +++ b/OpenSim/Region/ScriptEngine/DotNetEngine/Compiler/LSL/LSL2CSConverter.cs @@ -32,6 +32,7 @@ using System; namespace OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.LSL { + public class LSL2CSConverter { @@ -41,6 +42,7 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.LSL //private Regex rnw = new Regex(@"[a-zA-Z0-9_\-]", RegexOptions.Compiled); private Dictionary dataTypes = new Dictionary(); private Dictionary quotes = new Dictionary(); + private Dictionary state_events = new Dictionary(); public LSL2CSConverter() { @@ -294,8 +296,63 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.LSL } + // Finds out which events are in the script and writes a method call with the events in each state_entry event + + // Note the (?:)? block optional, and not returning a group. Less greedy then .* + + string[] eventmatches = new string[0]; + //Regex stateevents = new Regex(@"(public void )([^_]+)(_event_)([^\(]+)[\(\)]+\s+[^\{]\{"); + eventmatches = Regex.Split(Script, @"public void\s([^_]+)_event_([^\(]+)\((?:[a-zA-Z0-9\s_,\.\-]+)?\)+\s+[^\{]\{", RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.Singleline | RegexOptions.IgnoreCase); + for (int pos = 0; pos