From af75c37543eda9429842b77ded3ec432a12f85af Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Tue, 11 Feb 2025 01:00:35 +0000 Subject: [PATCH] add option --skipbadassets to iar save. THis will skip inventory items with missing or empty main asset. Avoid using unless on try to recover from already damaged assets/inventory --- .../Archiver/InventoryArchiveWriteRequest.cs | 84 +++++++++++-------- .../Archiver/InventoryArchiverModule.cs | 6 +- 2 files changed, 55 insertions(+), 35 deletions(-) diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs index 1758f2ff3f..8146d566a2 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs @@ -56,6 +56,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver /// Determine whether this archive will save assets. Default is true. /// public bool SaveAssets { get; set; } + public bool SkipBadAssets { get; set; } + /// /// Determines which items will be included in the archive, according to their permissions. @@ -136,6 +138,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver m_assetGatherer = new UuidGatherer(m_scene.AssetService); SaveAssets = true; + SkipBadAssets = false; FilterContent = null; } @@ -201,56 +204,65 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver return; } - if (options.ContainsKey("verbose")) - m_log.InfoFormat( - "[INVENTORY ARCHIVER]: Saving item {0} {1} (asset UUID {2})", - inventoryItem.ID, inventoryItem.Name, inventoryItem.AssetID); - - string filename = path + CreateArchiveItemName(inventoryItem); // Record the creator of this item for user record purposes (which might go away soon) m_userUuids[inventoryItem.CreatorIdAsUuid] = 1; - string serialization = UserInventoryItemSerializer.Serialize(inventoryItem, options, userAccountService); - m_archiveWriter.WriteFile(filename, serialization); - AssetType itemAssetType = (AssetType)inventoryItem.AssetType; // Count inventory items (different to asset count) CountItems++; - + bool badasset = false; // Don't chase down link asset items as they actually point to their target item IDs rather than an asset if (SaveAssets && itemAssetType != AssetType.Link && itemAssetType != AssetType.LinkFolder) { - int curErrorCntr = m_assetGatherer.ErrorCount; - int possible = m_assetGatherer.possibleNotAssetCount; - m_assetGatherer.AddForInspection(inventoryItem.AssetID); - m_assetGatherer.GatherAll(); - curErrorCntr = m_assetGatherer.ErrorCount - curErrorCntr; - possible = m_assetGatherer.possibleNotAssetCount - possible; - - if(curErrorCntr > 0 || possible > 0) + if(SkipBadAssets) { - string spath; - int indx = path.IndexOf("__"); - if(indx > 0) - spath = path.Substring(0,indx); - else - spath = path; + AssetBase asset = m_scene.AssetService.Get(inventoryItem.AssetID.ToString()); + if(asset is null || asset.Data is null || asset.Data.Length == 0) + badasset = true; + } + if(!badasset) + { + int curErrorCntr = m_assetGatherer.ErrorCount; + int possible = m_assetGatherer.possibleNotAssetCount; + m_assetGatherer.AddForInspection(inventoryItem.AssetID); + m_assetGatherer.GatherAll(); + curErrorCntr = m_assetGatherer.ErrorCount - curErrorCntr; + possible = m_assetGatherer.possibleNotAssetCount - possible; - if(curErrorCntr > 0) + if(curErrorCntr > 0 || possible > 0) { - m_log.ErrorFormat("[INVENTORY ARCHIVER Warning]: item {0} '{1}', type {2}, in '{3}', contains {4} references to missing or damaged assets", - inventoryItem.ID, inventoryItem.Name, itemAssetType.ToString(), spath, curErrorCntr); - if(possible > 0) - m_log.WarnFormat("[INVENTORY ARCHIVER Warning]: item also contains {0} references that may be to missing or damaged assets or not a problem", possible); - } - else if(possible > 0) - { - m_log.WarnFormat("[INVENTORY ARCHIVER Warning]: item {0} '{1}', type {2}, in '{3}', contains {4} references that may be to missing or damaged assets or not a problem", inventoryItem.ID, inventoryItem.Name, itemAssetType.ToString(), spath, possible); + string spath; + int indx = path.IndexOf("__"); + if(indx > 0) + spath = path.Substring(0,indx); + else + spath = path; + + if(curErrorCntr > 0) + { + m_log.ErrorFormat("[INVENTORY ARCHIVER Warning]: item {0} '{1}', type {2}, in '{3}', contains {4} references to missing or damaged assets", + inventoryItem.ID, inventoryItem.Name, itemAssetType.ToString(), spath, curErrorCntr); + if(possible > 0) + m_log.WarnFormat("[INVENTORY ARCHIVER Warning]: item also contains {0} references that may be to missing or damaged assets or not a problem", possible); + } + else if(possible > 0) + { + m_log.WarnFormat("[INVENTORY ARCHIVER Warning]: item {0} '{1}', type {2}, in '{3}', contains {4} references that may be to missing or damaged assets or not a problem", inventoryItem.ID, inventoryItem.Name, itemAssetType.ToString(), spath, possible); + } } } } + if(!badasset) + { + if (options.ContainsKey("verbose")) + m_log.Info( + $"[INVENTORY ARCHIVER]: Saving item {inventoryItem.ID} {inventoryItem.Name} (asset UUID {inventoryItem.AssetID})"); + string filename = path + CreateArchiveItemName(inventoryItem); + string serialization = UserInventoryItemSerializer.Serialize(inventoryItem, options, userAccountService); + m_archiveWriter.WriteFile(filename, serialization); + } } /// @@ -342,6 +354,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver if (options.ContainsKey("noassets") && (bool)options["noassets"]) SaveAssets = false; + if (options.ContainsKey("skipbadassets") && (bool)options["skipbadassets"]) + { + SaveAssets = true; + SkipBadAssets = true; + } + // Set Permission filter if flag is set if (options.ContainsKey("checkPermissions")) { diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs index d50ebf5bb5..237a2e8ea3 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs @@ -128,7 +128,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver scene.AddCommand( "Archiving", this, "save iar", - "save iar [-h|--home=] [--noassets] [] [-c|--creators] [-e|--exclude=] [-f|--excludefolder=] [-v|--verbose]", + "save iar [-h|--home=] [--noassets | --skipbadassets] [] [-c|--creators] [-e|--exclude=] [-f|--excludefolder=] [-v|--verbose]", "Save user inventory archive (IAR).", " is the user's first name.\n" + " is the user's last name.\n" @@ -141,6 +141,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver + "-f|--excludefolder= don't save contents of the folder in archive" + Environment.NewLine + "-v|--verbose extra debug messages.\n" + "--noassets stops assets being saved to the IAR." + + "--skipbadassets skips inventory items when their main asset is missing. Avoid to use unless tring to recover a already very damaged inventory" + "--perm= stops items with insufficient permissions from being saved to the IAR.\n" + " can contain one or more of these characters: \"C\" = Copy, \"T\" = Transfer, \"M\" = Modify.\n", HandleSaveInvConsoleCommand); @@ -446,6 +447,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver ops.Add("v|verbose", delegate(string v) { options["verbose"] = v; }); ops.Add("c|creators", delegate(string v) { options["creators"] = v; }); ops.Add("noassets", delegate(string v) { options["noassets"] = v != null; }); + ops.Add("skipbadassets", delegate(string v) { options["skipbadassets"] = v != null; }); ops.Add("e|exclude=", delegate(string v) { if (!options.ContainsKey("exclude")) @@ -467,7 +469,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver if (mainParams.Count < 6) { m_log.Error( - "[INVENTORY ARCHIVER]: save iar [-h|--home=] [--noassets] [] [-c|--creators] [-e|--exclude=] [-f|--excludefolder=] [-v|--verbose]"); + "[INVENTORY ARCHIVER]: save iar [-h|--home=] [--noassets | --skipbadassets] [] [-c|--creators] [-e|--exclude=] [-f|--excludefolder=] [-v|--verbose]"); return; }