mirror of
https://github.com/goatcorp/Dalamud.git
synced 2025-12-13 12:14:16 +01:00
commit
ad802d2cbf
6 changed files with 69 additions and 19 deletions
|
|
@ -23,9 +23,14 @@ namespace Dalamud.Configuration.Internal
|
||||||
public static bool DalamudNoPlugins { get; } = GetEnvironmentVariable("DALAMUD_NOT_HAVE_PLUGINS");
|
public static bool DalamudNoPlugins { get; } = GetEnvironmentVariable("DALAMUD_NOT_HAVE_PLUGINS");
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets a value indicating whether the DalamudForceCoreHook setting has been enabled.
|
/// Gets a value indicating whether the DalamudForceReloaded setting has been enabled.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static bool DalamudForceMinHook { get; } = GetEnvironmentVariable("DALAMUD_FORCE_COREHOOK");
|
public static bool DalamudForceReloaded { get; } = GetEnvironmentVariable("DALAMUD_FORCE_RELOADED");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a value indicating whether the DalamudForceMinHook setting has been enabled.
|
||||||
|
/// </summary>
|
||||||
|
public static bool DalamudForceMinHook { get; } = GetEnvironmentVariable("DALAMUD_FORCE_MINHOOK");
|
||||||
|
|
||||||
private static bool GetEnvironmentVariable(string name)
|
private static bool GetEnvironmentVariable(string name)
|
||||||
=> bool.Parse(Environment.GetEnvironmentVariable(name) ?? "false");
|
=> bool.Parse(Environment.GetEnvironmentVariable(name) ?? "false");
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,11 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Diagnostics;
|
using System.Collections.Generic;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
|
||||||
using Dalamud.Configuration.Internal;
|
using Dalamud.Configuration.Internal;
|
||||||
using Dalamud.Hooking.Internal;
|
using Dalamud.Hooking.Internal;
|
||||||
using Dalamud.Memory;
|
using Dalamud.Memory;
|
||||||
using Reloaded.Hooks;
|
using Reloaded.Hooks;
|
||||||
using Serilog;
|
|
||||||
|
|
||||||
namespace Dalamud.Hooking
|
namespace Dalamud.Hooking
|
||||||
{
|
{
|
||||||
|
|
@ -29,7 +28,7 @@ namespace Dalamud.Hooking
|
||||||
/// <param name="address">A memory address to install a hook.</param>
|
/// <param name="address">A memory address to install a hook.</param>
|
||||||
/// <param name="detour">Callback function. Delegate must have a same original function prototype.</param>
|
/// <param name="detour">Callback function. Delegate must have a same original function prototype.</param>
|
||||||
public Hook(IntPtr address, T detour)
|
public Hook(IntPtr address, T detour)
|
||||||
: this(address, detour, false)
|
: this(address, detour, false, Assembly.GetCallingAssembly())
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -42,9 +41,14 @@ namespace Dalamud.Hooking
|
||||||
/// <param name="detour">Callback function. Delegate must have a same original function prototype.</param>
|
/// <param name="detour">Callback function. Delegate must have a same original function prototype.</param>
|
||||||
/// <param name="useMinHook">Use the MinHook hooking library instead of Reloaded.</param>
|
/// <param name="useMinHook">Use the MinHook hooking library instead of Reloaded.</param>
|
||||||
public Hook(IntPtr address, T detour, bool useMinHook)
|
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);
|
address = HookManager.FollowJmp(address);
|
||||||
this.isMinHook = EnvironmentConfiguration.DalamudForceMinHook || useMinHook;
|
this.isMinHook = !EnvironmentConfiguration.DalamudForceReloaded && (EnvironmentConfiguration.DalamudForceMinHook || useMinHook);
|
||||||
|
|
||||||
var hasOtherHooks = HookManager.Originals.ContainsKey(address);
|
var hasOtherHooks = HookManager.Originals.ContainsKey(address);
|
||||||
if (!hasOtherHooks)
|
if (!hasOtherHooks)
|
||||||
|
|
@ -56,9 +60,9 @@ namespace Dalamud.Hooking
|
||||||
this.address = address;
|
this.address = address;
|
||||||
if (this.isMinHook)
|
if (this.isMinHook)
|
||||||
{
|
{
|
||||||
var indexList = hasOtherHooks
|
if (!HookManager.MultiHookTracker.TryGetValue(address, out var indexList))
|
||||||
? HookManager.MultiHookTracker[address]
|
indexList = HookManager.MultiHookTracker[address] = new();
|
||||||
: HookManager.MultiHookTracker[address] = new();
|
|
||||||
var index = (ulong)indexList.Count;
|
var index = (ulong)indexList.Count;
|
||||||
|
|
||||||
this.minHookImpl = new MinSharp.Hook<T>(address, detour, index);
|
this.minHookImpl = new MinSharp.Hook<T>(address, detour, index);
|
||||||
|
|
@ -71,7 +75,7 @@ namespace Dalamud.Hooking
|
||||||
this.hookImpl = ReloadedHooks.Instance.CreateHook<T>(detour, address.ToInt64());
|
this.hookImpl = ReloadedHooks.Instance.CreateHook<T>(detour, address.ToInt64());
|
||||||
}
|
}
|
||||||
|
|
||||||
HookManager.TrackedHooks.Add(new HookInfo(this, detour, Assembly.GetCallingAssembly()));
|
HookManager.TrackedHooks.Add(new HookInfo(this, detour, callingAssembly));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -188,7 +192,9 @@ namespace Dalamud.Hooking
|
||||||
if (this.isMinHook)
|
if (this.isMinHook)
|
||||||
{
|
{
|
||||||
this.minHookImpl.Dispose();
|
this.minHookImpl.Dispose();
|
||||||
HookManager.MultiHookTracker[this.address] = null;
|
|
||||||
|
var index = HookManager.MultiHookTracker[this.address].IndexOf(this);
|
||||||
|
HookManager.MultiHookTracker[this.address][index] = null;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -196,7 +196,7 @@ namespace Dalamud.Interface.Internal.Windows
|
||||||
if (ImGui.IsItemHovered())
|
if (ImGui.IsItemHovered())
|
||||||
ImGui.SetTooltip("Kill game");
|
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)
|
if (clear)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1564,6 +1564,8 @@ namespace Dalamud.Interface.Internal.Windows
|
||||||
|
|
||||||
if (ImGui.CollapsingHeader($"#{task.Id} - {task.Status} {(subTime - task.StartTime).TotalMilliseconds}ms###task{i}"))
|
if (ImGui.CollapsingHeader($"#{task.Id} - {task.Status} {(subTime - task.StartTime).TotalMilliseconds}ms###task{i}"))
|
||||||
{
|
{
|
||||||
|
task.IsBeingViewed = true;
|
||||||
|
|
||||||
if (ImGui.Button("CANCEL (May not work)"))
|
if (ImGui.Button("CANCEL (May not work)"))
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
|
@ -1589,6 +1591,10 @@ namespace Dalamud.Interface.Internal.Windows
|
||||||
ImGui.TextUnformatted(task.Exception.ToString());
|
ImGui.TextUnformatted(task.Exception.ToString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
task.IsBeingViewed = false;
|
||||||
|
}
|
||||||
|
|
||||||
ImGui.PopStyleColor(1);
|
ImGui.PopStyleColor(1);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@ namespace Dalamud.Logging.Internal
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal class TaskTracker : IDisposable
|
internal class TaskTracker : IDisposable
|
||||||
{
|
{
|
||||||
|
private static readonly ModuleLog Log = new("TT");
|
||||||
private static readonly List<TaskInfo> TrackedTasksInternal = new();
|
private static readonly List<TaskInfo> TrackedTasksInternal = new();
|
||||||
private static readonly ConcurrentQueue<TaskInfo> NewlyCreatedTasks = new();
|
private static readonly ConcurrentQueue<TaskInfo> NewlyCreatedTasks = new();
|
||||||
private static bool clearRequested = false;
|
private static bool clearRequested = false;
|
||||||
|
|
@ -53,12 +54,33 @@ namespace Dalamud.Logging.Internal
|
||||||
clearRequested = false;
|
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))
|
while (NewlyCreatedTasks.TryDequeue(out var newTask))
|
||||||
{
|
{
|
||||||
TrackedTasksInternal.Add(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];
|
var taskInfo = TrackedTasksInternal[i];
|
||||||
if (taskInfo.Task == null)
|
if (taskInfo.Task == null)
|
||||||
|
|
@ -123,10 +145,16 @@ namespace Dalamud.Logging.Internal
|
||||||
var patchMethod = typeof(TaskTracker).GetMethod(nameof(AddToActiveTasksHook), BindingFlags.NonPublic | BindingFlags.Static);
|
var patchMethod = typeof(TaskTracker).GetMethod(nameof(AddToActiveTasksHook), BindingFlags.NonPublic | BindingFlags.Static);
|
||||||
|
|
||||||
if (targetMethod == null)
|
if (targetMethod == null)
|
||||||
Log.Error("TargetMethod null!");
|
{
|
||||||
|
Log.Error("AddToActiveTasks TargetMethod null!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (patchMethod == null)
|
if (patchMethod == null)
|
||||||
Log.Error("PatchMethod null!");
|
{
|
||||||
|
Log.Error("AddToActiveTasks PatchMethod null!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
this.scheduleAndStartHook = new MonoMod.RuntimeDetour.Hook(targetMethod, patchMethod);
|
this.scheduleAndStartHook = new MonoMod.RuntimeDetour.Hook(targetMethod, patchMethod);
|
||||||
|
|
||||||
|
|
@ -173,6 +201,11 @@ namespace Dalamud.Logging.Internal
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool IsCompletedSuccessfully { get; set; }
|
public bool IsCompletedSuccessfully { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets a value indicating whether this task is being viewed.
|
||||||
|
/// </summary>
|
||||||
|
public bool IsBeingViewed { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the status of the task.
|
/// Gets or sets the status of the task.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
||||||
|
|
@ -478,8 +478,8 @@ namespace Dalamud
|
||||||
WM_INPUT_DEVICE_CHANGE = 0x00FE,
|
WM_INPUT_DEVICE_CHANGE = 0x00FE,
|
||||||
WM_INPUT = 0x00FF,
|
WM_INPUT = 0x00FF,
|
||||||
|
|
||||||
WM_KEYFIRST = WM_KEYDOWN,
|
WM_KEYFIRST = 0x0100,
|
||||||
WM_KEYDOWN = 0x0100,
|
WM_KEYDOWN = WM_KEYFIRST,
|
||||||
WM_KEYUP = 0x0101,
|
WM_KEYUP = 0x0101,
|
||||||
WM_CHAR = 0x0102,
|
WM_CHAR = 0x0102,
|
||||||
WM_DEADCHAR = 0x0103,
|
WM_DEADCHAR = 0x0103,
|
||||||
|
|
@ -525,8 +525,8 @@ namespace Dalamud
|
||||||
WM_CTLCOLORSTATIC = 0x0138,
|
WM_CTLCOLORSTATIC = 0x0138,
|
||||||
MN_GETHMENU = 0x01E1,
|
MN_GETHMENU = 0x01E1,
|
||||||
|
|
||||||
WM_MOUSEFIRST = WM_MOUSEMOVE,
|
WM_MOUSEFIRST = 0x0200,
|
||||||
WM_MOUSEMOVE = 0x0200,
|
WM_MOUSEMOVE = WM_MOUSEFIRST,
|
||||||
WM_LBUTTONDOWN = 0x0201,
|
WM_LBUTTONDOWN = 0x0201,
|
||||||
WM_LBUTTONUP = 0x0202,
|
WM_LBUTTONUP = 0x0202,
|
||||||
WM_LBUTTONDBLCLK = 0x0203,
|
WM_LBUTTONDBLCLK = 0x0203,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue