506 lines
20 KiB
C#
506 lines
20 KiB
C#
/*
|
|
* Copyright (c) Contributors, http://opensimulator.org/
|
|
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions are met:
|
|
* * Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer.
|
|
* * Redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
* documentation and/or other materials provided with the distribution.
|
|
* * Neither the name of the OpenSimulator Project nor the
|
|
* names of its contributors may be used to endorse or promote products
|
|
* derived from this software without specific prior written permission.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
*/
|
|
|
|
using System;
|
|
using System.IO;
|
|
using System.Threading;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.Security.Policy;
|
|
using System.Reflection;
|
|
using System.Globalization;
|
|
using System.Xml;
|
|
using OpenMetaverse;
|
|
using log4net;
|
|
using Nini.Config;
|
|
using Amib.Threading;
|
|
using OpenSim.Framework;
|
|
using OpenSim.Region.CoreModules;
|
|
using OpenSim.Region.Framework.Scenes;
|
|
using OpenSim.Region.Framework.Interfaces;
|
|
using OpenSim.Region.ScriptEngine.Shared;
|
|
using OpenSim.Region.ScriptEngine.Shared.Api;
|
|
using OpenSim.Region.ScriptEngine.Shared.ScriptBase;
|
|
using OpenSim.Region.ScriptEngine.Shared.CodeTools;
|
|
using OpenSim.Region.ScriptEngine.Interfaces;
|
|
|
|
namespace OpenSim.Region.ScriptEngine.Shared.Instance
|
|
{
|
|
public class ScriptSerializer
|
|
{
|
|
public static string Serialize(ScriptInstance instance)
|
|
{
|
|
bool running = instance.Running;
|
|
|
|
XmlDocument xmldoc = new XmlDocument();
|
|
|
|
XmlNode xmlnode = xmldoc.CreateNode(XmlNodeType.XmlDeclaration,
|
|
"", "");
|
|
xmldoc.AppendChild(xmlnode);
|
|
|
|
XmlElement rootElement = xmldoc.CreateElement("", "ScriptState",
|
|
"");
|
|
xmldoc.AppendChild(rootElement);
|
|
|
|
XmlElement state = xmldoc.CreateElement("", "State", "");
|
|
state.AppendChild(xmldoc.CreateTextNode(instance.State));
|
|
|
|
rootElement.AppendChild(state);
|
|
|
|
XmlElement run = xmldoc.CreateElement("", "Running", "");
|
|
run.AppendChild(xmldoc.CreateTextNode(
|
|
running.ToString()));
|
|
|
|
rootElement.AppendChild(run);
|
|
|
|
Dictionary<string, Object> vars = instance.GetVars();
|
|
|
|
XmlElement variables = xmldoc.CreateElement("", "Variables", "");
|
|
|
|
foreach (KeyValuePair<string, Object> var in vars)
|
|
WriteTypedValue(xmldoc, variables, "Variable", var.Key,
|
|
var.Value);
|
|
|
|
rootElement.AppendChild(variables);
|
|
|
|
XmlElement queue = xmldoc.CreateElement("", "Queue", "");
|
|
|
|
int count = instance.EventQueue.Count;
|
|
|
|
while (count > 0)
|
|
{
|
|
EventParams ep = (EventParams)instance.EventQueue.Dequeue();
|
|
instance.EventQueue.Enqueue(ep);
|
|
count--;
|
|
|
|
XmlElement item = xmldoc.CreateElement("", "Item", "");
|
|
XmlAttribute itemEvent = xmldoc.CreateAttribute("", "event",
|
|
"");
|
|
itemEvent.Value = ep.EventName;
|
|
item.Attributes.Append(itemEvent);
|
|
|
|
XmlElement parms = xmldoc.CreateElement("", "Params", "");
|
|
|
|
foreach (Object o in ep.Params)
|
|
WriteTypedValue(xmldoc, parms, "Param", String.Empty, o);
|
|
|
|
item.AppendChild(parms);
|
|
|
|
XmlElement detect = xmldoc.CreateElement("", "Detected", "");
|
|
|
|
foreach (DetectParams det in ep.DetectParams)
|
|
{
|
|
XmlElement objectElem = xmldoc.CreateElement("", "Object",
|
|
"");
|
|
XmlAttribute pos = xmldoc.CreateAttribute("", "pos", "");
|
|
pos.Value = det.OffsetPos.ToString();
|
|
objectElem.Attributes.Append(pos);
|
|
|
|
XmlAttribute d_linkNum = xmldoc.CreateAttribute("",
|
|
"linkNum", "");
|
|
d_linkNum.Value = det.LinkNum.ToString();
|
|
objectElem.Attributes.Append(d_linkNum);
|
|
|
|
XmlAttribute d_group = xmldoc.CreateAttribute("",
|
|
"group", "");
|
|
d_group.Value = det.Group.ToString();
|
|
objectElem.Attributes.Append(d_group);
|
|
|
|
XmlAttribute d_name = xmldoc.CreateAttribute("",
|
|
"name", "");
|
|
d_name.Value = det.Name.ToString();
|
|
objectElem.Attributes.Append(d_name);
|
|
|
|
XmlAttribute d_owner = xmldoc.CreateAttribute("",
|
|
"owner", "");
|
|
d_owner.Value = det.Owner.ToString();
|
|
objectElem.Attributes.Append(d_owner);
|
|
|
|
XmlAttribute d_position = xmldoc.CreateAttribute("",
|
|
"position", "");
|
|
d_position.Value = det.Position.ToString();
|
|
objectElem.Attributes.Append(d_position);
|
|
|
|
XmlAttribute d_rotation = xmldoc.CreateAttribute("",
|
|
"rotation", "");
|
|
d_rotation.Value = det.Rotation.ToString();
|
|
objectElem.Attributes.Append(d_rotation);
|
|
|
|
XmlAttribute d_type = xmldoc.CreateAttribute("",
|
|
"type", "");
|
|
d_type.Value = det.Type.ToString();
|
|
objectElem.Attributes.Append(d_type);
|
|
|
|
XmlAttribute d_velocity = xmldoc.CreateAttribute("",
|
|
"velocity", "");
|
|
d_velocity.Value = det.Velocity.ToString();
|
|
objectElem.Attributes.Append(d_velocity);
|
|
|
|
objectElem.AppendChild(
|
|
xmldoc.CreateTextNode(det.Key.ToString()));
|
|
|
|
detect.AppendChild(objectElem);
|
|
}
|
|
|
|
item.AppendChild(detect);
|
|
|
|
queue.AppendChild(item);
|
|
}
|
|
|
|
rootElement.AppendChild(queue);
|
|
|
|
XmlNode plugins = xmldoc.CreateElement("", "Plugins", "");
|
|
DumpList(xmldoc, plugins,
|
|
new LSL_Types.list(instance.PluginData));
|
|
|
|
rootElement.AppendChild(plugins);
|
|
|
|
if (instance.ScriptTask != null)
|
|
{
|
|
if (instance.ScriptTask.PermsMask != 0 && instance.ScriptTask.PermsGranter != UUID.Zero)
|
|
{
|
|
XmlNode permissions = xmldoc.CreateElement("", "Permissions", "");
|
|
XmlAttribute granter = xmldoc.CreateAttribute("", "granter", "");
|
|
granter.Value = instance.ScriptTask.PermsGranter.ToString();
|
|
permissions.Attributes.Append(granter);
|
|
XmlAttribute mask = xmldoc.CreateAttribute("", "mask", "");
|
|
mask.Value = instance.ScriptTask.PermsMask.ToString();
|
|
permissions.Attributes.Append(mask);
|
|
rootElement.AppendChild(permissions);
|
|
}
|
|
}
|
|
|
|
if (instance.MinEventDelay > 0.0)
|
|
{
|
|
XmlElement eventDelay = xmldoc.CreateElement("", "MinEventDelay", "");
|
|
eventDelay.AppendChild(xmldoc.CreateTextNode(instance.MinEventDelay.ToString()));
|
|
rootElement.AppendChild(eventDelay);
|
|
}
|
|
|
|
return xmldoc.InnerXml;
|
|
}
|
|
|
|
public static void Deserialize(string xml, ScriptInstance instance)
|
|
{
|
|
XmlDocument doc = new XmlDocument();
|
|
|
|
Dictionary<string, object> vars = instance.GetVars();
|
|
|
|
instance.PluginData = new Object[0];
|
|
|
|
doc.LoadXml(xml);
|
|
|
|
XmlNodeList rootL = doc.GetElementsByTagName("ScriptState");
|
|
if (rootL.Count != 1)
|
|
{
|
|
return;
|
|
}
|
|
XmlNode rootNode = rootL[0];
|
|
|
|
if (rootNode != null)
|
|
{
|
|
object varValue;
|
|
XmlNodeList partL = rootNode.ChildNodes;
|
|
|
|
foreach (XmlNode part in partL)
|
|
{
|
|
switch (part.Name)
|
|
{
|
|
case "State":
|
|
instance.State=part.InnerText;
|
|
break;
|
|
case "Running":
|
|
instance.Running=bool.Parse(part.InnerText);
|
|
break;
|
|
case "Variables":
|
|
XmlNodeList varL = part.ChildNodes;
|
|
foreach (XmlNode var in varL)
|
|
{
|
|
string varName;
|
|
varValue=ReadTypedValue(var, out varName);
|
|
|
|
if (vars.ContainsKey(varName))
|
|
vars[varName] = varValue;
|
|
}
|
|
instance.SetVars(vars);
|
|
break;
|
|
case "Queue":
|
|
XmlNodeList itemL = part.ChildNodes;
|
|
foreach (XmlNode item in itemL)
|
|
{
|
|
List<Object> parms = new List<Object>();
|
|
List<DetectParams> detected =
|
|
new List<DetectParams>();
|
|
|
|
string eventName =
|
|
item.Attributes.GetNamedItem("event").Value;
|
|
XmlNodeList eventL = item.ChildNodes;
|
|
foreach (XmlNode evt in eventL)
|
|
{
|
|
switch (evt.Name)
|
|
{
|
|
case "Params":
|
|
XmlNodeList prms = evt.ChildNodes;
|
|
foreach (XmlNode pm in prms)
|
|
parms.Add(ReadTypedValue(pm));
|
|
|
|
break;
|
|
case "Detected":
|
|
XmlNodeList detL = evt.ChildNodes;
|
|
foreach (XmlNode det in detL)
|
|
{
|
|
string vect =
|
|
det.Attributes.GetNamedItem(
|
|
"pos").Value;
|
|
LSL_Types.Vector3 v =
|
|
new LSL_Types.Vector3(vect);
|
|
|
|
int d_linkNum=0;
|
|
UUID d_group = UUID.Zero;
|
|
string d_name = String.Empty;
|
|
UUID d_owner = UUID.Zero;
|
|
LSL_Types.Vector3 d_position =
|
|
new LSL_Types.Vector3();
|
|
LSL_Types.Quaternion d_rotation =
|
|
new LSL_Types.Quaternion();
|
|
int d_type = 0;
|
|
LSL_Types.Vector3 d_velocity =
|
|
new LSL_Types.Vector3();
|
|
|
|
try
|
|
{
|
|
string tmp;
|
|
|
|
tmp = det.Attributes.GetNamedItem(
|
|
"linkNum").Value;
|
|
int.TryParse(tmp, out d_linkNum);
|
|
|
|
tmp = det.Attributes.GetNamedItem(
|
|
"group").Value;
|
|
UUID.TryParse(tmp, out d_group);
|
|
|
|
d_name = det.Attributes.GetNamedItem(
|
|
"name").Value;
|
|
|
|
tmp = det.Attributes.GetNamedItem(
|
|
"owner").Value;
|
|
UUID.TryParse(tmp, out d_owner);
|
|
|
|
tmp = det.Attributes.GetNamedItem(
|
|
"position").Value;
|
|
d_position =
|
|
new LSL_Types.Vector3(tmp);
|
|
|
|
tmp = det.Attributes.GetNamedItem(
|
|
"rotation").Value;
|
|
d_rotation =
|
|
new LSL_Types.Quaternion(tmp);
|
|
|
|
tmp = det.Attributes.GetNamedItem(
|
|
"type").Value;
|
|
int.TryParse(tmp, out d_type);
|
|
|
|
tmp = det.Attributes.GetNamedItem(
|
|
"velocity").Value;
|
|
d_velocity =
|
|
new LSL_Types.Vector3(tmp);
|
|
|
|
}
|
|
catch (Exception) // Old version XML
|
|
{
|
|
}
|
|
|
|
UUID uuid = new UUID();
|
|
UUID.TryParse(det.InnerText,
|
|
out uuid);
|
|
|
|
DetectParams d = new DetectParams();
|
|
d.Key = uuid;
|
|
d.OffsetPos = v;
|
|
d.LinkNum = d_linkNum;
|
|
d.Group = d_group;
|
|
d.Name = d_name;
|
|
d.Owner = d_owner;
|
|
d.Position = d_position;
|
|
d.Rotation = d_rotation;
|
|
d.Type = d_type;
|
|
d.Velocity = d_velocity;
|
|
|
|
detected.Add(d);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
EventParams ep = new EventParams(
|
|
eventName, parms.ToArray(),
|
|
detected.ToArray());
|
|
instance.EventQueue.Enqueue(ep);
|
|
}
|
|
break;
|
|
case "Plugins":
|
|
instance.PluginData = ReadList(part).Data;
|
|
break;
|
|
case "Permissions":
|
|
string tmpPerm;
|
|
int mask = 0;
|
|
tmpPerm = part.Attributes.GetNamedItem("mask").Value;
|
|
if (tmpPerm != null)
|
|
{
|
|
int.TryParse(tmpPerm, out mask);
|
|
if (mask != 0)
|
|
{
|
|
tmpPerm = part.Attributes.GetNamedItem("granter").Value;
|
|
if (tmpPerm != null)
|
|
{
|
|
UUID granter = new UUID();
|
|
UUID.TryParse(tmpPerm, out granter);
|
|
if (granter != UUID.Zero)
|
|
{
|
|
instance.ScriptTask.PermsMask = mask;
|
|
instance.ScriptTask.PermsGranter = granter;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
case "MinEventDelay":
|
|
double minEventDelay = 0.0;
|
|
double.TryParse(part.InnerText, NumberStyles.Float, Culture.NumberFormatInfo, out minEventDelay);
|
|
instance.MinEventDelay = minEventDelay;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private static void DumpList(XmlDocument doc, XmlNode parent,
|
|
LSL_Types.list l)
|
|
{
|
|
foreach (Object o in l.Data)
|
|
WriteTypedValue(doc, parent, "ListItem", "", o);
|
|
}
|
|
|
|
private static LSL_Types.list ReadList(XmlNode parent)
|
|
{
|
|
List<Object> olist = new List<Object>();
|
|
|
|
XmlNodeList itemL = parent.ChildNodes;
|
|
foreach (XmlNode item in itemL)
|
|
olist.Add(ReadTypedValue(item));
|
|
|
|
return new LSL_Types.list(olist.ToArray());
|
|
}
|
|
|
|
private static void WriteTypedValue(XmlDocument doc, XmlNode parent,
|
|
string tag, string name, object value)
|
|
{
|
|
Type t=value.GetType();
|
|
XmlAttribute typ = doc.CreateAttribute("", "type", "");
|
|
XmlNode n = doc.CreateElement("", tag, "");
|
|
|
|
if (value is LSL_Types.list)
|
|
{
|
|
typ.Value = "list";
|
|
n.Attributes.Append(typ);
|
|
|
|
DumpList(doc, n, (LSL_Types.list) value);
|
|
|
|
if (name != String.Empty)
|
|
{
|
|
XmlAttribute nam = doc.CreateAttribute("", "name", "");
|
|
nam.Value = name;
|
|
n.Attributes.Append(nam);
|
|
}
|
|
|
|
parent.AppendChild(n);
|
|
return;
|
|
}
|
|
|
|
n.AppendChild(doc.CreateTextNode(value.ToString()));
|
|
|
|
typ.Value = t.ToString();
|
|
n.Attributes.Append(typ);
|
|
if (name != String.Empty)
|
|
{
|
|
XmlAttribute nam = doc.CreateAttribute("", "name", "");
|
|
nam.Value = name;
|
|
n.Attributes.Append(nam);
|
|
}
|
|
|
|
parent.AppendChild(n);
|
|
}
|
|
|
|
private static object ReadTypedValue(XmlNode tag, out string name)
|
|
{
|
|
name = tag.Attributes.GetNamedItem("name").Value;
|
|
|
|
return ReadTypedValue(tag);
|
|
}
|
|
|
|
private static object ReadTypedValue(XmlNode tag)
|
|
{
|
|
Object varValue;
|
|
string assembly;
|
|
|
|
string itemType = tag.Attributes.GetNamedItem("type").Value;
|
|
|
|
if (itemType == "list")
|
|
return ReadList(tag);
|
|
|
|
if (itemType == "OpenMetaverse.UUID")
|
|
{
|
|
UUID val = new UUID();
|
|
UUID.TryParse(tag.InnerText, out val);
|
|
|
|
return val;
|
|
}
|
|
|
|
Type itemT = Type.GetType(itemType);
|
|
if (itemT == null)
|
|
{
|
|
Object[] args =
|
|
new Object[] { tag.InnerText };
|
|
|
|
assembly = itemType+", OpenSim.Region.ScriptEngine.Shared";
|
|
itemT = Type.GetType(assembly);
|
|
if (itemT == null)
|
|
return null;
|
|
|
|
varValue = Activator.CreateInstance(itemT, args);
|
|
|
|
if (varValue == null)
|
|
return null;
|
|
}
|
|
else
|
|
{
|
|
varValue = Convert.ChangeType(tag.InnerText, itemT);
|
|
}
|
|
return varValue;
|
|
}
|
|
}
|
|
}
|