OpenSim
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros
SimianInventoryServiceConnector.cs
Go to the documentation of this file.
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;
42 
43 namespace OpenSim.Services.Connectors.SimianGrid
44 {
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 
65  [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "SimianInventoryServiceConnector")]
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  private const double CACHE_EXPIRATION_SECONDS = 20.0;
78  private static ExpiringCache<UUID, InventoryItemBase> m_ItemCache;
79 
80  #region ISharedRegionModule
81 
82  public Type ReplaceableInterface { get { return null; } }
83  public void RegionLoaded(Scene scene) { }
84  public void PostInitialise() { }
85  public void Close() { }
86 
88  public string Name { get { return "SimianInventoryServiceConnector"; } }
89  public void AddRegion(Scene scene) { if (m_Enabled) { scene.RegisterModuleInterface<IInventoryService>(this); } }
90  public void RemoveRegion(Scene scene) { if (m_Enabled) { scene.UnregisterModuleInterface<IInventoryService>(this); } }
91 
92  #endregion ISharedRegionModule
93 
94  public SimianInventoryServiceConnector(IConfigSource source)
95  {
96  CommonInit(source);
97  }
98 
100  {
101  if (!url.EndsWith("/") && !url.EndsWith("="))
102  url = url + '/';
103  m_serverUrl = url;
104 
105  if (m_ItemCache == null)
106  m_ItemCache = new ExpiringCache<UUID, InventoryItemBase>();
107 
108  }
109 
110  public void Initialise(IConfigSource source)
111  {
112  IConfig moduleConfig = source.Configs["Modules"];
113  if (moduleConfig != null)
114  {
115  string name = moduleConfig.GetString("InventoryServices", "");
116  if (name == Name)
117  CommonInit(source);
118  }
119  }
120 
121  private void CommonInit(IConfigSource source)
122  {
123  IConfig gridConfig = source.Configs["InventoryService"];
124  if (gridConfig != null)
125  {
126  string serviceUrl = gridConfig.GetString("InventoryServerURI");
127  if (!String.IsNullOrEmpty(serviceUrl))
128  {
129  if (!serviceUrl.EndsWith("/") && !serviceUrl.EndsWith("="))
130  serviceUrl = serviceUrl + '/';
131  m_serverUrl = serviceUrl;
132 
133  gridConfig = source.Configs["UserAccountService"];
134  if (gridConfig != null)
135  {
136  serviceUrl = gridConfig.GetString("UserAccountServerURI");
137  if (!String.IsNullOrEmpty(serviceUrl))
138  {
139  m_userServerUrl = serviceUrl;
140  m_Enabled = true;
141  if (m_ItemCache == null)
142  m_ItemCache = new ExpiringCache<UUID, InventoryItemBase>();
143  }
144  }
145  }
146  }
147 
148  if (String.IsNullOrEmpty(m_serverUrl))
149  m_log.Info("[SIMIAN INVENTORY CONNECTOR]: No InventoryServerURI specified, disabling connector");
150  else if (String.IsNullOrEmpty(m_userServerUrl))
151  m_log.Info("[SIMIAN INVENTORY CONNECTOR]: No UserAccountServerURI specified, disabling connector");
152  }
153 
159  public bool CreateUserInventory(UUID userID)
160  {
161  NameValueCollection requestArgs = new NameValueCollection
162  {
163  { "RequestMethod", "AddInventory" },
164  { "OwnerID", userID.ToString() }
165  };
166 
167  OSDMap response = SimianGrid.PostToService(m_serverUrl, requestArgs);
168  bool success = response["Success"].AsBoolean();
169 
170  if (!success)
171  m_log.Warn("[SIMIAN INVENTORY CONNECTOR]: Inventory creation for " + userID + " failed: " + response["Message"].AsString());
172 
173  return success;
174  }
175 
181  public List<InventoryFolderBase> GetInventorySkeleton(UUID userID)
182  {
183  NameValueCollection requestArgs = new NameValueCollection
184  {
185  { "RequestMethod", "GetInventoryNode" },
186  { "ItemID", userID.ToString() },
187  { "OwnerID", userID.ToString() },
188  { "IncludeFolders", "1" },
189  { "IncludeItems", "0" },
190  { "ChildrenOnly", "0" }
191  };
192 
193  OSDMap response = SimianGrid.PostToService(m_serverUrl, requestArgs);
194  if (response["Success"].AsBoolean() && response["Items"] is OSDArray)
195  {
196  OSDArray items = (OSDArray)response["Items"];
197  return GetFoldersFromResponse(items, userID, true);
198  }
199  else
200  {
201  m_log.Warn("[SIMIAN INVENTORY CONNECTOR]: Failed to retrieve inventory skeleton for " + userID + ": " +
202  response["Message"].AsString());
203  return new List<InventoryFolderBase>(0);
204  }
205  }
206 
212  public InventoryFolderBase GetRootFolder(UUID userID)
213  {
214  NameValueCollection requestArgs = new NameValueCollection
215  {
216  { "RequestMethod", "GetInventoryNode" },
217  { "ItemID", userID.ToString() },
218  { "OwnerID", userID.ToString() },
219  { "IncludeFolders", "1" },
220  { "IncludeItems", "0" },
221  { "ChildrenOnly", "1" }
222  };
223 
224  OSDMap response = SimianGrid.PostToService(m_serverUrl, requestArgs);
225  if (response["Success"].AsBoolean() && response["Items"] is OSDArray)
226  {
227  OSDArray items = (OSDArray)response["Items"];
228  List<InventoryFolderBase> folders = GetFoldersFromResponse(items, userID, true);
229 
230  if (folders.Count > 0)
231  return folders[0];
232  }
233 
234  return null;
235  }
236 
243  public InventoryFolderBase GetFolderForType(UUID userID, FolderType type)
244  {
245  string contentType = SLUtil.SLAssetTypeToContentType((int)type);
246 
247  NameValueCollection requestArgs = new NameValueCollection
248  {
249  { "RequestMethod", "GetFolderForType" },
250  { "ContentType", contentType },
251  { "OwnerID", userID.ToString() }
252  };
253 
254  OSDMap response = SimianGrid.PostToService(m_serverUrl, requestArgs);
255  if (response["Success"].AsBoolean() && response["Folder"] is OSDMap)
256  {
257  OSDMap folder = (OSDMap)response["Folder"];
258 
259  return new InventoryFolderBase(
260  folder["ID"].AsUUID(),
261  folder["Name"].AsString(),
262  folder["OwnerID"].AsUUID(),
263  (short)SLUtil.ContentTypeToSLAssetType(folder["ContentType"].AsString()),
264  folder["ParentID"].AsUUID(),
265  (ushort)folder["Version"].AsInteger()
266  );
267  }
268  else
269  {
270  m_log.Warn("[SIMIAN INVENTORY CONNECTOR]: Default folder not found for content type " + contentType + ": " + response["Message"].AsString());
271  return GetRootFolder(userID);
272  }
273  }
274 
281  {
282  InventoryItemBase retrieved = null;
283  if (m_ItemCache.TryGetValue(item.ID, out retrieved))
284  return retrieved;
285 
286  NameValueCollection requestArgs = new NameValueCollection
287  {
288  { "RequestMethod", "GetInventoryNode" },
289  { "ItemID", item.ID.ToString() },
290  { "OwnerID", item.Owner.ToString() },
291  { "IncludeFolders", "1" },
292  { "IncludeItems", "1" },
293  { "ChildrenOnly", "1" }
294  };
295 
296  OSDMap response = SimianGrid.PostToService(m_serverUrl, requestArgs);
297  if (response["Success"].AsBoolean() && response["Items"] is OSDArray)
298  {
299  List<InventoryItemBase> items = GetItemsFromResponse((OSDArray)response["Items"]);
300  if (items.Count > 0)
301  {
302  // The requested item should be the first in this list, but loop through
303  // and sanity check just in case
304  for (int i = 0; i < items.Count; i++)
305  {
306  if (items[i].ID == item.ID)
307  {
308  retrieved = items[i];
309  m_ItemCache.AddOrUpdate(item.ID, retrieved, CACHE_EXPIRATION_SECONDS);
310  return retrieved;
311  }
312  }
313  }
314  }
315 
316  m_log.Warn("[SIMIAN INVENTORY CONNECTOR]: Item " + item.ID + " owned by " + item.Owner + " not found");
317  return null;
318  }
319 
320  public InventoryItemBase[] GetMultipleItems(UUID principalID, UUID[] itemIDs)
321  {
322  InventoryItemBase[] result = new InventoryItemBase[itemIDs.Length];
323  int i = 0;
325  item.Owner = principalID;
326  foreach (UUID id in itemIDs)
327  {
328  item.ID = id;
329  result[i++] = GetItem(item);
330  }
331 
332  return result;
333  }
334 
341  {
342  NameValueCollection requestArgs = new NameValueCollection
343  {
344  { "RequestMethod", "GetInventoryNode" },
345  { "ItemID", folder.ID.ToString() },
346  { "OwnerID", folder.Owner.ToString() },
347  { "IncludeFolders", "1" },
348  { "IncludeItems", "0" },
349  { "ChildrenOnly", "1" }
350  };
351 
352  OSDMap response = SimianGrid.PostToService(m_serverUrl, requestArgs);
353  if (response["Success"].AsBoolean() && response["Items"] is OSDArray)
354  {
355  OSDArray items = (OSDArray)response["Items"];
356  List<InventoryFolderBase> folders = GetFoldersFromResponse(items, folder.ID, true);
357 
358  if (folders.Count > 0)
359  return folders[0];
360  }
361 
362  return null;
363  }
364 
371  public InventoryCollection GetFolderContent(UUID userID, UUID folderID)
372  {
373  InventoryCollection inventory = new InventoryCollection();
374  inventory.OwnerID = userID;
375 
376  NameValueCollection requestArgs = new NameValueCollection
377  {
378  { "RequestMethod", "GetInventoryNode" },
379  { "ItemID", folderID.ToString() },
380  { "OwnerID", userID.ToString() },
381  { "IncludeFolders", "1" },
382  { "IncludeItems", "1" },
383  { "ChildrenOnly", "1" }
384  };
385 
386  OSDMap response = SimianGrid.PostToService(m_serverUrl, requestArgs);
387  if (response["Success"].AsBoolean() && response["Items"] is OSDArray)
388  {
389  OSDArray items = (OSDArray)response["Items"];
390 
391  inventory.Folders = GetFoldersFromResponse(items, folderID, false);
392  inventory.Items = GetItemsFromResponse(items);
393  }
394  else
395  {
396  m_log.Warn("[SIMIAN INVENTORY CONNECTOR]: Error fetching folder " + folderID + " content for " + userID + ": " +
397  response["Message"].AsString());
398  inventory.Folders = new List<InventoryFolderBase>(0);
399  inventory.Items = new List<InventoryItemBase>(0);
400  }
401 
402  return inventory;
403  }
404 
405  public virtual InventoryCollection[] GetMultipleFoldersContent(UUID principalID, UUID[] folderIDs)
406  {
407  InventoryCollection[] invColl = new InventoryCollection[folderIDs.Length];
408  int i = 0;
409  foreach (UUID fid in folderIDs)
410  {
411  invColl[i++] = GetFolderContent(principalID, fid);
412  }
413 
414  return invColl;
415  }
416 
423  public List<InventoryItemBase> GetFolderItems(UUID userID, UUID folderID)
424  {
425  InventoryCollection inventory = new InventoryCollection();
426  inventory.OwnerID = userID;
427 
428  NameValueCollection requestArgs = new NameValueCollection
429  {
430  { "RequestMethod", "GetInventoryNode" },
431  { "ItemID", folderID.ToString() },
432  { "OwnerID", userID.ToString() },
433  { "IncludeFolders", "0" },
434  { "IncludeItems", "1" },
435  { "ChildrenOnly", "1" }
436  };
437 
438  OSDMap response = SimianGrid.PostToService(m_serverUrl, requestArgs);
439  if (response["Success"].AsBoolean() && response["Items"] is OSDArray)
440  {
441  OSDArray items = (OSDArray)response["Items"];
442  return GetItemsFromResponse(items);
443  }
444  else
445  {
446  m_log.Warn("[SIMIAN INVENTORY CONNECTOR]: Error fetching folder " + folderID + " for " + userID + ": " +
447  response["Message"].AsString());
448  return new List<InventoryItemBase>(0);
449  }
450  }
451 
457  public bool AddFolder(InventoryFolderBase folder)
458  {
459  NameValueCollection requestArgs = new NameValueCollection
460  {
461  { "RequestMethod", "AddInventoryFolder" },
462  { "FolderID", folder.ID.ToString() },
463  { "ParentID", folder.ParentID.ToString() },
464  { "OwnerID", folder.Owner.ToString() },
465  { "Name", folder.Name },
466  { "ContentType", SLUtil.SLAssetTypeToContentType(folder.Type) }
467  };
468 
469  OSDMap response = SimianGrid.PostToService(m_serverUrl, requestArgs);
470  bool success = response["Success"].AsBoolean();
471 
472  if (!success)
473  {
474  m_log.Warn("[SIMIAN INVENTORY CONNECTOR]: Error creating folder " + folder.Name + " for " + folder.Owner + ": " +
475  response["Message"].AsString());
476  }
477 
478  return success;
479  }
480 
486  public bool UpdateFolder(InventoryFolderBase folder)
487  {
488  return AddFolder(folder);
489  }
490 
496  public bool MoveFolder(InventoryFolderBase folder)
497  {
498  return AddFolder(folder);
499  }
500 
506  //bool DeleteItem(InventoryItemBase item);
507  public bool DeleteFolders(UUID userID, List<UUID> folderIDs)
508  {
509  return DeleteItems(userID, folderIDs);
510  }
511 
517  public bool DeleteItems(UUID userID, List<UUID> itemIDs)
518  {
519  // TODO: RemoveInventoryNode should be replaced with RemoveInventoryNodes
520  bool allSuccess = true;
521 
522  for (int i = 0; i < itemIDs.Count; i++)
523  {
524  UUID itemID = itemIDs[i];
525 
526  NameValueCollection requestArgs = new NameValueCollection
527  {
528  { "RequestMethod", "RemoveInventoryNode" },
529  { "OwnerID", userID.ToString() },
530  { "ItemID", itemID.ToString() }
531  };
532 
533  OSDMap response = SimianGrid.PostToService(m_serverUrl, requestArgs);
534  bool success = response["Success"].AsBoolean();
535 
536  if (!success)
537  {
538  m_log.Warn("[SIMIAN INVENTORY CONNECTOR]: Error removing item " + itemID + " for " + userID + ": " +
539  response["Message"].AsString());
540  allSuccess = false;
541  }
542  }
543 
544  return allSuccess;
545  }
546 
552  public bool PurgeFolder(InventoryFolderBase folder)
553  {
554  NameValueCollection requestArgs = new NameValueCollection
555  {
556  { "RequestMethod", "PurgeInventoryFolder" },
557  { "OwnerID", folder.Owner.ToString() },
558  { "FolderID", folder.ID.ToString() }
559  };
560 
561  OSDMap response = SimianGrid.PostToService(m_serverUrl, requestArgs);
562  bool success = response["Success"].AsBoolean();
563 
564  if (!success)
565  {
566  m_log.Warn("[SIMIAN INVENTORY CONNECTOR]: Error purging folder " + folder.ID + " for " + folder.Owner + ": " +
567  response["Message"].AsString());
568  }
569 
570  return success;
571  }
572 
578  public bool AddItem(InventoryItemBase item)
579  {
580  // A folder of UUID.Zero means we need to find the most appropriate home for this item
581  if (item.Folder == UUID.Zero)
582  {
583  InventoryFolderBase folder = null;
584  if (Enum.IsDefined(typeof(FolderType), (sbyte)item.AssetType))
585  folder = GetFolderForType(item.Owner, (FolderType)item.AssetType);
586  if (folder != null && folder.ID != UUID.Zero)
587  item.Folder = folder.ID;
588  else
589  item.Folder = item.Owner; // Root folder
590  }
591 
592  if ((AssetType)item.AssetType == AssetType.Gesture)
593  UpdateGesture(item.Owner, item.ID, item.Flags == 1);
594 
595  if (item.BasePermissions == 0)
596  m_log.WarnFormat("[SIMIAN INVENTORY CONNECTOR]: Adding inventory item {0} ({1}) with no base permissions", item.Name, item.ID);
597 
598  OSDMap permissions = new OSDMap
599  {
600  { "BaseMask", OSD.FromInteger(item.BasePermissions) },
601  { "EveryoneMask", OSD.FromInteger(item.EveryOnePermissions) },
602  { "GroupMask", OSD.FromInteger(item.GroupPermissions) },
603  { "NextOwnerMask", OSD.FromInteger(item.NextPermissions) },
604  { "OwnerMask", OSD.FromInteger(item.CurrentPermissions) }
605  };
606 
607  OSDMap extraData = new OSDMap()
608  {
609  { "Flags", OSD.FromInteger(item.Flags) },
610  { "GroupID", OSD.FromUUID(item.GroupID) },
611  { "GroupOwned", OSD.FromBoolean(item.GroupOwned) },
612  { "SalePrice", OSD.FromInteger(item.SalePrice) },
613  { "SaleType", OSD.FromInteger(item.SaleType) },
614  { "Permissions", permissions }
615  };
616 
617  // Add different asset type only if it differs from inventory type
618  // (needed for links)
619  string invContentType = SLUtil.SLInvTypeToContentType(item.InvType);
620  string assetContentType = SLUtil.SLAssetTypeToContentType(item.AssetType);
621 
622  if (invContentType != assetContentType)
623  extraData["LinkedItemType"] = OSD.FromString(assetContentType);
624 
625  NameValueCollection requestArgs = new NameValueCollection
626  {
627  { "RequestMethod", "AddInventoryItem" },
628  { "ItemID", item.ID.ToString() },
629  { "AssetID", item.AssetID.ToString() },
630  { "ParentID", item.Folder.ToString() },
631  { "OwnerID", item.Owner.ToString() },
632  { "Name", item.Name },
633  { "Description", item.Description },
634  { "CreatorID", item.CreatorId },
635  { "CreatorData", item.CreatorData },
636  { "ContentType", invContentType },
637  { "ExtraData", OSDParser.SerializeJsonString(extraData) }
638  };
639 
640  OSDMap response = SimianGrid.PostToService(m_serverUrl, requestArgs);
641  bool success = response["Success"].AsBoolean();
642 
643  if (!success)
644  {
645  m_log.Warn("[SIMIAN INVENTORY CONNECTOR]: Error creating item " + item.Name + " for " + item.Owner + ": " +
646  response["Message"].AsString());
647  }
648 
649  return success;
650  }
651 
657  public bool UpdateItem(InventoryItemBase item)
658  {
659  if (item.AssetID != UUID.Zero)
660  {
661  return AddItem(item);
662  }
663  else
664  {
665  // This is actually a folder update
666  InventoryFolderBase folder = new InventoryFolderBase(item.ID, item.Name, item.Owner, (short)item.AssetType, item.Folder, 0);
667  return UpdateFolder(folder);
668  }
669  }
670 
671  public bool MoveItems(UUID ownerID, List<InventoryItemBase> items)
672  {
673  bool success = true;
674 
675  while (items.Count > 0)
676  {
677  List<InventoryItemBase> currentItems = new List<InventoryItemBase>();
678  UUID destFolderID = items[0].Folder;
679 
680  // Find all of the items being moved to the current destination folder
681  for (int i = 0; i < items.Count; i++)
682  {
683  InventoryItemBase item = items[i];
684  if (item.Folder == destFolderID)
685  currentItems.Add(item);
686  }
687 
688  // Do the inventory move for the current items
689  success &= MoveItems(ownerID, items, destFolderID);
690 
691  // Remove the processed items from the list
692  for (int i = 0; i < currentItems.Count; i++)
693  items.Remove(currentItems[i]);
694  }
695 
696  return success;
697  }
698 
704  public bool HasInventoryForUser(UUID userID)
705  {
706  return GetRootFolder(userID) != null;
707  }
708 
714  public List<InventoryItemBase> GetActiveGestures(UUID userID)
715  {
716  OSDArray items = FetchGestures(userID);
717 
718  string[] itemIDs = new string[items.Count];
719  for (int i = 0; i < items.Count; i++)
720  itemIDs[i] = items[i].AsUUID().ToString();
721 
722 // NameValueCollection requestArgs = new NameValueCollection
723 // {
724 // { "RequestMethod", "GetInventoryNodes" },
725 // { "OwnerID", userID.ToString() },
726 // { "Items", String.Join(",", itemIDs) }
727 // };
728 
729  // FIXME: Implement this in SimianGrid
730  return new List<InventoryItemBase>(0);
731  }
732 
741  public int GetAssetPermissions(UUID userID, UUID assetID)
742  {
743 // NameValueCollection requestArgs = new NameValueCollection
744 // {
745 // { "RequestMethod", "GetInventoryNodes" },
746 // { "OwnerID", userID.ToString() },
747 // { "AssetID", assetID.ToString() }
748 // };
749 
750  // FIXME: Implement this in SimianGrid
751  return (int)PermissionMask.All;
752  }
753 
754  private List<InventoryFolderBase> GetFoldersFromResponse(OSDArray items, UUID baseFolder, bool includeBaseFolder)
755  {
756  List<InventoryFolderBase> invFolders = new List<InventoryFolderBase>(items.Count);
757 
758  for (int i = 0; i < items.Count; i++)
759  {
760  OSDMap item = items[i] as OSDMap;
761 
762  if (item != null && item["Type"].AsString() == "Folder")
763  {
764  UUID folderID = item["ID"].AsUUID();
765 
766  if (folderID == baseFolder && !includeBaseFolder)
767  continue;
768 
769  invFolders.Add(new InventoryFolderBase(
770  folderID,
771  item["Name"].AsString(),
772  item["OwnerID"].AsUUID(),
773  (short)SLUtil.ContentTypeToSLAssetType(item["ContentType"].AsString()),
774  item["ParentID"].AsUUID(),
775  (ushort)item["Version"].AsInteger()
776  ));
777  }
778  }
779 
780 // m_log.Debug("[SIMIAN INVENTORY CONNECTOR]: Parsed " + invFolders.Count + " folders from SimianGrid response");
781  return invFolders;
782  }
783 
784  private List<InventoryItemBase> GetItemsFromResponse(OSDArray items)
785  {
786  List<InventoryItemBase> invItems = new List<InventoryItemBase>(items.Count);
787 
788  for (int i = 0; i < items.Count; i++)
789  {
790  OSDMap item = items[i] as OSDMap;
791 
792  if (item != null && item["Type"].AsString() == "Item")
793  {
794  InventoryItemBase invItem = new InventoryItemBase();
795 
796  invItem.AssetID = item["AssetID"].AsUUID();
797  invItem.AssetType = SLUtil.ContentTypeToSLAssetType(item["ContentType"].AsString());
798  invItem.CreationDate = item["CreationDate"].AsInteger();
799  invItem.CreatorId = item["CreatorID"].AsString();
800  invItem.CreatorData = item["CreatorData"].AsString();
801  invItem.Description = item["Description"].AsString();
802  invItem.Folder = item["ParentID"].AsUUID();
803  invItem.ID = item["ID"].AsUUID();
804  invItem.InvType = SLUtil.ContentTypeToSLInvType(item["ContentType"].AsString());
805  invItem.Name = item["Name"].AsString();
806  invItem.Owner = item["OwnerID"].AsUUID();
807 
808  OSDMap extraData = item["ExtraData"] as OSDMap;
809  if (extraData != null && extraData.Count > 0)
810  {
811  invItem.Flags = extraData["Flags"].AsUInteger();
812  invItem.GroupID = extraData["GroupID"].AsUUID();
813  invItem.GroupOwned = extraData["GroupOwned"].AsBoolean();
814  invItem.SalePrice = extraData["SalePrice"].AsInteger();
815  invItem.SaleType = (byte)extraData["SaleType"].AsInteger();
816 
817  OSDMap perms = extraData["Permissions"] as OSDMap;
818  if (perms != null)
819  {
820  invItem.BasePermissions = perms["BaseMask"].AsUInteger();
821  invItem.CurrentPermissions = perms["OwnerMask"].AsUInteger();
822  invItem.EveryOnePermissions = perms["EveryoneMask"].AsUInteger();
823  invItem.GroupPermissions = perms["GroupMask"].AsUInteger();
824  invItem.NextPermissions = perms["NextOwnerMask"].AsUInteger();
825  }
826 
827  if (extraData.ContainsKey("LinkedItemType"))
828  invItem.AssetType = SLUtil.ContentTypeToSLAssetType(extraData["LinkedItemType"].AsString());
829  }
830 
831  if (invItem.BasePermissions == 0)
832  {
833  m_log.InfoFormat("[SIMIAN INVENTORY CONNECTOR]: Forcing item permissions to full for item {0} ({1})",
834  invItem.Name, invItem.ID);
835  invItem.BasePermissions = (uint)PermissionMask.All;
836  invItem.CurrentPermissions = (uint)PermissionMask.All;
837  invItem.EveryOnePermissions = (uint)PermissionMask.All;
838  invItem.GroupPermissions = (uint)PermissionMask.All;
839  invItem.NextPermissions = (uint)PermissionMask.All;
840  }
841 
842  invItems.Add(invItem);
843  }
844  }
845 
846 // m_log.Debug("[SIMIAN INVENTORY CONNECTOR]: Parsed " + invItems.Count + " items from SimianGrid response");
847  return invItems;
848  }
849 
850  private bool MoveItems(UUID ownerID, List<InventoryItemBase> items, UUID destFolderID)
851  {
852  string[] itemIDs = new string[items.Count];
853  for (int i = 0; i < items.Count; i++)
854  itemIDs[i] = items[i].ID.ToString();
855 
856  NameValueCollection requestArgs = new NameValueCollection
857  {
858  { "RequestMethod", "MoveInventoryNodes" },
859  { "OwnerID", ownerID.ToString() },
860  { "FolderID", destFolderID.ToString() },
861  { "Items", String.Join(",", itemIDs) }
862  };
863 
864  OSDMap response = SimianGrid.PostToService(m_serverUrl, requestArgs);
865  bool success = response["Success"].AsBoolean();
866 
867  if (!success)
868  {
869  m_log.Warn("[SIMIAN INVENTORY CONNECTOR]: Failed to move " + items.Count + " items to " +
870  destFolderID + ": " + response["Message"].AsString());
871  }
872 
873  return success;
874  }
875 
876  private void UpdateGesture(UUID userID, UUID itemID, bool enabled)
877  {
878  OSDArray gestures = FetchGestures(userID);
879  OSDArray newGestures = new OSDArray();
880 
881  for (int i = 0; i < gestures.Count; i++)
882  {
883  UUID gesture = gestures[i].AsUUID();
884  if (gesture != itemID)
885  newGestures.Add(OSD.FromUUID(gesture));
886  }
887 
888  if (enabled)
889  newGestures.Add(OSD.FromUUID(itemID));
890 
891  SaveGestures(userID, newGestures);
892  }
893 
894  private OSDArray FetchGestures(UUID userID)
895  {
896  NameValueCollection requestArgs = new NameValueCollection
897  {
898  { "RequestMethod", "GetUser" },
899  { "UserID", userID.ToString() }
900  };
901 
902  OSDMap response = SimianGrid.PostToService(m_userServerUrl, requestArgs);
903  if (response["Success"].AsBoolean())
904  {
905  OSDMap user = response["User"] as OSDMap;
906  if (user != null && response.ContainsKey("Gestures"))
907  {
908  OSD gestures = OSDParser.DeserializeJson(response["Gestures"].AsString());
909  if (gestures != null && gestures is OSDArray)
910  return (OSDArray)gestures;
911  else
912  m_log.Error("[SIMIAN INVENTORY CONNECTOR]: Unrecognized active gestures data for " + userID);
913  }
914  }
915  else
916  {
917  m_log.Warn("[SIMIAN INVENTORY CONNECTOR]: Failed to fetch active gestures for " + userID + ": " +
918  response["Message"].AsString());
919  }
920 
921  return new OSDArray();
922  }
923 
924  private void SaveGestures(UUID userID, OSDArray gestures)
925  {
926  NameValueCollection requestArgs = new NameValueCollection
927  {
928  { "RequestMethod", "AddUserData" },
929  { "UserID", userID.ToString() },
930  { "Gestures", OSDParser.SerializeJsonString(gestures) }
931  };
932 
933  OSDMap response = SimianGrid.PostToService(m_userServerUrl, requestArgs);
934  if (!response["Success"].AsBoolean())
935  {
936  m_log.Warn("[SIMIAN INVENTORY CONNECTOR]: Failed to save active gestures for " + userID + ": " +
937  response["Message"].AsString());
938  }
939  }
940  }
941 }
InventoryItemBase GetItem(InventoryItemBase item)
Get an item, given by its UUID
bool DeleteFolders(UUID userID, List< UUID > folderIDs)
Delete an item from the user's inventory
bool DeleteItems(UUID userID, List< UUID > itemIDs)
Delete an item from the user's inventory
OpenMetaverse.StructuredData.OSDArray OSDArray
bool UpdateFolder(InventoryFolderBase folder)
Update a folder in the user's inventory
bool AddItem(InventoryItemBase item)
Add a new item to the user's inventory
bool MoveFolder(InventoryFolderBase folder)
Move an inventory folder to a new location
InventoryFolderBase GetFolder(InventoryFolderBase folder)
Get a folder, given by its UUID
bool PurgeFolder(InventoryFolderBase folder)
Purge an inventory folder of all its items and subfolders.
List< InventoryFolderBase > GetInventorySkeleton(UUID userID)
Gets the skeleton of the inventory – folders only
OpenMetaverse.StructuredData.OSDMap OSDMap
void RegionLoaded(Scene scene)
This will be called once for every scene loaded. In a shared module this will be multiple times in on...
List< InventoryItemBase > GetFolderItems(UUID userID, UUID folderID)
Gets the items inside a folder
InventoryFolderBase GetFolderForType(UUID userID, FolderType type)
Gets the user folder for the given folder-type
InventoryItemBase[] GetMultipleItems(UUID principalID, UUID[] itemIDs)
Get multiple items, given by their UUIDs
OpenSim.Framework.PermissionMask PermissionMask
void PostInitialise()
This is called exactly once after all the shared region-modules have been instanciated and IRegionMod...
InventoryCollection GetFolderContent(UUID userID, UUID folderID)
Gets everything (folders and items) inside a folder
List< InventoryItemBase > GetActiveGestures(UUID userID)
Get the active gestures of the agent.
bool AddFolder(InventoryFolderBase folder)
Add a new folder to the user's inventory
InventoryFolderBase GetRootFolder(UUID userID)
Retrieve the root inventory folder for the given user.
virtual UUID Owner
The agent who's inventory this is contained by
bool HasInventoryForUser(UUID userID)
Does the given user have an inventory structure?
void Close()
This is the inverse to Initialise. After a Close(), this instance won't be usable anymore...
Inventory Item - contains all the properties associated with an individual inventory piece...
int GetAssetPermissions(UUID userID, UUID assetID)
Get the union of permissions of all inventory items that hold the given assetID.
OpenMetaverse.StructuredData.OSD OSD
void RemoveRegion(Scene scene)
This is called whenever a Scene is removed. For shared modules, this can happen several times...
bool CreateUserInventory(UUID userID)
Create the entire inventory for a given user
UUID ID
A UUID containing the ID for the inventory node itself
void Initialise(IConfigSource source)
This is called to initialize the region module. For shared modules, this is called exactly once...
void AddRegion(Scene scene)
This is called whenever a Scene is added. For shared modules, this can happen several times...
virtual string Name
The name of the node (64 characters or less)
virtual InventoryCollection[] GetMultipleFoldersContent(UUID principalID, UUID[] folderIDs)
Gets everything (folders and items) inside a folder
Used to serialize a whole inventory for transfer over the network.
bool UpdateItem(InventoryItemBase item)
Update an item in the user's inventory