From 304df7805b9925c2edd992fd4177eef80197f807 Mon Sep 17 00:00:00 2001 From: Ben Harris Date: Thu, 14 May 2020 22:17:22 -0400 Subject: working ircstates example --- IrcStates/README.md | 77 +++++++++++++++++++++++++++++++++++++++++++++++++++++ IrcStates/Server.cs | 6 ++--- 2 files changed, 80 insertions(+), 3 deletions(-) (limited to 'IrcStates') diff --git a/IrcStates/README.md b/IrcStates/README.md index 60fcc44..05daa8c 100644 --- a/IrcStates/README.md +++ b/IrcStates/README.md @@ -3,3 +3,80 @@ port of [jesopo/ircstates](https://github.com/jesopo/ircstates) bare bones irc client state + +see the full example in [StatesSample/Client.cs](../Examples/States/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()) + { + var bytesSent = _socket.Send(_encoder.PendingBytes); + var sentLines = _encoder.Pop(bytesSent); + foreach (var line in sentLines) 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; + } + } + } + } + } \ No newline at end of file diff --git a/IrcStates/Server.cs b/IrcStates/Server.cs index ca812f6..2e80b75 100644 --- a/IrcStates/Server.cs +++ b/IrcStates/Server.cs @@ -95,7 +95,7 @@ namespace IrcStates ISupport.ChanTypes.Contains(target[0].ToString(CultureInfo.InvariantCulture)); } - private bool HasChannel(string name) + public bool HasChannel(string name) { return Channels.ContainsKey(CaseFold(name)); } @@ -201,11 +201,11 @@ namespace IrcStates } } - public List<(Line, Emit)> Recv(byte[] data) + public IEnumerable<(Line, Emit)> Receive(byte[] data, int length) { if (data == null) return null; - var lines = _decoder.Push(data, data.Length); + var lines = _decoder.Push(data, length); if (lines == null) throw new ServerDisconnectedException(); return lines.Select(l => (l, Parse(l))).ToList(); -- cgit 1.4.1