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