using Dalamud.Logging; using Dalamud.Plugin; using Dalamud.Plugin.Ipc; using System; namespace MareSynchronos.Managers { public class IpcManager : IDisposable { private readonly DalamudPluginInterface pluginInterface; private ICallGateSubscriber penumbraInit; private ICallGateSubscriber? penumbraResolvePath; private ICallGateSubscriber? penumbraResolveModDir; private ICallGateSubscriber? glamourerGetCharacterCustomization; private ICallGateSubscriber? glamourerApplyCharacterCustomization; private ICallGateSubscriber penumbraApiVersion; private ICallGateSubscriber glamourerApiVersion; private ICallGateSubscriber penumbraObjectIsRedrawn; private ICallGateSubscriber? penumbraRedraw; private ICallGateSubscriber? penumbraReverseResolvePath; private ICallGateSubscriber glamourerRevertCustomization; public bool Initialized { get; private set; } = false; public event EventHandler? PenumbraRedrawEvent; public IpcManager(DalamudPluginInterface pi) { pluginInterface = pi; penumbraInit = pluginInterface.GetIpcSubscriber("Penumbra.Initialized"); penumbraResolvePath = pluginInterface.GetIpcSubscriber("Penumbra.ResolveCharacterPath"); penumbraResolveModDir = pluginInterface.GetIpcSubscriber("Penumbra.GetModDirectory"); penumbraRedraw = pluginInterface.GetIpcSubscriber("Penumbra.RedrawObjectByName"); glamourerGetCharacterCustomization = pluginInterface.GetIpcSubscriber("Glamourer.GetCharacterCustomization"); glamourerApplyCharacterCustomization = pluginInterface.GetIpcSubscriber("Glamourer.ApplyCharacterCustomization"); penumbraReverseResolvePath = pluginInterface.GetIpcSubscriber("Penumbra.ReverseResolvePath"); penumbraApiVersion = pluginInterface.GetIpcSubscriber("Penumbra.ApiVersion"); glamourerApiVersion = pluginInterface.GetIpcSubscriber("Glamourer.ApiVersion"); glamourerRevertCustomization = pluginInterface.GetIpcSubscriber("Glamourer.RevertCharacterCustomization"); penumbraObjectIsRedrawn = pluginInterface.GetIpcSubscriber("Penumbra.GameObjectRedrawn"); penumbraObjectIsRedrawn.Subscribe(RedrawEvent); penumbraInit.Subscribe(RedrawSelf); Initialized = true; } public bool CheckPenumbraAPI() { try { return penumbraApiVersion.InvokeFunc() >= 4; } catch { return false; } } public bool CheckGlamourerAPI() { try { return glamourerApiVersion.InvokeFunc() >= 0; } catch { return false; } } private void RedrawEvent(IntPtr objectAddress, int objectTableIndex) { PenumbraRedrawEvent?.Invoke(objectTableIndex, EventArgs.Empty); } private void RedrawSelf() { penumbraRedraw!.InvokeAction("self", 0); } private void Uninitialize() { penumbraInit.Unsubscribe(RedrawSelf); penumbraObjectIsRedrawn.Unsubscribe(RedrawEvent); penumbraResolvePath = null; penumbraResolveModDir = null; glamourerGetCharacterCustomization = null; glamourerApplyCharacterCustomization = null; penumbraReverseResolvePath = null; Initialized = false; PluginLog.Debug("IPC Manager disposed"); } public string[] PenumbraReverseResolvePath(string path, string characterName) { if (!CheckPenumbraAPI()) return new[] { path }; return penumbraReverseResolvePath!.InvokeFunc(path, characterName); } public string? PenumbraResolvePath(string path, string characterName) { if (!CheckPenumbraAPI()) return null; return penumbraResolvePath!.InvokeFunc(path, characterName); } public string? PenumbraModDirectory() { if (!CheckPenumbraAPI()) return null; return penumbraResolveModDir!.InvokeFunc(); } public string? GlamourerGetCharacterCustomization() { if (!CheckGlamourerAPI()) return null; return glamourerGetCharacterCustomization!.InvokeFunc(); } public void GlamourerApplyCharacterCustomization(string customization, string characterName) { if (!CheckGlamourerAPI()) return; glamourerApplyCharacterCustomization!.InvokeAction(customization, characterName); } public void GlamourerRevertCharacterCustomization(string characterName) { if (!CheckGlamourerAPI()) return; glamourerRevertCustomization!.InvokeAction(characterName); } public void PenumbraRedraw(string actorName) { if (!CheckPenumbraAPI()) return; penumbraRedraw!.InvokeAction(actorName, 0); } public void Dispose() { Uninitialize(); } } }