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 <root.darkarchon@outlook.com>
This commit is contained in:
@@ -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<string> _customizePlusApiVersion;
|
||||
private readonly ICallGateSubscriber<string, string> _customizePlusGetBodyScale;
|
||||
private readonly ICallGateSubscriber<string?, object> _customizePlusOnScaleUpdate;
|
||||
private readonly ICallGateSubscriber<Character?, object> _customizePlusRevert;
|
||||
private readonly ICallGateSubscriber<(int, int)> _customizePlusApiVersion;
|
||||
private readonly ICallGateSubscriber<Character?, string?> _customizePlusGetBodyScale;
|
||||
private readonly ICallGateSubscriber<string?, string?, object> _customizePlusOnScaleUpdate;
|
||||
private readonly ICallGateSubscriber<Character?, object> _customizePlusRevertCharacter;
|
||||
private readonly ICallGateSubscriber<string, Character?, object> _customizePlusSetBodyScaleToCharacter;
|
||||
private readonly DalamudUtilService _dalamudUtil;
|
||||
private readonly ICallGateSubscriber<int> _glamourerApiVersion;
|
||||
@@ -28,11 +28,10 @@ public sealed class IpcManager : DisposableMediatorSubscriberBase
|
||||
private readonly ICallGateSubscriber<string, GameObject?, object>? _glamourerApplyOnlyCustomization;
|
||||
private readonly ICallGateSubscriber<string, GameObject?, object>? _glamourerApplyOnlyEquipment;
|
||||
private readonly ICallGateSubscriber<GameObject?, string>? _glamourerGetAllCustomization;
|
||||
private readonly ConcurrentQueue<Action> _gposeActionQueue = new();
|
||||
private readonly ICallGateSubscriber<string> _heelsGetApiVersion;
|
||||
private readonly ICallGateSubscriber<float> _heelsGetOffset;
|
||||
private readonly ICallGateSubscriber<float, object?> _heelsOffsetUpdate;
|
||||
private readonly ICallGateSubscriber<GameObject, float, object?> _heelsRegisterPlayer;
|
||||
private readonly ICallGateSubscriber<(int, int)> _heelsGetApiVersion;
|
||||
private readonly ICallGateSubscriber<string> _heelsGetOffset;
|
||||
private readonly ICallGateSubscriber<string, object?> _heelsOffsetUpdate;
|
||||
private readonly ICallGateSubscriber<GameObject, string, object?> _heelsRegisterPlayer;
|
||||
private readonly ICallGateSubscriber<GameObject, object?> _heelsUnregisterPlayer;
|
||||
private readonly ICallGateSubscriber<(uint major, uint minor)> _honorificApiVersion;
|
||||
private readonly ICallGateSubscriber<Character, object> _honorificClearCharacterTitle;
|
||||
@@ -41,7 +40,6 @@ public sealed class IpcManager : DisposableMediatorSubscriberBase
|
||||
private readonly ICallGateSubscriber<string, object> _honorificLocalCharacterTitleChanged;
|
||||
private readonly ICallGateSubscriber<object> _honorificReady;
|
||||
private readonly ICallGateSubscriber<Character, string, object> _honorificSetCharacterTitle;
|
||||
private readonly ConcurrentQueue<Action> _normalQueue = new();
|
||||
private readonly ICallGateSubscriber<string> _palettePlusApiVersion;
|
||||
private readonly ICallGateSubscriber<Character, string> _palettePlusBuildCharaPalette;
|
||||
private readonly ICallGateSubscriber<Character, string, object> _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<string, GameObject?, object>("Glamourer.ApplyOnlyCustomizationToCharacter");
|
||||
_glamourerApplyOnlyEquipment = pi.GetIpcSubscriber<string, GameObject?, object>("Glamourer.ApplyOnlyEquipmentToCharacter");
|
||||
|
||||
_heelsGetApiVersion = pi.GetIpcSubscriber<string>("HeelsPlugin.ApiVersion");
|
||||
_heelsGetOffset = pi.GetIpcSubscriber<float>("HeelsPlugin.GetOffset");
|
||||
_heelsRegisterPlayer = pi.GetIpcSubscriber<GameObject, float, object?>("HeelsPlugin.RegisterPlayer");
|
||||
_heelsUnregisterPlayer = pi.GetIpcSubscriber<GameObject, object?>("HeelsPlugin.UnregisterPlayer");
|
||||
_heelsOffsetUpdate = pi.GetIpcSubscriber<float, object?>("HeelsPlugin.OffsetChanged");
|
||||
_heelsGetApiVersion = pi.GetIpcSubscriber<(int, int)>("SimpleHeels.ApiVersion");
|
||||
_heelsGetOffset = pi.GetIpcSubscriber<string>("SimpleHeels.GetLocalPlayer");
|
||||
_heelsRegisterPlayer = pi.GetIpcSubscriber<GameObject, string, object?>("SimpleHeels.RegisterPlayer");
|
||||
_heelsUnregisterPlayer = pi.GetIpcSubscriber<GameObject, object?>("SimpleHeels.UnregisterPlayer");
|
||||
_heelsOffsetUpdate = pi.GetIpcSubscriber<string, object?>("SimpleHeels.LocalChanged");
|
||||
|
||||
_heelsOffsetUpdate.Subscribe(HeelsOffsetChange);
|
||||
|
||||
_customizePlusApiVersion = pi.GetIpcSubscriber<string>("CustomizePlus.GetApiVersion");
|
||||
_customizePlusGetBodyScale = pi.GetIpcSubscriber<string, string>("CustomizePlus.GetBodyScale");
|
||||
_customizePlusRevert = pi.GetIpcSubscriber<Character?, object>("CustomizePlus.RevertCharacter");
|
||||
_customizePlusSetBodyScaleToCharacter = pi.GetIpcSubscriber<string, Character?, object>("CustomizePlus.SetBodyScaleToCharacter");
|
||||
_customizePlusOnScaleUpdate = pi.GetIpcSubscriber<string?, object>("CustomizePlus.OnScaleUpdate");
|
||||
_customizePlusApiVersion = pi.GetIpcSubscriber<(int, int)>("CustomizePlus.GetApiVersion");
|
||||
_customizePlusGetBodyScale = pi.GetIpcSubscriber<Character?, string?>("CustomizePlus.GetProfileFromCharacter");
|
||||
_customizePlusRevertCharacter = pi.GetIpcSubscriber<Character?, object>("CustomizePlus.RevertCharacter");
|
||||
_customizePlusSetBodyScaleToCharacter = pi.GetIpcSubscriber<string, Character?, object>("CustomizePlus.SetProfileToCharacter");
|
||||
_customizePlusOnScaleUpdate = pi.GetIpcSubscriber<string?, string?, object>("CustomizePlus.OnProfileUpdate");
|
||||
|
||||
_customizePlusOnScaleUpdate.Subscribe(OnCustomizePlusScaleChange);
|
||||
|
||||
@@ -151,9 +148,6 @@ public sealed class IpcManager : DisposableMediatorSubscriberBase
|
||||
Mediator.Publish(new PenumbraInitializedMessage());
|
||||
}
|
||||
|
||||
Mediator.Subscribe<FrameworkUpdateMessage>(this, (_) => HandleActionQueue());
|
||||
Mediator.Subscribe<CutsceneFrameworkUpdateMessage>(this, (_) => HandleGposeActionQueue());
|
||||
Mediator.Subscribe<ZoneSwitchEndMessage>(this, (_) => ClearActionQueue());
|
||||
Mediator.Subscribe<DelayedFrameworkUpdateMessage>(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<Action> 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<string> GetCustomizePlusScaleAsync()
|
||||
public async Task<string> 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<float> GetHeelsOffsetAsync()
|
||||
public async Task<string> 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();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user