diff options
author | Tor Andersson <tor@ccxvii.net> | 2025-04-25 12:18:00 +0200 |
---|---|---|
committer | Tor Andersson <tor@ccxvii.net> | 2025-04-25 17:56:43 +0200 |
commit | fc3501382c2aa3ef5b692f4f55c2616f9cade3f5 (patch) | |
tree | a047bb94f8f1854c621fa0fba5ed62c8e0d0be14 | |
parent | ed2361980b455d1825d811670f329cbcf5624927 (diff) | |
download | server-fc3501382c2aa3ef5b692f4f55c2616f9cade3f5.tar.gz |
Move toolbox scripts to a "bin" directory.
Add a super "rtt" command to run the scripts.
-rwxr-xr-x | bin/rtt | 31 | ||||
-rwxr-xr-x[-rw-r--r--] | bin/rtt-archive-backup (renamed from tools/archive.sql) | 9 | ||||
-rwxr-xr-x[-rw-r--r--] | bin/rtt-archive-prune (renamed from tools/purge.sql) | 5 | ||||
-rwxr-xr-x[-rw-r--r--] | bin/rtt-archive-restore (renamed from tools/unarchive.sh) | 2 | ||||
-rwxr-xr-x | bin/rtt-backup | 4 | ||||
-rwxr-xr-x[-rw-r--r--] | bin/rtt-export (renamed from tools/export-game.sh) | 3 | ||||
-rwxr-xr-x | bin/rtt-foreach | 17 | ||||
-rwxr-xr-x | bin/rtt-fuzz (renamed from tools/fuzz.sh) | 4 | ||||
-rwxr-xr-x | bin/rtt-help | 34 | ||||
-rwxr-xr-x | bin/rtt-import (renamed from tools/import-game.js) | 2 | ||||
-rwxr-xr-x | bin/rtt-init | 13 | ||||
-rwxr-xr-x | bin/rtt-patch (renamed from tools/patchgame.js) | 6 | ||||
-rwxr-xr-x[-rw-r--r--] | bin/rtt-run (renamed from tools/run.sh) | 4 | ||||
-rwxr-xr-x | bin/rtt-show-chat | 7 | ||||
-rwxr-xr-x[-rw-r--r--] | bin/rtt-show-game (renamed from tools/showgame.sh) | 2 | ||||
-rwxr-xr-x | bin/rtt-show-replay | 7 | ||||
-rwxr-xr-x[-rw-r--r--] | bin/rtt-tm-unban-tick (renamed from tools/lift-bans.sh) | 2 | ||||
-rwxr-xr-x[-rw-r--r--] | bin/rtt-undo (renamed from tools/undo.sh) | 4 | ||||
-rwxr-xr-x[-rw-r--r--] | bin/rtt-update-covers (renamed from tools/gencovers.sh) | 12 | ||||
-rwxr-xr-x[-rw-r--r--] | bin/rtt-update-elo (renamed from tools/elo.js) | 2 | ||||
-rw-r--r-- | docs/index.md | 3 | ||||
-rw-r--r-- | docs/server/install.md | 1 | ||||
-rw-r--r-- | docs/server/production.md | 4 | ||||
-rw-r--r-- | docs/server/toolbox.md | 52 | ||||
-rw-r--r-- | package.json | 1 | ||||
-rw-r--r--[-rwxr-xr-x] | tools/fuzz.js (renamed from tools/rtt-fuzz.js) | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | tools/new-layout.js | 2 | ||||
-rw-r--r-- | tools/readgame.sh | 10 | ||||
-rw-r--r-- | tools/showreplay.sh | 2 | ||||
-rw-r--r-- | tools/writegame.sh | 7 |
30 files changed, 213 insertions, 39 deletions
@@ -0,0 +1,31 @@ +#!/bin/bash + +cmd=$1 +shift + +bindir=$(dirname $(readlink -f $0)) + +if [ ! -n "$cmd" ] +then + cmd=help +fi + +if [ ! -f ./server.js ] +then + echo "rtt: command must run in the top-level server directory!" + exit 1 +fi + +if [ ! -f $bindir/rtt-$cmd ] +then + echo "rtt: '$cmd' is not an rtt command" + exit 1 +fi + +if [ ! -f ./db -a "$cmd" != init -a "$cmd" != "help" ] +then + echo "rtt: the database does not exist!" + exit 1 +fi + +exec $bindir/rtt-$cmd "$@" diff --git a/tools/archive.sql b/bin/rtt-archive-backup index e8b5458..f1b63e5 100644..100755 --- a/tools/archive.sql +++ b/bin/rtt-archive-backup @@ -1,10 +1,13 @@ --- Make a copy of finished games in a separate archive database. +#!/bin/bash +sqlite3 <<EOF -pragma busy_timeout=10000; +-- Make a copy of finished games in a separate archive database. attach database 'db' as live; attach database 'archive.db' as archive; +pragma live.busy_timeout=10000; + -- List finished (and rated) games in live that are not in archive. create temporary view candidates as select @@ -99,3 +102,5 @@ insert into archive.games (game_id, title_id, scenario, options, player_count, c from candidates join live.games using(game_id); commit; + +EOF diff --git a/tools/purge.sql b/bin/rtt-archive-prune index 2a95f01..fff7f23 100644..100755 --- a/tools/purge.sql +++ b/bin/rtt-archive-prune @@ -1,3 +1,6 @@ +#!/bin/bash +sqlite3 <<EOF + -- Prune game snapshot and game state data to save database space. attach database 'db' as live; @@ -33,3 +36,5 @@ 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); + +EOF diff --git a/tools/unarchive.sh b/bin/rtt-archive-restore index 6adb300..dc4d59e 100644..100755 --- a/tools/unarchive.sh +++ b/bin/rtt-archive-restore @@ -3,7 +3,7 @@ if [ -z "$1" ] then - echo 'usage: bash tools/unarchive.sh <gameid>' + echo "usage: rtt-archive-restore GAME" exit 1 fi diff --git a/bin/rtt-backup b/bin/rtt-backup new file mode 100755 index 0000000..40a0efc --- /dev/null +++ b/bin/rtt-backup @@ -0,0 +1,4 @@ +#!/bin/bash +FILE=$(date +backup-%Y%m%d-%H%M.db) +echo $FILE +sqlite3 db "vacuum into '$FILE'" diff --git a/tools/export-game.sh b/bin/rtt-export index 19cd4e7..b82950c 100644..100755 --- a/tools/export-game.sh +++ b/bin/rtt-export @@ -3,6 +3,5 @@ if [ -n "$1" ] then sqlite3 db "select export from game_export_view where game_id=$1" else - echo "usage: bash tools/export-game.sh GAME > game.json" + echo "usage: rtt-export GAME > game.json" fi - diff --git a/bin/rtt-foreach b/bin/rtt-foreach new file mode 100755 index 0000000..22feb77 --- /dev/null +++ b/bin/rtt-foreach @@ -0,0 +1,17 @@ +#!/bin/bash + +if [ -z "$1" ] +then + echo "usage: rtt-foreach <command>" + exit 1 +fi + +for M in $(sqlite3 db "select title_id from titles") +do + echo "Entering 'public/$M'" + if pushd public/$M >/dev/null + then + "$@" + popd >/dev/null + fi +done diff --git a/tools/fuzz.sh b/bin/rtt-fuzz index fd2391b..d7f2aef 100755 --- a/tools/fuzz.sh +++ b/bin/rtt-fuzz @@ -5,12 +5,12 @@ shift if [ ! -f ./public/$TITLE/rules.js ] then - echo usage: bash tools/fuzz.sh title_id + echo usage: rtt-fuzz TITLE exit 1 fi mkdir -p fuzzer/corpus-$TITLE RULES=../public/$TITLE/rules.js \ - npx jazzer tools/rtt-fuzz.js --sync fuzzer/corpus-$TITLE "$@" -- -exact_artifact_path=/dev/null | \ + npx jazzer tools/fuzz.js --sync fuzzer/corpus-$TITLE "$@" -- -exact_artifact_path=/dev/null | \ tee fuzzer/log-$TITLE.txt diff --git a/bin/rtt-help b/bin/rtt-help new file mode 100755 index 0000000..5f6815c --- /dev/null +++ b/bin/rtt-help @@ -0,0 +1,34 @@ +#!/bin/bash +cat <<EOF +usage: rtt <subcommand> [ arguments... ] + +database management + init -- create database + run -- run server + backup -- backup database + +game management + export -- export game + import -- import game + patch -- patch game state (using replay) + undo -- rewind game state (using replay) + +module development + foreach -- run a command for each module + fuzz -- fuzz test a module + +game debugging + show-chat -- show game chat (for moderation) + show-game -- show game state object + show-replay -- show game replay log + +miscellaneous tools + update-covers -- generate cover thumbnails + update-elo -- recalculate Elo ratings + +archive database + archive-backup -- backup replay data into archive + archive-prune -- prune replay data from live database + archive-restore -- restore replay data from archive + +EOF diff --git a/tools/import-game.js b/bin/rtt-import index 4380252..2e4295b 100755 --- a/tools/import-game.js +++ b/bin/rtt-import @@ -17,7 +17,7 @@ for (let i = 2; i < process.argv.length; ++i) { } if (input.length < 1) { - console.error("usage: node tools/import-game.js [title_id=value] [notice=value] game.json") + console.error("usage: rtt-import [title_id=value] [notice=value] game-dump.json") process.exit(1) } diff --git a/bin/rtt-init b/bin/rtt-init new file mode 100755 index 0000000..02b9e9b --- /dev/null +++ b/bin/rtt-init @@ -0,0 +1,13 @@ +#!/bin/bash + +echo installing node packages +npm install -s + +echo creating database +sqlite3 db < schema.sql + +for M in public/*/title.sql +do + echo registering module $(basename $(dirname $M)) + sqlite3 db < $M +done diff --git a/tools/patchgame.js b/bin/rtt-patch index de8721e..19e9874 100755 --- a/tools/patchgame.js +++ b/bin/rtt-patch @@ -272,9 +272,9 @@ function patch_title(title_id, options) { } if (process.argv.length < 3) { - process.stderr.write("usage: ./tools/patchgame.js <game_id> '{options}'\n") - process.stderr.write(" or: ./tools/patchgame.js <title_id> '{options}'\n") - process.stderr.write(" or: ./tools/patchgame.js all '{options}'\n") + process.stderr.write("usage: rtt-patch <game_id> '{options}'\n") + process.stderr.write(" or: rtt-patch <title_id> '{options}'\n") + process.stderr.write(" or: rtt-patch all '{options}'\n") process.stderr.write('options: { "validate_actions":true, "delete_invalid":false, "save_snaps":true, "delete_undo":false }\n') process.exit(1) } diff --git a/tools/run.sh b/bin/rtt-run index efadfe7..6873e2f 100644..100755 --- a/tools/run.sh +++ b/bin/rtt-run @@ -2,6 +2,8 @@ while true do nodemon --exitcrash server.js - echo Restarting soon... + echo + echo "Restarting soon!" + echo "Hit Ctl-C to exit." sleep 3 done diff --git a/bin/rtt-show-chat b/bin/rtt-show-chat new file mode 100755 index 0000000..7d71718 --- /dev/null +++ b/bin/rtt-show-chat @@ -0,0 +1,7 @@ +#!/bin/bash +if [ -n "$1" ] +then + sqlite3 db ".mode column --wrap 40 -ww" "select time,name,message from game_chat_view where game_id=$1" | less -FX +else + echo "usage: rtt-show-chat GAME" +fi diff --git a/tools/showgame.sh b/bin/rtt-show-game index f45be78..ece9e49 100644..100755 --- a/tools/showgame.sh +++ b/bin/rtt-show-game @@ -3,5 +3,5 @@ if [ -n "$1" ] then sqlite3 db "select json_remove(json_remove(state, '$.undo'), '$.log') from game_state where game_id = $1" else - echo "usage: bash tools/showgame.sh GAME" + echo "usage: rtt-show-state GAME" fi diff --git a/bin/rtt-show-replay b/bin/rtt-show-replay new file mode 100755 index 0000000..4bbbdce --- /dev/null +++ b/bin/rtt-show-replay @@ -0,0 +1,7 @@ +#!/bin/bash +if [ -n "$1" ] +then + sqlite3 db "select replay_id, role, action, arguments from game_replay where game_id=$1" +else + echo "usage: rtt-show-replay GAME" +fi diff --git a/tools/lift-bans.sh b/bin/rtt-tm-unban-tick index e76f621..7294e81 100644..100755 --- a/tools/lift-bans.sh +++ b/bin/rtt-tm-unban-tick @@ -1,5 +1,7 @@ #!/bin/bash +# Run this script in a cron job to lift tournament bans periodically. + sqlite3 db <<EOF begin immediate; diff --git a/tools/undo.sh b/bin/rtt-undo index b75182f..2f69eed 100644..100755 --- a/tools/undo.sh +++ b/bin/rtt-undo @@ -9,7 +9,7 @@ then echo Game has $COUNT actions. fi sqlite3 db "delete from game_replay where game_id=$1 and replay_id>=$COUNT" - node tools/patchgame.js $1 '{"validate_actions":false}' + ./bin/rtt-patch $1 '{"validate_actions":false}' else - echo "usage: bash tools/undo.sh GAME" + echo "usage: rtt-undo GAME" fi diff --git a/tools/gencovers.sh b/bin/rtt-update-covers index 454d69b..0eae8e7 100644..100755 --- a/tools/gencovers.sh +++ b/bin/rtt-update-covers @@ -1,6 +1,16 @@ +#!/bin/bash + +if command -v convert && command -v pngtopnm && command -v cjpeg +then + echo "Generating cover images and thumbnails!" +else + echo error: cannot find imagemagick, netpbm, and/or cjpeg + exit 1 +fi + for F in public/*/cover.jpg public/*/cover.png do - echo Processing: $F + echo processing $F B=$(echo $F | sed s/.jpg// | sed s/.png//) D=$(dirname $F) diff --git a/tools/elo.js b/bin/rtt-update-elo index f6064f1..538964a 100644..100755 --- a/tools/elo.js +++ b/bin/rtt-update-elo @@ -1,5 +1,7 @@ #!/usr/bin/env -S node +// Recompute Elo ratings from scratch! + const sqlite3 = require("better-sqlite3") const db = new sqlite3("db") diff --git a/docs/index.md b/docs/index.md index 96c9a7b..254cc74 100644 --- a/docs/index.md +++ b/docs/index.md @@ -13,6 +13,7 @@ server instance and how to create new modules. * [Installing the server](/docs/server/install) * [Running a public server](/docs/server/production) +* [Toolbox](/docs/server/toolbox) ## System overview @@ -22,7 +23,7 @@ server instance and how to create new modules. ## Module implementation -* [Step by step guide](/docs/module/guide) +* [General tips and where to start](/docs/module/guide) * [Rules framework](/docs/module/rules) * [Script syntax](/docs/module/script) * [Utility library](/docs/module/library) diff --git a/docs/server/install.md b/docs/server/install.md index 86359bc..4e48440 100644 --- a/docs/server/install.md +++ b/docs/server/install.md @@ -43,4 +43,3 @@ Register it in the database: Open the browser to http://localhost:8080/ and create an account. The first account created will have administrator privileges. - diff --git a/docs/server/production.md b/docs/server/production.md index 9882a5a..4344630 100644 --- a/docs/server/production.md +++ b/docs/server/production.md @@ -91,11 +91,11 @@ Run the archive and purge scripts as part of the backup cron job. Copy game state data of finished games into archive database. - sqlite3 tools/archive.sql + sqlite3 < tools/archive.sql Delete game state data of finished games over a certain age. - sqlite3 tools/purge.sql + sqlite3 < tools/purge.sql Restore archived game state. diff --git a/docs/server/toolbox.md b/docs/server/toolbox.md new file mode 100644 index 0000000..ebbabaf --- /dev/null +++ b/docs/server/toolbox.md @@ -0,0 +1,52 @@ +# Toolbox + +There are a few programs that help maintain the database and are useful to +develop and debug modules. + +## Setup + +These programs can be invoked from the command line by running the "rtt" +command that is found in the "bin" directory. +I suggest creating a symlink to the "rtt" command somewhere in your PATH. + + ln -s ~/server/bin/rtt ~/.local/bin + +Alternatively, you can edit your .profile to add the server bin directory to your PATH. + + PATH=$PATH:$HOME/server/bin + +## Commands + +database management + + init -- create database + run -- run server + backup -- backup database + +game management + + export -- export game + import -- import game + patch -- patch game state (using replay) + undo -- rewind game state (using replay) + +module development + + foreach -- run a command for each module + fuzz -- fuzz test a module + +game debugging + + show-chat -- show game chat (for moderation) + show-game -- show game state object + show-replay -- show game replay log + +miscellaneous tools + + update-covers -- generate cover thumbnails + update-elo -- recalculate Elo ratings + +## Miscellaneous + +The "tools" directory holds various useful bits and bobs. + diff --git a/package.json b/package.json index 98e6b06..2ac0ce2 100644 --- a/package.json +++ b/package.json @@ -9,6 +9,7 @@ "express": "^4.18.2", "marked": "^15.0.10", "nodemailer": "^6.9.9", + "nodemon": "^3.1.10", "pug": "^3.0.2", "utf-8-validate": "^6.0.3", "ws": "^8.16.0" diff --git a/tools/rtt-fuzz.js b/tools/fuzz.js index 0690697..0690697 100755..100644 --- a/tools/rtt-fuzz.js +++ b/tools/fuzz.js diff --git a/tools/new-layout.js b/tools/new-layout.js index ce0bb6e..238a257 100644..100755 --- a/tools/new-layout.js +++ b/tools/new-layout.js @@ -1,3 +1,5 @@ +#!/usr/bin/env -S node + const print = console.log if (process.argv.length < 4) { diff --git a/tools/readgame.sh b/tools/readgame.sh deleted file mode 100644 index 4a8fdbd..0000000 --- a/tools/readgame.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/bash -if [ -n "$1" -a -n "$2" ] -then - sqlite3 db "select writefile('$2',state) from game_state where game_id = $1" -elif [ -n "$1" ] -then - sqlite3 db "select state from game_state where game_id = $1" -else - echo "usage: bash tools/readgame.sh GAME [ state.json ]" -fi diff --git a/tools/showreplay.sh b/tools/showreplay.sh deleted file mode 100644 index 413e12f..0000000 --- a/tools/showreplay.sh +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/bash -sqlite3 db "select * from game_replay where game_id=$1" diff --git a/tools/writegame.sh b/tools/writegame.sh deleted file mode 100644 index ea0f599..0000000 --- a/tools/writegame.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/bash -if [ -n "$1" -a -f "$2" ] -then - sqlite3 db "update game_state set state=readfile('$2') where game_id = $1" -else - echo "usage: bash tools/writegame.sh GAME state.json" -fi |