aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Framework/Serialization
diff options
context:
space:
mode:
authorUbitUmarov2015-09-01 11:43:07 +0100
committerUbitUmarov2015-09-01 11:43:07 +0100
commitfb78b182520fc9bb0f971afd0322029c70278ea6 (patch)
treeb4e30d383938fdeef8c92d1d1c2f44bb61d329bd /OpenSim/Framework/Serialization
parentlixo (diff)
parentMantis #7713: fixed bug introduced by 1st MOSES patch. (diff)
downloadopensim-SC-fb78b182520fc9bb0f971afd0322029c70278ea6.zip
opensim-SC-fb78b182520fc9bb0f971afd0322029c70278ea6.tar.gz
opensim-SC-fb78b182520fc9bb0f971afd0322029c70278ea6.tar.bz2
opensim-SC-fb78b182520fc9bb0f971afd0322029c70278ea6.tar.xz
Merge remote-tracking branch 'os/master'
Diffstat (limited to '')
-rw-r--r--OpenSim/Framework/Serialization/ArchiveConstants.cs208
-rw-r--r--OpenSim/Framework/Serialization/External/ExternalRepresentationUtils.cs411
-rw-r--r--OpenSim/Framework/Serialization/External/LandDataSerializer.cs266
-rw-r--r--OpenSim/Framework/Serialization/External/OspResolver.cs208
-rw-r--r--OpenSim/Framework/Serialization/External/RegionSettingsSerializer.cs287
-rw-r--r--OpenSim/Framework/Serialization/External/UserInventoryItemSerializer.cs304
-rw-r--r--OpenSim/Framework/Serialization/External/UserProfileSerializer.cs73
-rw-r--r--OpenSim/Framework/Serialization/Properties/AssemblyInfo.cs33
-rw-r--r--OpenSim/Framework/Serialization/TarArchiveReader.cs226
-rw-r--r--OpenSim/Framework/Serialization/TarArchiveWriter.cs229
-rw-r--r--OpenSim/Framework/Serialization/Tests/LandDataSerializerTests.cs166
-rw-r--r--OpenSim/Framework/Serialization/Tests/RegionSettingsSerializerTests.cs142
12 files changed, 2553 insertions, 0 deletions
diff --git a/OpenSim/Framework/Serialization/ArchiveConstants.cs b/OpenSim/Framework/Serialization/ArchiveConstants.cs
new file mode 100644
index 0000000..ab3c285
--- /dev/null
+++ b/OpenSim/Framework/Serialization/ArchiveConstants.cs
@@ -0,0 +1,208 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.Text;
31using OpenMetaverse;
32using OpenSimAssetType = OpenSim.Framework.SLUtil.OpenSimAssetType;
33
34namespace OpenSim.Framework.Serialization
35{
36 /// <summary>
37 /// Constants for the archiving module
38 /// </summary>
39 public class ArchiveConstants
40 {
41 /// <value>
42 /// The location of the archive control file
43 /// </value>
44 public const string CONTROL_FILE_PATH = "archive.xml";
45
46 /// <value>
47 /// Path for the assets held in an archive
48 /// </value>
49 public const string ASSETS_PATH = "assets/";
50
51 /// <value>
52 /// Path for the inventory data
53 /// </value>
54 public const string INVENTORY_PATH = "inventory/";
55
56 /// <value>
57 /// Path for regions in a multi-region archive
58 /// </value>
59 public const string REGIONS_PATH = "regions/";
60
61 /// <value>
62 /// Path for the prims file
63 /// </value>
64 public const string OBJECTS_PATH = "objects/";
65
66 /// <value>
67 /// Path for terrains. Technically these may be assets, but I think it's quite nice to split them out.
68 /// </value>
69 public const string TERRAINS_PATH = "terrains/";
70
71 /// <value>
72 /// Path for region settings.
73 /// </value>
74 public const string SETTINGS_PATH = "settings/";
75
76 /// <value>
77 /// Path for region settings.
78 /// </value>
79 public const string LANDDATA_PATH = "landdata/";
80
81 /// <value>
82 /// Path for user profiles
83 /// </value>
84 public const string USERS_PATH = "userprofiles/";
85
86 /// <value>
87 /// The character the separates the uuid from extension information in an archived asset filename
88 /// </value>
89 public const string ASSET_EXTENSION_SEPARATOR = "_";
90
91 /// <value>
92 /// Used to separate components in an inventory node name
93 /// </value>
94 public const string INVENTORY_NODE_NAME_COMPONENT_SEPARATOR = "__";
95
96 /// <summary>
97 /// Template used for creating filenames in OpenSim Archives.
98 /// </summary>
99 public const string OAR_OBJECT_FILENAME_TEMPLATE = "{0}_{1:000}-{2:000}-{3:000}__{4}.xml";
100
101 /// <value>
102 /// Extensions used for asset types in the archive
103 /// </value>
104 public static readonly IDictionary<sbyte, string> ASSET_TYPE_TO_EXTENSION = new Dictionary<sbyte, string>();
105 public static readonly IDictionary<string, sbyte> EXTENSION_TO_ASSET_TYPE = new Dictionary<string, sbyte>();
106
107 static ArchiveConstants()
108 {
109 ASSET_TYPE_TO_EXTENSION[(sbyte)AssetType.Animation] = ASSET_EXTENSION_SEPARATOR + "animation.bvh";
110 ASSET_TYPE_TO_EXTENSION[(sbyte)AssetType.Bodypart] = ASSET_EXTENSION_SEPARATOR + "bodypart.txt";
111 ASSET_TYPE_TO_EXTENSION[(sbyte)AssetType.CallingCard] = ASSET_EXTENSION_SEPARATOR + "callingcard.txt";
112 ASSET_TYPE_TO_EXTENSION[(sbyte)AssetType.Clothing] = ASSET_EXTENSION_SEPARATOR + "clothing.txt";
113 ASSET_TYPE_TO_EXTENSION[(sbyte)AssetType.Folder] = ASSET_EXTENSION_SEPARATOR + "folder.txt"; // Not sure if we'll ever see this
114 ASSET_TYPE_TO_EXTENSION[(sbyte)AssetType.Gesture] = ASSET_EXTENSION_SEPARATOR + "gesture.txt";
115 ASSET_TYPE_TO_EXTENSION[(sbyte)AssetType.ImageJPEG] = ASSET_EXTENSION_SEPARATOR + "image.jpg";
116 ASSET_TYPE_TO_EXTENSION[(sbyte)AssetType.ImageTGA] = ASSET_EXTENSION_SEPARATOR + "image.tga";
117 ASSET_TYPE_TO_EXTENSION[(sbyte)AssetType.Landmark] = ASSET_EXTENSION_SEPARATOR + "landmark.txt";
118 ASSET_TYPE_TO_EXTENSION[(sbyte)AssetType.LSLBytecode] = ASSET_EXTENSION_SEPARATOR + "bytecode.lso";
119 ASSET_TYPE_TO_EXTENSION[(sbyte)AssetType.LSLText] = ASSET_EXTENSION_SEPARATOR + "script.lsl";
120 ASSET_TYPE_TO_EXTENSION[(sbyte)AssetType.Mesh] = ASSET_EXTENSION_SEPARATOR + "mesh.llmesh";
121 ASSET_TYPE_TO_EXTENSION[(sbyte)AssetType.Notecard] = ASSET_EXTENSION_SEPARATOR + "notecard.txt";
122 ASSET_TYPE_TO_EXTENSION[(sbyte)AssetType.Object] = ASSET_EXTENSION_SEPARATOR + "object.xml";
123 ASSET_TYPE_TO_EXTENSION[(sbyte)AssetType.Simstate] = ASSET_EXTENSION_SEPARATOR + "simstate.bin"; // Not sure if we'll ever see this
124 ASSET_TYPE_TO_EXTENSION[(sbyte)AssetType.Sound] = ASSET_EXTENSION_SEPARATOR + "sound.ogg";
125 ASSET_TYPE_TO_EXTENSION[(sbyte)AssetType.SoundWAV] = ASSET_EXTENSION_SEPARATOR + "sound.wav";
126 ASSET_TYPE_TO_EXTENSION[(sbyte)AssetType.Texture] = ASSET_EXTENSION_SEPARATOR + "texture.jp2";
127 ASSET_TYPE_TO_EXTENSION[(sbyte)AssetType.TextureTGA] = ASSET_EXTENSION_SEPARATOR + "texture.tga";
128 ASSET_TYPE_TO_EXTENSION[(sbyte)OpenSimAssetType.Material] = ASSET_EXTENSION_SEPARATOR + "material.xml"; // Not sure if we'll ever see this
129
130 EXTENSION_TO_ASSET_TYPE[ASSET_EXTENSION_SEPARATOR + "animation.bvh"] = (sbyte)AssetType.Animation;
131 EXTENSION_TO_ASSET_TYPE[ASSET_EXTENSION_SEPARATOR + "bodypart.txt"] = (sbyte)AssetType.Bodypart;
132 EXTENSION_TO_ASSET_TYPE[ASSET_EXTENSION_SEPARATOR + "callingcard.txt"] = (sbyte)AssetType.CallingCard;
133 EXTENSION_TO_ASSET_TYPE[ASSET_EXTENSION_SEPARATOR + "clothing.txt"] = (sbyte)AssetType.Clothing;
134 EXTENSION_TO_ASSET_TYPE[ASSET_EXTENSION_SEPARATOR + "folder.txt"] = (sbyte)AssetType.Folder;
135 EXTENSION_TO_ASSET_TYPE[ASSET_EXTENSION_SEPARATOR + "gesture.txt"] = (sbyte)AssetType.Gesture;
136 EXTENSION_TO_ASSET_TYPE[ASSET_EXTENSION_SEPARATOR + "image.jpg"] = (sbyte)AssetType.ImageJPEG;
137 EXTENSION_TO_ASSET_TYPE[ASSET_EXTENSION_SEPARATOR + "image.tga"] = (sbyte)AssetType.ImageTGA;
138 EXTENSION_TO_ASSET_TYPE[ASSET_EXTENSION_SEPARATOR + "landmark.txt"] = (sbyte)AssetType.Landmark;
139 EXTENSION_TO_ASSET_TYPE[ASSET_EXTENSION_SEPARATOR + "bytecode.lso"] = (sbyte)AssetType.LSLBytecode;
140 EXTENSION_TO_ASSET_TYPE[ASSET_EXTENSION_SEPARATOR + "script.lsl"] = (sbyte)AssetType.LSLText;
141 EXTENSION_TO_ASSET_TYPE[ASSET_EXTENSION_SEPARATOR + "mesh.llmesh"] = (sbyte)AssetType.Mesh;
142 EXTENSION_TO_ASSET_TYPE[ASSET_EXTENSION_SEPARATOR + "notecard.txt"] = (sbyte)AssetType.Notecard;
143 EXTENSION_TO_ASSET_TYPE[ASSET_EXTENSION_SEPARATOR + "object.xml"] = (sbyte)AssetType.Object;
144 EXTENSION_TO_ASSET_TYPE[ASSET_EXTENSION_SEPARATOR + "simstate.bin"] = (sbyte)AssetType.Simstate;
145 EXTENSION_TO_ASSET_TYPE[ASSET_EXTENSION_SEPARATOR + "sound.ogg"] = (sbyte)AssetType.Sound;
146 EXTENSION_TO_ASSET_TYPE[ASSET_EXTENSION_SEPARATOR + "sound.wav"] = (sbyte)AssetType.SoundWAV;
147 EXTENSION_TO_ASSET_TYPE[ASSET_EXTENSION_SEPARATOR + "texture.jp2"] = (sbyte)AssetType.Texture;
148 EXTENSION_TO_ASSET_TYPE[ASSET_EXTENSION_SEPARATOR + "texture.tga"] = (sbyte)AssetType.TextureTGA;
149 EXTENSION_TO_ASSET_TYPE[ASSET_EXTENSION_SEPARATOR + "material.xml"] = (sbyte)OpenSimAssetType.Material;
150 }
151
152 public static string CreateOarLandDataPath(LandData ld)
153 {
154 return string.Format("{0}{1}.xml", ArchiveConstants.LANDDATA_PATH, ld.GlobalID);
155 }
156
157 /// <summary>
158 /// Create the filename used to store an object in an OpenSim Archive.
159 /// </summary>
160 /// <param name="objectName"></param>
161 /// <param name="uuid"></param>
162 /// <param name="pos"></param>
163 /// <returns></returns>
164 public static string CreateOarObjectFilename(string objectName, UUID uuid, Vector3 pos)
165 {
166 return string.Format(
167 OAR_OBJECT_FILENAME_TEMPLATE, objectName,
168 Math.Round(pos.X), Math.Round(pos.Y), Math.Round(pos.Z),
169 uuid);
170 }
171
172 /// <summary>
173 /// Create the path used to store an object in an OpenSim Archives.
174 /// </summary>
175 /// <param name="objectName"></param>
176 /// <param name="uuid"></param>
177 /// <param name="pos"></param>
178 /// <returns></returns>
179 public static string CreateOarObjectPath(string objectName, UUID uuid, Vector3 pos)
180 {
181 return OBJECTS_PATH + CreateOarObjectFilename(objectName, uuid, pos);
182 }
183
184 /// <summary>
185 /// Extract a plain path from an IAR path
186 /// </summary>
187 /// <param name="iarPath"></param>
188 /// <returns></returns>
189 public static string ExtractPlainPathFromIarPath(string iarPath)
190 {
191 List<string> plainDirs = new List<string>();
192
193 string[] iarDirs = iarPath.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
194
195 foreach (string iarDir in iarDirs)
196 {
197 if (!iarDir.Contains(ArchiveConstants.INVENTORY_NODE_NAME_COMPONENT_SEPARATOR))
198 plainDirs.Add(iarDir);
199
200 int i = iarDir.LastIndexOf(ArchiveConstants.INVENTORY_NODE_NAME_COMPONENT_SEPARATOR);
201
202 plainDirs.Add(iarDir.Remove(i));
203 }
204
205 return string.Join("/", plainDirs.ToArray());
206 }
207 }
208}
diff --git a/OpenSim/Framework/Serialization/External/ExternalRepresentationUtils.cs b/OpenSim/Framework/Serialization/External/ExternalRepresentationUtils.cs
new file mode 100644
index 0000000..55640ac
--- /dev/null
+++ b/OpenSim/Framework/Serialization/External/ExternalRepresentationUtils.cs
@@ -0,0 +1,411 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.Diagnostics;
31using System.IO;
32using System.Reflection;
33using System.Xml;
34using log4net;
35using OpenMetaverse;
36using OpenSim.Services.Interfaces;
37
38namespace OpenSim.Framework.Serialization.External
39{
40 /// <summary>
41 /// Utilities for manipulating external representations of data structures in OpenSim
42 /// </summary>
43 public class ExternalRepresentationUtils
44 {
45 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
46
47 /// <summary>
48 /// Populate a node with data read from xml using a dictinoary of processors
49 /// </summary>
50 /// <param name="nodeToFill"></param>
51 /// <param name="processors"></param>
52 /// <param name="xtr"></param>
53 /// <returns>true on successful, false if there were any processing failures</returns>
54 public static bool ExecuteReadProcessors<NodeType>(
55 NodeType nodeToFill, Dictionary<string, Action<NodeType, XmlReader>> processors, XmlReader xtr)
56 {
57 return ExecuteReadProcessors(
58 nodeToFill,
59 processors,
60 xtr,
61 (o, nodeName, e) => {
62 m_log.Debug(string.Format("[ExternalRepresentationUtils]: Error while parsing element {0} ",
63 nodeName), e);
64 });
65 }
66
67 /// <summary>
68 /// Populate a node with data read from xml using a dictinoary of processors
69 /// </summary>
70 /// <param name="nodeToFill"></param>
71 /// <param name="processors"></param>
72 /// <param name="xtr"></param>
73 /// <param name="parseExceptionAction">
74 /// Action to take if there is a parsing problem. This will usually just be to log the exception
75 /// </param>
76 /// <returns>true on successful, false if there were any processing failures</returns>
77 public static bool ExecuteReadProcessors<NodeType>(
78 NodeType nodeToFill,
79 Dictionary<string, Action<NodeType, XmlReader>> processors,
80 XmlReader xtr,
81 Action<NodeType, string, Exception> parseExceptionAction)
82 {
83 bool errors = false;
84 int numErrors = 0;
85
86 Stopwatch timer = new Stopwatch();
87 timer.Start();
88
89 string nodeName = string.Empty;
90 while (xtr.NodeType != XmlNodeType.EndElement)
91 {
92 nodeName = xtr.Name;
93
94 // m_log.DebugFormat("[ExternalRepresentationUtils]: Processing node: {0}", nodeName);
95
96 Action<NodeType, XmlReader> p = null;
97 if (processors.TryGetValue(xtr.Name, out p))
98 {
99 // m_log.DebugFormat("[ExternalRepresentationUtils]: Found processor for {0}", nodeName);
100
101 try
102 {
103 p(nodeToFill, xtr);
104 }
105 catch (Exception e)
106 {
107 errors = true;
108 parseExceptionAction(nodeToFill, nodeName, e);
109
110 if (xtr.EOF)
111 {
112 m_log.Debug("[ExternalRepresentationUtils]: Aborting ExecuteReadProcessors due to unexpected end of XML");
113 break;
114 }
115
116 if (++numErrors == 10)
117 {
118 m_log.Debug("[ExternalRepresentationUtils]: Aborting ExecuteReadProcessors due to too many parsing errors");
119 break;
120 }
121
122 if (xtr.NodeType == XmlNodeType.EndElement)
123 xtr.Read();
124 }
125 }
126 else
127 {
128 // m_log.DebugFormat("[ExternalRepresentationUtils]: found unknown element \"{0}\"", nodeName);
129 xtr.ReadOuterXml(); // ignore
130 }
131
132 if (timer.Elapsed.TotalSeconds >= 60)
133 {
134 m_log.Debug("[ExternalRepresentationUtils]: Aborting ExecuteReadProcessors due to timeout");
135 errors = true;
136 break;
137 }
138 }
139
140 return errors;
141 }
142
143 /// <summary>
144 /// Takes a XML representation of a SceneObjectPart and returns another XML representation
145 /// with creator data added to it.
146 /// </summary>
147 /// <param name="xml">The SceneObjectPart represented in XML2</param>
148 /// <param name="homeURL">The URL of the user agents service (home) for the creator</param>
149 /// <param name="userService">The service for retrieving user account information</param>
150 /// <param name="scopeID">The scope of the user account information (Grid ID)</param>
151 /// <returns>The SceneObjectPart represented in XML2</returns>
152 [Obsolete("This method is deprecated. Use RewriteSOP instead.")]
153 public static string RewriteSOP_Old(string xml, string homeURL, IUserAccountService userService, UUID scopeID)
154 {
155 if (xml == string.Empty || homeURL == string.Empty || userService == null)
156 return xml;
157
158 XmlDocument doc = new XmlDocument();
159 doc.LoadXml(xml);
160 XmlNodeList sops = doc.GetElementsByTagName("SceneObjectPart");
161
162 foreach (XmlNode sop in sops)
163 {
164 UserAccount creator = null;
165 bool hasCreatorData = false;
166 XmlNodeList nodes = sop.ChildNodes;
167 foreach (XmlNode node in nodes)
168 {
169 if (node.Name == "CreatorID")
170 {
171 UUID uuid = UUID.Zero;
172 UUID.TryParse(node.InnerText, out uuid);
173 creator = userService.GetUserAccount(scopeID, uuid);
174 }
175
176 if (node.Name == "CreatorData" && node.InnerText != null && node.InnerText != string.Empty)
177 hasCreatorData = true;
178
179 //if (node.Name == "OwnerID")
180 //{
181 // UserAccount owner = GetUser(node.InnerText);
182 // if (owner != null)
183 // node.InnerText = m_ProfileServiceURL + "/" + node.InnerText + "/" + owner.FirstName + " " + owner.LastName;
184 //}
185 }
186 if (!hasCreatorData && creator != null)
187 {
188 XmlElement creatorData = doc.CreateElement("CreatorData");
189 creatorData.InnerText = CalcCreatorData(homeURL, creator.FirstName + " " + creator.LastName);
190 sop.AppendChild(creatorData);
191 }
192 }
193
194 using (StringWriter wr = new StringWriter())
195 {
196 doc.Save(wr);
197 return wr.ToString();
198 }
199 }
200
201 /// <summary>
202 /// Takes a XML representation of a SceneObjectPart and returns another XML representation
203 /// with creator data added to it.
204 /// </summary>
205 /// <param name="xml">The SceneObjectPart represented in XML2</param>
206 /// <param name="sceneName">An identifier for the component that's calling this function</param>
207 /// <param name="homeURL">The URL of the user agents service (home) for the creator</param>
208 /// <param name="userService">The service for retrieving user account information</param>
209 /// <param name="scopeID">The scope of the user account information (Grid ID)</param>
210 /// <returns>The SceneObjectPart represented in XML2</returns>
211 public static string RewriteSOP(string xmlData, string sceneName, string homeURL, IUserAccountService userService, UUID scopeID)
212 {
213 // Console.WriteLine("Input XML [{0}]", xmlData);
214 if (xmlData == string.Empty || homeURL == string.Empty || userService == null)
215 return xmlData;
216
217 // Deal with bug
218 xmlData = ExternalRepresentationUtils.SanitizeXml(xmlData);
219
220 using (StringWriter sw = new StringWriter())
221 using (XmlTextWriter writer = new XmlTextWriter(sw))
222 using (XmlTextReader wrappedReader = new XmlTextReader(xmlData, XmlNodeType.Element, null))
223 using (XmlReader reader = XmlReader.Create(wrappedReader, new XmlReaderSettings() { IgnoreWhitespace = true, ConformanceLevel = ConformanceLevel.Fragment }))
224 {
225 TransformXml(reader, writer, sceneName, homeURL, userService, scopeID);
226
227 // Console.WriteLine("Output: [{0}]", sw.ToString());
228
229 return sw.ToString();
230 }
231 }
232
233 protected static void TransformXml(XmlReader reader, XmlWriter writer, string sceneName, string homeURI, IUserAccountService userAccountService, UUID scopeID)
234 {
235 // m_log.DebugFormat("[HG ASSET MAPPER]: Transforming XML");
236
237 int sopDepth = -1;
238 UserAccount creator = null;
239 bool hasCreatorData = false;
240
241 while (reader.Read())
242 {
243 // Console.WriteLine("Depth: {0}, name {1}", reader.Depth, reader.Name);
244
245 switch (reader.NodeType)
246 {
247 case XmlNodeType.Attribute:
248 // Console.WriteLine("FOUND ATTRIBUTE {0}", reader.Name);
249 writer.WriteAttributeString(reader.Name, reader.Value);
250 break;
251
252 case XmlNodeType.CDATA:
253 writer.WriteCData(reader.Value);
254 break;
255
256 case XmlNodeType.Comment:
257 writer.WriteComment(reader.Value);
258 break;
259
260 case XmlNodeType.DocumentType:
261 writer.WriteDocType(reader.Name, reader.Value, null, null);
262 break;
263
264 case XmlNodeType.Element:
265 // m_log.DebugFormat("Depth {0} at element {1}", reader.Depth, reader.Name);
266
267 writer.WriteStartElement(reader.Prefix, reader.LocalName, reader.NamespaceURI);
268
269 if (reader.HasAttributes)
270 {
271 while (reader.MoveToNextAttribute())
272 writer.WriteAttributeString(reader.Name, reader.Value);
273
274 reader.MoveToElement();
275 }
276
277 if (reader.LocalName == "SceneObjectPart")
278 {
279 if (sopDepth < 0)
280 {
281 sopDepth = reader.Depth;
282 // m_log.DebugFormat("[HG ASSET MAPPER]: Set sopDepth to {0}", sopDepth);
283 }
284 }
285 else
286 {
287 if (sopDepth >= 0 && reader.Depth == sopDepth + 1)
288 {
289 if (reader.Name == "CreatorID")
290 {
291 reader.Read();
292 if (reader.NodeType == XmlNodeType.Element && reader.Name == "Guid" || reader.Name == "UUID")
293 {
294 reader.Read();
295
296 if (reader.NodeType == XmlNodeType.Text)
297 {
298 UUID uuid = UUID.Zero;
299 UUID.TryParse(reader.Value, out uuid);
300 creator = userAccountService.GetUserAccount(scopeID, uuid);
301 writer.WriteElementString("UUID", reader.Value);
302 reader.Read();
303 }
304 else
305 {
306 // If we unexpected run across mixed content in this node, still carry on
307 // transforming the subtree (this replicates earlier behaviour).
308 TransformXml(reader, writer, sceneName, homeURI, userAccountService, scopeID);
309 }
310 }
311 else
312 {
313 // If we unexpected run across mixed content in this node, still carry on
314 // transforming the subtree (this replicates earlier behaviour).
315 TransformXml(reader, writer, sceneName, homeURI, userAccountService, scopeID);
316 }
317 }
318 else if (reader.Name == "CreatorData")
319 {
320 reader.Read();
321 if (reader.NodeType == XmlNodeType.Text)
322 {
323 hasCreatorData = true;
324 writer.WriteString(reader.Value);
325 }
326 else
327 {
328 // If we unexpected run across mixed content in this node, still carry on
329 // transforming the subtree (this replicates earlier behaviour).
330 TransformXml(reader, writer, sceneName, homeURI, userAccountService, scopeID);
331 }
332 }
333 }
334 }
335
336 if (reader.IsEmptyElement)
337 {
338 // m_log.DebugFormat("[HG ASSET MAPPER]: Writing end for empty element {0}", reader.Name);
339 writer.WriteEndElement();
340 }
341
342 break;
343
344 case XmlNodeType.EndElement:
345 // m_log.DebugFormat("Depth {0} at EndElement", reader.Depth);
346 if (sopDepth == reader.Depth)
347 {
348 if (!hasCreatorData && creator != null)
349 writer.WriteElementString(reader.Prefix, "CreatorData", reader.NamespaceURI, string.Format("{0};{1} {2}", homeURI, creator.FirstName, creator.LastName));
350
351 // m_log.DebugFormat("[HG ASSET MAPPER]: Reset sopDepth");
352 sopDepth = -1;
353 creator = null;
354 hasCreatorData = false;
355 }
356 writer.WriteEndElement();
357 break;
358
359 case XmlNodeType.EntityReference:
360 writer.WriteEntityRef(reader.Name);
361 break;
362
363 case XmlNodeType.ProcessingInstruction:
364 writer.WriteProcessingInstruction(reader.Name, reader.Value);
365 break;
366
367 case XmlNodeType.Text:
368 writer.WriteString(reader.Value);
369 break;
370
371 case XmlNodeType.XmlDeclaration:
372 // For various reasons, not all serializations have xml declarations (or consistent ones)
373 // and as it's embedded inside a byte stream we don't need it anyway, so ignore.
374 break;
375
376 default:
377 m_log.WarnFormat(
378 "[HG ASSET MAPPER]: Unrecognized node {0} in asset XML transform in {1}",
379 reader.NodeType, sceneName);
380 break;
381 }
382 }
383 }
384
385 public static string CalcCreatorData(string homeURL, string name)
386 {
387 return homeURL + ";" + name;
388 }
389
390 internal static string CalcCreatorData(string homeURL, UUID uuid, string name)
391 {
392 return homeURL + "/" + uuid + ";" + name;
393 }
394
395 /// <summary>
396 /// Sanitation for bug introduced in Oct. 20 (1eb3e6cc43e2a7b4053bc1185c7c88e22356c5e8)
397 /// </summary>
398 /// <param name="xmlData"></param>
399 /// <returns></returns>
400 public static string SanitizeXml(string xmlData)
401 {
402 string fixedData = xmlData;
403 if (fixedData != null)
404 // Loop, because it may contain multiple
405 while (fixedData.Contains("xmlns:xmlns:"))
406 fixedData = fixedData.Replace("xmlns:xmlns:", "xmlns:");
407 return fixedData;
408 }
409
410 }
411}
diff --git a/OpenSim/Framework/Serialization/External/LandDataSerializer.cs b/OpenSim/Framework/Serialization/External/LandDataSerializer.cs
new file mode 100644
index 0000000..e42d56f
--- /dev/null
+++ b/OpenSim/Framework/Serialization/External/LandDataSerializer.cs
@@ -0,0 +1,266 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.IO;
31using System.Reflection;
32using System.Text;
33using System.Xml;
34using log4net;
35using OpenMetaverse;
36using OpenSim.Framework;
37
38namespace OpenSim.Framework.Serialization.External
39{
40 /// <summary>
41 /// Serialize and deserialize LandData as an external format.
42 /// </summary>
43 public class LandDataSerializer
44 {
45// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
46
47 private static Dictionary<string, Action<LandData, XmlReader>> m_ldProcessors
48 = new Dictionary<string, Action<LandData, XmlReader>>();
49
50 private static Dictionary<string, Action<LandAccessEntry, XmlReader>> m_laeProcessors
51 = new Dictionary<string, Action<LandAccessEntry, XmlReader>>();
52
53 static LandDataSerializer()
54 {
55 // LandData processors
56 m_ldProcessors.Add(
57 "Area", (ld, xtr) => ld.Area = Convert.ToInt32(xtr.ReadElementString("Area")));
58 m_ldProcessors.Add(
59 "AuctionID", (ld, xtr) => ld.AuctionID = Convert.ToUInt32(xtr.ReadElementString("AuctionID")));
60 m_ldProcessors.Add(
61 "AuthBuyerID", (ld, xtr) => ld.AuthBuyerID = UUID.Parse(xtr.ReadElementString("AuthBuyerID")));
62 m_ldProcessors.Add(
63 "Category", (ld, xtr) => ld.Category = (ParcelCategory)Convert.ToSByte(xtr.ReadElementString("Category")));
64 m_ldProcessors.Add(
65 "ClaimDate", (ld, xtr) => ld.ClaimDate = Convert.ToInt32(xtr.ReadElementString("ClaimDate")));
66 m_ldProcessors.Add(
67 "ClaimPrice", (ld, xtr) => ld.ClaimPrice = Convert.ToInt32(xtr.ReadElementString("ClaimPrice")));
68 m_ldProcessors.Add(
69 "GlobalID", (ld, xtr) => ld.GlobalID = UUID.Parse(xtr.ReadElementString("GlobalID")));
70 m_ldProcessors.Add(
71 "GroupID", (ld, xtr) => ld.GroupID = UUID.Parse(xtr.ReadElementString("GroupID")));
72 m_ldProcessors.Add(
73 "IsGroupOwned", (ld, xtr) => ld.IsGroupOwned = Convert.ToBoolean(xtr.ReadElementString("IsGroupOwned")));
74 m_ldProcessors.Add(
75 "Bitmap", (ld, xtr) => ld.Bitmap = Convert.FromBase64String(xtr.ReadElementString("Bitmap")));
76 m_ldProcessors.Add(
77 "Description", (ld, xtr) => ld.Description = xtr.ReadElementString("Description"));
78 m_ldProcessors.Add(
79 "Flags", (ld, xtr) => ld.Flags = Convert.ToUInt32(xtr.ReadElementString("Flags")));
80 m_ldProcessors.Add(
81 "LandingType", (ld, xtr) => ld.LandingType = Convert.ToByte(xtr.ReadElementString("LandingType")));
82 m_ldProcessors.Add(
83 "Name", (ld, xtr) => ld.Name = xtr.ReadElementString("Name"));
84 m_ldProcessors.Add(
85 "Status", (ld, xtr) => ld.Status = (ParcelStatus)Convert.ToSByte(xtr.ReadElementString("Status")));
86 m_ldProcessors.Add(
87 "LocalID", (ld, xtr) => ld.LocalID = Convert.ToInt32(xtr.ReadElementString("LocalID")));
88 m_ldProcessors.Add(
89 "MediaAutoScale", (ld, xtr) => ld.MediaAutoScale = Convert.ToByte(xtr.ReadElementString("MediaAutoScale")));
90 m_ldProcessors.Add(
91 "MediaID", (ld, xtr) => ld.MediaID = UUID.Parse(xtr.ReadElementString("MediaID")));
92 m_ldProcessors.Add(
93 "MediaURL", (ld, xtr) => ld.MediaURL = xtr.ReadElementString("MediaURL"));
94 m_ldProcessors.Add(
95 "MusicURL", (ld, xtr) => ld.MusicURL = xtr.ReadElementString("MusicURL"));
96 m_ldProcessors.Add(
97 "OwnerID", (ld, xtr) => ld.OwnerID = UUID.Parse(xtr.ReadElementString("OwnerID")));
98
99 m_ldProcessors.Add(
100 "ParcelAccessList", ProcessParcelAccessList);
101
102 m_ldProcessors.Add(
103 "PassHours", (ld, xtr) => ld.PassHours = Convert.ToSingle(xtr.ReadElementString("PassHours")));
104 m_ldProcessors.Add(
105 "PassPrice", (ld, xtr) => ld.PassPrice = Convert.ToInt32(xtr.ReadElementString("PassPrice")));
106 m_ldProcessors.Add(
107 "SalePrice", (ld, xtr) => ld.SalePrice = Convert.ToInt32(xtr.ReadElementString("SalePrice")));
108 m_ldProcessors.Add(
109 "SnapshotID", (ld, xtr) => ld.SnapshotID = UUID.Parse(xtr.ReadElementString("SnapshotID")));
110 m_ldProcessors.Add(
111 "UserLocation", (ld, xtr) => ld.UserLocation = Vector3.Parse(xtr.ReadElementString("UserLocation")));
112 m_ldProcessors.Add(
113 "UserLookAt", (ld, xtr) => ld.UserLookAt = Vector3.Parse(xtr.ReadElementString("UserLookAt")));
114
115 // No longer used here //
116 // m_ldProcessors.Add("Dwell", (landData, xtr) => return);
117
118 m_ldProcessors.Add(
119 "OtherCleanTime", (ld, xtr) => ld.OtherCleanTime = Convert.ToInt32(xtr.ReadElementString("OtherCleanTime")));
120
121 // LandAccessEntryProcessors
122 m_laeProcessors.Add(
123 "AgentID", (lae, xtr) => lae.AgentID = UUID.Parse(xtr.ReadElementString("AgentID")));
124 m_laeProcessors.Add(
125 "Time", (lae, xtr) =>
126 {
127 // We really don't care about temp vs perm here and this
128 // would break on old oars. Assume all bans are perm
129 xtr.ReadElementString("Time");
130 lae.Expires = 0; // Convert.ToUint( xtr.ReadElementString("Time"));
131 }
132 );
133 m_laeProcessors.Add(
134 "AccessList", (lae, xtr) => lae.Flags = (AccessList)Convert.ToUInt32(xtr.ReadElementString("AccessList")));
135 }
136
137 public static void ProcessParcelAccessList(LandData ld, XmlReader xtr)
138 {
139 if (!xtr.IsEmptyElement)
140 {
141 while (xtr.Read() && xtr.NodeType != XmlNodeType.EndElement)
142 {
143 LandAccessEntry lae = new LandAccessEntry();
144
145 xtr.ReadStartElement("ParcelAccessEntry");
146
147 ExternalRepresentationUtils.ExecuteReadProcessors<LandAccessEntry>(lae, m_laeProcessors, xtr);
148
149 xtr.ReadEndElement();
150
151 ld.ParcelAccessList.Add(lae);
152 }
153 }
154
155 xtr.Read();
156 }
157
158 /// <summary>
159 /// Reify/deserialize landData
160 /// </summary>
161 /// <param name="serializedLandData"></param>
162 /// <returns></returns>
163 /// <exception cref="System.Xml.XmlException"></exception>
164 public static LandData Deserialize(byte[] serializedLandData)
165 {
166 return Deserialize(Encoding.UTF8.GetString(serializedLandData, 0, serializedLandData.Length));
167 }
168
169 /// <summary>
170 /// Reify/deserialize landData
171 /// </summary>
172 /// <param name="serializedLandData"></param>
173 /// <returns></returns>
174 /// <exception cref="System.Xml.XmlException"></exception>
175 public static LandData Deserialize(string serializedLandData)
176 {
177 LandData landData = new LandData();
178
179 using (XmlTextReader reader = new XmlTextReader(new StringReader(serializedLandData)))
180 {
181 reader.ReadStartElement("LandData");
182
183 ExternalRepresentationUtils.ExecuteReadProcessors<LandData>(landData, m_ldProcessors, reader);
184
185 reader.ReadEndElement();
186 }
187
188 return landData;
189 }
190
191 /// <summary>
192 /// Serialize land data
193 /// </summary>
194 /// <param name='landData'></param>
195 /// <param name='options'>
196 /// Serialization options.
197 /// Can be null if there are no options.
198 /// "wipe-owners" will write UUID.Zero rather than the ownerID so that a later reload loads all parcels with the estate owner as the owner
199 /// </param>
200 public static string Serialize(LandData landData, Dictionary<string, object> options)
201 {
202 StringWriter sw = new StringWriter();
203 XmlTextWriter xtw = new XmlTextWriter(sw);
204 xtw.Formatting = Formatting.Indented;
205
206 xtw.WriteStartDocument();
207 xtw.WriteStartElement("LandData");
208
209 xtw.WriteElementString("Area", Convert.ToString(landData.Area));
210 xtw.WriteElementString("AuctionID", Convert.ToString(landData.AuctionID));
211 xtw.WriteElementString("AuthBuyerID", landData.AuthBuyerID.ToString());
212 xtw.WriteElementString("Category", Convert.ToString((sbyte)landData.Category));
213 xtw.WriteElementString("ClaimDate", Convert.ToString(landData.ClaimDate));
214 xtw.WriteElementString("ClaimPrice", Convert.ToString(landData.ClaimPrice));
215 xtw.WriteElementString("GlobalID", landData.GlobalID.ToString());
216
217 UUID groupID = options.ContainsKey("wipe-owners") ? UUID.Zero : landData.GroupID;
218 xtw.WriteElementString("GroupID", groupID.ToString());
219
220 bool isGroupOwned = options.ContainsKey("wipe-owners") ? false : landData.IsGroupOwned;
221 xtw.WriteElementString("IsGroupOwned", Convert.ToString(isGroupOwned));
222
223 xtw.WriteElementString("Bitmap", Convert.ToBase64String(landData.Bitmap));
224 xtw.WriteElementString("Description", landData.Description);
225 xtw.WriteElementString("Flags", Convert.ToString((uint)landData.Flags));
226 xtw.WriteElementString("LandingType", Convert.ToString((byte)landData.LandingType));
227 xtw.WriteElementString("Name", landData.Name);
228 xtw.WriteElementString("Status", Convert.ToString((sbyte)landData.Status));
229 xtw.WriteElementString("LocalID", landData.LocalID.ToString());
230 xtw.WriteElementString("MediaAutoScale", Convert.ToString(landData.MediaAutoScale));
231 xtw.WriteElementString("MediaID", landData.MediaID.ToString());
232 xtw.WriteElementString("MediaURL", landData.MediaURL);
233 xtw.WriteElementString("MusicURL", landData.MusicURL);
234
235 UUID ownerID = options.ContainsKey("wipe-owners") ? UUID.Zero : landData.OwnerID;
236 xtw.WriteElementString("OwnerID", ownerID.ToString());
237
238 xtw.WriteStartElement("ParcelAccessList");
239 foreach (LandAccessEntry pal in landData.ParcelAccessList)
240 {
241 xtw.WriteStartElement("ParcelAccessEntry");
242 xtw.WriteElementString("AgentID", pal.AgentID.ToString());
243 xtw.WriteElementString("Time", pal.Expires.ToString());
244 xtw.WriteElementString("AccessList", Convert.ToString((uint)pal.Flags));
245 xtw.WriteEndElement();
246 }
247 xtw.WriteEndElement();
248
249 xtw.WriteElementString("PassHours", Convert.ToString(landData.PassHours));
250 xtw.WriteElementString("PassPrice", Convert.ToString(landData.PassPrice));
251 xtw.WriteElementString("SalePrice", Convert.ToString(landData.SalePrice));
252 xtw.WriteElementString("SnapshotID", landData.SnapshotID.ToString());
253 xtw.WriteElementString("UserLocation", landData.UserLocation.ToString());
254 xtw.WriteElementString("UserLookAt", landData.UserLookAt.ToString());
255 xtw.WriteElementString("Dwell", "0");
256 xtw.WriteElementString("OtherCleanTime", Convert.ToString(landData.OtherCleanTime));
257
258 xtw.WriteEndElement();
259
260 xtw.Close();
261 sw.Close();
262
263 return sw.ToString();
264 }
265 }
266}
diff --git a/OpenSim/Framework/Serialization/External/OspResolver.cs b/OpenSim/Framework/Serialization/External/OspResolver.cs
new file mode 100644
index 0000000..fa7160f
--- /dev/null
+++ b/OpenSim/Framework/Serialization/External/OspResolver.cs
@@ -0,0 +1,208 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System.Reflection;
29using System.Text;
30using log4net;
31using OpenMetaverse;
32using OpenSim.Framework;
33using OpenSim.Services.Interfaces;
34
35namespace OpenSim.Framework.Serialization
36{
37 /// <summary>
38 /// Resolves OpenSim Profile Anchors (OSPA). An OSPA is a string used to provide information for
39 /// identifying user profiles or supplying a simple name if no profile is available.
40 /// </summary>
41 public class OspResolver
42 {
43 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
44
45 public const string OSPA_PREFIX = "ospa:";
46 public const string OSPA_NAME_KEY = "n";
47 public const string OSPA_NAME_VALUE_SEPARATOR = " ";
48 public const string OSPA_TUPLE_SEPARATOR = "|";
49 public static readonly char[] OSPA_TUPLE_SEPARATOR_ARRAY = OSPA_TUPLE_SEPARATOR.ToCharArray();
50 public const string OSPA_PAIR_SEPARATOR = "=";
51
52 /// <summary>
53 /// Make an OSPA given a user UUID
54 /// </summary>
55 /// <param name="userId"></param>
56 /// <param name="commsManager"></param>
57 /// <returns>The OSPA. Null if a user with the given UUID could not be found.</returns>
58 public static string MakeOspa(UUID userId, IUserAccountService userService)
59 {
60 if (userService == null)
61 {
62 m_log.Warn("[OSP RESOLVER]: UserService is null");
63 return userId.ToString();
64 }
65
66 UserAccount account = userService.GetUserAccount(UUID.Zero, userId);
67 if (account != null)
68 {
69 return MakeOspa(account.FirstName, account.LastName);
70 }
71// else
72// {
73// m_log.WarnFormat("[OSP RESOLVER]: No user account for {0}", userId);
74// System.Console.WriteLine("[OSP RESOLVER]: No user account for {0}", userId);
75// }
76
77 return null;
78 }
79
80 /// <summary>
81 /// Make an OSPA given a user name
82 /// </summary>
83 /// <param name="name"></param>
84 /// <returns></returns>
85 public static string MakeOspa(string firstName, string lastName)
86 {
87 string ospa
88 = OSPA_PREFIX + OSPA_NAME_KEY + OSPA_PAIR_SEPARATOR + firstName + OSPA_NAME_VALUE_SEPARATOR + lastName;
89
90// m_log.DebugFormat("[OSP RESOLVER]: Made OSPA {0} for {1} {2}", ospa, firstName, lastName);
91// System.Console.WriteLine("[OSP RESOLVER]: Made OSPA {0} for {1} {2}", ospa, firstName, lastName);
92
93 return ospa;
94 }
95
96 /// <summary>
97 /// Resolve an osp string into the most suitable internal OpenSim identifier.
98 /// </summary>
99 ///
100 /// In some cases this will be a UUID if a suitable profile exists on the system. In other cases, this may
101 /// just return the same identifier after creating a temporary profile.
102 ///
103 /// <param name="ospa"></param>
104 /// <param name="commsManager"></param>
105 /// <returns>
106 /// A suitable UUID for use in Second Life client communication. If the string was not a valid ospa, then UUID.Zero
107 /// is returned.
108 /// </returns>
109 public static UUID ResolveOspa(string ospa, IUserAccountService userService)
110 {
111 if (!ospa.StartsWith(OSPA_PREFIX))
112 {
113// m_log.DebugFormat("[OSP RESOLVER]: ResolveOspa() got unrecognized format [{0}]", ospa);
114 return UUID.Zero;
115 }
116
117// m_log.DebugFormat("[OSP RESOLVER]: Resolving {0}", ospa);
118
119 string ospaMeat = ospa.Substring(OSPA_PREFIX.Length);
120 string[] ospaTuples = ospaMeat.Split(OSPA_TUPLE_SEPARATOR_ARRAY);
121
122 foreach (string tuple in ospaTuples)
123 {
124 int tupleSeparatorIndex = tuple.IndexOf(OSPA_PAIR_SEPARATOR);
125
126 if (tupleSeparatorIndex < 0)
127 {
128 m_log.WarnFormat("[OSP RESOLVER]: Ignoring non-tuple component {0} in OSPA {1}", tuple, ospa);
129 continue;
130 }
131
132 string key = tuple.Remove(tupleSeparatorIndex).Trim();
133 string value = tuple.Substring(tupleSeparatorIndex + 1).Trim();
134
135 if (OSPA_NAME_KEY == key)
136 return ResolveOspaName(value, userService);
137 }
138
139 return UUID.Zero;
140 }
141
142 /// <summary>
143 /// Hash a profile name into a UUID
144 /// </summary>
145 /// <param name="name"></param>
146 /// <returns></returns>
147 public static UUID HashName(string name)
148 {
149 return new UUID(Utils.MD5(Encoding.Unicode.GetBytes(name)), 0);
150 }
151
152 /// <summary>
153 /// Resolve an OSPI name by querying existing persistent user profiles. If there is no persistent user profile
154 /// then a temporary user profile is inserted in the cache.
155 /// </summary>
156 /// <param name="name"></param>
157 /// <param name="commsManager"></param>
158 /// <returns>
159 /// An OpenSim internal identifier for the name given. Returns null if the name was not valid
160 /// </returns>
161 protected static UUID ResolveOspaName(string name, IUserAccountService userService)
162 {
163 if (userService == null)
164 return UUID.Zero;
165
166 int nameSeparatorIndex = name.IndexOf(OSPA_NAME_VALUE_SEPARATOR);
167
168 if (nameSeparatorIndex < 0)
169 {
170 m_log.WarnFormat("[OSP RESOLVER]: Ignoring unseparated name {0}", name);
171 return UUID.Zero;
172 }
173
174 string firstName = name.Remove(nameSeparatorIndex).TrimEnd();
175 string lastName = name.Substring(nameSeparatorIndex + 1).TrimStart();
176
177 UserAccount account = userService.GetUserAccount(UUID.Zero, firstName, lastName);
178 if (account != null)
179 {
180// m_log.DebugFormat(
181// "[OSP RESOLVER]: Found user account with uuid {0} for {1} {2}",
182// account.PrincipalID, firstName, lastName);
183
184 return account.PrincipalID;
185 }
186// else
187// {
188// m_log.DebugFormat("[OSP RESOLVER]: No resolved OSPA user account for {0}", name);
189// }
190
191 // XXX: Disable temporary user profile creation for now as implementation is incomplete - justincc
192 /*
193 UserProfileData tempUserProfile = new UserProfileData();
194 tempUserProfile.FirstName = firstName;
195 tempUserProfile.SurName = lastName;
196 tempUserProfile.ID = HashName(tempUserProfile.Name);
197
198 m_log.DebugFormat(
199 "[OSP RESOLVER]: Adding temporary user profile for {0} {1}", tempUserProfile.Name, tempUserProfile.ID);
200 commsManager.UserService.AddTemporaryUserProfile(tempUserProfile);
201
202 return tempUserProfile.ID;
203 */
204
205 return UUID.Zero;
206 }
207 }
208}
diff --git a/OpenSim/Framework/Serialization/External/RegionSettingsSerializer.cs b/OpenSim/Framework/Serialization/External/RegionSettingsSerializer.cs
new file mode 100644
index 0000000..19468c3
--- /dev/null
+++ b/OpenSim/Framework/Serialization/External/RegionSettingsSerializer.cs
@@ -0,0 +1,287 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System.IO;
29using System.Text;
30using System.Xml;
31using OpenMetaverse;
32using OpenSim.Framework;
33using log4net;
34using System.Reflection;
35
36namespace OpenSim.Framework.Serialization.External
37{
38 /// <summary>
39 /// Serialize and deserialize region settings as an external format.
40 /// </summary>
41 public class RegionSettingsSerializer
42 {
43 /// <summary>
44 /// Deserialize settings
45 /// </summary>
46 /// <param name="serializedSettings"></param>
47 /// <returns></returns>
48 /// <exception cref="System.Xml.XmlException"></exception>
49 public static RegionSettings Deserialize(byte[] serializedSettings)
50 {
51 return Deserialize(Encoding.ASCII.GetString(serializedSettings, 0, serializedSettings.Length));
52 }
53
54 /// <summary>
55 /// Deserialize settings
56 /// </summary>
57 /// <param name="serializedSettings"></param>
58 /// <returns></returns>
59 /// <exception cref="System.Xml.XmlException"></exception>
60 public static RegionSettings Deserialize(string serializedSettings)
61 {
62 RegionSettings settings = new RegionSettings();
63
64 StringReader sr = new StringReader(serializedSettings);
65 XmlTextReader xtr = new XmlTextReader(sr);
66
67 xtr.ReadStartElement("RegionSettings");
68
69 xtr.ReadStartElement("General");
70
71 while (xtr.Read() && xtr.NodeType != XmlNodeType.EndElement)
72 {
73 switch (xtr.Name)
74 {
75 case "AllowDamage":
76 settings.AllowDamage = bool.Parse(xtr.ReadElementContentAsString());
77 break;
78 case "AllowLandResell":
79 settings.AllowLandResell = bool.Parse(xtr.ReadElementContentAsString());
80 break;
81 case "AllowLandJoinDivide":
82 settings.AllowLandJoinDivide = bool.Parse(xtr.ReadElementContentAsString());
83 break;
84 case "BlockFly":
85 settings.BlockFly = bool.Parse(xtr.ReadElementContentAsString());
86 break;
87 case "BlockLandShowInSearch":
88 settings.BlockShowInSearch = bool.Parse(xtr.ReadElementContentAsString());
89 break;
90 case "BlockTerraform":
91 settings.BlockTerraform = bool.Parse(xtr.ReadElementContentAsString());
92 break;
93 case "DisableCollisions":
94 settings.DisableCollisions = bool.Parse(xtr.ReadElementContentAsString());
95 break;
96 case "DisablePhysics":
97 settings.DisablePhysics = bool.Parse(xtr.ReadElementContentAsString());
98 break;
99 case "DisableScripts":
100 settings.DisableScripts = bool.Parse(xtr.ReadElementContentAsString());
101 break;
102 case "MaturityRating":
103 settings.Maturity = int.Parse(xtr.ReadElementContentAsString());
104 break;
105 case "RestrictPushing":
106 settings.RestrictPushing = bool.Parse(xtr.ReadElementContentAsString());
107 break;
108 case "AgentLimit":
109 settings.AgentLimit = int.Parse(xtr.ReadElementContentAsString());
110 break;
111 case "ObjectBonus":
112 settings.ObjectBonus = double.Parse(xtr.ReadElementContentAsString(), Culture.NumberFormatInfo);
113 break;
114 }
115 }
116
117 xtr.ReadEndElement();
118 xtr.ReadStartElement("GroundTextures");
119
120 while (xtr.Read() && xtr.NodeType != XmlNodeType.EndElement)
121 {
122 switch (xtr.Name)
123 {
124 case "Texture1":
125 settings.TerrainTexture1 = UUID.Parse(xtr.ReadElementContentAsString());
126 break;
127 case "Texture2":
128 settings.TerrainTexture2 = UUID.Parse(xtr.ReadElementContentAsString());
129 break;
130 case "Texture3":
131 settings.TerrainTexture3 = UUID.Parse(xtr.ReadElementContentAsString());
132 break;
133 case "Texture4":
134 settings.TerrainTexture4 = UUID.Parse(xtr.ReadElementContentAsString());
135 break;
136 case "ElevationLowSW":
137 settings.Elevation1SW = double.Parse(xtr.ReadElementContentAsString(), Culture.NumberFormatInfo);
138 break;
139 case "ElevationLowNW":
140 settings.Elevation1NW = double.Parse(xtr.ReadElementContentAsString(), Culture.NumberFormatInfo);
141 break;
142 case "ElevationLowSE":
143 settings.Elevation1SE = double.Parse(xtr.ReadElementContentAsString(), Culture.NumberFormatInfo);
144 break;
145 case "ElevationLowNE":
146 settings.Elevation1NE = double.Parse(xtr.ReadElementContentAsString(), Culture.NumberFormatInfo);
147 break;
148 case "ElevationHighSW":
149 settings.Elevation2SW = double.Parse(xtr.ReadElementContentAsString(), Culture.NumberFormatInfo);
150 break;
151 case "ElevationHighNW":
152 settings.Elevation2NW = double.Parse(xtr.ReadElementContentAsString(), Culture.NumberFormatInfo);
153 break;
154 case "ElevationHighSE":
155 settings.Elevation2SE = double.Parse(xtr.ReadElementContentAsString(), Culture.NumberFormatInfo);
156 break;
157 case "ElevationHighNE":
158 settings.Elevation2NE = double.Parse(xtr.ReadElementContentAsString(), Culture.NumberFormatInfo);
159 break;
160 }
161 }
162
163 xtr.ReadEndElement();
164 xtr.ReadStartElement("Terrain");
165
166 while (xtr.Read() && xtr.NodeType != XmlNodeType.EndElement)
167 {
168 switch (xtr.Name)
169 {
170 case "WaterHeight":
171 settings.WaterHeight = double.Parse(xtr.ReadElementContentAsString(), Culture.NumberFormatInfo);
172 break;
173 case "TerrainRaiseLimit":
174 settings.TerrainRaiseLimit = double.Parse(xtr.ReadElementContentAsString(), Culture.NumberFormatInfo);
175 break;
176 case "TerrainLowerLimit":
177 settings.TerrainLowerLimit = double.Parse(xtr.ReadElementContentAsString(), Culture.NumberFormatInfo);
178 break;
179 case "UseEstateSun":
180 settings.UseEstateSun = bool.Parse(xtr.ReadElementContentAsString());
181 break;
182 case "FixedSun":
183 settings.FixedSun = bool.Parse(xtr.ReadElementContentAsString());
184 break;
185 case "SunPosition":
186 settings.SunPosition = double.Parse(xtr.ReadElementContentAsString());
187 break;
188 }
189 }
190
191 xtr.ReadEndElement();
192
193 if (xtr.IsStartElement("Telehub"))
194 {
195 xtr.ReadStartElement("Telehub");
196
197 while (xtr.Read() && xtr.NodeType != XmlNodeType.EndElement)
198 {
199 switch (xtr.Name)
200 {
201 case "TelehubObject":
202 settings.TelehubObject = UUID.Parse(xtr.ReadElementContentAsString());
203 break;
204 case "SpawnPoint":
205 string str = xtr.ReadElementContentAsString();
206 SpawnPoint sp = SpawnPoint.Parse(str);
207 settings.AddSpawnPoint(sp);
208 break;
209 }
210 }
211 }
212
213 xtr.Close();
214 sr.Close();
215
216 return settings;
217 }
218
219 public static string Serialize(RegionSettings settings)
220 {
221 StringWriter sw = new StringWriter();
222 XmlTextWriter xtw = new XmlTextWriter(sw);
223 xtw.Formatting = Formatting.Indented;
224 xtw.WriteStartDocument();
225
226 xtw.WriteStartElement("RegionSettings");
227
228 xtw.WriteStartElement("General");
229 xtw.WriteElementString("AllowDamage", settings.AllowDamage.ToString());
230 xtw.WriteElementString("AllowLandResell", settings.AllowLandResell.ToString());
231 xtw.WriteElementString("AllowLandJoinDivide", settings.AllowLandJoinDivide.ToString());
232 xtw.WriteElementString("BlockFly", settings.BlockFly.ToString());
233 xtw.WriteElementString("BlockLandShowInSearch", settings.BlockShowInSearch.ToString());
234 xtw.WriteElementString("BlockTerraform", settings.BlockTerraform.ToString());
235 xtw.WriteElementString("DisableCollisions", settings.DisableCollisions.ToString());
236 xtw.WriteElementString("DisablePhysics", settings.DisablePhysics.ToString());
237 xtw.WriteElementString("DisableScripts", settings.DisableScripts.ToString());
238 xtw.WriteElementString("MaturityRating", settings.Maturity.ToString());
239 xtw.WriteElementString("RestrictPushing", settings.RestrictPushing.ToString());
240 xtw.WriteElementString("AgentLimit", settings.AgentLimit.ToString());
241 xtw.WriteElementString("ObjectBonus", settings.ObjectBonus.ToString());
242 xtw.WriteEndElement();
243
244 xtw.WriteStartElement("GroundTextures");
245 xtw.WriteElementString("Texture1", settings.TerrainTexture1.ToString());
246 xtw.WriteElementString("Texture2", settings.TerrainTexture2.ToString());
247 xtw.WriteElementString("Texture3", settings.TerrainTexture3.ToString());
248 xtw.WriteElementString("Texture4", settings.TerrainTexture4.ToString());
249 xtw.WriteElementString("ElevationLowSW", settings.Elevation1SW.ToString());
250 xtw.WriteElementString("ElevationLowNW", settings.Elevation1NW.ToString());
251 xtw.WriteElementString("ElevationLowSE", settings.Elevation1SE.ToString());
252 xtw.WriteElementString("ElevationLowNE", settings.Elevation1NE.ToString());
253 xtw.WriteElementString("ElevationHighSW", settings.Elevation2SW.ToString());
254 xtw.WriteElementString("ElevationHighNW", settings.Elevation2NW.ToString());
255 xtw.WriteElementString("ElevationHighSE", settings.Elevation2SE.ToString());
256 xtw.WriteElementString("ElevationHighNE", settings.Elevation2NE.ToString());
257 xtw.WriteEndElement();
258
259 xtw.WriteStartElement("Terrain");
260 xtw.WriteElementString("WaterHeight", settings.WaterHeight.ToString());
261 xtw.WriteElementString("TerrainRaiseLimit", settings.TerrainRaiseLimit.ToString());
262 xtw.WriteElementString("TerrainLowerLimit", settings.TerrainLowerLimit.ToString());
263 xtw.WriteElementString("UseEstateSun", settings.UseEstateSun.ToString());
264 xtw.WriteElementString("FixedSun", settings.FixedSun.ToString());
265 xtw.WriteElementString("SunPosition", settings.SunPosition.ToString());
266 // Note: 'SunVector' isn't saved because this value is owned by the Sun Module, which
267 // calculates it automatically according to the date and other factors.
268 xtw.WriteEndElement();
269
270 xtw.WriteStartElement("Telehub");
271 if (settings.TelehubObject != UUID.Zero)
272 {
273 xtw.WriteElementString("TelehubObject", settings.TelehubObject.ToString());
274 foreach (SpawnPoint sp in settings.SpawnPoints())
275 xtw.WriteElementString("SpawnPoint", sp.ToString());
276 }
277 xtw.WriteEndElement();
278
279 xtw.WriteEndElement();
280
281 xtw.Close();
282 sw.Close();
283
284 return sw.ToString();
285 }
286 }
287}
diff --git a/OpenSim/Framework/Serialization/External/UserInventoryItemSerializer.cs b/OpenSim/Framework/Serialization/External/UserInventoryItemSerializer.cs
new file mode 100644
index 0000000..994cede
--- /dev/null
+++ b/OpenSim/Framework/Serialization/External/UserInventoryItemSerializer.cs
@@ -0,0 +1,304 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.IO;
31using System.Reflection;
32using System.Text;
33using System.Xml;
34
35using log4net;
36using OpenMetaverse;
37using OpenSim.Framework;
38using OpenSim.Services.Interfaces;
39
40namespace OpenSim.Framework.Serialization.External
41{
42 /// <summary>
43 /// Serialize and deserialize user inventory items as an external format.
44 /// </summary>
45 public class UserInventoryItemSerializer
46 {
47// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
48
49 private static Dictionary<string, Action<InventoryItemBase, XmlReader>> m_InventoryItemXmlProcessors
50 = new Dictionary<string, Action<InventoryItemBase, XmlReader>>();
51
52 #region InventoryItemBase Processor initialization
53 static UserInventoryItemSerializer()
54 {
55 m_InventoryItemXmlProcessors.Add("Name", ProcessName);
56 m_InventoryItemXmlProcessors.Add("ID", ProcessID);
57 m_InventoryItemXmlProcessors.Add("InvType", ProcessInvType);
58 m_InventoryItemXmlProcessors.Add("CreatorUUID", ProcessCreatorUUID);
59 m_InventoryItemXmlProcessors.Add("CreatorID", ProcessCreatorID);
60 m_InventoryItemXmlProcessors.Add("CreatorData", ProcessCreatorData);
61 m_InventoryItemXmlProcessors.Add("CreationDate", ProcessCreationDate);
62 m_InventoryItemXmlProcessors.Add("Owner", ProcessOwner);
63 m_InventoryItemXmlProcessors.Add("Description", ProcessDescription);
64 m_InventoryItemXmlProcessors.Add("AssetType", ProcessAssetType);
65 m_InventoryItemXmlProcessors.Add("AssetID", ProcessAssetID);
66 m_InventoryItemXmlProcessors.Add("SaleType", ProcessSaleType);
67 m_InventoryItemXmlProcessors.Add("SalePrice", ProcessSalePrice);
68 m_InventoryItemXmlProcessors.Add("BasePermissions", ProcessBasePermissions);
69 m_InventoryItemXmlProcessors.Add("CurrentPermissions", ProcessCurrentPermissions);
70 m_InventoryItemXmlProcessors.Add("EveryOnePermissions", ProcessEveryOnePermissions);
71 m_InventoryItemXmlProcessors.Add("NextPermissions", ProcessNextPermissions);
72 m_InventoryItemXmlProcessors.Add("Flags", ProcessFlags);
73 m_InventoryItemXmlProcessors.Add("GroupID", ProcessGroupID);
74 m_InventoryItemXmlProcessors.Add("GroupOwned", ProcessGroupOwned);
75 }
76 #endregion
77
78 #region InventoryItemBase Processors
79 private static void ProcessName(InventoryItemBase item, XmlReader reader)
80 {
81 item.Name = reader.ReadElementContentAsString("Name", String.Empty);
82 }
83
84 private static void ProcessID(InventoryItemBase item, XmlReader reader)
85 {
86 item.ID = Util.ReadUUID(reader, "ID");
87 }
88
89 private static void ProcessInvType(InventoryItemBase item, XmlReader reader)
90 {
91 item.InvType = reader.ReadElementContentAsInt("InvType", String.Empty);
92 }
93
94 private static void ProcessCreatorUUID(InventoryItemBase item, XmlReader reader)
95 {
96 item.CreatorId = reader.ReadElementContentAsString("CreatorUUID", String.Empty);
97 }
98
99 private static void ProcessCreatorID(InventoryItemBase item, XmlReader reader)
100 {
101 // when it exists, this overrides the previous
102 item.CreatorId = reader.ReadElementContentAsString("CreatorID", String.Empty);
103 }
104
105 private static void ProcessCreationDate(InventoryItemBase item, XmlReader reader)
106 {
107 item.CreationDate = reader.ReadElementContentAsInt("CreationDate", String.Empty);
108 }
109
110 private static void ProcessOwner(InventoryItemBase item, XmlReader reader)
111 {
112 item.Owner = Util.ReadUUID(reader, "Owner");
113 }
114
115 private static void ProcessDescription(InventoryItemBase item, XmlReader reader)
116 {
117 item.Description = reader.ReadElementContentAsString("Description", String.Empty);
118 }
119
120 private static void ProcessAssetType(InventoryItemBase item, XmlReader reader)
121 {
122 item.AssetType = reader.ReadElementContentAsInt("AssetType", String.Empty);
123 }
124
125 private static void ProcessAssetID(InventoryItemBase item, XmlReader reader)
126 {
127 item.AssetID = Util.ReadUUID(reader, "AssetID");
128 }
129
130 private static void ProcessSaleType(InventoryItemBase item, XmlReader reader)
131 {
132 item.SaleType = (byte)reader.ReadElementContentAsInt("SaleType", String.Empty);
133 }
134
135 private static void ProcessSalePrice(InventoryItemBase item, XmlReader reader)
136 {
137 item.SalePrice = reader.ReadElementContentAsInt("SalePrice", String.Empty);
138 }
139
140 private static void ProcessBasePermissions(InventoryItemBase item, XmlReader reader)
141 {
142 item.BasePermissions = (uint)reader.ReadElementContentAsInt("BasePermissions", String.Empty);
143 }
144
145 private static void ProcessCurrentPermissions(InventoryItemBase item, XmlReader reader)
146 {
147 item.CurrentPermissions = (uint)reader.ReadElementContentAsInt("CurrentPermissions", String.Empty);
148 }
149
150 private static void ProcessEveryOnePermissions(InventoryItemBase item, XmlReader reader)
151 {
152 item.EveryOnePermissions = (uint)reader.ReadElementContentAsInt("EveryOnePermissions", String.Empty);
153 }
154
155 private static void ProcessNextPermissions(InventoryItemBase item, XmlReader reader)
156 {
157 item.NextPermissions = (uint)reader.ReadElementContentAsInt("NextPermissions", String.Empty);
158 }
159
160 private static void ProcessFlags(InventoryItemBase item, XmlReader reader)
161 {
162 item.Flags = (uint)reader.ReadElementContentAsInt("Flags", String.Empty);
163 }
164
165 private static void ProcessGroupID(InventoryItemBase item, XmlReader reader)
166 {
167 item.GroupID = Util.ReadUUID(reader, "GroupID");
168 }
169
170 private static void ProcessGroupOwned(InventoryItemBase item, XmlReader reader)
171 {
172 item.GroupOwned = Util.ReadBoolean(reader);
173 }
174
175 private static void ProcessCreatorData(InventoryItemBase item, XmlReader reader)
176 {
177 item.CreatorData = reader.ReadElementContentAsString("CreatorData", String.Empty);
178 }
179
180 #endregion
181
182 /// <summary>
183 /// Deserialize item
184 /// </summary>
185 /// <param name="serializedSettings"></param>
186 /// <returns></returns>
187 /// <exception cref="System.Xml.XmlException"></exception>
188 public static InventoryItemBase Deserialize(byte[] serialization)
189 {
190 return Deserialize(Encoding.ASCII.GetString(serialization, 0, serialization.Length));
191 }
192
193 /// <summary>
194 /// Deserialize settings
195 /// </summary>
196 /// <param name="serializedSettings"></param>
197 /// <returns></returns>
198 /// <exception cref="System.Xml.XmlException"></exception>
199 public static InventoryItemBase Deserialize(string serialization)
200 {
201 InventoryItemBase item = new InventoryItemBase();
202
203 using (XmlTextReader reader = new XmlTextReader(new StringReader(serialization)))
204 {
205 reader.ReadStartElement("InventoryItem");
206
207 ExternalRepresentationUtils.ExecuteReadProcessors<InventoryItemBase>(
208 item, m_InventoryItemXmlProcessors, reader);
209
210 reader.ReadEndElement(); // InventoryItem
211 }
212
213 //m_log.DebugFormat("[XXX]: parsed InventoryItemBase {0} - {1}", obj.Name, obj.UUID);
214 return item;
215 }
216
217 public static string Serialize(InventoryItemBase inventoryItem, Dictionary<string, object> options, IUserAccountService userAccountService)
218 {
219 StringWriter sw = new StringWriter();
220 XmlTextWriter writer = new XmlTextWriter(sw);
221 writer.Formatting = Formatting.Indented;
222 writer.WriteStartDocument();
223
224 writer.WriteStartElement("InventoryItem");
225
226 writer.WriteStartElement("Name");
227 writer.WriteString(inventoryItem.Name);
228 writer.WriteEndElement();
229 writer.WriteStartElement("ID");
230 writer.WriteString(inventoryItem.ID.ToString());
231 writer.WriteEndElement();
232 writer.WriteStartElement("InvType");
233 writer.WriteString(inventoryItem.InvType.ToString());
234 writer.WriteEndElement();
235 writer.WriteStartElement("CreatorUUID");
236 writer.WriteString(OspResolver.MakeOspa(inventoryItem.CreatorIdAsUuid, userAccountService));
237 writer.WriteEndElement();
238 writer.WriteStartElement("CreationDate");
239 writer.WriteString(inventoryItem.CreationDate.ToString());
240 writer.WriteEndElement();
241 writer.WriteStartElement("Owner");
242 writer.WriteString(inventoryItem.Owner.ToString());
243 writer.WriteEndElement();
244 writer.WriteStartElement("Description");
245 writer.WriteString(inventoryItem.Description);
246 writer.WriteEndElement();
247 writer.WriteStartElement("AssetType");
248 writer.WriteString(inventoryItem.AssetType.ToString());
249 writer.WriteEndElement();
250 writer.WriteStartElement("AssetID");
251 writer.WriteString(inventoryItem.AssetID.ToString());
252 writer.WriteEndElement();
253 writer.WriteStartElement("SaleType");
254 writer.WriteString(inventoryItem.SaleType.ToString());
255 writer.WriteEndElement();
256 writer.WriteStartElement("SalePrice");
257 writer.WriteString(inventoryItem.SalePrice.ToString());
258 writer.WriteEndElement();
259 writer.WriteStartElement("BasePermissions");
260 writer.WriteString(inventoryItem.BasePermissions.ToString());
261 writer.WriteEndElement();
262 writer.WriteStartElement("CurrentPermissions");
263 writer.WriteString(inventoryItem.CurrentPermissions.ToString());
264 writer.WriteEndElement();
265 writer.WriteStartElement("EveryOnePermissions");
266 writer.WriteString(inventoryItem.EveryOnePermissions.ToString());
267 writer.WriteEndElement();
268 writer.WriteStartElement("NextPermissions");
269 writer.WriteString(inventoryItem.NextPermissions.ToString());
270 writer.WriteEndElement();
271 writer.WriteStartElement("Flags");
272 writer.WriteString(inventoryItem.Flags.ToString());
273 writer.WriteEndElement();
274 writer.WriteStartElement("GroupID");
275 writer.WriteString(inventoryItem.GroupID.ToString());
276 writer.WriteEndElement();
277 writer.WriteStartElement("GroupOwned");
278 writer.WriteString(inventoryItem.GroupOwned.ToString());
279 writer.WriteEndElement();
280 if (options.ContainsKey("creators") && !string.IsNullOrEmpty(inventoryItem.CreatorData))
281 writer.WriteElementString("CreatorData", inventoryItem.CreatorData);
282 else if (options.ContainsKey("home"))
283 {
284 if (userAccountService != null)
285 {
286 UserAccount account = userAccountService.GetUserAccount(UUID.Zero, inventoryItem.CreatorIdAsUuid);
287 if (account != null)
288 {
289 string creatorData = ExternalRepresentationUtils.CalcCreatorData((string)options["home"], inventoryItem.CreatorIdAsUuid, account.FirstName + " " + account.LastName);
290 writer.WriteElementString("CreatorData", creatorData);
291 }
292 writer.WriteElementString("CreatorID", inventoryItem.CreatorId);
293 }
294 }
295
296 writer.WriteEndElement();
297
298 writer.Close();
299 sw.Close();
300
301 return sw.ToString();
302 }
303 }
304}
diff --git a/OpenSim/Framework/Serialization/External/UserProfileSerializer.cs b/OpenSim/Framework/Serialization/External/UserProfileSerializer.cs
new file mode 100644
index 0000000..c685a15
--- /dev/null
+++ b/OpenSim/Framework/Serialization/External/UserProfileSerializer.cs
@@ -0,0 +1,73 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System.IO;
29using System.Xml;
30using OpenMetaverse;
31using OpenSim.Framework;
32
33namespace OpenSim.Framework.Serialization.External
34{
35 /// <summary>
36 /// Serialize and deserialize user profiles as an external format.
37 /// </summary>
38 /// <remarks>
39 /// Currently UNUSED.
40 /// </remarks>
41 public class UserProfileSerializer
42 {
43 public const int MAJOR_VERSION = 0;
44 public const int MINOR_VERSION = 1;
45
46 public static string Serialize(UUID userID, string firstName, string lastName)
47 {
48 StringWriter sw = new StringWriter();
49 XmlTextWriter xtw = new XmlTextWriter(sw);
50 xtw.Formatting = Formatting.Indented;
51 xtw.WriteStartDocument();
52
53 xtw.WriteStartElement("user_profile");
54 xtw.WriteAttributeString("major_version", MAJOR_VERSION.ToString());
55 xtw.WriteAttributeString("minor_version", MINOR_VERSION.ToString());
56
57 xtw.WriteElementString("name", firstName + " " + lastName);
58 xtw.WriteElementString("id", userID.ToString());
59 xtw.WriteElementString("about", "");
60
61 // Not sure if we're storing this yet, need to take a look
62// xtw.WriteElementString("Url", profile.Url);
63 // or, indeed, interests
64
65 xtw.WriteEndElement();
66
67 xtw.Close();
68 sw.Close();
69
70 return sw.ToString();
71 }
72 }
73} \ No newline at end of file
diff --git a/OpenSim/Framework/Serialization/Properties/AssemblyInfo.cs b/OpenSim/Framework/Serialization/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..0cce722
--- /dev/null
+++ b/OpenSim/Framework/Serialization/Properties/AssemblyInfo.cs
@@ -0,0 +1,33 @@
1using System.Reflection;
2using System.Runtime.CompilerServices;
3using System.Runtime.InteropServices;
4
5// General Information about an assembly is controlled through the following
6// set of attributes. Change these attribute values to modify the information
7// associated with an assembly.
8[assembly: AssemblyTitle("OpenSim.Framework.Serialization")]
9[assembly: AssemblyDescription("")]
10[assembly: AssemblyConfiguration("")]
11[assembly: AssemblyCompany("http://opensimulator.org")]
12[assembly: AssemblyProduct("OpenSim")]
13[assembly: AssemblyCopyright("OpenSimulator developers")]
14[assembly: AssemblyTrademark("")]
15[assembly: AssemblyCulture("")]
16
17// Setting ComVisible to false makes the types in this assembly not visible
18// to COM components. If you need to access a type in this assembly from
19// COM, set the ComVisible attribute to true on that type.
20[assembly: ComVisible(false)]
21
22// The following GUID is for the ID of the typelib if this project is exposed to COM
23[assembly: Guid("919db41e-4ac0-4f24-9992-81d62c0ee183")]
24
25// Version information for an assembly consists of the following four values:
26//
27// Major Version
28// Minor Version
29// Build Number
30// Revision
31//
32[assembly: AssemblyVersion("0.8.2.*")]
33
diff --git a/OpenSim/Framework/Serialization/TarArchiveReader.cs b/OpenSim/Framework/Serialization/TarArchiveReader.cs
new file mode 100644
index 0000000..339a37a
--- /dev/null
+++ b/OpenSim/Framework/Serialization/TarArchiveReader.cs
@@ -0,0 +1,226 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.IO;
30using System.Reflection;
31using System.Text;
32using log4net;
33
34namespace OpenSim.Framework.Serialization
35{
36 /// <summary>
37 /// Temporary code to do the bare minimum required to read a tar archive for our purposes
38 /// </summary>
39 public class TarArchiveReader
40 {
41 //private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
42
43 public enum TarEntryType
44 {
45 TYPE_UNKNOWN = 0,
46 TYPE_NORMAL_FILE = 1,
47 TYPE_HARD_LINK = 2,
48 TYPE_SYMBOLIC_LINK = 3,
49 TYPE_CHAR_SPECIAL = 4,
50 TYPE_BLOCK_SPECIAL = 5,
51 TYPE_DIRECTORY = 6,
52 TYPE_FIFO = 7,
53 TYPE_CONTIGUOUS_FILE = 8,
54 }
55
56 /// <summary>
57 /// Binary reader for the underlying stream
58 /// </summary>
59 protected BinaryReader m_br;
60
61 /// <summary>
62 /// Used to trim off null chars
63 /// </summary>
64 protected static char[] m_nullCharArray = new char[] { '\0' };
65 /// <summary>
66 /// Used to trim off space chars
67 /// </summary>
68 protected static char[] m_spaceCharArray = new char[] { ' ' };
69
70 /// <summary>
71 /// Generate a tar reader which reads from the given stream.
72 /// </summary>
73 /// <param name="s"></param>
74 public TarArchiveReader(Stream s)
75 {
76 m_br = new BinaryReader(s);
77 }
78
79 /// <summary>
80 /// Read the next entry in the tar file.
81 /// </summary>
82 /// <param name="filePath"></param>
83 /// <returns>the data for the entry. Returns null if there are no more entries</returns>
84 public byte[] ReadEntry(out string filePath, out TarEntryType entryType)
85 {
86 filePath = String.Empty;
87 entryType = TarEntryType.TYPE_UNKNOWN;
88 TarHeader header = ReadHeader();
89
90 if (null == header)
91 return null;
92
93 entryType = header.EntryType;
94 filePath = header.FilePath;
95 return ReadData(header.FileSize);
96 }
97
98 /// <summary>
99 /// Read the next 512 byte chunk of data as a tar header.
100 /// </summary>
101 /// <returns>A tar header struct. null if we have reached the end of the archive.</returns>
102 protected TarHeader ReadHeader()
103 {
104 byte[] header = m_br.ReadBytes(512);
105
106 // If there are no more bytes in the stream, return null header
107 if (header.Length == 0)
108 return null;
109
110 // If we've reached the end of the archive we'll be in null block territory, which means
111 // the next byte will be 0
112 if (header[0] == 0)
113 return null;
114
115 TarHeader tarHeader = new TarHeader();
116
117 // If we're looking at a GNU tar long link then extract the long name and pull up the next header
118 if (header[156] == (byte)'L')
119 {
120 int longNameLength = ConvertOctalBytesToDecimal(header, 124, 11);
121 tarHeader.FilePath = Encoding.ASCII.GetString(ReadData(longNameLength));
122 //m_log.DebugFormat("[TAR ARCHIVE READER]: Got long file name {0}", tarHeader.FilePath);
123 header = m_br.ReadBytes(512);
124 }
125 else
126 {
127 tarHeader.FilePath = Encoding.ASCII.GetString(header, 0, 100);
128 tarHeader.FilePath = tarHeader.FilePath.Trim(m_nullCharArray);
129 //m_log.DebugFormat("[TAR ARCHIVE READER]: Got short file name {0}", tarHeader.FilePath);
130 }
131
132 tarHeader.FileSize = ConvertOctalBytesToDecimal(header, 124, 11);
133
134 switch (header[156])
135 {
136 case 0:
137 tarHeader.EntryType = TarEntryType.TYPE_NORMAL_FILE;
138 break;
139 case (byte)'0':
140 tarHeader.EntryType = TarEntryType.TYPE_NORMAL_FILE;
141 break;
142 case (byte)'1':
143 tarHeader.EntryType = TarEntryType.TYPE_HARD_LINK;
144 break;
145 case (byte)'2':
146 tarHeader.EntryType = TarEntryType.TYPE_SYMBOLIC_LINK;
147 break;
148 case (byte)'3':
149 tarHeader.EntryType = TarEntryType.TYPE_CHAR_SPECIAL;
150 break;
151 case (byte)'4':
152 tarHeader.EntryType = TarEntryType.TYPE_BLOCK_SPECIAL;
153 break;
154 case (byte)'5':
155 tarHeader.EntryType = TarEntryType.TYPE_DIRECTORY;
156 break;
157 case (byte)'6':
158 tarHeader.EntryType = TarEntryType.TYPE_FIFO;
159 break;
160 case (byte)'7':
161 tarHeader.EntryType = TarEntryType.TYPE_CONTIGUOUS_FILE;
162 break;
163 }
164
165 return tarHeader;
166 }
167
168 /// <summary>
169 /// Read data following a header
170 /// </summary>
171 /// <param name="fileSize"></param>
172 /// <returns></returns>
173 protected byte[] ReadData(int fileSize)
174 {
175 byte[] data = m_br.ReadBytes(fileSize);
176
177 //m_log.DebugFormat("[TAR ARCHIVE READER]: fileSize {0}", fileSize);
178
179 // Read the rest of the empty padding in the 512 byte block
180 if (fileSize % 512 != 0)
181 {
182 int paddingLeft = 512 - (fileSize % 512);
183
184 //m_log.DebugFormat("[TAR ARCHIVE READER]: Reading {0} padding bytes", paddingLeft);
185
186 m_br.ReadBytes(paddingLeft);
187 }
188
189 return data;
190 }
191
192 public void Close()
193 {
194 m_br.Close();
195 }
196
197 /// <summary>
198 /// Convert octal bytes to a decimal representation
199 /// </summary>
200 /// <param name="bytes"></param>
201 /// <returns></returns>
202 public static int ConvertOctalBytesToDecimal(byte[] bytes, int startIndex, int count)
203 {
204 // Trim leading white space: ancient tars do that instead
205 // of leading 0s :-( don't ask. really.
206 string oString = Encoding.ASCII.GetString(bytes, startIndex, count).TrimStart(m_spaceCharArray);
207
208 int d = 0;
209
210 foreach (char c in oString)
211 {
212 d <<= 3;
213 d |= c - '0';
214 }
215
216 return d;
217 }
218 }
219
220 public class TarHeader
221 {
222 public string FilePath;
223 public int FileSize;
224 public TarArchiveReader.TarEntryType EntryType;
225 }
226}
diff --git a/OpenSim/Framework/Serialization/TarArchiveWriter.cs b/OpenSim/Framework/Serialization/TarArchiveWriter.cs
new file mode 100644
index 0000000..2a3bc48
--- /dev/null
+++ b/OpenSim/Framework/Serialization/TarArchiveWriter.cs
@@ -0,0 +1,229 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.IO;
31using System.Reflection;
32using System.Text;
33using log4net;
34
35namespace OpenSim.Framework.Serialization
36{
37 /// <summary>
38 /// Temporary code to produce a tar archive in tar v7 format
39 /// </summary>
40 public class TarArchiveWriter
41 {
42// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
43
44 /// <summary>
45 /// Binary writer for the underlying stream
46 /// </summary>
47 protected BinaryWriter m_bw;
48
49 public TarArchiveWriter(Stream s)
50 {
51 m_bw = new BinaryWriter(s);
52 }
53
54 /// <summary>
55 /// Write a directory entry to the tar archive. We can only handle one path level right now!
56 /// </summary>
57 /// <param name="dirName"></param>
58 public void WriteDir(string dirName)
59 {
60 // Directories are signalled by a final /
61 if (!dirName.EndsWith("/"))
62 dirName += "/";
63
64 WriteFile(dirName, new byte[0]);
65 }
66
67 /// <summary>
68 /// Write a file to the tar archive
69 /// </summary>
70 /// <param name="filePath"></param>
71 /// <param name="data"></param>
72 public void WriteFile(string filePath, string data)
73 {
74 WriteFile(filePath, Util.UTF8NoBomEncoding.GetBytes(data));
75 }
76
77 /// <summary>
78 /// Write a file to the tar archive
79 /// </summary>
80 /// <param name="filePath"></param>
81 /// <param name="data"></param>
82 public void WriteFile(string filePath, byte[] data)
83 {
84 if (filePath.Length > 100)
85 WriteEntry("././@LongLink", Encoding.ASCII.GetBytes(filePath), 'L');
86
87 char fileType;
88
89 if (filePath.EndsWith("/"))
90 {
91 fileType = '5';
92 }
93 else
94 {
95 fileType = '0';
96 }
97
98 WriteEntry(filePath, data, fileType);
99 }
100
101 /// <summary>
102 /// Finish writing the raw tar archive data to a stream. The stream will be closed on completion.
103 /// </summary>
104 /// <param name="s">Stream to which to write the data</param>
105 /// <returns></returns>
106 public void Close()
107 {
108 //m_log.Debug("[TAR ARCHIVE WRITER]: Writing final consecutive 0 blocks");
109
110 // Write two consecutive 0 blocks to end the archive
111 byte[] finalZeroPadding = new byte[1024];
112
113 lock (m_bw)
114 {
115 m_bw.Write(finalZeroPadding);
116
117 m_bw.Flush();
118 m_bw.Close();
119 }
120 }
121
122 public static byte[] ConvertDecimalToPaddedOctalBytes(int d, int padding)
123 {
124 string oString = "";
125
126 while (d > 0)
127 {
128 oString = Convert.ToString((byte)'0' + d & 7) + oString;
129 d >>= 3;
130 }
131
132 while (oString.Length < padding)
133 {
134 oString = "0" + oString;
135 }
136
137 byte[] oBytes = Encoding.ASCII.GetBytes(oString);
138
139 return oBytes;
140 }
141
142 /// <summary>
143 /// Write a particular entry
144 /// </summary>
145 /// <param name="filePath"></param>
146 /// <param name="data"></param>
147 /// <param name="fileType"></param>
148 protected void WriteEntry(string filePath, byte[] data, char fileType)
149 {
150// m_log.DebugFormat(
151// "[TAR ARCHIVE WRITER]: Data for {0} is {1} bytes", filePath, (null == data ? "null" : data.Length.ToString()));
152
153 byte[] header = new byte[512];
154
155 // file path field (100)
156 byte[] nameBytes = Encoding.ASCII.GetBytes(filePath);
157 int nameSize = (nameBytes.Length >= 100) ? 100 : nameBytes.Length;
158 Array.Copy(nameBytes, header, nameSize);
159
160 // file mode (8)
161 byte[] modeBytes = Encoding.ASCII.GetBytes("0000777");
162 Array.Copy(modeBytes, 0, header, 100, 7);
163
164 // owner user id (8)
165 byte[] ownerIdBytes = Encoding.ASCII.GetBytes("0000764");
166 Array.Copy(ownerIdBytes, 0, header, 108, 7);
167
168 // group user id (8)
169 byte[] groupIdBytes = Encoding.ASCII.GetBytes("0000764");
170 Array.Copy(groupIdBytes, 0, header, 116, 7);
171
172 // file size in bytes (12)
173 int fileSize = data.Length;
174 //m_log.DebugFormat("[TAR ARCHIVE WRITER]: File size of {0} is {1}", filePath, fileSize);
175
176 byte[] fileSizeBytes = ConvertDecimalToPaddedOctalBytes(fileSize, 11);
177
178 Array.Copy(fileSizeBytes, 0, header, 124, 11);
179
180 // last modification time (12)
181 byte[] lastModTimeBytes = Encoding.ASCII.GetBytes("11017037332");
182 Array.Copy(lastModTimeBytes, 0, header, 136, 11);
183
184 // entry type indicator (1)
185 header[156] = Encoding.ASCII.GetBytes(new char[] { fileType })[0];
186
187 Array.Copy(Encoding.ASCII.GetBytes("0000000"), 0, header, 329, 7);
188 Array.Copy(Encoding.ASCII.GetBytes("0000000"), 0, header, 337, 7);
189
190 // check sum for header block (8) [calculated last]
191 Array.Copy(Encoding.ASCII.GetBytes(" "), 0, header, 148, 8);
192
193 int checksum = 0;
194 foreach (byte b in header)
195 {
196 checksum += b;
197 }
198
199 //m_log.DebugFormat("[TAR ARCHIVE WRITER]: Decimal header checksum is {0}", checksum);
200
201 byte[] checkSumBytes = ConvertDecimalToPaddedOctalBytes(checksum, 6);
202
203 Array.Copy(checkSumBytes, 0, header, 148, 6);
204
205 header[154] = 0;
206
207 lock (m_bw)
208 {
209 // Write out header
210 m_bw.Write(header);
211
212 // Write out data
213 // An IOException occurs if we try to write out an empty array in Mono 2.6
214 if (data.Length > 0)
215 m_bw.Write(data);
216
217 if (data.Length % 512 != 0)
218 {
219 int paddingRequired = 512 - (data.Length % 512);
220
221 //m_log.DebugFormat("[TAR ARCHIVE WRITER]: Padding data with {0} bytes", paddingRequired);
222
223 byte[] padding = new byte[paddingRequired];
224 m_bw.Write(padding);
225 }
226 }
227 }
228 }
229}
diff --git a/OpenSim/Framework/Serialization/Tests/LandDataSerializerTests.cs b/OpenSim/Framework/Serialization/Tests/LandDataSerializerTests.cs
new file mode 100644
index 0000000..e81cb78
--- /dev/null
+++ b/OpenSim/Framework/Serialization/Tests/LandDataSerializerTests.cs
@@ -0,0 +1,166 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using OpenMetaverse;
31using OpenMetaverse.StructuredData;
32using NUnit.Framework;
33using OpenSim.Framework;
34using OpenSim.Framework.Serialization.External;
35using OpenSim.Tests.Common;
36
37namespace OpenSim.Framework.Serialization.Tests
38{
39 [TestFixture]
40 public class LandDataSerializerTest : OpenSimTestCase
41 {
42 private LandData land;
43 private LandData landWithParcelAccessList;
44
45// private static string preSerialized = "<?xml version=\"1.0\" encoding=\"utf-16\"?>\n<LandData>\n <Area>128</Area>\n <AuctionID>0</AuctionID>\n <AuthBuyerID>00000000-0000-0000-0000-000000000000</AuthBuyerID>\n <Category>10</Category>\n <ClaimDate>0</ClaimDate>\n <ClaimPrice>0</ClaimPrice>\n <GlobalID>54ff9641-dd40-4a2c-b1f1-47dd3af24e50</GlobalID>\n <GroupID>d740204e-bbbf-44aa-949d-02c7d739f6a5</GroupID>\n <IsGroupOwned>False</IsGroupOwned>\n <Bitmap>AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=</Bitmap>\n <Description>land data to test LandDataSerializer</Description>\n <Flags>536870944</Flags>\n <LandingType>2</LandingType>\n <Name>LandDataSerializerTest Land</Name>\n <Status>0</Status>\n <LocalID>0</LocalID>\n <MediaAutoScale>1</MediaAutoScale>\n <MediaID>d4452578-2f25-4b97-a81b-819af559cfd7</MediaID>\n <MediaURL>http://videos.opensimulator.org/bumblebee.mp4</MediaURL>\n <MusicURL />\n <OwnerID>1b8eedf9-6d15-448b-8015-24286f1756bf</OwnerID>\n <ParcelAccessList />\n <PassHours>0</PassHours>\n <PassPrice>0</PassPrice>\n <SalePrice>0</SalePrice>\n <SnapshotID>00000000-0000-0000-0000-000000000000</SnapshotID>\n <UserLocation>&lt;0, 0, 0&gt;</UserLocation>\n <UserLookAt>&lt;0, 0, 0&gt;</UserLookAt>\n <Dwell>0</Dwell>\n <OtherCleanTime>0</OtherCleanTime>\n</LandData>";
46 private static string preSerializedWithParcelAccessList
47 = "<?xml version=\"1.0\" encoding=\"utf-16\"?>\n<LandData>\n <Area>128</Area>\n <AuctionID>0</AuctionID>\n <AuthBuyerID>00000000-0000-0000-0000-000000000000</AuthBuyerID>\n <Category>10</Category>\n <ClaimDate>0</ClaimDate>\n <ClaimPrice>0</ClaimPrice>\n <GlobalID>54ff9641-dd40-4a2c-b1f1-47dd3af24e50</GlobalID>\n <GroupID>d740204e-bbbf-44aa-949d-02c7d739f6a5</GroupID>\n <IsGroupOwned>False</IsGroupOwned>\n <Bitmap>AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=</Bitmap>\n <Description>land data to test LandDataSerializer</Description>\n <Flags>536870944</Flags>\n <LandingType>2</LandingType>\n <Name>LandDataSerializerTest Land</Name>\n <Status>0</Status>\n <LocalID>0</LocalID>\n <MediaAutoScale>1</MediaAutoScale>\n <MediaID>d4452578-2f25-4b97-a81b-819af559cfd7</MediaID>\n <MediaURL>http://videos.opensimulator.org/bumblebee.mp4</MediaURL>\n <MusicURL />\n <OwnerID>1b8eedf9-6d15-448b-8015-24286f1756bf</OwnerID>\n <ParcelAccessList>\n <ParcelAccessEntry>\n <AgentID>62d65d45-c91a-4f77-862c-46557d978b6c</AgentID>\n <Time>0</Time>\n <AccessList>2</AccessList>\n </ParcelAccessEntry>\n <ParcelAccessEntry>\n <AgentID>ec2a8d18-2378-4fe0-8b68-2a31b57c481e</AgentID>\n <Time>0</Time>\n <AccessList>1</AccessList>\n </ParcelAccessEntry>\n </ParcelAccessList>\n <PassHours>0</PassHours>\n <PassPrice>0</PassPrice>\n <SalePrice>0</SalePrice>\n <SnapshotID>00000000-0000-0000-0000-000000000000</SnapshotID>\n <UserLocation>&lt;0, 0, 0&gt;</UserLocation>\n <UserLookAt>&lt;0, 0, 0&gt;</UserLookAt>\n <Dwell>0</Dwell>\n <OtherCleanTime>0</OtherCleanTime>\n</LandData>";
48
49 [SetUp]
50 public void setup()
51 {
52 // setup LandData object
53 this.land = new LandData();
54 this.land.AABBMax = new Vector3(1, 2, 3);
55 this.land.AABBMin = new Vector3(129, 130, 131);
56 this.land.Area = 128;
57 this.land.AuctionID = 4;
58 this.land.AuthBuyerID = new UUID("7176df0c-6c50-45db-8a37-5e78be56a0cd");
59 this.land.Category = ParcelCategory.Residential;
60 this.land.ClaimDate = 1;
61 this.land.ClaimPrice = 2;
62 this.land.GlobalID = new UUID("54ff9641-dd40-4a2c-b1f1-47dd3af24e50");
63 this.land.GroupID = new UUID("d740204e-bbbf-44aa-949d-02c7d739f6a5");
64 this.land.Description = "land data to test LandDataSerializer";
65 this.land.Flags = (uint)(ParcelFlags.AllowDamage | ParcelFlags.AllowVoiceChat);
66 this.land.LandingType = (byte)LandingType.Direct;
67 this.land.Name = "LandDataSerializerTest Land";
68 this.land.Status = ParcelStatus.Leased;
69 this.land.LocalID = 1;
70 this.land.MediaAutoScale = (byte)0x01;
71 this.land.MediaID = new UUID("d4452578-2f25-4b97-a81b-819af559cfd7");
72 this.land.MediaURL = "http://videos.opensimulator.org/bumblebee.mp4";
73 this.land.OwnerID = new UUID("1b8eedf9-6d15-448b-8015-24286f1756bf");
74
75 this.landWithParcelAccessList = this.land.Copy();
76 this.landWithParcelAccessList.ParcelAccessList.Clear();
77
78 LandAccessEntry pae0 = new LandAccessEntry();
79 pae0.AgentID = new UUID("62d65d45-c91a-4f77-862c-46557d978b6c");
80 pae0.Flags = AccessList.Ban;
81 pae0.Expires = 0;
82 this.landWithParcelAccessList.ParcelAccessList.Add(pae0);
83
84 LandAccessEntry pae1 = new LandAccessEntry();
85 pae1.AgentID = new UUID("ec2a8d18-2378-4fe0-8b68-2a31b57c481e");
86 pae1.Flags = AccessList.Access;
87 pae1.Expires = 0;
88 this.landWithParcelAccessList.ParcelAccessList.Add(pae1);
89 }
90
91 /// <summary>
92 /// Test the LandDataSerializer.Serialize() method
93 /// </summary>
94// [Test]
95// public void LandDataSerializerSerializeTest()
96// {
97// TestHelpers.InMethod();
98//
99// string serialized = LandDataSerializer.Serialize(this.land).Replace("\r\n", "\n");
100// Assert.That(serialized.Length > 0, "Serialize(LandData) returned empty string");
101//
102// // adding a simple boolean variable because resharper nUnit integration doesn't like this
103// // XML data in the Assert.That statement. Not sure why.
104// bool result = (serialized == preSerialized);
105// Assert.That(result, "result of Serialize LandData does not match expected result");
106//
107// string serializedWithParcelAccessList = LandDataSerializer.Serialize(this.landWithParcelAccessList).Replace("\r\n", "\n");
108// Assert.That(serializedWithParcelAccessList.Length > 0,
109// "Serialize(LandData) returned empty string for LandData object with ParcelAccessList");
110// result = (serializedWithParcelAccessList == preSerializedWithParcelAccessList);
111// Assert.That(result,
112// "result of Serialize(LandData) does not match expected result (pre-serialized with parcel access list");
113// }
114
115 /// <summary>
116 /// Test the LandDataSerializer.Deserialize() method
117 /// </summary>
118 [Test]
119 public void TestLandDataDeserializeNoAccessLists()
120 {
121 TestHelpers.InMethod();
122// log4net.Config.XmlConfigurator.Configure();
123
124 Dictionary<string, object> options = new Dictionary<string, object>();
125 LandData ld = LandDataSerializer.Deserialize(LandDataSerializer.Serialize(this.land, options));
126 Assert.That(ld, Is.Not.Null, "Deserialize(string) returned null");
127// Assert.That(ld.AABBMax, Is.EqualTo(land.AABBMax));
128// Assert.That(ld.AABBMin, Is.EqualTo(land.AABBMin));
129 Assert.That(ld.Area, Is.EqualTo(land.Area));
130 Assert.That(ld.AuctionID, Is.EqualTo(land.AuctionID));
131 Assert.That(ld.AuthBuyerID, Is.EqualTo(land.AuthBuyerID));
132 Assert.That(ld.Category, Is.EqualTo(land.Category));
133 Assert.That(ld.ClaimDate, Is.EqualTo(land.ClaimDate));
134 Assert.That(ld.ClaimPrice, Is.EqualTo(land.ClaimPrice));
135 Assert.That(ld.GlobalID, Is.EqualTo(land.GlobalID), "Reified LandData.GlobalID != original LandData.GlobalID");
136 Assert.That(ld.GroupID, Is.EqualTo(land.GroupID));
137 Assert.That(ld.Description, Is.EqualTo(land.Description));
138 Assert.That(ld.Flags, Is.EqualTo(land.Flags));
139 Assert.That(ld.LandingType, Is.EqualTo(land.LandingType));
140 Assert.That(ld.Name, Is.EqualTo(land.Name), "Reified LandData.Name != original LandData.Name");
141 Assert.That(ld.Status, Is.EqualTo(land.Status));
142 Assert.That(ld.LocalID, Is.EqualTo(land.LocalID));
143 Assert.That(ld.MediaAutoScale, Is.EqualTo(land.MediaAutoScale));
144 Assert.That(ld.MediaID, Is.EqualTo(land.MediaID));
145 Assert.That(ld.MediaURL, Is.EqualTo(land.MediaURL));
146 Assert.That(ld.OwnerID, Is.EqualTo(land.OwnerID));
147 }
148
149 [Test]
150 public void TestLandDataDeserializeWithAccessLists()
151 {
152 TestHelpers.InMethod();
153// log4net.Config.XmlConfigurator.Configure();
154
155 LandData ld = LandDataSerializer.Deserialize(LandDataSerializerTest.preSerializedWithParcelAccessList);
156 Assert.That(ld != null,
157 "Deserialize(string) returned null (pre-serialized with parcel access list)");
158 Assert.That(ld.GlobalID == this.landWithParcelAccessList.GlobalID,
159 "Reified LandData.GlobalID != original LandData.GlobalID (pre-serialized with parcel access list)");
160 Assert.That(ld.Name == this.landWithParcelAccessList.Name,
161 "Reified LandData.Name != original LandData.Name (pre-serialized with parcel access list)");
162 Assert.That(ld.ParcelAccessList.Count, Is.EqualTo(2));
163 Assert.That(ld.ParcelAccessList[0].AgentID, Is.EqualTo(UUID.Parse("62d65d45-c91a-4f77-862c-46557d978b6c")));
164 }
165 }
166}
diff --git a/OpenSim/Framework/Serialization/Tests/RegionSettingsSerializerTests.cs b/OpenSim/Framework/Serialization/Tests/RegionSettingsSerializerTests.cs
new file mode 100644
index 0000000..142726b
--- /dev/null
+++ b/OpenSim/Framework/Serialization/Tests/RegionSettingsSerializerTests.cs
@@ -0,0 +1,142 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using OpenMetaverse;
31using OpenMetaverse.StructuredData;
32using NUnit.Framework;
33using OpenSim.Framework;
34using OpenSim.Framework.Serialization.External;
35using OpenSim.Tests.Common;
36
37namespace OpenSim.Framework.Serialization.Tests
38{
39 [TestFixture]
40 public class RegionSettingsSerializerTests : OpenSimTestCase
41 {
42 private string m_serializedRs = @"<?xml version=""1.0"" encoding=""utf-16""?>
43<RegionSettings>
44 <General>
45 <AllowDamage>True</AllowDamage>
46 <AllowLandResell>True</AllowLandResell>
47 <AllowLandJoinDivide>True</AllowLandJoinDivide>
48 <BlockFly>True</BlockFly>
49 <BlockLandShowInSearch>True</BlockLandShowInSearch>
50 <BlockTerraform>True</BlockTerraform>
51 <DisableCollisions>True</DisableCollisions>
52 <DisablePhysics>True</DisablePhysics>
53 <DisableScripts>True</DisableScripts>
54 <MaturityRating>1</MaturityRating>
55 <RestrictPushing>True</RestrictPushing>
56 <AgentLimit>40</AgentLimit>
57 <ObjectBonus>1.4</ObjectBonus>
58 </General>
59 <GroundTextures>
60 <Texture1>00000000-0000-0000-0000-000000000020</Texture1>
61 <Texture2>00000000-0000-0000-0000-000000000040</Texture2>
62 <Texture3>00000000-0000-0000-0000-000000000060</Texture3>
63 <Texture4>00000000-0000-0000-0000-000000000080</Texture4>
64 <ElevationLowSW>1.9</ElevationLowSW>
65 <ElevationLowNW>15.9</ElevationLowNW>
66 <ElevationLowSE>49</ElevationLowSE>
67 <ElevationLowNE>45.3</ElevationLowNE>
68 <ElevationHighSW>2.1</ElevationHighSW>
69 <ElevationHighNW>4.5</ElevationHighNW>
70 <ElevationHighSE>9.2</ElevationHighSE>
71 <ElevationHighNE>19.2</ElevationHighNE>
72 </GroundTextures>
73 <Terrain>
74 <WaterHeight>23</WaterHeight>
75 <TerrainRaiseLimit>17.9</TerrainRaiseLimit>
76 <TerrainLowerLimit>0.4</TerrainLowerLimit>
77 <UseEstateSun>True</UseEstateSun>
78 <FixedSun>true</FixedSun>
79 <SunPosition>12</SunPosition>
80 </Terrain>
81 <Telehub>
82 <TelehubObject>00000000-0000-0000-0000-111111111111</TelehubObject>
83 <SpawnPoint>1,-2,0.33</SpawnPoint>
84 </Telehub>
85</RegionSettings>";
86
87 private RegionSettings m_rs;
88
89 [SetUp]
90 public void Setup()
91 {
92 m_rs = new RegionSettings();
93 m_rs.AgentLimit = 17;
94 m_rs.AllowDamage = true;
95 m_rs.AllowLandJoinDivide = true;
96 m_rs.AllowLandResell = true;
97 m_rs.BlockFly = true;
98 m_rs.BlockShowInSearch = true;
99 m_rs.BlockTerraform = true;
100 m_rs.DisableCollisions = true;
101 m_rs.DisablePhysics = true;
102 m_rs.DisableScripts = true;
103 m_rs.Elevation1NW = 15.9;
104 m_rs.Elevation1NE = 45.3;
105 m_rs.Elevation1SE = 49;
106 m_rs.Elevation1SW = 1.9;
107 m_rs.Elevation2NW = 4.5;
108 m_rs.Elevation2NE = 19.2;
109 m_rs.Elevation2SE = 9.2;
110 m_rs.Elevation2SW = 2.1;
111 m_rs.FixedSun = true;
112 m_rs.SunPosition = 12.0;
113 m_rs.ObjectBonus = 1.4;
114 m_rs.RestrictPushing = true;
115 m_rs.TerrainLowerLimit = 0.4;
116 m_rs.TerrainRaiseLimit = 17.9;
117 m_rs.TerrainTexture1 = UUID.Parse("00000000-0000-0000-0000-000000000020");
118 m_rs.TerrainTexture2 = UUID.Parse("00000000-0000-0000-0000-000000000040");
119 m_rs.TerrainTexture3 = UUID.Parse("00000000-0000-0000-0000-000000000060");
120 m_rs.TerrainTexture4 = UUID.Parse("00000000-0000-0000-0000-000000000080");
121 m_rs.UseEstateSun = true;
122 m_rs.WaterHeight = 23;
123 m_rs.TelehubObject = UUID.Parse("00000000-0000-0000-0000-111111111111");
124 m_rs.AddSpawnPoint(SpawnPoint.Parse("1,-2,0.33"));
125 }
126
127 [Test]
128 public void TestRegionSettingsDeserialize()
129 {
130 TestHelpers.InMethod();
131// log4net.Config.XmlConfigurator.Configure();
132
133 RegionSettings deserRs = RegionSettingsSerializer.Deserialize(m_serializedRs);
134 Assert.That(deserRs, Is.Not.Null);
135 Assert.That(deserRs.TerrainTexture2, Is.EqualTo(m_rs.TerrainTexture2));
136 Assert.That(deserRs.DisablePhysics, Is.EqualTo(m_rs.DisablePhysics));
137 Assert.That(deserRs.TerrainLowerLimit, Is.EqualTo(m_rs.TerrainLowerLimit));
138 Assert.That(deserRs.TelehubObject, Is.EqualTo(m_rs.TelehubObject));
139 Assert.That(deserRs.SpawnPoints()[0].ToString(), Is.EqualTo(m_rs.SpawnPoints()[0].ToString()));
140 }
141 }
142}