mirror of
https://github.com/xivdev/Penumbra.git
synced 2025-12-12 18:27:24 +01:00
Implement reloading eqdp, gmp, awt, etc.
This commit is contained in:
parent
edc616da36
commit
ab3cc6dc78
2 changed files with 63 additions and 1 deletions
|
|
@ -1,6 +1,7 @@
|
|||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using Dalamud.Plugin;
|
||||
using Penumbra.Structs;
|
||||
using Reloaded.Hooks.Definitions.X64;
|
||||
|
||||
namespace Penumbra.Game
|
||||
|
|
@ -13,13 +14,24 @@ namespace Penumbra.Game
|
|||
[Function( CallingConventions.Microsoft )]
|
||||
public unsafe delegate void* UnloadPlayerResourcesPrototype( IntPtr pResourceManager );
|
||||
|
||||
[Function( CallingConventions.Microsoft )]
|
||||
public unsafe delegate void* LoadCharacterResourcesPrototype( CharacterResourceManager *pCharacterResourceManager );
|
||||
|
||||
[Function( CallingConventions.Microsoft )]
|
||||
public unsafe delegate void* UnloadCharacterResourcePrototype( IntPtr resource );
|
||||
|
||||
|
||||
public LoadPlayerResourcesPrototype LoadPlayerResources { get; }
|
||||
public UnloadPlayerResourcesPrototype UnloadPlayerResources { get; }
|
||||
public LoadCharacterResourcesPrototype LoadCharacterResources { get; }
|
||||
public UnloadCharacterResourcePrototype UnloadCharacterResource { get; }
|
||||
|
||||
// Object addresses
|
||||
private readonly IntPtr _playerResourceManagerAddress;
|
||||
public IntPtr PlayerResourceManagerPtr => Marshal.ReadIntPtr( _playerResourceManagerAddress );
|
||||
private readonly IntPtr _characterResourceManagerAddress;
|
||||
public unsafe CharacterResourceManager* CharacterResourceManagerPtr =>
|
||||
( CharacterResourceManager* )Marshal.ReadIntPtr( _characterResourceManagerAddress ).ToPointer();
|
||||
|
||||
public GameUtils( DalamudPluginInterface pluginInterface )
|
||||
{
|
||||
|
|
@ -30,17 +42,54 @@ namespace Penumbra.Game
|
|||
"E8 ?? ?? ?? ?? 48 8B 05 ?? ?? ?? ?? BA ?? ?? ?? ?? 41 B8 ?? ?? ?? ?? 48 8B 48 30 48 8B 01 FF 50 10 48 85 C0 74 0A " );
|
||||
var unloadPlayerResourcesAddress =
|
||||
scanner.ScanText( "41 55 48 81 EC ?? ?? ?? ?? 48 8B 05 ?? ?? ?? ?? 48 33 C4 48 89 84 24 ?? ?? ?? ?? 4C 8B E9 48 83 C1 08" );
|
||||
var loadCharacterResourcesAddress = scanner.ScanText( "E8 ?? ?? ?? 00 48 8D 8E ?? ?? 00 00 E8 ?? ?? ?? 00 33 D2" );
|
||||
var unloadCharacterResourceAddress = scanner.ScanText( "E8 ?? ?? ?? FF 4C 89 37 48 83 C7 08 48 83 ED 01 75 ?? 48 8B CB" );
|
||||
|
||||
_playerResourceManagerAddress = scanner.GetStaticAddressFromSig( "0F 44 FE 48 8B 0D ?? ?? ?? ?? 48 85 C9 74 05" );
|
||||
_playerResourceManagerAddress = scanner.GetStaticAddressFromSig( "0F 44 FE 48 8B 0D ?? ?? ?? ?? 48 85 C9 74 05" );
|
||||
_characterResourceManagerAddress = scanner.GetStaticAddressFromSig( "48 8B 0D ?? ?? ?? ?? E8 ?? ?? ?? 00 48 8D 8E ?? ?? 00 00 E8 ?? ?? ?? 00 33 D2" );
|
||||
|
||||
LoadPlayerResources = Marshal.GetDelegateForFunctionPointer< LoadPlayerResourcesPrototype >( loadPlayerResourcesAddress );
|
||||
UnloadPlayerResources = Marshal.GetDelegateForFunctionPointer< UnloadPlayerResourcesPrototype >( unloadPlayerResourcesAddress );
|
||||
LoadCharacterResources = Marshal.GetDelegateForFunctionPointer< LoadCharacterResourcesPrototype >( loadCharacterResourcesAddress );
|
||||
UnloadCharacterResource = Marshal.GetDelegateForFunctionPointer<UnloadCharacterResourcePrototype>( unloadCharacterResourceAddress );
|
||||
}
|
||||
|
||||
public unsafe void ReloadPlayerResources()
|
||||
{
|
||||
ReloadCharacterResources();
|
||||
|
||||
UnloadPlayerResources( PlayerResourceManagerPtr );
|
||||
LoadPlayerResources( PlayerResourceManagerPtr );
|
||||
}
|
||||
|
||||
public unsafe string ResourceToPath( byte *resource ) =>
|
||||
Marshal.PtrToStringAnsi( new IntPtr( *(char **)( resource + 9 * 8 ) ) );
|
||||
|
||||
public unsafe void ReloadCharacterResources()
|
||||
{
|
||||
var oldResources = new IntPtr[85];
|
||||
var resources = new IntPtr(&CharacterResourceManagerPtr->Resources);
|
||||
var pResources = (void **)resources.ToPointer();
|
||||
|
||||
Marshal.Copy( resources, oldResources, 0, 85 );
|
||||
|
||||
LoadCharacterResources( CharacterResourceManagerPtr );
|
||||
|
||||
for( var i = 0; i < 85; i++ )
|
||||
{
|
||||
if( oldResources[ i ].ToPointer() == pResources[ i ] )
|
||||
{
|
||||
PluginLog.Debug($"Unchanged resource: {ResourceToPath( ( byte* )oldResources[i].ToPointer() )}");
|
||||
continue;
|
||||
}
|
||||
|
||||
PluginLog.Debug( "Freeing " +
|
||||
$"{ResourceToPath( ( byte* )oldResources[i].ToPointer() )}, replaced with " +
|
||||
$"{ResourceToPath( ( byte* )pResources[i] )}" );
|
||||
|
||||
UnloadCharacterResource( oldResources[ i ] );
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
13
Penumbra/Structs/CharacterResourceManager.cs
Normal file
13
Penumbra/Structs/CharacterResourceManager.cs
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Penumbra.Structs
|
||||
{
|
||||
[StructLayout( LayoutKind.Sequential )]
|
||||
public unsafe struct CharacterResourceManager
|
||||
{
|
||||
public void* VTable;
|
||||
|
||||
public IntPtr Resources; // Size: 85, I hate C#
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue