Keep track of hooks and display them in the Plugin Stats window

This will make it easier to find plugins that are not correctly removing their hooks
This commit is contained in:
Cara 2020-12-15 02:57:04 +10:30
parent f1f7803434
commit 850123aece
4 changed files with 130 additions and 6 deletions

View file

@ -1,6 +1,8 @@
using System;
using System.Linq;
using System.Reflection;
using Dalamud.Game.Internal;
using Dalamud.Hooking;
using Dalamud.Plugin;
using ImGuiNET;
@ -8,6 +10,8 @@ namespace Dalamud.Interface {
internal class DalamudPluginStatWindow : IDisposable {
private readonly PluginManager pluginManager;
private bool showDalamudHooks;
public DalamudPluginStatWindow(PluginManager pluginManager) {
this.pluginManager = pluginManager;
}
@ -122,10 +126,70 @@ namespace Dalamud.Interface {
ImGui.EndTabItem();
}
if (ImGui.BeginTabItem("Hooks")) {
ImGui.Columns(3);
ImGui.SetColumnWidth(0, ImGui.GetWindowContentRegionWidth() - 280);
ImGui.SetColumnWidth(1, 180f);
ImGui.SetColumnWidth(2, 100f);
ImGui.Text("Detour Method");
ImGui.SameLine();
ImGui.Text(" ");
ImGui.SameLine();
ImGui.Checkbox("Show Dalamud Hooks ###showDalamudHooksCheckbox", ref showDalamudHooks);
ImGui.NextColumn();
ImGui.Text("Address");
ImGui.NextColumn();
ImGui.Text("Status");
ImGui.NextColumn();
ImGui.Separator();
ImGui.Separator();
foreach (var trackedHook in HookInfo.TrackedHooks) {
try {
if (!this.showDalamudHooks && trackedHook.Assembly == Assembly.GetExecutingAssembly()) continue;
ImGui.Text($"{trackedHook.Delegate.Target} :: {trackedHook.Delegate.Method.Name}");
ImGui.TextDisabled(trackedHook.Assembly.FullName);
ImGui.NextColumn();
if (!trackedHook.Hook.IsDisposed) {
ImGui.Text($"{trackedHook.Hook.Address.ToInt64():X}");
if (ImGui.IsItemClicked()) ImGui.SetClipboardText($"{trackedHook.Hook.Address.ToInt64():X}");
var processMemoryOffset = trackedHook.InProcessMemory;
if (processMemoryOffset.HasValue) {
ImGui.Text($"ffxiv_dx11.exe + {processMemoryOffset:X}");
if (ImGui.IsItemClicked()) ImGui.SetClipboardText($"ffxiv_dx11.exe+{processMemoryOffset:X}");
}
}
ImGui.NextColumn();
if (trackedHook.Hook.IsDisposed) {
ImGui.Text("Disposed");
} else {
ImGui.Text(trackedHook.Hook.IsEnabled ? "Enabled" : "Disabled");
}
ImGui.NextColumn();
} catch (Exception ex) {
ImGui.Text(ex.Message);
ImGui.NextColumn();
while (ImGui.GetColumnIndex() != 0) ImGui.NextColumn();
}
ImGui.Separator();
}
ImGui.Columns();
}
if (ImGui.IsWindowAppearing()) {
HookInfo.TrackedHooks.RemoveAll(h => h.Hook.IsDisposed);
}
ImGui.EndTabBar();
ImGui.End();