using System.Collections.Generic; using System.Linq; namespace ChatSharp { /// /// Represents a raw IRC message. This is a low-level construct - PrivateMessage is used /// to represent messages sent from users. /// public class IrcMessage { /// /// The unparsed message. /// public string RawMessage { get; private set; } /// /// The message prefix. /// public string Prefix { get; private set; } /// /// The message command. /// public string Command { get; private set; } /// /// Additional parameters supplied with the message. /// public string[] Parameters { get; private set; } /// /// The message tags. /// public KeyValuePair[] Tags { get; private set; } /// /// The message timestamp in ISO 8601 format. /// public Timestamp Timestamp { get; private set; } /// /// Initializes and decodes an IRC message, given the raw message from the server. /// public IrcMessage(string rawMessage) { RawMessage = rawMessage; if (rawMessage.StartsWith("@")) { var rawTags = rawMessage.Substring(1, rawMessage.IndexOf(' ') - 1); rawMessage = rawMessage.Substring(rawMessage.IndexOf(' ') + 1); // Parse tags as key value pairs var tags = new List>(); foreach (string rawTag in rawTags.Split(';')) { var replacedTag = rawTag.Replace(@"\:", ";"); KeyValuePair tag = new KeyValuePair(replacedTag, string.Empty); if (replacedTag.Contains("=")) { string key = replacedTag.Substring(0, replacedTag.IndexOf("=")); string value = replacedTag.Substring(replacedTag.IndexOf("=") + 1); tag = new KeyValuePair(key, value); } tags.Add(tag); } Tags = tags.ToArray(); } if (rawMessage.StartsWith(":")) { Prefix = rawMessage.Substring(1, rawMessage.IndexOf(' ') - 1); rawMessage = rawMessage.Substring(rawMessage.IndexOf(' ') + 1); } if (rawMessage.Contains(' ')) { Command = rawMessage.Remove(rawMessage.IndexOf(' ')); rawMessage = rawMessage.Substring(rawMessage.IndexOf(' ') + 1); // Parse parameters var parameters = new List(); while (!string.IsNullOrEmpty(rawMessage)) { if (rawMessage.StartsWith(":")) { parameters.Add(rawMessage.Substring(1)); break; } if (!rawMessage.Contains(' ')) { parameters.Add(rawMessage); rawMessage = string.Empty; break; } parameters.Add(rawMessage.Remove(rawMessage.IndexOf(' '))); rawMessage = rawMessage.Substring(rawMessage.IndexOf(' ') + 1); } Parameters = parameters.ToArray(); } else { // Violates RFC 1459, but we'll parse it anyway Command = rawMessage; Parameters = new string[0]; } // Parse server-time message tag. // Fallback to server-info if both znc.in/server-info and the former exists. // // znc.in/server-time tag if (Tags.Any(tag => tag.Key == "t")) { var tag = Tags.SingleOrDefault(x => x.Key == "t"); Timestamp = new Timestamp(tag.Value, true); } // server-time tag else if (Tags.Any(tag => tag.Key == "time")) { var tag = Tags.SingleOrDefault(x => x.Key == "time"); Timestamp = new Timestamp(tag.Value); } } } }