using Dalamud.Logging; using Dalamud.Plugin; using Dalamud.Plugin.Ipc; using System; using System.Collections.Generic; using System.Collections.Immutable; using System.Reflection.Metadata; namespace MareSynchronos.Managers { public class IpcManager : IDisposable { private readonly DalamudPluginInterface _pluginInterface; private readonly ICallGateSubscriber _penumbraInit; private readonly ICallGateSubscriber? _penumbraResolvePath; private readonly ICallGateSubscriber? _penumbraResolveModDir; private readonly ICallGateSubscriber? _glamourerGetCharacterCustomization; private readonly ICallGateSubscriber? _glamourerApplyCharacterCustomization; private readonly ICallGateSubscriber _penumbraApiVersion; private readonly ICallGateSubscriber _glamourerApiVersion; private readonly ICallGateSubscriber _penumbraObjectIsRedrawn; private readonly ICallGateSubscriber? _penumbraRedraw; private readonly ICallGateSubscriber? _penumbraReverseResolvePath; private readonly ICallGateSubscriber _glamourerRevertCustomization; private readonly ICallGateSubscriber, List, int, int> _penumbraSetTemporaryMod; private readonly ICallGateSubscriber _penumbraCreateTemporaryCollection; private readonly ICallGateSubscriber _penumbraRemoveTemporaryCollection; 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); _penumbraSetTemporaryMod = _pluginInterface .GetIpcSubscriber, List, int, int>("Penumbra.AddTemporaryMod"); _penumbraCreateTemporaryCollection = _pluginInterface.GetIpcSubscriber("Penumbra.CreateTemporaryCollection"); _penumbraRemoveTemporaryCollection = _pluginInterface.GetIpcSubscriber("Penumbra.RemoveTemporaryCollection"); 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); 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 PenumbraCreateTemporaryCollection(string characterName) { if (!CheckPenumbraApi()) return; PluginLog.Debug("Creating temp collection for " + characterName); //penumbraCreateTemporaryCollection.InvokeFunc("MareSynchronos", characterName, true); } public void PenumbraRemoveTemporaryCollection(string characterName) { if (!CheckPenumbraApi()) return; PluginLog.Debug("Removing temp collection for " + characterName); //penumbraRemoveTemporaryCollection.InvokeFunc(characterName); } public void PenumbraSetTemporaryMods(string characterName, IReadOnlyDictionary modPaths) { if (!CheckPenumbraApi()) return; PluginLog.Debug("Assigning temp mods for " + characterName); //penumbraSetTemporaryMod.InvokeFunc("MareSynchronos", characterName, modPaths, new List(), 0); } public void Dispose() { Uninitialize(); } } }