From e3f804e1d816910c1f144cce82a51e9b7622fc3c Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Fri, 26 Jan 2018 16:18:45 +0000 Subject: try fix IAR load inventory links and objects owner --- .../Archiver/InventoryArchiveReadRequest.cs | 147 +++++++++++++-------- .../Inventory/Archiver/InventoryArchiverModule.cs | 4 +- .../Tests/InventoryArchiveLoadPathTests.cs | 6 +- .../CoreModules/Framework/Library/LibraryModule.cs | 4 +- 4 files changed, 100 insertions(+), 61 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs index 3838316..1e21b74 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs @@ -109,7 +109,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver /// /// Inventory nodes loaded from the iar. /// - protected HashSet m_loadedNodes = new HashSet(); + protected Dictionary m_loadedNodes = new Dictionary(); /// /// In order to load identically named folders, we need to keep track of the folders that we have already @@ -122,6 +122,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver /// after OSP resolution (since OSP creators are only stored in the item /// protected Dictionary m_creatorIdForAssetId = new Dictionary(); + protected Dictionary m_itemIDs = new Dictionary(); + protected List m_invLinks = new List(); + protected Dictionary m_invLinksFolders = new Dictionary(); public InventoryArchiveReadRequest( IInventoryService inv, IAssetService assets, IUserAccountService uacc, UserAccount userInfo, string invPath, string loadPath, bool merge) @@ -181,7 +184,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver /// returned /// /// Thrown if load fails. - public HashSet Execute() + public Dictionary Execute() { try { @@ -223,6 +226,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver } archive.Close(); + LoadInventoryLinks(); m_log.DebugFormat( "[INVENTORY ARCHIVER]: Successfully loaded {0} assets with {1} failures", @@ -271,7 +275,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver string iarPath, InventoryFolderBase rootDestFolder, Dictionary resolvedFolders, - HashSet loadedNodes) + Dictionary loadedNodes) { string iarPathExisting = iarPath; @@ -392,7 +396,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver string iarPathExisting, string iarPathToReplicate, Dictionary resolvedFolders, - HashSet loadedNodes) + Dictionary loadedNodes) { string[] rawDirsToCreate = iarPathToReplicate.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries); @@ -424,7 +428,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver resolvedFolders[iarPathExisting] = destFolder; if (0 == i) - loadedNodes.Add(destFolder); + loadedNodes[destFolder.ID] = destFolder; } } @@ -439,8 +443,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver { 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 @@ -457,7 +463,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver else if (string.IsNullOrEmpty(item.CreatorData)) { item.CreatorId = m_userInfo.PrincipalID.ToString(); -// item.CreatorIdAsUuid = new UUID(item.CreatorId); } item.Owner = m_userInfo.PrincipalID; @@ -470,10 +475,19 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver // 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; - - if (!m_InventoryService.AddItem(item)) - m_log.WarnFormat("[INVENTORY ARCHIVER]: Unable to save item {0} in folder {1}", item.Name, item.Folder); + 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; } @@ -504,56 +518,57 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver string rawUuid = filename.Remove(filename.Length - extension.Length); UUID assetId = new UUID(rawUuid); - if (ArchiveConstants.EXTENSION_TO_ASSET_TYPE.ContainsKey(extension)) + if (!ArchiveConstants.EXTENSION_TO_ASSET_TYPE.ContainsKey(extension)) + { + m_log.ErrorFormat( + "[INVENTORY ARCHIVER]: Tried to dearchive data with path {0} with an unknown type extension {1}", + assetPath, extension); + return false; + } + + sbyte assetType = ArchiveConstants.EXTENSION_TO_ASSET_TYPE[extension]; + if (assetType == (sbyte)AssetType.Unknown) { - sbyte assetType = ArchiveConstants.EXTENSION_TO_ASSET_TYPE[extension]; + m_log.WarnFormat("[INVENTORY ARCHIVER]: Importing {0} byte asset {1} with unknown type", data.Length, assetId); + return false; + } - if (assetType == (sbyte)AssetType.Unknown) - { - m_log.WarnFormat("[INVENTORY ARCHIVER]: Importing {0} byte asset {1} with unknown type", data.Length, assetId); - } - else if (assetType == (sbyte)AssetType.Object) - { - if (m_creatorIdForAssetId.ContainsKey(assetId)) + if(assetType == (sbyte)AssetType.Object) + { + UUID owner = m_userInfo.PrincipalID; + bool doCreatorID = m_creatorIdForAssetId.ContainsKey(assetId); + + data = SceneObjectSerializer.ModifySerializedObject(assetId, data, + sog => { - data = SceneObjectSerializer.ModifySerializedObject(assetId, data, - sog => { - bool modified = false; - - foreach (SceneObjectPart sop in sog.Parts) - { - if (string.IsNullOrEmpty(sop.CreatorData)) - { - sop.CreatorID = m_creatorIdForAssetId[assetId]; - modified = true; - } - } - - return modified; - }); - - if (data == null) - return false; - } - } + foreach(SceneObjectPart sop in sog.Parts) + { + sop.OwnerID = owner; + if(doCreatorID && string.IsNullOrEmpty(sop.CreatorData)) + sop.CreatorID = m_creatorIdForAssetId[assetId]; + + foreach(TaskInventoryItem it in sop.Inventory.GetInventoryItems()) + { + it.OwnerID = owner; + if(string.IsNullOrEmpty(it.CreatorData) && m_creatorIdForAssetId.ContainsKey(it.AssetID)) + it.CreatorID = m_creatorIdForAssetId[it.AssetID]; + } + } + return true; + }); - //m_log.DebugFormat("[INVENTORY ARCHIVER]: Importing asset {0}, type {1}", uuid, assetType); + if(data == null) + return false; + } - AssetBase asset = new AssetBase(assetId, "From IAR", assetType, UUID.Zero.ToString()); - asset.Data = data; + //m_log.DebugFormat("[INVENTORY ARCHIVER]: Importing asset {0}, type {1}", uuid, assetType); - m_AssetService.Store(asset); + AssetBase asset = new AssetBase(assetId, "From IAR", assetType, UUID.Zero.ToString()); + asset.Data = data; - return true; - } - else - { - m_log.ErrorFormat( - "[INVENTORY ARCHIVER]: Tried to dearchive data with path {0} with an unknown type extension {1}", - assetPath, extension); + m_AssetService.Store(asset); - return false; - } + return true; } /// @@ -621,14 +636,38 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver // If we aren't loading the folder containing the item then well need to update the // viewer separately for that item. - if (!m_loadedNodes.Contains(foundFolder)) - m_loadedNodes.Add(item); + if (!m_loadedNodes.ContainsKey(foundFolder.ID)) + m_loadedNodes[foundFolder.ID] = item; } } m_inventoryNodesLoaded = true; } + private void LoadInventoryLinks() + { + foreach(InventoryItemBase it in m_invLinks) + { + UUID target = it.AssetID; + if(m_itemIDs.ContainsKey(target)) + { + it.AssetID = m_itemIDs[target]; + if(!m_InventoryService.AddItem(it)) + m_log.WarnFormat("[INVENTORY ARCHIVER]: Unable to save item {0} in folder {1}",it.Name,it.Folder); + else + { + m_successfulItemRestores++; + UUID fid = it.Folder; + if (!m_loadedNodes.ContainsKey(fid) && m_invLinksFolders.ContainsKey(fid)) + m_loadedNodes[fid] = m_invLinksFolders[fid]; + } + } + } + + m_itemIDs.Clear(); + m_invLinks.Clear(); + m_invLinksFolders.Clear(); + } /// /// Load asset file /// diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs index 06aec7b..d50ebf5 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs @@ -593,7 +593,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver /// Notify the client of loaded nodes if they are logged in /// /// Can be empty. In which case, nothing happens - private void UpdateClientWithLoadedNodes(UserAccount userInfo, HashSet loadedNodes) + private void UpdateClientWithLoadedNodes(UserAccount userInfo, Dictionary loadedNodes) { if (loadedNodes.Count == 0) return; @@ -604,7 +604,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver if (user != null && !user.IsChildAgent) { - foreach (InventoryNodeBase node in loadedNodes) + foreach (InventoryNodeBase node in loadedNodes.Values) { // m_log.DebugFormat( // "[INVENTORY ARCHIVER]: Notifying {0} of loaded inventory node {1}", diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveLoadPathTests.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveLoadPathTests.cs index f559c2e..86eca17 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveLoadPathTests.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveLoadPathTests.cs @@ -212,7 +212,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene); Dictionary foldersCreated = new Dictionary(); - HashSet nodesLoaded = new HashSet(); + Dictionary nodesLoaded = new Dictionary(); string folder1Name = "1"; string folder2aName = "2a"; @@ -293,7 +293,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests new InventoryArchiveReadRequest(UUID.Random(), null, scene.InventoryService, scene.AssetService, scene.UserAccountService, ua1, null, (Stream)null, false) .ReplicateArchivePathToUserInventory( itemArchivePath, scene.InventoryService.GetRootFolder(ua1.PrincipalID), - new Dictionary(), new HashSet()); + new Dictionary(), new Dictionary()); List folder1PostCandidates = InventoryArchiveUtils.FindFoldersByPath(scene.InventoryService, ua1.PrincipalID, folder1ExistingName); @@ -344,7 +344,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests new InventoryArchiveReadRequest(UUID.Random(), null, scene.InventoryService, scene.AssetService, scene.UserAccountService, ua1, folder1ExistingName, (Stream)null, true) .ReplicateArchivePathToUserInventory( itemArchivePath, scene.InventoryService.GetRootFolder(ua1.PrincipalID), - new Dictionary(), new HashSet()); + new Dictionary(), new Dictionary()); List folder1PostCandidates = InventoryArchiveUtils.FindFoldersByPath(scene.InventoryService, ua1.PrincipalID, folder1ExistingName); diff --git a/OpenSim/Region/CoreModules/Framework/Library/LibraryModule.cs b/OpenSim/Region/CoreModules/Framework/Library/LibraryModule.cs index df9d4f9..5d77201 100644 --- a/OpenSim/Region/CoreModules/Framework/Library/LibraryModule.cs +++ b/OpenSim/Region/CoreModules/Framework/Library/LibraryModule.cs @@ -178,7 +178,7 @@ namespace OpenSim.Region.CoreModules.Framework.Library InventoryArchiveReadRequest archread = new InventoryArchiveReadRequest(m_MockScene.InventoryService, m_MockScene.AssetService, m_MockScene.UserAccountService, uinfo, simpleName, iarFileName, false); try { - HashSet nodes = archread.Execute(); + Dictionary nodes = archread.Execute(); if (nodes != null && nodes.Count == 0) { // didn't find the subfolder with the given name; place it on the top @@ -188,7 +188,7 @@ namespace OpenSim.Region.CoreModules.Framework.Library archread.Execute(); } - foreach (InventoryNodeBase node in nodes) + foreach (InventoryNodeBase node in nodes.Values) FixPerms(node); } catch (Exception e) -- cgit v1.1