WSMessage object

This commit is contained in:
Eden Kirin
2023-03-30 18:53:24 +02:00
parent b80130d942
commit 6111d07f09
5 changed files with 54 additions and 12 deletions

View File

@ -115,6 +115,13 @@
renderCellContent(position, BOARD_ICONS.DESTINATION); renderCellContent(position, BOARD_ICONS.DESTINATION);
} }
function renderGameDump(data) {
createBoard(data.board);
renderObstacles(data.layers)
renderDestination(data.destination.position);
renderPlayerList(data.players);
renderPlayers(data.players);
}
function wsConnect() { function wsConnect() {
let ws = new WebSocket('ws://localhost:8011'); let ws = new WebSocket('ws://localhost:8011');
@ -123,14 +130,16 @@
}; };
ws.onmessage = (e) => { ws.onmessage = (e) => {
const data = JSON.parse(e.data); const wsMessage = JSON.parse(e.data);
console.log("WS message received:", data) console.log("WS message received:", wsMessage)
createBoard(data.board); switch (wsMessage.message) {
renderObstacles(data.layers) case "game_dump":
renderDestination(data.destination.position); renderGameDump(wsMessage.data);
renderPlayerList(data.players); break;
renderPlayers(data.players); default:
console.error("Unknown message:", wsMessage)
}
}; };
ws.onclose = (e) => { ws.onclose = (e) => {

View File

@ -3,6 +3,7 @@ from dataclasses import dataclass
from typing import List, Optional from typing import List, Optional
from hopper.models.player import Player from hopper.models.player import Player
from hopper.models.product import Product
@dataclass @dataclass
@ -44,4 +45,5 @@ class Settings:
ws_server: WSServerSettings ws_server: WSServerSettings
purchase_timeout: int = 10 # seconds purchase_timeout: int = 10 # seconds
log_level: int = logging.INFO log_level: int = logging.INFO
products: Optional[List[Product]] = None
debug: Optional[DebugSettings] = None debug: Optional[DebugSettings] = None

8
hopper/models/product.py Normal file
View File

@ -0,0 +1,8 @@
from dataclasses import dataclass, field
import uuid
@dataclass
class Product:
name: str
uuid: str = field(default_factory=lambda: str(uuid.uuid4()))

View File

@ -1,6 +1,10 @@
from __future__ import annotations from __future__ import annotations
import json
from typing import TypeVar, Generic
from pydantic import Field from pydantic import Field
from pydantic.generics import GenericModel
from hopper.api.dto import BaseModel, BoardDto, DestinationDto, PlayerDto, PositionDto from hopper.api.dto import BaseModel, BoardDto, DestinationDto, PlayerDto, PositionDto
from hopper.enums import ObjectType from hopper.enums import ObjectType
@ -15,6 +19,7 @@ class LayerDto(BaseModel):
name: str name: str
objects: list[LayerObjectDto] objects: list[LayerObjectDto]
class GameDumpPlayerDto(PlayerDto): class GameDumpPlayerDto(PlayerDto):
... ...
@ -24,3 +29,22 @@ class GameDumpDto(BaseModel):
destination: DestinationDto destination: DestinationDto
players: list[GameDumpPlayerDto] players: list[GameDumpPlayerDto]
layers: list[LayerDto] layers: list[LayerDto]
TMessageData = TypeVar("TMessageData", bound=BaseModel)
class WSMessage(GenericModel):
message: str
data: TMessageData
def __str__(self) -> str:
return self.to_str()
def to_str(self) -> str:
return json.dumps(self.dict())
class WSGameDumpMessage(WSMessage):
message: str = "game_dump"
data: GameDumpDto

View File

@ -1,5 +1,4 @@
import asyncio import asyncio
import json
import logging import logging
from threading import Thread from threading import Thread
@ -7,7 +6,7 @@ import websockets
from websockets import WebSocketServerProtocol from websockets import WebSocketServerProtocol
from websockets.exceptions import ConnectionClosedOK from websockets.exceptions import ConnectionClosedOK
from hopper.models.ws_dto import GameDumpDto from hopper.models.ws_dto import GameDumpDto, WSGameDumpMessage
from settings import settings from settings import settings
@ -32,7 +31,7 @@ class WSServer(Thread):
self.connected_clients.remove(websocket) self.connected_clients.remove(websocket)
logging.info(f"Remove client: {websocket.id}") logging.info(f"Remove client: {websocket.id}")
def _create_game_dump_message(self) -> str: def _create_game_dump_message(self) -> WSGameDumpMessage:
# avoid circular imports # avoid circular imports
from hopper.api.dependencies import get_game_engine from hopper.api.dependencies import get_game_engine
@ -44,7 +43,7 @@ class WSServer(Thread):
players=engine.players, players=engine.players,
layers=engine.get_board_layout().layers, layers=engine.get_board_layout().layers,
) )
return json.dumps(game_dump.dict()) return WSGameDumpMessage(data=game_dump)
async def send_game_dump_to_client( async def send_game_dump_to_client(
self, websocket: WebSocketServerProtocol self, websocket: WebSocketServerProtocol
@ -52,7 +51,7 @@ class WSServer(Thread):
"""Send game dump to the client""" """Send game dump to the client"""
message = self._create_game_dump_message() message = self._create_game_dump_message()
logging.debug(f"Sending game dump to client: {websocket.id}") logging.debug(f"Sending game dump to client: {websocket.id}")
await websocket.send(message) await websocket.send(message.to_str())
async def send_game_dump(self) -> None: async def send_game_dump(self) -> None:
"""Broadcast game state to all connected clients""" """Broadcast game state to all connected clients"""