fix: some kind of mitigation for actortable crashes

This commit is contained in:
goat 2020-04-01 01:53:02 +09:00
parent 4d6f7762e6
commit e02bca714f

View file

@ -1,6 +1,8 @@
using System; using System;
using System.Collections; using System.Collections;
using System.Runtime.ExceptionServices;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Security;
using System.Windows.Forms; using System.Windows.Forms;
using Dalamud.Game.ClientState.Actors.Types; using Dalamud.Game.ClientState.Actors.Types;
using Dalamud.Game.ClientState.Actors.Types.NonPlayer; using Dalamud.Game.ClientState.Actors.Types.NonPlayer;
@ -56,12 +58,17 @@ namespace Dalamud.Game.ClientState.Actors {
/// </summary> /// </summary>
/// <param name="index">Spawn index.</param> /// <param name="index">Spawn index.</param>
/// <returns><see cref="Actor" /> at the specified spawn index.</returns> /// <returns><see cref="Actor" /> at the specified spawn index.</returns>
public Actor this[int index] { public Actor this[int index] => At(index);
get {
[HandleProcessCorruptedStateExceptions]
[SecurityCritical]
private Actor At(int index) {
try {
if (!this.isReady) if (!this.isReady)
return null; return null;
if (this.someActorTableAccessHook != null) { if (this.someActorTableAccessHook != null)
{
this.someActorTableAccessHook.Dispose(); this.someActorTableAccessHook.Dispose();
this.someActorTableAccessHook = null; this.someActorTableAccessHook = null;
} }
@ -69,17 +76,17 @@ namespace Dalamud.Game.ClientState.Actors {
if (index > Length) if (index > Length)
return null; return null;
//Log.Information("Trying to get actor at {0}", index);
var tblIndex = this.realActorTablePtr + 8 + index * 8; var tblIndex = this.realActorTablePtr + 8 + index * 8;
var offset = Marshal.ReadIntPtr(tblIndex); var offset = Marshal.ReadIntPtr(tblIndex);
//Log.Information("Actor at {0}", offset.ToString()); Log.Information("Actor at {0} for {1}", offset.ToInt64().ToString("X"), index);
if (offset == IntPtr.Zero) if (offset == IntPtr.Zero)
return null; return null;
try { try
{
var actorStruct = Marshal.PtrToStructure<Structs.Actor>(offset); var actorStruct = Marshal.PtrToStructure<Structs.Actor>(offset);
//Log.Debug("ActorTable[{0}]: {1} - {2} - {3}", index, tblIndex.ToString("X"), offset.ToString("X"), //Log.Debug("ActorTable[{0}]: {1} - {2} - {3}", index, tblIndex.ToString("X"), offset.ToString("X"),
@ -91,9 +98,14 @@ namespace Dalamud.Game.ClientState.Actors {
case ObjectKind.BattleNpc: return new BattleNpc(actorStruct, this.dalamud); case ObjectKind.BattleNpc: return new BattleNpc(actorStruct, this.dalamud);
default: return new Actor(actorStruct, this.dalamud); default: return new Actor(actorStruct, this.dalamud);
} }
} catch (AccessViolationException) { }
catch (AccessViolationException)
{
return null; return null;
} }
} catch (Exception e) {
Log.Error(e, "Could not get Actor.");
return null;
} }
} }