sharp-chat/SharpChat.Protocol.IRC/ServerCommands/ServerPrivateMessageCommand.cs

65 lines
2.4 KiB
C#
Raw Permalink Normal View History

2022-08-30 15:05:29 +00:00
using SharpChat.Channels;
using SharpChat.Events;
using SharpChat.Messages;
using SharpChat.Protocol.IRC.Channels;
using SharpChat.Protocol.IRC.Users;
using SharpChat.Users;
using System;
using System.Collections.Generic;
using System.Text;
namespace SharpChat.Protocol.IRC.ServerCommands {
public class ServerPrivateMessageCommand : ServerCommand {
public const string NAME = @"PRIVMSG";
public override string CommandName => NAME;
private IChannel Channel { get; }
public override IUser Sender { get; }
private string Line { get; }
public ServerPrivateMessageCommand(IChannel channel, IUser sender, string line) {
Channel = channel ?? throw new ArgumentNullException(nameof(channel));
Sender = sender ?? throw new ArgumentNullException(nameof(sender));
Line = line ?? throw new ArgumentNullException(nameof(line));
}
protected override string BuildLine() {
return $@"{Channel.GetIRCName()} :{Line}";
}
public static IEnumerable<ServerPrivateMessageCommand> Split(IMessage message) {
return Split(message.Channel, message.Sender, message.Text);
}
public static IEnumerable<ServerPrivateMessageCommand> Split(IChannel channel, IUser sender, string text) {
Queue<string> parts = new(SplitText(text));
while(parts.TryDequeue(out string part))
yield return new ServerPrivateMessageCommand(channel, sender, part);
}
public static IEnumerable<string> SplitText(string text, int targetLength = 400) {
Queue<string> lines = new(text.Split('\n'));
static int getStartingChar(byte[] buff, int index) {
return (buff[index] & 0xC0) == 0x80 ? getStartingChar(buff, index - 1) : index;
};
while(lines.TryDequeue(out string rawLine)) {
byte[] line = Encoding.UTF8.GetBytes(rawLine.Trim());
int chunks = line.Length / targetLength;
int start = 0;
for(int i = chunks; i > 0; --i) {
int end = getStartingChar(line, start + targetLength);
yield return Encoding.UTF8.GetString(line, start, end - start);
start = end;
}
if(line.Length > start)
yield return Encoding.UTF8.GetString(line, start, line.Length - start);
}
}
}
}