From 08a35c91521aad961f580f0d321304dce8e3cef4 Mon Sep 17 00:00:00 2001 From: rootdarkarchon Date: Mon, 17 Jul 2023 08:57:56 +0200 Subject: [PATCH] Heels and C+ updates (#54) * add heels and customize plus multi data * adjust customize plus api calls * adjustments to ipc for customize --------- Co-authored-by: rootdarkarchon --- MareAPI | 2 +- MareSynchronos/Interop/IpcManager.cs | 143 +++++++----------- .../PlayerData/Data/CharacterData.cs | 10 +- .../PlayerData/Export/MareCharaFileData.cs | 3 +- .../PlayerData/Export/MareCharaFileManager.cs | 18 ++- .../PlayerData/Factories/PlayerDataFactory.cs | 13 +- .../PlayerData/Handlers/PairHandler.cs | 7 +- .../Services/CacheCreationService.cs | 16 +- MareSynchronos/Services/Mediator/Messages.cs | 2 +- MareSynchronos/UI/DtrEntry.cs | 5 +- MareSynchronos/Utils/VariousExtensions.cs | 22 +-- 11 files changed, 116 insertions(+), 125 deletions(-) diff --git a/MareAPI b/MareAPI index 51645cb..a422dc8 160000 --- a/MareAPI +++ b/MareAPI @@ -1 +1 @@ -Subproject commit 51645cbc7913b594a2c5f4b52562396f7902f5eb +Subproject commit a422dc8798d1812d2c60be22441c4ac424c2f31c diff --git a/MareSynchronos/Interop/IpcManager.cs b/MareSynchronos/Interop/IpcManager.cs index f69b471..4fa50e5 100644 --- a/MareSynchronos/Interop/IpcManager.cs +++ b/MareSynchronos/Interop/IpcManager.cs @@ -2,7 +2,6 @@ using Dalamud.Plugin.Ipc; using Dalamud.Game.ClientState.Objects.SubKinds; using Dalamud.Game.ClientState.Objects.Types; -using Action = System.Action; using System.Collections.Concurrent; using System.Text; using Penumbra.Api.Enums; @@ -12,15 +11,16 @@ using Microsoft.Extensions.Logging; using MareSynchronos.PlayerData.Handlers; using MareSynchronos.Services.Mediator; using MareSynchronos.Services; +using Dalamud.Utility; namespace MareSynchronos.Interop; public sealed class IpcManager : DisposableMediatorSubscriberBase { - private readonly ICallGateSubscriber _customizePlusApiVersion; - private readonly ICallGateSubscriber _customizePlusGetBodyScale; - private readonly ICallGateSubscriber _customizePlusOnScaleUpdate; - private readonly ICallGateSubscriber _customizePlusRevert; + private readonly ICallGateSubscriber<(int, int)> _customizePlusApiVersion; + private readonly ICallGateSubscriber _customizePlusGetBodyScale; + private readonly ICallGateSubscriber _customizePlusOnScaleUpdate; + private readonly ICallGateSubscriber _customizePlusRevertCharacter; private readonly ICallGateSubscriber _customizePlusSetBodyScaleToCharacter; private readonly DalamudUtilService _dalamudUtil; private readonly ICallGateSubscriber _glamourerApiVersion; @@ -28,11 +28,10 @@ public sealed class IpcManager : DisposableMediatorSubscriberBase private readonly ICallGateSubscriber? _glamourerApplyOnlyCustomization; private readonly ICallGateSubscriber? _glamourerApplyOnlyEquipment; private readonly ICallGateSubscriber? _glamourerGetAllCustomization; - private readonly ConcurrentQueue _gposeActionQueue = new(); - private readonly ICallGateSubscriber _heelsGetApiVersion; - private readonly ICallGateSubscriber _heelsGetOffset; - private readonly ICallGateSubscriber _heelsOffsetUpdate; - private readonly ICallGateSubscriber _heelsRegisterPlayer; + private readonly ICallGateSubscriber<(int, int)> _heelsGetApiVersion; + private readonly ICallGateSubscriber _heelsGetOffset; + private readonly ICallGateSubscriber _heelsOffsetUpdate; + private readonly ICallGateSubscriber _heelsRegisterPlayer; private readonly ICallGateSubscriber _heelsUnregisterPlayer; private readonly ICallGateSubscriber<(uint major, uint minor)> _honorificApiVersion; private readonly ICallGateSubscriber _honorificClearCharacterTitle; @@ -41,7 +40,6 @@ public sealed class IpcManager : DisposableMediatorSubscriberBase private readonly ICallGateSubscriber _honorificLocalCharacterTitleChanged; private readonly ICallGateSubscriber _honorificReady; private readonly ICallGateSubscriber _honorificSetCharacterTitle; - private readonly ConcurrentQueue _normalQueue = new(); private readonly ICallGateSubscriber _palettePlusApiVersion; private readonly ICallGateSubscriber _palettePlusBuildCharaPalette; private readonly ICallGateSubscriber _palettePlusPaletteChanged; @@ -71,7 +69,6 @@ public sealed class IpcManager : DisposableMediatorSubscriberBase private bool _glamourerAvailable = false; private bool _heelsAvailable = false; private bool _honorificAvailable = false; - private bool _inGposeQueueMode = false; private bool _palettePlusAvailable = false; private bool _penumbraAvailable = false; private bool _shownGlamourerUnavailable = false; @@ -110,19 +107,19 @@ public sealed class IpcManager : DisposableMediatorSubscriberBase _glamourerApplyOnlyCustomization = pi.GetIpcSubscriber("Glamourer.ApplyOnlyCustomizationToCharacter"); _glamourerApplyOnlyEquipment = pi.GetIpcSubscriber("Glamourer.ApplyOnlyEquipmentToCharacter"); - _heelsGetApiVersion = pi.GetIpcSubscriber("HeelsPlugin.ApiVersion"); - _heelsGetOffset = pi.GetIpcSubscriber("HeelsPlugin.GetOffset"); - _heelsRegisterPlayer = pi.GetIpcSubscriber("HeelsPlugin.RegisterPlayer"); - _heelsUnregisterPlayer = pi.GetIpcSubscriber("HeelsPlugin.UnregisterPlayer"); - _heelsOffsetUpdate = pi.GetIpcSubscriber("HeelsPlugin.OffsetChanged"); + _heelsGetApiVersion = pi.GetIpcSubscriber<(int, int)>("SimpleHeels.ApiVersion"); + _heelsGetOffset = pi.GetIpcSubscriber("SimpleHeels.GetLocalPlayer"); + _heelsRegisterPlayer = pi.GetIpcSubscriber("SimpleHeels.RegisterPlayer"); + _heelsUnregisterPlayer = pi.GetIpcSubscriber("SimpleHeels.UnregisterPlayer"); + _heelsOffsetUpdate = pi.GetIpcSubscriber("SimpleHeels.LocalChanged"); _heelsOffsetUpdate.Subscribe(HeelsOffsetChange); - _customizePlusApiVersion = pi.GetIpcSubscriber("CustomizePlus.GetApiVersion"); - _customizePlusGetBodyScale = pi.GetIpcSubscriber("CustomizePlus.GetBodyScale"); - _customizePlusRevert = pi.GetIpcSubscriber("CustomizePlus.RevertCharacter"); - _customizePlusSetBodyScaleToCharacter = pi.GetIpcSubscriber("CustomizePlus.SetBodyScaleToCharacter"); - _customizePlusOnScaleUpdate = pi.GetIpcSubscriber("CustomizePlus.OnScaleUpdate"); + _customizePlusApiVersion = pi.GetIpcSubscriber<(int, int)>("CustomizePlus.GetApiVersion"); + _customizePlusGetBodyScale = pi.GetIpcSubscriber("CustomizePlus.GetProfileFromCharacter"); + _customizePlusRevertCharacter = pi.GetIpcSubscriber("CustomizePlus.RevertCharacter"); + _customizePlusSetBodyScaleToCharacter = pi.GetIpcSubscriber("CustomizePlus.SetProfileToCharacter"); + _customizePlusOnScaleUpdate = pi.GetIpcSubscriber("CustomizePlus.OnProfileUpdate"); _customizePlusOnScaleUpdate.Subscribe(OnCustomizePlusScaleChange); @@ -151,9 +148,6 @@ public sealed class IpcManager : DisposableMediatorSubscriberBase Mediator.Publish(new PenumbraInitializedMessage()); } - Mediator.Subscribe(this, (_) => HandleActionQueue()); - Mediator.Subscribe(this, (_) => HandleGposeActionQueue()); - Mediator.Subscribe(this, (_) => ClearActionQueue()); Mediator.Subscribe(this, (_) => PeriodicApiStateCheck()); PeriodicApiStateCheck(); @@ -161,7 +155,6 @@ public sealed class IpcManager : DisposableMediatorSubscriberBase public bool Initialized => CheckPenumbraApiInternal() && CheckGlamourerApiInternal(); public string? PenumbraModDirectory { get; private set; } - private ConcurrentQueue ActionQueue => _inGposeQueueMode ? _gposeActionQueue : _normalQueue; public bool CheckCustomizePlusApi() => _customizePlusAvailable; @@ -184,14 +177,14 @@ public sealed class IpcManager : DisposableMediatorSubscriberBase if (gameObj is Character c) { Logger.LogTrace("CustomizePlus reverting for {chara}", c.Address.ToString("X")); - _customizePlusRevert!.InvokeAction(c); + _customizePlusRevertCharacter!.InvokeAction(c); } }).ConfigureAwait(false); } public async Task CustomizePlusSetBodyScaleAsync(IntPtr character, string scale) { - if (!CheckCustomizePlusApi() || string.IsNullOrEmpty(scale)) return; + if (!CheckCustomizePlusApi()) return; await _dalamudUtil.RunOnFrameworkThread(() => { var gameObj = _dalamudUtil.CreateGameObject(character); @@ -199,22 +192,38 @@ public sealed class IpcManager : DisposableMediatorSubscriberBase { string decodedScale = Encoding.UTF8.GetString(Convert.FromBase64String(scale)); Logger.LogTrace("CustomizePlus applying for {chara}", c.Address.ToString("X")); - _customizePlusSetBodyScaleToCharacter!.InvokeAction(decodedScale, c); + if (scale.IsNullOrEmpty()) + { + _customizePlusRevertCharacter!.InvokeAction(c); + } + else + { + _customizePlusSetBodyScaleToCharacter!.InvokeAction(decodedScale, c); + } } }).ConfigureAwait(false); } - public async Task GetCustomizePlusScaleAsync() + public async Task GetCustomizePlusScaleAsync(IntPtr character) { if (!CheckCustomizePlusApi()) return string.Empty; - var scale = await _dalamudUtil.RunOnFrameworkThread(() => _customizePlusGetBodyScale.InvokeFunc(_dalamudUtil.GetPlayerName())).ConfigureAwait(false); + var scale = await _dalamudUtil.RunOnFrameworkThread(() => + { + var gameObj = _dalamudUtil.CreateGameObject(character); + if (gameObj is Character c) + { + return _customizePlusGetBodyScale.InvokeFunc(c); + } + + return string.Empty; + }).ConfigureAwait(false); if (string.IsNullOrEmpty(scale)) return string.Empty; return Convert.ToBase64String(Encoding.UTF8.GetBytes(scale)); } - public async Task GetHeelsOffsetAsync() + public async Task GetHeelsOffsetAsync() { - if (!CheckHeelsApi()) return 0.0f; + if (!CheckHeelsApi()) return string.Empty; return await _dalamudUtil.RunOnFrameworkThread(_heelsGetOffset.InvokeFunc).ConfigureAwait(false); } @@ -300,7 +309,7 @@ public sealed class IpcManager : DisposableMediatorSubscriberBase }).ConfigureAwait(false); } - public async Task HeelsSetOffsetForPlayerAsync(IntPtr character, float offset) + public async Task HeelsSetOffsetForPlayerAsync(IntPtr character, string data) { if (!CheckHeelsApi()) return; await _dalamudUtil.RunOnFrameworkThread(() => @@ -309,7 +318,7 @@ public sealed class IpcManager : DisposableMediatorSubscriberBase if (gameObj != null) { Logger.LogTrace("Applying Heels data to {chara}", character.ToString("X")); - _heelsRegisterPlayer.InvokeAction(gameObj, offset); + _heelsRegisterPlayer.InvokeAction(gameObj, data); } }).ConfigureAwait(false); } @@ -503,37 +512,12 @@ public sealed class IpcManager : DisposableMediatorSubscriberBase }).ConfigureAwait(false); } - public void ToggleGposeQueueMode(bool on) - { - _inGposeQueueMode = on; - } - protected override void Dispose(bool disposing) { base.Dispose(disposing); _disposalCts.Cancel(); - int totalSleepTime = 0; - while (!ActionQueue.IsEmpty && totalSleepTime < 2000) - { - Logger.LogTrace("Waiting for actionqueue to clear..."); - PeriodicApiStateCheck(); - if (CheckPenumbraApi()) - { - HandleActionQueue(); - } - Thread.Sleep(16); - totalSleepTime += 16; - } - - if (totalSleepTime >= 2000) - { - Logger.LogTrace("Action queue clear or not, disposing"); - } - - ActionQueue.Clear(); - _penumbraModSettingChanged.Dispose(); _penumbraGameObjectResourcePathResolved.Dispose(); _penumbraDispose.Dispose(); @@ -551,7 +535,9 @@ public sealed class IpcManager : DisposableMediatorSubscriberBase { try { - return string.Equals(_customizePlusApiVersion.InvokeFunc(), "2.0", StringComparison.Ordinal); + var version = _customizePlusApiVersion.InvokeFunc(); + if (version.Item1 == 3 && version.Item2 >= 0) return true; + return false; } catch { @@ -586,7 +572,7 @@ public sealed class IpcManager : DisposableMediatorSubscriberBase { try { - return string.Equals(_heelsGetApiVersion.InvokeFunc(), "1.0.1", StringComparison.Ordinal); + return _heelsGetApiVersion.InvokeFunc() is { Item1: 1, Item2: >= 0 }; } catch { @@ -641,46 +627,20 @@ public sealed class IpcManager : DisposableMediatorSubscriberBase } } - 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)) - { - if (action == null) return; - Logger.LogDebug("Execution action in queue: {method}", action.Method); - action(); - } - } - - private void HandleGposeActionQueue() - { - if (_gposeActionQueue.TryDequeue(out var action)) - { - if (action == null) return; - Logger.LogDebug("Execution action in gpose queue: {method}", action.Method); - action(); - } - } - - private void HeelsOffsetChange(float offset) + private void HeelsOffsetChange(string offset) { Mediator.Publish(new HeelsOffsetMessage()); } - private void OnCustomizePlusScaleChange(string? scale) + private void OnCustomizePlusScaleChange(string? profileName, string? scale) { - Mediator.Publish(new CustomizePlusMessage()); + Mediator.Publish(new CustomizePlusMessage(profileName ?? string.Empty)); } private void OnHonorificDisposing() @@ -710,7 +670,6 @@ public sealed class IpcManager : DisposableMediatorSubscriberBase _disposalCts.Cancel(); _disposalCts.Dispose(); Mediator.Publish(new PenumbraDisposedMessage()); - ActionQueue.Clear(); _disposalCts = new(); } diff --git a/MareSynchronos/PlayerData/Data/CharacterData.cs b/MareSynchronos/PlayerData/Data/CharacterData.cs index bad42fa..270401c 100644 --- a/MareSynchronos/PlayerData/Data/CharacterData.cs +++ b/MareSynchronos/PlayerData/Data/CharacterData.cs @@ -6,17 +6,17 @@ namespace MareSynchronos.PlayerData.Data; public class CharacterData { - public string CustomizePlusScale { get; set; } = string.Empty; + public Dictionary CustomizePlusScale { get; set; } = new(); public Dictionary> FileReplacements { get; set; } = new(); public Dictionary GlamourerString { get; set; } = new(); - public float HeelsOffset { get; set; } = 0f; + public string HeelsData { get; set; } = string.Empty; + public string HonorificData { get; set; } = string.Empty; public bool IsReady => FileReplacements.SelectMany(k => k.Value).All(f => f.Computed); public string ManipulationString { get; set; } = string.Empty; public string PalettePlusPalette { get; set; } = string.Empty; - public string HonorificData { get; set; } = string.Empty; public API.Data.CharacterData ToAPI() { @@ -40,8 +40,8 @@ public class CharacterData FileReplacements = fileReplacements, GlamourerData = GlamourerString.ToDictionary(d => d.Key, d => d.Value), ManipulationData = ManipulationString, - HeelsOffset = HeelsOffset, - CustomizePlusData = CustomizePlusScale, + HeelsData = HeelsData, + CustomizePlusData = CustomizePlusScale.ToDictionary(d => d.Key, d => d.Value), PalettePlusData = PalettePlusPalette, HonorificData = HonorificData }; diff --git a/MareSynchronos/PlayerData/Export/MareCharaFileData.cs b/MareSynchronos/PlayerData/Export/MareCharaFileData.cs index a139794..42e42be 100644 --- a/MareSynchronos/PlayerData/Export/MareCharaFileData.cs +++ b/MareSynchronos/PlayerData/Export/MareCharaFileData.cs @@ -26,7 +26,8 @@ public record MareCharaFileData GlamourerData = glamourerData; } - CustomizePlusData = dto.CustomizePlusData; + dto.CustomizePlusData.TryGetValue(ObjectKind.Player, out var customizePlusData); + CustomizePlusData = customizePlusData ?? string.Empty; PalettePlusData = dto.PalettePlusData; ManipulationData = dto.ManipulationData; diff --git a/MareSynchronos/PlayerData/Export/MareCharaFileManager.cs b/MareSynchronos/PlayerData/Export/MareCharaFileManager.cs index 9a34192..2a3d175 100644 --- a/MareSynchronos/PlayerData/Export/MareCharaFileManager.cs +++ b/MareSynchronos/PlayerData/Export/MareCharaFileManager.cs @@ -64,7 +64,6 @@ public class MareCharaFileManager } } var applicationId = Guid.NewGuid(); - _ipcManager.ToggleGposeQueueMode(on: true); await _ipcManager.PenumbraRemoveTemporaryCollectionAsync(_logger, applicationId, charaTarget.Name.TextValue).ConfigureAwait(false); var coll = await _ipcManager.PenumbraCreateTemporaryCollectionAsync(_logger, charaTarget.Name.TextValue).ConfigureAwait(false); await _ipcManager.PenumbraAssignTemporaryCollectionAsync(_logger, coll, charaTarget.ObjectTableIndex()!.Value).ConfigureAwait(false); @@ -74,7 +73,22 @@ public class MareCharaFileManager await _ipcManager.GlamourerApplyAllAsync(_logger, tempHandler, LoadedCharaFile.CharaFileData.GlamourerData, applicationId, disposeCts.Token).ConfigureAwait(false); _dalamudUtil.WaitWhileGposeCharacterIsDrawing(charaTarget.Address, 30000); await _ipcManager.PenumbraRemoveTemporaryCollectionAsync(_logger, applicationId, coll).ConfigureAwait(false); - _ipcManager.ToggleGposeQueueMode(on: false); + if (!string.IsNullOrEmpty(LoadedCharaFile.CharaFileData.CustomizePlusData)) + { + await _ipcManager.CustomizePlusSetBodyScaleAsync(tempHandler.Address, LoadedCharaFile.CharaFileData.CustomizePlusData).ConfigureAwait(false); + } + else + { + await _ipcManager.CustomizePlusRevertAsync(tempHandler.Address).ConfigureAwait(false); + } + if (!string.IsNullOrEmpty(LoadedCharaFile.CharaFileData.PalettePlusData)) + { + await _ipcManager.PalettePlusSetPaletteAsync(tempHandler.Address, LoadedCharaFile.CharaFileData.PalettePlusData).ConfigureAwait(false); + } + else + { + await _ipcManager.PalettePlusRemovePaletteAsync(tempHandler.Address).ConfigureAwait(false); + } } } finally diff --git a/MareSynchronos/PlayerData/Factories/PlayerDataFactory.cs b/MareSynchronos/PlayerData/Factories/PlayerDataFactory.cs index c578f5e..5409497 100644 --- a/MareSynchronos/PlayerData/Factories/PlayerDataFactory.cs +++ b/MareSynchronos/PlayerData/Factories/PlayerDataFactory.cs @@ -73,6 +73,7 @@ public class PlayerDataFactory _logger.LogTrace("Pointer was zero for {objectKind}", playerRelatedObject.ObjectKind); previousData.FileReplacements.Remove(playerRelatedObject.ObjectKind); previousData.GlamourerString.Remove(playerRelatedObject.ObjectKind); + previousData.CustomizePlusScale.Remove(playerRelatedObject.ObjectKind); return; } @@ -373,20 +374,20 @@ public class PlayerDataFactory // gather up data from ipc previousData.ManipulationString = _ipcManager.PenumbraGetMetaManipulations(); - Task getHeelsOffset = _ipcManager.GetHeelsOffsetAsync(); + Task getHeelsOffset = _ipcManager.GetHeelsOffsetAsync(); Task getGlamourerData = _ipcManager.GlamourerGetCharacterCustomizationAsync(playerRelatedObject.Address); - Task getCustomizeData = _ipcManager.GetCustomizePlusScaleAsync(); + Task getCustomizeData = _ipcManager.GetCustomizePlusScaleAsync(playerRelatedObject.Address); Task getPalettePlusData = _ipcManager.PalettePlusBuildPaletteAsync(); previousData.GlamourerString[playerRelatedObject.ObjectKind] = await getGlamourerData.ConfigureAwait(false); _logger.LogDebug("Glamourer is now: {data}", previousData.GlamourerString[playerRelatedObject.ObjectKind]); - previousData.CustomizePlusScale = await getCustomizeData.ConfigureAwait(false); - _logger.LogDebug("Customize is now: {data}", previousData.CustomizePlusScale); + previousData.CustomizePlusScale[playerRelatedObject.ObjectKind] = await getCustomizeData.ConfigureAwait(false); + _logger.LogDebug("Customize is now: {data}", previousData.CustomizePlusScale[playerRelatedObject.ObjectKind]); previousData.PalettePlusPalette = await getPalettePlusData.ConfigureAwait(false); _logger.LogDebug("Palette is now: {data}", previousData.PalettePlusPalette); previousData.HonorificData = _ipcManager.HonorificGetTitle(); _logger.LogDebug("Honorific is now: {data}", previousData.HonorificData); - previousData.HeelsOffset = await getHeelsOffset.ConfigureAwait(false); - _logger.LogDebug("Heels is now: {heels}", previousData.HeelsOffset); + previousData.HeelsData = await getHeelsOffset.ConfigureAwait(false); + _logger.LogDebug("Heels is now: {heels}", previousData.HeelsData); st.Stop(); _logger.LogInformation("Building character data for {obj} took {time}ms", objectKind, TimeSpan.FromTicks(st.ElapsedTicks).TotalMilliseconds); diff --git a/MareSynchronos/PlayerData/Handlers/PairHandler.cs b/MareSynchronos/PlayerData/Handlers/PairHandler.cs index e4d602e..ef69572 100644 --- a/MareSynchronos/PlayerData/Handlers/PairHandler.cs +++ b/MareSynchronos/PlayerData/Handlers/PairHandler.cs @@ -229,11 +229,14 @@ public sealed class PairHandler : DisposableMediatorSubscriberBase break; case PlayerChanges.Customize: - await _ipcManager.CustomizePlusSetBodyScaleAsync(handler.Address, charaData.CustomizePlusData).ConfigureAwait(false); + if (charaData.CustomizePlusData.TryGetValue(changes.Key, out var customizePlusData)) + { + await _ipcManager.CustomizePlusSetBodyScaleAsync(handler.Address, customizePlusData).ConfigureAwait(false); + } break; case PlayerChanges.Heels: - await _ipcManager.HeelsSetOffsetForPlayerAsync(handler.Address, charaData.HeelsOffset).ConfigureAwait(false); + await _ipcManager.HeelsSetOffsetForPlayerAsync(handler.Address, charaData.HeelsData).ConfigureAwait(false); break; case PlayerChanges.Honorific: diff --git a/MareSynchronos/PlayerData/Services/CacheCreationService.cs b/MareSynchronos/PlayerData/Services/CacheCreationService.cs index 30dca5e..beab3b5 100644 --- a/MareSynchronos/PlayerData/Services/CacheCreationService.cs +++ b/MareSynchronos/PlayerData/Services/CacheCreationService.cs @@ -5,6 +5,7 @@ using MareSynchronos.PlayerData.Handlers; using MareSynchronos.Services; using MareSynchronos.Services.Mediator; using Microsoft.Extensions.Logging; +using System.Linq; namespace MareSynchronos.PlayerData.Services; @@ -53,15 +54,20 @@ public sealed class CacheCreationService : DisposableMediatorSubscriberBase Logger.LogTrace("Clearing cache for {obj}", msg.ObjectToCreateFor); _playerData.FileReplacements.Remove(msg.ObjectToCreateFor.ObjectKind); _playerData.GlamourerString.Remove(msg.ObjectToCreateFor.ObjectKind); + _playerData.CustomizePlusScale.Remove(msg.ObjectToCreateFor.ObjectKind); Mediator.Publish(new CharacterDataCreatedMessage(_playerData.ToAPI())); }); }); - Mediator.Subscribe(this, async (_) => + Mediator.Subscribe(this, async (msg) => { if (_isZoning) return; - Logger.LogDebug("Received CustomizePlus change, updating player"); - await AddPlayerCacheToCreate().ConfigureAwait(false); + foreach (var item in _playerRelatedObjects + .Where(item => string.Equals(item.Value.Name, msg.ProfileName, StringComparison.Ordinal)).Select(k => k.Key)) + { + Logger.LogDebug("Received CustomizePlus change, updating {obj}", item); + await AddPlayerCacheToCreate(item).ConfigureAwait(false); + } }); Mediator.Subscribe(this, async (_) => { @@ -104,10 +110,10 @@ public sealed class CacheCreationService : DisposableMediatorSubscriberBase _cts.Dispose(); } - private async Task AddPlayerCacheToCreate() + private async Task AddPlayerCacheToCreate(ObjectKind kind = ObjectKind.Player) { await _cacheCreateLock.WaitAsync().ConfigureAwait(false); - _cachesToCreate[ObjectKind.Player] = _playerRelatedObjects[ObjectKind.Player]; + _cachesToCreate[kind] = _playerRelatedObjects[kind]; _cacheCreateLock.Release(); } diff --git a/MareSynchronos/Services/Mediator/Messages.cs b/MareSynchronos/Services/Mediator/Messages.cs index 2c07710..e80f8f3 100644 --- a/MareSynchronos/Services/Mediator/Messages.cs +++ b/MareSynchronos/Services/Mediator/Messages.cs @@ -34,7 +34,7 @@ public record PenumbraDisposedMessage : MessageBase; public record PenumbraRedrawMessage(IntPtr Address, int ObjTblIdx, bool WasRequested) : SameThreadMessage; public record HeelsOffsetMessage : MessageBase; public record PenumbraResourceLoadMessage(IntPtr GameObject, string GamePath, string FilePath) : SameThreadMessage; -public record CustomizePlusMessage : MessageBase; +public record CustomizePlusMessage(string ProfileName) : MessageBase; public record PalettePlusMessage(Character Character) : MessageBase; public record HonorificMessage(string NewHonorificTitle) : MessageBase; public record HonorificReadyMessage : MessageBase; diff --git a/MareSynchronos/UI/DtrEntry.cs b/MareSynchronos/UI/DtrEntry.cs index 05d23eb..f1bb17e 100644 --- a/MareSynchronos/UI/DtrEntry.cs +++ b/MareSynchronos/UI/DtrEntry.cs @@ -52,7 +52,10 @@ public sealed class DtrEntry : IDisposable, IHostedService { await _runTask!.ConfigureAwait(false); } - catch (OperationCanceledException) { } + catch (OperationCanceledException) + { + // ignore cancelled + } finally { _cancellationTokenSource.Dispose(); diff --git a/MareSynchronos/Utils/VariousExtensions.cs b/MareSynchronos/Utils/VariousExtensions.cs index e785cf4..c4d44db 100644 --- a/MareSynchronos/Utils/VariousExtensions.cs +++ b/MareSynchronos/Utils/VariousExtensions.cs @@ -1,4 +1,5 @@ using Dalamud.Game.ClientState.Objects.Types; +using Dalamud.Utility; using MareSynchronos.API.Data; using MareSynchronos.API.Data.Enum; using MareSynchronos.PlayerData.Handlers; @@ -83,6 +84,16 @@ public static class VariousExtensions } } + oldData.CustomizePlusData.TryGetValue(objectKind, out var oldCustomizePlusData); + newData.CustomizePlusData.TryGetValue(objectKind, out var newCustomizePlusData); + + bool customizeDataDifferent = !string.Equals(oldCustomizePlusData, newCustomizePlusData, StringComparison.Ordinal); + if (customizeDataDifferent || (forceApplyCustomization && !string.IsNullOrEmpty(newCustomizePlusData))) + { + logger.LogDebug("[BASE-{appBase}] Updating {object}/{kind} (Diff customize data) => {change}", applicationBase, cachedPlayer, objectKind, PlayerChanges.Customize); + charaDataToUpdate[objectKind].Add(PlayerChanges.Customize); + } + if (objectKind != ObjectKind.Player) continue; bool manipDataDifferent = !string.Equals(oldData.ManipulationData, newData.ManipulationData, StringComparison.Ordinal); @@ -92,20 +103,13 @@ public static class VariousExtensions charaDataToUpdate[objectKind].Add(PlayerChanges.ModManip); } - bool heelsOffsetDifferent = oldData.HeelsOffset != newData.HeelsOffset; - if (heelsOffsetDifferent || (forceApplyCustomization && newData.HeelsOffset != 0)) + bool heelsOffsetDifferent = !string.Equals(oldData.HeelsData, newData.HeelsData, StringComparison.Ordinal); + if (heelsOffsetDifferent || (forceApplyCustomization && !string.IsNullOrEmpty(newData.HeelsData))) { logger.LogDebug("[BASE-{appBase}] Updating {object}/{kind} (Diff heels data) => {change}", applicationBase, cachedPlayer, objectKind, PlayerChanges.Heels); charaDataToUpdate[objectKind].Add(PlayerChanges.Heels); } - bool customizeDataDifferent = !string.Equals(oldData.CustomizePlusData, newData.CustomizePlusData, StringComparison.Ordinal); - if (customizeDataDifferent || (forceApplyCustomization && !string.IsNullOrEmpty(newData.CustomizePlusData))) - { - logger.LogDebug("[BASE-{appBase}] Updating {object}/{kind} (Diff customize data) => {change}", applicationBase, cachedPlayer, objectKind, PlayerChanges.Customize); - charaDataToUpdate[objectKind].Add(PlayerChanges.Customize); - } - bool palettePlusDataDifferent = !string.Equals(oldData.PalettePlusData, newData.PalettePlusData, StringComparison.Ordinal); if (palettePlusDataDifferent || (forceApplyCustomization && !string.IsNullOrEmpty(newData.PalettePlusData))) {