import json from urllib.parse import parse_qs from channels.generic.websocket import AsyncJsonWebsocketConsumer from fupogfakta.models import Player class GameConsumer(AsyncJsonWebsocketConsumer): """ WebSocket consumer for a game session. URL: ws/game// Query params: - session_token: player session token (players only) - role=host: skip token check for host in MVP """ async def connect(self): self.session_code = self.scope["url_route"]["kwargs"]["session_code"].upper() self.group_name = f"game_{self.session_code}" query_string = self.scope.get("query_string", b"").decode() params = parse_qs(query_string) role = params.get("role", [None])[0] session_token = params.get("session_token", [None])[0] if role != "host": if not session_token: await self.close(code=4001) return try: self.player = await Player.objects.aget( session_token=session_token, session__code=self.session_code, ) except Player.DoesNotExist: await self.close(code=4003) return else: self.player = None await self.channel_layer.group_add(self.group_name, self.channel_name) await self.accept() async def disconnect(self, close_code): if hasattr(self, "group_name"): await self.channel_layer.group_discard(self.group_name, self.channel_name) async def receive_json(self, content, **kwargs): if content.get("type") == "ping": await self.send_json({"type": "pong"}) # --- Group message handlers --- async def phase_event(self, event): """Forward any phase_event broadcast to the WebSocket client.""" payload = dict(event.get("payload") or {}) payload["type"] = event["event_type"] await self.send_json(payload)