Announce presses
This commit is contained in:
@@ -198,6 +198,9 @@ def load_state():
|
||||
);
|
||||
CREATE INDEX IF NOT EXISTS chat_player_messages ON chat_messages (player_id, id);
|
||||
""")
|
||||
columns = {row["name"] for row in connection.execute("PRAGMA table_info(chat_messages)")}
|
||||
if "kind" not in columns:
|
||||
connection.execute("ALTER TABLE chat_messages ADD COLUMN kind TEXT NOT NULL DEFAULT 'message'")
|
||||
# Serialize initialization. A committed game row is the migration marker,
|
||||
# not merely the existence of a possibly empty or interrupted database.
|
||||
connection.execute("BEGIN IMMEDIATE")
|
||||
@@ -249,7 +252,7 @@ failed_logins = {} # lowercase name -> (failure count, first failure ms)
|
||||
def chat_messages():
|
||||
with database() as connection:
|
||||
rows = connection.execute(
|
||||
"SELECT id, name, at, message FROM chat_messages ORDER BY id DESC LIMIT ?",
|
||||
"SELECT id, name, at, message, kind FROM chat_messages ORDER BY id DESC LIMIT ?",
|
||||
(CHAT_HISTORY_LIMIT,),
|
||||
).fetchall()
|
||||
return [dict(row) for row in reversed(rows)]
|
||||
@@ -481,7 +484,7 @@ class Handler(BaseHTTPRequestHandler):
|
||||
connection.execute("BEGIN IMMEDIATE")
|
||||
t = now_ms()
|
||||
last = connection.execute(
|
||||
"SELECT at FROM chat_messages WHERE player_id = ? ORDER BY id DESC LIMIT 1", (pid,),
|
||||
"SELECT at FROM chat_messages WHERE player_id = ? AND kind = 'message' ORDER BY id DESC LIMIT 1", (pid,),
|
||||
).fetchone()
|
||||
if last is not None and t - last["at"] < CHAT_COOLDOWN_MS:
|
||||
return self.send_json(HTTPStatus.TOO_MANY_REQUESTS, {"error": "Please wait two seconds between messages"})
|
||||
@@ -490,7 +493,7 @@ class Handler(BaseHTTPRequestHandler):
|
||||
"INSERT INTO chat_messages (player_id, name, at, message) VALUES (?, ?, ?, ?)",
|
||||
(pid, name, t, message),
|
||||
)
|
||||
posted = {"id": cursor.lastrowid, "name": name, "at": t, "message": message}
|
||||
posted = {"id": cursor.lastrowid, "name": name, "at": t, "message": message, "kind": "message"}
|
||||
return self.send_json(HTTPStatus.CREATED, posted)
|
||||
|
||||
if path == "/api/register":
|
||||
@@ -589,7 +592,25 @@ class Handler(BaseHTTPRequestHandler):
|
||||
}
|
||||
state["presses"].append(press)
|
||||
state["deadline"] = t + DURATION_MS
|
||||
save_state(state)
|
||||
hours, remainder = divmod(max(0, remaining), 3600000)
|
||||
minutes, remainder = divmod(remainder, 60000)
|
||||
seconds, milliseconds = divmod(remainder, 1000)
|
||||
time_left = f"{hours:02d}:{minutes:02d}:{seconds:02d}.{milliseconds:03d}"
|
||||
name = state["players"][pid]["name"]
|
||||
points = press["points"]
|
||||
announcement = f"{name} pushed the button with {time_left} remaining and received {points} {'point' if points == 1 else 'points'}."
|
||||
try:
|
||||
with database() as connection:
|
||||
write_state(connection, state)
|
||||
connection.execute(
|
||||
"INSERT INTO chat_messages (player_id, name, at, message, kind) VALUES (?, ?, ?, ?, 'press')",
|
||||
(pid, "The Button", t, announcement),
|
||||
)
|
||||
except Exception:
|
||||
# Keep memory consistent with the rolled-back database snapshot.
|
||||
state["presses"].pop()
|
||||
state["deadline"] = t + remaining
|
||||
raise
|
||||
return self.send_json(HTTPStatus.OK, {
|
||||
"press": {k: press[k] for k in ("at", "remaining_ms", "zone", "points")},
|
||||
"deadline": state["deadline"],
|
||||
|
||||
Reference in New Issue
Block a user