diff options
Diffstat (limited to 'OpenSim/Region/ScriptEngine/XMREngine/XMRInstMisc.cs')
-rw-r--r-- | OpenSim/Region/ScriptEngine/XMREngine/XMRInstMisc.cs | 384 |
1 files changed, 384 insertions, 0 deletions
diff --git a/OpenSim/Region/ScriptEngine/XMREngine/XMRInstMisc.cs b/OpenSim/Region/ScriptEngine/XMREngine/XMRInstMisc.cs new file mode 100644 index 0000000..6ff486a --- /dev/null +++ b/OpenSim/Region/ScriptEngine/XMREngine/XMRInstMisc.cs | |||
@@ -0,0 +1,384 @@ | |||
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.Threading; | ||
30 | using System.Reflection; | ||
31 | using System.Collections; | ||
32 | using System.Collections.Generic; | ||
33 | using System.Reflection.Emit; | ||
34 | using System.Runtime.Remoting.Lifetime; | ||
35 | using System.Security.Policy; | ||
36 | using System.IO; | ||
37 | using System.Xml; | ||
38 | using System.Text; | ||
39 | using OpenMetaverse; | ||
40 | using OpenSim.Framework; | ||
41 | using OpenSim.Region.ScriptEngine.Interfaces; | ||
42 | using OpenSim.Region.ScriptEngine.Shared; | ||
43 | using OpenSim.Region.ScriptEngine.Shared.Api; | ||
44 | using OpenSim.Region.ScriptEngine.Shared.ScriptBase; | ||
45 | using OpenSim.Region.ScriptEngine.XMREngine; | ||
46 | using OpenSim.Region.Framework.Scenes; | ||
47 | using log4net; | ||
48 | |||
49 | using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat; | ||
50 | using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger; | ||
51 | using LSL_Key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; | ||
52 | using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list; | ||
53 | using LSL_Rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion; | ||
54 | using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; | ||
55 | using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3; | ||
56 | |||
57 | // This class exists in the main app domain | ||
58 | // | ||
59 | namespace OpenSim.Region.ScriptEngine.XMREngine | ||
60 | { | ||
61 | public partial class XMRInstance | ||
62 | { | ||
63 | |||
64 | // In case Dispose() doesn't get called, we want to be sure to clean | ||
65 | // up. This makes sure we decrement m_CompiledScriptRefCount. | ||
66 | ~XMRInstance() | ||
67 | { | ||
68 | Dispose(); | ||
69 | } | ||
70 | |||
71 | /** | ||
72 | * @brief Clean up stuff. | ||
73 | * We specifically leave m_DescName intact for 'xmr ls' command. | ||
74 | */ | ||
75 | public void Dispose() | ||
76 | { | ||
77 | /* | ||
78 | * Tell script stop executing next time it calls CheckRun(). | ||
79 | */ | ||
80 | suspendOnCheckRunHold = true; | ||
81 | |||
82 | /* | ||
83 | * Wait for it to stop executing and prevent it from starting again | ||
84 | * as it can't run without a microthread. | ||
85 | */ | ||
86 | lock (m_RunLock) | ||
87 | { | ||
88 | if (microthread != null) | ||
89 | { | ||
90 | m_RunOnePhase = "disposing"; | ||
91 | CheckRunLockInvariants(true); | ||
92 | microthread.Dispose (); | ||
93 | microthread = null; | ||
94 | } | ||
95 | } | ||
96 | |||
97 | /* | ||
98 | * Don't send us any more events. | ||
99 | */ | ||
100 | if (m_Part != null) | ||
101 | { | ||
102 | xmrTrapRegionCrossing (0); | ||
103 | m_Part.RemoveScriptEvents(m_ItemID); | ||
104 | AsyncCommandManager.RemoveScript(m_Engine, m_LocalID, m_ItemID); | ||
105 | m_Part = null; | ||
106 | } | ||
107 | |||
108 | /* | ||
109 | * Let script methods get garbage collected if no one else is using | ||
110 | * them. | ||
111 | */ | ||
112 | DecObjCodeRefCount (); | ||
113 | } | ||
114 | |||
115 | private void DecObjCodeRefCount () | ||
116 | { | ||
117 | if (m_ObjCode != null) { | ||
118 | lock (m_CompileLock) { | ||
119 | ScriptObjCode objCode; | ||
120 | |||
121 | if (m_CompiledScriptObjCode.TryGetValue (m_ScriptObjCodeKey, out objCode) && | ||
122 | (objCode == m_ObjCode) && | ||
123 | (-- objCode.refCount == 0)) { | ||
124 | m_CompiledScriptObjCode.Remove (m_ScriptObjCodeKey); | ||
125 | } | ||
126 | } | ||
127 | m_ObjCode = null; | ||
128 | } | ||
129 | } | ||
130 | |||
131 | public void Verbose (string format, params object[] args) | ||
132 | { | ||
133 | if (m_Engine.m_Verbose) m_log.DebugFormat (format, args); | ||
134 | } | ||
135 | |||
136 | // Called by 'xmr top' console command | ||
137 | // to dump this script's state to console | ||
138 | // Sacha | ||
139 | public void RunTestTop() | ||
140 | { | ||
141 | if (m_InstEHSlice > 0){ | ||
142 | Console.WriteLine(m_DescName); | ||
143 | Console.WriteLine(" m_LocalID = " + m_LocalID); | ||
144 | Console.WriteLine(" m_ItemID = " + m_ItemID); | ||
145 | Console.WriteLine(" m_Item.AssetID = " + m_Item.AssetID); | ||
146 | Console.WriteLine(" m_StartParam = " + m_StartParam); | ||
147 | Console.WriteLine(" m_PostOnRez = " + m_PostOnRez); | ||
148 | Console.WriteLine(" m_StateSource = " + m_StateSource); | ||
149 | Console.WriteLine(" m_SuspendCount = " + m_SuspendCount); | ||
150 | Console.WriteLine(" m_SleepUntil = " + m_SleepUntil); | ||
151 | Console.WriteLine(" m_IState = " + m_IState.ToString()); | ||
152 | Console.WriteLine(" m_StateCode = " + GetStateName(stateCode)); | ||
153 | Console.WriteLine(" eventCode = " + eventCode.ToString()); | ||
154 | Console.WriteLine(" m_LastRanAt = " + m_LastRanAt.ToString()); | ||
155 | Console.WriteLine(" heapUsed/Limit = " + xmrHeapUsed () + "/" + heapLimit); | ||
156 | Console.WriteLine(" m_InstEHEvent = " + m_InstEHEvent.ToString()); | ||
157 | Console.WriteLine(" m_InstEHSlice = " + m_InstEHSlice.ToString()); | ||
158 | } | ||
159 | } | ||
160 | |||
161 | // Called by 'xmr ls' console command | ||
162 | // to dump this script's state to console | ||
163 | public string RunTestLs(bool flagFull) | ||
164 | { | ||
165 | if (flagFull) { | ||
166 | StringBuilder sb = new StringBuilder(); | ||
167 | sb.AppendLine(m_DescName); | ||
168 | sb.AppendLine(" m_LocalID = " + m_LocalID); | ||
169 | sb.AppendLine(" m_ItemID = " + m_ItemID + " (.state file)"); | ||
170 | sb.AppendLine(" m_Item.AssetID = " + m_Item.AssetID); | ||
171 | sb.AppendLine(" m_Part.WorldPosition = " + m_Part.GetWorldPosition ()); | ||
172 | sb.AppendLine(" m_ScriptObjCodeKey = " + m_ScriptObjCodeKey + " (source text)"); | ||
173 | sb.AppendLine(" m_StartParam = " + m_StartParam); | ||
174 | sb.AppendLine(" m_PostOnRez = " + m_PostOnRez); | ||
175 | sb.AppendLine(" m_StateSource = " + m_StateSource); | ||
176 | sb.AppendLine(" m_SuspendCount = " + m_SuspendCount); | ||
177 | sb.AppendLine(" m_SleepUntil = " + m_SleepUntil); | ||
178 | sb.AppendLine(" m_SleepEvMask1 = 0x" + m_SleepEventMask1.ToString("X")); | ||
179 | sb.AppendLine(" m_SleepEvMask2 = 0x" + m_SleepEventMask2.ToString("X")); | ||
180 | sb.AppendLine(" m_IState = " + m_IState.ToString()); | ||
181 | sb.AppendLine(" m_StateCode = " + GetStateName(stateCode)); | ||
182 | sb.AppendLine(" eventCode = " + eventCode.ToString()); | ||
183 | sb.AppendLine(" m_LastRanAt = " + m_LastRanAt.ToString()); | ||
184 | sb.AppendLine(" m_RunOnePhase = " + m_RunOnePhase); | ||
185 | sb.AppendLine(" suspOnCkRunHold = " + suspendOnCheckRunHold); | ||
186 | sb.AppendLine(" suspOnCkRunTemp = " + suspendOnCheckRunTemp); | ||
187 | sb.AppendLine(" m_CheckRunPhase = " + m_CheckRunPhase); | ||
188 | sb.AppendLine(" heapUsed/Limit = " + xmrHeapUsed () + "/" + heapLimit); | ||
189 | sb.AppendLine(" m_InstEHEvent = " + m_InstEHEvent.ToString()); | ||
190 | sb.AppendLine(" m_InstEHSlice = " + m_InstEHSlice.ToString()); | ||
191 | sb.AppendLine(" m_CPUTime = " + m_CPUTime); | ||
192 | sb.AppendLine(" callMode = " + callMode); | ||
193 | sb.AppendLine(" captureStackFrames = " + captureStackFrames); | ||
194 | sb.AppendLine(" stackFramesRestored = " + stackFramesRestored); | ||
195 | lock (m_QueueLock) | ||
196 | { | ||
197 | sb.AppendLine(" m_Running = " + m_Running); | ||
198 | foreach (EventParams evt in m_EventQueue) | ||
199 | { | ||
200 | sb.AppendLine(" evt.EventName = " + evt.EventName); | ||
201 | } | ||
202 | } | ||
203 | return sb.ToString(); | ||
204 | } else { | ||
205 | return String.Format("{0} {1} {2} {3} {4} {5}", | ||
206 | m_ItemID, | ||
207 | m_CPUTime.ToString("F3").PadLeft(9), | ||
208 | m_InstEHEvent.ToString().PadLeft(9), | ||
209 | m_IState.ToString().PadRight(10), | ||
210 | m_Part.GetWorldPosition().ToString().PadRight(32), | ||
211 | m_DescName); | ||
212 | } | ||
213 | } | ||
214 | |||
215 | /** | ||
216 | * @brief For a given stateCode, get a mask of the low 32 event codes | ||
217 | * that the state has handlers defined for. | ||
218 | */ | ||
219 | public int GetStateEventFlags(int stateCode) | ||
220 | { | ||
221 | if ((stateCode < 0) || | ||
222 | (stateCode >= m_ObjCode.scriptEventHandlerTable.GetLength(0))) | ||
223 | { | ||
224 | return 0; | ||
225 | } | ||
226 | |||
227 | int code = 0; | ||
228 | for (int i = 0 ; i < 32; i ++) | ||
229 | { | ||
230 | if (m_ObjCode.scriptEventHandlerTable[stateCode, i] != null) | ||
231 | { | ||
232 | code |= 1 << i; | ||
233 | } | ||
234 | } | ||
235 | |||
236 | return code; | ||
237 | } | ||
238 | |||
239 | /** | ||
240 | * @brief Get the .state file name. | ||
241 | */ | ||
242 | public static string GetStateFileName (string scriptBasePath, UUID itemID) | ||
243 | { | ||
244 | return GetScriptFileName (scriptBasePath, itemID.ToString() + ".state"); | ||
245 | } | ||
246 | |||
247 | public string GetScriptFileName (string filename) | ||
248 | { | ||
249 | return GetScriptFileName (m_ScriptBasePath, filename); | ||
250 | } | ||
251 | |||
252 | public static string GetScriptFileName (string scriptBasePath, string filename) | ||
253 | { | ||
254 | /* | ||
255 | * Get old path, ie, all files lumped in a single huge directory. | ||
256 | */ | ||
257 | string oldPath = Path.Combine (scriptBasePath, filename); | ||
258 | |||
259 | /* | ||
260 | * Get new path, ie, files split up based on first 2 chars of name. | ||
261 | */ | ||
262 | string subdir = filename.Substring (0, 2); | ||
263 | filename = filename.Substring (2); | ||
264 | scriptBasePath = Path.Combine (scriptBasePath, subdir); | ||
265 | Directory.CreateDirectory (scriptBasePath); | ||
266 | string newPath = Path.Combine (scriptBasePath, filename); | ||
267 | |||
268 | /* | ||
269 | * If file exists only in old location, move to new location. | ||
270 | * If file exists in both locations, delete old location. | ||
271 | */ | ||
272 | if (File.Exists (oldPath)) { | ||
273 | if (File.Exists (newPath)) { | ||
274 | File.Delete (oldPath); | ||
275 | } else { | ||
276 | File.Move (oldPath, newPath); | ||
277 | } | ||
278 | } | ||
279 | |||
280 | /* | ||
281 | * Always return new location. | ||
282 | */ | ||
283 | return newPath; | ||
284 | } | ||
285 | |||
286 | /** | ||
287 | * @brief Decode state code (int) to state name (string). | ||
288 | */ | ||
289 | public string GetStateName (int stateCode) | ||
290 | { | ||
291 | try { | ||
292 | return m_ObjCode.stateNames[stateCode]; | ||
293 | } catch { | ||
294 | return stateCode.ToString (); | ||
295 | } | ||
296 | } | ||
297 | |||
298 | /** | ||
299 | * @brief various gets & sets. | ||
300 | */ | ||
301 | public int StartParam | ||
302 | { | ||
303 | get { return m_StartParam; } | ||
304 | set { m_StartParam = value; } | ||
305 | } | ||
306 | |||
307 | public SceneObjectPart SceneObject | ||
308 | { | ||
309 | get { return m_Part; } | ||
310 | } | ||
311 | |||
312 | public DetectParams[] DetectParams | ||
313 | { | ||
314 | get { return m_DetectParams; } | ||
315 | set { m_DetectParams = value; } | ||
316 | } | ||
317 | |||
318 | public UUID ItemID | ||
319 | { | ||
320 | get { return m_ItemID; } | ||
321 | } | ||
322 | |||
323 | public UUID AssetID | ||
324 | { | ||
325 | get { return m_Item.AssetID; } | ||
326 | } | ||
327 | |||
328 | public bool Running | ||
329 | { | ||
330 | get { return m_Running; } | ||
331 | set | ||
332 | { | ||
333 | lock (m_QueueLock) | ||
334 | { | ||
335 | m_Running = value; | ||
336 | if (!value) | ||
337 | { | ||
338 | EmptyEventQueues (); | ||
339 | } | ||
340 | } | ||
341 | } | ||
342 | } | ||
343 | |||
344 | /** | ||
345 | * @brief Empty out the event queues. | ||
346 | * Assumes caller has the m_QueueLock locked. | ||
347 | */ | ||
348 | public void EmptyEventQueues () | ||
349 | { | ||
350 | m_EventQueue.Clear(); | ||
351 | for (int i = m_EventCounts.Length; -- i >= 0;) m_EventCounts[i] = 0; | ||
352 | } | ||
353 | |||
354 | /** | ||
355 | * @brief Convert an LSL vector to an Openmetaverse vector. | ||
356 | */ | ||
357 | public static OpenMetaverse.Vector3 LSLVec2OMVec (LSL_Vector lslVec) | ||
358 | { | ||
359 | return new OpenMetaverse.Vector3 ((float)lslVec.x, (float)lslVec.y, (float)lslVec.z); | ||
360 | } | ||
361 | |||
362 | /** | ||
363 | * @brief Extract an integer from an element of an LSL_List. | ||
364 | */ | ||
365 | public static int ListInt (object element) | ||
366 | { | ||
367 | if (element is LSL_Integer) { | ||
368 | return (int)(LSL_Integer)element; | ||
369 | } | ||
370 | return (int)element; | ||
371 | } | ||
372 | |||
373 | /** | ||
374 | * @brief Extract a string from an element of an LSL_List. | ||
375 | */ | ||
376 | public static string ListStr (object element) | ||
377 | { | ||
378 | if (element is LSL_String) { | ||
379 | return (string)(LSL_String)element; | ||
380 | } | ||
381 | return (string)element; | ||
382 | } | ||
383 | } | ||
384 | } | ||