From 7f0f122b756599806ce0df2fa228a7fba771d4be Mon Sep 17 00:00:00 2001 From: Stanley Dimant Date: Sun, 2 Jun 2024 01:17:53 +0200 Subject: [PATCH] fix c+ bullshit --- .../Interop/Ipc/IpcCallerCustomize.cs | 4 +- .../Interop/Ipc/IpcCallerGlamourer.cs | 332 +++++----- .../Interop/Ipc/IpcCallerPenumbra.cs | 612 +++++++++--------- 3 files changed, 474 insertions(+), 474 deletions(-) diff --git a/MareSynchronos/Interop/Ipc/IpcCallerCustomize.cs b/MareSynchronos/Interop/Ipc/IpcCallerCustomize.cs index a06ab5a..f6f92e9 100644 --- a/MareSynchronos/Interop/Ipc/IpcCallerCustomize.cs +++ b/MareSynchronos/Interop/Ipc/IpcCallerCustomize.cs @@ -52,7 +52,7 @@ public sealed class IpcCallerCustomize : IIpcCaller if (gameObj is Character c) { _logger.LogTrace("CustomizePlus reverting for {chara}", c.Address.ToString("X")); - _customizePlusRevertCharacter!.InvokeAction(c); + _customizePlusRevertCharacter!.InvokeFunc(c); } }).ConfigureAwait(false); } @@ -69,7 +69,7 @@ public sealed class IpcCallerCustomize : IIpcCaller _logger.LogTrace("CustomizePlus applying for {chara}", c.Address.ToString("X")); if (scale.IsNullOrEmpty()) { - _customizePlusRevertCharacter!.InvokeAction(c); + _customizePlusRevertCharacter!.InvokeFunc(c); return null; } else diff --git a/MareSynchronos/Interop/Ipc/IpcCallerGlamourer.cs b/MareSynchronos/Interop/Ipc/IpcCallerGlamourer.cs index 57c5a5d..85e6e8a 100644 --- a/MareSynchronos/Interop/Ipc/IpcCallerGlamourer.cs +++ b/MareSynchronos/Interop/Ipc/IpcCallerGlamourer.cs @@ -1,66 +1,66 @@ -using Dalamud.Game.ClientState.Objects.Types; -using Dalamud.Interface.Internal.Notifications; -using Dalamud.Plugin; -using Glamourer.Api.Helpers; -using Glamourer.Api.IpcSubscribers; -using MareSynchronos.PlayerData.Handlers; -using MareSynchronos.Services; -using MareSynchronos.Services.Mediator; -using Microsoft.Extensions.Logging; - -namespace MareSynchronos.Interop.Ipc; - -public sealed class IpcCallerGlamourer : IIpcCaller +using Dalamud.Game.ClientState.Objects.Types; +using Dalamud.Interface.Internal.Notifications; +using Dalamud.Plugin; +using Glamourer.Api.Helpers; +using Glamourer.Api.IpcSubscribers; +using MareSynchronos.PlayerData.Handlers; +using MareSynchronos.Services; +using MareSynchronos.Services.Mediator; +using Microsoft.Extensions.Logging; + +namespace MareSynchronos.Interop.Ipc; + +public sealed class IpcCallerGlamourer : IIpcCaller { - private readonly ILogger _logger; - private readonly DalamudPluginInterface _pi; - private readonly DalamudUtilService _dalamudUtil; - private readonly MareMediator _mareMediator; + private readonly ILogger _logger; + private readonly DalamudPluginInterface _pi; + private readonly DalamudUtilService _dalamudUtil; + private readonly MareMediator _mareMediator; private readonly RedrawManager _redrawManager; - - private readonly ApiVersion _glamourerApiVersions; - private readonly ApplyState? _glamourerApplyAll; - private readonly GetStateBase64? _glamourerGetAllCustomization; - private readonly RevertState _glamourerRevert; - private readonly RevertStateName _glamourerRevertByName; + + private readonly ApiVersion _glamourerApiVersions; + private readonly ApplyState? _glamourerApplyAll; + private readonly GetStateBase64? _glamourerGetAllCustomization; + private readonly RevertState _glamourerRevert; + private readonly RevertStateName _glamourerRevertByName; private readonly UnlockState _glamourerUnlock; private readonly UnlockStateName _glamourerUnlockByName; private readonly EventSubscriber? _glamourerStateChanged; - private bool _shownGlamourerUnavailable = false; + private bool _shownGlamourerUnavailable = false; private readonly uint LockCode = 0x6D617265; - - public IpcCallerGlamourer(ILogger logger, DalamudPluginInterface pi, DalamudUtilService dalamudUtil, MareMediator mareMediator, - RedrawManager redrawManager) - { - _glamourerApiVersions = new ApiVersion(pi); - _glamourerGetAllCustomization = new GetStateBase64(pi); - _glamourerApplyAll = new ApplyState(pi); - _glamourerRevert = new RevertState(pi); - _glamourerRevertByName = new RevertStateName(pi); - _glamourerUnlock = new UnlockState(pi); - _glamourerUnlockByName = new UnlockStateName(pi); - - _logger = logger; - _pi = pi; - _dalamudUtil = dalamudUtil; - _mareMediator = mareMediator; - _redrawManager = redrawManager; + + public IpcCallerGlamourer(ILogger logger, DalamudPluginInterface pi, DalamudUtilService dalamudUtil, MareMediator mareMediator, + RedrawManager redrawManager) + { + _glamourerApiVersions = new ApiVersion(pi); + _glamourerGetAllCustomization = new GetStateBase64(pi); + _glamourerApplyAll = new ApplyState(pi); + _glamourerRevert = new RevertState(pi); + _glamourerRevertByName = new RevertStateName(pi); + _glamourerUnlock = new UnlockState(pi); + _glamourerUnlockByName = new UnlockStateName(pi); + + _logger = logger; + _pi = pi; + _dalamudUtil = dalamudUtil; + _mareMediator = mareMediator; + _redrawManager = redrawManager; CheckAPI(); _glamourerStateChanged = StateChanged.Subscriber(pi, GlamourerChanged); _glamourerStateChanged.Enable(); - } - - public bool APIAvailable { get; private set; } - - public void CheckAPI() - { - bool apiAvailable = false; - try - { - bool versionValid = (_pi.InstalledPlugins - .FirstOrDefault(p => string.Equals(p.InternalName, "Glamourer", StringComparison.OrdinalIgnoreCase)) + } + + public bool APIAvailable { get; private set; } + + public void CheckAPI() + { + bool apiAvailable = false; + try + { + bool versionValid = (_pi.InstalledPlugins + .FirstOrDefault(p => string.Equals(p.InternalName, "Glamourer", StringComparison.OrdinalIgnoreCase)) ?.Version ?? new Version(0, 0, 0, 0)) >= new Version(1, 2, 3, 0); try { @@ -73,123 +73,123 @@ public sealed class IpcCallerGlamourer : IIpcCaller catch { // ignore - } - _shownGlamourerUnavailable = _shownGlamourerUnavailable && !apiAvailable; - - APIAvailable = apiAvailable; - } - catch - { - APIAvailable = apiAvailable; - } - finally - { - if (!apiAvailable && !_shownGlamourerUnavailable) - { - _shownGlamourerUnavailable = true; - _mareMediator.Publish(new NotificationMessage("Glamourer inactive", "Your Glamourer installation is not active or out of date. Update Glamourer to continue to use Mare. If you just updated Glamourer, ignore this message.", - NotificationType.Error)); - } - } - } - - public void Dispose() - { + } + _shownGlamourerUnavailable = _shownGlamourerUnavailable && !apiAvailable; + + APIAvailable = apiAvailable; + } + catch + { + APIAvailable = apiAvailable; + } + finally + { + if (!apiAvailable && !_shownGlamourerUnavailable) + { + _shownGlamourerUnavailable = true; + _mareMediator.Publish(new NotificationMessage("Glamourer inactive", "Your Glamourer installation is not active or out of date. Update Glamourer to continue to use Mare. If you just updated Glamourer, ignore this message.", + NotificationType.Error)); + } + } + } + + public void Dispose() + { _glamourerStateChanged?.Dispose(); - } - - public async Task ApplyAllAsync(ILogger logger, GameObjectHandler handler, string? customization, Guid applicationId, CancellationToken token, bool fireAndForget = false) - { - if (!APIAvailable || string.IsNullOrEmpty(customization) || _dalamudUtil.IsZoning) return; - - await _redrawManager.RedrawSemaphore.WaitAsync(token).ConfigureAwait(false); - - try - { - - await _redrawManager.PenumbraRedrawInternalAsync(logger, handler, applicationId, (chara) => - { - try - { + } + + public async Task ApplyAllAsync(ILogger logger, GameObjectHandler handler, string? customization, Guid applicationId, CancellationToken token, bool fireAndForget = false) + { + if (!APIAvailable || string.IsNullOrEmpty(customization) || _dalamudUtil.IsZoning) return; + + await _redrawManager.RedrawSemaphore.WaitAsync(token).ConfigureAwait(false); + + try + { + + await _redrawManager.PenumbraRedrawInternalAsync(logger, handler, applicationId, (chara) => + { + try + { logger.LogDebug("[{appid}] Calling on IPC: GlamourerApplyAll", applicationId); _glamourerApplyAll!.Invoke(customization, chara.ObjectIndex, LockCode); - } - catch (Exception ex) - { - logger.LogWarning(ex, "[{appid}] Failed to apply Glamourer data", applicationId); - } - }).ConfigureAwait(false); - } - finally - { - _redrawManager.RedrawSemaphore.Release(); - } - } - - public async Task GetCharacterCustomizationAsync(IntPtr character) - { - if (!APIAvailable) return string.Empty; - try - { - return await _dalamudUtil.RunOnFrameworkThread(() => - { - var gameObj = _dalamudUtil.CreateGameObject(character); - if (gameObj is Character c) + } + catch (Exception ex) { - return _glamourerGetAllCustomization!.Invoke(c.ObjectIndex).Item2 ?? string.Empty; - } - return string.Empty; - }).ConfigureAwait(false); - } - catch - { - return string.Empty; - } - } - - public async Task RevertAsync(ILogger logger, string name, GameObjectHandler handler, Guid applicationId, CancellationToken token) - { - if ((!APIAvailable) || _dalamudUtil.IsZoning) return; - try - { - await _redrawManager.RedrawSemaphore.WaitAsync(token).ConfigureAwait(false); - await _redrawManager.PenumbraRedrawInternalAsync(logger, handler, applicationId, (chara) => - { - try + logger.LogWarning(ex, "[{appid}] Failed to apply Glamourer data", applicationId); + } + }).ConfigureAwait(false); + } + finally + { + _redrawManager.RedrawSemaphore.Release(); + } + } + + public async Task GetCharacterCustomizationAsync(IntPtr character) + { + if (!APIAvailable) return string.Empty; + try + { + return await _dalamudUtil.RunOnFrameworkThread(() => + { + var gameObj = _dalamudUtil.CreateGameObject(character); + if (gameObj is Character c) + { + return _glamourerGetAllCustomization!.Invoke(c.ObjectIndex).Item2 ?? string.Empty; + } + return string.Empty; + }).ConfigureAwait(false); + } + catch + { + return string.Empty; + } + } + + public async Task RevertAsync(ILogger logger, string name, GameObjectHandler handler, Guid applicationId, CancellationToken token) + { + if ((!APIAvailable) || _dalamudUtil.IsZoning) return; + try + { + await _redrawManager.RedrawSemaphore.WaitAsync(token).ConfigureAwait(false); + await _redrawManager.PenumbraRedrawInternalAsync(logger, handler, applicationId, (chara) => + { + try { logger.LogDebug("[{appid}] Calling On IPC: GlamourerUnlockName", applicationId); _glamourerUnlock.Invoke(chara.ObjectIndex, LockCode); logger.LogDebug("[{appid}] Calling On IPC: GlamourerRevert", applicationId); _glamourerRevert.Invoke(chara.ObjectIndex, LockCode); logger.LogDebug("[{appid}] Calling On IPC: PenumbraRedraw", applicationId); - - _mareMediator.Publish(new PenumbraRedrawCharacterMessage(chara)); - } - catch (Exception ex) - { - logger.LogWarning(ex, "[{appid}] Error during GlamourerRevert", applicationId); - } - }).ConfigureAwait(false); - } - finally - { - _redrawManager.RedrawSemaphore.Release(); - } - } - - public async Task RevertByNameAsync(ILogger logger, string name, Guid applicationId) - { - if ((!APIAvailable) || _dalamudUtil.IsZoning) return; - - await _dalamudUtil.RunOnFrameworkThread(() => + + _mareMediator.Publish(new PenumbraRedrawCharacterMessage(chara)); + } + catch (Exception ex) + { + logger.LogWarning(ex, "[{appid}] Error during GlamourerRevert", applicationId); + } + }).ConfigureAwait(false); + } + finally { - RevertByName(logger, name, applicationId); - - }).ConfigureAwait(false); - } - - public void RevertByName(ILogger logger, string name, Guid applicationId) - { + _redrawManager.RedrawSemaphore.Release(); + } + } + + public async Task RevertByNameAsync(ILogger logger, string name, Guid applicationId) + { + if ((!APIAvailable) || _dalamudUtil.IsZoning) return; + + await _dalamudUtil.RunOnFrameworkThread(() => + { + RevertByName(logger, name, applicationId); + + }).ConfigureAwait(false); + } + + public void RevertByName(ILogger logger, string name, Guid applicationId) + { if ((!APIAvailable) || _dalamudUtil.IsZoning) return; try @@ -202,11 +202,11 @@ public sealed class IpcCallerGlamourer : IIpcCaller catch (Exception ex) { _logger.LogWarning(ex, "Error during Glamourer RevertByName"); - } - } - - private void GlamourerChanged(nint address) - { - _mareMediator.Publish(new GlamourerChangedMessage(address)); - } -} + } + } + + private void GlamourerChanged(nint address) + { + _mareMediator.Publish(new GlamourerChangedMessage(address)); + } +} diff --git a/MareSynchronos/Interop/Ipc/IpcCallerPenumbra.cs b/MareSynchronos/Interop/Ipc/IpcCallerPenumbra.cs index 60890eb..a47badb 100644 --- a/MareSynchronos/Interop/Ipc/IpcCallerPenumbra.cs +++ b/MareSynchronos/Interop/Ipc/IpcCallerPenumbra.cs @@ -1,36 +1,36 @@ -using Dalamud.Interface.Internal.Notifications; -using Dalamud.Plugin; -using MareSynchronos.PlayerData.Handlers; -using MareSynchronos.Services; -using MareSynchronos.Services.Mediator; -using Microsoft.Extensions.Logging; -using Penumbra.Api.Enums; -using Penumbra.Api.Helpers; -using Penumbra.Api.IpcSubscribers; -using System.Collections.Concurrent; - -namespace MareSynchronos.Interop.Ipc; - -public sealed class IpcCallerPenumbra : DisposableMediatorSubscriberBase, IIpcCaller -{ - private readonly DalamudPluginInterface _pi; - private readonly DalamudUtilService _dalamudUtil; - private readonly MareMediator _mareMediator; - private readonly RedrawManager _redrawManager; +using Dalamud.Interface.Internal.Notifications; +using Dalamud.Plugin; +using MareSynchronos.PlayerData.Handlers; +using MareSynchronos.Services; +using MareSynchronos.Services.Mediator; +using Microsoft.Extensions.Logging; +using Penumbra.Api.Enums; +using Penumbra.Api.Helpers; +using Penumbra.Api.IpcSubscribers; +using System.Collections.Concurrent; + +namespace MareSynchronos.Interop.Ipc; + +public sealed class IpcCallerPenumbra : DisposableMediatorSubscriberBase, IIpcCaller +{ + private readonly DalamudPluginInterface _pi; + private readonly DalamudUtilService _dalamudUtil; + private readonly MareMediator _mareMediator; + private readonly RedrawManager _redrawManager; private bool _shownPenumbraUnavailable = false; - private string? _penumbraModDirectory; - public string? ModDirectory - { - get => _penumbraModDirectory; - private set - { - if (!string.Equals(_penumbraModDirectory, value, StringComparison.Ordinal)) - { - _penumbraModDirectory = value; - _mareMediator.Publish(new PenumbraDirectoryChangedMessage(_penumbraModDirectory)); - } - } - } + private string? _penumbraModDirectory; + public string? ModDirectory + { + get => _penumbraModDirectory; + private set + { + if (!string.Equals(_penumbraModDirectory, value, StringComparison.Ordinal)) + { + _penumbraModDirectory = value; + _mareMediator.Publish(new PenumbraDirectoryChangedMessage(_penumbraModDirectory)); + } + } + } private readonly ConcurrentDictionary _penumbraRedrawRequests = new(); @@ -39,296 +39,296 @@ public sealed class IpcCallerPenumbra : DisposableMediatorSubscriberBase, IIpcCa private readonly EventSubscriber _penumbraInit; private readonly EventSubscriber _penumbraModSettingChanged; private readonly EventSubscriber _penumbraObjectIsRedrawn; - - private readonly AddTemporaryMod _penumbraAddTemporaryMod; - private readonly AssignTemporaryCollection _penumbraAssignTemporaryCollection; - private readonly ConvertTextureFile _penumbraConvertTextureFile; - private readonly CreateTemporaryCollection _penumbraCreateNamedTemporaryCollection; - private readonly GetEnabledState _penumbraEnabled; - private readonly GetPlayerMetaManipulations _penumbraGetMetaManipulations; - private readonly RedrawObject _penumbraRedraw; - private readonly DeleteTemporaryCollection _penumbraRemoveTemporaryCollection; - private readonly RemoveTemporaryMod _penumbraRemoveTemporaryMod; - private readonly GetModDirectory _penumbraResolveModDir; - private readonly ResolvePlayerPathsAsync _penumbraResolvePaths; + + private readonly AddTemporaryMod _penumbraAddTemporaryMod; + private readonly AssignTemporaryCollection _penumbraAssignTemporaryCollection; + private readonly ConvertTextureFile _penumbraConvertTextureFile; + private readonly CreateTemporaryCollection _penumbraCreateNamedTemporaryCollection; + private readonly GetEnabledState _penumbraEnabled; + private readonly GetPlayerMetaManipulations _penumbraGetMetaManipulations; + private readonly RedrawObject _penumbraRedraw; + private readonly DeleteTemporaryCollection _penumbraRemoveTemporaryCollection; + private readonly RemoveTemporaryMod _penumbraRemoveTemporaryMod; + private readonly GetModDirectory _penumbraResolveModDir; + private readonly ResolvePlayerPathsAsync _penumbraResolvePaths; private readonly GetGameObjectResourcePaths _penumbraResourcePaths; - - public IpcCallerPenumbra(ILogger logger, DalamudPluginInterface pi, DalamudUtilService dalamudUtil, - MareMediator mareMediator, RedrawManager redrawManager) : base(logger, mareMediator) - { - _pi = pi; - _dalamudUtil = dalamudUtil; - _mareMediator = mareMediator; - _redrawManager = redrawManager; - _penumbraInit = Initialized.Subscriber(pi, PenumbraInit); - _penumbraDispose = Disposed.Subscriber(pi, PenumbraDispose); - _penumbraResolveModDir = new GetModDirectory(pi); - _penumbraRedraw = new RedrawObject(pi); - _penumbraObjectIsRedrawn = GameObjectRedrawn.Subscriber(pi, RedrawEvent); - _penumbraGetMetaManipulations = new GetPlayerMetaManipulations(pi); - _penumbraRemoveTemporaryMod = new RemoveTemporaryMod(pi); - _penumbraAddTemporaryMod = new AddTemporaryMod(pi); - _penumbraCreateNamedTemporaryCollection = new CreateTemporaryCollection(pi); - _penumbraRemoveTemporaryCollection = new DeleteTemporaryCollection(pi); - _penumbraAssignTemporaryCollection = new AssignTemporaryCollection(pi); - _penumbraResolvePaths = new ResolvePlayerPathsAsync(pi); - _penumbraEnabled = new GetEnabledState(pi); - _penumbraModSettingChanged = ModSettingChanged.Subscriber(pi, (change, arg1, arg, b) => - { - if (change == ModSettingChange.EnableState) - _mareMediator.Publish(new PenumbraModSettingChangedMessage()); - }); - _penumbraConvertTextureFile = new ConvertTextureFile(pi); + + public IpcCallerPenumbra(ILogger logger, DalamudPluginInterface pi, DalamudUtilService dalamudUtil, + MareMediator mareMediator, RedrawManager redrawManager) : base(logger, mareMediator) + { + _pi = pi; + _dalamudUtil = dalamudUtil; + _mareMediator = mareMediator; + _redrawManager = redrawManager; + _penumbraInit = Initialized.Subscriber(pi, PenumbraInit); + _penumbraDispose = Disposed.Subscriber(pi, PenumbraDispose); + _penumbraResolveModDir = new GetModDirectory(pi); + _penumbraRedraw = new RedrawObject(pi); + _penumbraObjectIsRedrawn = GameObjectRedrawn.Subscriber(pi, RedrawEvent); + _penumbraGetMetaManipulations = new GetPlayerMetaManipulations(pi); + _penumbraRemoveTemporaryMod = new RemoveTemporaryMod(pi); + _penumbraAddTemporaryMod = new AddTemporaryMod(pi); + _penumbraCreateNamedTemporaryCollection = new CreateTemporaryCollection(pi); + _penumbraRemoveTemporaryCollection = new DeleteTemporaryCollection(pi); + _penumbraAssignTemporaryCollection = new AssignTemporaryCollection(pi); + _penumbraResolvePaths = new ResolvePlayerPathsAsync(pi); + _penumbraEnabled = new GetEnabledState(pi); + _penumbraModSettingChanged = ModSettingChanged.Subscriber(pi, (change, arg1, arg, b) => + { + if (change == ModSettingChange.EnableState) + _mareMediator.Publish(new PenumbraModSettingChangedMessage()); + }); + _penumbraConvertTextureFile = new ConvertTextureFile(pi); _penumbraResourcePaths = new GetGameObjectResourcePaths(pi); - - _penumbraGameObjectResourcePathResolved = GameObjectResourcePathResolved.Subscriber(pi, ResourceLoaded); - - CheckAPI(); - CheckModDirectory(); - + + _penumbraGameObjectResourcePathResolved = GameObjectResourcePathResolved.Subscriber(pi, ResourceLoaded); + + CheckAPI(); + CheckModDirectory(); + Mediator.Subscribe(this, (msg) => { _penumbraRedraw.Invoke(msg.Character.ObjectIndex, RedrawType.AfterGPose); - }); - } - - public bool APIAvailable { get; private set; } = false; - - public void CheckAPI() - { - bool penumbraAvailable = false; - try + }); + } + + public bool APIAvailable { get; private set; } = false; + + public void CheckAPI() + { + bool penumbraAvailable = false; + try { - var penumbraVersion = (_pi.InstalledPlugins - .FirstOrDefault(p => string.Equals(p.InternalName, "Penumbra", StringComparison.OrdinalIgnoreCase)) - ?.Version ?? new Version(0, 0, 0, 0)); + var penumbraVersion = (_pi.InstalledPlugins + .FirstOrDefault(p => string.Equals(p.InternalName, "Penumbra", StringComparison.OrdinalIgnoreCase)) + ?.Version ?? new Version(0, 0, 0, 0)); penumbraAvailable = penumbraVersion >= new Version(1, 1, 0, 0); - penumbraAvailable &= _penumbraEnabled.Invoke(); - _shownPenumbraUnavailable = _shownPenumbraUnavailable && !penumbraAvailable; - APIAvailable = penumbraAvailable; - } - catch - { - APIAvailable = penumbraAvailable; - } - finally - { - if (!penumbraAvailable && !_shownPenumbraUnavailable) - { - _shownPenumbraUnavailable = true; - _mareMediator.Publish(new NotificationMessage("Penumbra inactive", - "Your Penumbra installation is not active or out of date. Update Penumbra and/or the Enable Mods setting in Penumbra to continue to use Mare. If you just updated Penumbra, ignore this message.", - NotificationType.Error)); - } - } - } - - public void CheckModDirectory() - { - if (!APIAvailable) - { - ModDirectory = string.Empty; - } - else - { - ModDirectory = _penumbraResolveModDir!.Invoke().ToLowerInvariant(); - } - } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - - _redrawManager.Cancel(); - - _penumbraModSettingChanged.Dispose(); - _penumbraGameObjectResourcePathResolved.Dispose(); - _penumbraDispose.Dispose(); - _penumbraInit.Dispose(); - _penumbraObjectIsRedrawn.Dispose(); - } - - public async Task AssignTemporaryCollectionAsync(ILogger logger, Guid collName, int idx) - { - if (!APIAvailable) return; - - await _dalamudUtil.RunOnFrameworkThread(() => - { - var retAssign = _penumbraAssignTemporaryCollection.Invoke(collName, idx, forceAssignment: true); - logger.LogTrace("Assigning Temp Collection {collName} to index {idx}, Success: {ret}", collName, idx, retAssign); - return collName; - }).ConfigureAwait(false); - } - - public async Task ConvertTextureFiles(ILogger logger, Dictionary textures, IProgress<(string, int)> progress, CancellationToken token) - { - if (!APIAvailable) return; - - _mareMediator.Publish(new HaltScanMessage(nameof(ConvertTextureFiles))); - int currentTexture = 0; - foreach (var texture in textures) - { - if (token.IsCancellationRequested) break; - - progress.Report((texture.Key, ++currentTexture)); - - logger.LogInformation("Converting Texture {path} to {type}", texture.Key, TextureType.Bc7Tex); - var convertTask = _penumbraConvertTextureFile.Invoke(texture.Key, texture.Key, TextureType.Bc7Tex, mipMaps: true); - await convertTask.ConfigureAwait(false); - if (convertTask.IsCompletedSuccessfully && texture.Value.Any()) - { - foreach (var duplicatedTexture in texture.Value) - { - logger.LogInformation("Migrating duplicate {dup}", duplicatedTexture); - try - { - File.Copy(texture.Key, duplicatedTexture, overwrite: true); - } - catch (Exception ex) - { - logger.LogError(ex, "Failed to copy duplicate {dup}", duplicatedTexture); - } - } - } - } - _mareMediator.Publish(new ResumeScanMessage(nameof(ConvertTextureFiles))); - - await _dalamudUtil.RunOnFrameworkThread(async () => - { + penumbraAvailable &= _penumbraEnabled.Invoke(); + _shownPenumbraUnavailable = _shownPenumbraUnavailable && !penumbraAvailable; + APIAvailable = penumbraAvailable; + } + catch + { + APIAvailable = penumbraAvailable; + } + finally + { + if (!penumbraAvailable && !_shownPenumbraUnavailable) + { + _shownPenumbraUnavailable = true; + _mareMediator.Publish(new NotificationMessage("Penumbra inactive", + "Your Penumbra installation is not active or out of date. Update Penumbra and/or the Enable Mods setting in Penumbra to continue to use Mare. If you just updated Penumbra, ignore this message.", + NotificationType.Error)); + } + } + } + + public void CheckModDirectory() + { + if (!APIAvailable) + { + ModDirectory = string.Empty; + } + else + { + ModDirectory = _penumbraResolveModDir!.Invoke().ToLowerInvariant(); + } + } + + protected override void Dispose(bool disposing) + { + base.Dispose(disposing); + + _redrawManager.Cancel(); + + _penumbraModSettingChanged.Dispose(); + _penumbraGameObjectResourcePathResolved.Dispose(); + _penumbraDispose.Dispose(); + _penumbraInit.Dispose(); + _penumbraObjectIsRedrawn.Dispose(); + } + + public async Task AssignTemporaryCollectionAsync(ILogger logger, Guid collName, int idx) + { + if (!APIAvailable) return; + + await _dalamudUtil.RunOnFrameworkThread(() => + { + var retAssign = _penumbraAssignTemporaryCollection.Invoke(collName, idx, forceAssignment: true); + logger.LogTrace("Assigning Temp Collection {collName} to index {idx}, Success: {ret}", collName, idx, retAssign); + return collName; + }).ConfigureAwait(false); + } + + public async Task ConvertTextureFiles(ILogger logger, Dictionary textures, IProgress<(string, int)> progress, CancellationToken token) + { + if (!APIAvailable) return; + + _mareMediator.Publish(new HaltScanMessage(nameof(ConvertTextureFiles))); + int currentTexture = 0; + foreach (var texture in textures) + { + if (token.IsCancellationRequested) break; + + progress.Report((texture.Key, ++currentTexture)); + + logger.LogInformation("Converting Texture {path} to {type}", texture.Key, TextureType.Bc7Tex); + var convertTask = _penumbraConvertTextureFile.Invoke(texture.Key, texture.Key, TextureType.Bc7Tex, mipMaps: true); + await convertTask.ConfigureAwait(false); + if (convertTask.IsCompletedSuccessfully && texture.Value.Any()) + { + foreach (var duplicatedTexture in texture.Value) + { + logger.LogInformation("Migrating duplicate {dup}", duplicatedTexture); + try + { + File.Copy(texture.Key, duplicatedTexture, overwrite: true); + } + catch (Exception ex) + { + logger.LogError(ex, "Failed to copy duplicate {dup}", duplicatedTexture); + } + } + } + } + _mareMediator.Publish(new ResumeScanMessage(nameof(ConvertTextureFiles))); + + await _dalamudUtil.RunOnFrameworkThread(async () => + { var gameObject = await _dalamudUtil.CreateGameObjectAsync(await _dalamudUtil.GetPlayerPointerAsync().ConfigureAwait(false)).ConfigureAwait(false); - _penumbraRedraw.Invoke(gameObject!.ObjectIndex, setting: RedrawType.Redraw); - }).ConfigureAwait(false); - } - - public async Task CreateTemporaryCollectionAsync(ILogger logger, string uid) - { - if (!APIAvailable) return Guid.Empty; - - return await _dalamudUtil.RunOnFrameworkThread(() => + _penumbraRedraw.Invoke(gameObject!.ObjectIndex, setting: RedrawType.Redraw); + }).ConfigureAwait(false); + } + + public async Task CreateTemporaryCollectionAsync(ILogger logger, string uid) + { + if (!APIAvailable) return Guid.Empty; + + return await _dalamudUtil.RunOnFrameworkThread(() => { var collName = "Mare_" + uid; var collId = _penumbraCreateNamedTemporaryCollection.Invoke(collName); logger.LogTrace("Creating Temp Collection {collName}, GUID: {collId}", collName, collId); return collId; - - }).ConfigureAwait(false); - } - - public async Task>?> GetCharacterData(ILogger logger, GameObjectHandler handler) - { - if (!APIAvailable) return null; - - return await _dalamudUtil.RunOnFrameworkThread(() => - { - logger.LogTrace("Calling On IPC: Penumbra.GetGameObjectResourcePaths"); - var idx = handler.GetGameObject()?.ObjectIndex; + + }).ConfigureAwait(false); + } + + public async Task>?> GetCharacterData(ILogger logger, GameObjectHandler handler) + { + if (!APIAvailable) return null; + + return await _dalamudUtil.RunOnFrameworkThread(() => + { + logger.LogTrace("Calling On IPC: Penumbra.GetGameObjectResourcePaths"); + var idx = handler.GetGameObject()?.ObjectIndex; if (idx == null) return null; return _penumbraResourcePaths.Invoke(idx.Value)[0]; - }).ConfigureAwait(false); - } - - public string GetMetaManipulations() - { - if (!APIAvailable) return string.Empty; - return _penumbraGetMetaManipulations.Invoke(); - } - - public async Task RedrawAsync(ILogger logger, GameObjectHandler handler, Guid applicationId, CancellationToken token) - { - if (!APIAvailable || _dalamudUtil.IsZoning) return; - try - { - await _redrawManager.RedrawSemaphore.WaitAsync(token).ConfigureAwait(false); - await _redrawManager.PenumbraRedrawInternalAsync(logger, handler, applicationId, (chara) => - { + }).ConfigureAwait(false); + } + + public string GetMetaManipulations() + { + if (!APIAvailable) return string.Empty; + return _penumbraGetMetaManipulations.Invoke(); + } + + public async Task RedrawAsync(ILogger logger, GameObjectHandler handler, Guid applicationId, CancellationToken token) + { + if (!APIAvailable || _dalamudUtil.IsZoning) return; + try + { + await _redrawManager.RedrawSemaphore.WaitAsync(token).ConfigureAwait(false); + await _redrawManager.PenumbraRedrawInternalAsync(logger, handler, applicationId, (chara) => + { logger.LogDebug("[{appid}] Calling on IPC: PenumbraRedraw", applicationId); _penumbraRedraw!.Invoke(chara.ObjectIndex, setting: RedrawType.Redraw); - - }).ConfigureAwait(false); - } - finally - { - _redrawManager.RedrawSemaphore.Release(); - } - } - - public async Task RemoveTemporaryCollectionAsync(ILogger logger, Guid applicationId, Guid collId) - { - if (!APIAvailable) return; - await _dalamudUtil.RunOnFrameworkThread(() => - { - logger.LogTrace("[{applicationId}] Removing temp collection for {collId}", applicationId, collId); - var ret2 = _penumbraRemoveTemporaryCollection.Invoke(collId); - logger.LogTrace("[{applicationId}] RemoveTemporaryCollection: {ret2}", applicationId, ret2); - }).ConfigureAwait(false); - } - - public async Task<(string[] forward, string[][] reverse)> ResolvePathsAsync(string[] forward, string[] reverse) - { - return await _penumbraResolvePaths.Invoke(forward, reverse).ConfigureAwait(false); - } - - public async Task SetManipulationDataAsync(ILogger logger, Guid applicationId, Guid collId, string manipulationData) - { - if (!APIAvailable) return; - - await _dalamudUtil.RunOnFrameworkThread(() => - { - logger.LogTrace("[{applicationId}] Manip: {data}", applicationId, manipulationData); - var retAdd = _penumbraAddTemporaryMod.Invoke("MareChara_Meta", collId, [], manipulationData, 0); - logger.LogTrace("[{applicationId}] Setting temp meta mod for {collId}, Success: {ret}", applicationId, collId, retAdd); - }).ConfigureAwait(false); - } - - public async Task SetTemporaryModsAsync(ILogger logger, Guid applicationId, Guid collId, Dictionary modPaths) - { - if (!APIAvailable) return; - - await _dalamudUtil.RunOnFrameworkThread(() => - { - foreach (var mod in modPaths) - { - logger.LogTrace("[{applicationId}] Change: {from} => {to}", applicationId, mod.Key, mod.Value); - } - var retRemove = _penumbraRemoveTemporaryMod.Invoke("MareChara_Files", collId, 0); - logger.LogTrace("[{applicationId}] Removing temp files mod for {collId}, Success: {ret}", applicationId, collId, retRemove); - var retAdd = _penumbraAddTemporaryMod.Invoke("MareChara_Files", collId, modPaths, string.Empty, 0); - logger.LogTrace("[{applicationId}] Setting temp files mod for {collId}, Success: {ret}", applicationId, collId, retAdd); - }).ConfigureAwait(false); - } - - private void RedrawEvent(IntPtr objectAddress, int objectTableIndex) - { - bool wasRequested = false; - if (_penumbraRedrawRequests.TryGetValue(objectAddress, out var redrawRequest) && redrawRequest) - { - _penumbraRedrawRequests[objectAddress] = false; - } - else - { - _mareMediator.Publish(new PenumbraRedrawMessage(objectAddress, objectTableIndex, wasRequested)); - } - } - - private void ResourceLoaded(IntPtr ptr, string arg1, string arg2) - { - if (ptr != IntPtr.Zero && string.Compare(arg1, arg2, ignoreCase: true, System.Globalization.CultureInfo.InvariantCulture) != 0) - { - _mareMediator.Publish(new PenumbraResourceLoadMessage(ptr, arg1, arg2)); - } - } - - private void PenumbraDispose() - { - _redrawManager.Cancel(); - _mareMediator.Publish(new PenumbraDisposedMessage()); - } - - private void PenumbraInit() - { - APIAvailable = true; - ModDirectory = _penumbraResolveModDir.Invoke(); + + }).ConfigureAwait(false); + } + finally + { + _redrawManager.RedrawSemaphore.Release(); + } + } + + public async Task RemoveTemporaryCollectionAsync(ILogger logger, Guid applicationId, Guid collId) + { + if (!APIAvailable) return; + await _dalamudUtil.RunOnFrameworkThread(() => + { + logger.LogTrace("[{applicationId}] Removing temp collection for {collId}", applicationId, collId); + var ret2 = _penumbraRemoveTemporaryCollection.Invoke(collId); + logger.LogTrace("[{applicationId}] RemoveTemporaryCollection: {ret2}", applicationId, ret2); + }).ConfigureAwait(false); + } + + public async Task<(string[] forward, string[][] reverse)> ResolvePathsAsync(string[] forward, string[] reverse) + { + return await _penumbraResolvePaths.Invoke(forward, reverse).ConfigureAwait(false); + } + + public async Task SetManipulationDataAsync(ILogger logger, Guid applicationId, Guid collId, string manipulationData) + { + if (!APIAvailable) return; + + await _dalamudUtil.RunOnFrameworkThread(() => + { + logger.LogTrace("[{applicationId}] Manip: {data}", applicationId, manipulationData); + var retAdd = _penumbraAddTemporaryMod.Invoke("MareChara_Meta", collId, [], manipulationData, 0); + logger.LogTrace("[{applicationId}] Setting temp meta mod for {collId}, Success: {ret}", applicationId, collId, retAdd); + }).ConfigureAwait(false); + } + + public async Task SetTemporaryModsAsync(ILogger logger, Guid applicationId, Guid collId, Dictionary modPaths) + { + if (!APIAvailable) return; + + await _dalamudUtil.RunOnFrameworkThread(() => + { + foreach (var mod in modPaths) + { + logger.LogTrace("[{applicationId}] Change: {from} => {to}", applicationId, mod.Key, mod.Value); + } + var retRemove = _penumbraRemoveTemporaryMod.Invoke("MareChara_Files", collId, 0); + logger.LogTrace("[{applicationId}] Removing temp files mod for {collId}, Success: {ret}", applicationId, collId, retRemove); + var retAdd = _penumbraAddTemporaryMod.Invoke("MareChara_Files", collId, modPaths, string.Empty, 0); + logger.LogTrace("[{applicationId}] Setting temp files mod for {collId}, Success: {ret}", applicationId, collId, retAdd); + }).ConfigureAwait(false); + } + + private void RedrawEvent(IntPtr objectAddress, int objectTableIndex) + { + bool wasRequested = false; + if (_penumbraRedrawRequests.TryGetValue(objectAddress, out var redrawRequest) && redrawRequest) + { + _penumbraRedrawRequests[objectAddress] = false; + } + else + { + _mareMediator.Publish(new PenumbraRedrawMessage(objectAddress, objectTableIndex, wasRequested)); + } + } + + private void ResourceLoaded(IntPtr ptr, string arg1, string arg2) + { + if (ptr != IntPtr.Zero && string.Compare(arg1, arg2, ignoreCase: true, System.Globalization.CultureInfo.InvariantCulture) != 0) + { + _mareMediator.Publish(new PenumbraResourceLoadMessage(ptr, arg1, arg2)); + } + } + + private void PenumbraDispose() + { + _redrawManager.Cancel(); + _mareMediator.Publish(new PenumbraDisposedMessage()); + } + + private void PenumbraInit() + { + APIAvailable = true; + ModDirectory = _penumbraResolveModDir.Invoke(); _mareMediator.Publish(new PenumbraInitializedMessage()); _penumbraRedraw!.Invoke(0, setting: RedrawType.Redraw); - } -} + } +}