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