157 lines
5.4 KiB
C#
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);
|
|
}
|
|
}
|
|
}
|
|
}
|