fix: reintroduce ReadProcessMemory hack in ActorTable

This commit is contained in:
goat 2020-08-03 19:49:18 +02:00
parent 1fffc18da9
commit 7439065e79

View file

@ -1,6 +1,7 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Runtime.InteropServices;
using Dalamud.Game.ClientState.Actors.Types;
@ -30,6 +31,22 @@ namespace Dalamud.Game.ClientState.Actors {
private void ResetCache() => actorsCache = null;
#endregion
#region ReadProcessMemory Hack
[DllImport("kernel32.dll", SetLastError = true)]
static extern bool ReadProcessMemory(
IntPtr hProcess,
IntPtr lpBaseAddress,
IntPtr lpBuffer,
int dwSize,
out IntPtr lpNumberOfBytesRead);
private static readonly int ActorMemSize = Marshal.SizeOf(typeof(Structs.Actor));
private IntPtr actorMem = Marshal.AllocHGlobal(ActorMemSize);
private Process currentProcess = Process.GetCurrentProcess();
#endregion
private ClientStateAddressResolver Address { get; }
private Dalamud dalamud;
@ -63,7 +80,14 @@ namespace Dalamud.Game.ClientState.Actors {
private Actor ReadActorFromMemory(IntPtr offset)
{
try {
var actorStruct = Marshal.PtrToStructure<Structs.Actor>(offset);
// FIXME: hack workaround for trying to access the player on logout, after the main object has been deleted
if (!ReadProcessMemory(this.currentProcess.Handle, offset, this.actorMem, ActorMemSize, out _))
{
Log.Debug("ActorTable - ReadProcessMemory failed: likely player deletion during logout");
return null;
}
var actorStruct = Marshal.PtrToStructure<Structs.Actor>(this.actorMem);
return actorStruct.ObjectKind switch {
ObjectKind.Player => new PlayerCharacter(offset, actorStruct, this.dalamud),
@ -127,6 +151,7 @@ namespace Dalamud.Game.ClientState.Actors {
{
if (this.disposed) return;
this.dalamud.Framework.OnUpdateEvent -= Framework_OnUpdateEvent;
Marshal.FreeHGlobal(this.actorMem);
this.disposed = true;
}