IRC parsing, tokenization, and state handling in C#
at ircrobots 83 lines 2.8 kB view raw view rendered
1# IRCStates 2 3port of [jesopo/ircstates](https://github.com/jesopo/ircstates) 4 5available on [nuget](https://www.nuget.org/packages/IRCStates) 6 7bare bones irc client state 8 9see the full example in [StatesSample/Client.cs](../Examples/States/Client.cs) 10 11 internal class Client 12 { 13 private readonly byte[] _bytes; 14 private readonly StatefulEncoder _encoder; 15 private readonly string _host; 16 private readonly string _nick; 17 private readonly int _port; 18 private readonly Server _server; 19 private readonly Socket _socket; 20 21 public Client(string host, int port, string nick) 22 { 23 _server = new Server("test"); 24 _socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); 25 _encoder = new StatefulEncoder(); 26 _host = host; 27 _port = port; 28 _nick = nick; 29 _bytes = new byte[1024]; 30 } 31 32 private void Send(string raw) 33 { 34 _encoder.Push(new Line(raw)); 35 } 36 37 public void Start() 38 { 39 _socket.Connect(_host, _port); 40 while (!_socket.Connected) Thread.Sleep(1000); 41 42 Send("USER test 0 * test"); 43 Send($"NICK {_nick}"); 44 45 while (true) 46 { 47 while (_encoder.PendingBytes.Any()) 48 { 49 foreach (var line in _encoder.Pop(_socket.Send(_encoder.PendingBytes))) 50 Console.WriteLine($"> {line.Format()}"); 51 } 52 53 var bytesReceived = _socket.Receive(_bytes); 54 if (bytesReceived == 0) 55 { 56 Console.WriteLine("! disconnected"); 57 _socket.Shutdown(SocketShutdown.Both); 58 _socket.Close(); 59 break; 60 } 61 62 var receivedLines = _server.Receive(_bytes, bytesReceived); 63 foreach (var (line, _) in receivedLines) 64 { 65 Console.WriteLine($"< {line.Format()}"); 66 67 switch (line.Command) 68 { 69 case Commands.Privmsg: 70 if (line.Params[1].Contains(_server.NickName)) 71 Send($"PRIVMSG {line.Params[0]} :hi {line.Hostmask.NickName}!"); 72 break; 73 case "PING": 74 Send($"PONG :{line.Params[0]}"); 75 break; 76 case Numeric.RPL_WELCOME: 77 if (!_server.HasChannel("#test")) Send("JOIN #test"); 78 break; 79 } 80 } 81 } 82 } 83 }