···11+using System;
22+using System.Linq;
33+using System.Net.Sockets;
44+using System.Threading;
55+using IrcStates;
66+using IrcTokens;
77+88+namespace StatesSample
99+{
1010+ internal class Client
1111+ {
1212+ private readonly byte[] _bytes;
1313+ private readonly StatefulEncoder _encoder;
1414+ private readonly string _host;
1515+ private readonly string _nick;
1616+ private readonly int _port;
1717+ private readonly Server _server;
1818+ private readonly Socket _socket;
1919+2020+ public Client(string host, int port, string nick)
2121+ {
2222+ _server = new Server("test");
2323+ _socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
2424+ _encoder = new StatefulEncoder();
2525+ _host = host;
2626+ _port = port;
2727+ _nick = nick;
2828+ _bytes = new byte[1024];
2929+ }
3030+3131+ private void Send(string raw)
3232+ {
3333+ _encoder.Push(new Line(raw));
3434+ }
3535+3636+ public void Start()
3737+ {
3838+ _socket.Connect(_host, _port);
3939+ while (!_socket.Connected) Thread.Sleep(1000);
4040+4141+ Send("USER test 0 * test");
4242+ Send($"NICK {_nick}");
4343+4444+ while (true)
4545+ {
4646+ while (_encoder.PendingBytes.Any())
4747+ {
4848+ var bytesSent = _socket.Send(_encoder.PendingBytes);
4949+ var sentLines = _encoder.Pop(bytesSent);
5050+ foreach (var line in sentLines) Console.WriteLine($"> {line.Format()}");
5151+ }
5252+5353+ var bytesReceived = _socket.Receive(_bytes);
5454+ if (bytesReceived == 0)
5555+ {
5656+ Console.WriteLine("! disconnected");
5757+ _socket.Shutdown(SocketShutdown.Both);
5858+ _socket.Close();
5959+ break;
6060+ }
6161+6262+ var receivedLines = _server.Receive(_bytes, bytesReceived);
6363+ foreach (var (line, _) in receivedLines)
6464+ {
6565+ Console.WriteLine($"< {line.Format()}");
6666+6767+ switch (line.Command)
6868+ {
6969+ case Commands.Privmsg:
7070+ if (line.Params[1].Contains(_server.NickName))
7171+ Send($"PRIVMSG {line.Params[0]} :hi {line.Hostmask.NickName}!");
7272+ break;
7373+ case "PING":
7474+ Send($"PONG :{line.Params[0]}");
7575+ break;
7676+ case Numeric.RPL_WELCOME:
7777+ if (!_server.HasChannel("#test")) Send("JOIN #test");
7878+ break;
7979+ }
8080+ }
8181+ }
8282+ }
8383+ }
8484+}
+3-4
Examples/States/Program.cs
···11-using System;
22-33-namespace StatesSample
11+namespace StatesSample
42{
53 public static class Program
64 {
75 private static void Main(string[] args)
86 {
99- Console.WriteLine("Hello World!");
77+ var client = new Client("localhost", 6667, "statesbot");
88+ client.Start();
109 }
1110 }
1211}
+77
IrcStates/README.md
···33port of [jesopo/ircstates](https://github.com/jesopo/ircstates)
4455bare bones irc client state
66+77+see the full example in [StatesSample/Client.cs](../Examples/States/Client.cs)
88+99+ internal class Client
1010+ {
1111+ private readonly byte[] _bytes;
1212+ private readonly StatefulEncoder _encoder;
1313+ private readonly string _host;
1414+ private readonly string _nick;
1515+ private readonly int _port;
1616+ private readonly Server _server;
1717+ private readonly Socket _socket;
1818+1919+ public Client(string host, int port, string nick)
2020+ {
2121+ _server = new Server("test");
2222+ _socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
2323+ _encoder = new StatefulEncoder();
2424+ _host = host;
2525+ _port = port;
2626+ _nick = nick;
2727+ _bytes = new byte[1024];
2828+ }
2929+3030+ private void Send(string raw)
3131+ {
3232+ _encoder.Push(new Line(raw));
3333+ }
3434+3535+ public void Start()
3636+ {
3737+ _socket.Connect(_host, _port);
3838+ while (!_socket.Connected) Thread.Sleep(1000);
3939+4040+ Send("USER test 0 * test");
4141+ Send($"NICK {_nick}");
4242+4343+ while (true)
4444+ {
4545+ while (_encoder.PendingBytes.Any())
4646+ {
4747+ var bytesSent = _socket.Send(_encoder.PendingBytes);
4848+ var sentLines = _encoder.Pop(bytesSent);
4949+ foreach (var line in sentLines) Console.WriteLine($"> {line.Format()}");
5050+ }
5151+5252+ var bytesReceived = _socket.Receive(_bytes);
5353+ if (bytesReceived == 0)
5454+ {
5555+ Console.WriteLine("! disconnected");
5656+ _socket.Shutdown(SocketShutdown.Both);
5757+ _socket.Close();
5858+ break;
5959+ }
6060+6161+ var receivedLines = _server.Receive(_bytes, bytesReceived);
6262+ foreach (var (line, _) in receivedLines)
6363+ {
6464+ Console.WriteLine($"< {line.Format()}");
6565+6666+ switch (line.Command)
6767+ {
6868+ case Commands.Privmsg:
6969+ if (line.Params[1].Contains(_server.NickName))
7070+ Send($"PRIVMSG {line.Params[0]} :hi {line.Hostmask.NickName}!");
7171+ break;
7272+ case "PING":
7373+ Send($"PONG :{line.Params[0]}");
7474+ break;
7575+ case Numeric.RPL_WELCOME:
7676+ if (!_server.HasChannel("#test")) Send("JOIN #test");
7777+ break;
7878+ }
7979+ }
8080+ }
8181+ }
8282+ }
+3-3
IrcStates/Server.cs
···9595 ISupport.ChanTypes.Contains(target[0].ToString(CultureInfo.InvariantCulture));
9696 }
97979898- private bool HasChannel(string name)
9898+ public bool HasChannel(string name)
9999 {
100100 return Channels.ContainsKey(CaseFold(name));
101101 }
···201201 }
202202 }
203203204204- public List<(Line, Emit)> Recv(byte[] data)
204204+ public IEnumerable<(Line, Emit)> Receive(byte[] data, int length)
205205 {
206206 if (data == null) return null;
207207208208- var lines = _decoder.Push(data, data.Length);
208208+ var lines = _decoder.Push(data, length);
209209 if (lines == null) throw new ServerDisconnectedException();
210210211211 return lines.Select(l => (l, Parse(l))).ToList();
+1-1
IrcTokens/README.md
···23232424### stateful
25252626-see the full example in [Examples/Tokens/Client.cs](../Examples/Tokens/Client.cs)
2626+see the full example in [TokensSample/Client.cs](../Examples/Tokens/Client.cs)
27272828 public class Client
2929 {