try fix IAR load inventory links and objects owner
parent
af9bff7ed2
commit
e3f804e1d8
|
@ -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>
|
||||||
|
|
|
@ -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}",
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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)
|
||||||
|
|
Loading…
Reference in New Issue