using System; using System.Collections.Generic; using System.Diagnostics; using System.Dynamic; using System.Linq; using System.Reflection.Metadata; using System.Reflection.Metadata.Ecma335; using System.Text; using System.Threading.Tasks; public class TwitchChatMessage { public static readonly string Delimter = "\r\n"; public TwitchChatMessageType MessageType { get; protected set; } public string Prefix { get; protected set; } public string Source { get; protected set; } public List Parameters { get; } = new(); public string RawParameters { get; protected set; } public string RawText { get; protected set; } public TwitchMessageTags MessageTags { get; protected set; } = new(); protected TwitchChatMessage() { } protected TwitchChatMessage(TwitchChatMessage other) { MessageType = other.MessageType; Prefix = other.Prefix; Source = other.Source; Parameters = new(other.Parameters); RawParameters = other.RawParameters; RawText = other.RawText; MessageTags = new(other.MessageTags); } public static TwitchChatMessage Parse(string s) { TwitchChatMessage message = new(); message.RawText = s; //message has tags if (s.StartsWith('@')) { s = s[1..]; //first ' ' acts as the delimeter var split = s.Split(' ', 2); Debug.Assert(split.Length == 2, "no space found to end tag section"); string tagString = split[0]; s = split[1].TrimStart(' '); message.MessageTags = TwitchMessageTags.Parse(tagString); } //message has source if (s.StartsWith(':')) { s = s[1..]; var split = s.Split(' ', 2); Debug.Assert(split.Length == 2, "no space found to end prefix"); message.Prefix = split[0]; s = split[1].TrimStart(' '); } var spl_command = s.Split(' ', 2); message.MessageType = TwitchChatMessageTypeHelper.Parse(spl_command[0]); //message has parameters if (spl_command.Length >= 2) { s = spl_command[1]; message.RawParameters = s; //message has single parameter marked as the final parameter //this needs to be handled specially because the leading ' ' //is stripped if (s.StartsWith(':')) { message.Parameters.Add(s[1..]); } else { var spl_final = s.Split(" :", 2); var spl_initial = spl_final[0].Split(' ', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries); message.Parameters.AddRange(spl_initial); if (spl_final.Length >= 2) message.Parameters.Add(spl_final[1]); } } return message.MessageType switch { TwitchChatMessageType.PRIVMSG => new Privmsg(message), _ => message, }; } protected string TryGetTag(string s) { if (!MessageTags.TryGetValue(s, out string value)) return ""; return value ?? ""; } public static TwitchChatMessage MakePong(TwitchChatMessage ping) { var pong = new TwitchChatMessage(ping); pong.MessageType = TwitchChatMessageType.PONG; return pong; } }