From 98b4b29ff5ced970e8bde36c077e531e13c647f9 Mon Sep 17 00:00:00 2001 From: Ottermandias Date: Sun, 20 Mar 2022 16:21:14 +0100 Subject: [PATCH] Add debug display for ResidentResources. --- Penumbra/Interop/ResidentResourceManager.cs | 4 +- .../Interop/Resolver/PathResolver.Resolve.cs | 3 + Penumbra/Interop/Structs/FileMode.cs | 4 +- .../Structs/ResidentResourceManager.cs | 19 +++++ Penumbra/Penumbra.csproj | 4 - Penumbra/UI/MenuTabs/TabDebug.cs | 32 +++++++ Penumbra/Util/RelPath.cs | 84 ------------------- Penumbra/Util/TempFile.cs | 11 +-- 8 files changed, 59 insertions(+), 102 deletions(-) create mode 100644 Penumbra/Interop/Structs/ResidentResourceManager.cs delete mode 100644 Penumbra/Util/RelPath.cs diff --git a/Penumbra/Interop/ResidentResourceManager.cs b/Penumbra/Interop/ResidentResourceManager.cs index dbe49df1..8e75dcde 100644 --- a/Penumbra/Interop/ResidentResourceManager.cs +++ b/Penumbra/Interop/ResidentResourceManager.cs @@ -16,9 +16,9 @@ public unsafe class ResidentResourceManager // A static pointer to the resident resource manager address. [Signature( "0F 44 FE 48 8B 0D ?? ?? ?? ?? 48 85 C9 74 05", ScanType = ScanType.StaticAddress )] - private readonly void** _residentResourceManagerAddress = null; + private readonly Structs.ResidentResourceManager** _residentResourceManagerAddress = null; - public void* Address + public Structs.ResidentResourceManager* Address => *_residentResourceManagerAddress; public ResidentResourceManager() diff --git a/Penumbra/Interop/Resolver/PathResolver.Resolve.cs b/Penumbra/Interop/Resolver/PathResolver.Resolve.cs index 77fba089..ce3ec0dd 100644 --- a/Penumbra/Interop/Resolver/PathResolver.Resolve.cs +++ b/Penumbra/Interop/Resolver/PathResolver.Resolve.cs @@ -107,6 +107,9 @@ public unsafe partial class PathResolver ? Penumbra.ModManager.Collections.DefaultCollection : collection, path ); + // Weapons have the characters DrawObject as a parent, + // but that may not be set yet when creating a new object, so we have to do the same detour + // as for Human DrawObjects that are just being created. [MethodImpl( MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization )] private IntPtr ResolveWeaponPathDetour( IntPtr drawObject, IntPtr path ) { diff --git a/Penumbra/Interop/Structs/FileMode.cs b/Penumbra/Interop/Structs/FileMode.cs index 21270176..13966e65 100644 --- a/Penumbra/Interop/Structs/FileMode.cs +++ b/Penumbra/Interop/Structs/FileMode.cs @@ -3,9 +3,9 @@ namespace Penumbra.Interop.Structs; public enum FileMode : uint { LoadUnpackedResource = 0, - LoadFileResource = 1, // Shit in My Games uses this + LoadFileResource = 1, // The config files in MyGames use this. - // some shit here, the game does some jump if its < 0xA for other files for some reason but there's no impl, probs debug? + // Probably debug options only. LoadIndexResource = 0xA, // load index/index2 LoadSqPackResource = 0xB, } \ No newline at end of file diff --git a/Penumbra/Interop/Structs/ResidentResourceManager.cs b/Penumbra/Interop/Structs/ResidentResourceManager.cs new file mode 100644 index 00000000..d5dd1715 --- /dev/null +++ b/Penumbra/Interop/Structs/ResidentResourceManager.cs @@ -0,0 +1,19 @@ +using System.Runtime.InteropServices; + +namespace Penumbra.Interop.Structs; + +[StructLayout(LayoutKind.Explicit)] +public unsafe struct ResidentResourceManager +{ + [FieldOffset( 0x00 )] + public void** VTable; + + [FieldOffset( 0x08 )] + public void** ResourceListVTable; + + [FieldOffset( 0x14 )] + public uint NumResources; + + [FieldOffset( 0x18 )] + public ResourceHandle** ResourceList; +} \ No newline at end of file diff --git a/Penumbra/Penumbra.csproj b/Penumbra/Penumbra.csproj index 84c1b98d..13a25cc0 100644 --- a/Penumbra/Penumbra.csproj +++ b/Penumbra/Penumbra.csproj @@ -79,8 +79,4 @@ Always - - - - \ No newline at end of file diff --git a/Penumbra/UI/MenuTabs/TabDebug.cs b/Penumbra/UI/MenuTabs/TabDebug.cs index ab109e49..4aba0ee8 100644 --- a/Penumbra/UI/MenuTabs/TabDebug.cs +++ b/Penumbra/UI/MenuTabs/TabDebug.cs @@ -327,6 +327,36 @@ public partial class SettingsInterface } } + + public unsafe void DrawDebugResidentResources() + { + if( !ImGui.CollapsingHeader( "Resident Resources##Debug" ) ) + { + return; + } + + if( Penumbra.ResidentResources.Address == null || Penumbra.ResidentResources.Address->NumResources == 0 ) + { + return; + } + + if( !ImGui.BeginTable( "##Resident ResourcesDebugList", 2, ImGuiTableFlags.RowBg | ImGuiTableFlags.SizingFixedFit, -Vector2.UnitX ) ) + { + return; + } + + using var end = ImGuiRaii.DeferredEnd( ImGui.EndTable ); + + for( var i = 0; i < Penumbra.ResidentResources.Address->NumResources; ++i ) + { + var resource = Penumbra.ResidentResources.Address->ResourceList[ i ]; + ImGui.TableNextColumn(); + ImGui.Text( $"0x{( ulong )resource:X}" ); + ImGui.TableNextColumn(); + ImGuiNative.igTextUnformatted( resource->FileName(), resource->FileName() + resource->FileNameLength ); + } + } + private unsafe void DrawPathResolverDebug() { if( !ImGui.CollapsingHeader( "Path Resolver##Debug" ) ) @@ -404,6 +434,8 @@ public partial class SettingsInterface ImGui.NewLine(); DrawDebugCharacterUtility(); ImGui.NewLine(); + DrawDebugResidentResources(); + ImGui.NewLine(); DrawDebugTabRedraw(); ImGui.NewLine(); DrawDebugTabIpc(); diff --git a/Penumbra/Util/RelPath.cs b/Penumbra/Util/RelPath.cs deleted file mode 100644 index f4ce0021..00000000 --- a/Penumbra/Util/RelPath.cs +++ /dev/null @@ -1,84 +0,0 @@ -using System; -using System.IO; -using System.Linq; -using Penumbra.GameData.ByteString; -using Penumbra.GameData.Util; - -namespace Penumbra.Util; - -public readonly struct RelPath : IComparable -{ - public const int MaxRelPathLength = 256; - - private readonly string _path; - - private RelPath( string path, bool _ ) - => _path = path; - - private RelPath( string? path ) - { - if( path != null && path.Length < MaxRelPathLength ) - { - _path = Trim( ReplaceSlash( path ) ); - } - else - { - _path = ""; - } - } - - public RelPath( FullPath file, DirectoryInfo baseDir ) - => _path = CheckPre( file.FullName, baseDir ) ? ReplaceSlash( Trim( Substring( file.FullName, baseDir ) ) ) : string.Empty; - - public RelPath( FileInfo file, DirectoryInfo baseDir ) - => _path = CheckPre( file.FullName, baseDir ) ? Trim( Substring( file.FullName, baseDir ) ) : string.Empty; - - public RelPath( GamePath gamePath ) - => _path = ReplaceSlash( gamePath ); - - public GamePath ToGamePath( int skipFolders = 0 ) - { - string p = this; - if( skipFolders > 0 ) - { - p = string.Join( "/", p.Split( '\\' ).Skip( skipFolders ) ); - return GamePath.GenerateUncheckedLower( p ); - } - - return GamePath.GenerateUncheckedLower( p.Replace( '\\', '/' ) ); - } - - private static bool CheckPre( string file, DirectoryInfo baseDir ) - => file.StartsWith( baseDir.FullName ) && file.Length < MaxRelPathLength; - - private static string Substring( string file, DirectoryInfo baseDir ) - => file.Substring( baseDir.FullName.Length ); - - private static string ReplaceSlash( string path ) - => path.Replace( '/', '\\' ); - - private static string Trim( string path ) - => path.TrimStart( '\\' ); - - public static implicit operator string( RelPath relPath ) - => relPath._path; - - public static explicit operator RelPath( string relPath ) - => new(relPath); - - public bool Empty - => _path.Length == 0; - - public int CompareTo( object? rhs ) - { - return rhs switch - { - string path => string.Compare( _path, path, StringComparison.InvariantCulture ), - RelPath path => string.Compare( _path, path._path, StringComparison.InvariantCulture ), - _ => -1, - }; - } - - public override string ToString() - => _path; -} \ No newline at end of file diff --git a/Penumbra/Util/TempFile.cs b/Penumbra/Util/TempFile.cs index 4e2e22ca..19e8b47e 100644 --- a/Penumbra/Util/TempFile.cs +++ b/Penumbra/Util/TempFile.cs @@ -12,7 +12,7 @@ public static class TempFile { var name = Path.GetRandomFileName(); var path = new FileInfo( Path.Combine( baseDir.FullName, - suffix.Any() ? name.Substring( 0, name.LastIndexOf( '.' ) ) + suffix : name ) ); + suffix.Length > 0 ? name[ ..name.LastIndexOf( '.' ) ] + suffix : name ) ); if( !path.Exists ) { return path; @@ -21,13 +21,4 @@ public static class TempFile throw new IOException(); } - - public static FileInfo WriteNew( DirectoryInfo baseDir, byte[] data, string suffix = "" ) - { - var fileName = TempFileName( baseDir, suffix ); - using var stream = fileName.OpenWrite(); - stream.Write( data, 0, data.Length ); - fileName.Refresh(); - return fileName; - } } \ No newline at end of file