diff options
Diffstat (limited to '')
-rw-r--r-- | OpenSim/Region/ScriptEngine/Shared/Instance/ScriptSerializer.cs | 461 |
1 files changed, 461 insertions, 0 deletions
diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptSerializer.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptSerializer.cs new file mode 100644 index 0000000..ba003c5 --- /dev/null +++ b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptSerializer.cs | |||
@@ -0,0 +1,461 @@ | |||
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 ScriptSerializer | ||
54 | { | ||
55 | public static string Serialize(ScriptInstance instance) | ||
56 | { | ||
57 | bool running = instance.Running; | ||
58 | |||
59 | if (running) | ||
60 | instance.Stop(50); | ||
61 | |||
62 | XmlDocument xmldoc = new XmlDocument(); | ||
63 | |||
64 | XmlNode xmlnode = xmldoc.CreateNode(XmlNodeType.XmlDeclaration, | ||
65 | "", ""); | ||
66 | xmldoc.AppendChild(xmlnode); | ||
67 | |||
68 | XmlElement rootElement = xmldoc.CreateElement("", "ScriptState", | ||
69 | ""); | ||
70 | xmldoc.AppendChild(rootElement); | ||
71 | |||
72 | XmlElement state = xmldoc.CreateElement("", "State", ""); | ||
73 | state.AppendChild(xmldoc.CreateTextNode(instance.State)); | ||
74 | |||
75 | rootElement.AppendChild(state); | ||
76 | |||
77 | XmlElement run = xmldoc.CreateElement("", "Running", ""); | ||
78 | run.AppendChild(xmldoc.CreateTextNode( | ||
79 | running.ToString())); | ||
80 | |||
81 | rootElement.AppendChild(run); | ||
82 | |||
83 | Dictionary<string, Object> vars = instance.GetVars(); | ||
84 | |||
85 | XmlElement variables = xmldoc.CreateElement("", "Variables", ""); | ||
86 | |||
87 | foreach (KeyValuePair<string, Object> var in vars) | ||
88 | WriteTypedValue(xmldoc, variables, "Variable", var.Key, | ||
89 | var.Value); | ||
90 | |||
91 | rootElement.AppendChild(variables); | ||
92 | |||
93 | XmlElement queue = xmldoc.CreateElement("", "Queue", ""); | ||
94 | |||
95 | int count = instance.EventQueue.Count; | ||
96 | |||
97 | while (count > 0) | ||
98 | { | ||
99 | EventParams ep = (EventParams)instance.EventQueue.Dequeue(); | ||
100 | instance.EventQueue.Enqueue(ep); | ||
101 | count--; | ||
102 | |||
103 | XmlElement item = xmldoc.CreateElement("", "Item", ""); | ||
104 | XmlAttribute itemEvent = xmldoc.CreateAttribute("", "event", | ||
105 | ""); | ||
106 | itemEvent.Value = ep.EventName; | ||
107 | item.Attributes.Append(itemEvent); | ||
108 | |||
109 | XmlElement parms = xmldoc.CreateElement("", "Params", ""); | ||
110 | |||
111 | foreach (Object o in ep.Params) | ||
112 | WriteTypedValue(xmldoc, parms, "Param", String.Empty, o); | ||
113 | |||
114 | item.AppendChild(parms); | ||
115 | |||
116 | XmlElement detect = xmldoc.CreateElement("", "Detected", ""); | ||
117 | |||
118 | foreach (DetectParams det in ep.DetectParams) | ||
119 | { | ||
120 | XmlElement objectElem = xmldoc.CreateElement("", "Object", | ||
121 | ""); | ||
122 | XmlAttribute pos = xmldoc.CreateAttribute("", "pos", ""); | ||
123 | pos.Value = det.OffsetPos.ToString(); | ||
124 | objectElem.Attributes.Append(pos); | ||
125 | |||
126 | XmlAttribute d_linkNum = xmldoc.CreateAttribute("", | ||
127 | "linkNum", ""); | ||
128 | d_linkNum.Value = det.LinkNum.ToString(); | ||
129 | objectElem.Attributes.Append(d_linkNum); | ||
130 | |||
131 | XmlAttribute d_group = xmldoc.CreateAttribute("", | ||
132 | "group", ""); | ||
133 | d_group.Value = det.Group.ToString(); | ||
134 | objectElem.Attributes.Append(d_group); | ||
135 | |||
136 | XmlAttribute d_name = xmldoc.CreateAttribute("", | ||
137 | "name", ""); | ||
138 | d_name.Value = det.Name.ToString(); | ||
139 | objectElem.Attributes.Append(d_name); | ||
140 | |||
141 | XmlAttribute d_owner = xmldoc.CreateAttribute("", | ||
142 | "owner", ""); | ||
143 | d_owner.Value = det.Owner.ToString(); | ||
144 | objectElem.Attributes.Append(d_owner); | ||
145 | |||
146 | XmlAttribute d_position = xmldoc.CreateAttribute("", | ||
147 | "position", ""); | ||
148 | d_position.Value = det.Position.ToString(); | ||
149 | objectElem.Attributes.Append(d_position); | ||
150 | |||
151 | XmlAttribute d_rotation = xmldoc.CreateAttribute("", | ||
152 | "rotation", ""); | ||
153 | d_rotation.Value = det.Rotation.ToString(); | ||
154 | objectElem.Attributes.Append(d_rotation); | ||
155 | |||
156 | XmlAttribute d_type = xmldoc.CreateAttribute("", | ||
157 | "type", ""); | ||
158 | d_type.Value = det.Type.ToString(); | ||
159 | objectElem.Attributes.Append(d_type); | ||
160 | |||
161 | XmlAttribute d_velocity = xmldoc.CreateAttribute("", | ||
162 | "velocity", ""); | ||
163 | d_velocity.Value = det.Velocity.ToString(); | ||
164 | objectElem.Attributes.Append(d_velocity); | ||
165 | |||
166 | objectElem.AppendChild( | ||
167 | xmldoc.CreateTextNode(det.Key.ToString())); | ||
168 | |||
169 | detect.AppendChild(objectElem); | ||
170 | } | ||
171 | |||
172 | item.AppendChild(detect); | ||
173 | |||
174 | queue.AppendChild(item); | ||
175 | } | ||
176 | |||
177 | rootElement.AppendChild(queue); | ||
178 | |||
179 | XmlNode plugins = xmldoc.CreateElement("", "Plugins", ""); | ||
180 | DumpList(xmldoc, plugins, | ||
181 | new LSL_Types.list(instance.PluginData)); | ||
182 | |||
183 | rootElement.AppendChild(plugins); | ||
184 | |||
185 | if (running) | ||
186 | instance.Start(); | ||
187 | |||
188 | return xmldoc.InnerXml; | ||
189 | } | ||
190 | |||
191 | public static void Deserialize(string xml, ScriptInstance instance) | ||
192 | { | ||
193 | XmlDocument doc = new XmlDocument(); | ||
194 | |||
195 | Dictionary<string, object> vars = instance.GetVars(); | ||
196 | |||
197 | instance.PluginData = new Object[0]; | ||
198 | |||
199 | doc.LoadXml(xml); | ||
200 | |||
201 | XmlNodeList rootL = doc.GetElementsByTagName("ScriptState"); | ||
202 | if (rootL.Count != 1) | ||
203 | { | ||
204 | return; | ||
205 | } | ||
206 | XmlNode rootNode = rootL[0]; | ||
207 | |||
208 | if (rootNode != null) | ||
209 | { | ||
210 | object varValue; | ||
211 | XmlNodeList partL = rootNode.ChildNodes; | ||
212 | |||
213 | foreach (XmlNode part in partL) | ||
214 | { | ||
215 | switch (part.Name) | ||
216 | { | ||
217 | case "State": | ||
218 | instance.State=part.InnerText; | ||
219 | break; | ||
220 | case "Running": | ||
221 | instance.Running=bool.Parse(part.InnerText); | ||
222 | break; | ||
223 | case "Variables": | ||
224 | XmlNodeList varL = part.ChildNodes; | ||
225 | foreach (XmlNode var in varL) | ||
226 | { | ||
227 | string varName; | ||
228 | varValue=ReadTypedValue(var, out varName); | ||
229 | |||
230 | if (vars.ContainsKey(varName)) | ||
231 | vars[varName] = varValue; | ||
232 | } | ||
233 | instance.SetVars(vars); | ||
234 | break; | ||
235 | case "Queue": | ||
236 | XmlNodeList itemL = part.ChildNodes; | ||
237 | foreach (XmlNode item in itemL) | ||
238 | { | ||
239 | List<Object> parms = new List<Object>(); | ||
240 | List<DetectParams> detected = | ||
241 | new List<DetectParams>(); | ||
242 | |||
243 | string eventName = | ||
244 | item.Attributes.GetNamedItem("event").Value; | ||
245 | XmlNodeList eventL = item.ChildNodes; | ||
246 | foreach (XmlNode evt in eventL) | ||
247 | { | ||
248 | switch (evt.Name) | ||
249 | { | ||
250 | case "Params": | ||
251 | XmlNodeList prms = evt.ChildNodes; | ||
252 | foreach (XmlNode pm in prms) | ||
253 | parms.Add(ReadTypedValue(pm)); | ||
254 | |||
255 | break; | ||
256 | case "Detected": | ||
257 | XmlNodeList detL = evt.ChildNodes; | ||
258 | foreach (XmlNode det in detL) | ||
259 | { | ||
260 | string vect = | ||
261 | det.Attributes.GetNamedItem( | ||
262 | "pos").Value; | ||
263 | LSL_Types.Vector3 v = | ||
264 | new LSL_Types.Vector3(vect); | ||
265 | |||
266 | int d_linkNum=0; | ||
267 | LLUUID d_group = LLUUID.Zero; | ||
268 | string d_name = String.Empty; | ||
269 | LLUUID d_owner = LLUUID.Zero; | ||
270 | LSL_Types.Vector3 d_position = | ||
271 | new LSL_Types.Vector3(); | ||
272 | LSL_Types.Quaternion d_rotation = | ||
273 | new LSL_Types.Quaternion(); | ||
274 | int d_type = 0; | ||
275 | LSL_Types.Vector3 d_velocity = | ||
276 | new LSL_Types.Vector3(); | ||
277 | |||
278 | try | ||
279 | { | ||
280 | string tmp; | ||
281 | |||
282 | tmp = det.Attributes.GetNamedItem( | ||
283 | "linkNum").Value; | ||
284 | int.TryParse(tmp, out d_linkNum); | ||
285 | |||
286 | tmp = det.Attributes.GetNamedItem( | ||
287 | "group").Value; | ||
288 | LLUUID.TryParse(tmp, out d_group); | ||
289 | |||
290 | d_name = det.Attributes.GetNamedItem( | ||
291 | "name").Value; | ||
292 | |||
293 | tmp = det.Attributes.GetNamedItem( | ||
294 | "owner").Value; | ||
295 | LLUUID.TryParse(tmp, out d_owner); | ||
296 | |||
297 | tmp = det.Attributes.GetNamedItem( | ||
298 | "position").Value; | ||
299 | d_position = | ||
300 | new LSL_Types.Vector3(tmp); | ||
301 | |||
302 | tmp = det.Attributes.GetNamedItem( | ||
303 | "rotation").Value; | ||
304 | d_rotation = | ||
305 | new LSL_Types.Quaternion(tmp); | ||
306 | |||
307 | tmp = det.Attributes.GetNamedItem( | ||
308 | "type").Value; | ||
309 | int.TryParse(tmp, out d_type); | ||
310 | |||
311 | tmp = det.Attributes.GetNamedItem( | ||
312 | "velocity").Value; | ||
313 | d_velocity = | ||
314 | new LSL_Types.Vector3(tmp); | ||
315 | |||
316 | } | ||
317 | catch (Exception) // Old version XML | ||
318 | { | ||
319 | } | ||
320 | |||
321 | LLUUID uuid = new LLUUID(); | ||
322 | LLUUID.TryParse(det.InnerText, | ||
323 | out uuid); | ||
324 | |||
325 | DetectParams d = new DetectParams(); | ||
326 | d.Key = uuid; | ||
327 | d.OffsetPos = v; | ||
328 | d.LinkNum = d_linkNum; | ||
329 | d.Group = d_group; | ||
330 | d.Name = d_name; | ||
331 | d.Owner = d_owner; | ||
332 | d.Position = d_position; | ||
333 | d.Rotation = d_rotation; | ||
334 | d.Type = d_type; | ||
335 | d.Velocity = d_velocity; | ||
336 | |||
337 | detected.Add(d); | ||
338 | } | ||
339 | break; | ||
340 | } | ||
341 | } | ||
342 | EventParams ep = new EventParams( | ||
343 | eventName, parms.ToArray(), | ||
344 | detected.ToArray()); | ||
345 | instance.EventQueue.Enqueue(ep); | ||
346 | } | ||
347 | break; | ||
348 | case "Plugins": | ||
349 | instance.PluginData = ReadList(part).Data; | ||
350 | break; | ||
351 | } | ||
352 | } | ||
353 | } | ||
354 | } | ||
355 | |||
356 | private static void DumpList(XmlDocument doc, XmlNode parent, | ||
357 | LSL_Types.list l) | ||
358 | { | ||
359 | foreach (Object o in l.Data) | ||
360 | WriteTypedValue(doc, parent, "ListItem", "", o); | ||
361 | } | ||
362 | |||
363 | private static LSL_Types.list ReadList(XmlNode parent) | ||
364 | { | ||
365 | List<Object> olist = new List<Object>(); | ||
366 | |||
367 | XmlNodeList itemL = parent.ChildNodes; | ||
368 | foreach (XmlNode item in itemL) | ||
369 | olist.Add(ReadTypedValue(item)); | ||
370 | |||
371 | return new LSL_Types.list(olist.ToArray()); | ||
372 | } | ||
373 | |||
374 | private static void WriteTypedValue(XmlDocument doc, XmlNode parent, | ||
375 | string tag, string name, object value) | ||
376 | { | ||
377 | Type t=value.GetType(); | ||
378 | XmlAttribute typ = doc.CreateAttribute("", "type", ""); | ||
379 | XmlNode n = doc.CreateElement("", tag, ""); | ||
380 | |||
381 | if (value is LSL_Types.list) | ||
382 | { | ||
383 | typ.Value = "list"; | ||
384 | n.Attributes.Append(typ); | ||
385 | |||
386 | DumpList(doc, n, (LSL_Types.list) value); | ||
387 | |||
388 | if (name != String.Empty) | ||
389 | { | ||
390 | XmlAttribute nam = doc.CreateAttribute("", "name", ""); | ||
391 | nam.Value = name; | ||
392 | n.Attributes.Append(nam); | ||
393 | } | ||
394 | |||
395 | parent.AppendChild(n); | ||
396 | return; | ||
397 | } | ||
398 | |||
399 | n.AppendChild(doc.CreateTextNode(value.ToString())); | ||
400 | |||
401 | typ.Value = t.ToString(); | ||
402 | n.Attributes.Append(typ); | ||
403 | if (name != String.Empty) | ||
404 | { | ||
405 | XmlAttribute nam = doc.CreateAttribute("", "name", ""); | ||
406 | nam.Value = name; | ||
407 | n.Attributes.Append(nam); | ||
408 | } | ||
409 | |||
410 | parent.AppendChild(n); | ||
411 | } | ||
412 | |||
413 | private static object ReadTypedValue(XmlNode tag, out string name) | ||
414 | { | ||
415 | name = tag.Attributes.GetNamedItem("name").Value; | ||
416 | |||
417 | return ReadTypedValue(tag); | ||
418 | } | ||
419 | |||
420 | private static object ReadTypedValue(XmlNode tag) | ||
421 | { | ||
422 | Object varValue; | ||
423 | string assembly; | ||
424 | |||
425 | string itemType = tag.Attributes.GetNamedItem("type").Value; | ||
426 | |||
427 | if (itemType == "list") | ||
428 | return ReadList(tag); | ||
429 | |||
430 | if (itemType == "libsecondlife.LLUUID") | ||
431 | { | ||
432 | LLUUID val = new LLUUID(); | ||
433 | LLUUID.TryParse(tag.InnerText, out val); | ||
434 | |||
435 | return val; | ||
436 | } | ||
437 | |||
438 | Type itemT = Type.GetType(itemType); | ||
439 | if (itemT == null) | ||
440 | { | ||
441 | Object[] args = | ||
442 | new Object[] { tag.InnerText }; | ||
443 | |||
444 | assembly = itemType+", OpenSim.Region.ScriptEngine.Shared"; | ||
445 | itemT = Type.GetType(assembly); | ||
446 | if (itemT == null) | ||
447 | return null; | ||
448 | |||
449 | varValue = Activator.CreateInstance(itemT, args); | ||
450 | |||
451 | if (varValue == null) | ||
452 | return null; | ||
453 | } | ||
454 | else | ||
455 | { | ||
456 | varValue = Convert.ChangeType(tag.InnerText, itemT); | ||
457 | } | ||
458 | return varValue; | ||
459 | } | ||
460 | } | ||
461 | } | ||