29 using System.Collections.Generic;
34 using System.Reflection;
35 using OpenSim.Services.Base;
36 using OpenSim.Services.Interfaces;
37 using OpenSim.Services.InventoryService;
39 using OpenSim.Framework;
40 using OpenSim.Server.Base;
42 namespace OpenSim.Services.HypergridService
53 private static readonly ILog m_log =
55 MethodBase.GetCurrentMethod().DeclaringType);
63 private ExpiringCache<UUID, List<XInventoryFolder>> m_SuitcaseTrees =
new ExpiringCache<UUID, List<XInventoryFolder>>();
64 private ExpiringCache<UUID, AvatarAppearance> m_Appearances =
new ExpiringCache<UUID, AvatarAppearance>();
67 : base(config, configName)
69 m_log.DebugFormat(
"[HG SUITCASE INVENTORY SERVICE]: Starting with config name {0}", configName);
70 if (configName !=
string.Empty)
71 m_ConfigName = configName;
73 if (m_Database == null)
74 m_log.ErrorFormat(
"[HG SUITCASE INVENTORY SERVICE]: m_Database is null!");
79 IConfig invConfig = config.Configs[m_ConfigName];
80 if (invConfig != null)
82 string userAccountsDll = invConfig.GetString(
"UserAccountsService", string.Empty);
83 if (userAccountsDll ==
string.Empty)
84 throw new Exception(
"Please specify UserAccountsService in HGInventoryService configuration");
86 Object[] args =
new Object[] { config };
88 if (m_UserAccountService == null)
89 throw new Exception(String.Format(
"Unable to create UserAccountService from {0}", userAccountsDll));
91 string avatarDll = invConfig.GetString(
"AvatarService", string.Empty);
92 if (avatarDll ==
string.Empty)
93 throw new Exception(
"Please specify AvatarService in HGInventoryService configuration");
95 m_AvatarService = ServerUtils.LoadPlugin<
IAvatarService>(avatarDll, args);
96 if (m_AvatarService == null)
97 throw new Exception(String.Format(
"Unable to create m_AvatarService from {0}", avatarDll));
105 m_log.Debug(
"[HG SUITCASE INVENTORY SERVICE]: Starting...");
118 if (suitcase == null)
120 m_log.WarnFormat(
"[HG SUITCASE INVENTORY SERVICE]: Found no suitcase folder for user {0} when looking for inventory skeleton", principalID);
124 List<XInventoryFolder> tree = GetFolderTree(principalID, suitcase.
folderID);
128 List<InventoryFolderBase> folders =
new List<InventoryFolderBase>();
131 folders.Add(ConvertToOpenSim(x));
134 SetAsNormalFolder(suitcase);
135 folders.Add(ConvertToOpenSim(suitcase));
142 m_log.DebugFormat(
"[HG SUITCASE INVENTORY SERVICE]: GetRootFolder for {0}", principalID);
149 m_log.WarnFormat(
"[HG SUITCASE INVENTORY SERVICE]: Unable to retrieve local root folder for user {0}", principalID);
156 if (suitcase == null)
158 m_log.DebugFormat(
"[HG SUITCASE INVENTORY SERVICE]: User {0} does not have a Suitcase folder. Creating it...", principalID);
162 if (suitcase == null)
164 m_log.ErrorFormat(
"[HG SUITCASE INVENTORY SERVICE]: Unable to create suitcase folder");
168 CreateSystemFolders(principalID, suitcase.folderID);
171 SetAsNormalFolder(suitcase);
173 return ConvertToOpenSim(suitcase);
178 m_log.Debug(
"[HG SUITCASE INVENTORY SERVICE]: Creating System folders under Suitcase...");
181 if (!Array.Exists(sysFolders, delegate(
XInventoryFolder f) {
if (f.
type == (
int)FolderType.Animation)
return true;
return false; }))
182 CreateFolder(principalID, rootID, (
int)FolderType.Animation,
"Animations");
183 if (!Array.Exists(sysFolders, delegate(
XInventoryFolder f) {
if (f.
type == (
int)FolderType.BodyPart)
return true;
return false; }))
184 CreateFolder(principalID, rootID, (
int)FolderType.BodyPart,
"Body Parts");
185 if (!Array.Exists(sysFolders, delegate(
XInventoryFolder f) {
if (f.
type == (
int)FolderType.CallingCard)
return true;
return false; }))
186 CreateFolder(principalID, rootID, (
int)FolderType.CallingCard,
"Calling Cards");
187 if (!Array.Exists(sysFolders, delegate(
XInventoryFolder f) {
if (f.
type == (
int)FolderType.Clothing)
return true;
return false; }))
188 CreateFolder(principalID, rootID, (
int)FolderType.Clothing,
"Clothing");
189 if (!Array.Exists(sysFolders, delegate(
XInventoryFolder f) {
if (f.
type == (
int)FolderType.CurrentOutfit)
return true;
return false; }))
190 CreateFolder(principalID, rootID, (
int)FolderType.CurrentOutfit,
"Current Outfit");
191 if (!Array.Exists(sysFolders, delegate(
XInventoryFolder f) {
if (f.
type == (
int)FolderType.Favorites)
return true;
return false; }))
192 CreateFolder(principalID, rootID, (
int)FolderType.Favorites,
"Favorites");
193 if (!Array.Exists(sysFolders, delegate(
XInventoryFolder f) {
if (f.
type == (
int)FolderType.Gesture)
return true;
return false; }))
194 CreateFolder(principalID, rootID, (
int)FolderType.Gesture,
"Gestures");
195 if (!Array.Exists(sysFolders, delegate(
XInventoryFolder f) {
if (f.
type == (
int)FolderType.Landmark)
return true;
return false; }))
196 CreateFolder(principalID, rootID, (
int)FolderType.Landmark,
"Landmarks");
197 if (!Array.Exists(sysFolders, delegate(
XInventoryFolder f) {
if (f.
type == (
int)FolderType.LostAndFound)
return true;
return false; }))
198 CreateFolder(principalID, rootID, (
int)FolderType.LostAndFound,
"Lost And Found");
199 if (!Array.Exists(sysFolders, delegate(
XInventoryFolder f) {
if (f.
type == (
int)FolderType.Notecard)
return true;
return false; }))
200 CreateFolder(principalID, rootID, (
int)FolderType.Notecard,
"Notecards");
201 if (!Array.Exists(sysFolders, delegate(
XInventoryFolder f) {
if (f.
type == (
int)FolderType.Object)
return true;
return false; }))
202 CreateFolder(principalID, rootID, (
int)FolderType.Object,
"Objects");
203 if (!Array.Exists(sysFolders, delegate(
XInventoryFolder f) {
if (f.
type == (
int)FolderType.Snapshot)
return true;
return false; }))
204 CreateFolder(principalID, rootID, (
int)FolderType.Snapshot,
"Photo Album");
205 if (!Array.Exists(sysFolders, delegate(
XInventoryFolder f) {
if (f.
type == (
int)FolderType.LSLText)
return true;
return false; }))
206 CreateFolder(principalID, rootID, (
int)FolderType.LSLText,
"Scripts");
207 if (!Array.Exists(sysFolders, delegate(
XInventoryFolder f) {
if (f.
type == (
int)FolderType.Sound)
return true;
return false; }))
208 CreateFolder(principalID, rootID, (
int)FolderType.Sound,
"Sounds");
209 if (!Array.Exists(sysFolders, delegate(
XInventoryFolder f) {
if (f.
type == (
int)FolderType.Texture)
return true;
return false; }))
210 CreateFolder(principalID, rootID, (
int)FolderType.Texture,
"Textures");
211 if (!Array.Exists(sysFolders, delegate(
XInventoryFolder f) {
if (f.
type == (
int)FolderType.Trash)
return true;
return false; }))
212 CreateFolder(principalID, rootID, (
int)FolderType.Trash,
"Trash");
220 if (suitcase == null)
222 m_log.WarnFormat(
"[HG SUITCASE INVENTORY SERVICE]: Found no suitcase folder for user {0} when looking for child type folder {1}", principalID, type);
227 new string[] {
"agentID",
"type",
"parentFolderID" },
228 new string[] { principalID.ToString(), ((
int)type).ToString(), suitcase.folderID.ToString() });
230 if (folders.Length == 0)
232 m_log.WarnFormat(
"[HG SUITCASE INVENTORY SERVICE]: Found no folder for type {0} for user {1}", type, principalID);
237 "[HG SUITCASE INVENTORY SERVICE]: Found folder {0} {1} for type {2} for user {3}",
238 folders[0].folderName, folders[0].folderID, type, principalID);
240 return ConvertToOpenSim(folders[0]);
247 if (!IsWithinSuitcaseTree(principalID, folderID))
249 m_log.DebugFormat(
"[HG SUITCASE INVENTORY SERVICE]: GetFolderContent: folder {0} (user {1}) is not within Suitcase tree", folderID, principalID);
253 coll = base.GetFolderContent(principalID, folderID);
257 m_log.WarnFormat(
"[HG SUITCASE INVENTORY SERVICE]: Something wrong with user {0}'s suitcase folder", principalID);
263 public override List<InventoryItemBase>
GetFolderItems(UUID principalID, UUID folderID)
267 if (!IsWithinSuitcaseTree(principalID, folderID))
269 m_log.DebugFormat(
"[HG SUITCASE INVENTORY SERVICE]: GetFolderItems: folder {0} (user {1}) is not within Suitcase tree", folderID, principalID);
270 return new List<InventoryItemBase>();
273 return base.GetFolderItems(principalID, folderID);
284 m_log.DebugFormat(
"[HG SUITCASE INVENTORY SERVICE]: AddFolder: folder {0} (user {1}) is not within Suitcase tree", folder.ParentID, folder.Owner);
289 if (base.AddFolder(folder))
291 List<XInventoryFolder> tree;
292 if (m_SuitcaseTrees.TryGetValue(folder.
Owner, out tree))
293 tree.Add(ConvertFromOpenSim(folder));
304 if (!IsWithinSuitcaseTree(folder.
Owner, folder.
ID))
306 m_log.DebugFormat(
"[HG SUITCASE INVENTORY SERVICE]: UpdateFolder: folder {0}/{1} (user {2}) is not within Suitcase tree", folder.Name, folder.ID, folder.Owner);
311 return base.UpdateFolder(folder);
316 if (!IsWithinSuitcaseTree(folder.
Owner, folder.
ID))
318 m_log.DebugFormat(
"[HG SUITCASE INVENTORY SERVICE]: MoveFolder: folder {0} (user {1}) is not within Suitcase tree", folder.ID, folder.Owner);
324 m_log.DebugFormat(
"[HG SUITCASE INVENTORY SERVICE]: MoveFolder: folder {0} (user {1}) is not within Suitcase tree", folder.ParentID, folder.Owner);
328 return base.MoveFolder(folder);
347 if (!IsWithinSuitcaseTree(item.
Owner, item.
Folder))
349 m_log.DebugFormat(
"[HG SUITCASE INVENTORY SERVICE]: AddItem: folder {0} (user {1}) is not within Suitcase tree", item.Folder, item.Owner);
354 return base.AddItem(item);
360 if (!IsWithinSuitcaseTree(item.
Owner, item.
Folder))
362 m_log.DebugFormat(
"[HG SUITCASE INVENTORY SERVICE]: UpdateItem: folder {0} (user {1}) is not within Suitcase tree", item.Folder, item.Owner);
366 return base.UpdateItem(item);
369 public override bool MoveItems(UUID principalID, List<InventoryItemBase> items)
376 if (!IsWithinSuitcaseTree(item.
Owner, item.
Folder))
378 m_log.DebugFormat(
"[HG SUITCASE INVENTORY SERVICE]: MoveItems: folder {0} (user {1}) is not within Suitcase tree", item.Folder, item.Owner);
387 if (!IsWithinSuitcaseTree(originalItem.
Owner, originalItem.
Folder))
389 m_log.DebugFormat(
"[HG SUITCASE INVENTORY SERVICE]: MoveItems: folder {0} (user {1}) is not within Suitcase tree", item.Folder, item.Owner);
394 return base.MoveItems(principalID, items);
397 public override bool DeleteItems(UUID principalID, List<UUID> itemIDs)
407 m_log.DebugFormat(
"[HG SUITCASE INVENTORY SERVICE]: Unable to retrieve item {0} ({1}) in folder {2}",
408 item.Name, item.ID, item.Folder);
412 if (!IsWithinSuitcaseTree(it.
Owner, it.
Folder) && !IsPartOfAppearance(it.
Owner, it.
ID))
414 m_log.DebugFormat(
"[HG SUITCASE INVENTORY SERVICE]: GetItem: item {0}/{1} (folder {2}) (user {3}) is not within Suitcase tree or Appearance",
415 it.Name, it.ID, it.Folder, it.Owner);
435 if (!IsWithinSuitcaseTree(f.
Owner, f.
ID))
437 m_log.DebugFormat(
"[HG SUITCASE INVENTORY SERVICE]: GetFolder: folder {0}/{1} (user {2}) is not within Suitcase tree",
438 f.Name, f.ID, f.Owner);
454 #region Auxiliary functions
458 new string[] {
"agentID",
"folderID" },
459 new string[] { userID.ToString(), folderID.ToString() });
461 if (folders.Length == 0)
470 new string[] {
"agentID",
"folderName",
"type" },
473 if (folders != null && folders.Length > 0)
477 folders = m_Database.GetFolders(
478 new string[] {
"agentID",
"folderName",
"parentFolderID" },
481 if (folders != null && folders.Length > 0)
494 new string[] {
"agentID",
"type",
"parentFolderID" },
495 new string[] { userID.ToString(), ((
int)FolderType.CurrentOutfit).ToString(), root.folderID.ToString() });
497 if (folders.Length == 0)
507 new string[] {
"agentID",
"type" },
508 new string[] { principalID.ToString(), ((
int)FolderType.Suitcase).ToString() });
510 if (folders != null && folders.Length > 0)
514 folders = m_Database.GetFolders(
515 new
string[] {
"agentID",
"folderName",
"parentFolderID" },
517 if (folders != null && folders.Length > 0)
521 folders[0].parentFolderID = root.folderID;
522 folders[0].type = (int)FolderType.Suitcase;
523 m_Database.StoreFolder(folders[0]);
535 private List<XInventoryFolder> GetFolderTree(UUID principalID, UUID folder)
537 List<XInventoryFolder> t;
538 if (m_SuitcaseTrees.TryGetValue(principalID, out t))
542 t = GetFolderTreeRecursive(folder);
543 m_SuitcaseTrees.AddOrUpdate(principalID, t, 5*60);
547 private List<XInventoryFolder> GetFolderTreeRecursive(UUID root)
549 List<XInventoryFolder> tree =
new List<XInventoryFolder>();
551 new string[] {
"parentFolderID" },
552 new string[] { root.ToString() });
554 if (folders == null || folders.Length == 0)
563 tree.AddRange(GetFolderTreeRecursive(f.
folderID));
577 private bool IsWithinSuitcaseTree(UUID principalID, UUID folderID)
581 if (suitcase == null)
583 m_log.WarnFormat(
"[HG SUITCASE INVENTORY SERVICE]: User {0} does not have a Suitcase folder", principalID);
587 List<XInventoryFolder> tree =
new List<XInventoryFolder>();
589 tree.AddRange(GetFolderTree(principalID, suitcase.
folderID));
605 #region Avatar Appearance
610 if (m_Appearances.TryGetValue(principalID, out a))
613 a = m_AvatarService.GetAppearance(principalID);
614 m_Appearances.AddOrUpdate(principalID, a, 5 * 60);
618 private bool IsPartOfAppearance(UUID principalID, UUID itemID)
626 for (
int i = 0; i < a.Wearables.Length; i++)
628 for (
int j = 0; j < a.Wearables[i].Count; j++)
override List< InventoryItemBase > GetFolderItems(UUID principalID, UUID folderID)
Gets the items inside a folder
override bool MoveFolder(InventoryFolderBase folder)
Move an inventory folder to a new location
override List< InventoryFolderBase > GetInventorySkeleton(UUID principalID)
Gets the skeleton of the inventory – folders only
override bool MoveItems(UUID principalID, List< InventoryItemBase > items)
void CreateSystemFolders(UUID principalID, UUID rootID)
override bool AddFolder(InventoryFolderBase folder)
Add a new folder to the user's inventory
Contains the Avatar's Appearance and methods to manipulate the appearance.
override bool UpdateFolder(InventoryFolderBase folder)
Update a folder in the user's inventory
override bool AddItem(InventoryItemBase item)
Add a new item to the user's inventory
AvatarAttachment GetAttachmentForItem(UUID itemID)
If the item is already attached, return it.
virtual UUID Owner
The agent who's inventory this is contained by
static readonly string SUITCASE_FOLDER_NAME
override bool PurgeFolder(InventoryFolderBase folder)
Purge an inventory folder of all its items and subfolders.
override InventoryFolderBase GetFolderForType(UUID principalID, FolderType type)
Gets the user folder for the given folder-type
override bool CreateUserInventory(UUID principalID)
Create the entire inventory for a given user
Inventory Item - contains all the properties associated with an individual inventory piece...
new InventoryFolderBase GetFolder(InventoryFolderBase folder)
Get a folder, given by its UUID
virtual AvatarWearable[] Wearables
Hypergrid inventory service. It serves the IInventoryService interface, but implements it in ways tha...
UUID ID
A UUID containing the ID for the inventory node itself
override bool DeleteFolders(UUID principalID, List< UUID > folderIDs)
Delete an item from the user's inventory
override InventoryFolderBase GetRootFolder(UUID principalID)
Retrieve the root inventory folder for the given user.
HGSuitcaseInventoryService(IConfigSource config, string configName)
override InventoryCollection GetFolderContent(UUID principalID, UUID folderID)
Gets everything (folders and items) inside a folder
static readonly string ROOT_FOLDER_NAME
new InventoryItemBase GetItem(InventoryItemBase item)
Get an item, given by its UUID
override bool UpdateItem(InventoryItemBase item)
Update an item in the user's inventory
Used to serialize a whole inventory for transfer over the network.
override bool DeleteItems(UUID principalID, List< UUID > itemIDs)
Delete an item from the user's inventory