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