6 Commits

Author SHA1 Message Date
fb4651ec23 Update readme 2023-05-12 09:30:50 +02:00
6ff6433be3 Update makefile 2023-05-11 21:39:26 +02:00
2653eabb6c Update readme 2023-05-11 21:23:52 +02:00
b56071e2c7 Thread event to stop inactivity WD 2023-05-11 20:01:33 +02:00
78c3286c17 Update docs 2023-05-11 19:42:11 +02:00
b2a132a002 Merge branch 'client-endgame' 2023-05-11 19:38:45 +02:00
3 changed files with 32 additions and 20 deletions

View File

@ -5,9 +5,11 @@ INTERNAL_WS_PORT=8011
EXTERNAL_API_PORT=8010
EXTERNAL_WS_PORT=8011
timestamp := `/bin/date "+%Y-%m-%d-%H-%M-%S"`
run:
@poetry run \
@ \
poetry run \
uvicorn \
main:app \
--host 0.0.0.0 \
@ -15,7 +17,8 @@ run:
--workers=1
run-dev:
@poetry run \
@ \
poetry run \
uvicorn \
main:app \
--host 0.0.0.0 \
@ -24,7 +27,8 @@ run-dev:
--reload
create-requirements:
@poetry export \
@ \
poetry export \
--without-hashes \
--format=requirements.txt \
> requirements.txt
@ -37,15 +41,17 @@ docker-clean:
docker-build:
@docker \
@ \
docker \
buildx build \
--build-arg INTERNAL_API_PORT=$(INTERNAL_API_PORT) \
--build-arg INTERNAL_WS_PORT=$(INTERNAL_WS_PORT) \
--tag $(CONTAINER_NAME) \
--tag $(CONTAINER_NAME):$(timestamp) \
.
docker-run:
@docker \
@ \
docker \
run \
--publish $(EXTERNAL_API_PORT):$(INTERNAL_API_PORT) \
--publish $(EXTERNAL_WS_PORT):$(INTERNAL_WS_PORT) \

View File

@ -44,8 +44,7 @@ state "Product Selected" as ProductSelected
state "Selection Timeout" as SelectionTimeout
state "End Player's Game" as EndPlayer
state "Lock Game" as LockGame <<end>>
state "End Game" as EndGame <<end>>
state "Unlock game" as UnlockGame <<end>>
state "Unlock game and restart" as UnlockGame <<end>>
[*] -> StartGame
StartGame -> MovePlayer
@ -55,9 +54,9 @@ DestinationReached --> ProductSelection
DestinationReached -> LockGame: Lock game for all other players
ProductSelection --> ProductSelected
ProductSelection --> SelectionTimeout
ProductSelected --> EndGame: End game\nfor all players
ProductSelected --> UnlockGame: Unlock game\nand restart
SelectionTimeout -> EndPlayer
EndPlayer --> UnlockGame: Unlock game\n for all players
EndPlayer --> UnlockGame: Unlock game\nand restart
```
## FairHopper Game Server
@ -222,7 +221,7 @@ end
== Player reached destination ==
Game -> Game: Lock game for other players
activate Game
activate Game #skyblue
Game -> WS: Player reached destination
activate WS #coral
WS o-> Client1: Select product
@ -232,7 +231,7 @@ deactivate Game
loop #lightyellow Product select countdown timer (60s)
Game ->o WS: Timer timeout
activate Game
activate Game #skyblue
activate WS #coral
WS o-> Client1: Selection timeout
WS o-> Client2: Selection timeout
@ -241,16 +240,21 @@ loop #lightyellow Product select countdown timer (60s)
deactivate Game
end
Client1 -> WS: Product selected
Client1 -> Client1: Product selection
activate Client1 #greenyellow
Client1 -> Client1: Dispense product
Client1 ->o WS: Product selected
deactivate Client1
activate WS #coral
WS o-> Game: Product selected
activate Game
activate Game #skyblue
WS o-> Client2: Product selected
deactivate WS
Game -> Game: Unlock game
Game -> WS: Game state
Game ->o WS: Game state
activate WS #coral
WS o-> Client1: Game state
WS o-> Client2: Game state
@ -323,6 +327,7 @@ Response code:
- 403 Forbidden: Player id not valid, probably timeout
- 409 Conflict: Invalid move, obstacle or position out of board
- 422 Unprocessable Content: Validation error
- 423 Locked: Game locked, product selection in progress
Response body:
```json

View File

@ -2,7 +2,7 @@ import asyncio
import datetime
import logging
import time
from threading import Thread
from threading import Thread, Event
from hopper.models.player import PlayerList
from hopper.ws_server import WSServer
@ -15,14 +15,15 @@ class InactivityWatchdog(Thread):
) -> None:
self.players = players
self.ws_server = ws_server
self.stopped = False
self.stop_event = Event()
super().__init__(daemon=True)
def run(self) -> None:
logging.info("Starting inactivity watchdog")
while not self.stopped:
while not self.stop_event.is_set():
self.cleanup_players()
time.sleep(settings.inacivity_watchdog.TICK_INTERVAL)
if not self.stop_event.is_set():
time.sleep(settings.inacivity_watchdog.TICK_INTERVAL)
def cleanup_players(self) -> None:
now = datetime.datetime.now()
@ -64,4 +65,4 @@ class InactivityWatchdog(Thread):
asyncio.run(self.ws_server.send_game_dump())
def stop(self) -> None:
self.stopped = True
self.stop_event.set()