/// <summary> /// Load an item from the archive /// </summary> /// <param name="filePath">The archive path for the item</param> /// <param name="data">The raw item data</param> /// <param name="rootDestinationFolder">The root destination folder for loaded items</param> /// <param name="nodesLoaded">All the inventory nodes (items and folders) loaded so far</param> protected InventoryItemBase LoadItem(byte[] data, InventoryFolderBase loadFolder) { InventoryItemBase item = UserInventoryItemSerializer.Deserialize(data); // Don't use the item ID that's in the file item.ID = UUID.Random(); UUID ospResolvedId = OspResolver.ResolveOspa(item.CreatorId, m_registry.RequestModuleInterface <IUserAccountService>()); if (UUID.Zero != ospResolvedId) { item.CreatorIdAsUuid = ospResolvedId; // XXX: For now, don't preserve the OSPA in the creator id (which actually gets persisted to the // database). Instead, replace with the UUID that we found. item.CreatorId = ospResolvedId.ToString(); } else { item.CreatorIdAsUuid = m_userInfo.PrincipalID; } item.Owner = m_userInfo.PrincipalID; // Reset folder ID to the one in which we want to load it item.Folder = loadFolder.ID; AddInventoryItem(item); return(item); }
/// <summary> /// Load an item from the archive /// </summary> /// <param name="filePath">The archive path for the item</param> /// <param name="data">The raw item data</param> /// <param name="rootDestinationFolder">The root destination folder for loaded items</param> /// <param name="nodesLoaded">All the inventory nodes (items and folders) loaded so far</param> protected InventoryItemBase LoadItem(byte[] data, InventoryFolderBase loadFolder) { InventoryItemBase item = UserInventoryItemSerializer.Deserialize(data); UUID oldID = item.ID; // Don't use the item ID that's in the file item.ID = UUID.Random(); m_itemIDs[oldID] = item.ID; UUID ospResolvedId = OspResolver.ResolveOspa(item.CreatorId, m_UserAccountService); if (UUID.Zero != ospResolvedId) // The user exists in this grid { // m_log.DebugFormat("[INVENTORY ARCHIVER]: Found creator {0} via OSPA resolution", ospResolvedId); // item.CreatorIdAsUuid = ospResolvedId; // Don't preserve the OSPA in the creator id (which actually gets persisted to the // database). Instead, replace with the UUID that we found. item.CreatorId = ospResolvedId.ToString(); item.CreatorData = string.Empty; } else if (string.IsNullOrEmpty(item.CreatorData)) { item.CreatorId = m_userInfo.PrincipalID.ToString(); } item.Owner = m_userInfo.PrincipalID; // Reset folder ID to the one in which we want to load it item.Folder = loadFolder.ID; // Record the creator id for the item's asset so that we can use it later, if necessary, when the asset // is loaded. // FIXME: This relies on the items coming before the assets in the TAR file. Need to create stronger // checks for this, and maybe even an external tool for creating OARs which enforces this, rather than // relying on native tar tools. if (item.AssetType == (int)AssetType.Link) { m_invLinks.Add(item); if (!m_loadedNodes.ContainsKey(item.Folder) && !m_invLinksFolders.ContainsKey(item.Folder)) { m_invLinksFolders[item.Folder] = loadFolder; } return(null); } else { m_creatorIdForAssetId[item.AssetID] = item.CreatorIdAsUuid; if (!m_InventoryService.AddItem(item)) { m_log.WarnFormat("[INVENTORY ARCHIVER]: Unable to save item {0} in folder {1}", item.Name, item.Folder); } } return(item); }
/// <summary> /// Load an item from the archive /// </summary> /// <param name="filePath">The archive path for the item</param> /// <param name="data">The raw item data</param> /// <param name="rootDestinationFolder">The root destination folder for loaded items</param> /// <param name="nodesLoaded">All the inventory nodes (items and folders) loaded so far</param> protected InventoryItemBase LoadItem(byte[] data, InventoryFolderBase loadFolder) { InventoryItemBase item = UserInventoryItemSerializer.Deserialize(data); // Don't use the item ID that's in the file item.ID = UUID.Random(); UUID ospResolvedId = OspResolver.ResolveOspa(item.CreatorId, m_scene.UserAccountService); if (UUID.Zero != ospResolvedId) // The user exists in this grid { // m_log.DebugFormat("[INVENTORY ARCHIVER]: Found creator {0} via OSPA resolution", ospResolvedId); item.CreatorIdAsUuid = ospResolvedId; // Don't preserve the OSPA in the creator id (which actually gets persisted to the // database). Instead, replace with the UUID that we found. item.CreatorId = ospResolvedId.ToString(); item.CreatorData = string.Empty; } else if (item.CreatorData == null || item.CreatorData == String.Empty) { item.CreatorId = m_userInfo.PrincipalID.ToString(); item.CreatorIdAsUuid = new UUID(item.CreatorId); } item.Owner = m_userInfo.PrincipalID; // Reset folder ID to the one in which we want to load it item.Folder = loadFolder.ID; // Record the creator id for the item's asset so that we can use it later, if necessary, when the asset // is loaded. // FIXME: This relies on the items coming before the assets in the TAR file. Need to create stronger // checks for this, and maybe even an external tool for creating OARs which enforces this, rather than // relying on native tar tools. m_creatorIdForAssetId[item.AssetID] = item.CreatorIdAsUuid; m_scene.AddInventoryItem(item); return(item); }
/// <summary> /// Execute the request /// </summary> /// <returns> /// A list of the inventory nodes loaded. If folders were loaded then only the root folders are /// returned /// </returns> public List <InventoryNodeBase> Execute() { string filePath = "ERROR"; int successfulAssetRestores = 0; int failedAssetRestores = 0; int successfulItemRestores = 0; List <InventoryNodeBase> nodesLoaded = new List <InventoryNodeBase>(); if (!m_userInfo.HasReceivedInventory) { // If the region server has access to the user admin service (by which users are created), // then we'll assume that it's okay to fiddle with the user's inventory even if they are not on the // server. // // FIXME: FetchInventory should probably be assumed to by async anyway, since even standalones might // use a remote inventory service, though this is vanishingly rare at the moment. if (null == m_commsManager.UserAdminService) { m_log.ErrorFormat( "[INVENTORY ARCHIVER]: Have not yet received inventory info for user {0} {1}", m_userInfo.UserProfile.Name, m_userInfo.UserProfile.ID); return(nodesLoaded); } else { m_userInfo.FetchInventory(); } } InventoryFolderImpl rootDestinationFolder = m_userInfo.RootFolder.FindFolderByPath(m_invPath); if (null == rootDestinationFolder) { // Possibly provide an option later on to automatically create this folder if it does not exist m_log.ErrorFormat("[INVENTORY ARCHIVER]: Inventory path {0} does not exist", m_invPath); return(nodesLoaded); } archive = new TarArchiveReader(m_loadStream); // In order to load identically named folders, we need to keep track of the folders that we have already // created Dictionary <string, InventoryFolderImpl> foldersCreated = new Dictionary <string, InventoryFolderImpl>(); byte[] data; TarArchiveReader.TarEntryType entryType; while ((data = archive.ReadEntry(out filePath, out entryType)) != null) { if (filePath.StartsWith(ArchiveConstants.ASSETS_PATH)) { if (LoadAsset(filePath, data)) { successfulAssetRestores++; } else { failedAssetRestores++; } } else if (filePath.StartsWith(ArchiveConstants.INVENTORY_PATH)) { InventoryFolderImpl foundFolder = ReplicateArchivePathToUserInventory( filePath, TarArchiveReader.TarEntryType.TYPE_DIRECTORY == entryType, rootDestinationFolder, foldersCreated, nodesLoaded); if (TarArchiveReader.TarEntryType.TYPE_DIRECTORY != entryType) { InventoryItemBase item = UserInventoryItemSerializer.Deserialize(data); // Don't use the item ID that's in the file item.ID = UUID.Random(); UUID ospResolvedId = OspResolver.ResolveOspa(item.CreatorId, m_commsManager); if (UUID.Zero != ospResolvedId) { item.CreatorIdAsUuid = ospResolvedId; } item.Owner = m_userInfo.UserProfile.ID; // Reset folder ID to the one in which we want to load it item.Folder = foundFolder.ID; m_userInfo.AddItem(item); successfulItemRestores++; // If we're loading an item directly into the given destination folder then we need to record // it separately from any loaded root folders if (rootDestinationFolder == foundFolder) { nodesLoaded.Add(item); } } } } archive.Close(); m_log.DebugFormat("[INVENTORY ARCHIVER]: Restored {0} assets", successfulAssetRestores); m_log.InfoFormat("[INVENTORY ARCHIVER]: Restored {0} items", successfulItemRestores); return(nodesLoaded); }