try fix IAR load inventory links and objects owner

0.9.0.1-postfixes
UbitUmarov 2018-01-26 16:18:45 +00:00
parent af9bff7ed2
commit e3f804e1d8
4 changed files with 102 additions and 63 deletions

View File

@ -109,7 +109,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
/// <summary> /// <summary>
/// Inventory nodes loaded from the iar. /// Inventory nodes loaded from the iar.
/// </summary> /// </summary>
protected HashSet<InventoryNodeBase> m_loadedNodes = new HashSet<InventoryNodeBase>(); protected Dictionary<UUID, InventoryNodeBase> m_loadedNodes = new Dictionary<UUID, InventoryNodeBase>();
/// <summary> /// <summary>
/// In order to load identically named folders, we need to keep track of the folders that we have already /// 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 /// after OSP resolution (since OSP creators are only stored in the item
/// </summary> /// </summary>
protected Dictionary<UUID, UUID> m_creatorIdForAssetId = new Dictionary<UUID, UUID>(); protected Dictionary<UUID, UUID> m_creatorIdForAssetId = new Dictionary<UUID, UUID>();
protected Dictionary<UUID, UUID> m_itemIDs = new Dictionary<UUID, UUID>();
protected List<InventoryItemBase> m_invLinks = new List<InventoryItemBase>();
protected Dictionary<UUID, InventoryNodeBase> m_invLinksFolders = new Dictionary<UUID, InventoryNodeBase>();
public InventoryArchiveReadRequest( public InventoryArchiveReadRequest(
IInventoryService inv, IAssetService assets, IUserAccountService uacc, UserAccount userInfo, string invPath, string loadPath, bool merge) 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 /// returned
/// </returns> /// </returns>
/// <exception cref="System.Exception">Thrown if load fails.</exception> /// <exception cref="System.Exception">Thrown if load fails.</exception>
public HashSet<InventoryNodeBase> Execute() public Dictionary<UUID,InventoryNodeBase> Execute()
{ {
try try
{ {
@ -223,6 +226,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
} }
archive.Close(); archive.Close();
LoadInventoryLinks();
m_log.DebugFormat( m_log.DebugFormat(
"[INVENTORY ARCHIVER]: Successfully loaded {0} assets with {1} failures", "[INVENTORY ARCHIVER]: Successfully loaded {0} assets with {1} failures",
@ -271,7 +275,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
string iarPath, string iarPath,
InventoryFolderBase rootDestFolder, InventoryFolderBase rootDestFolder,
Dictionary <string, InventoryFolderBase> resolvedFolders, Dictionary <string, InventoryFolderBase> resolvedFolders,
HashSet<InventoryNodeBase> loadedNodes) Dictionary<UUID, InventoryNodeBase> loadedNodes)
{ {
string iarPathExisting = iarPath; string iarPathExisting = iarPath;
@ -392,7 +396,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
string iarPathExisting, string iarPathExisting,
string iarPathToReplicate, string iarPathToReplicate,
Dictionary <string, InventoryFolderBase> resolvedFolders, Dictionary <string, InventoryFolderBase> resolvedFolders,
HashSet<InventoryNodeBase> loadedNodes) Dictionary<UUID, InventoryNodeBase> loadedNodes)
{ {
string[] rawDirsToCreate = iarPathToReplicate.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries); string[] rawDirsToCreate = iarPathToReplicate.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
@ -424,7 +428,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
resolvedFolders[iarPathExisting] = destFolder; resolvedFolders[iarPathExisting] = destFolder;
if (0 == i) 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); InventoryItemBase item = UserInventoryItemSerializer.Deserialize(data);
UUID oldID = item.ID;
// Don't use the item ID that's in the file // Don't use the item ID that's in the file
item.ID = UUID.Random(); item.ID = UUID.Random();
m_itemIDs[oldID] = item.ID;
UUID ospResolvedId = OspResolver.ResolveOspa(item.CreatorId, m_UserAccountService); UUID ospResolvedId = OspResolver.ResolveOspa(item.CreatorId, m_UserAccountService);
if (UUID.Zero != ospResolvedId) // The user exists in this grid 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)) else if (string.IsNullOrEmpty(item.CreatorData))
{ {
item.CreatorId = m_userInfo.PrincipalID.ToString(); item.CreatorId = m_userInfo.PrincipalID.ToString();
// item.CreatorIdAsUuid = new UUID(item.CreatorId);
} }
item.Owner = m_userInfo.PrincipalID; 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 // 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 // checks for this, and maybe even an external tool for creating OARs which enforces this, rather than
// relying on native tar tools. // relying on native tar tools.
m_creatorIdForAssetId[item.AssetID] = item.CreatorIdAsUuid; if(item.AssetType == (int)AssetType.Link)
{
if (!m_InventoryService.AddItem(item)) m_invLinks.Add(item);
m_log.WarnFormat("[INVENTORY ARCHIVER]: Unable to save item {0} in folder {1}", item.Name, item.Folder); 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; return item;
} }
@ -504,56 +518,57 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
string rawUuid = filename.Remove(filename.Length - extension.Length); string rawUuid = filename.Remove(filename.Length - extension.Length);
UUID assetId = new UUID(rawUuid); UUID assetId = new UUID(rawUuid);
if (ArchiveConstants.EXTENSION_TO_ASSET_TYPE.ContainsKey(extension)) if (!ArchiveConstants.EXTENSION_TO_ASSET_TYPE.ContainsKey(extension))
{
sbyte assetType = ArchiveConstants.EXTENSION_TO_ASSET_TYPE[extension];
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))
{
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;
}
}
//m_log.DebugFormat("[INVENTORY ARCHIVER]: Importing asset {0}, type {1}", uuid, assetType);
AssetBase asset = new AssetBase(assetId, "From IAR", assetType, UUID.Zero.ToString());
asset.Data = data;
m_AssetService.Store(asset);
return true;
}
else
{ {
m_log.ErrorFormat( m_log.ErrorFormat(
"[INVENTORY ARCHIVER]: Tried to dearchive data with path {0} with an unknown type extension {1}", "[INVENTORY ARCHIVER]: Tried to dearchive data with path {0} with an unknown type extension {1}",
assetPath, extension); assetPath, extension);
return false; return false;
} }
sbyte assetType = ArchiveConstants.EXTENSION_TO_ASSET_TYPE[extension];
if (assetType == (sbyte)AssetType.Unknown)
{
m_log.WarnFormat("[INVENTORY ARCHIVER]: Importing {0} byte asset {1} with unknown type", data.Length, assetId);
return false;
}
if(assetType == (sbyte)AssetType.Object)
{
UUID owner = m_userInfo.PrincipalID;
bool doCreatorID = m_creatorIdForAssetId.ContainsKey(assetId);
data = SceneObjectSerializer.ModifySerializedObject(assetId, data,
sog =>
{
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;
});
if(data == null)
return false;
}
//m_log.DebugFormat("[INVENTORY ARCHIVER]: Importing asset {0}, type {1}", uuid, assetType);
AssetBase asset = new AssetBase(assetId, "From IAR", assetType, UUID.Zero.ToString());
asset.Data = data;
m_AssetService.Store(asset);
return true;
} }
/// <summary> /// <summary>
@ -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 // If we aren't loading the folder containing the item then well need to update the
// viewer separately for that item. // viewer separately for that item.
if (!m_loadedNodes.Contains(foundFolder)) if (!m_loadedNodes.ContainsKey(foundFolder.ID))
m_loadedNodes.Add(item); m_loadedNodes[foundFolder.ID] = item;
} }
} }
m_inventoryNodesLoaded = true; 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();
}
/// <summary> /// <summary>
/// Load asset file /// Load asset file
/// </summary> /// </summary>

View File

@ -593,7 +593,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
/// Notify the client of loaded nodes if they are logged in /// Notify the client of loaded nodes if they are logged in
/// </summary> /// </summary>
/// <param name="loadedNodes">Can be empty. In which case, nothing happens</param> /// <param name="loadedNodes">Can be empty. In which case, nothing happens</param>
private void UpdateClientWithLoadedNodes(UserAccount userInfo, HashSet<InventoryNodeBase> loadedNodes) private void UpdateClientWithLoadedNodes(UserAccount userInfo, Dictionary<UUID, InventoryNodeBase> loadedNodes)
{ {
if (loadedNodes.Count == 0) if (loadedNodes.Count == 0)
return; return;
@ -604,7 +604,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
if (user != null && !user.IsChildAgent) if (user != null && !user.IsChildAgent)
{ {
foreach (InventoryNodeBase node in loadedNodes) foreach (InventoryNodeBase node in loadedNodes.Values)
{ {
// m_log.DebugFormat( // m_log.DebugFormat(
// "[INVENTORY ARCHIVER]: Notifying {0} of loaded inventory node {1}", // "[INVENTORY ARCHIVER]: Notifying {0} of loaded inventory node {1}",

View File

@ -212,7 +212,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene); UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene);
Dictionary <string, InventoryFolderBase> foldersCreated = new Dictionary<string, InventoryFolderBase>(); Dictionary <string, InventoryFolderBase> foldersCreated = new Dictionary<string, InventoryFolderBase>();
HashSet<InventoryNodeBase> nodesLoaded = new HashSet<InventoryNodeBase>(); Dictionary<UUID, InventoryNodeBase> nodesLoaded = new Dictionary<UUID, InventoryNodeBase>();
string folder1Name = "1"; string folder1Name = "1";
string folder2aName = "2a"; 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) new InventoryArchiveReadRequest(UUID.Random(), null, scene.InventoryService, scene.AssetService, scene.UserAccountService, ua1, null, (Stream)null, false)
.ReplicateArchivePathToUserInventory( .ReplicateArchivePathToUserInventory(
itemArchivePath, scene.InventoryService.GetRootFolder(ua1.PrincipalID), itemArchivePath, scene.InventoryService.GetRootFolder(ua1.PrincipalID),
new Dictionary<string, InventoryFolderBase>(), new HashSet<InventoryNodeBase>()); new Dictionary<string, InventoryFolderBase>(), new Dictionary<UUID, InventoryNodeBase>());
List<InventoryFolderBase> folder1PostCandidates List<InventoryFolderBase> folder1PostCandidates
= InventoryArchiveUtils.FindFoldersByPath(scene.InventoryService, ua1.PrincipalID, folder1ExistingName); = 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) new InventoryArchiveReadRequest(UUID.Random(), null, scene.InventoryService, scene.AssetService, scene.UserAccountService, ua1, folder1ExistingName, (Stream)null, true)
.ReplicateArchivePathToUserInventory( .ReplicateArchivePathToUserInventory(
itemArchivePath, scene.InventoryService.GetRootFolder(ua1.PrincipalID), itemArchivePath, scene.InventoryService.GetRootFolder(ua1.PrincipalID),
new Dictionary<string, InventoryFolderBase>(), new HashSet<InventoryNodeBase>()); new Dictionary<string, InventoryFolderBase>(), new Dictionary<UUID, InventoryNodeBase>());
List<InventoryFolderBase> folder1PostCandidates List<InventoryFolderBase> folder1PostCandidates
= InventoryArchiveUtils.FindFoldersByPath(scene.InventoryService, ua1.PrincipalID, folder1ExistingName); = InventoryArchiveUtils.FindFoldersByPath(scene.InventoryService, ua1.PrincipalID, folder1ExistingName);

View File

@ -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); InventoryArchiveReadRequest archread = new InventoryArchiveReadRequest(m_MockScene.InventoryService, m_MockScene.AssetService, m_MockScene.UserAccountService, uinfo, simpleName, iarFileName, false);
try try
{ {
HashSet<InventoryNodeBase> nodes = archread.Execute(); Dictionary<UUID, InventoryNodeBase> nodes = archread.Execute();
if (nodes != null && nodes.Count == 0) if (nodes != null && nodes.Count == 0)
{ {
// didn't find the subfolder with the given name; place it on the top // 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(); archread.Execute();
} }
foreach (InventoryNodeBase node in nodes) foreach (InventoryNodeBase node in nodes.Values)
FixPerms(node); FixPerms(node);
} }
catch (Exception e) catch (Exception e)