mirror of
https://github.com/goatcorp/Dalamud.git
synced 2025-12-13 12:14:16 +01:00
fix: correctly dispose dalamud when closing the game
This commit is contained in:
parent
094099c570
commit
05f8adfaf9
4 changed files with 42 additions and 5 deletions
|
|
@ -143,6 +143,8 @@ namespace Dalamud {
|
|||
|
||||
private readonly ManualResetEvent unloadSignal;
|
||||
|
||||
private readonly ManualResetEvent finishUnloadSignal;
|
||||
|
||||
private readonly string baseDirectory;
|
||||
|
||||
#endregion
|
||||
|
|
@ -162,13 +164,14 @@ namespace Dalamud {
|
|||
/// </summary>
|
||||
internal DirectoryInfo AssetDirectory => new DirectoryInfo(this.StartInfo.AssetDirectory);
|
||||
|
||||
public Dalamud(DalamudStartInfo info, LoggingLevelSwitch loggingLevelSwitch) {
|
||||
public Dalamud(DalamudStartInfo info, LoggingLevelSwitch loggingLevelSwitch, ManualResetEvent finishSignal) {
|
||||
this.StartInfo = info;
|
||||
this.LogLevelSwitch = loggingLevelSwitch;
|
||||
|
||||
this.baseDirectory = info.WorkingDirectory;
|
||||
|
||||
this.unloadSignal = new ManualResetEvent(false);
|
||||
this.finishUnloadSignal = finishSignal;
|
||||
|
||||
this.Configuration = DalamudConfiguration.Load(info.ConfigurationPath);
|
||||
|
||||
|
|
@ -277,6 +280,10 @@ namespace Dalamud {
|
|||
this.unloadSignal.WaitOne();
|
||||
}
|
||||
|
||||
public void WaitForUnloadFinish() {
|
||||
this.finishUnloadSignal.WaitOne();
|
||||
}
|
||||
|
||||
public void Dispose() {
|
||||
// this must be done before unloading plugins, or it can cause a race condition
|
||||
// due to rendering happening on another thread, where a plugin might receive
|
||||
|
|
@ -305,6 +312,8 @@ namespace Dalamud {
|
|||
this.Data.Dispose();
|
||||
|
||||
this.AntiDebug?.Dispose();
|
||||
|
||||
Log.Debug("Dalamud::Dispose OK!");
|
||||
}
|
||||
|
||||
internal void ReplaceExceptionHandler() {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Dalamud.Interface;
|
||||
using EasyHook;
|
||||
|
|
@ -19,6 +20,8 @@ namespace Dalamud {
|
|||
var (logger, levelSwitch) = NewLogger(info.WorkingDirectory);
|
||||
Log.Logger = logger;
|
||||
|
||||
var finishSignal = new ManualResetEvent(false);
|
||||
|
||||
try {
|
||||
Log.Information(new string('-', 200));
|
||||
Log.Information("Initializing a session..");
|
||||
|
|
@ -31,7 +34,7 @@ namespace Dalamud {
|
|||
AppDomain.CurrentDomain.UnhandledException += OnUnhandledException;
|
||||
TaskScheduler.UnobservedTaskException += OnUnobservedTaskException;
|
||||
|
||||
using var dalamud = new Dalamud(info, levelSwitch);
|
||||
using var dalamud = new Dalamud(info, levelSwitch, finishSignal);
|
||||
Log.Information("Starting a session..");
|
||||
|
||||
// Run session
|
||||
|
|
@ -44,6 +47,8 @@ namespace Dalamud {
|
|||
|
||||
Log.Information("Session has ended.");
|
||||
Log.CloseAndFlush();
|
||||
|
||||
finishSignal.Set();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue