7a1bd1babc
Seven services across Integrations/, Ipc/ and GameFunctions/ shift from Plugin.LogProxy to Microsoft.Extensions.Logging.ILogger<T>. Files with live LogProxy sites (10 in total): - Ipc/ExtraChat (1) - GameFunctions/Chat (6) - GameFunctions/GameFunctions (2) - GameFunctions/KeybindManager (1) Foundation-touch files (no current sites, ctor takes ILogger<T> as seed for the v1.5.7-11 Plugin-Integrations wave): - Integrations/HonorificService (also drops the local IPluginLog _log field in favour of ILogger<HonorificService> _logger; the three _log.* calls there are migrated as a bonus since the field had to change anyway) - IpcManager - Ipc/TypingIpc GameFunctions takes ILoggerFactory as an extra ctor arg so it can hand a typed logger to its nested Chat and KeybindManager (same pattern MessageStore + MessageEnumerator use in Slice A). PluginHostFactory factory lambdas updated for all five Slice B services that need extra resolves. Plan drift D8: GameFunctions.TryOpenAdventurerPlate is an internal static method whose only Warning call cannot reach the instance _logger. The one site stays on Plugin.LogProxy with an inline note; promoting it to instance + PayloadHandler.cs:814 call-site update is a v1.5.1+ cleanup, out of DI-4 Slice B scope.
90 lines
3.2 KiB
C#
90 lines
3.2 KiB
C#
using Dalamud.Plugin.Ipc;
|
|
using Microsoft.Extensions.Logging;
|
|
|
|
namespace HellionChat.Ipc;
|
|
|
|
public sealed class ExtraChat : IDisposable
|
|
{
|
|
private readonly ILogger<ExtraChat> _logger;
|
|
|
|
#pragma warning disable CS0649 // Assigned through IPC
|
|
[Serializable]
|
|
private struct OverrideInfo
|
|
{
|
|
public string? Channel;
|
|
public ushort UiColour;
|
|
public uint Rgba;
|
|
}
|
|
#pragma warning restore CS0649
|
|
|
|
private ICallGateSubscriber<OverrideInfo, object> OverrideChannelGate { get; }
|
|
private ICallGateSubscriber<
|
|
Dictionary<string, uint>,
|
|
Dictionary<string, uint>
|
|
> ChannelCommandColoursGate { get; }
|
|
private ICallGateSubscriber<
|
|
Dictionary<Guid, string>,
|
|
Dictionary<Guid, string>
|
|
> ChannelNamesGate { get; }
|
|
|
|
internal (string, uint)? ChannelOverride { get; set; }
|
|
|
|
// volatile: IPC callbacks fire on a Dalamud thread while ImGui reads these.
|
|
// Reference assignment is atomic on x64, but the barrier ensures visibility
|
|
// across threads (especially Mono/Wine). See AUDIT-2026-05-05 [SEC-01].
|
|
private volatile Dictionary<string, uint> ChannelCommandColoursInternal = new();
|
|
internal IReadOnlyDictionary<string, uint> ChannelCommandColours =>
|
|
ChannelCommandColoursInternal;
|
|
|
|
private volatile Dictionary<Guid, string> ChannelNamesInternal = new();
|
|
internal IReadOnlyDictionary<Guid, string> ChannelNames => ChannelNamesInternal;
|
|
|
|
internal ExtraChat(ILogger<ExtraChat> logger)
|
|
{
|
|
_logger = logger;
|
|
OverrideChannelGate = Plugin.Interface.GetIpcSubscriber<OverrideInfo, object>(
|
|
"ExtraChat.OverrideChannelColour"
|
|
);
|
|
ChannelCommandColoursGate = Plugin.Interface.GetIpcSubscriber<
|
|
Dictionary<string, uint>,
|
|
Dictionary<string, uint>
|
|
>("ExtraChat.ChannelCommandColours");
|
|
ChannelNamesGate = Plugin.Interface.GetIpcSubscriber<
|
|
Dictionary<Guid, string>,
|
|
Dictionary<Guid, string>
|
|
>("ExtraChat.ChannelNames");
|
|
|
|
OverrideChannelGate.Subscribe(OnOverrideChannel);
|
|
ChannelCommandColoursGate.Subscribe(OnChannelCommandColours);
|
|
ChannelNamesGate.Subscribe(OnChannelNames);
|
|
|
|
try
|
|
{
|
|
ChannelCommandColoursInternal = ChannelCommandColoursGate.InvokeFunc(null!);
|
|
ChannelNamesInternal = ChannelNamesGate.InvokeFunc(null!);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
// ExtraChat is optional; IPC failure is normal when the plugin isn't loaded.
|
|
_logger.LogTrace(ex, "ExtraChat IPC initial state query failed (peer not loaded?)");
|
|
}
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
OverrideChannelGate.Unsubscribe(OnOverrideChannel);
|
|
ChannelCommandColoursGate.Unsubscribe(OnChannelCommandColours);
|
|
ChannelNamesGate.Unsubscribe(OnChannelNames);
|
|
}
|
|
|
|
private void OnOverrideChannel(OverrideInfo info)
|
|
{
|
|
ChannelOverride = info.Channel == null ? null : (info.Channel, info.Rgba);
|
|
}
|
|
|
|
private void OnChannelCommandColours(Dictionary<string, uint> obj) =>
|
|
ChannelCommandColoursInternal = obj;
|
|
|
|
private void OnChannelNames(Dictionary<Guid, string> obj) => ChannelNamesInternal = obj;
|
|
}
|