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. --- OpenSim/Region/ScriptEngine/XEngine/XEngine.cs | 1076 +----------------------- 1 file changed, 28 insertions(+), 1048 deletions(-) (limited to 'OpenSim/Region/ScriptEngine/XEngine') diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs index cfe0599..c5bcfd5 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs @@ -46,6 +46,7 @@ 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.Shared.Instance; using OpenSim.Region.ScriptEngine.Interfaces; namespace OpenSim.Region.ScriptEngine.XEngine @@ -67,7 +68,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine #pragma warning restore 414 private int m_EventLimit; private bool m_KillTimedOutScripts; - public AsyncCommandManager m_AsyncCommands; + private AsyncCommandManager m_AsyncCommands; bool m_firstStart = true; private static List m_ScriptEngines = @@ -80,8 +81,8 @@ namespace OpenSim.Region.ScriptEngine.XEngine // Maps the LLUUID above to the script instance - private Dictionary m_Scripts = - new Dictionary(); + private Dictionary m_Scripts = + new Dictionary(); // Maps the asset ID to the assembly @@ -254,15 +255,15 @@ namespace OpenSim.Region.ScriptEngine.XEngine // m_log.Debug("[XEngine] Backing up script states"); - List instances = new List(); + List instances = new List(); lock (m_Scripts) { - foreach (XScriptInstance instance in m_Scripts.Values) + foreach (IScriptInstance instance in m_Scripts.Values) instances.Add(instance); } - foreach (XScriptInstance i in instances) + foreach (IScriptInstance i in instances) { string assembly = String.Empty; @@ -289,7 +290,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine object[] parms = (object[])p; int sleepTime = (int)parms[0]; - foreach (XScriptInstance inst in m_Scripts.Values) + foreach (IScriptInstance inst in m_Scripts.Values) { if (inst.EventTime() > m_EventLimit) { @@ -502,12 +503,12 @@ namespace OpenSim.Region.ScriptEngine.XEngine } m_DomainScripts[appDomain].Add(itemID); - XScriptInstance instance = new XScriptInstance(this,localID, + ScriptInstance instance = new ScriptInstance(this,localID, part.UUID, itemID, assetID, assembly, m_AppDomains[appDomain], part.ParentGroup.RootPart.Name, item.Name, startParam, postOnRez, - XScriptInstance.StateSource.NewRez); + StateSource.NewRez); m_log.DebugFormat("[XEngine] Loaded script {0}.{1}", part.ParentGroup.RootPart.Name, item.Name); @@ -539,7 +540,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine m_AsyncCommands.RemoveScript(localID, itemID); - XScriptInstance instance=m_Scripts[itemID]; + IScriptInstance instance=m_Scripts[itemID]; m_Scripts.Remove(itemID); instance.ClearQueue(); @@ -599,7 +600,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine { List assetIDList = new List(m_Assemblies.Keys); - foreach (XScriptInstance i in m_Scripts.Values) + foreach (IScriptInstance i in m_Scripts.Values) { if (assetIDList.Contains(i.AssetID)) assetIDList.Remove(i.AssetID); @@ -676,7 +677,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine CultureInfo USCulture = new CultureInfo("en-US"); Thread.CurrentThread.CurrentCulture = USCulture; - XScriptInstance instance = (XScriptInstance) parms; + IScriptInstance instance = (ScriptInstance) parms; return instance.EventProcessor(); } @@ -695,7 +696,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine { if (m_Scripts.ContainsKey(itemID)) { - XScriptInstance instance = m_Scripts[itemID]; + IScriptInstance instance = m_Scripts[itemID]; if (instance != null) { instance.PostEvent(p); @@ -713,7 +714,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine { if (m_Scripts.ContainsKey(itemID)) { - XScriptInstance instance = m_Scripts[itemID]; + IScriptInstance instance = m_Scripts[itemID]; if (instance != null) instance.PostEvent(p); return true; @@ -747,9 +748,9 @@ namespace OpenSim.Region.ScriptEngine.XEngine return null; } - private XScriptInstance GetInstance(LLUUID itemID) + private IScriptInstance GetInstance(LLUUID itemID) { - XScriptInstance instance; + IScriptInstance instance; lock (m_Scripts) { if (!m_Scripts.ContainsKey(itemID)) @@ -761,7 +762,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine public void SetScriptState(LLUUID itemID, bool running) { - XScriptInstance instance = GetInstance(itemID); + IScriptInstance instance = GetInstance(itemID); if (instance != null) { if (running) @@ -773,7 +774,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine public bool GetScriptState(LLUUID itemID) { - XScriptInstance instance = GetInstance(itemID); + IScriptInstance instance = GetInstance(itemID); if (instance != null) return instance.Running; return false; @@ -781,35 +782,35 @@ namespace OpenSim.Region.ScriptEngine.XEngine public void ApiResetScript(LLUUID itemID) { - XScriptInstance instance = GetInstance(itemID); + IScriptInstance instance = GetInstance(itemID); if (instance != null) instance.ApiResetScript(); } public void ResetScript(LLUUID itemID) { - XScriptInstance instance = GetInstance(itemID); + IScriptInstance instance = GetInstance(itemID); if (instance != null) instance.ResetScript(); } public void StartScript(LLUUID itemID) { - XScriptInstance instance = GetInstance(itemID); + IScriptInstance instance = GetInstance(itemID); if (instance != null) instance.Start(); } public void StopScript(LLUUID itemID) { - XScriptInstance instance = GetInstance(itemID); + IScriptInstance instance = GetInstance(itemID); if (instance != null) instance.Stop(0); } public DetectParams GetDetectParams(LLUUID itemID, int idx) { - XScriptInstance instance = GetInstance(itemID); + IScriptInstance instance = GetInstance(itemID); if (instance != null) return instance.GetDetectParams(idx); return null; @@ -817,7 +818,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine public LLUUID GetDetectID(LLUUID itemID, int idx) { - XScriptInstance instance = GetInstance(itemID); + IScriptInstance instance = GetInstance(itemID); if (instance != null) return instance.GetDetectID(idx); return LLUUID.Zero; @@ -825,14 +826,14 @@ namespace OpenSim.Region.ScriptEngine.XEngine public void SetState(LLUUID itemID, string newState) { - XScriptInstance instance = GetInstance(itemID); + IScriptInstance instance = GetInstance(itemID); if (instance == null) return; instance.SetState(newState); } public string GetState(LLUUID itemID) { - XScriptInstance instance = GetInstance(itemID); + IScriptInstance instance = GetInstance(itemID); if (instance == null) return "default"; return instance.State; @@ -840,7 +841,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine public int GetStartParameter(LLUUID itemID) { - XScriptInstance instance = GetInstance(itemID); + IScriptInstance instance = GetInstance(itemID); if (instance == null) return 0; return instance.StartParam; @@ -851,1025 +852,4 @@ namespace OpenSim.Region.ScriptEngine.XEngine return GetScriptState(itemID); } } - - public class XScriptInstance - { - private XEngine m_Engine; - private IWorkItemResult m_CurrentResult=null; - private Queue m_EventQueue = new Queue(32); - private bool m_RunEvents = false; - private LLUUID m_ItemID; - private uint m_LocalID; - private LLUUID m_ObjectID; - private LLUUID m_AssetID; - private IScript m_Script; - private LLUUID m_AppDomain; - private DetectParams[] m_DetectParams; - private bool m_TimerQueued; - private DateTime m_EventStart; - private bool m_InEvent; - private string m_PrimName; - private string m_ScriptName; - private string m_Assembly; - private int m_StartParam = 0; - private string m_CurrentEvent = String.Empty; - private bool m_InSelfDelete = false; - - private Dictionary m_Apis = new Dictionary(); - - public enum StateSource - { - NewRez = 0, - PrimCrossing = 1, - AttachmentCrossing = 2 - } - - // Script state - private string m_State="default"; - - public Object[] PluginData = new Object[0]; - - public bool Running - { - get { return m_RunEvents; } - set { m_RunEvents = value; } - } - - public string State - { - get { return m_State; } - set { m_State = value; } - } - - public XEngine Engine - { - get { return m_Engine; } - } - - public LLUUID AppDomain - { - get { return m_AppDomain; } - set { m_AppDomain = value; } - } - - public string PrimName - { - get { return m_PrimName; } - } - - public string ScriptName - { - get { return m_ScriptName; } - } - - public LLUUID ItemID - { - get { return m_ItemID; } - } - - public LLUUID ObjectID - { - get { return m_ObjectID; } - } - - public uint LocalID - { - get { return m_LocalID; } - } - - public LLUUID AssetID - { - get { return m_AssetID; } - } - - public Queue EventQueue - { - get { return m_EventQueue; } - } - - public void ClearQueue() - { - m_TimerQueued = false; - m_EventQueue.Clear(); - } - - public int StartParam - { - get { return m_StartParam; } - set { m_StartParam = value; } - } - - public XScriptInstance(XEngine engine, uint localID, LLUUID objectID, - LLUUID itemID, LLUUID assetID, string assembly, AppDomain dom, - string primName, string scriptName, int startParam, - bool postOnRez, StateSource stateSource) - { - m_Engine = engine; - - m_LocalID = localID; - m_ObjectID = objectID; - m_ItemID = itemID; - m_AssetID = assetID; - m_PrimName = primName; - m_ScriptName = scriptName; - m_Assembly = assembly; - m_StartParam = startParam; - - ApiManager am = new ApiManager(); - - SceneObjectPart part=engine.World.GetSceneObjectPart(localID); - if (part == null) - { - engine.Log.Error("[XEngine] SceneObjectPart unavailable. Script NOT started."); - return; - } - - foreach (string api in am.GetApis()) - { - m_Apis[api] = am.CreateApi(api); - m_Apis[api].Initialize(engine, part, localID, itemID); - } - - try - { - m_Script = (IScript)dom.CreateInstanceAndUnwrap( - Path.GetFileNameWithoutExtension(assembly), - "SecondLife.Script"); - } - catch (Exception e) - { - m_Engine.Log.ErrorFormat("[XEngine] Error loading assembly {0}\n"+e.ToString(), assembly); - } - - try - { - foreach (KeyValuePair kv in m_Apis) - { - m_Script.InitApi(kv.Key, kv.Value); - } - -// m_Engine.Log.Debug("[XEngine] Script instance created"); - - part.SetScriptEvents(m_ItemID, - (int)m_Script.GetStateEventFlags(State)); - } - catch (Exception e) - { - m_Engine.Log.Error("[XEngine] Error loading script instance\n"+e.ToString()); - return; - } - - string savedState = Path.Combine(Path.GetDirectoryName(assembly), - m_ItemID.ToString() + ".state"); - if (File.Exists(savedState)) - { - string xml = String.Empty; - - try - { - FileInfo fi = new FileInfo(savedState); - int size=(int)fi.Length; - if (size < 512000) - { - using (FileStream fs = File.Open(savedState, - FileMode.Open, FileAccess.Read, FileShare.None)) - { - System.Text.ASCIIEncoding enc = - new System.Text.ASCIIEncoding(); - - Byte[] data = new Byte[size]; - fs.Read(data, 0, size); - - xml = enc.GetString(data); - - ScriptSerializer.Deserialize(xml, this); - - m_Engine.m_AsyncCommands.CreateFromData( - m_LocalID, m_ItemID, m_ObjectID, - PluginData); - - m_Engine.Log.DebugFormat("[XEngine] Successfully retrieved state for script {0}.{1}", m_PrimName, m_ScriptName); - - if (m_RunEvents) - { - m_RunEvents = false; - Start(); - if (postOnRez) - PostEvent(new EventParams("on_rez", - new Object[] {new LSL_Types.LSLInteger(startParam)}, new DetectParams[0])); - } - - // we get new rez events on sim restart, too - // but if there is state, then we fire the change - // event - if (stateSource == StateSource.NewRez) - { -// m_Engine.Log.Debug("[XEngine] Posted changed(CHANGED_REGION_RESTART) to script"); - PostEvent(new EventParams("changed", - new Object[] {new LSL_Types.LSLInteger(256)}, new DetectParams[0])); - } - } - } - else - { - m_Engine.Log.Error("[XEngine] Unable to load script state: Memory limit exceeded"); - Start(); - PostEvent(new EventParams("state_entry", - new Object[0], new DetectParams[0])); - if (postOnRez) - PostEvent(new EventParams("on_rez", - new Object[] {new LSL_Types.LSLInteger(startParam)}, new DetectParams[0])); - - } - } - catch (Exception e) - { - m_Engine.Log.ErrorFormat("[XEngine] Unable to load script state from xml: {0}\n"+e.ToString(), xml); - Start(); - PostEvent(new EventParams("state_entry", - new Object[0], new DetectParams[0])); - if (postOnRez) - PostEvent(new EventParams("on_rez", - new Object[] {new LSL_Types.LSLInteger(startParam)}, new DetectParams[0])); - } - } - else - { -// m_Engine.Log.ErrorFormat("[XEngine] Unable to load script state, file not found"); - Start(); - PostEvent(new EventParams("state_entry", - new Object[0], new DetectParams[0])); - - if (postOnRez) - PostEvent(new EventParams("on_rez", - new Object[] {new LSL_Types.LSLInteger(startParam)}, new DetectParams[0])); - } - } - - public void RemoveState() - { - string savedState = Path.Combine(Path.GetDirectoryName(m_Assembly), - m_ItemID.ToString() + ".state"); - - try - { - File.Delete(savedState); - } - catch(Exception) - { - } - } - - public void VarDump(Dictionary vars) - { - Console.WriteLine("Variable dump for script {0}", m_ItemID.ToString()); - foreach (KeyValuePair v in vars) - { - Console.WriteLine("Variable: {0} = '{1}'", v. Key, - v.Value.ToString()); - } - } - - public void Start() - { - lock (m_EventQueue) - { - if (Running) - return; - - m_RunEvents = true; - - if (m_EventQueue.Count > 0) - { - if (m_CurrentResult == null) - m_CurrentResult = m_Engine.QueueEventHandler(this); - else - m_Engine.Log.Error("[XEngine] Tried to start a script that was already queued"); - } - } - } - - public bool Stop(int timeout) - { - IWorkItemResult result; - - lock (m_EventQueue) - { - if (!Running) - return true; - - if (m_CurrentResult == null) - { - m_RunEvents = false; - return true; - } - - if (m_CurrentResult.Cancel()) - { - m_CurrentResult = null; - m_RunEvents = false; - return true; - } - - result = m_CurrentResult; - m_RunEvents = false; - } - - if (SmartThreadPool.WaitAll(new IWorkItemResult[] {result}, new TimeSpan((long)timeout * 100000), false)) - { - return true; - } - - lock (m_EventQueue) - { - result = m_CurrentResult; - } - - if (result == null) - return true; - - if (!m_InSelfDelete) - result.Abort(); - - lock (m_EventQueue) - { - m_CurrentResult = null; - } - - return true; - } - - public void SetState(string state) - { - PostEvent(new EventParams("state_exit", new Object[0], - new DetectParams[0])); - PostEvent(new EventParams("state", new Object[] { state }, - new DetectParams[0])); - PostEvent(new EventParams("state_entry", new Object[0], - new DetectParams[0])); - } - - public void PostEvent(EventParams data) - { -// m_Engine.Log.DebugFormat("[XEngine] Posted event {2} in state {3} to {0}.{1}", -// m_PrimName, m_ScriptName, data.EventName, m_State); - - if (!Running) - return; - - lock (m_EventQueue) - { - if (m_EventQueue.Count >= m_Engine.MaxScriptQueue) - return; - - m_EventQueue.Enqueue(data); - if (data.EventName == "timer") - { - if (m_TimerQueued) - return; - m_TimerQueued = true; - } - - if (!m_RunEvents) - return; - - if (m_CurrentResult == null) - { - m_CurrentResult = m_Engine.QueueEventHandler(this); - } - } - } - - public object EventProcessor() - { - EventParams data = null; - - lock (m_EventQueue) - { - data = (EventParams) m_EventQueue.Dequeue(); - if (data == null) // Shouldn't happen - { - m_CurrentResult = null; - return 0; - } - if (data.EventName == "timer") - m_TimerQueued = false; - } - - m_DetectParams = data.DetectParams; - - if (data.EventName == "state") // Hardcoded state change - { -// m_Engine.Log.DebugFormat("[XEngine] Script {0}.{1} state set to {2}", -// m_PrimName, m_ScriptName, data.Params[0].ToString()); - m_State=data.Params[0].ToString(); - m_Engine.m_AsyncCommands.RemoveScript( - m_LocalID, m_ItemID); - - SceneObjectPart part = m_Engine.World.GetSceneObjectPart( - m_LocalID); - if (part != null) - { - part.SetScriptEvents(m_ItemID, - (int)m_Script.GetStateEventFlags(State)); - } - } - else - { - SceneObjectPart part = m_Engine.World.GetSceneObjectPart( - m_LocalID); -// m_Engine.Log.DebugFormat("[XEngine] Delivered event {2} in state {3} to {0}.{1}", -// m_PrimName, m_ScriptName, data.EventName, m_State); - - try - { - m_CurrentEvent = data.EventName; - m_EventStart = DateTime.Now; - m_InEvent = true; - - m_Script.ExecuteEvent(State, data.EventName, data.Params); - - m_InEvent = false; - m_CurrentEvent = String.Empty; - } - catch (Exception e) - { - m_InEvent = false; - m_CurrentEvent = String.Empty; - - if (!(e is TargetInvocationException) || (!(e.InnerException is EventAbortException) && (!(e.InnerException is SelfDeleteException)))) - { - if (e is System.Threading.ThreadAbortException) - { - lock (m_EventQueue) - { - if ((m_EventQueue.Count > 0) && m_RunEvents) - { - m_CurrentResult=m_Engine.QueueEventHandler(this); - } - else - { - m_CurrentResult = null; - } - } - - m_DetectParams = null; - - return 0; - } - - try - { - // DISPLAY ERROR INWORLD - string text = "Runtime error:\n" + e.ToString(); - if (text.Length > 1400) - text = text.Substring(0, 1400); - m_Engine.World.SimChat(Helpers.StringToField(text), - ChatTypeEnum.DebugChannel, 2147483647, - part.AbsolutePosition, - part.Name, part.UUID, false); - } - catch (Exception e2) // LEGIT: User Scripting - { - m_Engine.Log.Error("[XEngine]: "+ - "Error displaying error in-world: " + - e2.ToString()); - m_Engine.Log.Error("[XEngine]: " + - "Errormessage: Error compiling script:\r\n" + - e.ToString()); - } - } - else if ((e is TargetInvocationException) && (e.InnerException is SelfDeleteException)) - { - m_InSelfDelete = true; - if (part != null && part.ParentGroup != null) - m_Engine.World.DeleteSceneObject(part.ParentGroup); - } - } - } - - lock (m_EventQueue) - { - if ((m_EventQueue.Count > 0) && m_RunEvents) - { - m_CurrentResult = m_Engine.QueueEventHandler(this); - } - else - { - m_CurrentResult = null; - } - } - - m_DetectParams = null; - - return 0; - } - - public int EventTime() - { - if (!m_InEvent) - return 0; - - return (DateTime.Now - m_EventStart).Seconds; - } - - public void ResetScript() - { - bool running = Running; - - RemoveState(); - - Stop(0); - SceneObjectPart part=m_Engine.World.GetSceneObjectPart(m_LocalID); - part.GetInventoryItem(m_ItemID).PermsMask = 0; - part.GetInventoryItem(m_ItemID).PermsGranter = LLUUID.Zero; - m_Engine.m_AsyncCommands.RemoveScript(m_LocalID, m_ItemID); - m_EventQueue.Clear(); - m_Script.ResetVars(); - m_State = "default"; - if (running) - Start(); - PostEvent(new EventParams("state_entry", - new Object[0], new DetectParams[0])); - } - - public void ApiResetScript() - { - // bool running = Running; - - RemoveState(); - - m_Script.ResetVars(); - SceneObjectPart part=m_Engine.World.GetSceneObjectPart(m_LocalID); - part.GetInventoryItem(m_ItemID).PermsMask = 0; - part.GetInventoryItem(m_ItemID).PermsGranter = LLUUID.Zero; - m_Engine.m_AsyncCommands.RemoveScript(m_LocalID, m_ItemID); - if (m_CurrentEvent != "state_entry") - { - PostEvent(new EventParams("state_entry", - new Object[0], new DetectParams[0])); - } - } - - public Dictionary GetVars() - { - return m_Script.GetVars(); - } - - public void SetVars(Dictionary vars) - { - m_Script.SetVars(vars); - } - - public DetectParams GetDetectParams(int idx) - { - if (idx < 0 || idx >= m_DetectParams.Length) - return null; - - return m_DetectParams[idx]; - } - - public LLUUID GetDetectID(int idx) - { - if (idx < 0 || idx >= m_DetectParams.Length) - return LLUUID.Zero; - - return m_DetectParams[idx].Key; - } - - public void SaveState(string assembly) - { - PluginData = - m_Engine.m_AsyncCommands.GetSerializationData( - m_ItemID); - - string xml = ScriptSerializer.Serialize(this); - - try - { - FileStream fs = File.Create(Path.Combine(Path.GetDirectoryName(assembly), m_ItemID.ToString() + ".state")); - System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding(); - Byte[] buf = enc.GetBytes(xml); - fs.Write(buf, 0, buf.Length); - fs.Close(); - } - catch(Exception e) - { - Console.WriteLine("Unable to save xml\n"+e.ToString()); - } - if (!File.Exists(Path.Combine(Path.GetDirectoryName(assembly), m_ItemID.ToString() + ".state"))) - { - throw new Exception("Completed persistence save, but no file was created"); - } - } - } - - public class ScriptSerializer - { - public static string Serialize(XScriptInstance 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, XScriptInstance 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