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 Penumbra.Api.Enums;
using Penumbra.Collections;
using Penumbra.Interop.Hooks.ResourceLoading;
using Penumbra.Interop.PathResolving;
using Penumbra.Interop.ResourceLoading;
using Penumbra.Interop.Structs;
using Penumbra.Services;
using Penumbra.String.Classes;

View file

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

View file

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

View file

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

View file

@ -2,7 +2,13 @@ namespace Penumbra.Interop.Hooks;
public static class HookSettings
{
public const bool MetaEntryHooks = false;
public const bool MetaParentHooks = false;
public const bool VfxIdentificationHooks = false;
public const bool AllHooks = true;
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)
: 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;

View file

@ -19,7 +19,7 @@ public sealed unsafe class CharacterDestructor : EventWrapperPtr<Character, Char
public CharacterDestructor(HookManager hooks)
: 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;

View file

@ -15,7 +15,7 @@ public sealed unsafe class CopyCharacter : EventWrapperPtr<Character, Character,
public CopyCharacter(HookManager hooks)
: 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;

View file

@ -16,7 +16,7 @@ public sealed unsafe class CreateCharacterBase : EventWrapperPtr<ModelCharaId, C
public CreateCharacterBase(HookManager hooks)
: 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;

View file

@ -17,7 +17,7 @@ public sealed unsafe class EnableDraw : IHookService
public EnableDraw(HookManager hooks, GameState 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);

View file

@ -16,7 +16,7 @@ public sealed unsafe class WeaponReload : EventWrapperPtr<DrawDataContainer, Cha
public WeaponReload(HookManager hooks)
: 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;

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -1,14 +1,16 @@
using Dalamud.Hooking;
using Dalamud.Plugin.Services;
using Dalamud.Utility.Signatures;
using FFXIVClientStructs.FFXIV.Client.LayoutEngine;
using FFXIVClientStructs.FFXIV.Client.System.Resource.Handle;
using Lumina.Excel.GeneratedSheets2;
using OtterGui.Services;
using Penumbra.Api.Enums;
using Penumbra.GameData;
using Penumbra.Interop.Structs;
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
{
@ -25,15 +27,20 @@ public unsafe class TexMdlService : IDisposable, IRequiredService
public TexMdlService(IGameInteropProvider interop)
{
interop.InitializeFromAttributes(this);
//_checkFileStateHook.Enable();
if (HookSettings.ReplacementHooks)
{
_checkFileStateHook.Enable();
_loadMdlFileExternHook.Enable();
_textureSomethingHook.Enable();
_vf32Hook.Enable();
//_loadTexFileExternHook.Enable();
//_loadMdlFileExternHook.Enable();
}
}
/// <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)
{
if (path.HasValue && type is ResourceType.Mdl or ResourceType.Tex)
if (path.HasValue && type is ResourceType.Mdl)
_customFileCrc.Add(path.Value.Crc64);
}
@ -43,18 +50,35 @@ public unsafe class TexMdlService : IDisposable, IRequiredService
public void Dispose()
{
//_checkFileStateHook.Dispose();
_checkFileStateHook.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 TextureSomethingDelegate(TextureResourceHandle* handle, int lod, SeFileDescriptor* descriptor);
[Signature(Sigs.CheckFileState, DetourName = nameof(CheckFileStateDetour))]
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>
/// 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.
@ -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 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))]
//private readonly Hook<TexResourceHandleVf32Prototype> _vf32Hook = null!;
//
//private byte Vf32Detour(ResourceHandle* handle, nint unk1, byte unk2)
[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 byte Vf32Detour(TextureResourceHandle* handle, SeFileDescriptor* descriptor, byte unk2)
{
//if (handle->Handle.GamePath(out var path) && path.IsRooted())
//{
// var ret = _vf32Hook.Original(handle, unk1, unk2);
// return _loadTexFileLocal()
// Penumbra.Log.Information($"Replacing {descriptor->FileMode} with {FileMode.LoadSqPackResource} in VF32 for {path}.");
// descriptor->FileMode = FileMode.LoadSqPackResource;
//}
var ret = _vf32Hook.Original(handle, descriptor, unk2);
return ret;
}
//[Signature(Sigs.LoadTexFileExtern, DetourName = nameof(LoadTexFileExternDetour))]
//private readonly Hook<LoadTexFileExternPrototype> _loadTexFileExternHook = null!;
@ -97,7 +127,6 @@ public unsafe class TexMdlService : IDisposable, IRequiredService
// => ptr.Equals(CustomFileFlag)
// ? _loadTexFileLocal.Invoke(resourceHandle, unk1, unk2, unk3)
// : _loadTexFileExternHook.Original(resourceHandle, unk1, unk2, unk3, ptr);
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)
{
_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);

View file

@ -14,7 +14,7 @@ public sealed unsafe class LoadMtrlShpk : FastHook<LoadMtrlShpk.Delegate>
{
_gameState = gameState;
_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);

View file

@ -11,7 +11,7 @@ public sealed unsafe class LoadMtrlTex : FastHook<LoadMtrlTex.Delegate>
public LoadMtrlTex(HookManager hooks, 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);

View file

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

View file

@ -23,7 +23,7 @@ public sealed unsafe class ResourceHandleDestructor : EventWrapperPtr<ResourceHa
public ResourceHandleDestructor(HookManager hooks)
: 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;

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -5,7 +5,7 @@ using FFXIVClientStructs.FFXIV.Client.System.Resource.Handle;
using Penumbra.GameData.Data;
using Penumbra.GameData.Enums;
using Penumbra.GameData.Structs;
using Penumbra.Interop.Services;
using Penumbra.Interop.Hooks.PostProcessing;
using Penumbra.UI;
using CustomizeData = FFXIVClientStructs.FFXIV.Client.Game.Character.CustomizeData;
using CustomizeIndex = Dalamud.Game.ClientState.Objects.Enums.CustomizeIndex;
@ -31,7 +31,8 @@ public class ResourceTree
public CustomizeData CustomizeData;
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;
AnonymizedName = anonymizedName;
@ -62,7 +63,8 @@ public class ResourceTree
var equipment = modelType switch
{
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,
};
ModelId = character->CharacterData.ModelCharaId;
@ -112,15 +114,17 @@ public class ResourceTree
{
if (baseSubObject->GetObjectType() != FFXIVClientStructs.FFXIV.Client.Graphics.Scene.ObjectType.CharacterBase)
continue;
var subObject = (CharacterBase*)baseSubObject;
if (subObject->GetModelType() != CharacterBase.ModelType.Weapon)
continue;
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.
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 genericContext = globalContext.CreateContext(subObject, 0xFFFFFFFFu, slot, equipment, weaponType);
@ -152,6 +156,7 @@ public class ResourceTree
++weaponIndex;
}
Nodes.InsertRange(0, weaponNodes);
}
@ -171,6 +176,7 @@ public class ResourceTree
pbdNode.FallbackName = "Racial Deformer";
pbdNode.Icon = ChangedItemDrawer.ChangedItemIcon.Customization;
}
Nodes.Add(pbdNode);
}
}
@ -188,6 +194,7 @@ public class ResourceTree
decalNode.FallbackName = "Face Decal";
decalNode.Icon = ChangedItemDrawer.ChangedItemIcon.Customization;
}
Nodes.Add(decalNode);
}
@ -204,6 +211,7 @@ public class ResourceTree
legacyDecalNode.FallbackName = "Legacy Body Decal";
legacyDecalNode.Icon = ChangedItemDrawer.ChangedItemIcon.Customization;
}
Nodes.Add(legacyDecalNode);
}
}

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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