Lobby: MP3 dice sound with pitch per die, DM sound settings

Default dice sound is public/dice.mp3 with a small random pitch and a
base pitch per die size (d4 lighter ... d100 heavier). The DM can upload
an own dice sound and sounds for critical success / failure per lobby,
reset them, and switch result and critical sounds on or off.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HJhXuLD2Z6hv3Wqeq9UL9K
This commit is contained in:
Claude
2026-10-23 19:04:12 +00:00
parent ce24a0ba6f
commit 03ebc3a138
7 changed files with 226 additions and 62 deletions
+5 -1
View File
@@ -16,6 +16,7 @@ from . import auth
from .derive import compute
from . import rules_edit
from . import maps as maps_mod
from . import sounds as sounds_mod
from .realtime import hub
from .export import to_docx, to_pdf
@@ -102,6 +103,7 @@ def db() -> sqlite3.Connection:
if col not in [r["name"] for r in con.execute(f"PRAGMA table_info({table})")]:
con.execute(f"ALTER TABLE {table} ADD COLUMN {col} {ddl}")
maps_mod.schema(con)
sounds_mod.schema(con)
for table in ("characters", "presets"): # older databases: add the owner column
if "owner_id" not in [r["name"] for r in con.execute(f"PRAGMA table_info({table})")]:
con.execute(f"ALTER TABLE {table} ADD COLUMN owner_id INTEGER")
@@ -612,7 +614,7 @@ def read_lobby(lid: str, user: dict = Depends(current_user)):
diff = {"label": "", "mod": None, "hidden": True}
return {"id": lobby["id"], "name": lobby["name"], "dm": lobby["dm"], "is_dm": is_dm,
"code": lobby["code"] if is_dm else None, "members": members, "difficulty": diff,
"levels": _levels(rules), "palette": [{"id": i, "hex": h} for i, h in PALETTE], "dm_color": DM_COLOR}
"sounds": sounds_mod.settings(lobby["sounds"]), "levels": _levels(rules), "palette": [{"id": i, "hex": h} for i, h in PALETTE], "dm_color": DM_COLOR}
@api.put("/lobbies/{lid}/difficulty")
@@ -841,6 +843,7 @@ def delete_lobby(lid: str, user: dict = Depends(current_user)):
con.execute("DELETE FROM lobby_messages WHERE lobby_id=?", (lid,))
con.execute("DELETE FROM lobby_tokens WHERE lobby_id=?", (lid,))
con.execute("DELETE FROM lobbies WHERE id=?", (lid,))
purge_sounds(lid)
hub.close_lobby(lid)
return {"ok": True}
@@ -1018,6 +1021,7 @@ def editor_reset(section: str, confirm: bool = False, user: dict = Depends(admin
maps_mod.install(api, db, current_user, _lobby_for, _dm_only, hub, _event, Path(DB_PATH).parent / "maps")
purge_sounds = sounds_mod.install(api, db, current_user, _lobby_for, _dm_only, hub, Path(DB_PATH).parent / "sounds")
@app.websocket("/api/lobbies/{lid}/ws")