diff --git a/server/gns_gameplay_adapter.py b/server/gns_gameplay_adapter.py index ed9fd62..db2eeca 100644 --- a/server/gns_gameplay_adapter.py +++ b/server/gns_gameplay_adapter.py @@ -1,13 +1,12 @@ from __future__ import annotations -import json import threading import time from dataclasses import dataclass from typing import TYPE_CHECKING from client_session import ClientSession -from gns_transport import EventType, GnsEvent, GnsServerTransport, RemoteEndpoint, SendResult +from gns_transport import EventType, GnsEvent, GnsServerTransport, GnsTransportError, SendResult from packet_codec import EncodedPacket, PacketCodecError, decode_packet from transport_policy import delivery_for_packet_type, is_snapshot_packet @@ -51,8 +50,12 @@ class GnsConnectionAdapter: packet_type = packet["type"] encoded = EncodedPacket(packet_type, payload, delivery_for_packet_type(packet_type)) result = self.transport.send_encoded(self.connection_id, encoded) - if result in (SendResult.SENT, SendResult.DROPPED): + if result is SendResult.SENT: return + if result is SendResult.DROPPED and is_snapshot_packet(packet_type): + return + if result is SendResult.DROPPED: + raise OSError("GNS refused to queue a reliable message") if result is SendResult.BACKPRESSURE and is_snapshot_packet(packet_type): return if result is SendResult.BACKPRESSURE: @@ -94,13 +97,15 @@ class GnsGameplayAdapter: self.transport.send_packet(connection_id, packet) def _welcome_packet(self, client: ClientSession) -> dict: + from server_core import PROTOCOL_VERSION + return { "type": "welcome", "playerId": client.player_id, "serverTime": time.time(), "serverName": self.server.server_name, "serverDescription": self.server.server_description, - "protocolVersion": self.server.PROTOCOL_VERSION if hasattr(self.server, "PROTOCOL_VERSION") else 2, + "protocolVersion": PROTOCOL_VERSION, "capabilities": [ "interest-v1", "hello-v2", @@ -270,7 +275,13 @@ class GnsGameplayAdapter: with self._lock: if not self._thread_running: break - processed = self.pump_once() + try: + processed = self.pump_once() + except GnsTransportError as error: + self.server._log(f"GNS transport loop stopped: {error}", level="error") + with self._lock: + self._thread_running = False + break if processed == 0: time.sleep(0.002) @@ -293,7 +304,10 @@ class GnsGameplayAdapter: for connection_id, client in clients: if isinstance(client.connection, GnsConnectionAdapter): client.connection.mark_remote_closed() - self.transport.disconnect(connection_id, debug="GNS adapter stopped") + try: + self.transport.disconnect(connection_id, debug="GNS adapter stopped") + except Exception: + pass self.server._disconnect_client(client) with self._lock: self._clients.clear()