mirror of
https://github.com/goatcorp/Dalamud.git
synced 2026-01-03 06:13:40 +01:00
Merge pull request #662 from goatcorp/multihook
This commit is contained in:
commit
736a0826a3
10 changed files with 142 additions and 54 deletions
|
|
@ -25,7 +25,7 @@ namespace Dalamud.Configuration.Internal
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets a value indicating whether the DalamudForceCoreHook setting has been enabled.
|
/// Gets a value indicating whether the DalamudForceCoreHook setting has been enabled.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static bool DalamudForceCoreHook { get; } = GetEnvironmentVariable("DALAMUD_FORCE_COREHOOK");
|
public static bool DalamudForceMinHook { get; } = GetEnvironmentVariable("DALAMUD_FORCE_COREHOOK");
|
||||||
|
|
||||||
private static bool GetEnvironmentVariable(string name)
|
private static bool GetEnvironmentVariable(string name)
|
||||||
=> bool.Parse(Environment.GetEnvironmentVariable(name) ?? "false");
|
=> bool.Parse(Environment.GetEnvironmentVariable(name) ?? "false");
|
||||||
|
|
|
||||||
|
|
@ -64,10 +64,10 @@
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="CheapLoc" Version="1.1.6" />
|
<PackageReference Include="CheapLoc" Version="1.1.6" />
|
||||||
<PackageReference Include="CoreHook" Version="1.0.4" />
|
|
||||||
<PackageReference Include="JetBrains.Annotations" Version="2021.2.0" />
|
<PackageReference Include="JetBrains.Annotations" Version="2021.2.0" />
|
||||||
<PackageReference Include="Lumina" Version="3.3.0" />
|
<PackageReference Include="Lumina" Version="3.3.0" />
|
||||||
<PackageReference Include="Lumina.Excel" Version="5.50.0" />
|
<PackageReference Include="Lumina.Excel" Version="5.50.0" />
|
||||||
|
<PackageReference Include="MinSharp" Version="1.0.4" />
|
||||||
<PackageReference Include="MonoMod.RuntimeDetour" Version="21.10.10.01" />
|
<PackageReference Include="MonoMod.RuntimeDetour" Version="21.10.10.01" />
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
|
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
|
||||||
<PackageReference Include="Serilog" Version="2.10.0" />
|
<PackageReference Include="Serilog" Version="2.10.0" />
|
||||||
|
|
@ -94,12 +94,6 @@
|
||||||
<AdditionalFiles Include="..\stylecop.json" />
|
<AdditionalFiles Include="..\stylecop.json" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<None Update="corehook64.dll">
|
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
|
||||||
</None>
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<Target Name="AddRuntimeDependenciesToContent" BeforeTargets="GetCopyToOutputDirectoryItems" DependsOnTargets="GenerateBuildDependencyFile;GenerateBuildRuntimeConfigurationFiles">
|
<Target Name="AddRuntimeDependenciesToContent" BeforeTargets="GetCopyToOutputDirectoryItems" DependsOnTargets="GenerateBuildDependencyFile;GenerateBuildRuntimeConfigurationFiles">
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ContentWithTargetPath Include="$(ProjectDepsFilePath)" CopyToOutputDirectory="PreserveNewest" TargetPath="$(ProjectDepsFileName)" />
|
<ContentWithTargetPath Include="$(ProjectDepsFilePath)" CopyToOutputDirectory="PreserveNewest" TargetPath="$(ProjectDepsFileName)" />
|
||||||
|
|
|
||||||
|
|
@ -112,6 +112,9 @@ namespace Dalamud.Hooking
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool IsDisposed { get; private set; }
|
public bool IsDisposed { get; private set; }
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public string BackendName => "Reloaded/Asm";
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Remove a hook from the current process.
|
/// Remove a hook from the current process.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
using System;
|
using System;
|
||||||
|
using System.Diagnostics;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
|
||||||
using Dalamud.Configuration.Internal;
|
using Dalamud.Configuration.Internal;
|
||||||
|
|
@ -18,8 +19,8 @@ namespace Dalamud.Hooking
|
||||||
{
|
{
|
||||||
private readonly IntPtr address;
|
private readonly IntPtr address;
|
||||||
private readonly Reloaded.Hooks.Definitions.IHook<T> hookImpl;
|
private readonly Reloaded.Hooks.Definitions.IHook<T> hookImpl;
|
||||||
private readonly CoreHook.IHook<T> coreHookImpl;
|
private readonly MinSharp.Hook<T> minHookImpl;
|
||||||
private readonly bool isCoreHook;
|
private readonly bool isMinHook;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="Hook{T}"/> class.
|
/// Initializes a new instance of the <see cref="Hook{T}"/> class.
|
||||||
|
|
@ -35,15 +36,15 @@ namespace Dalamud.Hooking
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="Hook{T}"/> class.
|
/// Initializes a new instance of the <see cref="Hook{T}"/> class.
|
||||||
/// Hook is not activated until Enable() method is called.
|
/// Hook is not activated until Enable() method is called.
|
||||||
/// Please do not use CoreHook unless you have thoroughly troubleshot why Reloaded does not work.
|
/// Please do not use MinHook unless you have thoroughly troubleshot why Reloaded does not work.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <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>
|
||||||
/// <param name="useCoreHook">Use the corehook 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 useCoreHook)
|
public Hook(IntPtr address, T detour, bool useMinHook)
|
||||||
{
|
{
|
||||||
address = HookManager.FollowJmp(address);
|
address = HookManager.FollowJmp(address);
|
||||||
this.isCoreHook = useCoreHook || EnvironmentConfiguration.DalamudForceCoreHook;
|
this.isMinHook = EnvironmentConfiguration.DalamudForceMinHook || useMinHook;
|
||||||
|
|
||||||
var hasOtherHooks = HookManager.Originals.ContainsKey(address);
|
var hasOtherHooks = HookManager.Originals.ContainsKey(address);
|
||||||
if (!hasOtherHooks)
|
if (!hasOtherHooks)
|
||||||
|
|
@ -53,18 +54,17 @@ namespace Dalamud.Hooking
|
||||||
}
|
}
|
||||||
|
|
||||||
this.address = address;
|
this.address = address;
|
||||||
if (this.isCoreHook)
|
if (this.isMinHook)
|
||||||
{
|
{
|
||||||
try
|
var indexList = hasOtherHooks
|
||||||
{
|
? HookManager.MultiHookTracker[address]
|
||||||
this.coreHookImpl = CoreHook.HookFactory.CreateHook<T>(address, detour);
|
: HookManager.MultiHookTracker[address] = new();
|
||||||
}
|
var index = (ulong)indexList.Count;
|
||||||
catch (Exception ex)
|
|
||||||
{
|
this.minHookImpl = new MinSharp.Hook<T>(address, detour, index);
|
||||||
this.isCoreHook = false;
|
|
||||||
Log.Error(ex, "CoreHook is having a bad day, defaulting to Reloaded");
|
// Add afterwards, so the hookIdent starts at 0.
|
||||||
this.hookImpl = ReloadedHooks.Instance.CreateHook<T>(detour, address.ToInt64());
|
indexList.Add(this);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -96,9 +96,9 @@ namespace Dalamud.Hooking
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
this.CheckDisposed();
|
this.CheckDisposed();
|
||||||
if (this.isCoreHook)
|
if (this.isMinHook)
|
||||||
{
|
{
|
||||||
return this.coreHookImpl.Original;
|
return this.minHookImpl.Original;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -115,9 +115,9 @@ namespace Dalamud.Hooking
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
this.CheckDisposed();
|
this.CheckDisposed();
|
||||||
if (this.isCoreHook)
|
if (this.isMinHook)
|
||||||
{
|
{
|
||||||
return this.coreHookImpl.Enabled;
|
return this.minHookImpl.Enabled;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -131,6 +131,18 @@ namespace Dalamud.Hooking
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool IsDisposed { get; private set; }
|
public bool IsDisposed { get; private set; }
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public string BackendName
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (this.isMinHook)
|
||||||
|
return "MinHook";
|
||||||
|
|
||||||
|
return "Reloaded";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a hook. Hooking address is inferred by calling to GetProcAddress() function.
|
/// Creates a hook. Hooking address is inferred by calling to GetProcAddress() function.
|
||||||
/// The hook is not activated until Enable() method is called.
|
/// The hook is not activated until Enable() method is called.
|
||||||
|
|
@ -145,14 +157,14 @@ namespace Dalamud.Hooking
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a hook. Hooking address is inferred by calling to GetProcAddress() function.
|
/// Creates a hook. Hooking address is inferred by calling to GetProcAddress() function.
|
||||||
/// The hook is not activated until Enable() method is called.
|
/// The hook is not activated until Enable() method is called.
|
||||||
/// Please do not use CoreHook unless you have thoroughly troubleshot why Reloaded does not work.
|
/// Please do not use MinHook unless you have thoroughly troubleshot why Reloaded does not work.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="moduleName">A name of the module currently loaded in the memory. (e.g. ws2_32.dll).</param>
|
/// <param name="moduleName">A name of the module currently loaded in the memory. (e.g. ws2_32.dll).</param>
|
||||||
/// <param name="exportName">A name of the exported function name (e.g. send).</param>
|
/// <param name="exportName">A name of the exported function name (e.g. send).</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>
|
||||||
/// <param name="useCoreHook">Use the corehook hooking library instead of Reloaded.</param>
|
/// <param name="useMinHook">Use the MinHook hooking library instead of Reloaded.</param>
|
||||||
/// <returns>The hook with the supplied parameters.</returns>
|
/// <returns>The hook with the supplied parameters.</returns>
|
||||||
public static Hook<T> FromSymbol(string moduleName, string exportName, T detour, bool useCoreHook)
|
public static Hook<T> FromSymbol(string moduleName, string exportName, T detour, bool useMinHook)
|
||||||
{
|
{
|
||||||
var moduleHandle = NativeFunctions.GetModuleHandleW(moduleName);
|
var moduleHandle = NativeFunctions.GetModuleHandleW(moduleName);
|
||||||
if (moduleHandle == IntPtr.Zero)
|
if (moduleHandle == IntPtr.Zero)
|
||||||
|
|
@ -162,7 +174,7 @@ namespace Dalamud.Hooking
|
||||||
if (procAddress == IntPtr.Zero)
|
if (procAddress == IntPtr.Zero)
|
||||||
throw new Exception($"Could not get the address of {moduleName}::{exportName}");
|
throw new Exception($"Could not get the address of {moduleName}::{exportName}");
|
||||||
|
|
||||||
return new Hook<T>(procAddress, detour, useCoreHook);
|
return new Hook<T>(procAddress, detour, useMinHook);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -173,12 +185,10 @@ namespace Dalamud.Hooking
|
||||||
if (this.IsDisposed)
|
if (this.IsDisposed)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (this.isCoreHook)
|
if (this.isMinHook)
|
||||||
{
|
{
|
||||||
this.Disable();
|
this.minHookImpl.Dispose();
|
||||||
// Disposing CoreHook causes an APPCRASH on game exit.
|
HookManager.MultiHookTracker[this.address] = null;
|
||||||
// We already overwrite the original hook code, so there shouldn't be any real risk with not disposing here.
|
|
||||||
// this.coreHookImpl.Dispose();
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -195,10 +205,12 @@ namespace Dalamud.Hooking
|
||||||
{
|
{
|
||||||
this.CheckDisposed();
|
this.CheckDisposed();
|
||||||
|
|
||||||
if (this.isCoreHook)
|
if (this.isMinHook)
|
||||||
{
|
{
|
||||||
if (!this.coreHookImpl.Enabled)
|
if (!this.minHookImpl.Enabled)
|
||||||
this.coreHookImpl.Enabled = true;
|
{
|
||||||
|
this.minHookImpl.Enable();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -217,10 +229,12 @@ namespace Dalamud.Hooking
|
||||||
{
|
{
|
||||||
this.CheckDisposed();
|
this.CheckDisposed();
|
||||||
|
|
||||||
if (this.isCoreHook)
|
if (this.isMinHook)
|
||||||
{
|
{
|
||||||
if (this.coreHookImpl.Enabled)
|
if (this.minHookImpl.Enabled)
|
||||||
this.coreHookImpl.Enabled = false;
|
{
|
||||||
|
this.minHookImpl.Disable();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -21,5 +21,10 @@ namespace Dalamud.Hooking
|
||||||
/// Gets a value indicating whether or not the hook is disposed.
|
/// Gets a value indicating whether or not the hook is disposed.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool IsDisposed { get; }
|
public bool IsDisposed { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the name of the hooking backend used for the hook.
|
||||||
|
/// </summary>
|
||||||
|
public string BackendName { get; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -79,6 +79,11 @@ namespace Dalamud.Hooking.Internal
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal static Dictionary<IntPtr, byte[]> Originals { get; } = new();
|
internal static Dictionary<IntPtr, byte[]> Originals { get; } = new();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a static dictionary of the number of hooks on a given address.
|
||||||
|
/// </summary>
|
||||||
|
internal static Dictionary<IntPtr, List<IDalamudHook?>> MultiHookTracker { get; } = new();
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Numerics;
|
using System.Numerics;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
|
@ -27,6 +28,7 @@ using Dalamud.Game.Gui;
|
||||||
using Dalamud.Game.Gui.FlyText;
|
using Dalamud.Game.Gui.FlyText;
|
||||||
using Dalamud.Game.Gui.Toast;
|
using Dalamud.Game.Gui.Toast;
|
||||||
using Dalamud.Game.Text;
|
using Dalamud.Game.Text;
|
||||||
|
using Dalamud.Hooking;
|
||||||
using Dalamud.Interface.Colors;
|
using Dalamud.Interface.Colors;
|
||||||
using Dalamud.Interface.Internal.Notifications;
|
using Dalamud.Interface.Internal.Notifications;
|
||||||
using Dalamud.Interface.Windowing;
|
using Dalamud.Interface.Windowing;
|
||||||
|
|
@ -69,6 +71,9 @@ namespace Dalamud.Interface.Internal.Windows
|
||||||
|
|
||||||
private UIDebug addonInspector = null;
|
private UIDebug addonInspector = null;
|
||||||
|
|
||||||
|
private Hook<MessageBoxWDelegate>? messageBoxMinHook;
|
||||||
|
private bool hookUseMinHook = false;
|
||||||
|
|
||||||
// IPC
|
// IPC
|
||||||
private ICallGateProvider<string, string> ipcPub;
|
private ICallGateProvider<string, string> ipcPub;
|
||||||
private ICallGateSubscriber<string, string> ipcSub;
|
private ICallGateSubscriber<string, string> ipcSub;
|
||||||
|
|
@ -117,6 +122,12 @@ namespace Dalamud.Interface.Internal.Windows
|
||||||
this.Load();
|
this.Load();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private delegate int MessageBoxWDelegate(
|
||||||
|
IntPtr hWnd,
|
||||||
|
[MarshalAs(UnmanagedType.LPWStr)] string text,
|
||||||
|
[MarshalAs(UnmanagedType.LPWStr)] string caption,
|
||||||
|
NativeFunctions.MessageBoxType type);
|
||||||
|
|
||||||
private enum DataKind
|
private enum DataKind
|
||||||
{
|
{
|
||||||
Server_OpCode,
|
Server_OpCode,
|
||||||
|
|
@ -143,6 +154,7 @@ namespace Dalamud.Interface.Internal.Windows
|
||||||
Gamepad,
|
Gamepad,
|
||||||
Configuration,
|
Configuration,
|
||||||
TaskSched,
|
TaskSched,
|
||||||
|
Hook,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
|
|
@ -318,6 +330,10 @@ namespace Dalamud.Interface.Internal.Windows
|
||||||
case DataKind.TaskSched:
|
case DataKind.TaskSched:
|
||||||
this.DrawTaskSched();
|
this.DrawTaskSched();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case DataKind.Hook:
|
||||||
|
this.DrawHook();
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
@ -335,6 +351,12 @@ namespace Dalamud.Interface.Internal.Windows
|
||||||
ImGui.EndChild();
|
ImGui.EndChild();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private int MessageBoxWDetour(IntPtr hwnd, string text, string caption, NativeFunctions.MessageBoxType type)
|
||||||
|
{
|
||||||
|
Log.Information("[DATAHOOK] {0} {1} {2} {3}", hwnd, text, caption, type);
|
||||||
|
return this.messageBoxMinHook.Original(hwnd, text, caption, type);
|
||||||
|
}
|
||||||
|
|
||||||
private void DrawServerOpCode()
|
private void DrawServerOpCode()
|
||||||
{
|
{
|
||||||
ImGui.TextUnformatted(this.serverOpString);
|
ImGui.TextUnformatted(this.serverOpString);
|
||||||
|
|
@ -975,7 +997,7 @@ namespace Dalamud.Interface.Internal.Windows
|
||||||
ImGui.TableSetupColumn("Size", ImGuiTableColumnFlags.WidthFixed, fontWidth * 10);
|
ImGui.TableSetupColumn("Size", ImGuiTableColumnFlags.WidthFixed, fontWidth * 10);
|
||||||
ImGui.TableSetupColumn("Pointer", ImGuiTableColumnFlags.WidthStretch);
|
ImGui.TableSetupColumn("Pointer", ImGuiTableColumnFlags.WidthStretch);
|
||||||
ImGui.TableHeadersRow();
|
ImGui.TableHeadersRow();
|
||||||
for (int numberArrayIndex = 0; numberArrayIndex < atkArrayDataHolder->NumberArrayCount; numberArrayIndex++)
|
for (var numberArrayIndex = 0; numberArrayIndex < atkArrayDataHolder->NumberArrayCount; numberArrayIndex++)
|
||||||
{
|
{
|
||||||
ImGui.TableNextRow();
|
ImGui.TableNextRow();
|
||||||
ImGui.TableNextColumn();
|
ImGui.TableNextColumn();
|
||||||
|
|
@ -989,7 +1011,7 @@ namespace Dalamud.Interface.Internal.Windows
|
||||||
if (ImGui.TreeNodeEx($"{(long)numberArrayData:X}###{numberArrayIndex}", ImGuiTreeNodeFlags.SpanFullWidth))
|
if (ImGui.TreeNodeEx($"{(long)numberArrayData:X}###{numberArrayIndex}", ImGuiTreeNodeFlags.SpanFullWidth))
|
||||||
{
|
{
|
||||||
ImGui.NewLine();
|
ImGui.NewLine();
|
||||||
int tableHeight = Math.Min(40, numberArrayData->AtkArrayData.Size + 4);
|
var tableHeight = Math.Min(40, numberArrayData->AtkArrayData.Size + 4);
|
||||||
if (ImGui.BeginTable($"NumberArrayDataTable", 4, ImGuiTableFlags.RowBg | ImGuiTableFlags.ScrollY, new Vector2(0.0F, fontHeight * tableHeight)))
|
if (ImGui.BeginTable($"NumberArrayDataTable", 4, ImGuiTableFlags.RowBg | ImGuiTableFlags.ScrollY, new Vector2(0.0F, fontHeight * tableHeight)))
|
||||||
{
|
{
|
||||||
ImGui.TableSetupColumn("Index", ImGuiTableColumnFlags.WidthFixed, fontWidth * 6);
|
ImGui.TableSetupColumn("Index", ImGuiTableColumnFlags.WidthFixed, fontWidth * 6);
|
||||||
|
|
@ -997,7 +1019,7 @@ namespace Dalamud.Interface.Internal.Windows
|
||||||
ImGui.TableSetupColumn("Integer", ImGuiTableColumnFlags.WidthFixed, fontWidth * 12);
|
ImGui.TableSetupColumn("Integer", ImGuiTableColumnFlags.WidthFixed, fontWidth * 12);
|
||||||
ImGui.TableSetupColumn("Float", ImGuiTableColumnFlags.WidthFixed, fontWidth * 20);
|
ImGui.TableSetupColumn("Float", ImGuiTableColumnFlags.WidthFixed, fontWidth * 20);
|
||||||
ImGui.TableHeadersRow();
|
ImGui.TableHeadersRow();
|
||||||
for (int numberIndex = 0; numberIndex < numberArrayData->AtkArrayData.Size; numberIndex++)
|
for (var numberIndex = 0; numberIndex < numberArrayData->AtkArrayData.Size; numberIndex++)
|
||||||
{
|
{
|
||||||
ImGui.TableNextRow();
|
ImGui.TableNextRow();
|
||||||
ImGui.TableNextColumn();
|
ImGui.TableNextColumn();
|
||||||
|
|
@ -1038,7 +1060,7 @@ namespace Dalamud.Interface.Internal.Windows
|
||||||
ImGui.TableSetupColumn("Size", ImGuiTableColumnFlags.WidthFixed, fontWidth * 10);
|
ImGui.TableSetupColumn("Size", ImGuiTableColumnFlags.WidthFixed, fontWidth * 10);
|
||||||
ImGui.TableSetupColumn("Pointer", ImGuiTableColumnFlags.WidthStretch);
|
ImGui.TableSetupColumn("Pointer", ImGuiTableColumnFlags.WidthStretch);
|
||||||
ImGui.TableHeadersRow();
|
ImGui.TableHeadersRow();
|
||||||
for (int stringArrayIndex = 0; stringArrayIndex < atkArrayDataHolder->StringArrayCount; stringArrayIndex++)
|
for (var stringArrayIndex = 0; stringArrayIndex < atkArrayDataHolder->StringArrayCount; stringArrayIndex++)
|
||||||
{
|
{
|
||||||
ImGui.TableNextRow();
|
ImGui.TableNextRow();
|
||||||
ImGui.TableNextColumn();
|
ImGui.TableNextColumn();
|
||||||
|
|
@ -1052,13 +1074,13 @@ namespace Dalamud.Interface.Internal.Windows
|
||||||
if (ImGui.TreeNodeEx($"{(long)stringArrayData:X}###{stringArrayIndex}", ImGuiTreeNodeFlags.SpanFullWidth))
|
if (ImGui.TreeNodeEx($"{(long)stringArrayData:X}###{stringArrayIndex}", ImGuiTreeNodeFlags.SpanFullWidth))
|
||||||
{
|
{
|
||||||
ImGui.NewLine();
|
ImGui.NewLine();
|
||||||
int tableHeight = Math.Min(40, stringArrayData->AtkArrayData.Size + 4);
|
var tableHeight = Math.Min(40, stringArrayData->AtkArrayData.Size + 4);
|
||||||
if (ImGui.BeginTable($"StringArrayDataTable", 2, ImGuiTableFlags.RowBg | ImGuiTableFlags.ScrollY, new Vector2(0.0F, fontHeight * tableHeight)))
|
if (ImGui.BeginTable($"StringArrayDataTable", 2, ImGuiTableFlags.RowBg | ImGuiTableFlags.ScrollY, new Vector2(0.0F, fontHeight * tableHeight)))
|
||||||
{
|
{
|
||||||
ImGui.TableSetupColumn("Index", ImGuiTableColumnFlags.WidthFixed, fontWidth * 6);
|
ImGui.TableSetupColumn("Index", ImGuiTableColumnFlags.WidthFixed, fontWidth * 6);
|
||||||
ImGui.TableSetupColumn("String", ImGuiTableColumnFlags.WidthStretch);
|
ImGui.TableSetupColumn("String", ImGuiTableColumnFlags.WidthStretch);
|
||||||
ImGui.TableHeadersRow();
|
ImGui.TableHeadersRow();
|
||||||
for (int stringIndex = 0; stringIndex < stringArrayData->AtkArrayData.Size; stringIndex++)
|
for (var stringIndex = 0; stringIndex < stringArrayData->AtkArrayData.Size; stringIndex++)
|
||||||
{
|
{
|
||||||
ImGui.TableNextRow();
|
ImGui.TableNextRow();
|
||||||
ImGui.TableNextColumn();
|
ImGui.TableNextColumn();
|
||||||
|
|
@ -1563,6 +1585,42 @@ namespace Dalamud.Interface.Internal.Windows
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void DrawHook()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
ImGui.Checkbox("Use MinHook", ref this.hookUseMinHook);
|
||||||
|
|
||||||
|
if (ImGui.Button("Create"))
|
||||||
|
this.messageBoxMinHook = Hook<MessageBoxWDelegate>.FromSymbol("User32", "MessageBoxW", this.MessageBoxWDetour, this.hookUseMinHook);
|
||||||
|
|
||||||
|
if (ImGui.Button("Enable"))
|
||||||
|
this.messageBoxMinHook?.Enable();
|
||||||
|
|
||||||
|
if (ImGui.Button("Disable"))
|
||||||
|
this.messageBoxMinHook?.Disable();
|
||||||
|
|
||||||
|
if (ImGui.Button("Call Original"))
|
||||||
|
this.messageBoxMinHook?.Original(IntPtr.Zero, "Hello from .Original", "Hook Test", NativeFunctions.MessageBoxType.Ok);
|
||||||
|
|
||||||
|
if (ImGui.Button("Dispose"))
|
||||||
|
{
|
||||||
|
this.messageBoxMinHook?.Dispose();
|
||||||
|
this.messageBoxMinHook = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ImGui.Button("Test"))
|
||||||
|
_ = NativeFunctions.MessageBoxW(IntPtr.Zero, "Hi", "Hello", NativeFunctions.MessageBoxType.Ok);
|
||||||
|
|
||||||
|
if (this.messageBoxMinHook != null)
|
||||||
|
ImGui.Text("Enabled: " + this.messageBoxMinHook?.IsEnabled);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Log.Error(ex, "MinHook error caught");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private async Task TestTaskInTaskDelay()
|
private async Task TestTaskInTaskDelay()
|
||||||
{
|
{
|
||||||
await Task.Delay(5000);
|
await Task.Delay(5000);
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ using System.Reflection;
|
||||||
|
|
||||||
using Dalamud.Game;
|
using Dalamud.Game;
|
||||||
using Dalamud.Game.Internal;
|
using Dalamud.Game.Internal;
|
||||||
|
using Dalamud.Hooking;
|
||||||
using Dalamud.Hooking.Internal;
|
using Dalamud.Hooking.Internal;
|
||||||
using Dalamud.Interface.Windowing;
|
using Dalamud.Interface.Windowing;
|
||||||
using Dalamud.Plugin.Internal;
|
using Dalamud.Plugin.Internal;
|
||||||
|
|
@ -175,11 +176,12 @@ namespace Dalamud.Interface.Internal.Windows
|
||||||
|
|
||||||
if (ImGui.BeginTabItem("Hooks"))
|
if (ImGui.BeginTabItem("Hooks"))
|
||||||
{
|
{
|
||||||
ImGui.Columns(3);
|
ImGui.Columns(4);
|
||||||
|
|
||||||
ImGui.SetColumnWidth(0, ImGui.GetWindowContentRegionWidth() - 280);
|
ImGui.SetColumnWidth(0, ImGui.GetWindowContentRegionWidth() - 330);
|
||||||
ImGui.SetColumnWidth(1, 180f);
|
ImGui.SetColumnWidth(1, 180f);
|
||||||
ImGui.SetColumnWidth(2, 100f);
|
ImGui.SetColumnWidth(2, 100f);
|
||||||
|
ImGui.SetColumnWidth(3, 100f);
|
||||||
|
|
||||||
ImGui.Text("Detour Method");
|
ImGui.Text("Detour Method");
|
||||||
ImGui.SameLine();
|
ImGui.SameLine();
|
||||||
|
|
@ -196,6 +198,9 @@ namespace Dalamud.Interface.Internal.Windows
|
||||||
ImGui.Text("Status");
|
ImGui.Text("Status");
|
||||||
ImGui.NextColumn();
|
ImGui.NextColumn();
|
||||||
|
|
||||||
|
ImGui.Text("Backend");
|
||||||
|
ImGui.NextColumn();
|
||||||
|
|
||||||
ImGui.Separator();
|
ImGui.Separator();
|
||||||
ImGui.Separator();
|
ImGui.Separator();
|
||||||
|
|
||||||
|
|
@ -240,6 +245,10 @@ namespace Dalamud.Interface.Internal.Windows
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui.NextColumn();
|
ImGui.NextColumn();
|
||||||
|
|
||||||
|
ImGui.Text(trackedHook.Hook.BackendName);
|
||||||
|
|
||||||
|
ImGui.NextColumn();
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -74,7 +74,7 @@ namespace Dalamud.Support
|
||||||
DoPluginTest = configuration.DoPluginTest,
|
DoPluginTest = configuration.DoPluginTest,
|
||||||
InterfaceLoaded = interfaceManager?.IsReady ?? false,
|
InterfaceLoaded = interfaceManager?.IsReady ?? false,
|
||||||
ThirdRepo = configuration.ThirdRepoList,
|
ThirdRepo = configuration.ThirdRepoList,
|
||||||
ForcedCoreHook = EnvironmentConfiguration.DalamudForceCoreHook,
|
ForcedMinHook = EnvironmentConfiguration.DalamudForceMinHook,
|
||||||
};
|
};
|
||||||
|
|
||||||
var encodedPayload = Convert.ToBase64String(Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(payload)));
|
var encodedPayload = Convert.ToBase64String(Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(payload)));
|
||||||
|
|
@ -113,7 +113,7 @@ namespace Dalamud.Support
|
||||||
|
|
||||||
public bool InterfaceLoaded { get; set; }
|
public bool InterfaceLoaded { get; set; }
|
||||||
|
|
||||||
public bool ForcedCoreHook { get; set; }
|
public bool ForcedMinHook { get; set; }
|
||||||
|
|
||||||
public List<ThirdPartyRepoSettings> ThirdRepo { get; set; }
|
public List<ThirdPartyRepoSettings> ThirdRepo { get; set; }
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Binary file not shown.
Loading…
Add table
Add a link
Reference in a new issue