From 6e3367d68ca6e0e632078dc02f52b03bd034afce Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Wed, 27 Aug 2008 22:38:36 +0000 Subject: Refactor XScriptInstance to IScriptInstance and move into Shared/. Now engines that want to use the XEngine's instance handling and state persistence can do so. IScriptInstance is optional, but it does require the SmartThreadPool if it is used. --- .../Shared/Instance/ScriptSerializer.cs | 461 +++++++++++++++++++++ 1 file changed, 461 insertions(+) create mode 100644 OpenSim/Region/ScriptEngine/Shared/Instance/ScriptSerializer.cs (limited to 'OpenSim/Region/ScriptEngine/Shared/Instance/ScriptSerializer.cs') 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 @@ +/* + * 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 OpenSim 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 libsecondlife; +using log4net; +using Nini.Config; +using Amib.Threading; +using OpenSim.Framework; +using OpenSim.Region.Environment; +using OpenSim.Region.Environment.Scenes; +using OpenSim.Region.Environment.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; + + if (running) + instance.Stop(50); + + 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 vars = instance.GetVars(); + + XmlElement variables = xmldoc.CreateElement("", "Variables", ""); + + foreach (KeyValuePair 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 (running) + instance.Start(); + + return xmldoc.InnerXml; + } + + public static void Deserialize(string xml, ScriptInstance instance) + { + XmlDocument doc = new XmlDocument(); + + Dictionary 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 parms = new List(); + List detected = + new List(); + + 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; + LLUUID d_group = LLUUID.Zero; + string d_name = String.Empty; + LLUUID d_owner = LLUUID.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; + LLUUID.TryParse(tmp, out d_group); + + d_name = det.Attributes.GetNamedItem( + "name").Value; + + tmp = det.Attributes.GetNamedItem( + "owner").Value; + LLUUID.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 + { + } + + LLUUID uuid = new LLUUID(); + LLUUID.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; + } + } + } + } + + 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 olist = new List(); + + 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 == "libsecondlife.LLUUID") + { + LLUUID val = new LLUUID(); + LLUUID.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; + } + } +} -- cgit v1.1