feat: complete realtime challenge matchmaking
This commit is contained in:
@@ -6,8 +6,12 @@ from rest_framework.views import APIView
|
||||
from .game_services import game_payload, request_sudoku_hint, start_game, submit_game
|
||||
from .models import Contest, ContestAttempt, MathGameAttempt, RealtimeMatch
|
||||
from .services import (
|
||||
cancel_waiting_match,
|
||||
create_challenge,
|
||||
find_match,
|
||||
join_challenge,
|
||||
match_payload,
|
||||
refresh_match_state,
|
||||
start_attempt,
|
||||
submit_attempt,
|
||||
)
|
||||
@@ -44,13 +48,16 @@ class AttemptStartView(APIView):
|
||||
|
||||
class AttemptSubmitView(APIView):
|
||||
def post(self, request, attempt_id):
|
||||
get_object_or_404(ContestAttempt, id=attempt_id, user=request.user)
|
||||
attempt = get_object_or_404(ContestAttempt, id=attempt_id, user=request.user)
|
||||
payload = submit_attempt(
|
||||
user=request.user,
|
||||
attempt_id=attempt_id,
|
||||
raw_answers=request.data.get("answers", []),
|
||||
submission_key=request.headers.get("Idempotency-Key"),
|
||||
)
|
||||
if attempt.match_id:
|
||||
match = refresh_match_state(attempt.match_id)
|
||||
return Response(match_payload(match, request.user))
|
||||
return Response(payload)
|
||||
|
||||
|
||||
@@ -63,12 +70,33 @@ class MatchmakingView(APIView):
|
||||
|
||||
class MatchStateView(APIView):
|
||||
def get(self, request, match_id):
|
||||
match = get_object_or_404(
|
||||
existing = get_object_or_404(
|
||||
RealtimeMatch.objects.select_related("player_one", "player_two"),
|
||||
id=match_id,
|
||||
)
|
||||
if request.user.id not in (match.player_one_id, match.player_two_id):
|
||||
if request.user.id not in (existing.player_one_id, existing.player_two_id):
|
||||
return Response(status=status.HTTP_403_FORBIDDEN)
|
||||
match = refresh_match_state(match_id)
|
||||
return Response(match_payload(match, request.user))
|
||||
|
||||
|
||||
class ChallengeCreateView(APIView):
|
||||
def post(self, request, slug):
|
||||
contest = get_object_or_404(Contest, slug=slug)
|
||||
match = create_challenge(request.user, contest)
|
||||
return Response(match_payload(match, request.user), status=status.HTTP_201_CREATED)
|
||||
|
||||
|
||||
class ChallengeJoinView(APIView):
|
||||
def post(self, request):
|
||||
match = join_challenge(request.user, request.data.get("challenge_code"))
|
||||
return Response(match_payload(match, request.user))
|
||||
|
||||
|
||||
class MatchCancelView(APIView):
|
||||
def post(self, request, match_id):
|
||||
get_object_or_404(RealtimeMatch, id=match_id)
|
||||
match = cancel_waiting_match(request.user, match_id)
|
||||
return Response(match_payload(match, request.user))
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user