From 69e087c0c9b944820a4b0db92ba0bf7bbab38924 Mon Sep 17 00:00:00 2001 From: Eden Kirin Date: Wed, 10 May 2023 15:49:08 +0200 Subject: [PATCH] Drop old purchase views and models --- frontend/index.html | 38 +++++++++++++++++++++++++- frontend/js/frontend.js | 14 ++++++++++ hopper/api/dto.py | 15 ----------- hopper/api/views.py | 60 ----------------------------------------- hopper/engine.py | 26 ++++++++---------- hopper/errors.py | 4 --- hopper/models/ws_dto.py | 21 +++++---------- hopper/ws_server.py | 28 ++++++++----------- 8 files changed, 79 insertions(+), 127 deletions(-) diff --git a/frontend/index.html b/frontend/index.html index 1f06bca..25ea775 100644 --- a/frontend/index.html +++ b/frontend/index.html @@ -6,8 +6,9 @@ + integrity="sha384-rbsA2VBKQhggwzxH7pPCaAqO46MgnOM80zW1RWuH61DGLwZJEdK2Kadq2F9CUG65" crossorigin="anonymous"> + @@ -19,6 +20,9 @@

FairHopper Visualisation Client

+

@@ -42,6 +46,38 @@

+ + + + + \ No newline at end of file diff --git a/frontend/js/frontend.js b/frontend/js/frontend.js index c9d4524..9caaa62 100644 --- a/frontend/js/frontend.js +++ b/frontend/js/frontend.js @@ -96,6 +96,17 @@ function renderGameDump(data) { renderPlayers(data.players); } +function playerReachedDestination(data) { + console.log(data); + + const dlgElement = document.getElementById("player-on-destination-modal"); + dlgElement.querySelector(".player-name").textContent = data.player.name; + dlgElement.querySelector(".move-count").textContent = data.player.move_count; + + const modal = new bootstrap.Modal(dlgElement); + modal.show(); +} + function productPurchaseStart(products, purchaseTimeout) { console.log("productPurchaseStart:", products); const containerElement = document.getElementById("purchase-container"); @@ -149,6 +160,9 @@ function wsConnect() { case "game_dump": renderGameDump(wsMessage.data); break; + case "player_on_destination": + playerReachedDestination(wsMessage.data); + break; case "product_purchase_start": productPurchaseStart(wsMessage.data.products, wsMessage.data.timeout); break; diff --git a/hopper/api/dto.py b/hopper/api/dto.py index 5654929..8a923d9 100644 --- a/hopper/api/dto.py +++ b/hopper/api/dto.py @@ -1,7 +1,5 @@ from __future__ import annotations -from typing import Optional - from pydantic import BaseModel as PydanticBaseModel from hopper.enums import PlayerState @@ -40,11 +38,6 @@ class DestinationDto(BaseModel): position: PositionDto -class ProductDto(BaseModel): - name: str - id: str - description: Optional[str] = None - class StartGameRequestDto(BaseModel): player_name: str @@ -68,11 +61,3 @@ class PlayerInfoResponseDto(MovePlayerResponseDto): class ErrorResponseDto(BaseModel): detail: str - - -class GetProductsResponse(BaseModel): - products: list[ProductDto] - - -class PurchaseProductDto(BaseModel): - product_id: str diff --git a/hopper/api/views.py b/hopper/api/views.py index 5102edb..fdb0038 100644 --- a/hopper/api/views.py +++ b/hopper/api/views.py @@ -6,12 +6,9 @@ from hopper.api.dto import ( DestinationDto, ErrorResponseDto, GameInfoDto, - GetProductsResponse, MovePlayerResponseDto, PingResponse, PlayerInfoResponseDto, - ProductDto, - PurchaseProductDto, StartGameRequestDto, StartGameResponseDto, ) @@ -21,10 +18,8 @@ from hopper.errors import ( Collision, GameLockForMovement, PositionOutOfBounds, - PurchaseForbiddenForPlayer, ) from hopper.models.player import Player -from settings import settings router = APIRouter() @@ -153,58 +148,3 @@ async def move_player( response.status_code = status.HTTP_200_OK return MovePlayerResponseDto(player=player) - - -@router.get("/products", response_model=GetProductsResponse) -async def get_products() -> GetProductsResponse: - return GetProductsResponse( - products=settings.products, - ) - - -@router.get("/products/{id}", response_model=ProductDto) -async def get_product(id: str) -> ProductDto: - for product in settings.products: - if product.id == id: - return ProductDto.from_orm(product) - raise HTTPException( - status_code=status.HTTP_404_NOT_FOUND, detail="Product not found" - ) - - -@router.post( - "/player/{id}/product/purchase", - response_model=ProductDto, - responses={ - status.HTTP_200_OK: { - "model": ProductDto, - "description": "Product purchased", - }, - status.HTTP_403_FORBIDDEN: { - "model": ErrorResponseDto, - "description": "Purchase forbidden for this player", - }, - status.HTTP_404_NOT_FOUND: { - "model": ErrorResponseDto, - "description": " Player with id not found, probably kicked out", - }, - }, -) -async def purchase_product( - body: PurchaseProductDto, - engine: GameEngine = Depends(get_game_engine), - player: Player = Depends(get_player), -) -> ProductDto: - for product in settings.products: - if product.id == body.product_id: - try: - await engine.purchase_product(player=player, product=product) - return ProductDto.from_orm(product) - except PurchaseForbiddenForPlayer: - raise HTTPException( - status_code=status.HTTP_403_FORBIDDEN, - detail="Purchase forbidden for this player", - ) - raise HTTPException( - status_code=status.HTTP_404_NOT_FOUND, detail="Product not found" - ) diff --git a/hopper/engine.py b/hopper/engine.py index 9493da8..9fce5a4 100644 --- a/hopper/engine.py +++ b/hopper/engine.py @@ -9,7 +9,6 @@ from hopper.errors import ( Collision, GameLockForMovement, PositionOutOfBounds, - PurchaseForbiddenForPlayer, ) from hopper.models.board import ( BOARD_DUMP_CHARS, @@ -22,7 +21,6 @@ from hopper.models.board import ( create_random_position, ) from hopper.models.player import Player, PlayerList, Position -from hopper.models.product import Product from hopper.watchdog import InactivityWatchdog from hopper.ws_server import WSServer from settings import settings @@ -178,9 +176,7 @@ class GameEngine: self.game_state = GameState.LOCK_FOR_MOVEMENT await self.send_game_dump() - await self.ws_server.send_product_purchase_start_message( - player=player, products=settings.products - ) + await self.ws_server.send_player_reached_destination_message(player=player) logging.info( f"Starting purchase countdown timer for {settings.purchase_timeout} seconds" @@ -214,16 +210,16 @@ class GameEngine: await asyncio.sleep(settings.game.PURCHASE_START_DELAY) - async def purchase_product(self, player: Player, product: Product) -> None: - if not player.state == PlayerState.ON_DESTINATION: - raise PurchaseForbiddenForPlayer() - if self._purchase_countdown_timer: - self._purchase_countdown_timer.stop() - await self.ws_server.send_product_purchase_done_message( - player=player, product=product - ) - await asyncio.sleep(settings.game.PURCHASE_FINISHED_DELAY) - await self.reset_game() + # async def purchase_product(self, player: Player, product: Product) -> None: + # if not player.state == PlayerState.ON_DESTINATION: + # raise PurchaseForbiddenForPlayer() + # if self._purchase_countdown_timer: + # self._purchase_countdown_timer.stop() + # await self.ws_server.send_product_purchase_done_message( + # player=player, product=product + # ) + # await asyncio.sleep(settings.game.PURCHASE_FINISHED_DELAY) + # await self.reset_game() def _reset_player(self, player) -> None: # move player to start position diff --git a/hopper/errors.py b/hopper/errors.py index f4159be..cf74c54 100644 --- a/hopper/errors.py +++ b/hopper/errors.py @@ -12,7 +12,3 @@ class Collision(BaseError): class GameLockForMovement(BaseError): ... - - -class PurchaseForbiddenForPlayer(BaseError): - ... diff --git a/hopper/models/ws_dto.py b/hopper/models/ws_dto.py index d047b97..bf7765a 100644 --- a/hopper/models/ws_dto.py +++ b/hopper/models/ws_dto.py @@ -12,7 +12,6 @@ from hopper.api.dto import ( DestinationDto, PlayerDto, PositionDto, - ProductDto, ) from hopper.enums import ObjectType @@ -34,20 +33,13 @@ class GameDumpDto(BaseModel): layers: list[LayerDto] -class ProductPurchaseStartDto(BaseModel): - player: PlayerDto - products: list[ProductDto] - timeout: int - - class ProductPurchaseTimerDto(BaseModel): time_left: int player: PlayerDto -class ProductPurchaseDoneDto(BaseModel): +class PlayerReachedDestinationDto(BaseModel): player: PlayerDto - product: Optional[ProductDto] = None TMessageData = TypeVar("TMessageData", bound=BaseModel) @@ -69,11 +61,6 @@ class WSGameDumpMessage(WSMessage): data: GameDumpDto -class WSProductPurchaseStartMessage(WSMessage): - message: str = "product_purchase_start" - data: ProductPurchaseStartDto - - class WSProductPurchaseTimerTickMessage(WSMessage): message: str = "product_purchase_timer_tick" data: ProductPurchaseTimerDto @@ -81,4 +68,8 @@ class WSProductPurchaseTimerTickMessage(WSMessage): class WSProductPurchaseDoneMessage(WSMessage): message: str = "product_purchase_done" - data: ProductPurchaseDoneDto + + +class WSPlayerReachedDestinationMessage(WSMessage): + message: str = "player_reached_destination" + data: PlayerReachedDestinationDto diff --git a/hopper/ws_server.py b/hopper/ws_server.py index 9b6ca2c..6c0eed2 100644 --- a/hopper/ws_server.py +++ b/hopper/ws_server.py @@ -5,22 +5,19 @@ from typing import Iterable, Optional import websockets from websockets import WebSocketServerProtocol -from websockets.exceptions import ConnectionClosedOK, ConnectionClosedError +from websockets.exceptions import ConnectionClosedError, ConnectionClosedOK from hopper.models.player import Player from hopper.models.product import Product from hopper.models.ws_dto import ( GameDumpDto, - ProductPurchaseDoneDto, - ProductPurchaseStartDto, + PlayerReachedDestinationDto, ProductPurchaseTimerDto, WSGameDumpMessage, WSMessage, - WSProductPurchaseDoneMessage, - WSProductPurchaseStartMessage, + WSPlayerReachedDestinationMessage, WSProductPurchaseTimerTickMessage, ) -from settings import settings class WSServer(Thread): @@ -93,14 +90,10 @@ class WSServer(Thread): message = self._create_game_dump_message() await self.send_message_to_clients(message) - async def send_product_purchase_start_message( - self, player: Player, products: Iterable[Product] - ) -> None: - message = WSProductPurchaseStartMessage( - data=ProductPurchaseStartDto( + async def send_player_reached_destination_message(self, player: Player) -> None: + message = WSPlayerReachedDestinationMessage( + data=PlayerReachedDestinationDto( player=player, - products=products, - timeout=settings.purchase_timeout, ) ) await self.send_message_to_clients(message) @@ -119,10 +112,11 @@ class WSServer(Thread): async def send_product_purchase_done_message( self, player: Player, product: Optional[Product] = None ) -> None: - message = WSProductPurchaseDoneMessage( - data=ProductPurchaseDoneDto(player=player, product=product), - ) - await self.send_message_to_clients(message) + # message = WSProductPurchaseDoneMessage( + # data=ProductPurchaseDoneDto(player=player, product=product), + # ) + # await self.send_message_to_clients(message) + ... async def run_async(self) -> None: logging.info(