diff options
Diffstat (limited to 'OpenSim/Region/ScriptEngine')
14 files changed, 721 insertions, 1367 deletions
diff --git a/OpenSim/Region/ScriptEngine/Common/IScript.cs b/OpenSim/Region/ScriptEngine/Common/IScript.cs index 8d91071..d38dc7b 100644 --- a/OpenSim/Region/ScriptEngine/Common/IScript.cs +++ b/OpenSim/Region/ScriptEngine/Common/IScript.cs | |||
@@ -25,7 +25,6 @@ | |||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | */ | 26 | */ |
27 | 27 | ||
28 | using OpenSim.Region.ScriptEngine.Common.ScriptEngineBase; | ||
29 | using OpenSim.Region.ScriptEngine.Shared; | 28 | using OpenSim.Region.ScriptEngine.Shared; |
30 | using OpenSim.Region.ScriptEngine.Interfaces; | 29 | using OpenSim.Region.ScriptEngine.Interfaces; |
31 | 30 | ||
diff --git a/OpenSim/Region/ScriptEngine/Common/ScriptBaseClass.cs b/OpenSim/Region/ScriptEngine/Common/ScriptBaseClass.cs index 927ab2c..dc3ae05 100644 --- a/OpenSim/Region/ScriptEngine/Common/ScriptBaseClass.cs +++ b/OpenSim/Region/ScriptEngine/Common/ScriptBaseClass.cs | |||
@@ -29,7 +29,6 @@ using System; | |||
29 | using System.Runtime.Remoting.Lifetime; | 29 | using System.Runtime.Remoting.Lifetime; |
30 | using System.Threading; | 30 | using System.Threading; |
31 | using OpenSim.Region.Environment.Interfaces; | 31 | using OpenSim.Region.Environment.Interfaces; |
32 | using OpenSim.Region.ScriptEngine.Common.ScriptEngineBase; | ||
33 | using OpenSim.Region.ScriptEngine.Shared; | 32 | using OpenSim.Region.ScriptEngine.Shared; |
34 | using OpenSim.Region.ScriptEngine.Shared.Api.Interfaces; | 33 | using OpenSim.Region.ScriptEngine.Shared.Api.Interfaces; |
35 | using OpenSim.Region.ScriptEngine.Interfaces; | 34 | using OpenSim.Region.ScriptEngine.Interfaces; |
diff --git a/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/EventManager.cs b/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/EventManager.cs deleted file mode 100644 index 8293fae..0000000 --- a/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/EventManager.cs +++ /dev/null | |||
@@ -1,479 +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 | using System; | ||
29 | using System.Collections.Generic; | ||
30 | using OpenMetaverse; | ||
31 | using OpenSim.Framework; | ||
32 | using OpenSim.Region.Environment.Modules.Avatar.Currency.SampleMoney; | ||
33 | using OpenSim.Region.Environment; | ||
34 | using OpenSim.Region.Interfaces; | ||
35 | using OpenSim.Region; | ||
36 | using OpenSim.Region.Environment.Scenes; | ||
37 | using OpenSim.Region.Environment.Interfaces; | ||
38 | using OpenSim.Region.ScriptEngine.Shared; | ||
39 | |||
40 | namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase | ||
41 | { | ||
42 | /// <summary> | ||
43 | /// Prepares events so they can be directly executed upon a script by EventQueueManager, then queues it. | ||
44 | /// </summary> | ||
45 | [Serializable] | ||
46 | public class EventManager : iScriptEngineFunctionModule | ||
47 | { | ||
48 | // | ||
49 | // Class is instanced in "ScriptEngine" and Uses "EventQueueManager" that is also instanced in "ScriptEngine". | ||
50 | // This class needs a bit of explaining: | ||
51 | // | ||
52 | // This class it the link between an event inside OpenSim and the corresponding event in a user script being executed. | ||
53 | // | ||
54 | // For example when an user touches an object then the "myScriptEngine.World.EventManager.OnObjectGrab" event is fired inside OpenSim. | ||
55 | // We hook up to this event and queue a touch_start in EventQueueManager with the proper LSL parameters. | ||
56 | // It will then be delivered to the script by EventQueueManager. | ||
57 | // | ||
58 | // You can check debug C# dump of an LSL script if you need to verify what exact parameters are needed. | ||
59 | // | ||
60 | |||
61 | |||
62 | private ScriptEngine myScriptEngine; | ||
63 | //public IScriptHost TEMP_OBJECT_ID; | ||
64 | public EventManager(ScriptEngine _ScriptEngine, bool performHookUp) | ||
65 | { | ||
66 | myScriptEngine = _ScriptEngine; | ||
67 | ReadConfig(); | ||
68 | |||
69 | if (performHookUp) | ||
70 | { | ||
71 | myScriptEngine.World.EventManager.OnRezScript += OnRezScript; | ||
72 | } | ||
73 | } | ||
74 | |||
75 | public void HookUpEvents() | ||
76 | { | ||
77 | // Hook up to events from OpenSim | ||
78 | // We may not want to do it because someone is controlling us and will deliver events to us | ||
79 | |||
80 | myScriptEngine.Log.Info("[" + myScriptEngine.ScriptEngineName + "]: Hooking up to server events"); | ||
81 | myScriptEngine.World.EventManager.OnObjectGrab += touch_start; | ||
82 | myScriptEngine.World.EventManager.OnObjectDeGrab += touch_end; | ||
83 | myScriptEngine.World.EventManager.OnRemoveScript += OnRemoveScript; | ||
84 | myScriptEngine.World.EventManager.OnScriptChangedEvent += changed; | ||
85 | myScriptEngine.World.EventManager.OnScriptAtTargetEvent += at_target; | ||
86 | myScriptEngine.World.EventManager.OnScriptNotAtTargetEvent += not_at_target; | ||
87 | myScriptEngine.World.EventManager.OnScriptControlEvent += control; | ||
88 | myScriptEngine.World.EventManager.OnScriptColliderStart += collision_start; | ||
89 | myScriptEngine.World.EventManager.OnScriptColliding += collision; | ||
90 | myScriptEngine.World.EventManager.OnScriptCollidingEnd += collision_end; | ||
91 | |||
92 | // TODO: HOOK ALL EVENTS UP TO SERVER! | ||
93 | IMoneyModule money=myScriptEngine.World.RequestModuleInterface<IMoneyModule>(); | ||
94 | if (money != null) | ||
95 | { | ||
96 | money.OnObjectPaid+=HandleObjectPaid; | ||
97 | } | ||
98 | |||
99 | } | ||
100 | |||
101 | public void ReadConfig() | ||
102 | { | ||
103 | } | ||
104 | |||
105 | private void HandleObjectPaid(UUID objectID, UUID agentID, int amount) | ||
106 | { | ||
107 | SceneObjectPart part=myScriptEngine.World.GetSceneObjectPart(objectID); | ||
108 | if (part != null) | ||
109 | { | ||
110 | money(part.LocalId, agentID, amount); | ||
111 | } | ||
112 | } | ||
113 | |||
114 | public void changed(uint localID, uint change) | ||
115 | { | ||
116 | // Add to queue for all scripts in localID, Object pass change. | ||
117 | myScriptEngine.PostObjectEvent(localID, new EventParams( | ||
118 | "changed",new object[] { new LSL_Types.LSLInteger(change) }, | ||
119 | new DetectParams[0])); | ||
120 | } | ||
121 | |||
122 | public void state_entry(uint localID) | ||
123 | { | ||
124 | // Add to queue for all scripts in ObjectID object | ||
125 | myScriptEngine.PostObjectEvent(localID, new EventParams( | ||
126 | "state_entry",new object[] { }, | ||
127 | new DetectParams[0])); | ||
128 | } | ||
129 | |||
130 | public void touch_start(uint localID, uint originalID, Vector3 offsetPos, | ||
131 | IClientAPI remoteClient) | ||
132 | { | ||
133 | // Add to queue for all scripts in ObjectID object | ||
134 | DetectParams[] det = new DetectParams[1]; | ||
135 | det[0] = new DetectParams(); | ||
136 | det[0].Key = remoteClient.AgentId; | ||
137 | det[0].Populate(myScriptEngine.World); | ||
138 | |||
139 | if (originalID == 0) | ||
140 | { | ||
141 | SceneObjectPart part = myScriptEngine.World.GetSceneObjectPart(localID); | ||
142 | if (part == null) | ||
143 | return; | ||
144 | |||
145 | det[0].LinkNum = part.LinkNum; | ||
146 | } | ||
147 | else | ||
148 | { | ||
149 | SceneObjectPart originalPart = myScriptEngine.World.GetSceneObjectPart(originalID); | ||
150 | det[0].LinkNum = originalPart.LinkNum; | ||
151 | } | ||
152 | |||
153 | myScriptEngine.PostObjectEvent(localID, new EventParams( | ||
154 | "touch_start", new Object[] { new LSL_Types.LSLInteger(1) }, | ||
155 | det)); | ||
156 | } | ||
157 | |||
158 | public void touch(uint localID, uint originalID, Vector3 offsetPos, | ||
159 | IClientAPI remoteClient) | ||
160 | { | ||
161 | // Add to queue for all scripts in ObjectID object | ||
162 | DetectParams[] det = new DetectParams[1]; | ||
163 | det[0] = new DetectParams(); | ||
164 | det[0].Key = remoteClient.AgentId; | ||
165 | det[0].Populate(myScriptEngine.World); | ||
166 | det[0].OffsetPos = new LSL_Types.Vector3(offsetPos.X, | ||
167 | offsetPos.Y, | ||
168 | offsetPos.Z); | ||
169 | |||
170 | if (originalID == 0) | ||
171 | { | ||
172 | SceneObjectPart part = myScriptEngine.World.GetSceneObjectPart(localID); | ||
173 | if (part == null) | ||
174 | return; | ||
175 | |||
176 | det[0].LinkNum = part.LinkNum; | ||
177 | } | ||
178 | else | ||
179 | { | ||
180 | SceneObjectPart originalPart = myScriptEngine.World.GetSceneObjectPart(originalID); | ||
181 | det[0].LinkNum = originalPart.LinkNum; | ||
182 | } | ||
183 | |||
184 | myScriptEngine.PostObjectEvent(localID, new EventParams( | ||
185 | "touch", new Object[] { new LSL_Types.LSLInteger(1) }, | ||
186 | det)); | ||
187 | } | ||
188 | |||
189 | public void touch_end(uint localID, uint originalID, IClientAPI remoteClient) | ||
190 | { | ||
191 | // Add to queue for all scripts in ObjectID object | ||
192 | DetectParams[] det = new DetectParams[1]; | ||
193 | det[0] = new DetectParams(); | ||
194 | det[0].Key = remoteClient.AgentId; | ||
195 | det[0].Populate(myScriptEngine.World); | ||
196 | |||
197 | if (originalID == 0) | ||
198 | { | ||
199 | SceneObjectPart part = myScriptEngine.World.GetSceneObjectPart(localID); | ||
200 | if (part == null) | ||
201 | return; | ||
202 | |||
203 | det[0].LinkNum = part.LinkNum; | ||
204 | } | ||
205 | else | ||
206 | { | ||
207 | SceneObjectPart originalPart = myScriptEngine.World.GetSceneObjectPart(originalID); | ||
208 | det[0].LinkNum = originalPart.LinkNum; | ||
209 | } | ||
210 | |||
211 | myScriptEngine.PostObjectEvent(localID, new EventParams( | ||
212 | "touch_end", new Object[] { new LSL_Types.LSLInteger(1) }, | ||
213 | det)); | ||
214 | } | ||
215 | |||
216 | public void OnRezScript(uint localID, UUID itemID, string script, int startParam, bool postOnRez, string engine) | ||
217 | { | ||
218 | List<IScriptModule> engines = new List<IScriptModule>(myScriptEngine.World.RequestModuleInterfaces<IScriptModule>()); | ||
219 | |||
220 | List<string> names = new List<string>(); | ||
221 | foreach (IScriptModule m in engines) | ||
222 | names.Add(m.ScriptEngineName); | ||
223 | |||
224 | int lineEnd = script.IndexOf('\n'); | ||
225 | |||
226 | if (lineEnd != 1) | ||
227 | { | ||
228 | string firstline = script.Substring(0, lineEnd).Trim(); | ||
229 | |||
230 | int colon = firstline.IndexOf(':'); | ||
231 | if (firstline.Length > 2 && firstline.Substring(0, 2) == "//" && colon != -1) | ||
232 | { | ||
233 | string engineName = firstline.Substring(2, colon-2); | ||
234 | |||
235 | if (names.Contains(engineName)) | ||
236 | { | ||
237 | engine = engineName; | ||
238 | script = "//" + script.Substring(script.IndexOf(':')+1); | ||
239 | } | ||
240 | } | ||
241 | } | ||
242 | |||
243 | if (engine != myScriptEngine.ScriptEngineName) | ||
244 | return; | ||
245 | |||
246 | myScriptEngine.Log.Debug("OnRezScript localID: " + localID + " LLUID: " + itemID.ToString() + " Size: " + | ||
247 | script.Length); | ||
248 | myScriptEngine.m_ScriptManager.StartScript(localID, itemID, script, startParam, postOnRez); | ||
249 | } | ||
250 | |||
251 | public void OnRemoveScript(uint localID, UUID itemID) | ||
252 | { | ||
253 | myScriptEngine.Log.Debug("OnRemoveScript localID: " + localID + " LLUID: " + itemID.ToString()); | ||
254 | myScriptEngine.m_ScriptManager.StopScript( | ||
255 | localID, | ||
256 | itemID | ||
257 | ); | ||
258 | } | ||
259 | |||
260 | public void money(uint localID, UUID agentID, int amount) | ||
261 | { | ||
262 | myScriptEngine.PostObjectEvent(localID, new EventParams( | ||
263 | "money", new object[] { | ||
264 | new LSL_Types.LSLString(agentID.ToString()), | ||
265 | new LSL_Types.LSLInteger(amount) }, | ||
266 | new DetectParams[0])); | ||
267 | } | ||
268 | |||
269 | // TODO: Replace placeholders below | ||
270 | // NOTE! THE PARAMETERS FOR THESE FUNCTIONS ARE NOT CORRECT! | ||
271 | // These needs to be hooked up to OpenSim during init of this class | ||
272 | // then queued in EventQueueManager. | ||
273 | // When queued in EventQueueManager they need to be LSL compatible (name and params) | ||
274 | |||
275 | public void state_exit(uint localID) | ||
276 | { | ||
277 | myScriptEngine.PostObjectEvent(localID, new EventParams( | ||
278 | "state_exit", new object[] { }, | ||
279 | new DetectParams[0])); | ||
280 | } | ||
281 | |||
282 | public void collision_start(uint localID, ColliderArgs col) | ||
283 | { | ||
284 | // Add to queue for all scripts in ObjectID object | ||
285 | List<DetectParams> det = new List<DetectParams>(); | ||
286 | |||
287 | foreach (DetectedObject detobj in col.Colliders) | ||
288 | { | ||
289 | DetectParams d = new DetectParams(); | ||
290 | d.Key =detobj.keyUUID; | ||
291 | d.Populate(myScriptEngine.World); | ||
292 | det.Add(d); | ||
293 | } | ||
294 | |||
295 | if (det.Count > 0) | ||
296 | myScriptEngine.PostObjectEvent(localID, new EventParams( | ||
297 | "collision_start", | ||
298 | new Object[] { new LSL_Types.LSLInteger(det.Count) }, | ||
299 | det.ToArray())); | ||
300 | } | ||
301 | |||
302 | public void collision(uint localID, ColliderArgs col) | ||
303 | { | ||
304 | // Add to queue for all scripts in ObjectID object | ||
305 | List<DetectParams> det = new List<DetectParams>(); | ||
306 | |||
307 | foreach (DetectedObject detobj in col.Colliders) | ||
308 | { | ||
309 | DetectParams d = new DetectParams(); | ||
310 | d.Key =detobj.keyUUID; | ||
311 | d.Populate(myScriptEngine.World); | ||
312 | det.Add(d); | ||
313 | } | ||
314 | |||
315 | if (det.Count > 0) | ||
316 | myScriptEngine.PostObjectEvent(localID, new EventParams( | ||
317 | "collision", new Object[] { new LSL_Types.LSLInteger(det.Count) }, | ||
318 | det.ToArray())); | ||
319 | } | ||
320 | |||
321 | public void collision_end(uint localID, ColliderArgs col) | ||
322 | { | ||
323 | // Add to queue for all scripts in ObjectID object | ||
324 | List<DetectParams> det = new List<DetectParams>(); | ||
325 | |||
326 | foreach (DetectedObject detobj in col.Colliders) | ||
327 | { | ||
328 | DetectParams d = new DetectParams(); | ||
329 | d.Key =detobj.keyUUID; | ||
330 | d.Populate(myScriptEngine.World); | ||
331 | det.Add(d); | ||
332 | } | ||
333 | |||
334 | if (det.Count > 0) | ||
335 | myScriptEngine.PostObjectEvent(localID, new EventParams( | ||
336 | "collision_end", | ||
337 | new Object[] { new LSL_Types.LSLInteger(det.Count) }, | ||
338 | det.ToArray())); | ||
339 | } | ||
340 | |||
341 | public void land_collision_start(uint localID, UUID itemID) | ||
342 | { | ||
343 | myScriptEngine.PostObjectEvent(localID, new EventParams( | ||
344 | "land_collision_start", | ||
345 | new object[0], | ||
346 | new DetectParams[0])); | ||
347 | } | ||
348 | |||
349 | public void land_collision(uint localID, UUID itemID) | ||
350 | { | ||
351 | myScriptEngine.PostObjectEvent(localID, new EventParams( | ||
352 | "land_collision", | ||
353 | new object[0], | ||
354 | new DetectParams[0])); | ||
355 | } | ||
356 | |||
357 | public void land_collision_end(uint localID, UUID itemID) | ||
358 | { | ||
359 | myScriptEngine.PostObjectEvent(localID, new EventParams( | ||
360 | "land_collision_end", | ||
361 | new object[0], | ||
362 | new DetectParams[0])); | ||
363 | } | ||
364 | |||
365 | // Handled by long commands | ||
366 | public void timer(uint localID, UUID itemID) | ||
367 | { | ||
368 | } | ||
369 | |||
370 | public void listen(uint localID, UUID itemID) | ||
371 | { | ||
372 | } | ||
373 | |||
374 | public void control(uint localID, UUID itemID, UUID agentID, uint held, uint change) | ||
375 | { | ||
376 | if ((change == 0) && (myScriptEngine.m_EventQueueManager.CheckEeventQueueForEvent(localID,"control"))) return; | ||
377 | myScriptEngine.PostObjectEvent(localID, new EventParams( | ||
378 | "control",new object[] { | ||
379 | new LSL_Types.LSLString(agentID.ToString()), | ||
380 | new LSL_Types.LSLInteger(held), | ||
381 | new LSL_Types.LSLInteger(change)}, | ||
382 | new DetectParams[0])); | ||
383 | } | ||
384 | |||
385 | public void email(uint localID, UUID itemID, string timeSent, | ||
386 | string address, string subject, string message, int numLeft) | ||
387 | { | ||
388 | myScriptEngine.PostObjectEvent(localID, new EventParams( | ||
389 | "email",new object[] { | ||
390 | new LSL_Types.LSLString(timeSent), | ||
391 | new LSL_Types.LSLString(address), | ||
392 | new LSL_Types.LSLString(subject), | ||
393 | new LSL_Types.LSLString(message), | ||
394 | new LSL_Types.LSLInteger(numLeft)}, | ||
395 | new DetectParams[0])); | ||
396 | } | ||
397 | |||
398 | public void at_target(uint localID, uint handle, Vector3 targetpos, | ||
399 | Vector3 atpos) | ||
400 | { | ||
401 | myScriptEngine.PostObjectEvent(localID, new EventParams( | ||
402 | "at_target", new object[] { | ||
403 | new LSL_Types.LSLInteger(handle), | ||
404 | new LSL_Types.Vector3(targetpos.X,targetpos.Y,targetpos.Z), | ||
405 | new LSL_Types.Vector3(atpos.X,atpos.Y,atpos.Z) }, | ||
406 | new DetectParams[0])); | ||
407 | } | ||
408 | |||
409 | public void not_at_target(uint localID) | ||
410 | { | ||
411 | myScriptEngine.PostObjectEvent(localID, new EventParams( | ||
412 | "not_at_target",new object[0], | ||
413 | new DetectParams[0])); | ||
414 | } | ||
415 | |||
416 | public void at_rot_target(uint localID, UUID itemID) | ||
417 | { | ||
418 | myScriptEngine.PostObjectEvent(localID, new EventParams( | ||
419 | "at_rot_target",new object[0], | ||
420 | new DetectParams[0])); | ||
421 | } | ||
422 | |||
423 | public void not_at_rot_target(uint localID, UUID itemID) | ||
424 | { | ||
425 | myScriptEngine.PostObjectEvent(localID, new EventParams( | ||
426 | "not_at_rot_target",new object[0], | ||
427 | new DetectParams[0])); | ||
428 | } | ||
429 | |||
430 | public void attach(uint localID, UUID itemID) | ||
431 | { | ||
432 | } | ||
433 | |||
434 | public void dataserver(uint localID, UUID itemID) | ||
435 | { | ||
436 | } | ||
437 | |||
438 | public void link_message(uint localID, UUID itemID) | ||
439 | { | ||
440 | } | ||
441 | |||
442 | public void moving_start(uint localID, UUID itemID) | ||
443 | { | ||
444 | myScriptEngine.PostObjectEvent(localID, new EventParams( | ||
445 | "moving_start",new object[0], | ||
446 | new DetectParams[0])); | ||
447 | } | ||
448 | |||
449 | public void moving_end(uint localID, UUID itemID) | ||
450 | { | ||
451 | myScriptEngine.PostObjectEvent(localID, new EventParams( | ||
452 | "moving_end",new object[0], | ||
453 | new DetectParams[0])); | ||
454 | } | ||
455 | |||
456 | public void object_rez(uint localID, UUID itemID) | ||
457 | { | ||
458 | } | ||
459 | |||
460 | public void remote_data(uint localID, UUID itemID) | ||
461 | { | ||
462 | } | ||
463 | |||
464 | // Handled by long commands | ||
465 | public void http_response(uint localID, UUID itemID) | ||
466 | { | ||
467 | } | ||
468 | |||
469 | /// <summary> | ||
470 | /// If set to true then threads and stuff should try to make a graceful exit | ||
471 | /// </summary> | ||
472 | public bool PleaseShutdown | ||
473 | { | ||
474 | get { return _PleaseShutdown; } | ||
475 | set { _PleaseShutdown = value; } | ||
476 | } | ||
477 | private bool _PleaseShutdown = false; | ||
478 | } | ||
479 | } | ||
diff --git a/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/ScriptEngine.cs b/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/ScriptEngine.cs deleted file mode 100644 index f259ec1..0000000 --- a/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/ScriptEngine.cs +++ /dev/null | |||
@@ -1,317 +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 | using System; | ||
29 | using System.Collections.Generic; | ||
30 | using System.Reflection; | ||
31 | using log4net; | ||
32 | using Nini.Config; | ||
33 | using OpenSim.Region.Interfaces; | ||
34 | using OpenSim.Region.Environment.Interfaces; | ||
35 | using OpenSim.Region.Environment.Scenes; | ||
36 | using OpenSim.Region.ScriptEngine.Interfaces; | ||
37 | using OpenMetaverse; | ||
38 | using OpenSim.Region.ScriptEngine.Shared; | ||
39 | |||
40 | namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase | ||
41 | { | ||
42 | /// <summary> | ||
43 | /// This is the root object for ScriptEngine. Objects access each other trough this class. | ||
44 | /// </summary> | ||
45 | /// | ||
46 | [Serializable] | ||
47 | public abstract class ScriptEngine : IRegionModule, IScriptModule, iScriptEngineFunctionModule, IEventReceiver | ||
48 | { | ||
49 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||
50 | |||
51 | public static List<ScriptEngine> ScriptEngines = new List<ScriptEngine>(); | ||
52 | private Scene m_Scene; | ||
53 | public Scene World | ||
54 | { | ||
55 | get { return m_Scene; } | ||
56 | } | ||
57 | public EventManager m_EventManager; // Handles and queues incoming events from OpenSim | ||
58 | public EventQueueManager m_EventQueueManager; // Executes events, handles script threads | ||
59 | public ScriptManager m_ScriptManager; // Load, unload and execute scripts | ||
60 | public AppDomainManager m_AppDomainManager; // Handles loading/unloading of scripts into AppDomains | ||
61 | public static MaintenanceThread m_MaintenanceThread; // Thread that does different kinds of maintenance, for example refreshing config and killing scripts that has been running too long | ||
62 | |||
63 | public IConfigSource ConfigSource; | ||
64 | public IConfig ScriptConfigSource; | ||
65 | public abstract string ScriptEngineName { get; } | ||
66 | private bool m_enabled = false; | ||
67 | private bool m_hookUpToServer = false; | ||
68 | |||
69 | public IConfig Config | ||
70 | { | ||
71 | get { return ScriptConfigSource; } | ||
72 | } | ||
73 | |||
74 | /// <summary> | ||
75 | /// How many seconds between re-reading config-file. 0 = never. ScriptEngine will try to adjust to new config changes. | ||
76 | /// </summary> | ||
77 | public int RefreshConfigFileSeconds { | ||
78 | get { return (int)(RefreshConfigFilens / 10000000); } | ||
79 | set { RefreshConfigFilens = value * 10000000; } | ||
80 | } | ||
81 | public long RefreshConfigFilens; | ||
82 | |||
83 | public ScriptManager GetScriptManager() | ||
84 | { | ||
85 | return _GetScriptManager(); | ||
86 | } | ||
87 | |||
88 | public abstract ScriptManager _GetScriptManager(); | ||
89 | |||
90 | public ILog Log | ||
91 | { | ||
92 | get { return m_log; } | ||
93 | } | ||
94 | |||
95 | public ScriptEngine() | ||
96 | { | ||
97 | Common.mySE = this; // For logging, just need any instance, doesn't matter | ||
98 | lock (ScriptEngines) | ||
99 | { | ||
100 | ScriptEngines.Add(this); // Keep a list of ScriptEngines for shared threads to process all instances | ||
101 | } | ||
102 | } | ||
103 | |||
104 | public void InitializeEngine(Scene Sceneworld, IConfigSource config, bool HookUpToServer, ScriptManager newScriptManager) | ||
105 | { | ||
106 | m_Scene = Sceneworld; | ||
107 | ConfigSource = config; | ||
108 | m_hookUpToServer = HookUpToServer; | ||
109 | |||
110 | m_log.Info("[" + ScriptEngineName + "]: ScriptEngine initializing"); | ||
111 | |||
112 | // Make sure we have config | ||
113 | if (ConfigSource.Configs[ScriptEngineName] == null) | ||
114 | ConfigSource.AddConfig(ScriptEngineName); | ||
115 | ScriptConfigSource = ConfigSource.Configs[ScriptEngineName]; | ||
116 | |||
117 | m_enabled = ScriptConfigSource.GetBoolean("Enabled", true); | ||
118 | if (!m_enabled) | ||
119 | return; | ||
120 | |||
121 | //m_log.Info("[" + ScriptEngineName + "]: InitializeEngine"); | ||
122 | |||
123 | // Create all objects we'll be using | ||
124 | m_EventQueueManager = new EventQueueManager(this); | ||
125 | m_EventManager = new EventManager(this, HookUpToServer); | ||
126 | // We need to start it | ||
127 | m_ScriptManager = newScriptManager; | ||
128 | m_ScriptManager.Setup(); | ||
129 | m_AppDomainManager = new AppDomainManager(this); | ||
130 | if (m_MaintenanceThread == null) | ||
131 | m_MaintenanceThread = new MaintenanceThread(); | ||
132 | |||
133 | m_log.Info("[" + ScriptEngineName + "]: Reading configuration from config section \"" + ScriptEngineName + "\""); | ||
134 | ReadConfig(); | ||
135 | |||
136 | m_Scene.StackModuleInterface<IScriptModule>(this); | ||
137 | } | ||
138 | |||
139 | public void PostInitialise() | ||
140 | { | ||
141 | if (!m_enabled) | ||
142 | return; | ||
143 | |||
144 | if (m_hookUpToServer) | ||
145 | m_EventManager.HookUpEvents(); | ||
146 | |||
147 | m_ScriptManager.Start(); | ||
148 | } | ||
149 | |||
150 | public void Shutdown() | ||
151 | { | ||
152 | // We are shutting down | ||
153 | lock (ScriptEngines) | ||
154 | { | ||
155 | ScriptEngines.Remove(this); | ||
156 | } | ||
157 | } | ||
158 | |||
159 | public void ReadConfig() | ||
160 | { | ||
161 | #if DEBUG | ||
162 | //m_log.Debug("[" + ScriptEngineName + "]: Refreshing configuration for all modules"); | ||
163 | #endif | ||
164 | RefreshConfigFileSeconds = ScriptConfigSource.GetInt("RefreshConfig", 30); | ||
165 | |||
166 | |||
167 | // Create a new object (probably not necessary?) | ||
168 | // ScriptConfigSource = ConfigSource.Configs[ScriptEngineName]; | ||
169 | |||
170 | if (m_EventQueueManager != null) m_EventQueueManager.ReadConfig(); | ||
171 | if (m_EventManager != null) m_EventManager.ReadConfig(); | ||
172 | if (m_ScriptManager != null) m_ScriptManager.ReadConfig(); | ||
173 | if (m_AppDomainManager != null) m_AppDomainManager.ReadConfig(); | ||
174 | if (m_MaintenanceThread != null) m_MaintenanceThread.ReadConfig(); | ||
175 | } | ||
176 | |||
177 | #region IRegionModule | ||
178 | |||
179 | public abstract void Initialise(Scene scene, IConfigSource config); | ||
180 | |||
181 | public void Close() | ||
182 | { | ||
183 | } | ||
184 | |||
185 | public string Name | ||
186 | { | ||
187 | get { return "Common." + ScriptEngineName; } | ||
188 | } | ||
189 | |||
190 | public bool IsSharedModule | ||
191 | { | ||
192 | get { return false; } | ||
193 | } | ||
194 | |||
195 | public bool PostObjectEvent(uint localID, EventParams p) | ||
196 | { | ||
197 | return m_EventQueueManager.AddToObjectQueue(localID, p.EventName, p.DetectParams, p.Params); | ||
198 | } | ||
199 | |||
200 | public bool PostScriptEvent(UUID itemID, EventParams p) | ||
201 | { | ||
202 | uint localID = m_ScriptManager.GetLocalID(itemID); | ||
203 | return m_EventQueueManager.AddToScriptQueue(localID, itemID, p.EventName, p.DetectParams, p.Params); | ||
204 | } | ||
205 | |||
206 | public DetectParams GetDetectParams(UUID itemID, int number) | ||
207 | { | ||
208 | uint localID = m_ScriptManager.GetLocalID(itemID); | ||
209 | if (localID == 0) | ||
210 | return null; | ||
211 | |||
212 | IScript Script = m_ScriptManager.GetScript(localID, itemID); | ||
213 | |||
214 | if (Script == null) | ||
215 | return null; | ||
216 | |||
217 | DetectParams[] det = m_ScriptManager.GetDetectParams(Script); | ||
218 | |||
219 | if (number < 0 || number >= det.Length) | ||
220 | return null; | ||
221 | |||
222 | return det[number]; | ||
223 | } | ||
224 | |||
225 | public int GetStartParameter(UUID itemID) | ||
226 | { | ||
227 | return 0; | ||
228 | } | ||
229 | #endregion | ||
230 | |||
231 | public void SetState(UUID itemID, string state) | ||
232 | { | ||
233 | uint localID = m_ScriptManager.GetLocalID(itemID); | ||
234 | if (localID == 0) | ||
235 | return; | ||
236 | |||
237 | IScript Script = m_ScriptManager.GetScript(localID, itemID); | ||
238 | |||
239 | if (Script == null) | ||
240 | return; | ||
241 | |||
242 | string currentState = Script.State; | ||
243 | |||
244 | if (currentState != state) | ||
245 | { | ||
246 | try | ||
247 | { | ||
248 | m_EventManager.state_exit(localID); | ||
249 | |||
250 | } | ||
251 | catch (AppDomainUnloadedException) | ||
252 | { | ||
253 | Console.WriteLine("[SCRIPT]: state change called when script was unloaded. Nothing to worry about, but noting the occurance"); | ||
254 | } | ||
255 | |||
256 | Script.State = state; | ||
257 | |||
258 | try | ||
259 | { | ||
260 | int eventFlags = m_ScriptManager.GetStateEventFlags(localID, itemID); | ||
261 | SceneObjectPart part = m_Scene.GetSceneObjectPart(itemID); | ||
262 | if (part != null) | ||
263 | part.SetScriptEvents(itemID, eventFlags); | ||
264 | m_EventManager.state_entry(localID); | ||
265 | } | ||
266 | catch (AppDomainUnloadedException) | ||
267 | { | ||
268 | Console.WriteLine("[SCRIPT]: state change called when script was unloaded. Nothing to worry about, but noting the occurance"); | ||
269 | } | ||
270 | } | ||
271 | } | ||
272 | |||
273 | public bool GetScriptState(UUID itemID) | ||
274 | { | ||
275 | uint localID = m_ScriptManager.GetLocalID(itemID); | ||
276 | if (localID == 0) | ||
277 | return false; | ||
278 | |||
279 | IScript script = m_ScriptManager.GetScript(localID, itemID); | ||
280 | if (script == null) | ||
281 | return false; | ||
282 | |||
283 | return script.Exec.Running?true:false; | ||
284 | } | ||
285 | |||
286 | public void SetScriptState(UUID itemID, bool state) | ||
287 | { | ||
288 | uint localID = m_ScriptManager.GetLocalID(itemID); | ||
289 | if (localID == 0) | ||
290 | return; | ||
291 | |||
292 | IScript script = m_ScriptManager.GetScript(localID, itemID); | ||
293 | if (script == null) | ||
294 | return; | ||
295 | |||
296 | script.Exec.Running = state; | ||
297 | } | ||
298 | |||
299 | public void ApiResetScript(UUID itemID) | ||
300 | { | ||
301 | uint localID = m_ScriptManager.GetLocalID(itemID); | ||
302 | if (localID == 0) | ||
303 | return; | ||
304 | |||
305 | m_ScriptManager.ResetScript(localID, itemID); | ||
306 | } | ||
307 | |||
308 | public void ResetScript(UUID itemID) | ||
309 | { | ||
310 | uint localID = m_ScriptManager.GetLocalID(itemID); | ||
311 | if (localID == 0) | ||
312 | return; | ||
313 | |||
314 | m_ScriptManager.ResetScript(localID, itemID); | ||
315 | } | ||
316 | } | ||
317 | } | ||
diff --git a/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/ScriptManager.cs b/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/ScriptManager.cs deleted file mode 100644 index 987a0a0..0000000 --- a/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/ScriptManager.cs +++ /dev/null | |||
@@ -1,510 +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 | using System; | ||
29 | using System.Collections.Generic; | ||
30 | using System.IO; | ||
31 | using System.Reflection; | ||
32 | using System.Runtime.Serialization.Formatters.Binary; | ||
33 | using System.Threading; | ||
34 | using OpenMetaverse; | ||
35 | using OpenSim.Region.Environment.Scenes; | ||
36 | using OpenSim.Region.ScriptEngine.Shared; | ||
37 | |||
38 | namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase | ||
39 | { | ||
40 | /// <summary> | ||
41 | /// Loads scripts | ||
42 | /// Compiles them if necessary | ||
43 | /// Execute functions for EventQueueManager (Sends them to script on other AppDomain for execution) | ||
44 | /// </summary> | ||
45 | /// | ||
46 | |||
47 | // This class is as close as you get to the script without being inside script class. It handles all the dirty work for other classes. | ||
48 | // * Keeps track of running scripts | ||
49 | // * Compiles script if necessary (through "Compiler") | ||
50 | // * Loads script (through "AppDomainManager" called from for example "EventQueueManager") | ||
51 | // * Executes functions inside script (called from for example "EventQueueManager" class) | ||
52 | // * Unloads script (through "AppDomainManager" called from for example "EventQueueManager") | ||
53 | // * Dedicated load/unload thread, and queues loading/unloading. | ||
54 | // This so that scripts starting or stopping will not slow down other theads or whole system. | ||
55 | // | ||
56 | [Serializable] | ||
57 | public abstract class ScriptManager : iScriptEngineFunctionModule | ||
58 | { | ||
59 | #region Declares | ||
60 | |||
61 | private Thread scriptLoadUnloadThread; | ||
62 | private static Thread staticScriptLoadUnloadThread; | ||
63 | // private int scriptLoadUnloadThread_IdleSleepms; | ||
64 | private Queue<LUStruct> LUQueue = new Queue<LUStruct>(); | ||
65 | private static bool PrivateThread; | ||
66 | private int LoadUnloadMaxQueueSize; | ||
67 | private Object scriptLock = new Object(); | ||
68 | private bool m_started = false; | ||
69 | private Dictionary<IScript, DetectParams[]> detparms = new Dictionary<IScript, DetectParams[]>(); | ||
70 | |||
71 | // Load/Unload structure | ||
72 | private struct LUStruct | ||
73 | { | ||
74 | public uint localID; | ||
75 | public UUID itemID; | ||
76 | public string script; | ||
77 | public LUType Action; | ||
78 | public int startParam; | ||
79 | public bool postOnRez; | ||
80 | } | ||
81 | |||
82 | private enum LUType | ||
83 | { | ||
84 | Unknown = 0, | ||
85 | Load = 1, | ||
86 | Unload = 2 | ||
87 | } | ||
88 | |||
89 | // Xantor 20080525: Keep a list of compiled scripts this session for reuse | ||
90 | public Dictionary<UUID, String> scriptList = new Dictionary<UUID, string>(); | ||
91 | |||
92 | // Object<string, Script<string, script>> | ||
93 | // IMPORTANT: Types and MemberInfo-derived objects require a LOT of memory. | ||
94 | // Instead use RuntimeTypeHandle, RuntimeFieldHandle and RunTimeHandle (IntPtr) instead! | ||
95 | public Dictionary<uint, Dictionary<UUID, IScript>> Scripts = | ||
96 | new Dictionary<uint, Dictionary<UUID, IScript>>(); | ||
97 | |||
98 | |||
99 | public Scene World | ||
100 | { | ||
101 | get { return m_scriptEngine.World; } | ||
102 | } | ||
103 | |||
104 | #endregion | ||
105 | |||
106 | public void ReadConfig() | ||
107 | { | ||
108 | // scriptLoadUnloadThread_IdleSleepms = m_scriptEngine.ScriptConfigSource.GetInt("ScriptLoadUnloadLoopms", 30); | ||
109 | // TODO: Requires sharing of all ScriptManagers to single thread | ||
110 | PrivateThread = true; // m_scriptEngine.ScriptConfigSource.GetBoolean("PrivateScriptLoadUnloadThread", false); | ||
111 | LoadUnloadMaxQueueSize = m_scriptEngine.ScriptConfigSource.GetInt("LoadUnloadMaxQueueSize", 100); | ||
112 | } | ||
113 | |||
114 | #region Object init/shutdown | ||
115 | |||
116 | public ScriptEngine m_scriptEngine; | ||
117 | |||
118 | public ScriptManager(ScriptEngine scriptEngine) | ||
119 | { | ||
120 | m_scriptEngine = scriptEngine; | ||
121 | } | ||
122 | public abstract void Initialize(); | ||
123 | public void Setup() | ||
124 | { | ||
125 | ReadConfig(); | ||
126 | Initialize(); | ||
127 | } | ||
128 | public void Start() | ||
129 | { | ||
130 | m_started = true; | ||
131 | |||
132 | |||
133 | AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve); | ||
134 | |||
135 | // | ||
136 | // CREATE THREAD | ||
137 | // Private or shared | ||
138 | // | ||
139 | if (PrivateThread) | ||
140 | { | ||
141 | // Assign one thread per region | ||
142 | //scriptLoadUnloadThread = StartScriptLoadUnloadThread(); | ||
143 | } | ||
144 | else | ||
145 | { | ||
146 | // Shared thread - make sure one exist, then assign it to the private | ||
147 | if (staticScriptLoadUnloadThread == null) | ||
148 | { | ||
149 | //staticScriptLoadUnloadThread = StartScriptLoadUnloadThread(); | ||
150 | } | ||
151 | scriptLoadUnloadThread = staticScriptLoadUnloadThread; | ||
152 | } | ||
153 | } | ||
154 | |||
155 | // TODO: unused | ||
156 | // private static int privateThreadCount = 0; | ||
157 | // private Thread StartScriptLoadUnloadThread() | ||
158 | // { | ||
159 | // Thread t = new Thread(ScriptLoadUnloadThreadLoop); | ||
160 | // string name = "ScriptLoadUnloadThread:"; | ||
161 | // if (PrivateThread) | ||
162 | // { | ||
163 | // name += "Private:" + privateThreadCount; | ||
164 | // privateThreadCount++; | ||
165 | // } | ||
166 | // else | ||
167 | // { | ||
168 | // name += "Shared"; | ||
169 | // } | ||
170 | // t.Name = name; | ||
171 | // t.IsBackground = true; | ||
172 | // t.Priority = ThreadPriority.Normal; | ||
173 | // t.Start(); | ||
174 | // OpenSim.Framework.ThreadTracker.Add(t); | ||
175 | // return t; | ||
176 | // } | ||
177 | |||
178 | ~ScriptManager() | ||
179 | { | ||
180 | // Abort load/unload thread | ||
181 | try | ||
182 | { | ||
183 | //PleaseShutdown = true; | ||
184 | //Thread.Sleep(100); | ||
185 | if (scriptLoadUnloadThread != null && scriptLoadUnloadThread.IsAlive == true) | ||
186 | { | ||
187 | scriptLoadUnloadThread.Abort(); | ||
188 | //scriptLoadUnloadThread.Join(); | ||
189 | } | ||
190 | } | ||
191 | catch | ||
192 | { | ||
193 | } | ||
194 | } | ||
195 | |||
196 | #endregion | ||
197 | |||
198 | #region Load / Unload scripts (Thread loop) | ||
199 | |||
200 | // TODO: unused | ||
201 | // private void ScriptLoadUnloadThreadLoop() | ||
202 | // { | ||
203 | // try | ||
204 | // { | ||
205 | // while (true) | ||
206 | // { | ||
207 | // if (LUQueue.Count == 0) | ||
208 | // Thread.Sleep(scriptLoadUnloadThread_IdleSleepms); | ||
209 | // //if (PleaseShutdown) | ||
210 | // // return; | ||
211 | // DoScriptLoadUnload(); | ||
212 | // } | ||
213 | // } | ||
214 | // catch (ThreadAbortException tae) | ||
215 | // { | ||
216 | // string a = tae.ToString(); | ||
217 | // a = String.Empty; | ||
218 | // // Expected | ||
219 | // } | ||
220 | // } | ||
221 | |||
222 | public void DoScriptLoadUnload() | ||
223 | { | ||
224 | if (!m_started) | ||
225 | return; | ||
226 | |||
227 | lock (LUQueue) | ||
228 | { | ||
229 | if (LUQueue.Count > 0) | ||
230 | { | ||
231 | m_scriptEngine.Log.InfoFormat("[{0}]: Loading script", m_scriptEngine.ScriptEngineName); | ||
232 | LUStruct item = LUQueue.Dequeue(); | ||
233 | |||
234 | if (item.Action == LUType.Unload) | ||
235 | { | ||
236 | _StopScript(item.localID, item.itemID); | ||
237 | RemoveScript(item.localID, item.itemID); | ||
238 | } | ||
239 | else if (item.Action == LUType.Load) | ||
240 | { | ||
241 | _StartScript(item.localID, item.itemID, item.script, item.startParam, item.postOnRez); | ||
242 | } | ||
243 | } | ||
244 | } | ||
245 | } | ||
246 | |||
247 | #endregion | ||
248 | |||
249 | #region Helper functions | ||
250 | |||
251 | private static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args) | ||
252 | { | ||
253 | //Console.WriteLine("ScriptManager.CurrentDomain_AssemblyResolve: " + args.Name); | ||
254 | return Assembly.GetExecutingAssembly().FullName == args.Name ? Assembly.GetExecutingAssembly() : null; | ||
255 | } | ||
256 | |||
257 | #endregion | ||
258 | |||
259 | |||
260 | |||
261 | #region Start/Stop/Reset script | ||
262 | |||
263 | // private readonly Object startStopLock = new Object(); | ||
264 | |||
265 | /// <summary> | ||
266 | /// Fetches, loads and hooks up a script to an objects events | ||
267 | /// </summary> | ||
268 | /// <param name="itemID"></param> | ||
269 | /// <param name="localID"></param> | ||
270 | public void StartScript(uint localID, UUID itemID, string Script, int startParam, bool postOnRez) | ||
271 | { | ||
272 | lock (LUQueue) | ||
273 | { | ||
274 | if ((LUQueue.Count >= LoadUnloadMaxQueueSize) && m_started) | ||
275 | { | ||
276 | m_scriptEngine.Log.Error("[" + m_scriptEngine.ScriptEngineName + "]: ERROR: Load/unload queue item count is at " + LUQueue.Count + ". Config variable \"LoadUnloadMaxQueueSize\" is set to " + LoadUnloadMaxQueueSize + ", so ignoring new script."); | ||
277 | return; | ||
278 | } | ||
279 | |||
280 | LUStruct ls = new LUStruct(); | ||
281 | ls.localID = localID; | ||
282 | ls.itemID = itemID; | ||
283 | ls.script = Script; | ||
284 | ls.Action = LUType.Load; | ||
285 | ls.startParam = startParam; | ||
286 | ls.postOnRez = postOnRez; | ||
287 | LUQueue.Enqueue(ls); | ||
288 | m_scriptEngine.Log.InfoFormat("[{0}]: Queued script for load", m_scriptEngine.ScriptEngineName); | ||
289 | } | ||
290 | } | ||
291 | |||
292 | /// <summary> | ||
293 | /// Disables and unloads a script | ||
294 | /// </summary> | ||
295 | /// <param name="localID"></param> | ||
296 | /// <param name="itemID"></param> | ||
297 | public void StopScript(uint localID, UUID itemID) | ||
298 | { | ||
299 | LUStruct ls = new LUStruct(); | ||
300 | ls.localID = localID; | ||
301 | ls.itemID = itemID; | ||
302 | ls.Action = LUType.Unload; | ||
303 | ls.startParam = 0; | ||
304 | ls.postOnRez = false; | ||
305 | lock (LUQueue) | ||
306 | { | ||
307 | LUQueue.Enqueue(ls); | ||
308 | } | ||
309 | } | ||
310 | |||
311 | // Create a new instance of the compiler (reuse) | ||
312 | //private Compiler.LSL.Compiler LSLCompiler = new Compiler.LSL.Compiler(); | ||
313 | |||
314 | public abstract void _StartScript(uint localID, UUID itemID, string Script, int startParam, bool postOnRez); | ||
315 | public abstract void _StopScript(uint localID, UUID itemID); | ||
316 | |||
317 | |||
318 | #endregion | ||
319 | |||
320 | #region Perform event execution in script | ||
321 | |||
322 | /// <summary> | ||
323 | /// Execute a LL-event-function in Script | ||
324 | /// </summary> | ||
325 | /// <param name="localID">Object the script is located in</param> | ||
326 | /// <param name="itemID">Script ID</param> | ||
327 | /// <param name="FunctionName">Name of function</param> | ||
328 | /// <param name="args">Arguments to pass to function</param> | ||
329 | internal void ExecuteEvent(uint localID, UUID itemID, string FunctionName, DetectParams[] qParams, object[] args) | ||
330 | { | ||
331 | //cfk 2-7-08 dont need this right now and the default Linux build has DEBUG defined | ||
332 | ///#if DEBUG | ||
333 | /// Console.WriteLine("ScriptEngine: Inside ExecuteEvent for event " + FunctionName); | ||
334 | ///#endif | ||
335 | // Execute a function in the script | ||
336 | //m_scriptEngine.Log.Info("[" + ScriptEngineName + "]: Executing Function localID: " + localID + ", itemID: " + itemID + ", FunctionName: " + FunctionName); | ||
337 | //ScriptBaseInterface Script = (ScriptBaseInterface)GetScript(localID, itemID); | ||
338 | IScript Script = GetScript(localID, itemID); | ||
339 | if (Script == null) | ||
340 | { | ||
341 | return; | ||
342 | } | ||
343 | //cfk 2-7-08 dont need this right now and the default Linux build has DEBUG defined | ||
344 | ///#if DEBUG | ||
345 | /// Console.WriteLine("ScriptEngine: Executing event: " + FunctionName); | ||
346 | ///#endif | ||
347 | // Must be done in correct AppDomain, so leaving it up to the script itself | ||
348 | detparms[Script] = qParams; | ||
349 | Script.Exec.ExecuteEvent(FunctionName, args); | ||
350 | detparms.Remove(Script); | ||
351 | } | ||
352 | |||
353 | public uint GetLocalID(UUID itemID) | ||
354 | { | ||
355 | foreach (KeyValuePair<uint, Dictionary<UUID, IScript> > k in Scripts) | ||
356 | { | ||
357 | if (k.Value.ContainsKey(itemID)) | ||
358 | return k.Key; | ||
359 | } | ||
360 | return 0; | ||
361 | } | ||
362 | |||
363 | public int GetStateEventFlags(uint localID, UUID itemID) | ||
364 | { | ||
365 | // Console.WriteLine("GetStateEventFlags for <" + localID + "," + itemID + ">"); | ||
366 | try | ||
367 | { | ||
368 | IScript Script = GetScript(localID, itemID); | ||
369 | if (Script == null) | ||
370 | { | ||
371 | return 0; | ||
372 | } | ||
373 | ExecutorBase.scriptEvents evflags = Script.Exec.GetStateEventFlags(); | ||
374 | return (int)evflags; | ||
375 | } | ||
376 | catch (Exception) | ||
377 | { | ||
378 | } | ||
379 | |||
380 | return 0; | ||
381 | } | ||
382 | |||
383 | |||
384 | #endregion | ||
385 | |||
386 | #region Internal functions to keep track of script | ||
387 | |||
388 | public List<UUID> GetScriptKeys(uint localID) | ||
389 | { | ||
390 | if (Scripts.ContainsKey(localID) == false) | ||
391 | return new List<UUID>(); | ||
392 | |||
393 | Dictionary<UUID, IScript> Obj; | ||
394 | Scripts.TryGetValue(localID, out Obj); | ||
395 | |||
396 | return new List<UUID>(Obj.Keys); | ||
397 | } | ||
398 | |||
399 | public IScript GetScript(uint localID, UUID itemID) | ||
400 | { | ||
401 | lock (scriptLock) | ||
402 | { | ||
403 | IScript Script = null; | ||
404 | |||
405 | if (Scripts.ContainsKey(localID) == false) | ||
406 | return null; | ||
407 | |||
408 | Dictionary<UUID, IScript> Obj; | ||
409 | Scripts.TryGetValue(localID, out Obj); | ||
410 | if (Obj.ContainsKey(itemID) == false) | ||
411 | return null; | ||
412 | |||
413 | // Get script | ||
414 | Obj.TryGetValue(itemID, out Script); | ||
415 | return Script; | ||
416 | } | ||
417 | } | ||
418 | |||
419 | public void SetScript(uint localID, UUID itemID, IScript Script) | ||
420 | { | ||
421 | lock (scriptLock) | ||
422 | { | ||
423 | // Create object if it doesn't exist | ||
424 | if (Scripts.ContainsKey(localID) == false) | ||
425 | { | ||
426 | Scripts.Add(localID, new Dictionary<UUID, IScript>()); | ||
427 | } | ||
428 | |||
429 | // Delete script if it exists | ||
430 | Dictionary<UUID, IScript> Obj; | ||
431 | Scripts.TryGetValue(localID, out Obj); | ||
432 | if (Obj.ContainsKey(itemID) == true) | ||
433 | Obj.Remove(itemID); | ||
434 | |||
435 | // Add to object | ||
436 | Obj.Add(itemID, Script); | ||
437 | } | ||
438 | } | ||
439 | |||
440 | public void RemoveScript(uint localID, UUID itemID) | ||
441 | { | ||
442 | if (localID == 0) | ||
443 | localID = GetLocalID(itemID); | ||
444 | |||
445 | // Don't have that object? | ||
446 | if (Scripts.ContainsKey(localID) == false) | ||
447 | return; | ||
448 | |||
449 | // Delete script if it exists | ||
450 | Dictionary<UUID, IScript> Obj; | ||
451 | Scripts.TryGetValue(localID, out Obj); | ||
452 | if (Obj.ContainsKey(itemID) == true) | ||
453 | Obj.Remove(itemID); | ||
454 | } | ||
455 | |||
456 | #endregion | ||
457 | |||
458 | |||
459 | public void ResetScript(uint localID, UUID itemID) | ||
460 | { | ||
461 | IScript s = GetScript(localID, itemID); | ||
462 | string script = s.Source; | ||
463 | StopScript(localID, itemID); | ||
464 | SceneObjectPart part = World.GetSceneObjectPart(localID); | ||
465 | part.GetInventoryItem(itemID).PermsMask = 0; | ||
466 | part.GetInventoryItem(itemID).PermsGranter = UUID.Zero; | ||
467 | StartScript(localID, itemID, script, s.StartParam, false); | ||
468 | } | ||
469 | |||
470 | |||
471 | #region Script serialization/deserialization | ||
472 | |||
473 | public void GetSerializedScript(uint localID, UUID itemID) | ||
474 | { | ||
475 | // Serialize the script and return it | ||
476 | // Should not be a problem | ||
477 | FileStream fs = File.Create("SERIALIZED_SCRIPT_" + itemID); | ||
478 | BinaryFormatter b = new BinaryFormatter(); | ||
479 | b.Serialize(fs, GetScript(localID, itemID)); | ||
480 | fs.Close(); | ||
481 | } | ||
482 | |||
483 | public void PutSerializedScript(uint localID, UUID itemID) | ||
484 | { | ||
485 | // Deserialize the script and inject it into an AppDomain | ||
486 | |||
487 | // How to inject into an AppDomain? | ||
488 | } | ||
489 | |||
490 | #endregion | ||
491 | |||
492 | ///// <summary> | ||
493 | ///// If set to true then threads and stuff should try to make a graceful exit | ||
494 | ///// </summary> | ||
495 | //public bool PleaseShutdown | ||
496 | //{ | ||
497 | // get { return _PleaseShutdown; } | ||
498 | // set { _PleaseShutdown = value; } | ||
499 | //} | ||
500 | //private bool _PleaseShutdown = false; | ||
501 | |||
502 | public DetectParams[] GetDetectParams(IScript script) | ||
503 | { | ||
504 | if (detparms.ContainsKey(script)) | ||
505 | return detparms[script]; | ||
506 | |||
507 | return null; | ||
508 | } | ||
509 | } | ||
510 | } | ||
diff --git a/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/iScriptEngineFunctionModule.cs b/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/iScriptEngineFunctionModule.cs deleted file mode 100644 index 768ba6d..0000000 --- a/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/iScriptEngineFunctionModule.cs +++ /dev/null | |||
@@ -1,35 +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 | namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase | ||
29 | { | ||
30 | public interface iScriptEngineFunctionModule | ||
31 | { | ||
32 | void ReadConfig(); | ||
33 | // bool PleaseShutdown { get; set; } | ||
34 | } | ||
35 | } | ||
diff --git a/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/AppDomainManager.cs b/OpenSim/Region/ScriptEngine/DotNetEngine/AppDomainManager.cs index 262d75f..969a05e 100644 --- a/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/AppDomainManager.cs +++ b/OpenSim/Region/ScriptEngine/DotNetEngine/AppDomainManager.cs | |||
@@ -29,8 +29,9 @@ using System; | |||
29 | using System.Collections; | 29 | using System.Collections; |
30 | using System.Collections.Generic; | 30 | using System.Collections.Generic; |
31 | using System.Reflection; | 31 | using System.Reflection; |
32 | using OpenSim.Region.ScriptEngine.Common; | ||
32 | 33 | ||
33 | namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase | 34 | namespace OpenSim.Region.ScriptEngine.DotNetEngine |
34 | { | 35 | { |
35 | public class AppDomainManager : iScriptEngineFunctionModule | 36 | public class AppDomainManager : iScriptEngineFunctionModule |
36 | { | 37 | { |
diff --git a/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/Common.cs b/OpenSim/Region/ScriptEngine/DotNetEngine/Common.cs index d5ec9b4..3d9e19b 100644 --- a/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/Common.cs +++ b/OpenSim/Region/ScriptEngine/DotNetEngine/Common.cs | |||
@@ -25,7 +25,7 @@ | |||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | */ | 26 | */ |
27 | 27 | ||
28 | namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase | 28 | namespace OpenSim.Region.ScriptEngine.DotNetEngine |
29 | { | 29 | { |
30 | public static class Common | 30 | public static class Common |
31 | { | 31 | { |
diff --git a/OpenSim/Region/ScriptEngine/DotNetEngine/Compiler/LSL/Compiler.cs b/OpenSim/Region/ScriptEngine/DotNetEngine/Compiler/LSL/Compiler.cs index b50e823..4cb74fa 100644 --- a/OpenSim/Region/ScriptEngine/DotNetEngine/Compiler/LSL/Compiler.cs +++ b/OpenSim/Region/ScriptEngine/DotNetEngine/Compiler/LSL/Compiler.cs | |||
@@ -83,8 +83,8 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.LSL | |||
83 | private static int instanceID = new Random().Next(0, int.MaxValue); // Unique number to use on our compiled files | 83 | private static int instanceID = new Random().Next(0, int.MaxValue); // Unique number to use on our compiled files |
84 | private static UInt64 scriptCompileCounter = 0; // And a counter | 84 | private static UInt64 scriptCompileCounter = 0; // And a counter |
85 | 85 | ||
86 | public Common.ScriptEngineBase.ScriptEngine m_scriptEngine; | 86 | public ScriptEngine m_scriptEngine; |
87 | public Compiler(Common.ScriptEngineBase.ScriptEngine scriptEngine) | 87 | public Compiler(ScriptEngine scriptEngine) |
88 | { | 88 | { |
89 | m_scriptEngine = scriptEngine; | 89 | m_scriptEngine = scriptEngine; |
90 | ReadConfig(); | 90 | ReadConfig(); |
diff --git a/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/EventQueueManager.cs b/OpenSim/Region/ScriptEngine/DotNetEngine/EventQueueManager.cs index b13ab21..7805d67 100644 --- a/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/EventQueueManager.cs +++ b/OpenSim/Region/ScriptEngine/DotNetEngine/EventQueueManager.cs | |||
@@ -31,7 +31,7 @@ using System.Collections.Generic; | |||
31 | using OpenMetaverse; | 31 | using OpenMetaverse; |
32 | using OpenSim.Region.ScriptEngine.Shared; | 32 | using OpenSim.Region.ScriptEngine.Shared; |
33 | 33 | ||
34 | namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase | 34 | namespace OpenSim.Region.ScriptEngine.DotNetEngine |
35 | { | 35 | { |
36 | /// <summary> | 36 | /// <summary> |
37 | /// EventQueueManager handles event queues | 37 | /// EventQueueManager handles event queues |
diff --git a/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/EventQueueThreadClass.cs b/OpenSim/Region/ScriptEngine/DotNetEngine/EventQueueThreadClass.cs index 7f52793..db3f89f 100644 --- a/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/EventQueueThreadClass.cs +++ b/OpenSim/Region/ScriptEngine/DotNetEngine/EventQueueThreadClass.cs | |||
@@ -36,7 +36,7 @@ using log4net; | |||
36 | using OpenSim.Framework; | 36 | using OpenSim.Framework; |
37 | using OpenSim.Region.Environment.Scenes.Scripting; | 37 | using OpenSim.Region.Environment.Scenes.Scripting; |
38 | 38 | ||
39 | namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase | 39 | namespace OpenSim.Region.ScriptEngine.DotNetEngine |
40 | { | 40 | { |
41 | /// <summary> | 41 | /// <summary> |
42 | /// Because every thread needs some data set for it (time started to execute current function), it will do its work within a class | 42 | /// Because every thread needs some data set for it (time started to execute current function), it will do its work within a class |
@@ -103,7 +103,7 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase | |||
103 | break; | 103 | break; |
104 | default: | 104 | default: |
105 | MyThreadPriority = ThreadPriority.BelowNormal; // Default | 105 | MyThreadPriority = ThreadPriority.BelowNormal; // Default |
106 | m_ScriptEngine.Log.Error("[ScriptEngineBase]: Unknown priority type \"" + pri + | 106 | m_ScriptEngine.Log.Error("[ScriptEngine.DotNetEngine]: Unknown priority type \"" + pri + |
107 | "\" in config file. Defaulting to \"BelowNormal\"."); | 107 | "\" in config file. Defaulting to \"BelowNormal\"."); |
108 | break; | 108 | break; |
109 | } | 109 | } |
diff --git a/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/MaintenanceThread.cs b/OpenSim/Region/ScriptEngine/DotNetEngine/MaintenanceThread.cs index ef87b2f..6c1528f 100644 --- a/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/MaintenanceThread.cs +++ b/OpenSim/Region/ScriptEngine/DotNetEngine/MaintenanceThread.cs | |||
@@ -32,7 +32,7 @@ using System.Threading; | |||
32 | using log4net; | 32 | using log4net; |
33 | using OpenSim.Framework; | 33 | using OpenSim.Framework; |
34 | 34 | ||
35 | namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase | 35 | namespace OpenSim.Region.ScriptEngine.DotNetEngine |
36 | { | 36 | { |
37 | /// <summary> | 37 | /// <summary> |
38 | /// This class does maintenance on script engine. | 38 | /// This class does maintenance on script engine. |
diff --git a/OpenSim/Region/ScriptEngine/DotNetEngine/ScriptEngine.cs b/OpenSim/Region/ScriptEngine/DotNetEngine/ScriptEngine.cs index e785cc0..7ec71c2 100644 --- a/OpenSim/Region/ScriptEngine/DotNetEngine/ScriptEngine.cs +++ b/OpenSim/Region/ScriptEngine/DotNetEngine/ScriptEngine.cs | |||
@@ -26,29 +26,281 @@ | |||
26 | */ | 26 | */ |
27 | 27 | ||
28 | using System; | 28 | using System; |
29 | using System.Collections.Generic; | ||
30 | using System.Reflection; | ||
31 | using log4net; | ||
29 | using Nini.Config; | 32 | using Nini.Config; |
33 | using OpenSim.Region.Interfaces; | ||
34 | using OpenSim.Region.Environment.Interfaces; | ||
30 | using OpenSim.Region.Environment.Scenes; | 35 | using OpenSim.Region.Environment.Scenes; |
36 | using OpenSim.Region.ScriptEngine.Interfaces; | ||
37 | using OpenMetaverse; | ||
38 | using OpenSim.Region.ScriptEngine.Shared; | ||
39 | using OpenSim.Region.ScriptEngine.Common; | ||
31 | 40 | ||
32 | namespace OpenSim.Region.ScriptEngine.DotNetEngine | 41 | namespace OpenSim.Region.ScriptEngine.DotNetEngine |
33 | { | 42 | { |
34 | [Serializable] | 43 | [Serializable] |
35 | public class ScriptEngine : Common.ScriptEngineBase.ScriptEngine | 44 | public class ScriptEngine : IRegionModule, IEventReceiver, IScriptModule |
36 | { | 45 | { |
37 | // We need to override a few things for our DotNetEngine | 46 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
38 | public override void Initialise(Scene scene, IConfigSource config) | 47 | |
48 | public static List<ScriptEngine> ScriptEngines = new List<ScriptEngine>(); | ||
49 | private Scene m_Scene; | ||
50 | public Scene World | ||
39 | { | 51 | { |
40 | ConfigSource = config; | 52 | get { return m_Scene; } |
41 | InitializeEngine(scene, config, true, GetScriptManager()); | ||
42 | } | 53 | } |
54 | public EventManager m_EventManager; // Handles and queues incoming events from OpenSim | ||
55 | public EventQueueManager m_EventQueueManager; // Executes events, handles script threads | ||
56 | public ScriptManager m_ScriptManager; // Load, unload and execute scripts | ||
57 | public AppDomainManager m_AppDomainManager; // Handles loading/unloading of scripts into AppDomains | ||
58 | public static MaintenanceThread m_MaintenanceThread; // Thread that does different kinds of maintenance, for example refreshing config and killing scripts that has been running too long | ||
59 | |||
60 | public IConfigSource ConfigSource; | ||
61 | public IConfig ScriptConfigSource; | ||
62 | private bool m_enabled = false; | ||
43 | 63 | ||
44 | public override Common.ScriptEngineBase.ScriptManager _GetScriptManager() | 64 | public IConfig Config |
45 | { | 65 | { |
46 | return new ScriptManager(this); | 66 | get { return ScriptConfigSource; } |
47 | } | 67 | } |
48 | 68 | ||
49 | public override string ScriptEngineName | 69 | /// <summary> |
70 | /// How many seconds between re-reading config-file. 0 = never. ScriptEngine will try to adjust to new config changes. | ||
71 | /// </summary> | ||
72 | public int RefreshConfigFileSeconds { | ||
73 | get { return (int)(RefreshConfigFilens / 10000000); } | ||
74 | set { RefreshConfigFilens = value * 10000000; } | ||
75 | } | ||
76 | public long RefreshConfigFilens; | ||
77 | |||
78 | public string ScriptEngineName | ||
50 | { | 79 | { |
51 | get { return "ScriptEngine.DotNetEngine"; } | 80 | get { return "ScriptEngine.DotNetEngine"; } |
52 | } | 81 | } |
82 | |||
83 | public ILog Log | ||
84 | { | ||
85 | get { return m_log; } | ||
86 | } | ||
87 | |||
88 | public ScriptEngine() | ||
89 | { | ||
90 | Common.mySE = this; // For logging, just need any instance, doesn't matter | ||
91 | lock (ScriptEngines) | ||
92 | { | ||
93 | ScriptEngines.Add(this); // Keep a list of ScriptEngines for shared threads to process all instances | ||
94 | } | ||
95 | } | ||
96 | |||
97 | public void Initialise(Scene Sceneworld, IConfigSource config) | ||
98 | { | ||
99 | m_log.Info("[" + ScriptEngineName + "]: ScriptEngine initializing"); | ||
100 | |||
101 | ConfigSource = config; | ||
102 | m_Scene = Sceneworld; | ||
103 | |||
104 | // Make sure we have config | ||
105 | if (ConfigSource.Configs[ScriptEngineName] == null) | ||
106 | ConfigSource.AddConfig(ScriptEngineName); | ||
107 | ScriptConfigSource = ConfigSource.Configs[ScriptEngineName]; | ||
108 | |||
109 | m_enabled = ScriptConfigSource.GetBoolean("Enabled", true); | ||
110 | if (!m_enabled) | ||
111 | return; | ||
112 | |||
113 | //m_log.Info("[" + ScriptEngineName + "]: InitializeEngine"); | ||
114 | |||
115 | // Create all objects we'll be using | ||
116 | m_EventQueueManager = new EventQueueManager(this); | ||
117 | m_EventManager = new EventManager(this, true); | ||
118 | // We need to start it | ||
119 | m_ScriptManager = new ScriptManager(this); | ||
120 | m_ScriptManager.Setup(); | ||
121 | m_AppDomainManager = new AppDomainManager(this); | ||
122 | if (m_MaintenanceThread == null) | ||
123 | m_MaintenanceThread = new MaintenanceThread(); | ||
124 | |||
125 | m_log.Info("[" + ScriptEngineName + "]: Reading configuration from config section \"" + ScriptEngineName + "\""); | ||
126 | ReadConfig(); | ||
127 | |||
128 | m_Scene.StackModuleInterface<IScriptModule>(this); | ||
129 | } | ||
130 | |||
131 | public void PostInitialise() | ||
132 | { | ||
133 | if (!m_enabled) | ||
134 | return; | ||
135 | |||
136 | m_EventManager.HookUpEvents(); | ||
137 | |||
138 | m_ScriptManager.Start(); | ||
139 | } | ||
140 | |||
141 | public void Shutdown() | ||
142 | { | ||
143 | // We are shutting down | ||
144 | lock (ScriptEngines) | ||
145 | { | ||
146 | ScriptEngines.Remove(this); | ||
147 | } | ||
148 | } | ||
149 | |||
150 | public void ReadConfig() | ||
151 | { | ||
152 | #if DEBUG | ||
153 | //m_log.Debug("[" + ScriptEngineName + "]: Refreshing configuration for all modules"); | ||
154 | #endif | ||
155 | RefreshConfigFileSeconds = ScriptConfigSource.GetInt("RefreshConfig", 30); | ||
156 | |||
157 | |||
158 | // Create a new object (probably not necessary?) | ||
159 | // ScriptConfigSource = ConfigSource.Configs[ScriptEngineName]; | ||
160 | |||
161 | if (m_EventQueueManager != null) m_EventQueueManager.ReadConfig(); | ||
162 | if (m_EventManager != null) m_EventManager.ReadConfig(); | ||
163 | if (m_ScriptManager != null) m_ScriptManager.ReadConfig(); | ||
164 | if (m_AppDomainManager != null) m_AppDomainManager.ReadConfig(); | ||
165 | if (m_MaintenanceThread != null) m_MaintenanceThread.ReadConfig(); | ||
166 | } | ||
167 | |||
168 | #region IRegionModule | ||
169 | |||
170 | public void Close() | ||
171 | { | ||
172 | } | ||
173 | |||
174 | public string Name | ||
175 | { | ||
176 | get { return "Common." + ScriptEngineName; } | ||
177 | } | ||
178 | |||
179 | public bool IsSharedModule | ||
180 | { | ||
181 | get { return false; } | ||
182 | } | ||
183 | |||
184 | public bool PostObjectEvent(uint localID, EventParams p) | ||
185 | { | ||
186 | return m_EventQueueManager.AddToObjectQueue(localID, p.EventName, p.DetectParams, p.Params); | ||
187 | } | ||
188 | |||
189 | public bool PostScriptEvent(UUID itemID, EventParams p) | ||
190 | { | ||
191 | uint localID = m_ScriptManager.GetLocalID(itemID); | ||
192 | return m_EventQueueManager.AddToScriptQueue(localID, itemID, p.EventName, p.DetectParams, p.Params); | ||
193 | } | ||
194 | |||
195 | public DetectParams GetDetectParams(UUID itemID, int number) | ||
196 | { | ||
197 | uint localID = m_ScriptManager.GetLocalID(itemID); | ||
198 | if (localID == 0) | ||
199 | return null; | ||
200 | |||
201 | IScript Script = m_ScriptManager.GetScript(localID, itemID); | ||
202 | |||
203 | if (Script == null) | ||
204 | return null; | ||
205 | |||
206 | DetectParams[] det = m_ScriptManager.GetDetectParams(Script); | ||
207 | |||
208 | if (number < 0 || number >= det.Length) | ||
209 | return null; | ||
210 | |||
211 | return det[number]; | ||
212 | } | ||
213 | |||
214 | public int GetStartParameter(UUID itemID) | ||
215 | { | ||
216 | return 0; | ||
217 | } | ||
218 | #endregion | ||
219 | |||
220 | public void SetState(UUID itemID, string state) | ||
221 | { | ||
222 | uint localID = m_ScriptManager.GetLocalID(itemID); | ||
223 | if (localID == 0) | ||
224 | return; | ||
225 | |||
226 | IScript Script = m_ScriptManager.GetScript(localID, itemID); | ||
227 | |||
228 | if (Script == null) | ||
229 | return; | ||
230 | |||
231 | string currentState = Script.State; | ||
232 | |||
233 | if (currentState != state) | ||
234 | { | ||
235 | try | ||
236 | { | ||
237 | m_EventManager.state_exit(localID); | ||
238 | |||
239 | } | ||
240 | catch (AppDomainUnloadedException) | ||
241 | { | ||
242 | Console.WriteLine("[SCRIPT]: state change called when script was unloaded. Nothing to worry about, but noting the occurance"); | ||
243 | } | ||
244 | |||
245 | Script.State = state; | ||
246 | |||
247 | try | ||
248 | { | ||
249 | int eventFlags = m_ScriptManager.GetStateEventFlags(localID, itemID); | ||
250 | SceneObjectPart part = m_Scene.GetSceneObjectPart(itemID); | ||
251 | if (part != null) | ||
252 | part.SetScriptEvents(itemID, eventFlags); | ||
253 | m_EventManager.state_entry(localID); | ||
254 | } | ||
255 | catch (AppDomainUnloadedException) | ||
256 | { | ||
257 | Console.WriteLine("[SCRIPT]: state change called when script was unloaded. Nothing to worry about, but noting the occurance"); | ||
258 | } | ||
259 | } | ||
260 | } | ||
261 | |||
262 | public bool GetScriptState(UUID itemID) | ||
263 | { | ||
264 | uint localID = m_ScriptManager.GetLocalID(itemID); | ||
265 | if (localID == 0) | ||
266 | return false; | ||
267 | |||
268 | IScript script = m_ScriptManager.GetScript(localID, itemID); | ||
269 | if (script == null) | ||
270 | return false; | ||
271 | |||
272 | return script.Exec.Running?true:false; | ||
273 | } | ||
274 | |||
275 | public void SetScriptState(UUID itemID, bool state) | ||
276 | { | ||
277 | uint localID = m_ScriptManager.GetLocalID(itemID); | ||
278 | if (localID == 0) | ||
279 | return; | ||
280 | |||
281 | IScript script = m_ScriptManager.GetScript(localID, itemID); | ||
282 | if (script == null) | ||
283 | return; | ||
284 | |||
285 | script.Exec.Running = state; | ||
286 | } | ||
287 | |||
288 | public void ApiResetScript(UUID itemID) | ||
289 | { | ||
290 | uint localID = m_ScriptManager.GetLocalID(itemID); | ||
291 | if (localID == 0) | ||
292 | return; | ||
293 | |||
294 | m_ScriptManager.ResetScript(localID, itemID); | ||
295 | } | ||
296 | |||
297 | public void ResetScript(UUID itemID) | ||
298 | { | ||
299 | uint localID = m_ScriptManager.GetLocalID(itemID); | ||
300 | if (localID == 0) | ||
301 | return; | ||
302 | |||
303 | m_ScriptManager.ResetScript(localID, itemID); | ||
304 | } | ||
53 | } | 305 | } |
54 | } | 306 | } |
diff --git a/OpenSim/Region/ScriptEngine/DotNetEngine/ScriptManager.cs b/OpenSim/Region/ScriptEngine/DotNetEngine/ScriptManager.cs index 8ff3bfd..12a8fe4 100644 --- a/OpenSim/Region/ScriptEngine/DotNetEngine/ScriptManager.cs +++ b/OpenSim/Region/ScriptEngine/DotNetEngine/ScriptManager.cs | |||
@@ -34,22 +34,66 @@ using OpenSim.Region.Environment.Scenes; | |||
34 | using OpenSim.Region.ScriptEngine.Common; | 34 | using OpenSim.Region.ScriptEngine.Common; |
35 | using OpenSim.Region.ScriptEngine.Shared; | 35 | using OpenSim.Region.ScriptEngine.Shared; |
36 | using OpenSim.Region.ScriptEngine.Shared.Api; | 36 | using OpenSim.Region.ScriptEngine.Shared.Api; |
37 | using OpenSim.Region.ScriptEngine.Common.ScriptEngineBase; | 37 | using System.Collections.Generic; |
38 | using System.IO; | ||
39 | using System.Runtime.Serialization.Formatters.Binary; | ||
40 | using System.Threading; | ||
38 | 41 | ||
39 | namespace OpenSim.Region.ScriptEngine.DotNetEngine | 42 | namespace OpenSim.Region.ScriptEngine.DotNetEngine |
40 | { | 43 | { |
41 | public class ScriptManager : Common.ScriptEngineBase.ScriptManager | 44 | public class ScriptManager |
42 | { | 45 | { |
43 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 46 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
44 | 47 | ||
45 | public ScriptManager(Common.ScriptEngineBase.ScriptEngine scriptEngine) | 48 | #region Declares |
46 | : base(scriptEngine) | 49 | |
50 | private Thread scriptLoadUnloadThread; | ||
51 | private static Thread staticScriptLoadUnloadThread; | ||
52 | // private int scriptLoadUnloadThread_IdleSleepms; | ||
53 | private Queue<LUStruct> LUQueue = new Queue<LUStruct>(); | ||
54 | private static bool PrivateThread; | ||
55 | private int LoadUnloadMaxQueueSize; | ||
56 | private Object scriptLock = new Object(); | ||
57 | private bool m_started = false; | ||
58 | private Dictionary<IScript, DetectParams[]> detparms = new Dictionary<IScript, DetectParams[]>(); | ||
59 | |||
60 | // Load/Unload structure | ||
61 | private struct LUStruct | ||
62 | { | ||
63 | public uint localID; | ||
64 | public UUID itemID; | ||
65 | public string script; | ||
66 | public LUType Action; | ||
67 | public int startParam; | ||
68 | public bool postOnRez; | ||
69 | } | ||
70 | |||
71 | private enum LUType | ||
72 | { | ||
73 | Unknown = 0, | ||
74 | Load = 1, | ||
75 | Unload = 2 | ||
76 | } | ||
77 | |||
78 | // Xantor 20080525: Keep a list of compiled scripts this session for reuse | ||
79 | public Dictionary<UUID, String> scriptList = new Dictionary<UUID, string>(); | ||
80 | |||
81 | // Object<string, Script<string, script>> | ||
82 | // IMPORTANT: Types and MemberInfo-derived objects require a LOT of memory. | ||
83 | // Instead use RuntimeTypeHandle, RuntimeFieldHandle and RunTimeHandle (IntPtr) instead! | ||
84 | public Dictionary<uint, Dictionary<UUID, IScript>> Scripts = | ||
85 | new Dictionary<uint, Dictionary<UUID, IScript>>(); | ||
86 | |||
87 | |||
88 | public Scene World | ||
47 | { | 89 | { |
48 | base.m_scriptEngine = scriptEngine; | 90 | get { return m_scriptEngine.World; } |
49 | } | 91 | } |
92 | |||
93 | #endregion | ||
50 | private Compiler.LSL.Compiler LSLCompiler; | 94 | private Compiler.LSL.Compiler LSLCompiler; |
51 | 95 | ||
52 | public override void Initialize() | 96 | public void Initialize() |
53 | { | 97 | { |
54 | // Create our compiler | 98 | // Create our compiler |
55 | LSLCompiler = new Compiler.LSL.Compiler(m_scriptEngine); | 99 | LSLCompiler = new Compiler.LSL.Compiler(m_scriptEngine); |
@@ -62,7 +106,7 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine | |||
62 | // PROVIDE SCRIPT WITH ITS INTERFACE TO OpenSim | 106 | // PROVIDE SCRIPT WITH ITS INTERFACE TO OpenSim |
63 | 107 | ||
64 | 108 | ||
65 | public override void _StartScript(uint localID, UUID itemID, string Script, int startParam, bool postOnRez) | 109 | public void _StartScript(uint localID, UUID itemID, string Script, int startParam, bool postOnRez) |
66 | { | 110 | { |
67 | m_log.DebugFormat( | 111 | m_log.DebugFormat( |
68 | "[{0}]: ScriptManager StartScript: localID: {1}, itemID: {2}", | 112 | "[{0}]: ScriptManager StartScript: localID: {1}, itemID: {2}", |
@@ -173,7 +217,7 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine | |||
173 | } | 217 | } |
174 | } | 218 | } |
175 | 219 | ||
176 | public override void _StopScript(uint localID, UUID itemID) | 220 | public void _StopScript(uint localID, UUID itemID) |
177 | { | 221 | { |
178 | IScript LSLBC = GetScript(localID, itemID); | 222 | IScript LSLBC = GetScript(localID, itemID); |
179 | if (LSLBC == null) | 223 | if (LSLBC == null) |
@@ -202,5 +246,405 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine | |||
202 | ": " + e.ToString()); | 246 | ": " + e.ToString()); |
203 | } | 247 | } |
204 | } | 248 | } |
249 | |||
250 | public void ReadConfig() | ||
251 | { | ||
252 | // scriptLoadUnloadThread_IdleSleepms = m_scriptEngine.ScriptConfigSource.GetInt("ScriptLoadUnloadLoopms", 30); | ||
253 | // TODO: Requires sharing of all ScriptManagers to single thread | ||
254 | PrivateThread = true; // m_scriptEngine.ScriptConfigSource.GetBoolean("PrivateScriptLoadUnloadThread", false); | ||
255 | LoadUnloadMaxQueueSize = m_scriptEngine.ScriptConfigSource.GetInt("LoadUnloadMaxQueueSize", 100); | ||
256 | } | ||
257 | |||
258 | #region Object init/shutdown | ||
259 | |||
260 | public ScriptEngine m_scriptEngine; | ||
261 | |||
262 | public ScriptManager(ScriptEngine scriptEngine) | ||
263 | { | ||
264 | m_scriptEngine = scriptEngine; | ||
265 | } | ||
266 | public void Setup() | ||
267 | { | ||
268 | ReadConfig(); | ||
269 | Initialize(); | ||
270 | } | ||
271 | public void Start() | ||
272 | { | ||
273 | m_started = true; | ||
274 | |||
275 | |||
276 | AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve); | ||
277 | |||
278 | // | ||
279 | // CREATE THREAD | ||
280 | // Private or shared | ||
281 | // | ||
282 | if (PrivateThread) | ||
283 | { | ||
284 | // Assign one thread per region | ||
285 | //scriptLoadUnloadThread = StartScriptLoadUnloadThread(); | ||
286 | } | ||
287 | else | ||
288 | { | ||
289 | // Shared thread - make sure one exist, then assign it to the private | ||
290 | if (staticScriptLoadUnloadThread == null) | ||
291 | { | ||
292 | //staticScriptLoadUnloadThread = StartScriptLoadUnloadThread(); | ||
293 | } | ||
294 | scriptLoadUnloadThread = staticScriptLoadUnloadThread; | ||
295 | } | ||
296 | } | ||
297 | |||
298 | // TODO: unused | ||
299 | // private static int privateThreadCount = 0; | ||
300 | // private Thread StartScriptLoadUnloadThread() | ||
301 | // { | ||
302 | // Thread t = new Thread(ScriptLoadUnloadThreadLoop); | ||
303 | // string name = "ScriptLoadUnloadThread:"; | ||
304 | // if (PrivateThread) | ||
305 | // { | ||
306 | // name += "Private:" + privateThreadCount; | ||
307 | // privateThreadCount++; | ||
308 | // } | ||
309 | // else | ||
310 | // { | ||
311 | // name += "Shared"; | ||
312 | // } | ||
313 | // t.Name = name; | ||
314 | // t.IsBackground = true; | ||
315 | // t.Priority = ThreadPriority.Normal; | ||
316 | // t.Start(); | ||
317 | // OpenSim.Framework.ThreadTracker.Add(t); | ||
318 | // return t; | ||
319 | // } | ||
320 | |||
321 | ~ScriptManager() | ||
322 | { | ||
323 | // Abort load/unload thread | ||
324 | try | ||
325 | { | ||
326 | //PleaseShutdown = true; | ||
327 | //Thread.Sleep(100); | ||
328 | if (scriptLoadUnloadThread != null && scriptLoadUnloadThread.IsAlive == true) | ||
329 | { | ||
330 | scriptLoadUnloadThread.Abort(); | ||
331 | //scriptLoadUnloadThread.Join(); | ||
332 | } | ||
333 | } | ||
334 | catch | ||
335 | { | ||
336 | } | ||
337 | } | ||
338 | |||
339 | #endregion | ||
340 | |||
341 | #region Load / Unload scripts (Thread loop) | ||
342 | |||
343 | // TODO: unused | ||
344 | // private void ScriptLoadUnloadThreadLoop() | ||
345 | // { | ||
346 | // try | ||
347 | // { | ||
348 | // while (true) | ||
349 | // { | ||
350 | // if (LUQueue.Count == 0) | ||
351 | // Thread.Sleep(scriptLoadUnloadThread_IdleSleepms); | ||
352 | // //if (PleaseShutdown) | ||
353 | // // return; | ||
354 | // DoScriptLoadUnload(); | ||
355 | // } | ||
356 | // } | ||
357 | // catch (ThreadAbortException tae) | ||
358 | // { | ||
359 | // string a = tae.ToString(); | ||
360 | // a = String.Empty; | ||
361 | // // Expected | ||
362 | // } | ||
363 | // } | ||
364 | |||
365 | public void DoScriptLoadUnload() | ||
366 | { | ||
367 | if (!m_started) | ||
368 | return; | ||
369 | |||
370 | lock (LUQueue) | ||
371 | { | ||
372 | if (LUQueue.Count > 0) | ||
373 | { | ||
374 | m_scriptEngine.Log.InfoFormat("[{0}]: Loading script", m_scriptEngine.ScriptEngineName); | ||
375 | LUStruct item = LUQueue.Dequeue(); | ||
376 | |||
377 | if (item.Action == LUType.Unload) | ||
378 | { | ||
379 | _StopScript(item.localID, item.itemID); | ||
380 | RemoveScript(item.localID, item.itemID); | ||
381 | } | ||
382 | else if (item.Action == LUType.Load) | ||
383 | { | ||
384 | _StartScript(item.localID, item.itemID, item.script, item.startParam, item.postOnRez); | ||
385 | } | ||
386 | } | ||
387 | } | ||
388 | } | ||
389 | |||
390 | #endregion | ||
391 | |||
392 | #region Helper functions | ||
393 | |||
394 | private static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args) | ||
395 | { | ||
396 | //Console.WriteLine("ScriptManager.CurrentDomain_AssemblyResolve: " + args.Name); | ||
397 | return Assembly.GetExecutingAssembly().FullName == args.Name ? Assembly.GetExecutingAssembly() : null; | ||
398 | } | ||
399 | |||
400 | #endregion | ||
401 | |||
402 | |||
403 | |||
404 | #region Start/Stop/Reset script | ||
405 | |||
406 | // private readonly Object startStopLock = new Object(); | ||
407 | |||
408 | /// <summary> | ||
409 | /// Fetches, loads and hooks up a script to an objects events | ||
410 | /// </summary> | ||
411 | /// <param name="itemID"></param> | ||
412 | /// <param name="localID"></param> | ||
413 | public void StartScript(uint localID, UUID itemID, string Script, int startParam, bool postOnRez) | ||
414 | { | ||
415 | lock (LUQueue) | ||
416 | { | ||
417 | if ((LUQueue.Count >= LoadUnloadMaxQueueSize) && m_started) | ||
418 | { | ||
419 | m_scriptEngine.Log.Error("[" + m_scriptEngine.ScriptEngineName + "]: ERROR: Load/unload queue item count is at " + LUQueue.Count + ". Config variable \"LoadUnloadMaxQueueSize\" is set to " + LoadUnloadMaxQueueSize + ", so ignoring new script."); | ||
420 | return; | ||
421 | } | ||
422 | |||
423 | LUStruct ls = new LUStruct(); | ||
424 | ls.localID = localID; | ||
425 | ls.itemID = itemID; | ||
426 | ls.script = Script; | ||
427 | ls.Action = LUType.Load; | ||
428 | ls.startParam = startParam; | ||
429 | ls.postOnRez = postOnRez; | ||
430 | LUQueue.Enqueue(ls); | ||
431 | m_scriptEngine.Log.InfoFormat("[{0}]: Queued script for load", m_scriptEngine.ScriptEngineName); | ||
432 | } | ||
433 | } | ||
434 | |||
435 | /// <summary> | ||
436 | /// Disables and unloads a script | ||
437 | /// </summary> | ||
438 | /// <param name="localID"></param> | ||
439 | /// <param name="itemID"></param> | ||
440 | public void StopScript(uint localID, UUID itemID) | ||
441 | { | ||
442 | LUStruct ls = new LUStruct(); | ||
443 | ls.localID = localID; | ||
444 | ls.itemID = itemID; | ||
445 | ls.Action = LUType.Unload; | ||
446 | ls.startParam = 0; | ||
447 | ls.postOnRez = false; | ||
448 | lock (LUQueue) | ||
449 | { | ||
450 | LUQueue.Enqueue(ls); | ||
451 | } | ||
452 | } | ||
453 | |||
454 | // Create a new instance of the compiler (reuse) | ||
455 | //private Compiler.LSL.Compiler LSLCompiler = new Compiler.LSL.Compiler(); | ||
456 | |||
457 | |||
458 | #endregion | ||
459 | |||
460 | #region Perform event execution in script | ||
461 | |||
462 | /// <summary> | ||
463 | /// Execute a LL-event-function in Script | ||
464 | /// </summary> | ||
465 | /// <param name="localID">Object the script is located in</param> | ||
466 | /// <param name="itemID">Script ID</param> | ||
467 | /// <param name="FunctionName">Name of function</param> | ||
468 | /// <param name="args">Arguments to pass to function</param> | ||
469 | internal void ExecuteEvent(uint localID, UUID itemID, string FunctionName, DetectParams[] qParams, object[] args) | ||
470 | { | ||
471 | //cfk 2-7-08 dont need this right now and the default Linux build has DEBUG defined | ||
472 | ///#if DEBUG | ||
473 | /// Console.WriteLine("ScriptEngine: Inside ExecuteEvent for event " + FunctionName); | ||
474 | ///#endif | ||
475 | // Execute a function in the script | ||
476 | //m_scriptEngine.Log.Info("[" + ScriptEngineName + "]: Executing Function localID: " + localID + ", itemID: " + itemID + ", FunctionName: " + FunctionName); | ||
477 | //ScriptBaseInterface Script = (ScriptBaseInterface)GetScript(localID, itemID); | ||
478 | IScript Script = GetScript(localID, itemID); | ||
479 | if (Script == null) | ||
480 | { | ||
481 | return; | ||
482 | } | ||
483 | //cfk 2-7-08 dont need this right now and the default Linux build has DEBUG defined | ||
484 | ///#if DEBUG | ||
485 | /// Console.WriteLine("ScriptEngine: Executing event: " + FunctionName); | ||
486 | ///#endif | ||
487 | // Must be done in correct AppDomain, so leaving it up to the script itself | ||
488 | detparms[Script] = qParams; | ||
489 | Script.Exec.ExecuteEvent(FunctionName, args); | ||
490 | detparms.Remove(Script); | ||
491 | } | ||
492 | |||
493 | public uint GetLocalID(UUID itemID) | ||
494 | { | ||
495 | foreach (KeyValuePair<uint, Dictionary<UUID, IScript> > k in Scripts) | ||
496 | { | ||
497 | if (k.Value.ContainsKey(itemID)) | ||
498 | return k.Key; | ||
499 | } | ||
500 | return 0; | ||
501 | } | ||
502 | |||
503 | public int GetStateEventFlags(uint localID, UUID itemID) | ||
504 | { | ||
505 | // Console.WriteLine("GetStateEventFlags for <" + localID + "," + itemID + ">"); | ||
506 | try | ||
507 | { | ||
508 | IScript Script = GetScript(localID, itemID); | ||
509 | if (Script == null) | ||
510 | { | ||
511 | return 0; | ||
512 | } | ||
513 | ExecutorBase.scriptEvents evflags = Script.Exec.GetStateEventFlags(); | ||
514 | return (int)evflags; | ||
515 | } | ||
516 | catch (Exception) | ||
517 | { | ||
518 | } | ||
519 | |||
520 | return 0; | ||
521 | } | ||
522 | |||
523 | |||
524 | #endregion | ||
525 | |||
526 | #region Internal functions to keep track of script | ||
527 | |||
528 | public List<UUID> GetScriptKeys(uint localID) | ||
529 | { | ||
530 | if (Scripts.ContainsKey(localID) == false) | ||
531 | return new List<UUID>(); | ||
532 | |||
533 | Dictionary<UUID, IScript> Obj; | ||
534 | Scripts.TryGetValue(localID, out Obj); | ||
535 | |||
536 | return new List<UUID>(Obj.Keys); | ||
537 | } | ||
538 | |||
539 | public IScript GetScript(uint localID, UUID itemID) | ||
540 | { | ||
541 | lock (scriptLock) | ||
542 | { | ||
543 | IScript Script = null; | ||
544 | |||
545 | if (Scripts.ContainsKey(localID) == false) | ||
546 | return null; | ||
547 | |||
548 | Dictionary<UUID, IScript> Obj; | ||
549 | Scripts.TryGetValue(localID, out Obj); | ||
550 | if (Obj.ContainsKey(itemID) == false) | ||
551 | return null; | ||
552 | |||
553 | // Get script | ||
554 | Obj.TryGetValue(itemID, out Script); | ||
555 | return Script; | ||
556 | } | ||
557 | } | ||
558 | |||
559 | public void SetScript(uint localID, UUID itemID, IScript Script) | ||
560 | { | ||
561 | lock (scriptLock) | ||
562 | { | ||
563 | // Create object if it doesn't exist | ||
564 | if (Scripts.ContainsKey(localID) == false) | ||
565 | { | ||
566 | Scripts.Add(localID, new Dictionary<UUID, IScript>()); | ||
567 | } | ||
568 | |||
569 | // Delete script if it exists | ||
570 | Dictionary<UUID, IScript> Obj; | ||
571 | Scripts.TryGetValue(localID, out Obj); | ||
572 | if (Obj.ContainsKey(itemID) == true) | ||
573 | Obj.Remove(itemID); | ||
574 | |||
575 | // Add to object | ||
576 | Obj.Add(itemID, Script); | ||
577 | } | ||
578 | } | ||
579 | |||
580 | public void RemoveScript(uint localID, UUID itemID) | ||
581 | { | ||
582 | if (localID == 0) | ||
583 | localID = GetLocalID(itemID); | ||
584 | |||
585 | // Don't have that object? | ||
586 | if (Scripts.ContainsKey(localID) == false) | ||
587 | return; | ||
588 | |||
589 | // Delete script if it exists | ||
590 | Dictionary<UUID, IScript> Obj; | ||
591 | Scripts.TryGetValue(localID, out Obj); | ||
592 | if (Obj.ContainsKey(itemID) == true) | ||
593 | Obj.Remove(itemID); | ||
594 | } | ||
595 | |||
596 | #endregion | ||
597 | |||
598 | |||
599 | public void ResetScript(uint localID, UUID itemID) | ||
600 | { | ||
601 | IScript s = GetScript(localID, itemID); | ||
602 | string script = s.Source; | ||
603 | StopScript(localID, itemID); | ||
604 | SceneObjectPart part = World.GetSceneObjectPart(localID); | ||
605 | part.GetInventoryItem(itemID).PermsMask = 0; | ||
606 | part.GetInventoryItem(itemID).PermsGranter = UUID.Zero; | ||
607 | StartScript(localID, itemID, script, s.StartParam, false); | ||
608 | } | ||
609 | |||
610 | |||
611 | #region Script serialization/deserialization | ||
612 | |||
613 | public void GetSerializedScript(uint localID, UUID itemID) | ||
614 | { | ||
615 | // Serialize the script and return it | ||
616 | // Should not be a problem | ||
617 | FileStream fs = File.Create("SERIALIZED_SCRIPT_" + itemID); | ||
618 | BinaryFormatter b = new BinaryFormatter(); | ||
619 | b.Serialize(fs, GetScript(localID, itemID)); | ||
620 | fs.Close(); | ||
621 | } | ||
622 | |||
623 | public void PutSerializedScript(uint localID, UUID itemID) | ||
624 | { | ||
625 | // Deserialize the script and inject it into an AppDomain | ||
626 | |||
627 | // How to inject into an AppDomain? | ||
628 | } | ||
629 | |||
630 | #endregion | ||
631 | |||
632 | ///// <summary> | ||
633 | ///// If set to true then threads and stuff should try to make a graceful exit | ||
634 | ///// </summary> | ||
635 | //public bool PleaseShutdown | ||
636 | //{ | ||
637 | // get { return _PleaseShutdown; } | ||
638 | // set { _PleaseShutdown = value; } | ||
639 | //} | ||
640 | //private bool _PleaseShutdown = false; | ||
641 | |||
642 | public DetectParams[] GetDetectParams(IScript script) | ||
643 | { | ||
644 | if (detparms.ContainsKey(script)) | ||
645 | return detparms[script]; | ||
646 | |||
647 | return null; | ||
648 | } | ||
205 | } | 649 | } |
206 | } | 650 | } |