fix: hack around actor table address acquiring

This commit is contained in:
goat 2020-03-29 16:43:52 +09:00
parent 3b9e04e7a2
commit ea8df55b9d
6 changed files with 50 additions and 8 deletions

View file

@ -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);
}

View file

@ -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 {
/// <summary>
/// This collection represents the currently spawned FFXIV actors.
/// </summary>
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<SomeActorTableAccessDelegate> someActorTableAccessHook;
private bool isReady = false;
private IntPtr realActorTablePtr;
/// <summary>
/// Set up the actor table collection.
/// </summary>
@ -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<SomeActorTableAccessDelegate>(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);
}
/// <summary>
@ -31,11 +58,19 @@ namespace Dalamud.Game.ClientState.Actors {
/// <returns><see cref="Actor" /> at the specified spawn index.</returns>
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 {
/// <summary>
/// The amount of currently spawned actors.
/// </summary>
public int Length => Marshal.ReadInt32(Address.ActorTable);
public int Length => !this.isReady ? 0 : Marshal.ReadInt32(this.realActorTablePtr);
int ICollection.Count => Length;

View file

@ -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();
}

View file

@ -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;

View file

@ -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

View file

@ -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;