From e461c6d5c90bc1afba5128882cacdb633eae9438 Mon Sep 17 00:00:00 2001 From: rootdarkarchon Date: Mon, 20 Feb 2023 10:25:32 +0100 Subject: [PATCH] further fixes --- .../Factories/CharacterDataFactory.cs | 2 +- MareSynchronos/Factories/PairFactory.cs | 6 ++- MareSynchronos/Managers/CachedPlayer.cs | 7 +++- MareSynchronos/Managers/PairManager.cs | 42 ++++++++----------- MareSynchronos/MareSynchronos.csproj | 2 +- MareSynchronos/Mediator/MareMediator.cs | 15 +++++-- .../Mediator/MediatorSubscriberBase.cs | 2 +- MareSynchronos/Models/Pair.cs | 42 +++++++++++++++++-- MareSynchronos/Utils/DalamudLogger.cs | 6 +-- 9 files changed, 85 insertions(+), 39 deletions(-) diff --git a/MareSynchronos/Factories/CharacterDataFactory.cs b/MareSynchronos/Factories/CharacterDataFactory.cs index e6b83b2..687759d 100644 --- a/MareSynchronos/Factories/CharacterDataFactory.cs +++ b/MareSynchronos/Factories/CharacterDataFactory.cs @@ -207,7 +207,7 @@ public class CharacterDataFactory : MediatorSubscriberBase } st.Stop(); - _logger.LogInformation("Building character data for {obj} took {time}ms", objectKind, st.ElapsedTicks / 60.0d); + _logger.LogInformation("Building character data for {obj} took {time}ms", objectKind, TimeSpan.FromTicks(st.ElapsedTicks).TotalMilliseconds); return previousData; } diff --git a/MareSynchronos/Factories/PairFactory.cs b/MareSynchronos/Factories/PairFactory.cs index ab565a8..4eb7f5f 100644 --- a/MareSynchronos/Factories/PairFactory.cs +++ b/MareSynchronos/Factories/PairFactory.cs @@ -9,17 +9,19 @@ public class PairFactory { private readonly MareConfigService _configService; private readonly ServerConfigurationManager _serverConfigurationManager; + private readonly CachedPlayerFactory _cachedPlayerFactory; private readonly ILoggerFactory _loggerFactory; - public PairFactory(MareConfigService configService, ServerConfigurationManager serverConfigurationManager, ILoggerFactory loggerFactory) + public PairFactory(MareConfigService configService, ServerConfigurationManager serverConfigurationManager, CachedPlayerFactory cachedPlayerFactory, ILoggerFactory loggerFactory) { _configService = configService; _serverConfigurationManager = serverConfigurationManager; + _cachedPlayerFactory = cachedPlayerFactory; _loggerFactory = loggerFactory; } public Pair Create() { - return new Pair(_loggerFactory.CreateLogger(), _configService, _serverConfigurationManager); + return new Pair(_loggerFactory.CreateLogger(), _cachedPlayerFactory, _configService, _serverConfigurationManager); } } diff --git a/MareSynchronos/Managers/CachedPlayer.cs b/MareSynchronos/Managers/CachedPlayer.cs index fee5e9e..061b5e9 100644 --- a/MareSynchronos/Managers/CachedPlayer.cs +++ b/MareSynchronos/Managers/CachedPlayer.cs @@ -303,7 +303,12 @@ public class CachedPlayer : MediatorSubscriberBase, IDisposable CancellationTokenSource applicationTokenSource = new(); applicationTokenSource.CancelAfter(TimeSpan.FromSeconds(30)); - if (handler.Address == IntPtr.Zero) return; + if (handler.Address == IntPtr.Zero) + { + if (handler != _currentOtherChara) handler.Dispose(); + return; + } + _logger.LogDebug("[{applicationId}] Applying Customization Data for {handler}", applicationId, handler); _dalamudUtil.WaitWhileCharacterIsDrawing(_logger, handler, applicationId, 30000); foreach (var change in changes.Value) diff --git a/MareSynchronos/Managers/PairManager.cs b/MareSynchronos/Managers/PairManager.cs index b196fe9..2f1cb08 100644 --- a/MareSynchronos/Managers/PairManager.cs +++ b/MareSynchronos/Managers/PairManager.cs @@ -21,14 +21,12 @@ public class PairManager : MediatorSubscriberBase, IDisposable { private readonly ConcurrentDictionary _allClientPairs = new(UserDataComparer.Instance); private readonly ConcurrentDictionary _allGroups = new(GroupDataComparer.Instance); - private readonly CachedPlayerFactory _cachedPlayerFactory; private readonly PairFactory _pairFactory; private readonly MareConfigService _configurationService; - public PairManager(ILogger logger, CachedPlayerFactory cachedPlayerFactory, PairFactory pairFactory, + public PairManager(ILogger logger, PairFactory pairFactory, MareConfigService configurationService, MareMediator mediator) : base(logger, mediator) { - _cachedPlayerFactory = cachedPlayerFactory; _pairFactory = pairFactory; _configurationService = configurationService; Mediator.Subscribe(this, (_) => DalamudUtilOnZoneSwitched()); @@ -64,7 +62,7 @@ public class PairManager : MediatorSubscriberBase, IDisposable } public List OnlineUserPairs => _allClientPairs.Where(p => !string.IsNullOrEmpty(p.Value.PlayerNameHash)).Select(p => p.Value).ToList(); - public List VisibleUsers => _allClientPairs.Where(p => p.Value.CachedPlayer?.PlayerName != null).Select(p => p.Key).ToList(); + public List VisibleUsers => _allClientPairs.Where(p => p.Value.HasCachedPlayer).Select(p => p.Key).ToList(); public Pair? LastAddedUser { get; internal set; } @@ -91,8 +89,7 @@ public class PairManager : MediatorSubscriberBase, IDisposable { if (_allClientPairs.TryRemove(item.Key, out var pair)) { - pair.CachedPlayer?.Dispose(); - pair.CachedPlayer = null; + pair.MarkOffline(); } } } @@ -141,14 +138,17 @@ public class PairManager : MediatorSubscriberBase, IDisposable DisposePairs(); } - private void DisposePairs() + private void DisposePairs(bool recreate = false) { _logger.LogDebug("Disposing all Pairs"); foreach (var item in _allClientPairs) { - item.Value.CachedPlayer?.Dispose(); - item.Value.CachedPlayer = null; + if (recreate) + item.Value.RecreateCachedPlayer(); + else + item.Value.Dispose(); } + RecreateLazy(); } public Pair? FindPair(PlayerCharacter? pChar) @@ -162,8 +162,7 @@ public class PairManager : MediatorSubscriberBase, IDisposable { if (_allClientPairs.TryGetValue(user, out var pair)) { - pair.CachedPlayer?.Dispose(); - pair.CachedPlayer = null; + pair.MarkOffline(); RecreateLazy(); } } @@ -172,7 +171,7 @@ public class PairManager : MediatorSubscriberBase, IDisposable { if (!_allClientPairs.ContainsKey(dto.User)) throw new InvalidOperationException("No user found for " + dto); var pair = _allClientPairs[dto.User]; - if (pair.CachedPlayer != null) return; + if (pair.HasCachedPlayer) return; if (sendNotif && _configurationService.Current.ShowOnlineNotifications && ((_configurationService.Current.ShowOnlineNotificationsOnlyForIndividualPairs && pair.UserPair != null) @@ -187,9 +186,7 @@ public class PairManager : MediatorSubscriberBase, IDisposable Mediator.Publish(new NotificationMessage("User online", msg, NotificationType.Info, 5000)); } - pair.CachedPlayer?.Dispose(); - pair.CachedPlayer = null; - pair.CachedPlayer = _cachedPlayerFactory.Create(dto, controller); + pair.RecreateCachedPlayer(dto, controller); RecreateLazy(); } @@ -217,8 +214,7 @@ public class PairManager : MediatorSubscriberBase, IDisposable if (!pair.HasAnyConnection()) { - pair.CachedPlayer?.Dispose(); - pair.CachedPlayer = null; + pair.Dispose(); _allClientPairs.TryRemove(dto.User, out _); } @@ -233,8 +229,7 @@ public class PairManager : MediatorSubscriberBase, IDisposable pair.UserPair = null; if (!pair.HasAnyConnection()) { - pair.CachedPlayer?.Dispose(); - pair.CachedPlayer = null; + pair.Dispose(); _allClientPairs.TryRemove(dto.User, out _); } else @@ -276,19 +271,18 @@ public class PairManager : MediatorSubscriberBase, IDisposable private void DalamudUtilOnDelayedFrameworkUpdate() { - foreach (Pair pair in _allClientPairs.Select(p => p.Value).Where(p => p.CachedPlayer?.PlayerName != null).ToList()) + foreach (Pair pair in _allClientPairs.Select(p => p.Value).Where(p => p.HasCachedPlayer).ToList()) { - if (!pair.CachedPlayer?.CheckExistence() ?? false) + if (!pair.CachedPlayerExists) { - pair.CachedPlayer?.Dispose(); - pair.CachedPlayer = null; + pair.Dispose(); } } } private void DalamudUtilOnZoneSwitched() { - DisposePairs(); + DisposePairs(true); } public void SetGroupInfo(GroupInfoDto dto) diff --git a/MareSynchronos/MareSynchronos.csproj b/MareSynchronos/MareSynchronos.csproj index ee907cd..a0d82dc 100644 --- a/MareSynchronos/MareSynchronos.csproj +++ b/MareSynchronos/MareSynchronos.csproj @@ -3,7 +3,7 @@ - 0.7.35 + 0.7.36 https://github.com/Penumbra-Sync/client diff --git a/MareSynchronos/Mediator/MareMediator.cs b/MareSynchronos/Mediator/MareMediator.cs index 15a093d..c33f828 100644 --- a/MareSynchronos/Mediator/MareMediator.cs +++ b/MareSynchronos/Mediator/MareMediator.cs @@ -39,6 +39,8 @@ public class MareMediator : IDisposable { throw new InvalidOperationException("Already subscribed"); } + + _logger.LogDebug("Subscriber added for message {message}: {sub}", typeof(T), subscriber); } } @@ -80,13 +82,20 @@ public class MareMediator : IDisposable internal void UnsubscribeAll(IMediatorSubscriber subscriber) { - lock (_subscriberDict) + lock (_addRemoveLock) { - foreach (KeyValuePair> kvp in _subscriberDict.ToList()) + foreach (KeyValuePair> kvp in _subscriberDict) { int unSubbed = _subscriberDict[kvp.Key]?.RemoveWhere(p => p.Subscriber == subscriber) ?? 0; if (unSubbed > 0) + { _logger.LogDebug("{sub} unsubscribed from {msg}", subscriber, kvp.Key.Name); + _logger.LogTrace("Remaining Subscribers:"); + foreach (var item in _subscriberDict[kvp.Key]) + { + _logger.LogTrace("{Key}: {item}", kvp.Key, item.Subscriber); + } + } } } } @@ -96,7 +105,7 @@ public class MareMediator : IDisposable 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); + _logger.LogInformation("Subscriber {type}: {sub}", kvp.Subscriber.GetType().FullName, kvp.Subscriber.ToString()); StringBuilder sb = new(); sb.Append("=> "); foreach (var item in _subscriberDict.ToList()) diff --git a/MareSynchronos/Mediator/MediatorSubscriberBase.cs b/MareSynchronos/Mediator/MediatorSubscriberBase.cs index 4da551b..c8ad718 100644 --- a/MareSynchronos/Mediator/MediatorSubscriberBase.cs +++ b/MareSynchronos/Mediator/MediatorSubscriberBase.cs @@ -14,7 +14,7 @@ public abstract class MediatorSubscriberBase : IMediatorSubscriber public virtual void Dispose() { - _logger.LogTrace($"Disposing {GetType()}"); + _logger.LogTrace("Disposing {type} ({this})", GetType(), this); Mediator.UnsubscribeAll(this); } } diff --git a/MareSynchronos/Models/Pair.cs b/MareSynchronos/Models/Pair.cs index 7cb84f9..83b8558 100644 --- a/MareSynchronos/Models/Pair.cs +++ b/MareSynchronos/Models/Pair.cs @@ -4,29 +4,34 @@ using MareSynchronos.API.Data.Comparer; using MareSynchronos.API.Data.Extensions; using MareSynchronos.API.Dto.Group; using MareSynchronos.API.Dto.User; +using MareSynchronos.Factories; using MareSynchronos.Managers; using MareSynchronos.MareConfiguration; using MareSynchronos.Utils; +using MareSynchronos.WebAPI; using Microsoft.Extensions.Logging; namespace MareSynchronos.Models; -public class Pair +public class Pair : IDisposable { private readonly ILogger _logger; + private readonly CachedPlayerFactory _cachedPlayerFactory; private readonly MareConfigService _configService; private readonly ServerConfigurationManager _serverConfigurationManager; private OptionalPluginWarning? _pluginWarnings; - public Pair(ILogger logger, MareConfigService configService, ServerConfigurationManager serverConfigurationManager) + public Pair(ILogger logger, CachedPlayerFactory cachedPlayerFactory, MareConfigService configService, ServerConfigurationManager serverConfigurationManager) { _logger = logger; + _cachedPlayerFactory = cachedPlayerFactory; _configService = configService; _serverConfigurationManager = serverConfigurationManager; } public UserPairDto? UserPair { get; set; } - public CachedPlayer? CachedPlayer { get; set; } + private CachedPlayer? CachedPlayer { get; set; } + public bool HasCachedPlayer => CachedPlayer != null && !string.IsNullOrEmpty(CachedPlayer.PlayerName); public API.Data.CharacterData? LastReceivedCharacterData { get; set; } public Dictionary GroupPair { get; set; } = new(GroupDtoComparer.Instance); public string PlayerNameHash => CachedPlayer?.PlayerNameHash ?? string.Empty; @@ -127,4 +132,35 @@ public class Pair return data; } + + public bool CachedPlayerExists => CachedPlayer?.CheckExistence() ?? false; + + private OnlineUserIdentDto? _onlineUserIdentDto = null; + private ApiController? _apiController = null; + + public void RecreateCachedPlayer(OnlineUserIdentDto? dto = null, ApiController? controller = null) + { + if (dto == null && _onlineUserIdentDto == null || _apiController == null && controller == null) return; + if (dto != null || controller != null) + { + _onlineUserIdentDto = dto; + _apiController = controller; + } + CachedPlayer?.Dispose(); + CachedPlayer = null; + CachedPlayer = _cachedPlayerFactory.Create(_onlineUserIdentDto!, _apiController!); + } + + public void MarkOffline() + { + _onlineUserIdentDto = null; + CachedPlayer?.Dispose(); + CachedPlayer = null; + } + + public void Dispose() + { + CachedPlayer?.Dispose(); + CachedPlayer = null; + } } diff --git a/MareSynchronos/Utils/DalamudLogger.cs b/MareSynchronos/Utils/DalamudLogger.cs index 8fa1ef4..18cfdcb 100644 --- a/MareSynchronos/Utils/DalamudLogger.cs +++ b/MareSynchronos/Utils/DalamudLogger.cs @@ -20,13 +20,13 @@ internal class DalamudLogger : ILogger { if (!IsEnabled(logLevel)) return; - if (exception == null) + if ((int)logLevel <= (int)LogLevel.Information) PluginLog.Information($"[{_name}]{{{(int)logLevel}}} {state}"); else { StringBuilder sb = new(); - sb.AppendLine($"[{_name}]{{{(int)logLevel}}} {state}: {exception.Message}"); - sb.AppendLine(exception.StackTrace); + sb.AppendLine($"[{_name}]{{{(int)logLevel}}} {state}: {exception?.Message}"); + sb.AppendLine(exception?.StackTrace); if (logLevel == LogLevel.Warning) PluginLog.Warning(sb.ToString()); else if (logLevel == LogLevel.Error)