forked from HarryCordewener/TelnetNegotiationCore
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathKestrelMockServer.cs
More file actions
102 lines (91 loc) · 3.35 KB
/
KestrelMockServer.cs
File metadata and controls
102 lines (91 loc) · 3.35 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
using TelnetNegotiationCore.Interpreters;
using TelnetNegotiationCore.Models;
using Microsoft.AspNetCore.Connections;
using Microsoft.Extensions.Logging;
using TelnetNegotiationCore.Handlers;
using TelnetNegotiationCore.Builders;
using TelnetNegotiationCore.Protocols;
namespace TelnetNegotiationCore.TestServer
{
public class KestrelMockServer(ILogger<KestrelMockServer> logger, ITelnetInterpreterFactory telnetFactory) : ConnectionHandler
{
public ValueTask SignalGMCPAsync((string module, string writeback) val)
{
logger.LogDebug("GMCP Signal: {Module}: {WriteBack}", val.module, val.writeback);
return ValueTask.CompletedTask;
}
public ValueTask SignalMSSPAsync(MSSPConfig val)
{
logger.LogDebug("New MSSP: {@MSSPConfig}", val);
return ValueTask.CompletedTask;
}
public ValueTask SignalNAWSAsync(int height, int width)
{
logger.LogDebug("Client Height and Width updated: {Height}x{Width}", height, width);
return ValueTask.CompletedTask;
}
private static async ValueTask SignalMSDPAsync(MSDPServerHandler handler, TelnetInterpreter telnet, string config) =>
await handler.HandleAsync(telnet, config);
public static async ValueTask WriteBackAsync(byte[] writeback, Encoding encoding, TelnetInterpreter telnet)
{
var str = encoding.GetString(writeback);
if (str.StartsWith("echo"))
{
await telnet.SendAsync(encoding.GetBytes($"We heard: {str}"));
}
Console.WriteLine(encoding.GetString(writeback));
}
private async ValueTask MSDPUpdateBehavior(string resetVariable)
{
logger.LogDebug("MSDP Reset Request: {@Reset}", resetVariable);
await ValueTask.CompletedTask;
}
public override async Task OnConnectedAsync(ConnectionContext connection)
{
using (logger.BeginScope(new Dictionary<string, object> { { "ConnectionId", connection.ConnectionId } }))
{
logger.LogInformation("{ConnectionId} connected", connection.ConnectionId);
var msdpHandler = new MSDPServerHandler(new MSDPServerModel(MSDPUpdateBehavior)
{
Commands = () => ["help", "stats", "info"],
Configurable_Variables = () => ["CLIENT_NAME", "CLIENT_VERSION", "PLUGIN_ID"],
Reportable_Variables = () => ["ROOM"],
Sendable_Variables = () => ["ROOM"],
});
var (telnet, readTask) = await telnetFactory.CreateBuilder()
.OnSubmit(WriteBackAsync)
.AddPlugin<NAWSProtocol>()
.OnNAWS(SignalNAWSAsync)
.AddPlugin<GMCPProtocol>()
.OnGMCPMessage(SignalGMCPAsync)
.AddPlugin<MSDPProtocol>()
.OnMSDPMessage((t, config) => SignalMSDPAsync(msdpHandler, t, config))
.AddPlugin<MSSPProtocol>()
.OnMSSP(SignalMSSPAsync)
.WithMSSPConfig(() => new MSSPConfig
{
Name = "My Telnet Negotiated Server",
UTF_8 = true,
Gameplay = ["ABC", "DEF"],
Extended = new Dictionary<string, dynamic>
{
{ "Foo", "Bar"},
{ "Baz", (string[])["Moo", "Meow"] }
}
})
.AddPlugin<TerminalTypeProtocol>()
.AddPlugin<CharsetProtocol>()
.WithCharsetOrder(Encoding.GetEncoding("utf-8"), Encoding.GetEncoding("iso-8859-1"))
.AddPlugin<EORProtocol>()
.AddPlugin<SuppressGoAheadProtocol>()
.BuildAndStartAsync(connection.Transport);
await readTask;
logger.LogInformation("{ConnectionId} disconnected", connection.ConnectionId);
}
}
}
}