aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Grid/AssetInventoryServer/Plugins/OpenSim/OpenSimInventoryFrontendPlugin.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Grid/AssetInventoryServer/Plugins/OpenSim/OpenSimInventoryFrontendPlugin.cs')
-rw-r--r--OpenSim/Grid/AssetInventoryServer/Plugins/OpenSim/OpenSimInventoryFrontendPlugin.cs663
1 files changed, 663 insertions, 0 deletions
diff --git a/OpenSim/Grid/AssetInventoryServer/Plugins/OpenSim/OpenSimInventoryFrontendPlugin.cs b/OpenSim/Grid/AssetInventoryServer/Plugins/OpenSim/OpenSimInventoryFrontendPlugin.cs
new file mode 100644
index 0000000..6e33cdf
--- /dev/null
+++ b/OpenSim/Grid/AssetInventoryServer/Plugins/OpenSim/OpenSimInventoryFrontendPlugin.cs
@@ -0,0 +1,663 @@
1/*
2 * Copyright (c) 2008 Intel Corporation
3 * All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * -- Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * -- Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * -- Neither the name of the Intel Corporation nor the names of its
14 * contributors may be used to endorse or promote products derived from
15 * this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
20 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE INTEL OR ITS
21 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
24 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
25 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30using System;
31using System.Collections.Generic;
32using System.Net;
33using System.IO;
34using System.Xml;
35using ExtensionLoader;
36using OpenMetaverse;
37using OpenMetaverse.StructuredData;
38using HttpServer;
39using OpenSim.Framework;
40
41namespace OpenSim.Grid.AssetInventoryServer.Plugins.OpenSim
42{
43 public class OpenSimInventoryFrontendPlugin : IAssetInventoryServerPlugin
44 {
45 private AssetInventoryServer server;
46 private Utils.InventoryItemSerializer itemSerializer = new Utils.InventoryItemSerializer();
47 private Utils.InventoryFolderSerializer folderSerializer = new Utils.InventoryFolderSerializer();
48 private Utils.InventoryCollectionSerializer collectionSerializer = new Utils.InventoryCollectionSerializer();
49
50 public OpenSimInventoryFrontendPlugin()
51 {
52 }
53
54 #region IPlugin implementation
55
56 public void Initialise(AssetInventoryServer server)
57 {
58 this.server = server;
59
60 server.HttpServer.AddHandler("post", null, @"^/GetInventory/", GetInventoryHandler);
61 server.HttpServer.AddHandler("post", null, @"^/CreateInventory/", CreateInventoryHandler);
62 server.HttpServer.AddHandler("post", null, @"^/NewFolder/", NewFolderHandler);
63 server.HttpServer.AddHandler("post", null, @"^/UpdateFolder/", UpdateFolderHandler);
64 server.HttpServer.AddHandler("post", null, @"^/MoveFolder/", MoveFolderHandler);
65 server.HttpServer.AddHandler("post", null, @"^/PurgeFolder/", PurgeFolderHandler);
66 server.HttpServer.AddHandler("post", null, @"^/NewItem/", NewItemHandler);
67 server.HttpServer.AddHandler("post", null, @"^/DeleteItem/", DeleteItemHandler);
68 server.HttpServer.AddHandler("post", null, @"^/RootFolders/", RootFoldersHandler);
69 server.HttpServer.AddHandler("post", null, @"^/ActiveGestures/", ActiveGesturesHandler);
70
71 Logger.Log.Info("[INVENTORY] OpenSim Inventory Frontend loaded.");
72 }
73
74 /// <summary>
75 /// <para>Initialises asset interface</para>
76 /// </summary>
77 public void Initialise()
78 {
79 Logger.Log.InfoFormat("[INVENTORY]: {0} cannot be default-initialized!", Name);
80 throw new PluginNotInitialisedException(Name);
81 }
82
83 public void Dispose()
84 {
85 }
86
87 public string Version
88 {
89 // TODO: this should be something meaningful and not hardcoded?
90 get { return "0.1"; }
91 }
92
93 public string Name
94 {
95 get { return "AssetInventoryServer OpenSim asset frontend"; }
96 }
97
98 #endregion IPlugin implementation
99
100 bool GetInventoryHandler(IHttpClientContext client, IHttpRequest request, IHttpResponse response)
101 {
102 UUID sessionID, agentID;
103 UUID ownerID = DeserializeUUID(request.Body, out agentID, out sessionID);
104
105 if (ownerID != UUID.Zero)
106 {
107 Logger.Log.Warn("GetInventory is not scalable on some inventory backends, avoid calling it wherever possible");
108
109 Uri owner = Utils.GetOpenSimUri(ownerID);
110 InventoryCollection inventory;
111 BackendResponse storageResponse = server.InventoryProvider.TryFetchInventory(owner, out inventory);
112
113 if (storageResponse == BackendResponse.Success)
114 {
115 collectionSerializer.Serialize(response.Body, inventory);
116 response.Body.Flush();
117 }
118 else if (storageResponse == BackendResponse.NotFound)
119 {
120 // Return an empty inventory set to mimic OpenSim.Grid.InventoryServer.exe
121 inventory = new InventoryCollection();
122 inventory.UserID = ownerID;
123 inventory.Folders = new Dictionary<UUID, InventoryFolder>();
124 inventory.Items = new Dictionary<UUID, InventoryItem>();
125 collectionSerializer.Serialize(response.Body, inventory);
126 response.Body.Flush();
127 }
128 else
129 {
130 response.Status = HttpStatusCode.InternalServerError;
131 }
132 }
133 else
134 {
135 response.Status = HttpStatusCode.BadRequest;
136 }
137
138 return true;
139 }
140
141 bool CreateInventoryHandler(IHttpClientContext client, IHttpRequest request, IHttpResponse response)
142 {
143 UUID ownerID = DeserializeUUID(request.Body);
144
145 if (ownerID != UUID.Zero)
146 {
147 Uri owner = Utils.GetOpenSimUri(ownerID);
148 Logger.Log.DebugFormat("Created URI {0} for inventory creation", owner);
149
150 InventoryFolder rootFolder = new InventoryFolder("My Inventory", ownerID, UUID.Zero, (short)AssetType.Folder);
151 BackendResponse storageResponse = server.InventoryProvider.TryCreateInventory(owner, rootFolder);
152 if (storageResponse == BackendResponse.Success)
153 {
154 CreateFolder("Animations", ownerID, rootFolder.ID, AssetType.Animation);
155 CreateFolder("Body Parts", ownerID, rootFolder.ID, AssetType.Bodypart);
156 CreateFolder("Calling Cards", ownerID, rootFolder.ID, AssetType.CallingCard);
157 CreateFolder("Clothing", ownerID, rootFolder.ID, AssetType.Clothing);
158 CreateFolder("Gestures", ownerID, rootFolder.ID, AssetType.Gesture);
159 CreateFolder("Landmarks", ownerID, rootFolder.ID, AssetType.Landmark);
160 CreateFolder("Lost and Found", ownerID, rootFolder.ID, AssetType.LostAndFoundFolder);
161 CreateFolder("Notecards", ownerID, rootFolder.ID, AssetType.Notecard);
162 CreateFolder("Objects", ownerID, rootFolder.ID, AssetType.Object);
163 CreateFolder("Photo Album", ownerID, rootFolder.ID, AssetType.SnapshotFolder);
164 CreateFolder("Scripts", ownerID, rootFolder.ID, AssetType.LSLText);
165 CreateFolder("Sounds", ownerID, rootFolder.ID, AssetType.Sound);
166 CreateFolder("Textures", ownerID, rootFolder.ID, AssetType.Texture);
167 CreateFolder("Trash", ownerID, rootFolder.ID, AssetType.TrashFolder);
168
169 SerializeBool(response.Body, true);
170 return true;
171 }
172 }
173
174 SerializeBool(response.Body, false);
175 return true;
176 }
177
178 bool NewFolderHandler(IHttpClientContext client, IHttpRequest request, IHttpResponse response)
179 {
180 UUID agentID, sessionID;
181 InventoryFolder folder = DeserializeFolder(request.Body, out agentID, out sessionID);
182
183 if (folder != null)
184 {
185 Uri owner = Utils.GetOpenSimUri(folder.Owner);
186
187 // Some calls that are moving or updating a folder instead of creating a new one
188 // will pass in an InventoryFolder without the name set. If this is the case we
189 // need to look up the name first
190 if (String.IsNullOrEmpty(folder.Name))
191 {
192 InventoryFolder oldFolder;
193 if (server.InventoryProvider.TryFetchFolder(owner, folder.ID, out oldFolder) == BackendResponse.Success)
194 folder.Name = oldFolder.Name;
195 }
196
197 BackendResponse storageResponse = server.InventoryProvider.TryCreateFolder(owner, folder);
198
199 if (storageResponse == BackendResponse.Success)
200 {
201 SerializeBool(response.Body, true);
202 return true;
203 }
204 }
205
206 SerializeBool(response.Body, false);
207 return true;
208 }
209
210 bool UpdateFolderHandler(IHttpClientContext client, IHttpRequest request, IHttpResponse response)
211 {
212 return NewFolderHandler(client, request, response);
213 }
214
215 bool MoveFolderHandler(IHttpClientContext client, IHttpRequest request, IHttpResponse response)
216 {
217 return NewFolderHandler(client, request, response);
218 }
219
220 bool PurgeFolderHandler(IHttpClientContext client, IHttpRequest request, IHttpResponse response)
221 {
222 UUID agentID, sessionID;
223 InventoryFolder folder = DeserializeFolder(request.Body, out agentID, out sessionID);
224
225 if (folder != null)
226 {
227 Uri owner = Utils.GetOpenSimUri(folder.Owner);
228 BackendResponse storageResponse = server.InventoryProvider.TryPurgeFolder(owner, folder.ID);
229
230 if (storageResponse == BackendResponse.Success)
231 {
232 SerializeBool(response.Body, true);
233 return true;
234 }
235 }
236
237 SerializeBool(response.Body, false);
238 return true;
239 }
240
241 bool NewItemHandler(IHttpClientContext client, IHttpRequest request, IHttpResponse response)
242 {
243 UUID agentID, sessionID;
244 InventoryItem item = DeserializeItem(request.Body, out agentID, out sessionID);
245
246 if (item != null)
247 {
248 Uri owner = Utils.GetOpenSimUri(agentID);
249 BackendResponse storageResponse = server.InventoryProvider.TryCreateItem(owner, item);
250
251 if (storageResponse == BackendResponse.Success)
252 {
253 SerializeBool(response.Body, true);
254 return true;
255 }
256 }
257
258 SerializeBool(response.Body, false);
259 return true;
260 }
261
262 bool DeleteItemHandler(IHttpClientContext client, IHttpRequest request, IHttpResponse response)
263 {
264 UUID agentID, sessionID;
265 InventoryItem item = DeserializeItem(request.Body, out agentID, out sessionID);
266
267 if (item != null)
268 {
269 Uri owner = Utils.GetOpenSimUri(item.Owner);
270 BackendResponse storageResponse = server.InventoryProvider.TryDeleteItem(owner, item.ID);
271
272 if (storageResponse == BackendResponse.Success)
273 {
274 SerializeBool(response.Body, true);
275 return true;
276 }
277 }
278
279 SerializeBool(response.Body, false);
280 return true;
281 }
282
283 bool RootFoldersHandler(IHttpClientContext client, IHttpRequest request, IHttpResponse response)
284 {
285 UUID ownerID = DeserializeUUID(request.Body);
286
287 if (ownerID != UUID.Zero)
288 {
289 Uri owner = Utils.GetOpenSimUri(ownerID);
290 List<InventoryFolder> skeleton;
291 BackendResponse storageResponse = server.InventoryProvider.TryFetchFolderList(owner, out skeleton);
292
293 if (storageResponse == BackendResponse.Success)
294 {
295 SerializeFolderList(response.Body, skeleton);
296 }
297 else if (storageResponse == BackendResponse.NotFound)
298 {
299 // Return an empty set of inventory so the requester knows that
300 // an inventory needs to be created for this agent
301 SerializeFolderList(response.Body, new List<InventoryFolder>(0));
302 }
303 else
304 {
305 response.Status = HttpStatusCode.InternalServerError;
306 }
307 }
308 else
309 {
310 response.Status = HttpStatusCode.BadRequest;
311 }
312
313 return true;
314 }
315
316 bool ActiveGesturesHandler(IHttpClientContext client, IHttpRequest request, IHttpResponse response)
317 {
318 UUID ownerID = DeserializeUUID(request.Body);
319
320 if (ownerID != UUID.Zero)
321 {
322 Uri owner = Utils.GetOpenSimUri(ownerID);
323 List<InventoryItem> gestures;
324 BackendResponse storageResponse = server.InventoryProvider.TryFetchActiveGestures(owner, out gestures);
325
326 if (storageResponse == BackendResponse.Success)
327 {
328 SerializeItemList(response.Body, gestures);
329 }
330 else if (storageResponse == BackendResponse.NotFound)
331 {
332 // Return an empty set of gestures to match OpenSim.Grid.InventoryServer.exe behavior
333 SerializeItemList(response.Body, new List<InventoryItem>(0));
334 }
335 else
336 {
337 response.Status = HttpStatusCode.InternalServerError;
338 }
339 }
340 else
341 {
342 response.Status = HttpStatusCode.BadRequest;
343 }
344
345 return true;
346 }
347
348 BackendResponse CreateFolder(string name, UUID ownerID, UUID parentID, AssetType assetType)
349 {
350 InventoryFolder folder = new InventoryFolder(name, ownerID, parentID, (short)assetType);
351 Uri owner = Utils.GetOpenSimUri(ownerID);
352 return server.InventoryProvider.TryCreateFolder(owner, folder);
353 }
354
355 UUID DeserializeUUID(Stream stream)
356 {
357 UUID id = UUID.Zero;
358
359 try
360 {
361 using (XmlReader reader = XmlReader.Create(stream))
362 {
363 reader.MoveToContent();
364 UUID.TryParse(reader.ReadElementContentAsString("guid", String.Empty), out id);
365 }
366 }
367 catch (Exception ex)
368 {
369 Logger.Log.Warn("Failed to parse POST data (expecting guid): " + ex.Message);
370 }
371
372 return id;
373 }
374
375 UUID DeserializeUUID(Stream stream, out UUID agentID, out UUID sessionID)
376 {
377 UUID id;
378
379 try
380 {
381 using (XmlReader reader = XmlReader.Create(stream))
382 {
383 reader.MoveToContent();
384 reader.ReadStartElement("RestSessionObjectOfGuid");
385 UUID.TryParse(reader.ReadElementContentAsString("SessionID", String.Empty), out sessionID);
386 UUID.TryParse(reader.ReadElementContentAsString("AvatarID", String.Empty), out agentID);
387 UUID.TryParse(reader.ReadElementContentAsString("Body", String.Empty), out id);
388 reader.ReadEndElement();
389 }
390 }
391 catch (Exception ex)
392 {
393 Logger.Log.Warn("Failed to parse GetInventory POST data: " + ex.Message);
394 agentID = UUID.Zero;
395 sessionID = UUID.Zero;
396 return UUID.Zero;
397 }
398
399 return id;
400 }
401
402 InventoryFolder DeserializeFolder(Stream stream, out UUID agentID, out UUID sessionID)
403 {
404 InventoryFolder folder = new InventoryFolder();
405
406 try
407 {
408 using (XmlReader reader = XmlReader.Create(stream))
409 {
410 reader.MoveToContent();
411 reader.ReadStartElement("RestSessionObjectOfInventoryFolderBase");
412 UUID.TryParse(reader.ReadElementContentAsString("SessionID", String.Empty), out sessionID);
413 UUID.TryParse(reader.ReadElementContentAsString("AvatarID", String.Empty), out agentID);
414 reader.ReadStartElement("Body");
415 if (reader.Name == "Name")
416 folder.Name = reader.ReadElementContentAsString("Name", String.Empty);
417 else
418 folder.Name = String.Empty;
419 ReadUUID(reader, "Owner", out folder.Owner);
420 ReadUUID(reader, "ParentID", out folder.ParentID);
421 ReadUUID(reader, "ID", out folder.ID);
422 Int16.TryParse(reader.ReadElementContentAsString("Type", String.Empty), out folder.Type);
423 UInt16.TryParse(reader.ReadElementContentAsString("Version", String.Empty), out folder.Version);
424 reader.ReadEndElement();
425 reader.ReadEndElement();
426 }
427 }
428 catch (Exception ex)
429 {
430 Logger.Log.Warn("Failed to parse POST data (expecting InventoryFolderBase): " + ex.Message);
431 agentID = UUID.Zero;
432 sessionID = UUID.Zero;
433 return null;
434 }
435
436 return folder;
437 }
438
439 InventoryItem DeserializeItem(Stream stream, out UUID agentID, out UUID sessionID)
440 {
441 InventoryItem item = new InventoryItem();
442
443 try
444 {
445 using (XmlReader reader = XmlReader.Create(stream))
446 {
447 reader.MoveToContent();
448 reader.ReadStartElement("RestSessionObjectOfInventoryItemBase");
449 UUID.TryParse(reader.ReadElementContentAsString("SessionID", String.Empty), out sessionID);
450 UUID.TryParse(reader.ReadElementContentAsString("AvatarID", String.Empty), out agentID);
451 reader.ReadStartElement("Body");
452 ReadUUID(reader, "ID", out item.ID);
453 Int32.TryParse(reader.ReadElementContentAsString("InvType", String.Empty), out item.InvType);
454 ReadUUID(reader, "Folder", out item.Folder);
455 ReadUUID(reader, "Owner", out item.Owner);
456 ReadUUID(reader, "Creator", out item.Creator);
457 item.Name = reader.ReadElementContentAsString("Name", String.Empty);
458 item.Description = reader.ReadElementContentAsString("Description", String.Empty);
459 UInt32.TryParse(reader.ReadElementContentAsString("NextPermissions", String.Empty), out item.NextPermissions);
460 UInt32.TryParse(reader.ReadElementContentAsString("CurrentPermissions", String.Empty), out item.CurrentPermissions);
461 UInt32.TryParse(reader.ReadElementContentAsString("BasePermissions", String.Empty), out item.BasePermissions);
462 UInt32.TryParse(reader.ReadElementContentAsString("EveryOnePermissions", String.Empty), out item.EveryOnePermissions);
463 UInt32.TryParse(reader.ReadElementContentAsString("GroupPermissions", String.Empty), out item.GroupPermissions);
464 Int32.TryParse(reader.ReadElementContentAsString("AssetType", String.Empty), out item.AssetType);
465 ReadUUID(reader, "AssetID", out item.AssetID);
466 ReadUUID(reader, "GroupID", out item.GroupID);
467 Boolean.TryParse(reader.ReadElementContentAsString("GroupOwned", String.Empty), out item.GroupOwned);
468 Int32.TryParse(reader.ReadElementContentAsString("SalePrice", String.Empty), out item.SalePrice);
469 Byte.TryParse(reader.ReadElementContentAsString("SaleType", String.Empty), out item.SaleType);
470 UInt32.TryParse(reader.ReadElementContentAsString("Flags", String.Empty), out item.Flags);
471 Int32.TryParse(reader.ReadElementContentAsString("CreationDate", String.Empty), out item.CreationDate);
472 reader.ReadEndElement();
473 reader.ReadEndElement();
474 }
475 }
476 catch (Exception ex)
477 {
478 Logger.Log.Warn("Failed to parse POST data (expecting InventoryItemBase): " + ex.Message);
479 agentID = UUID.Zero;
480 sessionID = UUID.Zero;
481 return null;
482 }
483
484 return item;
485 }
486
487 void SerializeBool(Stream stream, bool value)
488 {
489 using (XmlWriter writer = XmlWriter.Create(stream))
490 {
491 writer.WriteStartDocument();
492 writer.WriteStartElement("boolean");
493 writer.WriteAttributeString("xmlns", "xsi", null, "http://www.w3.org/2001/XMLSchema-instance");
494 writer.WriteAttributeString("xmlns", "xsd", null, "http://www.w3.org/2001/XMLSchema");
495 writer.WriteString(value.ToString().ToLower());
496 writer.WriteEndElement();
497 writer.WriteEndDocument();
498 writer.Flush();
499 }
500
501 stream.Flush();
502 }
503
504 void SerializeFolderList(Stream stream, List<InventoryFolder> folders)
505 {
506 using (XmlWriter writer = XmlWriter.Create(stream))
507 {
508 writer.WriteStartDocument();
509 writer.WriteStartElement("ArrayOfInventoryFolderBase");
510 writer.WriteAttributeString("xmlns", "xsi", null, "http://www.w3.org/2001/XMLSchema-instance");
511 writer.WriteAttributeString("xmlns", "xsd", null, "http://www.w3.org/2001/XMLSchema");
512
513 if (folders != null)
514 {
515 foreach (InventoryFolder folder in folders)
516 {
517 writer.WriteStartElement("InventoryFolderBase");
518 writer.WriteElementString("Name", folder.Name);
519 WriteUUID(writer, "Owner", folder.Owner);
520 WriteUUID(writer, "ParentID", folder.ParentID);
521 WriteUUID(writer, "ID", folder.ID);
522 writer.WriteElementString("Type", XmlConvert.ToString(folder.Type));
523 writer.WriteElementString("Version", XmlConvert.ToString(folder.Version));
524 writer.WriteEndElement();
525 }
526 }
527
528 writer.WriteEndElement();
529 writer.WriteEndDocument();
530
531 writer.Flush();
532 }
533
534 stream.Flush();
535 }
536
537 void SerializeItemList(Stream stream, List<InventoryItem> items)
538 {
539 using (XmlWriter writer = XmlWriter.Create(stream))
540 {
541 writer.WriteStartDocument();
542 writer.WriteStartElement("ArrayOfInventoryItemBase");
543 writer.WriteAttributeString("xmlns", "xsi", null, "http://www.w3.org/2001/XMLSchema-instance");
544 writer.WriteAttributeString("xmlns", "xsd", null, "http://www.w3.org/2001/XMLSchema");
545
546 if (items != null)
547 {
548 foreach (InventoryItem item in items)
549 {
550 writer.WriteStartElement("InventoryItemBase");
551 WriteUUID(writer, "ID", item.ID);
552 writer.WriteElementString("InvType", XmlConvert.ToString(item.InvType));
553 WriteUUID(writer, "Folder", item.Folder);
554 WriteUUID(writer, "Owner", item.Owner);
555 WriteUUID(writer, "Creator", item.Creator);
556 writer.WriteElementString("Name", item.Name);
557 writer.WriteElementString("Description", item.Description);
558 writer.WriteElementString("NextPermissions", XmlConvert.ToString(item.NextPermissions));
559 writer.WriteElementString("CurrentPermissions", XmlConvert.ToString(item.CurrentPermissions));
560 writer.WriteElementString("BasePermissions", XmlConvert.ToString(item.BasePermissions));
561 writer.WriteElementString("EveryOnePermissions", XmlConvert.ToString(item.EveryOnePermissions));
562 writer.WriteElementString("GroupPermissions", XmlConvert.ToString(item.GroupPermissions));
563 writer.WriteElementString("AssetType", XmlConvert.ToString(item.AssetType));
564 WriteUUID(writer, "AssetID", item.AssetID);
565 WriteUUID(writer, "GroupID", item.GroupID);
566 writer.WriteElementString("GroupOwned", XmlConvert.ToString(item.GroupOwned));
567 writer.WriteElementString("SalePrice", XmlConvert.ToString(item.SalePrice));
568 writer.WriteElementString("SaleType", XmlConvert.ToString(item.SaleType));
569 writer.WriteElementString("Flags", XmlConvert.ToString(item.Flags));
570 writer.WriteElementString("CreationDate", XmlConvert.ToString(item.CreationDate));
571 writer.WriteEndElement();
572 }
573 }
574
575 writer.WriteEndElement();
576 writer.WriteEndDocument();
577
578 writer.Flush();
579 }
580
581 stream.Flush();
582 }
583
584 void WriteUUID(XmlWriter writer, string name, UUID id)
585 {
586 writer.WriteStartElement(name);
587 writer.WriteElementString("Guid", XmlConvert.ToString(id.Guid));
588 writer.WriteEndElement();
589 }
590
591 void ReadUUID(XmlReader reader, string name, out UUID id)
592 {
593 reader.ReadStartElement(name);
594 UUID.TryParse(reader.ReadElementContentAsString("Guid", String.Empty), out id);
595 reader.ReadEndElement();
596 }
597 }
598
599 #region OpenSim AssetType
600
601 /// <summary>
602 /// The different types of grid assets
603 /// </summary>
604 public enum AssetType : sbyte
605 {
606 /// <summary>Unknown asset type</summary>
607 Unknown = -1,
608 /// <summary>Texture asset, stores in JPEG2000 J2C stream format</summary>
609 Texture = 0,
610 /// <summary>Sound asset</summary>
611 Sound = 1,
612 /// <summary>Calling card for another avatar</summary>
613 CallingCard = 2,
614 /// <summary>Link to a location in world</summary>
615 Landmark = 3,
616 // <summary>Legacy script asset, you should never see one of these</summary>
617 //[Obsolete]
618 //Script = 4,
619 /// <summary>Collection of textures and parameters that can be
620 /// worn by an avatar</summary>
621 Clothing = 5,
622 /// <summary>Primitive that can contain textures, sounds,
623 /// scripts and more</summary>
624 Object = 6,
625 /// <summary>Notecard asset</summary>
626 Notecard = 7,
627 /// <summary>Holds a collection of inventory items</summary>
628 Folder = 8,
629 /// <summary>Root inventory folder</summary>
630 RootFolder = 9,
631 /// <summary>Linden scripting language script</summary>
632 LSLText = 10,
633 /// <summary>LSO bytecode for a script</summary>
634 LSLBytecode = 11,
635 /// <summary>Uncompressed TGA texture</summary>
636 TextureTGA = 12,
637 /// <summary>Collection of textures and shape parameters that can
638 /// be worn</summary>
639 Bodypart = 13,
640 /// <summary>Trash folder</summary>
641 TrashFolder = 14,
642 /// <summary>Snapshot folder</summary>
643 SnapshotFolder = 15,
644 /// <summary>Lost and found folder</summary>
645 LostAndFoundFolder = 16,
646 /// <summary>Uncompressed sound</summary>
647 SoundWAV = 17,
648 /// <summary>Uncompressed TGA non-square image, not to be used as a
649 /// texture</summary>
650 ImageTGA = 18,
651 /// <summary>Compressed JPEG non-square image, not to be used as a
652 /// texture</summary>
653 ImageJPEG = 19,
654 /// <summary>Animation</summary>
655 Animation = 20,
656 /// <summary>Sequence of animations, sounds, chat, and pauses</summary>
657 Gesture = 21,
658 /// <summary>Simstate file</summary>
659 Simstate = 22,
660 }
661
662 #endregion OpenSim AssetType
663}