MosswartMassacre/MosswartMassacre/ChatEventRouter.cs
erik f9264f2767 Phase 4: Extract ChatEventRouter and GameEventRouter
- ChatEventRouter.cs: routes chat events to KillTracker, RareTracker, handles
  allegiance report trigger and WebSocket chat streaming
- GameEventRouter.cs: routes ServerDispatch messages (0xF7B0, 0x02CF) to CharacterStats
- PluginCore no longer contains OnChatText, AllChatText, NormalizeChatLine,
  or EchoFilter_ServerDispatch methods

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-27 07:50:41 +00:00

90 lines
3.2 KiB
C#

using System;
using System.Text.RegularExpressions;
using Decal.Adapter;
using Decal.Adapter.Wrappers;
namespace MosswartMassacre
{
/// <summary>
/// Routes chat events to the appropriate handler (KillTracker, RareTracker, etc.)
/// Replaces the big if/else chain in PluginCore.OnChatText.
/// </summary>
internal class ChatEventRouter
{
private readonly IPluginLogger _logger;
private readonly KillTracker _killTracker;
private RareTracker _rareTracker;
private readonly Action<int> _onRareCountChanged;
private readonly Action<string> _onAllegianceReport;
internal void SetRareTracker(RareTracker rareTracker) => _rareTracker = rareTracker;
internal ChatEventRouter(
IPluginLogger logger,
KillTracker killTracker,
RareTracker rareTracker,
Action<int> onRareCountChanged,
Action<string> onAllegianceReport)
{
_logger = logger;
_killTracker = killTracker;
_rareTracker = rareTracker;
_onRareCountChanged = onRareCountChanged;
_onAllegianceReport = onAllegianceReport;
}
internal void OnChatText(object sender, ChatTextInterceptEventArgs e)
{
try
{
_killTracker.CheckForKill(e.Text);
if (_rareTracker != null && _rareTracker.CheckForRare(e.Text, out string rareText))
{
_killTracker.RareCount = _rareTracker.RareCount;
_onRareCountChanged?.Invoke(_rareTracker.RareCount);
}
if (e.Color == 18 && e.Text.EndsWith("!report\""))
{
TimeSpan elapsed = DateTime.Now - _killTracker.StatsStartTime;
string reportMessage = $"Total Kills: {_killTracker.TotalKills}, Kills per Hour: {_killTracker.KillsPerHour:F2}, Elapsed Time: {elapsed:dd\\.hh\\:mm\\:ss}, Rares Found: {_rareTracker?.RareCount ?? 0}";
_logger?.Log($"[Mosswart Massacre] Reporting to allegiance: {reportMessage}");
_onAllegianceReport?.Invoke(reportMessage);
}
}
catch (Exception ex)
{
_logger?.Log("Error processing chat message: " + ex.Message);
}
}
/// <summary>
/// Streams all chat text to WebSocket (separate handler from the filtered one above).
/// </summary>
internal static async void AllChatText(object sender, ChatTextInterceptEventArgs e)
{
try
{
string cleaned = NormalizeChatLine(e.Text);
await WebSocket.SendChatTextAsync(e.Color, cleaned);
}
catch (Exception ex)
{
PluginCore.WriteToChat($"[WS] Chat send failed: {ex}");
}
}
private static string NormalizeChatLine(string raw)
{
if (string.IsNullOrEmpty(raw))
return raw;
var noTags = Regex.Replace(raw, "<[^>]+>", "");
var trimmed = noTags.TrimEnd('\r', '\n');
var collapsed = Regex.Replace(trimmed, @"[ ]{2,}", " ");
return collapsed;
}
}
}