""" This file is part of the SplendidBear Websites' projects. Copyright (c) 2026 @ www.splendidbear.org For the full copyright and license information, please view the LICENSE file that was distributed with this source code. """ from __future__ import annotations import base64 import json from mineseeker.api import client def fetch_token() -> dict: """ GET /api/game/token Returns { "mercureJwt": str, "gameAssoc": str } """ resp = client.get("/api/game/token") return resp.json() def connect(game_assoc: str) -> dict: """ GET /api/game/connect/{gameAssoc} Returns the decoded connect-information dict. """ resp = client.get(f"/api/game/connect/{game_assoc}") raw = resp.text.strip() decoded = base64.b64decode(raw).decode("utf-8") return json.loads(decoded) def start(game_assoc: str) -> bool: """POST /api/game/start — initialise the grid for a new game.""" resp = client.post("/api/game/start", json={"gameAssoc": game_assoc}) return bool(resp.json().get("success", False)) def join(game_assoc: str) -> bool: """POST /api/game/join/{gameAssoc} — announce this player's presence.""" resp = client.post(f"/api/game/join/{game_assoc}", json={}) return bool(resp.json().get("success", False)) def step( game_assoc: str, coords: list[int], player: str, bomb: bool, resign: str | None, step_elapsed: float, ) -> dict: """ POST /api/game/step/{gameAssoc} Returns the full step result dict published by TopicManager::publish(). """ resp = client.post( f"/api/game/step/{game_assoc}", json={ "coords": coords, "player": player, "bomb": bomb, "resign": resign, "stepElapsed": step_elapsed, }, ) return resp.json() def leave(game_assoc: str) -> None: """POST /api/game/leave/{gameAssoc} — fire-and-forget on window close.""" try: client.post(f"/api/game/leave/{game_assoc}", json={}) except Exception: pass # best-effort def heartbeat(game_assoc: str, color: str) -> None: """POST /api/game/heartbeat/{gameAssoc} — keep-alive ping.""" try: client.post(f"/api/game/heartbeat/{game_assoc}", json={"color": color}) except Exception: pass # best-effort def waiting() -> list[dict]: """GET /api/game/waiting — list of waiting players in the lobby.""" resp = client.get("/api/game/waiting") return resp.json() def challenge(target_game_assoc: str, challenger_game_assoc: str) -> None: """POST /api/game/challenge/{targetGameAssoc}""" client.post( f"/api/game/challenge/{target_game_assoc}", json={"challengerGameAssoc": challenger_game_assoc}, ) def challenge_respond( challenger_game_assoc: str, accepted: bool, target_game_assoc: str, ) -> None: """POST /api/game/challenge/respond/{challengerGameAssoc}""" client.post( f"/api/game/challenge/respond/{challenger_game_assoc}", json={ "accepted": accepted, "targetGameAssoc": target_game_assoc, }, )