using System; using System.Linq; using System.Net.Sockets; using System.Threading; using IRCStates; using IRCTokens; namespace States; internal class Client(string host, int port, string nick) { private readonly byte[] _bytes = new byte[1024]; private readonly StatefulEncoder _encoder = new(); private readonly Server _server = new("test"); private readonly Socket _socket = new(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); private void Send(string raw) { _encoder.Push(new(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.Length != 0) { 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; } } } } }