refactor: move dalamud init logic out of ctor, AntiDebug cleanup(WIP!!1!!!!)

This commit is contained in:
goat 2021-01-19 22:23:01 +01:00
parent 3d32d9c59c
commit 5df28e4e22
4 changed files with 106 additions and 106 deletions

View file

@ -33,27 +33,27 @@ namespace Dalamud {
/// <summary> /// <summary>
/// Game framework subsystem /// Game framework subsystem
/// </summary> /// </summary>
internal readonly Framework Framework; internal Framework Framework { get; private set; }
/// <summary> /// <summary>
/// Anti-Debug detection prevention system /// Anti-Debug detection prevention system
/// </summary> /// </summary>
internal readonly AntiDebug AntiDebug; internal AntiDebug AntiDebug { get; private set; }
/// <summary> /// <summary>
/// WinSock optimization subsystem /// WinSock optimization subsystem
/// </summary> /// </summary>
internal readonly WinSockHandlers WinSock2; internal WinSockHandlers WinSock2 { get; private set; }
/// <summary> /// <summary>
/// ImGui Interface subsystem /// ImGui Interface subsystem
/// </summary> /// </summary>
internal readonly InterfaceManager InterfaceManager; internal InterfaceManager InterfaceManager { get; private set; }
/// <summary> /// <summary>
/// ClientState subsystem /// ClientState subsystem
/// </summary> /// </summary>
public readonly ClientState ClientState; public ClientState ClientState { get; private set; }
#endregion #endregion
@ -62,27 +62,27 @@ namespace Dalamud {
/// <summary> /// <summary>
/// Plugin Manager subsystem /// Plugin Manager subsystem
/// </summary> /// </summary>
internal readonly PluginManager PluginManager; internal PluginManager PluginManager { get; private set; }
/// <summary> /// <summary>
/// Plugin Repository subsystem /// Plugin Repository subsystem
/// </summary> /// </summary>
internal readonly PluginRepository PluginRepository; internal PluginRepository PluginRepository { get; private set; }
/// <summary> /// <summary>
/// Data provider subsystem /// Data provider subsystem
/// </summary> /// </summary>
internal readonly DataManager Data; internal DataManager Data { get; private set; }
/// <summary> /// <summary>
/// Command Manager subsystem /// Command Manager subsystem
/// </summary> /// </summary>
internal readonly CommandManager CommandManager; internal CommandManager CommandManager { get; private set; }
/// <summary> /// <summary>
/// Localization subsystem facilitating localization for Dalamud and plugins /// Localization subsystem facilitating localization for Dalamud and plugins
/// </summary> /// </summary>
internal readonly Localization LocalizationManager; internal Localization LocalizationManager { get; private set; }
#endregion #endregion
@ -91,27 +91,27 @@ namespace Dalamud {
/// <summary> /// <summary>
/// SeStringManager subsystem facilitating string parsing /// SeStringManager subsystem facilitating string parsing
/// </summary> /// </summary>
internal readonly SeStringManager SeStringManager; internal SeStringManager SeStringManager { get; private set; }
/// <summary> /// <summary>
/// Copy-enabled SigScanner for target module /// Copy-enabled SigScanner for target module
/// </summary> /// </summary>
internal readonly SigScanner SigScanner; internal SigScanner SigScanner { get; private set; }
/// <summary> /// <summary>
/// LoggingLevelSwitch for Dalamud and Plugin logs /// LoggingLevelSwitch for Dalamud and Plugin logs
/// </summary> /// </summary>
internal readonly LoggingLevelSwitch LogLevelSwitch; internal LoggingLevelSwitch LogLevelSwitch { get; private set; }
/// <summary> /// <summary>
/// StartInfo object passed from injector /// StartInfo object passed from injector
/// </summary> /// </summary>
internal readonly DalamudStartInfo StartInfo; internal DalamudStartInfo StartInfo { get; private set; }
/// <summary> /// <summary>
/// Configuration object facilitating save and load of Dalamud configuration /// Configuration object facilitating save and load of Dalamud configuration
/// </summary> /// </summary>
internal readonly DalamudConfiguration Configuration; internal DalamudConfiguration Configuration { get; private set; }
#endregion #endregion
@ -120,22 +120,22 @@ namespace Dalamud {
/// <summary> /// <summary>
/// Dalamud base UI /// Dalamud base UI
/// </summary> /// </summary>
internal readonly DalamudInterface DalamudUi; internal DalamudInterface DalamudUi { get; private set; }
/// <summary> /// <summary>
/// Dalamud chat commands /// Dalamud chat commands
/// </summary> /// </summary>
internal readonly DalamudCommands DalamudCommands; internal DalamudCommands DalamudCommands { get; private set; }
/// <summary> /// <summary>
/// Dalamud chat-based features /// Dalamud chat-based features
/// </summary> /// </summary>
internal readonly ChatHandlers ChatHandlers; internal ChatHandlers ChatHandlers { get; private set; }
/// <summary> /// <summary>
/// Dalamud network-based features /// Dalamud network-based features
/// </summary> /// </summary>
internal readonly NetworkHandlers NetworkHandlers; internal NetworkHandlers NetworkHandlers { get; private set; }
#endregion #endregion
@ -152,7 +152,7 @@ namespace Dalamud {
/// <summary> /// <summary>
/// Injected process module /// Injected process module
/// </summary> /// </summary>
internal readonly ProcessModule TargetModule; internal ProcessModule TargetModule { get; private set; }
/// <summary> /// <summary>
/// Value indicating if Dalamud was successfully loaded /// Value indicating if Dalamud was successfully loaded
@ -165,92 +165,89 @@ namespace Dalamud {
internal DirectoryInfo AssetDirectory => new DirectoryInfo(this.StartInfo.AssetDirectory); internal DirectoryInfo AssetDirectory => new DirectoryInfo(this.StartInfo.AssetDirectory);
public Dalamud(DalamudStartInfo info, LoggingLevelSwitch loggingLevelSwitch, ManualResetEvent finishSignal) { public Dalamud(DalamudStartInfo info, LoggingLevelSwitch loggingLevelSwitch, ManualResetEvent finishSignal) {
this.StartInfo = info; StartInfo = info;
this.LogLevelSwitch = loggingLevelSwitch; LogLevelSwitch = loggingLevelSwitch;
this.baseDirectory = info.WorkingDirectory; this.baseDirectory = info.WorkingDirectory;
this.unloadSignal = new ManualResetEvent(false); this.unloadSignal = new ManualResetEvent(false);
this.finishUnloadSignal = finishSignal; this.unloadSignal.Reset();
this.Configuration = DalamudConfiguration.Load(info.ConfigurationPath); this.finishUnloadSignal = finishSignal;
this.unloadSignal.Reset();
}
public void Start() {
Configuration = DalamudConfiguration.Load(StartInfo.ConfigurationPath);
// Initialize the process information. // Initialize the process information.
this.TargetModule = Process.GetCurrentProcess().MainModule; TargetModule = Process.GetCurrentProcess().MainModule;
this.SigScanner = new SigScanner(this.TargetModule, true); SigScanner = new SigScanner(TargetModule, true);
this.AntiDebug = new AntiDebug(this.SigScanner); AntiDebug = new AntiDebug(SigScanner);
#if DEBUG
AntiDebug.Enable();
#endif
// Initialize game subsystem // Initialize game subsystem
this.Framework = new Framework(this.SigScanner, this); Framework = new Framework(SigScanner, this);
this.WinSock2 = new WinSockHandlers(); WinSock2 = new WinSockHandlers();
this.NetworkHandlers = new NetworkHandlers(this, info.OptOutMbCollection); NetworkHandlers = new NetworkHandlers(this, StartInfo.OptOutMbCollection);
this.ClientState = new ClientState(this, info, this.SigScanner); ClientState = new ClientState(this, StartInfo, SigScanner);
this.LocalizationManager = new Localization(AssetDirectory.FullName); LocalizationManager = new Localization(AssetDirectory.FullName);
if (!string.IsNullOrEmpty(this.Configuration.LanguageOverride)) if (!string.IsNullOrEmpty(Configuration.LanguageOverride))
this.LocalizationManager.SetupWithLangCode(this.Configuration.LanguageOverride); LocalizationManager.SetupWithLangCode(Configuration.LanguageOverride);
else else
this.LocalizationManager.SetupWithUiCulture(); LocalizationManager.SetupWithUiCulture();
this.PluginRepository = new PluginRepository(this, this.StartInfo.PluginDirectory, this.StartInfo.GameVersion); PluginRepository = new PluginRepository(this, StartInfo.PluginDirectory, StartInfo.GameVersion);
this.DalamudUi = new DalamudInterface(this); DalamudUi = new DalamudInterface(this);
var isInterfaceLoaded = false; var isInterfaceLoaded = false;
if (!bool.Parse(Environment.GetEnvironmentVariable("DALAMUD_NOT_HAVE_INTERFACE") ?? "false")) if (!bool.Parse(Environment.GetEnvironmentVariable("DALAMUD_NOT_HAVE_INTERFACE") ?? "false")) {
{ try {
try InterfaceManager = new InterfaceManager(this, SigScanner);
{ InterfaceManager.OnDraw += DalamudUi.Draw;
this.InterfaceManager = new InterfaceManager(this, this.SigScanner);
this.InterfaceManager.OnDraw += this.DalamudUi.Draw;
this.InterfaceManager.Enable(); InterfaceManager.Enable();
isInterfaceLoaded = true; isInterfaceLoaded = true;
} } catch (Exception e) {
catch (Exception e)
{
Log.Information(e, "Could not init interface."); Log.Information(e, "Could not init interface.");
} }
} }
this.Data = new DataManager(this.StartInfo.Language); Data = new DataManager(StartInfo.Language);
try try {
{ Data.Initialize(AssetDirectory.FullName);
this.Data.Initialize(AssetDirectory.FullName); } catch (Exception e) {
}
catch (Exception e)
{
Log.Error(e, "Could not initialize DataManager."); Log.Error(e, "Could not initialize DataManager.");
Unload(); Unload();
return; return;
} }
this.SeStringManager = new SeStringManager(this.Data); SeStringManager = new SeStringManager(Data);
#if DEBUG
this.AntiDebug = new AntiDebug(this.SigScanner);
#endif
// Initialize managers. Basically handlers for the logic // Initialize managers. Basically handlers for the logic
this.CommandManager = new CommandManager(this, info.Language); CommandManager = new CommandManager(this, StartInfo.Language);
this.DalamudCommands = new DalamudCommands(this); DalamudCommands = new DalamudCommands(this);
this.DalamudCommands.SetupCommands(); DalamudCommands.SetupCommands();
this.ChatHandlers = new ChatHandlers(this); ChatHandlers = new ChatHandlers(this);
if (!bool.Parse(Environment.GetEnvironmentVariable("DALAMUD_NOT_HAVE_PLUGINS") ?? "false")) if (!bool.Parse(Environment.GetEnvironmentVariable("DALAMUD_NOT_HAVE_PLUGINS") ?? "false"))
{ {
try try
{ {
this.PluginRepository.CleanupPlugins(); PluginRepository.CleanupPlugins();
this.PluginManager = PluginManager =
new PluginManager(this, this.StartInfo.PluginDirectory, this.StartInfo.DefaultPluginDirectory); new PluginManager(this, StartInfo.PluginDirectory, StartInfo.DefaultPluginDirectory);
this.PluginManager.LoadPlugins(); PluginManager.LoadPlugins();
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -258,22 +255,18 @@ namespace Dalamud {
} }
} }
this.Framework.Enable(); Framework.Enable();
this.ClientState.Enable(); ClientState.Enable();
IsReady = true; IsReady = true;
Troubleshooting.LogTroubleshooting(this, isInterfaceLoaded); Troubleshooting.LogTroubleshooting(this, isInterfaceLoaded);
}
public void Start() { Log.Information("Dalamud is ready.");
#if DEBUG
AntiDebug.Enable();
//ReplaceExceptionHandler();
#endif
} }
public void Unload() { public void Unload() {
Log.Information("Trigger unload");
this.unloadSignal.Set(); this.unloadSignal.Set();
} }
@ -286,35 +279,36 @@ namespace Dalamud {
} }
public void Dispose() { public void Dispose() {
// this must be done before unloading plugins, or it can cause a race condition try {
// due to rendering happening on another thread, where a plugin might receive // this must be done before unloading plugins, or it can cause a race condition
// a render call after it has been disposed, which can crash if it attempts to // due to rendering happening on another thread, where a plugin might receive
// use any resources that it freed in its own Dispose method // a render call after it has been disposed, which can crash if it attempts to
this.InterfaceManager?.Dispose(); // use any resources that it freed in its own Dispose method
InterfaceManager?.Dispose();
try try {
{ PluginManager.UnloadPlugins();
this.PluginManager.UnloadPlugins(); } catch (Exception ex) {
Log.Error(ex, "Plugin unload failed.");
}
Framework.Dispose();
ClientState.Dispose();
this.unloadSignal.Dispose();
WinSock2.Dispose();
SigScanner.Dispose();
Data.Dispose();
AntiDebug.Dispose();
Log.Debug("Dalamud::Dispose OK!");
} catch (Exception ex) {
Log.Error(ex, "skjdgjjkodsfg");
} }
catch (Exception ex)
{
Log.Error(ex, "Plugin unload failed.");
}
this.Framework.Dispose();
this.ClientState.Dispose();
this.unloadSignal.Dispose();
this.WinSock2.Dispose();
this.SigScanner.Dispose();
this.Data.Dispose();
this.AntiDebug?.Dispose();
Log.Debug("Dalamud::Dispose OK!");
} }
internal void ReplaceExceptionHandler() { internal void ReplaceExceptionHandler() {

View file

@ -23,7 +23,7 @@ namespace Dalamud {
var finishSignal = new ManualResetEvent(false); var finishSignal = new ManualResetEvent(false);
try { try {
Log.Information(new string('-', 200)); Log.Information(new string('-', 80));
Log.Information("Initializing a session.."); Log.Information("Initializing a session..");
// This is due to GitHub not supporting TLS 1.0, so we enable all TLS versions globally // This is due to GitHub not supporting TLS 1.0, so we enable all TLS versions globally
@ -34,12 +34,14 @@ namespace Dalamud {
AppDomain.CurrentDomain.UnhandledException += OnUnhandledException; AppDomain.CurrentDomain.UnhandledException += OnUnhandledException;
TaskScheduler.UnobservedTaskException += OnUnobservedTaskException; TaskScheduler.UnobservedTaskException += OnUnobservedTaskException;
using var dalamud = new Dalamud(info, levelSwitch, finishSignal); var dalamud = new Dalamud(info, levelSwitch, finishSignal);
Log.Information("Starting a session.."); Log.Information("Starting a session..");
// Run session // Run session
dalamud.Start(); dalamud.Start();
dalamud.WaitForUnload(); dalamud.WaitForUnload();
dalamud.Dispose();
} catch (Exception ex) { } catch (Exception ex) {
Log.Fatal(ex, "Unhandled exception on main thread."); Log.Fatal(ex, "Unhandled exception on main thread.");
} finally { } finally {

View file

@ -11,6 +11,8 @@ namespace Dalamud.Game.Internal
{ {
private IntPtr DebugCheckAddress { get; set; } private IntPtr DebugCheckAddress { get; set; }
public bool IsEnabled { get; private set; }
public AntiDebug(SigScanner scanner) { public AntiDebug(SigScanner scanner) {
DebugCheckAddress = scanner.ScanText("FF 15 ?? ?? ?? ?? 85 C0 74 11"); DebugCheckAddress = scanner.ScanText("FF 15 ?? ?? ?? ?? 85 C0 74 11");
@ -22,11 +24,13 @@ namespace Dalamud.Game.Internal
public void Enable() { public void Enable() {
this.original = new byte[this.nop.Length]; this.original = new byte[this.nop.Length];
if (DebugCheckAddress != IntPtr.Zero) { if (DebugCheckAddress != IntPtr.Zero && !IsEnabled) {
Log.Information($"Overwriting Debug Check @ 0x{DebugCheckAddress.ToInt64():X}"); Log.Information($"Overwriting Debug Check @ 0x{DebugCheckAddress.ToInt64():X}");
Marshal.Copy(DebugCheckAddress, this.original, 0, this.nop.Length); Marshal.Copy(DebugCheckAddress, this.original, 0, this.nop.Length);
Marshal.Copy(this.nop, 0, DebugCheckAddress, this.nop.Length); Marshal.Copy(this.nop, 0, DebugCheckAddress, this.nop.Length);
} }
IsEnabled = true;
} }
public void Dispose() { public void Dispose() {

View file

@ -108,7 +108,7 @@ namespace Dalamud.Interface
ImGui.EndMenu(); ImGui.EndMenu();
} }
if (this.dalamud.AntiDebug == null && ImGui.MenuItem("Enable AntiDebug")) if (ImGui.MenuItem("Enable AntiDebug", null, this.dalamud.AntiDebug.IsEnabled))
{ {
this.dalamud.AntiDebug.Enable(); this.dalamud.AntiDebug.Enable();
} }