Skip to content

Commit

Permalink
Target .Net 8.0
Browse files Browse the repository at this point in the history
  • Loading branch information
HarryCordewener committed Jan 4, 2024
1 parent 13cdbaf commit e08bc60
Show file tree
Hide file tree
Showing 12 changed files with 58 additions and 77 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/dotnet.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jobs:
- name: Setup .NET
uses: actions/setup-dotnet@v2
with:
dotnet-version: 6.0.x
dotnet-version: 8.0.x
- name: Restore dependencies
run: dotnet restore
- name: Build
Expand Down
2 changes: 1 addition & 1 deletion TelnetNegotiationCore.TestClient/MockPipelineClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ private async Task WriteToOutputStreamAsync(byte[] arg, PipeWriter writer)
public static Task WriteBackAsync(byte[] writeback, Encoding encoding) =>
Task.Run(() => Console.WriteLine(encoding.GetString(writeback)));

public Task SignalGMCPAsync((string module, string writeback) val, Encoding encoding) =>
public Task SignalGMCPAsync((string module, string writeback) val) =>
Task.Run(() => _Logger.Debug("GMCP Signal: {Module}: {WriteBack}", val.module, val.writeback));

public Task SignalMSSPAsync(MSSPConfig val) =>
Expand Down
8 changes: 5 additions & 3 deletions TelnetNegotiationCore.TestServer/KestrelMockServer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ namespace TelnetNegotiationCore.TestServer
public class KestrelMockServer : ConnectionHandler
{
readonly ILogger _Logger;
private static readonly string[] config = ["ABC", "DEF"];
private static readonly string[] value = ["Moo", "Meow"];

public KestrelMockServer(ILogger logger = null): base()
{
Expand All @@ -34,7 +36,7 @@ private async Task WriteToOutputStreamAsync(byte[] arg, PipeWriter writer)
}
}

public Task SignalGMCPAsync((string module, string writeback) val, Encoding encoding) =>
public Task SignalGMCPAsync((string module, string writeback) val) =>
Task.Run(() => _Logger.Debug("GMCP Signal: {Module}: {WriteBack}", val.module, val.writeback));

public Task SignalMSSPAsync(MSSPConfig val) =>
Expand Down Expand Up @@ -63,11 +65,11 @@ public async override Task OnConnectedAsync(ConnectionContext connection)
{
Name = "My Telnet Negotiated Server",
UTF_8 = true,
Gameplay = new[] { "ABC", "DEF" },
Gameplay = config,
Extended = new Dictionary<string, dynamic>
{
{ "Foo", "Bar"},
{ "Baz", new [] {"Moo", "Meow" }}
{ "Baz", value }
}
})
.BuildAsync();
Expand Down
12 changes: 2 additions & 10 deletions TelnetNegotiationCore.TestServer/Startup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,9 @@ public class Startup
{
// This method gets called by the runtime. Use this method to add services to the container.
// For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
public void ConfigureServices(IServiceCollection services)
{
}
public static void ConfigureServices(IServiceCollection _) { }

// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.Run(async (context) =>
{
await Task.CompletedTask;
});
}
public static void Configure(IApplicationBuilder app, IHostingEnvironment _) => app.Run(async _ => await Task.CompletedTask);
}
}
14 changes: 3 additions & 11 deletions TelnetNegotiationCore.UnitTests/CHARSETTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,11 @@ public class CHARSETTests

private Task WriteBackToOutput(byte[] arg1, Encoding arg2) => throw new NotImplementedException();

private Task WriteBackToGMCP((string module, string writeback) arg1, Encoding arg2) => throw new NotImplementedException();
private Task WriteBackToGMCP((string module, string writeback) arg1) => throw new NotImplementedException();

private Task ClientWriteBackToNegotiate(byte[] arg1)
{
_negotiationOutput = arg1;
return Task.CompletedTask;
}
private Task ClientWriteBackToNegotiate(byte[] arg1) => Task.Run(() => _negotiationOutput = arg1);

private Task ServerWriteBackToNegotiate(byte[] arg1)
{
_negotiationOutput = arg1;
return Task.CompletedTask;
}
private Task ServerWriteBackToNegotiate(byte[] arg1) => Task.Run(() => _negotiationOutput = arg1);

[SetUp]
public void Setup()
Expand Down
2 changes: 1 addition & 1 deletion TelnetNegotiationCore.UnitTests/CreateDotGraph.cs
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,6 @@ public async Task WriteServerDotGraph()

private async Task WriteBack(byte[] arg1, Encoding encoding) => await Task.CompletedTask;

private async Task WriteBackToGMCP((string module, string writeback) arg1, Encoding arg2) => await Task.CompletedTask;
private async Task WriteBackToGMCP((string module, string writeback) arg1) => await Task.CompletedTask;
}
}
11 changes: 2 additions & 9 deletions TelnetNegotiationCore.UnitTests/TTypeTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,9 @@ public class TTypeTests

private Task WriteBackToOutput(byte[] arg1, Encoding arg2) => throw new NotImplementedException();

private Task WriteBackToNegotiate(byte[] arg1)
{
_negotiationOutput = arg1;
return Task.CompletedTask;
}
private Task WriteBackToNegotiate(byte[] arg1) => Task.Run(() => _negotiationOutput = arg1);

private Task WriteBackToGMCP((string Package, string Info) tuple, Encoding encoding)
{
throw new NotImplementedException();
}
private Task WriteBackToGMCP((string Package, string Info) tuple) => throw new NotImplementedException();

[SetUp]
public async Task Setup()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>

<IsPackable>false</IsPackable>
</PropertyGroup>
Expand Down
28 changes: 14 additions & 14 deletions TelnetNegotiationCore/Interpreters/TelnetCharsetInterpreter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ private StateMachine<State, Trigger> SetupCharsetNegotiation(StateMachine<State,
/// <param name="_">Ignored</param>
private void GetCharset(StateMachine<State, Trigger>.Transition _)
{
_charsetByteState = new byte[buffer.Length];
_charsetByteState = new byte[_buffer.Length];
_charsetByteIndex = 0;
}

Expand Down Expand Up @@ -196,7 +196,7 @@ private async Task CompleteCharsetAsync(StateMachine<State, Trigger>.Transition
{
if (charsetOffered && Mode == TelnetMode.Server)
{
await CallbackNegotiationAsync(new byte[] { (byte)Trigger.IAC, (byte)Trigger.SB, (byte)Trigger.CHARSET, (byte)Trigger.REJECTED, (byte)Trigger.IAC, (byte)Trigger.SE });
await CallbackNegotiationAsync([(byte)Trigger.IAC, (byte)Trigger.SB, (byte)Trigger.CHARSET, (byte)Trigger.REJECTED, (byte)Trigger.IAC, (byte)Trigger.SE]);
return;
}

Expand All @@ -212,22 +212,22 @@ private async Task CompleteCharsetAsync(StateMachine<State, Trigger>.Transition

if (chosenEncoding == null)
{
await CallbackNegotiationAsync(new byte[] { (byte)Trigger.IAC, (byte)Trigger.SB, (byte)Trigger.CHARSET, (byte)Trigger.REJECTED, (byte)Trigger.IAC, (byte)Trigger.SE });
await CallbackNegotiationAsync([(byte)Trigger.IAC, (byte)Trigger.SB, (byte)Trigger.CHARSET, (byte)Trigger.REJECTED, (byte)Trigger.IAC, (byte)Trigger.SE]);
return;
}

_Logger.Debug("Charsets chosen by us: {@charsetWebName} (CP: {@cp})", chosenEncoding.WebName, chosenEncoding.CodePage);

var preamble = new byte[] { (byte)Trigger.IAC, (byte)Trigger.SB, (byte)Trigger.CHARSET, (byte)Trigger.ACCEPTED };
var charsetAscii = ascii.GetBytes(chosenEncoding.WebName);
var postamble = new byte[] { (byte)Trigger.IAC, (byte)Trigger.SE };
byte[] preamble = [(byte)Trigger.IAC, (byte)Trigger.SB, (byte)Trigger.CHARSET, (byte)Trigger.ACCEPTED];
byte[] charsetAscii = ascii.GetBytes(chosenEncoding.WebName);
byte[] postAmble = [ (byte)Trigger.IAC, (byte)Trigger.SE ];

CurrentEncoding = chosenEncoding;

// TODO: The implementing Server or Client needs to be warned when CurrentEncoding is set!
// This would allow, for instance, the Console to ensure it displays Unicode correctly.

await CallbackNegotiationAsync(preamble.Concat(charsetAscii).Concat(postamble).ToArray());
await CallbackNegotiationAsync([.. preamble, .. charsetAscii, .. postAmble]);
}

/// <summary>
Expand All @@ -243,7 +243,7 @@ private async Task CompleteAcceptedCharsetAsync(StateMachine<State, Trigger>.Tra
catch (Exception ex)
{
_Logger.Error(ex, "Unexpected error during Accepting Charset Negotiation. Could not find charset: {charset}", ascii.GetString(_acceptedCharsetByteState, 0, _acceptedCharsetByteIndex));
await CallbackNegotiationAsync(new byte[] { (byte)Trigger.IAC, (byte)Trigger.SB, (byte)Trigger.CHARSET, (byte)Trigger.REJECTED, (byte)Trigger.IAC, (byte)Trigger.SE });
await CallbackNegotiationAsync([(byte)Trigger.IAC, (byte)Trigger.SB, (byte)Trigger.CHARSET, (byte)Trigger.REJECTED, (byte)Trigger.IAC, (byte)Trigger.SE]);
}
_Logger.Information("Connection: Accepted Charset Negotiation for: {charset}", CurrentEncoding.WebName);
charsetOffered = false;
Expand All @@ -255,7 +255,7 @@ private async Task CompleteAcceptedCharsetAsync(StateMachine<State, Trigger>.Tra
private async Task OnWillingCharsetAsync(StateMachine<State, Trigger>.Transition _)
{
_Logger.Debug("Connection: {ConnectionState}", "Request charset negotiation from Client");
await CallbackNegotiationAsync(new byte[] { (byte)Trigger.IAC, (byte)Trigger.DO, (byte)Trigger.CHARSET });
await CallbackNegotiationAsync([(byte)Trigger.IAC, (byte)Trigger.DO, (byte)Trigger.CHARSET]);
charsetOffered = false;
}

Expand All @@ -265,15 +265,15 @@ private async Task OnWillingCharsetAsync(StateMachine<State, Trigger>.Transition
private async Task WillingCharsetAsync()
{
_Logger.Debug("Connection: {ConnectionState}", "Announcing willingness to Charset!");
await CallbackNegotiationAsync(new byte[] { (byte)Trigger.IAC, (byte)Trigger.WILL, (byte)Trigger.CHARSET });
await CallbackNegotiationAsync([(byte)Trigger.IAC, (byte)Trigger.WILL, (byte)Trigger.CHARSET]);
}

/// <summary>
/// Announce the charsets we support to the client after getting a Do.
/// </summary>
private async Task OnDoCharsetAsync(StateMachine<State, Trigger>.Transition _)
{
_Logger.Debug("Charsets String: {charsetlist}", ";" + string.Join(";", _charsetOrder(Encoding.GetEncodings()).Select(x => x.WebName)));
_Logger.Debug("Charsets String: {CharsetList}", ";" + string.Join(";", _charsetOrder(Encoding.GetEncodings()).Select(x => x.WebName)));
await CallbackNegotiationAsync(SupportedCharacterSets.Value);
charsetOffered = true;
}
Expand All @@ -284,10 +284,10 @@ private async Task OnDoCharsetAsync(StateMachine<State, Trigger>.Transition _)
/// <returns>A byte array representing the charset offering.</returns>
private byte[] CharacterSets()
{
byte[] pre = new byte[] { (byte)Trigger.IAC, (byte)Trigger.SB, (byte)Trigger.CHARSET, (byte)Trigger.REQUEST };
byte[] post = new byte[] { (byte)Trigger.IAC, (byte)Trigger.SE };
byte[] pre = [(byte)Trigger.IAC, (byte)Trigger.SB, (byte)Trigger.CHARSET, (byte)Trigger.REQUEST];
byte[] post = [(byte)Trigger.IAC, (byte)Trigger.SE];
byte[] defaultCharsets = ascii.GetBytes($";{string.Join(";", _charsetOrder(Encoding.GetEncodings()).Select(x => x.WebName))}");
return pre.Concat(defaultCharsets).Concat(post).ToArray();
return [.. pre, .. defaultCharsets, .. post];
}
}
}
32 changes: 17 additions & 15 deletions TelnetNegotiationCore/Interpreters/TelnetGMCPInterpreter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ namespace TelnetNegotiationCore.Interpreters
{
public partial class TelnetInterpreter
{
private List<byte> _gmcpBytes = new();
private List<byte> _GMCPBytes = [];

public Func<(string Package, string Info), Encoding, Task> SignalOnGMCPAsync { get; init; }
public Func<(string Package, string Info), Task> SignalOnGMCPAsync { get; init; }

private StateMachine<State, Trigger> SetupGMCPNegotiation(StateMachine<State, Trigger> tsm)
{
Expand Down Expand Up @@ -55,7 +55,7 @@ private StateMachine<State, Trigger> SetupGMCPNegotiation(StateMachine<State, Tr

tsm.Configure(State.SubNegotiation)
.Permit(Trigger.GMCP, State.AlmostNegotiatingGMCP)
.OnEntry(() => _gmcpBytes.Clear());
.OnEntry(() => _GMCPBytes.Clear());

TriggerHelper.ForAllTriggersButIAC(t => tsm
.Configure(State.EvaluatingGMCPValue)
Expand Down Expand Up @@ -89,7 +89,7 @@ private StateMachine<State, Trigger> SetupGMCPNegotiation(StateMachine<State, Tr
/// <param name="b">Byte.</param>
private void RegisterGMCPValue(OneOf<byte, Trigger> b)
{
_gmcpBytes.Add(b.AsT0);
_GMCPBytes.Add(b.AsT0);
}

public Task SendGMCPCommand(string package, string command) =>
Expand All @@ -101,11 +101,13 @@ public Task SendGMCPCommand(string package, byte[] command) =>
public async Task SendGMCPCommand(byte[] package, byte[] command)
{
await CallbackNegotiationAsync(
new byte[] { (byte)Trigger.IAC, (byte)Trigger.SB, (byte)Trigger.GMCP }
.Concat(package)
.Concat(CurrentEncoding.GetBytes(" "))
.Concat(command)
.Concat(new byte[] { (byte)Trigger.IAC, (byte)Trigger.SE }).ToArray());
[
(byte)Trigger.IAC, (byte)Trigger.SB, (byte)Trigger.GMCP,
.. package,
.. CurrentEncoding.GetBytes(" "),
.. command,
.. new byte[] { (byte)Trigger.IAC, (byte)Trigger.SE },
]);
}

/// <summary>
Expand All @@ -116,12 +118,12 @@ await CallbackNegotiationAsync(
private async Task CompleteGMCPNegotiation(StateMachine<State, Trigger>.Transition _)
{
var space = CurrentEncoding.GetBytes(" ").First();
var firstSpace = _gmcpBytes.FindIndex(x => x == space);
var packageBytes = _gmcpBytes.Take(firstSpace).ToArray();
var rest = _gmcpBytes.Skip(firstSpace + 1).ToArray();
var firstSpace = _GMCPBytes.FindIndex(x => x == space);
var packageBytes = _GMCPBytes.Take(firstSpace).ToArray();
var rest = _GMCPBytes.Skip(firstSpace + 1).ToArray();
// TODO: Check for MSDP information, if so, convert to JSON first, then send as Info.
// TODO: Consideration: a version of this that sends back a Dynamic or other similar object.
await (SignalOnGMCPAsync?.Invoke((Package: CurrentEncoding.GetString(packageBytes), Info: CurrentEncoding.GetString(packageBytes)), CurrentEncoding) ?? Task.CompletedTask);
await (SignalOnGMCPAsync?.Invoke((Package: CurrentEncoding.GetString(packageBytes), Info: CurrentEncoding.GetString(packageBytes))) ?? Task.CompletedTask);
}

/// <summary>
Expand All @@ -133,14 +135,14 @@ private async Task WillGMCPAsync(StateMachine<State, Trigger>.Transition _)
{
_Logger.Debug("Connection: {ConnectionState}", "Announcing the server will GMCP");

await CallbackNegotiationAsync(new byte[] { (byte)Trigger.IAC, (byte)Trigger.WILL, (byte)Trigger.GMCP });
await CallbackNegotiationAsync([(byte)Trigger.IAC, (byte)Trigger.WILL, (byte)Trigger.GMCP]);
}

private async Task DoGMCPAsync(StateMachine<State, Trigger>.Transition _)
{
_Logger.Debug("Connection: {ConnectionState}", "Announcing the client can do GMCP");

await CallbackNegotiationAsync(new byte[] { (byte)Trigger.IAC, (byte)Trigger.DO, (byte)Trigger.GMCP });
await CallbackNegotiationAsync([(byte)Trigger.IAC, (byte)Trigger.DO, (byte)Trigger.GMCP]);
}
}
}
20 changes: 10 additions & 10 deletions TelnetNegotiationCore/Interpreters/TelnetStandardInterpreter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,12 @@ public partial class TelnetInterpreter
/// <summary>
/// Local buffer. We only take up to 5mb in buffer space.
/// </summary>
private readonly byte[] buffer = new byte[5242880];
private readonly byte[] _buffer = new byte[5242880];

/// <summary>
/// Buffer position where we are writing.
/// </summary>
private int bufferposition = 0;
private int _bufferPosition = 0;

/// <summary>
/// Helper function for Byte parameterized triggers.
Expand Down Expand Up @@ -95,7 +95,7 @@ public TelnetInterpreter(TelnetMode mode, ILogger logger = null)
{
Mode = mode;
_Logger = logger ?? Log.Logger.ForContext<TelnetInterpreter>().ForContext("TelnetMode", mode);
_InitialCall = new List<Func<Task>>();
_InitialCall = [];
TelnetStateMachine = new StateMachine<State, Trigger>(State.Accepting);
_parameterizedTriggers = new ParameterizedTriggers();

Expand Down Expand Up @@ -197,8 +197,8 @@ private async Task WriteToBufferAndAdvanceAsync(OneOf<byte, Trigger> b)
{
if (b.AsT0 == (byte)Trigger.CARRIAGERETURN) return;
_Logger.Verbose("Debug: Writing into buffer: {Byte}", b.AsT0);
buffer[bufferposition] = b.AsT0;
bufferposition++;
_buffer[_bufferPosition] = b.AsT0;
_bufferPosition++;
await (CallbackOnByteAsync?.Invoke(b.AsT0, CurrentEncoding) ?? Task.CompletedTask);
}

Expand All @@ -207,9 +207,9 @@ private async Task WriteToBufferAndAdvanceAsync(OneOf<byte, Trigger> b)
/// </summary>
private void WriteToOutput()
{
byte[] cp = new byte[bufferposition];
Array.Copy(buffer, cp, bufferposition);
bufferposition = 0;
byte[] cp = new byte[_bufferPosition];
Array.Copy(_buffer, cp, _bufferPosition);
_bufferPosition = 0;
CallbackOnSubmitAsync.Invoke(cp, CurrentEncoding);
}

Expand Down Expand Up @@ -244,7 +244,7 @@ private void RegisterInitialWilling(Func<Task> fun)
/// TODO: Cache the value of IsDefined, or get a way to compile this down to a faster call that doesn't require reflection each time.
/// </summary>
/// <param name="bt">An integer representation of a byte.</param>
/// <returns>Awaitable Task</returns>
/// <returns>Task</returns>
public async Task InterpretAsync(byte bt)
{
if (Enum.IsDefined(typeof(Trigger), (short)bt))
Expand All @@ -263,7 +263,7 @@ public async Task InterpretAsync(byte bt)
/// TODO: Cache the value of IsDefined, or get a way to compile this down to a faster call that doesn't require reflection each time.
/// </summary>
/// <param name="bt">An integer representation of a byte.</param>
/// <returns>Awaitable Task</returns>
/// <returns>Task</returns>
public async Task InterpretByteArrayAsync(ImmutableArray<byte> byteArray)
{
foreach (var b in byteArray)
Expand Down
2 changes: 1 addition & 1 deletion TelnetNegotiationCore/TelnetNegotiationCore.csproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
<LangVersion>latest</LangVersion>
<Version>1.0.0</Version>
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
Expand Down

0 comments on commit e08bc60

Please sign in to comment.