using System.Net.Sockets; using IRCStates; using IRCTokens; // ReSharper disable StringLiteralTypo 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 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.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; } } } } }