Current state.

This commit is contained in:
Ottermandias 2024-07-03 17:29:49 +02:00
parent 431933e9c1
commit 9fb8090781
39 changed files with 186 additions and 139 deletions

@ -1 +1 @@
Subproject commit 437ef65c6464c54c8f40196dd2428da901d73aab Subproject commit c2738e1d42974cddbe5a31238c6ed236a831d17d

@ -1 +1 @@
Subproject commit 3a97e5aeee3b7375b333c1add5305d0ce80cbf83 Subproject commit 066637abe05c659b79d84f52e6db33487498f433

View file

@ -2,8 +2,8 @@ using FFXIVClientStructs.FFXIV.Client.Graphics.Scene;
using OtterGui.Services; using OtterGui.Services;
using Penumbra.Api.Enums; using Penumbra.Api.Enums;
using Penumbra.Collections; using Penumbra.Collections;
using Penumbra.Interop.Hooks.ResourceLoading;
using Penumbra.Interop.PathResolving; using Penumbra.Interop.PathResolving;
using Penumbra.Interop.ResourceLoading;
using Penumbra.Interop.Structs; using Penumbra.Interop.Structs;
using Penumbra.Services; using Penumbra.Services;
using Penumbra.String.Classes; using Penumbra.String.Classes;

View file

@ -5,7 +5,7 @@ using Penumbra.Api;
using Penumbra.Api.Enums; using Penumbra.Api.Enums;
using Penumbra.Collections.Manager; using Penumbra.Collections.Manager;
using Penumbra.Communication; using Penumbra.Communication;
using Penumbra.Interop.ResourceLoading; using Penumbra.Interop.Hooks.ResourceLoading;
using Penumbra.Meta; using Penumbra.Meta;
using Penumbra.Mods; using Penumbra.Mods;
using Penumbra.Mods.Groups; using Penumbra.Mods.Groups;

View file

@ -1,6 +1,6 @@
using FFXIVClientStructs.FFXIV.Client.System.Resource; using FFXIVClientStructs.FFXIV.Client.System.Resource;
using Penumbra.Api.Enums; using Penumbra.Api.Enums;
using Penumbra.Interop.ResourceLoading; using Penumbra.Interop.Hooks.ResourceLoading;
using Penumbra.Interop.SafeHandles; using Penumbra.Interop.SafeHandles;
using Penumbra.String.Classes; using Penumbra.String.Classes;

View file

@ -10,7 +10,7 @@ public sealed class MtrlShpkLoaded() : EventWrapper<nint, nint, MtrlShpkLoaded.P
{ {
public enum Priority public enum Priority
{ {
/// <seealso cref="Interop.Services.ShaderReplacementFixer.OnMtrlShpkLoaded"/> /// <seealso cref="Penumbra.Interop.Hooks.PostProcessing.ShaderReplacementFixer.OnMtrlShpkLoaded"/>
ShaderReplacementFixer = 0, ShaderReplacementFixer = 0,
} }
} }

View file

@ -2,7 +2,13 @@ namespace Penumbra.Interop.Hooks;
public static class HookSettings public static class HookSettings
{ {
public const bool MetaEntryHooks = false; public const bool AllHooks = true;
public const bool MetaParentHooks = false;
public const bool VfxIdentificationHooks = false; public const bool ObjectHooks = false && AllHooks;
public const bool ReplacementHooks = true && AllHooks;
public const bool ResourceHooks = false && AllHooks;
public const bool MetaEntryHooks = false && AllHooks;
public const bool MetaParentHooks = false && AllHooks;
public const bool VfxIdentificationHooks = false && AllHooks;
public const bool PostProcessingHooks = false && AllHooks;
} }

View file

@ -19,7 +19,7 @@ public sealed unsafe class CharacterBaseDestructor : EventWrapperPtr<CharacterBa
public CharacterBaseDestructor(HookManager hooks) public CharacterBaseDestructor(HookManager hooks)
: base("Destroy CharacterBase") : base("Destroy CharacterBase")
=> _task = hooks.CreateHook<Delegate>(Name, Address, Detour, true); => _task = hooks.CreateHook<Delegate>(Name, Address, Detour, HookSettings.ObjectHooks);
private readonly Task<Hook<Delegate>> _task; private readonly Task<Hook<Delegate>> _task;

View file

@ -19,7 +19,7 @@ public sealed unsafe class CharacterDestructor : EventWrapperPtr<Character, Char
public CharacterDestructor(HookManager hooks) public CharacterDestructor(HookManager hooks)
: base("Character Destructor") : base("Character Destructor")
=> _task = hooks.CreateHook<Delegate>(Name, Sigs.CharacterDestructor, Detour, true); => _task = hooks.CreateHook<Delegate>(Name, Sigs.CharacterDestructor, Detour, HookSettings.ObjectHooks);
private readonly Task<Hook<Delegate>> _task; private readonly Task<Hook<Delegate>> _task;

View file

@ -15,7 +15,7 @@ public sealed unsafe class CopyCharacter : EventWrapperPtr<Character, Character,
public CopyCharacter(HookManager hooks) public CopyCharacter(HookManager hooks)
: base("Copy Character") : base("Copy Character")
=> _task = hooks.CreateHook<Delegate>(Name, Address, Detour, true); => _task = hooks.CreateHook<Delegate>(Name, Address, Detour, HookSettings.ObjectHooks);
private readonly Task<Hook<Delegate>> _task; private readonly Task<Hook<Delegate>> _task;

View file

@ -16,7 +16,7 @@ public sealed unsafe class CreateCharacterBase : EventWrapperPtr<ModelCharaId, C
public CreateCharacterBase(HookManager hooks) public CreateCharacterBase(HookManager hooks)
: base("Create CharacterBase") : base("Create CharacterBase")
=> _task = hooks.CreateHook<Delegate>(Name, Address, Detour, true); => _task = hooks.CreateHook<Delegate>(Name, Address, Detour, HookSettings.ObjectHooks);
private readonly Task<Hook<Delegate>> _task; private readonly Task<Hook<Delegate>> _task;

View file

@ -17,7 +17,7 @@ public sealed unsafe class EnableDraw : IHookService
public EnableDraw(HookManager hooks, GameState state) public EnableDraw(HookManager hooks, GameState state)
{ {
_state = state; _state = state;
_task = hooks.CreateHook<Delegate>("Enable Draw", Sigs.EnableDraw, Detour, true); _task = hooks.CreateHook<Delegate>("Enable Draw", Sigs.EnableDraw, Detour, HookSettings.ObjectHooks);
} }
private delegate void Delegate(GameObject* gameObject); private delegate void Delegate(GameObject* gameObject);

View file

@ -16,7 +16,7 @@ public sealed unsafe class WeaponReload : EventWrapperPtr<DrawDataContainer, Cha
public WeaponReload(HookManager hooks) public WeaponReload(HookManager hooks)
: base("Reload Weapon") : base("Reload Weapon")
=> _task = hooks.CreateHook<Delegate>(Name, Address, Detour, true); => _task = hooks.CreateHook<Delegate>(Name, Address, Detour, HookSettings.ObjectHooks);
private readonly Task<Hook<Delegate>> _task; private readonly Task<Hook<Delegate>> _task;

View file

@ -4,12 +4,13 @@ using FFXIVClientStructs.FFXIV.Client.Graphics.Scene;
using FFXIVClientStructs.FFXIV.Client.System.Resource; using FFXIVClientStructs.FFXIV.Client.System.Resource;
using OtterGui.Services; using OtterGui.Services;
using Penumbra.Api.Enums; using Penumbra.Api.Enums;
using Penumbra.Interop.Hooks.ResourceLoading;
using Penumbra.Interop.PathResolving; using Penumbra.Interop.PathResolving;
using Penumbra.Interop.ResourceLoading;
using Penumbra.Interop.SafeHandles; using Penumbra.Interop.SafeHandles;
using Penumbra.String.Classes; using Penumbra.String.Classes;
using CharacterUtility = Penumbra.Interop.Services.CharacterUtility;
namespace Penumbra.Interop.Services; namespace Penumbra.Interop.Hooks.PostProcessing;
public sealed unsafe class PreBoneDeformerReplacer : IDisposable, IRequiredService public sealed unsafe class PreBoneDeformerReplacer : IDisposable, IRequiredService
{ {
@ -29,17 +30,16 @@ public sealed unsafe class PreBoneDeformerReplacer : IDisposable, IRequiredServi
private readonly IFramework _framework; private readonly IFramework _framework;
public PreBoneDeformerReplacer(CharacterUtility utility, CollectionResolver collectionResolver, ResourceLoader resourceLoader, public PreBoneDeformerReplacer(CharacterUtility utility, CollectionResolver collectionResolver, ResourceLoader resourceLoader,
IGameInteropProvider interop, IFramework framework, CharacterBaseVTables vTables) HookManager hooks, IFramework framework, CharacterBaseVTables vTables)
{ {
interop.InitializeFromAttributes(this);
_utility = utility; _utility = utility;
_collectionResolver = collectionResolver; _collectionResolver = collectionResolver;
_resourceLoader = resourceLoader; _resourceLoader = resourceLoader;
_framework = framework; _framework = framework;
_humanSetupScalingHook = interop.HookFromAddress<CharacterBaseSetupScalingDelegate>(vTables.HumanVTable[57], SetupScaling); _humanSetupScalingHook = hooks.CreateHook<CharacterBaseSetupScalingDelegate>("HumanSetupScaling", vTables.HumanVTable[58], SetupScaling,
_humanCreateDeformerHook = interop.HookFromAddress<CharacterBaseCreateDeformerDelegate>(vTables.HumanVTable[91], CreateDeformer); HookSettings.PostProcessingHooks).Result;
_humanSetupScalingHook.Enable(); _humanCreateDeformerHook = hooks.CreateHook<CharacterBaseCreateDeformerDelegate>("HumanCreateDeformer", vTables.HumanVTable[101],
_humanCreateDeformerHook.Enable(); CreateDeformer, HookSettings.PostProcessingHooks).Result;
} }
public void Dispose() public void Dispose()

View file

@ -1,6 +1,4 @@
using Dalamud.Hooking; using Dalamud.Hooking;
using Dalamud.Plugin.Services;
using Dalamud.Utility.Signatures;
using FFXIVClientStructs.FFXIV.Client.Graphics.Render; using FFXIVClientStructs.FFXIV.Client.Graphics.Render;
using FFXIVClientStructs.FFXIV.Client.Graphics.Scene; using FFXIVClientStructs.FFXIV.Client.Graphics.Scene;
using FFXIVClientStructs.FFXIV.Client.System.Resource.Handle; using FFXIVClientStructs.FFXIV.Client.System.Resource.Handle;
@ -10,9 +8,11 @@ using Penumbra.Communication;
using Penumbra.GameData; using Penumbra.GameData;
using Penumbra.Interop.Hooks.Resources; using Penumbra.Interop.Hooks.Resources;
using Penumbra.Services; using Penumbra.Services;
using CharacterUtility = Penumbra.Interop.Services.CharacterUtility;
using CSModelRenderer = FFXIVClientStructs.FFXIV.Client.Graphics.Render.ModelRenderer; using CSModelRenderer = FFXIVClientStructs.FFXIV.Client.Graphics.Render.ModelRenderer;
using ModelRenderer = Penumbra.Interop.Services.ModelRenderer;
namespace Penumbra.Interop.Services; namespace Penumbra.Interop.Hooks.PostProcessing;
public sealed unsafe class ShaderReplacementFixer : IDisposable, IRequiredService public sealed unsafe class ShaderReplacementFixer : IDisposable, IRequiredService
{ {
@ -29,8 +29,7 @@ public sealed unsafe class ShaderReplacementFixer : IDisposable, IRequiredServic
private readonly Hook<CharacterBaseOnRenderMaterialDelegate> _humanOnRenderMaterialHook; private readonly Hook<CharacterBaseOnRenderMaterialDelegate> _humanOnRenderMaterialHook;
[Signature(Sigs.ModelRendererOnRenderMaterial, DetourName = nameof(ModelRendererOnRenderMaterialDetour))] private readonly Hook<ModelRendererOnRenderMaterialDelegate> _modelRendererOnRenderMaterialHook;
private readonly Hook<ModelRendererOnRenderMaterialDelegate> _modelRendererOnRenderMaterialHook = null!;
private readonly ResourceHandleDestructor _resourceHandleDestructor; private readonly ResourceHandleDestructor _resourceHandleDestructor;
private readonly CommunicatorService _communicator; private readonly CommunicatorService _communicator;
@ -59,19 +58,18 @@ public sealed unsafe class ShaderReplacementFixer : IDisposable, IRequiredServic
=> _moddedCharacterGlassShpkCount; => _moddedCharacterGlassShpkCount;
public ShaderReplacementFixer(ResourceHandleDestructor resourceHandleDestructor, CharacterUtility utility, ModelRenderer modelRenderer, public ShaderReplacementFixer(ResourceHandleDestructor resourceHandleDestructor, CharacterUtility utility, ModelRenderer modelRenderer,
CommunicatorService communicator, IGameInteropProvider interop, CharacterBaseVTables vTables) CommunicatorService communicator, HookManager hooks, CharacterBaseVTables vTables)
{ {
interop.InitializeFromAttributes(this);
_resourceHandleDestructor = resourceHandleDestructor; _resourceHandleDestructor = resourceHandleDestructor;
_utility = utility; _utility = utility;
_modelRenderer = modelRenderer; _modelRenderer = modelRenderer;
_communicator = communicator; _communicator = communicator;
_humanOnRenderMaterialHook = _humanOnRenderMaterialHook = hooks.CreateHook<CharacterBaseOnRenderMaterialDelegate>("Human.OnRenderMaterial", vTables.HumanVTable[62],
interop.HookFromAddress<CharacterBaseOnRenderMaterialDelegate>(vTables.HumanVTable[62], OnRenderHumanMaterial); OnRenderHumanMaterial, HookSettings.PostProcessingHooks).Result;
_modelRendererOnRenderMaterialHook = hooks.CreateHook<ModelRendererOnRenderMaterialDelegate>("ModelRenderer.OnRenderMaterial",
Sigs.ModelRendererOnRenderMaterial, ModelRendererOnRenderMaterialDetour, HookSettings.PostProcessingHooks).Result;
_communicator.MtrlShpkLoaded.Subscribe(OnMtrlShpkLoaded, MtrlShpkLoaded.Priority.ShaderReplacementFixer); _communicator.MtrlShpkLoaded.Subscribe(OnMtrlShpkLoaded, MtrlShpkLoaded.Priority.ShaderReplacementFixer);
_resourceHandleDestructor.Subscribe(OnResourceHandleDestructor, ResourceHandleDestructor.Priority.ShaderReplacementFixer); _resourceHandleDestructor.Subscribe(OnResourceHandleDestructor, ResourceHandleDestructor.Priority.ShaderReplacementFixer);
_humanOnRenderMaterialHook.Enable();
_modelRendererOnRenderMaterialHook.Enable();
} }
public void Dispose() public void Dispose()

View file

@ -5,7 +5,7 @@ using Penumbra.String;
using Penumbra.String.Classes; using Penumbra.String.Classes;
using Penumbra.String.Functions; using Penumbra.String.Functions;
namespace Penumbra.Interop.ResourceLoading; namespace Penumbra.Interop.Hooks.ResourceLoading;
/// <summary> /// <summary>
/// To allow XIV to load files of arbitrary path length, /// To allow XIV to load files of arbitrary path length,
@ -19,6 +19,7 @@ public unsafe class CreateFileWHook : IDisposable, IRequiredService
public CreateFileWHook(IGameInteropProvider interop) public CreateFileWHook(IGameInteropProvider interop)
{ {
_createFileWHook = interop.HookFromImport<CreateFileWDelegate>(null, "KERNEL32.dll", "CreateFileW", 0, CreateFileWDetour); _createFileWHook = interop.HookFromImport<CreateFileWDelegate>(null, "KERNEL32.dll", "CreateFileW", 0, CreateFileWDetour);
if (HookSettings.ReplacementHooks)
_createFileWHook.Enable(); _createFileWHook.Enable();
} }

View file

@ -6,7 +6,7 @@ using Penumbra.GameData;
using Penumbra.Interop.Structs; using Penumbra.Interop.Structs;
using Penumbra.Util; using Penumbra.Util;
namespace Penumbra.Interop.ResourceLoading; namespace Penumbra.Interop.Hooks.ResourceLoading;
public unsafe class FileReadService : IDisposable, IRequiredService public unsafe class FileReadService : IDisposable, IRequiredService
{ {
@ -15,6 +15,7 @@ public unsafe class FileReadService : IDisposable, IRequiredService
_resourceManager = resourceManager; _resourceManager = resourceManager;
_performance = performance; _performance = performance;
interop.InitializeFromAttributes(this); interop.InitializeFromAttributes(this);
if (HookSettings.ReplacementHooks)
_readSqPackHook.Enable(); _readSqPackHook.Enable();
} }

View file

@ -9,7 +9,7 @@ using Penumbra.String;
using Penumbra.String.Classes; using Penumbra.String.Classes;
using FileMode = Penumbra.Interop.Structs.FileMode; using FileMode = Penumbra.Interop.Structs.FileMode;
namespace Penumbra.Interop.ResourceLoading; namespace Penumbra.Interop.Hooks.ResourceLoading;
public unsafe class ResourceLoader : IDisposable, IService public unsafe class ResourceLoader : IDisposable, IService
{ {

View file

@ -8,7 +8,7 @@ using OtterGui.Services;
using Penumbra.Api.Enums; using Penumbra.Api.Enums;
using Penumbra.GameData; using Penumbra.GameData;
namespace Penumbra.Interop.ResourceLoading; namespace Penumbra.Interop.Hooks.ResourceLoading;
public unsafe class ResourceManagerService : IRequiredService public unsafe class ResourceManagerService : IRequiredService
{ {

View file

@ -12,7 +12,7 @@ using Penumbra.String.Classes;
using Penumbra.Util; using Penumbra.Util;
using CSResourceHandle = FFXIVClientStructs.FFXIV.Client.System.Resource.Handle.ResourceHandle; using CSResourceHandle = FFXIVClientStructs.FFXIV.Client.System.Resource.Handle.ResourceHandle;
namespace Penumbra.Interop.ResourceLoading; namespace Penumbra.Interop.Hooks.ResourceLoading;
public unsafe class ResourceService : IDisposable, IRequiredService public unsafe class ResourceService : IDisposable, IRequiredService
{ {
@ -24,17 +24,20 @@ public unsafe class ResourceService : IDisposable, IRequiredService
_performance = performance; _performance = performance;
_resourceManager = resourceManager; _resourceManager = resourceManager;
interop.InitializeFromAttributes(this); interop.InitializeFromAttributes(this);
_getResourceSyncHook.Enable();
_getResourceAsyncHook.Enable();
_incRefHook = interop.HookFromAddress<ResourceHandlePrototype>( _incRefHook = interop.HookFromAddress<ResourceHandlePrototype>(
(nint)CSResourceHandle.MemberFunctionPointers.IncRef, (nint)CSResourceHandle.MemberFunctionPointers.IncRef,
ResourceHandleIncRefDetour); ResourceHandleIncRefDetour);
_incRefHook.Enable();
_decRefHook = interop.HookFromAddress<ResourceHandleDecRefPrototype>( _decRefHook = interop.HookFromAddress<ResourceHandleDecRefPrototype>(
(nint)CSResourceHandle.MemberFunctionPointers.DecRef, (nint)CSResourceHandle.MemberFunctionPointers.DecRef,
ResourceHandleDecRefDetour); ResourceHandleDecRefDetour);
if (HookSettings.ReplacementHooks)
{
_getResourceSyncHook.Enable();
_getResourceAsyncHook.Enable();
_incRefHook.Enable();
_decRefHook.Enable(); _decRefHook.Enable();
} }
}
public ResourceHandle* GetResource(ResourceCategory category, ResourceType type, ByteString path) public ResourceHandle* GetResource(ResourceCategory category, ResourceType type, ByteString path)
{ {

View file

@ -1,14 +1,16 @@
using Dalamud.Hooking; using Dalamud.Hooking;
using Dalamud.Plugin.Services; using Dalamud.Plugin.Services;
using Dalamud.Utility.Signatures; using Dalamud.Utility.Signatures;
using FFXIVClientStructs.FFXIV.Client.LayoutEngine; using Lumina.Excel.GeneratedSheets2;
using FFXIVClientStructs.FFXIV.Client.System.Resource.Handle;
using OtterGui.Services; using OtterGui.Services;
using Penumbra.Api.Enums; using Penumbra.Api.Enums;
using Penumbra.GameData; using Penumbra.GameData;
using Penumbra.Interop.Structs;
using Penumbra.String.Classes; using Penumbra.String.Classes;
using FileMode = Penumbra.Interop.Structs.FileMode;
using ResourceHandle = FFXIVClientStructs.FFXIV.Client.System.Resource.Handle.ResourceHandle;
namespace Penumbra.Interop.ResourceLoading; namespace Penumbra.Interop.Hooks.ResourceLoading;
public unsafe class TexMdlService : IDisposable, IRequiredService public unsafe class TexMdlService : IDisposable, IRequiredService
{ {
@ -25,15 +27,20 @@ public unsafe class TexMdlService : IDisposable, IRequiredService
public TexMdlService(IGameInteropProvider interop) public TexMdlService(IGameInteropProvider interop)
{ {
interop.InitializeFromAttributes(this); interop.InitializeFromAttributes(this);
//_checkFileStateHook.Enable(); if (HookSettings.ReplacementHooks)
{
_checkFileStateHook.Enable();
_loadMdlFileExternHook.Enable();
_textureSomethingHook.Enable();
_vf32Hook.Enable();
//_loadTexFileExternHook.Enable(); //_loadTexFileExternHook.Enable();
//_loadMdlFileExternHook.Enable(); }
} }
/// <summary> Add CRC64 if the given file is a model or texture file and has an associated path. </summary> /// <summary> Add CRC64 if the given file is a model or texture file and has an associated path. </summary>
public void AddCrc(ResourceType type, FullPath? path) public void AddCrc(ResourceType type, FullPath? path)
{ {
if (path.HasValue && type is ResourceType.Mdl or ResourceType.Tex) if (path.HasValue && type is ResourceType.Mdl)
_customFileCrc.Add(path.Value.Crc64); _customFileCrc.Add(path.Value.Crc64);
} }
@ -43,18 +50,35 @@ public unsafe class TexMdlService : IDisposable, IRequiredService
public void Dispose() public void Dispose()
{ {
//_checkFileStateHook.Dispose(); _checkFileStateHook.Dispose();
//_loadTexFileExternHook.Dispose(); //_loadTexFileExternHook.Dispose();
//_loadMdlFileExternHook.Dispose(); _textureSomethingHook.Dispose();
_loadMdlFileExternHook.Dispose();
_vf32Hook.Dispose();
} }
private readonly HashSet<ulong> _customFileCrc = new(); private readonly HashSet<ulong> _customFileCrc = [];
private delegate nint CheckFileStatePrototype(nint unk1, ulong crc64); private delegate nint CheckFileStatePrototype(nint unk1, ulong crc64);
private delegate nint TextureSomethingDelegate(TextureResourceHandle* handle, int lod, SeFileDescriptor* descriptor);
[Signature(Sigs.CheckFileState, DetourName = nameof(CheckFileStateDetour))] [Signature(Sigs.CheckFileState, DetourName = nameof(CheckFileStateDetour))]
private readonly Hook<CheckFileStatePrototype> _checkFileStateHook = null!; private readonly Hook<CheckFileStatePrototype> _checkFileStateHook = null!;
[Signature("E8 ?? ?? ?? ?? 0F B6 C8 EB ?? 4C 8B 83", DetourName = nameof(TextureSomethingDetour))]
private readonly Hook<TextureSomethingDelegate> _textureSomethingHook = null!;
private nint TextureSomethingDetour(TextureResourceHandle* handle, int lod, SeFileDescriptor* descriptor)
{
//Penumbra.Log.Information($"SomethingDetour {handle->Handle.FileName()}");
//if (!handle->Handle.GamePath(out var path) || !path.IsRooted())
return _textureSomethingHook.Original(handle, lod, descriptor);
descriptor->FileMode = FileMode.LoadUnpackedResource;
return _loadTexFileLocal.Invoke((ResourceHandle*)handle, lod, (nint)descriptor, true);
}
/// <summary> /// <summary>
/// The function that checks a files CRC64 to determine whether it is 'protected'. /// The function that checks a files CRC64 to determine whether it is 'protected'.
/// We use it to check against our stored CRC64s and if it corresponds, we return the custom flag. /// We use it to check against our stored CRC64s and if it corresponds, we return the custom flag.
@ -78,17 +102,23 @@ public unsafe class TexMdlService : IDisposable, IRequiredService
private delegate byte LoadTexFileExternPrototype(ResourceHandle* handle, int unk1, nint unk2, bool unk3, nint unk4); private delegate byte LoadTexFileExternPrototype(ResourceHandle* handle, int unk1, nint unk2, bool unk3, nint unk4);
private delegate byte TexResourceHandleVf32Prototype(ResourceHandle* handle, nint unk1, byte unk2); private delegate byte TexResourceHandleVf32Prototype(TextureResourceHandle* handle, SeFileDescriptor* descriptor, byte unk2);
//[Signature("40 53 55 41 54 41 55 41 56 41 57 48 81 EC ?? ?? ?? ?? 48 8B D9", DetourName = nameof(Vf32Detour))] [Signature("40 53 55 41 54 41 55 41 56 41 57 48 81 EC ?? ?? ?? ?? 48 8B D9", DetourName = nameof(Vf32Detour))]
//private readonly Hook<TexResourceHandleVf32Prototype> _vf32Hook = null!; private readonly Hook<TexResourceHandleVf32Prototype> _vf32Hook = null!;
//
//private byte Vf32Detour(ResourceHandle* handle, nint unk1, byte unk2) private byte Vf32Detour(TextureResourceHandle* handle, SeFileDescriptor* descriptor, byte unk2)
{
//if (handle->Handle.GamePath(out var path) && path.IsRooted())
//{ //{
// var ret = _vf32Hook.Original(handle, unk1, unk2); // Penumbra.Log.Information($"Replacing {descriptor->FileMode} with {FileMode.LoadSqPackResource} in VF32 for {path}.");
// return _loadTexFileLocal() // descriptor->FileMode = FileMode.LoadSqPackResource;
//} //}
var ret = _vf32Hook.Original(handle, descriptor, unk2);
return ret;
}
//[Signature(Sigs.LoadTexFileExtern, DetourName = nameof(LoadTexFileExternDetour))] //[Signature(Sigs.LoadTexFileExtern, DetourName = nameof(LoadTexFileExternDetour))]
//private readonly Hook<LoadTexFileExternPrototype> _loadTexFileExternHook = null!; //private readonly Hook<LoadTexFileExternPrototype> _loadTexFileExternHook = null!;
@ -97,7 +127,6 @@ public unsafe class TexMdlService : IDisposable, IRequiredService
// => ptr.Equals(CustomFileFlag) // => ptr.Equals(CustomFileFlag)
// ? _loadTexFileLocal.Invoke(resourceHandle, unk1, unk2, unk3) // ? _loadTexFileLocal.Invoke(resourceHandle, unk1, unk2, unk3)
// : _loadTexFileExternHook.Original(resourceHandle, unk1, unk2, unk3, ptr); // : _loadTexFileExternHook.Original(resourceHandle, unk1, unk2, unk3, ptr);
public delegate byte LoadMdlFileExternPrototype(ResourceHandle* handle, nint unk1, bool unk2, nint unk3); public delegate byte LoadMdlFileExternPrototype(ResourceHandle* handle, nint unk1, bool unk2, nint unk3);

View file

@ -11,7 +11,7 @@ public sealed unsafe class ApricotResourceLoad : FastHook<ApricotResourceLoad.De
public ApricotResourceLoad(HookManager hooks, GameState gameState) public ApricotResourceLoad(HookManager hooks, GameState gameState)
{ {
_gameState = gameState; _gameState = gameState;
Task = hooks.CreateHook<Delegate>("Load Apricot Resource", Sigs.ApricotResourceLoad, Detour, true); Task = hooks.CreateHook<Delegate>("Load Apricot Resource", Sigs.ApricotResourceLoad, Detour, HookSettings.ResourceHooks);
} }
public delegate byte Delegate(ResourceHandle* handle, nint unk1, byte unk2); public delegate byte Delegate(ResourceHandle* handle, nint unk1, byte unk2);

View file

@ -14,7 +14,7 @@ public sealed unsafe class LoadMtrlShpk : FastHook<LoadMtrlShpk.Delegate>
{ {
_gameState = gameState; _gameState = gameState;
_communicator = communicator; _communicator = communicator;
Task = hooks.CreateHook<Delegate>("Load Material Shaders", Sigs.LoadMtrlShpk, Detour, true); Task = hooks.CreateHook<Delegate>("Load Material Shaders", Sigs.LoadMtrlShpk, Detour, HookSettings.ResourceHooks);
} }
public delegate byte Delegate(MaterialResourceHandle* mtrlResourceHandle); public delegate byte Delegate(MaterialResourceHandle* mtrlResourceHandle);

View file

@ -11,7 +11,7 @@ public sealed unsafe class LoadMtrlTex : FastHook<LoadMtrlTex.Delegate>
public LoadMtrlTex(HookManager hooks, GameState gameState) public LoadMtrlTex(HookManager hooks, GameState gameState)
{ {
_gameState = gameState; _gameState = gameState;
Task = hooks.CreateHook<Delegate>("Load Material Textures", Sigs.LoadMtrlTex, Detour, true); Task = hooks.CreateHook<Delegate>("Load Material Textures", Sigs.LoadMtrlTex, Detour, HookSettings.ResourceHooks);
} }
public delegate byte Delegate(MaterialResourceHandle* mtrlResourceHandle); public delegate byte Delegate(MaterialResourceHandle* mtrlResourceHandle);

View file

@ -59,6 +59,7 @@ public sealed unsafe class ResolvePathHooksBase : IDisposable
_resolveVfxPathHook = Create<VfxResolveDelegate>( $"{name}.{nameof(ResolveVfx)}", hooks, vTable[93], type, ResolveVfx, ResolveVfxHuman); _resolveVfxPathHook = Create<VfxResolveDelegate>( $"{name}.{nameof(ResolveVfx)}", hooks, vTable[93], type, ResolveVfx, ResolveVfxHuman);
_resolveEidPathHook = Create<SingleResolveDelegate>( $"{name}.{nameof(ResolveEid)}", hooks, vTable[94], ResolveEid); _resolveEidPathHook = Create<SingleResolveDelegate>( $"{name}.{nameof(ResolveEid)}", hooks, vTable[94], ResolveEid);
// @formatter:on // @formatter:on
if (HookSettings.ResourceHooks)
Enable(); Enable();
} }

View file

@ -23,7 +23,7 @@ public sealed unsafe class ResourceHandleDestructor : EventWrapperPtr<ResourceHa
public ResourceHandleDestructor(HookManager hooks) public ResourceHandleDestructor(HookManager hooks)
: base("Destroy ResourceHandle") : base("Destroy ResourceHandle")
=> _task = hooks.CreateHook<Delegate>(Name, Sigs.ResourceHandleDestructor, Detour, true); => _task = hooks.CreateHook<Delegate>(Name, Sigs.ResourceHandleDestructor, Detour, HookSettings.ResourceHooks);
private readonly Task<Hook<Delegate>> _task; private readonly Task<Hook<Delegate>> _task;

View file

@ -4,12 +4,12 @@ using OtterGui.Services;
using Penumbra.Collections; using Penumbra.Collections;
using Penumbra.Api.Enums; using Penumbra.Api.Enums;
using Penumbra.GameData.Structs; using Penumbra.GameData.Structs;
using Penumbra.Interop.ResourceLoading;
using Penumbra.Interop.Services; using Penumbra.Interop.Services;
using Penumbra.Services; using Penumbra.Services;
using Penumbra.String.Classes; using Penumbra.String.Classes;
using CharacterUtility = Penumbra.Interop.Services.CharacterUtility; using CharacterUtility = Penumbra.Interop.Services.CharacterUtility;
using Penumbra.Interop.Hooks.Objects; using Penumbra.Interop.Hooks.Objects;
using Penumbra.Interop.Hooks.ResourceLoading;
namespace Penumbra.Interop.PathResolving; namespace Penumbra.Interop.PathResolving;

View file

@ -3,8 +3,8 @@ using OtterGui.Services;
using Penumbra.Api.Enums; using Penumbra.Api.Enums;
using Penumbra.Collections; using Penumbra.Collections;
using Penumbra.Collections.Manager; using Penumbra.Collections.Manager;
using Penumbra.Interop.Hooks.ResourceLoading;
using Penumbra.Interop.Processing; using Penumbra.Interop.Processing;
using Penumbra.Interop.ResourceLoading;
using Penumbra.String.Classes; using Penumbra.String.Classes;
using Penumbra.Util; using Penumbra.Util;

View file

@ -1,8 +1,8 @@
using OtterGui.Services; using OtterGui.Services;
using Penumbra.Api.Enums; using Penumbra.Api.Enums;
using Penumbra.Collections; using Penumbra.Collections;
using Penumbra.Interop.Hooks.ResourceLoading;
using Penumbra.Interop.Hooks.Resources; using Penumbra.Interop.Hooks.Resources;
using Penumbra.Interop.ResourceLoading;
using Penumbra.Interop.Structs; using Penumbra.Interop.Structs;
using Penumbra.String.Classes; using Penumbra.String.Classes;

View file

@ -1,7 +1,7 @@
using System.Collections.Frozen; using System.Collections.Frozen;
using OtterGui.Services; using OtterGui.Services;
using Penumbra.Api.Enums; using Penumbra.Api.Enums;
using Penumbra.Interop.ResourceLoading; using Penumbra.Interop.Hooks.ResourceLoading;
using Penumbra.Interop.Structs; using Penumbra.Interop.Structs;
using Penumbra.String; using Penumbra.String;

View file

@ -9,8 +9,8 @@ using Penumbra.Collections;
using Penumbra.GameData.Data; using Penumbra.GameData.Data;
using Penumbra.GameData.Enums; using Penumbra.GameData.Enums;
using Penumbra.GameData.Structs; using Penumbra.GameData.Structs;
using Penumbra.Interop.Hooks.PostProcessing;
using Penumbra.Interop.PathResolving; using Penumbra.Interop.PathResolving;
using Penumbra.Interop.Services;
using Penumbra.String; using Penumbra.String;
using Penumbra.String.Classes; using Penumbra.String.Classes;
using Penumbra.UI; using Penumbra.UI;

View file

@ -5,7 +5,7 @@ using FFXIVClientStructs.FFXIV.Client.System.Resource.Handle;
using Penumbra.GameData.Data; using Penumbra.GameData.Data;
using Penumbra.GameData.Enums; using Penumbra.GameData.Enums;
using Penumbra.GameData.Structs; using Penumbra.GameData.Structs;
using Penumbra.Interop.Services; using Penumbra.Interop.Hooks.PostProcessing;
using Penumbra.UI; using Penumbra.UI;
using CustomizeData = FFXIVClientStructs.FFXIV.Client.Game.Character.CustomizeData; using CustomizeData = FFXIVClientStructs.FFXIV.Client.Game.Character.CustomizeData;
using CustomizeIndex = Dalamud.Game.ClientState.Objects.Enums.CustomizeIndex; using CustomizeIndex = Dalamud.Game.ClientState.Objects.Enums.CustomizeIndex;
@ -31,7 +31,8 @@ public class ResourceTree
public CustomizeData CustomizeData; public CustomizeData CustomizeData;
public GenderRace RaceCode; public GenderRace RaceCode;
public ResourceTree(string name, string anonymizedName, int gameObjectIndex, nint gameObjectAddress, nint drawObjectAddress, bool localPlayerRelated, bool playerRelated, bool networked, string collectionName, string anonymizedCollectionName) public ResourceTree(string name, string anonymizedName, int gameObjectIndex, nint gameObjectAddress, nint drawObjectAddress,
bool localPlayerRelated, bool playerRelated, bool networked, string collectionName, string anonymizedCollectionName)
{ {
Name = name; Name = name;
AnonymizedName = anonymizedName; AnonymizedName = anonymizedName;
@ -62,7 +63,8 @@ public class ResourceTree
var equipment = modelType switch var equipment = modelType switch
{ {
CharacterBase.ModelType.Human => new ReadOnlySpan<CharacterArmor>(&human->Head, 10), CharacterBase.ModelType.Human => new ReadOnlySpan<CharacterArmor>(&human->Head, 10),
CharacterBase.ModelType.DemiHuman => new ReadOnlySpan<CharacterArmor>(Unsafe.AsPointer(ref character->DrawData.EquipmentModelIds[0]), 10), CharacterBase.ModelType.DemiHuman => new ReadOnlySpan<CharacterArmor>(
Unsafe.AsPointer(ref character->DrawData.EquipmentModelIds[0]), 10),
_ => ReadOnlySpan<CharacterArmor>.Empty, _ => ReadOnlySpan<CharacterArmor>.Empty,
}; };
ModelId = character->CharacterData.ModelCharaId; ModelId = character->CharacterData.ModelCharaId;
@ -112,15 +114,17 @@ public class ResourceTree
{ {
if (baseSubObject->GetObjectType() != FFXIVClientStructs.FFXIV.Client.Graphics.Scene.ObjectType.CharacterBase) if (baseSubObject->GetObjectType() != FFXIVClientStructs.FFXIV.Client.Graphics.Scene.ObjectType.CharacterBase)
continue; continue;
var subObject = (CharacterBase*)baseSubObject; var subObject = (CharacterBase*)baseSubObject;
if (subObject->GetModelType() != CharacterBase.ModelType.Weapon) if (subObject->GetModelType() != CharacterBase.ModelType.Weapon)
continue; continue;
var weapon = (Weapon*)subObject; var weapon = (Weapon*)subObject;
// This way to tell apart MainHand and OffHand is not always accurate, but seems good enough for what we're doing with it. // This way to tell apart MainHand and OffHand is not always accurate, but seems good enough for what we're doing with it.
var slot = weaponIndex > 0 ? EquipSlot.OffHand : EquipSlot.MainHand; var slot = weaponIndex > 0 ? EquipSlot.OffHand : EquipSlot.MainHand;
var equipment = new CharacterArmor(weapon->ModelSetId, (byte)weapon->Variant, (byte)weapon->ModelUnknown); var equipment = new CharacterArmor(weapon->ModelSetId, (byte)weapon->Variant, new StainIds(weapon->Stain1, weapon->Stain2));
var weaponType = weapon->SecondaryId; var weaponType = weapon->SecondaryId;
var genericContext = globalContext.CreateContext(subObject, 0xFFFFFFFFu, slot, equipment, weaponType); var genericContext = globalContext.CreateContext(subObject, 0xFFFFFFFFu, slot, equipment, weaponType);
@ -152,6 +156,7 @@ public class ResourceTree
++weaponIndex; ++weaponIndex;
} }
Nodes.InsertRange(0, weaponNodes); Nodes.InsertRange(0, weaponNodes);
} }
@ -171,6 +176,7 @@ public class ResourceTree
pbdNode.FallbackName = "Racial Deformer"; pbdNode.FallbackName = "Racial Deformer";
pbdNode.Icon = ChangedItemDrawer.ChangedItemIcon.Customization; pbdNode.Icon = ChangedItemDrawer.ChangedItemIcon.Customization;
} }
Nodes.Add(pbdNode); Nodes.Add(pbdNode);
} }
} }
@ -188,6 +194,7 @@ public class ResourceTree
decalNode.FallbackName = "Face Decal"; decalNode.FallbackName = "Face Decal";
decalNode.Icon = ChangedItemDrawer.ChangedItemIcon.Customization; decalNode.Icon = ChangedItemDrawer.ChangedItemIcon.Customization;
} }
Nodes.Add(decalNode); Nodes.Add(decalNode);
} }
@ -204,6 +211,7 @@ public class ResourceTree
legacyDecalNode.FallbackName = "Legacy Body Decal"; legacyDecalNode.FallbackName = "Legacy Body Decal";
legacyDecalNode.Icon = ChangedItemDrawer.ChangedItemIcon.Customization; legacyDecalNode.Icon = ChangedItemDrawer.ChangedItemIcon.Customization;
} }
Nodes.Add(legacyDecalNode); Nodes.Add(legacyDecalNode);
} }
} }

View file

@ -1,7 +1,7 @@
using FFXIVClientStructs.FFXIV.Client.System.Resource; using FFXIVClientStructs.FFXIV.Client.System.Resource;
using Penumbra.Api.Enums; using Penumbra.Api.Enums;
using Penumbra.Collections; using Penumbra.Collections;
using Penumbra.Interop.ResourceLoading; using Penumbra.Interop.Hooks.ResourceLoading;
using Penumbra.String.Classes; using Penumbra.String.Classes;
namespace Penumbra.Interop.Services; namespace Penumbra.Interop.Services;

View file

@ -8,7 +8,6 @@ using Penumbra.Api;
using Penumbra.Api.Enums; using Penumbra.Api.Enums;
using Penumbra.Collections; using Penumbra.Collections;
using Penumbra.Collections.Cache; using Penumbra.Collections.Cache;
using Penumbra.Interop.ResourceLoading;
using Penumbra.Interop.PathResolving; using Penumbra.Interop.PathResolving;
using Penumbra.Services; using Penumbra.Services;
using Penumbra.Interop.Services; using Penumbra.Interop.Services;
@ -22,6 +21,7 @@ using Penumbra.GameData.Enums;
using Penumbra.UI; using Penumbra.UI;
using ResidentResourceManager = Penumbra.Interop.Services.ResidentResourceManager; using ResidentResourceManager = Penumbra.Interop.Services.ResidentResourceManager;
using System.Xml.Linq; using System.Xml.Linq;
using Penumbra.Interop.Hooks.ResourceLoading;
namespace Penumbra; namespace Penumbra;

View file

@ -37,7 +37,6 @@
<PropertyGroup> <PropertyGroup>
<DalamudLibPath>$(AppData)\XIVLauncher\addon\Hooks\dev\</DalamudLibPath> <DalamudLibPath>$(AppData)\XIVLauncher\addon\Hooks\dev\</DalamudLibPath>
<DalamudLibPath>H:\Projects\FFPlugins\Dalamud\bin\Release\</DalamudLibPath>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>

View file

@ -7,8 +7,8 @@ using Penumbra.Communication;
using Penumbra.CrashHandler; using Penumbra.CrashHandler;
using Penumbra.CrashHandler.Buffers; using Penumbra.CrashHandler.Buffers;
using Penumbra.GameData.Actors; using Penumbra.GameData.Actors;
using Penumbra.Interop.Hooks.ResourceLoading;
using Penumbra.Interop.PathResolving; using Penumbra.Interop.PathResolving;
using Penumbra.Interop.ResourceLoading;
using Penumbra.Interop.Structs; using Penumbra.Interop.Structs;
using Penumbra.String; using Penumbra.String;
using Penumbra.String.Classes; using Penumbra.String.Classes;

View file

@ -8,8 +8,8 @@ using Penumbra.Api.Enums;
using Penumbra.Collections; using Penumbra.Collections;
using Penumbra.GameData.Actors; using Penumbra.GameData.Actors;
using Penumbra.GameData.Enums; using Penumbra.GameData.Enums;
using Penumbra.Interop.Hooks.ResourceLoading;
using Penumbra.Interop.Hooks.Resources; using Penumbra.Interop.Hooks.Resources;
using Penumbra.Interop.ResourceLoading;
using Penumbra.Interop.Structs; using Penumbra.Interop.Structs;
using Penumbra.Services; using Penumbra.Services;
using Penumbra.String; using Penumbra.String;

View file

@ -25,7 +25,6 @@ using Penumbra.GameData.Interop;
using Penumbra.Import.Structs; using Penumbra.Import.Structs;
using Penumbra.Import.Textures; using Penumbra.Import.Textures;
using Penumbra.Interop.PathResolving; using Penumbra.Interop.PathResolving;
using Penumbra.Interop.ResourceLoading;
using Penumbra.Interop.Services; using Penumbra.Interop.Services;
using Penumbra.Interop.Structs; using Penumbra.Interop.Structs;
using Penumbra.Mods; using Penumbra.Mods;
@ -40,6 +39,8 @@ using CharacterUtility = Penumbra.Interop.Services.CharacterUtility;
using ResidentResourceManager = Penumbra.Interop.Services.ResidentResourceManager; using ResidentResourceManager = Penumbra.Interop.Services.ResidentResourceManager;
using ImGuiClip = OtterGui.ImGuiClip; using ImGuiClip = OtterGui.ImGuiClip;
using Penumbra.Api.IpcTester; using Penumbra.Api.IpcTester;
using Penumbra.Interop.Hooks.PostProcessing;
using Penumbra.Interop.Hooks.ResourceLoading;
namespace Penumbra.UI.Tabs.Debug; namespace Penumbra.UI.Tabs.Debug;

View file

@ -8,7 +8,7 @@ using OtterGui;
using OtterGui.Raii; using OtterGui.Raii;
using OtterGui.Services; using OtterGui.Services;
using OtterGui.Widgets; using OtterGui.Widgets;
using Penumbra.Interop.ResourceLoading; using Penumbra.Interop.Hooks.ResourceLoading;
using Penumbra.String.Classes; using Penumbra.String.Classes;
namespace Penumbra.UI.Tabs; namespace Penumbra.UI.Tabs;