Force ChangeCustomizeService to reapply hooks when Penumbra is reloaded.

This commit is contained in:
Ottermandias 2023-08-01 17:40:29 +02:00
parent e9a4e8fa1b
commit b1db737586
4 changed files with 55 additions and 9 deletions

View file

@ -0,0 +1,23 @@
using System;
using OtterGui.Classes;
namespace Glamourer.Events;
/// <summary>
/// Triggered when Penumbra is reloaded.
/// </summary>
public sealed class PenumbraReloaded : EventWrapper<Action, PenumbraReloaded.Priority>
{
public enum Priority
{
/// <seealso cref="Interop.ChangeCustomizeService.Restore"/>
ChangeCustomizeService = 0,
}
public PenumbraReloaded()
: base(nameof(PenumbraReloaded))
{ }
public void Invoke()
=> Invoke(this);
}

View file

@ -3,6 +3,7 @@ using Dalamud.Hooking;
using Dalamud.Utility.Signatures; using Dalamud.Utility.Signatures;
using FFXIVClientStructs.FFXIV.Client.Graphics.Scene; using FFXIVClientStructs.FFXIV.Client.Graphics.Scene;
using Glamourer.Customization; using Glamourer.Customization;
using Glamourer.Events;
using Glamourer.Interop.Structs; using Glamourer.Interop.Structs;
using OtterGui.Classes; using OtterGui.Classes;
using CustomizeData = Penumbra.GameData.Structs.CustomizeData; using CustomizeData = Penumbra.GameData.Structs.CustomizeData;
@ -16,30 +17,46 @@ namespace Glamourer.Interop;
/// </summary> /// </summary>
public unsafe class ChangeCustomizeService : EventWrapper<Action<Model, Ref<Customize>>, ChangeCustomizeService.Priority> public unsafe class ChangeCustomizeService : EventWrapper<Action<Model, Ref<Customize>>, ChangeCustomizeService.Priority>
{ {
private readonly PenumbraReloaded _penumbraReloaded;
public enum Priority public enum Priority
{ {
/// <seealso cref="State.StateListener.OnCustomizeChange"/> /// <seealso cref="State.StateListener.OnCustomizeChange"/>
StateListener = 0, StateListener = 0,
} }
public ChangeCustomizeService() public ChangeCustomizeService(PenumbraReloaded penumbraReloaded)
: base("ChangeCustomize") : base("ChangeCustomize")
{ {
_changeCustomizeHook = _penumbraReloaded = penumbraReloaded;
Hook<ChangeCustomizeDelegate>.FromAddress((nint)Human.MemberFunctionPointers.UpdateDrawData, ChangeCustomizeDetour); _changeCustomizeHook = Create();
_changeCustomizeHook.Enable(); _penumbraReloaded.Subscribe(Restore, PenumbraReloaded.Priority.ChangeCustomizeService);
} }
public new void Dispose() public new void Dispose()
{ {
base.Dispose(); base.Dispose();
_changeCustomizeHook.Dispose(); _changeCustomizeHook.Dispose();
_penumbraReloaded.Unsubscribe(Restore);
}
private void Restore()
{
_changeCustomizeHook.Dispose();
_changeCustomizeHook = Create();
}
private Hook<ChangeCustomizeDelegate> Create()
{
var ret = Hook<ChangeCustomizeDelegate>.FromAddress((nint)Human.MemberFunctionPointers.UpdateDrawData, ChangeCustomizeDetour);
ret.Enable();
return ret;
} }
private delegate bool ChangeCustomizeDelegate(Human* human, byte* data, byte skipEquipment); private delegate bool ChangeCustomizeDelegate(Human* human, byte* data, byte skipEquipment);
[Signature(Sigs.ChangeCustomize, DetourName = nameof(ChangeCustomizeDetour))] [Signature(Sigs.ChangeCustomize, DetourName = nameof(ChangeCustomizeDetour))]
private readonly Hook<ChangeCustomizeDelegate> _changeCustomizeHook; private Hook<ChangeCustomizeDelegate> _changeCustomizeHook;
public bool UpdateCustomize(Model model, CustomizeData customize) public bool UpdateCustomize(Model model, CustomizeData customize)
{ {

View file

@ -5,6 +5,7 @@ using System.Linq;
using System.Text; using System.Text;
using Dalamud.Logging; using Dalamud.Logging;
using Dalamud.Plugin; using Dalamud.Plugin;
using Glamourer.Events;
using Glamourer.Interop.Structs; using Glamourer.Interop.Structs;
using Penumbra.Api; using Penumbra.Api;
using Penumbra.Api.Enums; using Penumbra.Api.Enums;
@ -61,11 +62,15 @@ public unsafe class PenumbraService : IDisposable
private readonly EventSubscriber _initializedEvent; private readonly EventSubscriber _initializedEvent;
private readonly EventSubscriber _disposedEvent; private readonly EventSubscriber _disposedEvent;
public bool Available { get; private set; }
public PenumbraService(DalamudPluginInterface pi) private readonly PenumbraReloaded _penumbraReloaded;
public bool Available { get; private set; }
public PenumbraService(DalamudPluginInterface pi, PenumbraReloaded penumbraReloaded)
{ {
_pluginInterface = pi; _pluginInterface = pi;
_penumbraReloaded = penumbraReloaded;
_initializedEvent = Ipc.Initialized.Subscriber(pi, Reattach); _initializedEvent = Ipc.Initialized.Subscriber(pi, Reattach);
_disposedEvent = Ipc.Disposed.Subscriber(pi, Unattach); _disposedEvent = Ipc.Disposed.Subscriber(pi, Unattach);
_tooltipSubscriber = Ipc.ChangedItemTooltip.Subscriber(pi); _tooltipSubscriber = Ipc.ChangedItemTooltip.Subscriber(pi);
@ -253,8 +258,8 @@ public unsafe class PenumbraService : IDisposable
_setModPriority = Ipc.TrySetModPriority.Subscriber(_pluginInterface); _setModPriority = Ipc.TrySetModPriority.Subscriber(_pluginInterface);
_setModSetting = Ipc.TrySetModSetting.Subscriber(_pluginInterface); _setModSetting = Ipc.TrySetModSetting.Subscriber(_pluginInterface);
_setModSettings = Ipc.TrySetModSettings.Subscriber(_pluginInterface); _setModSettings = Ipc.TrySetModSettings.Subscriber(_pluginInterface);
Available = true; Available = true;
_penumbraReloaded.Invoke();
Glamourer.Log.Debug("Glamourer attached to Penumbra."); Glamourer.Log.Debug("Glamourer attached to Penumbra.");
} }
catch (Exception e) catch (Exception e)

View file

@ -70,7 +70,8 @@ public static class ServiceManager
.AddSingleton<ObjectUnlocked>() .AddSingleton<ObjectUnlocked>()
.AddSingleton<TabSelected>() .AddSingleton<TabSelected>()
.AddSingleton<MovedEquipment>() .AddSingleton<MovedEquipment>()
.AddSingleton<GPoseService>(); .AddSingleton<GPoseService>()
.AddSingleton<PenumbraReloaded>();
private static IServiceCollection AddData(this IServiceCollection services) private static IServiceCollection AddData(this IServiceCollection services)
=> services.AddSingleton<IdentifierService>() => services.AddSingleton<IdentifierService>()