113 lines
4.4 KiB
C#
Executable File
113 lines
4.4 KiB
C#
Executable File
using System;
|
|
using System.Runtime.InteropServices;
|
|
using Dalamud.Game.ClientState.Actors;
|
|
using Dalamud.Game.ClientState.Structs;
|
|
using Dalamud.Hooking;
|
|
using ImGuiNET;
|
|
|
|
namespace RoleplayersToolbox.Tools.Targeting {
|
|
internal class TargetingTool : BaseTool, IDisposable {
|
|
private static class Signatures {
|
|
internal const string LeftClickTarget = "E8 ?? ?? ?? ?? BA ?? ?? ?? ?? 48 8D 0D ?? ?? ?? ?? E8 ?? ?? ?? ?? 84 C0 74 16";
|
|
internal const string RightClickTarget = "E8 ?? ?? ?? ?? 48 8B CE E8 ?? ?? ?? ?? 48 85 C0 74 1B";
|
|
}
|
|
|
|
private unsafe delegate void* ClickTargetDelegate(void** a1, void* a2, bool a3);
|
|
|
|
public override string Name => "Targeting";
|
|
private Plugin Plugin { get; }
|
|
private TargetingConfig Config { get; }
|
|
private Hook<ClickTargetDelegate>? LeftClickHook { get; }
|
|
private Hook<ClickTargetDelegate>? RightClickHook { get; }
|
|
|
|
internal TargetingTool(Plugin plugin) {
|
|
this.Plugin = plugin;
|
|
this.Config = this.Plugin.Config.Tools.Targeting;
|
|
|
|
if (this.Plugin.Interface.TargetModuleScanner.TryScanText(Signatures.LeftClickTarget, out var leftClickPtr)) {
|
|
unsafe {
|
|
this.LeftClickHook = new Hook<ClickTargetDelegate>(leftClickPtr, new ClickTargetDelegate(this.LeftClickDetour));
|
|
}
|
|
|
|
this.LeftClickHook.Enable();
|
|
}
|
|
|
|
if (this.Plugin.Interface.TargetModuleScanner.TryScanText(Signatures.RightClickTarget, out var rightClickPtr)) {
|
|
unsafe {
|
|
this.RightClickHook = new Hook<ClickTargetDelegate>(rightClickPtr, new ClickTargetDelegate(this.RightClickDetour));
|
|
}
|
|
|
|
this.RightClickHook.Enable();
|
|
}
|
|
}
|
|
|
|
public void Dispose() {
|
|
this.LeftClickHook?.Dispose();
|
|
this.RightClickHook?.Dispose();
|
|
}
|
|
|
|
public override void DrawSettings(ref bool anyChanged) {
|
|
anyChanged |= ImGui.Checkbox("Enable left click to examine", ref this.Config.LeftClickExamine);
|
|
anyChanged |= ImGui.Checkbox("Enable right click to examine", ref this.Config.RightClickExamine);
|
|
anyChanged |= ImGui.Checkbox("Prevent removing or changing current target", ref this.Config.KeepTarget);
|
|
}
|
|
|
|
private unsafe void* LeftClickDetour(void** a1, void* clickedOn, bool a3) {
|
|
var target = a1[16];
|
|
|
|
if (clickedOn == null) {
|
|
if (this.Config.KeepTarget) {
|
|
return this.LeftClickHook!.Original(a1, target, a3);
|
|
}
|
|
|
|
goto Original;
|
|
}
|
|
|
|
if (this.Config.LeftClickExamine) {
|
|
var actorStruct = Marshal.PtrToStructure<Actor>((IntPtr) clickedOn);
|
|
if (actorStruct.ObjectKind == ObjectKind.Player) {
|
|
this.Plugin.Common.Functions.Examine.OpenExamineWindow(actorStruct.ActorId);
|
|
// tell game current target was left-clicked
|
|
return this.LeftClickHook!.Original(a1, target, a3);
|
|
}
|
|
}
|
|
|
|
if (this.Config.KeepTarget && clickedOn != target) {
|
|
return this.LeftClickHook!.Original(a1, target, a3);
|
|
}
|
|
|
|
Original:
|
|
return this.LeftClickHook!.Original(a1, clickedOn, a3);
|
|
}
|
|
|
|
private unsafe void* RightClickDetour(void** a1, void* clickedOn, bool a3) {
|
|
if (clickedOn == null) {
|
|
goto Original;
|
|
}
|
|
|
|
var target = a1[16];
|
|
|
|
if (this.Config.RightClickExamine) {
|
|
if (clickedOn == target) {
|
|
// allow right-clicking on target
|
|
goto Original;
|
|
}
|
|
|
|
var actorStruct = Marshal.PtrToStructure<Actor>((IntPtr) clickedOn);
|
|
if (actorStruct.ObjectKind == ObjectKind.Player) {
|
|
this.Plugin.Common.Functions.Examine.OpenExamineWindow(actorStruct.ActorId);
|
|
// tell game nothing was right-clicked
|
|
return this.RightClickHook!.Original(a1, null, a3);
|
|
}
|
|
}
|
|
|
|
if (this.Config.KeepTarget && clickedOn != target) {
|
|
return this.RightClickHook!.Original(a1, null, a3);
|
|
}
|
|
|
|
Original:
|
|
return this.RightClickHook!.Original(a1, clickedOn, a3);
|
|
}
|
|
}
|
|
}
|