async void ReceiveTask() { while (State != TCPState.Dead) { if (stream.DataAvailable) { TCPMessageType type = (TCPMessageType)stream.ReadByte(); switch (type) { case TCPMessageType.Map: if (isServer && State == TCPState.WaitingForMap) { var newmap = (List <SignalMap.SignalID>)formatter.Deserialize(stream); Map = new SignalMap(newmap); State = TCPState.Ready; Console.WriteLine($"{Name}: Recieved Map with {Map.Count} signals"); } else { throw new InvalidOperationException(); } break; case TCPMessageType.MapUpdate: if (isServer && State == TCPState.Ready) { var newmap = (List <SignalMap.SignalID>)formatter.Deserialize(stream); var oldcount = Map.Count; Map.AddRange(newmap); Console.WriteLine($"{Name}: Recieved Map Update with {newmap.Count} signals. Map {oldcount} -> {Map.Count} signals."); // map update... } else { throw new InvalidOperationException(); } break; case TCPMessageType.PeerAnnounce: if (State == TCPState.Ready) { // read peers into remotePeers var newpeers = (List <VarInt>)formatter.Deserialize(stream); remotePeers = newpeers.ToList(); Console.WriteLine($"{Name}: Recieved Peers {remotePeers.Print()} "); } else { throw new InvalidOperationException(); } break; case TCPMessageType.Frame: if (State == TCPState.Ready) { var bframe = (BinaryFrame)formatter.Deserialize(stream); var pframe = new PackedFrame( bframe.dstid, bframe.srcid, bframe.payload.Select(u => (VarInt)u), Map); var frame = pframe.Unpack(); Console.WriteLine($"{Name}: Recieved Frame of {frame.signals.Length} signals in {bframe.payload.Length} VarInts"); frame.origin = this; OnReceive?.Invoke(frame); } else { throw new InvalidOperationException(); } break; default: throw new InvalidOperationException(); } } else { await Task.Delay(10); } } }