fix: correctly dispose dalamud when closing the game

This commit is contained in:
goat 2021-01-17 22:13:23 +01:00
parent 094099c570
commit 05f8adfaf9
4 changed files with 42 additions and 5 deletions

View file

@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Runtime.InteropServices;
using System.Threading;
using Dalamud.Game.Internal.Gui;
using Dalamud.Game.Internal.Libc;
using Dalamud.Game.Internal.Network;
@ -14,18 +15,25 @@ namespace Dalamud.Game.Internal {
/// This class represents the Framework of the native game client and grants access to various subsystems.
/// </summary>
public sealed class Framework : IDisposable {
private readonly Dalamud dalamud;
[UnmanagedFunctionPointer(CallingConvention.ThisCall)]
private delegate bool OnUpdateDetour(IntPtr framework);
private delegate IntPtr OnDestroyDetour();
public delegate void OnUpdateDelegate(Framework framework);
public delegate IntPtr OnDestroyDelegate();
/// <summary>
/// Event that gets fired every time the game framework updates.
/// </summary>
public event OnUpdateDelegate OnUpdateEvent;
private Hook<OnUpdateDetour> updateHook;
private Hook<OnDestroyDetour> destroyHook;
/// <summary>
/// A raw pointer to the instance of Client::Framework
@ -56,6 +64,7 @@ namespace Dalamud.Game.Internal {
#endregion
public Framework(SigScanner scanner, Dalamud dalamud) {
this.dalamud = dalamud;
Address = new FrameworkAddressResolver();
Address.Setup(scanner);
@ -74,7 +83,8 @@ namespace Dalamud.Game.Internal {
Network = new GameNetwork(scanner);
//Resource = new ResourceManager(dalamud, scanner);
this.destroyHook =
new Hook<OnDestroyDetour>(Address.OnDestroy, new OnDestroyDelegate(HandleFrameworkDestroy), this);
}
private void HookVTable() {
@ -93,9 +103,9 @@ namespace Dalamud.Game.Internal {
public void Enable() {
Gui.Enable();
Network.Enable();
//Resource.Enable();
this.updateHook.Enable();
this.destroyHook.Enable();
}
public void Dispose() {
@ -150,5 +160,14 @@ namespace Dalamud.Game.Internal {
return this.updateHook.Original(framework);
}
private IntPtr HandleFrameworkDestroy() {
Log.Information("Framework::OnDestroy!");
this.dalamud.Unload();
this.dalamud.WaitForUnloadFinish();
return this.destroyHook.Original();
}
}
}

View file

@ -8,6 +8,8 @@ namespace Dalamud.Game.Internal {
public IntPtr GuiManager { get; private set; }
public IntPtr ScriptManager { get; private set; }
public IntPtr OnDestroy { get; private set; }
protected override void Setup64Bit(SigScanner sig) {
@ -19,6 +21,8 @@ namespace Dalamud.Game.Internal {
// Called from Framework::Init
ScriptManager = BaseAddress + 0x2C68; // note that no deref here
OnDestroy = sig.ScanText("48 83 EC 48 48 8B 0D ?? ?? ?? ?? 48 85 C9");
}
private void SetupFramework(SigScanner scanner) {