122 lines
3.2 KiB
C#
122 lines
3.2 KiB
C#
using System.Net.Sockets;
|
|
using System.Runtime.CompilerServices;
|
|
using System.Text;
|
|
using System.Threading.Channels;
|
|
|
|
namespace riff;
|
|
|
|
public abstract class IRCBot
|
|
{
|
|
public string Host;
|
|
public int Port;
|
|
public string Nick;
|
|
public string RealName;
|
|
public List<string>? Channels;
|
|
public List<Action<PRIVMSG>> Listeners = new();
|
|
private List<CommandRunner> CommandRunners = new();
|
|
private List<PollRunner> PollRunners = new();
|
|
private TcpClient Client;
|
|
private NetworkStream Stream;
|
|
|
|
public IRCBot(string host, int port, string nick, string realname)
|
|
{
|
|
Host = host;
|
|
Port = port;
|
|
Nick = nick;
|
|
RealName = realname;
|
|
Client = new TcpClient(Host, Port);
|
|
Stream = Client.GetStream();
|
|
SendLine($"NICK {Nick}");
|
|
SendLine($"USER {Nick} 0 * :{RealName}");
|
|
}
|
|
|
|
public void HookCommands((string, Action<PRIVMSG>)[] commands)
|
|
{
|
|
foreach ((string, Action<PRIVMSG>) command in commands)
|
|
{
|
|
CommandRunners.Add(new CommandRunner(command.Item1, command.Item2));
|
|
}
|
|
}
|
|
|
|
public void HookPollRunners((int, Action)[] runners)
|
|
{
|
|
foreach ((int, Action) runner in runners)
|
|
{
|
|
PollRunners.Add(new PollRunner(runner.Item1, runner.Item2));
|
|
}
|
|
}
|
|
|
|
public void HookListeners(Action<PRIVMSG>[] listeners)
|
|
{
|
|
foreach (Action<PRIVMSG> listener in listeners)
|
|
{
|
|
Listeners.Add(listener);
|
|
}
|
|
}
|
|
|
|
private void SendLine(string line)
|
|
{
|
|
Byte[] bytes = Encoding.UTF8.GetBytes(line + "\r\n");
|
|
Stream.Write(bytes, 0, bytes.Length);
|
|
}
|
|
|
|
public void SendPrivmsg(string channel, string message)
|
|
{
|
|
if (message != string.Empty)
|
|
SendLine($"PRIVMSG {channel} :{message}");
|
|
}
|
|
|
|
public void JoinChannel(string channel)
|
|
{
|
|
SendLine($"JOIN {channel}");
|
|
}
|
|
|
|
public void JoinChannels(string[] channels)
|
|
{
|
|
foreach (string channel in channels)
|
|
JoinChannel(channel);
|
|
}
|
|
|
|
public void PartChannel(string channel)
|
|
{
|
|
SendLine($"PART {channel}");
|
|
}
|
|
|
|
public void MainLoop()
|
|
{
|
|
foreach (PollRunner runner in PollRunners)
|
|
{
|
|
runner.Run();
|
|
}
|
|
using var reader = new StreamReader(Stream, Encoding.UTF8);
|
|
while (true)
|
|
{
|
|
string? line = reader.ReadLine();
|
|
if (line == null)
|
|
{
|
|
Console.WriteLine($"{Nick} disconnected");
|
|
break;
|
|
}
|
|
IRCMessage msg = new(line);
|
|
switch (msg.Command)
|
|
{
|
|
case "PING":
|
|
if (msg.Arguments == null)
|
|
SendLine("PONG");
|
|
else
|
|
SendLine("PONG " + msg.Arguments[0]);
|
|
break;
|
|
case "PRIVMSG":
|
|
PRIVMSG privmsg = new(msg);
|
|
foreach (Action<PRIVMSG> listener in Listeners)
|
|
listener(privmsg);
|
|
foreach (CommandRunner command in CommandRunners)
|
|
if (command.Run(privmsg))
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|