mirror of
https://github.com/RedWizardsLab/EchoHub.git
synced 2026-09-04 16:46:08 +02:00
- Add IrcGatewayService to handle IRC connections and commands. - Create IrcMessage class for parsing IRC protocol lines. - Implement IrcMessageFormatter for formatting messages as IRC lines. - Define IrcNumericReply constants for IRC numeric replies. - Add IrcOptions class for configuration settings related to IRC. - Create IrcServiceExtensions for adding IRC services to the application. - Refactor ChannelsController to use IChatService for broadcasting messages and channel updates. - Update ChatHub to utilize IChatService for user connection and message handling. - Introduce ChatService to manage chat-related operations and interactions. - Implement SignalRBroadcaster for broadcasting messages to SignalR clients. - Update PresenceTracker to retrieve usernames for connections. - Modify appsettings.example.json to include IRC configuration options. - Update solution file to include the new IRC project.
81 lines
2.6 KiB
C#
81 lines
2.6 KiB
C#
using System.Text;
|
|
using EchoHub.Core.DTOs;
|
|
using EchoHub.Core.Models;
|
|
|
|
namespace EchoHub.Server.Irc;
|
|
|
|
public static class IrcMessageFormatter
|
|
{
|
|
private const int MaxIrcLineContentBytes = 400;
|
|
|
|
/// <summary>
|
|
/// Format a MessageDto as one or more IRC PRIVMSG lines.
|
|
/// </summary>
|
|
public static List<string> FormatMessage(MessageDto message)
|
|
{
|
|
var lines = new List<string>();
|
|
var ircChannel = $"#{message.ChannelName}";
|
|
var prefix = $":{message.SenderUsername}!{message.SenderUsername}@echohub";
|
|
|
|
switch (message.Type)
|
|
{
|
|
case MessageType.Text:
|
|
foreach (var chunk in SplitMessage(message.Content, MaxIrcLineContentBytes))
|
|
lines.Add($"{prefix} PRIVMSG {ircChannel} :{chunk}");
|
|
break;
|
|
|
|
case MessageType.Image:
|
|
lines.Add($"{prefix} PRIVMSG {ircChannel} :[Image: {message.AttachmentFileName}]");
|
|
if (message.AttachmentUrl is not null)
|
|
lines.Add($"{prefix} PRIVMSG {ircChannel} :Download: {message.AttachmentUrl}");
|
|
|
|
foreach (var line in message.Content.Split('\n'))
|
|
{
|
|
var trimmed = line.TrimEnd('\r');
|
|
if (trimmed.Length > 0)
|
|
lines.Add($"{prefix} PRIVMSG {ircChannel} :{trimmed}");
|
|
}
|
|
break;
|
|
|
|
case MessageType.File:
|
|
lines.Add($"{prefix} PRIVMSG {ircChannel} :[File: {message.AttachmentFileName}] {message.AttachmentUrl}");
|
|
break;
|
|
}
|
|
|
|
return lines;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Split a message into chunks of approximately maxBytes (UTF-8), at word boundaries.
|
|
/// </summary>
|
|
public static List<string> SplitMessage(string content, int maxBytes)
|
|
{
|
|
if (Encoding.UTF8.GetByteCount(content) <= maxBytes)
|
|
return [content];
|
|
|
|
var chunks = new List<string>();
|
|
var current = new StringBuilder();
|
|
var currentBytes = 0;
|
|
|
|
foreach (var word in content.Split(' '))
|
|
{
|
|
var wordBytes = Encoding.UTF8.GetByteCount(word) + 1; // +1 for space
|
|
|
|
if (currentBytes + wordBytes > maxBytes && current.Length > 0)
|
|
{
|
|
chunks.Add(current.ToString().TrimEnd());
|
|
current.Clear();
|
|
currentBytes = 0;
|
|
}
|
|
|
|
current.Append(word).Append(' ');
|
|
currentBytes += wordBytes;
|
|
}
|
|
|
|
if (current.Length > 0)
|
|
chunks.Add(current.ToString().TrimEnd());
|
|
|
|
return chunks;
|
|
}
|
|
}
|