diff options
Diffstat (limited to 'tools')
-rw-r--r-- | tools/elo.js | 2 | ||||
-rwxr-xr-x | tools/import-game.js | 90 | ||||
-rw-r--r-- | tools/lift-bans.sh | 30 | ||||
-rwxr-xr-x | tools/patchgame.js | 78 | ||||
-rw-r--r-- | tools/purge.sql | 6 |
5 files changed, 151 insertions, 55 deletions
diff --git a/tools/elo.js b/tools/elo.js index ad0dbad..f6064f1 100644 --- a/tools/elo.js +++ b/tools/elo.js @@ -14,7 +14,7 @@ function is_winner(role, result) { } function elo_k(n) { - return n < 10 ? 60 : 30 + return 30 } function elo_ev(a, players) { diff --git a/tools/import-game.js b/tools/import-game.js index 87b93ab..42391e1 100755 --- a/tools/import-game.js +++ b/tools/import-game.js @@ -4,7 +4,7 @@ const fs = require("fs") const sqlite3 = require("better-sqlite3") var options = {} -var input = null +var input = [] for (let i = 2; i < process.argv.length; ++i) { let opt = process.argv[i] @@ -12,65 +12,69 @@ for (let i = 2; i < process.argv.length; ++i) { let [key, val] = opt.split("=", 2) options[key] = val } else { - input = opt + input.push(opt) } } -if (!input) { +if (input.length < 1) { console.error("usage: node tools/import-game.js [title_id=value] [notice=value] game.json") process.exit(1) } -var game = JSON.parse(fs.readFileSync(input, "utf8")) +for (let file of input) { + var game = JSON.parse(fs.readFileSync(file, "utf8")) -if (options.title_id) - game.setup.title_id = options.title_id -if (options.notice) - game.setup.notice = options.notice + if (options.title_id) + game.setup.title_id = options.title_id + if (options.notice) + game.setup.notice = options.notice -if (game.setup.notice === undefined) - game.setup.notice = "" -if (game.setup.options === undefined) - game.setup.options = "{}" + if (game.setup.notice === undefined) + game.setup.notice = "" + if (game.setup.options === undefined) + game.setup.options = "{}" -game.setup.active = game.state.active -game.setup.moves = game.snaps && game.snaps.length > 0 ? game.snaps.length - 1 : 0 + game.setup.active = game.state.active + game.setup.moves = game.snaps && game.snaps.length > 0 ? game.snaps.length - 1 : 0 -let db = new sqlite3("db") + let db = new sqlite3("db") -let insert_game = db.prepare("insert into games(status,owner_id,title_id,scenario,options,player_count,active,moves,notice) values (1,1,:title_id,:scenario,:options,:player_count,:active,:moves,:notice) returning game_id").pluck() -let insert_player = db.prepare("insert into players(game_id,role,user_id) values (?,?,?)") -let insert_state = db.prepare("insert into game_state(game_id,state) values (?,?)") + let insert_game = db.prepare("insert into games(status,owner_id,title_id,scenario,options,player_count,active,moves,notice) values (1,1,:title_id,:scenario,:options,:player_count,:active,:moves,:notice) returning game_id").pluck() + let insert_player = db.prepare("insert into players(game_id,role,user_id,clock) values (?,?,?,21)") + let insert_state = db.prepare("insert into game_state(game_id,state) values (?,?)") + let update_active_trigger = db.prepare("update games set active=active where game_id=?") -let select_user = db.prepare("select user_id from users where name=?").pluck() + let select_user = db.prepare("select user_id from users where name=?").pluck() -db.exec("begin") + db.exec("begin") -game.setup.options = JSON.stringify(game.setup.options) + game.setup.options = JSON.stringify(game.setup.options) -function find_user(name) { - return select_user.get(name) || 1 -} - -let game_id = insert_game.get(game.setup) -for (let p of game.players) - insert_player.run(game_id, p.role, find_user(p.name)) -insert_state.run(game_id, JSON.stringify(game.state)) + function find_user(name) { + return select_user.get(name) || 1 + } -if (game.replay) { - let insert_replay = db.prepare("insert into game_replay(game_id,replay_id,role,action,arguments) values (?,?,?,?,?)") - game.replay.forEach(([role, action, args], i) => { - insert_replay.run(game_id, i+1, role, action, JSON.stringify(args)) - }) -} + let game_id = insert_game.get(game.setup) + for (let p of game.players) + insert_player.run(game_id, p.role, find_user(p.name)) + insert_state.run(game_id, JSON.stringify(game.state)) + update_active_trigger.run(game_id) + + if (game.replay) { + let insert_replay = db.prepare("insert into game_replay(game_id,replay_id,role,action,arguments) values (?,?,?,?,?)") + game.replay.forEach(([role, action, args], i) => { + insert_replay.run(game_id, i+1, role, action, JSON.stringify(args)) + }) + } -if (game.snaps) { - let insert_snap = db.prepare("insert into game_snap(game_id,snap_id,replay_id,state) values (?,?,?,?)") - game.snaps.forEach(([replay_id, state], i) => { - insert_snap.run(game_id, i+1, replay_id, JSON.stringify(state)) - }) -} + if (game.snaps) { + let insert_snap = db.prepare("insert into game_snap(game_id,snap_id,replay_id,state) values (?,?,?,?)") + game.snaps.forEach(([replay_id, state], i) => { + insert_snap.run(game_id, i+1, replay_id, JSON.stringify(state)) + }) + } -console.log(game_id) + console.log(game_id) -db.exec("commit") + db.exec("commit") +} diff --git a/tools/lift-bans.sh b/tools/lift-bans.sh new file mode 100644 index 0000000..e76f621 --- /dev/null +++ b/tools/lift-bans.sh @@ -0,0 +1,30 @@ +#!/bin/bash + +sqlite3 db <<EOF + +begin immediate; + +.mode column + +create temporary view tm_lift_ban_view as + select + user_id, + name, + date(timeout_last), + timeout_total, + games_since_timeout, + (games_since_timeout > timeout_total) and (julianday() > julianday(timeout_last)+14) as lift_ban + from + user_profile_view + where + user_id in (select user_id from tm_banned) + order by lift_ban desc, timeout_last asc +; + +select * from tm_lift_ban_view; + +delete from tm_banned where user_id in (select user_id from tm_lift_ban_view where lift_ban) returning user_id; + +commit; + +EOF diff --git a/tools/patchgame.js b/tools/patchgame.js index c2b0802..de8721e 100755 --- a/tools/patchgame.js +++ b/tools/patchgame.js @@ -71,24 +71,82 @@ function snapshot(state) { return snap } +function is_role_active(active, role) { + return active === role || active === "Both" || active.includes(role) +} + +function is_nobody_active(active) { + return !active || active === "None" +} + +function is_multi_active(active) { + if (!active) + return false + if (Array.isArray(active)) + return true + return active === "Both" || active.includes(",") +} + +function is_changed_active(old_active, new_active) { + return String(old_active) !== String(new_active) +} + function is_valid_action(rules, state, role, action, arg) { if (action === "undo") // for jc, hots, r3, and cr compatibility return true - if (state.active !== role && state.active !== "Both") + if (!is_role_active(state.active, role)) return false let view = rules.view(state, role) let va = view.actions[action] if (va) { - if (Array.isArray(arg)) - arg = arg[0] if (Array.isArray(va) && va.includes(arg)) return true - if (arg === undefined || arg === null || arg === 1) + if (arg === undefined || arg === null || arg === 1 || Array.isArray(arg)) return (va === 1 || va === true || typeof va === "string") } return false } +function dont_snap(rules, state, old_active) { + if (is_nobody_active(state.active)) + return true + if (is_multi_active(old_active) && is_multi_active(state.active)) + return true + if (!is_changed_active(old_active, state.active)) + return true + if (rules.dont_snap && rules.dont_snap(state)) + return true + return false +} + +function get_game_roles(rules, scenario, options) { + let roles = rules.roles + if (typeof roles === "function") { + if (typeof options === "string") + options = JSON.parse(options) + return roles(scenario, options) + } + return roles +} + +function get_resign_result(roles, role) { + return roles.filter(r => r !== role).join(", ") +} + +function finish_game(rules, state, result, message) { + if (typeof rules.finish === "function") { + state = RULES[title_id].finish(state, result, message) + } else { + state.state = "game_over" + state.active = "None" + state.result = result + state.victory = message + state.log.push("") + state.log.push(message) + } + return state +} + function patch_game(game_id, {validate_actions=true, save_snaps=true, delete_undo=false, delete_invalid=false}, verbose) { let game = select_game.get(game_id) if (!game) { @@ -98,6 +156,7 @@ function patch_game(game_id, {validate_actions=true, save_snaps=true, delete_und let title_id = game.title_id let rules = require("../public/" + title_id + "/rules.js") + let roles = get_game_roles(rules, game.scenario, game.options) let replay = select_replay.all(game_id) if (replay.length === 0) @@ -121,8 +180,13 @@ function patch_game(game_id, {validate_actions=true, save_snaps=true, delete_und case ".setup": state = rules.setup(...args) break + case ".timeout": + finish_game(rules, state, "None", item.role + " timed out.") + break + case ".abandon": + finish_game(rules, state, "None", item.role + " abandoned the game.") case ".resign": - state = rules.resign(state, item.role) + finish_game(rules, state, get_resign_result(roles, item.role), item.role + " resigned.") break default: if (validate_actions) { @@ -142,7 +206,7 @@ function patch_game(game_id, {validate_actions=true, save_snaps=true, delete_und item.state = snapshot(state) item.checksum = crc32c(item.state) - if (old_active !== state.active) + if (!dont_snap(rules, state, old_active)) item.save = 1 old_active = state.active @@ -177,7 +241,7 @@ function patch_game(game_id, {validate_actions=true, save_snaps=true, delete_und insert_snap.run(game_id, ++snap_id, item.replay_id, item.state) } - update_active.run(state.active, game_id) + update_active.run(String(state.active), game_id) update_state.run(JSON.stringify(state), game_id) if (state.state === "game_over") diff --git a/tools/purge.sql b/tools/purge.sql index 3e0c898..2a95f01 100644 --- a/tools/purge.sql +++ b/tools/purge.sql @@ -2,6 +2,8 @@ attach database 'db' as live; +pragma live.busy_timeout=10000; + create temporary view prune_snap_list as select distinct game_id @@ -26,12 +28,8 @@ create temporary view prune_all_list as ) ; -begin; - select 'PURGE SNAPS FROM ' || count(1) from prune_snap_list; delete from live.game_snap where game_id in (select game_id from prune_snap_list); select 'PURGE ALL FROM ' || count(1) from prune_all_list; update live.games set status = 3 where game_id in (select game_id from prune_all_list); - -commit; |