75 lines
2.5 KiB
C#
75 lines
2.5 KiB
C#
using System;
|
|
using Dalamud.Hooking;
|
|
using Dalamud.Interface.ImGuiNotification;
|
|
using FFXIVClientStructs.FFXIV.Client.System.String;
|
|
using FFXIVClientStructs.FFXIV.Client.UI.Misc;
|
|
using HellionChat._Helpers;
|
|
using HellionChat.Resources;
|
|
using HellionChat.Util;
|
|
using Microsoft.Extensions.Logging;
|
|
|
|
namespace HellionChat.Integrations;
|
|
|
|
// A minimal, failed-tell-specific game hook. A locale-robust "tell failed"
|
|
// signal is not reachable over the processed message stream (Message carries
|
|
// no LogMessage row id, ChatCode 60 is too broad). This hooks the one
|
|
// ShowLogMessageString overload and toasts on a pinned id set. It is NOT the
|
|
// broad ad-block hook layer.
|
|
internal sealed class FailedTellNotifier : IDisposable
|
|
{
|
|
private readonly ILogger<FailedTellNotifier> _logger;
|
|
private readonly Hook<RaptureLogModule.Delegates.ShowLogMessageString>? _hook;
|
|
|
|
public unsafe FailedTellNotifier(ILogger<FailedTellNotifier> logger)
|
|
{
|
|
_logger = logger;
|
|
|
|
// Creating/enabling a hook is safe off the framework thread (the
|
|
// ctor runs during host startup on the framework thread,
|
|
// eager-resolved via FailedTellNotifierInitHostedService).
|
|
_hook =
|
|
Plugin.GameInteropProvider.HookFromAddress<RaptureLogModule.Delegates.ShowLogMessageString>(
|
|
RaptureLogModule.MemberFunctionPointers.ShowLogMessageString,
|
|
ShowLogMessageStringDetour
|
|
);
|
|
_hook.Enable();
|
|
}
|
|
|
|
private unsafe void ShowLogMessageStringDetour(
|
|
RaptureLogModule* module,
|
|
uint logMessageId,
|
|
Utf8String* value
|
|
)
|
|
{
|
|
try
|
|
{
|
|
if (
|
|
FailedTellMatcher.ShouldNotify(
|
|
logMessageId,
|
|
Plugin.Config.NotifyFailedTell,
|
|
FailedTellMatcher.FailedTellLogMessageIds
|
|
)
|
|
)
|
|
{
|
|
var recipient = value is null ? string.Empty : value->ToString();
|
|
var content = string.IsNullOrEmpty(recipient)
|
|
? HellionStrings.FailedTell_Notification_Generic
|
|
: string.Format(HellionStrings.FailedTell_Notification_Named, recipient);
|
|
WrapperUtil.AddNotification(content, NotificationType.Warning);
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError(ex, "FailedTellNotifier detour threw");
|
|
}
|
|
|
|
_hook!.Original(module, logMessageId, value);
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
_hook?.Disable();
|
|
_hook?.Dispose();
|
|
}
|
|
}
|