chatsharp/ChatSharp/IrcMessage.cs

124 lines
4.4 KiB
C#
Raw Normal View History

2015-07-07 19:16:52 +00:00
using System.Collections.Generic;
using System.Linq;
2013-04-09 21:19:48 +00:00
namespace ChatSharp
{
2015-08-01 01:06:22 +00:00
/// <summary>
/// Represents a raw IRC message. This is a low-level construct - PrivateMessage is used
/// to represent messages sent from users.
/// </summary>
2013-04-09 21:19:48 +00:00
public class IrcMessage
{
2015-08-01 01:06:22 +00:00
/// <summary>
/// The unparsed message.
/// </summary>
2013-04-13 19:43:00 +00:00
public string RawMessage { get; private set; }
2015-08-01 01:06:22 +00:00
/// <summary>
/// The message prefix.
/// </summary>
2013-04-13 19:43:00 +00:00
public string Prefix { get; private set; }
2015-08-01 01:06:22 +00:00
/// <summary>
/// The message command.
/// </summary>
2013-04-13 19:43:00 +00:00
public string Command { get; private set; }
2015-08-01 01:06:22 +00:00
/// <summary>
/// Additional parameters supplied with the message.
/// </summary>
2013-04-13 19:43:00 +00:00
public string[] Parameters { get; private set; }
/// <summary>
/// The message tags.
/// </summary>
public KeyValuePair<string, string>[] Tags { get; private set; }
/// <summary>
/// The message timestamp in ISO 8601 format.
/// </summary>
public Timestamp Timestamp { get; private set; }
2013-04-09 21:19:48 +00:00
2015-08-01 01:06:22 +00:00
/// <summary>
/// Initializes and decodes an IRC message, given the raw message from the server.
/// </summary>
2013-04-13 19:43:00 +00:00
public IrcMessage(string rawMessage)
{
RawMessage = rawMessage;
2013-04-09 21:19:48 +00:00
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<KeyValuePair<string, string>>();
foreach (string rawTag in rawTags.Split(';'))
{
var replacedTag = rawTag.Replace(@"\:", ";");
KeyValuePair<string, string> tag = new KeyValuePair<string, string>(replacedTag, string.Empty);
if (replacedTag.Contains("="))
{
string key = replacedTag.Substring(0, replacedTag.IndexOf("="));
string value = replacedTag.Substring(replacedTag.IndexOf("=") + 1);
tag = new KeyValuePair<string, string>(key, value);
}
tags.Add(tag);
}
Tags = tags.ToArray();
}
2013-04-13 19:43:00 +00:00
if (rawMessage.StartsWith(":"))
{
Prefix = rawMessage.Substring(1, rawMessage.IndexOf(' ') - 1);
rawMessage = rawMessage.Substring(rawMessage.IndexOf(' ') + 1);
}
2013-04-09 21:19:48 +00:00
2013-04-13 19:43:00 +00:00
if (rawMessage.Contains(' '))
{
Command = rawMessage.Remove(rawMessage.IndexOf(' '));
rawMessage = rawMessage.Substring(rawMessage.IndexOf(' ') + 1);
// Parse parameters
var parameters = new List<string>();
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);
}
2013-04-09 21:19:48 +00:00
}
}
}