From 36bf16d35e928a338c932feeec42c0c8f35d8846 Mon Sep 17 00:00:00 2001 From: Teravus Ovares Date: Wed, 30 Apr 2008 03:36:13 +0000 Subject: [PATCH] Patch from Melanie: 0001077: [PATCH] LSL types cannot be cast implicitly or explicitly in many cases Thanks Melanie! * Also, I moved the event parser and re-writer to a separate static object. More work will be done here shortly. --- .../Common/LSL_BuiltIn_Commands.cs | 64 ++- .../Region/ScriptEngine/Common/LSL_Types.cs | 176 +++++-- .../AsyncCommandPlugins/HttpRequest.cs | 2 +- .../AsyncCommandPlugins/Listener.cs | 2 +- .../AsyncCommandPlugins/SensorRepeat.cs | 2 +- .../AsyncCommandPlugins/XmlRequest.cs | 12 +- .../Common/ScriptEngineBase/EventManager.cs | 23 +- .../Common/ScriptServerInterfaces.cs | 2 +- .../DotNetEngine/Compiler/LSL/Compiler.cs | 2 + .../Compiler/LSL/EventReaderRewriter.cs | 488 ++++++++++++++++++ .../Compiler/LSL/LSL2CSConverter.cs | 250 +-------- 11 files changed, 684 insertions(+), 339 deletions(-) create mode 100644 OpenSim/Region/ScriptEngine/DotNetEngine/Compiler/LSL/EventReaderRewriter.cs diff --git a/OpenSim/Region/ScriptEngine/Common/LSL_BuiltIn_Commands.cs b/OpenSim/Region/ScriptEngine/Common/LSL_BuiltIn_Commands.cs index e29ee5a79e..66d2700948 100644 --- a/OpenSim/Region/ScriptEngine/Common/LSL_BuiltIn_Commands.cs +++ b/OpenSim/Region/ScriptEngine/Common/LSL_BuiltIn_Commands.cs @@ -80,6 +80,15 @@ namespace OpenSim.Region.ScriptEngine.Common // Set it if it changed if (m_state != value) { + try + { + m_ScriptEngine.m_EventManager.state_exit(m_localID); + + } + catch (AppDomainUnloadedException) + { + Console.WriteLine("[SCRIPT]: state change called when script was unloaded. Nothing to worry about, but noting the occurance"); + } m_state = value; try { @@ -2136,7 +2145,7 @@ namespace OpenSim.Region.ScriptEngine.Common m_host.TaskInventory[invItemID].PermsMask=0; m_ScriptEngine.m_EventQueueManager.AddToScriptQueue( - m_localID, m_itemID, "run_time_permissions", EventQueueManager.llDetectNull, new Object[] {(int)0}); + m_localID, m_itemID, "run_time_permissions", EventQueueManager.llDetectNull, new Object[] {new LSL_Types.LSLInteger(0)}); return; } @@ -2158,7 +2167,7 @@ namespace OpenSim.Region.ScriptEngine.Common m_host.TaskInventory[invItemID].PermsMask=perm; m_ScriptEngine.m_EventQueueManager.AddToScriptQueue( - m_localID, m_itemID, "run_time_permissions", EventQueueManager.llDetectNull, new Object[] {(int)perm}); + m_localID, m_itemID, "run_time_permissions", EventQueueManager.llDetectNull, new Object[] {new LSL_Types.LSLInteger(perm)}); return; } @@ -2175,7 +2184,7 @@ namespace OpenSim.Region.ScriptEngine.Common m_host.TaskInventory[invItemID].PermsMask=perm; m_ScriptEngine.m_EventQueueManager.AddToScriptQueue( - m_localID, m_itemID, "run_time_permissions", EventQueueManager.llDetectNull, new Object[] {(int)perm}); + m_localID, m_itemID, "run_time_permissions", EventQueueManager.llDetectNull, new Object[] {new LSL_Types.LSLInteger(perm)}); return; } @@ -2202,7 +2211,7 @@ namespace OpenSim.Region.ScriptEngine.Common // Requested agent is not in range, refuse perms m_ScriptEngine.m_EventQueueManager.AddToScriptQueue( - m_localID, m_itemID, "run_time_permissions", EventQueueManager.llDetectNull, new Object[] {(int)0}); + m_localID, m_itemID, "run_time_permissions", EventQueueManager.llDetectNull, new Object[] {new LSL_Types.LSLInteger(0)}); } void handleScriptAnswer(IClientAPI client, LLUUID taskID, LLUUID itemID, int answer) @@ -2220,7 +2229,7 @@ namespace OpenSim.Region.ScriptEngine.Common m_host.TaskInventory[invItemID].PermsMask=answer; m_ScriptEngine.m_EventQueueManager.AddToScriptQueue( - m_localID, m_itemID, "run_time_permissions", EventQueueManager.llDetectNull, new Object[] {(int)answer}); + m_localID, m_itemID, "run_time_permissions", EventQueueManager.llDetectNull, new Object[] {new LSL_Types.LSLInteger(answer)}); } public string llGetPermissionsKey() @@ -2600,7 +2609,7 @@ namespace OpenSim.Region.ScriptEngine.Common object[] resobj = new object[] { - m_host.LinkNum + 1, num, msg, id + new LSL_Types.LSLInteger(m_host.LinkNum + 1), new LSL_Types.LSLInteger(num), new LSL_Types.LSLString(msg), new LSL_Types.LSLString(id) }; m_ScriptEngine.m_EventQueueManager.AddToScriptQueue( @@ -2627,7 +2636,7 @@ namespace OpenSim.Region.ScriptEngine.Common partItemID = item.ItemID; Object[] resobj = new object[] { - m_host.LinkNum + 1, num, msg, id + new LSL_Types.LSLInteger(m_host.LinkNum + 1), new LSL_Types.LSLInteger(num), new LSL_Types.LSLString(msg), new LSL_Types.LSLString(id) }; m_ScriptEngine.m_EventQueueManager.AddToScriptQueue( @@ -2655,7 +2664,7 @@ namespace OpenSim.Region.ScriptEngine.Common partItemID = item.ItemID; Object[] resobj = new object[] { - m_host.LinkNum + 1, num, msg, id + new LSL_Types.LSLInteger(m_host.LinkNum + 1), new LSL_Types.LSLInteger(num), new LSL_Types.LSLString(msg), new LSL_Types.LSLString(id) }; m_ScriptEngine.m_EventQueueManager.AddToScriptQueue( @@ -2685,7 +2694,7 @@ namespace OpenSim.Region.ScriptEngine.Common partItemID = item.ItemID; Object[] resobj = new object[] { - m_host.LinkNum + 1, num, msg, id + new LSL_Types.LSLInteger(m_host.LinkNum + 1), new LSL_Types.LSLInteger(num), new LSL_Types.LSLString(msg), new LSL_Types.LSLString(id) }; m_ScriptEngine.m_EventQueueManager.AddToScriptQueue( @@ -2709,7 +2718,7 @@ namespace OpenSim.Region.ScriptEngine.Common object[] resobj = new object[] { - m_host.LinkNum + 1, num, msg, id + new LSL_Types.LSLInteger(m_host.LinkNum + 1), new LSL_Types.LSLInteger(num), new LSL_Types.LSLString(msg), new LSL_Types.LSLString(id) }; m_ScriptEngine.m_EventQueueManager.AddToScriptQueue( @@ -2737,7 +2746,7 @@ namespace OpenSim.Region.ScriptEngine.Common partItemID = item.ItemID; Object[] resObjDef = new object[] { - m_host.LinkNum + 1, num, msg, id + new LSL_Types.LSLInteger(m_host.LinkNum + 1), new LSL_Types.LSLInteger(num), new LSL_Types.LSLString(msg), new LSL_Types.LSLString(id) }; m_ScriptEngine.m_EventQueueManager.AddToScriptQueue( @@ -3058,7 +3067,14 @@ namespace OpenSim.Region.ScriptEngine.Common { return 0; } - return Convert.ToInt32(src.Data[index]); + try + { + return Convert.ToInt32(src.Data[index]); + } + catch (System.FormatException e) + { + return 0; + } } public double osList2Double(LSL_Types.list src, int index) @@ -3086,7 +3102,14 @@ namespace OpenSim.Region.ScriptEngine.Common { return 0.0; } - return Convert.ToDouble(src.Data[index]); + try + { + return Convert.ToDouble(src.Data[index]); + } + catch (System.FormatException e) + { + return 0.0; + } } public string llList2String(LSL_Types.list src, int index) @@ -3112,18 +3135,9 @@ namespace OpenSim.Region.ScriptEngine.Common } if (index >= src.Length) { - return "00000000-0000-0000-0000-000000000000"; - } - //return OpenSim.Framework.ToString(src[index]); - LLUUID tmpkey; - if (LLUUID.TryParse(src.Data[index].ToString(), out tmpkey)) - { - return tmpkey.ToString(); - } - else - { - return "00000000-0000-0000-0000-000000000000"; + return ""; } + return src.Data[index].ToString(); } public LSL_Types.Vector3 llList2Vector(LSL_Types.list src, int index) @@ -4317,7 +4331,7 @@ namespace OpenSim.Region.ScriptEngine.Common if (xmlrpcMod.IsEnabled()) { LLUUID channelID = xmlrpcMod.OpenXMLRPCChannel(m_localID, m_itemID); - object[] resobj = new object[] { 1, channelID.ToString(), LLUUID.Zero.ToString(), String.Empty, 0, String.Empty }; + object[] resobj = new object[] { new LSL_Types.LSLInteger(1), new LSL_Types.LSLString(channelID.ToString()), new LSL_Types.LSLString(LLUUID.Zero.ToString()), new LSL_Types.LSLString(String.Empty), new LSL_Types.LSLInteger(0), new LSL_Types.LSLString(String.Empty) }; m_ScriptEngine.m_EventQueueManager.AddToScriptQueue(m_localID, m_itemID, "remote_data", EventQueueManager.llDetectNull, resobj); } } diff --git a/OpenSim/Region/ScriptEngine/Common/LSL_Types.cs b/OpenSim/Region/ScriptEngine/Common/LSL_Types.cs index 65047fbc4e..5337d7ffab 100644 --- a/OpenSim/Region/ScriptEngine/Common/LSL_Types.cs +++ b/OpenSim/Region/ScriptEngine/Common/LSL_Types.cs @@ -64,6 +64,11 @@ namespace OpenSim.Region.ScriptEngine.Common str = str.Replace('<', ' '); str = str.Replace('>', ' '); string[] tmps = str.Split(new Char[] { ',', '<', '>' }); + if(tmps.Length < 3) + { + x=y=z=0; + return; + } bool res; res = Double.TryParse(tmps[0], out x); res = res & Double.TryParse(tmps[1], out y); @@ -76,14 +81,27 @@ namespace OpenSim.Region.ScriptEngine.Common public override string ToString() { - return "<" + x.ToString() + ", " + y.ToString() + ", " + z.ToString() + ">"; + string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000}>", x, y, z); + return s; + } + + public static explicit operator LSLString(Vector3 vec) + { + string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000}>", vec.x, vec.y, vec.z); + return new LSLString(s); } public static explicit operator string(Vector3 vec) { - return "<" + vec.x.ToString() + ", " + vec.y.ToString() + ", " + vec.z.ToString() + ">"; + string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000}>", vec.x, vec.y, vec.z); + return s; } + public static explicit operator Vector3(string s) + { + return new Vector3(s); + } + public static bool operator ==(Vector3 lhs, Vector3 rhs) { return (lhs.x == rhs.x && lhs.y == rhs.y && lhs.z == rhs.z); @@ -278,6 +296,11 @@ namespace OpenSim.Region.ScriptEngine.Common str = str.Replace('<', ' '); str = str.Replace('>', ' '); string[] tmps = str.Split(new Char[] { ',', '<', '>' }); + if(tmps.Length < 4) + { + x=y=z=s=0; + return; + } bool res; res = Double.TryParse(tmps[0], out x); res = res & Double.TryParse(tmps[1], out y); @@ -307,14 +330,27 @@ namespace OpenSim.Region.ScriptEngine.Common public override string ToString() { - return "<" + x.ToString() + ", " + y.ToString() + ", " + z.ToString() + ", " + s.ToString() + ">"; + string st=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000},{3:0.000000}>", x, y, z, s); + return st; } public static explicit operator string(Quaternion r) { - return "<" + r.x.ToString() + ", " + r.y.ToString() + ", " + r.z.ToString() + ", " + r.s.ToString() + ">"; + string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000},{3:0.000000}>", r.x, r.y, r.z, r.s); + return s; } + public static explicit operator LSLString(Quaternion r) + { + string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000},{3:0.000000}>", r.x, r.y, r.z, r.s); + return new LSLString(s); + } + + public static explicit operator Quaternion(string s) + { + return new Quaternion(s); + } + public static bool operator ==(Quaternion lhs, Quaternion rhs) { // Return true if the fields match: @@ -369,12 +405,20 @@ namespace OpenSim.Region.ScriptEngine.Common public int Length { - get { return m_data.Length; } + get { + if(m_data == null) + m_data=new Object[0]; + return m_data.Length; + } } public object[] Data { - get { return m_data; } + get { + if(m_data == null) + m_data=new Object[0]; + return m_data; + } } public static list operator +(list a, list b) @@ -571,13 +615,20 @@ namespace OpenSim.Region.ScriptEngine.Common if(Data.Length == 0) return new list(); // Don't even bother + string[] keys; + if(stride == 1) // The simple case { Object[] ret=new Object[Data.Length]; Array.Copy(Data, 0, ret, 0, Data.Length); - Array.Sort(ret); + keys=new string[Data.Length]; + int k; + for(k=0;k state_events = new Dictionary(); + // 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_,\.\-]+)?\)(?:[^\{]+)?\{", RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.Singleline | RegexOptions.IgnoreCase); + for (int pos = 0; pos < eventmatches.GetUpperBound(0); pos++) + { + pos++; // garbage + + string statea = eventmatches[pos]; pos++; + string eventa = eventmatches[pos]; + scriptEvents storedEventsForState = scriptEvents.None; + if (state_events.ContainsKey(statea)) + { + storedEventsForState = state_events[statea]; + state_events[statea] |= convertnametoFlag(eventa); + } + else + { + state_events.Add(statea, convertnametoFlag(eventa)); + } + Console.WriteLine("State:" + statea + ", event: " + eventa); + } + Console.WriteLine("Matches:" + eventmatches.GetUpperBound(0)); + // Add namespace, class name and inheritance + + // Looking *ONLY* for state entry events + string scriptCopy = ""; + + //Only match State_Entry events now + // Note the whole regex is a group, then we have the state this entry belongs to. + eventmatches = Regex.Split(Script, @"(public void\s([^_]+)_event_state_entry[\(\)](?:[^\{]+)?\{)", RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.Singleline | RegexOptions.IgnoreCase); + int endloop = eventmatches.GetUpperBound(0); + + // Add all the states to a list of + List unUsedStates = new List(); + + foreach (string state in state_events.Keys) + { + unUsedStates.Add(state); + } + + // If endloop is 0, then there are no state entry events in the entire script. + // Stick a default state entry in there. + if (endloop == 0) + { + if (state_events.ContainsKey("default")) + { + scriptCopy = "public void default_event_state_entry() {osSetStateEvents((int)" + (int)state_events["default"] + "); } " + Script; + unUsedStates.Remove("default"); + } + else + { + throw new Exception("You must define a default state. Compile failed. See LSL documentation for more details."); + } + } + + // Loop over state entry events and rewrite the first line to define the events the state listens for. + for (int pos = 0; pos < endloop; pos++) + { + // Returns text before state entry match, + scriptCopy += eventmatches[pos]; pos++; + + // Returns text of state entry match, + scriptCopy += eventmatches[pos]; pos++; + + // Returns which state we're matching and writes a method call to the end of the above state_entry + scriptCopy += "osSetStateEvents((int)" + (int)state_events[eventmatches[pos]] + ");"; //pos++; + + // Remove the state from the unused list. There might be more states matched then defined, so we + // check if the state was defined first + if (unUsedStates.Contains(eventmatches[pos])) + unUsedStates.Remove(eventmatches[pos]); + + // adds the remainder of the script. + if ((pos + 1) == endloop) + { + pos++; + scriptCopy += eventmatches[pos++]; + } + + } + + // states with missing state_entry blocks won't publish their events, + // so, to fix that we write a state entry with only the event publishing method for states missing a state_entry event + foreach (string state in unUsedStates) + { + // Write the remainder states out into a blank state entry with the event setting routine + scriptCopy = "public void " + state + "_event_state_entry() {tosSetStateEvents((int)" + (int)state_events[state] + ");} " + scriptCopy; + } + + // save modified script. + unUsedStates.Clear(); + state_events.Clear(); + return scriptCopy; + } + + public static string ReWriteScriptWithPublishedEventsJS(string Script) + { + Dictionary state_events = new Dictionary(); + // 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, @"function \s([^_]+)_event_([^\(]+)\((?:[a-zA-Z0-9\s_,\.\-]+)?\)(?:[^\{]+)?\{", RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.Singleline | RegexOptions.IgnoreCase); + for (int pos = 0; pos < eventmatches.GetUpperBound(0); pos++) + { + pos++; // garbage + + string statea = eventmatches[pos]; pos++; + string eventa = eventmatches[pos]; + scriptEvents storedEventsForState = scriptEvents.None; + if (state_events.ContainsKey(statea)) + { + storedEventsForState = state_events[statea]; + state_events[statea] |= convertnametoFlag(eventa); + } + else + { + state_events.Add(statea, convertnametoFlag(eventa)); + } + Console.WriteLine("State:" + statea + ", event: " + eventa); + } + Console.WriteLine("Matches:" + eventmatches.GetUpperBound(0)); + // Add namespace, class name and inheritance + + // Looking *ONLY* for state entry events + string scriptCopy = ""; + + //Only match State_Entry events now + // Note the whole regex is a group, then we have the state this entry belongs to. + eventmatches = Regex.Split(Script, @"(function \s([^_]+)_event_state_entry[\(\)](?:[^\{]+)?\{)", RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.Singleline | RegexOptions.IgnoreCase); + int endloop = eventmatches.GetUpperBound(0); + + // Add all the states to a list of + List unUsedStates = new List(); + + foreach (string state in state_events.Keys) + { + unUsedStates.Add(state); + } + + // If endloop is 0, then there are no state entry events in the entire script. + // Stick a default state entry in there. + if (endloop == 0) + { + if (state_events.ContainsKey("default")) + { + scriptCopy = "function default_event_state_entry() {osSetStateEvents(" + (int)state_events["default"] + "); } " + Script; + unUsedStates.Remove("default"); + } + else + { + throw new Exception("You must define a default state. Compile failed. See LSL documentation for more details."); + } + } + + // Loop over state entry events and rewrite the first line to define the events the state listens for. + for (int pos = 0; pos < endloop; pos++) + { + // Returns text before state entry match, + scriptCopy += eventmatches[pos]; pos++; + + // Returns text of state entry match, + scriptCopy += eventmatches[pos]; pos++; + + // Returns which state we're matching and writes a method call to the end of the above state_entry + scriptCopy += "osSetStateEvents(" + (int)state_events[eventmatches[pos]] + ");"; //pos++; + + // Remove the state from the unused list. There might be more states matched then defined, so we + // check if the state was defined first + if (unUsedStates.Contains(eventmatches[pos])) + unUsedStates.Remove(eventmatches[pos]); + + // adds the remainder of the script. + if ((pos + 1) == endloop) + { + pos++; + scriptCopy += eventmatches[pos++]; + } + + } + + // states with missing state_entry blocks won't publish their events, + // so, to fix that we write a state entry with only the event publishing method for states missing a state_entry event + foreach (string state in unUsedStates) + { + // Write the remainder states out into a blank state entry with the event setting routine + scriptCopy = "function " + state + "_event_state_entry() {tosSetStateEvents(" + (int)state_events[state] + ");} " + scriptCopy; + } + + // save modified script. + unUsedStates.Clear(); + state_events.Clear(); + return scriptCopy; + } + + + public static string ReWriteScriptWithPublishedEventsVB(string Script) + { + Dictionary state_events = new Dictionary(); + // 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 Sub\s([^_]+)_event_([^\(]+)\((?:[a-zA-Z0-9\s_,\.\-]+)?\)(?:[^()])", RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.Singleline | RegexOptions.IgnoreCase); + for (int pos = 0; pos < eventmatches.GetUpperBound(0); pos++) + { + pos++; // garbage + + string statea = eventmatches[pos]; pos++; + string eventa = eventmatches[pos]; + scriptEvents storedEventsForState = scriptEvents.None; + if (state_events.ContainsKey(statea)) + { + storedEventsForState = state_events[statea]; + state_events[statea] |= convertnametoFlag(eventa); + } + else + { + state_events.Add(statea, convertnametoFlag(eventa)); + } + Console.WriteLine("State:" + statea + ", event: " + eventa); + } + Console.WriteLine("Matches:" + eventmatches.GetUpperBound(0)); + // Add namespace, class name and inheritance + + // Looking *ONLY* for state entry events + string scriptCopy = ""; + + //Only match State_Entry events now + // Note the whole regex is a group, then we have the state this entry belongs to. + eventmatches = Regex.Split(Script, @"(Public Sub\s([^_]+)_event_state_entry(?:\s+)?\(\))", RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.Singleline | RegexOptions.IgnoreCase); + int endloop = eventmatches.GetUpperBound(0); + + // Add all the states to a list of + List unUsedStates = new List(); + + foreach (string state in state_events.Keys) + { + unUsedStates.Add(state); + } + + // If endloop is 0, then there are no state entry events in the entire script. + // Stick a default state entry in there. + if (endloop == 0) + { + if (state_events.ContainsKey("default")) + { + scriptCopy = "function default_event_state_entry() {osSetStateEvents(" + (int)state_events["default"] + "); } " + Script; + unUsedStates.Remove("default"); + } + else + { + throw new Exception("You must define a default state. Compile failed. See LSL documentation for more details."); + } + } + + // Loop over state entry events and rewrite the first line to define the events the state listens for. + for (int pos = 0; pos < endloop; pos++) + { + // Returns text before state entry match, + scriptCopy += eventmatches[pos]; pos++; + + // Returns text of state entry match, + scriptCopy += eventmatches[pos]; pos++; + + // Returns which state we're matching and writes a method call to the end of the above state_entry + scriptCopy += "osSetStateEvents(" + (int)state_events[eventmatches[pos]] + ");"; //pos++; + + // Remove the state from the unused list. There might be more states matched then defined, so we + // check if the state was defined first + if (unUsedStates.Contains(eventmatches[pos])) + unUsedStates.Remove(eventmatches[pos]); + + // adds the remainder of the script. + if ((pos + 1) == endloop) + { + pos++; + scriptCopy += eventmatches[pos++]; + } + + } + + // states with missing state_entry blocks won't publish their events, + // so, to fix that we write a state entry with only the event publishing method for states missing a state_entry event + foreach (string state in unUsedStates) + { + // Write the remainder states out into a blank state entry with the event setting routine + scriptCopy = "function " + state + "_event_state_entry() {tosSetStateEvents(" + (int)state_events[state] + ");} " + scriptCopy; + } + + // save modified script. + unUsedStates.Clear(); + state_events.Clear(); + return scriptCopy; + } + + + private static scriptEvents convertnametoFlag(string eventname) + { + switch (eventname) + { + case "attach": + return scriptEvents.attach; + //break; + // case "at_rot_target": + //return (long)scriptEvents.at_rot_target; + //break; + case "at_target": + return scriptEvents.at_target; + //break; + //case "changed": + //return (long)scriptEvents.changed; + //break; + case "collision": + return scriptEvents.collision; + // break; + case "collision_end": + return scriptEvents.collision_end; + //break; + case "collision_start": + return scriptEvents.collision_start; + // break; + case "control": + return scriptEvents.control; + //break; + case "dataserver": + return scriptEvents.dataserver; + // break; + case "email": + return scriptEvents.email; + // break; + case "http_response": + return scriptEvents.http_response; + // break; + case "land_collision": + return scriptEvents.land_collision; + // break; + case "land_collision_end": + return scriptEvents.land_collision_end; + // break; + case "land_collision_start": + return scriptEvents.land_collision_start; + // break; + //case "link_message": + //return scriptEvents.link_message; + // break; + case "listen": + return scriptEvents.listen; + // break; + case "money": + return scriptEvents.money; + // break; + case "moving_end": + return scriptEvents.moving_end; + // break; + case "moving_start": + return scriptEvents.moving_start; + // break; + case "not_at_rot_target": + return scriptEvents.not_at_rot_target; + // break; + case "not_at_target": + return scriptEvents.not_at_target; + // break; + // case "no_sensor": + //return (long)scriptEvents.no_sensor; + //break; + //case "on_rez": + //return (long)scriptEvents.on_rez; + // break; + case "remote_data": + return scriptEvents.remote_data; + // break; + case "run_time_permissions": + return scriptEvents.run_time_permissions; + // break; + //case "sensor": + //return (long)scriptEvents.sensor; + // break; + case "state_entry": + return scriptEvents.state_entry; + // break; + case "state_exit": + return scriptEvents.state_exit; + // break; + case "timer": + return scriptEvents.timer; + // break; + case "touch": + return scriptEvents.touch; + // break; + case "touch_end": + return scriptEvents.touch_end; + // break; + case "touch_start": + return scriptEvents.touch_start; + // break; + case "object_rez": + return scriptEvents.object_rez; + default: + return 0; + //break; + } + //return 0; + } + } + [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, + at_target = 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 + } +} diff --git a/OpenSim/Region/ScriptEngine/DotNetEngine/Compiler/LSL/LSL2CSConverter.cs b/OpenSim/Region/ScriptEngine/DotNetEngine/Compiler/LSL/LSL2CSConverter.cs index f1e6ebf526..06be20e749 100644 --- a/OpenSim/Region/ScriptEngine/DotNetEngine/Compiler/LSL/LSL2CSConverter.cs +++ b/OpenSim/Region/ScriptEngine/DotNetEngine/Compiler/LSL/LSL2CSConverter.cs @@ -42,16 +42,16 @@ 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() { // Only the types we need to convert dataTypes.Add("void", "void"); - dataTypes.Add("integer", "int"); + dataTypes.Add("integer", "LSL_Types.LSLInteger"); dataTypes.Add("float", "double"); - dataTypes.Add("string", "string"); - dataTypes.Add("key", "string"); + dataTypes.Add("string", "LSL_Types.LSLString"); + dataTypes.Add("key", "LSL_Types.LSLString"); dataTypes.Add("vector", "LSL_Types.Vector3"); dataTypes.Add("rotation", "LSL_Types.Quaternion"); dataTypes.Add("list", "LSL_Types.list"); @@ -314,100 +314,7 @@ 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_,\.\-]+)?\)(?:[^\{]+)?\{", RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.Singleline | RegexOptions.IgnoreCase); - for (int pos = 0; pos unUsedStates = new List(); - foreach (string state in state_events.Keys) - { - unUsedStates.Add(state); - } - - // If endloop is 0, then there are no state entry events in the entire script. - // Stick a default state entry in there. - if (endloop == 0) - { - if (state_events.ContainsKey("default")) - { - scriptCopy = "\r\n// programmatically added this state entry event.\r\n\r\npublic void default_event_state_entry() {\r\n\tosSetStateEvents((int)" + (int)state_events["default"] + ");\r\n }\r\n\r\n " + Script; - unUsedStates.Remove("default"); - } - else - { - throw new Exception("You must define a default state. Compile failed. See LSL documentation for more details."); - } - } - - // Loop over state entry events and rewrite the first line to define the events the state listens for. - for (int pos = 0; pos < endloop; pos++) - { - // Returns text before state entry match, - scriptCopy += eventmatches[pos]; pos++; - - // Returns text of state entry match, - scriptCopy += eventmatches[pos]; pos++; - - // Returns which state we're matching and writes a method call to the end of the above state_entry - scriptCopy += "\r\n\t\tosSetStateEvents((int)" + (int)state_events[eventmatches[pos]] + ");"; //pos++; - - // Remove the state from the unused list. There might be more states matched then defined, so we - // check if the state was defined first - if (unUsedStates.Contains(eventmatches[pos])) - unUsedStates.Remove(eventmatches[pos]); - - // adds the remainder of the script. - if ((pos + 1) == endloop) - { - pos++; - scriptCopy += eventmatches[pos++]; - } - - } - - // states with missing state_entry blocks won't publish their events, - // so, to fix that we write a state entry with only the event publishing method for states missing a state_entry event - foreach (string state in unUsedStates) - { - // Write the remainder states out into a blank state entry with the event setting routine - scriptCopy = "\r\n// programmatically added this state entry event.\r\n\r\npublic void " + state + "_event_state_entry() {\r\n\tosSetStateEvents((int)" + (int)state_events[state] + ");\r\n}\r\n\r\n " + scriptCopy; - } - - // save modified script. - Script = scriptCopy; + //System.Console.WriteLine(Script); Return = String.Empty;// + //"using OpenSim.Region.ScriptEngine.Common; using System.Collections.Generic;"; @@ -421,152 +328,13 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.LSL //Return += @"public Script() { } "; Return += Script; //Return += "} }\r\n"; - unUsedStates.Clear(); - state_events.Clear(); + quotes.Clear(); return Return; } - public scriptEvents convertnametoFlag(string eventname) - { - switch (eventname) - { - case "attach": - return scriptEvents.attach; - //break; - // case "at_rot_target": - //return (long)scriptEvents.at_rot_target; - //break; - case "at_target": - return scriptEvents.at_target; - //break; - //case "changed": - //return (long)scriptEvents.changed; - //break; - case "collision": - return scriptEvents.collision; - // break; - case "collision_end": - return scriptEvents.collision_end; - //break; - case "collision_start": - return scriptEvents.collision_start; - // break; - case "control": - return scriptEvents.control; - //break; - case "dataserver": - return scriptEvents.dataserver; - // break; - case "email": - return scriptEvents.email; - // break; - case "http_response": - return scriptEvents.http_response; - // break; - case "land_collision": - return scriptEvents.land_collision; - // break; - case "land_collision_end": - return scriptEvents.land_collision_end; - // break; - case "land_collision_start": - return scriptEvents.land_collision_start; - // break; - //case "link_message": - //return scriptEvents.link_message; - // break; - case "listen": - return scriptEvents.listen; - // break; - case "money": - return scriptEvents.money; - // break; - case "moving_end": - return scriptEvents.moving_end; - // break; - case "moving_start": - return scriptEvents.moving_start; - // break; - case "not_at_rot_target": - return scriptEvents.not_at_rot_target; - // break; - case "not_at_target": - return scriptEvents.not_at_target; - // break; - // case "no_sensor": - //return (long)scriptEvents.no_sensor; - //break; - //case "on_rez": - //return (long)scriptEvents.on_rez; - // break; - case "remote_data": - return scriptEvents.remote_data; - // break; - case "run_time_permissions": - return scriptEvents.run_time_permissions; - // break; - //case "sensor": - //return (long)scriptEvents.sensor; - // break; - case "state_entry": - return scriptEvents.state_entry; - // break; - case "state_exit": - return scriptEvents.state_exit; - // break; - case "timer": - return scriptEvents.timer; - // break; - case "touch": - return scriptEvents.touch; - // break; - case "touch_end": - return scriptEvents.touch_end; - // break; - case "touch_start": - return scriptEvents.touch_start; - // break; - case "object_rez": - return scriptEvents.object_rez; - default: - return 0; - //break; - } - //return 0; - } + } - [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, - at_target = 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 - } -} \ No newline at end of file + +}