diff --git a/MareSynchronos/Interop/IpcManager.cs b/MareSynchronos/Interop/IpcManager.cs index e6682bf..4fca4cb 100644 --- a/MareSynchronos/Interop/IpcManager.cs +++ b/MareSynchronos/Interop/IpcManager.cs @@ -36,9 +36,11 @@ public sealed class IpcManager : DisposableMediatorSubscriberBase private readonly ICallGateSubscriber _heelsUnregisterPlayer; private readonly ICallGateSubscriber<(uint major, uint minor)> _honorificApiVersion; private readonly ICallGateSubscriber _honorificClearCharacterTitle; - private readonly ICallGateSubscriber<(string Title, bool IsPrefix)> _honorificGetLocalCharacterTitle; - private readonly ICallGateSubscriber _honorificLocalCharacterTitleChanged; - private readonly ICallGateSubscriber _honorificSetCharacterTitle; + private readonly ICallGateSubscriber _honorificGetLocalCharacterTitle; + private readonly ICallGateSubscriber _honorificLocalCharacterTitleChanged; + private readonly ICallGateSubscriber _honorificSetCharacterTitle; + private readonly ICallGateSubscriber _honorificDisposing; + private readonly ICallGateSubscriber _honorificReady; private readonly ConcurrentQueue _normalQueue = new(); private readonly ICallGateSubscriber _palettePlusApiVersion; private readonly ICallGateSubscriber _palettePlusBuildCharaPalette; @@ -133,12 +135,16 @@ public sealed class IpcManager : DisposableMediatorSubscriberBase _palettePlusPaletteChanged.Subscribe(OnPalettePlusPaletteChange); _honorificApiVersion = pi.GetIpcSubscriber<(uint, uint)>("Honorific.ApiVersion"); - _honorificGetLocalCharacterTitle = pi.GetIpcSubscriber<(string, bool)>("Honorific.GetLocalCharacterTitle"); + _honorificGetLocalCharacterTitle = pi.GetIpcSubscriber("Honorific.GetLocalCharacterTitle"); _honorificClearCharacterTitle = pi.GetIpcSubscriber("Honorific.ClearCharacterTitle"); - _honorificSetCharacterTitle = pi.GetIpcSubscriber("Honorific.SetCharacterTitle"); - _honorificLocalCharacterTitleChanged = pi.GetIpcSubscriber("Honorific.LocalCharacterTitleChanged"); + _honorificSetCharacterTitle = pi.GetIpcSubscriber("Honorific.SetCharacterTitle"); + _honorificLocalCharacterTitleChanged = pi.GetIpcSubscriber("Honorific.LocalCharacterTitleChanged"); + _honorificDisposing = pi.GetIpcSubscriber("Honorific.Disposing"); + _honorificReady = pi.GetIpcSubscriber("Honorific.Ready"); _honorificLocalCharacterTitleChanged.Subscribe(OnHonorificLocalCharacterTitleChanged); + _honorificDisposing.Subscribe(OnHonorificDisposing); + _honorificReady.Subscribe(OnHonorificReady); if (Initialized) { @@ -323,11 +329,11 @@ public sealed class IpcManager : DisposableMediatorSubscriberBase public string HonorificGetTitle() { if (!CheckHonorificApi()) return string.Empty; - (string? title, bool isPrefix) = _honorificGetLocalCharacterTitle.InvokeFunc(); - return string.IsNullOrEmpty(title) ? string.Empty : $"{(isPrefix ? 1 : 0)}{title}"; + string title = _honorificGetLocalCharacterTitle.InvokeFunc(); + return string.IsNullOrEmpty(title) ? string.Empty : Convert.ToBase64String(Encoding.UTF8.GetBytes(title)); } - public async Task HonorificSetTitleAsync(IntPtr character, string honorificData) + public async Task HonorificSetTitleAsync(IntPtr character, string honorificDataB64) { if (!CheckHonorificApi()) return; Logger.LogTrace("Applying Honorific data to {chara}", character.ToString("X")); @@ -336,13 +342,14 @@ public sealed class IpcManager : DisposableMediatorSubscriberBase var gameObj = _dalamudUtil.CreateGameObject(character); if (gameObj is PlayerCharacter pc) { + string honorificData = string.IsNullOrEmpty(honorificDataB64) ? string.Empty : Encoding.UTF8.GetString(Convert.FromBase64String(honorificDataB64)); if (string.IsNullOrEmpty(honorificData)) { _honorificClearCharacterTitle!.InvokeAction(pc); } else { - _honorificSetCharacterTitle!.InvokeAction(pc, honorificData[1..], honorificData[0] == '1'); + _honorificSetCharacterTitle!.InvokeAction(pc, honorificData); } } }).ConfigureAwait(false); @@ -498,6 +505,8 @@ public sealed class IpcManager : DisposableMediatorSubscriberBase _palettePlusPaletteChanged.Unsubscribe(OnPalettePlusPaletteChange); _customizePlusOnScaleUpdate.Unsubscribe(OnCustomizePlusScaleChange); _honorificLocalCharacterTitleChanged.Unsubscribe(OnHonorificLocalCharacterTitleChanged); + _honorificDisposing.Unsubscribe(OnHonorificDisposing); + _honorificReady.Unsubscribe(OnHonorificReady); } private bool CheckCustomizePlusApiInternal() @@ -551,7 +560,7 @@ public sealed class IpcManager : DisposableMediatorSubscriberBase { try { - return _honorificApiVersion.InvokeFunc() is { Item1: 1, Item2: >= 0 }; + return _honorificApiVersion.InvokeFunc() is { Item1: 2, Item2: >= 0 }; } catch { @@ -636,9 +645,21 @@ public sealed class IpcManager : DisposableMediatorSubscriberBase Mediator.Publish(new CustomizePlusMessage()); } - private void OnHonorificLocalCharacterTitleChanged(string title, bool isPrefix) + private void OnHonorificLocalCharacterTitleChanged(string titleJson) { - Mediator.Publish(new HonorificMessage((isPrefix ? 1 : 0) + title)); + string titleData = string.IsNullOrEmpty(titleJson) ? string.Empty : Convert.ToBase64String(Encoding.UTF8.GetBytes(titleJson)); + Mediator.Publish(new HonorificMessage(titleData)); + } + + private void OnHonorificDisposing() + { + Mediator.Publish(new HonorificMessage(string.Empty)); + } + + private void OnHonorificReady() + { + _honorificAvailable = CheckHonorificApiInternal(); + Mediator.Publish(new HonorificReadyMessage()); } private void OnPalettePlusPaletteChange(Character character, string palette) diff --git a/MareSynchronos/PlayerData/Pairs/CachedPlayer.cs b/MareSynchronos/PlayerData/Pairs/CachedPlayer.cs index 9616977..da48de2 100644 --- a/MareSynchronos/PlayerData/Pairs/CachedPlayer.cs +++ b/MareSynchronos/PlayerData/Pairs/CachedPlayer.cs @@ -535,6 +535,12 @@ public sealed class CachedPlayer : DisposableMediatorSubscriberBase _lastGlamourerData = await _ipcManager.GlamourerGetCharacterCustomizationAsync(PlayerCharacter).ConfigureAwait(false); } }); + Mediator.Subscribe(this, async (_) => + { + if (string.IsNullOrEmpty(_cachedData?.HonorificData)) return; + Logger.LogTrace("Reapplying Honorific data for {this}", this); + await _ipcManager.HonorificSetTitleAsync(PlayerCharacter, _cachedData.HonorificData).ConfigureAwait(false); + }); _downloadManager.Initialize(); } diff --git a/MareSynchronos/Services/Mediator/Messages.cs b/MareSynchronos/Services/Mediator/Messages.cs index 1b2a59c..c390a2c 100644 --- a/MareSynchronos/Services/Mediator/Messages.cs +++ b/MareSynchronos/Services/Mediator/Messages.cs @@ -36,6 +36,7 @@ public record PenumbraResourceLoadMessage(IntPtr GameObject, string GamePath, st public record CustomizePlusMessage : MessageBase; public record PalettePlusMessage(Character Character) : MessageBase; public record HonorificMessage(string NewHonorificTitle) : MessageBase; +public record HonorificReadyMessage : MessageBase; public record PlayerChangedMessage(CharacterData Data) : MessageBase; public record CharacterChangedMessage(GameObjectHandler GameObjectHandler) : MessageBase; public record TransientResourceChangedMessage(IntPtr Address) : MessageBase;