diff options
5 files changed, 128 insertions, 71 deletions
diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs index b4771fd..8528c65 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 | |||
798 | UUID RayTargetID, byte BypassRayCast, bool RayEndIsIntersection, | 798 | UUID RayTargetID, byte BypassRayCast, bool RayEndIsIntersection, |
799 | bool RezSelected, bool RemoveItem, UUID fromTaskID, bool attachment) | 799 | bool RezSelected, bool RemoveItem, UUID fromTaskID, bool attachment) |
800 | { | 800 | { |
801 | AssetBase rezAsset = m_Scene.AssetService.Get(assetID.ToString()); | 801 | AssetBase rezAsset = m_Scene.AssetService.Get(assetID.ToString()); |
802 | 802 | ||
803 | if (rezAsset == null) | 803 | if (rezAsset == null) |
804 | { | 804 | { |
@@ -829,7 +829,9 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
829 | byte bRayEndIsIntersection = (byte)(RayEndIsIntersection ? 1 : 0); | 829 | byte bRayEndIsIntersection = (byte)(RayEndIsIntersection ? 1 : 0); |
830 | Vector3 pos; | 830 | Vector3 pos; |
831 | 831 | ||
832 | bool single = m_Scene.GetObjectsToRez(rezAsset.Data, attachment, out objlist, out veclist, out bbox, out offsetHeight); | 832 | bool single |
833 | = m_Scene.GetObjectsToRez( | ||
834 | rezAsset.Data, attachment, out objlist, out veclist, out bbox, out offsetHeight); | ||
833 | 835 | ||
834 | if (single) | 836 | if (single) |
835 | { | 837 | { |
diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/Tests/InventoryAccessModuleTests.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/Tests/InventoryAccessModuleTests.cs index ad1a0e1..80b9c0a 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 | |||
111 | InventoryFolderBase objsFolder | 111 | InventoryFolderBase objsFolder |
112 | = InventoryArchiveUtils.FindFoldersByPath(m_scene.InventoryService, m_userId, "Objects")[0]; | 112 | = InventoryArchiveUtils.FindFoldersByPath(m_scene.InventoryService, m_userId, "Objects")[0]; |
113 | item1.Folder = objsFolder.ID; | 113 | item1.Folder = objsFolder.ID; |
114 | item1.Flags |= (uint)InventoryItemFlags.ObjectHasMultipleItems; | ||
114 | m_scene.AddInventoryItem(item1); | 115 | m_scene.AddInventoryItem(item1); |
115 | 116 | ||
116 | SceneObjectGroup so | 117 | SceneObjectGroup so |
diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index 542d454..cbb4fe7 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; | |||
30 | using System.Collections; | 30 | using System.Collections; |
31 | using System.Reflection; | 31 | using System.Reflection; |
32 | using System.Text; | 32 | using System.Text; |
33 | using System.Threading; | ||
33 | using System.Timers; | 34 | using System.Timers; |
34 | using System.Xml; | 35 | using System.Xml; |
35 | using OpenMetaverse; | 36 | using OpenMetaverse; |
@@ -2192,60 +2193,84 @@ namespace OpenSim.Region.Framework.Scenes | |||
2192 | /// Returns one object if the asset is a regular object, and multiple objects for a coalesced object. | 2193 | /// Returns one object if the asset is a regular object, and multiple objects for a coalesced object. |
2193 | /// </remarks> | 2194 | /// </remarks> |
2194 | /// <param name="assetData">Asset data</param> | 2195 | /// <param name="assetData">Asset data</param> |
2195 | /// <param name="attachment">Whether the item is an attachment</param> | 2196 | /// <param name="isAttachment">True if the object is an attachment.</param> |
2196 | /// <param name="objlist">The objects included in the asset</param> | 2197 | /// <param name="objlist">The objects included in the asset</param> |
2197 | /// <param name="veclist">Relative positions of the objects</param> | 2198 | /// <param name="veclist">Relative positions of the objects</param> |
2198 | /// <param name="bbox">Bounding box of all the objects</param> | 2199 | /// <param name="bbox">Bounding box of all the objects</param> |
2199 | /// <param name="offsetHeight">Offset in the Z axis from the centre of the bounding box | 2200 | /// <param name="offsetHeight">Offset in the Z axis from the centre of the bounding box |
2200 | /// to the centre of the root prim (relevant only when returning a single object)</param> | 2201 | /// to the centre of the root prim (relevant only when returning a single object)</param> |
2201 | /// <returns>true = returning a single object; false = multiple objects</returns> | 2202 | /// <returns> |
2202 | public bool GetObjectsToRez(byte[] assetData, bool attachment, out List<SceneObjectGroup> objlist, out List<Vector3> veclist, | 2203 | /// true if returning a single object or deserialization fails, false if returning the coalesced |
2204 | /// list of objects | ||
2205 | /// </returns> | ||
2206 | public bool GetObjectsToRez( | ||
2207 | byte[] assetData, bool isAttachment, out List<SceneObjectGroup> objlist, out List<Vector3> veclist, | ||
2203 | out Vector3 bbox, out float offsetHeight) | 2208 | out Vector3 bbox, out float offsetHeight) |
2204 | { | 2209 | { |
2205 | objlist = new List<SceneObjectGroup>(); | 2210 | objlist = new List<SceneObjectGroup>(); |
2206 | veclist = new List<Vector3>(); | 2211 | veclist = new List<Vector3>(); |
2207 | 2212 | ||
2208 | XmlDocument doc = new XmlDocument(); | ||
2209 | string xmlData = Utils.BytesToString(assetData); | 2213 | string xmlData = Utils.BytesToString(assetData); |
2210 | doc.LoadXml(xmlData); | ||
2211 | XmlElement e = (XmlElement)doc.SelectSingleNode("/CoalescedObject"); | ||
2212 | 2214 | ||
2213 | if (e == null || attachment) // Single | 2215 | try |
2214 | { | 2216 | { |
2215 | SceneObjectGroup g = SceneObjectSerializer.FromOriginalXmlFormat(xmlData); | 2217 | using (XmlTextReader reader = new XmlTextReader(xmlData, XmlNodeType.Element, null)) |
2216 | objlist.Add(g); | 2218 | { |
2217 | veclist.Add(new Vector3(0, 0, 0)); | 2219 | reader.Read(); |
2218 | bbox = g.GetAxisAlignedBoundingBox(out offsetHeight); | 2220 | bool isSingleObject = reader.Name != "CoalescedObject"; |
2219 | return true; | 2221 | |
2222 | if (isSingleObject || isAttachment) | ||
2223 | { | ||
2224 | SceneObjectGroup g = SceneObjectSerializer.FromOriginalXmlFormat(reader); | ||
2225 | objlist.Add(g); | ||
2226 | veclist.Add(Vector3.Zero); | ||
2227 | bbox = g.GetAxisAlignedBoundingBox(out offsetHeight); | ||
2228 | return true; | ||
2229 | } | ||
2230 | else | ||
2231 | { | ||
2232 | XmlDocument doc = new XmlDocument(); | ||
2233 | doc.LoadXml(xmlData); | ||
2234 | XmlElement e = (XmlElement)doc.SelectSingleNode("/CoalescedObject"); | ||
2235 | XmlElement coll = (XmlElement)e; | ||
2236 | float bx = Convert.ToSingle(coll.GetAttribute("x")); | ||
2237 | float by = Convert.ToSingle(coll.GetAttribute("y")); | ||
2238 | float bz = Convert.ToSingle(coll.GetAttribute("z")); | ||
2239 | bbox = new Vector3(bx, by, bz); | ||
2240 | offsetHeight = 0; | ||
2241 | |||
2242 | XmlNodeList groups = e.SelectNodes("SceneObjectGroup"); | ||
2243 | foreach (XmlNode n in groups) | ||
2244 | { | ||
2245 | SceneObjectGroup g = SceneObjectSerializer.FromOriginalXmlFormat(n.OuterXml); | ||
2246 | objlist.Add(g); | ||
2247 | |||
2248 | XmlElement el = (XmlElement)n; | ||
2249 | string rawX = el.GetAttribute("offsetx"); | ||
2250 | string rawY = el.GetAttribute("offsety"); | ||
2251 | string rawZ = el.GetAttribute("offsetz"); | ||
2252 | |||
2253 | float x = Convert.ToSingle(rawX); | ||
2254 | float y = Convert.ToSingle(rawY); | ||
2255 | float z = Convert.ToSingle(rawZ); | ||
2256 | veclist.Add(new Vector3(x, y, z)); | ||
2257 | } | ||
2258 | |||
2259 | return false; | ||
2260 | } | ||
2261 | } | ||
2220 | } | 2262 | } |
2221 | else | 2263 | catch (Exception e) |
2222 | { | 2264 | { |
2223 | XmlElement coll = (XmlElement)e; | 2265 | m_log.Error( |
2224 | float bx = Convert.ToSingle(coll.GetAttribute("x")); | 2266 | "[AGENT INVENTORY]: Deserialization of xml failed when looking for CoalescedObject tag. Exception ", |
2225 | float by = Convert.ToSingle(coll.GetAttribute("y")); | 2267 | e); |
2226 | float bz = Convert.ToSingle(coll.GetAttribute("z")); | ||
2227 | bbox = new Vector3(bx, by, bz); | ||
2228 | offsetHeight = 0; | ||
2229 | 2268 | ||
2230 | XmlNodeList groups = e.SelectNodes("SceneObjectGroup"); | 2269 | bbox = Vector3.Zero; |
2231 | foreach (XmlNode n in groups) | 2270 | offsetHeight = 0; |
2232 | { | ||
2233 | SceneObjectGroup g = SceneObjectSerializer.FromOriginalXmlFormat(n.OuterXml); | ||
2234 | objlist.Add(g); | ||
2235 | |||
2236 | XmlElement el = (XmlElement)n; | ||
2237 | string rawX = el.GetAttribute("offsetx"); | ||
2238 | string rawY = el.GetAttribute("offsety"); | ||
2239 | string rawZ = el.GetAttribute("offsetz"); | ||
2240 | |||
2241 | float x = Convert.ToSingle(rawX); | ||
2242 | float y = Convert.ToSingle(rawY); | ||
2243 | float z = Convert.ToSingle(rawZ); | ||
2244 | veclist.Add(new Vector3(x, y, z)); | ||
2245 | } | ||
2246 | } | 2271 | } |
2247 | 2272 | ||
2248 | return false; | 2273 | return true; |
2249 | } | 2274 | } |
2250 | 2275 | ||
2251 | /// <summary> | 2276 | /// <summary> |
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 69491b7..c95d207 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | |||
@@ -902,6 +902,34 @@ namespace OpenSim.Region.Framework.Scenes | |||
902 | } | 902 | } |
903 | } | 903 | } |
904 | 904 | ||
905 | public void LoadScriptState(XmlTextReader reader) | ||
906 | { | ||
907 | // m_log.DebugFormat("[SCENE OBJECT GROUP]: Looking for script state for {0} in {1}", Name); | ||
908 | |||
909 | while (reader.ReadToFollowing("SavedScriptState")) | ||
910 | { | ||
911 | // m_log.DebugFormat("[SCENE OBJECT GROUP]: Loading script state for {0}", Name); | ||
912 | |||
913 | if (m_savedScriptState == null) | ||
914 | m_savedScriptState = new Dictionary<UUID, string>(); | ||
915 | |||
916 | string uuid = reader.GetAttribute("UUID"); | ||
917 | |||
918 | if (uuid != null) | ||
919 | { | ||
920 | // m_log.DebugFormat("[SCENE OBJECT GROUP]: Found state for item ID {0} in object {1}", uuid, Name); | ||
921 | |||
922 | UUID itemid = new UUID(uuid); | ||
923 | if (itemid != UUID.Zero) | ||
924 | m_savedScriptState[itemid] = reader.ReadInnerXml(); | ||
925 | } | ||
926 | else | ||
927 | { | ||
928 | m_log.WarnFormat("[SCENE OBJECT GROUP]: SavedScriptState element had no UUID in object {0}", Name); | ||
929 | } | ||
930 | } | ||
931 | } | ||
932 | |||
905 | /// <summary> | 933 | /// <summary> |
906 | /// Hooks this object up to the backup event so that it is persisted to the database when the update thread executes. | 934 | /// Hooks this object up to the backup event so that it is persisted to the database when the update thread executes. |
907 | /// </summary> | 935 | /// </summary> |
diff --git a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs index e68f954..8f99dc6 100644 --- a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs +++ b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs | |||
@@ -59,57 +59,58 @@ namespace OpenSim.Region.Framework.Scenes.Serialization | |||
59 | /// <returns>The scene object deserialized. Null on failure.</returns> | 59 | /// <returns>The scene object deserialized. Null on failure.</returns> |
60 | public static SceneObjectGroup FromOriginalXmlFormat(string xmlData) | 60 | public static SceneObjectGroup FromOriginalXmlFormat(string xmlData) |
61 | { | 61 | { |
62 | using (XmlTextReader reader = new XmlTextReader(xmlData, XmlNodeType.Element, null)) | ||
63 | return FromOriginalXmlFormat(reader); | ||
64 | } | ||
65 | |||
66 | /// <summary> | ||
67 | /// Deserialize a scene object from the original xml format | ||
68 | /// </summary> | ||
69 | /// <param name="xmlData"></param> | ||
70 | /// <returns>The scene object deserialized. Null on failure.</returns> | ||
71 | public static SceneObjectGroup FromOriginalXmlFormat(XmlTextReader reader) | ||
72 | { | ||
62 | //m_log.DebugFormat("[SOG]: Starting deserialization of SOG"); | 73 | //m_log.DebugFormat("[SOG]: Starting deserialization of SOG"); |
63 | //int time = System.Environment.TickCount; | 74 | //int time = System.Environment.TickCount; |
64 | 75 | ||
76 | SceneObjectGroup sceneObject = null; | ||
77 | |||
65 | try | 78 | try |
66 | { | 79 | { |
67 | StringReader sr; | ||
68 | XmlTextReader reader; | ||
69 | XmlNodeList parts; | ||
70 | XmlDocument doc; | ||
71 | int linkNum; | 80 | int linkNum; |
72 | 81 | ||
73 | doc = new XmlDocument(); | 82 | reader.ReadToFollowing("RootPart"); |
74 | doc.LoadXml(xmlData); | 83 | reader.ReadToFollowing("SceneObjectPart"); |
75 | parts = doc.GetElementsByTagName("RootPart"); | 84 | sceneObject = new SceneObjectGroup(SceneObjectPart.FromXml(reader)); |
85 | reader.ReadToFollowing("OtherParts"); | ||
76 | 86 | ||
77 | if (parts.Count == 0) | 87 | if (reader.ReadToDescendant("Part")) |
78 | throw new Exception("Invalid Xml format - no root part"); | ||
79 | |||
80 | sr = new StringReader(parts[0].InnerXml); | ||
81 | reader = new XmlTextReader(sr); | ||
82 | SceneObjectGroup sceneObject = new SceneObjectGroup(SceneObjectPart.FromXml(reader)); | ||
83 | reader.Close(); | ||
84 | sr.Close(); | ||
85 | |||
86 | parts = doc.GetElementsByTagName("Part"); | ||
87 | |||
88 | for (int i = 0; i < parts.Count; i++) | ||
89 | { | 88 | { |
90 | sr = new StringReader(parts[i].InnerXml); | 89 | do |
91 | reader = new XmlTextReader(sr); | 90 | { |
92 | SceneObjectPart part = SceneObjectPart.FromXml(reader); | 91 | if (reader.ReadToDescendant("SceneObjectPart")) |
93 | linkNum = part.LinkNum; | 92 | { |
94 | sceneObject.AddPart(part); | 93 | SceneObjectPart part = SceneObjectPart.FromXml(reader); |
95 | part.LinkNum = linkNum; | 94 | linkNum = part.LinkNum; |
96 | part.TrimPermissions(); | 95 | sceneObject.AddPart(part); |
97 | reader.Close(); | 96 | part.LinkNum = linkNum; |
98 | sr.Close(); | 97 | part.TrimPermissions(); |
98 | } | ||
99 | } | ||
100 | while (reader.ReadToNextSibling("Part")); | ||
99 | } | 101 | } |
100 | 102 | ||
101 | // Script state may, or may not, exist. Not having any, is NOT | 103 | // Script state may, or may not, exist. Not having any, is NOT |
102 | // ever a problem. | 104 | // ever a problem. |
103 | sceneObject.LoadScriptState(doc); | 105 | sceneObject.LoadScriptState(reader); |
104 | |||
105 | return sceneObject; | ||
106 | } | 106 | } |
107 | catch (Exception e) | 107 | catch (Exception e) |
108 | { | 108 | { |
109 | m_log.ErrorFormat( | 109 | m_log.ErrorFormat("[SERIALIZER]: Deserialization of xml failed. Exception {0}", e); |
110 | "[SERIALIZER]: Deserialization of xml failed with {0}. xml was {1}", e, xmlData); | ||
111 | return null; | 110 | return null; |
112 | } | 111 | } |
112 | |||
113 | return sceneObject; | ||
113 | } | 114 | } |
114 | 115 | ||
115 | /// <summary> | 116 | /// <summary> |