mirror of
https://github.com/xivdev/Penumbra.git
synced 2025-12-12 18:27:24 +01:00
Add explanations on why paths are redacted
This commit is contained in:
parent
d303e0c8b2
commit
1b8e76b269
3 changed files with 35 additions and 7 deletions
|
|
@ -16,6 +16,7 @@ public class ResourceNode : ICloneable
|
||||||
public readonly nint ResourceHandle;
|
public readonly nint ResourceHandle;
|
||||||
public Utf8GamePath[] PossibleGamePaths;
|
public Utf8GamePath[] PossibleGamePaths;
|
||||||
public FullPath FullPath;
|
public FullPath FullPath;
|
||||||
|
public PathStatus FullPathStatus;
|
||||||
public string? ModName;
|
public string? ModName;
|
||||||
public readonly WeakReference<Mod> Mod = new(null!);
|
public readonly WeakReference<Mod> Mod = new(null!);
|
||||||
public string? ModRelativePath;
|
public string? ModRelativePath;
|
||||||
|
|
@ -61,6 +62,7 @@ public class ResourceNode : ICloneable
|
||||||
ResourceHandle = other.ResourceHandle;
|
ResourceHandle = other.ResourceHandle;
|
||||||
PossibleGamePaths = other.PossibleGamePaths;
|
PossibleGamePaths = other.PossibleGamePaths;
|
||||||
FullPath = other.FullPath;
|
FullPath = other.FullPath;
|
||||||
|
FullPathStatus = other.FullPathStatus;
|
||||||
ModName = other.ModName;
|
ModName = other.ModName;
|
||||||
Mod = other.Mod;
|
Mod = other.Mod;
|
||||||
ModRelativePath = other.ModRelativePath;
|
ModRelativePath = other.ModRelativePath;
|
||||||
|
|
@ -100,4 +102,11 @@ public class ResourceNode : ICloneable
|
||||||
public UiData PrependName(string prefix)
|
public UiData PrependName(string prefix)
|
||||||
=> Name == null ? this : this with { Name = prefix + Name };
|
=> Name == null ? this : this with { Name = prefix + Name };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public enum PathStatus : byte
|
||||||
|
{
|
||||||
|
Valid,
|
||||||
|
NonExistent,
|
||||||
|
External,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -147,25 +147,28 @@ public class ResourceTreeFactory(
|
||||||
{
|
{
|
||||||
foreach (var node in tree.FlatNodes)
|
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;
|
node.FullPath = FullPath.Empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
static bool ShallKeepPath(FullPath fullPath, string? onlyWithinPath)
|
static ResourceNode.PathStatus GetPathStatus(FullPath fullPath, string? onlyWithinPath)
|
||||||
{
|
{
|
||||||
if (!fullPath.IsRooted)
|
if (!fullPath.IsRooted)
|
||||||
return true;
|
return ResourceNode.PathStatus.Valid;
|
||||||
|
|
||||||
if (onlyWithinPath != null)
|
if (onlyWithinPath != null)
|
||||||
{
|
{
|
||||||
var relPath = Path.GetRelativePath(onlyWithinPath, fullPath.FullName);
|
var relPath = Path.GetRelativePath(onlyWithinPath, fullPath.FullName);
|
||||||
if (relPath == ".." || relPath.StartsWith(ParentDirectoryPrefix) || Path.IsPathRooted(relPath))
|
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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -285,10 +285,10 @@ public class ResourceTreeViewer(
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ImGui.Selectable("(unavailable)", false, ImGuiSelectableFlags.Disabled,
|
ImUtf8.Selectable(GetPathStatusLabel(resourceNode.FullPathStatus), false, ImGuiSelectableFlags.Disabled,
|
||||||
new Vector2(ImGui.GetContentRegionAvail().X, cellHeight));
|
new Vector2(ImGui.GetContentRegionAvail().X, cellHeight));
|
||||||
ImGuiUtil.HoverTooltip(
|
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();
|
mutedColor.Dispose();
|
||||||
|
|
@ -354,6 +354,22 @@ public class ResourceTreeViewer(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static ReadOnlySpan<byte> 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]
|
[Flags]
|
||||||
private enum TreeCategory : uint
|
private enum TreeCategory : uint
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue