Files
Commonwealth-Online-Public/server/client_session.py
T
andrew fff6680fe5 Refactor server into reusable core and GUI
Split the monolithic test server into a reusable server core and a thin terminal launcher, and add a PySide6 developer GUI. Added server_core.py (FalloutTogetherServer) with lifecycle control, thread-safe client snapshots, stats and log listener support; added client_session.py for per-client state; added dev_server_app.py GUI and requirements.txt. Updated server.py to use the new server core, and revised server/README.md and docs/dev-log.md to document the new structure, usage, and validation steps. Protocol behavior (welcome/transform/disconnect handling and newline-separated JSON) remains unchanged.
2026-06-02 14:30:20 +12:00

54 lines
1.7 KiB
Python

from __future__ import annotations
import socket
import threading
from dataclasses import dataclass, field
from typing import Any
@dataclass
class ClientSession:
connection: socket.socket
address: tuple[str, int]
player_id: int
connected_at: float
last_packet_at: float | None = None
last_transform: dict[str, Any] | None = None
packets_received: int = 0
packets_sent: int = 0
packets_broadcast: int = 0
_lock: Any = field(repr=False, compare=False, default_factory=threading.RLock)
@property
def label(self) -> str:
return f"{self.address[0]}:{self.address[1]}"
def record_received(self, received_at: float) -> None:
with self._lock:
self.last_packet_at = received_at
self.packets_received += 1
def record_transform(self, packet: dict[str, Any]) -> None:
with self._lock:
self.last_transform = dict(packet)
def record_sent(self, *, broadcast: bool = False) -> None:
with self._lock:
self.packets_sent += 1
if broadcast:
self.packets_broadcast += 1
def to_snapshot(self) -> dict[str, Any]:
with self._lock:
return {
"playerId": self.player_id,
"address": self.address[0],
"port": self.address[1],
"connectedAt": self.connected_at,
"lastPacketAt": self.last_packet_at,
"lastTransform": dict(self.last_transform) if self.last_transform is not None else None,
"packetsReceived": self.packets_received,
"packetsSent": self.packets_sent,
"packetsBroadcast": self.packets_broadcast,
}