tangled
alpha
login
or
join now
benharri.org
/
ircsharp
1
fork
atom
IRC parsing, tokenization, and state handling in C#
1
fork
atom
overview
issues
pulls
pipelines
Add sample project
benharri.org
5 years ago
ca1518a9
06a9882f
+132
-3
5 changed files
expand all
collapse all
unified
split
IrcTokens
Line.cs
IrcTokens.sln
Sample
Client.cs
Program.cs
Sample.csproj
+7
-1
IrcTokens.sln
···
3
3
# Visual Studio Version 16
4
4
VisualStudioVersion = 16.0.30011.22
5
5
MinimumVisualStudioVersion = 10.0.40219.1
6
6
-
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "IrcTokens", "IrcTokens\IrcTokens.csproj", "{9E812F45-B2CD-42D2-8378-EBEBF8697905}"
6
6
+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IrcTokens", "IrcTokens\IrcTokens.csproj", "{9E812F45-B2CD-42D2-8378-EBEBF8697905}"
7
7
+
EndProject
8
8
+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sample", "Sample\Sample.csproj", "{A45DA39B-6B47-4713-8049-3B36E0235B67}"
7
9
EndProject
8
10
Global
9
11
GlobalSection(SolutionConfigurationPlatforms) = preSolution
···
15
17
{9E812F45-B2CD-42D2-8378-EBEBF8697905}.Debug|Any CPU.Build.0 = Debug|Any CPU
16
18
{9E812F45-B2CD-42D2-8378-EBEBF8697905}.Release|Any CPU.ActiveCfg = Release|Any CPU
17
19
{9E812F45-B2CD-42D2-8378-EBEBF8697905}.Release|Any CPU.Build.0 = Release|Any CPU
20
20
+
{A45DA39B-6B47-4713-8049-3B36E0235B67}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
21
21
+
{A45DA39B-6B47-4713-8049-3B36E0235B67}.Debug|Any CPU.Build.0 = Debug|Any CPU
22
22
+
{A45DA39B-6B47-4713-8049-3B36E0235B67}.Release|Any CPU.ActiveCfg = Release|Any CPU
23
23
+
{A45DA39B-6B47-4713-8049-3B36E0235B67}.Release|Any CPU.Build.0 = Release|Any CPU
18
24
EndGlobalSection
19
25
GlobalSection(SolutionProperties) = preSolution
20
26
HideSolutionNode = FALSE
+15
-2
IrcTokens/Line.cs
···
18
18
private Hostmask _hostmask;
19
19
private readonly string _rawLine;
20
20
21
21
-
public override string ToString() =>
22
22
-
$"Line(source={Source}, command={Command}, tags={string.Join(";", Tags.Select(kvp => $"{kvp.Key}={kvp.Value}"))}, params={string.Join(",", Params)})";
21
21
+
public override string ToString()
22
22
+
{
23
23
+
var vars = new List<string>();
24
24
+
25
25
+
if (Command != null)
26
26
+
vars.Add($"command={Command}");
27
27
+
if (Source != null)
28
28
+
vars.Add($"source={Source}");
29
29
+
if (Params != null && Params.Any())
30
30
+
vars.Add($"params=[{string.Join(",", Params)}]");
31
31
+
if (Tags != null && Tags.Any())
32
32
+
vars.Add($"tags=[{string.Join(";", Tags.Select(kvp => $"{kvp.Key}={kvp.Value}"))}]");
33
33
+
34
34
+
return $"Line({string.Join(", ", vars)})";
35
35
+
}
23
36
24
37
public override int GetHashCode() => Format().GetHashCode(StringComparison.Ordinal);
25
38
+68
Sample/Client.cs
···
1
1
+
using System;
2
2
+
using System.Collections.Generic;
3
3
+
using System.Net.Sockets;
4
4
+
using System.Text;
5
5
+
using IrcTokens;
6
6
+
7
7
+
namespace Sample
8
8
+
{
9
9
+
public class Client
10
10
+
{
11
11
+
private readonly Socket _socket;
12
12
+
private readonly StatefulDecoder _decoder;
13
13
+
private readonly StatefulEncoder _encoder;
14
14
+
private readonly byte[] _bytes;
15
15
+
16
16
+
public Client()
17
17
+
{
18
18
+
_decoder = new StatefulDecoder();
19
19
+
_encoder = new StatefulEncoder();
20
20
+
_socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
21
21
+
_bytes = new byte[1024];
22
22
+
}
23
23
+
24
24
+
public void Start()
25
25
+
{
26
26
+
_socket.Connect("127.0.0.1", 6667);
27
27
+
28
28
+
Send(new Line {Command = "USER", Params = new List<string> {"username", "0", "*", "real name"}});
29
29
+
Send(new Line {Command = "NICK", Params = new List<string> {"statefulbot"}});
30
30
+
31
31
+
while (true)
32
32
+
{
33
33
+
var bytesReceived = _socket.Receive(_bytes);
34
34
+
var lines = _decoder.Push(_bytes);
35
35
+
36
36
+
if (lines.Count == 0)
37
37
+
{
38
38
+
Console.WriteLine("! disconnected");
39
39
+
_socket.Shutdown(SocketShutdown.Both);
40
40
+
break;
41
41
+
}
42
42
+
43
43
+
foreach (var line in lines)
44
44
+
{
45
45
+
Console.WriteLine($"< {line.Format()}");
46
46
+
47
47
+
switch (line.Command)
48
48
+
{
49
49
+
case "PING":
50
50
+
Send(new Line {Command = "PONG", Params = line.Params});
51
51
+
break;
52
52
+
case "001":
53
53
+
Send(new Line {Command = "JOIN", Params = new List<string> {"#channel"}});
54
54
+
break;
55
55
+
}
56
56
+
}
57
57
+
}
58
58
+
}
59
59
+
60
60
+
private void Send(Line line)
61
61
+
{
62
62
+
Console.WriteLine($"> {line.Format()}");
63
63
+
_encoder.Push(line);
64
64
+
while (_encoder.PendingBytes.Length > 0)
65
65
+
_encoder.Pop(_socket.Send(_encoder.PendingBytes));
66
66
+
}
67
67
+
}
68
68
+
}
+30
Sample/Program.cs
···
1
1
+
using System;
2
2
+
using System.Collections.Generic;
3
3
+
using IrcTokens;
4
4
+
5
5
+
namespace Sample
6
6
+
{
7
7
+
public class Program
8
8
+
{
9
9
+
public static void Main(string[] args)
10
10
+
{
11
11
+
// tokenization
12
12
+
var line = new Line("@id=123 :ben!~ben@hostname PRIVMSG #channel :hello there!");
13
13
+
Console.WriteLine(line);
14
14
+
Console.WriteLine(line.Format());
15
15
+
16
16
+
// formatting
17
17
+
var line2 = new Line
18
18
+
{
19
19
+
Command = "USER",
20
20
+
Params = new List<string> {"user", "0", "*", "real name"}
21
21
+
};
22
22
+
Console.WriteLine(line2);
23
23
+
Console.WriteLine(line2.Format());
24
24
+
25
25
+
// stateful example
26
26
+
var client = new Client();
27
27
+
client.Start();
28
28
+
}
29
29
+
}
30
30
+
}
+12
Sample/Sample.csproj
···
1
1
+
<Project Sdk="Microsoft.NET.Sdk">
2
2
+
3
3
+
<PropertyGroup>
4
4
+
<OutputType>Exe</OutputType>
5
5
+
<TargetFramework>netcoreapp3.1</TargetFramework>
6
6
+
</PropertyGroup>
7
7
+
8
8
+
<ItemGroup>
9
9
+
<ProjectReference Include="..\IrcTokens\IrcTokens.csproj" />
10
10
+
</ItemGroup>
11
11
+
12
12
+
</Project>