Map ping with sound (custom MP3 per lobby)

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HJhXuLD2Z6hv3Wqeq9UL9K
This commit is contained in:
2026-10-25 09:18:46 +00:00
co-authored by Claude Sonnet 5.5
parent 2087ce9960
commit 0f97129243
7 changed files with 81 additions and 12 deletions
+23
View File
@@ -774,6 +774,29 @@ def install(api, db, current_user, lobby_for, dm_only, hub, event, store_dir: Pa
hub.notify(lid, "map")
return {"ok": True}
pinged: dict = {}
@api.post("/lobbies/{lid}/ping")
def ping(lid: str, body: dict = Body(...), user: dict = Depends(current_user)):
"""Anybody at the table can point at a spot of the map; everybody sees a ring there (and hears a ping)."""
with db() as con:
lobby = lobby_for(con, lid, user)
m = need_map(con, lobby)
try:
x, y = float(body.get("x")), float(body.get("y"))
except (TypeError, ValueError):
raise HTTPException(422, "Invalid position")
if not (0 <= x <= m["w"] and 0 <= y <= m["h"]):
raise HTTPException(422, "Outside of the map")
now = time.time()
if now - pinged.get((lid, user["id"]), 0) < 0.8:
raise HTTPException(429, "Slow down")
pinged[(lid, user["id"])] = now
if len(pinged) > 2000:
pinged.clear()
hub.notify(lid, "ping", delay=0, x=round(x, 1), y=round(y, 1), user=user["username"], dm=lobby["owner_id"] == user["id"])
return {"ok": True}
@api.put("/lobbies/{lid}/sight")
def set_sight(lid: str, body: dict = Body(...), user: dict = Depends(current_user)):
"""DM: switch line of sight on or off for the table (off: players see the whole map)."""
+3 -3
View File
@@ -6,8 +6,8 @@ from fastapi import Body, Depends, HTTPException, Request
from fastapi.responses import Response
MAX_SOUND = 1_500_000 # bytes per file
SLOTS = ("roll", "crit_success", "crit_failure")
FLAGS = ("result", "crit_success", "crit_failure") # result = the short tones for success / failure of a check
SLOTS = ("roll", "crit_success", "crit_failure", "ping")
FLAGS = ("result", "crit_success", "crit_failure", "ping") # result = the short tones for success / failure of a check
def schema(con):
@@ -20,7 +20,7 @@ def settings(raw) -> dict:
s = json.loads(raw or "{}")
except ValueError:
s = {}
return {"result": s.get("result", True), "crit_success": s.get("crit_success", True), "crit_failure": s.get("crit_failure", True),
return {"result": s.get("result", True), "crit_success": s.get("crit_success", True), "crit_failure": s.get("crit_failure", True), "ping": s.get("ping", True),
"custom": {k: bool(s.get("custom", {}).get(k)) for k in SLOTS}, "v": int(s.get("v", 0))}