From b7d88774914e2365a3f12159b110bc19b32d0f32 Mon Sep 17 00:00:00 2001 From: Stanley Dimant Date: Sun, 26 May 2024 22:55:32 +0200 Subject: [PATCH] update customize+ ipc --- .../Interop/Ipc/IpcCallerCustomize.cs | 55 +++++++++++++------ .../PlayerData/Export/MareCharaFileManager.cs | 12 +++- .../PlayerData/Handlers/PairHandler.cs | 22 +++++--- 3 files changed, 63 insertions(+), 26 deletions(-) diff --git a/MareSynchronos/Interop/Ipc/IpcCallerCustomize.cs b/MareSynchronos/Interop/Ipc/IpcCallerCustomize.cs index df13caa..a06ab5a 100644 --- a/MareSynchronos/Interop/Ipc/IpcCallerCustomize.cs +++ b/MareSynchronos/Interop/Ipc/IpcCallerCustomize.cs @@ -12,10 +12,12 @@ namespace MareSynchronos.Interop.Ipc; public sealed class IpcCallerCustomize : IIpcCaller { private readonly ICallGateSubscriber<(int, int)> _customizePlusApiVersion; - private readonly ICallGateSubscriber _customizePlusGetBodyScale; - private readonly ICallGateSubscriber _customizePlusOnScaleUpdate; - private readonly ICallGateSubscriber _customizePlusRevertCharacter; - private readonly ICallGateSubscriber _customizePlusSetBodyScaleToCharacter; + private readonly ICallGateSubscriber _customizePlusGetActiveProfile; + private readonly ICallGateSubscriber _customizePlusGetProfileById; + private readonly ICallGateSubscriber _customizePlusOnScaleUpdate; + private readonly ICallGateSubscriber _customizePlusRevertCharacter; + private readonly ICallGateSubscriber _customizePlusSetBodyScaleToCharacter; + private readonly ICallGateSubscriber _customizePlusDeleteByUniqueId; private readonly ILogger _logger; private readonly DalamudUtilService _dalamudUtil; private readonly MareMediator _mareMediator; @@ -23,11 +25,13 @@ public sealed class IpcCallerCustomize : IIpcCaller public IpcCallerCustomize(ILogger logger, DalamudPluginInterface dalamudPluginInterface, DalamudUtilService dalamudUtil, MareMediator mareMediator) { - _customizePlusApiVersion = dalamudPluginInterface.GetIpcSubscriber<(int, int)>("CustomizePlus.GetApiVersion"); - _customizePlusGetBodyScale = dalamudPluginInterface.GetIpcSubscriber("CustomizePlus.GetProfileFromCharacter"); - _customizePlusRevertCharacter = dalamudPluginInterface.GetIpcSubscriber("CustomizePlus.RevertCharacter"); - _customizePlusSetBodyScaleToCharacter = dalamudPluginInterface.GetIpcSubscriber("CustomizePlus.SetProfileToCharacter"); - _customizePlusOnScaleUpdate = dalamudPluginInterface.GetIpcSubscriber("CustomizePlus.OnProfileUpdate"); + _customizePlusApiVersion = dalamudPluginInterface.GetIpcSubscriber<(int, int)>("CustomizePlus.General.GetApiVersion"); + _customizePlusGetActiveProfile = dalamudPluginInterface.GetIpcSubscriber("CustomizePlus.Profile.GetActiveProfileIdOnCharacter"); + _customizePlusGetProfileById = dalamudPluginInterface.GetIpcSubscriber("CustomizePlus.Profile.GetByUniqueId"); + _customizePlusRevertCharacter = dalamudPluginInterface.GetIpcSubscriber("CustomizePlus.Profile.DeleteTemporaryProfileOnCharacter"); + _customizePlusSetBodyScaleToCharacter = dalamudPluginInterface.GetIpcSubscriber("CustomizePlus.Profile.SetTemporaryProfileOnCharacter"); + _customizePlusOnScaleUpdate = dalamudPluginInterface.GetIpcSubscriber("CustomizePlus.Profile.OnUpdate"); + _customizePlusDeleteByUniqueId = dalamudPluginInterface.GetIpcSubscriber("CustomizePlus.Profile.DeleteTemporaryProfileByUniqueId"); _customizePlusOnScaleUpdate.Subscribe(OnCustomizePlusScaleChange); _logger = logger; @@ -53,10 +57,10 @@ public sealed class IpcCallerCustomize : IIpcCaller }).ConfigureAwait(false); } - public async Task SetBodyScaleAsync(nint character, string scale) + public async Task SetBodyScaleAsync(nint character, string scale) { - if (!APIAvailable) return; - await _dalamudUtil.RunOnFrameworkThread(() => + if (!APIAvailable) return null; + return await _dalamudUtil.RunOnFrameworkThread(() => { var gameObj = _dalamudUtil.CreateGameObject(character); if (gameObj is Character c) @@ -66,12 +70,26 @@ public sealed class IpcCallerCustomize : IIpcCaller if (scale.IsNullOrEmpty()) { _customizePlusRevertCharacter!.InvokeAction(c); + return null; } else { - _customizePlusSetBodyScaleToCharacter!.InvokeAction(decodedScale, c); + var result = _customizePlusSetBodyScaleToCharacter!.InvokeFunc(c, decodedScale); + return result.Item2; } } + + return null; + }).ConfigureAwait(false); + } + + public async Task RevertByIdAsync(Guid? profileId) + { + if (!APIAvailable || profileId == null) return; + + await _dalamudUtil.RunOnFrameworkThread(() => + { + _ = _customizePlusDeleteByUniqueId.InvokeFunc(profileId.Value); }).ConfigureAwait(false); } @@ -83,7 +101,10 @@ public sealed class IpcCallerCustomize : IIpcCaller var gameObj = _dalamudUtil.CreateGameObject(character); if (gameObj is Character c) { - return _customizePlusGetBodyScale.InvokeFunc(c); + var res = _customizePlusGetActiveProfile.InvokeFunc(c); + _logger.LogTrace("CustomizePlus GetActiveProfile returned {err}", res.Item1); + if (res.Item1 != 0 || res.Item2 == null) return string.Empty; + return _customizePlusGetProfileById.InvokeFunc(res.Item2.Value).Item2; } return string.Empty; @@ -97,7 +118,7 @@ public sealed class IpcCallerCustomize : IIpcCaller try { var version = _customizePlusApiVersion.InvokeFunc(); - APIAvailable = (version.Item1 == 3 && version.Item2 >= 0); + APIAvailable = (version.Item1 == 4 && version.Item2 >= 0); } catch { @@ -105,9 +126,9 @@ public sealed class IpcCallerCustomize : IIpcCaller } } - private void OnCustomizePlusScaleChange(string? profileName, string? scale) + private void OnCustomizePlusScaleChange(Character c, Guid g) { - _mareMediator.Publish(new CustomizePlusMessage(profileName ?? string.Empty)); + _mareMediator.Publish(new CustomizePlusMessage(c.Name.ToString() ?? string.Empty)); } public void Dispose() diff --git a/MareSynchronos/PlayerData/Export/MareCharaFileManager.cs b/MareSynchronos/PlayerData/Export/MareCharaFileManager.cs index 7b9d229..30b16d3 100644 --- a/MareSynchronos/PlayerData/Export/MareCharaFileManager.cs +++ b/MareSynchronos/PlayerData/Export/MareCharaFileManager.cs @@ -21,6 +21,7 @@ public class MareCharaFileManager : DisposableMediatorSubscriberBase private readonly MareCharaFileDataFactory _factory; private readonly GameObjectHandlerFactory _gameObjectHandlerFactory; private readonly Dictionary _gposeGameObjects; + private readonly List _gposeCustomizeObjects; private readonly IpcManager _ipcManager; private readonly ILogger _logger; private readonly FileCacheManager _manager; @@ -39,6 +40,7 @@ public class MareCharaFileManager : DisposableMediatorSubscriberBase _configService = configService; _dalamudUtil = dalamudUtil; _gposeGameObjects = []; + _gposeCustomizeObjects = []; Mediator.Subscribe(this, _ => _isInGpose = true); Mediator.Subscribe(this, async _ => { @@ -59,6 +61,10 @@ public class MareCharaFileManager : DisposableMediatorSubscriberBase item.Value.Dispose(); } + foreach (var id in _gposeCustomizeObjects.Where(d => d != null)) + { + await _ipcManager.CustomizePlus.RevertByIdAsync(id.Value); + } _gposeGameObjects.Clear(); }); } @@ -109,11 +115,13 @@ public class MareCharaFileManager : DisposableMediatorSubscriberBase await _ipcManager.Penumbra.RemoveTemporaryCollectionAsync(_logger, applicationId, coll).ConfigureAwait(false); if (!string.IsNullOrEmpty(LoadedCharaFile.CharaFileData.CustomizePlusData)) { - await _ipcManager.CustomizePlus.SetBodyScaleAsync(tempHandler.Address, LoadedCharaFile.CharaFileData.CustomizePlusData).ConfigureAwait(false); + var id = await _ipcManager.CustomizePlus.SetBodyScaleAsync(tempHandler.Address, LoadedCharaFile.CharaFileData.CustomizePlusData).ConfigureAwait(false); + _gposeCustomizeObjects.Add(id); } else { - await _ipcManager.CustomizePlus.RevertAsync(tempHandler.Address).ConfigureAwait(false); + var id = await _ipcManager.CustomizePlus.SetBodyScaleAsync(tempHandler.Address, "{}").ConfigureAwait(false); + _gposeCustomizeObjects.Add(id); } } } diff --git a/MareSynchronos/PlayerData/Handlers/PairHandler.cs b/MareSynchronos/PlayerData/Handlers/PairHandler.cs index ed6b131..dfee048 100644 --- a/MareSynchronos/PlayerData/Handlers/PairHandler.cs +++ b/MareSynchronos/PlayerData/Handlers/PairHandler.cs @@ -13,6 +13,7 @@ using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; using System.Collections.Concurrent; using System.Diagnostics; +using System.Threading.Channels; using ObjectKind = MareSynchronos.API.Data.Enum.ObjectKind; namespace MareSynchronos.PlayerData.Handlers; @@ -38,6 +39,7 @@ public sealed class PairHandler : DisposableMediatorSubscriberBase private bool _forceApplyMods = false; private bool _isVisible; private Guid _penumbraCollection; + private Dictionary _customizeIds = []; private bool _redrawOnNextApplication = false; private CombatData? _dataReceivedInDowntime; public long LastAppliedDataSize { get; private set; } @@ -316,11 +318,12 @@ public sealed class PairHandler : DisposableMediatorSubscriberBase case PlayerChanges.Customize: if (charaData.CustomizePlusData.TryGetValue(changes.Key, out var customizePlusData)) { - await _ipcManager.CustomizePlus.SetBodyScaleAsync(handler.Address, customizePlusData).ConfigureAwait(false); + _customizeIds[changes.Key] = await _ipcManager.CustomizePlus.SetBodyScaleAsync(handler.Address, customizePlusData).ConfigureAwait(false); } - else + else if (_customizeIds.TryGetValue(changes.Key, out var customizeId)) { - await _ipcManager.CustomizePlus.RevertAsync(handler.Address).ConfigureAwait(false); + await _ipcManager.CustomizePlus.RevertByIdAsync(customizeId).ConfigureAwait(false); + _customizeIds.Remove(changes.Key); } break; @@ -557,6 +560,11 @@ public sealed class PairHandler : DisposableMediatorSubscriberBase Logger.LogDebug("[{applicationId}] Reverting all Customization for {alias}/{name} {objectKind}", applicationId, OnlineUser.User.AliasOrUID, name, objectKind); + if (_customizeIds.TryGetValue(objectKind, out var customizeId)) + { + _customizeIds.Remove(objectKind); + } + if (objectKind == ObjectKind.Player) { using GameObjectHandler tempHandler = await _gameObjectHandlerFactory.Create(ObjectKind.Player, () => address, isWatched: false).ConfigureAwait(false); @@ -568,7 +576,7 @@ public sealed class PairHandler : DisposableMediatorSubscriberBase await _ipcManager.Heels.RestoreOffsetForPlayerAsync(address).ConfigureAwait(false); tempHandler.CompareNameAndThrow(name); Logger.LogDebug("[{applicationId}] Restoring C+ for {alias}/{name}", applicationId, OnlineUser.User.AliasOrUID, name); - await _ipcManager.CustomizePlus.RevertAsync(address).ConfigureAwait(false); + await _ipcManager.CustomizePlus.RevertByIdAsync(customizeId).ConfigureAwait(false); tempHandler.CompareNameAndThrow(name); Logger.LogDebug("[{applicationId}] Restoring Honorific for {alias}/{name}", applicationId, OnlineUser.User.AliasOrUID, name); await _ipcManager.Honorific.ClearTitleAsync(address).ConfigureAwait(false); @@ -580,7 +588,7 @@ public sealed class PairHandler : DisposableMediatorSubscriberBase var minionOrMount = await _dalamudUtil.GetMinionOrMountAsync(address).ConfigureAwait(false); if (minionOrMount != nint.Zero) { - await _ipcManager.CustomizePlus.RevertAsync(minionOrMount).ConfigureAwait(false); + await _ipcManager.CustomizePlus.RevertByIdAsync(customizeId).ConfigureAwait(false); using GameObjectHandler tempHandler = await _gameObjectHandlerFactory.Create(ObjectKind.MinionOrMount, () => minionOrMount, isWatched: false).ConfigureAwait(false); await _ipcManager.Glamourer.RevertAsync(Logger, tempHandler.Name, tempHandler, applicationId, cancelToken).ConfigureAwait(false); await _ipcManager.Penumbra.RedrawAsync(Logger, tempHandler, applicationId, cancelToken).ConfigureAwait(false); @@ -591,7 +599,7 @@ public sealed class PairHandler : DisposableMediatorSubscriberBase var pet = await _dalamudUtil.GetPetAsync(address).ConfigureAwait(false); if (pet != nint.Zero) { - await _ipcManager.CustomizePlus.RevertAsync(pet).ConfigureAwait(false); + await _ipcManager.CustomizePlus.RevertByIdAsync(customizeId).ConfigureAwait(false); using GameObjectHandler tempHandler = await _gameObjectHandlerFactory.Create(ObjectKind.Pet, () => pet, isWatched: false).ConfigureAwait(false); await _ipcManager.Glamourer.RevertAsync(Logger, tempHandler.Name, tempHandler, applicationId, cancelToken).ConfigureAwait(false); await _ipcManager.Penumbra.RedrawAsync(Logger, tempHandler, applicationId, cancelToken).ConfigureAwait(false); @@ -602,7 +610,7 @@ public sealed class PairHandler : DisposableMediatorSubscriberBase var companion = await _dalamudUtil.GetCompanionAsync(address).ConfigureAwait(false); if (companion != nint.Zero) { - await _ipcManager.CustomizePlus.RevertAsync(companion).ConfigureAwait(false); + await _ipcManager.CustomizePlus.RevertByIdAsync(customizeId).ConfigureAwait(false); using GameObjectHandler tempHandler = await _gameObjectHandlerFactory.Create(ObjectKind.Pet, () => companion, isWatched: false).ConfigureAwait(false); await _ipcManager.Glamourer.RevertAsync(Logger, tempHandler.Name, tempHandler, applicationId, cancelToken).ConfigureAwait(false); await _ipcManager.Penumbra.RedrawAsync(Logger, tempHandler, applicationId, cancelToken).ConfigureAwait(false);