IRC parsing, tokenization, and state handling in C#
1using System;
2using System.Net.Sockets;
3using System.Threading;
4using IRCTokens;
5
6namespace Tokens
7{
8 public class Client
9 {
10 private readonly byte[] _bytes;
11 private readonly StatefulDecoder _decoder;
12 private readonly StatefulEncoder _encoder;
13 private readonly Socket _socket;
14
15 public Client()
16 {
17 _decoder = new StatefulDecoder();
18 _encoder = new StatefulEncoder();
19 _socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
20 _bytes = new byte[1024];
21 }
22
23 public void Start()
24 {
25 _socket.Connect("127.0.0.1", 6667);
26 while (!_socket.Connected) Thread.Sleep(1000);
27
28 Send(new Line("NICK", "tokensbot"));
29 Send(new Line("USER", "tokensbot", "0", "*", "real name"));
30
31 while (true)
32 {
33 var bytesReceived = _socket.Receive(_bytes);
34
35 if (bytesReceived == 0)
36 {
37 Console.WriteLine("! disconnected");
38 _socket.Shutdown(SocketShutdown.Both);
39 _socket.Close();
40 break;
41 }
42
43 var lines = _decoder.Push(_bytes, bytesReceived);
44
45 foreach (var line in lines)
46 {
47 Console.WriteLine($"< {line.Format()}");
48
49 switch (line.Command)
50 {
51 case "PING":
52 Send(new Line("PONG", line.Params[0]));
53 break;
54 case "001":
55 Send(new Line("JOIN", "#irctokens"));
56 break;
57 case "PRIVMSG":
58 Send(new Line("PRIVMSG", line.Params[0], "hello there"));
59 break;
60 }
61 }
62 }
63 }
64
65 private void Send(Line line)
66 {
67 Console.WriteLine($"> {line.Format()}");
68 _encoder.Push(line);
69 while (_encoder.PendingBytes.Length > 0)
70 _encoder.Pop(_socket.Send(_encoder.PendingBytes, SocketFlags.None));
71 }
72 }
73}