diff options
Diffstat (limited to 'OpenSim/Region/ScriptEngine/DotNetEngine/ScriptManager.cs')
-rw-r--r-- | OpenSim/Region/ScriptEngine/DotNetEngine/ScriptManager.cs | 703 |
1 files changed, 0 insertions, 703 deletions
diff --git a/OpenSim/Region/ScriptEngine/DotNetEngine/ScriptManager.cs b/OpenSim/Region/ScriptEngine/DotNetEngine/ScriptManager.cs deleted file mode 100644 index 6ac209e..0000000 --- a/OpenSim/Region/ScriptEngine/DotNetEngine/ScriptManager.cs +++ /dev/null | |||
@@ -1,703 +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 OpenSimulator 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.Reflection; | ||
30 | using System.Globalization; | ||
31 | using System.Runtime.Remoting; | ||
32 | using System.Runtime.Remoting.Lifetime; | ||
33 | using log4net; | ||
34 | using OpenMetaverse; | ||
35 | using OpenSim.Framework; | ||
36 | using OpenSim.Region.Framework.Scenes; | ||
37 | using OpenSim.Region.ScriptEngine.Interfaces; | ||
38 | using OpenSim.Region.ScriptEngine.Shared; | ||
39 | using OpenSim.Region.ScriptEngine.Shared.Api; | ||
40 | using System.Collections.Generic; | ||
41 | using System.IO; | ||
42 | using System.Runtime.Serialization.Formatters.Binary; | ||
43 | using System.Threading; | ||
44 | using OpenSim.Region.ScriptEngine.Shared.Api.Runtime; | ||
45 | using OpenSim.Region.ScriptEngine.Shared.ScriptBase; | ||
46 | using OpenSim.Region.ScriptEngine.Shared.CodeTools; | ||
47 | |||
48 | namespace OpenSim.Region.ScriptEngine.DotNetEngine | ||
49 | { | ||
50 | public class InstanceData | ||
51 | { | ||
52 | public IScript Script; | ||
53 | public string State; | ||
54 | public bool Running; | ||
55 | public bool Disabled; | ||
56 | public string Source; | ||
57 | public int StartParam; | ||
58 | public AppDomain AppDomain; | ||
59 | public Dictionary<string, IScriptApi> Apis; | ||
60 | public Dictionary<KeyValuePair<int,int>, KeyValuePair<int,int>> | ||
61 | LineMap; | ||
62 | // public ISponsor ScriptSponsor; | ||
63 | } | ||
64 | |||
65 | public class ScriptManager | ||
66 | { | ||
67 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||
68 | |||
69 | #region Declares | ||
70 | |||
71 | private Thread scriptLoadUnloadThread; | ||
72 | private static Thread staticScriptLoadUnloadThread = null; | ||
73 | private Queue<LUStruct> LUQueue = new Queue<LUStruct>(); | ||
74 | private static bool PrivateThread; | ||
75 | private int LoadUnloadMaxQueueSize; | ||
76 | private Object scriptLock = new Object(); | ||
77 | private bool m_started = false; | ||
78 | private Dictionary<InstanceData, DetectParams[]> detparms = | ||
79 | new Dictionary<InstanceData, DetectParams[]>(); | ||
80 | |||
81 | // Load/Unload structure | ||
82 | private struct LUStruct | ||
83 | { | ||
84 | public uint localID; | ||
85 | public UUID itemID; | ||
86 | public string script; | ||
87 | public LUType Action; | ||
88 | public int startParam; | ||
89 | public bool postOnRez; | ||
90 | } | ||
91 | |||
92 | private enum LUType | ||
93 | { | ||
94 | Unknown = 0, | ||
95 | Load = 1, | ||
96 | Unload = 2 | ||
97 | } | ||
98 | |||
99 | public Dictionary<uint, Dictionary<UUID, InstanceData>> Scripts = | ||
100 | new Dictionary<uint, Dictionary<UUID, InstanceData>>(); | ||
101 | |||
102 | private Compiler LSLCompiler; | ||
103 | |||
104 | public Scene World | ||
105 | { | ||
106 | get { return m_scriptEngine.World; } | ||
107 | } | ||
108 | |||
109 | #endregion | ||
110 | |||
111 | public void Initialize() | ||
112 | { | ||
113 | // Create our compiler | ||
114 | LSLCompiler = new Compiler(m_scriptEngine); | ||
115 | } | ||
116 | |||
117 | public void _StartScript(uint localID, UUID itemID, string Script, | ||
118 | int startParam, bool postOnRez) | ||
119 | { | ||
120 | m_log.DebugFormat( | ||
121 | "[{0}]: ScriptManager StartScript: localID: {1}, itemID: {2}", | ||
122 | m_scriptEngine.ScriptEngineName, localID, itemID); | ||
123 | |||
124 | // We will initialize and start the script. | ||
125 | // It will be up to the script itself to hook up the correct events. | ||
126 | string CompiledScriptFile = String.Empty; | ||
127 | |||
128 | SceneObjectPart m_host = World.GetSceneObjectPart(localID); | ||
129 | |||
130 | if (null == m_host) | ||
131 | { | ||
132 | m_log.ErrorFormat( | ||
133 | "[{0}]: Could not find scene object part corresponding "+ | ||
134 | "to localID {1} to start script", | ||
135 | m_scriptEngine.ScriptEngineName, localID); | ||
136 | |||
137 | return; | ||
138 | } | ||
139 | |||
140 | UUID assetID = UUID.Zero; | ||
141 | TaskInventoryItem taskInventoryItem = new TaskInventoryItem(); | ||
142 | if (m_host.TaskInventory.TryGetValue(itemID, out taskInventoryItem)) | ||
143 | assetID = taskInventoryItem.AssetID; | ||
144 | |||
145 | ScenePresence presence = | ||
146 | World.GetScenePresence(taskInventoryItem.OwnerID); | ||
147 | |||
148 | CultureInfo USCulture = new CultureInfo("en-US"); | ||
149 | Thread.CurrentThread.CurrentCulture = USCulture; | ||
150 | |||
151 | try | ||
152 | { | ||
153 | // Compile (We assume LSL) | ||
154 | CompiledScriptFile = | ||
155 | (string)LSLCompiler.PerformScriptCompile(Script, | ||
156 | assetID.ToString(), taskInventoryItem.OwnerID); | ||
157 | |||
158 | if (presence != null && (!postOnRez)) | ||
159 | presence.ControllingClient.SendAgentAlertMessage( | ||
160 | "Compile successful", false); | ||
161 | |||
162 | m_log.InfoFormat("[SCRIPT]: Compiled assetID {0}: {1}", | ||
163 | assetID, CompiledScriptFile); | ||
164 | |||
165 | InstanceData id = new InstanceData(); | ||
166 | |||
167 | IScript CompiledScript; | ||
168 | CompiledScript = | ||
169 | m_scriptEngine.m_AppDomainManager.LoadScript( | ||
170 | CompiledScriptFile, out id.AppDomain); | ||
171 | //Register the sponsor | ||
172 | // ISponsor scriptSponsor = new ScriptSponsor(); | ||
173 | // ILease lease = (ILease)RemotingServices.GetLifetimeService(CompiledScript as MarshalByRefObject); | ||
174 | // lease.Register(scriptSponsor); | ||
175 | // id.ScriptSponsor = scriptSponsor; | ||
176 | |||
177 | id.LineMap = LSLCompiler.LineMap(); | ||
178 | id.Script = CompiledScript; | ||
179 | id.Source = Script; | ||
180 | id.StartParam = startParam; | ||
181 | id.State = "default"; | ||
182 | id.Running = true; | ||
183 | id.Disabled = false; | ||
184 | |||
185 | // Add it to our script memstruct | ||
186 | m_scriptEngine.m_ScriptManager.SetScript(localID, itemID, id); | ||
187 | |||
188 | id.Apis = new Dictionary<string, IScriptApi>(); | ||
189 | |||
190 | ApiManager am = new ApiManager(); | ||
191 | |||
192 | foreach (string api in am.GetApis()) | ||
193 | { | ||
194 | id.Apis[api] = am.CreateApi(api); | ||
195 | id.Apis[api].Initialize(m_scriptEngine, m_host, | ||
196 | localID, itemID); | ||
197 | } | ||
198 | |||
199 | foreach (KeyValuePair<string,IScriptApi> kv in id.Apis) | ||
200 | { | ||
201 | CompiledScript.InitApi(kv.Key, kv.Value); | ||
202 | } | ||
203 | |||
204 | // Fire the first start-event | ||
205 | int eventFlags = | ||
206 | m_scriptEngine.m_ScriptManager.GetStateEventFlags( | ||
207 | localID, itemID); | ||
208 | |||
209 | m_host.SetScriptEvents(itemID, eventFlags); | ||
210 | |||
211 | m_scriptEngine.m_EventQueueManager.AddToScriptQueue( | ||
212 | localID, itemID, "state_entry", new DetectParams[0], | ||
213 | new object[] { }); | ||
214 | |||
215 | if (postOnRez) | ||
216 | { | ||
217 | m_scriptEngine.m_EventQueueManager.AddToScriptQueue( | ||
218 | localID, itemID, "on_rez", new DetectParams[0], | ||
219 | new object[] { new LSL_Types.LSLInteger(startParam) }); | ||
220 | } | ||
221 | |||
222 | string[] warnings = LSLCompiler.GetWarnings(); | ||
223 | |||
224 | if (warnings != null && warnings.Length != 0) | ||
225 | { | ||
226 | if (presence != null && (!postOnRez)) | ||
227 | presence.ControllingClient.SendAgentAlertMessage( | ||
228 | "Script saved with warnings, check debug window!", | ||
229 | false); | ||
230 | |||
231 | foreach (string warning in warnings) | ||
232 | { | ||
233 | try | ||
234 | { | ||
235 | // DISPLAY WARNING INWORLD | ||
236 | string text = "Warning:\n" + warning; | ||
237 | if (text.Length > 1100) | ||
238 | text = text.Substring(0, 1099); | ||
239 | |||
240 | World.SimChat(Utils.StringToBytes(text), | ||
241 | ChatTypeEnum.DebugChannel, 2147483647, | ||
242 | m_host.AbsolutePosition, m_host.Name, m_host.UUID, | ||
243 | false); | ||
244 | } | ||
245 | catch (Exception e2) // LEGIT: User Scripting | ||
246 | { | ||
247 | m_log.Error("[" + | ||
248 | m_scriptEngine.ScriptEngineName + | ||
249 | "]: Error displaying warning in-world: " + | ||
250 | e2.ToString()); | ||
251 | m_log.Error("[" + | ||
252 | m_scriptEngine.ScriptEngineName + "]: " + | ||
253 | "Warning:\r\n" + | ||
254 | warning); | ||
255 | } | ||
256 | } | ||
257 | } | ||
258 | } | ||
259 | catch (Exception e) // LEGIT: User Scripting | ||
260 | { | ||
261 | if (presence != null && (!postOnRez)) | ||
262 | presence.ControllingClient.SendAgentAlertMessage( | ||
263 | "Script saved with errors, check debug window!", | ||
264 | false); | ||
265 | try | ||
266 | { | ||
267 | // DISPLAY ERROR INWORLD | ||
268 | string text = "Error compiling script:\n" + | ||
269 | e.Message.ToString(); | ||
270 | if (text.Length > 1100) | ||
271 | text = text.Substring(0, 1099); | ||
272 | |||
273 | World.SimChat(Utils.StringToBytes(text), | ||
274 | ChatTypeEnum.DebugChannel, 2147483647, | ||
275 | m_host.AbsolutePosition, m_host.Name, m_host.UUID, | ||
276 | false); | ||
277 | } | ||
278 | catch (Exception e2) // LEGIT: User Scripting | ||
279 | { | ||
280 | m_log.Error("[" + | ||
281 | m_scriptEngine.ScriptEngineName + | ||
282 | "]: Error displaying error in-world: " + | ||
283 | e2.ToString()); | ||
284 | m_log.Error("[" + | ||
285 | m_scriptEngine.ScriptEngineName + "]: " + | ||
286 | "Errormessage: Error compiling script:\r\n" + | ||
287 | e2.Message.ToString()); | ||
288 | } | ||
289 | } | ||
290 | } | ||
291 | |||
292 | public void _StopScript(uint localID, UUID itemID) | ||
293 | { | ||
294 | InstanceData id = GetScript(localID, itemID); | ||
295 | if (id == null) | ||
296 | return; | ||
297 | |||
298 | m_log.DebugFormat("[{0}]: Unloading script", | ||
299 | m_scriptEngine.ScriptEngineName); | ||
300 | |||
301 | // Stop long command on script | ||
302 | AsyncCommandManager.RemoveScript(m_scriptEngine, localID, itemID); | ||
303 | |||
304 | try | ||
305 | { | ||
306 | // Get AppDomain | ||
307 | // Tell script not to accept new requests | ||
308 | id.Running = false; | ||
309 | id.Disabled = true; | ||
310 | AppDomain ad = id.AppDomain; | ||
311 | |||
312 | // Remove from internal structure | ||
313 | RemoveScript(localID, itemID); | ||
314 | |||
315 | // Tell AppDomain that we have stopped script | ||
316 | m_scriptEngine.m_AppDomainManager.StopScript(ad); | ||
317 | } | ||
318 | catch (Exception e) // LEGIT: User Scripting | ||
319 | { | ||
320 | m_log.Error("[" + | ||
321 | m_scriptEngine.ScriptEngineName + | ||
322 | "]: Exception stopping script localID: " + | ||
323 | localID + " LLUID: " + itemID.ToString() + | ||
324 | ": " + e.ToString()); | ||
325 | } | ||
326 | } | ||
327 | |||
328 | public void ReadConfig() | ||
329 | { | ||
330 | // TODO: Requires sharing of all ScriptManagers to single thread | ||
331 | PrivateThread = true; | ||
332 | LoadUnloadMaxQueueSize = m_scriptEngine.ScriptConfigSource.GetInt( | ||
333 | "LoadUnloadMaxQueueSize", 100); | ||
334 | } | ||
335 | |||
336 | #region Object init/shutdown | ||
337 | |||
338 | public ScriptEngine m_scriptEngine; | ||
339 | |||
340 | public ScriptManager(ScriptEngine scriptEngine) | ||
341 | { | ||
342 | m_scriptEngine = scriptEngine; | ||
343 | } | ||
344 | |||
345 | public void Setup() | ||
346 | { | ||
347 | ReadConfig(); | ||
348 | Initialize(); | ||
349 | } | ||
350 | |||
351 | public void Start() | ||
352 | { | ||
353 | m_started = true; | ||
354 | |||
355 | |||
356 | AppDomain.CurrentDomain.AssemblyResolve += | ||
357 | new ResolveEventHandler(CurrentDomain_AssemblyResolve); | ||
358 | |||
359 | // | ||
360 | // CREATE THREAD | ||
361 | // Private or shared | ||
362 | // | ||
363 | if (PrivateThread) | ||
364 | { | ||
365 | // Assign one thread per region | ||
366 | //scriptLoadUnloadThread = StartScriptLoadUnloadThread(); | ||
367 | } | ||
368 | else | ||
369 | { | ||
370 | // Shared thread - make sure one exist, then assign it to the private | ||
371 | if (staticScriptLoadUnloadThread == null) | ||
372 | { | ||
373 | //staticScriptLoadUnloadThread = | ||
374 | // StartScriptLoadUnloadThread(); | ||
375 | } | ||
376 | scriptLoadUnloadThread = staticScriptLoadUnloadThread; | ||
377 | } | ||
378 | } | ||
379 | |||
380 | ~ScriptManager() | ||
381 | { | ||
382 | // Abort load/unload thread | ||
383 | try | ||
384 | { | ||
385 | if (scriptLoadUnloadThread != null && | ||
386 | scriptLoadUnloadThread.IsAlive == true) | ||
387 | { | ||
388 | scriptLoadUnloadThread.Abort(); | ||
389 | //scriptLoadUnloadThread.Join(); | ||
390 | } | ||
391 | } | ||
392 | catch | ||
393 | { | ||
394 | } | ||
395 | } | ||
396 | |||
397 | #endregion | ||
398 | |||
399 | #region Load / Unload scripts (Thread loop) | ||
400 | |||
401 | public void DoScriptLoadUnload() | ||
402 | { | ||
403 | if (!m_started) | ||
404 | return; | ||
405 | |||
406 | lock (LUQueue) | ||
407 | { | ||
408 | if (LUQueue.Count > 0) | ||
409 | { | ||
410 | LUStruct item = LUQueue.Dequeue(); | ||
411 | |||
412 | if (item.Action == LUType.Unload) | ||
413 | { | ||
414 | _StopScript(item.localID, item.itemID); | ||
415 | RemoveScript(item.localID, item.itemID); | ||
416 | } | ||
417 | else if (item.Action == LUType.Load) | ||
418 | { | ||
419 | m_log.DebugFormat("[{0}]: Loading script", | ||
420 | m_scriptEngine.ScriptEngineName); | ||
421 | _StartScript(item.localID, item.itemID, item.script, | ||
422 | item.startParam, item.postOnRez); | ||
423 | } | ||
424 | } | ||
425 | } | ||
426 | } | ||
427 | |||
428 | #endregion | ||
429 | |||
430 | #region Helper functions | ||
431 | |||
432 | private static Assembly CurrentDomain_AssemblyResolve( | ||
433 | object sender, ResolveEventArgs args) | ||
434 | { | ||
435 | return Assembly.GetExecutingAssembly().FullName == args.Name ? | ||
436 | Assembly.GetExecutingAssembly() : null; | ||
437 | } | ||
438 | |||
439 | #endregion | ||
440 | |||
441 | #region Start/Stop/Reset script | ||
442 | |||
443 | /// <summary> | ||
444 | /// Fetches, loads and hooks up a script to an objects events | ||
445 | /// </summary> | ||
446 | /// <param name="itemID"></param> | ||
447 | /// <param name="localID"></param> | ||
448 | public void StartScript(uint localID, UUID itemID, string Script, int startParam, bool postOnRez) | ||
449 | { | ||
450 | lock (LUQueue) | ||
451 | { | ||
452 | if ((LUQueue.Count >= LoadUnloadMaxQueueSize) && m_started) | ||
453 | { | ||
454 | m_log.Error("[" + | ||
455 | m_scriptEngine.ScriptEngineName + | ||
456 | "]: ERROR: Load/unload queue item count is at " + | ||
457 | LUQueue.Count + | ||
458 | ". Config variable \"LoadUnloadMaxQueueSize\" "+ | ||
459 | "is set to " + LoadUnloadMaxQueueSize + | ||
460 | ", so ignoring new script."); | ||
461 | |||
462 | return; | ||
463 | } | ||
464 | |||
465 | LUStruct ls = new LUStruct(); | ||
466 | ls.localID = localID; | ||
467 | ls.itemID = itemID; | ||
468 | ls.script = Script; | ||
469 | ls.Action = LUType.Load; | ||
470 | ls.startParam = startParam; | ||
471 | ls.postOnRez = postOnRez; | ||
472 | LUQueue.Enqueue(ls); | ||
473 | } | ||
474 | } | ||
475 | |||
476 | /// <summary> | ||
477 | /// Disables and unloads a script | ||
478 | /// </summary> | ||
479 | /// <param name="localID"></param> | ||
480 | /// <param name="itemID"></param> | ||
481 | public void StopScript(uint localID, UUID itemID) | ||
482 | { | ||
483 | LUStruct ls = new LUStruct(); | ||
484 | ls.localID = localID; | ||
485 | ls.itemID = itemID; | ||
486 | ls.Action = LUType.Unload; | ||
487 | ls.startParam = 0; | ||
488 | ls.postOnRez = false; | ||
489 | lock (LUQueue) | ||
490 | { | ||
491 | LUQueue.Enqueue(ls); | ||
492 | } | ||
493 | } | ||
494 | |||
495 | #endregion | ||
496 | |||
497 | #region Perform event execution in script | ||
498 | |||
499 | // Execute a LL-event-function in Script | ||
500 | internal void ExecuteEvent(uint localID, UUID itemID, | ||
501 | string FunctionName, DetectParams[] qParams, object[] args) | ||
502 | { | ||
503 | int ExeStage=0; // ;^) Ewe Loon, for debuging | ||
504 | InstanceData id=null; | ||
505 | try // ;^) Ewe Loon,fix | ||
506 | { // ;^) Ewe Loon,fix | ||
507 | ExeStage = 1; // ;^) Ewe Loon, for debuging | ||
508 | id = GetScript(localID, itemID); | ||
509 | if (id == null) | ||
510 | return; | ||
511 | ExeStage = 2; // ;^) Ewe Loon, for debuging | ||
512 | if (qParams.Length>0) // ;^) Ewe Loon,fix | ||
513 | detparms[id] = qParams; | ||
514 | ExeStage = 3; // ;^) Ewe Loon, for debuging | ||
515 | if (id.Running) | ||
516 | id.Script.ExecuteEvent(id.State, FunctionName, args); | ||
517 | ExeStage = 4; // ;^) Ewe Loon, for debuging | ||
518 | if (qParams.Length>0) // ;^) Ewe Loon,fix | ||
519 | detparms.Remove(id); | ||
520 | ExeStage = 5; // ;^) Ewe Loon, for debuging | ||
521 | } | ||
522 | catch (Exception e) // ;^) Ewe Loon, From here down tis fix | ||
523 | { | ||
524 | if ((ExeStage == 3)&&(qParams.Length>0)) | ||
525 | detparms.Remove(id); | ||
526 | SceneObjectPart ob = m_scriptEngine.World.GetSceneObjectPart(localID); | ||
527 | m_log.InfoFormat("[Script Error] ,{0},{1},@{2},{3},{4},{5}", ob.Name , FunctionName, ExeStage, e.Message, qParams.Length, detparms.Count); | ||
528 | if (ExeStage != 2) throw e; | ||
529 | } | ||
530 | } | ||
531 | |||
532 | public uint GetLocalID(UUID itemID) | ||
533 | { | ||
534 | foreach (KeyValuePair<uint, Dictionary<UUID, InstanceData> > k | ||
535 | in Scripts) | ||
536 | { | ||
537 | if (k.Value.ContainsKey(itemID)) | ||
538 | return k.Key; | ||
539 | } | ||
540 | return 0; | ||
541 | } | ||
542 | |||
543 | public int GetStateEventFlags(uint localID, UUID itemID) | ||
544 | { | ||
545 | try | ||
546 | { | ||
547 | InstanceData id = GetScript(localID, itemID); | ||
548 | if (id == null) | ||
549 | { | ||
550 | return 0; | ||
551 | } | ||
552 | int evflags = id.Script.GetStateEventFlags(id.State); | ||
553 | |||
554 | return (int)evflags; | ||
555 | } | ||
556 | catch (Exception) | ||
557 | { | ||
558 | } | ||
559 | |||
560 | return 0; | ||
561 | } | ||
562 | |||
563 | #endregion | ||
564 | |||
565 | #region Internal functions to keep track of script | ||
566 | |||
567 | public List<UUID> GetScriptKeys(uint localID) | ||
568 | { | ||
569 | if (Scripts.ContainsKey(localID) == false) | ||
570 | return new List<UUID>(); | ||
571 | |||
572 | Dictionary<UUID, InstanceData> Obj; | ||
573 | Scripts.TryGetValue(localID, out Obj); | ||
574 | |||
575 | return new List<UUID>(Obj.Keys); | ||
576 | } | ||
577 | |||
578 | public InstanceData GetScript(uint localID, UUID itemID) | ||
579 | { | ||
580 | lock (scriptLock) | ||
581 | { | ||
582 | InstanceData id = null; | ||
583 | |||
584 | if (Scripts.ContainsKey(localID) == false) | ||
585 | return null; | ||
586 | |||
587 | Dictionary<UUID, InstanceData> Obj; | ||
588 | Scripts.TryGetValue(localID, out Obj); | ||
589 | if (Obj==null) return null; | ||
590 | if (Obj.ContainsKey(itemID) == false) | ||
591 | return null; | ||
592 | |||
593 | // Get script | ||
594 | Obj.TryGetValue(itemID, out id); | ||
595 | return id; | ||
596 | } | ||
597 | } | ||
598 | |||
599 | public void SetScript(uint localID, UUID itemID, InstanceData id) | ||
600 | { | ||
601 | lock (scriptLock) | ||
602 | { | ||
603 | // Create object if it doesn't exist | ||
604 | if (Scripts.ContainsKey(localID) == false) | ||
605 | { | ||
606 | Scripts.Add(localID, new Dictionary<UUID, InstanceData>()); | ||
607 | } | ||
608 | |||
609 | // Delete script if it exists | ||
610 | Dictionary<UUID, InstanceData> Obj; | ||
611 | Scripts.TryGetValue(localID, out Obj); | ||
612 | if (Obj.ContainsKey(itemID) == true) | ||
613 | Obj.Remove(itemID); | ||
614 | |||
615 | // Add to object | ||
616 | Obj.Add(itemID, id); | ||
617 | } | ||
618 | } | ||
619 | |||
620 | public void RemoveScript(uint localID, UUID itemID) | ||
621 | { | ||
622 | if (localID == 0) | ||
623 | localID = GetLocalID(itemID); | ||
624 | |||
625 | // Don't have that object? | ||
626 | if (Scripts.ContainsKey(localID) == false) | ||
627 | return; | ||
628 | |||
629 | // Delete script if it exists | ||
630 | Dictionary<UUID, InstanceData> Obj; | ||
631 | Scripts.TryGetValue(localID, out Obj); | ||
632 | if (Obj.ContainsKey(itemID) == true) | ||
633 | Obj.Remove(itemID); | ||
634 | } | ||
635 | |||
636 | #endregion | ||
637 | |||
638 | public void ResetScript(uint localID, UUID itemID) | ||
639 | { | ||
640 | InstanceData id = GetScript(localID, itemID); | ||
641 | string script = id.Source; | ||
642 | StopScript(localID, itemID); | ||
643 | SceneObjectPart part = World.GetSceneObjectPart(localID); | ||
644 | part.Inventory.GetInventoryItem(itemID).PermsMask = 0; | ||
645 | part.Inventory.GetInventoryItem(itemID).PermsGranter = UUID.Zero; | ||
646 | StartScript(localID, itemID, script, id.StartParam, false); | ||
647 | } | ||
648 | |||
649 | #region Script serialization/deserialization | ||
650 | |||
651 | public void GetSerializedScript(uint localID, UUID itemID) | ||
652 | { | ||
653 | // Serialize the script and return it | ||
654 | // Should not be a problem | ||
655 | FileStream fs = File.Create("SERIALIZED_SCRIPT_" + itemID); | ||
656 | BinaryFormatter b = new BinaryFormatter(); | ||
657 | b.Serialize(fs, GetScript(localID, itemID)); | ||
658 | fs.Close(); | ||
659 | } | ||
660 | |||
661 | public void PutSerializedScript(uint localID, UUID itemID) | ||
662 | { | ||
663 | // Deserialize the script and inject it into an AppDomain | ||
664 | |||
665 | // How to inject into an AppDomain? | ||
666 | } | ||
667 | |||
668 | #endregion | ||
669 | |||
670 | public DetectParams[] GetDetectParams(InstanceData id) | ||
671 | { | ||
672 | if (detparms.ContainsKey(id)) | ||
673 | return detparms[id]; | ||
674 | |||
675 | return null; | ||
676 | } | ||
677 | |||
678 | public int GetStartParameter(UUID itemID) | ||
679 | { | ||
680 | uint localID = GetLocalID(itemID); | ||
681 | InstanceData id = GetScript(localID, itemID); | ||
682 | |||
683 | if (id == null) | ||
684 | return 0; | ||
685 | |||
686 | return id.StartParam; | ||
687 | } | ||
688 | |||
689 | public IScriptApi GetApi(UUID itemID, string name) | ||
690 | { | ||
691 | uint localID = GetLocalID(itemID); | ||
692 | |||
693 | InstanceData id = GetScript(localID, itemID); | ||
694 | if (id == null) | ||
695 | return null; | ||
696 | |||
697 | if (id.Apis.ContainsKey(name)) | ||
698 | return id.Apis[name]; | ||
699 | |||
700 | return null; | ||
701 | } | ||
702 | } | ||
703 | } | ||