diff --git a/MareSynchronos/FileCache/TransientResourceManager.cs b/MareSynchronos/FileCache/TransientResourceManager.cs index fff95b9..87a8be1 100644 --- a/MareSynchronos/FileCache/TransientResourceManager.cs +++ b/MareSynchronos/FileCache/TransientResourceManager.cs @@ -35,13 +35,15 @@ public sealed class TransientResourceManager : DisposableMediatorSubscriberBase DalamudUtil_ClassJobChanged(); } }); - Mediator.Subscribe(this, (msg) => + Mediator.Subscribe(this, (msg) => { - _playerRelatedPointers.Add(msg.Handler); + if (!msg.OwnedObject) return; + _playerRelatedPointers.Add(msg.GameObjectHandler); }); - Mediator.Subscribe(this, (msg) => + Mediator.Subscribe(this, (msg) => { - _playerRelatedPointers.Remove(msg.Handler); + if (!msg.OwnedObject) return; + _playerRelatedPointers.Remove(msg.GameObjectHandler); }); } diff --git a/MareSynchronos/Interop/Ipc/IpcProvider.cs b/MareSynchronos/Interop/Ipc/IpcProvider.cs index 94ffba8..099162b 100644 --- a/MareSynchronos/Interop/Ipc/IpcProvider.cs +++ b/MareSynchronos/Interop/Ipc/IpcProvider.cs @@ -2,13 +2,15 @@ using Dalamud.Plugin; using Dalamud.Plugin.Ipc; using MareSynchronos.PlayerData.Export; +using MareSynchronos.PlayerData.Handlers; using MareSynchronos.Services; +using MareSynchronos.Services.Mediator; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; namespace MareSynchronos.Interop.Ipc; -public class IpcProvider : IHostedService +public class IpcProvider : IHostedService, IMediatorSubscriber { private readonly ILogger _logger; private readonly IDalamudPluginInterface _pi; @@ -16,14 +18,31 @@ public class IpcProvider : IHostedService private readonly DalamudUtilService _dalamudUtil; private ICallGateProvider? _loadFileProvider; private ICallGateProvider>? _loadFileAsyncProvider; + private ICallGateProvider>? _handledGameAddresses; + private readonly List _activeGameObjectHandlers = []; + + public MareMediator Mediator { get; init; } public IpcProvider(ILogger logger, IDalamudPluginInterface pi, - MareCharaFileManager mareCharaFileManager, DalamudUtilService dalamudUtil) + MareCharaFileManager mareCharaFileManager, DalamudUtilService dalamudUtil, + MareMediator mareMediator) { _logger = logger; _pi = pi; _mareCharaFileManager = mareCharaFileManager; _dalamudUtil = dalamudUtil; + Mediator = mareMediator; + + Mediator.Subscribe(this, (msg) => + { + if (msg.OwnedObject) return; + _activeGameObjectHandlers.Add(msg.GameObjectHandler); + }); + Mediator.Subscribe(this, (msg) => + { + if (msg.OwnedObject) return; + _activeGameObjectHandlers.Remove(msg.GameObjectHandler); + }); } public Task StartAsync(CancellationToken cancellationToken) @@ -33,6 +52,9 @@ public class IpcProvider : IHostedService _loadFileProvider.RegisterFunc(LoadMcdf); _loadFileAsyncProvider = _pi.GetIpcProvider>("MareSynchronos.LoadMcdfAsync"); _loadFileAsyncProvider.RegisterFunc(LoadMcdfAsync); + _handledGameAddresses = _pi.GetIpcProvider>("MareSynchronos.GetHandledAddresses"); + _handledGameAddresses.RegisterFunc(GetHandledAddresses); + _logger.LogInformation("Started IpcProviderService"); return Task.CompletedTask; } @@ -41,6 +63,8 @@ public class IpcProvider : IHostedService _logger.LogDebug("Stopping IpcProvider Service"); _loadFileProvider?.UnregisterFunc(); _loadFileAsyncProvider?.UnregisterFunc(); + _handledGameAddresses?.UnregisterFunc(); + Mediator.UnsubscribeAll(this); return Task.CompletedTask; } @@ -76,4 +100,9 @@ public class IpcProvider : IHostedService _mareCharaFileManager.ClearMareCharaFile(); } } + + private List GetHandledAddresses() + { + return _activeGameObjectHandlers.Where(g => g.Address != nint.Zero).Select(g => g.Address).Distinct().ToList(); + } } diff --git a/MareSynchronos/PlayerData/Handlers/GameObjectHandler.cs b/MareSynchronos/PlayerData/Handlers/GameObjectHandler.cs index 912d151..2e9fc66 100644 --- a/MareSynchronos/PlayerData/Handlers/GameObjectHandler.cs +++ b/MareSynchronos/PlayerData/Handlers/GameObjectHandler.cs @@ -48,7 +48,6 @@ public sealed class GameObjectHandler : DisposableMediatorSubscriberBase Mediator.Publish(new CreateCacheForObjectMessage(this)); } }); - Mediator.Publish(new AddWatchedGameObjectHandler(this)); } Mediator.Subscribe(this, (_) => FrameworkUpdate()); @@ -86,6 +85,8 @@ public sealed class GameObjectHandler : DisposableMediatorSubscriberBase } }); + Mediator.Publish(new GameObjectHandlerCreatedMessage(this, _isOwnedObject)); + _dalamudUtil.RunOnFrameworkThread(CheckAndUpdateObject).GetAwaiter().GetResult(); } @@ -173,8 +174,7 @@ public sealed class GameObjectHandler : DisposableMediatorSubscriberBase { base.Dispose(disposing); - if (_isOwnedObject) - Mediator.Publish(new RemoveWatchedGameObjectHandler(this)); + Mediator.Publish(new GameObjectHandlerDestroyedMessage(this, _isOwnedObject)); } private unsafe void CheckAndUpdateObject() diff --git a/MareSynchronos/Plugin.cs b/MareSynchronos/Plugin.cs index feafe3d..434776a 100644 --- a/MareSynchronos/Plugin.cs +++ b/MareSynchronos/Plugin.cs @@ -90,7 +90,8 @@ public sealed class Plugin : IDalamudPlugin collection.AddSingleton(); collection.AddSingleton((s) => new IpcProvider(s.GetRequiredService>(), pluginInterface, - s.GetRequiredService(), s.GetRequiredService())); + s.GetRequiredService(), s.GetRequiredService(), + s.GetRequiredService())); collection.AddSingleton(); collection.AddSingleton((s) => new EventAggregator(s.GetRequiredService(), s.GetRequiredService>(), s.GetRequiredService())); diff --git a/MareSynchronos/Services/Mediator/Messages.cs b/MareSynchronos/Services/Mediator/Messages.cs index 9add9af..4a7e0f1 100644 --- a/MareSynchronos/Services/Mediator/Messages.cs +++ b/MareSynchronos/Services/Mediator/Messages.cs @@ -47,8 +47,6 @@ public record HonorificReadyMessage : MessageBase; public record PlayerChangedMessage(CharacterData Data) : MessageBase; public record CharacterChangedMessage(GameObjectHandler GameObjectHandler) : MessageBase; public record TransientResourceChangedMessage(IntPtr Address) : MessageBase; -public record AddWatchedGameObjectHandler(GameObjectHandler Handler) : MessageBase; -public record RemoveWatchedGameObjectHandler(GameObjectHandler Handler) : MessageBase; public record HaltScanMessage(string Source) : MessageBase; public record ResumeScanMessage(string Source) : MessageBase; public record NotificationMessage @@ -98,5 +96,7 @@ public record HoldPairDownloadsMessage(string UID, string Source) : KeyedMessage public record UnholdPairDownloadsMessage(string UID, string Source) : KeyedMessage(UID); public record PairDataAppliedMessage(string UID, CharacterData? CharacterData) : KeyedMessage(UID); public record PairDataAnalyzedMessage(string UID) : KeyedMessage(UID); +public record GameObjectHandlerCreatedMessage(GameObjectHandler GameObjectHandler, bool OwnedObject) : MessageBase; +public record GameObjectHandlerDestroyedMessage(GameObjectHandler GameObjectHandler, bool OwnedObject) : MessageBase; #pragma warning restore S2094 #pragma warning restore MA0048 // File name must match type name \ No newline at end of file