feat: clock + place games
This commit is contained in:
@@ -0,0 +1,39 @@
|
||||
import struct
|
||||
|
||||
from django.http import HttpRequest, HttpResponse
|
||||
from ninja import Router
|
||||
from ninja.decorators import decorate_view
|
||||
from ninja.security import django_auth_is_staff
|
||||
|
||||
from games.decorators import require_game_enabled
|
||||
|
||||
from .canvas import read_canvas
|
||||
from .gif import build_evolution_gif
|
||||
from .models import PlaceSettings
|
||||
|
||||
router = Router()
|
||||
|
||||
PREFIX = "/events/{event_path}/place"
|
||||
|
||||
# 4-byte little-endian header (uint16 width, uint16 height) prefixed to the
|
||||
# canvas payload - the grid can be resized by an admin, so the frontend
|
||||
# can't hardcode dimensions and needs to read them off the payload itself.
|
||||
HEADER_FORMAT = "<HH"
|
||||
|
||||
|
||||
@router.get(f"{PREFIX}/canvas")
|
||||
@decorate_view(require_game_enabled(path="place"))
|
||||
def canvas(request: HttpRequest, event_path: str):
|
||||
"""The one-time full-grid load. Every placement after that arrives as a
|
||||
single websocket message, never a re-fetch."""
|
||||
place_settings = PlaceSettings.current(request.event)
|
||||
header = struct.pack(HEADER_FORMAT, place_settings.width, place_settings.height)
|
||||
pixels = read_canvas(event_path, place_settings.width, place_settings.height)
|
||||
return HttpResponse(header + pixels, content_type="application/octet-stream")
|
||||
|
||||
|
||||
@router.get(f"{PREFIX}/evolution.gif", auth=django_auth_is_staff)
|
||||
@decorate_view(require_game_enabled(path="place"))
|
||||
def evolution_gif(request: HttpRequest, event_path: str):
|
||||
"""Admin-only: replays the full placement history as an animated GIF."""
|
||||
return HttpResponse(build_evolution_gif(request.event), content_type="image/gif")
|
||||
Reference in New Issue
Block a user