From 99b242eee6efa555b5c0659e28fe029e12ec92af Mon Sep 17 00:00:00 2001 From: Nomads_Reach <144523850+NomadsReach@users.noreply.github.com> Date: Sun, 16 Aug 2026 00:44:34 -0400 Subject: [PATCH] Send GNS packets without TCP framing --- server/gns_gameplay_adapter.py | 60 +++++++++++++++++++++------------- 1 file changed, 37 insertions(+), 23 deletions(-) diff --git a/server/gns_gameplay_adapter.py b/server/gns_gameplay_adapter.py index e5f8d21..64e58e0 100644 --- a/server/gns_gameplay_adapter.py +++ b/server/gns_gameplay_adapter.py @@ -41,29 +41,7 @@ class GnsConnectionAdapter: with self._lock: self._closed = True - def sendall(self, framed_payload: bytes) -> None: - raw = bytes(framed_payload) - with self._lock: - if self._closed: - raise OSError("GNS connection is closed") - if not raw.endswith(b"\n") or raw.count(b"\n") != 1: - raise OSError("GNS compatibility adapter received invalid TCP framing") - payload = raw[:-1] - try: - packet = decode_packet(payload) - except PacketCodecError as error: - raise OSError(f"invalid outbound GNS packet: {error}") from error - packet_type = packet["type"] - wire_payload = payload - if is_snapshot_packet(packet_type): - with self._lock: - sequence = self._snapshot_counters[packet_type].advance() - try: - wire_payload = encode_snapshot(packet_type, payload, sequence) - except SnapshotEnvelopeError as error: - raise ValueError(str(error)) from error - encoded = EncodedPacket(packet_type, wire_payload, delivery_for_packet_type(packet_type)) - result = self.transport.send_encoded(self.connection_id, encoded) + def _handle_send_result(self, packet_type: str, result: SendResult) -> None: if result is SendResult.SENT: return if result is SendResult.DROPPED and is_snapshot_packet(packet_type): @@ -81,6 +59,42 @@ class GnsConnectionAdapter: raise ValueError("GNS outbound packet exceeds maximum message size") raise OSError("GNS outbound send failed") + def send_encoded(self, encoded: EncodedPacket) -> None: + with self._lock: + if self._closed: + raise OSError("GNS connection is closed") + + packet_type = encoded.packet_type + expected_delivery = delivery_for_packet_type(packet_type) + if encoded.delivery is not expected_delivery: + raise OSError("GNS packet delivery metadata does not match protocol policy") + + wire_payload = encoded.payload + if is_snapshot_packet(packet_type): + with self._lock: + sequence = self._snapshot_counters[packet_type].advance() + try: + wire_payload = encode_snapshot(packet_type, encoded.payload, sequence) + except SnapshotEnvelopeError as error: + raise ValueError(str(error)) from error + + wire_packet = EncodedPacket(packet_type, wire_payload, encoded.delivery) + result = self.transport.send_encoded(self.connection_id, wire_packet) + self._handle_send_result(packet_type, result) + + def sendall(self, framed_payload: bytes) -> None: + """Temporary compatibility for callers that still emit TCP line framing.""" + raw = bytes(framed_payload) + if not raw.endswith(b"\n") or raw.count(b"\n") != 1: + raise OSError("GNS compatibility adapter received invalid TCP framing") + payload = raw[:-1] + try: + packet = decode_packet(payload) + except PacketCodecError as error: + raise OSError(f"invalid outbound GNS packet: {error}") from error + packet_type = packet["type"] + self.send_encoded(EncodedPacket(packet_type, payload, delivery_for_packet_type(packet_type))) + def close(self) -> None: with self._lock: if self._closed: