From d99a6f8294330ba06d188567204b6ee082e4ba20 Mon Sep 17 00:00:00 2001 From: rootdarkarchon Date: Sun, 19 Feb 2023 22:24:54 +0100 Subject: [PATCH] potential fixes for mediator logspam --- MareSynchronos/Managers/CachedPlayer.cs | 16 +- MareSynchronos/MarePlugin.cs | 4 + MareSynchronos/MareSynchronos.csproj | 2 +- MareSynchronos/Mediator/MareMediator.cs | 24 ++- MareSynchronos/Models/GameObjectHandler.cs | 181 +++++++++++---------- MareSynchronos/Utils/DalamudUtil.cs | 1 + 6 files changed, 130 insertions(+), 98 deletions(-) diff --git a/MareSynchronos/Managers/CachedPlayer.cs b/MareSynchronos/Managers/CachedPlayer.cs index 7e0c39a..4a156e7 100644 --- a/MareSynchronos/Managers/CachedPlayer.cs +++ b/MareSynchronos/Managers/CachedPlayer.cs @@ -230,16 +230,17 @@ public class CachedPlayer : MediatorSubscriberBase, IDisposable _downloadCancellationTokenSource?.Cancel(); _downloadCancellationTokenSource?.Dispose(); _downloadCancellationTokenSource = null; - if (PlayerCharacter != IntPtr.Zero) + var ptr = PlayerCharacter; + _currentOtherChara?.Dispose(); + _currentOtherChara = null; + + if (ptr != IntPtr.Zero) { - var ptr = PlayerCharacter; foreach (var item in _cachedData.FileReplacements) { Task.Run(async () => await RevertCustomizationData(ptr, item.Key, name, applicationId).ConfigureAwait(false)); } } - _currentOtherChara?.Dispose(); - _currentOtherChara = null; } catch (Exception ex) { @@ -288,12 +289,13 @@ public class CachedPlayer : MediatorSubscriberBase, IDisposable private async Task ApplyCustomizationData(Guid applicationId, KeyValuePair> changes, API.Data.CharacterData charaData) { if (PlayerCharacter == IntPtr.Zero) return; + var ptr = PlayerCharacter; var handler = changes.Key switch { ObjectKind.Player => _currentOtherChara!, - ObjectKind.Companion => _gameObjectHandlerFactory.Create(changes.Key, () => _dalamudUtil.GetCompanion(PlayerCharacter), isWatched: false), - ObjectKind.MinionOrMount => _gameObjectHandlerFactory.Create(changes.Key, () => _dalamudUtil.GetMinionOrMount(PlayerCharacter), isWatched: false), - ObjectKind.Pet => _gameObjectHandlerFactory.Create(changes.Key, () => _dalamudUtil.GetPet(PlayerCharacter), isWatched: false), + ObjectKind.Companion => _gameObjectHandlerFactory.Create(changes.Key, () => _dalamudUtil.GetCompanion(ptr), isWatched: false), + ObjectKind.MinionOrMount => _gameObjectHandlerFactory.Create(changes.Key, () => _dalamudUtil.GetMinionOrMount(ptr), isWatched: false), + ObjectKind.Pet => _gameObjectHandlerFactory.Create(changes.Key, () => _dalamudUtil.GetPet(ptr), isWatched: false), _ => throw new NotSupportedException("ObjectKind not supported: " + changes.Key) }; diff --git a/MareSynchronos/MarePlugin.cs b/MareSynchronos/MarePlugin.cs index a506790..594dcf6 100644 --- a/MareSynchronos/MarePlugin.cs +++ b/MareSynchronos/MarePlugin.cs @@ -214,6 +214,10 @@ public class MarePlugin : MediatorSubscriberBase, IDisposable _serviceProvider.GetRequiredService().PrintPerformanceStats(); } } + else if (string.Equals(splitArgs[0], "medi", StringComparison.OrdinalIgnoreCase)) + { + _serviceProvider.GetRequiredService().PrintSubscriberInfo(); + } } private void OpenUi() diff --git a/MareSynchronos/MareSynchronos.csproj b/MareSynchronos/MareSynchronos.csproj index 65c5261..5dc00c6 100644 --- a/MareSynchronos/MareSynchronos.csproj +++ b/MareSynchronos/MareSynchronos.csproj @@ -3,7 +3,7 @@ - 0.7.33 + 0.7.34 https://github.com/Penumbra-Sync/client diff --git a/MareSynchronos/Mediator/MareMediator.cs b/MareSynchronos/Mediator/MareMediator.cs index 61db0f8..147a7b7 100644 --- a/MareSynchronos/Mediator/MareMediator.cs +++ b/MareSynchronos/Mediator/MareMediator.cs @@ -1,6 +1,7 @@ using MareSynchronos.Utils; using Microsoft.Extensions.Logging; using System.Diagnostics; +using System.Text; namespace MareSynchronos.Mediator; @@ -63,12 +64,33 @@ public class MareMediator : IDisposable { foreach (var kvp in _subscriberDict.ToList()) { - var unSubbed = kvp.Value.RemoveWhere(p => p.Subscriber == subscriber); + var unSubbed = _subscriberDict[kvp.Key].RemoveWhere(p => p.Subscriber == subscriber); if (unSubbed > 0) _logger.LogDebug("{sub} unsubscribed from {msg}", subscriber, kvp.Key.Name); } } + public void PrintSubscriberInfo() + { + foreach (var kvp in _subscriberDict.ToList().SelectMany(c => c.Value.Select(v => v)) + .DistinctBy(p => p.Subscriber).OrderBy(p => p.Subscriber.GetType().FullName, StringComparer.Ordinal)) + { + _logger.LogInformation("Subscriber {type}: {sub}", kvp.Subscriber.GetType().FullName, kvp); + StringBuilder sb = new(); + sb.Append("=> "); + foreach (var item in _subscriberDict.ToList()) + { + if (item.Value.Any(v => v.Subscriber == kvp.Subscriber)) + { + sb.Append(item.Key.Name + ", "); + } + } + if (!string.Equals(sb.ToString(), "=> ", StringComparison.Ordinal)) + _logger.LogInformation("{sb}", sb.ToString()); + _logger.LogInformation("---"); + } + } + public void Dispose() { _logger.LogTrace("Disposing {type}", GetType()); diff --git a/MareSynchronos/Models/GameObjectHandler.cs b/MareSynchronos/Models/GameObjectHandler.cs index 8ce134a..c1811f0 100644 --- a/MareSynchronos/Models/GameObjectHandler.cs +++ b/MareSynchronos/Models/GameObjectHandler.cs @@ -1,38 +1,27 @@ using FFXIVClientStructs.FFXIV.Client.Game.Character; using FFXIVClientStructs.FFXIV.Client.Game.Object; using FFXIVClientStructs.FFXIV.Client.Graphics.Scene; -using System.Runtime.InteropServices; -using Penumbra.String; using MareSynchronos.Mediator; -using ObjectKind = MareSynchronos.API.Data.Enum.ObjectKind; -using Microsoft.Extensions.Logging; using MareSynchronos.Utils; +using Microsoft.Extensions.Logging; +using Penumbra.String; +using System.Runtime.InteropServices; +using ObjectKind = MareSynchronos.API.Data.Enum.ObjectKind; namespace MareSynchronos.Models; public class GameObjectHandler : MediatorSubscriberBase { - private readonly PerformanceCollector _performanceCollector; - private readonly MareMediator _mediator; private readonly Func _getAddress; private readonly bool _isOwnedObject; - public unsafe Character* Character => (Character*)Address; - - public string Name { get; private set; } - public ObjectKind ObjectKind { get; } - public IntPtr Address { get; set; } - public IntPtr CurrentAddress => _getAddress.Invoke(); - private IntPtr DrawObjectAddress { get; set; } + private readonly MareMediator _mediator; + private readonly PerformanceCollector _performanceCollector; + private CancellationTokenSource? _clearCts = new(); + private Task? _clearTask; private Task? _delayedZoningTask; - private CancellationTokenSource _zoningCts = new(); private bool _haltProcessing = false; private bool _ignoreSendAfterRedraw = false; - - public override string ToString() - { - return $"{ObjectKind}:{Name} ({Address:X},{DrawObjectAddress:X})"; - } - + private CancellationTokenSource _zoningCts = new(); public GameObjectHandler(ILogger logger, PerformanceCollector performanceCollector, MareMediator mediator, ObjectKind objectKind, Func getAddress, bool watchedObject = true) : base(logger, mediator) { _performanceCollector = performanceCollector; @@ -93,66 +82,34 @@ public class GameObjectHandler : MediatorSubscriberBase CheckAndUpdateObject(); } + public IntPtr Address { get; set; } + public unsafe Character* Character => (Character*)Address; + + public IntPtr CurrentAddress => _getAddress.Invoke(); + public bool IsBeingDrawn { get; private set; } + public string Name { get; private set; } + public ObjectKind ObjectKind { get; } + private byte[] CustomizeData { get; set; } = new byte[26]; + private IntPtr DrawObjectAddress { get; set; } + private byte[] EquipSlotData { get; set; } = new byte[40]; + + private byte? HatState { get; set; } + + private byte? VisorWeaponState { get; set; } + public override void Dispose() { base.Dispose(); - Mediator.Publish(new RemoveWatchedGameObjectHandler(this)); + if (_isOwnedObject) + Mediator.Publish(new RemoveWatchedGameObjectHandler(this)); } - private void FrameworkUpdate() + public override string ToString() { - if (!_delayedZoningTask?.IsCompleted ?? false) return; - - try - { - _performanceCollector.LogPerformance(this, "CheckAndUpdateObject>" + (_isOwnedObject ? "Self+" : "Other+") + ObjectKind + "/" - + (string.IsNullOrEmpty(Name) ? "Unk" : Name) + "+" + Address.ToString("X"), CheckAndUpdateObject); - } - catch (Exception ex) - { - _logger.LogWarning(ex, "Error during FrameworkUpdate of {this}", this); - } + var owned = (_isOwnedObject ? "Self" : "Other"); + return $"{owned}/{ObjectKind}:{Name} ({Address:X},{DrawObjectAddress:X})"; } - private void ZoneSwitchEnd() - { - if (!_isOwnedObject || _haltProcessing) return; - - _clearCts?.Cancel(); - _clearCts?.Dispose(); - _clearCts = null; - _zoningCts.CancelAfter(2500); - } - - private void ZoneSwitchStart() - { - if (!_isOwnedObject || _haltProcessing) return; - - _zoningCts = new(); - _logger.LogDebug("[{obj}] Starting Delay After Zoning", this); - _delayedZoningTask = Task.Run(async () => - { - try - { - await Task.Delay(TimeSpan.FromSeconds(120), _zoningCts.Token).ConfigureAwait(false); - } - catch { } - finally - { - _logger.LogDebug("[{this}] Delay after zoning complete", this); - _zoningCts.Dispose(); - } - }); - } - - public bool IsBeingDrawn { get; private set; } - private byte[] EquipSlotData { get; set; } = new byte[40]; - private byte[] CustomizeData { get; set; } = new byte[26]; - private Task? _clearTask; - private CancellationTokenSource? _clearCts = new(); - private byte? HatState { get; set; } - private byte? VisorWeaponState { get; set; } - private unsafe void CheckAndUpdateObject() { if (_haltProcessing) return; @@ -246,22 +203,6 @@ public class GameObjectHandler : MediatorSubscriberBase _clearCts = null; } - private unsafe bool CompareAndUpdateEquipByteData(byte* equipSlotData) - { - bool hasChanges = false; - for (int i = 0; i < EquipSlotData.Length; i++) - { - var data = Marshal.ReadByte((IntPtr)equipSlotData, i); - if (EquipSlotData[i] != data) - { - EquipSlotData[i] = data; - hasChanges = true; - } - } - - return hasChanges; - } - private unsafe bool CompareAndUpdateCustomizeData(byte* customizeData, out bool doNotSendUpdate) { bool hasChanges = false; @@ -303,4 +244,66 @@ public class GameObjectHandler : MediatorSubscriberBase return hasChanges; } -} + + private unsafe bool CompareAndUpdateEquipByteData(byte* equipSlotData) + { + bool hasChanges = false; + for (int i = 0; i < EquipSlotData.Length; i++) + { + var data = Marshal.ReadByte((IntPtr)equipSlotData, i); + if (EquipSlotData[i] != data) + { + EquipSlotData[i] = data; + hasChanges = true; + } + } + + return hasChanges; + } + + private void FrameworkUpdate() + { + if (!_delayedZoningTask?.IsCompleted ?? false) return; + + try + { + _performanceCollector.LogPerformance(this, "CheckAndUpdateObject>" + (_isOwnedObject ? "Self+" : "Other+") + ObjectKind + "/" + + (string.IsNullOrEmpty(Name) ? "Unk" : Name) + "+" + Address.ToString("X"), CheckAndUpdateObject); + } + catch (Exception ex) + { + _logger.LogWarning(ex, "Error during FrameworkUpdate of {this}", this); + } + } + + private void ZoneSwitchEnd() + { + if (!_isOwnedObject || _haltProcessing) return; + + _clearCts?.Cancel(); + _clearCts?.Dispose(); + _clearCts = null; + _zoningCts.CancelAfter(2500); + } + + private void ZoneSwitchStart() + { + if (!_isOwnedObject || _haltProcessing) return; + + _zoningCts = new(); + _logger.LogDebug("[{obj}] Starting Delay After Zoning", this); + _delayedZoningTask = Task.Run(async () => + { + try + { + await Task.Delay(TimeSpan.FromSeconds(120), _zoningCts.Token).ConfigureAwait(false); + } + catch { } + finally + { + _logger.LogDebug("[{this}] Delay after zoning complete", this); + _zoningCts.Dispose(); + } + }); + } +} \ No newline at end of file diff --git a/MareSynchronos/Utils/DalamudUtil.cs b/MareSynchronos/Utils/DalamudUtil.cs index 1f9a375..df8228d 100644 --- a/MareSynchronos/Utils/DalamudUtil.cs +++ b/MareSynchronos/Utils/DalamudUtil.cs @@ -201,6 +201,7 @@ public class DalamudUtil : IDisposable public unsafe IntPtr GetMinionOrMount(IntPtr? playerPointer = null) { playerPointer ??= PlayerPointer; + if (playerPointer == IntPtr.Zero) return IntPtr.Zero; return _objectTable.GetObjectAddress(((GameObject*)playerPointer)->ObjectIndex + 1); }