diff --git a/HellionChat/Ipc/TypingIpc.cs b/HellionChat/Ipc/TypingIpc.cs index 474c8ff..33b6fd6 100644 --- a/HellionChat/Ipc/TypingIpc.cs +++ b/HellionChat/Ipc/TypingIpc.cs @@ -19,6 +19,17 @@ internal sealed class TypingIpc : IDisposable private ICallGateProvider StateQueryGate { get; } private ICallGateProvider StateChangedGate { get; } + // v1.4.9 R4: ChatTwo IPC compatibility mirror. Some third-party plugins + // have a no-fork policy and subscribe only to ChatTwo.*-prefixed IPC + // gates. HellionChat replaces ChatTwo (conflict detection prevents + // parallel loading), so mirroring the ChatTwo provider slots lets those + // plugins keep working without code changes on their side. The tuple + // shape is textually identical to ChatTwo's IPC surface (same member + // order, same underlying types — ChatType is `ushort` in both repos) + // so Dalamud's IPC marshalling matches across plugin boundaries. + private ICallGateProvider ChatTwoStateQueryGate { get; } + private ICallGateProvider ChatTwoStateChangedGate { get; } + private ChatInputState LastState; private bool HasState; @@ -33,7 +44,16 @@ internal sealed class TypingIpc : IDisposable "HellionChat.ChatInputStateChanged" ); + // v1.4.9 R4: ChatTwo-prefixed compatibility slots (see class-level comment). + ChatTwoStateQueryGate = Plugin.Interface.GetIpcProvider( + "ChatTwo.GetChatInputState" + ); + ChatTwoStateChangedGate = Plugin.Interface.GetIpcProvider( + "ChatTwo.ChatInputStateChanged" + ); + StateQueryGate.RegisterFunc(GetState); + ChatTwoStateQueryGate.RegisterFunc(GetState); } private ChatInputState BuildState() @@ -67,10 +87,13 @@ internal sealed class TypingIpc : IDisposable HasState = true; LastState = state; StateChangedGate.SendMessage(state); + // v1.4.9 R4: mirror on ChatTwo-prefixed slot for no-fork-policy plugins. + ChatTwoStateChangedGate.SendMessage(state); } public void Dispose() { StateQueryGate.UnregisterFunc(); + ChatTwoStateQueryGate.UnregisterFunc(); } }