using System; using System.Linq; using System.Net.Sockets; using System.Threading; using IRCStates; using IRCTokens; namespace States { internal class Client { private readonly byte[] _bytes; private readonly StatefulEncoder _encoder; private readonly string _host; private readonly string _nick; private readonly int _port; private readonly Server _server; private readonly Socket _socket; public Client(string host, int port, string nick) { _server = new Server("test"); _socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); _encoder = new StatefulEncoder(); _host = host; _port = port; _nick = nick; _bytes = new byte[1024]; } private void Send(string raw) { _encoder.Push(new Line(raw)); } public void Start() { _socket.Connect(_host, _port); while (!_socket.Connected) Thread.Sleep(1000); Send("USER test 0 * test"); Send($"NICK {_nick}"); while (true) { while (_encoder.PendingBytes.Any()) { foreach (var line in _encoder.Pop(_socket.Send(_encoder.PendingBytes))) Console.WriteLine($"> {line.Format()}"); } var bytesReceived = _socket.Receive(_bytes); if (bytesReceived == 0) { Console.WriteLine("! disconnected"); _socket.Shutdown(SocketShutdown.Both); _socket.Close(); break; } var receivedLines = _server.Receive(_bytes, bytesReceived); foreach (var (line, _) in receivedLines) { Console.WriteLine($"< {line.Format()}"); switch (line.Command) { case Commands.Privmsg: if (line.Params[1].Contains(_server.NickName)) Send($"PRIVMSG {line.Params[0]} :hi {line.Hostmask.NickName}!"); break; case "PING": Send($"PONG :{line.Params[0]}"); break; case Numeric.RPL_WELCOME: if (!_server.HasChannel("#irctokens")) Send("JOIN #irctokens"); break; case "INVITE": var c = line.Params[1]; if (!_server.HasChannel(c)) Send($"JOIN {c}"); break; } } } } } }