diff --git a/MareSynchronos/Interop/Ipc/IpcProvider.cs b/MareSynchronos/Interop/Ipc/IpcProvider.cs new file mode 100644 index 0000000..94ffba8 --- /dev/null +++ b/MareSynchronos/Interop/Ipc/IpcProvider.cs @@ -0,0 +1,79 @@ +using Dalamud.Game.ClientState.Objects.Types; +using Dalamud.Plugin; +using Dalamud.Plugin.Ipc; +using MareSynchronos.PlayerData.Export; +using MareSynchronos.Services; +using Microsoft.Extensions.Hosting; +using Microsoft.Extensions.Logging; + +namespace MareSynchronos.Interop.Ipc; + +public class IpcProvider : IHostedService +{ + private readonly ILogger _logger; + private readonly IDalamudPluginInterface _pi; + private readonly MareCharaFileManager _mareCharaFileManager; + private readonly DalamudUtilService _dalamudUtil; + private ICallGateProvider? _loadFileProvider; + private ICallGateProvider>? _loadFileAsyncProvider; + + public IpcProvider(ILogger logger, IDalamudPluginInterface pi, + MareCharaFileManager mareCharaFileManager, DalamudUtilService dalamudUtil) + { + _logger = logger; + _pi = pi; + _mareCharaFileManager = mareCharaFileManager; + _dalamudUtil = dalamudUtil; + } + + public Task StartAsync(CancellationToken cancellationToken) + { + _logger.LogDebug("Starting IpcProvider Service"); + _loadFileProvider = _pi.GetIpcProvider("MareSynchronos.LoadMcdf"); + _loadFileProvider.RegisterFunc(LoadMcdf); + _loadFileAsyncProvider = _pi.GetIpcProvider>("MareSynchronos.LoadMcdfAsync"); + _loadFileAsyncProvider.RegisterFunc(LoadMcdfAsync); + return Task.CompletedTask; + } + + public Task StopAsync(CancellationToken cancellationToken) + { + _logger.LogDebug("Stopping IpcProvider Service"); + _loadFileProvider?.UnregisterFunc(); + _loadFileAsyncProvider?.UnregisterFunc(); + return Task.CompletedTask; + } + + private async Task LoadMcdfAsync(string path, IGameObject target) + { + if (_mareCharaFileManager.CurrentlyWorking || !_dalamudUtil.IsInGpose) + return false; + + await ApplyFileAsync(path, target).ConfigureAwait(false); + + return true; + } + + private bool LoadMcdf(string path, IGameObject target) + { + if (_mareCharaFileManager.CurrentlyWorking || !_dalamudUtil.IsInGpose) + return false; + + _ = Task.Run(async () => await ApplyFileAsync(path, target).ConfigureAwait(false)).ConfigureAwait(false); + + return true; + } + + private async Task ApplyFileAsync(string path, IGameObject target) + { + try + { + var expectedLength = _mareCharaFileManager.LoadMareCharaFile(path); + await _mareCharaFileManager.ApplyMareCharaFile(target, expectedLength).ConfigureAwait(false); + } + finally + { + _mareCharaFileManager.ClearMareCharaFile(); + } + } +} diff --git a/MareSynchronos/Plugin.cs b/MareSynchronos/Plugin.cs index 77d76b4..9edb8e5 100644 --- a/MareSynchronos/Plugin.cs +++ b/MareSynchronos/Plugin.cs @@ -88,6 +88,9 @@ public sealed class Plugin : IDalamudPlugin collection.AddSingleton(); collection.AddSingleton(); collection.AddSingleton(); + collection.AddSingleton((s) => new IpcProvider(s.GetRequiredService>(), + pluginInterface, + s.GetRequiredService(), s.GetRequiredService())); collection.AddSingleton(); collection.AddSingleton((s) => new EventAggregator(s.GetRequiredService(), s.GetRequiredService>(), s.GetRequiredService())); @@ -178,6 +181,7 @@ public sealed class Plugin : IDalamudPlugin collection.AddHostedService(p => p.GetRequiredService()); collection.AddHostedService(p => p.GetRequiredService()); collection.AddHostedService(p => p.GetRequiredService()); + collection.AddHostedService(p => p.GetRequiredService()); }) .Build();