diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs index b4771fd2ca..8528c65f32 100644 --- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs @@ -798,7 +798,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess UUID RayTargetID, byte BypassRayCast, bool RayEndIsIntersection, bool RezSelected, bool RemoveItem, UUID fromTaskID, bool attachment) { - AssetBase rezAsset = m_Scene.AssetService.Get(assetID.ToString()); + AssetBase rezAsset = m_Scene.AssetService.Get(assetID.ToString()); if (rezAsset == null) { @@ -829,7 +829,9 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess byte bRayEndIsIntersection = (byte)(RayEndIsIntersection ? 1 : 0); Vector3 pos; - bool single = m_Scene.GetObjectsToRez(rezAsset.Data, attachment, out objlist, out veclist, out bbox, out offsetHeight); + bool single + = m_Scene.GetObjectsToRez( + rezAsset.Data, attachment, out objlist, out veclist, out bbox, out offsetHeight); if (single) { diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/Tests/InventoryAccessModuleTests.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/Tests/InventoryAccessModuleTests.cs index ad1a0e1a96..80b9c0af78 100644 --- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/Tests/InventoryAccessModuleTests.cs +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/Tests/InventoryAccessModuleTests.cs @@ -111,6 +111,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess.Tests InventoryFolderBase objsFolder = InventoryArchiveUtils.FindFoldersByPath(m_scene.InventoryService, m_userId, "Objects")[0]; item1.Folder = objsFolder.ID; + item1.Flags |= (uint)InventoryItemFlags.ObjectHasMultipleItems; m_scene.AddInventoryItem(item1); SceneObjectGroup so diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index 542d454629..cbb4fe771a 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs @@ -30,6 +30,7 @@ using System.Collections.Generic; using System.Collections; using System.Reflection; using System.Text; +using System.Threading; using System.Timers; using System.Xml; using OpenMetaverse; @@ -2192,60 +2193,84 @@ namespace OpenSim.Region.Framework.Scenes /// Returns one object if the asset is a regular object, and multiple objects for a coalesced object. /// /// Asset data - /// Whether the item is an attachment + /// True if the object is an attachment. /// The objects included in the asset /// Relative positions of the objects /// Bounding box of all the objects /// Offset in the Z axis from the centre of the bounding box /// to the centre of the root prim (relevant only when returning a single object) - /// true = returning a single object; false = multiple objects - public bool GetObjectsToRez(byte[] assetData, bool attachment, out List objlist, out List veclist, + /// + /// true if returning a single object or deserialization fails, false if returning the coalesced + /// list of objects + /// + public bool GetObjectsToRez( + byte[] assetData, bool isAttachment, out List objlist, out List veclist, out Vector3 bbox, out float offsetHeight) { objlist = new List(); veclist = new List(); - XmlDocument doc = new XmlDocument(); string xmlData = Utils.BytesToString(assetData); - doc.LoadXml(xmlData); - XmlElement e = (XmlElement)doc.SelectSingleNode("/CoalescedObject"); - if (e == null || attachment) // Single + try { - SceneObjectGroup g = SceneObjectSerializer.FromOriginalXmlFormat(xmlData); - objlist.Add(g); - veclist.Add(new Vector3(0, 0, 0)); - bbox = g.GetAxisAlignedBoundingBox(out offsetHeight); - return true; - } - else - { - XmlElement coll = (XmlElement)e; - float bx = Convert.ToSingle(coll.GetAttribute("x")); - float by = Convert.ToSingle(coll.GetAttribute("y")); - float bz = Convert.ToSingle(coll.GetAttribute("z")); - bbox = new Vector3(bx, by, bz); - offsetHeight = 0; - - XmlNodeList groups = e.SelectNodes("SceneObjectGroup"); - foreach (XmlNode n in groups) + using (XmlTextReader reader = new XmlTextReader(xmlData, XmlNodeType.Element, null)) { - SceneObjectGroup g = SceneObjectSerializer.FromOriginalXmlFormat(n.OuterXml); - objlist.Add(g); + reader.Read(); + bool isSingleObject = reader.Name != "CoalescedObject"; - XmlElement el = (XmlElement)n; - string rawX = el.GetAttribute("offsetx"); - string rawY = el.GetAttribute("offsety"); - string rawZ = el.GetAttribute("offsetz"); + if (isSingleObject || isAttachment) + { + SceneObjectGroup g = SceneObjectSerializer.FromOriginalXmlFormat(reader); + objlist.Add(g); + veclist.Add(Vector3.Zero); + bbox = g.GetAxisAlignedBoundingBox(out offsetHeight); + return true; + } + else + { + XmlDocument doc = new XmlDocument(); + doc.LoadXml(xmlData); + XmlElement e = (XmlElement)doc.SelectSingleNode("/CoalescedObject"); + XmlElement coll = (XmlElement)e; + float bx = Convert.ToSingle(coll.GetAttribute("x")); + float by = Convert.ToSingle(coll.GetAttribute("y")); + float bz = Convert.ToSingle(coll.GetAttribute("z")); + bbox = new Vector3(bx, by, bz); + offsetHeight = 0; - float x = Convert.ToSingle(rawX); - float y = Convert.ToSingle(rawY); - float z = Convert.ToSingle(rawZ); - veclist.Add(new Vector3(x, y, z)); + XmlNodeList groups = e.SelectNodes("SceneObjectGroup"); + foreach (XmlNode n in groups) + { + SceneObjectGroup g = SceneObjectSerializer.FromOriginalXmlFormat(n.OuterXml); + objlist.Add(g); + + XmlElement el = (XmlElement)n; + string rawX = el.GetAttribute("offsetx"); + string rawY = el.GetAttribute("offsety"); + string rawZ = el.GetAttribute("offsetz"); + + float x = Convert.ToSingle(rawX); + float y = Convert.ToSingle(rawY); + float z = Convert.ToSingle(rawZ); + veclist.Add(new Vector3(x, y, z)); + } + + return false; + } } } + catch (Exception e) + { + m_log.Error( + "[AGENT INVENTORY]: Deserialization of xml failed when looking for CoalescedObject tag. Exception ", + e); - return false; + bbox = Vector3.Zero; + offsetHeight = 0; + } + + return true; } /// diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 69491b7e1d..c95d2076a4 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -902,6 +902,34 @@ namespace OpenSim.Region.Framework.Scenes } } + public void LoadScriptState(XmlTextReader reader) + { +// m_log.DebugFormat("[SCENE OBJECT GROUP]: Looking for script state for {0} in {1}", Name); + + while (reader.ReadToFollowing("SavedScriptState")) + { +// m_log.DebugFormat("[SCENE OBJECT GROUP]: Loading script state for {0}", Name); + + if (m_savedScriptState == null) + m_savedScriptState = new Dictionary(); + + string uuid = reader.GetAttribute("UUID"); + + if (uuid != null) + { +// m_log.DebugFormat("[SCENE OBJECT GROUP]: Found state for item ID {0} in object {1}", uuid, Name); + + UUID itemid = new UUID(uuid); + if (itemid != UUID.Zero) + m_savedScriptState[itemid] = reader.ReadInnerXml(); + } + else + { + m_log.WarnFormat("[SCENE OBJECT GROUP]: SavedScriptState element had no UUID in object {0}", Name); + } + } + } + /// /// Hooks this object up to the backup event so that it is persisted to the database when the update thread executes. /// diff --git a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs index e68f954956..8f99dc6f8e 100644 --- a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs +++ b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs @@ -58,58 +58,59 @@ namespace OpenSim.Region.Framework.Scenes.Serialization /// /// The scene object deserialized. Null on failure. public static SceneObjectGroup FromOriginalXmlFormat(string xmlData) + { + using (XmlTextReader reader = new XmlTextReader(xmlData, XmlNodeType.Element, null)) + return FromOriginalXmlFormat(reader); + } + + /// + /// Deserialize a scene object from the original xml format + /// + /// + /// The scene object deserialized. Null on failure. + public static SceneObjectGroup FromOriginalXmlFormat(XmlTextReader reader) { //m_log.DebugFormat("[SOG]: Starting deserialization of SOG"); //int time = System.Environment.TickCount; + SceneObjectGroup sceneObject = null; + try { - StringReader sr; - XmlTextReader reader; - XmlNodeList parts; - XmlDocument doc; int linkNum; - doc = new XmlDocument(); - doc.LoadXml(xmlData); - parts = doc.GetElementsByTagName("RootPart"); + reader.ReadToFollowing("RootPart"); + reader.ReadToFollowing("SceneObjectPart"); + sceneObject = new SceneObjectGroup(SceneObjectPart.FromXml(reader)); + reader.ReadToFollowing("OtherParts"); - if (parts.Count == 0) - throw new Exception("Invalid Xml format - no root part"); - - sr = new StringReader(parts[0].InnerXml); - reader = new XmlTextReader(sr); - SceneObjectGroup sceneObject = new SceneObjectGroup(SceneObjectPart.FromXml(reader)); - reader.Close(); - sr.Close(); - - parts = doc.GetElementsByTagName("Part"); - - for (int i = 0; i < parts.Count; i++) + if (reader.ReadToDescendant("Part")) { - sr = new StringReader(parts[i].InnerXml); - reader = new XmlTextReader(sr); - SceneObjectPart part = SceneObjectPart.FromXml(reader); - linkNum = part.LinkNum; - sceneObject.AddPart(part); - part.LinkNum = linkNum; - part.TrimPermissions(); - reader.Close(); - sr.Close(); + do + { + if (reader.ReadToDescendant("SceneObjectPart")) + { + SceneObjectPart part = SceneObjectPart.FromXml(reader); + linkNum = part.LinkNum; + sceneObject.AddPart(part); + part.LinkNum = linkNum; + part.TrimPermissions(); + } + } + while (reader.ReadToNextSibling("Part")); } // Script state may, or may not, exist. Not having any, is NOT // ever a problem. - sceneObject.LoadScriptState(doc); - - return sceneObject; + sceneObject.LoadScriptState(reader); } catch (Exception e) { - m_log.ErrorFormat( - "[SERIALIZER]: Deserialization of xml failed with {0}. xml was {1}", e, xmlData); + m_log.ErrorFormat("[SERIALIZER]: Deserialization of xml failed. Exception {0}", e); return null; } + + return sceneObject; } ///