From a9536ac780eca22d2581b745ce8480817c2ab8e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Feh=C3=A9r=20Roland?= Date: Wed, 4 Feb 2026 15:45:33 +0100 Subject: [PATCH] dis be bork --- YetAnotherDummy/Program.cs | 87 ++++++++++++++++++++++++++++++++++---- 1 file changed, 79 insertions(+), 8 deletions(-) diff --git a/YetAnotherDummy/Program.cs b/YetAnotherDummy/Program.cs index 27538ff..002baad 100644 --- a/YetAnotherDummy/Program.cs +++ b/YetAnotherDummy/Program.cs @@ -1,6 +1,9 @@ // See https://aka.ms/new-console-template for more information using System.Net; using System.Net.Sockets; +using System.Numerics; +using System.Text; +using System.Text.RegularExpressions; using static RemoteFrameBufferClientProtocol; IPAddress tessia = new([192,168,16,253]); @@ -76,7 +79,7 @@ public interface IRemoteFrameBufferClientStreamProvider } } -public class RemoteFramebufferClient +public partial class RemoteFramebufferClient { private static Dictionary _protocolHandlers; @@ -117,13 +120,46 @@ public class RemoteFramebufferClient private void Worker() { + Int32 failcount = 0; while (!this.cancellationTokenSource.Token.IsCancellationRequested) { Console.Error.WriteLine("Attempting to connect"); Stream s = this._socketProvider.GetRemoteFrameBufferClientStream(); 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) - { - public Int16 Major = major; - public Int16 Minor = minor; - } - + [GeneratedRegex(@"^RFB (?'major'\d{3}).(?'minor'\d{3})$")] + private static partial Regex _rfbVersionRegex(); } +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 { protected readonly Stream vncStream; + public abstract RfbProtoVersion Version { get; } public RemoteFrameBufferClientProtocol(Stream s) { @@ -169,6 +238,8 @@ public abstract class RemoteFrameBufferClientProtocol public class RemoteFrameBufferClientProtocol_3_3 : RemoteFrameBufferClientProtocol { + public override RfbProtoVersion Version => new(3,3); + public RemoteFrameBufferClientProtocol_3_3(Stream s) : base(s) { }