1
0
Fork 0
csbot/csbot/Core/Message.cs

157 lines
5.4 KiB
C#

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Csbot.Core
{
/// <summary>
/// The Message class is used to store any message sent to/received from the IRCd.
/// This class makes message parsing look easy, but it really isn't.
/// </summary>
public class Message
{
public String line { get; set; }
public String action { get; set; }
public String text { get; set; }
public String channel { get; set; }
public String command { get; set; }
public ISender author;
public bool isCommand;
/// <summary>
/// Public constructor for the Message class.
/// Please call this to parse received messages, don't just simply assign values to the properties.
/// </summary>
/// <param name="line">The message from start to newline, as received from the server.</param>
/// <param name="commandStart">A Char indicating the start character for bot commands, as defined in the config file.</param>
public Message(String line, Char commandStart)
{
this.line = line;
String[] parts = this.line.Split(' ');
if ("PING".Equals(parts[0]))
{
this.action = "PING";
this.text = parts[1];
this.channel = null;
this.author = new Host(parts[1].Substring(1));
this.isCommand = false;
this.command = null;
return;
}
if (parts[0].Contains("!") && parts[0].Contains("@"))
{
this.author = new User(parts[0].Substring(1, parts[0].IndexOf("!") - 1),
parts[0].Substring(parts[0].IndexOf("!"), (parts[0].IndexOf("@") - parts[0].IndexOf("!"))),
parts[0].Substring(parts[0].IndexOf("@"), (parts[0].Length - parts[0].IndexOf("@"))));
}
else
{
this.author = new Host(parts[0].Substring(1));
}
if ("NOTICE".Equals(parts[1]))
{
this.action = "NOTICE";
this.text = this.line.Substring(this.line.IndexOf(" :") + 2);
this.channel = parts[2];
return;
}
if ("PRIVMSG".Equals(parts[1]))
{
this.action = "PRIVMSG";
this.text = this.line.Substring(this.line.IndexOf(" :") + 2);
this.channel = parts[2];
if (commandStart == this.text[0])
{
this.isCommand = true;
this.command = this.text.Contains(" ") ? this.text.Substring(1, this.text.IndexOf(" ") - 1) : this.text.Substring(1, this.text.Length - 1);
}
else
{
this.isCommand = false;
this.command = null;
}
return;
}
else
{
//TODO pls add parsing here
this.action = parts[1];
this.text = null;
this.channel = null;
this.isCommand = false;
this.command = null;
}
}
/// <summary>
/// Please please please only use this constructor for outgoing PRIVMSGs.
/// </summary>
/// <param name="line">The message to be sent to the server.</param>
public Message(String line)
{
this.line = line;
this.action = "PRIVMSG";
this.channel = this.line.Split(' ')[1];
this.text = this.line.Substring(this.line.IndexOf(" :") + 2);
}
/// <summary>
/// Empty constructor, pls do not use. Only used to build messages sent during startup.
/// </summary>
public Message()
{
this.line = null;
this.action = null;
this.text = null;
this.channel = null;
this.command = null;
this.author = null;
this.isCommand = false;
}
/// <summary>
/// This function splits messages (PRIVMSGs only) over 512 chars in two or more lines, as required by the RFC.
/// </summary>
/// <returns>The list of messages ready to be sent.</returns>
protected List<String> Split()
{
List<String> ret = new List<string> { };
if (this.line.Length > 510 && "PRIVMSG".Equals(this.action))
{
for (int i = 0; i <= this.line.Length / 510; i++)
{
ret.Add(this.action + " " + this.channel + " :" + this.text.Substring(i * 510, 510)); //yay, math. But no, really, twy it, it works.
}
}
else
{
ret.Add(this.line);
}
return ret;
}
/// <summary>
/// This functions takes care of sending the message, splitting it in more than one lines if necessary.
/// </summary>
/// <param name="sock">The StreamWriter to write the message(s) to.</param>
public void Send(StreamWriter sock, bool debug)
{
foreach (String line in this.Split())
{
if (debug)
Console.WriteLine(line);
sock.WriteLine(line);
}
}
}
}