dis be bork

This commit is contained in:
2026-02-04 15:45:33 +01:00
parent b8d02bb115
commit a9536ac780

View File

@@ -1,6 +1,9 @@
// See https://aka.ms/new-console-template for more information // See https://aka.ms/new-console-template for more information
using System.Net; using System.Net;
using System.Net.Sockets; using System.Net.Sockets;
using System.Numerics;
using System.Text;
using System.Text.RegularExpressions;
using static RemoteFrameBufferClientProtocol; using static RemoteFrameBufferClientProtocol;
IPAddress tessia = new([192,168,16,253]); IPAddress tessia = new([192,168,16,253]);
@@ -76,7 +79,7 @@ public interface IRemoteFrameBufferClientStreamProvider
} }
} }
public class RemoteFramebufferClient public partial class RemoteFramebufferClient
{ {
private static Dictionary<RfbProtoVersion, RemoteFrameBufferClientProtocol.IRemoteFramebufferClientProtocolFactory> _protocolHandlers; private static Dictionary<RfbProtoVersion, RemoteFrameBufferClientProtocol.IRemoteFramebufferClientProtocolFactory> _protocolHandlers;
@@ -117,13 +120,46 @@ public class RemoteFramebufferClient
private void Worker() private void Worker()
{ {
Int32 failcount = 0;
while (!this.cancellationTokenSource.Token.IsCancellationRequested) while (!this.cancellationTokenSource.Token.IsCancellationRequested)
{ {
Console.Error.WriteLine("Attempting to connect"); Console.Error.WriteLine("Attempting to connect");
Stream s = this._socketProvider.GetRemoteFrameBufferClientStream(); Stream s = this._socketProvider.GetRemoteFrameBufferClientStream();
using (s) using (s)
{ {
Byte[] buf = new Byte[12];
CancellationTokenSource readTimeout = new CancellationTokenSource(TimeSpan.FromSeconds(5));
CancellationTokenSource readTokenSource = CancellationTokenSource.CreateLinkedTokenSource(this.cancellationTokenSource.Token, readTimeout.Token);
try
{
s.ReadExactlyAsync(buf, 0, buf.Length, readTokenSource.Token).AsTask().Wait();
}catch (AggregateException e)// TODO: go through InnerExceptions and only throw if we are left with unhandled ones
{
if (e.InnerException is TaskCanceledException)
{
if (failcount++ >= 5)
{
break;
}
Task.Delay(1000).Wait();
continue;
}else
{
throw new Exception("Something broke. Yeah, I know, very useful message.", e);
}
}
failcount = 0;
String protover = Encoding.ASCII.GetString(buf);
Console.Error.Write($"Server protocol: {protover}");
Match m = _rfbVersionRegex().Match(protover);
if (!m.Success)
{
throw new Exception("Cannot parse protocol version");
}
RfbProtoVersion serverVersion = new(Int16.Parse(m.Groups["major"].Value), Int16.Parse(m.Groups["minor"].Value));
RfbProtoVersion maxProto = _protocolHandlers.Keys.Where((ph) => ph <= serverVersion).Max();
RemoteFrameBufferClientProtocol proto = _protocolHandlers[maxProto].Construct(s);
Console.Error.WriteLine($"Using client protocol {proto.Version.Major}.{proto.Version.Minor}");
} }
} }
@@ -139,17 +175,50 @@ public class RemoteFramebufferClient
} }
} }
private struct RfbProtoVersion(Int16 major, Int16 minor) [GeneratedRegex(@"^RFB (?'major'\d{3}).(?'minor'\d{3})$")]
{ private static partial Regex _rfbVersionRegex();
public Int16 Major = major;
public Int16 Minor = minor;
}
} }
public struct RfbProtoVersion(Int16 major, Int16 minor)
{
public Int16 Major = major;
public Int16 Minor = minor;
public static Boolean operator ==(RfbProtoVersion a, RfbProtoVersion b)
{
return (a.Major == b.Major) && (a.Minor == b.Minor);
}
public static Boolean operator !=(RfbProtoVersion a, RfbProtoVersion b)
{
return !(a == b);
}
public static Boolean operator <(RfbProtoVersion a, RfbProtoVersion b)
{
if (a.Major == b.Major)
{
return a.Minor < b.Minor;
} else
{
return a.Major < b.Major;
}
}
public static Boolean operator >(RfbProtoVersion a, RfbProtoVersion b)
{
return b < a;
}
public static Boolean operator <=(RfbProtoVersion a, RfbProtoVersion b)
{
return b < a;
}
public static Boolean operator >=(RfbProtoVersion a, RfbProtoVersion b)
{
return a < b;
}
}
public abstract class RemoteFrameBufferClientProtocol public abstract class RemoteFrameBufferClientProtocol
{ {
protected readonly Stream vncStream; protected readonly Stream vncStream;
public abstract RfbProtoVersion Version { get; }
public RemoteFrameBufferClientProtocol(Stream s) public RemoteFrameBufferClientProtocol(Stream s)
{ {
@@ -169,6 +238,8 @@ public abstract class RemoteFrameBufferClientProtocol
public class RemoteFrameBufferClientProtocol_3_3 : RemoteFrameBufferClientProtocol public class RemoteFrameBufferClientProtocol_3_3 : RemoteFrameBufferClientProtocol
{ {
public override RfbProtoVersion Version => new(3,3);
public RemoteFrameBufferClientProtocol_3_3(Stream s) : base(s) public RemoteFrameBufferClientProtocol_3_3(Stream s) : base(s)
{ {
} }