diff --git a/Dalamud/Configuration/Internal/EnvironmentConfiguration.cs b/Dalamud/Configuration/Internal/EnvironmentConfiguration.cs index 31bee1204..641cd5c2b 100644 --- a/Dalamud/Configuration/Internal/EnvironmentConfiguration.cs +++ b/Dalamud/Configuration/Internal/EnvironmentConfiguration.cs @@ -23,9 +23,14 @@ namespace Dalamud.Configuration.Internal public static bool DalamudNoPlugins { get; } = GetEnvironmentVariable("DALAMUD_NOT_HAVE_PLUGINS"); /// - /// Gets a value indicating whether the DalamudForceCoreHook setting has been enabled. + /// Gets a value indicating whether the DalamudForceReloaded setting has been enabled. /// - public static bool DalamudForceMinHook { get; } = GetEnvironmentVariable("DALAMUD_FORCE_COREHOOK"); + public static bool DalamudForceReloaded { get; } = GetEnvironmentVariable("DALAMUD_FORCE_RELOADED"); + + /// + /// Gets a value indicating whether the DalamudForceMinHook setting has been enabled. + /// + public static bool DalamudForceMinHook { get; } = GetEnvironmentVariable("DALAMUD_FORCE_MINHOOK"); private static bool GetEnvironmentVariable(string name) => bool.Parse(Environment.GetEnvironmentVariable(name) ?? "false"); diff --git a/Dalamud/Hooking/Hook.cs b/Dalamud/Hooking/Hook.cs index ba19ffb18..430527ed0 100644 --- a/Dalamud/Hooking/Hook.cs +++ b/Dalamud/Hooking/Hook.cs @@ -1,12 +1,11 @@ using System; -using System.Diagnostics; +using System.Collections.Generic; using System.Reflection; using Dalamud.Configuration.Internal; using Dalamud.Hooking.Internal; using Dalamud.Memory; using Reloaded.Hooks; -using Serilog; namespace Dalamud.Hooking { @@ -29,7 +28,7 @@ namespace Dalamud.Hooking /// A memory address to install a hook. /// Callback function. Delegate must have a same original function prototype. public Hook(IntPtr address, T detour) - : this(address, detour, false) + : this(address, detour, false, Assembly.GetCallingAssembly()) { } @@ -42,9 +41,14 @@ namespace Dalamud.Hooking /// Callback function. Delegate must have a same original function prototype. /// Use the MinHook hooking library instead of Reloaded. public Hook(IntPtr address, T detour, bool useMinHook) + : this(address, detour, useMinHook, Assembly.GetCallingAssembly()) + { + } + + private Hook(IntPtr address, T detour, bool useMinHook, Assembly callingAssembly) { address = HookManager.FollowJmp(address); - this.isMinHook = EnvironmentConfiguration.DalamudForceMinHook || useMinHook; + this.isMinHook = !EnvironmentConfiguration.DalamudForceReloaded && (EnvironmentConfiguration.DalamudForceMinHook || useMinHook); var hasOtherHooks = HookManager.Originals.ContainsKey(address); if (!hasOtherHooks) @@ -56,9 +60,9 @@ namespace Dalamud.Hooking this.address = address; if (this.isMinHook) { - var indexList = hasOtherHooks - ? HookManager.MultiHookTracker[address] - : HookManager.MultiHookTracker[address] = new(); + if (!HookManager.MultiHookTracker.TryGetValue(address, out var indexList)) + indexList = HookManager.MultiHookTracker[address] = new(); + var index = (ulong)indexList.Count; this.minHookImpl = new MinSharp.Hook(address, detour, index); @@ -71,7 +75,7 @@ namespace Dalamud.Hooking this.hookImpl = ReloadedHooks.Instance.CreateHook(detour, address.ToInt64()); } - HookManager.TrackedHooks.Add(new HookInfo(this, detour, Assembly.GetCallingAssembly())); + HookManager.TrackedHooks.Add(new HookInfo(this, detour, callingAssembly)); } /// @@ -188,7 +192,9 @@ namespace Dalamud.Hooking if (this.isMinHook) { this.minHookImpl.Dispose(); - HookManager.MultiHookTracker[this.address] = null; + + var index = HookManager.MultiHookTracker[this.address].IndexOf(this); + HookManager.MultiHookTracker[this.address][index] = null; } else { diff --git a/Dalamud/Interface/Internal/Windows/ConsoleWindow.cs b/Dalamud/Interface/Internal/Windows/ConsoleWindow.cs index fadf974c1..a34d758f7 100644 --- a/Dalamud/Interface/Internal/Windows/ConsoleWindow.cs +++ b/Dalamud/Interface/Internal/Windows/ConsoleWindow.cs @@ -196,7 +196,7 @@ namespace Dalamud.Interface.Internal.Windows if (ImGui.IsItemHovered()) ImGui.SetTooltip("Kill game"); - ImGui.BeginChild("scrolling", new Vector2(0, ImGui.GetFrameHeightWithSpacing() - 55), false, ImGuiWindowFlags.HorizontalScrollbar); + ImGui.BeginChild("scrolling", new Vector2(0, ImGui.GetFrameHeightWithSpacing() - 55), false, ImGuiWindowFlags.AlwaysHorizontalScrollbar | ImGuiWindowFlags.AlwaysVerticalScrollbar); if (clear) { diff --git a/Dalamud/Interface/Internal/Windows/DataWindow.cs b/Dalamud/Interface/Internal/Windows/DataWindow.cs index 7d24198e7..4128d41d3 100644 --- a/Dalamud/Interface/Internal/Windows/DataWindow.cs +++ b/Dalamud/Interface/Internal/Windows/DataWindow.cs @@ -1564,6 +1564,8 @@ namespace Dalamud.Interface.Internal.Windows if (ImGui.CollapsingHeader($"#{task.Id} - {task.Status} {(subTime - task.StartTime).TotalMilliseconds}ms###task{i}")) { + task.IsBeingViewed = true; + if (ImGui.Button("CANCEL (May not work)")) { try @@ -1589,6 +1591,10 @@ namespace Dalamud.Interface.Internal.Windows ImGui.TextUnformatted(task.Exception.ToString()); } } + else + { + task.IsBeingViewed = false; + } ImGui.PopStyleColor(1); } diff --git a/Dalamud/Logging/Internal/TaskTracker.cs b/Dalamud/Logging/Internal/TaskTracker.cs index 2ed3ccbbe..3888d55db 100644 --- a/Dalamud/Logging/Internal/TaskTracker.cs +++ b/Dalamud/Logging/Internal/TaskTracker.cs @@ -15,6 +15,7 @@ namespace Dalamud.Logging.Internal /// internal class TaskTracker : IDisposable { + private static readonly ModuleLog Log = new("TT"); private static readonly List TrackedTasksInternal = new(); private static readonly ConcurrentQueue NewlyCreatedTasks = new(); private static bool clearRequested = false; @@ -53,12 +54,33 @@ namespace Dalamud.Logging.Internal clearRequested = false; } + var i = 0; + var pruned = 0; + // Prune old tasks. Technically a memory "leak" that grows infinitely otherwise. + while (i < TrackedTasksInternal.Count) + { + var taskInfo = TrackedTasksInternal[i]; + if (taskInfo.IsCompleted && !taskInfo.IsBeingViewed && TrackedTasksInternal.Count > 1000) + { + TrackedTasksInternal.RemoveAt(i); + pruned++; + continue; + } + + i++; + } + + // if (pruned > 0) + // Log.Debug($"Pruned {pruned} tasks"); + + // Consume from a queue to prevent iteration errors while (NewlyCreatedTasks.TryDequeue(out var newTask)) { TrackedTasksInternal.Add(newTask); } - for (var i = 0; i < TrackedTasksInternal.Count; i++) + // Update each task + for (i = 0; i < TrackedTasksInternal.Count; i++) { var taskInfo = TrackedTasksInternal[i]; if (taskInfo.Task == null) @@ -123,10 +145,16 @@ namespace Dalamud.Logging.Internal var patchMethod = typeof(TaskTracker).GetMethod(nameof(AddToActiveTasksHook), BindingFlags.NonPublic | BindingFlags.Static); if (targetMethod == null) - Log.Error("TargetMethod null!"); + { + Log.Error("AddToActiveTasks TargetMethod null!"); + return; + } if (patchMethod == null) - Log.Error("PatchMethod null!"); + { + Log.Error("AddToActiveTasks PatchMethod null!"); + return; + } this.scheduleAndStartHook = new MonoMod.RuntimeDetour.Hook(targetMethod, patchMethod); @@ -173,6 +201,11 @@ namespace Dalamud.Logging.Internal /// public bool IsCompletedSuccessfully { get; set; } + /// + /// Gets or sets a value indicating whether this task is being viewed. + /// + public bool IsBeingViewed { get; set; } + /// /// Gets or sets the status of the task. /// diff --git a/Dalamud/NativeFunctions.cs b/Dalamud/NativeFunctions.cs index e23a7d237..d11c39464 100644 --- a/Dalamud/NativeFunctions.cs +++ b/Dalamud/NativeFunctions.cs @@ -478,8 +478,8 @@ namespace Dalamud WM_INPUT_DEVICE_CHANGE = 0x00FE, WM_INPUT = 0x00FF, - WM_KEYFIRST = WM_KEYDOWN, - WM_KEYDOWN = 0x0100, + WM_KEYFIRST = 0x0100, + WM_KEYDOWN = WM_KEYFIRST, WM_KEYUP = 0x0101, WM_CHAR = 0x0102, WM_DEADCHAR = 0x0103, @@ -525,8 +525,8 @@ namespace Dalamud WM_CTLCOLORSTATIC = 0x0138, MN_GETHMENU = 0x01E1, - WM_MOUSEFIRST = WM_MOUSEMOVE, - WM_MOUSEMOVE = 0x0200, + WM_MOUSEFIRST = 0x0200, + WM_MOUSEMOVE = WM_MOUSEFIRST, WM_LBUTTONDOWN = 0x0201, WM_LBUTTONUP = 0x0202, WM_LBUTTONDBLCLK = 0x0203,