From f9b163e7c51a63bf01a4242f4d25cef7cef9c74c Mon Sep 17 00:00:00 2001 From: Exter-N Date: Mon, 3 Feb 2025 00:51:13 +0100 Subject: [PATCH] Add explanations on why paths are redacted --- Penumbra/Interop/ResourceTree/ResourceNode.cs | 9 +++++++++ .../ResourceTree/ResourceTreeFactory.cs | 13 +++++++----- .../UI/AdvancedWindow/ResourceTreeViewer.cs | 20 +++++++++++++++++-- 3 files changed, 35 insertions(+), 7 deletions(-) diff --git a/Penumbra/Interop/ResourceTree/ResourceNode.cs b/Penumbra/Interop/ResourceTree/ResourceNode.cs index 4fa13e1f..60cc48de 100644 --- a/Penumbra/Interop/ResourceTree/ResourceNode.cs +++ b/Penumbra/Interop/ResourceTree/ResourceNode.cs @@ -16,6 +16,7 @@ public class ResourceNode : ICloneable public readonly nint ResourceHandle; public Utf8GamePath[] PossibleGamePaths; public FullPath FullPath; + public PathStatus FullPathStatus; public string? ModName; public readonly WeakReference Mod = new(null!); public string? ModRelativePath; @@ -61,6 +62,7 @@ public class ResourceNode : ICloneable ResourceHandle = other.ResourceHandle; PossibleGamePaths = other.PossibleGamePaths; FullPath = other.FullPath; + FullPathStatus = other.FullPathStatus; ModName = other.ModName; Mod = other.Mod; ModRelativePath = other.ModRelativePath; @@ -100,4 +102,11 @@ public class ResourceNode : ICloneable public UiData PrependName(string prefix) => Name == null ? this : this with { Name = prefix + Name }; } + + public enum PathStatus : byte + { + Valid, + NonExistent, + External, + } } diff --git a/Penumbra/Interop/ResourceTree/ResourceTreeFactory.cs b/Penumbra/Interop/ResourceTree/ResourceTreeFactory.cs index 95627566..cb8be184 100644 --- a/Penumbra/Interop/ResourceTree/ResourceTreeFactory.cs +++ b/Penumbra/Interop/ResourceTree/ResourceTreeFactory.cs @@ -147,25 +147,28 @@ public class ResourceTreeFactory( { foreach (var node in tree.FlatNodes) { - if (!ShallKeepPath(node.FullPath, onlyWithinPath)) + node.FullPathStatus = GetPathStatus(node.FullPath, onlyWithinPath); + if (node.FullPathStatus != ResourceNode.PathStatus.Valid) node.FullPath = FullPath.Empty; } return; - static bool ShallKeepPath(FullPath fullPath, string? onlyWithinPath) + static ResourceNode.PathStatus GetPathStatus(FullPath fullPath, string? onlyWithinPath) { if (!fullPath.IsRooted) - return true; + return ResourceNode.PathStatus.Valid; if (onlyWithinPath != null) { var relPath = Path.GetRelativePath(onlyWithinPath, fullPath.FullName); if (relPath == ".." || relPath.StartsWith(ParentDirectoryPrefix) || Path.IsPathRooted(relPath)) - return false; + return ResourceNode.PathStatus.External; } - return fullPath.Exists; + return fullPath.Exists + ? ResourceNode.PathStatus.Valid + : ResourceNode.PathStatus.NonExistent; } } diff --git a/Penumbra/UI/AdvancedWindow/ResourceTreeViewer.cs b/Penumbra/UI/AdvancedWindow/ResourceTreeViewer.cs index 7bad64f9..3482f620 100644 --- a/Penumbra/UI/AdvancedWindow/ResourceTreeViewer.cs +++ b/Penumbra/UI/AdvancedWindow/ResourceTreeViewer.cs @@ -285,10 +285,10 @@ public class ResourceTreeViewer( } else { - ImGui.Selectable("(unavailable)", false, ImGuiSelectableFlags.Disabled, + ImUtf8.Selectable(GetPathStatusLabel(resourceNode.FullPathStatus), false, ImGuiSelectableFlags.Disabled, new Vector2(ImGui.GetContentRegionAvail().X, cellHeight)); ImGuiUtil.HoverTooltip( - $"The actual path to this file is unavailable.\nIt may be managed by another plug-in.{GetAdditionalDataSuffix(resourceNode.AdditionalData)}"); + $"{GetPathStatusDescription(resourceNode.FullPathStatus)}{GetAdditionalDataSuffix(resourceNode.AdditionalData)}"); } mutedColor.Dispose(); @@ -354,6 +354,22 @@ public class ResourceTreeViewer( } } + private static ReadOnlySpan GetPathStatusLabel(ResourceNode.PathStatus status) + => status switch + { + ResourceNode.PathStatus.External => "(managed by external tools)"u8, + ResourceNode.PathStatus.NonExistent => "(not found)"u8, + _ => "(unavailable)"u8, + }; + + private static string GetPathStatusDescription(ResourceNode.PathStatus status) + => status switch + { + ResourceNode.PathStatus.External => "The actual path to this file is unavailable, because it is managed by external tools.", + ResourceNode.PathStatus.NonExistent => "The actual path to this file is unavailable, because it seems to have been moved or deleted since it was loaded.", + _ => "The actual path to this file is unavailable.", + }; + [Flags] private enum TreeCategory : uint {