mirror of
https://github.com/xivdev/Penumbra.git
synced 2026-02-21 15:27:51 +01:00
Move more hooks in own classes.
This commit is contained in:
parent
be588e2fa3
commit
91cea50f02
26 changed files with 274 additions and 262 deletions
49
Penumbra/Interop/Hooks/Objects/CharacterBaseDestructor.cs
Normal file
49
Penumbra/Interop/Hooks/Objects/CharacterBaseDestructor.cs
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
using Dalamud.Hooking;
|
||||
using FFXIVClientStructs.FFXIV.Client.Graphics.Scene;
|
||||
using OtterGui.Classes;
|
||||
using OtterGui.Services;
|
||||
using Penumbra.UI.AdvancedWindow;
|
||||
|
||||
namespace Penumbra.Interop.Hooks.Objects;
|
||||
|
||||
public sealed unsafe class CharacterBaseDestructor : EventWrapperPtr<CharacterBase, CharacterBaseDestructor.Priority>, IHookService
|
||||
{
|
||||
public enum Priority
|
||||
{
|
||||
/// <seealso cref="PathResolving.DrawObjectState"/>
|
||||
DrawObjectState = 0,
|
||||
|
||||
/// <seealso cref="ModEditWindow.MtrlTab"/>
|
||||
MtrlTab = -1000,
|
||||
}
|
||||
|
||||
public CharacterBaseDestructor(HookManager hooks)
|
||||
: base("Destroy CharacterBase")
|
||||
=> _task = hooks.CreateHook<Delegate>(Name, Address, Detour, true);
|
||||
|
||||
private readonly Task<Hook<Delegate>> _task;
|
||||
|
||||
public nint Address
|
||||
=> (nint)CharacterBase.MemberFunctionPointers.Destroy;
|
||||
|
||||
public void Enable()
|
||||
=> _task.Result.Enable();
|
||||
|
||||
public void Disable()
|
||||
=> _task.Result.Disable();
|
||||
|
||||
public Task Awaiter
|
||||
=> _task;
|
||||
|
||||
public bool Finished
|
||||
=> _task.IsCompletedSuccessfully;
|
||||
|
||||
private delegate nint Delegate(CharacterBase* characterBase);
|
||||
|
||||
private nint Detour(CharacterBase* characterBase)
|
||||
{
|
||||
Penumbra.Log.Verbose($"[{Name}] Triggered with 0x{(nint)characterBase:X}.");
|
||||
Invoke(characterBase);
|
||||
return _task.Result.Original(characterBase);
|
||||
}
|
||||
}
|
||||
49
Penumbra/Interop/Hooks/Objects/CharacterDestructor.cs
Normal file
49
Penumbra/Interop/Hooks/Objects/CharacterDestructor.cs
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
using Dalamud.Hooking;
|
||||
using FFXIVClientStructs.FFXIV.Client.Game.Character;
|
||||
using OtterGui.Classes;
|
||||
using OtterGui.Services;
|
||||
using Penumbra.GameData;
|
||||
|
||||
namespace Penumbra.Interop.Hooks.Objects;
|
||||
|
||||
public sealed unsafe class CharacterDestructor : EventWrapperPtr<Character, CharacterDestructor.Priority>, IHookService
|
||||
{
|
||||
public enum Priority
|
||||
{
|
||||
/// <seealso cref="PathResolving.CutsceneService"/>
|
||||
CutsceneService = 0,
|
||||
|
||||
/// <seealso cref="PathResolving.IdentifiedCollectionCache"/>
|
||||
IdentifiedCollectionCache = 0,
|
||||
}
|
||||
|
||||
public CharacterDestructor(HookManager hooks)
|
||||
: base("Character Destructor")
|
||||
=> _task = hooks.CreateHook<Delegate>(Name, Sigs.CharacterDestructor, Detour, true);
|
||||
|
||||
private readonly Task<Hook<Delegate>> _task;
|
||||
|
||||
public nint Address
|
||||
=> _task.Result.Address;
|
||||
|
||||
public void Enable()
|
||||
=> _task.Result.Enable();
|
||||
|
||||
public void Disable()
|
||||
=> _task.Result.Disable();
|
||||
|
||||
public Task Awaiter
|
||||
=> _task;
|
||||
|
||||
public bool Finished
|
||||
=> _task.IsCompletedSuccessfully;
|
||||
|
||||
private delegate void Delegate(Character* character);
|
||||
|
||||
private void Detour(Character* character)
|
||||
{
|
||||
Penumbra.Log.Verbose($"[{Name}] Triggered with 0x{(nint)character:X}.");
|
||||
Invoke(character);
|
||||
_task.Result.Original(character);
|
||||
}
|
||||
}
|
||||
47
Penumbra/Interop/Hooks/Objects/CopyCharacter.cs
Normal file
47
Penumbra/Interop/Hooks/Objects/CopyCharacter.cs
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
using Dalamud.Hooking;
|
||||
using FFXIVClientStructs.FFXIV.Client.Game.Character;
|
||||
using OtterGui.Classes;
|
||||
using OtterGui.Services;
|
||||
|
||||
namespace Penumbra.Interop.Hooks.Objects;
|
||||
|
||||
public sealed unsafe class CopyCharacter : EventWrapperPtr<Character, Character, CopyCharacter.Priority>, IHookService
|
||||
{
|
||||
public enum Priority
|
||||
{
|
||||
/// <seealso cref="PathResolving.CutsceneService"/>
|
||||
CutsceneService = 0,
|
||||
}
|
||||
|
||||
public CopyCharacter(HookManager hooks)
|
||||
: base("Copy Character")
|
||||
=> _task = hooks.CreateHook<Delegate>(Name, Address, Detour, true);
|
||||
|
||||
private readonly Task<Hook<Delegate>> _task;
|
||||
|
||||
public nint Address
|
||||
=> (nint)CharacterSetup.MemberFunctionPointers.CopyFromCharacter;
|
||||
|
||||
public void Enable()
|
||||
=> _task.Result.Enable();
|
||||
|
||||
public void Disable()
|
||||
=> _task.Result.Disable();
|
||||
|
||||
public Task Awaiter
|
||||
=> _task;
|
||||
|
||||
public bool Finished
|
||||
=> _task.IsCompletedSuccessfully;
|
||||
|
||||
private delegate ulong Delegate(CharacterSetup* target, Character* source, uint unk);
|
||||
|
||||
private ulong Detour(CharacterSetup* target, Character* source, uint unk)
|
||||
{
|
||||
// TODO: update when CS updated.
|
||||
var character = ((Character**)target)[1];
|
||||
Penumbra.Log.Verbose($"[{Name}] Triggered with target: 0x{(nint)target:X}, source : 0x{(nint)source:X} unk: {unk}.");
|
||||
Invoke(character, source);
|
||||
return _task.Result.Original(target, source, unk);
|
||||
}
|
||||
}
|
||||
74
Penumbra/Interop/Hooks/Objects/CreateCharacterBase.cs
Normal file
74
Penumbra/Interop/Hooks/Objects/CreateCharacterBase.cs
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
using Dalamud.Hooking;
|
||||
using FFXIVClientStructs.FFXIV.Client.Graphics.Scene;
|
||||
using OtterGui.Classes;
|
||||
using OtterGui.Services;
|
||||
using Penumbra.GameData.Structs;
|
||||
|
||||
namespace Penumbra.Interop.Hooks.Objects;
|
||||
|
||||
public sealed unsafe class CreateCharacterBase : EventWrapperPtr<ModelCharaId, CustomizeArray, CharacterArmor, CreateCharacterBase.Priority>, IHookService
|
||||
{
|
||||
public enum Priority
|
||||
{
|
||||
/// <seealso cref="PathResolving.MetaState"/>
|
||||
MetaState = 0,
|
||||
}
|
||||
|
||||
public CreateCharacterBase(HookManager hooks)
|
||||
: base("Create CharacterBase")
|
||||
=> _task = hooks.CreateHook<Delegate>(Name, Address, Detour, true);
|
||||
|
||||
private readonly Task<Hook<Delegate>> _task;
|
||||
|
||||
public nint Address
|
||||
=> (nint)CharacterBase.MemberFunctionPointers.Create;
|
||||
|
||||
public void Enable()
|
||||
=> _task.Result.Enable();
|
||||
|
||||
public void Disable()
|
||||
=> _task.Result.Disable();
|
||||
|
||||
public Task Awaiter
|
||||
=> _task;
|
||||
|
||||
public bool Finished
|
||||
=> _task.IsCompletedSuccessfully;
|
||||
|
||||
private delegate CharacterBase* Delegate(ModelCharaId model, CustomizeArray* customize, CharacterArmor* equipment, byte unk);
|
||||
|
||||
private CharacterBase* Detour(ModelCharaId model, CustomizeArray* customize, CharacterArmor* equipment, byte unk)
|
||||
{
|
||||
Penumbra.Log.Verbose($"[{Name}] Triggered with model: {model.Id}, customize: 0x{(nint)customize:X}, equipment: 0x{(nint)equipment:X}, unk: {unk}.");
|
||||
Invoke(&model, customize, equipment);
|
||||
var ret = _task.Result.Original(model, customize, equipment, unk);
|
||||
_postEvent.Invoke(model, customize, equipment, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
public void Subscribe(ActionPtr234<ModelCharaId, CustomizeArray, CharacterArmor, CharacterBase> subscriber, PostEvent.Priority priority)
|
||||
=> _postEvent.Subscribe(subscriber, priority);
|
||||
|
||||
public void Unsubscribe(ActionPtr234<ModelCharaId, CustomizeArray, CharacterArmor, CharacterBase> subscriber)
|
||||
=> _postEvent.Unsubscribe(subscriber);
|
||||
|
||||
|
||||
private readonly PostEvent _postEvent = new("Created CharacterBase");
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
_postEvent.Dispose();
|
||||
}
|
||||
|
||||
public class PostEvent(string name) : EventWrapperPtr234<ModelCharaId, CustomizeArray, CharacterArmor, CharacterBase, PostEvent.Priority>(name)
|
||||
{
|
||||
public enum Priority
|
||||
{
|
||||
/// <seealso cref="PathResolving.DrawObjectState"/>
|
||||
DrawObjectState = 0,
|
||||
|
||||
/// <seealso cref="PathResolving.MetaState"/>
|
||||
MetaState = 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
48
Penumbra/Interop/Hooks/Objects/EnableDraw.cs
Normal file
48
Penumbra/Interop/Hooks/Objects/EnableDraw.cs
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
using Dalamud.Hooking;
|
||||
using FFXIVClientStructs.FFXIV.Client.Game.Object;
|
||||
using OtterGui.Services;
|
||||
using Penumbra.GameData;
|
||||
|
||||
namespace Penumbra.Interop.Hooks.Objects;
|
||||
|
||||
/// <summary>
|
||||
/// EnableDraw is what creates DrawObjects for gameObjects,
|
||||
/// so we always keep track of the current GameObject to be able to link it to the DrawObject.
|
||||
/// </summary>
|
||||
public sealed unsafe class EnableDraw : IHookService
|
||||
{
|
||||
private readonly Task<Hook<Delegate>> _task;
|
||||
private readonly GameState _state;
|
||||
|
||||
public EnableDraw(HookManager hooks, GameState state)
|
||||
{
|
||||
_state = state;
|
||||
_task = hooks.CreateHook<Delegate>("Enable Draw", Sigs.EnableDraw, Detour, true);
|
||||
}
|
||||
|
||||
private delegate void Delegate(GameObject* gameObject);
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
|
||||
private void Detour(GameObject* gameObject)
|
||||
{
|
||||
_state.QueueGameObject(gameObject);
|
||||
Penumbra.Log.Excessive($"[Enable Draw] Invoked on 0x{(nint)gameObject:X}.");
|
||||
_task.Result.Original.Invoke(gameObject);
|
||||
_state.DequeueGameObject();
|
||||
}
|
||||
|
||||
public Task Awaiter
|
||||
=> _task;
|
||||
|
||||
public bool Finished
|
||||
=> _task.IsCompletedSuccessfully;
|
||||
|
||||
public nint Address
|
||||
=> _task.Result.Address;
|
||||
|
||||
public void Enable()
|
||||
=> _task.Result.Enable();
|
||||
|
||||
public void Disable()
|
||||
=> _task.Result.Disable();
|
||||
}
|
||||
71
Penumbra/Interop/Hooks/Objects/WeaponReload.cs
Normal file
71
Penumbra/Interop/Hooks/Objects/WeaponReload.cs
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
using Dalamud.Hooking;
|
||||
using FFXIVClientStructs.FFXIV.Client.Game.Character;
|
||||
using OtterGui.Classes;
|
||||
using OtterGui.Services;
|
||||
using Penumbra.GameData.Structs;
|
||||
|
||||
namespace Penumbra.Interop.Hooks.Objects;
|
||||
|
||||
public sealed unsafe class WeaponReload : EventWrapperPtr<DrawDataContainer, Character, CharacterWeapon, WeaponReload.Priority>, IHookService
|
||||
{
|
||||
public enum Priority
|
||||
{
|
||||
/// <seealso cref="PathResolving.DrawObjectState"/>
|
||||
DrawObjectState = 0,
|
||||
}
|
||||
|
||||
public WeaponReload(HookManager hooks)
|
||||
: base("Reload Weapon")
|
||||
=> _task = hooks.CreateHook<Delegate>(Name, Address, Detour, true);
|
||||
|
||||
private readonly Task<Hook<Delegate>> _task;
|
||||
|
||||
public nint Address
|
||||
=> (nint)DrawDataContainer.MemberFunctionPointers.LoadWeapon;
|
||||
|
||||
public void Enable()
|
||||
=> _task.Result.Enable();
|
||||
|
||||
public void Disable()
|
||||
=> _task.Result.Disable();
|
||||
|
||||
public Task Awaiter
|
||||
=> _task;
|
||||
|
||||
public bool Finished
|
||||
=> _task.IsCompletedSuccessfully;
|
||||
|
||||
private delegate void Delegate(DrawDataContainer* drawData, uint slot, ulong weapon, byte d, byte e, byte f, byte g);
|
||||
|
||||
private void Detour(DrawDataContainer* drawData, uint slot, ulong weapon, byte d, byte e, byte f, byte g)
|
||||
{
|
||||
var gameObject = drawData->Parent;
|
||||
Penumbra.Log.Verbose($"[{Name}] Triggered with drawData: 0x{(nint)drawData:X}, {slot}, {weapon}, {d}, {e}, {f}, {g}.");
|
||||
Invoke(drawData, gameObject, (CharacterWeapon*)(&weapon));
|
||||
_task.Result.Original(drawData, slot, weapon, d, e, f, g);
|
||||
_postEvent.Invoke(drawData, gameObject);
|
||||
}
|
||||
|
||||
public void Subscribe(ActionPtr<DrawDataContainer, Character> subscriber, PostEvent.Priority priority)
|
||||
=> _postEvent.Subscribe(subscriber, priority);
|
||||
|
||||
public void Unsubscribe(ActionPtr<DrawDataContainer, Character> subscriber)
|
||||
=> _postEvent.Unsubscribe(subscriber);
|
||||
|
||||
|
||||
private readonly PostEvent _postEvent = new("Created CharacterBase");
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
_postEvent.Dispose();
|
||||
}
|
||||
|
||||
public class PostEvent(string name) : EventWrapperPtr<DrawDataContainer, Character, PostEvent.Priority>(name)
|
||||
{
|
||||
public enum Priority
|
||||
{
|
||||
/// <seealso cref="PathResolving.DrawObjectState"/>
|
||||
DrawObjectState = 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue