using Dalamud.Plugin; using Dalamud.Plugin.Ipc; using LightlessSync.Interop.Ipc.Framework; using LightlessSync.Services; using LightlessSync.Services.Mediator; using Microsoft.Extensions.Logging; namespace LightlessSync.Interop.Ipc; public sealed class IpcCallerHeels : IpcServiceBase { private static readonly IpcServiceDescriptor HeelsDescriptor = new("SimpleHeels", "Simple Heels", new Version(0, 0, 0, 0)); private readonly ILogger _logger; private readonly LightlessMediator _lightlessMediator; private readonly DalamudUtilService _dalamudUtil; private readonly ICallGateSubscriber<(int, int)> _heelsGetApiVersion; private readonly ICallGateSubscriber _heelsGetOffset; private readonly ICallGateSubscriber _heelsOffsetUpdate; private readonly ICallGateSubscriber _heelsRegisterPlayer; private readonly ICallGateSubscriber _heelsUnregisterPlayer; public IpcCallerHeels(ILogger logger, IDalamudPluginInterface pi, DalamudUtilService dalamudUtil, LightlessMediator lightlessMediator) : base(logger, lightlessMediator, pi, HeelsDescriptor) { _logger = logger; _lightlessMediator = lightlessMediator; _dalamudUtil = dalamudUtil; _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); CheckAPI(); } protected override IpcConnectionState EvaluateState() { var state = base.EvaluateState(); if (state != IpcConnectionState.Available) { return state; } try { return _heelsGetApiVersion.InvokeFunc() is { Item1: 2, Item2: >= 1 } ? IpcConnectionState.Available : IpcConnectionState.VersionMismatch; } catch (Exception ex) { _logger.LogDebug(ex, "Failed to query SimpleHeels API version"); return IpcConnectionState.Error; } } private void HeelsOffsetChange(string offset) { _lightlessMediator.Publish(new HeelsOffsetMessage()); } public async Task GetOffsetAsync() { if (!APIAvailable) return string.Empty; return await _dalamudUtil.RunOnFrameworkThread(_heelsGetOffset.InvokeFunc).ConfigureAwait(false); } public async Task RestoreOffsetForPlayerAsync(IntPtr character) { if (!APIAvailable) return; await _dalamudUtil.RunOnFrameworkThread(() => { var gameObj = _dalamudUtil.CreateGameObject(character); if (gameObj != null) { _logger.LogTrace("Restoring Heels data to {chara}", character.ToString("X")); _heelsUnregisterPlayer.InvokeAction(gameObj.ObjectIndex); } }).ConfigureAwait(false); } public async Task SetOffsetForPlayerAsync(IntPtr character, string data) { if (!APIAvailable) return; await _dalamudUtil.RunOnFrameworkThread(() => { var gameObj = _dalamudUtil.CreateGameObject(character); if (gameObj != null) { _logger.LogTrace("Applying Heels data to {chara}", character.ToString("X")); _heelsRegisterPlayer.InvokeAction(gameObj.ObjectIndex, data); } }).ConfigureAwait(false); } protected override void Dispose(bool disposing) { base.Dispose(disposing); if (!disposing) { return; } _heelsOffsetUpdate.Unsubscribe(HeelsOffsetChange); } }