ClassQuizController basic gameplay cleanup

This commit is contained in:
Mawoka
2026-06-15 18:02:11 +02:00
parent 71d5989925
commit eb35654539
2 changed files with 44 additions and 31 deletions
+9
View File
@@ -11,3 +11,12 @@
reverse_proxy /openapi.json localhost:8000
reverse_proxy /socket.io* localhost:8000
}
192.168.100.127:8081 {
tls internal
reverse_proxy /* localhost:3000
reverse_proxy /api* localhost:8000
reverse_proxy /rapidoc* localhost:8000
reverse_proxy /openapi.json localhost:8000
reverse_proxy /socket.io* localhost:8000
}
@@ -7,55 +7,53 @@ import enum
import typing
from datetime import datetime
from fastapi import APIRouter, HTTPException, WebSocket, WebSocketDisconnect, status
from fastapi import APIRouter, WebSocket, WebSocketDisconnect, status
from pydantic import BaseModel, ValidationError
from classquiz.config import redis
from classquiz.db.models import PlayGame, QuizQuestionType, AnswerData, GamePlayer
from classquiz.socket_server import sio, calculate_score, set_answer
from classquiz.db.models import AnswerData, GamePlayer, PlayGame, QuizQuestionType
from classquiz.socket_server import calculate_score, set_answer, sio
from classquiz.socket_server.helpers import check_answer, has_already_answered
from classquiz.socket_server.models import SubmitAnswerData
router = APIRouter()
class SubmitAnswerInput(BaseModel):
answer: int
async def submit_answer_fn(data_answer: int, game_pin: str, player_id: str, now: datetime):
redis_res_game = await redis.get(f"game:{game_pin}")
username = await redis.get(f"game:cqc:player:{player_id}")
if redis_res_game is None or username is None:
raise HTTPException(status_code=404, detail="id not existent")
game = PlayGame.model_validate_json(redis_res_game)
print(data_answer)
game = await PlayGame.get_from_redis(game_pin)
if not game.question_show:
print("Not showing q")
return
question = game.questions[game.current_question]
question_time = datetime.fromisoformat(await redis.get(f"game:{game_pin}:current_time"))
try:
selected_answer = question.answers[data_answer].answer
except (KeyError, IndexError):
username = await redis.get(f"game:cqc:player:{player_id}")
already_answered = await has_already_answered(game_pin, game.current_question, username)
if already_answered:
print("already answerered")
return
if await redis.get(f"answer_given:{player_id}:{game.current_question}") is not None:
return
answer_right = False
if question.type == QuizQuestionType.ABCD:
for answer in question.answers:
if answer.answer == selected_answer and answer.right:
answer_right = True
break
elif question.type == QuizQuestionType.VOTING:
answer_right = False
else:
if question.type not in (QuizQuestionType.ABCD, QuizQuestionType.VOTING):
print("Wrong q type")
return
selected_answer = question.answers[data_answer].answer
answer_data_obj = SubmitAnswerData(question_index=game.current_question, answer=selected_answer)
answer_right, stored_answer = check_answer(game, answer_data_obj)
diff = (question_time - now).total_seconds() * 1000
score = 0
if answer_right:
score = calculate_score(abs(diff), int(float(question.time)))
score = calculate_score(
abs(diff),
int(float(question.time)),
)
if score > 1000:
score = 1000
await redis.set(f"answer_given:{player_id}:{game.current_question}", "True", ex=600)
await redis.hincrby(f"game_session:{game_pin}:player_scores", username, score)
answer_data = AnswerData(
username=username,
answer=selected_answer,
answer=stored_answer,
right=answer_right,
time_taken=abs(diff),
score=score,
@@ -64,11 +62,13 @@ async def submit_answer_fn(data_answer: int, game_pin: str, player_id: str, now:
answers = await set_answer(answers, game_pin=game_pin, data=answer_data, q_index=game.current_question)
player_count = await redis.scard(f"game_session:{game_pin}:players")
await sio.emit("player_answer", {})
if answers is not None and len(answers) == player_count:
if len(answers) == player_count:
game.question_show = False
await game.save(game_pin)
await sio.emit("everyone_answered", {})
button_to_index_map = {"y": 0, "r": 3, "g": 1, "b": 2}
button_to_index_map = {"b": 0, "y": 1, "g": 2, "r": 3}
class WebSocketTypes(enum.Enum):
@@ -104,7 +104,10 @@ async def websocket_endpoint(ws: WebSocket, game_id: str):
{"username": username, "sid": None},
room=f"admin:{game_pin}",
)
await redis.sadd(f"game_session:{game_pin}:players", GamePlayer(username=username, sid=None).model_dump_json())
await redis.sadd(
f"game_session:{game_pin}:players",
GamePlayer(username=username, sid=None).model_dump_json(),
)
while True:
raw_data = await ws.receive_text()
@@ -120,6 +123,7 @@ async def websocket_endpoint(ws: WebSocket, game_id: str):
continue
if data.type == WebSocketTypes.ButtonPress:
print("submitting")
now = datetime.now()
try:
answer_index = button_to_index_map[data.data.lower()]