mirror of
https://github.com/goatcorp/Dalamud.git
synced 2025-12-12 18:27:23 +01:00
feat: new actor table shenanigans
This commit is contained in:
parent
03e4a4d25c
commit
f80a4e7432
5 changed files with 26 additions and 52 deletions
|
|
@ -43,6 +43,7 @@
|
|||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="CheapLoc" Version="1.1.3" />
|
||||
<PackageReference Include="JetBrains.Annotations" Version="2020.1.0" />
|
||||
<PackageReference Include="Lumina" Version="1.1.1" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="12.0.2" />
|
||||
<PackageReference Include="PropertyChanged.Fody" Version="2.6.1" />
|
||||
|
|
|
|||
|
|
@ -6,13 +6,16 @@ using System.Runtime.InteropServices;
|
|||
using Dalamud.Game.ClientState.Actors.Types;
|
||||
using Dalamud.Game.ClientState.Actors.Types.NonPlayer;
|
||||
using Dalamud.Hooking;
|
||||
using JetBrains.Annotations;
|
||||
using Serilog;
|
||||
|
||||
namespace Dalamud.Game.ClientState.Actors {
|
||||
/// <summary>
|
||||
/// This collection represents the currently spawned FFXIV actors.
|
||||
/// </summary>
|
||||
public class ActorTable : IReadOnlyCollection<Actor>, ICollection, IDisposable {
|
||||
public class ActorTable : IReadOnlyCollection<Actor>, ICollection {
|
||||
|
||||
private const int ActorTableLength = 424;
|
||||
|
||||
#region temporary imports for crash workaround
|
||||
|
||||
|
|
@ -29,14 +32,6 @@ namespace Dalamud.Game.ClientState.Actors {
|
|||
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>
|
||||
|
|
@ -45,27 +40,7 @@ namespace Dalamud.Game.ClientState.Actors {
|
|||
Address = addressResolver;
|
||||
this.dalamud = dalamud;
|
||||
|
||||
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();
|
||||
|
||||
this.isReady = false;
|
||||
}
|
||||
|
||||
private IntPtr SomeActorTableAccessDetour(IntPtr manager, IntPtr offset) {
|
||||
this.realActorTablePtr = offset;
|
||||
this.isReady = true;
|
||||
return this.someActorTableAccessHook.Original(manager, offset);
|
||||
Log.Verbose("Actor table address {ActorTable}", Address.ActorTable);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -73,24 +48,17 @@ namespace Dalamud.Game.ClientState.Actors {
|
|||
/// </summary>
|
||||
/// <param name="index">Spawn index.</param>
|
||||
/// <returns><see cref="Actor" /> at the specified spawn index.</returns>
|
||||
[CanBeNull]
|
||||
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;
|
||||
|
||||
var tblIndex = this.realActorTablePtr + 8 + index * 8;
|
||||
var tblIndex = Address.ActorTable + index * 8;
|
||||
|
||||
var offset = Marshal.ReadIntPtr(tblIndex);
|
||||
|
||||
//Log.Verbose("Actor at {0} for {1}", offset.ToInt64().ToString("X"), index);
|
||||
Log.Debug($"Reading actor {index} at {tblIndex.ToInt64():X} pointing to {offset.ToInt64():X}");
|
||||
|
||||
if (offset == IntPtr.Zero)
|
||||
return null;
|
||||
|
|
@ -154,7 +122,7 @@ namespace Dalamud.Game.ClientState.Actors {
|
|||
/// <summary>
|
||||
/// The amount of currently spawned actors.
|
||||
/// </summary>
|
||||
public int Length => !this.isReady ? 0 : Marshal.ReadInt32(this.realActorTablePtr);
|
||||
public int Length => ActorTableLength;
|
||||
|
||||
int IReadOnlyCollection<Actor>.Count => Length;
|
||||
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ using Dalamud.Game.ClientState.Actors.Types;
|
|||
using Dalamud.Game.Internal;
|
||||
using Dalamud.Game.Internal.Network;
|
||||
using Dalamud.Hooking;
|
||||
using JetBrains.Annotations;
|
||||
using Lumina.Excel.GeneratedSheets;
|
||||
using Serilog;
|
||||
|
||||
|
|
@ -29,6 +30,7 @@ namespace Dalamud.Game.ClientState
|
|||
/// <summary>
|
||||
/// The local player character, if one is present.
|
||||
/// </summary>
|
||||
[CanBeNull]
|
||||
public PlayerCharacter LocalPlayer {
|
||||
get {
|
||||
var actor = this.Actors[0];
|
||||
|
|
@ -122,13 +124,11 @@ namespace Dalamud.Game.ClientState
|
|||
}
|
||||
|
||||
public void Enable() {
|
||||
this.Actors.Enable();
|
||||
this.PartyList.Enable();
|
||||
this.setupTerritoryTypeHook.Enable();
|
||||
}
|
||||
|
||||
public void Dispose() {
|
||||
this.Actors.Dispose();
|
||||
this.PartyList.Dispose();
|
||||
this.setupTerritoryTypeHook.Dispose();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,19 +5,22 @@ namespace Dalamud.Game.ClientState
|
|||
{
|
||||
public sealed class ClientStateAddressResolver : BaseAddressResolver {
|
||||
// Static offsets
|
||||
public IntPtr ViewportActorTable { get; private set; }
|
||||
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; }
|
||||
//public IntPtr SomeActorTableAccess { get; private set; }
|
||||
public IntPtr PartyListUpdate { get; private set; }
|
||||
|
||||
protected override void Setup64Bit(SigScanner sig) {
|
||||
ViewportActorTable = sig.GetStaticAddressFromSig("48 8D 0D ?? ?? ?? ?? 85 ED", 0) + 0x148;
|
||||
SomeActorTableAccess = sig.ScanText("E8 ?? ?? ?? ?? 48 8D 55 A0 48 8D 8E ?? ?? ?? ??");
|
||||
// We don't need those anymore, but maybe someone else will - let's leave them here for good measure
|
||||
//ViewportActorTable = sig.GetStaticAddressFromSig("48 8D 0D ?? ?? ?? ?? 85 ED", 0) + 0x148;
|
||||
//SomeActorTableAccess = sig.ScanText("E8 ?? ?? ?? ?? 48 8D 55 A0 48 8D 8E ?? ?? ?? ??");
|
||||
ActorTable = sig.GetStaticAddressFromSig("88 91 ?? ?? ?? ?? 48 8D 3D ?? ?? ?? ??", 0x0);
|
||||
|
||||
LocalContentId = sig.GetStaticAddressFromSig("48 8B 05 ?? ?? ?? ?? 48 89 86 ?? ?? ?? ??", 0);
|
||||
JobGaugeData = sig.GetStaticAddressFromSig("E8 ?? ?? ?? ?? FF C6 48 8D 5B 0C", 0xB9) + 0x10;
|
||||
|
|
|
|||
|
|
@ -69,12 +69,11 @@ namespace Dalamud.Interface
|
|||
var stateString = string.Empty;
|
||||
// LocalPlayer is null in a number of situations (at least with the current visible-actors list)
|
||||
// which would crash here.
|
||||
if (this.dalamud.ClientState.Actors.Length == 0 || this.dalamud.ClientState.LocalPlayer == null)
|
||||
{
|
||||
if (this.dalamud.ClientState.Actors.Length == 0) {
|
||||
ImGui.TextUnformatted("Data not ready.");
|
||||
}
|
||||
else
|
||||
{
|
||||
} else if (this.dalamud.ClientState.LocalPlayer == null) {
|
||||
ImGui.TextUnformatted("LocalPlayer null.");
|
||||
} else {
|
||||
stateString += $"FrameworkBase: {this.dalamud.Framework.Address.BaseAddress.ToInt64():X}\n";
|
||||
|
||||
stateString += $"ActorTableLen: {this.dalamud.ClientState.Actors.Length}\n";
|
||||
|
|
@ -88,6 +87,9 @@ namespace Dalamud.Interface
|
|||
for (var i = 0; i < this.dalamud.ClientState.Actors.Length; i++) {
|
||||
var actor = this.dalamud.ClientState.Actors[i];
|
||||
|
||||
if (actor == null)
|
||||
continue;
|
||||
|
||||
stateString +=
|
||||
$"{actor.Address.ToInt64():X}:{actor.ActorId:X}[{i}] - {actor.ObjectKind} - {actor.Name} - {actor.Position.X} {actor.Position.Y} {actor.Position.Z}\n";
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue