clockwerk-opensim – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 vero 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  
28 using System;
29 using System.Collections.Generic;
30 using System.Collections.Specialized;
31 using System.Reflection;
32 using log4net;
33 using Mono.Addins;
34 using Nini.Config;
35 using OpenMetaverse;
36 using OpenMetaverse.StructuredData;
37 using OpenSim.Framework;
38 using OpenSim.Region.Framework.Interfaces;
39 using OpenSim.Region.Framework.Scenes;
40 using OpenSim.Services.Interfaces;
41 using PermissionMask = OpenSim.Framework.PermissionMask;
42  
43 namespace OpenSim.Services.Connectors.SimianGrid
44 {
45 /// <summary>
46 /// Permissions bitflags
47 /// </summary>
48 /*
49 [Flags]
50 public enum PermissionMask : uint
51 {
52 None = 0,
53 Transfer = 1 << 13,
54 Modify = 1 << 14,
55 Copy = 1 << 15,
56 Move = 1 << 19,
57 Damage = 1 << 20,
58 All = 0x7FFFFFFF
59 }
60 */
61  
62 /// <summary>
63 /// Connects avatar inventories to the SimianGrid backend
64 /// </summary>
65 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "SimianInventoryServiceConnector")]
66 public class SimianInventoryServiceConnector : IInventoryService, ISharedRegionModule
67 {
68 private static readonly ILog m_log =
69 LogManager.GetLogger(
70 MethodBase.GetCurrentMethod().DeclaringType);
71  
72 private string m_serverUrl = String.Empty;
73 private string m_userServerUrl = String.Empty;
74 // private object m_gestureSyncRoot = new object();
75 private bool m_Enabled = false;
76  
77 #region ISharedRegionModule
78  
79 public Type ReplaceableInterface { get { return null; } }
80 public void RegionLoaded(Scene scene) { }
81 public void PostInitialise() { }
82 public void Close() { }
83  
84 public SimianInventoryServiceConnector() { }
85 public string Name { get { return "SimianInventoryServiceConnector"; } }
86 public void AddRegion(Scene scene) { if (m_Enabled) { scene.RegisterModuleInterface<IInventoryService>(this); } }
87 public void RemoveRegion(Scene scene) { if (m_Enabled) { scene.UnregisterModuleInterface<IInventoryService>(this); } }
88  
89 #endregion ISharedRegionModule
90  
91 public SimianInventoryServiceConnector(IConfigSource source)
92 {
93 CommonInit(source);
94 }
95  
96 public SimianInventoryServiceConnector(string url)
97 {
98 if (!url.EndsWith("/") && !url.EndsWith("="))
99 url = url + '/';
100 m_serverUrl = url;
101  
102 }
103  
104 public void Initialise(IConfigSource source)
105 {
106 IConfig moduleConfig = source.Configs["Modules"];
107 if (moduleConfig != null)
108 {
109 string name = moduleConfig.GetString("InventoryServices", "");
110 if (name == Name)
111 CommonInit(source);
112 }
113 }
114  
115 private void CommonInit(IConfigSource source)
116 {
117 IConfig gridConfig = source.Configs["InventoryService"];
118 if (gridConfig != null)
119 {
120 string serviceUrl = gridConfig.GetString("InventoryServerURI");
121 if (!String.IsNullOrEmpty(serviceUrl))
122 {
123 if (!serviceUrl.EndsWith("/") && !serviceUrl.EndsWith("="))
124 serviceUrl = serviceUrl + '/';
125 m_serverUrl = serviceUrl;
126  
127 gridConfig = source.Configs["UserAccountService"];
128 if (gridConfig != null)
129 {
130 serviceUrl = gridConfig.GetString("UserAccountServerURI");
131 if (!String.IsNullOrEmpty(serviceUrl))
132 {
133 m_userServerUrl = serviceUrl;
134 m_Enabled = true;
135 }
136 }
137 }
138 }
139  
140 if (String.IsNullOrEmpty(m_serverUrl))
141 m_log.Info("[SIMIAN INVENTORY CONNECTOR]: No InventoryServerURI specified, disabling connector");
142 else if (String.IsNullOrEmpty(m_userServerUrl))
143 m_log.Info("[SIMIAN INVENTORY CONNECTOR]: No UserAccountServerURI specified, disabling connector");
144 }
145  
146 /// <summary>
147 /// Create the entire inventory for a given user
148 /// </summary>
149 /// <param name="user"></param>
150 /// <returns></returns>
151 public bool CreateUserInventory(UUID userID)
152 {
153 NameValueCollection requestArgs = new NameValueCollection
154 {
155 { "RequestMethod", "AddInventory" },
156 { "OwnerID", userID.ToString() }
157 };
158  
159 OSDMap response = SimianGrid.PostToService(m_serverUrl, requestArgs);
160 bool success = response["Success"].AsBoolean();
161  
162 if (!success)
163 m_log.Warn("[SIMIAN INVENTORY CONNECTOR]: Inventory creation for " + userID + " failed: " + response["Message"].AsString());
164  
165 return success;
166 }
167  
168 /// <summary>
169 /// Gets the skeleton of the inventory -- folders only
170 /// </summary>
171 /// <param name="userID"></param>
172 /// <returns></returns>
173 public List<InventoryFolderBase> GetInventorySkeleton(UUID userID)
174 {
175 NameValueCollection requestArgs = new NameValueCollection
176 {
177 { "RequestMethod", "GetInventoryNode" },
178 { "ItemID", userID.ToString() },
179 { "OwnerID", userID.ToString() },
180 { "IncludeFolders", "1" },
181 { "IncludeItems", "0" },
182 { "ChildrenOnly", "0" }
183 };
184  
185 OSDMap response = SimianGrid.PostToService(m_serverUrl, requestArgs);
186 if (response["Success"].AsBoolean() && response["Items"] is OSDArray)
187 {
188 OSDArray items = (OSDArray)response["Items"];
189 return GetFoldersFromResponse(items, userID, true);
190 }
191 else
192 {
193 m_log.Warn("[SIMIAN INVENTORY CONNECTOR]: Failed to retrieve inventory skeleton for " + userID + ": " +
194 response["Message"].AsString());
195 return new List<InventoryFolderBase>(0);
196 }
197 }
198  
199 /// <summary>
200 /// Retrieve the root inventory folder for the given user.
201 /// </summary>
202 /// <param name="userID"></param>
203 /// <returns>null if no root folder was found</returns>
204 public InventoryFolderBase GetRootFolder(UUID userID)
205 {
206 NameValueCollection requestArgs = new NameValueCollection
207 {
208 { "RequestMethod", "GetInventoryNode" },
209 { "ItemID", userID.ToString() },
210 { "OwnerID", userID.ToString() },
211 { "IncludeFolders", "1" },
212 { "IncludeItems", "0" },
213 { "ChildrenOnly", "1" }
214 };
215  
216 OSDMap response = SimianGrid.PostToService(m_serverUrl, requestArgs);
217 if (response["Success"].AsBoolean() && response["Items"] is OSDArray)
218 {
219 OSDArray items = (OSDArray)response["Items"];
220 List<InventoryFolderBase> folders = GetFoldersFromResponse(items, userID, true);
221  
222 if (folders.Count > 0)
223 return folders[0];
224 }
225  
226 return null;
227 }
228  
229 /// <summary>
230 /// Gets the user folder for the given folder-type
231 /// </summary>
232 /// <param name="userID"></param>
233 /// <param name="type"></param>
234 /// <returns></returns>
235 public InventoryFolderBase GetFolderForType(UUID userID, AssetType type)
236 {
237 string contentType = SLUtil.SLAssetTypeToContentType((int)type);
238  
239 NameValueCollection requestArgs = new NameValueCollection
240 {
241 { "RequestMethod", "GetFolderForType" },
242 { "ContentType", contentType },
243 { "OwnerID", userID.ToString() }
244 };
245  
246 OSDMap response = SimianGrid.PostToService(m_serverUrl, requestArgs);
247 if (response["Success"].AsBoolean() && response["Folder"] is OSDMap)
248 {
249 OSDMap folder = (OSDMap)response["Folder"];
250  
251 return new InventoryFolderBase(
252 folder["ID"].AsUUID(),
253 folder["Name"].AsString(),
254 folder["OwnerID"].AsUUID(),
255 (short)SLUtil.ContentTypeToSLAssetType(folder["ContentType"].AsString()),
256 folder["ParentID"].AsUUID(),
257 (ushort)folder["Version"].AsInteger()
258 );
259 }
260 else
261 {
262 m_log.Warn("[SIMIAN INVENTORY CONNECTOR]: Default folder not found for content type " + contentType + ": " + response["Message"].AsString());
263 return GetRootFolder(userID);
264 }
265 }
266  
267 /// <summary>
268 /// Get an item, given by its UUID
269 /// </summary>
270 /// <param name="item"></param>
271 /// <returns></returns>
272 public InventoryItemBase GetItem(InventoryItemBase item)
273 {
274 NameValueCollection requestArgs = new NameValueCollection
275 {
276 { "RequestMethod", "GetInventoryNode" },
277 { "ItemID", item.ID.ToString() },
278 { "OwnerID", item.Owner.ToString() },
279 { "IncludeFolders", "1" },
280 { "IncludeItems", "1" },
281 { "ChildrenOnly", "1" }
282 };
283  
284 OSDMap response = SimianGrid.PostToService(m_serverUrl, requestArgs);
285 if (response["Success"].AsBoolean() && response["Items"] is OSDArray)
286 {
287 List<InventoryItemBase> items = GetItemsFromResponse((OSDArray)response["Items"]);
288 if (items.Count > 0)
289 {
290 // The requested item should be the first in this list, but loop through
291 // and sanity check just in case
292 for (int i = 0; i < items.Count; i++)
293 {
294 if (items[i].ID == item.ID)
295 return items[i];
296 }
297 }
298 }
299  
300 m_log.Warn("[SIMIAN INVENTORY CONNECTOR]: Item " + item.ID + " owned by " + item.Owner + " not found");
301 return null;
302 }
303  
304 /// <summary>
305 /// Get a folder, given by its UUID
306 /// </summary>
307 /// <param name="folder"></param>
308 /// <returns></returns>
309 public InventoryFolderBase GetFolder(InventoryFolderBase folder)
310 {
311 NameValueCollection requestArgs = new NameValueCollection
312 {
313 { "RequestMethod", "GetInventoryNode" },
314 { "ItemID", folder.ID.ToString() },
315 { "OwnerID", folder.Owner.ToString() },
316 { "IncludeFolders", "1" },
317 { "IncludeItems", "0" },
318 { "ChildrenOnly", "1" }
319 };
320  
321 OSDMap response = SimianGrid.PostToService(m_serverUrl, requestArgs);
322 if (response["Success"].AsBoolean() && response["Items"] is OSDArray)
323 {
324 OSDArray items = (OSDArray)response["Items"];
325 List<InventoryFolderBase> folders = GetFoldersFromResponse(items, folder.ID, true);
326  
327 if (folders.Count > 0)
328 return folders[0];
329 }
330  
331 return null;
332 }
333  
334 /// <summary>
335 /// Gets everything (folders and items) inside a folder
336 /// </summary>
337 /// <param name="userID"></param>
338 /// <param name="folderID"></param>
339 /// <returns></returns>
340 public InventoryCollection GetFolderContent(UUID userID, UUID folderID)
341 {
342 InventoryCollection inventory = new InventoryCollection();
343 inventory.UserID = userID;
344  
345 NameValueCollection requestArgs = new NameValueCollection
346 {
347 { "RequestMethod", "GetInventoryNode" },
348 { "ItemID", folderID.ToString() },
349 { "OwnerID", userID.ToString() },
350 { "IncludeFolders", "1" },
351 { "IncludeItems", "1" },
352 { "ChildrenOnly", "1" }
353 };
354  
355 OSDMap response = SimianGrid.PostToService(m_serverUrl, requestArgs);
356 if (response["Success"].AsBoolean() && response["Items"] is OSDArray)
357 {
358 OSDArray items = (OSDArray)response["Items"];
359  
360 inventory.Folders = GetFoldersFromResponse(items, folderID, false);
361 inventory.Items = GetItemsFromResponse(items);
362 }
363 else
364 {
365 m_log.Warn("[SIMIAN INVENTORY CONNECTOR]: Error fetching folder " + folderID + " content for " + userID + ": " +
366 response["Message"].AsString());
367 inventory.Folders = new List<InventoryFolderBase>(0);
368 inventory.Items = new List<InventoryItemBase>(0);
369 }
370  
371 return inventory;
372 }
373  
374 /// <summary>
375 /// Gets the items inside a folder
376 /// </summary>
377 /// <param name="userID"></param>
378 /// <param name="folderID"></param>
379 /// <returns></returns>
380 public List<InventoryItemBase> GetFolderItems(UUID userID, UUID folderID)
381 {
382 InventoryCollection inventory = new InventoryCollection();
383 inventory.UserID = userID;
384  
385 NameValueCollection requestArgs = new NameValueCollection
386 {
387 { "RequestMethod", "GetInventoryNode" },
388 { "ItemID", folderID.ToString() },
389 { "OwnerID", userID.ToString() },
390 { "IncludeFolders", "0" },
391 { "IncludeItems", "1" },
392 { "ChildrenOnly", "1" }
393 };
394  
395 OSDMap response = SimianGrid.PostToService(m_serverUrl, requestArgs);
396 if (response["Success"].AsBoolean() && response["Items"] is OSDArray)
397 {
398 OSDArray items = (OSDArray)response["Items"];
399 return GetItemsFromResponse(items);
400 }
401 else
402 {
403 m_log.Warn("[SIMIAN INVENTORY CONNECTOR]: Error fetching folder " + folderID + " for " + userID + ": " +
404 response["Message"].AsString());
405 return new List<InventoryItemBase>(0);
406 }
407 }
408  
409 /// <summary>
410 /// Add a new folder to the user's inventory
411 /// </summary>
412 /// <param name="folder"></param>
413 /// <returns>true if the folder was successfully added</returns>
414 public bool AddFolder(InventoryFolderBase folder)
415 {
416 NameValueCollection requestArgs = new NameValueCollection
417 {
418 { "RequestMethod", "AddInventoryFolder" },
419 { "FolderID", folder.ID.ToString() },
420 { "ParentID", folder.ParentID.ToString() },
421 { "OwnerID", folder.Owner.ToString() },
422 { "Name", folder.Name },
423 { "ContentType", SLUtil.SLAssetTypeToContentType(folder.Type) }
424 };
425  
426 OSDMap response = SimianGrid.PostToService(m_serverUrl, requestArgs);
427 bool success = response["Success"].AsBoolean();
428  
429 if (!success)
430 {
431 m_log.Warn("[SIMIAN INVENTORY CONNECTOR]: Error creating folder " + folder.Name + " for " + folder.Owner + ": " +
432 response["Message"].AsString());
433 }
434  
435 return success;
436 }
437  
438 /// <summary>
439 /// Update a folder in the user's inventory
440 /// </summary>
441 /// <param name="folder"></param>
442 /// <returns>true if the folder was successfully updated</returns>
443 public bool UpdateFolder(InventoryFolderBase folder)
444 {
445 return AddFolder(folder);
446 }
447  
448 /// <summary>
449 /// Move an inventory folder to a new location
450 /// </summary>
451 /// <param name="folder">A folder containing the details of the new location</param>
452 /// <returns>true if the folder was successfully moved</returns>
453 public bool MoveFolder(InventoryFolderBase folder)
454 {
455 return AddFolder(folder);
456 }
457  
458 /// <summary>
459 /// Delete an item from the user's inventory
460 /// </summary>
461 /// <param name="item"></param>
462 /// <returns>true if the item was successfully deleted</returns>
463 //bool DeleteItem(InventoryItemBase item);
464 public bool DeleteFolders(UUID userID, List<UUID> folderIDs)
465 {
466 return DeleteItems(userID, folderIDs);
467 }
468  
469 /// <summary>
470 /// Delete an item from the user's inventory
471 /// </summary>
472 /// <param name="item"></param>
473 /// <returns>true if the item was successfully deleted</returns>
474 public bool DeleteItems(UUID userID, List<UUID> itemIDs)
475 {
476 // TODO: RemoveInventoryNode should be replaced with RemoveInventoryNodes
477 bool allSuccess = true;
478  
479 for (int i = 0; i < itemIDs.Count; i++)
480 {
481 UUID itemID = itemIDs[i];
482  
483 NameValueCollection requestArgs = new NameValueCollection
484 {
485 { "RequestMethod", "RemoveInventoryNode" },
486 { "OwnerID", userID.ToString() },
487 { "ItemID", itemID.ToString() }
488 };
489  
490 OSDMap response = SimianGrid.PostToService(m_serverUrl, requestArgs);
491 bool success = response["Success"].AsBoolean();
492  
493 if (!success)
494 {
495 m_log.Warn("[SIMIAN INVENTORY CONNECTOR]: Error removing item " + itemID + " for " + userID + ": " +
496 response["Message"].AsString());
497 allSuccess = false;
498 }
499 }
500  
501 return allSuccess;
502 }
503  
504 /// <summary>
505 /// Purge an inventory folder of all its items and subfolders.
506 /// </summary>
507 /// <param name="folder"></param>
508 /// <returns>true if the folder was successfully purged</returns>
509 public bool PurgeFolder(InventoryFolderBase folder)
510 {
511 NameValueCollection requestArgs = new NameValueCollection
512 {
513 { "RequestMethod", "PurgeInventoryFolder" },
514 { "OwnerID", folder.Owner.ToString() },
515 { "FolderID", folder.ID.ToString() }
516 };
517  
518 OSDMap response = SimianGrid.PostToService(m_serverUrl, requestArgs);
519 bool success = response["Success"].AsBoolean();
520  
521 if (!success)
522 {
523 m_log.Warn("[SIMIAN INVENTORY CONNECTOR]: Error purging folder " + folder.ID + " for " + folder.Owner + ": " +
524 response["Message"].AsString());
525 }
526  
527 return success;
528 }
529  
530 /// <summary>
531 /// Add a new item to the user's inventory
532 /// </summary>
533 /// <param name="item"></param>
534 /// <returns>true if the item was successfully added</returns>
535 public bool AddItem(InventoryItemBase item)
536 {
537 // A folder of UUID.Zero means we need to find the most appropriate home for this item
538 if (item.Folder == UUID.Zero)
539 {
540 InventoryFolderBase folder = GetFolderForType(item.Owner, (AssetType)item.AssetType);
541 if (folder != null && folder.ID != UUID.Zero)
542 item.Folder = folder.ID;
543 else
544 item.Folder = item.Owner; // Root folder
545 }
546  
547 if ((AssetType)item.AssetType == AssetType.Gesture)
548 UpdateGesture(item.Owner, item.ID, item.Flags == 1);
549  
550 if (item.BasePermissions == 0)
551 m_log.WarnFormat("[SIMIAN INVENTORY CONNECTOR]: Adding inventory item {0} ({1}) with no base permissions", item.Name, item.ID);
552  
553 OSDMap permissions = new OSDMap
554 {
555 { "BaseMask", OSD.FromInteger(item.BasePermissions) },
556 { "EveryoneMask", OSD.FromInteger(item.EveryOnePermissions) },
557 { "GroupMask", OSD.FromInteger(item.GroupPermissions) },
558 { "NextOwnerMask", OSD.FromInteger(item.NextPermissions) },
559 { "OwnerMask", OSD.FromInteger(item.CurrentPermissions) }
560 };
561  
562 OSDMap extraData = new OSDMap()
563 {
564 { "Flags", OSD.FromInteger(item.Flags) },
565 { "GroupID", OSD.FromUUID(item.GroupID) },
566 { "GroupOwned", OSD.FromBoolean(item.GroupOwned) },
567 { "SalePrice", OSD.FromInteger(item.SalePrice) },
568 { "SaleType", OSD.FromInteger(item.SaleType) },
569 { "Permissions", permissions }
570 };
571  
572 // Add different asset type only if it differs from inventory type
573 // (needed for links)
574 string invContentType = SLUtil.SLInvTypeToContentType(item.InvType);
575 string assetContentType = SLUtil.SLAssetTypeToContentType(item.AssetType);
576  
577 if (invContentType != assetContentType)
578 extraData["LinkedItemType"] = OSD.FromString(assetContentType);
579  
580 NameValueCollection requestArgs = new NameValueCollection
581 {
582 { "RequestMethod", "AddInventoryItem" },
583 { "ItemID", item.ID.ToString() },
584 { "AssetID", item.AssetID.ToString() },
585 { "ParentID", item.Folder.ToString() },
586 { "OwnerID", item.Owner.ToString() },
587 { "Name", item.Name },
588 { "Description", item.Description },
589 { "CreatorID", item.CreatorId },
590 { "CreatorData", item.CreatorData },
591 { "ContentType", invContentType },
592 { "ExtraData", OSDParser.SerializeJsonString(extraData) }
593 };
594  
595 OSDMap response = SimianGrid.PostToService(m_serverUrl, requestArgs);
596 bool success = response["Success"].AsBoolean();
597  
598 if (!success)
599 {
600 m_log.Warn("[SIMIAN INVENTORY CONNECTOR]: Error creating item " + item.Name + " for " + item.Owner + ": " +
601 response["Message"].AsString());
602 }
603  
604 return success;
605 }
606  
607 /// <summary>
608 /// Update an item in the user's inventory
609 /// </summary>
610 /// <param name="item"></param>
611 /// <returns>true if the item was successfully updated</returns>
612 public bool UpdateItem(InventoryItemBase item)
613 {
614 if (item.AssetID != UUID.Zero)
615 {
616 return AddItem(item);
617 }
618 else
619 {
620 // This is actually a folder update
621 InventoryFolderBase folder = new InventoryFolderBase(item.ID, item.Name, item.Owner, (short)item.AssetType, item.Folder, 0);
622 return UpdateFolder(folder);
623 }
624 }
625  
626 public bool MoveItems(UUID ownerID, List<InventoryItemBase> items)
627 {
628 bool success = true;
629  
630 while (items.Count > 0)
631 {
632 List<InventoryItemBase> currentItems = new List<InventoryItemBase>();
633 UUID destFolderID = items[0].Folder;
634  
635 // Find all of the items being moved to the current destination folder
636 for (int i = 0; i < items.Count; i++)
637 {
638 InventoryItemBase item = items[i];
639 if (item.Folder == destFolderID)
640 currentItems.Add(item);
641 }
642  
643 // Do the inventory move for the current items
644 success &= MoveItems(ownerID, items, destFolderID);
645  
646 // Remove the processed items from the list
647 for (int i = 0; i < currentItems.Count; i++)
648 items.Remove(currentItems[i]);
649 }
650  
651 return success;
652 }
653  
654 /// <summary>
655 /// Does the given user have an inventory structure?
656 /// </summary>
657 /// <param name="userID"></param>
658 /// <returns></returns>
659 public bool HasInventoryForUser(UUID userID)
660 {
661 return GetRootFolder(userID) != null;
662 }
663  
664 /// <summary>
665 /// Get the active gestures of the agent.
666 /// </summary>
667 /// <param name="userID"></param>
668 /// <returns></returns>
669 public List<InventoryItemBase> GetActiveGestures(UUID userID)
670 {
671 OSDArray items = FetchGestures(userID);
672  
673 string[] itemIDs = new string[items.Count];
674 for (int i = 0; i < items.Count; i++)
675 itemIDs[i] = items[i].AsUUID().ToString();
676  
677 // NameValueCollection requestArgs = new NameValueCollection
678 // {
679 // { "RequestMethod", "GetInventoryNodes" },
680 // { "OwnerID", userID.ToString() },
681 // { "Items", String.Join(",", itemIDs) }
682 // };
683  
684 // FIXME: Implement this in SimianGrid
685 return new List<InventoryItemBase>(0);
686 }
687  
688 /// <summary>
689 /// Get the union of permissions of all inventory items
690 /// that hold the given assetID.
691 /// </summary>
692 /// <param name="userID"></param>
693 /// <param name="assetID"></param>
694 /// <returns>The permissions or 0 if no such asset is found in
695 /// the user's inventory</returns>
696 public int GetAssetPermissions(UUID userID, UUID assetID)
697 {
698 // NameValueCollection requestArgs = new NameValueCollection
699 // {
700 // { "RequestMethod", "GetInventoryNodes" },
701 // { "OwnerID", userID.ToString() },
702 // { "AssetID", assetID.ToString() }
703 // };
704  
705 // FIXME: Implement this in SimianGrid
706 return (int)PermissionMask.All;
707 }
708  
709 private List<InventoryFolderBase> GetFoldersFromResponse(OSDArray items, UUID baseFolder, bool includeBaseFolder)
710 {
711 List<InventoryFolderBase> invFolders = new List<InventoryFolderBase>(items.Count);
712  
713 for (int i = 0; i < items.Count; i++)
714 {
715 OSDMap item = items[i] as OSDMap;
716  
717 if (item != null && item["Type"].AsString() == "Folder")
718 {
719 UUID folderID = item["ID"].AsUUID();
720  
721 if (folderID == baseFolder && !includeBaseFolder)
722 continue;
723  
724 invFolders.Add(new InventoryFolderBase(
725 folderID,
726 item["Name"].AsString(),
727 item["OwnerID"].AsUUID(),
728 (short)SLUtil.ContentTypeToSLAssetType(item["ContentType"].AsString()),
729 item["ParentID"].AsUUID(),
730 (ushort)item["Version"].AsInteger()
731 ));
732 }
733 }
734  
735 // m_log.Debug("[SIMIAN INVENTORY CONNECTOR]: Parsed " + invFolders.Count + " folders from SimianGrid response");
736 return invFolders;
737 }
738  
739 private List<InventoryItemBase> GetItemsFromResponse(OSDArray items)
740 {
741 List<InventoryItemBase> invItems = new List<InventoryItemBase>(items.Count);
742  
743 for (int i = 0; i < items.Count; i++)
744 {
745 OSDMap item = items[i] as OSDMap;
746  
747 if (item != null && item["Type"].AsString() == "Item")
748 {
749 InventoryItemBase invItem = new InventoryItemBase();
750  
751 invItem.AssetID = item["AssetID"].AsUUID();
752 invItem.AssetType = SLUtil.ContentTypeToSLAssetType(item["ContentType"].AsString());
753 invItem.CreationDate = item["CreationDate"].AsInteger();
754 invItem.CreatorId = item["CreatorID"].AsString();
755 invItem.CreatorData = item["CreatorData"].AsString();
756 invItem.Description = item["Description"].AsString();
757 invItem.Folder = item["ParentID"].AsUUID();
758 invItem.ID = item["ID"].AsUUID();
759 invItem.InvType = SLUtil.ContentTypeToSLInvType(item["ContentType"].AsString());
760 invItem.Name = item["Name"].AsString();
761 invItem.Owner = item["OwnerID"].AsUUID();
762  
763 OSDMap extraData = item["ExtraData"] as OSDMap;
764 if (extraData != null && extraData.Count > 0)
765 {
766 invItem.Flags = extraData["Flags"].AsUInteger();
767 invItem.GroupID = extraData["GroupID"].AsUUID();
768 invItem.GroupOwned = extraData["GroupOwned"].AsBoolean();
769 invItem.SalePrice = extraData["SalePrice"].AsInteger();
770 invItem.SaleType = (byte)extraData["SaleType"].AsInteger();
771  
772 OSDMap perms = extraData["Permissions"] as OSDMap;
773 if (perms != null)
774 {
775 invItem.BasePermissions = perms["BaseMask"].AsUInteger();
776 invItem.CurrentPermissions = perms["OwnerMask"].AsUInteger();
777 invItem.EveryOnePermissions = perms["EveryoneMask"].AsUInteger();
778 invItem.GroupPermissions = perms["GroupMask"].AsUInteger();
779 invItem.NextPermissions = perms["NextOwnerMask"].AsUInteger();
780 }
781  
782 if (extraData.ContainsKey("LinkedItemType"))
783 invItem.AssetType = SLUtil.ContentTypeToSLAssetType(extraData["LinkedItemType"].AsString());
784 }
785  
786 if (invItem.BasePermissions == 0)
787 {
788 m_log.InfoFormat("[SIMIAN INVENTORY CONNECTOR]: Forcing item permissions to full for item {0} ({1})",
789 invItem.Name, invItem.ID);
790 invItem.BasePermissions = (uint)PermissionMask.All;
791 invItem.CurrentPermissions = (uint)PermissionMask.All;
792 invItem.EveryOnePermissions = (uint)PermissionMask.All;
793 invItem.GroupPermissions = (uint)PermissionMask.All;
794 invItem.NextPermissions = (uint)PermissionMask.All;
795 }
796  
797 invItems.Add(invItem);
798 }
799 }
800  
801 // m_log.Debug("[SIMIAN INVENTORY CONNECTOR]: Parsed " + invItems.Count + " items from SimianGrid response");
802 return invItems;
803 }
804  
805 private bool MoveItems(UUID ownerID, List<InventoryItemBase> items, UUID destFolderID)
806 {
807 string[] itemIDs = new string[items.Count];
808 for (int i = 0; i < items.Count; i++)
809 itemIDs[i] = items[i].ID.ToString();
810  
811 NameValueCollection requestArgs = new NameValueCollection
812 {
813 { "RequestMethod", "MoveInventoryNodes" },
814 { "OwnerID", ownerID.ToString() },
815 { "FolderID", destFolderID.ToString() },
816 { "Items", String.Join(",", itemIDs) }
817 };
818  
819 OSDMap response = SimianGrid.PostToService(m_serverUrl, requestArgs);
820 bool success = response["Success"].AsBoolean();
821  
822 if (!success)
823 {
824 m_log.Warn("[SIMIAN INVENTORY CONNECTOR]: Failed to move " + items.Count + " items to " +
825 destFolderID + ": " + response["Message"].AsString());
826 }
827  
828 return success;
829 }
830  
831 private void UpdateGesture(UUID userID, UUID itemID, bool enabled)
832 {
833 OSDArray gestures = FetchGestures(userID);
834 OSDArray newGestures = new OSDArray();
835  
836 for (int i = 0; i < gestures.Count; i++)
837 {
838 UUID gesture = gestures[i].AsUUID();
839 if (gesture != itemID)
840 newGestures.Add(OSD.FromUUID(gesture));
841 }
842  
843 if (enabled)
844 newGestures.Add(OSD.FromUUID(itemID));
845  
846 SaveGestures(userID, newGestures);
847 }
848  
849 private OSDArray FetchGestures(UUID userID)
850 {
851 NameValueCollection requestArgs = new NameValueCollection
852 {
853 { "RequestMethod", "GetUser" },
854 { "UserID", userID.ToString() }
855 };
856  
857 OSDMap response = SimianGrid.PostToService(m_userServerUrl, requestArgs);
858 if (response["Success"].AsBoolean())
859 {
860 OSDMap user = response["User"] as OSDMap;
861 if (user != null && response.ContainsKey("Gestures"))
862 {
863 OSD gestures = OSDParser.DeserializeJson(response["Gestures"].AsString());
864 if (gestures != null && gestures is OSDArray)
865 return (OSDArray)gestures;
866 else
867 m_log.Error("[SIMIAN INVENTORY CONNECTOR]: Unrecognized active gestures data for " + userID);
868 }
869 }
870 else
871 {
872 m_log.Warn("[SIMIAN INVENTORY CONNECTOR]: Failed to fetch active gestures for " + userID + ": " +
873 response["Message"].AsString());
874 }
875  
876 return new OSDArray();
877 }
878  
879 private void SaveGestures(UUID userID, OSDArray gestures)
880 {
881 NameValueCollection requestArgs = new NameValueCollection
882 {
883 { "RequestMethod", "AddUserData" },
884 { "UserID", userID.ToString() },
885 { "Gestures", OSDParser.SerializeJsonString(gestures) }
886 };
887  
888 OSDMap response = SimianGrid.PostToService(m_userServerUrl, requestArgs);
889 if (!response["Success"].AsBoolean())
890 {
891 m_log.Warn("[SIMIAN INVENTORY CONNECTOR]: Failed to save active gestures for " + userID + ": " +
892 response["Message"].AsString());
893 }
894 }
895 }
896 }