Add Addon.OnRefresh

This commit is contained in:
MidoriKami 2023-09-07 12:24:45 -07:00
parent 6a0401646f
commit e54b09a3c5
3 changed files with 46 additions and 1 deletions

View file

@ -49,4 +49,14 @@ public enum AddonEvent
/// Event that is fired after an addon finishes a requested update.
/// </summary>
PostRequestedUpdate,
/// <summary>
/// Event that is fired before an addon begins a refresh.
/// </summary>
PreRefresh,
/// <summary>
/// Event that is fired after an addon has finished a refresh.
/// </summary>
PostRefresh,
}

View file

@ -30,6 +30,7 @@ internal unsafe class AddonLifecycle : IDisposable, IServiceType
private readonly Hook<AddonFinalizeDelegate> onAddonFinalizeHook;
private readonly CallHook<AddonDrawDelegate> onAddonDrawHook;
private readonly CallHook<AddonUpdateDelegate> onAddonUpdateHook;
private readonly Hook<AddonOnRefreshDelegate> onAddonRefreshHook;
// private readonly CallHook<AddonOnRequestedUpdate> onAddonRequestedUpdateHook; // See Note in Ctor
private readonly ConcurrentBag<AddonLifecycleEventListener> newEventListeners = new();
@ -48,6 +49,7 @@ internal unsafe class AddonLifecycle : IDisposable, IServiceType
this.onAddonFinalizeHook = Hook<AddonFinalizeDelegate>.FromAddress(this.address.AddonFinalize, this.OnAddonFinalize);
this.onAddonDrawHook = new CallHook<AddonDrawDelegate>(this.address.AddonDraw, this.OnAddonDraw);
this.onAddonUpdateHook = new CallHook<AddonUpdateDelegate>(this.address.AddonUpdate, this.OnAddonUpdate);
this.onAddonRefreshHook = Hook<AddonOnRefreshDelegate>.FromAddress(this.address.AddonOnRefresh, this.OnAddonRefresh);
// todo: reenable this. WARNING: This hook overwrites a system that SimpleTweaks uses, causing SimpleTweaks to report exceptions.
// this.onAddonRequestedUpdateHook = new CallHook<AddonOnRequestedUpdate>(this.address.AddonOnRequestedUpdate, this.OnRequestedUpdate);
@ -61,7 +63,9 @@ internal unsafe class AddonLifecycle : IDisposable, IServiceType
private delegate void AddonUpdateDelegate(AtkUnitBase* addon, float delta);
private delegate void AddonOnRequestedUpdate(AtkUnitBase* addon, NumberArrayData** numberArrayData, StringArrayData** stringArrayData);
private delegate void AddonOnRequestedUpdateDelegate(AtkUnitBase* addon, NumberArrayData** numberArrayData, StringArrayData** stringArrayData);
private delegate void AddonOnRefreshDelegate(AtkUnitManager* unitManager, AtkUnitBase* addon, uint valueCount, AtkValue* values);
/// <inheritdoc/>
public void Dispose()
@ -72,6 +76,7 @@ internal unsafe class AddonLifecycle : IDisposable, IServiceType
this.onAddonFinalizeHook.Dispose();
this.onAddonDrawHook.Dispose();
this.onAddonUpdateHook.Dispose();
this.onAddonRefreshHook.Dispose();
// this.onAddonRequestedUpdateHook.Dispose(); // See Note in Ctor
}
@ -120,6 +125,7 @@ internal unsafe class AddonLifecycle : IDisposable, IServiceType
this.onAddonFinalizeHook.Enable();
this.onAddonDrawHook.Enable();
this.onAddonUpdateHook.Enable();
this.onAddonRefreshHook.Enable();
// this.onAddonRequestedUpdateHook.Enable(); // See Note in Ctor
}
@ -226,6 +232,29 @@ internal unsafe class AddonLifecycle : IDisposable, IServiceType
}
}
private void OnAddonRefresh(AtkUnitManager* atkUnitManager, AtkUnitBase* addon, uint valueCount, AtkValue* values)
{
try
{
this.InvokeListeners(AddonEvent.PreRefresh, new IAddonLifecycle.AddonArgs { Addon = (nint)addon });
}
catch (Exception e)
{
Log.Error(e, "Exception in OnAddonRefresh pre-refresh invoke.");
}
this.onAddonRefreshHook.Original(atkUnitManager, addon, valueCount, values);
try
{
this.InvokeListeners(AddonEvent.PostRefresh, new IAddonLifecycle.AddonArgs { Addon = (nint)addon });
}
catch (Exception e)
{
Log.Error(e, "Exception in OnAddonRefresh post-refresh invoke.");
}
}
private void OnRequestedUpdate(AtkUnitBase* addon, NumberArrayData** numberArrayData, StringArrayData** stringArrayData)
{
try

View file

@ -29,6 +29,11 @@ internal class AddonLifecycleAddressResolver : BaseAddressResolver
/// Gets the address of the addon onRequestedUpdate hook invoked by virtual function call.
/// </summary>
public nint AddonOnRequestedUpdate { get; private set; }
/// <summary>
/// Gets the address of AtkUnitManager_vf10 which triggers addon onRefresh.
/// </summary>
public nint AddonOnRefresh { get; private set; }
/// <summary>
/// Scan for and setup any configured address pointers.
@ -41,5 +46,6 @@ internal class AddonLifecycleAddressResolver : BaseAddressResolver
this.AddonDraw = sig.ScanText("FF 90 ?? ?? ?? ?? 83 EB 01 79 C1");
this.AddonUpdate = sig.ScanText("FF 90 ?? ?? ?? ?? 40 88 AF");
this.AddonOnRequestedUpdate = sig.ScanText("FF 90 90 01 00 00 48 8B 5C 24 30 48 83 C4 20");
this.AddonOnRefresh = sig.ScanText("48 89 5C 24 08 57 48 83 EC 20 41 8B F8 48 8B DA");
}
}