feat(ipc): mirror TypingIpc provider slots under ChatTwo namespace (v1.4.9 R4)
HellionChat replaces ChatTwo (conflict detection prevents parallel loading) but third-party plugins with a no-fork policy keep subscribing only to the ChatTwo.*-prefixed IPC gates. Mirroring the two TypingIpc provider slots under the ChatTwo namespace lets those plugins keep working without code changes on their side. Mirrored slots: - ChatTwo.GetChatInputState ←→ HellionChat.GetChatInputState - ChatTwo.ChatInputStateChanged ←→ HellionChat.ChatInputStateChanged Implementation: - Two additional ICallGateProvider fields (ChatTwoStateQueryGate + ChatTwoStateChangedGate) with the identical ChatInputState tuple signature. The tuple's underlying types match ChatTwo's surface byte- for-byte (bool/bool/bool/bool/int/ushort — ChatType is `ushort` in both repos), so Dalamud's IPC marshalling matches across plugin boundaries even when the subscribing plugin defines its own copy of the ChatType enum. - ctor registers the new provider gates and binds RegisterFunc(GetState) to ChatTwoStateQueryGate so query calls route to the same backing path. - Update() pushes the state to both ChatTwoStateChangedGate and the existing StateChangedGate in lockstep. - Dispose() unregisters both query gates. Ipc/ExtraChat.cs is intentionally unchanged — it is a subscriber on ExtraChat's own IPC, not a provider, so no compatibility mirror applies. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -19,6 +19,17 @@ internal sealed class TypingIpc : IDisposable
|
||||
private ICallGateProvider<ChatInputState> StateQueryGate { get; }
|
||||
private ICallGateProvider<ChatInputState, object?> 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<ChatInputState> ChatTwoStateQueryGate { get; }
|
||||
private ICallGateProvider<ChatInputState, object?> 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<ChatInputState>(
|
||||
"ChatTwo.GetChatInputState"
|
||||
);
|
||||
ChatTwoStateChangedGate = Plugin.Interface.GetIpcProvider<ChatInputState, object?>(
|
||||
"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();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user