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
wip
benharri.org
3 weeks ago
2f5adc1b
6f8e62e9
+288
-2
7 changed files
expand all
collapse all
unified
split
Directory.Packages.props
IRCRobots
Bot.cs
IRCRobots.csproj
Params.cs
Security.cs
Server.cs
IRCSharp.slnx
+2
-2
Directory.Packages.props
···
3
3
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
4
4
</PropertyGroup>
5
5
<ItemGroup>
6
6
-
<PackageVersion Include="Microsoft.SourceLink.Gitea" Version="8.0.0" />
7
7
-
<PackageVersion Include="TUnit" Version="1.2.11" />
6
6
+
<PackageVersion Include="Microsoft.SourceLink.Gitea" Version="10.0.103" />
7
7
+
<PackageVersion Include="TUnit" Version="1.16.4" />
8
8
<PackageVersion Include="YamlDotNet" Version="16.3.0" />
9
9
</ItemGroup>
10
10
</Project>
+46
IRCRobots/Bot.cs
···
1
1
+
namespace IRCRobots;
2
2
+
3
3
+
public class Bot : IBot
4
4
+
{
5
5
+
private readonly Dictionary<string, Server> _servers = [];
6
6
+
private readonly Queue<Server> _serverQueue = [];
7
7
+
8
8
+
public Server CreateServer(string name)
9
9
+
{
10
10
+
throw new NotImplementedException();
11
11
+
}
12
12
+
13
13
+
public Task Disconnected(Server server)
14
14
+
{
15
15
+
throw new NotImplementedException();
16
16
+
}
17
17
+
18
18
+
public async Task DisconnectAsync(Server server)
19
19
+
{
20
20
+
_servers.Remove(server.Name);
21
21
+
await server.DisconnectAsync();
22
22
+
}
23
23
+
24
24
+
public async Task<Server> AddServerAsync(string name, ConnectionParams connectionParams)
25
25
+
{
26
26
+
var server = CreateServer(name);
27
27
+
_servers[name] = server;
28
28
+
await server.ConnectAsync();
29
29
+
_serverQueue.Enqueue(server);
30
30
+
return server;
31
31
+
}
32
32
+
33
33
+
public Task RunAsync()
34
34
+
{
35
35
+
return Task.CompletedTask;
36
36
+
}
37
37
+
}
38
38
+
39
39
+
public interface IBot
40
40
+
{
41
41
+
Server CreateServer(string name);
42
42
+
Task Disconnected(Server server);
43
43
+
Task DisconnectAsync(Server server);
44
44
+
Task<Server> AddServerAsync(string name, ConnectionParams connectionParams);
45
45
+
Task RunAsync();
46
46
+
}
+18
IRCRobots/IRCRobots.csproj
···
1
1
+
<Project Sdk="Microsoft.NET.Sdk">
2
2
+
<PropertyGroup>
3
3
+
<TargetFramework>netstandard2.0</TargetFramework>
4
4
+
<PackageId>IRCRobots</PackageId>
5
5
+
<IsPackable>true</IsPackable>
6
6
+
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
7
7
+
<DebugType>embedded</DebugType>
8
8
+
</PropertyGroup>
9
9
+
<ItemGroup>
10
10
+
<ProjectReference Include="..\IRCStates\IRCStates.csproj" />
11
11
+
</ItemGroup>
12
12
+
<ItemGroup>
13
13
+
<None Include="README.md" Pack="true" PackagePath="\" />
14
14
+
</ItemGroup>
15
15
+
<ItemGroup>
16
16
+
<PackageReference Include="Microsoft.SourceLink.Gitea" PrivateAssets="All" />
17
17
+
</ItemGroup>
18
18
+
</Project>
+64
IRCRobots/Params.cs
···
1
1
+
namespace IRCRobots;
2
2
+
3
3
+
public abstract class SaslParams
4
4
+
{
5
5
+
public virtual string Mechanism { get; set; }
6
6
+
}
7
7
+
8
8
+
public class SaslUserPass : SaslParams
9
9
+
{
10
10
+
public override string Mechanism => "USERPASS";
11
11
+
public string Username { get; set; }
12
12
+
public string Password { get; set; }
13
13
+
}
14
14
+
15
15
+
public class SaslSCRAM : SaslUserPass
16
16
+
{
17
17
+
public override string Mechanism => "SCRAM";
18
18
+
}
19
19
+
20
20
+
public class SaslExternal : SaslParams
21
21
+
{
22
22
+
public override string Mechanism => "EXTERNAL";
23
23
+
}
24
24
+
25
25
+
public record struct STSPolicy
26
26
+
{
27
27
+
public int Created { get; set; }
28
28
+
public int Port { get; set; }
29
29
+
public int Duration { get; set; }
30
30
+
public bool Preload { get; set; }
31
31
+
}
32
32
+
33
33
+
public record struct ResumePolicy
34
34
+
{
35
35
+
public string Address { get; set; }
36
36
+
public string Token { get; set; }
37
37
+
}
38
38
+
39
39
+
public record struct ConnectionParams()
40
40
+
{
41
41
+
public string Nickname { get; set; }
42
42
+
public string Host { get; set; }
43
43
+
public int Port { get; set; }
44
44
+
45
45
+
public string Username { get; set; }
46
46
+
public string Realname { get; set; }
47
47
+
public string Bindhost { get; set; }
48
48
+
49
49
+
public string Password { get; set; }
50
50
+
public SaslParams Sasl { get; set; }
51
51
+
52
52
+
public STSPolicy STS { get; set; }
53
53
+
public ResumePolicy Resume { get; set; }
54
54
+
55
55
+
public int Reconnect { get; set; } = 10;
56
56
+
public List<string> AlternateNicknames { get; set; } = [];
57
57
+
58
58
+
public List<string> Autojoin { get; set; } = [];
59
59
+
60
60
+
public static ConnectionParams FromHoststring(string nickname, string hoststring)
61
61
+
{
62
62
+
return new();
63
63
+
}
64
64
+
}
+12
IRCRobots/Security.cs
···
1
1
+
using System.Net.Security;
2
2
+
3
3
+
namespace IRCRobots;
4
4
+
5
5
+
public abstract class Tls((string, string) ClientKeypair)
6
6
+
{
7
7
+
}
8
8
+
9
9
+
public class TlsNoVerify((string, string) clientKeypair) : Tls(clientKeypair);
10
10
+
public class TlsVerifyChain((string, string) clientKeypair) : Tls(clientKeypair);
11
11
+
public class TlsVerifyHash((string, string) clientKeypair) : TlsNoVerify(clientKeypair);
12
12
+
public class TlsVerifySha512((string, string) clientKeypair) : TlsVerifyHash(clientKeypair);
+145
IRCRobots/Server.cs
···
1
1
+
using IRCTokens;
2
2
+
3
3
+
namespace IRCRobots;
4
4
+
5
5
+
public class Server : IServer
6
6
+
{
7
7
+
public string Name { get; set; }
8
8
+
public IBot Bot { get; set; }
9
9
+
public bool Disconnected { get; set; }
10
10
+
public ConnectionParams Params { get; set; }
11
11
+
public List<ICapability> DesiredCaps { get; set; }
12
12
+
public float LastRead { get; set; }
13
13
+
14
14
+
private int _sentCount = 0;
15
15
+
16
16
+
public Task<SentLine> SendRawAsync(string line, SendPriority priority = SendPriority.Medium) =>
17
17
+
SendAsync(new(line), priority);
18
18
+
19
19
+
public Task<SentLine> SendAsync(Line line, SendPriority priority = SendPriority.Medium)
20
20
+
{
21
21
+
LinePresend(line);
22
22
+
var sentLine = new SentLine(_sentCount++, priority, line);
23
23
+
24
24
+
var label = CapAvailable(CAP_LABEL);
25
25
+
if (label is not null)
26
26
+
{
27
27
+
}
28
28
+
}
29
29
+
30
30
+
public Task<Line> WaitForAsync()
31
31
+
{
32
32
+
throw new NotImplementedException();
33
33
+
}
34
34
+
35
35
+
public void SetThrottle(int rate, float time)
36
36
+
{
37
37
+
throw new NotImplementedException();
38
38
+
}
39
39
+
40
40
+
public (string, int) ServerAddress()
41
41
+
{
42
42
+
throw new NotImplementedException();
43
43
+
}
44
44
+
45
45
+
public Task ConnectAsync(ITcpTransport transport, ConnectionParams connectionParams)
46
46
+
{
47
47
+
throw new NotImplementedException();
48
48
+
}
49
49
+
50
50
+
public Task DisconnectAsync()
51
51
+
{
52
52
+
throw new NotImplementedException();
53
53
+
}
54
54
+
55
55
+
public void LinePreread(Line line)
56
56
+
{
57
57
+
throw new NotImplementedException();
58
58
+
}
59
59
+
60
60
+
public void LinePresend(Line line)
61
61
+
{
62
62
+
throw new NotImplementedException();
63
63
+
}
64
64
+
65
65
+
public Task LineReadAsync(Line line)
66
66
+
{
67
67
+
throw new NotImplementedException();
68
68
+
}
69
69
+
70
70
+
public Task LineSendAsync(Line line)
71
71
+
{
72
72
+
throw new NotImplementedException();
73
73
+
}
74
74
+
75
75
+
public Task StsPolicyAsync(STSPolicy sts)
76
76
+
{
77
77
+
throw new NotImplementedException();
78
78
+
}
79
79
+
80
80
+
public Task ResumePolicyAsync(ResumePolicy resume)
81
81
+
{
82
82
+
throw new NotImplementedException();
83
83
+
}
84
84
+
85
85
+
public bool CapAgreed(ICapability capability)
86
86
+
{
87
87
+
throw new NotImplementedException();
88
88
+
}
89
89
+
90
90
+
public string CapAvailable(ICapability capability)
91
91
+
{
92
92
+
throw new NotImplementedException();
93
93
+
}
94
94
+
95
95
+
public Task<bool> SaslAuthAsync(SaslParams sasl)
96
96
+
{
97
97
+
throw new NotImplementedException();
98
98
+
}
99
99
+
}
100
100
+
101
101
+
public enum SendPriority
102
102
+
{
103
103
+
High = 0,
104
104
+
Medium = 10,
105
105
+
Low = 20,
106
106
+
Default = Medium
107
107
+
}
108
108
+
public interface IServer
109
109
+
{
110
110
+
Task<SentLine> SendRawAsync(string line, SendPriority priority = SendPriority.Default);
111
111
+
Task<SentLine> SendAsync(Line line, SendPriority priority = SendPriority.Default);
112
112
+
113
113
+
Task<Line> WaitForAsync();
114
114
+
void SetThrottle(int rate, float time);
115
115
+
(string, int) ServerAddress();
116
116
+
117
117
+
Task ConnectAsync(ITcpTransport transport, ConnectionParams connectionParams);
118
118
+
Task DisconnectAsync();
119
119
+
120
120
+
void LinePreread(Line line);
121
121
+
void LinePresend(Line line);
122
122
+
Task LineReadAsync(Line line);
123
123
+
Task LineSendAsync(Line line);
124
124
+
Task StsPolicyAsync(STSPolicy sts);
125
125
+
Task ResumePolicyAsync(ResumePolicy resume);
126
126
+
127
127
+
bool CapAgreed(ICapability capability);
128
128
+
string CapAvailable(ICapability capability);
129
129
+
130
130
+
Task<bool> SaslAuthAsync(SaslParams sasl);
131
131
+
}
132
132
+
133
133
+
public interface ITcpTransport
134
134
+
{
135
135
+
(ITcpReader, ITcpWriter) Connect(string hostname, int port, Tls tls, string bindhost);
136
136
+
}
137
137
+
138
138
+
public interface ICapability
139
139
+
{
140
140
+
string Available(IEnumerable<string> capabilities);
141
141
+
bool Match(string capability);
142
142
+
ICapability Copy();
143
143
+
}
144
144
+
145
145
+
public record struct SentLine(int Id, SendPriority Priority, Line Line);
+1
IRCSharp.slnx
···
3
3
<Project Path="Examples/States/States.csproj" />
4
4
<Project Path="Examples/Tokens/Tokens.csproj" />
5
5
</Folder>
6
6
+
<Project Path="IRCRobots/IRCRobots.csproj" />
6
7
<Project Path="IRCSharp.Tests/IRCSharp.Tests.csproj" />
7
8
<Project Path="IRCStates/IRCStates.csproj" />
8
9
<Project Path="IRCTokens/IRCTokens.csproj" />