From 6d355d9b90ba62a5d14750f2591666b23ab70e21 Mon Sep 17 00:00:00 2001 From: Stanley Dimant Date: Sun, 23 Feb 2025 03:28:09 +0100 Subject: [PATCH] clean up some stuff --- .../FileCache/TransientResourceManager.cs | 2 +- .../PlayerData/Handlers/GameObjectHandler.cs | 49 +++---------------- .../Services/CacheCreationService.cs | 16 +++--- .../IHighPriorityMediatorSubscriber.cs | 3 ++ .../Services/Mediator/MareMediator.cs | 7 ++- .../WebAPI/SignalR/ApiController.cs | 14 ++++-- .../WebAPI/SignalR/TokenProvider.cs | 1 - 7 files changed, 32 insertions(+), 60 deletions(-) create mode 100644 MareSynchronos/Services/Mediator/IHighPriorityMediatorSubscriber.cs diff --git a/MareSynchronos/FileCache/TransientResourceManager.cs b/MareSynchronos/FileCache/TransientResourceManager.cs index 620aaa1..c19c8d9 100644 --- a/MareSynchronos/FileCache/TransientResourceManager.cs +++ b/MareSynchronos/FileCache/TransientResourceManager.cs @@ -246,7 +246,7 @@ public sealed class TransientResourceManager : DisposableMediatorSubscriberBase private void DalamudUtil_FrameworkUpdate() { - _cachedFrameAddresses = _cachedFrameAddresses = new(_playerRelatedPointers.Where(k => k.Address != nint.Zero).ToDictionary(c => c.CurrentAddress(), c => c.ObjectKind)); + _cachedFrameAddresses = new(_playerRelatedPointers.Where(k => k.Address != nint.Zero).ToDictionary(c => c.Address, c => c.ObjectKind)); lock (_cacheAdditionLock) { _cachedHandledPaths.Clear(); diff --git a/MareSynchronos/PlayerData/Handlers/GameObjectHandler.cs b/MareSynchronos/PlayerData/Handlers/GameObjectHandler.cs index 037558f..e0a06be 100644 --- a/MareSynchronos/PlayerData/Handlers/GameObjectHandler.cs +++ b/MareSynchronos/PlayerData/Handlers/GameObjectHandler.cs @@ -9,16 +9,15 @@ using ObjectKind = MareSynchronos.API.Data.Enum.ObjectKind; namespace MareSynchronos.PlayerData.Handlers; -public sealed class GameObjectHandler : DisposableMediatorSubscriberBase +public sealed class GameObjectHandler : DisposableMediatorSubscriberBase, IHighPriorityMediatorSubscriber { private readonly DalamudUtilService _dalamudUtil; private readonly Func _getAddress; private readonly bool _isOwnedObject; private readonly PerformanceCollectorService _performanceCollector; + private byte _classJob = 0; private Task? _delayedZoningTask; private bool _haltProcessing = false; - private int _ptrNullCounter = 0; - private byte _classJob = 0; private CancellationTokenSource _zoningCts = new(); public GameObjectHandler(ILogger logger, PerformanceCollectorService performanceCollector, @@ -91,21 +90,19 @@ public sealed class GameObjectHandler : DisposableMediatorSubscriberBase ModelFilesInSlotLoaded } - public byte RaceId { get; private set; } - public byte Gender { get; private set; } - public byte TribeId { get; private set; } - public IntPtr Address { get; private set; } + public DrawCondition CurrentDrawCondition { get; set; } = DrawCondition.None; + public byte Gender { get; private set; } public string Name { get; private set; } public ObjectKind ObjectKind { get; } + public byte RaceId { get; private set; } + public byte TribeId { get; private set; } private byte[] CustomizeData { get; set; } = new byte[26]; private IntPtr DrawObjectAddress { get; set; } private byte[] EquipSlotData { get; set; } = new byte[40]; private ushort[] MainHandData { get; set; } = new ushort[3]; private ushort[] OffHandData { get; set; } = new ushort[3]; - public DrawCondition CurrentDrawCondition { get; set; } = DrawCondition.None; - public async Task ActOnFrameworkAfterEnsureNoDrawAsync(Action act, CancellationToken token) { while (await _dalamudUtil.RunOnFrameworkThread(() => @@ -135,12 +132,6 @@ public sealed class GameObjectHandler : DisposableMediatorSubscriberBase } } - public IntPtr CurrentAddress() - { - _dalamudUtil.EnsureIsOnFramework(); - return _getAddress.Invoke(); - } - public Dalamud.Game.ClientState.Objects.Types.IGameObject? GetGameObject() { return _dalamudUtil.CreateGameObject(Address); @@ -179,7 +170,6 @@ public sealed class GameObjectHandler : DisposableMediatorSubscriberBase Address = _getAddress(); if (Address != IntPtr.Zero) { - _ptrNullCounter = 0; var drawObjAddr = (IntPtr)((FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject*)Address)->DrawObject; DrawObjectAddress = drawObjAddr; CurrentDrawCondition = DrawCondition.None; @@ -363,38 +353,15 @@ public sealed class GameObjectHandler : DisposableMediatorSubscriberBase } } - private unsafe IntPtr GetDrawObjUnsafe(nint curPtr) + private bool IsBeingDrawn() { - return (IntPtr)((FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject*)curPtr)->DrawObject; - } - - public bool IsBeingDrawn() - { - var curPtr = _getAddress(); - Logger.LogTrace("[{this}] IsBeingDrawn, CurPtr: {ptr}", this, curPtr.ToString("X")); - - if (curPtr == IntPtr.Zero && _ptrNullCounter < 2) - { - Logger.LogTrace("[{this}] IsBeingDrawn, CurPtr is ZERO, counter is {cnt}", this, _ptrNullCounter); - _ptrNullCounter++; - return true; - } - - if (curPtr == IntPtr.Zero) - { - Logger.LogTrace("[{this}] IsBeingDrawn, CurPtr is ZERO, returning", this); - - Address = IntPtr.Zero; - DrawObjectAddress = IntPtr.Zero; - throw new ArgumentNullException($"CurPtr for {this} turned ZERO"); - } - if (_dalamudUtil.IsAnythingDrawing) { Logger.LogTrace("[{this}] IsBeingDrawn, Global draw block", this); return true; } + Logger.LogTrace("[{this}] IsBeingDrawn, Condition: {cond}", this, CurrentDrawCondition); return CurrentDrawCondition != DrawCondition.None; } diff --git a/MareSynchronos/PlayerData/Services/CacheCreationService.cs b/MareSynchronos/PlayerData/Services/CacheCreationService.cs index 4bebecc..2a59725 100644 --- a/MareSynchronos/PlayerData/Services/CacheCreationService.cs +++ b/MareSynchronos/PlayerData/Services/CacheCreationService.cs @@ -13,13 +13,15 @@ public sealed class CacheCreationService : DisposableMediatorSubscriberBase private readonly SemaphoreSlim _cacheCreateLock = new(1); private readonly HashSet _cachesToCreate = []; private readonly PlayerDataFactory _characterDataFactory; - private readonly CancellationTokenSource _runtimeCts = new(); + private readonly HashSet _currentlyCreating = []; + private readonly HashSet _debouncedObjectCache = []; private readonly CharacterData _playerData = new(); private readonly Dictionary _playerRelatedObjects = []; + private readonly CancellationTokenSource _runtimeCts = new(); + private CancellationTokenSource _creationCts = new(); private CancellationTokenSource _debounceCts = new(); - private readonly HashSet _debouncedObjectCache = []; - private bool _isZoning = false; private bool _haltCharaDataCreation; + private bool _isZoning = false; public CacheCreationService(ILogger logger, MareMediator mediator, GameObjectHandlerFactory gameObjectHandlerFactory, PlayerDataFactory characterDataFactory, DalamudUtilService dalamudUtil) : base(logger, mediator) @@ -103,7 +105,6 @@ public sealed class CacheCreationService : DisposableMediatorSubscriberBase { Logger.LogDebug("Received Moodles change, updating player"); AddCacheToCreate(ObjectKind.Player); - } }); @@ -153,7 +154,7 @@ public sealed class CacheCreationService : DisposableMediatorSubscriberBase _ = Task.Run(async () => { await Task.Delay(TimeSpan.FromSeconds(1), token).ConfigureAwait(false); - Logger.LogWarning("Debounce complete, inserting objects to create for: {obj}", string.Join(", ", _debouncedObjectCache)); + Logger.LogTrace("Debounce complete, inserting objects to create for: {obj}", string.Join(", ", _debouncedObjectCache)); await _cacheCreateLock.WaitAsync(token).ConfigureAwait(false); foreach (var item in _debouncedObjectCache) { @@ -164,9 +165,6 @@ public sealed class CacheCreationService : DisposableMediatorSubscriberBase }); } - private readonly HashSet _currentlyCreating = []; - private CancellationTokenSource _creationCts = new(); - private void ProcessCacheCreation() { if (_isZoning || _haltCharaDataCreation) return; @@ -229,4 +227,4 @@ public sealed class CacheCreationService : DisposableMediatorSubscriberBase } }); } -} +} \ No newline at end of file diff --git a/MareSynchronos/Services/Mediator/IHighPriorityMediatorSubscriber.cs b/MareSynchronos/Services/Mediator/IHighPriorityMediatorSubscriber.cs new file mode 100644 index 0000000..7660026 --- /dev/null +++ b/MareSynchronos/Services/Mediator/IHighPriorityMediatorSubscriber.cs @@ -0,0 +1,3 @@ +namespace MareSynchronos.Services.Mediator; + +public interface IHighPriorityMediatorSubscriber : IMediatorSubscriber { } \ No newline at end of file diff --git a/MareSynchronos/Services/Mediator/MareMediator.cs b/MareSynchronos/Services/Mediator/MareMediator.cs index eecdb4c..3583878 100644 --- a/MareSynchronos/Services/Mediator/MareMediator.cs +++ b/MareSynchronos/Services/Mediator/MareMediator.cs @@ -92,6 +92,7 @@ public sealed class MareMediator : IHostedService { _messageQueue.Clear(); _loopCts.Cancel(); + _loopCts.Dispose(); return Task.CompletedTask; } @@ -105,8 +106,6 @@ public sealed class MareMediator : IHostedService { throw new InvalidOperationException("Already subscribed"); } - - _logger.LogDebug("Subscriber added for message {message}: {sub}", typeof(T).Name, subscriber.GetType().Name); } } @@ -143,7 +142,7 @@ public sealed class MareMediator : IHostedService List subscribersCopy = []; lock (_addRemoveLock) { - subscribersCopy = subscribers?.Where(s => s.Subscriber != null).ToList() ?? []; + subscribersCopy = subscribers?.Where(s => s.Subscriber != null).OrderBy(k => k.Subscriber is IHighPriorityMediatorSubscriber ? 0 : 1).ToList() ?? []; } #pragma warning disable S3011 // Reflection should not be used to increase accessibility of classes, methods, or fields @@ -151,7 +150,7 @@ public sealed class MareMediator : IHostedService if (!_genericExecuteMethods.TryGetValue(msgType, out var methodInfo)) { _genericExecuteMethods[msgType] = methodInfo = GetType() - .GetMethod(nameof(ExecuteReflected), System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance)? + .GetMethod(nameof(ExecuteReflected), BindingFlags.NonPublic | BindingFlags.Instance)? .MakeGenericMethod(msgType); } diff --git a/MareSynchronos/WebAPI/SignalR/ApiController.cs b/MareSynchronos/WebAPI/SignalR/ApiController.cs index 2a09c29..2bc8aff 100644 --- a/MareSynchronos/WebAPI/SignalR/ApiController.cs +++ b/MareSynchronos/WebAPI/SignalR/ApiController.cs @@ -268,18 +268,24 @@ public sealed partial class ApiController : DisposableMediatorSubscriberBase, IM NotificationType.Error, TimeSpan.FromSeconds(15))); } - if (_dalamudUtil.IsLodEnabled) + if (_dalamudUtil.IsLodEnabled && !_naggedAboutLod) { + _naggedAboutLod = true; Logger.LogWarning("Model LOD is enabled during connection"); if (!_mareConfigService.Current.DebugStopWhining) { Mediator.Publish(new NotificationMessage("Model LOD is enabled", "You have \"Use low-detail models on distant objects (LOD)\" enabled. Having model LOD enabled is known to be a reason to cause " + - "random crashes when loading in or rendering modded pairs. Disable LOD while using Mare: " + + "random crashes when loading in or rendering modded pairs. Disabling LOD has a very low performance impact. Disable LOD while using Mare: " + "Go to XIV Menu -> System Configuration -> Graphics Settings and disable the model LOD option.", NotificationType.Warning, TimeSpan.FromSeconds(15))); } } + if (_naggedAboutLod && !_dalamudUtil.IsLodEnabled) + { + _naggedAboutLod = false; + } + await LoadIninitialPairsAsync().ConfigureAwait(false); await LoadOnlinePairsAsync().ConfigureAwait(false); } @@ -318,6 +324,8 @@ public sealed partial class ApiController : DisposableMediatorSubscriberBase, IM } } + private bool _naggedAboutLod = false; + public Task CyclePauseAsync(UserData userData) { CancellationTokenSource cts = new(); @@ -533,8 +541,6 @@ public sealed partial class ApiController : DisposableMediatorSubscriberBase, IM private async Task RefreshTokenAsync(CancellationToken ct) { - Logger.LogDebug("Checking token"); - bool requireReconnect = false; try { diff --git a/MareSynchronos/WebAPI/SignalR/TokenProvider.cs b/MareSynchronos/WebAPI/SignalR/TokenProvider.cs index bd46f65..71baeeb 100644 --- a/MareSynchronos/WebAPI/SignalR/TokenProvider.cs +++ b/MareSynchronos/WebAPI/SignalR/TokenProvider.cs @@ -222,7 +222,6 @@ public sealed class TokenProvider : IDisposable, IMediatorSubscriber var jwt = handler.ReadJwtToken(token); if (jwt.ValidTo == DateTime.MinValue || jwt.ValidTo.Subtract(TimeSpan.FromMinutes(5)) > DateTime.UtcNow) { - _logger.LogTrace("GetOrUpdate: Returning token from cache"); return token; }