mirror of
https://github.com/xivdev/Penumbra.git
synced 2025-12-12 18:27:24 +01:00
Allow hook overrides.
This commit is contained in:
parent
9e15865a99
commit
a308fb9f77
52 changed files with 326 additions and 108 deletions
|
|
@ -24,7 +24,7 @@ public sealed unsafe class ApricotListenerSoundPlayCaller : FastHook<ApricotList
|
|||
_collectionResolver = collectionResolver;
|
||||
_crashHandler = crashHandler;
|
||||
Task = hooks.CreateHook<Delegate>("Apricot Listener Sound Play Caller", Sigs.ApricotListenerSoundPlayCaller, Detour,
|
||||
true); //HookSettings.VfxIdentificationHooks);
|
||||
!HookOverrides.Instance.Animation.ApricotListenerSoundPlayCaller);
|
||||
}
|
||||
|
||||
public delegate nint Delegate(nint a1, nint a2, float a3);
|
||||
|
|
|
|||
|
|
@ -26,7 +26,8 @@ public sealed unsafe class CharacterBaseLoadAnimation : FastHook<CharacterBaseLo
|
|||
_collectionResolver = collectionResolver;
|
||||
_drawObjectState = drawObjectState;
|
||||
_crashHandler = crashHandler;
|
||||
Task = hooks.CreateHook<Delegate>("CharacterBase Load Animation", Sigs.CharacterBaseLoadAnimation, Detour, HookSettings.VfxIdentificationHooks);
|
||||
Task = hooks.CreateHook<Delegate>("CharacterBase Load Animation", Sigs.CharacterBaseLoadAnimation, Detour,
|
||||
!HookOverrides.Instance.Animation.CharacterBaseLoadAnimation);
|
||||
}
|
||||
|
||||
public delegate void Delegate(DrawObject* drawBase);
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ public sealed unsafe class Dismount : FastHook<Dismount.Delegate>
|
|||
{
|
||||
_state = state;
|
||||
_collectionResolver = collectionResolver;
|
||||
Task = hooks.CreateHook<Delegate>("Dismount", Sigs.Dismount, Detour, HookSettings.VfxIdentificationHooks);
|
||||
Task = hooks.CreateHook<Delegate>("Dismount", Sigs.Dismount, Detour, !HookOverrides.Instance.Animation.Dismount);
|
||||
}
|
||||
|
||||
public delegate void Delegate(MountContainer* a1, nint a2);
|
||||
|
|
|
|||
|
|
@ -17,10 +17,10 @@ public sealed unsafe class LoadAreaVfx : FastHook<LoadAreaVfx.Delegate>
|
|||
|
||||
public LoadAreaVfx(HookManager hooks, GameState state, CollectionResolver collectionResolver, CrashHandlerService crashHandler)
|
||||
{
|
||||
_state = state;
|
||||
_state = state;
|
||||
_collectionResolver = collectionResolver;
|
||||
_crashHandler = crashHandler;
|
||||
Task = hooks.CreateHook<Delegate>("Load Area VFX", Sigs.LoadAreaVfx, Detour, HookSettings.VfxIdentificationHooks);
|
||||
_crashHandler = crashHandler;
|
||||
Task = hooks.CreateHook<Delegate>("Load Area VFX", Sigs.LoadAreaVfx, Detour, !HookOverrides.Instance.Animation.LoadAreaVfx);
|
||||
}
|
||||
|
||||
public delegate nint Delegate(uint vfxId, float* pos, GameObject* caster, float unk1, float unk2, byte unk3);
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ public sealed unsafe class LoadCharacterSound : FastHook<LoadCharacterSound.Dele
|
|||
_collectionResolver = collectionResolver;
|
||||
_crashHandler = crashHandler;
|
||||
Task = hooks.CreateHook<Delegate>("Load Character Sound", (nint)VfxContainer.MemberFunctionPointers.LoadCharacterSound, Detour,
|
||||
HookSettings.VfxIdentificationHooks);
|
||||
!HookOverrides.Instance.Animation.LoadCharacterSound);
|
||||
}
|
||||
|
||||
public delegate nint Delegate(VfxContainer* container, int unk1, int unk2, nint unk3, ulong unk4, int unk5, int unk6, ulong unk7);
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ public sealed unsafe class LoadCharacterVfx : FastHook<LoadCharacterVfx.Delegate
|
|||
_collectionResolver = collectionResolver;
|
||||
_objects = objects;
|
||||
_crashHandler = crashHandler;
|
||||
Task = hooks.CreateHook<Delegate>("Load Character VFX", Sigs.LoadCharacterVfx, Detour, HookSettings.VfxIdentificationHooks);
|
||||
Task = hooks.CreateHook<Delegate>("Load Character VFX", Sigs.LoadCharacterVfx, Detour, !HookOverrides.Instance.Animation.LoadCharacterVfx);
|
||||
}
|
||||
|
||||
public delegate nint Delegate(byte* vfxPath, VfxParams* vfxParams, byte unk1, byte unk2, float unk3, int unk4);
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ public sealed unsafe class LoadTimelineResources : FastHook<LoadTimelineResource
|
|||
_conditions = conditions;
|
||||
_objects = objects;
|
||||
_crashHandler = crashHandler;
|
||||
Task = hooks.CreateHook<Delegate>("Load Timeline Resources", Sigs.LoadTimelineResources, Detour, HookSettings.VfxIdentificationHooks);
|
||||
Task = hooks.CreateHook<Delegate>("Load Timeline Resources", Sigs.LoadTimelineResources, Detour, !HookOverrides.Instance.Animation.LoadTimelineResources);
|
||||
}
|
||||
|
||||
public delegate ulong Delegate(SchedulerTimeline* timeline);
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ public sealed unsafe class PlayFootstep : FastHook<PlayFootstep.Delegate>
|
|||
{
|
||||
_state = state;
|
||||
_collectionResolver = collectionResolver;
|
||||
Task = hooks.CreateHook<Delegate>("Play Footstep", Sigs.FootStepSound, Detour, HookSettings.VfxIdentificationHooks);
|
||||
Task = hooks.CreateHook<Delegate>("Play Footstep", Sigs.FootStepSound, Detour, !HookOverrides.Instance.Animation.PlayFootstep);
|
||||
}
|
||||
|
||||
public delegate void Delegate(GameObject* gameObject, int id, int unk);
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ public sealed unsafe class ScheduleClipUpdate : FastHook<ScheduleClipUpdate.Dele
|
|||
_collectionResolver = collectionResolver;
|
||||
_objects = objects;
|
||||
_crashHandler = crashHandler;
|
||||
Task = hooks.CreateHook<Delegate>("Schedule Clip Update", Sigs.ScheduleClipUpdate, Detour, HookSettings.VfxIdentificationHooks);
|
||||
Task = hooks.CreateHook<Delegate>("Schedule Clip Update", Sigs.ScheduleClipUpdate, Detour, !HookOverrides.Instance.Animation.ScheduleClipUpdate);
|
||||
}
|
||||
|
||||
public delegate void Delegate(ClipScheduler* x);
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ public sealed unsafe class SomeActionLoad : FastHook<SomeActionLoad.Delegate>
|
|||
_state = state;
|
||||
_collectionResolver = collectionResolver;
|
||||
_crashHandler = crashHandler;
|
||||
Task = hooks.CreateHook<Delegate>("Some Action Load", Sigs.LoadSomeAction, Detour, HookSettings.VfxIdentificationHooks);
|
||||
Task = hooks.CreateHook<Delegate>("Some Action Load", Sigs.LoadSomeAction, Detour, !HookOverrides.Instance.Animation.SomeActionLoad);
|
||||
}
|
||||
|
||||
public delegate void Delegate(TimelineContainer* timelineManager);
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ public sealed unsafe class SomeMountAnimation : FastHook<SomeMountAnimation.Dele
|
|||
{
|
||||
_state = state;
|
||||
_collectionResolver = collectionResolver;
|
||||
Task = hooks.CreateHook<Delegate>("Some Mount Animation", Sigs.UnkMountAnimation, Detour, HookSettings.VfxIdentificationHooks);
|
||||
Task = hooks.CreateHook<Delegate>("Some Mount Animation", Sigs.UnkMountAnimation, Detour, !HookOverrides.Instance.Animation.SomeMountAnimation);
|
||||
}
|
||||
|
||||
public delegate void Delegate(DrawObject* drawObject, uint unk1, byte unk2, uint unk3);
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ public sealed unsafe class SomePapLoad : FastHook<SomePapLoad.Delegate>
|
|||
_collectionResolver = collectionResolver;
|
||||
_objects = objects;
|
||||
_crashHandler = crashHandler;
|
||||
Task = hooks.CreateHook<Delegate>("Some PAP Load", Sigs.LoadSomePap, Detour, HookSettings.VfxIdentificationHooks);
|
||||
Task = hooks.CreateHook<Delegate>("Some PAP Load", Sigs.LoadSomePap, Detour, !HookOverrides.Instance.Animation.SomePapLoad);
|
||||
}
|
||||
|
||||
public delegate void Delegate(nint a1, int a2, nint a3, int a4);
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ public sealed unsafe class SomeParasolAnimation : FastHook<SomeParasolAnimation.
|
|||
{
|
||||
_state = state;
|
||||
_collectionResolver = collectionResolver;
|
||||
Task = hooks.CreateHook<Delegate>("Some Parasol Animation", Sigs.UnkParasolAnimation, Detour, HookSettings.VfxIdentificationHooks);
|
||||
Task = hooks.CreateHook<Delegate>("Some Parasol Animation", Sigs.UnkParasolAnimation, Detour, !HookOverrides.Instance.Animation.SomeParasolAnimation);
|
||||
}
|
||||
|
||||
public delegate void Delegate(DrawObject* drawObject, int unk1);
|
||||
|
|
|
|||
|
|
@ -1,14 +1,140 @@
|
|||
using Dalamud.Plugin;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Penumbra.Interop.Hooks;
|
||||
|
||||
public static class HookSettings
|
||||
public class HookOverrides
|
||||
{
|
||||
public const bool AllHooks = true;
|
||||
public static HookOverrides Instance = new();
|
||||
|
||||
public const bool ObjectHooks = true && AllHooks;
|
||||
public const bool ReplacementHooks = true && AllHooks;
|
||||
public const bool ResourceHooks = true && AllHooks;
|
||||
public const bool MetaEntryHooks = true && AllHooks;
|
||||
public const bool MetaParentHooks = true && AllHooks;
|
||||
public const bool VfxIdentificationHooks = true && AllHooks;
|
||||
public const bool PostProcessingHooks = true && AllHooks;
|
||||
public AnimationHooks Animation;
|
||||
public MetaHooks Meta;
|
||||
public ObjectHooks Objects;
|
||||
public PostProcessingHooks PostProcessing;
|
||||
public ResourceLoadingHooks ResourceLoading;
|
||||
public ResourceHooks Resources;
|
||||
|
||||
public HookOverrides Clone()
|
||||
=> new()
|
||||
{
|
||||
Animation = Animation,
|
||||
Meta = Meta,
|
||||
Objects = Objects,
|
||||
PostProcessing = PostProcessing,
|
||||
ResourceLoading = ResourceLoading,
|
||||
Resources = Resources,
|
||||
};
|
||||
|
||||
public struct AnimationHooks
|
||||
{
|
||||
public bool ApricotListenerSoundPlayCaller;
|
||||
public bool CharacterBaseLoadAnimation;
|
||||
public bool Dismount;
|
||||
public bool LoadAreaVfx;
|
||||
public bool LoadCharacterSound;
|
||||
public bool LoadCharacterVfx;
|
||||
public bool LoadTimelineResources;
|
||||
public bool PlayFootstep;
|
||||
public bool ScheduleClipUpdate;
|
||||
public bool SomeActionLoad;
|
||||
public bool SomeMountAnimation;
|
||||
public bool SomePapLoad;
|
||||
public bool SomeParasolAnimation;
|
||||
}
|
||||
|
||||
public struct MetaHooks
|
||||
{
|
||||
public bool CalculateHeight;
|
||||
public bool ChangeCustomize;
|
||||
public bool EqdpAccessoryHook;
|
||||
public bool EqdpEquipHook;
|
||||
public bool EqpHook;
|
||||
public bool EstHook;
|
||||
public bool GmpHook;
|
||||
public bool ModelLoadComplete;
|
||||
public bool RspBustHook;
|
||||
public bool RspHeightHook;
|
||||
public bool RspSetupCharacter;
|
||||
public bool RspTailHook;
|
||||
public bool SetupVisor;
|
||||
public bool UpdateModel;
|
||||
public bool UpdateRender;
|
||||
}
|
||||
|
||||
public struct ObjectHooks
|
||||
{
|
||||
public bool CharacterBaseDestructor;
|
||||
public bool CharacterDestructor;
|
||||
public bool CopyCharacter;
|
||||
public bool CreateCharacterBase;
|
||||
public bool EnableDraw;
|
||||
public bool WeaponReload;
|
||||
}
|
||||
|
||||
public struct PostProcessingHooks
|
||||
{
|
||||
public bool HumanSetupScaling;
|
||||
public bool HumanCreateDeformer;
|
||||
public bool HumanOnRenderMaterial;
|
||||
public bool ModelRendererOnRenderMaterial;
|
||||
}
|
||||
|
||||
public struct ResourceLoadingHooks
|
||||
{
|
||||
public bool CreateFileWHook;
|
||||
public bool PapHooks;
|
||||
public bool ReadSqPack;
|
||||
public bool IncRef;
|
||||
public bool DecRef;
|
||||
public bool GetResourceSync;
|
||||
public bool GetResourceAsync;
|
||||
public bool CheckFileState;
|
||||
public bool TexResourceHandleOnLoad;
|
||||
public bool LoadMdlFileExtern;
|
||||
}
|
||||
|
||||
public struct ResourceHooks
|
||||
{
|
||||
public bool ApricotResourceLoad;
|
||||
public bool LoadMtrlShpk;
|
||||
public bool LoadMtrlTex;
|
||||
public bool ResolvePathHooks;
|
||||
public bool ResourceHandleDestructor;
|
||||
}
|
||||
|
||||
public const string FileName = "HookOverrides.json";
|
||||
|
||||
public static HookOverrides LoadFile(IDalamudPluginInterface pi)
|
||||
{
|
||||
var path = Path.Combine(pi.GetPluginConfigDirectory(), FileName);
|
||||
if (!File.Exists(path))
|
||||
return new HookOverrides();
|
||||
|
||||
try
|
||||
{
|
||||
var text = File.ReadAllText(path);
|
||||
var ret = JsonConvert.DeserializeObject<HookOverrides>(text);
|
||||
Penumbra.Log.Warning("A hook override file was loaded, some hooks may be disabled and Penumbra might not be working as expected.");
|
||||
return ret;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Penumbra.Log.Error($"A hook override file was found at {path}, but could not be loaded:\n{ex}");
|
||||
return new HookOverrides();
|
||||
}
|
||||
}
|
||||
|
||||
public void Write(IDalamudPluginInterface pi)
|
||||
{
|
||||
var path = Path.Combine(pi.GetPluginConfigDirectory(), FileName);
|
||||
try
|
||||
{
|
||||
var text = JsonConvert.SerializeObject(this, Formatting.Indented);
|
||||
File.WriteAllText(path, text);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Penumbra.Log.Error($"Could not write hook override file to {path}:\n{ex}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ public sealed unsafe class CalculateHeight : FastHook<CalculateHeight.Delegate>
|
|||
{
|
||||
_collectionResolver = collectionResolver;
|
||||
_metaState = metaState;
|
||||
Task = hooks.CreateHook<Delegate>("Calculate Height", (nint)Character.MemberFunctionPointers.CalculateHeight, Detour, HookSettings.MetaParentHooks);
|
||||
Task = hooks.CreateHook<Delegate>("Calculate Height", (nint)Character.MemberFunctionPointers.CalculateHeight, Detour, !HookOverrides.Instance.Meta.CalculateHeight);
|
||||
}
|
||||
|
||||
public delegate ulong Delegate(Character* character);
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ public sealed unsafe class ChangeCustomize : FastHook<ChangeCustomize.Delegate>
|
|||
{
|
||||
_collectionResolver = collectionResolver;
|
||||
_metaState = metaState;
|
||||
Task = hooks.CreateHook<Delegate>("Change Customize", Sigs.ChangeCustomize, Detour, HookSettings.MetaParentHooks);
|
||||
Task = hooks.CreateHook<Delegate>("Change Customize", Sigs.ChangeCustomize, Detour, !HookOverrides.Instance.Meta.ChangeCustomize);
|
||||
}
|
||||
|
||||
public delegate bool Delegate(Human* human, CustomizeArray* data, byte skipEquipment);
|
||||
|
|
|
|||
|
|
@ -16,8 +16,10 @@ public unsafe class EqdpAccessoryHook : FastHook<EqdpAccessoryHook.Delegate>, ID
|
|||
public EqdpAccessoryHook(HookManager hooks, MetaState metaState)
|
||||
{
|
||||
_metaState = metaState;
|
||||
Task = hooks.CreateHook<Delegate>("GetEqdpAccessoryEntry", Sigs.GetEqdpAccessoryEntry, Detour, metaState.Config.EnableMods && HookSettings.MetaEntryHooks);
|
||||
_metaState.Config.ModsEnabled += Toggle;
|
||||
Task = hooks.CreateHook<Delegate>("GetEqdpAccessoryEntry", Sigs.GetEqdpAccessoryEntry, Detour,
|
||||
metaState.Config.EnableMods && !HookOverrides.Instance.Meta.EqdpAccessoryHook);
|
||||
if (!HookOverrides.Instance.Meta.EqdpAccessoryHook)
|
||||
_metaState.Config.ModsEnabled += Toggle;
|
||||
}
|
||||
|
||||
private void Detour(CharacterUtility* utility, EqdpEntry* entry, uint setId, uint raceCode)
|
||||
|
|
|
|||
|
|
@ -16,8 +16,9 @@ public unsafe class EqdpEquipHook : FastHook<EqdpEquipHook.Delegate>, IDisposabl
|
|||
public EqdpEquipHook(HookManager hooks, MetaState metaState)
|
||||
{
|
||||
_metaState = metaState;
|
||||
Task = hooks.CreateHook<Delegate>("GetEqdpEquipEntry", Sigs.GetEqdpEquipEntry, Detour, metaState.Config.EnableMods && HookSettings.MetaEntryHooks);
|
||||
_metaState.Config.ModsEnabled += Toggle;
|
||||
Task = hooks.CreateHook<Delegate>("GetEqdpEquipEntry", Sigs.GetEqdpEquipEntry, Detour, metaState.Config.EnableMods && !HookOverrides.Instance.Meta.EqdpEquipHook);
|
||||
if (!HookOverrides.Instance.Meta.EqdpEquipHook)
|
||||
_metaState.Config.ModsEnabled += Toggle;
|
||||
}
|
||||
|
||||
private void Detour(CharacterUtility* utility, EqdpEntry* entry, uint setId, uint raceCode)
|
||||
|
|
|
|||
|
|
@ -15,8 +15,10 @@ public unsafe class EqpHook : FastHook<EqpHook.Delegate>, IDisposable
|
|||
public EqpHook(HookManager hooks, MetaState metaState)
|
||||
{
|
||||
_metaState = metaState;
|
||||
Task = hooks.CreateHook<Delegate>("GetEqpFlags", Sigs.GetEqpEntry, Detour, metaState.Config.EnableMods && HookSettings.MetaEntryHooks);
|
||||
_metaState.Config.ModsEnabled += Toggle;
|
||||
Task = hooks.CreateHook<Delegate>("GetEqpFlags", Sigs.GetEqpEntry, Detour,
|
||||
metaState.Config.EnableMods && !HookOverrides.Instance.Meta.EqpHook);
|
||||
if (!HookOverrides.Instance.Meta.EqpHook)
|
||||
_metaState.Config.ModsEnabled += Toggle;
|
||||
}
|
||||
|
||||
private void Detour(CharacterUtility* utility, EqpEntry* flags, CharacterArmor* armor)
|
||||
|
|
|
|||
|
|
@ -21,8 +21,9 @@ public unsafe class EstHook : FastHook<EstHook.Delegate>, IDisposable
|
|||
_metaState = metaState;
|
||||
_characterUtility = characterUtility;
|
||||
Task = hooks.CreateHook<Delegate>("FindEstEntry", Sigs.FindEstEntry, Detour,
|
||||
metaState.Config.EnableMods && HookSettings.MetaEntryHooks);
|
||||
_metaState.Config.ModsEnabled += Toggle;
|
||||
metaState.Config.EnableMods && !HookOverrides.Instance.Meta.EstHook);
|
||||
if (!HookOverrides.Instance.Meta.EstHook)
|
||||
_metaState.Config.ModsEnabled += Toggle;
|
||||
}
|
||||
|
||||
private EstEntry Detour(ResourceHandle* estResource, uint genderRace, uint id)
|
||||
|
|
|
|||
|
|
@ -17,8 +17,10 @@ public unsafe class GmpHook : FastHook<GmpHook.Delegate>, IDisposable
|
|||
public GmpHook(HookManager hooks, MetaState metaState)
|
||||
{
|
||||
_metaState = metaState;
|
||||
Task = hooks.CreateHook<Delegate>("GetGmpEntry", Sigs.GetGmpEntry, Detour, metaState.Config.EnableMods && HookSettings.MetaEntryHooks);
|
||||
_metaState.Config.ModsEnabled += Toggle;
|
||||
Task = hooks.CreateHook<Delegate>("GetGmpEntry", Sigs.GetGmpEntry, Detour,
|
||||
metaState.Config.EnableMods && !HookOverrides.Instance.Meta.GmpHook);
|
||||
if (!HookOverrides.Instance.Meta.GmpHook)
|
||||
_metaState.Config.ModsEnabled += Toggle;
|
||||
}
|
||||
|
||||
private ulong Detour(CharacterUtility* characterUtility, ulong* outputEntry, ushort setId)
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ public sealed unsafe class ModelLoadComplete : FastHook<ModelLoadComplete.Delega
|
|||
{
|
||||
_collectionResolver = collectionResolver;
|
||||
_metaState = metaState;
|
||||
Task = hooks.CreateHook<Delegate>("Model Load Complete", vtables.HumanVTable[59], Detour, HookSettings.MetaParentHooks);
|
||||
Task = hooks.CreateHook<Delegate>("Model Load Complete", vtables.HumanVTable[59], Detour, !HookOverrides.Instance.Meta.ModelLoadComplete);
|
||||
}
|
||||
|
||||
public delegate void Delegate(DrawObject* drawObject);
|
||||
|
|
|
|||
|
|
@ -19,8 +19,10 @@ public unsafe class RspBustHook : FastHook<RspBustHook.Delegate>, IDisposable
|
|||
{
|
||||
_metaState = metaState;
|
||||
_metaFileManager = metaFileManager;
|
||||
Task = hooks.CreateHook<Delegate>("GetRspBust", Sigs.GetRspBust, Detour, metaState.Config.EnableMods && HookSettings.MetaEntryHooks);
|
||||
_metaState.Config.ModsEnabled += Toggle;
|
||||
Task = hooks.CreateHook<Delegate>("GetRspBust", Sigs.GetRspBust, Detour,
|
||||
metaState.Config.EnableMods && !HookOverrides.Instance.Meta.RspBustHook);
|
||||
if (!HookOverrides.Instance.Meta.RspBustHook)
|
||||
_metaState.Config.ModsEnabled += Toggle;
|
||||
}
|
||||
|
||||
private float* Detour(nint cmpResource, float* storage, SubRace clan, byte gender, byte bodyType, byte bustSize)
|
||||
|
|
@ -34,7 +36,9 @@ public unsafe class RspBustHook : FastHook<RspBustHook.Delegate>, IDisposable
|
|||
}
|
||||
|
||||
var ret = storage;
|
||||
if (bodyType < 2 && _metaState.RspCollection.TryPeek(out var collection) && collection is { Valid: true, ModCollection.MetaCache: { } cache })
|
||||
if (bodyType < 2
|
||||
&& _metaState.RspCollection.TryPeek(out var collection)
|
||||
&& collection is { Valid: true, ModCollection.MetaCache: { } cache })
|
||||
{
|
||||
var bustScale = bustSize / 100f;
|
||||
var ptr = CmpFile.GetDefaults(_metaFileManager, clan, RspAttribute.BustMinX);
|
||||
|
|
|
|||
|
|
@ -17,10 +17,12 @@ public class RspHeightHook : FastHook<RspHeightHook.Delegate>, IDisposable
|
|||
|
||||
public RspHeightHook(HookManager hooks, MetaState metaState, MetaFileManager metaFileManager)
|
||||
{
|
||||
_metaState = metaState;
|
||||
_metaState = metaState;
|
||||
_metaFileManager = metaFileManager;
|
||||
Task = hooks.CreateHook<Delegate>("GetRspHeight", Sigs.GetRspHeight, Detour, metaState.Config.EnableMods && HookSettings.MetaEntryHooks);
|
||||
_metaState.Config.ModsEnabled += Toggle;
|
||||
Task = hooks.CreateHook<Delegate>("GetRspHeight", Sigs.GetRspHeight, Detour,
|
||||
metaState.Config.EnableMods && !HookOverrides.Instance.Meta.RspHeightHook);
|
||||
if (!HookOverrides.Instance.Meta.RspHeightHook)
|
||||
_metaState.Config.ModsEnabled += Toggle;
|
||||
}
|
||||
|
||||
private unsafe float Detour(nint cmpResource, SubRace clan, byte gender, byte bodyType, byte height)
|
||||
|
|
@ -33,6 +35,7 @@ public class RspHeightHook : FastHook<RspHeightHook.Delegate>, IDisposable
|
|||
// Special cases.
|
||||
if (height == 0xFF)
|
||||
return 1.0f;
|
||||
|
||||
if (height > 100)
|
||||
height = 0;
|
||||
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ public sealed unsafe class RspSetupCharacter : FastHook<RspSetupCharacter.Delega
|
|||
{
|
||||
_collectionResolver = collectionResolver;
|
||||
_metaState = metaState;
|
||||
Task = hooks.CreateHook<Delegate>("RSP Setup Character", Sigs.RspSetupCharacter, Detour, HookSettings.MetaParentHooks);
|
||||
Task = hooks.CreateHook<Delegate>("RSP Setup Character", Sigs.RspSetupCharacter, Detour, !HookOverrides.Instance.Meta.RspSetupCharacter);
|
||||
}
|
||||
|
||||
public delegate void Delegate(DrawObject* drawObject, nint unk2, float unk3, nint unk4, byte unk5);
|
||||
|
|
|
|||
|
|
@ -19,14 +19,18 @@ public class RspTailHook : FastHook<RspTailHook.Delegate>, IDisposable
|
|||
{
|
||||
_metaState = metaState;
|
||||
_metaFileManager = metaFileManager;
|
||||
Task = hooks.CreateHook<Delegate>("GetRspTail", Sigs.GetRspTail, Detour, metaState.Config.EnableMods && HookSettings.MetaEntryHooks);
|
||||
_metaState.Config.ModsEnabled += Toggle;
|
||||
Task = hooks.CreateHook<Delegate>("GetRspTail", Sigs.GetRspTail, Detour,
|
||||
metaState.Config.EnableMods && !HookOverrides.Instance.Meta.RspTailHook);
|
||||
if (!HookOverrides.Instance.Meta.RspTailHook)
|
||||
_metaState.Config.ModsEnabled += Toggle;
|
||||
}
|
||||
|
||||
private unsafe float Detour(nint cmpResource, Race race, byte gender, byte isSecondSubRace, byte bodyType, byte tailLength)
|
||||
{
|
||||
float scale;
|
||||
if (bodyType < 2 && _metaState.RspCollection.TryPeek(out var collection) && collection is { Valid: true, ModCollection.MetaCache: { } cache })
|
||||
if (bodyType < 2
|
||||
&& _metaState.RspCollection.TryPeek(out var collection)
|
||||
&& collection is { Valid: true, ModCollection.MetaCache: { } cache })
|
||||
{
|
||||
var clan = (SubRace)(((int)race - 1) * 2 + 1 + isSecondSubRace);
|
||||
var (minIdent, maxIdent) = gender == 0
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ public sealed unsafe class SetupVisor : FastHook<SetupVisor.Delegate>
|
|||
{
|
||||
_collectionResolver = collectionResolver;
|
||||
_metaState = metaState;
|
||||
Task = hooks.CreateHook<Delegate>("Setup Visor", Sigs.SetupVisor, Detour, HookSettings.MetaParentHooks);
|
||||
Task = hooks.CreateHook<Delegate>("Setup Visor", Sigs.SetupVisor, Detour, !HookOverrides.Instance.Meta.SetupVisor);
|
||||
}
|
||||
|
||||
public delegate byte Delegate(DrawObject* drawObject, ushort modelId, byte visorState);
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ public sealed unsafe class UpdateModel : FastHook<UpdateModel.Delegate>
|
|||
{
|
||||
_collectionResolver = collectionResolver;
|
||||
_metaState = metaState;
|
||||
Task = hooks.CreateHook<Delegate>("Update Model", Sigs.UpdateModel, Detour, HookSettings.MetaParentHooks);
|
||||
Task = hooks.CreateHook<Delegate>("Update Model", Sigs.UpdateModel, Detour, !HookOverrides.Instance.Meta.UpdateModel);
|
||||
}
|
||||
|
||||
public delegate void Delegate(DrawObject* drawObject);
|
||||
|
|
|
|||
|
|
@ -13,8 +13,8 @@ public sealed unsafe class UpdateRender : FastHook<UpdateRender.Delegate>
|
|||
public UpdateRender(HookManager hooks, CollectionResolver collectionResolver, MetaState metaState, CharacterBaseVTables vTables)
|
||||
{
|
||||
_collectionResolver = collectionResolver;
|
||||
_metaState = metaState;
|
||||
Task = hooks.CreateHook<Delegate>("Human.UpdateRender", vTables.HumanVTable[4], Detour, HookSettings.MetaParentHooks);
|
||||
_metaState = metaState;
|
||||
Task = hooks.CreateHook<Delegate>("Human.UpdateRender", vTables.HumanVTable[4], Detour, !HookOverrides.Instance.Meta.UpdateRender);
|
||||
}
|
||||
|
||||
public delegate void Delegate(DrawObject* drawObject);
|
||||
|
|
|
|||
|
|
@ -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, HookSettings.ObjectHooks);
|
||||
=> _task = hooks.CreateHook<Delegate>(Name, Address, Detour, !HookOverrides.Instance.Objects.CharacterBaseDestructor);
|
||||
|
||||
private readonly Task<Hook<Delegate>> _task;
|
||||
|
||||
|
|
|
|||
|
|
@ -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, HookSettings.ObjectHooks);
|
||||
=> _task = hooks.CreateHook<Delegate>(Name, Sigs.CharacterDestructor, Detour, !HookOverrides.Instance.Objects.CharacterDestructor);
|
||||
|
||||
private readonly Task<Hook<Delegate>> _task;
|
||||
|
||||
|
|
|
|||
|
|
@ -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, HookSettings.ObjectHooks);
|
||||
=> _task = hooks.CreateHook<Delegate>(Name, Address, Detour, !HookOverrides.Instance.Objects.CopyCharacter);
|
||||
|
||||
private readonly Task<Hook<Delegate>> _task;
|
||||
|
||||
|
|
|
|||
|
|
@ -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, HookSettings.ObjectHooks);
|
||||
=> _task = hooks.CreateHook<Delegate>(Name, Address, Detour, !HookOverrides.Instance.Objects.CreateCharacterBase);
|
||||
|
||||
private readonly Task<Hook<Delegate>> _task;
|
||||
|
||||
|
|
|
|||
|
|
@ -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, HookSettings.ObjectHooks);
|
||||
_task = hooks.CreateHook<Delegate>("Enable Draw", Sigs.EnableDraw, Detour, !HookOverrides.Instance.Objects.EnableDraw);
|
||||
}
|
||||
|
||||
private delegate void Delegate(GameObject* gameObject);
|
||||
|
|
|
|||
|
|
@ -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, HookSettings.ObjectHooks);
|
||||
=> _task = hooks.CreateHook<Delegate>(Name, Address, Detour, !HookOverrides.Instance.Objects.WeaponReload);
|
||||
|
||||
private readonly Task<Hook<Delegate>> _task;
|
||||
|
||||
|
|
|
|||
|
|
@ -38,9 +38,9 @@ public sealed unsafe class PreBoneDeformerReplacer : IDisposable, IRequiredServi
|
|||
_resourceLoader = resourceLoader;
|
||||
_framework = framework;
|
||||
_humanSetupScalingHook = hooks.CreateHook<CharacterBaseSetupScalingDelegate>("HumanSetupScaling", vTables.HumanVTable[58], SetupScaling,
|
||||
HookSettings.PostProcessingHooks).Result;
|
||||
!HookOverrides.Instance.PostProcessing.HumanSetupScaling).Result;
|
||||
_humanCreateDeformerHook = hooks.CreateHook<CharacterBaseCreateDeformerDelegate>("HumanCreateDeformer", vTables.HumanVTable[101],
|
||||
CreateDeformer, HookSettings.PostProcessingHooks).Result;
|
||||
CreateDeformer, !HookOverrides.Instance.PostProcessing.HumanCreateDeformer).Result;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
|
|
|
|||
|
|
@ -90,20 +90,26 @@ public sealed unsafe class ShaderReplacementFixer : IDisposable, IRequiredServic
|
|||
_modelRenderer = modelRenderer;
|
||||
_communicator = communicator;
|
||||
|
||||
_skinState = new(
|
||||
_skinState = new ModdedShaderPackageState(
|
||||
() => (ShaderPackageResourceHandle**)&_utility.Address->SkinShpkResource,
|
||||
() => (ShaderPackageResourceHandle*)_utility.DefaultSkinShpkResource);
|
||||
_irisState = new(() => _modelRenderer.IrisShaderPackage, () => _modelRenderer.DefaultIrisShaderPackage);
|
||||
_characterGlassState = new(() => _modelRenderer.CharacterGlassShaderPackage, () => _modelRenderer.DefaultCharacterGlassShaderPackage);
|
||||
_characterTransparencyState = new(() => _modelRenderer.CharacterTransparencyShaderPackage, () => _modelRenderer.DefaultCharacterTransparencyShaderPackage);
|
||||
_characterTattooState = new(() => _modelRenderer.CharacterTattooShaderPackage, () => _modelRenderer.DefaultCharacterTattooShaderPackage);
|
||||
_characterOcclusionState = new(() => _modelRenderer.CharacterOcclusionShaderPackage, () => _modelRenderer.DefaultCharacterOcclusionShaderPackage);
|
||||
_hairMaskState = new(() => _modelRenderer.HairMaskShaderPackage, () => _modelRenderer.DefaultHairMaskShaderPackage);
|
||||
_irisState = new ModdedShaderPackageState(() => _modelRenderer.IrisShaderPackage, () => _modelRenderer.DefaultIrisShaderPackage);
|
||||
_characterGlassState = new ModdedShaderPackageState(() => _modelRenderer.CharacterGlassShaderPackage,
|
||||
() => _modelRenderer.DefaultCharacterGlassShaderPackage);
|
||||
_characterTransparencyState = new ModdedShaderPackageState(() => _modelRenderer.CharacterTransparencyShaderPackage,
|
||||
() => _modelRenderer.DefaultCharacterTransparencyShaderPackage);
|
||||
_characterTattooState = new ModdedShaderPackageState(() => _modelRenderer.CharacterTattooShaderPackage,
|
||||
() => _modelRenderer.DefaultCharacterTattooShaderPackage);
|
||||
_characterOcclusionState = new ModdedShaderPackageState(() => _modelRenderer.CharacterOcclusionShaderPackage,
|
||||
() => _modelRenderer.DefaultCharacterOcclusionShaderPackage);
|
||||
_hairMaskState =
|
||||
new ModdedShaderPackageState(() => _modelRenderer.HairMaskShaderPackage, () => _modelRenderer.DefaultHairMaskShaderPackage);
|
||||
|
||||
_humanOnRenderMaterialHook = hooks.CreateHook<CharacterBaseOnRenderMaterialDelegate>("Human.OnRenderMaterial", vTables.HumanVTable[64],
|
||||
OnRenderHumanMaterial, HookSettings.PostProcessingHooks).Result;
|
||||
OnRenderHumanMaterial, !HookOverrides.Instance.PostProcessing.HumanOnRenderMaterial).Result;
|
||||
_modelRendererOnRenderMaterialHook = hooks.CreateHook<ModelRendererOnRenderMaterialDelegate>("ModelRenderer.OnRenderMaterial",
|
||||
Sigs.ModelRendererOnRenderMaterial, ModelRendererOnRenderMaterialDetour, HookSettings.PostProcessingHooks).Result;
|
||||
Sigs.ModelRendererOnRenderMaterial, ModelRendererOnRenderMaterialDetour,
|
||||
!HookOverrides.Instance.PostProcessing.ModelRendererOnRenderMaterial).Result;
|
||||
_communicator.MtrlShpkLoaded.Subscribe(OnMtrlShpkLoaded, MtrlShpkLoaded.Priority.ShaderReplacementFixer);
|
||||
_resourceHandleDestructor.Subscribe(OnResourceHandleDestructor, ResourceHandleDestructor.Priority.ShaderReplacementFixer);
|
||||
}
|
||||
|
|
@ -123,7 +129,8 @@ public sealed unsafe class ShaderReplacementFixer : IDisposable, IRequiredServic
|
|||
_skinState.ClearMaterials();
|
||||
}
|
||||
|
||||
public (ulong Skin, ulong Iris, ulong CharacterGlass, ulong CharacterTransparency, ulong CharacterTattoo, ulong CharacterOcclusion, ulong HairMask) GetAndResetSlowPathCallDeltas()
|
||||
public (ulong Skin, ulong Iris, ulong CharacterGlass, ulong CharacterTransparency, ulong CharacterTattoo, ulong CharacterOcclusion, ulong
|
||||
HairMask) GetAndResetSlowPathCallDeltas()
|
||||
=> (_skinState.GetAndResetSlowPathCallDelta(),
|
||||
_irisState.GetAndResetSlowPathCallDelta(),
|
||||
_characterGlassState.GetAndResetSlowPathCallDelta(),
|
||||
|
|
@ -208,7 +215,12 @@ public sealed unsafe class ShaderReplacementFixer : IDisposable, IRequiredServic
|
|||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
|
||||
private uint GetTotalMaterialCountForModelRenderer()
|
||||
=> _irisState.MaterialCount + _characterGlassState.MaterialCount + _characterTransparencyState.MaterialCount + _characterTattooState.MaterialCount + _characterOcclusionState.MaterialCount + _hairMaskState.MaterialCount;
|
||||
=> _irisState.MaterialCount
|
||||
+ _characterGlassState.MaterialCount
|
||||
+ _characterTransparencyState.MaterialCount
|
||||
+ _characterTattooState.MaterialCount
|
||||
+ _characterOcclusionState.MaterialCount
|
||||
+ _hairMaskState.MaterialCount;
|
||||
|
||||
private nint OnRenderHumanMaterial(CharacterBase* human, CSModelRenderer.OnRenderMaterialParams* param)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -19,7 +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)
|
||||
if (!HookOverrides.Instance.ResourceLoading.CreateFileWHook)
|
||||
_createFileWHook.Enable();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ public unsafe class FileReadService : IDisposable, IRequiredService
|
|||
_resourceManager = resourceManager;
|
||||
_performance = performance;
|
||||
interop.InitializeFromAttributes(this);
|
||||
if (HookSettings.ReplacementHooks)
|
||||
if (!HookOverrides.Instance.ResourceLoading.ReadSqPack)
|
||||
_readSqPackHook.Enable();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4,10 +4,11 @@ namespace Penumbra.Interop.Hooks.ResourceLoading;
|
|||
|
||||
public class MappedCodeReader(UnmanagedMemoryAccessor data, long offset) : CodeReader
|
||||
{
|
||||
public override int ReadByte() {
|
||||
if (offset >= data.Capacity)
|
||||
return -1;
|
||||
public override int ReadByte()
|
||||
{
|
||||
if (offset >= data.Capacity)
|
||||
return -1;
|
||||
|
||||
return data.ReadByte(offset++);
|
||||
}
|
||||
return data.ReadByte(offset++);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,9 @@ public sealed class PapHandler(PapRewriter.PapResourceHandlerPrototype papResour
|
|||
|
||||
public void Enable()
|
||||
{
|
||||
if (HookOverrides.Instance.ResourceLoading.PapHooks)
|
||||
return;
|
||||
|
||||
ReadOnlySpan<(string Sig, string Name)> signatures =
|
||||
[
|
||||
(Sigs.LoadAlwaysResidentMotionPacks, nameof(Sigs.LoadAlwaysResidentMotionPacks)),
|
||||
|
|
|
|||
|
|
@ -14,7 +14,6 @@ public unsafe class PeSigScanner : IDisposable
|
|||
private readonly nint _moduleBaseAddress;
|
||||
private readonly uint _textSectionVirtualAddress;
|
||||
|
||||
|
||||
public PeSigScanner()
|
||||
{
|
||||
var mainModule = Process.GetCurrentProcess().MainModule!;
|
||||
|
|
|
|||
|
|
@ -30,13 +30,14 @@ public unsafe class ResourceService : IDisposable, IRequiredService
|
|||
_decRefHook = interop.HookFromAddress<ResourceHandleDecRefPrototype>(
|
||||
(nint)CSResourceHandle.MemberFunctionPointers.DecRef,
|
||||
ResourceHandleDecRefDetour);
|
||||
if (HookSettings.ReplacementHooks)
|
||||
{
|
||||
if (HookOverrides.Instance.ResourceLoading.GetResourceSync)
|
||||
_getResourceSyncHook.Enable();
|
||||
if (HookOverrides.Instance.ResourceLoading.GetResourceAsync)
|
||||
_getResourceAsyncHook.Enable();
|
||||
if (HookOverrides.Instance.ResourceLoading.IncRef)
|
||||
_incRefHook.Enable();
|
||||
if (HookOverrides.Instance.ResourceLoading.DecRef)
|
||||
_decRefHook.Enable();
|
||||
}
|
||||
}
|
||||
|
||||
public ResourceHandle* GetResource(ResourceCategory category, ResourceType type, CiByteString path)
|
||||
|
|
|
|||
|
|
@ -46,12 +46,12 @@ public unsafe class TexMdlService : IDisposable, IRequiredService
|
|||
{
|
||||
interop.InitializeFromAttributes(this);
|
||||
_lodService = new LodService(interop);
|
||||
if (HookSettings.ReplacementHooks)
|
||||
{
|
||||
if (HookOverrides.Instance.ResourceLoading.CheckFileState)
|
||||
_checkFileStateHook.Enable();
|
||||
if (HookOverrides.Instance.ResourceLoading.LoadMdlFileExtern)
|
||||
_loadMdlFileExternHook.Enable();
|
||||
if (HookOverrides.Instance.ResourceLoading.TexResourceHandleOnLoad)
|
||||
_textureOnLoadHook.Enable();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary> Add CRC64 if the given file is a model or texture file and has an associated path. </summary>
|
||||
|
|
|
|||
|
|
@ -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, HookSettings.ResourceHooks);
|
||||
Task = hooks.CreateHook<Delegate>("Load Apricot Resource", Sigs.ApricotResourceLoad, Detour, HookOverrides.Instance.Resources.ApricotResourceLoad);
|
||||
}
|
||||
|
||||
public delegate byte Delegate(ResourceHandle* handle, nint unk1, byte unk2);
|
||||
|
|
|
|||
|
|
@ -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, HookSettings.ResourceHooks);
|
||||
Task = hooks.CreateHook<Delegate>("Load Material Shaders", Sigs.LoadMtrlShpk, Detour, HookOverrides.Instance.Resources.LoadMtrlShpk);
|
||||
}
|
||||
|
||||
public delegate byte Delegate(MaterialResourceHandle* mtrlResourceHandle);
|
||||
|
|
|
|||
|
|
@ -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, HookSettings.ResourceHooks);
|
||||
Task = hooks.CreateHook<Delegate>("Load Material Textures", Sigs.LoadMtrlTex, Detour, HookOverrides.Instance.Resources.LoadMtrlTex);
|
||||
}
|
||||
|
||||
public delegate byte Delegate(MaterialResourceHandle* mtrlResourceHandle);
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@ public sealed unsafe class ResolvePathHooksBase : IDisposable
|
|||
|
||||
|
||||
// @formatter:on
|
||||
if (HookSettings.ResourceHooks)
|
||||
if (HookOverrides.Instance.Resources.ResolvePathHooks)
|
||||
Enable();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -23,7 +23,8 @@ public sealed unsafe class ResourceHandleDestructor : EventWrapperPtr<ResourceHa
|
|||
|
||||
public ResourceHandleDestructor(HookManager hooks)
|
||||
: base("Destroy ResourceHandle")
|
||||
=> _task = hooks.CreateHook<Delegate>(Name, Sigs.ResourceHandleDestructor, Detour, HookSettings.ResourceHooks);
|
||||
=> _task = hooks.CreateHook<Delegate>(Name, Sigs.ResourceHandleDestructor, Detour,
|
||||
HookOverrides.Instance.Resources.ResourceHandleDestructor);
|
||||
|
||||
private readonly Task<Hook<Delegate>> _task;
|
||||
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ using Penumbra.GameData.Enums;
|
|||
using Penumbra.UI;
|
||||
using ResidentResourceManager = Penumbra.Interop.Services.ResidentResourceManager;
|
||||
using System.Xml.Linq;
|
||||
using Penumbra.Interop.Hooks;
|
||||
using Penumbra.Interop.Hooks.ResourceLoading;
|
||||
|
||||
namespace Penumbra;
|
||||
|
|
@ -52,9 +53,10 @@ public class Penumbra : IDalamudPlugin
|
|||
{
|
||||
try
|
||||
{
|
||||
_services = StaticServiceManager.CreateProvider(this, pluginInterface, Log);
|
||||
Messager = _services.GetService<MessageService>();
|
||||
_validityChecker = _services.GetService<ValidityChecker>();
|
||||
HookOverrides.Instance = HookOverrides.LoadFile(pluginInterface);
|
||||
_services = StaticServiceManager.CreateProvider(this, pluginInterface, Log);
|
||||
Messager = _services.GetService<MessageService>();
|
||||
_validityChecker = _services.GetService<ValidityChecker>();
|
||||
_services.EnsureRequiredServices();
|
||||
|
||||
var startup = _services.GetService<DalamudConfigService>()
|
||||
|
|
@ -215,6 +217,7 @@ public class Penumbra : IDalamudPlugin
|
|||
sb.Append($"> **`Auto-Deduplication: `** {_config.AutoDeduplicateOnImport}\n");
|
||||
sb.Append($"> **`Auto-UI-Reduplication: `** {_config.AutoReduplicateUiOnImport}\n");
|
||||
sb.Append($"> **`Debug Mode: `** {_config.DebugMode}\n");
|
||||
sb.Append($"> **`Hook Overrides: `** {HookOverrides.Instance.IsCustomLoaded}\n");
|
||||
sb.Append(
|
||||
$"> **`Synchronous Load (Dalamud): `** {(_services.GetService<DalamudConfigService>().GetDalamudConfig(DalamudConfigService.WaitingForPluginsOption, out bool v) ? v.ToString() : "Unknown")}\n");
|
||||
sb.Append(
|
||||
|
|
|
|||
|
|
@ -97,6 +97,7 @@ public class DebugTab : Window, ITab, IUiService
|
|||
private readonly IpcTester _ipcTester;
|
||||
private readonly CrashHandlerPanel _crashHandlerPanel;
|
||||
private readonly TexHeaderDrawer _texHeaderDrawer;
|
||||
private readonly HookOverrideDrawer _hookOverrides;
|
||||
|
||||
public DebugTab(PerformanceTracker performance, Configuration config, CollectionManager collectionManager, ObjectManager objects,
|
||||
IClientState clientState,
|
||||
|
|
@ -106,7 +107,8 @@ public class DebugTab : Window, ITab, IUiService
|
|||
DrawObjectState drawObjectState, PathState pathState, SubfileHelper subfileHelper, IdentifiedCollectionCache identifiedCollectionCache,
|
||||
CutsceneService cutsceneService, ModImportManager modImporter, ImportPopup importPopup, FrameworkManager framework,
|
||||
TextureManager textureManager, ShaderReplacementFixer shaderReplacementFixer, RedrawService redraws, DictEmote emotes,
|
||||
Diagnostics diagnostics, IpcTester ipcTester, CrashHandlerPanel crashHandlerPanel, TexHeaderDrawer texHeaderDrawer)
|
||||
Diagnostics diagnostics, IpcTester ipcTester, CrashHandlerPanel crashHandlerPanel, TexHeaderDrawer texHeaderDrawer,
|
||||
HookOverrideDrawer hookOverrides)
|
||||
: base("Penumbra Debug Window", ImGuiWindowFlags.NoCollapse)
|
||||
{
|
||||
IsOpen = true;
|
||||
|
|
@ -143,6 +145,7 @@ public class DebugTab : Window, ITab, IUiService
|
|||
_ipcTester = ipcTester;
|
||||
_crashHandlerPanel = crashHandlerPanel;
|
||||
_texHeaderDrawer = texHeaderDrawer;
|
||||
_hookOverrides = hookOverrides;
|
||||
_objects = objects;
|
||||
_clientState = clientState;
|
||||
}
|
||||
|
|
@ -166,34 +169,21 @@ public class DebugTab : Window, ITab, IUiService
|
|||
return;
|
||||
|
||||
DrawDebugTabGeneral();
|
||||
ImGui.NewLine();
|
||||
_crashHandlerPanel.Draw();
|
||||
ImGui.NewLine();
|
||||
_diagnostics.DrawDiagnostics();
|
||||
DrawPerformanceTab();
|
||||
ImGui.NewLine();
|
||||
DrawPathResolverDebug();
|
||||
ImGui.NewLine();
|
||||
DrawActorsDebug();
|
||||
ImGui.NewLine();
|
||||
DrawCollectionCaches();
|
||||
ImGui.NewLine();
|
||||
_texHeaderDrawer.Draw();
|
||||
ImGui.NewLine();
|
||||
DrawDebugCharacterUtility();
|
||||
ImGui.NewLine();
|
||||
DrawShaderReplacementFixer();
|
||||
ImGui.NewLine();
|
||||
DrawData();
|
||||
ImGui.NewLine();
|
||||
DrawResourceProblems();
|
||||
ImGui.NewLine();
|
||||
_hookOverrides.Draw();
|
||||
DrawPlayerModelInfo();
|
||||
ImGui.NewLine();
|
||||
DrawGlobalVariableInfo();
|
||||
ImGui.NewLine();
|
||||
DrawDebugTabIpc();
|
||||
ImGui.NewLine();
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -434,7 +424,6 @@ public class DebugTab : Window, ITab, IUiService
|
|||
|
||||
private void DrawPerformanceTab()
|
||||
{
|
||||
ImGui.NewLine();
|
||||
if (!ImGui.CollapsingHeader("Performance"))
|
||||
return;
|
||||
|
||||
|
|
|
|||
63
Penumbra/UI/Tabs/Debug/HookOverrideDrawer.cs
Normal file
63
Penumbra/UI/Tabs/Debug/HookOverrideDrawer.cs
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
using Dalamud.Plugin;
|
||||
using ImGuiNET;
|
||||
using OtterGui.Services;
|
||||
using OtterGui.Text;
|
||||
using Penumbra.Interop.Hooks;
|
||||
|
||||
namespace Penumbra.UI.Tabs.Debug;
|
||||
|
||||
public class HookOverrideDrawer(IDalamudPluginInterface pluginInterface) : IUiService
|
||||
{
|
||||
private HookOverrides? _overrides;
|
||||
|
||||
public void Draw()
|
||||
{
|
||||
using var header = ImUtf8.CollapsingHeaderId("Generate Hook Override"u8);
|
||||
if (!header)
|
||||
return;
|
||||
|
||||
_overrides ??= HookOverrides.Instance.Clone();
|
||||
|
||||
if (ImUtf8.Button("Save"u8))
|
||||
_overrides.Write(pluginInterface);
|
||||
|
||||
ImGui.SameLine();
|
||||
var path = Path.Combine(pluginInterface.GetPluginConfigDirectory(), HookOverrides.FileName);
|
||||
var exists = File.Exists(path);
|
||||
if (ImUtf8.ButtonEx("Delete"u8, disabled: !exists, tooltip: exists ? ""u8 : "File does not exist."u8))
|
||||
try
|
||||
{
|
||||
File.Delete(path);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Penumbra.Log.Error($"Could not delete hook override file at {path}:\n{ex}");
|
||||
}
|
||||
|
||||
bool? all = null;
|
||||
ImGui.SameLine();
|
||||
if (ImUtf8.Button("Disable All Hooks"u8))
|
||||
all = true;
|
||||
ImGui.SameLine();
|
||||
if (ImUtf8.Button("Enable All Hooks"u8))
|
||||
all = false;
|
||||
|
||||
foreach (var propertyField in typeof(HookOverrides).GetFields().Where(f => f is { IsStatic: false, FieldType.IsValueType: true }))
|
||||
{
|
||||
using var tree = ImUtf8.TreeNode(propertyField.Name);
|
||||
if (!tree)
|
||||
continue;
|
||||
|
||||
var property = propertyField.GetValue(_overrides);
|
||||
foreach (var valueField in propertyField.FieldType.GetFields())
|
||||
{
|
||||
var value = valueField.GetValue(property) as bool? ?? false;
|
||||
if (ImUtf8.Checkbox($"Disable {valueField.Name}", ref value) || all.HasValue)
|
||||
{
|
||||
valueField.SetValue(property, all ?? value);
|
||||
propertyField.SetValue(_overrides, property);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue