mirror of
https://github.com/xivdev/Penumbra.git
synced 2025-12-12 18:27:24 +01:00
Start
This commit is contained in:
parent
9130932a7f
commit
e15d844d4b
3 changed files with 116 additions and 5 deletions
108
Penumbra/Interop/PathResolver.cs
Normal file
108
Penumbra/Interop/PathResolver.cs
Normal file
|
|
@ -0,0 +1,108 @@
|
|||
using System;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using Dalamud.Hooking;
|
||||
using Dalamud.Logging;
|
||||
using Dalamud.Utility.Signatures;
|
||||
using FFXIVClientStructs.FFXIV.Client.Game.Object;
|
||||
using FFXIVClientStructs.FFXIV.Client.Graphics.Scene;
|
||||
using Penumbra.GameData.Util;
|
||||
using Penumbra.Mods;
|
||||
using Penumbra.Util;
|
||||
|
||||
namespace Penumbra.Interop;
|
||||
|
||||
public unsafe class PathResolver : IDisposable
|
||||
{
|
||||
public delegate IntPtr ResolveMdlPath( IntPtr drawObject, IntPtr path, IntPtr unk3, uint unk4 );
|
||||
public delegate IntPtr ResolveMtrlPath( IntPtr drawObject, IntPtr path, IntPtr unk3, uint unk4, IntPtr unk5 );
|
||||
|
||||
[Signature( "?? 89 ?? ?? ?? ?? 89 ?? ?? ?? ?? 89 ?? ?? ?? ?? 89 ?? ?? ?? 41 ?? 48 83 ?? ?? 45 8B ?? 49 8B ?? 48 8B ?? 48 8B ?? 41" )]
|
||||
public Hook< ResolveMdlPath >? ResolveMdlPathHook;
|
||||
|
||||
[Signature( "?? 89 ?? ?? ?? ?? 89 ?? ?? ?? ?? 89 ?? ?? ?? 57 48 83 ?? ?? 49 8B ?? 48 8B ?? 48 8B ?? 41 83 ?? ?? 0F" )]
|
||||
public Hook<ResolveMtrlPath>? ResolveMtrlPathHook;
|
||||
|
||||
private global::Dalamud.Game.ClientState.Objects.Types.GameObject? FindParent( IntPtr drawObject )
|
||||
=> Dalamud.Objects.FirstOrDefault( a => ( ( GameObject* )a.Address )->DrawObject == ( DrawObject* )drawObject );
|
||||
|
||||
private readonly byte[] _data = new byte[512];
|
||||
|
||||
private unsafe IntPtr ResolveMdlPathDetour( IntPtr drawObject, IntPtr path, IntPtr unk3, uint unk4 )
|
||||
{
|
||||
var ret = ResolveMdlPathHook!.Original( drawObject, path, unk3, unk4 );
|
||||
var n = Marshal.PtrToStringAnsi( ret )!;
|
||||
var name = FindParent( drawObject )?.Name.ToString() ?? string.Empty;
|
||||
PluginLog.Information( $"{drawObject:X} {path:X} {unk3:X} {unk4}\n{n}\n{name}" );
|
||||
if( Service< ModManager >.Get().Collections.CharacterCollection.TryGetValue( name, out var collection ) )
|
||||
{
|
||||
var replacement = collection.ResolveSwappedOrReplacementPath( GamePath.GenerateUncheckedLower( n ) );
|
||||
if( replacement != null )
|
||||
{
|
||||
for( var i = 0; i < replacement.Length; ++i )
|
||||
{
|
||||
_data[ i ] = ( byte )replacement[ i ];
|
||||
}
|
||||
|
||||
_data[ replacement.Length ] = 0;
|
||||
fixed( byte* data = _data )
|
||||
{
|
||||
return ( IntPtr )data;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
private unsafe IntPtr ResolveMtrlPathDetour( IntPtr drawObject, IntPtr path, IntPtr unk3, uint unk4, IntPtr unk5 )
|
||||
{
|
||||
var ret = ResolveMtrlPathHook!.Original( drawObject, path, unk3, unk4, unk5 );
|
||||
var n = Marshal.PtrToStringAnsi( ret )!;
|
||||
var name = FindParent( drawObject )?.Name.ToString() ?? string.Empty;
|
||||
PluginLog.Information( $"{drawObject:X} {path:X} {unk3:X} {unk4} {unk5:X}\n{n}\n{name}" );
|
||||
if( Service<ModManager>.Get().Collections.CharacterCollection.TryGetValue( name, out var collection ) )
|
||||
{
|
||||
var replacement = collection.ResolveSwappedOrReplacementPath( GamePath.GenerateUncheckedLower( n ) );
|
||||
if( replacement != null )
|
||||
{
|
||||
for( var i = 0; i < replacement.Length; ++i )
|
||||
{
|
||||
_data[i] = ( byte )replacement[i];
|
||||
}
|
||||
|
||||
_data[replacement.Length] = 0;
|
||||
fixed( byte* data = _data )
|
||||
{
|
||||
return ( IntPtr )data;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
public PathResolver()
|
||||
{
|
||||
SignatureHelper.Initialise( this );
|
||||
Enable();
|
||||
}
|
||||
|
||||
public void Enable()
|
||||
{
|
||||
ResolveMdlPathHook?.Enable();
|
||||
ResolveMtrlPathHook?.Enable();
|
||||
}
|
||||
|
||||
public void Disable()
|
||||
{
|
||||
ResolveMdlPathHook?.Disable();
|
||||
ResolveMtrlPathHook?.Disable();
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
ResolveMdlPathHook?.Dispose();
|
||||
ResolveMtrlPathHook?.Dispose();
|
||||
}
|
||||
}
|
||||
|
|
@ -129,7 +129,7 @@ public class ResourceLoader : IDisposable
|
|||
private IntPtr CheckFileStateDetour( IntPtr ptr, ulong crc64 )
|
||||
{
|
||||
var modManager = Service< ModManager >.Get();
|
||||
return modManager.CheckCrc64( crc64 ) ? CustomFileFlag : CheckFileStateHook!.Original( ptr, crc64 );
|
||||
return true || modManager.CheckCrc64( crc64 ) ? CustomFileFlag : CheckFileStateHook!.Original( ptr, crc64 );
|
||||
}
|
||||
|
||||
private byte LoadTexFileExternDetour( IntPtr resourceHandle, int unk1, IntPtr unk2, bool unk3, IntPtr ptr )
|
||||
|
|
@ -282,8 +282,8 @@ public class ResourceLoader : IDisposable
|
|||
Marshal.Copy( utfPath, 0, new IntPtr( fd + 0x21 ), utfPath.Length );
|
||||
|
||||
pFileDesc->FileDescriptor = fd;
|
||||
|
||||
return ReadFile( pFileHandler, pFileDesc, priority, isSync );
|
||||
var ret = ReadFile( pFileHandler, pFileDesc, priority, isSync );
|
||||
return ret;
|
||||
}
|
||||
|
||||
public void Enable()
|
||||
|
|
@ -311,7 +311,7 @@ public class ResourceLoader : IDisposable
|
|||
LoadTexFileExternHook.Enable();
|
||||
LoadMdlFileExternHook.Enable();
|
||||
|
||||
IsEnabled = true;
|
||||
IsEnabled = true;
|
||||
}
|
||||
|
||||
public void Disable()
|
||||
|
|
@ -327,7 +327,7 @@ public class ResourceLoader : IDisposable
|
|||
CheckFileStateHook?.Disable();
|
||||
LoadTexFileExternHook?.Disable();
|
||||
LoadMdlFileExternHook?.Disable();
|
||||
IsEnabled = false;
|
||||
IsEnabled = false;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ public class Penumbra : IDalamudPlugin
|
|||
public static IPlayerWatcher PlayerWatcher { get; private set; } = null!;
|
||||
|
||||
public ResourceLoader ResourceLoader { get; }
|
||||
public PathResolver PathResolver { get; }
|
||||
public SettingsInterface SettingsInterface { get; }
|
||||
public MusicManager MusicManager { get; }
|
||||
public ObjectReloader ObjectReloader { get; }
|
||||
|
|
@ -53,6 +54,7 @@ public class Penumbra : IDalamudPlugin
|
|||
}
|
||||
|
||||
var gameUtils = Service< ResidentResources >.Set();
|
||||
PathResolver = new PathResolver();
|
||||
PlayerWatcher = PlayerWatchFactory.Create( Dalamud.Framework, Dalamud.ClientState, Dalamud.Objects );
|
||||
Service< MetaDefaults >.Set();
|
||||
_modManager = Service< ModManager >.Set();
|
||||
|
|
@ -190,6 +192,7 @@ public class Penumbra : IDalamudPlugin
|
|||
|
||||
Dalamud.Commands.RemoveHandler( CommandName );
|
||||
|
||||
PathResolver.Dispose();
|
||||
ResourceLoader.Dispose();
|
||||
|
||||
ShutdownWebServer();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue