aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/ScriptEngine/Common/Executor.cs39
-rw-r--r--OpenSim/Region/ScriptEngine/Common/ExecutorBase.cs101
-rw-r--r--OpenSim/Region/ScriptEngine/Common/LSL_BuiltIn_Commands.cs3
-rw-r--r--OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/ScriptManager.cs23
-rw-r--r--OpenSim/Region/ScriptEngine/DotNetEngine/Compiler/LSL/Compiler.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/DotNetEngine/Compiler/LSL/EventReaderRewriter.cs488
-rw-r--r--OpenSim/Region/ScriptEngine/DotNetEngine/ScriptManager.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/LSOEngine/ScriptManager.cs2
8 files changed, 166 insertions, 494 deletions
diff --git a/OpenSim/Region/ScriptEngine/Common/Executor.cs b/OpenSim/Region/ScriptEngine/Common/Executor.cs
index 8e0d6f1..56baa66 100644
--- a/OpenSim/Region/ScriptEngine/Common/Executor.cs
+++ b/OpenSim/Region/ScriptEngine/Common/Executor.cs
@@ -35,9 +35,48 @@ namespace OpenSim.Region.ScriptEngine.Common
35 { 35 {
36 // Cache functions by keeping a reference to them in a dictionary 36 // Cache functions by keeping a reference to them in a dictionary
37 private Dictionary<string, MethodInfo> Events = new Dictionary<string, MethodInfo>(); 37 private Dictionary<string, MethodInfo> Events = new Dictionary<string, MethodInfo>();
38 private Dictionary<string, scriptEvents> m_stateEvents = new Dictionary<string, scriptEvents>();
38 39
39 public Executor(IScript script) : base(script) 40 public Executor(IScript script) : base(script)
40 { 41 {
42 initEventFlags();
43 }
44
45
46 protected override scriptEvents DoGetStateEventFlags()
47 {
48 // Console.WriteLine("Get event flags for " + m_Script.State);
49
50 // Check to see if we've already computed the flags for this state
51 scriptEvents eventFlags = scriptEvents.None;
52 if (m_stateEvents.ContainsKey(m_Script.State))
53 {
54 m_stateEvents.TryGetValue(m_Script.State, out eventFlags);
55 return eventFlags;
56 }
57
58 // Fill in the events for this state, cache the results in the map
59 foreach (KeyValuePair<string, scriptEvents> kvp in m_eventFlagsMap)
60 {
61 string evname = m_Script.State + "_event_" + kvp.Key;
62 Type type = m_Script.GetType();
63 try
64 {
65 MethodInfo mi = type.GetMethod(evname);
66 if (mi != null)
67 {
68 // Console.WriteLine("Found handler for " + kvp.Key);
69 eventFlags |= kvp.Value;
70 }
71 }
72 catch
73 {
74 }
75 }
76
77 // Save the flags we just computed and return the result
78 m_stateEvents.Add(m_Script.State, eventFlags);
79 return (eventFlags);
41 } 80 }
42 81
43 protected override void DoExecuteEvent(string FunctionName, object[] args) 82 protected override void DoExecuteEvent(string FunctionName, object[] args)
diff --git a/OpenSim/Region/ScriptEngine/Common/ExecutorBase.cs b/OpenSim/Region/ScriptEngine/Common/ExecutorBase.cs
index 19fb487..2e35b46 100644
--- a/OpenSim/Region/ScriptEngine/Common/ExecutorBase.cs
+++ b/OpenSim/Region/ScriptEngine/Common/ExecutorBase.cs
@@ -26,6 +26,7 @@
26 */ 26 */
27 27
28using System; 28using System;
29using System.Collections.Generic;
29using System.Runtime.Remoting.Lifetime; 30using System.Runtime.Remoting.Lifetime;
30 31
31namespace OpenSim.Region.ScriptEngine.Common 32namespace OpenSim.Region.ScriptEngine.Common
@@ -54,10 +55,46 @@ namespace OpenSim.Region.ScriptEngine.Common
54 public bool Running 55 public bool Running
55 { 56 {
56 get { return m_Running; } 57 get { return m_Running; }
57 set { 58 set
58 if(!m_Disable) 59 {
59 m_Running = value; 60 if (!m_Disable)
60 } 61 m_Running = value;
62 }
63 }
64
65 protected Dictionary<string, scriptEvents> m_eventFlagsMap = new Dictionary<string, scriptEvents>();
66
67 [Flags]
68 public enum scriptEvents : int
69 {
70 None = 0,
71 attach = 1,
72 collision = 15,
73 collision_end = 32,
74 collision_start = 64,
75 control = 128,
76 dataserver = 256,
77 email = 512,
78 http_response = 1024,
79 land_collision = 2048,
80 land_collision_end = 4096,
81 land_collision_start = 8192,
82 at_target = 16384,
83 listen = 32768,
84 money = 65536,
85 moving_end = 131072,
86 moving_start = 262144,
87 not_at_rot_target = 524288,
88 not_at_target = 1048576,
89 remote_data = 8388608,
90 run_time_permissions = 268435456,
91 state_entry = 1073741824,
92 state_exit = 2,
93 timer = 4,
94 touch = 8,
95 touch_end = 536870912,
96 touch_start = 2097152,
97 object_rez = 4194304
61 } 98 }
62 99
63 /// <summary> 100 /// <summary>
@@ -67,6 +104,7 @@ namespace OpenSim.Region.ScriptEngine.Common
67 public ExecutorBase(IScript Script) 104 public ExecutorBase(IScript Script)
68 { 105 {
69 m_Script = Script; 106 m_Script = Script;
107 initEventFlags();
70 } 108 }
71 109
72 /// <summary> 110 /// <summary>
@@ -111,9 +149,21 @@ namespace OpenSim.Region.ScriptEngine.Common
111 } 149 }
112 DoExecuteEvent(FunctionName, args); 150 DoExecuteEvent(FunctionName, args);
113 } 151 }
152
114 protected abstract void DoExecuteEvent(string FunctionName, object[] args); 153 protected abstract void DoExecuteEvent(string FunctionName, object[] args);
115 154
116 /// <summary> 155 /// <summary>
156 /// Compute the events handled by the current state of the script
157 /// </summary>
158 /// <returns>state mask</returns>
159 public scriptEvents GetStateEventFlags()
160 {
161 return DoGetStateEventFlags();
162 }
163
164 protected abstract scriptEvents DoGetStateEventFlags();
165
166 /// <summary>
117 /// Stop script from running. Event execution will be ignored. 167 /// Stop script from running. Event execution will be ignored.
118 /// </summary> 168 /// </summary>
119 public void StopScript() 169 public void StopScript()
@@ -121,5 +171,48 @@ namespace OpenSim.Region.ScriptEngine.Common
121 m_Running = false; 171 m_Running = false;
122 m_Disable = true; 172 m_Disable = true;
123 } 173 }
174
175 protected void initEventFlags()
176 {
177 // Initialize the table if it hasn't already been done
178 if (m_eventFlagsMap.Count > 0)
179 {
180 return;
181 }
182
183 m_eventFlagsMap.Add("attach", scriptEvents.attach);
184 // m_eventFlagsMap.Add("at_rot_target",(long)scriptEvents.at_rot_target);
185 m_eventFlagsMap.Add("at_target", scriptEvents.at_target);
186 // m_eventFlagsMap.Add("changed",(long)scriptEvents.changed);
187 m_eventFlagsMap.Add("collision", scriptEvents.collision);
188 m_eventFlagsMap.Add("collision_end", scriptEvents.collision_end);
189 m_eventFlagsMap.Add("collision_start", scriptEvents.collision_start);
190 m_eventFlagsMap.Add("control", scriptEvents.control);
191 m_eventFlagsMap.Add("dataserver", scriptEvents.dataserver);
192 m_eventFlagsMap.Add("email", scriptEvents.email);
193 m_eventFlagsMap.Add("http_response", scriptEvents.http_response);
194 m_eventFlagsMap.Add("land_collision", scriptEvents.land_collision);
195 m_eventFlagsMap.Add("land_collision_end", scriptEvents.land_collision_end);
196 m_eventFlagsMap.Add("land_collision_start", scriptEvents.land_collision_start);
197 // m_eventFlagsMap.Add("link_message",scriptEvents.link_message);
198 m_eventFlagsMap.Add("listen", scriptEvents.listen);
199 m_eventFlagsMap.Add("money", scriptEvents.money);
200 m_eventFlagsMap.Add("moving_end", scriptEvents.moving_end);
201 m_eventFlagsMap.Add("moving_start", scriptEvents.moving_start);
202 m_eventFlagsMap.Add("not_at_rot_target", scriptEvents.not_at_rot_target);
203 m_eventFlagsMap.Add("not_at_target", scriptEvents.not_at_target);
204 // m_eventFlagsMap.Add("no_sensor",(long)scriptEvents.no_sensor);
205 // m_eventFlagsMap.Add("on_rez",(long)scriptEvents.on_rez);
206 m_eventFlagsMap.Add("remote_data", scriptEvents.remote_data);
207 m_eventFlagsMap.Add("run_time_permissions", scriptEvents.run_time_permissions);
208 // m_eventFlagsMap.Add("sensor",(long)scriptEvents.sensor);
209 m_eventFlagsMap.Add("state_entry", scriptEvents.state_entry);
210 m_eventFlagsMap.Add("state_exit", scriptEvents.state_exit);
211 m_eventFlagsMap.Add("timer", scriptEvents.timer);
212 m_eventFlagsMap.Add("touch", scriptEvents.touch);
213 m_eventFlagsMap.Add("touch_end", scriptEvents.touch_end);
214 m_eventFlagsMap.Add("touch_start", scriptEvents.touch_start);
215 m_eventFlagsMap.Add("object_rez", scriptEvents.object_rez);
216 }
124 } 217 }
125} 218}
diff --git a/OpenSim/Region/ScriptEngine/Common/LSL_BuiltIn_Commands.cs b/OpenSim/Region/ScriptEngine/Common/LSL_BuiltIn_Commands.cs
index 31ca3f3..419ca8f 100644
--- a/OpenSim/Region/ScriptEngine/Common/LSL_BuiltIn_Commands.cs
+++ b/OpenSim/Region/ScriptEngine/Common/LSL_BuiltIn_Commands.cs
@@ -92,8 +92,9 @@ namespace OpenSim.Region.ScriptEngine.Common
92 m_state = value; 92 m_state = value;
93 try 93 try
94 { 94 {
95 int eventFlags = m_ScriptEngine.m_ScriptManager.GetStateEventFlags(m_localID, m_itemID);
96 m_host.SetScriptEvents(m_itemID, eventFlags);
95 m_ScriptEngine.m_EventManager.state_entry(m_localID); 97 m_ScriptEngine.m_EventManager.state_entry(m_localID);
96
97 } 98 }
98 catch (AppDomainUnloadedException) 99 catch (AppDomainUnloadedException)
99 { 100 {
diff --git a/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/ScriptManager.cs b/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/ScriptManager.cs
index cd2e530..7812c8c 100644
--- a/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/ScriptManager.cs
+++ b/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/ScriptManager.cs
@@ -319,6 +319,29 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
319 Script.Exec.ExecuteEvent(FunctionName, args); 319 Script.Exec.ExecuteEvent(FunctionName, args);
320 } 320 }
321 321
322 public int GetStateEventFlags(uint localID, LLUUID itemID)
323 {
324 // Console.WriteLine("GetStateEventFlags for <" + localID + "," + itemID + ">");
325 try
326 {
327 IScript Script = GetScript(localID, itemID);
328 if (Script == null)
329 {
330 return 0;
331 }
332 ExecutorBase.scriptEvents evflags = Script.Exec.GetStateEventFlags();
333 return (int)evflags;
334 }
335 catch (Exception e)
336 {
337 // Console.WriteLine("Failed to get script reference for <" + localID + "," + itemID + ">");
338 // Console.WriteLine(e.ToString());
339 }
340
341 return 0;
342 }
343
344
322 #endregion 345 #endregion
323 346
324 #region Internal functions to keep track of script 347 #region Internal functions to keep track of script
diff --git a/OpenSim/Region/ScriptEngine/DotNetEngine/Compiler/LSL/Compiler.cs b/OpenSim/Region/ScriptEngine/DotNetEngine/Compiler/LSL/Compiler.cs
index dad1b23..944f9e7 100644
--- a/OpenSim/Region/ScriptEngine/DotNetEngine/Compiler/LSL/Compiler.cs
+++ b/OpenSim/Region/ScriptEngine/DotNetEngine/Compiler/LSL/Compiler.cs
@@ -319,7 +319,7 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.LSL
319 319
320 private static string CreateCSCompilerScript(string compileScript) 320 private static string CreateCSCompilerScript(string compileScript)
321 { 321 {
322 compileScript = EventReaderRewriter.ReWriteScriptWithPublishedEventsCS(compileScript); 322
323 323
324 compileScript = String.Empty + 324 compileScript = String.Empty +
325 "using OpenSim.Region.ScriptEngine.Common; using System.Collections.Generic;\r\n" + 325 "using OpenSim.Region.ScriptEngine.Common; using System.Collections.Generic;\r\n" +
diff --git a/OpenSim/Region/ScriptEngine/DotNetEngine/Compiler/LSL/EventReaderRewriter.cs b/OpenSim/Region/ScriptEngine/DotNetEngine/Compiler/LSL/EventReaderRewriter.cs
deleted file mode 100644
index 46ba850..0000000
--- a/OpenSim/Region/ScriptEngine/DotNetEngine/Compiler/LSL/EventReaderRewriter.cs
+++ /dev/null
@@ -1,488 +0,0 @@
1/*
2* Copyright (c) Contributors, http://opensimulator.org/
3* See CONTRIBUTORS.TXT for a full list of copyright holders.
4*
5* Redistribution and use in source and binary forms, with or without
6* modification, are permitted provided that the following conditions are met:
7* * Redistributions of source code must retain the above copyright
8* notice, this list of conditions and the following disclaimer.
9* * Redistributions in binary form must reproduce the above copyright
10* notice, this list of conditions and the following disclaimer in the
11* documentation and/or other materials provided with the distribution.
12* * Neither the name of the OpenSim Project nor the
13* names of its contributors may be used to endorse or promote products
14* derived from this software without specific prior written permission.
15*
16* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS AS IS AND ANY
17* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26*
27*/
28
29using System;
30using System.Collections.Generic;
31using System.Text.RegularExpressions;
32
33namespace OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.LSL
34{
35 public static class EventReaderRewriter
36 {
37
38
39 public static string ReWriteScriptWithPublishedEventsCS(string Script)
40 {
41 Dictionary<string, scriptEvents> state_events = new Dictionary<string, scriptEvents>();
42 // Finds out which events are in the script and writes a method call with the events in each state_entry event
43
44 // Note the (?:)? block optional, and not returning a group. Less greedy then .*
45
46 string[] eventmatches = new string[0];
47 //Regex stateevents = new Regex(@"(public void )([^_]+)(_event_)([^\(]+)[\(\)]+\s+[^\{]\{");
48 eventmatches = Regex.Split(Script, @"public void\s([^_]+)_event_([^\(]+)\((?:[a-zA-Z0-9\s_,\.\-]+)?\)(?:[^\{]+)?\{", RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.Singleline | RegexOptions.IgnoreCase);
49 for (int pos = 0; pos < eventmatches.GetUpperBound(0); pos++)
50 {
51 pos++; // garbage
52
53 string statea = eventmatches[pos]; pos++;
54 string eventa = eventmatches[pos];
55 scriptEvents storedEventsForState = scriptEvents.None;
56 if (state_events.ContainsKey(statea))
57 {
58 storedEventsForState = state_events[statea];
59 state_events[statea] |= convertnametoFlag(eventa);
60 }
61 else
62 {
63 state_events.Add(statea, convertnametoFlag(eventa));
64 }
65 Console.WriteLine("State:" + statea + ", event: " + eventa);
66 }
67 Console.WriteLine("Matches:" + eventmatches.GetUpperBound(0));
68 // Add namespace, class name and inheritance
69
70 // Looking *ONLY* for state entry events
71 string scriptCopy = "";
72
73 //Only match State_Entry events now
74 // Note the whole regex is a group, then we have the state this entry belongs to.
75 eventmatches = Regex.Split(Script, @"(public void\s([^_]+)_event_state_entry[\(\)](?:[^\{]+)?\{)", RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.Singleline | RegexOptions.IgnoreCase);
76 int endloop = eventmatches.GetUpperBound(0);
77
78 // Add all the states to a list of
79 List<string> unUsedStates = new List<string>();
80
81 foreach (string state in state_events.Keys)
82 {
83 unUsedStates.Add(state);
84 }
85
86 // If endloop is 0, then there are no state entry events in the entire script.
87 // Stick a default state entry in there.
88 if (endloop == 0)
89 {
90 if (state_events.ContainsKey("default"))
91 {
92 scriptCopy = "public void default_event_state_entry() {osSetStateEvents((int)" + (int)state_events["default"] + "); } " + Script;
93 unUsedStates.Remove("default");
94 }
95 else
96 {
97 throw new Exception("You must define a default state. Compile failed. See LSL documentation for more details.");
98 }
99 }
100
101 // Loop over state entry events and rewrite the first line to define the events the state listens for.
102 for (int pos = 0; pos < endloop; pos++)
103 {
104 // Returns text before state entry match,
105 scriptCopy += eventmatches[pos]; pos++;
106
107 // Returns text of state entry match,
108 scriptCopy += eventmatches[pos]; pos++;
109
110 // Returns which state we're matching and writes a method call to the end of the above state_entry
111 scriptCopy += "osSetStateEvents((int)" + (int)state_events[eventmatches[pos]] + ");"; //pos++;
112
113 // Remove the state from the unused list. There might be more states matched then defined, so we
114 // check if the state was defined first
115 if (unUsedStates.Contains(eventmatches[pos]))
116 unUsedStates.Remove(eventmatches[pos]);
117
118 // adds the remainder of the script.
119 if ((pos + 1) == endloop)
120 {
121 pos++;
122 scriptCopy += eventmatches[pos++];
123 }
124
125 }
126
127 // states with missing state_entry blocks won't publish their events,
128 // so, to fix that we write a state entry with only the event publishing method for states missing a state_entry event
129 foreach (string state in unUsedStates)
130 {
131 // Write the remainder states out into a blank state entry with the event setting routine
132 scriptCopy = "public void " + state + "_event_state_entry() {tosSetStateEvents((int)" + (int)state_events[state] + ");} " + scriptCopy;
133 }
134
135 // save modified script.
136 unUsedStates.Clear();
137 state_events.Clear();
138 return scriptCopy;
139 }
140
141 public static string ReWriteScriptWithPublishedEventsJS(string Script)
142 {
143 Dictionary<string, scriptEvents> state_events = new Dictionary<string, scriptEvents>();
144 // Finds out which events are in the script and writes a method call with the events in each state_entry event
145
146 // Note the (?:)? block optional, and not returning a group. Less greedy then .*
147
148 string[] eventmatches = new string[0];
149 //Regex stateevents = new Regex(@"(public void )([^_]+)(_event_)([^\(]+)[\(\)]+\s+[^\{]\{");
150 eventmatches = Regex.Split(Script, @"function \s([^_]+)_event_([^\(]+)\((?:[a-zA-Z0-9\s_,\.\-]+)?\)(?:[^\{]+)?\{", RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.Singleline | RegexOptions.IgnoreCase);
151 for (int pos = 0; pos < eventmatches.GetUpperBound(0); pos++)
152 {
153 pos++; // garbage
154
155 string statea = eventmatches[pos]; pos++;
156 string eventa = eventmatches[pos];
157 scriptEvents storedEventsForState = scriptEvents.None;
158 if (state_events.ContainsKey(statea))
159 {
160 storedEventsForState = state_events[statea];
161 state_events[statea] |= convertnametoFlag(eventa);
162 }
163 else
164 {
165 state_events.Add(statea, convertnametoFlag(eventa));
166 }
167 Console.WriteLine("State:" + statea + ", event: " + eventa);
168 }
169 Console.WriteLine("Matches:" + eventmatches.GetUpperBound(0));
170 // Add namespace, class name and inheritance
171
172 // Looking *ONLY* for state entry events
173 string scriptCopy = "";
174
175 //Only match State_Entry events now
176 // Note the whole regex is a group, then we have the state this entry belongs to.
177 eventmatches = Regex.Split(Script, @"(function \s([^_]+)_event_state_entry[\(\)](?:[^\{]+)?\{)", RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.Singleline | RegexOptions.IgnoreCase);
178 int endloop = eventmatches.GetUpperBound(0);
179
180 // Add all the states to a list of
181 List<string> unUsedStates = new List<string>();
182
183 foreach (string state in state_events.Keys)
184 {
185 unUsedStates.Add(state);
186 }
187
188 // If endloop is 0, then there are no state entry events in the entire script.
189 // Stick a default state entry in there.
190 if (endloop == 0)
191 {
192 if (state_events.ContainsKey("default"))
193 {
194 scriptCopy = "function default_event_state_entry() {osSetStateEvents(" + (int)state_events["default"] + "); } " + Script;
195 unUsedStates.Remove("default");
196 }
197 else
198 {
199 throw new Exception("You must define a default state. Compile failed. See LSL documentation for more details.");
200 }
201 }
202
203 // Loop over state entry events and rewrite the first line to define the events the state listens for.
204 for (int pos = 0; pos < endloop; pos++)
205 {
206 // Returns text before state entry match,
207 scriptCopy += eventmatches[pos]; pos++;
208
209 // Returns text of state entry match,
210 scriptCopy += eventmatches[pos]; pos++;
211
212 // Returns which state we're matching and writes a method call to the end of the above state_entry
213 scriptCopy += "osSetStateEvents(" + (int)state_events[eventmatches[pos]] + ");"; //pos++;
214
215 // Remove the state from the unused list. There might be more states matched then defined, so we
216 // check if the state was defined first
217 if (unUsedStates.Contains(eventmatches[pos]))
218 unUsedStates.Remove(eventmatches[pos]);
219
220 // adds the remainder of the script.
221 if ((pos + 1) == endloop)
222 {
223 pos++;
224 scriptCopy += eventmatches[pos++];
225 }
226
227 }
228
229 // states with missing state_entry blocks won't publish their events,
230 // so, to fix that we write a state entry with only the event publishing method for states missing a state_entry event
231 foreach (string state in unUsedStates)
232 {
233 // Write the remainder states out into a blank state entry with the event setting routine
234 scriptCopy = "function " + state + "_event_state_entry() {tosSetStateEvents(" + (int)state_events[state] + ");} " + scriptCopy;
235 }
236
237 // save modified script.
238 unUsedStates.Clear();
239 state_events.Clear();
240 return scriptCopy;
241 }
242
243
244 public static string ReWriteScriptWithPublishedEventsVB(string Script)
245 {
246 Dictionary<string, scriptEvents> state_events = new Dictionary<string, scriptEvents>();
247 // Finds out which events are in the script and writes a method call with the events in each state_entry event
248
249 // Note the (?:)? block optional, and not returning a group. Less greedy then .*
250
251 string[] eventmatches = new string[0];
252 //Regex stateevents = new Regex(@"(public void )([^_]+)(_event_)([^\(]+)[\(\)]+\s+[^\{]\{");
253 eventmatches = Regex.Split(Script, @"Public Sub\s([^_]+)_event_([^\(]+)\((?:[a-zA-Z0-9\s_,\.\-]+)?\)(?:[^()])", RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.Singleline | RegexOptions.IgnoreCase);
254 for (int pos = 0; pos < eventmatches.GetUpperBound(0); pos++)
255 {
256 pos++; // garbage
257
258 string statea = eventmatches[pos]; pos++;
259 string eventa = eventmatches[pos];
260 scriptEvents storedEventsForState = scriptEvents.None;
261 if (state_events.ContainsKey(statea))
262 {
263 storedEventsForState = state_events[statea];
264 state_events[statea] |= convertnametoFlag(eventa);
265 }
266 else
267 {
268 state_events.Add(statea, convertnametoFlag(eventa));
269 }
270 Console.WriteLine("State:" + statea + ", event: " + eventa);
271 }
272 Console.WriteLine("Matches:" + eventmatches.GetUpperBound(0));
273 // Add namespace, class name and inheritance
274
275 // Looking *ONLY* for state entry events
276 string scriptCopy = "";
277
278 //Only match State_Entry events now
279 // Note the whole regex is a group, then we have the state this entry belongs to.
280 eventmatches = Regex.Split(Script, @"(Public Sub\s([^_]+)_event_state_entry(?:\s+)?\(\))", RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.Singleline | RegexOptions.IgnoreCase);
281 int endloop = eventmatches.GetUpperBound(0);
282
283 // Add all the states to a list of
284 List<string> unUsedStates = new List<string>();
285
286 foreach (string state in state_events.Keys)
287 {
288 unUsedStates.Add(state);
289 }
290
291 // If endloop is 0, then there are no state entry events in the entire script.
292 // Stick a default state entry in there.
293 if (endloop == 0)
294 {
295 if (state_events.ContainsKey("default"))
296 {
297 scriptCopy = "function default_event_state_entry() {osSetStateEvents(" + (int)state_events["default"] + "); } " + Script;
298 unUsedStates.Remove("default");
299 }
300 else
301 {
302 throw new Exception("You must define a default state. Compile failed. See LSL documentation for more details.");
303 }
304 }
305
306 // Loop over state entry events and rewrite the first line to define the events the state listens for.
307 for (int pos = 0; pos < endloop; pos++)
308 {
309 // Returns text before state entry match,
310 scriptCopy += eventmatches[pos]; pos++;
311
312 // Returns text of state entry match,
313 scriptCopy += eventmatches[pos]; pos++;
314
315 // Returns which state we're matching and writes a method call to the end of the above state_entry
316 scriptCopy += "osSetStateEvents(" + (int)state_events[eventmatches[pos]] + ");"; //pos++;
317
318 // Remove the state from the unused list. There might be more states matched then defined, so we
319 // check if the state was defined first
320 if (unUsedStates.Contains(eventmatches[pos]))
321 unUsedStates.Remove(eventmatches[pos]);
322
323 // adds the remainder of the script.
324 if ((pos + 1) == endloop)
325 {
326 pos++;
327 scriptCopy += eventmatches[pos++];
328 }
329
330 }
331
332 // states with missing state_entry blocks won't publish their events,
333 // so, to fix that we write a state entry with only the event publishing method for states missing a state_entry event
334 foreach (string state in unUsedStates)
335 {
336 // Write the remainder states out into a blank state entry with the event setting routine
337 scriptCopy = "function " + state + "_event_state_entry() {tosSetStateEvents(" + (int)state_events[state] + ");} " + scriptCopy;
338 }
339
340 // save modified script.
341 unUsedStates.Clear();
342 state_events.Clear();
343 return scriptCopy;
344 }
345
346
347 private static scriptEvents convertnametoFlag(string eventname)
348 {
349 switch (eventname)
350 {
351 case "attach":
352 return scriptEvents.attach;
353 //break;
354 // case "at_rot_target":
355 //return (long)scriptEvents.at_rot_target;
356 //break;
357 case "at_target":
358 return scriptEvents.at_target;
359 //break;
360 //case "changed":
361 //return (long)scriptEvents.changed;
362 //break;
363 case "collision":
364 return scriptEvents.collision;
365 // break;
366 case "collision_end":
367 return scriptEvents.collision_end;
368 //break;
369 case "collision_start":
370 return scriptEvents.collision_start;
371 // break;
372 case "control":
373 return scriptEvents.control;
374 //break;
375 case "dataserver":
376 return scriptEvents.dataserver;
377 // break;
378 case "email":
379 return scriptEvents.email;
380 // break;
381 case "http_response":
382 return scriptEvents.http_response;
383 // break;
384 case "land_collision":
385 return scriptEvents.land_collision;
386 // break;
387 case "land_collision_end":
388 return scriptEvents.land_collision_end;
389 // break;
390 case "land_collision_start":
391 return scriptEvents.land_collision_start;
392 // break;
393 //case "link_message":
394 //return scriptEvents.link_message;
395 // break;
396 case "listen":
397 return scriptEvents.listen;
398 // break;
399 case "money":
400 return scriptEvents.money;
401 // break;
402 case "moving_end":
403 return scriptEvents.moving_end;
404 // break;
405 case "moving_start":
406 return scriptEvents.moving_start;
407 // break;
408 case "not_at_rot_target":
409 return scriptEvents.not_at_rot_target;
410 // break;
411 case "not_at_target":
412 return scriptEvents.not_at_target;
413 // break;
414 // case "no_sensor":
415 //return (long)scriptEvents.no_sensor;
416 //break;
417 //case "on_rez":
418 //return (long)scriptEvents.on_rez;
419 // break;
420 case "remote_data":
421 return scriptEvents.remote_data;
422 // break;
423 case "run_time_permissions":
424 return scriptEvents.run_time_permissions;
425 // break;
426 //case "sensor":
427 //return (long)scriptEvents.sensor;
428 // break;
429 case "state_entry":
430 return scriptEvents.state_entry;
431 // break;
432 case "state_exit":
433 return scriptEvents.state_exit;
434 // break;
435 case "timer":
436 return scriptEvents.timer;
437 // break;
438 case "touch":
439 return scriptEvents.touch;
440 // break;
441 case "touch_end":
442 return scriptEvents.touch_end;
443 // break;
444 case "touch_start":
445 return scriptEvents.touch_start;
446 // break;
447 case "object_rez":
448 return scriptEvents.object_rez;
449 default:
450 return 0;
451 //break;
452 }
453 //return 0;
454 }
455 }
456 [Flags]
457 public enum scriptEvents : int
458 {
459 None = 0,
460 attach = 1,
461 collision = 15,
462 collision_end = 32,
463 collision_start = 64,
464 control = 128,
465 dataserver = 256,
466 email = 512,
467 http_response = 1024,
468 land_collision = 2048,
469 land_collision_end = 4096,
470 land_collision_start = 8192,
471 at_target = 16384,
472 listen = 32768,
473 money = 65536,
474 moving_end = 131072,
475 moving_start = 262144,
476 not_at_rot_target = 524288,
477 not_at_target = 1048576,
478 remote_data = 8388608,
479 run_time_permissions = 268435456,
480 state_entry = 1073741824,
481 state_exit = 2,
482 timer = 4,
483 touch = 8,
484 touch_end = 536870912,
485 touch_start = 2097152,
486 object_rez = 4194304
487 }
488}
diff --git a/OpenSim/Region/ScriptEngine/DotNetEngine/ScriptManager.cs b/OpenSim/Region/ScriptEngine/DotNetEngine/ScriptManager.cs
index e242748..32c98a8 100644
--- a/OpenSim/Region/ScriptEngine/DotNetEngine/ScriptManager.cs
+++ b/OpenSim/Region/ScriptEngine/DotNetEngine/ScriptManager.cs
@@ -101,6 +101,8 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine
101 CompiledScript.Start(LSLB); 101 CompiledScript.Start(LSLB);
102 102
103 // Fire the first start-event 103 // Fire the first start-event
104 int eventFlags = m_scriptEngine.m_ScriptManager.GetStateEventFlags(localID, itemID);
105 m_host.SetScriptEvents(itemID, eventFlags);
104 m_scriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "state_entry", EventQueueManager.llDetectNull, new object[] { }); 106 m_scriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "state_entry", EventQueueManager.llDetectNull, new object[] { });
105 } 107 }
106 catch (Exception e) // LEGIT: User Scripting 108 catch (Exception e) // LEGIT: User Scripting
diff --git a/OpenSim/Region/ScriptEngine/LSOEngine/ScriptManager.cs b/OpenSim/Region/ScriptEngine/LSOEngine/ScriptManager.cs
index 0434f55..20d1a58 100644
--- a/OpenSim/Region/ScriptEngine/LSOEngine/ScriptManager.cs
+++ b/OpenSim/Region/ScriptEngine/LSOEngine/ScriptManager.cs
@@ -91,6 +91,8 @@ namespace OpenSim.Region.ScriptEngine.LSOEngine
91 CompiledScript.Start(LSLB); 91 CompiledScript.Start(LSLB);
92 92
93 // Fire the first start-event 93 // Fire the first start-event
94 int eventFlags = m_scriptEngine.m_ScriptManager.GetStateEventFlags(localID, itemID);
95 m_host.SetScriptEvents(itemID, eventFlags);
94 m_scriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "state_entry", EventQueueManager.llDetectNull, new object[] { }); 96 m_scriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "state_entry", EventQueueManager.llDetectNull, new object[] { });
95 } 97 }
96 catch (Exception e) // LEGIT - User Script Compilation 98 catch (Exception e) // LEGIT - User Script Compilation