WSMessage object
This commit is contained in:
@ -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) => {
|
||||||
|
|||||||
@ -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
8
hopper/models/product.py
Normal 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()))
|
||||||
@ -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
|
||||||
|
|||||||
@ -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"""
|
||||||
|
|||||||
Reference in New Issue
Block a user