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