From ea8df55b9d1d1efee9b7ea9d96f9407636fb158e Mon Sep 17 00:00:00 2001 From: goat Date: Sun, 29 Mar 2020 16:43:52 +0900 Subject: [PATCH] fix: hack around actor table address acquiring --- Dalamud.Injector/Program.cs | 2 + Dalamud/Game/ClientState/Actors/ActorTable.cs | 43 +++++++++++++++++-- Dalamud/Game/ClientState/ClientState.cs | 2 + .../ClientState/ClientStateAddressResolver.cs | 7 ++- Dalamud/Game/ClientState/JobGauge.cs | 2 +- Dalamud/Interface/DalamudDataWindow.cs | 2 +- 6 files changed, 50 insertions(+), 8 deletions(-) diff --git a/Dalamud.Injector/Program.cs b/Dalamud.Injector/Program.cs index 4e1760460..d25243c8e 100644 --- a/Dalamud.Injector/Program.cs +++ b/Dalamud.Injector/Program.cs @@ -58,6 +58,8 @@ namespace Dalamud.Injector { // Seems to help with the STATUS_INTERNAL_ERROR condition Thread.Sleep(1000); + //Thread.Sleep(10000); + // Inject to process Inject(process, startInfo); } diff --git a/Dalamud/Game/ClientState/Actors/ActorTable.cs b/Dalamud/Game/ClientState/Actors/ActorTable.cs index b1100065e..81cf2a31f 100644 --- a/Dalamud/Game/ClientState/Actors/ActorTable.cs +++ b/Dalamud/Game/ClientState/Actors/ActorTable.cs @@ -1,18 +1,28 @@ using System; using System.Collections; using System.Runtime.InteropServices; +using System.Windows.Forms; using Dalamud.Game.ClientState.Actors.Types; using Dalamud.Game.ClientState.Actors.Types.NonPlayer; +using Dalamud.Hooking; using Serilog; namespace Dalamud.Game.ClientState.Actors { /// /// This collection represents the currently spawned FFXIV actors. /// - public class ActorTable : ICollection { + public class ActorTable : ICollection, IDisposable { private ClientStateAddressResolver Address { get; } private Dalamud dalamud; + [UnmanagedFunctionPointer(CallingConvention.ThisCall)] + private delegate IntPtr SomeActorTableAccessDelegate(IntPtr manager, IntPtr offset); + + private Hook someActorTableAccessHook; + + private bool isReady = false; + private IntPtr realActorTablePtr; + /// /// Set up the actor table collection. /// @@ -21,7 +31,24 @@ namespace Dalamud.Game.ClientState.Actors { Address = addressResolver; this.dalamud = dalamud; - Log.Verbose("Actor table address {ActorTable}", Address.ActorTable); + this.someActorTableAccessHook = new Hook(Address.SomeActorTableAccess, new SomeActorTableAccessDelegate(SomeActorTableAccessDetour), this); + + Log.Verbose("Actor table address {ActorTable}", Address.ViewportActorTable); + } + + public void Enable() { + this.someActorTableAccessHook.Enable(); + } + + public void Dispose() { + if (!this.isReady) + this.someActorTableAccessHook.Dispose(); + } + + private IntPtr SomeActorTableAccessDetour(IntPtr manager, IntPtr offset) { + this.realActorTablePtr = offset; + this.isReady = true; + return this.someActorTableAccessHook.Original(manager, offset); } /// @@ -31,11 +58,19 @@ namespace Dalamud.Game.ClientState.Actors { /// at the specified spawn index. public Actor this[int index] { get { + if (!this.isReady) + return null; + + if (this.someActorTableAccessHook != null) { + this.someActorTableAccessHook.Dispose(); + this.someActorTableAccessHook = null; + } + if (index > Length) return null; //Log.Information("Trying to get actor at {0}", index); - var tblIndex = Address.ActorTable + 8 + index * 8; + var tblIndex = this.realActorTablePtr + 8 + index * 8; var offset = Marshal.ReadIntPtr(tblIndex); @@ -90,7 +125,7 @@ namespace Dalamud.Game.ClientState.Actors { /// /// The amount of currently spawned actors. /// - public int Length => Marshal.ReadInt32(Address.ActorTable); + public int Length => !this.isReady ? 0 : Marshal.ReadInt32(this.realActorTablePtr); int ICollection.Count => Length; diff --git a/Dalamud/Game/ClientState/ClientState.cs b/Dalamud/Game/ClientState/ClientState.cs index ca2572fc3..6215be83b 100644 --- a/Dalamud/Game/ClientState/ClientState.cs +++ b/Dalamud/Game/ClientState/ClientState.cs @@ -115,10 +115,12 @@ namespace Dalamud.Game.ClientState } public void Enable() { + this.Actors.Enable(); this.setupTerritoryTypeHook.Enable(); } public void Dispose() { + this.Actors.Dispose(); this.setupTerritoryTypeHook.Dispose(); } diff --git a/Dalamud/Game/ClientState/ClientStateAddressResolver.cs b/Dalamud/Game/ClientState/ClientStateAddressResolver.cs index fa29d53b9..27717981a 100644 --- a/Dalamud/Game/ClientState/ClientStateAddressResolver.cs +++ b/Dalamud/Game/ClientState/ClientStateAddressResolver.cs @@ -5,16 +5,19 @@ namespace Dalamud.Game.ClientState { public sealed class ClientStateAddressResolver : BaseAddressResolver { // Static offsets - public IntPtr ActorTable { get; private set; } + public IntPtr ViewportActorTable { get; private set; } public IntPtr LocalContentId { get; private set; } public IntPtr JobGaugeData { get; private set; } public IntPtr KeyboardState { get; private set; } // Functions public IntPtr SetupTerritoryType { get; private set; } + public IntPtr SomeActorTableAccess { get; private set; } protected override void Setup64Bit(SigScanner sig) { - ActorTable = sig.GetStaticAddressFromSig("48 8D 0D ?? ?? ?? ?? 85 ED", 0) + 0x148; + ViewportActorTable = sig.GetStaticAddressFromSig("48 8D 0D ?? ?? ?? ?? 85 ED", 0) + 0x148; + SomeActorTableAccess = sig.ScanText("E8 ?? ?? ?? ?? 48 8D 55 A0 48 8D 8E ?? ?? ?? ??"); + LocalContentId = sig.GetStaticAddressFromSig("48 8B 05 ?? ?? ?? ?? 48 89 86 ?? ?? ?? ??", 0); JobGaugeData = sig.GetStaticAddressFromSig("E8 ?? ?? ?? ?? FF C6 48 8D 5B 0C", 0xB9) + 0x10; diff --git a/Dalamud/Game/ClientState/JobGauge.cs b/Dalamud/Game/ClientState/JobGauge.cs index 916921af7..70a142e98 100644 --- a/Dalamud/Game/ClientState/JobGauge.cs +++ b/Dalamud/Game/ClientState/JobGauge.cs @@ -8,7 +8,7 @@ namespace Dalamud.Game.ClientState { public JobGauges(ClientStateAddressResolver addressResolver) { Address = addressResolver; - Log.Verbose("JobGaugeData address {JobGaugeData}", Address.ActorTable); + Log.Verbose("JobGaugeData address {JobGaugeData}", Address.JobGaugeData); } // Should only be called with the gauge types in diff --git a/Dalamud/Interface/DalamudDataWindow.cs b/Dalamud/Interface/DalamudDataWindow.cs index 9be30dfd2..a872f2442 100644 --- a/Dalamud/Interface/DalamudDataWindow.cs +++ b/Dalamud/Interface/DalamudDataWindow.cs @@ -30,7 +30,7 @@ namespace Dalamud.Interface } public bool Draw() { - ImGui.SetNextWindowSize(new Vector2(500, 500), ImGuiCond.Always); + ImGui.SetNextWindowSize(new Vector2(500, 500), ImGuiCond.FirstUseEver); var isOpen = true;