diff --git a/LightlessSync/PlayerData/Handlers/GameObjectHandler.cs b/LightlessSync/PlayerData/Handlers/GameObjectHandler.cs index 4b01917..0a9bf66 100644 --- a/LightlessSync/PlayerData/Handlers/GameObjectHandler.cs +++ b/LightlessSync/PlayerData/Handlers/GameObjectHandler.cs @@ -174,65 +174,85 @@ public sealed class GameObjectHandler : DisposableMediatorSubscriberBase, IHighP private unsafe void CheckAndUpdateObject(bool allowPublish) { - var prevAddr = Address; - var prevDrawObj = DrawObjectAddress; - string? nameString = null; - - var nextAddr = _getAddress(); - - if (nextAddr != IntPtr.Zero && !PtrGuard.LooksLikePtr(nextAddr)) + try { - nextAddr = IntPtr.Zero; - } + var prevAddr = Address; + var prevDrawObj = DrawObjectAddress; + string? nameString = null; - if (nextAddr != IntPtr.Zero && - !PtrGuard.IsReadable(nextAddr, (nuint)sizeof(FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject))) - { - nextAddr = IntPtr.Zero; - } + var nextAddr = _getAddress(); - Address = nextAddr; - - if (Address != IntPtr.Zero) - { - var gameObject = (FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject*)Address; - - var draw = (nint)gameObject->DrawObject; - - if (!PtrGuard.LooksLikePtr(draw) || !PtrGuard.IsReadable(draw, (nuint)sizeof(DrawObject))) - draw = 0; - - DrawObjectAddress = draw; - EntityId = gameObject->EntityId; - - if (PtrGuard.IsReadable(Address, (nuint)sizeof(Character))) + if (nextAddr != IntPtr.Zero && !PtrGuard.LooksLikePtr(nextAddr)) { - var chara = (Character*)Address; - nameString = chara->GameObject.NameString; - - if (!string.IsNullOrEmpty(nameString) && !string.Equals(nameString, Name, StringComparison.Ordinal)) - Name = nameString; + nextAddr = IntPtr.Zero; } - } - else - { - DrawObjectAddress = IntPtr.Zero; - EntityId = uint.MaxValue; - } - CurrentDrawCondition = (Address != IntPtr.Zero && DrawObjectAddress != IntPtr.Zero) - ? IsBeingDrawnUnsafe() - : DrawCondition.DrawObjectZero; + if (nextAddr != IntPtr.Zero && + !PtrGuard.IsReadable(nextAddr, (nuint)sizeof(FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject))) + { + nextAddr = IntPtr.Zero; + } - if (_haltProcessing || !allowPublish) return; + Address = nextAddr; - bool drawObjDiff = DrawObjectAddress != prevDrawObj; - bool addrDiff = Address != prevAddr; + if (Address != IntPtr.Zero) + { + var gameObject = (FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject*)Address; + + var draw = (nint)gameObject->DrawObject; + + if (!PtrGuard.LooksLikePtr(draw) || !PtrGuard.IsReadable(draw, (nuint)sizeof(DrawObject))) + draw = 0; + + DrawObjectAddress = draw; + EntityId = gameObject->EntityId; + + if (PtrGuard.IsReadable(Address, (nuint)sizeof(Character))) + { + var chara = (Character*)Address; + nameString = chara->GameObject.NameString; + + if (!string.IsNullOrEmpty(nameString) && !string.Equals(nameString, Name, StringComparison.Ordinal)) + Name = nameString; + } + } + else + { + DrawObjectAddress = IntPtr.Zero; + EntityId = uint.MaxValue; + } + + CurrentDrawCondition = (Address != IntPtr.Zero && DrawObjectAddress != IntPtr.Zero) + ? IsBeingDrawnUnsafe() + : DrawCondition.DrawObjectZero; + + if (_haltProcessing || !allowPublish) return; + + bool drawObjDiff = DrawObjectAddress != prevDrawObj; + bool addrDiff = Address != prevAddr; + + if (Address == IntPtr.Zero || DrawObjectAddress == IntPtr.Zero) + { + if (addrDiff || drawObjDiff) + { + CurrentDrawCondition = DrawCondition.DrawObjectZero; + Logger.LogTrace("[{this}] Changed", this); + if (_isOwnedObject && ObjectKind != ObjectKind.Player) + Mediator.Publish(new ClearCacheForObjectMessage(this)); + } + return; + } + + if (!PtrGuard.IsReadable(Address, (nuint)sizeof(Character)) || + !PtrGuard.IsReadable(DrawObjectAddress, (nuint)sizeof(DrawObject))) + { + Logger.LogTrace("[{this}] Pointers became invalid during update", this); + Address = IntPtr.Zero; + DrawObjectAddress = IntPtr.Zero; + CurrentDrawCondition = DrawCondition.DrawObjectZero; + return; + } - if (Address != IntPtr.Zero && DrawObjectAddress != IntPtr.Zero - && PtrGuard.IsReadable(Address, (nuint)sizeof(Character)) - && PtrGuard.IsReadable(DrawObjectAddress, (nuint)sizeof(DrawObject))) - { var chara = (Character*)Address; var drawObj = (DrawObject*)DrawObjectAddress; @@ -315,12 +335,11 @@ public sealed class GameObjectHandler : DisposableMediatorSubscriberBase, IHighP Mediator.Publish(new CreateCacheForObjectMessage(this)); } } - else if (addrDiff || drawObjDiff) + catch (Exception ex) { + Address = IntPtr.Zero; + DrawObjectAddress = IntPtr.Zero; CurrentDrawCondition = DrawCondition.DrawObjectZero; - Logger.LogTrace("[{this}] Changed", this); - if (_isOwnedObject && ObjectKind != ObjectKind.Player) - Mediator.Publish(new ClearCacheForObjectMessage(this)); } } @@ -443,11 +462,18 @@ public sealed class GameObjectHandler : DisposableMediatorSubscriberBase, IHighP { if (Address == IntPtr.Zero) return DrawCondition.ObjectZero; if (DrawObjectAddress == IntPtr.Zero) return DrawCondition.DrawObjectZero; + + if (!PtrGuard.IsReadable(Address, (nuint)sizeof(FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject))) + return DrawCondition.ObjectZero; + var visibilityFlags = ((FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject*)Address)->RenderFlags; if (visibilityFlags != VisibilityFlags.None) return DrawCondition.RenderFlags; if (ObjectKind == ObjectKind.Player) { + if (!PtrGuard.IsReadable(DrawObjectAddress, (nuint)sizeof(CharacterBase))) + return DrawCondition.DrawObjectZero; + var modelInSlotLoaded = (((CharacterBase*)DrawObjectAddress)->HasModelInSlotLoaded != 0); if (modelInSlotLoaded) return DrawCondition.ModelInSlotLoaded; var modelFilesInSlotLoaded = (((CharacterBase*)DrawObjectAddress)->HasModelFilesInSlotLoaded != 0);