diff options
author | Melanie Thielker | 2008-09-26 13:16:11 +0000 |
---|---|---|
committer | Melanie Thielker | 2008-09-26 13:16:11 +0000 |
commit | 824283ca3c2ab54868ed61fdb0a329221d69e5fa (patch) | |
tree | 9013892fa2afa579bffe8bdcd6a46e2242ed085c /OpenSim/Region/ScriptEngine | |
parent | * Wind updates. Still random.. but in 4 directions instead of two! (diff) | |
download | opensim-SC-824283ca3c2ab54868ed61fdb0a329221d69e5fa.zip opensim-SC-824283ca3c2ab54868ed61fdb0a329221d69e5fa.tar.gz opensim-SC-824283ca3c2ab54868ed61fdb0a329221d69e5fa.tar.bz2 opensim-SC-824283ca3c2ab54868ed61fdb0a329221d69e5fa.tar.xz |
Remove all the subclassing complexity and script server interfaces from
DNE and move all of DNE into the DotNetEngine directory. Remove references
that would cause the script runtime to load the entire engine + scene into
each script appdomain. This might help DNE memory consumption.
Diffstat (limited to '')
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 | } |