aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--OpenSim/Region/ScriptEngine/DotNetEngine/EventManager.cs130
-rw-r--r--OpenSim/Region/ScriptEngine/DotNetEngine/EventQueueThreadClass.cs359
-rw-r--r--OpenSim/Region/ScriptEngine/DotNetEngine/ScriptManager.cs10
-rw-r--r--OpenSim/Region/ScriptEngine/XEngine/XEngine.cs25
4 files changed, 288 insertions, 236 deletions
diff --git a/OpenSim/Region/ScriptEngine/DotNetEngine/EventManager.cs b/OpenSim/Region/ScriptEngine/DotNetEngine/EventManager.cs
index 934d981..fa4970f 100644
--- a/OpenSim/Region/ScriptEngine/DotNetEngine/EventManager.cs
+++ b/OpenSim/Region/ScriptEngine/DotNetEngine/EventManager.cs
@@ -46,21 +46,26 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine
46 public class EventManager : iScriptEngineFunctionModule 46 public class EventManager : iScriptEngineFunctionModule
47 { 47 {
48 // 48 //
49 // Class is instanced in "ScriptEngine" and Uses "EventQueueManager" that is also instanced in "ScriptEngine". 49 // Class is instanced in "ScriptEngine" and Uses "EventQueueManager"
50 // that is also instanced in "ScriptEngine".
50 // This class needs a bit of explaining: 51 // This class needs a bit of explaining:
51 // 52 //
52 // This class it the link between an event inside OpenSim and the corresponding event in a user script being executed. 53 // This class it the link between an event inside OpenSim and
54 // the corresponding event in a user script being executed.
53 // 55 //
54 // For example when an user touches an object then the "myScriptEngine.World.EventManager.OnObjectGrab" event is fired inside OpenSim. 56 // For example when an user touches an object then the
55 // We hook up to this event and queue a touch_start in EventQueueManager with the proper LSL parameters. 57 // "myScriptEngine.World.EventManager.OnObjectGrab" event is fired
58 // inside OpenSim.
59 // We hook up to this event and queue a touch_start in
60 // EventQueueManager with the proper LSL parameters.
56 // It will then be delivered to the script by EventQueueManager. 61 // It will then be delivered to the script by EventQueueManager.
57 // 62 //
58 // You can check debug C# dump of an LSL script if you need to verify what exact parameters are needed. 63 // You can check debug C# dump of an LSL script if you need to
64 // verify what exact parameters are needed.
59 // 65 //
60 66
61
62 private ScriptEngine myScriptEngine; 67 private ScriptEngine myScriptEngine;
63 //public IScriptHost TEMP_OBJECT_ID; 68
64 public EventManager(ScriptEngine _ScriptEngine, bool performHookUp) 69 public EventManager(ScriptEngine _ScriptEngine, bool performHookUp)
65 { 70 {
66 myScriptEngine = _ScriptEngine; 71 myScriptEngine = _ScriptEngine;
@@ -74,28 +79,34 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine
74 79
75 public void HookUpEvents() 80 public void HookUpEvents()
76 { 81 {
77 // Hook up to events from OpenSim 82 myScriptEngine.Log.Info("[" + myScriptEngine.ScriptEngineName +
78 // We may not want to do it because someone is controlling us and will deliver events to us 83 "]: Hooking up to server events");
79 84
80 myScriptEngine.Log.Info("[" + myScriptEngine.ScriptEngineName + "]: Hooking up to server events"); 85 myScriptEngine.World.EventManager.OnObjectGrab +=
81 myScriptEngine.World.EventManager.OnObjectGrab += touch_start; 86 touch_start;
82 myScriptEngine.World.EventManager.OnObjectDeGrab += touch_end; 87 myScriptEngine.World.EventManager.OnObjectDeGrab +=
83 myScriptEngine.World.EventManager.OnRemoveScript += OnRemoveScript; 88 touch_end;
84 myScriptEngine.World.EventManager.OnScriptChangedEvent += changed; 89 myScriptEngine.World.EventManager.OnRemoveScript +=
85 myScriptEngine.World.EventManager.OnScriptAtTargetEvent += at_target; 90 OnRemoveScript;
86 myScriptEngine.World.EventManager.OnScriptNotAtTargetEvent += not_at_target; 91 myScriptEngine.World.EventManager.OnScriptChangedEvent +=
87 myScriptEngine.World.EventManager.OnScriptControlEvent += control; 92 changed;
88 myScriptEngine.World.EventManager.OnScriptColliderStart += collision_start; 93 myScriptEngine.World.EventManager.OnScriptAtTargetEvent +=
89 myScriptEngine.World.EventManager.OnScriptColliding += collision; 94 at_target;
90 myScriptEngine.World.EventManager.OnScriptCollidingEnd += collision_end; 95 myScriptEngine.World.EventManager.OnScriptNotAtTargetEvent +=
91 96 not_at_target;
92 // TODO: HOOK ALL EVENTS UP TO SERVER! 97 myScriptEngine.World.EventManager.OnScriptControlEvent +=
93 IMoneyModule money=myScriptEngine.World.RequestModuleInterface<IMoneyModule>(); 98 control;
99 myScriptEngine.World.EventManager.OnScriptColliderStart +=
100 collision_start;
101 myScriptEngine.World.EventManager.OnScriptColliding +=
102 collision;
103 myScriptEngine.World.EventManager.OnScriptCollidingEnd +=
104 collision_end;
105
106 IMoneyModule money =
107 myScriptEngine.World.RequestModuleInterface<IMoneyModule>();
94 if (money != null) 108 if (money != null)
95 {
96 money.OnObjectPaid+=HandleObjectPaid; 109 money.OnObjectPaid+=HandleObjectPaid;
97 }
98
99 } 110 }
100 111
101 public void ReadConfig() 112 public void ReadConfig()
@@ -104,7 +115,9 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine
104 115
105 private void HandleObjectPaid(UUID objectID, UUID agentID, int amount) 116 private void HandleObjectPaid(UUID objectID, UUID agentID, int amount)
106 { 117 {
107 SceneObjectPart part=myScriptEngine.World.GetSceneObjectPart(objectID); 118 SceneObjectPart part =
119 myScriptEngine.World.GetSceneObjectPart(objectID);
120
108 if (part != null) 121 if (part != null)
109 { 122 {
110 money(part.LocalId, agentID, amount); 123 money(part.LocalId, agentID, amount);
@@ -127,8 +140,8 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine
127 new DetectParams[0])); 140 new DetectParams[0]));
128 } 141 }
129 142
130 public void touch_start(uint localID, uint originalID, Vector3 offsetPos, 143 public void touch_start(uint localID, uint originalID,
131 IClientAPI remoteClient) 144 Vector3 offsetPos, IClientAPI remoteClient)
132 { 145 {
133 // Add to queue for all scripts in ObjectID object 146 // Add to queue for all scripts in ObjectID object
134 DetectParams[] det = new DetectParams[1]; 147 DetectParams[] det = new DetectParams[1];
@@ -138,7 +151,9 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine
138 151
139 if (originalID == 0) 152 if (originalID == 0)
140 { 153 {
141 SceneObjectPart part = myScriptEngine.World.GetSceneObjectPart(localID); 154 SceneObjectPart part =
155 myScriptEngine.World.GetSceneObjectPart(localID);
156
142 if (part == null) 157 if (part == null)
143 return; 158 return;
144 159
@@ -146,7 +161,8 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine
146 } 161 }
147 else 162 else
148 { 163 {
149 SceneObjectPart originalPart = myScriptEngine.World.GetSceneObjectPart(originalID); 164 SceneObjectPart originalPart =
165 myScriptEngine.World.GetSceneObjectPart(originalID);
150 det[0].LinkNum = originalPart.LinkNum; 166 det[0].LinkNum = originalPart.LinkNum;
151 } 167 }
152 168
@@ -196,7 +212,8 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine
196 212
197 if (originalID == 0) 213 if (originalID == 0)
198 { 214 {
199 SceneObjectPart part = myScriptEngine.World.GetSceneObjectPart(localID); 215 SceneObjectPart part =
216 myScriptEngine.World.GetSceneObjectPart(localID);
200 if (part == null) 217 if (part == null)
201 return; 218 return;
202 219
@@ -204,7 +221,8 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine
204 } 221 }
205 else 222 else
206 { 223 {
207 SceneObjectPart originalPart = myScriptEngine.World.GetSceneObjectPart(originalID); 224 SceneObjectPart originalPart =
225 myScriptEngine.World.GetSceneObjectPart(originalID);
208 det[0].LinkNum = originalPart.LinkNum; 226 det[0].LinkNum = originalPart.LinkNum;
209 } 227 }
210 228
@@ -213,9 +231,12 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine
213 det)); 231 det));
214 } 232 }
215 233
216 public void OnRezScript(uint localID, UUID itemID, string script, int startParam, bool postOnRez, string engine) 234 public void OnRezScript(uint localID, UUID itemID, string script,
235 int startParam, bool postOnRez, string engine)
217 { 236 {
218 List<IScriptModule> engines = new List<IScriptModule>(myScriptEngine.World.RequestModuleInterfaces<IScriptModule>()); 237 List<IScriptModule> engines =
238 new List<IScriptModule>(
239 myScriptEngine.World.RequestModuleInterfaces<IScriptModule>());
219 240
220 List<string> names = new List<string>(); 241 List<string> names = new List<string>();
221 foreach (IScriptModule m in engines) 242 foreach (IScriptModule m in engines)
@@ -228,7 +249,8 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine
228 string firstline = script.Substring(0, lineEnd).Trim(); 249 string firstline = script.Substring(0, lineEnd).Trim();
229 250
230 int colon = firstline.IndexOf(':'); 251 int colon = firstline.IndexOf(':');
231 if (firstline.Length > 2 && firstline.Substring(0, 2) == "//" && colon != -1) 252 if (firstline.Length > 2 &&
253 firstline.Substring(0, 2) == "//" && colon != -1)
232 { 254 {
233 string engineName = firstline.Substring(2, colon-2); 255 string engineName = firstline.Substring(2, colon-2);
234 256
@@ -237,15 +259,43 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine
237 engine = engineName; 259 engine = engineName;
238 script = "//" + script.Substring(script.IndexOf(':')+1); 260 script = "//" + script.Substring(script.IndexOf(':')+1);
239 } 261 }
262 else
263 {
264 if (engine == myScriptEngine.ScriptEngineName)
265 {
266 SceneObjectPart part =
267 myScriptEngine.World.GetSceneObjectPart(
268 localID);
269
270 TaskInventoryItem item =
271 part.GetInventoryItem(itemID);
272
273 ScenePresence presence =
274 myScriptEngine.World.GetScenePresence(
275 item.OwnerID);
276
277 if (presence != null)
278 {
279 presence.ControllingClient.SendAgentAlertMessage(
280 "Selected engine unavailable. "+
281 "Running script on "+
282 myScriptEngine.ScriptEngineName,
283 false);
284 }
285 }
286 }
240 } 287 }
241 } 288 }
242 289
243 if (engine != myScriptEngine.ScriptEngineName) 290 if (engine != myScriptEngine.ScriptEngineName)
244 return; 291 return;
245 292
246 myScriptEngine.Log.Debug("OnRezScript localID: " + localID + " LLUID: " + itemID.ToString() + " Size: " + 293 myScriptEngine.Log.Debug("OnRezScript localID: " + localID +
247 script.Length); 294 " LLUID: " + itemID.ToString() + " Size: " +
248 myScriptEngine.m_ScriptManager.StartScript(localID, itemID, script, startParam, postOnRez); 295 script.Length);
296
297 myScriptEngine.m_ScriptManager.StartScript(localID, itemID, script,
298 startParam, postOnRez);
249 } 299 }
250 300
251 public void OnRemoveScript(uint localID, UUID itemID) 301 public void OnRemoveScript(uint localID, UUID itemID)
diff --git a/OpenSim/Region/ScriptEngine/DotNetEngine/EventQueueThreadClass.cs b/OpenSim/Region/ScriptEngine/DotNetEngine/EventQueueThreadClass.cs
index db3f89f..a9de503 100644
--- a/OpenSim/Region/ScriptEngine/DotNetEngine/EventQueueThreadClass.cs
+++ b/OpenSim/Region/ScriptEngine/DotNetEngine/EventQueueThreadClass.cs
@@ -34,20 +34,18 @@ using System.Globalization;
34using OpenMetaverse; 34using OpenMetaverse;
35using log4net; 35using log4net;
36using OpenSim.Framework; 36using OpenSim.Framework;
37using OpenSim.Region.Environment.Scenes;
37using OpenSim.Region.Environment.Scenes.Scripting; 38using OpenSim.Region.Environment.Scenes.Scripting;
39using OpenSim.Region.ScriptEngine.Shared;
38 40
39namespace OpenSim.Region.ScriptEngine.DotNetEngine 41namespace OpenSim.Region.ScriptEngine.DotNetEngine
40{ 42{
41 /// <summary> 43 // Because every thread needs some data set for it
42 /// Because every thread needs some data set for it (time started to execute current function), it will do its work within a class 44 // (time started to execute current function), it will do its work
43 /// </summary> 45 // within a class
44 public class EventQueueThreadClass : iScriptEngineFunctionModule 46 public class EventQueueThreadClass : iScriptEngineFunctionModule
45 { 47 {
46 // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 48 // How many ms to sleep if queue is empty
47
48 /// <summary>
49 /// How many ms to sleep if queue is empty
50 /// </summary>
51 private static int nothingToDoSleepms;// = 50; 49 private static int nothingToDoSleepms;// = 50;
52 private static ThreadPriority MyThreadPriority; 50 private static ThreadPriority MyThreadPriority;
53 51
@@ -77,13 +75,17 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine
77 { 75 {
78 lock (ScriptEngine.ScriptEngines) 76 lock (ScriptEngine.ScriptEngines)
79 { 77 {
80 foreach (ScriptEngine m_ScriptEngine in ScriptEngine.ScriptEngines) 78 foreach (ScriptEngine m_ScriptEngine in
79 ScriptEngine.ScriptEngines)
81 { 80 {
82 ScriptEngineName = m_ScriptEngine.ScriptEngineName; 81 ScriptEngineName = m_ScriptEngine.ScriptEngineName;
83 nothingToDoSleepms = m_ScriptEngine.ScriptConfigSource.GetInt("SleepTimeIfNoScriptExecutionMs", 50); 82 nothingToDoSleepms =
83 m_ScriptEngine.ScriptConfigSource.GetInt(
84 "SleepTimeIfNoScriptExecutionMs", 50);
85
86 string pri = m_ScriptEngine.ScriptConfigSource.GetString(
87 "ScriptThreadPriority", "BelowNormal");
84 88
85 // Later with ScriptServer we might want to ask OS for stuff too, so doing this a bit manually
86 string pri = m_ScriptEngine.ScriptConfigSource.GetString("ScriptThreadPriority", "BelowNormal");
87 switch (pri.ToLower()) 89 switch (pri.ToLower())
88 { 90 {
89 case "lowest": 91 case "lowest":
@@ -102,9 +104,12 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine
102 MyThreadPriority = ThreadPriority.Highest; 104 MyThreadPriority = ThreadPriority.Highest;
103 break; 105 break;
104 default: 106 default:
105 MyThreadPriority = ThreadPriority.BelowNormal; // Default 107 MyThreadPriority = ThreadPriority.BelowNormal;
106 m_ScriptEngine.Log.Error("[ScriptEngine.DotNetEngine]: Unknown priority type \"" + pri + 108 m_ScriptEngine.Log.Error(
107 "\" in config file. Defaulting to \"BelowNormal\"."); 109 "[ScriptEngine.DotNetEngine]: Unknown "+
110 "priority type \"" + pri +
111 "\" in config file. Defaulting to "+
112 "\"BelowNormal\".");
108 break; 113 break;
109 } 114 }
110 } 115 }
@@ -128,41 +133,41 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine
128 EventQueueThread.Start(); 133 EventQueueThread.Start();
129 ThreadTracker.Add(EventQueueThread); 134 ThreadTracker.Add(EventQueueThread);
130 135
131 // Look at this... Don't you wish everyone did that solid coding everywhere? :P 136 // Look at this... Don't you wish everyone did that solid
137 // coding everywhere? :P
138
132 if (ThreadCount == int.MaxValue) 139 if (ThreadCount == int.MaxValue)
133 ThreadCount = 0; 140 ThreadCount = 0;
141
134 ThreadCount++; 142 ThreadCount++;
135 } 143 }
136 144
137 public void Stop() 145 public void Stop()
138 { 146 {
139 //PleaseShutdown = true; // Set shutdown flag
140 //Thread.Sleep(100); // Wait a bit
141 if (EventQueueThread != null && EventQueueThread.IsAlive == true) 147 if (EventQueueThread != null && EventQueueThread.IsAlive == true)
142 { 148 {
143 try 149 try
144 { 150 {
145 EventQueueThread.Abort(); // Send abort 151 EventQueueThread.Abort(); // Send abort
146 //EventQueueThread.Join(); // Wait for it
147 } 152 }
148 catch (Exception) 153 catch (Exception)
149 { 154 {
150 //myScriptEngine.Log.Info("[" + ScriptEngineName + "]: EventQueueManager Exception killing worker thread: " + e.ToString());
151 } 155 }
152 } 156 }
153 } 157 }
154 158
155 private EventQueueManager.QueueItemStruct BlankQIS = new EventQueueManager.QueueItemStruct(); 159 private EventQueueManager.QueueItemStruct BlankQIS =
160 new EventQueueManager.QueueItemStruct();
161
156 private ScriptEngine lastScriptEngine; 162 private ScriptEngine lastScriptEngine;
157 /// <summary> 163 private uint lastLocalID;
158 /// Queue processing thread loop 164
159 /// </summary> 165 // Queue processing thread loop
160 private void EventQueueThreadLoop() 166 private void EventQueueThreadLoop()
161 { 167 {
162 CultureInfo USCulture = new CultureInfo("en-US"); 168 CultureInfo USCulture = new CultureInfo("en-US");
163 Thread.CurrentThread.CurrentCulture = USCulture; 169 Thread.CurrentThread.CurrentCulture = USCulture;
164 170
165 //myScriptEngine.Log.Info("[" + ScriptEngineName + "]: EventQueueManager Worker thread spawned");
166 try 171 try
167 { 172 {
168 while (true) 173 while (true)
@@ -177,205 +182,181 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine
177 catch (ThreadAbortException) 182 catch (ThreadAbortException)
178 { 183 {
179 if (lastScriptEngine != null) 184 if (lastScriptEngine != null)
180 lastScriptEngine.Log.Info("[" + ScriptEngineName + "]: ThreadAbortException while executing function."); 185 lastScriptEngine.Log.Info("[" + ScriptEngineName +
186 "]: ThreadAbortException while executing "+
187 "function.");
188 }
189 catch (SelfDeleteException) // Must delete SOG
190 {
191 SceneObjectPart part =
192 lastScriptEngine.World.GetSceneObjectPart(
193 lastLocalID);
194
195 if (part != null && part.ParentGroup != null)
196 lastScriptEngine.World.DeleteSceneObject(
197 part.ParentGroup);
181 } 198 }
182 catch (Exception e) 199 catch (Exception e)
183 { 200 {
184 if (lastScriptEngine != null) 201 if (lastScriptEngine != null)
185 lastScriptEngine.Log.Error("[" + ScriptEngineName + "]: Exception in EventQueueThreadLoop: " + e.ToString()); 202 lastScriptEngine.Log.Error("[" + ScriptEngineName +
203 "]: Exception in EventQueueThreadLoop: " +
204 e.ToString());
186 } 205 }
187 } 206 }
188 } 207 }
189 catch (ThreadAbortException) 208 catch (ThreadAbortException)
190 { 209 {
191 //myScriptEngine.Log.Info("[" + ScriptEngineName + "]: EventQueueManager Worker thread killed: " + tae.Message);
192 } 210 }
193 } 211 }
194 212
195 public void DoProcessQueue() 213 public void DoProcessQueue()
196 { 214 {
197 //lock (ScriptEngine.ScriptEngines) 215 foreach (ScriptEngine m_ScriptEngine in
198 //{ 216 new ArrayList(ScriptEngine.ScriptEngines))
199 foreach (ScriptEngine m_ScriptEngine in new ArrayList(ScriptEngine.ScriptEngines)) 217 {
218 lastScriptEngine = m_ScriptEngine;
219
220 EventQueueManager.QueueItemStruct QIS = BlankQIS;
221 bool GotItem = false;
222
223 //if (PleaseShutdown)
224 // return;
225
226 if (m_ScriptEngine.m_EventQueueManager == null ||
227 m_ScriptEngine.m_EventQueueManager.eventQueue == null)
228 continue;
229
230 if (m_ScriptEngine.m_EventQueueManager.eventQueue.Count == 0)
200 { 231 {
201 lastScriptEngine = m_ScriptEngine; 232 // Nothing to do? Sleep a bit waiting for something to do
202 // Every now and then check if we should shut down 233 Thread.Sleep(nothingToDoSleepms);
203 //if (PleaseShutdown || EventQueueManager.ThreadsToExit > 0) 234 }
204 //{ 235 else
205 // // Someone should shut down, lets get exclusive lock 236 {
206 // lock (EventQueueManager.ThreadsToExitLock) 237 // Something in queue, process
207 // { 238
208 // // Lets re-check in case someone grabbed it 239 // OBJECT BASED LOCK - TWO THREADS WORKING ON SAME
209 // if (EventQueueManager.ThreadsToExit > 0) 240 // OBJECT IS NOT GOOD
210 // { 241 lock (m_ScriptEngine.m_EventQueueManager.eventQueue)
211 // // Its crowded here so we'll shut down
212 // EventQueueManager.ThreadsToExit--;
213 // Stop();
214 // return;
215 // }
216 // else
217 // {
218 // // We have been asked to shut down
219 // Stop();
220 // return;
221 // }
222 // }
223 //}
224
225 //try
226 // {
227 EventQueueManager.QueueItemStruct QIS = BlankQIS;
228 bool GotItem = false;
229
230 //if (PleaseShutdown)
231 // return;
232
233 if (m_ScriptEngine.m_EventQueueManager == null || m_ScriptEngine.m_EventQueueManager.eventQueue == null)
234 continue;
235
236 if (m_ScriptEngine.m_EventQueueManager.eventQueue.Count == 0)
237 { 242 {
238 // Nothing to do? Sleep a bit waiting for something to do 243 GotItem = false;
239 Thread.Sleep(nothingToDoSleepms); 244 for (int qc = 0; qc < m_ScriptEngine.m_EventQueueManager.eventQueue.Count; qc++)
245 {
246 // Get queue item
247 QIS = m_ScriptEngine.m_EventQueueManager.eventQueue.Dequeue();
248
249 // Check if object is being processed by
250 // someone else
251 if (m_ScriptEngine.m_EventQueueManager.TryLock(
252 QIS.localID) == false)
253 {
254 // Object is already being processed, requeue it
255 m_ScriptEngine.m_EventQueueManager.
256 eventQueue.Enqueue(QIS);
257 }
258 else
259 {
260 // We have lock on an object and can process it
261 GotItem = true;
262 break;
263 }
264 }
240 } 265 }
241 else
242 {
243 // Something in queue, process
244 //myScriptEngine.Log.Info("[" + ScriptEngineName + "]: Processing event for localID: " + QIS.localID + ", itemID: " + QIS.itemID + ", FunctionName: " + QIS.FunctionName);
245 266
246 // OBJECT BASED LOCK - TWO THREADS WORKING ON SAME OBJECT IS NOT GOOD 267 if (GotItem == true)
247 lock (m_ScriptEngine.m_EventQueueManager.eventQueue) 268 {
269 // Execute function
270 try
248 { 271 {
249 GotItem = false; 272 // Only pipe event if land supports it.
250 for (int qc = 0; qc < m_ScriptEngine.m_EventQueueManager.eventQueue.Count; qc++) 273 if (m_ScriptEngine.World.PipeEventsForScript(
274 QIS.localID))
251 { 275 {
252 // Get queue item 276 lastLocalID = QIS.localID;
253 QIS = m_ScriptEngine.m_EventQueueManager.eventQueue.Dequeue(); 277 LastExecutionStarted = DateTime.Now.Ticks;
278 KillCurrentScript = false;
279 InExecution = true;
280 m_ScriptEngine.m_ScriptManager.ExecuteEvent(
281 QIS.localID,
282 QIS.itemID,
283 QIS.functionName,
284 QIS.llDetectParams,
285 QIS.param);
254 286
255 // Check if object is being processed by someone else 287 InExecution = false;
256 if (m_ScriptEngine.m_EventQueueManager.TryLock(QIS.localID) == false)
257 {
258 // Object is already being processed, requeue it
259 m_ScriptEngine.m_EventQueueManager.eventQueue.Enqueue(QIS);
260 }
261 else
262 {
263 // We have lock on an object and can process it
264 GotItem = true;
265 break;
266 }
267 } 288 }
268 } 289 }
269 290 catch (Exception e)
270 if (GotItem == true)
271 { 291 {
272 // Execute function 292 InExecution = false;
273 try 293 // DISPLAY ERROR INWORLD
294 string text = "Error executing script function \"" +
295 QIS.functionName + "\":\r\n";
296
297 if (e.InnerException != null)
274 { 298 {
275 ///cfk 2-7-08 dont need this right now and the default Linux build has DEBUG defined 299 // Send inner exception
276#if DEBUG 300 string line = " (unknown line)";
277 //eventQueueManager.m_ScriptEngine.Log.Debug("[" + ScriptEngineName + "]: " + 301 Regex rx = new Regex(@"SecondLife\.Script\..+[\s:](?<line>\d+)\.?\r?$", RegexOptions.Compiled);
278 // "Executing event:\r\n" 302 if (rx.Match(e.InnerException.ToString()).Success)
279 // + "QIS.localID: " + QIS.localID 303 line = " (line " + rx.Match(e.InnerException.ToString()).Result("${line}") + ")";
280 // + ", QIS.itemID: " + QIS.itemID 304 text += e.InnerException.Message.ToString() + line;
281 // + ", QIS.functionName: " +
282 // QIS.functionName);
283#endif
284 // Only pipe event if land supports it.
285 if (m_ScriptEngine.World.PipeEventsForScript(QIS.localID))
286 {
287 LastExecutionStarted = DateTime.Now.Ticks;
288 KillCurrentScript = false;
289 InExecution = true;
290 m_ScriptEngine.m_ScriptManager.ExecuteEvent(QIS.localID,
291 QIS.itemID,
292 QIS.functionName,
293 QIS.llDetectParams,
294 QIS.param);
295 InExecution = false;
296 }
297 } 305 }
298 catch (Exception e) 306 else
299 { 307 {
300 InExecution = false; 308 text += "\r\n";
301 // DISPLAY ERROR INWORLD 309 // Send normal
302 string text = "Error executing script function \"" + QIS.functionName + 310 text += e.Message.ToString();
303 "\":\r\n"; 311 }
304 if (e.InnerException != null) 312 if (KillCurrentScript)
305 { 313 text += "\r\nScript will be deactivated!";
306 // Send inner exception
307 string line = " (unknown line)";
308 Regex rx = new Regex(@"SecondLife\.Script\..+[\s:](?<line>\d+)\.?\r?$", RegexOptions.Compiled);
309 if (rx.Match(e.InnerException.ToString()).Success)
310 line = " (line " + rx.Match(e.InnerException.ToString()).Result("${line}") + ")";
311 text += e.InnerException.Message.ToString() + line;
312 }
313 else
314 {
315 text += "\r\n";
316 // Send normal
317 text += e.Message.ToString();
318 }
319 if (KillCurrentScript)
320 text += "\r\nScript will be deactivated!";
321
322 try
323 {
324 if (text.Length > 1500)
325 text = text.Substring(0, 1500);
326 IScriptHost m_host =
327 m_ScriptEngine.World.GetSceneObjectPart(QIS.localID);
328 //if (m_host != null)
329 //{
330 m_ScriptEngine.World.SimChat(Utils.StringToBytes(text),
331 ChatTypeEnum.DebugChannel, 2147483647,
332 m_host.AbsolutePosition,
333 m_host.Name, m_host.UUID, false);
334 }
335 catch (Exception)
336 {
337 //}
338 //else
339 //{
340 // T oconsole
341 m_ScriptEngine.m_EventQueueManager.m_ScriptEngine.Log.Error("[" + ScriptEngineName +
342 "]: " +
343 "Unable to send text in-world:\r\n" +
344 text);
345 }
346 finally
347 {
348 // So we are done sending message in-world
349 if (KillCurrentScript)
350 {
351 m_ScriptEngine.m_EventQueueManager.m_ScriptEngine.m_ScriptManager.StopScript(
352 QIS.localID, QIS.itemID);
353 }
354 }
355 314
356 // Pass it on so it's displayed on the console 315 try
357 // and in the logs (mikem 2008.06.02). 316 {
358 throw e.InnerException; 317 if (text.Length > 1500)
318 text = text.Substring(0, 1500);
319 IScriptHost m_host =
320 m_ScriptEngine.World.GetSceneObjectPart(QIS.localID);
321 m_ScriptEngine.World.SimChat(
322 Utils.StringToBytes(text),
323 ChatTypeEnum.DebugChannel, 2147483647,
324 m_host.AbsolutePosition,
325 m_host.Name, m_host.UUID, false);
326 }
327 catch (Exception)
328 {
329 m_ScriptEngine.m_EventQueueManager.
330 m_ScriptEngine.Log.Error("[" +
331 ScriptEngineName + "]: " +
332 "Unable to send text in-world:\r\n" +
333 text);
359 } 334 }
360 finally 335 finally
361 { 336 {
362 InExecution = false; 337 // So we are done sending message in-world
363 m_ScriptEngine.m_EventQueueManager.ReleaseLock(QIS.localID); 338 if (KillCurrentScript)
339 {
340 m_ScriptEngine.m_EventQueueManager.
341 m_ScriptEngine.m_ScriptManager.
342 StopScript(
343 QIS.localID, QIS.itemID);
344 }
364 } 345 }
346
347 // Pass it on so it's displayed on the console
348 // and in the logs (mikem 2008.06.02).
349 throw e.InnerException;
350 }
351 finally
352 {
353 InExecution = false;
354 m_ScriptEngine.m_EventQueueManager.ReleaseLock(
355 QIS.localID);
365 } 356 }
366 } 357 }
367 } 358 }
368 // } 359 }
369 } 360 }
370
371 ///// <summary>
372 ///// If set to true then threads and stuff should try to make a graceful exit
373 ///// </summary>
374 //public bool PleaseShutdown
375 //{
376 // get { return _PleaseShutdown; }
377 // set { _PleaseShutdown = value; }
378 //}
379 //private bool _PleaseShutdown = false;
380 } 361 }
381} 362}
diff --git a/OpenSim/Region/ScriptEngine/DotNetEngine/ScriptManager.cs b/OpenSim/Region/ScriptEngine/DotNetEngine/ScriptManager.cs
index fca4617..b593894 100644
--- a/OpenSim/Region/ScriptEngine/DotNetEngine/ScriptManager.cs
+++ b/OpenSim/Region/ScriptEngine/DotNetEngine/ScriptManager.cs
@@ -439,13 +439,7 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine
439 439
440 #region Perform event execution in script 440 #region Perform event execution in script
441 441
442 /// <summary> 442 // Execute a LL-event-function in Script
443 /// Execute a LL-event-function in Script
444 /// </summary>
445 /// <param name="localID">Object the script is located in</param>
446 /// <param name="itemID">Script ID</param>
447 /// <param name="FunctionName">Name of function</param>
448 /// <param name="args">Arguments to pass to function</param>
449 internal void ExecuteEvent(uint localID, UUID itemID, 443 internal void ExecuteEvent(uint localID, UUID itemID,
450 string FunctionName, DetectParams[] qParams, object[] args) 444 string FunctionName, DetectParams[] qParams, object[] args)
451 { 445 {
@@ -454,8 +448,10 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine
454 return; 448 return;
455 449
456 detparms[id] = qParams; 450 detparms[id] = qParams;
451
457 if (id.Running) 452 if (id.Running)
458 id.Script.ExecuteEvent(id.State, FunctionName, args); 453 id.Script.ExecuteEvent(id.State, FunctionName, args);
454
459 detparms.Remove(id); 455 detparms.Remove(id);
460 } 456 }
461 457
diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
index 3a06462..0448030 100644
--- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
+++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
@@ -356,6 +356,31 @@ namespace OpenSim.Region.ScriptEngine.XEngine
356 engine = engineName; 356 engine = engineName;
357 script = "//" + script.Substring(script.IndexOf(':')+1); 357 script = "//" + script.Substring(script.IndexOf(':')+1);
358 } 358 }
359 else
360 {
361 if (engine == ScriptEngineName)
362 {
363 SceneObjectPart part =
364 m_Scene.GetSceneObjectPart(
365 localID);
366
367 TaskInventoryItem item =
368 part.GetInventoryItem(itemID);
369
370 ScenePresence presence =
371 m_Scene.GetScenePresence(
372 item.OwnerID);
373
374 if (presence != null)
375 {
376 presence.ControllingClient.SendAgentAlertMessage(
377 "Selected engine unavailable. "+
378 "Running script on "+
379 ScriptEngineName,
380 false);
381 }
382 }
383 }
359 } 384 }
360 } 385 }
361 386