From e5f7c2f72daddd4082181c8b3721f574be5bab41 Mon Sep 17 00:00:00 2001 From: Stanley Dimant Date: Thu, 8 Sep 2022 11:48:20 +0200 Subject: [PATCH] add signalR logging and dalamudutil disposal, halt framework update between areas --- .../Managers/TransientResourceManager.cs | 3 +- MareSynchronos/Plugin.cs | 8 ++- MareSynchronos/Utils/DalamudUtil.cs | 33 ++++++--- MareSynchronos/Utils/Logger.cs | 72 ++++++++++++++++++- .../WebAPI/ApiController.Connectivity.cs | 5 ++ 5 files changed, 106 insertions(+), 15 deletions(-) diff --git a/MareSynchronos/Managers/TransientResourceManager.cs b/MareSynchronos/Managers/TransientResourceManager.cs index 848c42d..7bc3690 100644 --- a/MareSynchronos/Managers/TransientResourceManager.cs +++ b/MareSynchronos/Managers/TransientResourceManager.cs @@ -1,5 +1,4 @@ using MareSynchronos.API; -using MareSynchronos.FileCacheDB; using MareSynchronos.Models; using MareSynchronos.Utils; using System; @@ -42,7 +41,7 @@ namespace MareSynchronos.Managers { if (!dalamudUtil.IsGameObjectPresent(item.Key)) { - Logger.Debug("Object not present anymore: " + item.Key); + Logger.Debug("Object not present anymore: " + item.Key.ToString("X")); TransientResources.Remove(item.Key); } } diff --git a/MareSynchronos/Plugin.cs b/MareSynchronos/Plugin.cs index 753a233..d3b9ba8 100644 --- a/MareSynchronos/Plugin.cs +++ b/MareSynchronos/Plugin.cs @@ -14,6 +14,7 @@ using Dalamud.Interface.Windowing; using MareSynchronos.UI; using MareSynchronos.Utils; using System.Runtime.InteropServices; +using Dalamud.Game.ClientState.Conditions; namespace MareSynchronos { @@ -42,7 +43,7 @@ namespace MareSynchronos public Plugin(DalamudPluginInterface pluginInterface, CommandManager commandManager, - Framework framework, ObjectTable objectTable, ClientState clientState) + Framework framework, ObjectTable objectTable, ClientState clientState, Condition condition) { Logger.Debug("Launching " + Name); PluginInterface = pluginInterface; @@ -60,7 +61,7 @@ namespace MareSynchronos new FileCacheContext().Dispose(); // make sure db is initialized I guess // those can be initialized outside of game login - _dalamudUtil = new DalamudUtil(clientState, objectTable, framework); + _dalamudUtil = new DalamudUtil(clientState, objectTable, framework, condition); _apiController = new ApiController(_configuration, _dalamudUtil); _ipcManager = new IpcManager(PluginInterface, _dalamudUtil); @@ -124,7 +125,7 @@ namespace MareSynchronos _commandManager.RemoveHandler(CommandName); _dalamudUtil.LogIn -= DalamudUtilOnLogIn; _dalamudUtil.LogOut -= DalamudUtilOnLogOut; - + _uiSharedComponent.Dispose(); _settingsUi?.Dispose(); _introUi?.Dispose(); @@ -136,6 +137,7 @@ namespace MareSynchronos _playerManager?.Dispose(); _characterCacheManager?.Dispose(); _transientResourceManager?.Dispose(); + _dalamudUtil.Dispose(); Logger.Debug("Shut down"); } diff --git a/MareSynchronos/Utils/DalamudUtil.cs b/MareSynchronos/Utils/DalamudUtil.cs index e31e557..362d116 100644 --- a/MareSynchronos/Utils/DalamudUtil.cs +++ b/MareSynchronos/Utils/DalamudUtil.cs @@ -4,6 +4,7 @@ using System.Linq; using System.Threading; using Dalamud.Game; using Dalamud.Game.ClientState; +using Dalamud.Game.ClientState.Conditions; using Dalamud.Game.ClientState.Objects; using Dalamud.Game.ClientState.Objects.SubKinds; using FFXIVClientStructs.FFXIV.Client.Game.Character; @@ -24,6 +25,8 @@ namespace MareSynchronos.Utils private readonly ClientState _clientState; private readonly ObjectTable _objectTable; private readonly Framework _framework; + private readonly Condition _condition; + public event LogIn? LogIn; public event LogOut? LogOut; public event FrameworkUpdate? FrameworkUpdate; @@ -45,11 +48,12 @@ namespace MareSynchronos.Utils return false; } - public DalamudUtil(ClientState clientState, ObjectTable objectTable, Framework framework) + public DalamudUtil(ClientState clientState, ObjectTable objectTable, Framework framework, Condition condition) { _clientState = clientState; _objectTable = objectTable; _framework = framework; + _condition = condition; _clientState.Login += ClientStateOnLogin; _clientState.Logout += ClientStateOnLogout; _framework.Update += FrameworkOnUpdate; @@ -62,11 +66,16 @@ namespace MareSynchronos.Utils private void FrameworkOnUpdate(Framework framework) { - foreach (FrameworkUpdate frameworkInvocation in (FrameworkUpdate?.GetInvocationList() ?? Array.Empty()).Cast()) + if (_condition[ConditionFlag.BetweenAreas] || _condition[ConditionFlag.BetweenAreas51]) + { + return; + } + + foreach (FrameworkUpdate? frameworkInvocation in (FrameworkUpdate?.GetInvocationList() ?? Array.Empty()).Cast()) { try { - frameworkInvocation.Invoke(); + frameworkInvocation?.Invoke(); } catch (Exception ex) { @@ -75,15 +84,23 @@ namespace MareSynchronos.Utils } } - classJobId = _clientState.LocalPlayer.ClassJob.Id; - ClassJobChanged?.Invoke(); + if (DateTime.Now < _delayedFrameworkUpdateCheck.AddSeconds(1)) return; + if (_clientState.LocalPlayer != null && _clientState.LocalPlayer.IsValid()) + { + var newclassJobId = _clientState.LocalPlayer.ClassJob.Id; - if (DateTime.Now < _delayedFrameworkUpdateCheck.AddSeconds(0.25)) return; - foreach (FrameworkUpdate frameworkInvocation in (DelayedFrameworkUpdate?.GetInvocationList() ?? Array.Empty()).Cast()) + if (classJobId != newclassJobId) + { + classJobId = newclassJobId; + ClassJobChanged?.Invoke(); + } + } + + foreach (FrameworkUpdate? frameworkInvocation in (DelayedFrameworkUpdate?.GetInvocationList() ?? Array.Empty()).Cast()) { try { - frameworkInvocation.Invoke(); + frameworkInvocation?.Invoke(); } catch (Exception ex) { diff --git a/MareSynchronos/Utils/Logger.cs b/MareSynchronos/Utils/Logger.cs index 0e79f43..4785077 100644 --- a/MareSynchronos/Utils/Logger.cs +++ b/MareSynchronos/Utils/Logger.cs @@ -1,11 +1,37 @@ -using System.Diagnostics; +using System; +using System.Collections.Concurrent; +using System.Diagnostics; using Dalamud.Logging; using Dalamud.Utility; +using Microsoft.Extensions.Logging; namespace MareSynchronos.Utils { - internal class Logger + [ProviderAlias("Dalamud")] + public class DalamudLoggingProvider : ILoggerProvider { + private readonly ConcurrentDictionary _loggers = + new(StringComparer.OrdinalIgnoreCase); + + public DalamudLoggingProvider() + { + } + + public ILogger CreateLogger(string categoryName) + { + return _loggers.GetOrAdd(categoryName, name => new Logger(categoryName)); + } + + public void Dispose() + { + _loggers.Clear(); + } + } + + internal class Logger : ILogger + { + private readonly string name; + public static void Info(string info) { var caller = new StackTrace().GetFrame(1)?.GetMethod()?.ReflectedType?.Name ?? "Unknown"; @@ -40,5 +66,47 @@ namespace MareSynchronos.Utils PluginLog.Verbose($"[{caller}] {verbose}"); #endif } + + public Logger(string name) + { + this.name = name; + } + + public void Log(LogLevel logLevel, EventId eventId, TState state, Exception? exception, Func formatter) + { + if (!IsEnabled(logLevel)) return; + + switch (logLevel) + { + case LogLevel.Debug: + PluginLog.Debug($"[{name}] [{eventId}] {formatter(state, exception)}"); + break; + case LogLevel.Error: + case LogLevel.Critical: + PluginLog.Error($"[{name}] [{eventId}] {formatter(state, exception)}"); + break; + case LogLevel.Information: + PluginLog.Information($"[{name}] [{eventId}] {formatter(state, exception)}"); + break; + case LogLevel.Warning: + PluginLog.Warning($"[{name}] [{eventId}] {formatter(state, exception)}"); + break; + case LogLevel.Trace: + default: +#if DEBUG + PluginLog.Debug($"[{name}] [{eventId}] {formatter(state, exception)}"); +#else + PluginLog.Verbose($"[{name}] {eventId} {state} {formatter(state, exception)}"); +#endif + break; + } + } + + public bool IsEnabled(LogLevel logLevel) + { + return true; + } + + public IDisposable BeginScope(TState state) => default!; } } diff --git a/MareSynchronos/WebAPI/ApiController.Connectivity.cs b/MareSynchronos/WebAPI/ApiController.Connectivity.cs index 491299b..c6f722b 100644 --- a/MareSynchronos/WebAPI/ApiController.Connectivity.cs +++ b/MareSynchronos/WebAPI/ApiController.Connectivity.cs @@ -11,6 +11,7 @@ using MareSynchronos.WebAPI.Utils; using Microsoft.AspNetCore.Http.Connections; using Microsoft.AspNetCore.SignalR; using Microsoft.AspNetCore.SignalR.Client; +using Microsoft.Extensions.Logging; namespace MareSynchronos.WebAPI { @@ -304,6 +305,10 @@ namespace MareSynchronos.WebAPI options.Transports = HttpTransportType.WebSockets | HttpTransportType.ServerSentEvents | HttpTransportType.LongPolling; }) .WithAutomaticReconnect(new ForeverRetryPolicy()) + .ConfigureLogging(a => { + a.ClearProviders().AddProvider(new DalamudLoggingProvider()); + a.SetMinimumLevel(LogLevel.Trace); + }) .Build(); }