mirror of
https://github.com/xivdev/Penumbra.git
synced 2025-12-13 12:14:17 +01:00
Add debug display for ResidentResources.
This commit is contained in:
parent
ad55d178d4
commit
98b4b29ff5
8 changed files with 59 additions and 102 deletions
|
|
@ -16,9 +16,9 @@ public unsafe class ResidentResourceManager
|
||||||
|
|
||||||
// A static pointer to the resident resource manager address.
|
// A static pointer to the resident resource manager address.
|
||||||
[Signature( "0F 44 FE 48 8B 0D ?? ?? ?? ?? 48 85 C9 74 05", ScanType = ScanType.StaticAddress )]
|
[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;
|
=> *_residentResourceManagerAddress;
|
||||||
|
|
||||||
public ResidentResourceManager()
|
public ResidentResourceManager()
|
||||||
|
|
|
||||||
|
|
@ -107,6 +107,9 @@ public unsafe partial class PathResolver
|
||||||
? Penumbra.ModManager.Collections.DefaultCollection
|
? Penumbra.ModManager.Collections.DefaultCollection
|
||||||
: collection, path );
|
: 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 )]
|
[MethodImpl( MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization )]
|
||||||
private IntPtr ResolveWeaponPathDetour( IntPtr drawObject, IntPtr path )
|
private IntPtr ResolveWeaponPathDetour( IntPtr drawObject, IntPtr path )
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -3,9 +3,9 @@ namespace Penumbra.Interop.Structs;
|
||||||
public enum FileMode : uint
|
public enum FileMode : uint
|
||||||
{
|
{
|
||||||
LoadUnpackedResource = 0,
|
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
|
LoadIndexResource = 0xA, // load index/index2
|
||||||
LoadSqPackResource = 0xB,
|
LoadSqPackResource = 0xB,
|
||||||
}
|
}
|
||||||
19
Penumbra/Interop/Structs/ResidentResourceManager.cs
Normal file
19
Penumbra/Interop/Structs/ResidentResourceManager.cs
Normal file
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
@ -79,8 +79,4 @@
|
||||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
</None>
|
</None>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<Folder Include="Collection\" />
|
|
||||||
</ItemGroup>
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|
@ -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()
|
private unsafe void DrawPathResolverDebug()
|
||||||
{
|
{
|
||||||
if( !ImGui.CollapsingHeader( "Path Resolver##Debug" ) )
|
if( !ImGui.CollapsingHeader( "Path Resolver##Debug" ) )
|
||||||
|
|
@ -404,6 +434,8 @@ public partial class SettingsInterface
|
||||||
ImGui.NewLine();
|
ImGui.NewLine();
|
||||||
DrawDebugCharacterUtility();
|
DrawDebugCharacterUtility();
|
||||||
ImGui.NewLine();
|
ImGui.NewLine();
|
||||||
|
DrawDebugResidentResources();
|
||||||
|
ImGui.NewLine();
|
||||||
DrawDebugTabRedraw();
|
DrawDebugTabRedraw();
|
||||||
ImGui.NewLine();
|
ImGui.NewLine();
|
||||||
DrawDebugTabIpc();
|
DrawDebugTabIpc();
|
||||||
|
|
|
||||||
|
|
@ -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;
|
|
||||||
}
|
|
||||||
|
|
@ -12,7 +12,7 @@ public static class TempFile
|
||||||
{
|
{
|
||||||
var name = Path.GetRandomFileName();
|
var name = Path.GetRandomFileName();
|
||||||
var path = new FileInfo( Path.Combine( baseDir.FullName,
|
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 )
|
if( !path.Exists )
|
||||||
{
|
{
|
||||||
return path;
|
return path;
|
||||||
|
|
@ -21,13 +21,4 @@ public static class TempFile
|
||||||
|
|
||||||
throw new IOException();
|
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue