ircsharp/IRCStates/README.md

2.7 KiB

IRCStates

port of jesopo/ircstates

available on nuget

bare bones irc client state

see the full example in StatesSample/Client.cs

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("#test")) Send("JOIN #test");
                        break;
                }
            }
        }
    }
}