Files
classquiz-ai/classquiz/routers/box_controller/embedded/__init__.py
T
2023-04-15 13:24:36 +02:00

83 lines
2.9 KiB
Python

# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at https://mozilla.org/MPL/2.0/.
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at https://mozilla.org/MPL/2.0/.
import os
import uuid
from datetime import datetime
from fastapi import APIRouter, HTTPException
from pydantic import BaseModel
from classquiz.config import redis
from classquiz.db.models import PlayGame, Controllers
from classquiz.routers.box_controller.embedded.socket import router as socket_router
router = APIRouter()
router.include_router(socket_router, prefix="/socket")
class JoinGameInput(BaseModel):
id: uuid.UUID
secret_key: str
code: str
class JoinGameResponse(BaseModel):
id: str
@router.post("/join")
async def join_game(data: JoinGameInput) -> JoinGameResponse:
controller = await Controllers.objects.get_or_none(id=data.id, secret_key=data.secret_key)
game_pin = await redis.get(f"game:cqc:code:{data.code}")
if game_pin is None:
raise HTTPException(status_code=404, detail="Game not found")
game = await redis.get(f"game:{game_pin}")
game = PlayGame.parse_raw(game)
# Check if game is already running
if game.started:
raise HTTPException(status_code=400, detail="Game started already")
# check if username already exists
if await redis.get(f"game_session:{game_pin}:players:{controller.player_name}") is not None:
raise HTTPException(status_code=409, detail="Username already exists")
player_id = os.urandom(5).hex()
await redis.set(f"game:cqc:player:{player_id}", controller.player_name)
return JoinGameResponse(id=f"{player_id}:{game_pin}")
class RegisterWithCodeInput(BaseModel):
code: str
class RegisterWithCodeResponse(BaseModel):
id: uuid.UUID
secret_key: str
@router.post("/register")
async def register_with_code(data: RegisterWithCodeInput) -> RegisterWithCodeResponse:
c_id = await redis.get(f"controller_setup:{data.code}")
if c_id is None:
raise HTTPException(status_code=404, detail="Code not found")
await redis.delete(f"controller_setup:{data.code}")
c_id = uuid.UUID(c_id)
controller = await Controllers.objects.get(id=c_id)
controller.first_seen = datetime.now()
controller.last_seen = datetime.now()
await controller.update()
return RegisterWithCodeResponse(id=controller.id, secret_key=controller.secret_key)
@router.get("/ping")
async def ping_server(id: uuid.UUID, secret_key: str, version: str):
controller = await Controllers.objects.get_or_none(id=id, secret_key=secret_key)
if controller is None:
raise HTTPException(status_code=404, detail="Key and/or id invalid")
controller.last_seen = datetime.now()
controller.os_version = version
await controller.update()