diff options
Diffstat (limited to '')
-rw-r--r-- | OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs | 660 |
1 files changed, 660 insertions, 0 deletions
diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs new file mode 100644 index 0000000..30c0274 --- /dev/null +++ b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs | |||
@@ -0,0 +1,660 @@ | |||
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.IO; | ||
30 | using System.Threading; | ||
31 | using System.Collections; | ||
32 | using System.Collections.Generic; | ||
33 | using System.Security.Policy; | ||
34 | using System.Reflection; | ||
35 | using System.Globalization; | ||
36 | using System.Xml; | ||
37 | using libsecondlife; | ||
38 | using log4net; | ||
39 | using Nini.Config; | ||
40 | using Amib.Threading; | ||
41 | using OpenSim.Framework; | ||
42 | using OpenSim.Region.Environment; | ||
43 | using OpenSim.Region.Environment.Scenes; | ||
44 | using OpenSim.Region.Environment.Interfaces; | ||
45 | using OpenSim.Region.ScriptEngine.Shared; | ||
46 | using OpenSim.Region.ScriptEngine.Shared.Api; | ||
47 | using OpenSim.Region.ScriptEngine.Shared.ScriptBase; | ||
48 | using OpenSim.Region.ScriptEngine.Shared.CodeTools; | ||
49 | using OpenSim.Region.ScriptEngine.Interfaces; | ||
50 | |||
51 | namespace OpenSim.Region.ScriptEngine.Shared.Instance | ||
52 | { | ||
53 | public class ScriptInstance : IScriptInstance | ||
54 | { | ||
55 | private IScriptEngine m_Engine; | ||
56 | private IWorkItemResult m_CurrentResult=null; | ||
57 | private Queue m_EventQueue = new Queue(32); | ||
58 | private bool m_RunEvents = false; | ||
59 | private LLUUID m_ItemID; | ||
60 | private uint m_LocalID; | ||
61 | private LLUUID m_ObjectID; | ||
62 | private LLUUID m_AssetID; | ||
63 | private IScript m_Script; | ||
64 | private LLUUID m_AppDomain; | ||
65 | private DetectParams[] m_DetectParams; | ||
66 | private bool m_TimerQueued; | ||
67 | private DateTime m_EventStart; | ||
68 | private bool m_InEvent; | ||
69 | private string m_PrimName; | ||
70 | private string m_ScriptName; | ||
71 | private string m_Assembly; | ||
72 | private int m_StartParam = 0; | ||
73 | private string m_CurrentEvent = String.Empty; | ||
74 | private bool m_InSelfDelete = false; | ||
75 | |||
76 | private Dictionary<string,IScriptApi> m_Apis = new Dictionary<string,IScriptApi>(); | ||
77 | |||
78 | // Script state | ||
79 | private string m_State="default"; | ||
80 | |||
81 | public Object[] PluginData = new Object[0]; | ||
82 | |||
83 | public bool Running | ||
84 | { | ||
85 | get { return m_RunEvents; } | ||
86 | set { m_RunEvents = value; } | ||
87 | } | ||
88 | |||
89 | public string State | ||
90 | { | ||
91 | get { return m_State; } | ||
92 | set { m_State = value; } | ||
93 | } | ||
94 | |||
95 | public IScriptEngine Engine | ||
96 | { | ||
97 | get { return m_Engine; } | ||
98 | } | ||
99 | |||
100 | public LLUUID AppDomain | ||
101 | { | ||
102 | get { return m_AppDomain; } | ||
103 | set { m_AppDomain = value; } | ||
104 | } | ||
105 | |||
106 | public string PrimName | ||
107 | { | ||
108 | get { return m_PrimName; } | ||
109 | } | ||
110 | |||
111 | public string ScriptName | ||
112 | { | ||
113 | get { return m_ScriptName; } | ||
114 | } | ||
115 | |||
116 | public LLUUID ItemID | ||
117 | { | ||
118 | get { return m_ItemID; } | ||
119 | } | ||
120 | |||
121 | public LLUUID ObjectID | ||
122 | { | ||
123 | get { return m_ObjectID; } | ||
124 | } | ||
125 | |||
126 | public uint LocalID | ||
127 | { | ||
128 | get { return m_LocalID; } | ||
129 | } | ||
130 | |||
131 | public LLUUID AssetID | ||
132 | { | ||
133 | get { return m_AssetID; } | ||
134 | } | ||
135 | |||
136 | public Queue EventQueue | ||
137 | { | ||
138 | get { return m_EventQueue; } | ||
139 | } | ||
140 | |||
141 | public void ClearQueue() | ||
142 | { | ||
143 | m_TimerQueued = false; | ||
144 | m_EventQueue.Clear(); | ||
145 | } | ||
146 | |||
147 | public int StartParam | ||
148 | { | ||
149 | get { return m_StartParam; } | ||
150 | set { m_StartParam = value; } | ||
151 | } | ||
152 | |||
153 | public ScriptInstance(IScriptEngine engine, uint localID, | ||
154 | LLUUID objectID, LLUUID itemID, LLUUID assetID, string assembly, | ||
155 | AppDomain dom, string primName, string scriptName, | ||
156 | int startParam, bool postOnRez, StateSource stateSource) | ||
157 | { | ||
158 | m_Engine = engine; | ||
159 | |||
160 | m_LocalID = localID; | ||
161 | m_ObjectID = objectID; | ||
162 | m_ItemID = itemID; | ||
163 | m_AssetID = assetID; | ||
164 | m_PrimName = primName; | ||
165 | m_ScriptName = scriptName; | ||
166 | m_Assembly = assembly; | ||
167 | m_StartParam = startParam; | ||
168 | |||
169 | ApiManager am = new ApiManager(); | ||
170 | |||
171 | SceneObjectPart part=engine.World.GetSceneObjectPart(localID); | ||
172 | if (part == null) | ||
173 | { | ||
174 | engine.Log.Error("[Script] SceneObjectPart unavailable. Script NOT started."); | ||
175 | return; | ||
176 | } | ||
177 | |||
178 | foreach (string api in am.GetApis()) | ||
179 | { | ||
180 | m_Apis[api] = am.CreateApi(api); | ||
181 | m_Apis[api].Initialize(engine, part, localID, itemID); | ||
182 | } | ||
183 | |||
184 | try | ||
185 | { | ||
186 | m_Script = (IScript)dom.CreateInstanceAndUnwrap( | ||
187 | Path.GetFileNameWithoutExtension(assembly), | ||
188 | "SecondLife.Script"); | ||
189 | } | ||
190 | catch (Exception e) | ||
191 | { | ||
192 | m_Engine.Log.ErrorFormat("[Script] Error loading assembly {0}\n"+e.ToString(), assembly); | ||
193 | } | ||
194 | |||
195 | try | ||
196 | { | ||
197 | foreach (KeyValuePair<string,IScriptApi> kv in m_Apis) | ||
198 | { | ||
199 | m_Script.InitApi(kv.Key, kv.Value); | ||
200 | } | ||
201 | |||
202 | // m_Engine.Log.Debug("[Script] Script instance created"); | ||
203 | |||
204 | part.SetScriptEvents(m_ItemID, | ||
205 | (int)m_Script.GetStateEventFlags(State)); | ||
206 | } | ||
207 | catch (Exception e) | ||
208 | { | ||
209 | m_Engine.Log.Error("[Script] Error loading script instance\n"+e.ToString()); | ||
210 | return; | ||
211 | } | ||
212 | |||
213 | string savedState = Path.Combine(Path.GetDirectoryName(assembly), | ||
214 | m_ItemID.ToString() + ".state"); | ||
215 | if (File.Exists(savedState)) | ||
216 | { | ||
217 | string xml = String.Empty; | ||
218 | |||
219 | try | ||
220 | { | ||
221 | FileInfo fi = new FileInfo(savedState); | ||
222 | int size=(int)fi.Length; | ||
223 | if (size < 512000) | ||
224 | { | ||
225 | using (FileStream fs = File.Open(savedState, | ||
226 | FileMode.Open, FileAccess.Read, FileShare.None)) | ||
227 | { | ||
228 | System.Text.ASCIIEncoding enc = | ||
229 | new System.Text.ASCIIEncoding(); | ||
230 | |||
231 | Byte[] data = new Byte[size]; | ||
232 | fs.Read(data, 0, size); | ||
233 | |||
234 | xml = enc.GetString(data); | ||
235 | |||
236 | ScriptSerializer.Deserialize(xml, this); | ||
237 | |||
238 | AsyncCommandManager async = (AsyncCommandManager)m_Engine.AsyncCommands; | ||
239 | async.CreateFromData( | ||
240 | m_LocalID, m_ItemID, m_ObjectID, | ||
241 | PluginData); | ||
242 | |||
243 | m_Engine.Log.DebugFormat("[Script] Successfully retrieved state for script {0}.{1}", m_PrimName, m_ScriptName); | ||
244 | |||
245 | if (m_RunEvents) | ||
246 | { | ||
247 | m_RunEvents = false; | ||
248 | Start(); | ||
249 | if (postOnRez) | ||
250 | PostEvent(new EventParams("on_rez", | ||
251 | new Object[] {new LSL_Types.LSLInteger(startParam)}, new DetectParams[0])); | ||
252 | } | ||
253 | |||
254 | // we get new rez events on sim restart, too | ||
255 | // but if there is state, then we fire the change | ||
256 | // event | ||
257 | if (stateSource == StateSource.NewRez) | ||
258 | { | ||
259 | // m_Engine.Log.Debug("[Script] Posted changed(CHANGED_REGION_RESTART) to script"); | ||
260 | PostEvent(new EventParams("changed", | ||
261 | new Object[] {new LSL_Types.LSLInteger(256)}, new DetectParams[0])); | ||
262 | } | ||
263 | } | ||
264 | } | ||
265 | else | ||
266 | { | ||
267 | m_Engine.Log.Error("[Script] Unable to load script state: Memory limit exceeded"); | ||
268 | Start(); | ||
269 | PostEvent(new EventParams("state_entry", | ||
270 | new Object[0], new DetectParams[0])); | ||
271 | if (postOnRez) | ||
272 | PostEvent(new EventParams("on_rez", | ||
273 | new Object[] {new LSL_Types.LSLInteger(startParam)}, new DetectParams[0])); | ||
274 | |||
275 | } | ||
276 | } | ||
277 | catch (Exception e) | ||
278 | { | ||
279 | m_Engine.Log.ErrorFormat("[Script] Unable to load script state from xml: {0}\n"+e.ToString(), xml); | ||
280 | Start(); | ||
281 | PostEvent(new EventParams("state_entry", | ||
282 | new Object[0], new DetectParams[0])); | ||
283 | if (postOnRez) | ||
284 | PostEvent(new EventParams("on_rez", | ||
285 | new Object[] {new LSL_Types.LSLInteger(startParam)}, new DetectParams[0])); | ||
286 | } | ||
287 | } | ||
288 | else | ||
289 | { | ||
290 | // m_Engine.Log.ErrorFormat("[Script] Unable to load script state, file not found"); | ||
291 | Start(); | ||
292 | PostEvent(new EventParams("state_entry", | ||
293 | new Object[0], new DetectParams[0])); | ||
294 | |||
295 | if (postOnRez) | ||
296 | PostEvent(new EventParams("on_rez", | ||
297 | new Object[] {new LSL_Types.LSLInteger(startParam)}, new DetectParams[0])); | ||
298 | } | ||
299 | } | ||
300 | |||
301 | public void RemoveState() | ||
302 | { | ||
303 | string savedState = Path.Combine(Path.GetDirectoryName(m_Assembly), | ||
304 | m_ItemID.ToString() + ".state"); | ||
305 | |||
306 | try | ||
307 | { | ||
308 | File.Delete(savedState); | ||
309 | } | ||
310 | catch(Exception) | ||
311 | { | ||
312 | } | ||
313 | } | ||
314 | |||
315 | public void VarDump(Dictionary<string, object> vars) | ||
316 | { | ||
317 | Console.WriteLine("Variable dump for script {0}", m_ItemID.ToString()); | ||
318 | foreach (KeyValuePair<string, object> v in vars) | ||
319 | { | ||
320 | Console.WriteLine("Variable: {0} = '{1}'", v. Key, | ||
321 | v.Value.ToString()); | ||
322 | } | ||
323 | } | ||
324 | |||
325 | public void Start() | ||
326 | { | ||
327 | lock (m_EventQueue) | ||
328 | { | ||
329 | if (Running) | ||
330 | return; | ||
331 | |||
332 | m_RunEvents = true; | ||
333 | |||
334 | if (m_EventQueue.Count > 0) | ||
335 | { | ||
336 | if (m_CurrentResult == null) | ||
337 | m_CurrentResult = m_Engine.QueueEventHandler(this); | ||
338 | else | ||
339 | m_Engine.Log.Error("[Script] Tried to start a script that was already queued"); | ||
340 | } | ||
341 | } | ||
342 | } | ||
343 | |||
344 | public bool Stop(int timeout) | ||
345 | { | ||
346 | IWorkItemResult result; | ||
347 | |||
348 | lock (m_EventQueue) | ||
349 | { | ||
350 | if (!Running) | ||
351 | return true; | ||
352 | |||
353 | if (m_CurrentResult == null) | ||
354 | { | ||
355 | m_RunEvents = false; | ||
356 | return true; | ||
357 | } | ||
358 | |||
359 | if (m_CurrentResult.Cancel()) | ||
360 | { | ||
361 | m_CurrentResult = null; | ||
362 | m_RunEvents = false; | ||
363 | return true; | ||
364 | } | ||
365 | |||
366 | result = m_CurrentResult; | ||
367 | m_RunEvents = false; | ||
368 | } | ||
369 | |||
370 | if (SmartThreadPool.WaitAll(new IWorkItemResult[] {result}, new TimeSpan((long)timeout * 100000), false)) | ||
371 | { | ||
372 | return true; | ||
373 | } | ||
374 | |||
375 | lock (m_EventQueue) | ||
376 | { | ||
377 | result = m_CurrentResult; | ||
378 | } | ||
379 | |||
380 | if (result == null) | ||
381 | return true; | ||
382 | |||
383 | if (!m_InSelfDelete) | ||
384 | result.Abort(); | ||
385 | |||
386 | lock (m_EventQueue) | ||
387 | { | ||
388 | m_CurrentResult = null; | ||
389 | } | ||
390 | |||
391 | return true; | ||
392 | } | ||
393 | |||
394 | public void SetState(string state) | ||
395 | { | ||
396 | PostEvent(new EventParams("state_exit", new Object[0], | ||
397 | new DetectParams[0])); | ||
398 | PostEvent(new EventParams("state", new Object[] { state }, | ||
399 | new DetectParams[0])); | ||
400 | PostEvent(new EventParams("state_entry", new Object[0], | ||
401 | new DetectParams[0])); | ||
402 | } | ||
403 | |||
404 | public void PostEvent(EventParams data) | ||
405 | { | ||
406 | // m_Engine.Log.DebugFormat("[Script] Posted event {2} in state {3} to {0}.{1}", | ||
407 | // m_PrimName, m_ScriptName, data.EventName, m_State); | ||
408 | |||
409 | if (!Running) | ||
410 | return; | ||
411 | |||
412 | lock (m_EventQueue) | ||
413 | { | ||
414 | if (m_EventQueue.Count >= m_Engine.MaxScriptQueue) | ||
415 | return; | ||
416 | |||
417 | m_EventQueue.Enqueue(data); | ||
418 | if (data.EventName == "timer") | ||
419 | { | ||
420 | if (m_TimerQueued) | ||
421 | return; | ||
422 | m_TimerQueued = true; | ||
423 | } | ||
424 | |||
425 | if (!m_RunEvents) | ||
426 | return; | ||
427 | |||
428 | if (m_CurrentResult == null) | ||
429 | { | ||
430 | m_CurrentResult = m_Engine.QueueEventHandler(this); | ||
431 | } | ||
432 | } | ||
433 | } | ||
434 | |||
435 | public object EventProcessor() | ||
436 | { | ||
437 | EventParams data = null; | ||
438 | |||
439 | lock (m_EventQueue) | ||
440 | { | ||
441 | data = (EventParams) m_EventQueue.Dequeue(); | ||
442 | if (data == null) // Shouldn't happen | ||
443 | { | ||
444 | m_CurrentResult = null; | ||
445 | return 0; | ||
446 | } | ||
447 | if (data.EventName == "timer") | ||
448 | m_TimerQueued = false; | ||
449 | } | ||
450 | |||
451 | m_DetectParams = data.DetectParams; | ||
452 | |||
453 | if (data.EventName == "state") // Hardcoded state change | ||
454 | { | ||
455 | // m_Engine.Log.DebugFormat("[Script] Script {0}.{1} state set to {2}", | ||
456 | // m_PrimName, m_ScriptName, data.Params[0].ToString()); | ||
457 | m_State=data.Params[0].ToString(); | ||
458 | AsyncCommandManager async = (AsyncCommandManager)m_Engine.AsyncCommands; | ||
459 | async.RemoveScript( | ||
460 | m_LocalID, m_ItemID); | ||
461 | |||
462 | SceneObjectPart part = m_Engine.World.GetSceneObjectPart( | ||
463 | m_LocalID); | ||
464 | if (part != null) | ||
465 | { | ||
466 | part.SetScriptEvents(m_ItemID, | ||
467 | (int)m_Script.GetStateEventFlags(State)); | ||
468 | } | ||
469 | } | ||
470 | else | ||
471 | { | ||
472 | SceneObjectPart part = m_Engine.World.GetSceneObjectPart( | ||
473 | m_LocalID); | ||
474 | // m_Engine.Log.DebugFormat("[Script] Delivered event {2} in state {3} to {0}.{1}", | ||
475 | // m_PrimName, m_ScriptName, data.EventName, m_State); | ||
476 | |||
477 | try | ||
478 | { | ||
479 | m_CurrentEvent = data.EventName; | ||
480 | m_EventStart = DateTime.Now; | ||
481 | m_InEvent = true; | ||
482 | |||
483 | m_Script.ExecuteEvent(State, data.EventName, data.Params); | ||
484 | |||
485 | m_InEvent = false; | ||
486 | m_CurrentEvent = String.Empty; | ||
487 | } | ||
488 | catch (Exception e) | ||
489 | { | ||
490 | m_InEvent = false; | ||
491 | m_CurrentEvent = String.Empty; | ||
492 | |||
493 | if (!(e is TargetInvocationException) || (!(e.InnerException is EventAbortException) && (!(e.InnerException is SelfDeleteException)))) | ||
494 | { | ||
495 | if (e is System.Threading.ThreadAbortException) | ||
496 | { | ||
497 | lock (m_EventQueue) | ||
498 | { | ||
499 | if ((m_EventQueue.Count > 0) && m_RunEvents) | ||
500 | { | ||
501 | m_CurrentResult=m_Engine.QueueEventHandler(this); | ||
502 | } | ||
503 | else | ||
504 | { | ||
505 | m_CurrentResult = null; | ||
506 | } | ||
507 | } | ||
508 | |||
509 | m_DetectParams = null; | ||
510 | |||
511 | return 0; | ||
512 | } | ||
513 | |||
514 | try | ||
515 | { | ||
516 | // DISPLAY ERROR INWORLD | ||
517 | string text = "Runtime error:\n" + e.ToString(); | ||
518 | if (text.Length > 1400) | ||
519 | text = text.Substring(0, 1400); | ||
520 | m_Engine.World.SimChat(Helpers.StringToField(text), | ||
521 | ChatTypeEnum.DebugChannel, 2147483647, | ||
522 | part.AbsolutePosition, | ||
523 | part.Name, part.UUID, false); | ||
524 | } | ||
525 | catch (Exception e2) // LEGIT: User Scripting | ||
526 | { | ||
527 | m_Engine.Log.Error("[Script]: "+ | ||
528 | "Error displaying error in-world: " + | ||
529 | e2.ToString()); | ||
530 | m_Engine.Log.Error("[Script]: " + | ||
531 | "Errormessage: Error compiling script:\r\n" + | ||
532 | e.ToString()); | ||
533 | } | ||
534 | } | ||
535 | else if ((e is TargetInvocationException) && (e.InnerException is SelfDeleteException)) | ||
536 | { | ||
537 | m_InSelfDelete = true; | ||
538 | if (part != null && part.ParentGroup != null) | ||
539 | m_Engine.World.DeleteSceneObject(part.ParentGroup); | ||
540 | } | ||
541 | } | ||
542 | } | ||
543 | |||
544 | lock (m_EventQueue) | ||
545 | { | ||
546 | if ((m_EventQueue.Count > 0) && m_RunEvents) | ||
547 | { | ||
548 | m_CurrentResult = m_Engine.QueueEventHandler(this); | ||
549 | } | ||
550 | else | ||
551 | { | ||
552 | m_CurrentResult = null; | ||
553 | } | ||
554 | } | ||
555 | |||
556 | m_DetectParams = null; | ||
557 | |||
558 | return 0; | ||
559 | } | ||
560 | |||
561 | public int EventTime() | ||
562 | { | ||
563 | if (!m_InEvent) | ||
564 | return 0; | ||
565 | |||
566 | return (DateTime.Now - m_EventStart).Seconds; | ||
567 | } | ||
568 | |||
569 | public void ResetScript() | ||
570 | { | ||
571 | bool running = Running; | ||
572 | |||
573 | RemoveState(); | ||
574 | |||
575 | Stop(0); | ||
576 | SceneObjectPart part=m_Engine.World.GetSceneObjectPart(m_LocalID); | ||
577 | part.GetInventoryItem(m_ItemID).PermsMask = 0; | ||
578 | part.GetInventoryItem(m_ItemID).PermsGranter = LLUUID.Zero; | ||
579 | AsyncCommandManager async = (AsyncCommandManager)m_Engine.AsyncCommands; | ||
580 | async.RemoveScript(m_LocalID, m_ItemID); | ||
581 | m_EventQueue.Clear(); | ||
582 | m_Script.ResetVars(); | ||
583 | m_State = "default"; | ||
584 | if (running) | ||
585 | Start(); | ||
586 | PostEvent(new EventParams("state_entry", | ||
587 | new Object[0], new DetectParams[0])); | ||
588 | } | ||
589 | |||
590 | public void ApiResetScript() | ||
591 | { | ||
592 | // bool running = Running; | ||
593 | |||
594 | RemoveState(); | ||
595 | |||
596 | m_Script.ResetVars(); | ||
597 | SceneObjectPart part=m_Engine.World.GetSceneObjectPart(m_LocalID); | ||
598 | part.GetInventoryItem(m_ItemID).PermsMask = 0; | ||
599 | part.GetInventoryItem(m_ItemID).PermsGranter = LLUUID.Zero; | ||
600 | AsyncCommandManager async = (AsyncCommandManager)m_Engine.AsyncCommands; | ||
601 | async.RemoveScript(m_LocalID, m_ItemID); | ||
602 | if (m_CurrentEvent != "state_entry") | ||
603 | { | ||
604 | PostEvent(new EventParams("state_entry", | ||
605 | new Object[0], new DetectParams[0])); | ||
606 | } | ||
607 | } | ||
608 | |||
609 | public Dictionary<string, object> GetVars() | ||
610 | { | ||
611 | return m_Script.GetVars(); | ||
612 | } | ||
613 | |||
614 | public void SetVars(Dictionary<string, object> vars) | ||
615 | { | ||
616 | m_Script.SetVars(vars); | ||
617 | } | ||
618 | |||
619 | public DetectParams GetDetectParams(int idx) | ||
620 | { | ||
621 | if (idx < 0 || idx >= m_DetectParams.Length) | ||
622 | return null; | ||
623 | |||
624 | return m_DetectParams[idx]; | ||
625 | } | ||
626 | |||
627 | public LLUUID GetDetectID(int idx) | ||
628 | { | ||
629 | if (idx < 0 || idx >= m_DetectParams.Length) | ||
630 | return LLUUID.Zero; | ||
631 | |||
632 | return m_DetectParams[idx].Key; | ||
633 | } | ||
634 | |||
635 | public void SaveState(string assembly) | ||
636 | { | ||
637 | AsyncCommandManager async = (AsyncCommandManager)m_Engine.AsyncCommands; | ||
638 | PluginData = async.GetSerializationData(m_ItemID); | ||
639 | |||
640 | string xml = ScriptSerializer.Serialize(this); | ||
641 | |||
642 | try | ||
643 | { | ||
644 | FileStream fs = File.Create(Path.Combine(Path.GetDirectoryName(assembly), m_ItemID.ToString() + ".state")); | ||
645 | System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding(); | ||
646 | Byte[] buf = enc.GetBytes(xml); | ||
647 | fs.Write(buf, 0, buf.Length); | ||
648 | fs.Close(); | ||
649 | } | ||
650 | catch(Exception e) | ||
651 | { | ||
652 | Console.WriteLine("Unable to save xml\n"+e.ToString()); | ||
653 | } | ||
654 | if (!File.Exists(Path.Combine(Path.GetDirectoryName(assembly), m_ItemID.ToString() + ".state"))) | ||
655 | { | ||
656 | throw new Exception("Completed persistence save, but no file was created"); | ||
657 | } | ||
658 | } | ||
659 | } | ||
660 | } | ||