118 lines
3.1 KiB
Python
118 lines
3.1 KiB
Python
|
|
"""
|
||
|
|
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,
|
||
|
|
},
|
||
|
|
)
|