WS send game state

This commit is contained in:
Eden Kirin
2023-03-25 15:54:23 +01:00
parent 0f0fe68890
commit 4b511c0cb8
5 changed files with 41 additions and 18 deletions

View File

@ -18,14 +18,14 @@ from hopper.api.dto import (
from hopper.engine import GameEngine
from hopper.enums import Direction, PlayerMoveResult
from hopper.errors import Collision, PositionOutOfBounds
from hopper.ws_client import send_game_state
from hopper.ws_client import ws_send_game_state
router = APIRouter()
@router.get("/ping", response_model=PingResponse)
async def ping() -> PingResponse:
await send_game_state()
await ws_send_game_state()
return PingResponse(
message="Pong!",
)
@ -48,7 +48,7 @@ async def start_game(
body: StartGameRequestDto,
engine: GameEngine = Depends(get_game_engine),
) -> StartGameResponseDto:
new_player = engine.start_game(player_name=body.player_name)
new_player = await engine.start_game(player_name=body.player_name)
return StartGameResponseDto(
board=engine.board,
@ -118,7 +118,7 @@ async def move_player(
)
try:
move_result = engine.move_player(player, direction)
move_result = await engine.move_player(player, direction)
except PositionOutOfBounds:
raise HTTPException(
status_code=status.HTTP_409_CONFLICT, detail="Position out of bounds"

View File

@ -9,10 +9,11 @@ from hopper.models.board import (
Layer,
LayerObject,
ObjectType,
create_random_position,
create_random_position, BoardLayout,
)
from hopper.models.player import Player, PlayerList, Position
from hopper.watchdog import InactivityWatchdog
from hopper.ws_client import ws_send_game_state
from settings import settings
@ -46,7 +47,7 @@ class GameEngine:
)
self._inacivity_watchdog.start()
def start_game(self, player_name: str) -> Player:
async def start_game(self, player_name: str) -> Player:
self._start_inactivity_watchdog()
player = Player(
name=player_name,
@ -57,9 +58,11 @@ class GameEngine:
logging.info(f"Starting new game for player: {player}")
self.__debug_print_board()
await ws_send_game_state()
return player
def move_player(self, player: Player, direction: Direction) -> PlayerMoveResult:
async def move_player(self, player: Player, direction: Direction) -> PlayerMoveResult:
player.reset_timeout()
new_position = Position(player.position.x, player.position.y)
@ -87,6 +90,8 @@ class GameEngine:
player.position = new_position
player.move_count += 1
await ws_send_game_state()
if self.is_player_on_destination(player):
logging.info(f"Player {player} reached destination!")
return PlayerMoveResult.DESTINATION_REACHED
@ -105,6 +110,8 @@ class GameEngine:
def colided_with_obstacle(self, position: Position) -> bool:
return self.board.get_object_at_position(position) is not None
def get_board_layout(self) -> BoardLayout:
return BoardLayout(board=self.board, players=self.players)
class GameEngineFactory:
@staticmethod
@ -144,6 +151,7 @@ class GameEngineFactory:
def __add_test_player(players: PlayerList) -> None:
if not (settings.debug and settings.debug.CREATE_TEST_PLAYER):
return
player = Player(
name="Pero",
uuid="test-player-id",

View File

@ -1,9 +1,11 @@
import asyncio
import datetime
import logging
import time
from threading import Thread
from hopper.models.player import PlayerList
from hopper.ws_client import ws_send_game_state
from settings import settings
@ -28,6 +30,8 @@ class InactivityWatchdog(Thread):
seconds=settings.inacivity_watchdog.KICK_TIMEOUT
)
send_game_state = False
for player in self.players:
if (
player.can_be_deactivated
@ -36,6 +40,7 @@ class InactivityWatchdog(Thread):
):
player.active = False
logging.info(f"Player {player} set as inactive")
send_game_state = True
# safe remove from list
n = 0
@ -44,8 +49,16 @@ class InactivityWatchdog(Thread):
if player.can_be_deactivated and player.last_seen < kick_threshold:
self.players.pop(n)
logging.info(f"Player {player} kicked out")
send_game_state = True
else:
n += 1
if send_game_state:
self.send_game_state()
def send_game_state(self):
logging.info("Sending WS game state")
asyncio.run(ws_send_game_state())
def stop(self) -> None:
self.stopped = True

View File

@ -3,7 +3,6 @@ from contextlib import asynccontextmanager
import websockets
from hopper.api.dependencies import get_game_engine
from hopper.models.ws_dto import GameStateDto
from settings import settings
@ -15,7 +14,10 @@ async def create_ws_client() -> websockets.WebSocketServerProtocol:
yield websocket
async def send_game_state() -> None:
async def ws_send_game_state() -> None:
# avoid circular imports
from hopper.api.dependencies import get_game_engine
async with create_ws_client() as websocket:
engine = get_game_engine()
@ -23,9 +25,6 @@ async def send_game_state() -> None:
board=engine.board,
destination=engine.board.destination,
players=engine.players,
layers=engine.board.layers,
layers=engine.get_board_layout().layers,
)
print(json.dumps(game_state.dict(), indent=4))
await websocket.send(json.dumps(game_state.dict()))