From 4f123a7c8c8719491ddc4a497d37e99bb5dce549 Mon Sep 17 00:00:00 2001 From: Tor Andersson Date: Mon, 10 Feb 2025 22:09:13 +0100 Subject: Support multi-active player states for 3p+ games. --- server.js | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) (limited to 'server.js') diff --git a/server.js b/server.js index eca5aa9..9eb2ffd 100644 --- a/server.js +++ b/server.js @@ -1539,7 +1539,8 @@ const QUERY_NEXT_GAME_OF_USER = SQL(` join players using(game_id) where status = ${STATUS_ACTIVE} - and active in (role, 'Both') + -- and active in (role, 'Both') + and ( active = 'Both' or instr(active, role) > 0 ) and user_id = ? and is_opposed order by mtime @@ -2197,7 +2198,7 @@ function start_game(game) { state = RULES[game.title_id].setup(seed, game.scenario, options) - SQL_START_GAME.run(state.active, game.game_id) + SQL_START_GAME.run(String(state.active), game.game_id) let replay_id = put_replay(game.game_id, null, ".setup", [ seed, game.scenario, options ]) put_snap(game.game_id, replay_id, state) SQL_INSERT_GAME_STATE.run(game.game_id, JSON.stringify(state)) @@ -2248,7 +2249,7 @@ function rewind_game_to_snap(game_id, snap_id) { SQL_DELETE_GAME_REPLAY.run(game_id, snap.replay_id) SQL_INSERT_GAME_STATE.run(game_id, JSON.stringify(snap_state)) - SQL_REWIND_GAME.run(snap_id - 1, snap_state.active, game_id) + SQL_REWIND_GAME.run(snap_id - 1, String(snap_state.active), game_id) SQL_REWIND_GAME_CLOCK.run(game_id) update_join_clients(game_id) @@ -2539,7 +2540,7 @@ function send_chat_activity_notification(game_id, p) { } function is_active_role(active, role) { - return active === "Both" || active === role + return active === "Both" || active === role || active.includes(role) } function send_game_started_notification(game_id, active) { @@ -3557,7 +3558,7 @@ function put_replay(game_id, role, action, args) { } function dont_snap(rules, state, old_active) { - if (state.active === old_active || !state.active || state.active === "None") + if (String(state.active) === old_active || !state.active || state.active === "None") return true if (rules.dont_snap && rules.dont_snap(state)) return true @@ -3573,11 +3574,12 @@ function put_snap(game_id, replay_id, state) { function put_game_state(game_id, state, old_active, current_role) { // TODO: separate state, undo, and log entries (and reuse "snap" json stringifaction?) + let new_active = String(state.active) SQL_INSERT_GAME_STATE.run(game_id, JSON.stringify(state)) - if (state.active !== old_active) { - SQL_UPDATE_GAME_ACTIVE.run(state.active, game_id) + if (new_active !== old_active) { + SQL_UPDATE_GAME_ACTIVE.run(new_active, game_id) // add time for the player who took the current action SQL_UPDATE_PLAYERS_ADD_TIME.run(game_id, current_role) @@ -3600,7 +3602,7 @@ function put_new_state(title_id, game_id, state, old_active, role, action, args) put_game_state(game_id, state, old_active, role) - if (state.active !== old_active) + if (String(state.active) !== old_active) update_join_clients(game_id) if (game_clients[game_id]) for (let other of game_clients[game_id]) @@ -3632,11 +3634,11 @@ function on_action(socket, action, args, cookie) { try { let state = get_game_state(socket.game_id) - let old_active = state.active + let old_active = String(state.active) // Don't update cookie during simultaneous turns, as it results // in many in-flight collisions. - if (old_active !== "Both") + if (old_active !== "Both" && !old_active.includes(",")) game_cookies[socket.game_id] ++ state = RULES[socket.title_id].action(state, socket.role, action, args) @@ -3670,7 +3672,7 @@ function on_abondon(socket) { function do_abandon(game_id, role) { let game = SQL_SELECT_GAME.get(game_id) let state = get_game_state(game_id) - let old_active = state.active + let old_active = String(state.active) state = finish_game_state(game.title_id, state, "None", role + " abandoned the game.") put_new_state(game.title_id, game_id, state, old_active, role, ".abandon", null) } @@ -3678,7 +3680,7 @@ function do_abandon(game_id, role) { function do_timeout(game_id, role) { let game = SQL_SELECT_GAME.get(game_id) let state = get_game_state(game_id) - let old_active = state.active + let old_active = String(state.active) state = finish_game_state(game.title_id, state, "None", role + " timed out.") put_new_state(game.title_id, game_id, state, old_active, role, ".timeout", null) } @@ -3686,7 +3688,7 @@ function do_timeout(game_id, role) { function do_resign(game_id, role) { let game = SQL_SELECT_GAME.get(game_id) let state = get_game_state(game_id) - let old_active = state.active + let old_active = String(state.active) let result = "None" let roles = get_game_roles(game.title_id, game.scenario, game.options) -- cgit v1.2.3