ql-lg-server: Quake Live LG vampiric practice server in Docker
One-command setup (SteamCMD + minqlx build), .env settings with a listed/unlisted switch, three factories (lgvamp, lgvamp_nolag, lgvamp100), warmup-text and welcome minqlx plugins, watchdog/backup/daily-restart, docs for admins and players. Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
commit
bc5bd09c15
25 files changed
+1009
No files matched your search
Executable
+16
@@ -0,0 +1,16 @@
|
||||
#!/bin/sh
|
||||
# Nightly backup of settings, secrets, admins/bans and plugins (not the game files: setup.sh
|
||||
# re-downloads them). backups/ql-YYYY-MM-DD.tar.gz, 14 days kept. Also empties QL's log files
|
||||
# once they pass 50 MB (QL appends to them forever).
|
||||
. "$(dirname "$0")/env.sh"
|
||||
set -e
|
||||
umask 077
|
||||
mkdir -p backups
|
||||
chmod 700 backups
|
||||
tar czf backups/ql-$(date +%F).tar.gz .env secrets home/baseq3/access.txt \
|
||||
home/baseq3/server.cfg home/baseq3/scripts home/minqlx-plugins 2>/dev/null || true
|
||||
find backups -name "ql-*.tar.gz" -mtime +14 -delete
|
||||
for f in home/baseq3/*.log home/minqlx.log; do
|
||||
if [ -f "$f" ] && [ "$(stat -c %s "$f")" -gt 52428800 ]; then : > "$f"; fi
|
||||
done
|
||||
exit 0
|
||||
Executable
+16
@@ -0,0 +1,16 @@
|
||||
#!/bin/sh
|
||||
# Daily clean restart (cron). Skipped while a human is playing (bots have address 'bot'), and also
|
||||
# skipped if the player count can't be read: better a missed restart than kicking someone.
|
||||
. "$(dirname "$0")/env.sh"
|
||||
LOG=logs/watchdog.log
|
||||
[ "$(docker inspect -f '{{.State.Status}}' "$NAME" 2>/dev/null)" = running ] || exit 0
|
||||
H=$(python3 tools/qlq.py 127.0.0.1 "$QPORT" --humans 2>/dev/null)
|
||||
case "$H" in
|
||||
''|*[!0-9]*) echo "$(date '+%F %T') daily restart skipped: player count unknown" >> $LOG; exit 0 ;;
|
||||
esac
|
||||
if [ "$H" -gt 0 ]; then
|
||||
echo "$(date '+%F %T') daily restart skipped: $H player(s) on" >> $LOG
|
||||
exit 0
|
||||
fi
|
||||
echo "$(date '+%F %T') daily restart" >> $LOG
|
||||
[ -n "$DRYRUN" ] || docker restart "$NAME" >/dev/null 2>&1
|
||||
Executable
+5
@@ -0,0 +1,5 @@
|
||||
# Sourced by the scripts in this folder: cd to the repo and read QL_NAME / QL_PORT from .env.
|
||||
cd "$(dirname "$0")/.." || exit 1
|
||||
NAME=$(sed -n 's/^QL_NAME=//p' .env 2>/dev/null | tr -d '\r'); NAME=${NAME:-ql-lg}
|
||||
QPORT=$(sed -n 's/^QL_PORT=//p' .env 2>/dev/null | tr -d '\r'); QPORT=${QPORT:-27960}
|
||||
mkdir -p logs
|
||||
Executable
+17
@@ -0,0 +1,17 @@
|
||||
#!/bin/sh
|
||||
# Adds the watchdog (every 5 min), backup (04:40) and daily restart (05:00) to your crontab.
|
||||
# Safe to run again: replaces its own lines (tagged with this folder's path), leaves others alone.
|
||||
# ./scripts/install-cron.sh --remove takes them out again.
|
||||
D=$(cd "$(dirname "$0")/.." && pwd)
|
||||
TAG="# ql-lg-server $D"
|
||||
OLD=$(crontab -l 2>/dev/null | grep -vF "$TAG")
|
||||
if [ "$1" = "--remove" ]; then
|
||||
printf '%s\n' "$OLD" | crontab - && echo "removed cron lines for $D"; exit 0
|
||||
fi
|
||||
{
|
||||
[ -n "$OLD" ] && printf '%s\n' "$OLD"
|
||||
echo "*/5 * * * * $D/scripts/watchdog.sh $TAG"
|
||||
echo "40 4 * * * $D/scripts/backup.sh $TAG"
|
||||
echo "0 5 * * * $D/scripts/daily-restart.sh $TAG"
|
||||
} | crontab -
|
||||
echo "cron installed for $D:"; crontab -l | grep -F "$TAG"
|
||||
Executable
+22
@@ -0,0 +1,22 @@
|
||||
#!/bin/sh
|
||||
# Hang watchdog (cron every 5 min). Docker already restarts the server when it crashes; this covers
|
||||
# the other case: container "running" but the server not answering. Restarts it after 3 failed
|
||||
# checks in a row (~15 min). Does nothing if the container was stopped on purpose.
|
||||
# DRYRUN=1 logs without restarting; PORT=... overrides the port (testing).
|
||||
. "$(dirname "$0")/env.sh"
|
||||
STATE=logs/.watchdog-fails
|
||||
LOG=logs/watchdog.log
|
||||
PORT=${PORT:-$QPORT}
|
||||
[ "$(docker inspect -f '{{.State.Status}}' "$NAME" 2>/dev/null)" = running ] || { rm -f $STATE; exit 0; }
|
||||
if python3 tools/qlq.py 127.0.0.1 "$PORT" >/dev/null 2>&1; then
|
||||
rm -f $STATE
|
||||
else
|
||||
n=$(( $(cat $STATE 2>/dev/null || echo 0) + 1 ))
|
||||
echo $n > $STATE
|
||||
echo "$(date '+%F %T') no answer ($n/3)" >> $LOG
|
||||
if [ $n -ge 3 ]; then
|
||||
echo "$(date '+%F %T') restarting $NAME" >> $LOG
|
||||
[ -n "$DRYRUN" ] || docker restart "$NAME" >/dev/null 2>&1
|
||||
rm -f $STATE
|
||||
fi
|
||||
fi
|
||||
Reference in new issue
Block a user