using ImageConverter; using PVHelpers; using RemoteFrameBuffer; using System.Net; using System.Net.WebSockets; using System.Text; namespace CollabVM.Server { public class CollabVMv1_2GuacamoleServer { private String tbfile = @"C:\Users\rolan\Downloads\bootsplash.jpg"; private static String[] ParseMessage(String s) { List args = []; while (true) { String[] parts = s.Split('.', 2); if (parts.Length != 2) { throw new ArgumentException("Invalid message format: missing `.`", nameof(s)); } if (Int32.TryParse(parts[0], out Int32 len)) { if (parts[1].Length < len + 1) { throw new ArgumentException("Invalid message format: data doesn't fit in message", nameof(s)); } args.Add(parts[1][..len]); s = parts[1][(len+1)..]; if (parts[1][len] == ',') { continue; }else if (parts[1][len] == ';') { break; } else { throw new ArgumentException("Invalid message format: parameters must be separated by `,`, list closed by `;`", nameof(s)); } } else { throw new ArgumentException("Invalid message format: can't parse length field", nameof(s)); } } return args.ToArray(); } private static String ConstructMessage(params String[] args) => String.Join(',', args.Select((s) => $"{s.Length}.{s}")) + ";"; private RemoteFramebufferClient _client; public CollabVMv1_2GuacamoleServer(RemoteFramebufferClient client) { this._client = client; client.Start(); } public async void HandleSocket(WebSocket ws, IPEndPoint remote) { Console.Error.WriteLine("new WebSocket, who dis?"); #warning we probably don't need this much Byte[] buf = new Byte[1024]; try { while (ws.State == WebSocketState.Open) { #warning probably needs a real ctoken WebSocketReceiveResult recResult = await ws.ReceiveAsync(new ArraySegment(buf), CancellationToken.None); Console.Error.WriteLine(recResult.MessageType); switch (recResult.MessageType) { case WebSocketMessageType.Close: await ws.CloseAsync(WebSocketCloseStatus.NormalClosure, "", CancellationToken.None); break; case WebSocketMessageType.Text: String msg = Encoding.UTF8.GetString(buf, 0, recResult.Count); Console.Error.WriteLine(msg); await this.HandleCommand(ws, ParseMessage(msg)); break; default: throw new NotSupportedException(); } } } finally { ws.Dispose(); } } public async Task HandleCommand(WebSocket ws, params String[] args) { switch (args[0]) { case "cap": break; case "connect": break; case "list": //await this.Reply(ws, "list", "vmx", "Fake test VM", File.ReadAllBytes(tbfile).EncodeBase64String()); await this.Reply(ws, "list", "vmx", "Somewhat fake test VM", this._client.BitMap.BmpToJpg().EncodeBase64String()); break; case "rename": break; } } public async Task Reply(WebSocket ws, params String[] args) { Byte[] buf = Encoding.UTF8.GetBytes(ConstructMessage(args)); await ws.SendAsync(new ArraySegment(buf, 0, buf.Length), WebSocketMessageType.Text, true, CancellationToken.None); } } }