diff --git a/LightlessSync/Services/DalamudUtilService.cs b/LightlessSync/Services/DalamudUtilService.cs index 0806b42..2606d7b 100644 --- a/LightlessSync/Services/DalamudUtilService.cs +++ b/LightlessSync/Services/DalamudUtilService.cs @@ -958,59 +958,78 @@ public class DalamudUtilService : IHostedService, IMediatorSubscriber if (address == nint.Zero) return; - var gameObj = (GameObject*)address; - - if (gameObj == null || gameObj->ObjectKind == 0) - return; - var drawObj = gameObj->DrawObject; - bool isDrawing = false; - bool isDrawingChanged = false; - if ((nint)drawObj != IntPtr.Zero) + try { - isDrawing = gameObj->RenderFlags == (VisibilityFlags)0b100000000000; - if (!isDrawing) + var gameObj = (GameObject*)address; + + if (gameObj == null || gameObj->ObjectKind == 0) + return; + + if (!IsGameObjectPresent(address)) { - isDrawing = ((CharacterBase*)drawObj)->HasModelInSlotLoaded != 0; + _logger.LogDebug("Character {name} at {addr} no longer present in object table", characterName, address.ToString("X")); + return; + } + + var drawObj = gameObj->DrawObject; + bool isDrawing = false; + bool isDrawingChanged = false; + + if ((nint)drawObj != IntPtr.Zero) + { + isDrawing = gameObj->RenderFlags == (VisibilityFlags)0b100000000000; if (!isDrawing) { - isDrawing = ((CharacterBase*)drawObj)->HasModelFilesInSlotLoaded != 0; - if (isDrawing && !string.Equals(_lastGlobalBlockPlayer, characterName, StringComparison.Ordinal) - && !string.Equals(_lastGlobalBlockReason, "HasModelFilesInSlotLoaded", StringComparison.Ordinal)) + var charBase = (CharacterBase*)drawObj; + if (charBase != null) { - _lastGlobalBlockPlayer = characterName; - _lastGlobalBlockReason = "HasModelFilesInSlotLoaded"; - isDrawingChanged = true; + isDrawing = charBase->HasModelInSlotLoaded != 0; + if (!isDrawing) + { + isDrawing = charBase->HasModelFilesInSlotLoaded != 0; + if (isDrawing && !string.Equals(_lastGlobalBlockPlayer, characterName, StringComparison.Ordinal) + && !string.Equals(_lastGlobalBlockReason, "HasModelFilesInSlotLoaded", StringComparison.Ordinal)) + { + _lastGlobalBlockPlayer = characterName; + _lastGlobalBlockReason = "HasModelFilesInSlotLoaded"; + isDrawingChanged = true; + } + } + else + { + if (!string.Equals(_lastGlobalBlockPlayer, characterName, StringComparison.Ordinal) + && !string.Equals(_lastGlobalBlockReason, "HasModelInSlotLoaded", StringComparison.Ordinal)) + { + _lastGlobalBlockPlayer = characterName; + _lastGlobalBlockReason = "HasModelInSlotLoaded"; + isDrawingChanged = true; + } + } } } else { if (!string.Equals(_lastGlobalBlockPlayer, characterName, StringComparison.Ordinal) - && !string.Equals(_lastGlobalBlockReason, "HasModelInSlotLoaded", StringComparison.Ordinal)) + && !string.Equals(_lastGlobalBlockReason, "RenderFlags", StringComparison.Ordinal)) { _lastGlobalBlockPlayer = characterName; - _lastGlobalBlockReason = "HasModelInSlotLoaded"; + _lastGlobalBlockReason = "RenderFlags"; isDrawingChanged = true; } } } - else + + if (isDrawingChanged) { - if (!string.Equals(_lastGlobalBlockPlayer, characterName, StringComparison.Ordinal) - && !string.Equals(_lastGlobalBlockReason, "RenderFlags", StringComparison.Ordinal)) - { - _lastGlobalBlockPlayer = characterName; - _lastGlobalBlockReason = "RenderFlags"; - isDrawingChanged = true; - } + _logger.LogTrace("Global draw block: START => {name} ({reason})", characterName, _lastGlobalBlockReason); } - } - if (isDrawingChanged) + IsAnythingDrawing |= isDrawing; + } + catch (AccessViolationException ex) { - _logger.LogTrace("Global draw block: START => {name} ({reason})", characterName, _lastGlobalBlockReason); + _logger.LogWarning(ex, "access violation checking character {name} at {addr}", characterName, address.ToString("X")); } - - IsAnythingDrawing |= isDrawing; } private void FrameworkOnUpdate(IFramework framework)