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;