diff --git a/MareSynchronos/Interop/IpcManager.cs b/MareSynchronos/Interop/IpcManager.cs index a134c5e..a28d6b7 100644 --- a/MareSynchronos/Interop/IpcManager.cs +++ b/MareSynchronos/Interop/IpcManager.cs @@ -141,96 +141,14 @@ public sealed class IpcManager : DisposableMediatorSubscriberBase public bool CheckCustomizePlusApi() => _customizePlusAvailable; - private bool CheckCustomizePlusApiInternal() - { - try - { - return string.Equals(_customizePlusApiVersion.InvokeFunc(), "1.0", StringComparison.Ordinal); - } - catch - { - return false; - } - } - public bool CheckGlamourerApi() => _glamourerAvailable; - private bool CheckGlamourerApiInternal() - { - bool apiAvailable = false; - try - { - apiAvailable = _glamourerApiVersion.InvokeFunc() >= 0; - _shownGlamourerUnavailable = _shownGlamourerUnavailable && !apiAvailable; - return apiAvailable; - } - catch - { - return apiAvailable; - } - finally - { - if (!apiAvailable && !_shownGlamourerUnavailable) - { - _shownGlamourerUnavailable = true; - Mediator.Publish(new NotificationMessage("Glamourer inactive", "Your Glamourer installation is not active or out of date. Update Glamourer to continue to use Mare.", NotificationType.Error)); - } - } - } - public bool CheckHeelsApi() => _heelsAvailable; - private bool CheckHeelsApiInternal() - { - try - { - return string.Equals(_heelsGetApiVersion.InvokeFunc(), "1.0.1", StringComparison.Ordinal); - } - catch - { - return false; - } - } - public bool CheckPalettePlusApi() => _palettePlusAvailable; - private bool CheckPalettePlusApiInternal() - { - try - { - return string.Equals(_palettePlusApiVersion.InvokeFunc(), "1.1.0", StringComparison.Ordinal); - } - catch - { - return false; - } - } - public bool CheckPenumbraApi() => _penumbraAvailable; - private bool CheckPenumbraApiInternal() - { - bool apiAvailable = false; - try - { - apiAvailable = _penumbraApiVersion.Invoke() is { Item1: 4, Item2: >= 19 } && _penumbraEnabled.Invoke(); - _shownPenumbraUnavailable = _shownPenumbraUnavailable && !apiAvailable; - return apiAvailable; - } - catch - { - return apiAvailable; - } - finally - { - if (!apiAvailable && !_shownPenumbraUnavailable) - { - _shownPenumbraUnavailable = true; - Mediator.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.", NotificationType.Error)); - } - } - } - public async Task CustomizePlusRevert(IntPtr character) { if (!CheckCustomizePlusApi()) return; @@ -274,12 +192,6 @@ public sealed class IpcManager : DisposableMediatorSubscriberBase return _heelsGetOffset.InvokeFunc(); } - private string? GetPenumbraModDirectoryInternal() - { - if (!CheckPenumbraApi()) return null; - return _penumbraResolveModDir!.Invoke().ToLowerInvariant(); - } - public async Task GlamourerApplyAll(ILogger logger, GameObjectHandler handler, string? customization, Guid applicationId, CancellationToken token, bool fireAndForget = false) { if (!CheckGlamourerApi() || string.IsNullOrEmpty(customization) || _dalamudUtil.IsZoning) return; @@ -423,38 +335,44 @@ public sealed class IpcManager : DisposableMediatorSubscriberBase } } - public void PenumbraRemoveTemporaryCollection(ILogger logger, Guid applicationId, string characterName) + public async Task PenumbraRemoveTemporaryCollection(ILogger logger, Guid applicationId, string characterName) { if (!CheckPenumbraApi()) return; - var collName = "Mare_" + characterName; - logger.LogTrace("[{applicationId}] Removing temp collection for {collName}", applicationId, collName); - var ret = _penumbraRemoveTemporaryMod.Invoke("MareChara", collName, 0); - logger.LogTrace("[{applicationId}] RemoveTemporaryMod: {ret}", applicationId, ret); - var ret2 = _penumbraRemoveTemporaryCollection.Invoke(collName); - logger.LogTrace("[{applicationId}] RemoveTemporaryCollection: {ret2}", applicationId, ret2); + await _dalamudUtil.RunOnFrameworkThread(() => + { + var collName = "Mare_" + characterName; + logger.LogTrace("[{applicationId}] Removing temp collection for {collName}", applicationId, collName); + var ret = _penumbraRemoveTemporaryMod.Invoke("MareChara", collName, 0); + logger.LogTrace("[{applicationId}] RemoveTemporaryMod: {ret}", applicationId, ret); + var ret2 = _penumbraRemoveTemporaryCollection.Invoke(collName); + logger.LogTrace("[{applicationId}] RemoveTemporaryCollection: {ret2}", applicationId, ret2); + }).ConfigureAwait(false); } public async Task<(string[] forward, string[][] reverse)> PenumbraResolvePaths(string[] forward, string[] reverse) { - return await _dalamudUtil.RunOnFrameworkThread(() => _penumbraResolvePaths.Invoke(forward, reverse)); + return await _dalamudUtil.RunOnFrameworkThread(() => _penumbraResolvePaths.Invoke(forward, reverse)).ConfigureAwait(false); } - public void PenumbraSetTemporaryMods(ILogger logger, Guid applicationId, string characterName, int? idx, Dictionary modPaths, string manipulationData) + public async Task PenumbraSetTemporaryMods(ILogger logger, Guid applicationId, string characterName, int? idx, Dictionary modPaths, string manipulationData) { if (!CheckPenumbraApi() || idx == null) return; - var collName = "Mare_" + characterName; - var ret = _penumbraCreateNamedTemporaryCollection.Invoke(collName); - logger.LogTrace("[{applicationId}] Creating Temp Collection {collName}, Success: {ret}", applicationId, collName, ret); - var retAssign = _penumbraAssignTemporaryCollection.Invoke(collName, idx.Value, c: true); - logger.LogTrace("[{applicationId}] Assigning Temp Collection {collName} to index {idx}, Success: {ret}", applicationId, collName, idx, retAssign); - foreach (var mod in modPaths) + await _dalamudUtil.RunOnFrameworkThread(() => { - logger.LogTrace("[{applicationId}] Change: {from} => {to}", applicationId, mod.Key, mod.Value); - } + var collName = "Mare_" + characterName; + var ret = _penumbraCreateNamedTemporaryCollection.Invoke(collName); + logger.LogTrace("[{applicationId}] Creating Temp Collection {collName}, Success: {ret}", applicationId, collName, ret); + var retAssign = _penumbraAssignTemporaryCollection.Invoke(collName, idx.Value, c: true); + logger.LogTrace("[{applicationId}] Assigning Temp Collection {collName} to index {idx}, Success: {ret}", applicationId, collName, idx, retAssign); + foreach (var mod in modPaths) + { + logger.LogTrace("[{applicationId}] Change: {from} => {to}", applicationId, mod.Key, mod.Value); + } - var ret2 = _penumbraAddTemporaryMod.Invoke("MareChara", collName, modPaths, manipulationData, 0); - logger.LogTrace("[{applicationId}] Setting temp mods for {collName}, Success: {ret2}", applicationId, collName, ret2); + var ret2 = _penumbraAddTemporaryMod.Invoke("MareChara", collName, modPaths, manipulationData, 0); + logger.LogTrace("[{applicationId}] Setting temp mods for {collName}, Success: {ret2}", applicationId, collName, ret2); + }).ConfigureAwait(false); } public void ToggleGposeQueueMode(bool on) @@ -498,12 +416,100 @@ public sealed class IpcManager : DisposableMediatorSubscriberBase _customizePlusOnScaleUpdate.Unsubscribe(OnCustomizePlusScaleChange); } + private bool CheckCustomizePlusApiInternal() + { + try + { + return string.Equals(_customizePlusApiVersion.InvokeFunc(), "1.0", StringComparison.Ordinal); + } + catch + { + return false; + } + } + + private bool CheckGlamourerApiInternal() + { + bool apiAvailable = false; + try + { + apiAvailable = _glamourerApiVersion.InvokeFunc() >= 0; + _shownGlamourerUnavailable = _shownGlamourerUnavailable && !apiAvailable; + return apiAvailable; + } + catch + { + return apiAvailable; + } + finally + { + if (!apiAvailable && !_shownGlamourerUnavailable) + { + _shownGlamourerUnavailable = true; + Mediator.Publish(new NotificationMessage("Glamourer inactive", "Your Glamourer installation is not active or out of date. Update Glamourer to continue to use Mare.", NotificationType.Error)); + } + } + } + + private bool CheckHeelsApiInternal() + { + try + { + return string.Equals(_heelsGetApiVersion.InvokeFunc(), "1.0.1", StringComparison.Ordinal); + } + catch + { + return false; + } + } + + private bool CheckPalettePlusApiInternal() + { + try + { + return string.Equals(_palettePlusApiVersion.InvokeFunc(), "1.1.0", StringComparison.Ordinal); + } + catch + { + return false; + } + } + + private bool CheckPenumbraApiInternal() + { + bool apiAvailable = false; + try + { + apiAvailable = _penumbraApiVersion.Invoke() is { Item1: 4, Item2: >= 19 } && _penumbraEnabled.Invoke(); + _shownPenumbraUnavailable = _shownPenumbraUnavailable && !apiAvailable; + return apiAvailable; + } + catch + { + return apiAvailable; + } + finally + { + if (!apiAvailable && !_shownPenumbraUnavailable) + { + _shownPenumbraUnavailable = true; + Mediator.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.", NotificationType.Error)); + } + } + } + private void ClearActionQueue() { ActionQueue.Clear(); _gposeActionQueue.Clear(); } + private string? GetPenumbraModDirectoryInternal() + { + if (!CheckPenumbraApi()) return null; + return _penumbraResolveModDir!.Invoke().ToLowerInvariant(); + } + private void HandleActionQueue() { if (ActionQueue.TryDequeue(out var action)) @@ -564,7 +570,7 @@ public sealed class IpcManager : DisposableMediatorSubscriberBase { if (!fireAndForget) { - await _dalamudUtil.RunOnFrameworkThread(action); + await _dalamudUtil.RunOnFrameworkThread(action).ConfigureAwait(false); var disposeToken = _disposalCts.Token; var combinedToken = CancellationTokenSource.CreateLinkedTokenSource(disposeToken, token).Token; diff --git a/MareSynchronos/MareSynchronos.csproj b/MareSynchronos/MareSynchronos.csproj index a54cf7d..682dc6d 100644 --- a/MareSynchronos/MareSynchronos.csproj +++ b/MareSynchronos/MareSynchronos.csproj @@ -3,7 +3,7 @@ - 0.8.19 + 0.8.20 https://github.com/Penumbra-Sync/client diff --git a/MareSynchronos/PlayerData/Export/MareCharaFileManager.cs b/MareSynchronos/PlayerData/Export/MareCharaFileManager.cs index 4c1c014..8c4b965 100644 --- a/MareSynchronos/PlayerData/Export/MareCharaFileManager.cs +++ b/MareSynchronos/PlayerData/Export/MareCharaFileManager.cs @@ -64,14 +64,14 @@ public class MareCharaFileManager } var applicationId = Guid.NewGuid(); _ipcManager.ToggleGposeQueueMode(on: true); - _ipcManager.PenumbraRemoveTemporaryCollection(_logger, applicationId, charaTarget.Name.TextValue); - _ipcManager.PenumbraSetTemporaryMods(_logger, applicationId, charaTarget.Name.TextValue, charaTarget.ObjectTableIndex(), + await _ipcManager.PenumbraRemoveTemporaryCollection(_logger, applicationId, charaTarget.Name.TextValue).ConfigureAwait(false); + await _ipcManager.PenumbraSetTemporaryMods(_logger, applicationId, charaTarget.Name.TextValue, charaTarget.ObjectTableIndex(), extractedFiles.Union(fileSwaps).ToDictionary(d => d.Key, d => d.Value, StringComparer.Ordinal), - LoadedCharaFile.CharaFileData.ManipulationData); + LoadedCharaFile.CharaFileData.ManipulationData).ConfigureAwait(false); using GameObjectHandler tempHandler = _gameObjectHandlerFactory(ObjectKind.Player, () => charaTarget.Address, false); await _ipcManager.GlamourerApplyAll(_logger, tempHandler, LoadedCharaFile.CharaFileData.GlamourerData, applicationId, disposeCts.Token).ConfigureAwait(false); _dalamudUtil.WaitWhileGposeCharacterIsDrawing(charaTarget.Address, 30000); - _ipcManager.PenumbraRemoveTemporaryCollection(_logger, applicationId, charaTarget.Name.TextValue); + await _ipcManager.PenumbraRemoveTemporaryCollection(_logger, applicationId, charaTarget.Name.TextValue).ConfigureAwait(false); _ipcManager.ToggleGposeQueueMode(on: false); } } diff --git a/MareSynchronos/PlayerData/Pairs/CachedPlayer.cs b/MareSynchronos/PlayerData/Pairs/CachedPlayer.cs index 6a1ef8d..501324b 100644 --- a/MareSynchronos/PlayerData/Pairs/CachedPlayer.cs +++ b/MareSynchronos/PlayerData/Pairs/CachedPlayer.cs @@ -176,12 +176,12 @@ public sealed class CachedPlayer : DisposableMediatorSubscriberBase if (_dalamudUtil.IsZoning) { Logger.LogTrace("[{applicationId}] Removing temp collection for {name} ({OnlineUser})", applicationId, name, OnlineUser); - _ipcManager.PenumbraRemoveTemporaryCollection(Logger, applicationId, name); + _ipcManager.PenumbraRemoveTemporaryCollection(Logger, applicationId, name).GetAwaiter().GetResult(); } else if (_dalamudUtil is { IsZoning: false, IsInCutscene: false }) { Logger.LogTrace("[{applicationId}] Restoring state for {name} ({OnlineUser})", applicationId, name, OnlineUser); - _ipcManager.PenumbraRemoveTemporaryCollection(Logger, applicationId, name); + _ipcManager.PenumbraRemoveTemporaryCollection(Logger, applicationId, name).GetAwaiter().GetResult(); foreach (KeyValuePair> item in _cachedData.FileReplacements) { @@ -211,10 +211,10 @@ public sealed class CachedPlayer : DisposableMediatorSubscriberBase private async Task ApplyBaseData(Guid applicationId, Dictionary moddedPaths, string manipulationData, CancellationToken token) { - await _dalamudUtil.RunOnFrameworkThread(() => _ipcManager.PenumbraRemoveTemporaryCollection(Logger, applicationId, PlayerName!)).ConfigureAwait(false); + await _ipcManager.PenumbraRemoveTemporaryCollection(Logger, applicationId, PlayerName!).ConfigureAwait(false); token.ThrowIfCancellationRequested(); - await _dalamudUtil.RunOnFrameworkThread(() => _ipcManager.PenumbraSetTemporaryMods(Logger, applicationId, PlayerName!, - _charaHandler?.GameObjectLazy?.Value.ObjectTableIndex(), moddedPaths, manipulationData)).ConfigureAwait(false); + await _ipcManager.PenumbraSetTemporaryMods(Logger, applicationId, PlayerName!, + _charaHandler?.GameObjectLazy?.Value.ObjectTableIndex(), moddedPaths, manipulationData).ConfigureAwait(false); token.ThrowIfCancellationRequested(); } diff --git a/MareSynchronos/UI/Components/DrawGroupPair.cs b/MareSynchronos/UI/Components/DrawGroupPair.cs index 90d2dc3..afbfbbd 100644 --- a/MareSynchronos/UI/Components/DrawGroupPair.cs +++ b/MareSynchronos/UI/Components/DrawGroupPair.cs @@ -14,11 +14,11 @@ namespace MareSynchronos.UI.Components; public class DrawGroupPair : DrawPairBase { + private static string _banReason = string.Empty; + private static bool _banUserPopupOpen; + private static bool _showModalBanUser; private readonly GroupPairFullInfoDto _fullInfoDto; private readonly GroupFullInfoDto _group; - private string _banReason = string.Empty; - private bool _banUserPopupOpen; - private bool _showModalBanUser; public DrawGroupPair(string id, Pair entry, ApiController apiController, GroupFullInfoDto group, GroupPairFullInfoDto fullInfoDto, UidDisplayHandler handler) : base(id, entry, apiController, handler) {