/// <summary> /// /// </summary> /// <returns></returns> protected virtual ArrayList GetLibraryOwner(InventoryFolderImpl libFolder) { //for now create random inventory library owner Hashtable TempHash = new Hashtable(); TempHash["agent_id"] = "11111111-1111-0000-0000-000100bba000"; // libFolder.Owner ArrayList inventoryLibOwner = new ArrayList(); inventoryLibOwner.Add(TempHash); return(inventoryLibOwner); }
/// <summary> /// /// </summary> /// <returns></returns> protected virtual ArrayList GetLibraryOwner(InventoryFolderImpl libFolder) { //for now create random inventory library owner Hashtable TempHash = new Hashtable(); TempHash["agent_id"] = Constants.m_MrOpenSimID.ToString(); // libFolder.Owner ArrayList inventoryLibOwner = new ArrayList(); inventoryLibOwner.Add(TempHash); return(inventoryLibOwner); }
/// <summary> /// Drop all cached inventory. /// </summary> public void DropInventory() { m_log.Debug("[INVENTORY CACHE]: DropInventory called"); // Make sure there aren't pending requests around when we do this // FIXME: There is still a race condition where an inventory operation can be requested (since these aren't being locked). // Will have to extend locking to exclude this very soon. lock (m_pendingRequests) { m_hasReceivedInventory = false; m_rootFolder = null; } }
/// <summary> /// Create a folder in this agent's inventory. /// </summary> /// /// If the inventory service has not yet delievered the inventory /// for this user then the request will be queued. /// /// <param name="parentID"></param> /// <returns></returns> public bool CreateFolder(string folderName, UUID folderID, ushort folderType, UUID parentID) { // m_log.DebugFormat( // "[AGENT INVENTORY]: Creating inventory folder {0} {1} for {2} {3}", folderID, folderName, remoteClient.Name, remoteClient.AgentId); if (m_hasReceivedInventory) { InventoryFolderImpl parentFolder = RootFolder.FindFolder(parentID); if (null == parentFolder) { m_log.WarnFormat( "[AGENT INVENTORY]: Tried to create folder {0} {1} but the parent {2} does not exist", folderName, folderID, parentID); return(false); } InventoryFolderImpl createdFolder = parentFolder.CreateChildFolder(folderID, folderName, folderType); if (createdFolder != null) { InventoryFolderBase createdBaseFolder = new InventoryFolderBase(); createdBaseFolder.Owner = createdFolder.Owner; createdBaseFolder.ID = createdFolder.ID; createdBaseFolder.Name = createdFolder.Name; createdBaseFolder.ParentID = createdFolder.ParentID; createdBaseFolder.Type = createdFolder.Type; createdBaseFolder.Version = createdFolder.Version; m_InventoryService.AddFolder(createdBaseFolder); return(true); } else { m_log.WarnFormat( "[AGENT INVENTORY]: Tried to create folder {0} {1} but the folder already exists", folderName, folderID); return(false); } } else { AddRequest( new InventoryRequest( Delegate.CreateDelegate(typeof(CreateFolderDelegate), this, "CreateFolder"), new object[] { folderName, folderID, folderType, parentID })); return(true); } }
// private void DumpLibrary() // { // InventoryFolderImpl lib = m_Library.LibraryRootFolder; // // m_log.DebugFormat(" - folder {0}", lib.Name); // DumpFolder(lib); // } // // private void DumpLibrary() // { // InventoryFolderImpl lib = m_Scene.CommsManager.UserProfileCacheService.LibraryRoot; // // m_log.DebugFormat(" - folder {0}", lib.Name); // DumpFolder(lib); // } private void DumpFolder(InventoryFolderImpl folder) { foreach (InventoryItemBase item in folder.Items.Values) { m_log.DebugFormat(" --> item {0}", item.Name); } foreach (InventoryFolderImpl f in folder.RequestListOfFolderImpls()) { m_log.DebugFormat(" - folder {0}", f.Name); DumpFolder(f); } }
/// <summary> /// Tell the client about the various child items and folders contained in the requested folder. /// </summary> /// <param name="remoteClient"></param> /// <param name="folderID"></param> /// <param name="ownerID"></param> /// <param name="fetchFolders"></param> /// <param name="fetchItems"></param> /// <param name="sortOrder"></param> public void HandleFetchInventoryDescendents(IClientAPI remoteClient, UUID folderID, UUID ownerID, bool fetchFolders, bool fetchItems, int sortOrder) { // m_log.DebugFormat( // "[USER INVENTORY]: HandleFetchInventoryDescendents() for {0}, folder={1}, fetchFolders={2}, fetchItems={3}, sortOrder={4}", // remoteClient.Name, folderID, fetchFolders, fetchItems, sortOrder); if (folderID == UUID.Zero) { return; } // FIXME MAYBE: We're not handling sortOrder! // TODO: This code for looking in the folder for the library should be folded somewhere else // so that this class doesn't have to know the details (and so that multiple libraries, etc. // can be handled transparently). InventoryFolderImpl fold = null; if (LibraryService != null && LibraryService.LibraryRootFolder != null) { if ((fold = LibraryService.LibraryRootFolder.FindFolder(folderID)) != null) { List <InventoryItemBase> its = fold.RequestListOfItems(); List <InventoryFolderBase> fds = fold.RequestListOfFolders(); remoteClient.SendInventoryFolderDetails( fold.Owner, folderID, its, fds, fold.Version, its.Count + fds.Count, fetchFolders, fetchItems); return; } } DescendentsRequestData req = new DescendentsRequestData(); req.RemoteClient = remoteClient; req.FolderID = folderID; //req.OwnerID = ownerID; req.FetchFolders = fetchFolders; req.FetchItems = fetchItems; //req.SortOrder = sortOrder; m_descendentsRequestQueue.Enqueue(req); if (Monitor.TryEnter(m_descendentsRequestLock)) { if (!m_descendentsRequestProcessing) { m_descendentsRequestProcessing = true; Util.FireAndForget(x => SendInventoryAsync()); } Monitor.Exit(m_descendentsRequestLock); } }
private List <InventoryFolderImpl> TraverseFolder(InventoryFolderImpl node) { List <InventoryFolderImpl> folders = node.RequestListOfFolderImpls(); List <InventoryFolderImpl> subs = new List <InventoryFolderImpl>(); foreach (InventoryFolderImpl f in folders) { subs.AddRange(TraverseFolder(f)); } folders.AddRange(subs); return(folders); }
/// <summary> /// Read a library inventory folder from a loaded configuration /// </summary> /// <param name="source"></param> private void ReadFolderFromConfig(IConfig config, string path) { InventoryFolderImpl folderInfo = new InventoryFolderImpl(); folderInfo.ID = new UUID(config.GetString("folderID", UUID.Random().ToString())); folderInfo.Name = config.GetString("name", "unknown"); folderInfo.ParentID = new UUID(config.GetString("parentFolderID", UUID.Zero.ToString())); folderInfo.Type = (short)config.GetInt("type", 8); folderInfo.Owner = m_service.LibraryOwner; folderInfo.Version = 1; m_inventoryService.AddFolder(folderInfo); }
/// <summary> /// Save an inventory folder /// </summary> /// <param name="inventoryFolder">The inventory folder to save</param> /// <param name="path">The path to which the folder should be saved</param> /// <param name="saveThisFolderItself">If true, save this folder itself. If false, only saves contents</param> protected void SaveInvFolder(InventoryFolderImpl inventoryFolder, string path, bool saveThisFolderItself) { if (saveThisFolderItself) { path += string.Format( "{0}{1}{2}/", inventoryFolder.Name, ArchiveConstants.INVENTORY_NODE_NAME_COMPONENT_SEPARATOR, inventoryFolder.ID); // We need to make sure that we record empty folders m_archiveWriter.WriteDir(path); } List <InventoryFolderImpl> childFolders = inventoryFolder.RequestListOfFolderImpls(); List <InventoryItemBase> items = inventoryFolder.RequestListOfItems(); /* * Dictionary identicalFolderNames = new Dictionary<string, int>(); * * foreach (InventoryFolderImpl folder in inventories) * { * * if (!identicalFolderNames.ContainsKey(folder.Name)) * identicalFolderNames[folder.Name] = 0; * else * identicalFolderNames[folder.Name] = identicalFolderNames[folder.Name]++; * * int folderNameNumber = identicalFolderName[folder.Name]; * * SaveInvDir( * folder, * string.Format( * "{0}{1}{2}/", * path, ArchiveConstants.INVENTORY_NODE_NAME_COMPONENT_SEPARATOR, folderNameNumber)); * } */ foreach (InventoryFolderImpl childFolder in childFolders) { SaveInvFolder(childFolder, path, true); } foreach (InventoryItemBase item in items) { SaveInvItem(item, path); } }
private void TraverseFolders(InventoryFolderImpl folderimp, UUID ID, IInventoryService InventoryService) { InventoryCollection col = InventoryService.GetFolderContent(LibraryOwner, ID); foreach (InventoryItemBase item in col.Items) { folderimp.Items.Add(item.ID, item); } foreach (InventoryFolderBase folder in col.Folders) { InventoryFolderImpl childFolder = new InventoryFolderImpl(folder); TraverseFolders(childFolder, folder.ID, InventoryService); folderimp.AddChildFolder(childFolder); } }
/// <summary> /// Helper function for InventoryReceive() - Store a folder temporarily until we've received entire folder list /// </summary> /// <param name="folder"></param> private void AddFolderToDictionary(InventoryFolderImpl folder, IDictionary <UUID, IList <InventoryFolderImpl> > dictionary) { UUID parentFolderId = folder.ParentID; if (dictionary.ContainsKey(parentFolderId)) { dictionary[parentFolderId].Add(folder); } else { IList <InventoryFolderImpl> folders = new List <InventoryFolderImpl>(); folders.Add(folder); dictionary[parentFolderId] = folders; } }
/// <summary> /// Handle an inventory folder move request from the client. /// /// If the inventory service has not yet delievered the inventory /// for this user then the request will be queued. /// </summary> /// /// <param name="folderID"></param> /// <param name="parentID"></param> /// <returns> /// true if the delete was successful, or if it was queued pending folder receipt /// false if the folder to be deleted did not exist. /// </returns> public bool MoveFolder(UUID folderID, UUID parentID) { // m_log.DebugFormat( // "[AGENT INVENTORY]: Moving inventory folder {0} into folder {1} for {2} {3}", // parentID, remoteClient.Name, remoteClient.Name, remoteClient.AgentId); if (m_hasReceivedInventory) { InventoryFolderBase baseFolder = new InventoryFolderBase(); baseFolder.Owner = m_userProfile.ID; baseFolder.ID = folderID; baseFolder.ParentID = parentID; m_InventoryService.MoveFolder(baseFolder); InventoryFolderImpl folder = RootFolder.FindFolder(folderID); InventoryFolderImpl parentFolder = RootFolder.FindFolder(parentID); if (parentFolder != null && folder != null) { InventoryFolderImpl oldParentFolder = RootFolder.FindFolder(folder.ParentID); if (oldParentFolder != null) { oldParentFolder.RemoveChildFolder(folderID); parentFolder.AddChildFolder(folder); } else { return(false); } } else { return(false); } return(true); } else { AddRequest( new InventoryRequest( Delegate.CreateDelegate(typeof(MoveFolderDelegate), this, "MoveFolder"), new object[] { folderID, parentID })); return(true); } }
/// <summary> /// Asynchronous inventory fetch. /// </summary> /// <param name="userID"></param> /// <param name="callback"></param> public void GetUserInventory(UUID userID, InventoryReceiptCallback callback) { m_log.InfoFormat("[INVENTORY SERVICE]: Requesting inventory for user {0}", userID); List <InventoryFolderImpl> folders = new List <InventoryFolderImpl>(); List <InventoryItemBase> items = new List <InventoryItemBase>(); List <InventoryFolderBase> skeletonFolders = GetInventorySkeleton(userID); if (skeletonFolders != null) { InventoryFolderImpl rootFolder = null; // Need to retrieve the root folder on the first pass foreach (InventoryFolderBase folder in skeletonFolders) { if (folder.ParentID == UUID.Zero) { rootFolder = new InventoryFolderImpl(folder); folders.Add(rootFolder); items.AddRange(GetFolderItems(userID, rootFolder.ID)); break; // Only 1 root folder per user } } if (rootFolder != null) { foreach (InventoryFolderBase folder in skeletonFolders) { if (folder.ID != rootFolder.ID) { folders.Add(new InventoryFolderImpl(folder)); items.AddRange(GetFolderItems(userID, folder.ID)); } } } m_log.InfoFormat( "[INVENTORY SERVICE]: Received inventory response for user {0} containing {1} folders and {2} items", userID, folders.Count, items.Count); } else { m_log.WarnFormat("[INVENTORY SERVICE]: User {0} inventory not available", userID); } Util.FireAndForget(delegate { callback(folders, items); }); }
public override void RequestInventoryForUser(UUID userID, InventoryReceiptCallback callback) { m_log.InfoFormat("[LOCAL INVENTORY SERVICE]: Requesting inventory for user {0}", userID); List <InventoryFolderBase> skeletonFolders = GetInventorySkeleton(userID); if (skeletonFolders == null) { return; } InventoryFolderImpl rootFolder = null; List <InventoryFolderImpl> folders = new List <InventoryFolderImpl>(); List <InventoryItemBase> items = new List <InventoryItemBase>(); // Need to retrieve the root folder on the first pass foreach (InventoryFolderBase folder in skeletonFolders) { if (folder.ParentID == UUID.Zero) { rootFolder = new InventoryFolderImpl(folder); folders.Add(rootFolder); items.AddRange(RequestFolderItems(rootFolder.ID)); break; // Only 1 root folder per user } } if (rootFolder != null) { foreach (InventoryFolderBase folder in skeletonFolders) { if (folder.ID != rootFolder.ID) { folders.Add(new InventoryFolderImpl(folder)); items.AddRange(RequestFolderItems(folder.ID)); } } } m_log.InfoFormat( "[LOCAL INVENTORY SERVICE]: Received inventory response for user {0} containing {1} folders and {2} items", userID, folders.Count, items.Count); callback(folders, items); }
/// <summary> /// Test replication of an archive path to the user's inventory. /// </summary> //[Test] public void TestReplicateArchivePathToUserInventory() { TestHelper.InMethod(); Scene scene = SceneSetupHelpers.SetupScene(false); CommunicationsManager commsManager = scene.CommsManager; CachedUserInfo userInfo = UserProfileTestUtils.CreateUserWithInventory(commsManager); userInfo.FetchInventory(); for (int i = 0; i < 50; i++) { if (userInfo.HasReceivedInventory == true) { break; } Thread.Sleep(200); } Assert.That(userInfo.HasReceivedInventory, Is.True, "FetchInventory timed out (10 seconds)"); Dictionary <string, InventoryFolderImpl> foldersCreated = new Dictionary <string, InventoryFolderImpl>(); List <InventoryNodeBase> nodesLoaded = new List <InventoryNodeBase>(); string folder1Name = "a"; string folder2Name = "b"; string itemName = "c.lsl"; string folder1ArchiveName = string.Format( "{0}{1}{2}", folder1Name, ArchiveConstants.INVENTORY_NODE_NAME_COMPONENT_SEPARATOR, UUID.Random()); string folder2ArchiveName = string.Format( "{0}{1}{2}", folder2Name, ArchiveConstants.INVENTORY_NODE_NAME_COMPONENT_SEPARATOR, UUID.Random()); string itemArchivePath = string.Format( "{0}{1}/{2}/{3}", ArchiveConstants.INVENTORY_PATH, folder1ArchiveName, folder2ArchiveName, itemName); new InventoryArchiveReadRequest(userInfo, null, (Stream)null, null, null) .ReplicateArchivePathToUserInventory(itemArchivePath, false, userInfo.RootFolder, foldersCreated, nodesLoaded); InventoryFolderImpl folder1 = userInfo.RootFolder.FindFolderByPath("a"); Assert.That(folder1, Is.Not.Null, "Could not find folder a"); InventoryFolderImpl folder2 = folder1.FindFolderByPath("b"); Assert.That(folder2, Is.Not.Null, "Could not find folder b"); }
/// <summary> /// Add a new item to the user's inventory /// </summary> /// <param name="item"></param> /// <returns>true if the item was successfully added</returns> public bool AddItem(InventoryItemBase item) { //m_log.DebugFormat("[LIBRARY MODULE]: Adding item {0} to {1}", item.Name, item.Folder); InventoryFolderImpl folder = m_Library; if (m_Library.ID != item.Folder) { folder = m_Library.FindFolder(item.Folder); } if (folder == null) { m_log.DebugFormat("[LIBRARY MODULE]: could not add item {0} because folder {1} not found", item.Name, item.Folder); return(false); } folder.Items.Add(item.ID, item); return(true); }
/// <summary> /// Read a library inventory item metadata from a loaded configuration /// </summary> /// <param name="source"></param> private void ReadItemFromConfig(IConfig config, string path) { InventoryItemBase item = new InventoryItemBase(); item.Owner = libOwner; item.CreatorId = libOwner.ToString(); UUID itID = new UUID(config.GetString("inventoryID", m_LibraryRootFolder.ID.ToString())); item.ID = itID; item.AssetID = new UUID(config.GetString("assetID", item.ID.ToString())); item.Folder = new UUID(config.GetString("folderID", m_LibraryRootFolder.ID.ToString())); item.Name = config.GetString("name", String.Empty); item.Description = config.GetString("description", item.Name); item.InvType = config.GetInt("inventoryType", 0); item.AssetType = config.GetInt("assetType", item.InvType); item.CurrentPermissions = (uint)config.GetLong("currentPermissions", m_CurrentPermissions); item.NextPermissions = (uint)config.GetLong("nextPermissions", m_NextPermissions); item.EveryOnePermissions = (uint)config.GetLong("everyonePermissions", m_EveryOnePermissions); item.BasePermissions = (uint)config.GetLong("basePermissions", m_BasePermissions); item.GroupPermissions = (uint)config.GetLong("basePermissions", m_GroupPermissions);; item.Flags = (uint)config.GetInt("flags", 0); if (libraryFolders.ContainsKey(item.Folder)) { InventoryFolderImpl parentFolder = libraryFolders[item.Folder]; if (!parentFolder.Items.ContainsKey(itID)) { parentFolder.Items.Add(itID, item); m_items[itID] = item; } else { m_log.WarnFormat("[LIBRARY INVENTORY] Item {1} [{0}] not added, duplicate item", item.ID, item.Name); } } else { m_log.WarnFormat( "[LIBRARY INVENTORY]: Couldn't add item {0} ({1}) since parent folder with ID {2} does not exist!", item.Name, item.ID, item.Folder); } }
/// <summary> /// Add a new folder to the user's inventory /// </summary> /// <param name="folder"></param> /// <returns>true if the folder was successfully added</returns> public bool AddFolder(InventoryFolderBase folder) { //m_log.DebugFormat("[LIBRARY MODULE]: Adding folder {0} ({1}) to {2}", folder.Name, folder.ID, folder.ParentID); InventoryFolderImpl parent = m_Library; if (m_Library.ID != folder.ParentID) { parent = m_Library.FindFolder(folder.ParentID); } if (parent == null) { m_log.DebugFormat("[LIBRARY MODULE]: could not add folder {0} because parent folder {1} not found", folder.Name, folder.ParentID); return(false); } parent.CreateChildFolder(folder.ID, folder.Name, (ushort)folder.Type); return(true); }
public void LoadLibrary(ILibraryService service, IConfigSource source, IRegistryCore registry) { m_service = service; m_inventoryService = registry.RequestModuleInterface <IInventoryService>(); m_folder = new InventoryFolderImpl(); IConfig libConfig = source.Configs["InventoryXMLLoader"]; string pLibrariesLocation = Path.Combine("inventory", "Libraries.xml"); if (libConfig != null) { if (libConfig.GetBoolean("PreviouslyLoaded", false)) { return; //If it is loaded, don't reload } pLibrariesLocation = libConfig.GetString("DefaultLibrary", pLibrariesLocation); LoadLibraries(pLibrariesLocation); m_service.AddToDefaultInventory(m_folder); } }
private void LoadPreviouslyLoadedArchives(IRegistryCore registry) { IUserAccountService UserAccountService = registry.RequestModuleInterface <IUserAccountService>(); UserAccount uinfo = UserAccountService.GetUserAccount(UUID.Zero, LibraryOwner); IInventoryService InventoryService = registry.RequestModuleInterface <IInventoryService>(); //Make the user account for the default IAR if (uinfo == null) { uinfo = new UserAccount(LibraryOwner); uinfo.Name = LibraryOwnerName; uinfo.Email = ""; uinfo.ServiceURLs = new Dictionary <string, object>(); uinfo.UserLevel = 0; uinfo.UserFlags = 0; uinfo.ScopeID = UUID.Zero; uinfo.UserTitle = ""; UserAccountService.StoreUserAccount(uinfo); InventoryService.CreateUserInventory(uinfo.PrincipalID); uinfo = UserAccountService.GetUserAccount(UUID.Zero, LibraryOwner); if (uinfo == null) { //Grid mode, can't create the user... leave return; } } InventoryCollection col = InventoryService.GetFolderContent(LibraryOwner, UUID.Zero); foreach (InventoryFolderBase folder in col.Folders) { if (folder.Name == "My Inventory") { continue; //Pass My Inventory by } InventoryFolderImpl f = new InventoryFolderImpl(folder); TraverseFolders(f, folder.ID, InventoryService); //This is our loaded folder AddToDefaultInventory(f); } }
public bool QueryFolder(InventoryFolderBase folder) { if (m_hasReceivedInventory) { InventoryFolderBase invFolder = RootFolder.FindFolder(folder.ID); if (invFolder != null) { // Folder is in local cache, just update client // return(true); } InventoryFolderBase folderInfo = null; folderInfo = m_InventoryService.QueryFolder(folder); if (folderInfo != null) { InventoryFolderImpl createdFolder = RootFolder.CreateChildFolder(folderInfo.ID, folderInfo.Name, (ushort)folderInfo.Type); createdFolder.Version = folderInfo.Version; createdFolder.Owner = folderInfo.Owner; createdFolder.ParentID = folderInfo.ParentID; return(true); } return(false); } else { AddRequest( new InventoryRequest( Delegate.CreateDelegate(typeof(QueryFolderDelegate), this, "QueryFolder"), new object[] { folder.ID })); return(true); } }
private void TraverseFolders(InventoryFolderImpl folderimp, UUID ID, Scene m_MockScene) { InventoryCollection col = m_MockScene.InventoryService.GetFolderContent(m_service.LibraryOwner, ID); foreach (InventoryItemBase item in col.Items) { folderimp.Items[item.ID] = item; } foreach (InventoryFolderBase folder in col.Folders) { InventoryFolderImpl childFolder = new InventoryFolderImpl(folder); foreach (KeyValuePair <String, AssetType> type in m_assetTypes) { if (childFolder.Name.ToLower().StartsWith(type.Key.ToLower())) { childFolder.Type = (short)type.Value; } } TraverseFolders(childFolder, folder.ID, m_MockScene); folderimp.AddChildFolder(childFolder); } }
/// <summary> /// This method will delete all the items and folders in the given folder. /// </summary> /// If the inventory service has not yet delievered the inventory /// for this user then the request will be queued. /// /// <param name="folderID"></param> public bool PurgeFolder(UUID folderID) { // m_log.InfoFormat("[AGENT INVENTORY]: Purging folder {0} for {1} uuid {2}", // folderID, remoteClient.Name, remoteClient.AgentId); if (m_hasReceivedInventory) { InventoryFolderImpl purgedFolder = RootFolder.FindFolder(folderID); if (purgedFolder != null) { // XXX Nasty - have to create a new object to hold details we already have InventoryFolderBase purgedBaseFolder = new InventoryFolderBase(); purgedBaseFolder.Owner = purgedFolder.Owner; purgedBaseFolder.ID = purgedFolder.ID; purgedBaseFolder.Name = purgedFolder.Name; purgedBaseFolder.ParentID = purgedFolder.ParentID; purgedBaseFolder.Type = purgedFolder.Type; purgedBaseFolder.Version = purgedFolder.Version; m_InventoryService.PurgeFolder(purgedBaseFolder); purgedFolder.Purge(); return(true); } } else { AddRequest( new InventoryRequest( Delegate.CreateDelegate(typeof(PurgeFolderDelegate), this, "PurgeFolder"), new object[] { folderID })); return(true); } return(false); }
/// <summary> /// Recursively, in depth-first order, add all the folders we've received (stored /// in a dictionary indexed by parent ID) into the tree that describes user folder /// heirarchy /// Any folder that is resolved into the tree is also added to resolvedFolderDictionary, /// indexed by folder ID. /// </summary> /// <param name="parentId"> /// A <see cref="UUID"/> /// </param> private void ResolveReceivedFolders(InventoryFolderImpl parentFolder, IDictionary <UUID, IList <InventoryFolderImpl> > receivedFolderDictionary, IDictionary <UUID, InventoryFolderImpl> resolvedFolderDictionary) { if (receivedFolderDictionary.ContainsKey(parentFolder.ID)) { List <InventoryFolderImpl> resolvedFolders = new List <InventoryFolderImpl>(); // Folders we've resolved with this invocation foreach (InventoryFolderImpl folder in receivedFolderDictionary[parentFolder.ID]) { if (parentFolder.ContainsChildFolder(folder.ID)) { m_log.WarnFormat( "[INVENTORY CACHE]: Received folder {0} {1} from inventory service which has already been received", folder.Name, folder.ID); } else { if (resolvedFolderDictionary.ContainsKey(folder.ID)) { m_log.WarnFormat( "[INVENTORY CACHE]: Received folder {0} {1} from inventory service has already been received but with different parent", folder.Name, folder.ID); } else { resolvedFolders.Add(folder); resolvedFolderDictionary[folder.ID] = folder; parentFolder.AddChildFolder(folder); } } } // foreach (folder in pendingCategorizationFolders[parentFolder.ID]) receivedFolderDictionary.Remove(parentFolder.ID); foreach (InventoryFolderImpl folder in resolvedFolders) { ResolveReceivedFolders(folder, receivedFolderDictionary, resolvedFolderDictionary); } } // if (receivedFolderDictionary.ContainsKey(parentFolder.ID)) }
/// <summary> /// Add the folders to the user's inventory /// </summary> /// <param name="m_MockScene"></param> /// <param name="folder"></param> private void BuildInventoryFolder(Scene m_MockScene, InventoryFolderImpl folder) { InventoryFolderBase folderBase = new InventoryFolderBase(); folderBase.ID = folder.ID; folderBase.Name = folder.Name; folderBase.Owner = folder.Owner; folderBase.ParentID = folder.ParentID; folderBase.Type = folder.Type; folderBase.Version = folder.Version; m_MockScene.InventoryService.AddFolder(folderBase); foreach (InventoryFolderImpl childFolder in folder.RequestListOfFolderImpls()) { BuildInventoryFolder(m_MockScene, childFolder); } foreach (InventoryItemBase item in folder.RequestListOfItems()) { m_MockScene.InventoryService.AddItem(item); } }
/// <summary> /// Handle a client request to update the inventory folder /// </summary> /// /// If the inventory service has not yet delievered the inventory /// for this user then the request will be queued. /// /// FIXME: We call add new inventory folder because in the data layer, we happen to use an SQL REPLACE /// so this will work to rename an existing folder. Needless to say, to rely on this is very confusing, /// and needs to be changed. /// /// <param name="folderID"></param> /// <param name="type"></param> /// <param name="name"></param> /// <param name="parentID"></param> public bool UpdateFolder(string name, UUID folderID, ushort type, UUID parentID) { // m_log.DebugFormat( // "[AGENT INVENTORY]: Updating inventory folder {0} {1} for {2} {3}", folderID, name, remoteClient.Name, remoteClient.AgentId); if (m_hasReceivedInventory) { InventoryFolderImpl folder = RootFolder.FindFolder(folderID); // Delegate movement if updated parent id isn't the same as the existing parentId if (folder.ParentID != parentID) { MoveFolder(folderID, parentID); } InventoryFolderBase baseFolder = new InventoryFolderBase(); baseFolder.Owner = m_userProfile.ID; baseFolder.ID = folderID; baseFolder.Name = name; baseFolder.ParentID = parentID; baseFolder.Type = (short)type; baseFolder.Version = RootFolder.Version; m_InventoryService.UpdateFolder(baseFolder); folder.Name = name; folder.Type = (short)type; } else { AddRequest( new InventoryRequest( Delegate.CreateDelegate(typeof(UpdateFolderDelegate), this, "UpdateFolder"), new object[] { name, folderID, type, parentID })); } return(true); }
/// <summary> /// Tell the client about the various child items and folders contained in the requested folder. /// </summary> /// <param name="remoteClient"></param> /// <param name="folderID"></param> /// <param name="ownerID"></param> /// <param name="fetchFolders"></param> /// <param name="fetchItems"></param> /// <param name="sortOrder"></param> public void HandleFetchInventoryDescendents(IClientAPI remoteClient, UUID folderID, UUID ownerID, bool fetchFolders, bool fetchItems, int sortOrder) { // m_log.DebugFormat( // "[USER INVENTORY]: HandleFetchInventoryDescendents() for {0}, folder={1}, fetchFolders={2}, fetchItems={3}, sortOrder={4}", // remoteClient.Name, folderID, fetchFolders, fetchItems, sortOrder); if (folderID == UUID.Zero) { return; } // FIXME MAYBE: We're not handling sortOrder! // TODO: This code for looking in the folder for the library should be folded somewhere else // so that this class doesn't have to know the details (and so that multiple libraries, etc. // can be handled transparently). InventoryFolderImpl fold = null; if (LibraryService != null && LibraryService.LibraryRootFolder != null) { if ((fold = LibraryService.LibraryRootFolder.FindFolder(folderID)) != null) { remoteClient.SendInventoryFolderDetails( fold.Owner, folderID, fold.RequestListOfItems(), fold.RequestListOfFolders(), fold.Version, fetchFolders, fetchItems); return; } } // We're going to send the reply async, because there may be // an enormous quantity of packets -- basically the entire inventory! // We don't want to block the client thread while all that is happening. SendInventoryDelegate d = SendInventoryAsync; d.BeginInvoke(remoteClient, folderID, ownerID, fetchFolders, fetchItems, sortOrder, SendInventoryComplete, d); }
public LibraryService(IConfigSource config) : base(config) { lock (m_rootLock) { if (m_root != null) { return; } m_root = this; } string pLibrariesLocation = Path.Combine("inventory", "Libraries.xml"); string pLibName = "OpenSim Library"; IConfig libConfig = config.Configs["LibraryService"]; if (libConfig != null) { pLibrariesLocation = libConfig.GetString("DefaultLibrary", pLibrariesLocation); pLibName = libConfig.GetString("LibraryName", pLibName); } m_log.Debug("[LIBRARY]: Starting library service..."); m_LibraryRootFolder = new InventoryFolderImpl(); m_LibraryRootFolder.Owner = libOwner; m_LibraryRootFolder.ID = new UUID("00000112-000f-0000-0000-000100bba000"); m_LibraryRootFolder.Name = pLibName; m_LibraryRootFolder.ParentID = UUID.Zero; m_LibraryRootFolder.Type = 8; m_LibraryRootFolder.Version = 1; libraryFolders.Add(m_LibraryRootFolder.ID, m_LibraryRootFolder); LoadLibraries(pLibrariesLocation); }
// Load additional items that other regions have put into the database // The item will be added tot he local cache. Returns true if the item // was found and can be sent to the client // public bool QueryItem(InventoryItemBase item) { if (m_hasReceivedInventory) { InventoryItemBase invItem = RootFolder.FindItem(item.ID); if (invItem != null) { // Item is in local cache, just update client // return(true); } InventoryItemBase itemInfo = null; itemInfo = m_InventoryService.QueryItem(item); if (itemInfo != null) { InventoryFolderImpl folder = RootFolder.FindFolder(itemInfo.Folder); ItemReceive(itemInfo, folder); return(true); } return(false); } else { AddRequest( new InventoryRequest( Delegate.CreateDelegate(typeof(QueryItemDelegate), this, "QueryItem"), new object[] { item.ID })); return(true); } }
/// <summary> /// Recursively, in depth-first order, add all the folders we've received (stored /// in a dictionary indexed by parent ID) into the tree that describes user folder /// heirarchy /// Any folder that is resolved into the tree is also added to resolvedFolderDictionary, /// indexed by folder ID. /// </summary> /// <param name="parentId"> /// A <see cref="UUID"/> /// </param> private void ResolveReceivedFolders(InventoryFolderImpl parentFolder, IDictionary<UUID, IList<InventoryFolderImpl>> receivedFolderDictionary, IDictionary<UUID, InventoryFolderImpl> resolvedFolderDictionary) { if (receivedFolderDictionary.ContainsKey(parentFolder.ID)) { List<InventoryFolderImpl> resolvedFolders = new List<InventoryFolderImpl>(); // Folders we've resolved with this invocation foreach (InventoryFolderImpl folder in receivedFolderDictionary[parentFolder.ID]) { if (parentFolder.ContainsChildFolder(folder.ID)) { m_log.WarnFormat( "[INVENTORY CACHE]: Received folder {0} {1} from inventory service which has already been received", folder.Name, folder.ID); } else { if (resolvedFolderDictionary.ContainsKey(folder.ID)) { m_log.WarnFormat( "[INVENTORY CACHE]: Received folder {0} {1} from inventory service has already been received but with different parent", folder.Name, folder.ID); } else { resolvedFolders.Add(folder); resolvedFolderDictionary[folder.ID] = folder; parentFolder.AddChildFolder(folder); } } } // foreach (folder in pendingCategorizationFolders[parentFolder.ID]) receivedFolderDictionary.Remove(parentFolder.ID); foreach (InventoryFolderImpl folder in resolvedFolders) ResolveReceivedFolders(folder, receivedFolderDictionary, resolvedFolderDictionary); } // if (receivedFolderDictionary.ContainsKey(parentFolder.ID)) }
/// <summary> /// Read a library inventory folder from a loaded configuration /// </summary> /// <param name="source"></param> private void ReadFolderFromConfig(IConfig config, string path) { InventoryFolderImpl folderInfo = new InventoryFolderImpl(); folderInfo.ID = new UUID(config.GetString("folderID", UUID.Random().ToString())); folderInfo.Name = config.GetString("name", "unknown"); folderInfo.ParentID = new UUID (config.GetString ("parentFolderID", UUID.Zero.ToString ())); folderInfo.Type = (short)config.GetInt("type", 8); folderInfo.Owner = m_service.LibraryOwner; folderInfo.Version = 1; m_inventoryService.AddFolder(folderInfo); }
/// <summary> /// Read a library inventory folder from a loaded configuration /// </summary> /// <param name="source"></param> private void ReadFolderFromConfig(IConfig config, string path) { InventoryFolderImpl folderInfo = new InventoryFolderImpl(); folderInfo.ID = new UUID(config.GetString("folderID", ID.ToString())); folderInfo.Name = config.GetString("name", "unknown"); folderInfo.ParentID = new UUID(config.GetString("parentFolderID", ID.ToString())); folderInfo.Type = (short)config.GetInt("type", 8); folderInfo.Owner = libOwner; folderInfo.Version = 1; if (libraryFolders.ContainsKey(folderInfo.ParentID)) { InventoryFolderImpl parentFolder = libraryFolders[folderInfo.ParentID]; libraryFolders.Add(folderInfo.ID, folderInfo); parentFolder.AddChildFolder(folderInfo); // m_log.InfoFormat("[LIBRARY INVENTORY]: Adding folder {0} ({1})", folderInfo.name, folderInfo.folderID); } else { m_log.WarnFormat( "[LIBRARY INVENTORY]: Couldn't add folder {0} ({1}) since parent folder with ID {2} does not exist!", folderInfo.Name, folderInfo.ID, folderInfo.ParentID); } }
/// <summary> /// Callback invoked when an item is received from an async request to the inventory service. /// /// We're assuming here that items are always received after all the folders /// received. /// If folder is null, we will search for it starting from RootFolder (an O(n) operation), /// otherwise we'll just put it into folder /// </summary> /// <param name="folderInfo"></param> private void ItemReceive(InventoryItemBase itemInfo, InventoryFolderImpl folder) { if (OnItemReceived != null) OnItemReceived(itemInfo.ID); }
/// <summary> /// Helper function for InventoryReceive() - Store a folder temporarily until we've received entire folder list /// </summary> /// <param name="folder"></param> private void AddFolderToDictionary(InventoryFolderImpl folder, IDictionary<UUID, IList<InventoryFolderImpl>> dictionary) { UUID parentFolderId = folder.ParentID; if (dictionary.ContainsKey(parentFolderId)) { dictionary[parentFolderId].Add(folder); } else { IList<InventoryFolderImpl> folders = new List<InventoryFolderImpl>(); folders.Add(folder); dictionary[parentFolderId] = folders; } }
/// <summary> /// Callback invoked when the inventory is received from an async request to the inventory service /// </summary> /// <param name="userID"></param> /// <param name="inventoryCollection"></param> public void InventoryReceive(ICollection <InventoryFolderImpl> folders, ICollection <InventoryItemBase> items) { // FIXME: Exceptions thrown upwards never appear on the console. Could fix further up if these // are simply being swallowed try { // collection of all received folders, indexed by their parent ID IDictionary <UUID, IList <InventoryFolderImpl> > receivedFolders = new Dictionary <UUID, IList <InventoryFolderImpl> >(); // collection of all folders that have been placed into the folder heirarchy starting at m_rootFolder // This dictonary exists so we don't have to do an InventoryFolderImpl.FindFolder(), which is O(n) on the // number of folders in our inventory. // Maybe we should make this structure a member so we can skip InventoryFolderImpl.FindFolder() calls later too? IDictionary <UUID, InventoryFolderImpl> resolvedFolders = new Dictionary <UUID, InventoryFolderImpl>(); // Take all received folders, find the root folder, and put ther rest into // the pendingCategorizationFolders collection foreach (InventoryFolderImpl folder in folders) { AddFolderToDictionary(folder, receivedFolders); } if (!receivedFolders.ContainsKey(UUID.Zero)) { throw new Exception("Database did not return a root inventory folder"); } else { IList <InventoryFolderImpl> rootFolderList = receivedFolders[UUID.Zero]; m_rootFolder = rootFolderList[0]; resolvedFolders[m_rootFolder.ID] = m_rootFolder; if (rootFolderList.Count > 1) { for (int i = 1; i < rootFolderList.Count; i++) { m_log.WarnFormat( "[INVENTORY CACHE]: Discarding extra root folder {0}. Using previously received root folder {1}", rootFolderList[i].ID, RootFolder.ID); } } receivedFolders.Remove(UUID.Zero); } // Now take the pendingCategorizationFolders collection, and turn that into a tree, // with the root being RootFolder if (RootFolder != null) { ResolveReceivedFolders(RootFolder, receivedFolders, resolvedFolders); } // Generate a warning for folders that are not part of the heirarchy foreach (KeyValuePair <UUID, IList <InventoryFolderImpl> > folderList in receivedFolders) { foreach (InventoryFolderImpl folder in folderList.Value) { m_log.WarnFormat("[INVENTORY CACHE]: Malformed Database: Unresolved Pending Folder {0}", folder.Name); } } // Take all ther received items and put them into the folder tree heirarchy foreach (InventoryItemBase item in items) { InventoryFolderImpl folder = resolvedFolders.ContainsKey(item.Folder) ? resolvedFolders[item.Folder] : null; ItemReceive(item, folder); } } catch (Exception e) { m_log.ErrorFormat("[INVENTORY CACHE]: Error processing inventory received from inventory service, {0}", e); } // Deal with pending requests lock (m_pendingRequests) { // We're going to change inventory status within the lock to avoid a race condition // where requests are processed after the AddRequest() method has been called. m_hasReceivedInventory = true; foreach (IInventoryRequest request in m_pendingRequests) { request.Execute(); } } }
/// <summary> /// Constructor /// </summary> /// <param name="commsManager"></param> /// <param name="libraryRootFolder"></param> public UserProfileCacheService(CommunicationsManager commsManager, LibraryRootFolder libraryRootFolder) { m_commsManager = commsManager; LibraryRoot = libraryRootFolder; }
/// <summary> /// Callback invoked when an item is received from an async request to the inventory service. /// /// We're assuming here that items are always received after all the folders /// received. /// If folder is null, we will search for it starting from RootFolder (an O(n) operation), /// otherwise we'll just put it into folder /// </summary> /// <param name="folderInfo"></param> private void ItemReceive(InventoryItemBase itemInfo, InventoryFolderImpl folder) { // m_log.DebugFormat( // "[INVENTORY CACHE]: Received item {0} {1} for user {2}", // itemInfo.Name, itemInfo.ID, userID); if (folder == null && RootFolder != null) folder = RootFolder.FindFolder(itemInfo.Folder); if (null == folder) { m_log.WarnFormat( "Received item {0} {1} but its folder {2} does not exist", itemInfo.Name, itemInfo.ID, itemInfo.Folder); return; } lock (folder.Items) { folder.Items[itemInfo.ID] = itemInfo; } if (OnItemReceived != null) OnItemReceived(itemInfo.ID); }
/// <summary> /// Constructor /// </summary> /// <param name="serversInfo"></param> /// <param name="httpServer"></param> /// <param name="assetCache"></param> public CommunicationsManager(NetworkServersInfo serversInfo, IHttpServer httpServer, IAssetCache assetCache, LibraryRootFolder libraryRootFolder) { m_networkServersInfo = serversInfo; m_assetCache = assetCache; m_httpServer = httpServer; LibraryRoot = libraryRootFolder; Preload(); }
/// <summary> /// Callback invoked when an item is received from an async request to the inventory service. /// /// We're assuming here that items are always received after all the folders /// received. /// If folder is null, we will search for it starting from RootFolder (an O(n) operation), /// otherwise we'll just put it into folder /// </summary> /// <param name="folderInfo"></param> private void ItemReceive(InventoryItemBase itemInfo, InventoryFolderImpl folder) { // m_log.DebugFormat( // "[INVENTORY CACHE]: Received item {0} {1} for user {2}", // itemInfo.Name, itemInfo.ID, userID); if (folder == null && RootFolder != null) folder = RootFolder.FindFolder(itemInfo.Folder); if (null == folder) { m_log.WarnFormat( "Received item {0} {1} but its folder {2} does not exist", itemInfo.Name, itemInfo.ID, itemInfo.Folder); return; } lock (folder.Items) { folder.Items[itemInfo.ID] = itemInfo; } try { if (OnItemReceived != null) OnItemReceived(itemInfo.ID); } catch (Exception e) { m_log.ErrorFormat("[INVENTORY CACHE]: failed processing callbacks on inventory item {0}, {1}", itemInfo.AssetID.ToString(), e.ToString()); } }
/// <summary> /// Callback invoked when the inventory is received from an async request to the inventory service /// </summary> /// <param name="userID"></param> /// <param name="inventoryCollection"></param> public void InventoryReceive(ICollection<InventoryFolderImpl> folders, ICollection<InventoryItemBase> items) { // FIXME: Exceptions thrown upwards never appear on the console. Could fix further up if these // are simply being swallowed try { // collection of all received folders, indexed by their parent ID IDictionary<UUID, IList<InventoryFolderImpl>> receivedFolders = new Dictionary<UUID, IList<InventoryFolderImpl>>(); // collection of all folders that have been placed into the folder heirarchy starting at m_rootFolder // This dictonary exists so we don't have to do an InventoryFolderImpl.FindFolder(), which is O(n) on the // number of folders in our inventory. // Maybe we should make this structure a member so we can skip InventoryFolderImpl.FindFolder() calls later too? IDictionary<UUID, InventoryFolderImpl> resolvedFolders = new Dictionary<UUID, InventoryFolderImpl>(); // Take all received folders, find the root folder, and put ther rest into // the pendingCategorizationFolders collection foreach (InventoryFolderImpl folder in folders) AddFolderToDictionary(folder, receivedFolders); if (!receivedFolders.ContainsKey(UUID.Zero)) throw new Exception("Database did not return a root inventory folder"); else { IList<InventoryFolderImpl> rootFolderList = receivedFolders[UUID.Zero]; m_rootFolder = rootFolderList[0]; resolvedFolders[m_rootFolder.ID] = m_rootFolder; if (rootFolderList.Count > 1) { for (int i = 1; i < rootFolderList.Count; i++) { m_log.WarnFormat( "[INVENTORY CACHE]: Discarding extra root folder {0}. Using previously received root folder {1}", rootFolderList[i].ID, RootFolder.ID); } } receivedFolders.Remove(UUID.Zero); } // Now take the pendingCategorizationFolders collection, and turn that into a tree, // with the root being RootFolder if (RootFolder != null) ResolveReceivedFolders(RootFolder, receivedFolders, resolvedFolders); // Generate a warning for folders that are not part of the heirarchy foreach (KeyValuePair<UUID, IList<InventoryFolderImpl>> folderList in receivedFolders) { foreach (InventoryFolderImpl folder in folderList.Value) m_log.WarnFormat("[INVENTORY CACHE]: Malformed Database: Unresolved Pending Folder {0}", folder.Name); } // Take all ther received items and put them into the folder tree heirarchy foreach (InventoryItemBase item in items) { InventoryFolderImpl folder = resolvedFolders.ContainsKey(item.Folder) ? resolvedFolders[item.Folder] : null; ItemReceive(item, folder); } } catch (Exception e) { m_log.ErrorFormat("[INVENTORY CACHE]: Error processing inventory received from inventory service, {0}", e); } // Deal with pending requests lock (m_pendingRequests) { // We're going to change inventory status within the lock to avoid a race condition // where requests are processed after the AddRequest() method has been called. m_hasReceivedInventory = true; foreach (IInventoryRequest request in m_pendingRequests) { request.Execute(); } } if (OnInventoryReceived != null) OnInventoryReceived(UserProfile.ID); }