From ca1518a9705ac289875c65c396a2ef7d219492d5 Mon Sep 17 00:00:00 2001 From: Ben Harris Date: Wed, 22 Apr 2020 11:42:09 -0400 Subject: [PATCH] Add sample project --- IrcTokens.sln | 8 +++++- IrcTokens/Line.cs | 17 +++++++++-- Sample/Client.cs | 68 ++++++++++++++++++++++++++++++++++++++++++++ Sample/Program.cs | 30 +++++++++++++++++++ Sample/Sample.csproj | 12 ++++++++ 5 files changed, 132 insertions(+), 3 deletions(-) create mode 100644 Sample/Client.cs create mode 100644 Sample/Program.cs create mode 100644 Sample/Sample.csproj diff --git a/IrcTokens.sln b/IrcTokens.sln index bda403d..c9b3d28 100644 --- a/IrcTokens.sln +++ b/IrcTokens.sln @@ -3,7 +3,9 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 16 VisualStudioVersion = 16.0.30011.22 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "IrcTokens", "IrcTokens\IrcTokens.csproj", "{9E812F45-B2CD-42D2-8378-EBEBF8697905}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IrcTokens", "IrcTokens\IrcTokens.csproj", "{9E812F45-B2CD-42D2-8378-EBEBF8697905}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sample", "Sample\Sample.csproj", "{A45DA39B-6B47-4713-8049-3B36E0235B67}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -15,6 +17,10 @@ Global {9E812F45-B2CD-42D2-8378-EBEBF8697905}.Debug|Any CPU.Build.0 = Debug|Any CPU {9E812F45-B2CD-42D2-8378-EBEBF8697905}.Release|Any CPU.ActiveCfg = Release|Any CPU {9E812F45-B2CD-42D2-8378-EBEBF8697905}.Release|Any CPU.Build.0 = Release|Any CPU + {A45DA39B-6B47-4713-8049-3B36E0235B67}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A45DA39B-6B47-4713-8049-3B36E0235B67}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A45DA39B-6B47-4713-8049-3B36E0235B67}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A45DA39B-6B47-4713-8049-3B36E0235B67}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/IrcTokens/Line.cs b/IrcTokens/Line.cs index 27d9c0d..9056097 100644 --- a/IrcTokens/Line.cs +++ b/IrcTokens/Line.cs @@ -18,8 +18,21 @@ namespace IrcTokens private Hostmask _hostmask; private readonly string _rawLine; - public override string ToString() => - $"Line(source={Source}, command={Command}, tags={string.Join(";", Tags.Select(kvp => $"{kvp.Key}={kvp.Value}"))}, params={string.Join(",", Params)})"; + public override string ToString() + { + var vars = new List(); + + if (Command != null) + vars.Add($"command={Command}"); + if (Source != null) + vars.Add($"source={Source}"); + if (Params != null && Params.Any()) + vars.Add($"params=[{string.Join(",", Params)}]"); + if (Tags != null && Tags.Any()) + vars.Add($"tags=[{string.Join(";", Tags.Select(kvp => $"{kvp.Key}={kvp.Value}"))}]"); + + return $"Line({string.Join(", ", vars)})"; + } public override int GetHashCode() => Format().GetHashCode(StringComparison.Ordinal); diff --git a/Sample/Client.cs b/Sample/Client.cs new file mode 100644 index 0000000..e9e286f --- /dev/null +++ b/Sample/Client.cs @@ -0,0 +1,68 @@ +using System; +using System.Collections.Generic; +using System.Net.Sockets; +using System.Text; +using IrcTokens; + +namespace Sample +{ + public class Client + { + private readonly Socket _socket; + private readonly StatefulDecoder _decoder; + private readonly StatefulEncoder _encoder; + private readonly byte[] _bytes; + + public Client() + { + _decoder = new StatefulDecoder(); + _encoder = new StatefulEncoder(); + _socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP); + _bytes = new byte[1024]; + } + + public void Start() + { + _socket.Connect("127.0.0.1", 6667); + + Send(new Line {Command = "USER", Params = new List {"username", "0", "*", "real name"}}); + Send(new Line {Command = "NICK", Params = new List {"statefulbot"}}); + + while (true) + { + var bytesReceived = _socket.Receive(_bytes); + var lines = _decoder.Push(_bytes); + + if (lines.Count == 0) + { + Console.WriteLine("! disconnected"); + _socket.Shutdown(SocketShutdown.Both); + break; + } + + foreach (var line in lines) + { + Console.WriteLine($"< {line.Format()}"); + + switch (line.Command) + { + case "PING": + Send(new Line {Command = "PONG", Params = line.Params}); + break; + case "001": + Send(new Line {Command = "JOIN", Params = new List {"#channel"}}); + break; + } + } + } + } + + private void Send(Line line) + { + Console.WriteLine($"> {line.Format()}"); + _encoder.Push(line); + while (_encoder.PendingBytes.Length > 0) + _encoder.Pop(_socket.Send(_encoder.PendingBytes)); + } + } +} diff --git a/Sample/Program.cs b/Sample/Program.cs new file mode 100644 index 0000000..6800179 --- /dev/null +++ b/Sample/Program.cs @@ -0,0 +1,30 @@ +using System; +using System.Collections.Generic; +using IrcTokens; + +namespace Sample +{ + public class Program + { + public static void Main(string[] args) + { + // tokenization + var line = new Line("@id=123 :ben!~ben@hostname PRIVMSG #channel :hello there!"); + Console.WriteLine(line); + Console.WriteLine(line.Format()); + + // formatting + var line2 = new Line + { + Command = "USER", + Params = new List {"user", "0", "*", "real name"} + }; + Console.WriteLine(line2); + Console.WriteLine(line2.Format()); + + // stateful example + var client = new Client(); + client.Start(); + } + } +} diff --git a/Sample/Sample.csproj b/Sample/Sample.csproj new file mode 100644 index 0000000..7c66734 --- /dev/null +++ b/Sample/Sample.csproj @@ -0,0 +1,12 @@ + + + + Exe + netcoreapp3.1 + + + + + + +