initial commit
This commit is contained in:
commit
b36960f50e
|
@ -0,0 +1,4 @@
|
|||
\#*
|
||||
.#*
|
||||
logs/
|
||||
crawl-git-repository/
|
|
@ -0,0 +1,90 @@
|
|||
dgamelaunch-config
|
||||
------------------
|
||||
|
||||
This is a collection of scripts to manage a dgamelaunch
|
||||
(http://nethackwiki.com/wiki/Dgamelaunch) install, all run from an
|
||||
umbrella `dgl` script.
|
||||
|
||||
These are still very incomplete, WIP.
|
||||
|
||||
Currently available commands:
|
||||
|
||||
1. Update your dgamelaunch config from the repository:
|
||||
$ sudo dgl publish --confirm
|
||||
|
||||
2. Change a dgl user's password:
|
||||
$ sudo dgl passwd johndoe
|
||||
|
||||
3. Update Crawl alpha build from git master:
|
||||
$ dgl update-trunk
|
||||
|
||||
4. Remove stale Crawl alpha versions:
|
||||
$ dgl remove-trunks
|
||||
|
||||
5. Run dgl-whereis inotify daemon:
|
||||
$ sudo dgl crawl-inotify-dglwhere
|
||||
|
||||
This inotify daemon monitors the dgamelaunch in-progress dirs to keep
|
||||
track of active players, and monitors their morgue directories for
|
||||
changes to their .where files. When a .where changes, the daemon reads
|
||||
it and writes a human-readable .dglwhere file in the same directory.
|
||||
|
||||
You may configure dgamelaunch to show this .dglwhere information
|
||||
using the dgamelaunch extra_info_file option.
|
||||
|
||||
You may also run the crawl-inotify-dglwhere script standalone (without
|
||||
the rest of the dgamelaunch-config setup) by starting it as:
|
||||
|
||||
sudo -u dgl perl crawl-inotify-dglwhere.pl <dgldir> <morguedir>
|
||||
|
||||
Note: Some of these commands will probably change names soon.
|
||||
|
||||
The ultimate goal for this project is to become a one-stop shop for
|
||||
all your dgamelaunch+Crawl needs, starting from installing dgamelaunch
|
||||
itself
|
||||
|
||||
TODO
|
||||
----
|
||||
|
||||
1. `dgl install-dgl` command to fetch and install the latest dgamelaunch.
|
||||
|
||||
2. `dgl create-chroot` command to set up a basic chroot jail with all the
|
||||
fixtures dgamelaunch wants (dgamelaunch already has a skeleton script
|
||||
that can serve as a basis, although this is unfortunately NetHack-biased).
|
||||
|
||||
3. Support for installing different games, including fetching their sources
|
||||
from their respective source repositories, compiling, installing into the
|
||||
chroot, etc.
|
||||
`dgl install crawl master`,
|
||||
`dgl install nethack 3.4.3` etc.)
|
||||
|
||||
Installing a game should also (eventually) add a suitable entry to
|
||||
the various menu files and update the dgamelaunch config
|
||||
appropriately.
|
||||
|
||||
4. Support for tracking development versions of games (such as Crawl
|
||||
master) using a system similar to CDO's for creating versioned
|
||||
directories, migrating saves to newer versions, and deleting old
|
||||
versions with no remaining save games.
|
||||
|
||||
5. Module system so that management of say, crawl-git is a
|
||||
self-contained module. Each module should be able to contribute dgl
|
||||
commands and provide files that will be installed to the chroot or
|
||||
root filesystem.
|
||||
|
||||
6. Each dgl command that affects the machine or chroot should update a
|
||||
manifest. The manifest could be a file or a directory containing
|
||||
multiple manifest files.
|
||||
|
||||
Given a manifest, I should be able to install dgamelaunch-config
|
||||
on a brand new machine and use one dgl command to recreate the manifest.
|
||||
|
||||
For instance, something like:
|
||||
`dgl replicate-manifest <path-to-manifest>`
|
||||
|
||||
The manifest should include information like this:
|
||||
* What dgamelaunch version is installed, and from where (install-dgl module)
|
||||
* chroot configuration: what binaries and libraries have been installed
|
||||
into the chroot, with the exception of game binaries, i.e. the state of
|
||||
the chroot minus games (chroot module)
|
||||
* Game configuration (handled by the various game modules)
|
|
@ -0,0 +1,95 @@
|
|||
#! /bin/bash
|
||||
|
||||
help <<EOF
|
||||
|
||||
$SCRIPT_NAME: Manages dgamelaunch admin users.
|
||||
|
||||
Usage: $SCRIPT_NAME ls List admin users
|
||||
$SCRIPT_NAME add <user> Make <user> an admin
|
||||
$SCRIPT_NAME rm <user> Make <user> a regular (non-admin) user.
|
||||
|
||||
EOF
|
||||
|
||||
assert-login-db-exists
|
||||
|
||||
SUBCOMMAND=$1
|
||||
shift
|
||||
[[ -z "$SUBCOMMAND" ]] && SUBCOMMAND=ls
|
||||
|
||||
admin-ls() {
|
||||
echo "Existing admin users:"
|
||||
login-query <<EOF
|
||||
SELECT username, email FROM dglusers
|
||||
WHERE (flags & 1) = 1
|
||||
ORDER BY username;
|
||||
EOF
|
||||
}
|
||||
|
||||
|
||||
dgl-user-make-admin() {
|
||||
local user="$1"
|
||||
login-query <<EOF
|
||||
UPDATE dglusers
|
||||
SET flags = flags | 1
|
||||
WHERE username='$user';
|
||||
EOF
|
||||
}
|
||||
|
||||
dgl-user-unmake-admin() {
|
||||
local user="$1"
|
||||
login-query <<EOF
|
||||
UPDATE dglusers
|
||||
SET flags = flags & ~1
|
||||
WHERE username='$user';
|
||||
EOF
|
||||
}
|
||||
|
||||
|
||||
admin-add() {
|
||||
local new_admin="$1"
|
||||
dgl-user-exists "$new_admin" || \
|
||||
abort-saying "Cannot find user $new_admin in dgl login db"
|
||||
if dgl-user-is-admin "$new_admin"; then
|
||||
echo -e "User $new_admin is already an admin"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
assert-running-as-root
|
||||
dgl-user-make-admin "$new_admin"
|
||||
|
||||
if dgl-user-is-admin "$new_admin"; then
|
||||
printf "\nDone, $new_admin is now a DGL admin.\n"
|
||||
exit 0
|
||||
else
|
||||
echo -e "Oops, couldn't make $new_admin a DGL admin.\n"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
admin-rm() {
|
||||
local ex_admin="$1"
|
||||
dgl-user-exists "$ex_admin" || \
|
||||
abort-saying "Cannot find user $ex_admin in dgl login db"
|
||||
if ! dgl-user-is-admin "$ex_admin"; then
|
||||
echo -e "User $ex_admin is not an admin, nothing to do"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
assert-running-as-root
|
||||
dgl-user-unmake-admin "$ex_admin"
|
||||
|
||||
if ! dgl-user-is-admin "$ex_admin"; then
|
||||
printf "\nDone, $ex_admin is now a regular DGL non-admin user.\n"
|
||||
exit 0
|
||||
else
|
||||
echo -e "Oops, couldn't make $ex_admin a regular DGL non-admin user."
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
case $SUBCOMMAND in
|
||||
ls) admin-ls "$@" ;;
|
||||
add) each-do admin-add "$@" ;;
|
||||
rm) each-do admin-rm "$@" ;;
|
||||
*) abort-saying "Unknown usage: $SCRIPT_NAME $SUBCOMMAND"
|
||||
esac
|
|
@ -0,0 +1,54 @@
|
|||
#! /bin/bash
|
||||
|
||||
source $DGL_CONF_HOME/crawl-git.conf
|
||||
|
||||
if [[ $UID != 0 ]]; then
|
||||
echo "$0 must be run as root!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ $1 == -v || $1 == --verbose ]]; then
|
||||
verbose=1
|
||||
else
|
||||
verbose=0
|
||||
fi
|
||||
|
||||
verbiate() {
|
||||
((verbose)) && echo "$@" >&2
|
||||
}
|
||||
|
||||
quietly() {
|
||||
"$@" >/dev/null 2>&1
|
||||
}
|
||||
|
||||
failures=()
|
||||
skip=0 succ=0 fail=0
|
||||
shopt -s nullglob
|
||||
for ttyrec in "$TTYRECDIR"/*/*.ttyrec; do
|
||||
# If anyone has it open, skip it.
|
||||
if quietly lsof "$ttyrec"; then
|
||||
verbiate -n "."
|
||||
let ++skip
|
||||
continue
|
||||
fi
|
||||
if bzip2 "$ttyrec"; then
|
||||
let ++succ
|
||||
verbiate -n "+"
|
||||
else
|
||||
let ++fail
|
||||
verbiate -n "X"
|
||||
failures+=( "$ttyrec" )
|
||||
fi
|
||||
done
|
||||
verbiate
|
||||
|
||||
if (( failed || verbose )); then
|
||||
printf "%d succeeded\t%d failed\t%d skipped\n" "$succ" "$fail" "$skip"
|
||||
if (( failed )); then
|
||||
printf "\nFailing files:\n"
|
||||
printf " %s\n" "${failures[@]}"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
exit 0
|
|
@ -0,0 +1,312 @@
|
|||
#! /usr/bin/perl
|
||||
#
|
||||
# Monitors dgamelaunch inprogress-dirs to detect active games, and then
|
||||
# monitors those active games to find .where updates and converts them to
|
||||
# .dglwhere files that dgamelaunch can consume.
|
||||
#
|
||||
# Assumption: inprogress dirs are directly under DGLDIR/inprogress*
|
||||
# Assumption: player .where files are under TTYRECDIR/<playername>/
|
||||
# Assumption: the script runs with permissions to create .dglwhere alongside
|
||||
# the player .where
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use Linux::Inotify2;
|
||||
use POSIX;
|
||||
use Fcntl qw/:flock/;
|
||||
|
||||
use Getopt::Long;
|
||||
|
||||
my $DAEMON = 1;
|
||||
GetOptions("daemon!" => \$DAEMON)
|
||||
or die "Bad command line: @ARGV\n";
|
||||
|
||||
my $DGLDIR = $ARGV[0] || '';
|
||||
my $TTYRECDIR = $ARGV[1] || '';
|
||||
|
||||
$ENV{DGLDIR} = $DGLDIR;
|
||||
$ENV{TTYRECDIR} = $TTYRECDIR;
|
||||
|
||||
my $LOCKFILE = "$DGLDIR/.crawl-inotify.lock";
|
||||
my $LOGFILE = "$DGLDIR/crawl-inotify-where.log";
|
||||
|
||||
my $inotify;
|
||||
my %MONITORED_PLAYERS;
|
||||
|
||||
sub say($) {
|
||||
print STDERR "@_\n";
|
||||
}
|
||||
|
||||
sub assert_dir_exists($) {
|
||||
my $dir = shift;
|
||||
die "$dir not set\n" unless $ENV{$dir};
|
||||
die "Can't find $dir ($ENV{$dir})\n" unless -d $ENV{$dir};
|
||||
}
|
||||
|
||||
sub assert_environment_exists() {
|
||||
assert_dir_exists('DGLDIR');
|
||||
assert_dir_exists('TTYRECDIR');
|
||||
}
|
||||
|
||||
sub player_where_dir($$) {
|
||||
my ($player, $dir) = @_;
|
||||
for my $candidate ("$TTYRECDIR/$dir/morgue/$player") {
|
||||
return $candidate if -d $candidate;
|
||||
}
|
||||
"$TTYRECDIR/$player"
|
||||
}
|
||||
|
||||
sub player_where_file($$) {
|
||||
my ($player, $where_dir) = @_;
|
||||
player_where_dir($player, $where_dir) . "/$player.where"
|
||||
}
|
||||
|
||||
sub player_dglwhere_file($$) {
|
||||
my ($player, $morgue_dir) = @_;
|
||||
player_where_dir($player, $morgue_dir) . "/$player.dglwhere"
|
||||
}
|
||||
|
||||
sub whereis_read($) {
|
||||
my $whereis_file = shift;
|
||||
open my $inf, '<', $whereis_file or do {
|
||||
warn "Could not read whereis file: $whereis_file: $!\n";
|
||||
return;
|
||||
};
|
||||
chomp(my $text = <$inf>);
|
||||
close $inf;
|
||||
$text =~ s/::/\n/g;
|
||||
my %hash = map {
|
||||
my ($key, $value) = /(\w+)=(.*)/s;
|
||||
$value =~ s/\n/:/gs;
|
||||
($key, $value)
|
||||
} split(/:/s, $text);
|
||||
\%hash
|
||||
}
|
||||
|
||||
sub whereis_human_readable($) {
|
||||
my $w = shift;
|
||||
# No more than 18 characters, empty string for saved/dead characters:
|
||||
return '' if $$w{status} ne 'active';
|
||||
my $weight = $$w{xl} * 100 + $$w{lvl};
|
||||
sprintf("$weight|%-3s $$w{char}, $$w{place}",
|
||||
"L$$w{xl}")
|
||||
}
|
||||
|
||||
sub write_dglwhere_file($$) {
|
||||
my ($player, $where_dir) = @_;
|
||||
my $where_dict = whereis_read(player_where_file($player, $where_dir));
|
||||
|
||||
if ($where_dict) {
|
||||
my $human_readable_where = whereis_human_readable($where_dict);
|
||||
my $dglwhere_file = player_dglwhere_file($player, $where_dir);
|
||||
open my $outf, '>', $dglwhere_file or do {
|
||||
say "Could not write $dglwhere_file: $!";
|
||||
return;
|
||||
};
|
||||
print $outf "$human_readable_where\n";
|
||||
close $outf;
|
||||
say "Wrote $dglwhere_file: $human_readable_where";
|
||||
}
|
||||
}
|
||||
|
||||
sub inprog_player($) {
|
||||
my $ttyrec = shift;
|
||||
($ttyrec) = $ttyrec =~ m{.*/(.*)} if $ttyrec =~ m{/};
|
||||
my ($player) = $ttyrec =~ /(.+?):/;
|
||||
$player
|
||||
}
|
||||
|
||||
sub inprog_morgue_dir($) {
|
||||
my $dir = shift;
|
||||
$dir =~ s{/$}{};
|
||||
($dir) = $dir =~ m{.*/(.*)};
|
||||
# Strip alt qualifiers:
|
||||
$dir =~ s/\b(?:spr|zd|tut)-//;
|
||||
$dir
|
||||
}
|
||||
|
||||
## BEGIN inotify callbacks ##
|
||||
|
||||
sub inotify_player_where_file_changed {
|
||||
my ($player, $where_dir, $event) = @_;
|
||||
return unless $$event{name} =~ /$player\.where$/;
|
||||
write_dglwhere_file($player, $where_dir);
|
||||
}
|
||||
|
||||
sub inotify_inprogress_change {
|
||||
my ($inprog_dir, $event) = @_;
|
||||
my $file = $$event{name};
|
||||
return unless $file;
|
||||
|
||||
my $player = inprog_player($file);
|
||||
my $morgue_dir = inprog_morgue_dir($inprog_dir);
|
||||
my $gone_away = $$event{mask} & IN_DELETE;
|
||||
if ($player) {
|
||||
if ($gone_away) {
|
||||
say "$player went away, unmonitoring.";
|
||||
unmonitor_player($player);
|
||||
}
|
||||
else {
|
||||
say "$player started game, monitoring";
|
||||
write_dglwhere_file($player, $morgue_dir);
|
||||
monitor_player($inotify, $player, $morgue_dir);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
## END inotify callbacks ##
|
||||
|
||||
sub monitor_player($$$) {
|
||||
my ($inotify, $player, $morgue_dir) = @_;
|
||||
return if $MONITORED_PLAYERS{$player};
|
||||
say "++ MONITOR: $player";
|
||||
|
||||
my $watch;
|
||||
for my $i (1..3) {
|
||||
my $where_dir = player_where_dir($player, $morgue_dir);
|
||||
$watch = $inotify->watch($where_dir,
|
||||
IN_CLOSE_WRITE,
|
||||
sub {
|
||||
inotify_player_where_file_changed($player,
|
||||
$morgue_dir,
|
||||
@_)
|
||||
});
|
||||
last if $watch;
|
||||
|
||||
say " xx RETRY: $i";
|
||||
sleep 1;
|
||||
}
|
||||
if ($watch) {
|
||||
$MONITORED_PLAYERS{$player} = $watch;
|
||||
} else {
|
||||
say "[ERR] Watch object is false for $player: $!"
|
||||
}
|
||||
}
|
||||
|
||||
sub unmonitor_player($) {
|
||||
my $player = shift;
|
||||
my $watch = $MONITORED_PLAYERS{$player};
|
||||
if (defined $watch) {
|
||||
say "-- MONITOR: $player";
|
||||
$watch->cancel;
|
||||
delete $MONITORED_PLAYERS{$player};
|
||||
}
|
||||
else {
|
||||
say "$player was not being monitored, ignoring unmonitor request"
|
||||
}
|
||||
}
|
||||
|
||||
sub inprogress_dirs() {
|
||||
my $inprog_glob = $DGLDIR;
|
||||
if (-d "$DGLDIR/inprogress") {
|
||||
$inprog_glob = "$DGLDIR/inprogress/*";
|
||||
}
|
||||
else {
|
||||
$inprog_glob = "$DGLDIR/inprogress*";
|
||||
}
|
||||
my @dirs = grep(-d, glob($inprog_glob));
|
||||
die "No inprogress dirs under $DGLDIR!\n" unless @dirs;
|
||||
@dirs
|
||||
}
|
||||
|
||||
sub monitor_active_player_where($) {
|
||||
my $inotify = shift;
|
||||
|
||||
my %monitorees;
|
||||
my @inprog_dirs = inprogress_dirs();
|
||||
for my $dir (@inprog_dirs) {
|
||||
my @ttyrecs = glob("$dir/*.ttyrec");
|
||||
|
||||
my $morgue_dir = inprog_morgue_dir($dir);
|
||||
for my $ttyrec (@ttyrecs) {
|
||||
my $player = inprog_player($ttyrec);
|
||||
write_dglwhere_file($player, $morgue_dir);
|
||||
monitor_player($inotify, $player, $morgue_dir);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sub monitor_inprogress_dirs($) {
|
||||
my $inotify = shift;
|
||||
my @inprog_dirs = inprogress_dirs();
|
||||
for my $inprog (@inprog_dirs) {
|
||||
$inotify->watch($inprog, IN_CREATE | IN_DELETE,
|
||||
sub {
|
||||
my $event = shift;
|
||||
inotify_inprogress_change($inprog, $event)
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
sub lock_or_exit {
|
||||
my ($exitcode, $lockf) = @_;
|
||||
$exitcode ||= 0;
|
||||
open LOCKFILE, '>', $lockf or die "Couldn't open $lockf: $!\n";
|
||||
flock(LOCKFILE, LOCK_EX | LOCK_NB)
|
||||
or do {
|
||||
warn "Cannot start: $lockf is held by another process\n";
|
||||
exit($exitcode);
|
||||
};
|
||||
}
|
||||
|
||||
sub daemonify {
|
||||
my $log = shift;
|
||||
defined(my $pid = fork) or die "Unable to fork: $!";
|
||||
exit if $pid;
|
||||
setsid or die "Unable to start a new session: $!";
|
||||
print "Started daemon.\n";
|
||||
|
||||
open STDOUT, '>', $log or die "Can't write $log: $!\n";
|
||||
open STDERR, '>&', \*STDOUT;
|
||||
# Done daemonifying.
|
||||
}
|
||||
|
||||
sub ps_list($) {
|
||||
my $process_name = shift;
|
||||
my @processes = map([split],
|
||||
qx/ps -ef | grep \Q$process_name\E | grep -v grep/);
|
||||
grep($_->[1] != $$, @processes);
|
||||
}
|
||||
|
||||
sub ps_pid($) {
|
||||
my $process_name = shift;
|
||||
my @processes = ps_list($process_name);
|
||||
return unless @processes == 1;
|
||||
return $processes[0][1];
|
||||
}
|
||||
|
||||
sub pid_describe($) {
|
||||
my $pid = shift;
|
||||
my @lines = qx/ps -f -p \Q$pid\E/;
|
||||
join('', @lines)
|
||||
}
|
||||
|
||||
sub supersede_existing_daemon() {
|
||||
my $name = $0;
|
||||
($name) = $name =~ m{.*/(.*)} if $name =~ m{/};
|
||||
my $existing_daemon_pid = ps_pid($name);
|
||||
if ($existing_daemon_pid) {
|
||||
print "Killing existing daemon ($existing_daemon_pid):\n",
|
||||
pid_describe($existing_daemon_pid);
|
||||
kill TERM => $existing_daemon_pid;
|
||||
sleep 1;
|
||||
}
|
||||
}
|
||||
|
||||
sub main() {
|
||||
assert_environment_exists();
|
||||
|
||||
supersede_existing_daemon();
|
||||
lock_or_exit(1, $LOCKFILE);
|
||||
daemonify($LOGFILE) if $DAEMON;
|
||||
|
||||
$inotify = Linux::Inotify2->new;
|
||||
monitor_active_player_where($inotify);
|
||||
monitor_inprogress_dirs($inotify);
|
||||
|
||||
say "Monitoring and updating where info";
|
||||
$inotify->poll while 1;
|
||||
warn "Exiting, WTF?\n";
|
||||
}
|
||||
|
||||
main();
|
|
@ -0,0 +1,19 @@
|
|||
#! /bin/bash
|
||||
|
||||
assert-chroot-exists
|
||||
cat-error <<EOF
|
||||
$SCRIPT_NAME: Monitors Crawl .where files and creates .dglwhere files for the
|
||||
dgamelaunch menu to display
|
||||
|
||||
EOF
|
||||
|
||||
if [[ "$UID" != "0" && "$USER" != "$DGL_USER" ]]; then
|
||||
abort-saying "This script must be run as root or $DGL_USER"
|
||||
fi
|
||||
|
||||
SUDO=
|
||||
|
||||
if [[ "$USER" != "$DGL_USER" ]]; then
|
||||
SUDO="sudo -u $DGL_USER"
|
||||
fi
|
||||
$SUDO perl $DGL_CONF_HOME/bin/crawl-inotify-dglwhere.pl $DGLDIR $MORGUEDIR "$@"
|
|
@ -0,0 +1,25 @@
|
|||
#! /bin/bash
|
||||
|
||||
source $DGL_CONF_HOME/crawl-git.conf
|
||||
|
||||
set -e
|
||||
GAME_DIR=$CRAWL_GAMEDIR
|
||||
echo "Crawl basedir to create: $GAME_DIR"
|
||||
|
||||
[[ -d "$GAME_DIR" ]] && abort-saying "Crawl base directory already exists"
|
||||
assert-chroot-exists
|
||||
[[ "$UID" != "0" ]] && abort-saying "This script must be run as root"
|
||||
|
||||
mkdir -p $DGL_CHROOT/cores
|
||||
|
||||
mkdir -p $GAME_DIR/saves/{sprint,zotdef}
|
||||
( cd $GAME_DIR/saves &&
|
||||
touch logfile{,-sprint,-zotdef} \
|
||||
milestones{,-sprint,-zotdef} \
|
||||
scores{,-sprint,-zotdef} )
|
||||
|
||||
# Only the saves dir is chowned games: data dir is not supposed to be
|
||||
# games writable.
|
||||
chown -R $CRAWL_UGRP $GAME_DIR/saves
|
||||
|
||||
echo "Created $GAME_DIR"
|
|
@ -0,0 +1,27 @@
|
|||
#! /bin/bash
|
||||
|
||||
source ./crawl-git.conf
|
||||
|
||||
if [[ -f "$VERSIONS_DB" ]]; then
|
||||
echo -e "Crawl version db $VERSIONS_DB already exists, aborting."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
set -e
|
||||
if [[ -f "$VERSIONS_DB" ]]; then
|
||||
abort-saying "Versions DB file $VERSIONS_DB already exists"
|
||||
fi
|
||||
|
||||
echo "Creating $VERSIONS_DB"
|
||||
if [[ "$UID" != "0" ]]; then
|
||||
echo -e "This script must be run as root"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
VERSIONS_DB_DIR="$(dirname $VERSIONS_DB)"
|
||||
if [[ ! -d "$VERSIONS_DB_DIR" ]]; then
|
||||
say "Version DB directory $VERSIONS_DB_DIR doesn't exist, creating it."
|
||||
mkdir -p "$VERSIONS_DB_DIR"
|
||||
fi
|
||||
|
||||
cat $CRAWL_BUILD_DIR/version-db-schema.sql | sqlite3 $VERSIONS_DB
|
|
@ -0,0 +1,108 @@
|
|||
#! /bin/bash
|
||||
#
|
||||
# General launcher script for dgamelaunch actions. The idea is to symlink
|
||||
# this (one) script into $HOME/bin and use it to run the others.
|
||||
|
||||
SELF="$0"
|
||||
SCRIPT_NAME=$(basename $0)
|
||||
|
||||
usage() {
|
||||
echo -e "Usage: $SCRIPT_NAME $@"
|
||||
}
|
||||
|
||||
cat-error() {
|
||||
cat >&2
|
||||
}
|
||||
|
||||
report-usage() {
|
||||
printf "Usage: $SCRIPT_NAME " >&2
|
||||
cat-error
|
||||
exit 1
|
||||
}
|
||||
|
||||
canonical-name() {
|
||||
local name=$1
|
||||
if [[ -d "$name" ]]; then
|
||||
printf "%s\n" "$(cd $name && echo $PWD)"
|
||||
else
|
||||
local dir=$(cd $(dirname $name) && echo $PWD)
|
||||
printf "%s\n" "$dir/$(basename $name)"
|
||||
fi
|
||||
}
|
||||
|
||||
test-set-dgl-home() {
|
||||
if [[ -n "$DGL_CONF_HOME" ]]; then
|
||||
return 0
|
||||
fi
|
||||
local dir=$1
|
||||
if [[ -d "$dir" && -d "$dir/bin" && -f "$dir/dgamelaunch.conf" \
|
||||
&& -d "$dir/chroot" ]]; then
|
||||
export DGL_CONF_HOME="$(canonical-name $dir)"
|
||||
export DGL_CONF_LOGS="$dir/logs"
|
||||
mkdir -p "$DGL_CONF_LOGS"
|
||||
fi
|
||||
}
|
||||
|
||||
find-dgl-home() {
|
||||
test-set-dgl-home "$HOME/conf-dgamelaunch"
|
||||
test-set-dgl-home "$(dirname $SELF)/.."
|
||||
|
||||
local link_target="$(readlink $0)"
|
||||
if [[ -n "$link_target" ]]; then
|
||||
test-set-dgl-home "$(dirname $(readlink $SELF))/.."
|
||||
fi
|
||||
|
||||
if [[ -z "$DGL_CONF_HOME" ]]; then
|
||||
echo -e "Cannot find dgamelaunch config base directory"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
resolve-action() {
|
||||
local action="$1"
|
||||
local script="$DGL_CONF_HOME/bin/$action.sh"
|
||||
if [[ ! -f "$script" ]]; then
|
||||
cat-error <<EOF
|
||||
Can't find dgamelaunch action '$action'
|
||||
|
||||
Available actions are:
|
||||
$(list-all-actions)
|
||||
|
||||
EOF
|
||||
exit 1
|
||||
fi
|
||||
echo "$script"
|
||||
}
|
||||
|
||||
find-dgl-home || exit 1
|
||||
|
||||
ACTION=$1
|
||||
shift
|
||||
|
||||
find-all-actions() {
|
||||
local -a actions
|
||||
actions=($DGL_CONF_HOME/bin/*.sh)
|
||||
actions=(${actions[@]%%.sh})
|
||||
actions=(${actions[@]##$DGL_CONF_HOME/bin/})
|
||||
echo "${actions[@]}"
|
||||
}
|
||||
|
||||
list-all-actions() {
|
||||
find-all-actions | fold -s
|
||||
}
|
||||
|
||||
if [[ -z "$ACTION" ]]; then
|
||||
usage "<action>"
|
||||
echo -e "Where <action> is one of:"
|
||||
list-all-actions >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
ACTION_SCRIPT="$(resolve-action $ACTION)"
|
||||
[[ -z "$ACTION_SCRIPT" ]] && exit 1
|
||||
|
||||
cd "$DGL_CONF_HOME"
|
||||
source ./sh-utils
|
||||
|
||||
SCRIPT_NAME="$SCRIPT_NAME $ACTION"
|
||||
source "$ACTION_SCRIPT"
|
|
@ -0,0 +1,24 @@
|
|||
#! /bin/bash
|
||||
|
||||
GIVE_HELP=1
|
||||
COMMAND="$1"
|
||||
|
||||
if [[ -z "$COMMAND" ]]; then
|
||||
help <<EOF
|
||||
Gives help on how to use a command.
|
||||
|
||||
Usage: $SCRIPT_NAME <command>
|
||||
|
||||
Where <command> is one of: $(list-all-actions)
|
||||
EOF
|
||||
fi
|
||||
|
||||
SCRIPT="$(resolve-action $COMMAND)"
|
||||
[[ -z "$SCRIPT" ]] && exit 1
|
||||
|
||||
HELPFILE="help/$COMMAND.txt"
|
||||
if [[ ! -f "$HELPFILE" ]]; then
|
||||
abort-saying "No help available for \"dgl $COMMAND\""
|
||||
fi
|
||||
|
||||
cat "$HELPFILE"
|
|
@ -0,0 +1,6 @@
|
|||
#!/bin/bash
|
||||
|
||||
assert-login-db-exists
|
||||
sqlite3 "$LOGIN_DB" <<EOF | sort -f
|
||||
SELECT username, email FROM dglusers ORDER BY username;
|
||||
EOF
|
|
@ -0,0 +1,94 @@
|
|||
#! /bin/bash
|
||||
|
||||
assert-login-db-exists
|
||||
|
||||
(( $# == 1 )) || \
|
||||
report-usage <<EOF
|
||||
<dgl-username / email address>
|
||||
|
||||
Gives a password hint for the given username, and (if run as root)
|
||||
prompts for a new password. You may ^C out at the new password
|
||||
prompt.
|
||||
EOF
|
||||
|
||||
password-hint() {
|
||||
local user=$1
|
||||
sqlite3 "$LOGIN_DB" <<EOF
|
||||
SELECT SUBSTR(password, 1, 2)
|
||||
FROM dglusers
|
||||
WHERE username='$user' OR email='$user';
|
||||
EOF
|
||||
}
|
||||
|
||||
count-users() {
|
||||
local user=$1
|
||||
sqlite3 "$LOGIN_DB" <<EOF
|
||||
SELECT COUNT(*)
|
||||
FROM dglusers
|
||||
WHERE username='$user' OR email='$user';
|
||||
EOF
|
||||
}
|
||||
|
||||
assert-password-safe() {
|
||||
local password="$1"
|
||||
if [[ "$password" =~ \' ]]; then
|
||||
echo -e "Sorry, I can't handle passwords containing '"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
change-password() {
|
||||
local user="$1"
|
||||
local password_clear="$2"
|
||||
|
||||
assert-password-safe "$password_clear"
|
||||
local password_crypt="$(perl -le 'print crypt($ARGV[0], substr($ARGV[0], 0, 2))' "$password_clear")"
|
||||
sqlite3 "$LOGIN_DB" <<EOF
|
||||
UPDATE dglusers
|
||||
SET password='$password_crypt'
|
||||
WHERE username='$user' OR email='$user';
|
||||
EOF
|
||||
}
|
||||
|
||||
assert-sane-user-match() {
|
||||
local user=$1
|
||||
local count=$(count-users $user)
|
||||
if (( $count != 1 )); then
|
||||
if (( $count == 0 )); then
|
||||
abort-saying "Can't find user matching '$user'"
|
||||
else
|
||||
abort-saying "Too many user matches for '$user'"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
USER=$1
|
||||
assert-sane-user-match "$USER"
|
||||
|
||||
echo "Password hint for $USER: '$(password-hint $USER)'"
|
||||
|
||||
if [[ "$UID" == "0" ]]; then
|
||||
echo
|
||||
read -s -p "Enter new password for $USER: " PASSWORD
|
||||
echo
|
||||
if [[ -z "$PASSWORD" ]]; then
|
||||
abort-saying "Empty password"
|
||||
fi
|
||||
read -s -p "Retype password for $USER: " CONFIRM_PASSWORD
|
||||
echo
|
||||
|
||||
if [[ "$PASSWORD" != "$CONFIRM_PASSWORD" ]]; then
|
||||
abort-saying "Passwords do not match"
|
||||
fi
|
||||
|
||||
change-password "$USER" "$PASSWORD"
|
||||
echo "Updated password for $USER"
|
||||
else
|
||||
cat <<EOF
|
||||
|
||||
If you'd like to change the password for $USER, rerun this command as root:
|
||||
|
||||
$SCRIPT_NAME $@
|
||||
|
||||
EOF
|
||||
fi
|
|
@ -0,0 +1,8 @@
|
|||
#! /bin/bash
|
||||
#
|
||||
# Publish only the dgamelaunch config file.
|
||||
#
|
||||
|
||||
assert-chroot-exists
|
||||
set -- "--confirm" "--match" "dgamelaunch.conf" "$@"
|
||||
source $DGL_CONF_HOME/bin/publish.sh
|
|
@ -0,0 +1,8 @@
|
|||
#! /bin/bash
|
||||
#
|
||||
# Publish everything other than the dgamelaunch.conf file.
|
||||
#
|
||||
|
||||
assert-chroot-exists
|
||||
set -- "--confirm" "--skip" "dgamelaunch.conf" "$@"
|
||||
source $DGL_CONF_HOME/bin/publish.sh
|
|
@ -0,0 +1,302 @@
|
|||
#! /usr/bin/env perl
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use File::Copy;
|
||||
use File::Path;
|
||||
use Cwd qw/abs_path/;
|
||||
use Term::ANSIColor;
|
||||
use Getopt::Long;
|
||||
|
||||
use lib "$ENV{DGL_CONF_HOME}/lib";
|
||||
use DGLMan;
|
||||
|
||||
my %OPT;
|
||||
GetOptions(\%OPT, "match=s", "skip=s", "confirm", "target=s")
|
||||
or die "Bad command line: @ARGV\n";
|
||||
|
||||
my $CHROOT = $ENV{DGL_CHROOT};
|
||||
die "DGL chroot not specified in environment\n" unless $CHROOT;
|
||||
|
||||
my @COPY_TARGETS = ([ 'dgamelaunch.conf', '//etc' ],
|
||||
[ 'utils/auth-save-downloader.pl', '//usr/lib/cgi-bin' ],
|
||||
[ 'utils/trigger-rebuild.pl', '//usr/lib/cgi-bin' ],
|
||||
[ 'utils/webtiles', '//etc/init.d' ],
|
||||
[ 'config.py', "/crawl-master/webserver" ],
|
||||
[ 'chroot/data/menus/*.txt', "/dgldir/data/menus" ],
|
||||
[ 'chroot/data/*.{rc,macro}', "/dgldir/data" ],
|
||||
[ 'chroot/bin/*.sh', '/bin' ],
|
||||
[ 'chroot/sbin/*.sh', '/sbin' ]);
|
||||
|
||||
if ($OPT{match}) {
|
||||
@COPY_TARGETS = grep($$_[0] =~ /\Q$OPT{match}/, @COPY_TARGETS);
|
||||
}
|
||||
if ($OPT{skip}) {
|
||||
@COPY_TARGETS = grep($$_[0] !~ /\Q$OPT{skip}/, @COPY_TARGETS);
|
||||
}
|
||||
if ($OPT{target}) {
|
||||
die "--target specified, but more than one file to publish\n"
|
||||
if @COPY_TARGETS > 1;
|
||||
$COPY_TARGETS[0][1] = $OPT{target};
|
||||
}
|
||||
|
||||
sub change_stat($@) {
|
||||
my ($dst, @src) = @_;
|
||||
|
||||
my $changed = 0;
|
||||
my @changed;
|
||||
|
||||
my $new = 0;
|
||||
my @new;
|
||||
|
||||
for my $file (@src) {
|
||||
my $target = target_file($dst, $file);
|
||||
if (-l $target) {
|
||||
return "ERR: $target is a symlink";
|
||||
}
|
||||
|
||||
my $src_text = source_file_text($file);
|
||||
|
||||
if (-f $target) {
|
||||
my $dst_text = file_text($target);
|
||||
if ($src_text ne $dst_text) {
|
||||
++$changed;
|
||||
push @changed, basename($target);
|
||||
}
|
||||
} else {
|
||||
++$new;
|
||||
push @new, basename($file);
|
||||
}
|
||||
}
|
||||
|
||||
return { new => \@new,
|
||||
changed => \@changed };
|
||||
}
|
||||
|
||||
sub change_exists($) {
|
||||
my $stat = shift;
|
||||
return @{$$stat{new}} || @{$$stat{changed}};
|
||||
}
|
||||
|
||||
sub change_summary($) {
|
||||
my $stat = shift;
|
||||
my @report;
|
||||
my @new = @{$$stat{new}};
|
||||
my @changed = @{$$stat{changed}};
|
||||
my $new = scalar(@new);
|
||||
my $changed = scalar(@changed);
|
||||
push @report, neutral_text("$new new: @new") if @new;
|
||||
push @report, neutral_text("$changed changed: @changed") if @changed;
|
||||
@report? join(', ', @report) : 'no change'
|
||||
}
|
||||
|
||||
sub publishee_summary($) {
|
||||
my ($src, $dst) = @{$_[0]};
|
||||
|
||||
my @files = glob($src);
|
||||
$dst = qualify_directory($dst);
|
||||
|
||||
my $change_stat = change_stat($dst, @files);
|
||||
if (@files == 1 && $files[0] eq $src) {
|
||||
("$src -> $dst (" . change_summary($change_stat) . ")",
|
||||
$change_stat)
|
||||
} else {
|
||||
("$src (" . scalar(@files) . " files) -> $dst (" .
|
||||
change_summary($change_stat) . ")",
|
||||
$change_stat)
|
||||
}
|
||||
}
|
||||
|
||||
sub summarize_publishees() {
|
||||
my $index = 0;
|
||||
print "These are the publish copy targets:\n";
|
||||
my $dirty;
|
||||
for my $copy_target (@COPY_TARGETS) {
|
||||
++$index;
|
||||
my ($summary, $stat) = publishee_summary($copy_target);
|
||||
print("$index) $summary\n");
|
||||
$dirty = 1 if change_exists($stat);
|
||||
}
|
||||
$dirty
|
||||
}
|
||||
|
||||
my $copy_count = 0;
|
||||
sub nth_copy() {
|
||||
++$copy_count . ") ";
|
||||
}
|
||||
|
||||
sub qualify_directory($) {
|
||||
my $dir = shift;
|
||||
if ($dir =~ m{^//}) {
|
||||
$dir =~ s{^/}{};
|
||||
$dir
|
||||
} else {
|
||||
"$CHROOT$dir"
|
||||
}
|
||||
}
|
||||
|
||||
sub substitute_variable($$) {
|
||||
my ($file, $var) = @_;
|
||||
die "$file refers to unknown variable $var.\n" unless $ENV{$var};
|
||||
$ENV{$var}
|
||||
}
|
||||
|
||||
sub file_needs_banner($) {
|
||||
my $filename = shift;
|
||||
$filename =~ /(?:dgamelaunch\.conf|\.sh|\.pl)$/
|
||||
}
|
||||
|
||||
sub file_banner($) {
|
||||
my $filename = shift;
|
||||
my $basename = basename($filename);
|
||||
|
||||
my $source_file = abs_path($filename);
|
||||
|
||||
return <<BANNER;
|
||||
#############################################################################
|
||||
#
|
||||
# WARNING! AUTO-GENERATED FILE, DO NOT EDIT.
|
||||
#
|
||||
# This file ($basename) is automatically generated from $source_file.
|
||||
#
|
||||
# Do NOT edit this file; edit $source_file instead, and
|
||||
# use `dgl publish` to publish your changes.
|
||||
#
|
||||
#############################################################################
|
||||
BANNER
|
||||
}
|
||||
|
||||
sub file_add_banner($$) {
|
||||
my ($filename, $text) = @_;
|
||||
if ($text =~ /^#!.*\n/) {
|
||||
$text =~ s/(^#!.*\n)/$1 . file_banner($filename)/e;
|
||||
} else {
|
||||
$text =~ s/^/file_banner($filename)/e;
|
||||
}
|
||||
$text
|
||||
}
|
||||
|
||||
sub substitute_variables($$) {
|
||||
my ($filename, $text) = @_;
|
||||
|
||||
$text = file_add_banner($filename, $text) if file_needs_banner($filename);
|
||||
$text =~ s/%%(\w+)%%/ substitute_variable($filename, $1) /ge;
|
||||
$text
|
||||
}
|
||||
|
||||
sub basename($) {
|
||||
my $file = shift;
|
||||
my ($basename) = $file =~ m{.*/(.*)};
|
||||
$basename || $file
|
||||
}
|
||||
|
||||
sub target_file($$) {
|
||||
my ($dst, $src) = @_;
|
||||
my $basename = basename($src);
|
||||
"$dst/$basename"
|
||||
}
|
||||
|
||||
sub file_text($) {
|
||||
my $source_file = shift;
|
||||
|
||||
open my $inf, '<', $source_file or die "Can't read $source_file: $!\n";
|
||||
binmode $inf;
|
||||
my $text = do { local $/; <$inf> };
|
||||
close $inf;
|
||||
|
||||
$text
|
||||
}
|
||||
|
||||
sub source_file_text($) {
|
||||
my $source_file = shift;
|
||||
substitute_variables($source_file, file_text($source_file))
|
||||
}
|
||||
|
||||
sub copy_file($$) {
|
||||
my ($source_file, $dst) = @_;
|
||||
my $target_file = target_file($dst, $source_file);
|
||||
|
||||
if (-l $target_file) {
|
||||
die "Can't copy $source_file -> $target_file: destination is a symlink\n";
|
||||
}
|
||||
|
||||
my $text = source_file_text($source_file);
|
||||
|
||||
my $target_tmp = "$target_file.tmp";
|
||||
open my $outf, '>', $target_tmp or die "Can't write $target_tmp: $!\n";
|
||||
print $outf $text;
|
||||
close $outf;
|
||||
|
||||
if (-x $source_file) {
|
||||
chmod 0755, $target_tmp or
|
||||
die "Couldn't +x $target_tmp when copying $source_file -> $dst" ;
|
||||
}
|
||||
|
||||
rename $target_tmp, $target_file or
|
||||
die "Couldn't copy $source_file -> $target_file\n";
|
||||
}
|
||||
|
||||
sub copy_files($$) {
|
||||
my ($src, $dst) = @_;
|
||||
my @files = glob($src);
|
||||
if (!@files) {
|
||||
die "Can't find files to copy for $src\n";
|
||||
}
|
||||
$dst = qualify_directory($dst);
|
||||
if (!-d($dst)) {
|
||||
mkpath($dst) or die "Couldn't create $dst\n";
|
||||
}
|
||||
|
||||
my @quoted_files = map("\Q$_", @files);
|
||||
print(nth_copy() . "@files -> $dst ");
|
||||
|
||||
eval {
|
||||
for my $file (@files) {
|
||||
copy_file($file, $dst) or
|
||||
die "Failed to copy $file -> $dst: $!\n";
|
||||
}
|
||||
say_good(" [OK]\n");
|
||||
};
|
||||
if ($@) {
|
||||
say_bad(" [ERR]\n\n");
|
||||
die $@;
|
||||
}
|
||||
}
|
||||
|
||||
sub copy_targets(@) {
|
||||
print "Copying files:\n";
|
||||
for my $copy_target (@_) {
|
||||
copy_files($copy_target->[0], $copy_target->[1]);
|
||||
}
|
||||
}
|
||||
|
||||
print "Publishing DGL config files:\n\n";
|
||||
my $dirty = summarize_publishees();
|
||||
print "\n";
|
||||
|
||||
my $want_publish = $OPT{confirm};
|
||||
if (!$want_publish) {
|
||||
if ($dirty) {
|
||||
warn <<PUBLISH_HOWTO;
|
||||
To publish the new dgl config, run this command as root:
|
||||
|
||||
@{ [ emphasized_text('dgl publish --confirm') ] }
|
||||
|
||||
PUBLISH_HOWTO
|
||||
}
|
||||
else {
|
||||
say_coloured('bold green', <<INSYNC);
|
||||
DGL config is in sync.
|
||||
INSYNC
|
||||
}
|
||||
exit 0;
|
||||
}
|
||||
|
||||
if ($< != 0) {
|
||||
print STDERR "** This script must be run as root to publish changes **\n";
|
||||
exit 1;
|
||||
}
|
||||
|
||||
copy_targets(@COPY_TARGETS);
|
||||
print "\nAll done.\n";
|
|
@ -0,0 +1,7 @@
|
|||
#! /bin/bash
|
||||
|
||||
assert-chroot-exists
|
||||
|
||||
source $DGL_CONF_HOME/crawl-git.conf
|
||||
export DGL_CONF_HOME DGL_CHROOT
|
||||
exec perl $DGL_CONF_HOME/bin/publish.pl "$@"
|
|
@ -0,0 +1,4 @@
|
|||
#!/bin/bash
|
||||
|
||||
sudo -H $DGL_CHROOT/sbin/remove-trunks.sh $*
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
#!/bin/bash
|
||||
|
||||
set -u
|
||||
|
||||
source $DGL_CONF_HOME/crawl-git.conf
|
||||
|
||||
LATEST_GAME_HASH="$(latest-game-hash)"
|
||||
PREFIX="$DGL_CHROOT/$CRAWL_GIT_DIR"
|
||||
|
||||
SAVEBASE="${PREFIX}/${BINARY_BASE_NAME}-*/saves"
|
||||
ALL_CHARS="$(ls -1rt $SAVEBASE/*-${DGL_UID}.sav \
|
||||
$SAVEBASE/*-${DGL_UID}.chr \
|
||||
$SAVEBASE/*.cs \
|
||||
$SAVEBASE/sprint/*-${DGL_UID}.chr \
|
||||
$SAVEBASE/sprint/*.cs \
|
||||
$SAVEBASE/zotdef/*.cs 2>/dev/null | \
|
||||
grep -v $LATEST_GAME_HASH | \
|
||||
sed "s|${PREFIX}/${BINARY_BASE_NAME}-.*/saves/\(.*\)\..*|\1|;s|-${DGL_UID}||" | \
|
||||
sort -f)"
|
||||
|
||||
echo "Trying to transfer these chars to a newer version:"
|
||||
echo ${ALL_CHARS}
|
||||
echo
|
||||
|
||||
echo "-- Press RETURN to start transfer --"
|
||||
read
|
||||
|
||||
for char in ${ALL_CHARS}
|
||||
do
|
||||
dgl savegame-transfer ${char}
|
||||
done
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
#!/bin/bash
|
||||
|
||||
sudo -H $DGL_CHROOT/sbin/savegame-transfer.sh $*
|
|
@ -0,0 +1,44 @@
|
|||
#! /bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
DGAMELAUNCH="$1"
|
||||
|
||||
valid-dgl() {
|
||||
[[ -n "$DGAMELAUNCH" && -x "$DGAMELAUNCH" ]]
|
||||
}
|
||||
|
||||
valid-dgl || DGAMELAUNCH="$(which dgamelaunch 2>/dev/null || true)"
|
||||
valid-dgl || DGAMELAUNCH=/usr/local/sbin/dgamelaunch
|
||||
valid-dgl || abort-saying "Cannot find dgamelaunch binary"
|
||||
|
||||
STRACE_OUT=strace.out
|
||||
|
||||
if not-running-as-root; then
|
||||
cat-error <<EOF
|
||||
$SCRIPT_NAME: runs dgamelaunch with the current (testing) configuration
|
||||
|
||||
Run this command as root to test your dgamelaunch.conf
|
||||
|
||||
Options:
|
||||
--strace: Run dgamelaunch with strace and dump strace output to $STRACE_OUT
|
||||
|
||||
EOF
|
||||
exit 1
|
||||
fi
|
||||
|
||||
[[ "$1" == "--strace" ]] && STRACE=1 || STRACE=
|
||||
|
||||
TEST_FILE=dgamelaunch.conf
|
||||
TMP_DIR=.tmp
|
||||
|
||||
trap "rm $TMP_DIR/$TEST_FILE && rmdir $TMP_DIR" EXIT
|
||||
|
||||
mkdir -p $TMP_DIR
|
||||
dgl-run publish-conf --target /$PWD/$TMP_DIR
|
||||
|
||||
if [[ -z "$STRACE" ]]; then
|
||||
"$DGAMELAUNCH" -f "$TMP_DIR/$TEST_FILE"
|
||||
else
|
||||
strace -f "$DGAMELAUNCH" -f "$TMP_DIR/$TEST_FILE" 2>$STRACE_OUT
|
||||
fi
|
|
@ -0,0 +1,4 @@
|
|||
#!/bin/bash
|
||||
|
||||
cd $DGL_CONF_HOME/crawl-build
|
||||
source ./update-crawl-stable-build.sh
|
|
@ -0,0 +1,4 @@
|
|||
#!/bin/bash
|
||||
|
||||
cd $DGL_CONF_HOME/crawl-build
|
||||
source ./update-crawl-trunk-build.sh
|
|
@ -0,0 +1,304 @@
|
|||
#! /bin/bash
|
||||
#
|
||||
# Must be called as crawl-git -name <playername> [...]; character name
|
||||
# must always be the second argument.
|
||||
#
|
||||
# ===========================================================================
|
||||
# Copyright (C) 2008, 2009, 2010, 2011 Marc H. Thoben
|
||||
# Copyright (C) 2011 Darshan Shaligram
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
# ===========================================================================
|
||||
#
|
||||
|
||||
# The webtiles binary requires a UTF-8 locale.
|
||||
export LC_ALL=en_US.UTF-8
|
||||
|
||||
set -o nounset
|
||||
|
||||
CRAWL_GIT_DIR="%%CHROOT_CRAWL_BASEDIR%%"
|
||||
USER_DB="%%CHROOT_LOGIN_DB%%"
|
||||
CRAWL_BINARY_PATH="%%CHROOT_CRAWL_BINARY_PATH%%"
|
||||
BINARY_BASE_NAME="%%GAME%%"
|
||||
USER_ID="%%DGL_UID%%"
|
||||
VERSIONS_DB="%%CHROOT_VERSIONS_DB%%"
|
||||
|
||||
export HOME="%%CHROOT_COREDIR%%"
|
||||
|
||||
# Word boundary regex; bash's =~ is funny about that.
|
||||
wb='\b'
|
||||
|
||||
JUST_RUN_CRAWL_ALREADY=
|
||||
# If set, this script will not event report the existence of newer versions.
|
||||
[[ "$@" =~ -print-charset$wb ]] && JUST_RUN_CRAWL_ALREADY=1
|
||||
[[ "$@" =~ -print-webtiles-options$wb ]] && JUST_RUN_CRAWL_ALREADY=1
|
||||
|
||||
WEBTILES=
|
||||
[[ "$@" =~ -await-connection$wb ]] && WEBTILES=1
|
||||
|
||||
cecho() {
|
||||
[[ -z "$WEBTILES" ]] && echo "$@"
|
||||
}
|
||||
wecho() {
|
||||
[[ -n "$WEBTILES" ]] && echo "$@"
|
||||
}
|
||||
wcat() {
|
||||
if [[ -n "$WEBTILES" ]]; then
|
||||
tr '\n' ' ' | sed -e 's/ $//'
|
||||
echo
|
||||
else
|
||||
cat >/dev/null
|
||||
fi
|
||||
}
|
||||
|
||||
TRANSFER_ENABLED="1"
|
||||
CHAR_NAME="$2"
|
||||
|
||||
NICE=""
|
||||
[[ $CHAR_NAME = notqw ]] && NICE="nice -n 10 ionice -c 3"
|
||||
|
||||
# Clear screen
|
||||
[[ -z "$JUST_RUN_CRAWL_ALREADY" && -z "$WEBTILES" ]] && printf "\e[2J\e[H"
|
||||
|
||||
export LANG="en_US.UTF-8"
|
||||
export LC_CTYPE="en_US.UTF-8"
|
||||
|
||||
SAVES="saves"
|
||||
|
||||
[[ "$@" =~ -sprint$wb ]] && SAVES="$SAVES/sprint"
|
||||
[[ "$@" =~ -zotdef$wb ]] && SAVES="$SAVES/zotdef"
|
||||
|
||||
if [[ $# == 0 || -z "$CHAR_NAME" ]]; then
|
||||
if [[ -z "$JUST_RUN_CRAWL_ALREADY" ]]; then
|
||||
echo "Parameters missing. Aborting..."
|
||||
read -n 1 -s -p "--- any key to continue ---"
|
||||
echo
|
||||
fi
|
||||
exit 1
|
||||
fi
|
||||
|
||||
ulimit -S -c 1536000 2>/dev/null
|
||||
ulimit -S -v 1024000 2>/dev/null
|
||||
|
||||
first-real-file() {
|
||||
for file in "$@"; do
|
||||
if [[ -f "$file" ]]; then
|
||||
printf "%s\n" "$file"
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
query() {
|
||||
sqlite3 "$VERSIONS_DB"
|
||||
}
|
||||
|
||||
hash-description() {
|
||||
local hash=$1
|
||||
query <<EOF
|
||||
SELECT description FROM versions WHERE hash='$hash' LIMIT 1;
|
||||
EOF
|
||||
}
|
||||
|
||||
latest-game-hash() {
|
||||
query <<EOF
|
||||
SELECT hash FROM versions ORDER BY time DESC LIMIT 1;
|
||||
EOF
|
||||
}
|
||||
|
||||
major-version-for-game() {
|
||||
local game=$1
|
||||
query <<EOF
|
||||
SELECT major FROM versions WHERE hash='$game' LIMIT 1;
|
||||
EOF
|
||||
}
|
||||
|
||||
newest-version-with-major-version() {
|
||||
local major_version=$1
|
||||
query <<EOF
|
||||
SELECT hash FROM versions WHERE major=$major_version
|
||||
ORDER BY time DESC
|
||||
LIMIT 1;
|
||||
EOF
|
||||
}
|
||||
|
||||
user-is-admin() {
|
||||
local found="$(echo "SELECT username FROM dglusers
|
||||
WHERE username='$CHAR_NAME' AND (flags & 1) = 1;" |
|
||||
sqlite3 "$USER_DB")"
|
||||
[[ -n "$found" ]]
|
||||
}
|
||||
|
||||
transfer-save() {
|
||||
local save=$1
|
||||
local game_hash=$2
|
||||
local target="$CRAWL_GIT_DIR/$BINARY_BASE_NAME-$game_hash/$SAVES"
|
||||
local src_save_dir=$(dirname $save)
|
||||
|
||||
wecho -n '{"msg":"show_dialog", "html":"'
|
||||
|
||||
if [[ -d "$target" ]]; then
|
||||
# It's okay if moving the .prf fails (it might not exist one day).
|
||||
mv "$src_save_dir/start-$CHAR_NAME-ns.prf" "$target" 2>/dev/null || true
|
||||
mv "$src_save_dir/$CHAR_NAME".cs "$target"
|
||||
|
||||
if test $? -eq 0
|
||||
then
|
||||
wcat <<EOF
|
||||
<p>Transferring successful!</p>
|
||||
<input type='button' class='button' data-key=' ' value='Continue' style='float:right;'>
|
||||
"}
|
||||
EOF
|
||||
cecho ": successful!"
|
||||
cecho
|
||||
OUR_GAME_HASH="${game_hash}"
|
||||
cecho -n "--- any key to continue ---"
|
||||
read -n 1 -t 5 -s
|
||||
cecho
|
||||
else
|
||||
wcat <<EOF
|
||||
<p>Transferring failed!</p>
|
||||
<p>Transferring your save failed! Continuing with former version.</p>
|
||||
<input type='button' class='button' data-key=' ' value='Continue' style='float:right;'>
|
||||
"}
|
||||
EOF
|
||||
cecho ": failed!"
|
||||
cecho
|
||||
cecho "Transferring your save failed! Continuing with former version."
|
||||
cecho -n "--- any key to continue ---"
|
||||
read -n 1 -s
|
||||
cecho
|
||||
fi
|
||||
else
|
||||
wcat <<EOF
|
||||
<p>Transferring failed!</p>
|
||||
<p>Target version is corrupt! Continuing with former version.</p>
|
||||
<input type='button' class='button' data-key=' ' value='Continue' style='float:right;'>
|
||||
"}
|
||||
EOF
|
||||
cecho ": failed!"
|
||||
cecho
|
||||
cecho "Target version is corrupt! Continuing with former version."
|
||||
cecho -n "--- any key to continue ---"
|
||||
read -n 1 -s
|
||||
cecho
|
||||
fi
|
||||
wecho '{"msg":"hide_dialog"}'
|
||||
}
|
||||
|
||||
SAVEGLOB="$CRAWL_GIT_DIR/$BINARY_BASE_NAME-*/$SAVES"
|
||||
|
||||
declare -a SAVE_CANDIDATES
|
||||
SAVE_CANDIDATES=($SAVEGLOB/$CHAR_NAME.cs \
|
||||
$SAVEGLOB/$CHAR_NAME-$USER_ID.sav \
|
||||
$SAVEGLOB/$CHAR_NAME-$USER_ID.chr)
|
||||
|
||||
SAVE="$(first-real-file "${SAVE_CANDIDATES[@]}")"
|
||||
LATEST_GAME_HASH="$(latest-game-hash)"
|
||||
|
||||
if [[ -n "$SAVE" ]]; then
|
||||
OUR_GAME_HASH=${SAVE#$CRAWL_GIT_DIR/$BINARY_BASE_NAME-}
|
||||
OUR_GAME_HASH=${OUR_GAME_HASH%%/*}
|
||||
|
||||
if [[ -z "$JUST_RUN_CRAWL_ALREADY" && \
|
||||
"$OUR_GAME_HASH" != "$LATEST_GAME_HASH" ]]
|
||||
then
|
||||
current_ver="$(hash-description $OUR_GAME_HASH)"
|
||||
cecho "Hi, you have a $current_ver save game:"
|
||||
cecho
|
||||
|
||||
OUR_SGV_MAJOR="$(major-version-for-game $OUR_GAME_HASH)"
|
||||
NEW_GAME_HASH="$(newest-version-with-major-version $OUR_SGV_MAJOR)"
|
||||
new_ver="$(hash-description $NEW_GAME_HASH)"
|
||||
|
||||
if [[ "$OUR_GAME_HASH" != "$NEW_GAME_HASH" &&
|
||||
"$TRANSFER_ENABLED" == "1" ]]; then
|
||||
wecho '{"msg":"layer", "layer":"crt"}'
|
||||
wecho -n '{"msg":"show_dialog", "html":"'
|
||||
|
||||
if [[ "${NEW_GAME_HASH}" != "${LATEST_GAME_HASH}" ]]; then
|
||||
cecho "There's a newer version ($new_ver) that can load your save."
|
||||
cecho -n "[T]ransfer your save to this version?"
|
||||
wcat <<EOF
|
||||
<p>There's a newer version ($new_ver) that can load your save.</p>
|
||||
<p>[T]ransfer your save to this version?</p>
|
||||
<input type='button' class='button' data-key='N' value='No' style='float:right;'>
|
||||
<input type='button' class='button' data-key='T' value='Yes' style='float:right;'>
|
||||
"}
|
||||
EOF
|
||||
read -n 1 -s REPLY
|
||||
cecho
|
||||
else
|
||||
cecho -n "[T]ransfer your save to the latest version ($new_ver)?"
|
||||
wcat <<EOF
|
||||
<p>[T]ransfer your save to the latest version ($new_ver)?</p>
|
||||
<input type='button' class='button' data-key='N' value='No' style='float:right;'>
|
||||
<input type='button' class='button' data-key='T' value='Yes' style='float:right;'>
|
||||
"}
|
||||
EOF
|
||||
read -n 1 -s REPLY
|
||||
cecho
|
||||
fi
|
||||
wecho '{"msg":"hide_dialog"}'
|
||||
|
||||
if test "$REPLY" = "t" -o "$REPLY" = "T" -o "$REPLY" = "y" -o "$REPLY" = "Y"
|
||||
then
|
||||
cecho -n "Transferring..."
|
||||
transfer-save "$SAVE" "$NEW_GAME_HASH"
|
||||
fi
|
||||
else
|
||||
if test "${TRANSFER_ENABLED}" != "1"
|
||||
then
|
||||
cecho "Transfering of saves is currently disabled."
|
||||
cecho "Finish your game or end your character to play in latest version."
|
||||
else
|
||||
cecho "Your save cannot be tranferred though because of incompatibility."
|
||||
cecho "Finish your game or end your character to play in latest version."
|
||||
fi
|
||||
|
||||
cecho -n "--- any key to continue ---"
|
||||
[[ -z "$WEBTILES" ]] && read -n 1 -t 5 -s
|
||||
cecho
|
||||
fi
|
||||
fi
|
||||
else
|
||||
OUR_GAME_HASH="${LATEST_GAME_HASH}"
|
||||
fi
|
||||
|
||||
if test ${#OUR_GAME_HASH} -eq 0
|
||||
then
|
||||
cecho "Could not figure out the right game version. Aborting..."
|
||||
cecho -n "--- any key to continue ---"
|
||||
[[ -z "$WEBTILES" ]] && read -n 1 -s -p
|
||||
cecho
|
||||
exit 1
|
||||
fi
|
||||
|
||||
BINARY_NAME="$CRAWL_BINARY_PATH/$BINARY_BASE_NAME-$OUR_GAME_HASH"
|
||||
GAME_FOLDER="$CRAWL_GIT_DIR/$BINARY_BASE_NAME-$OUR_GAME_HASH"
|
||||
|
||||
if user-is-admin; then
|
||||
set -- "$@" -wizard
|
||||
fi
|
||||
|
||||
if test -x "${BINARY_NAME}" -a -d "${GAME_FOLDER}"
|
||||
then
|
||||
cd ${HOME}
|
||||
exec ${NICE} ${BINARY_NAME} "$@"
|
||||
fi
|
||||
|
||||
cecho "Failed starting: ${BINARY_NAME} not found!"
|
||||
read -n 1 -s -p "--- any key to continue ---"
|
||||
cecho
|
||||
exit 1
|
|
@ -0,0 +1,115 @@
|
|||
#! /bin/bash
|
||||
#
|
||||
# Must be called as crawl-git -name <playername> [...]; character name
|
||||
# must always be the second argument.
|
||||
#
|
||||
# ===========================================================================
|
||||
# Copyright (C) 2008, 2009, 2010, 2011 Marc H. Thoben
|
||||
# Copyright (C) 2011 Darshan Shaligram
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
# ===========================================================================
|
||||
#
|
||||
|
||||
# The webtiles binary requires a UTF-8 locale.
|
||||
export LC_ALL=en_US.UTF-8
|
||||
|
||||
set -o nounset
|
||||
|
||||
VERSION=$1
|
||||
shift
|
||||
|
||||
CRAWL_GIT_DIR="%%CHROOT_CRAWL_BASEDIR%%"
|
||||
USER_DB="%%CHROOT_LOGIN_DB%%"
|
||||
CRAWL_BINARY_PATH="%%CHROOT_CRAWL_BINARY_PATH%%"
|
||||
BINARY_BASE_NAME="crawl-$VERSION"
|
||||
USER_ID="%%DGL_UID%%"
|
||||
|
||||
export HOME="%%CHROOT_COREDIR%%"
|
||||
|
||||
# Word boundary regex; bash's =~ is funny about that.
|
||||
wb='\b'
|
||||
|
||||
JUST_RUN_CRAWL_ALREADY=
|
||||
# If set, this script will not event report the existence of newer versions.
|
||||
[[ "$@" =~ -print-charset$wb ]] && JUST_RUN_CRAWL_ALREADY=1
|
||||
[[ "$@" =~ -print-webtiles-options$wb ]] && JUST_RUN_CRAWL_ALREADY=1
|
||||
|
||||
WEBTILES=
|
||||
[[ "$@" =~ -await-connection$wb ]] && WEBTILES=1
|
||||
|
||||
cecho() {
|
||||
[[ -z "$WEBTILES" ]] && echo "$@"
|
||||
}
|
||||
wecho() {
|
||||
[[ -n "$WEBTILES" ]] && echo "$@"
|
||||
}
|
||||
|
||||
TRANSFER_ENABLED="1"
|
||||
CHAR_NAME="$2"
|
||||
|
||||
NICE=""
|
||||
[[ $CHAR_NAME = notqw ]] && NICE="nice -n 10 ionice -c 3"
|
||||
|
||||
# Clear screen
|
||||
[[ -z "$JUST_RUN_CRAWL_ALREADY" && -z "$WEBTILES" ]] && printf "\e[2J\e[H"
|
||||
|
||||
export LANG="en_US.UTF-8"
|
||||
export LC_CTYPE="en_US.UTF-8"
|
||||
|
||||
if [[ $# == 0 || -z "$CHAR_NAME" ]]; then
|
||||
if [[ -z "$JUST_RUN_CRAWL_ALREADY" ]]; then
|
||||
echo "Parameters missing. Aborting..."
|
||||
read -n 1 -s -p "--- any key to continue ---"
|
||||
echo
|
||||
fi;
|
||||
exit 1
|
||||
fi
|
||||
|
||||
ulimit -S -c 1536000 2>/dev/null
|
||||
ulimit -S -v 1024000 2>/dev/null
|
||||
|
||||
first-real-file() {
|
||||
for file in "$@"; do
|
||||
if [[ -f "$file" ]]; then
|
||||
printf "%s\n" "$file"
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
user-is-admin() {
|
||||
local found="$(echo "SELECT username FROM dglusers
|
||||
WHERE username='$CHAR_NAME' AND (flags & 1) = 1;" |
|
||||
sqlite3 "$USER_DB")"
|
||||
[[ -n "$found" ]]
|
||||
}
|
||||
|
||||
BINARY_NAME="$CRAWL_BINARY_PATH/$BINARY_BASE_NAME"
|
||||
GAME_FOLDER="$CRAWL_GIT_DIR/$BINARY_BASE_NAME"
|
||||
|
||||
if user-is-admin; then
|
||||
set -- "$@" -wizard
|
||||
fi
|
||||
|
||||
if test -x "${BINARY_NAME}" -a -d "${GAME_FOLDER}"
|
||||
then
|
||||
cd ${HOME}
|
||||
exec ${NICE} ${BINARY_NAME} "$@"
|
||||
fi
|
||||
|
||||
cecho "Failed starting: ${BINARY_NAME} not found!"
|
||||
read -n 1 -s -p "--- any key to continue ---"
|
||||
cecho
|
||||
exit 1
|
|
@ -0,0 +1,29 @@
|
|||
#! /bin/sh
|
||||
|
||||
ifnxcp() {
|
||||
[ -e "$2" ] || cp "$1" "$2";
|
||||
}
|
||||
|
||||
NAME=$1
|
||||
|
||||
ifnxcp %%CHROOT_DGLDIR%%/data/crawl-git-settings/init.txt %%CHROOT_RCFILESDIR%%/crawl-git/"$NAME".rc
|
||||
ifnxcp %%CHROOT_DGLDIR%%/data/crawl-git.macro %%CHROOT_RCFILESDIR%%/crawl-git/"$NAME".macro
|
||||
ifnxcp %%CHROOT_DGLDIR%%/data/crawl-0.17-settings/init.txt %%CHROOT_RCFILESDIR%%/crawl-0.17/"$NAME".rc
|
||||
ifnxcp %%CHROOT_DGLDIR%%/data/crawl-git.macro %%CHROOT_RCFILESDIR%%/crawl-0.17/"$NAME".macro
|
||||
ifnxcp %%CHROOT_DGLDIR%%/data/crawl-0.16-settings/init.txt %%CHROOT_RCFILESDIR%%/crawl-0.16/"$NAME".rc
|
||||
ifnxcp %%CHROOT_DGLDIR%%/data/crawl-git.macro %%CHROOT_RCFILESDIR%%/crawl-0.16/"$NAME".macro
|
||||
ifnxcp %%CHROOT_DGLDIR%%/data/crawl-0.15-settings/init.txt %%CHROOT_RCFILESDIR%%/crawl-0.15/"$NAME".rc
|
||||
ifnxcp %%CHROOT_DGLDIR%%/data/crawl-git.macro %%CHROOT_RCFILESDIR%%/crawl-0.15/"$NAME".macro
|
||||
ifnxcp %%CHROOT_DGLDIR%%/data/crawl-0.14-settings/init.txt %%CHROOT_RCFILESDIR%%/crawl-0.14/"$NAME".rc
|
||||
ifnxcp %%CHROOT_DGLDIR%%/data/crawl-git.macro %%CHROOT_RCFILESDIR%%/crawl-0.14/"$NAME".macro
|
||||
ifnxcp %%CHROOT_DGLDIR%%/data/crawl-0.13-settings/init.txt %%CHROOT_RCFILESDIR%%/crawl-0.13/"$NAME".rc
|
||||
ifnxcp %%CHROOT_DGLDIR%%/data/crawl-git.macro %%CHROOT_RCFILESDIR%%/crawl-0.13/"$NAME".macro
|
||||
ifnxcp %%CHROOT_DGLDIR%%/data/crawl-0.12-settings/init.txt %%CHROOT_RCFILESDIR%%/crawl-0.12/"$NAME".rc
|
||||
ifnxcp %%CHROOT_DGLDIR%%/data/crawl-git.macro %%CHROOT_RCFILESDIR%%/crawl-0.12/"$NAME".macro
|
||||
ifnxcp %%CHROOT_DGLDIR%%/data/crawl-0.11-settings/init.txt %%CHROOT_RCFILESDIR%%/crawl-0.11/"$NAME".rc
|
||||
ifnxcp %%CHROOT_DGLDIR%%/data/crawl-git.macro %%CHROOT_RCFILESDIR%%/crawl-0.11/"$NAME".macro
|
||||
ifnxcp %%CHROOT_DGLDIR%%/data/crawl-0.10-settings/init.txt %%CHROOT_RCFILESDIR%%/crawl-0.10/"$NAME".rc
|
||||
ifnxcp %%CHROOT_DGLDIR%%/data/crawl-git.macro %%CHROOT_RCFILESDIR%%/crawl-0.10/"$NAME".macro
|
||||
|
||||
mkdir -p %%CHROOT_MORGUEDIR%%/"$NAME"
|
||||
mkdir -p %%CHROOT_TTYRECDIR%%/"$NAME"
|
|
@ -0,0 +1,144 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# ===========================================================================
|
||||
# Copyright (C) 2008, 2009, 2010, 2011 Marc H. Thoben
|
||||
# Copyright (C) 2011 Darshan Shaligram
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
# ===========================================================================
|
||||
#
|
||||
|
||||
set -u
|
||||
|
||||
ARGUMENTS=($@)
|
||||
CHAR_NAME="$(echo ${ARGUMENTS[0]} | sed 's/[$*\/();.|+-]//g')"
|
||||
BINARY_MAIN_NAME=${ARGUMENTS[1]}
|
||||
BINARY_SAVE_NAME=$BINARY_MAIN_NAME
|
||||
PREFIX="${ARGUMENTS[2]}"
|
||||
|
||||
trap "read -n 1 -s -p '-- Hit a key to exit --'; exit 0" EXIT
|
||||
|
||||
clear
|
||||
|
||||
TODAY="$(date +%y%m%d-%H%M)"
|
||||
|
||||
TARGET_DIR="%%CHROOT_SAVE_DUMPDIR%%"
|
||||
HTTP_LINK="%%WEB_SAVEDUMP_URL%%"
|
||||
|
||||
USER_ID="%%DGL_UID%%"
|
||||
|
||||
existing-files() {
|
||||
for file in "$@"; do
|
||||
if [[ -f "$file" ]]; then
|
||||
printf "%s " "$file"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
first-existing-file() {
|
||||
for file in "$@"; do
|
||||
if [[ -f "$file" ]]; then
|
||||
echo "$file"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
savedir-containing() {
|
||||
local char="$1"
|
||||
local -a saves
|
||||
saves=($PREFIX/$BINARY_SAVE_NAME{,-*}/saves/$char{,-$USER_ID}.{cs,chr,sav})
|
||||
local savefile="$(first-existing-file "${saves[@]}")"
|
||||
[[ -n "$savefile" ]] && dirname "$savefile"
|
||||
return 0
|
||||
}
|
||||
|
||||
SAVES="$(savedir-containing $CHAR_NAME)"
|
||||
SPRINT_SAVES="$(savedir-containing sprint/$CHAR_NAME)"
|
||||
ZOTDEF_SAVES="$(savedir-containing zotdef/$CHAR_NAME)"
|
||||
|
||||
if [[ -z "$SAVES" && -z "$SPRINT_SAVES" && -z "$ZOTDEF_SAVES" ]]; then
|
||||
echo "No saves to backup for $CHAR_NAME"
|
||||
fi
|
||||
|
||||
SAVE_QUALIFIER=""
|
||||
|
||||
CHAR=Character
|
||||
|
||||
C_NORMAL="\033[0m"
|
||||
C_YELLOW="\033[1;33m"
|
||||
C_GREEN="\033[1;32m"
|
||||
C_RED="\033[1;31m"
|
||||
|
||||
PROMPT="Backup"
|
||||
[[ -n "$SAVES" ]] && PROMPT="$PROMPT [n]ormal save"
|
||||
[[ -n "$SPRINT_SAVES" ]] && PROMPT="$PROMPT [s]print"
|
||||
[[ -n "$ZOTDEF_SAVES" ]] && PROMPT="$PROMPT [z]otdef"
|
||||
PROMPT="$PROMPT character?"
|
||||
|
||||
read -n 1 -s -p "$PROMPT" REPLY
|
||||
echo
|
||||
|
||||
REPLY="$(echo "$REPLY" | sed 's/\([A-Z]\)/\L\1/g')"
|
||||
|
||||
if [[ -n "$SPRINT_SAVES" && ( "$REPLY" = "s" ) ]]; then
|
||||
SAVE_QUALIFIER="-sprint"
|
||||
SAVES="$SPRINT_SAVES"
|
||||
CHAR="Sprint character"
|
||||
elif [[ -n "$ZOTDEF_SAVES" && ( "$REPLY" = "z" ) ]]; then
|
||||
SAVE_QUALIFIER="-zotdef"
|
||||
SAVES="$ZOTDEF_SAVES"
|
||||
CHAR="Zot Defense character"
|
||||
elif [[ "$REPLY" != "n" ]]; then
|
||||
echo -e "Bad choice, aborting."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
declare -a SAVE_MATCHES
|
||||
SAVE_MATCHES=(${SAVES}/${CHAR_NAME}{,-${USER_ID}}.{sav,cs,chr}*)
|
||||
|
||||
# Get rid of glob patterns that failed to match anything:
|
||||
SAVE_MATCHES=(${SAVE_MATCHES[@]##*\*})
|
||||
|
||||
# And the first remaining entry is the matched save.
|
||||
SAVE_FOUND=${SAVE_MATCHES[0]}
|
||||
|
||||
if [[ -n "$SAVE_FOUND" && -f "$SAVE_FOUND" ]]; then
|
||||
GAME_NAME=${SAVES%/zotdef}
|
||||
GAME_NAME=${GAME_NAME%/sprint}
|
||||
GAME_NAME="$(dirname $GAME_NAME)"
|
||||
GAME_NAME="${GAME_NAME##*/}"
|
||||
|
||||
echo
|
||||
echo "$CHAR \"${CHAR_NAME}\" in $GAME_NAME. "
|
||||
|
||||
echo -n "Backing up:"
|
||||
cd $SAVES
|
||||
|
||||
TARNAME=${CHAR_NAME}${SAVE_QUALIFIER}-$GAME_NAME-${TODAY}.tar.bz2
|
||||
tar -cjf ${TARGET_DIR}/$TARNAME \
|
||||
$(existing-files ${CHAR_NAME}{,-${USER_ID}}.*)
|
||||
|
||||
if test $? -ne 0
|
||||
then
|
||||
echo -e " ${C_RED}failed!${C_NORMAL}"
|
||||
else
|
||||
echo -e " ${C_GREEN}successful.${C_NORMAL}"
|
||||
echo "- ${HTTP_LINK}/$TARNAME"
|
||||
echo
|
||||
echo "Please provide this link in your bug-report or give it to a developer."
|
||||
fi
|
||||
else
|
||||
echo "Your character ($CHAR_NAME) was not found in $SAVES."
|
||||
fi
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
Crawl server (Germany) hosted and maintained by Ben Morrison (ahriman).
|
||||
------------------------------------------------------------------------------
|
||||
Webtiles: http://crawl.tildeverse.org/
|
||||
Crawl information: http://crawl.develz.org/
|
||||
------------------------------------------------------------------------------
|
||||
** Games on this server are recorded for in-progress viewing and playback! **
|
||||
------------------------------------------------------------------------------
|
|
@ -0,0 +1,420 @@
|
|||
# Crawl Init file
|
||||
#
|
||||
# On Unix systems (such as Mac OS X, Linux and the BSDs), you must copy
|
||||
# init.txt to ~/.crawlrc or ~/.crawl/init.txt as:
|
||||
# cp init.txt ~/.crawlrc
|
||||
#
|
||||
# Lines beginning with '#' are comments. The basic syntax is:
|
||||
#
|
||||
# field = value or field.subfield = value
|
||||
#
|
||||
# Only one specification is allowed per line.
|
||||
#
|
||||
# The terms are typically case-insensitive except in the fairly obvious
|
||||
# cases (the character's name and specifying files or directories when
|
||||
# on a system that has case-sensitive filenames).
|
||||
#
|
||||
# White space is stripped from the beginning and end of the line, as
|
||||
# well as immediately before and after the '='. If the option allows
|
||||
# multiple comma/semicolon-separated terms (such as
|
||||
# autopickup_exceptions), all whitespace around the separator is also
|
||||
# trimmed. All other whitespace is left intact.
|
||||
#
|
||||
# For descriptions concerning an option consult the file
|
||||
# options_guide.txt
|
||||
# in your /docs directory. Also note that the ordering of the options
|
||||
# is taken from that file; this is for presentational reasons only.
|
||||
#
|
||||
# Note that all boolean options (i.e. values of 'true' or 'false') have
|
||||
# their non-default value commented out. You can toggle these by just
|
||||
# uncommenting.
|
||||
# Options with several values, e.g. drop_mode = (multi | single),
|
||||
# usually have the first value as default.
|
||||
#
|
||||
# The options for monster glyphs and item colours don't matter for Tiles.
|
||||
# Similarily, tile options are ignored in console games.
|
||||
|
||||
##### Ancient versions ##############################################
|
||||
# If you're used to the interface of ancient versions of Crawl, you may
|
||||
# get back parts of it by uncommenting the following options:
|
||||
|
||||
# include = 034_command_keys.txt
|
||||
# target_unshifted_dirs = true
|
||||
# clear_messages = true
|
||||
#
|
||||
# And to revert monster glyph and colouring changes:
|
||||
# include = 034_monster_glyphs.txt
|
||||
# include = 052_monster_glyphs.txt
|
||||
# include = 060_monster_glyphs.txt
|
||||
# include = 071_monster_glyphs.txt
|
||||
# include = 080_monster_glyphs.txt
|
||||
# include = 0.9_monster_glyphs.txt
|
||||
|
||||
##### 1- Starting Screen ############################################
|
||||
#
|
||||
# name = Delilah
|
||||
# remember_name = false
|
||||
# weapon = (short sword | falchion | quarterstaff | hand axe | spear | mace
|
||||
# | trident | unarmed | random)
|
||||
# species = (Human |...| Vampire | random)
|
||||
# job = (Fighter |...| Wanderer | random)
|
||||
# random_pick = true
|
||||
# good_random = false
|
||||
# restart_after_game = true
|
||||
# default_manual_training = true
|
||||
|
||||
##### 2- File System ###############################################
|
||||
#
|
||||
# crawl_dir = <path>
|
||||
# morgue_dir = morgue
|
||||
# save_dir = saves
|
||||
# macro_dir = settings/
|
||||
# sound = <regex>:<path to sound file>
|
||||
|
||||
##### 3- Lua Files #################################################
|
||||
#
|
||||
lua_file = lua/stash.lua
|
||||
lua_file = lua/wield.lua
|
||||
lua_file = lua/runrest.lua
|
||||
lua_file = lua/gearset.lua
|
||||
lua_file = lua/trapwalk.lua
|
||||
|
||||
# kills.lua yields more information at the cost of huge dumps.
|
||||
# lua_file = lua/kills.lua
|
||||
|
||||
# autofight.lua allows binding both movement and attack a single key.
|
||||
# Use at your own discretion! See options_guide.txt for details.
|
||||
lua_file = lua/autofight.lua
|
||||
|
||||
##### 4- Interface #################################################
|
||||
#
|
||||
##### 4-a Picking up and Dropping ###############
|
||||
#
|
||||
autopickup = $?!+"/%
|
||||
|
||||
# There is a long list of autopickup exceptions in
|
||||
include = autopickup_exceptions.txt
|
||||
|
||||
drop_filter = useless_item
|
||||
|
||||
# default_autopickup = false
|
||||
# autopickup_no_burden = false
|
||||
# pickup_thrown = false
|
||||
# chunks_autopickup = false
|
||||
# assign_item_slot = (forward | backward)
|
||||
#
|
||||
# drop_mode = (multi | single)
|
||||
# pickup_mode = (single | multi | auto:5)
|
||||
# drop_filter = skeleton, corpse, useless_item
|
||||
# default_friendly_pickup = (none | friend | player | all)
|
||||
|
||||
##### 4-b Targetting ############################
|
||||
#
|
||||
# default_target = false
|
||||
# target_unshifted_dirs = true
|
||||
# darken_beyond_range = false
|
||||
|
||||
##### 4-c Passive Sightings #####################
|
||||
#
|
||||
# detected_monster_colour = lightred
|
||||
# detected_item_colour = green
|
||||
# remembered_monster_colour = darkgrey
|
||||
# clean_map = true
|
||||
|
||||
##### 4-d Branding ##############################
|
||||
#
|
||||
# friend_brand = hi:green
|
||||
# neutral_brand = hi:lightgrey
|
||||
# stab_brand = hi:blue
|
||||
# may_stab_brand = hi:yellow
|
||||
# heap_brand = reverse
|
||||
# feature_item_brand = reverse
|
||||
# trap_item_brand = reverse
|
||||
|
||||
##### 4-e Level Map Functions ###################
|
||||
#
|
||||
# level_map_cursor_step = 7
|
||||
# level_map_title = false
|
||||
# show_waypoints = false
|
||||
|
||||
##### 4-f Viewport Options ###################
|
||||
#
|
||||
# view_max_width = 33
|
||||
# view_max_height = 21
|
||||
# view_lock_x = false
|
||||
# view_lock_y = false
|
||||
# view_lock = false
|
||||
# center_on_scroll = true
|
||||
# symmetric_scroll = false
|
||||
# scroll_margin_x = 2
|
||||
# scroll_margin_y = 2
|
||||
# scroll_margin = 2
|
||||
|
||||
##### 4-g Travel and Exploration #################
|
||||
#
|
||||
# travel_delay = 20
|
||||
# explore_delay = -1
|
||||
# travel_avoid_terrain = shallow water
|
||||
#
|
||||
# explore_greedy = false
|
||||
# explore_stop = items,greedy_pickup_smart,stairs,shops,altars,gates
|
||||
# explore_stop += greedy_visited_item_stack
|
||||
# explore_improved = true
|
||||
# explore_wall_bias = 0
|
||||
# travel_key_stop = false
|
||||
#
|
||||
# explore_stop_pickup_ignore = curare
|
||||
auto_exclude = oklob,statue,curse skull,roxanne,hyperactive,lightning spire
|
||||
|
||||
# tc_reachable = blue
|
||||
# tc_dangerous = cyan
|
||||
# tc_disconnected = darkgrey
|
||||
# tc_excluded = lightmagenta
|
||||
# tc_exclude_circle = red
|
||||
|
||||
# runrest options (require runrest.lua to be included above)
|
||||
runrest_ignore_poison = 2:30
|
||||
runrest_ignore_monster = butterfly:1
|
||||
# runrest_ignore_monster = swamp worm:3
|
||||
|
||||
# The file runrest_messages.txt contains a list of default
|
||||
# runrest message settings. Add your own before this to override
|
||||
# later settings.
|
||||
# runrest_stop_message = You hear a.* slurping noise
|
||||
# runrest_ignore_message = Jiyva's power touches on your attributes
|
||||
include = runrest_messages.txt
|
||||
|
||||
trapwalk_safe_hp = dart:20,needle:15,arrow:35,bolt:45,spear:40,axe:45,blade:95
|
||||
|
||||
#rest_wait_both = true
|
||||
|
||||
##### 4-h Stashes ###############################
|
||||
#
|
||||
|
||||
# annotate_item_class = true
|
||||
# annotate_item_dropped = true
|
||||
|
||||
##### 4-i Command Enhancements ##################
|
||||
#
|
||||
# auto_list = false
|
||||
# auto_switch = true
|
||||
# easy_open = false
|
||||
# easy_unequip = false
|
||||
# equip_unequip = true
|
||||
# easy_confirm = (none | safe | all)
|
||||
# allow_self_target = (yes | no | prompt)
|
||||
# confirm_butcher = (auto | always | never)
|
||||
# prefer_safe_chunks = false
|
||||
# easy_eat_chunks = true
|
||||
# easy_eat_gourmand = true
|
||||
# easy_eat_contaminated = true
|
||||
# auto_eat_chunks = true
|
||||
# prompt_for_swap = false
|
||||
# easy_quit_item_prompts = false
|
||||
# easy_exit_menu = true
|
||||
# sort_menus = pickup: true : art, ego, basename, qualname, curse, qty
|
||||
sort_menus = inv: true : equipped, freshness, charged
|
||||
|
||||
# autofight_stop = 30
|
||||
|
||||
##### 4-j Messages and Display Enhancements #####
|
||||
#
|
||||
# hp_warning = 30
|
||||
# mp_warning = 0
|
||||
# hp_colour = 50:yellow, 25:red
|
||||
# mp_colour = 50:yellow, 25:red
|
||||
# stat_colour = 1:lightred, 3:red
|
||||
|
||||
# status_caption_colour = yellow
|
||||
# mlist_min_height = 4
|
||||
# msg_min_height = 7
|
||||
# msg_max_height = 10
|
||||
# mlist_allow_alternate_layout = true
|
||||
# messages_at_top = true
|
||||
# mlist_targetting = true
|
||||
# show_gold_turns = true
|
||||
# show_game_turns = true
|
||||
# show_newturn_mark = false
|
||||
# clear_messages = true
|
||||
# small_more = true
|
||||
# show_more = false
|
||||
# show_inventory_weights = true
|
||||
# item_stack_summary_minimum = 5
|
||||
# list_rotten = false
|
||||
# msg_condense_repeats = false
|
||||
# msg_condense_short = false
|
||||
# show_no_ctele = false
|
||||
# skill_focus = false
|
||||
|
||||
##### Colours (messages and menus) #####
|
||||
#
|
||||
# menu_colour_prefix_class = false
|
||||
# menu_colour_shops = false
|
||||
|
||||
# Food is colour coded in standard_colours.txt as follows:
|
||||
include = standard_colours.txt
|
||||
#
|
||||
# yellow = preferred food ($preferred)
|
||||
# darkgrey = cannot be eaten at all ($inedible)
|
||||
# lightred = causes rot ($rot-inducing)
|
||||
# magenta = dangerous to use, mutagenic ($dangerous, $mutagenic)
|
||||
# red = considered "evil" by your deity ($evil)
|
||||
# lightgreen = poisonous ($poisonous)
|
||||
# brown = contaminated, may cause nausea ($contaminated)
|
||||
#
|
||||
# You can change colours by using something like
|
||||
# $contaminated := magenta
|
||||
|
||||
include = food_colouring.txt
|
||||
|
||||
# There is elaborate colouring of items in the inventory (and other menus)
|
||||
# depending on their usefulness, taking species and other criteria into account.
|
||||
include = menu_colours.txt
|
||||
|
||||
# Colouring of autoinscribed god gifts
|
||||
menu_colour = pickup:green:god gift
|
||||
|
||||
# Highlight (partly) selected items
|
||||
menu_colour = inventory:white:\w \+\s
|
||||
menu_colour = inventory:white:\w \#\s
|
||||
|
||||
# Colouring of messages
|
||||
# Messages are colour coded in standard_colours.txt as follows:
|
||||
#
|
||||
# lightred = really important messages ($danger)
|
||||
# yellow = significant messages ($warning)
|
||||
# lightred = item damaged/destroyed ($item_dmg [same as $danger])
|
||||
# darkgrey = boring, message clutter ($boring)
|
||||
#
|
||||
include = messages.txt
|
||||
|
||||
# Colouring for the notes
|
||||
menu_colour = notes:white:Reached XP level
|
||||
|
||||
# These lines will suppress extra feedback messages from travel/shift-running.
|
||||
#
|
||||
# message_colour = mute:warning:comes into view
|
||||
# message_colour = mute:You start (searching|resting)
|
||||
# message_colour = mute:Done searching
|
||||
# message_colour = mute:(HP|Magic) restored
|
||||
# message_colour = mute:warning:Not with.*(in view|monsters around)
|
||||
|
||||
# You can also enforce a --more-- prompt for messages
|
||||
|
||||
## Avoid wasting turns with aborted actions:
|
||||
# force_more_message = There are no visible monsters within range
|
||||
# force_more_message = This wand has no charges
|
||||
|
||||
force_more_message = You have reached level
|
||||
force_more_message = Your scales start
|
||||
force_more_message = You fall through a shaft
|
||||
|
||||
## Reduce chance of drowning because levitation or form runs out:
|
||||
force_more_message = Careful!
|
||||
|
||||
# Announcements of timed portal vaults (bazaar, labyrinths):
|
||||
force_more_message = interdimensional caravan
|
||||
force_more_message = distant snort
|
||||
|
||||
##### 4-k Firing Commands #######################
|
||||
#
|
||||
# fire_items_start = a
|
||||
# fire_order = launcher, return
|
||||
# fire_order += javelin / dart / stone / rock / spear / net / handaxe / dagger / club
|
||||
# fire_order += inscribed
|
||||
|
||||
##### 4-l Channels ##############################
|
||||
#
|
||||
# channel.multiturn = mute
|
||||
|
||||
##### 4-m Inscriptions ##########################
|
||||
#
|
||||
# autoinscribe = bad_item.*potion:!q
|
||||
# autoinscribe = potion.*mutation:!q
|
||||
# autoinscribe = royal jell:=g
|
||||
# autoinscribe_artefacts = false
|
||||
# autoinscribe_cursed = false
|
||||
# autoinscribe = fruit:!e
|
||||
|
||||
##### 4-n Macro related Options #################
|
||||
#
|
||||
# flush.failure = false
|
||||
# flush.command = true
|
||||
# flush.message = true
|
||||
|
||||
##### 4-t Tile related Options ##################
|
||||
|
||||
# All tiles specific options are in the external file
|
||||
include = tiles_options.txt
|
||||
|
||||
##### 5- Dump File #################################################
|
||||
#
|
||||
##### 5-a Items and Kill List ###################
|
||||
#
|
||||
# kill_map = friend:you, other:you
|
||||
# dump_kill_places = (single | all | none)
|
||||
# dump_item_origins = all,artifacts,ego_arm,ego_weap,jewellery,runes
|
||||
# dump_item_origin_price = -1
|
||||
# dump_message_count = 20
|
||||
# dump_order = header, hiscore, stats, misc, notes, inventory,
|
||||
# dump_order += turns_by_place, skills, spells, overview, mutations,
|
||||
# dump_order += messages, screenshot, monlist, kills_by_place, kills
|
||||
# dump_order += spell_usage, action_counts
|
||||
# dump_book_spells = false
|
||||
|
||||
##### 5-b Notes #################################
|
||||
#
|
||||
# user_note_prefix=@@@
|
||||
ood_interesting = 8
|
||||
note_hp_percent = 5
|
||||
note_skill_levels = 1,5,10,15,27
|
||||
#note_all_skill_levels = true
|
||||
#note_skill_max = false
|
||||
#note_all_spells = false
|
||||
#note_xom_effects = false
|
||||
note_items = rod of, acquirement, preservation, running, of Zot
|
||||
note_messages = You pass through the gate
|
||||
note_messages = cast .* Abyss
|
||||
note_messages = Your scales start
|
||||
note_messages = protects you from harm
|
||||
note_messages = You fall through a shaft
|
||||
note_monsters = orb of fire, ancient lich, Sigmund
|
||||
|
||||
##### 6- Miscellaneous #############################################
|
||||
#
|
||||
##### 6-a All OS ################################
|
||||
#
|
||||
# mouse_input = true
|
||||
# wiz_mode = no
|
||||
# char_set = ascii
|
||||
# use_fake_player_cursor = false
|
||||
#
|
||||
# colour.lightgray = black
|
||||
# colour.lightcyan = cyan
|
||||
# colour.yellow = brown
|
||||
#
|
||||
# pizza = Sausage
|
||||
# show_player_species = true
|
||||
|
||||
# See options_guide.txt for the options
|
||||
# cset, feature, mon_glyph
|
||||
|
||||
## Highlight the edge of unexplored terrain.
|
||||
# feature = explore horizon {',,green}
|
||||
|
||||
##### 6-b Windows console #######################
|
||||
#
|
||||
# dos_use_background_intensity = true
|
||||
# background = black
|
||||
|
||||
##### 6-c Unix console ##########################
|
||||
#
|
||||
# use_fake_cursor = false
|
||||
|
||||
##### 6-d Alternative keybinding files ##########
|
||||
#
|
||||
# Alternative vi bindings for Dvorak users.
|
||||
# include = dvorak_command_keys.txt
|
||||
#
|
||||
# Override the vi movement keys with a non-command.
|
||||
# include = no_vi_command_keys.txt
|
|
@ -0,0 +1,23 @@
|
|||
Crawl server (Germany) hosted and maintained by Ben Morrison (ahriman)
|
||||
------------------------------------------------------------------------------
|
||||
Webtiles: https://crawl.tildeverse.org/
|
||||
Crawl information: http://crawl.develz.org/
|
||||
------------------------------------------------------------------------------
|
||||
** Games on this server are recorded for in-progress viewing and playback! **
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
Logged in as: $USERNAME
|
||||
|
||||
Game selected: Dungeon Crawl Stone Soup 0.22
|
||||
|
||||
P)lay Crawl S)print T)utorial
|
||||
|
||||
o Edit options O) with Virus
|
||||
m Edit macros M) with Virus
|
||||
v View changelog V) with Virus
|
||||
|
||||
Advanced options
|
||||
|
||||
q Return to main menu
|
||||
|
||||
=>
|
|
@ -0,0 +1,22 @@
|
|||
Crawl server (Germany) hosted and maintained by Ben Morrison (ahriman)
|
||||
------------------------------------------------------------------------------
|
||||
Webtiles: https://crawl.tildeverse.org/
|
||||
Crawl information: http://crawl.develz.org/
|
||||
------------------------------------------------------------------------------
|
||||
** Games on this server are recorded for in-progress viewing and playback! **
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
Logged in as: $USERNAME
|
||||
|
||||
Game selected: Dungeon Crawl Stone Soup 0.22
|
||||
|
||||
Backup your save-game (for bug reports and debugging)
|
||||
|
||||
The next option allows you to reset your options.
|
||||
ALL CHANGES YOU'VE MADE TO YOUR OPTIONS WILL BE LOST.
|
||||
|
||||
O Reset options
|
||||
|
||||
q Return to previous menu
|
||||
|
||||
=>
|
|
@ -0,0 +1,23 @@
|
|||
Crawl server (Germany) hosted and maintained by Ben Morrison (ahriman)
|
||||
------------------------------------------------------------------------------
|
||||
Webtiles: https://crawl.tildeverse.org/
|
||||
Crawl information: http://crawl.develz.org/
|
||||
------------------------------------------------------------------------------
|
||||
** Games on this server are recorded for in-progress viewing and playback! **
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
Logged in as: $USERNAME
|
||||
|
||||
Game selected: Dungeon Crawl Stone Soup Trunk
|
||||
|
||||
P)lay Crawl S)print T)utorial
|
||||
|
||||
o Edit options O) with Virus
|
||||
m Edit macros M) with Virus
|
||||
v View changelog V) with Virus
|
||||
|
||||
Advanced options
|
||||
|
||||
q Return to main menu
|
||||
|
||||
=>
|
|
@ -0,0 +1,22 @@
|
|||
Crawl server (Germany) hosted and maintained by Ben Morrison (ahriman)
|
||||
------------------------------------------------------------------------------
|
||||
Webtiles: https://crawl.tildeverse.org/
|
||||
Crawl information: http://crawl.develz.org/
|
||||
------------------------------------------------------------------------------
|
||||
** Games on this server are recorded for in-progress viewing and playback! **
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
Logged in as: $USERNAME
|
||||
|
||||
Game selected: Dungeon Crawl Stone Soup Trunk
|
||||
|
||||
Backup your save-game (for bug reports and debugging)
|
||||
|
||||
The next option allows you to reset your options.
|
||||
ALL CHANGES YOU'VE MADE TO YOUR OPTIONS WILL BE LOST.
|
||||
|
||||
O Reset options
|
||||
|
||||
q Return to previous menu
|
||||
|
||||
=>
|
|
@ -0,0 +1,22 @@
|
|||
Crawl server (Germany) hosted and maintained by Ben Morrison (ahriman)
|
||||
------------------------------------------------------------------------------
|
||||
Webtiles: https://crawl.tildeverse.org/
|
||||
Crawl information: http://crawl.develz.org/
|
||||
------------------------------------------------------------------------------
|
||||
** Games on this server are recorded for in-progress viewing and playback! **
|
||||
------------------------------------------------------------------------------
|
||||
Logged in as: $USERNAME
|
||||
|
||||
Game selected: Dungeon Crawl Stone Soup experimental branches
|
||||
|
||||
WARNING: Experimental branches have limited save compatibility! Updates to the
|
||||
branches may cause the loss of existing games, and branches may be removed
|
||||
without warning: don't get too attached to your character. Thanks for helping
|
||||
us evaluate potential new features!
|
||||
|
||||
Chunkless
|
||||
Iashol
|
||||
Smith God (updated)
|
||||
|
||||
q Return to trunk menu
|
||||
=>
|
|
@ -0,0 +1,21 @@
|
|||
Crawl server (Germany) hosted and maintained by Ben Morrison (ahriman)
|
||||
------------------------------------------------------------------------------
|
||||
Webtiles: https://crawl.tildeverse.org
|
||||
Crawl information: http://crawl.develz.org/
|
||||
------------------------------------------------------------------------------
|
||||
** Games on this server are recorded for in-progress viewing and playback! **
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
Logged in as: $USERNAME (admin)
|
||||
W) Watch games in progress
|
||||
|
||||
T) Dungeon Crawl Stone Soup Trunk
|
||||
0) Dungeon Crawl Stone Soup 0.22
|
||||
|
||||
c) Change password e) Change email address
|
||||
|
||||
P)lay or S)print in Crawl 0.22 now
|
||||
|
||||
Q)uit
|
||||
|
||||
=>
|
|
@ -0,0 +1,18 @@
|
|||
Crawl server (Germany) hosted and maintained by Ben Morrison (ahriman)
|
||||
------------------------------------------------------------------------------
|
||||
Webtiles: https://crawl.tildeverse.org/
|
||||
Crawl information: http://crawl.develz.org/
|
||||
------------------------------------------------------------------------------
|
||||
** Games on this server are recorded for in-progress viewing and playback! **
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
Not logged in.
|
||||
|
||||
W) Watch games in progress
|
||||
|
||||
R) Register as new user
|
||||
L) Login
|
||||
|
||||
Q) Quit
|
||||
|
||||
=>
|
|
@ -0,0 +1,21 @@
|
|||
Crawl server (Germany) hosted and maintained by Ben Morrison (ahriman)
|
||||
------------------------------------------------------------------------------
|
||||
Webtiles: https://crawl.tildeverse.org/
|
||||
Crawl information: http://crawl.develz.org/
|
||||
------------------------------------------------------------------------------
|
||||
** Games on this server are recorded for in-progress viewing and playback! **
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
Logged in as: $USERNAME
|
||||
W) Watch games in progress
|
||||
|
||||
T) Dungeon Crawl Stone Soup Trunk
|
||||
0) Dungeon Crawl Stone Soup 0.22
|
||||
|
||||
c) Change password e) Change email address
|
||||
|
||||
P)lay or S)print in Crawl 0.22 now
|
||||
|
||||
Q)uit
|
||||
|
||||
=>
|
|
@ -0,0 +1,22 @@
|
|||
Help for watching-menu
|
||||
----------------------
|
||||
? show this help.
|
||||
> < next/previous page.
|
||||
. , change sorting method.
|
||||
q Q return to main menu.
|
||||
a-zA-Z select a game to watch.
|
||||
/ select/search by name a game to watch.
|
||||
* start showing a randomly selected game.
|
||||
enter start watching already selected game.
|
||||
|
||||
|
||||
While watching a game
|
||||
---------------------
|
||||
q return to the watching menu.
|
||||
m send mail to the player (requires login.
|
||||
s toggle charset stripping between Unicode/IBM/none.
|
||||
r resize your terminal to match the player's terminal.
|
||||
|
||||
|
||||
|
||||
Press 'q' or space to return.
|
|
@ -0,0 +1,133 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# This script needs a sudo entry for user crawl to run as root:
|
||||
# For obvious reasons, this script should not source any other scripts that
|
||||
# are not owned by root.
|
||||
#
|
||||
# ===========================================================================
|
||||
# Copyright (C) 2008, 2009, 2010, 2011 Marc H. Thoben
|
||||
# Copyright (C) 2011 Darshan Shaligram
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
# ===========================================================================
|
||||
#
|
||||
|
||||
set -e
|
||||
set -u
|
||||
|
||||
# These are not overrideable:
|
||||
CHROOT="%%DGL_CHROOT%%"
|
||||
CHROOT_BINARIES="%%CHROOT_CRAWL_BINARY_PATH%%"
|
||||
CHROOT_CRAWL_BASEDIR="%%CHROOT_CRAWL_BASEDIR%%"
|
||||
DESTDIR="%%CRAWL_BASEDIR%%"
|
||||
VERSIONS_DB="%%VERSIONS_DB%%"
|
||||
CRAWL_UGRP="%%CRAWL_UGRP%%"
|
||||
DGL_SETTINGS_DIR="%%DGL_SETTINGS_DIR%%"
|
||||
|
||||
VERSION="$1"
|
||||
|
||||
GAME="crawl-$VERSION"
|
||||
|
||||
# Safe path:
|
||||
PATH=/bin:/sbin:/usr/bin:/usr/sbin
|
||||
|
||||
if [[ "$UID" != "0" ]]; then
|
||||
echo "$0 must be run as root"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
copy-game-binary() {
|
||||
echo "Installing game binary ($GAME_BINARY) in $BINARIES_DIR"
|
||||
mkdir -p $BINARIES_DIR
|
||||
if [[ -f $BINARIES_DIR/$GAME_BINARY ]]; then
|
||||
mv $BINARIES_DIR/$GAME_BINARY $BINARIES_DIR/$GAME_BINARY.old
|
||||
fi
|
||||
if cp source/$GAME_BINARY $BINARIES_DIR; then
|
||||
rm $BINARIES_DIR/$GAME_BINARY.old || true
|
||||
else
|
||||
local ERR=$?
|
||||
mv $BINARIES_DIR/$GAME_BINARY.old $BINARIES_DIR/$GAME_BINARY || true
|
||||
return $ERR
|
||||
fi
|
||||
}
|
||||
|
||||
copy-data-files() {
|
||||
echo "Copying game data files to $DATADIR"
|
||||
cp -r source/dat docs settings $DATADIR
|
||||
# Only one of these exists, don't error for the other.
|
||||
cp -r README.txt README.md $DATADIR 2>/dev/null || true
|
||||
cp -r settings/. $DGL_SETTINGS_DIR/$GAME-settings
|
||||
cp -r source/webserver/game_data/. $DATADIR/web
|
||||
|
||||
mkdir -p "$ABS_COMMON_DIR/data/docs"
|
||||
cp docs/crawl_changelog.txt "$ABS_COMMON_DIR/data/docs"
|
||||
}
|
||||
|
||||
install-game() {
|
||||
mkdir -p $SAVEDIR/{,sprint,zotdef}
|
||||
mkdir -p $DATADIR
|
||||
|
||||
copy-game-binary
|
||||
copy-data-files
|
||||
|
||||
chown -R $CRAWL_UGRP $SAVEDIR
|
||||
}
|
||||
|
||||
assert-not-evil() {
|
||||
local file=$1
|
||||
if [[ "$file" != "$(echo "$file" |
|
||||
perl -lpe 's{[.]{2}|[^.a-zA-Z0-9_/-]+}{}g')" ]]
|
||||
then
|
||||
echo -e "Path $file contains characters I don't like, aborting."
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
if [[ -z "$VERSION" ]]; then
|
||||
echo -e "Missing version argument"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
assert-not-evil "$VERSION"
|
||||
|
||||
if [[ ! ( "$CRAWL_UGRP" =~ ^[a-z0-9]+:[a-z0-9]+$ ) ]]; then
|
||||
echo -e "Expected CRAWL_UGRP to be user:group, but got $CRAWL_UGRP"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# COMMON_DIR is the absolute path *inside* the chroot jail of the
|
||||
# directory holding common data for all game versions, viz: saves.
|
||||
COMMON_DIR=$CHROOT_CRAWL_BASEDIR/$GAME
|
||||
assert-not-evil "$COMMON_DIR"
|
||||
|
||||
# ABS_COMMON_DIR is the absolute path from outside the chroot
|
||||
# corresponding to COMMON_DIR
|
||||
ABS_COMMON_DIR=$CHROOT$COMMON_DIR
|
||||
|
||||
if [[ ! -d "$ABS_COMMON_DIR" ]]; then
|
||||
mkdir -p "$ABS_COMMON_DIR"
|
||||
fi
|
||||
|
||||
GAME_BINARY=$GAME
|
||||
BINARIES_DIR=$CHROOT$CHROOT_BINARIES
|
||||
|
||||
GAMEDIR=$CHROOT$CHROOT_CRAWL_BASEDIR/$GAME
|
||||
# Absolute path to save game directory
|
||||
SAVEDIR=$GAMEDIR/saves
|
||||
DATADIR=$GAMEDIR/data
|
||||
assert-not-evil "$SAVEDIR"
|
||||
assert-not-evil "$DATADIR"
|
||||
|
||||
echo "Installing game"
|
||||
install-game
|
|
@ -0,0 +1,175 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# This script needs a sudo entry for user crawl to run as root:
|
||||
# For obvious reasons, this script should not source any other scripts that
|
||||
# are not owned by root.
|
||||
#
|
||||
# ===========================================================================
|
||||
# Copyright (C) 2008, 2009, 2010, 2011 Marc H. Thoben
|
||||
# Copyright (C) 2011 Darshan Shaligram
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
# ===========================================================================
|
||||
#
|
||||
|
||||
set -e
|
||||
set -u
|
||||
shopt -s extglob
|
||||
|
||||
# These are not overrideable:
|
||||
CHROOT="%%DGL_CHROOT%%"
|
||||
CHROOT_BINARIES="%%CHROOT_CRAWL_BINARY_PATH%%"
|
||||
GAME="%%GAME%%"
|
||||
CHROOT_CRAWL_BASEDIR="%%CHROOT_CRAWL_BASEDIR%%"
|
||||
DESTDIR="%%CRAWL_BASEDIR%%"
|
||||
VERSIONS_DB="%%VERSIONS_DB%%"
|
||||
CRAWL_UGRP="%%CRAWL_UGRP%%"
|
||||
DGL_SETTINGS_DIR="%%DGL_SETTINGS_DIR%%"
|
||||
|
||||
REVISION="$1"
|
||||
DESCRIPTION="$2"
|
||||
SGV_MAJOR="$3"
|
||||
SGV_MINOR="$4"
|
||||
|
||||
# Safe path:
|
||||
PATH=/bin:/sbin:/usr/bin:/usr/sbin
|
||||
|
||||
if [[ "$UID" != "0" ]]; then
|
||||
echo "$0 must be run as root"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
copy-game-binary() {
|
||||
echo "Installing game binary ($GAME_BINARY) in $BINARIES_DIR"
|
||||
mkdir -p $BINARIES_DIR
|
||||
cp source/$GAME_BINARY $BINARIES_DIR
|
||||
ln -sf $GAME_BINARY $BINARIES_DIR/crawl-latest
|
||||
}
|
||||
|
||||
copy-data-files() {
|
||||
echo "Copying game data files to $DATADIR"
|
||||
cp -r source/dat docs settings $DATADIR
|
||||
# Only one of these exists, don't error for the other.
|
||||
cp -r README.txt README.md $DATADIR 2>/dev/null || true
|
||||
cp -r settings/. $DGL_SETTINGS_DIR/$GAME-settings
|
||||
cp -r source/webserver/game_data/. $DATADIR/web
|
||||
cp -r source/webserver/!(config.py|game_data|templates) $WEBDIR
|
||||
cp source/webserver/templates/client.html $WEBDIR/templates/
|
||||
cp source/webserver/templates/game_links.html $WEBDIR/templates/
|
||||
|
||||
mkdir -p "$ABS_COMMON_DIR/data/docs"
|
||||
cp docs/crawl_changelog.txt "$ABS_COMMON_DIR/data/docs"
|
||||
}
|
||||
|
||||
link-logfiles() {
|
||||
for file in logfile milestones scores; do
|
||||
ln -sf $COMMON_DIR/saves/$file $SAVEDIR
|
||||
ln -sf $COMMON_DIR/saves/$file-sprint $SAVEDIR
|
||||
ln -sf $COMMON_DIR/saves/$file-zotdef $SAVEDIR
|
||||
done
|
||||
}
|
||||
|
||||
install-game() {
|
||||
mkdir -p $SAVEDIR/{,sprint,zotdef}
|
||||
mkdir -p $DATADIR
|
||||
|
||||
copy-game-binary
|
||||
copy-data-files
|
||||
link-logfiles
|
||||
|
||||
chown -R $CRAWL_UGRP $SAVEDIR
|
||||
ln -snf $GAME_BINARY $CHROOT$CHROOT_CRAWL_BASEDIR/crawl-latest
|
||||
}
|
||||
|
||||
register-game-version() {
|
||||
echo
|
||||
echo "Adding version (${SGV_MAJOR}.${SGV_MINOR}) to database..."
|
||||
sqlite3 ${VERSIONS_DB} <<SQL
|
||||
INSERT INTO VERSIONS VALUES ('${REVISION}', '$DESCRIPTION', $(date +%s),
|
||||
${SGV_MAJOR}, ${SGV_MINOR}, 1);
|
||||
SQL
|
||||
}
|
||||
|
||||
assert-not-evil() {
|
||||
local file=$1
|
||||
if [[ "$file" != "$(echo "$file" |
|
||||
perl -lpe 's{[.]{2}|[^.a-zA-Z0-9_/-]+}{}g')" ]]
|
||||
then
|
||||
echo -e "Path $file contains characters I don't like, aborting."
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
assert-all-variables-exist() {
|
||||
local -a broken_variables=()
|
||||
for variable_name in "$@"; do
|
||||
eval "value=\"\$$variable_name\""
|
||||
if [[ -z "$value" ]]; then
|
||||
broken_variables=(${broken_variables[@]} $variable_name)
|
||||
fi
|
||||
done
|
||||
if (( ${#broken_variables[@]} > 0 )); then
|
||||
echo -e "These variables are required, but are unset:" \
|
||||
"${broken_variables[@]}"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
if [[ -z "$REVISION" ]]; then
|
||||
echo -e "Missing revision argument"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
assert-not-evil "$REVISION"
|
||||
|
||||
if [[ ! ( "$CRAWL_UGRP" =~ ^[a-z0-9]+:[a-z0-9]+$ ) ]]; then
|
||||
echo -e "Expected CRAWL_UGRP to be user:group, but got $CRAWL_UGRP"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ -n "${SGV_MAJOR}" && -n "${SGV_MINOR}" ]]; then
|
||||
# COMMON_DIR is the absolute path *inside* the chroot jail of the
|
||||
# directory holding common data for all game versions, viz: saves.
|
||||
COMMON_DIR=$CHROOT_CRAWL_BASEDIR/$GAME
|
||||
assert-not-evil "$COMMON_DIR"
|
||||
|
||||
# ABS_COMMON_DIR is the absolute path from outside the chroot
|
||||
# corresponding to COMMON_DIR
|
||||
ABS_COMMON_DIR=$CHROOT$CHROOT_CRAWL_BASEDIR/$GAME
|
||||
|
||||
if [[ ! -d "$CHROOT$COMMON_DIR" ]]; then
|
||||
echo -e "Expected to find common game dir $ABS_COMMON_DIR but did not find it"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
GAME_BINARY=$GAME-$REVISION
|
||||
BINARIES_DIR=$CHROOT$CHROOT_BINARIES
|
||||
|
||||
WEBDIR=$CHROOT$CHROOT_CRAWL_BASEDIR/webserver
|
||||
GAMEDIR=$CHROOT$CHROOT_CRAWL_BASEDIR/$GAME_BINARY
|
||||
# Absolute path to save game directory
|
||||
SAVEDIR=$GAMEDIR/saves
|
||||
DATADIR=$GAMEDIR/data
|
||||
assert-not-evil "$SAVEDIR"
|
||||
assert-not-evil "$DATADIR"
|
||||
|
||||
echo "Installing game"
|
||||
install-game
|
||||
register-game-version
|
||||
else
|
||||
echo "Could not figure out version tags. Installation cancelled."
|
||||
echo "Aborting installation!"
|
||||
echo
|
||||
exit 1
|
||||
fi
|
|
@ -0,0 +1,212 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# ===========================================================================
|
||||
# Copyright (C) 2008, 2009, 2010, 2011 Marc H. Thoben
|
||||
# Copyright (C) 2011 Darshan Shaligram
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
# ===========================================================================
|
||||
#
|
||||
|
||||
set -u
|
||||
|
||||
CHROOT="%%DGL_CHROOT%%"
|
||||
BASE_DIR="%%CHROOT_CRAWL_BASEDIR%%"
|
||||
GAME="%%GAME%%"
|
||||
|
||||
BINPATH="%%CHROOT_CRAWL_BINARY_PATH%%"
|
||||
VERSIONS_DB="%%VERSIONS_DB%%"
|
||||
USER_ID="%%DGL_UID%%"
|
||||
DGL_USER="%%DGL_USER%%"
|
||||
|
||||
GAME_BASE="$GAME-"
|
||||
GAME_GLOB="$GAME_BASE*"
|
||||
|
||||
VERBOSE=
|
||||
PROMPTS_ENABLED=1
|
||||
|
||||
# Toss the leading slash:
|
||||
BASE_DIR=${BASE_DIR#/}
|
||||
BINPATH=${BINPATH#/}
|
||||
FORCE=
|
||||
|
||||
while getopts vq opt; do
|
||||
case $opt in
|
||||
v) VERBOSE=1 ;;
|
||||
q) PROMPTS_ENABLED= ;;
|
||||
f) FORCE=1 ;;
|
||||
esac
|
||||
done
|
||||
shift $((OPTIND - 1))
|
||||
|
||||
verbose() {
|
||||
[[ -n "$VERBOSE" ]]
|
||||
}
|
||||
|
||||
prompts-enabled() {
|
||||
[[ -n "$PROMPTS_ENABLED" ]]
|
||||
}
|
||||
|
||||
hash-version-detail() {
|
||||
local hash="$1"
|
||||
sqlite3 "$VERSIONS_DB" <<EOF
|
||||
SELECT description || ' (' || major || '.' || minor || ')'
|
||||
FROM versions
|
||||
WHERE hash='$hash';
|
||||
EOF
|
||||
}
|
||||
|
||||
canonicalise-version() {
|
||||
local version="$1"
|
||||
sqlite3 "$VERSIONS_DB" <<EOF
|
||||
SELECT hash FROM versions
|
||||
WHERE hash LIKE '$version%' OR description='$version';
|
||||
EOF
|
||||
}
|
||||
|
||||
saves-in-dir() {
|
||||
local folder="$1"
|
||||
local -a globs
|
||||
globs=(${folder}/saves/{,sprint/,zotdef/}*.{sav,chr,cs})
|
||||
if (( $# == 2 )); then
|
||||
local suffix="/$2"
|
||||
globs=($folder/saves$suffix/*.{sav,chr,cs})
|
||||
fi
|
||||
/bin/ls -1 ${globs[@]} 2>/dev/null
|
||||
}
|
||||
|
||||
count-saves-in-dir() {
|
||||
saves-in-dir "$@" | wc -l
|
||||
}
|
||||
|
||||
strip-save-uid-extension() {
|
||||
sed 's/-'${USER_ID}'//g;s/\.\(sav\|chr\|cs\)//g;'
|
||||
}
|
||||
|
||||
savegame-dirs() {
|
||||
/bin/ls -1td $GAME_GLOB
|
||||
}
|
||||
|
||||
list_hashes()
|
||||
{
|
||||
cd $CHROOT/$BASE_DIR
|
||||
|
||||
if verbose; then
|
||||
echo "Date Version Amount Players"
|
||||
echo "**************************************************************"
|
||||
|
||||
for folder in $(savegame-dirs); do
|
||||
local hash=${folder/$GAME_BASE/}
|
||||
local version_detail="$(hash-version-detail $hash)"
|
||||
local save_count="$(count-saves-in-dir "$folder")"
|
||||
/bin/ls -1tdl ${folder} 2>/dev/null | \
|
||||
sed "s/$GAME_BASE//g;" | \
|
||||
awk '{ printf "%3s %2s %s %17s %6s ",
|
||||
$6, $7, $8,
|
||||
"'"$version_detail"'",
|
||||
"'"$save_count"'" }'
|
||||
|
||||
for char in $(saves-in-dir "$folder" | strip-save-uid-extension)
|
||||
do
|
||||
echo -n "${char#$folder/saves/} "
|
||||
done
|
||||
|
||||
echo
|
||||
done
|
||||
else
|
||||
echo "Date Version Players in Games"
|
||||
echo "*******************************************************************"
|
||||
|
||||
for folder in $(savegame-dirs)
|
||||
do
|
||||
local hash=${folder/$GAME_BASE/}
|
||||
local version_detail="$(hash-version-detail $hash)"
|
||||
local save_count="$(count-saves-in-dir "$folder" '')"
|
||||
local sprint_save_count="$(count-saves-in-dir "$folder" 'sprint')"
|
||||
local zotdef_save_count="$(count-saves-in-dir "$folder" 'zotdef')"
|
||||
/bin/ls -1tdl ${folder} 2>/dev/null | \
|
||||
sed "s/$GAME_BASE//g;" | \
|
||||
awk '{ printf "%3s %2s %s %17s %6s in trunk, %3s in sprint, %3s in zotdef", $6, $7, $8,
|
||||
"'"$version_detail"'",
|
||||
"'"$save_count"'",
|
||||
"'"$sprint_save_count"'",
|
||||
"'"$zotdef_save_count"'" }'
|
||||
echo
|
||||
done
|
||||
fi
|
||||
}
|
||||
|
||||
PARAMS="$(echo "$*" | sed 's/[$*\/();|+]//g')"
|
||||
|
||||
if test $# -eq 0
|
||||
then
|
||||
if prompts-enabled; then
|
||||
echo "Usage: $(basename $0) [-q] [-v] [hash] [hash] ..."
|
||||
echo
|
||||
fi
|
||||
list_hashes
|
||||
echo
|
||||
exit 0
|
||||
fi
|
||||
|
||||
cd $CHROOT
|
||||
|
||||
|
||||
for raw_version in ${PARAMS}
|
||||
do
|
||||
version="$(canonicalise-version $raw_version)"
|
||||
if [[ -z "$version" ]]; then
|
||||
echo -e "Revision $raw_version unknown\n";
|
||||
exit 1
|
||||
fi
|
||||
|
||||
GAME_VER="$GAME-$version"
|
||||
GAME_SAVEDIR="$BASE_DIR/$GAME_VER"
|
||||
if test -f $BINPATH/$GAME_VER -a -d $GAME_SAVEDIR; then
|
||||
if [[ "$(count-saves-in-dir "$GAME_SAVEDIR")" > 0 && -z "$FORCE" ]]
|
||||
then
|
||||
echo "$GAME_SAVEDIR contains save games, use -f to delete anyway"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if prompts-enabled; then
|
||||
while { ps -fC $GAME_VER | awk '{ print $1" "$2"\t "$5" "$7"\t "$8" "$9" "$10 }' | grep ^"$DGL_USER"; }
|
||||
do
|
||||
echo "There are still active crawl processes running..."
|
||||
echo "-- Press RETURN to try again --"
|
||||
read
|
||||
done
|
||||
|
||||
echo "Removing ${version} from repository..."
|
||||
echo "delete from versions where hash=\"${version}\";"| sqlite3 ${VERSIONS_DB}
|
||||
rm $BINPATH/$GAME_VER
|
||||
rm -r $BASE_DIR/$GAME_VER
|
||||
else
|
||||
if { ps -fC $GAME_VER | awk '{ print $1" "$2"\t "$5" "$7"\t "$8" "$9" "$10 }' | grep ^"$DGL_USER" >/dev/null; }
|
||||
then
|
||||
echo "Revision ${version} is being played..."
|
||||
else
|
||||
echo "Removing ${version} from repository..."
|
||||
echo "delete from versions where hash=\"${version}\";"| sqlite3 ${VERSIONS_DB}
|
||||
rm $BINPATH/$GAME_VER
|
||||
rm -r $BASE_DIR/$GAME_VER
|
||||
fi
|
||||
fi
|
||||
else
|
||||
echo "Revision ${version} not found..."
|
||||
fi
|
||||
done
|
||||
|
||||
echo
|
||||
exit 0
|
|
@ -0,0 +1,110 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# ===========================================================================
|
||||
# Copyright (C) 2008, 2009, 2010, 2011 Marc H. Thoben
|
||||
# Copyright (C) 2011 Darshan Shaligram
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
# ===========================================================================
|
||||
#
|
||||
|
||||
set -u
|
||||
|
||||
USER_ID="%%DGL_UID%%"
|
||||
CHROOT="%%DGL_CHROOT%%"
|
||||
PREFIX="$CHROOT%%CHROOT_CRAWL_BASEDIR%%"
|
||||
VERSIONS_DB="%%VERSIONS_DB%%"
|
||||
|
||||
BINARY_MAIN_NAME="%%GAME%%"
|
||||
|
||||
C_NORMAL="\033[0m"
|
||||
C_YELLOW="\033[1;33m"
|
||||
C_GREEN="\033[1;32m"
|
||||
C_RED="\033[1;31m"
|
||||
|
||||
PARAMS="$(echo "$*" | sed 's/[$*\();.|+-]//g')"
|
||||
|
||||
if test ${#PARAMS} -eq 0
|
||||
then
|
||||
$(dirname $0)/remove-trunks.sh -v | grep -v "Usage:"
|
||||
echo "Usage: $(basename $0) <charname> [charname] ..."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
LATEST_GAME_HASH="$(echo "select hash from versions order by time desc limit 1;" | sqlite3 ${VERSIONS_DB})"
|
||||
|
||||
for char in ${PARAMS}
|
||||
do
|
||||
CHAR_NAME="${char}"
|
||||
GAME_MODE=""
|
||||
PS_MOD="rc"
|
||||
|
||||
SAVE_FOUND="$(/bin/ls -1rt ${PREFIX}/${BINARY_MAIN_NAME}-*/saves/${CHAR_NAME}-${USER_ID}.sav ${PREFIX}/${BINARY_MAIN_NAME}-*/saves/${CHAR_NAME}-${USER_ID}.chr ${PREFIX}/${BINARY_MAIN_NAME}-*/saves/${CHAR_NAME}{-${USER_ID},}.cs 2>/dev/null | head -n 1)"
|
||||
|
||||
if test ${#SAVE_FOUND} -ne 0
|
||||
then
|
||||
OUR_GAME_HASH="$(echo ${SAVE_FOUND} | sed "s|${PREFIX}/${BINARY_MAIN_NAME}-\(.*\)/saves/${CHAR_NAME}.*|\1|")"
|
||||
OUR_GAME_SV="$(echo select major,minor from versions where hash=\"${OUR_GAME_HASH}\"\; | sqlite3 -separator \. ${VERSIONS_DB})"
|
||||
echo -n "Char \"${CHAR_NAME}\" in ${OUR_GAME_HASH} (${OUR_GAME_SV}). "
|
||||
|
||||
if test "${OUR_GAME_HASH}" != "${LATEST_GAME_HASH}"
|
||||
then
|
||||
OUR_SGV_MAJOR="$(echo "select major from versions where hash=\"${OUR_GAME_HASH}\";" | sqlite3 ${VERSIONS_DB})"
|
||||
POSSIBLE_GAME_HASH="$(echo "select hash from versions where major=${OUR_SGV_MAJOR} order by time desc limit 1;" | sqlite3 ${VERSIONS_DB})"
|
||||
|
||||
if test "${OUR_GAME_HASH}" != "${POSSIBLE_GAME_HASH}"
|
||||
then
|
||||
POSSIBLE_GAME_SV="$(echo select major,minor from versions where hash=\"${POSSIBLE_GAME_HASH}\"\; | sqlite3 -separator \. ${VERSIONS_DB})"
|
||||
echo -n "Moving to ${POSSIBLE_GAME_HASH} (${POSSIBLE_GAME_SV}):"
|
||||
|
||||
if test "$(basename ${CHAR_NAME})" != "${CHAR_NAME}"
|
||||
then
|
||||
GAME_MODE="$(dirname ${CHAR_NAME})"
|
||||
CHAR_NAME="$(basename ${CHAR_NAME})"
|
||||
PS_MOD="${GAME_MODE}"
|
||||
fi
|
||||
|
||||
if { ps -fC ${BINARY_MAIN_NAME}-${OUR_GAME_HASH} | awk '{ print $8, $9, $10, $11 }' | grep "\-name ${CHAR_NAME} \-${PS_MOD}" &>/dev/null; }
|
||||
then
|
||||
echo -e " ${C_YELLOW}in use!${C_NORMAL}"
|
||||
continue
|
||||
fi
|
||||
|
||||
if test -d ${PREFIX}/${BINARY_MAIN_NAME}-${POSSIBLE_GAME_HASH}/saves/${GAME_MODE}
|
||||
then
|
||||
mv ${PREFIX}/${BINARY_MAIN_NAME}-${OUR_GAME_HASH}/saves/${GAME_MODE}/${CHAR_NAME}* ${PREFIX}/${BINARY_MAIN_NAME}-${OUR_GAME_HASH}/saves/${GAME_MODE}/start-${CHAR_NAME}-ns.prf ${PREFIX}/${BINARY_MAIN_NAME}-${POSSIBLE_GAME_HASH}/saves/${GAME_MODE}/
|
||||
if test $? -eq 0
|
||||
then
|
||||
echo -e " ${C_GREEN}successful.${C_NORMAL}"
|
||||
else
|
||||
echo -e " ${C_RED}failed1!${C_NORMAL}"
|
||||
continue
|
||||
fi
|
||||
|
||||
else
|
||||
echo -e " ${C_RED}failed2!${C_NORMAL}"
|
||||
continue
|
||||
fi
|
||||
else
|
||||
echo -e "${C_YELLOW}No transfer possible.${C_NORMAL}"
|
||||
fi
|
||||
else
|
||||
echo "No transfer necessary."
|
||||
fi
|
||||
else
|
||||
echo "Character \"${CHAR_NAME}\" not found."
|
||||
fi
|
||||
done
|
||||
|
||||
exit 0
|
|
@ -0,0 +1,191 @@
|
|||
import logging
|
||||
try:
|
||||
from collections import OrderedDict
|
||||
except ImportError:
|
||||
from ordereddict import OrderedDict
|
||||
|
||||
dgl_mode = True
|
||||
|
||||
bind_nonsecure = True # Set to false to only use SSL
|
||||
bind_address = "0.0.0.0"
|
||||
bind_port = 8080
|
||||
|
||||
bind_pairs = (
|
||||
("0.0.0.0", 8080),
|
||||
)
|
||||
|
||||
logging_config = {
|
||||
"filename": "%%CHROOT_WEBDIR%%/run/webtiles.log",
|
||||
"level": logging.INFO,
|
||||
"format": "%(asctime)s %(levelname)s: %(message)s"
|
||||
}
|
||||
|
||||
password_db = "%%CHROOT_LOGIN_DB%%"
|
||||
|
||||
static_path = "%%CHROOT_WEBDIR%%/static"
|
||||
template_path = "%%CHROOT_WEBDIR%%/templates/"
|
||||
|
||||
# Path for server-side unix sockets (to be used to communicate with crawl)
|
||||
server_socket_path = None # Uses global temp dir
|
||||
|
||||
# Server name, so far only used in the ttyrec metadata
|
||||
server_id = "ctvo"
|
||||
|
||||
# Disable caching of game data files
|
||||
game_data_no_cache = False
|
||||
|
||||
# Watch socket dirs for games not started by the server
|
||||
watch_socket_dirs = True
|
||||
|
||||
# Game configs
|
||||
# %n in paths is replaced by the current username
|
||||
games = OrderedDict([
|
||||
|
||||
("dcss-git", dict(
|
||||
name = "DCSS trunk",
|
||||
crawl_binary = "/bin/crawl-git-launcher.sh",
|
||||
send_json_options = True,
|
||||
rcfile_path = "%%CHROOT_RCFILESDIR%%/crawl-git/",
|
||||
macro_path = "%%CHROOT_RCFILESDIR%%/crawl-git/",
|
||||
morgue_path = "%%CHROOT_MORGUEDIR%%/%n/",
|
||||
morgue_url = "https://crawl.tildeverse.org/crawl/morgue/%n/",
|
||||
inprogress_path = "%%CHROOT_INPROGRESSDIR%%/crawl-git/",
|
||||
ttyrec_path = "%%CHROOT_TTYRECDIR%%/%n/",
|
||||
socket_path = "%%CHROOT_WEBDIR%%/sockets")),
|
||||
("spr-git", dict(
|
||||
name = "Sprint trunk",
|
||||
crawl_binary = "/bin/crawl-git-launcher.sh",
|
||||
send_json_options = True,
|
||||
rcfile_path = "%%CHROOT_RCFILESDIR%%/crawl-git/",
|
||||
macro_path = "%%CHROOT_RCFILESDIR%%/crawl-git/",
|
||||
morgue_path = "%%CHROOT_MORGUEDIR%%/%n/",
|
||||
morgue_url = "https://crawl.tildeverse.org/crawl/morgue/%n/",
|
||||
inprogress_path = "%%CHROOT_INPROGRESSDIR%%/crawl-git-sprint/",
|
||||
ttyrec_path = "%%CHROOT_TTYRECDIR%%/%n/",
|
||||
socket_path = "%%CHROOT_WEBDIR%%/sockets",
|
||||
options = ["-sprint"])),
|
||||
("tut-git", dict(
|
||||
name = "Tutorial trunk",
|
||||
crawl_binary = "/bin/crawl-git-launcher.sh",
|
||||
send_json_options = True,
|
||||
rcfile_path = "%%CHROOT_RCFILESDIR%%/crawl-git/",
|
||||
macro_path = "%%CHROOT_RCFILESDIR%%/crawl-git/",
|
||||
morgue_path = "%%CHROOT_MORGUEDIR%%/%n/",
|
||||
morgue_url = "https://crawl.tildeverse.org/crawl/morgue/%n/",
|
||||
inprogress_path = "%%CHROOT_INPROGRESSDIR%%/crawl-git-tut/",
|
||||
ttyrec_path = "%%CHROOT_TTYRECDIR%%/%n/",
|
||||
socket_path = "%%CHROOT_WEBDIR%%/sockets",
|
||||
options = ["-tutorial"])),
|
||||
|
||||
("dcss-0.22", dict(
|
||||
name = "DCSS 0.22",
|
||||
crawl_binary = "/bin/crawl-stable-launcher.sh",
|
||||
send_json_options = True,
|
||||
pre_options = [ "0.22" ],
|
||||
rcfile_path = "%%CHROOT_RCFILESDIR%%/crawl-0.22/",
|
||||
macro_path = "%%CHROOT_RCFILESDIR%%/crawl-0.22/",
|
||||
morgue_path = "%%CHROOT_MORGUEDIR%%/%n/",
|
||||
morgue_url = "https://crawl.tildeverse.org/crawl/morgue/%n/",
|
||||
inprogress_path = "%%CHROOT_INPROGRESSDIR%%/crawl-0.22/",
|
||||
ttyrec_path = "%%CHROOT_TTYRECDIR%%/%n/",
|
||||
socket_path = "%%CHROOT_WEBDIR%%/sockets")),
|
||||
("spr-0.22", dict(
|
||||
name = "Sprint 0.22",
|
||||
crawl_binary = "/bin/crawl-stable-launcher.sh",
|
||||
send_json_options = True,
|
||||
pre_options = [ "0.22" ],
|
||||
rcfile_path = "%%CHROOT_RCFILESDIR%%/crawl-0.22/",
|
||||
macro_path = "%%CHROOT_RCFILESDIR%%/crawl-0.22/",
|
||||
morgue_path = "%%CHROOT_MORGUEDIR%%/%n/",
|
||||
morgue_url = "https://crawl.tildeverse.org/crawl/morgue/%n/",
|
||||
inprogress_path = "%%CHROOT_INPROGRESSDIR%%/crawl-22-sprint/",
|
||||
ttyrec_path = "%%CHROOT_TTYRECDIR%%/%n/",
|
||||
socket_path = "%%CHROOT_WEBDIR%%/sockets",
|
||||
options = ["-sprint"])),
|
||||
("tut-0.22", dict(
|
||||
name = "Tutorial 0.22",
|
||||
crawl_binary = "/bin/crawl-git-launcher.sh",
|
||||
send_json_options = True,
|
||||
pre_options = [ "0.22" ],
|
||||
rcfile_path = "%%CHROOT_RCFILESDIR%%/crawl-0.22/",
|
||||
macro_path = "%%CHROOT_RCFILESDIR%%/crawl-0.22/",
|
||||
morgue_path = "%%CHROOT_MORGUEDIR%%/%n/",
|
||||
morgue_url = "https://crawl.tildeverse.org/crawl/morgue/%n/",
|
||||
inprogress_path = "%%CHROOT_INPROGRESSDIR%%/crawl-0.22-tut/",
|
||||
ttyrec_path = "%%CHROOT_TTYRECDIR%%/%n/",
|
||||
socket_path = "%%CHROOT_WEBDIR%%/sockets",
|
||||
options = ["-tutorial"])),
|
||||
])
|
||||
|
||||
dgl_status_file = "%%CHROOT_WEBDIR%%/run/status"
|
||||
|
||||
# Set to None not to read milestones
|
||||
milestone_file = [
|
||||
"%%CHROOT_CRAWL_BASEDIR%%/crawl-0.22/saves/milestones",
|
||||
"%%CHROOT_CRAWL_BASEDIR%%/crawl-0.22/saves/milestones-tutorial",
|
||||
"%%CHROOT_CRAWL_BASEDIR%%/crawl-0.22/saves/milestones-sprint",
|
||||
"%%CHROOT_CRAWL_BASEDIR%%/crawl-git/saves/milestones",
|
||||
"%%CHROOT_CRAWL_BASEDIR%%/crawl-git/saves/milestones-tutorial",
|
||||
"%%CHROOT_CRAWL_BASEDIR%%/crawl-git/saves/milestones-sprint",
|
||||
"%%CHROOT_CRAWL_GAMEDIR%%/saves/milestones",
|
||||
"%%CHROOT_CRAWL_GAMEDIR%%/saves/milestones-tutorial",
|
||||
"%%CHROOT_CRAWL_GAMEDIR%%/saves/milestones-sprint"
|
||||
]
|
||||
|
||||
status_file_update_rate = 5
|
||||
|
||||
recording_term_size = (80, 24)
|
||||
|
||||
max_connections = 500
|
||||
|
||||
# Script to initialize a user, e.g. make sure the paths
|
||||
# and the rc file exist. This is not done by the server
|
||||
# at the moment.
|
||||
init_player_program = "/bin/init-webtiles.sh"
|
||||
|
||||
#ssl_options = None # No SSL
|
||||
ssl_options = {
|
||||
"certfile": "/etc/ssl/crawl.tildeverse.org.pem",
|
||||
"keyfile": "/etc/ssl/private/crawl.tildeverse.org.pem",
|
||||
"ca_certs": "/etc/ssl/certs/ca-certificates.crt"
|
||||
}
|
||||
ssl_address = "0.0.0.0"
|
||||
ssl_port = 8081
|
||||
|
||||
ssl_bind_pairs = (
|
||||
("0.0.0.0", 8081),
|
||||
)
|
||||
|
||||
connection_timeout = 600
|
||||
max_idle_time = 5 * 60 * 60
|
||||
|
||||
# Seconds until stale HTTP connections are closed
|
||||
# This needs a patch currently not in mainline tornado.
|
||||
http_connection_timeout = 600
|
||||
|
||||
kill_timeout = 10 # Seconds until crawl is killed after HUP is sent
|
||||
|
||||
nick_regex = r"^[a-zA-Z0-9]{3,20}$"
|
||||
max_passwd_length = 20
|
||||
|
||||
# crypt() algorithm, e.g. "1" for MD5 or "6" for SHA-512; see crypt(3).
|
||||
# If false, use traditional DES (but then only the first eight characters
|
||||
# are significant).
|
||||
crypt_algorithm = "6"
|
||||
# If crypt_algorithm is true, the length of the salt string to use. If
|
||||
# crypt_algorithm is false, a two-character salt is used.
|
||||
crypt_salt_length = 16
|
||||
|
||||
login_token_lifetime = 7 # Days
|
||||
|
||||
uid = 1001 # If this is not None, the server will setuid to that (numeric) id
|
||||
gid = 1001 # after binding its sockets.
|
||||
|
||||
umask = None # e.g. 0077
|
||||
|
||||
chroot = "%%DGL_CHROOT%%"
|
||||
|
||||
pidfile = "%%CHROOT_WEBDIR%%/run/webtiles.pid"
|
||||
daemon = True # If true, the server will detach from the session after startup
|
||||
|
||||
player_url = "http://crawl.akrasiac.org/scoring/players/%s.html"
|
|
@ -0,0 +1,4 @@
|
|||
#! /bin/bash
|
||||
|
||||
perl -lne 'print $1 if /#define\s+TAG_MAJOR_VERSION\s+(\d+)/' \
|
||||
source/tag-version.h
|
|
@ -0,0 +1,92 @@
|
|||
#!/bin/bash
|
||||
|
||||
VERSION=${1:-0.17}
|
||||
|
||||
# Quoting for =~ changed from bash 3.0 to 3.2; using a variable for the
|
||||
# regexp works with both.
|
||||
VERS_RE='^[0-9]+.[0-9]+$'
|
||||
if [[ ! $VERSION =~ $VERS_RE ]]; then
|
||||
echo "Bad crawl version $VERSION"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
set -e
|
||||
lock-or-die crawl-update "someone is already updating the crawl build"
|
||||
|
||||
source $DGL_CONF_HOME/crawl-git.conf
|
||||
GAME=crawl-$VERSION
|
||||
|
||||
export DESTDIR=$CRAWL_BASEDIR
|
||||
BRANCH=stone_soup-$VERSION
|
||||
if [[ $VERSION != [0-9]* ]]; then
|
||||
BRANCH=$VERSION
|
||||
fi
|
||||
|
||||
check-crawl-basedir-exists
|
||||
enable-prompts $*
|
||||
|
||||
TODAY="$(dgl-today)"
|
||||
|
||||
# Second argument can be a revision (SHA) to build
|
||||
REVISION="$2"
|
||||
./update-public-repository.sh $BRANCH "$REVISION"
|
||||
|
||||
REVISION="$(git-do rev-parse HEAD | cut -c 1-7)"
|
||||
REVISION_FULL="$(git-do describe --long HEAD)"
|
||||
VER_STR="$(git-do describe HEAD)"
|
||||
VER_STR_OLD="$(($CRAWL_BINARY_PATH/$GAME -version 2>/dev/null || true) | sed -ne 's/Crawl version //p')"
|
||||
REVISION_OLD="${VER_STR_OLD##*-g}"
|
||||
|
||||
[[ "$REVISION" == "$REVISION_OLD" || "$VER_STR" = "$VER_STR_OLD" ]] && \
|
||||
abort-saying "Nothing new to install at the moment: you asked for $REVISION_FULL and it's already installed"
|
||||
|
||||
prompt "start update build"
|
||||
|
||||
cd $CRAWL_REPOSITORY_DIR/crawl-ref
|
||||
|
||||
echo "Copying CREDITS to docs/crawl_credits.txt..."
|
||||
cp CREDITS.txt docs/crawl_credits.txt
|
||||
|
||||
dgl-git-log() {
|
||||
git-do log --pretty=tformat:"--------------------------------------------------------------------------------%n%h | %an | %ci%n%n%s%n%b" "$@" | grep -v "git-svn-id" | awk 1 RS= ORS="\n\n" | fold -s
|
||||
}
|
||||
|
||||
echo "Creating changelog in docs/crawl_changelog.txt..."
|
||||
dgl-git-log $BRANCH > docs/crawl_changelog.txt
|
||||
|
||||
if prompts-enabled; then
|
||||
echo "Changes to $BRANCH from $REVISION_OLD .. $REVISION"
|
||||
dgl-git-log ${REVISION_OLD:+$REVISION_OLD..}${REVISION} | less
|
||||
fi
|
||||
|
||||
prompt "compile ${GAME} (${REVISION})"
|
||||
|
||||
# REMEMBER to adjust /var/lib/dgamelaunch/sbin/install-stable.sh as well if make parameters change!
|
||||
##################################################################################################
|
||||
|
||||
say-do crawl-do nice make -C source \
|
||||
GAME=${GAME} \
|
||||
GAME_MAIN=${GAME} MCHMOD=0755 MCHMOD_SAVEDIR=755 \
|
||||
INSTALL_UGRP=$CRAWL_UGRP \
|
||||
WEBTILES=YesPlease USE_DGAMELAUNCH=YesPlease WIZARD=YesPlease \
|
||||
STRIP=true DESTDIR=${DESTDIR} prefix= bin_prefix=/bin \
|
||||
SAVEDIR=$CHROOT_CRAWL_BASEDIR/${GAME}/saves \
|
||||
DATADIR=$CHROOT_CRAWL_BASEDIR/${GAME}/data \
|
||||
WEBDIR=$CHROOT_CRAWL_BASEDIR/${GAME}/data/web \
|
||||
USE_PCRE=y \
|
||||
EXTERNAL_FLAGS_L="-g"
|
||||
|
||||
prompt "install ${GAME} (${REVISION})"
|
||||
|
||||
say-do sudo -H $DGL_CHROOT/sbin/install-stable.sh "$VERSION"
|
||||
|
||||
if [[ $VERSION = [0-9]* ]]; then
|
||||
SUPER_VER="Stable"
|
||||
else
|
||||
SUPER_VER="Experimental"
|
||||
fi
|
||||
|
||||
announce "$SUPER_VER ($VERSION) branch on $DGL_SERVER updated to: ${REVISION_FULL}"
|
||||
|
||||
echo "All done."
|
||||
echo
|
|
@ -0,0 +1,87 @@
|
|||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
lock-or-die crawl-update "someone is already updating the crawl build"
|
||||
|
||||
source $DGL_CONF_HOME/crawl-git.conf
|
||||
check-versions-db-exists
|
||||
|
||||
export DESTDIR=$CRAWL_BASEDIR
|
||||
|
||||
check-crawl-basedir-exists
|
||||
enable-prompts $*
|
||||
|
||||
TODAY="$(dgl-today)"
|
||||
|
||||
# First argument can be a revision (SHA) to build
|
||||
REVISION="$1"
|
||||
./update-public-repository.sh $BRANCH "$REVISION"
|
||||
|
||||
REVISION="$(git-do rev-parse HEAD | cut -c 1-10)"
|
||||
REVISION_FULL="$(git-do describe --long HEAD)"
|
||||
REVISION_OLD="$(echo "select hash from versions order by time desc limit 1;" | sqlite3 ${VERSIONS_DB})"
|
||||
|
||||
[[ "$REVISION" == "$REVISION_OLD" ]] && \
|
||||
abort-saying "Nothing new to install at the moment: you asked for $REVISION_FULL and it's already installed"
|
||||
|
||||
prompt "start update build"
|
||||
|
||||
cd $CRAWL_REPOSITORY_DIR/crawl-ref
|
||||
|
||||
echo "Copying CREDITS to docs/crawl_credits.txt..."
|
||||
cp CREDITS.txt docs/crawl_credits.txt
|
||||
|
||||
dgl-git-log() {
|
||||
git-do log --pretty=tformat:"--------------------------------------------------------------------------------%n%h | %an | %ci%n%n%s%n%b" "$@" | grep -v "git-svn-id" | awk 1 RS= ORS="\n\n" | fold -s
|
||||
}
|
||||
|
||||
echo "Creating changelog in docs/crawl_changelog.txt..."
|
||||
dgl-git-log $BRANCH > docs/crawl_changelog.txt
|
||||
|
||||
if prompts-enabled; then
|
||||
echo "Changes to $BRANCH from $REVISION_OLD .. $REVISION"
|
||||
dgl-git-log ${REVISION_OLD}..${REVISION} | less
|
||||
fi
|
||||
|
||||
prompt "compile ${GAME}-${REVISION}"
|
||||
|
||||
# REMEMBER to adjust /var/lib/dgamelaunch/sbin/install-trunk.sh as well if make parameters change!
|
||||
##################################################################################################
|
||||
|
||||
say-do crawl-do nice make -C source \
|
||||
GAME=${GAME}-${REVISION} \
|
||||
GAME_MAIN=${GAME} MCHMOD=0755 MCHMOD_SAVEDIR=755 \
|
||||
INSTALL_UGRP=$CRAWL_UGRP \
|
||||
WEBTILES=YesPlease USE_DGAMELAUNCH=YesPlease WIZARD=YesPlease \
|
||||
STRIP=true DESTDIR=${DESTDIR} prefix= bin_prefix=/bin \
|
||||
SAVEDIR=$CHROOT_CRAWL_BASEDIR/${GAME}-${REVISION}/saves \
|
||||
DATADIR=$CHROOT_CRAWL_BASEDIR/${GAME}-${REVISION}/data \
|
||||
WEBDIR=$CHROOT_CRAWL_BASEDIR/${GAME}-${REVISION}/data/web \
|
||||
SHAREDDIR=$CHROOT_CRAWL_BASEDIR/${GAME}/saves \
|
||||
USE_PCRE=y \
|
||||
EXTERNAL_FLAGS_L="-g"
|
||||
|
||||
prompt "install ${GAME}-${REVISION}"
|
||||
|
||||
if [[ "$(uname)" != "Darwin" ]] && {
|
||||
ps -fC ${GAME}-${REVISION} |
|
||||
awk '{ print $1" "$2"\t "$5" "$7"\t "$8" "$9" "$10 }' |
|
||||
grep ^"$DGL_USER";
|
||||
}
|
||||
then
|
||||
abort-saying "There are already active instances of this version (${REVISION_FULL}) running"
|
||||
fi
|
||||
|
||||
echo "Searching for version tags..."
|
||||
export SGV_MAJOR=$($CRAWL_BUILD_DIR/crawl-tag-major-version.sh)
|
||||
[[ -n "$SGV_MAJOR" ]] || abort-saying "Couldn't find save major version"
|
||||
echo "Save major version: $SGV_MAJOR"
|
||||
export SGV_MINOR="0"
|
||||
|
||||
say-do sudo -H $DGL_CHROOT/sbin/install-trunk.sh "$REVISION" \
|
||||
"$REVISION_FULL" "$SGV_MAJOR" "$SGV_MINOR"
|
||||
|
||||
announce "Unstable branch on $DGL_SERVER updated to: ${REVISION_FULL} (${SGV_MAJOR})"
|
||||
|
||||
echo "All done."
|
||||
echo
|
|
@ -0,0 +1,40 @@
|
|||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
source $DGL_CONF_HOME/sh-utils
|
||||
source $DGL_CONF_HOME/crawl-git.conf
|
||||
|
||||
REPO_DIR=$PWD/$CRAWL_REPOSITORY_DIR
|
||||
|
||||
clone-crawl-ref() {
|
||||
if [[ -d "$CRAWL_REPOSITORY_DIR" && -d "$CRAWL_REPOSITORY_DIR/.git" ]]; then
|
||||
return 0
|
||||
fi
|
||||
CMDLINE="git clone $CRAWL_GIT_URL $CRAWL_REPOSITORY_DIR"
|
||||
say "$CMDLINE"
|
||||
$CMDLINE
|
||||
}
|
||||
|
||||
update-crawl-ref() {
|
||||
say "Updating git repository $REPO_DIR"
|
||||
( cd $REPO_DIR && git checkout -f &&
|
||||
git checkout $BRANCH &&
|
||||
git pull )
|
||||
if [[ -n "$REVISION" ]]; then
|
||||
say "Checking out requested revision: $REVISION"
|
||||
( cd $REPO_DIR && git checkout "$REVISION" )
|
||||
fi
|
||||
}
|
||||
|
||||
update-submodules() {
|
||||
say "Updating git submodules in $REPO_DIR"
|
||||
( cd $REPO_DIR && git submodule update --init )
|
||||
}
|
||||
|
||||
BRANCH=$1
|
||||
REVISION="$2"
|
||||
[[ -n "$BRANCH" ]] || abort-saying "$0: Checkout branch not specified!"
|
||||
clone-crawl-ref
|
||||
update-crawl-ref
|
||||
update-submodules
|
|
@ -0,0 +1,13 @@
|
|||
CREATE TABLE versions(hash TEXT(7) PRIMARY KEY,
|
||||
description STRING,
|
||||
time INTEGER,
|
||||
major INTEGER,
|
||||
minor INTEGER,
|
||||
wizard INTEGER);
|
||||
CREATE TABLE branches(name TEXT(50) NOT NULL PRIMARY KEY,
|
||||
git TEXT(50) NOT NULL,
|
||||
description STRING NOT NULL,
|
||||
abbrev TEXT(1) NOT NULL,
|
||||
sprintabbr TEXT(1), -- null means no sprint
|
||||
ord INTEGER, -- null to disable?
|
||||
wizard INTEGER NOT NULL); -- boolean?
|
|
@ -0,0 +1,64 @@
|
|||
#! /bin/bash
|
||||
|
||||
[[ -z "$BRANCH" ]] && BRANCH="master"
|
||||
|
||||
CONFIG_READ="true"
|
||||
|
||||
export GAME="crawl-git"
|
||||
CRAWL_BUILD_DIR=$DGL_CONF_HOME/crawl-build
|
||||
CRAWL_REPOSITORY_DIR=crawl-git-repository
|
||||
CRAWL_REPO=$DGL_CONF_HOME/crawl-build/$CRAWL_REPOSITORY_DIR
|
||||
CRAWL_GIT_URL=https://github.com/crawl/crawl.git
|
||||
|
||||
export CHROOT_CRAWL_BINARY_PATH="/usr/games"
|
||||
export CRAWL_BINARY_PATH="$DGL_CHROOT$CHROOT_CRAWL_BINARY_PATH"
|
||||
|
||||
export CHROOT_CRAWL_STABLE_GAMEDIR=/var/games
|
||||
|
||||
# Path in chroot where the build's data and savedir will be created:
|
||||
export CHROOT_CRAWL_BASEDIR=/crawl-master
|
||||
export CHROOT_CRAWL_GAMEDIR=$CHROOT_CRAWL_BASEDIR/$GAME
|
||||
|
||||
# Build config:
|
||||
export CRAWL_UGRP=crawl:crawl
|
||||
|
||||
export CRAWL_BASEDIR=$DGL_CHROOT$CHROOT_CRAWL_BASEDIR
|
||||
export CRAWL_GAMEDIR=$DGL_CHROOT$CHROOT_CRAWL_GAMEDIR
|
||||
|
||||
export CHROOT_VERSIONS_DB="/crawl-versions.db3"
|
||||
export VERSIONS_DB="$DGL_CHROOT$CHROOT_VERSIONS_DB"
|
||||
|
||||
check-versions-db-exists() {
|
||||
if [[ ! -f "$VERSIONS_DB" ]]; then
|
||||
echo -e "Crawl version db $VERSIONS_DB does not exist"
|
||||
echo -e "Please run 'dgl create-versions-db' as root to create it."
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
check-crawl-basedir-exists() {
|
||||
if [[ ! -d "$CRAWL_GAMEDIR" ]]; then
|
||||
echo -e "Chroot crawl game directory $CRAWL_GAMEDIR does not exist."
|
||||
echo -e "Please run 'dgl create-crawl-gamedir' to create it."
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
crawl-repo-do() {
|
||||
( cd $CRAWL_REPO && "$@" )
|
||||
}
|
||||
|
||||
crawl-do() {
|
||||
( cd $CRAWL_REPO/crawl-ref && "$@" )
|
||||
}
|
||||
|
||||
git-do() {
|
||||
crawl-repo-do git "$@"
|
||||
}
|
||||
|
||||
|
||||
latest-game-hash() {
|
||||
query <<EOF
|
||||
SELECT hash FROM versions ORDER BY time DESC LIMIT 1;
|
||||
EOF
|
||||
}
|
|
@ -0,0 +1,508 @@
|
|||
# Global config variables:
|
||||
|
||||
# Max amount of registered users to allow.
|
||||
maxusers = 64000
|
||||
|
||||
allow_new_nicks = yes
|
||||
|
||||
# Max length for newly registered nicks. Must be less than 20.
|
||||
# By default, NetHack only stores the first 10 chars of a name into
|
||||
# the record/logfile.
|
||||
maxnicklen = 20
|
||||
|
||||
# Set the default watching-screen sorting mode. Can be one of
|
||||
# "username", "game", "windowsize", "starttime" or "idletime".
|
||||
# "username" is the default.
|
||||
sortmode = "username"
|
||||
|
||||
# Maximum idle time in menus
|
||||
menu_max_idle_time = 3600
|
||||
|
||||
# Path to a prepared chroot jail.
|
||||
chroot_path = "%%DGL_CHROOT%%/"
|
||||
|
||||
# From inside the jail, dgamelaunch's working directory for rcfiles/ttyrec/etc
|
||||
dglroot = "%%CHROOT_DGLDIR%%/"
|
||||
|
||||
# Server ID string
|
||||
server_id = "CTVO - Dungeon Crawl Stone Soup - crawl.tildeverse.org"
|
||||
|
||||
|
||||
# From inside the jail, location of a banner file, the topmost line will be
|
||||
# shown in submenus that cannot be defined separately.
|
||||
# Some string substitution is done for the file:
|
||||
# $VERSION replaced with "dgamelaunch v" + dgl version number.
|
||||
# $SERVERID replaced with the server_id string, as defined above.
|
||||
banner = "%%CHROOT_DGLDIR%%/data/dgl-banner"
|
||||
|
||||
# The following two options are fairly insecure. They will force us to
|
||||
# load the password/group database into memory while still having root
|
||||
# privileges. Replace them with shed_uid/shed_gid entries as soon as
|
||||
# possible if you decide to use them. dgamelaunch will inform you of
|
||||
# the uids/gids corresponding to your choices when it loads.
|
||||
#
|
||||
# Note that shed_uid and shed_gid will always take precedence over
|
||||
# shed_user and shed_group if they are specified.
|
||||
|
||||
# shed_user: username to shed privileges to
|
||||
# shed_user = crawl
|
||||
# shed_group: group name to shed privileges to
|
||||
# shed_group = crawl
|
||||
|
||||
# Preferably, you may use the respective gids/uids.
|
||||
# crawl/crawl
|
||||
shed_uid = 1001
|
||||
shed_gid = 1001
|
||||
|
||||
# The defaults are usually just fine for this. passwd refers to the file
|
||||
# that stores the user database, and lockfile is only used internally by
|
||||
# dgamelaunch.
|
||||
|
||||
passwd = "%%CHROOT_DGLDIR%%/data/dgl-login"
|
||||
lockfile = "%%CHROOT_DGLDIR%%/data/dgl-lock"
|
||||
|
||||
watch_columns = [ ["", "", 0, "%s)"],
|
||||
["User", "username", 3, "%-15s"],
|
||||
["Game", "game", 19, "%-9s"],
|
||||
["Where", "extrainfo", 33, "%-18s"],
|
||||
["Term", "windowsize", 53, "%s"],
|
||||
["Idle", "idletime", 62, "%-10s"],
|
||||
["Viewers", "watchers", 73, "%4s"]
|
||||
]
|
||||
|
||||
#
|
||||
# define some commands that are run when something happens. format is
|
||||
# commands [ <time> ] = <command> ...
|
||||
#
|
||||
# <time> can be one of:
|
||||
# dglstart = when someone telnets in
|
||||
# login = when user has logged in
|
||||
# register = right after a new user is registered
|
||||
# gamestart = just before a game is started
|
||||
#
|
||||
# <command> is:
|
||||
# mkdir "foo" = create a directory "foo"
|
||||
# chdir "foo" = change current work dir to "foo"
|
||||
# cp "foo" "bar" = copy file "foo" to "bar", overwriting previous "bar"
|
||||
# ifnxcp "foo" "bar" = copy file "foo" to "bar", if "bar" doesn't exist
|
||||
# unlink "foo" = delete file "foo"
|
||||
# setenv "foo" "bar" = set environment variable "foo" to "bar"
|
||||
# exec "foo" "bar" = execute "foo" with "bar" as it's param
|
||||
# chpasswd = do the change password prompting, if logged in
|
||||
# chmail = do the change email prompting, if logged in
|
||||
# watch_menu = go to the watching menu
|
||||
# quit = quit dgl
|
||||
# ask_login = do the login prompting, if not logged in
|
||||
# ask_register = do register new user prompting, if not logged in and
|
||||
# registration of new nicks is allowed.
|
||||
# edit_options "foo" = edit options for game which has the short name "foo"
|
||||
# (user must be logged in)
|
||||
# play_game "foo" = start game which has the short name "foo"
|
||||
# (user must be logged in)
|
||||
# submenu "foo" = go to submenu "foo"
|
||||
# return = return from submenu
|
||||
#
|
||||
# The commands will be done inside the chroot and with the uid and gid
|
||||
# defined above.
|
||||
# Parameters to the commands are subject to variable substitution:
|
||||
# %r = dglroot, as defined above
|
||||
# %n = user nick, if user is logged in
|
||||
# %u = shed_uid, as defined above, but numeric
|
||||
# %g = game name, if user has selected a game.
|
||||
# %s = short game name, if user has selected a game.
|
||||
#
|
||||
# eg. commands[login] = mkdir "foo", unlink "bar", setenv "Z" "foo"
|
||||
#
|
||||
|
||||
commands[register] = mkdir "%%CHROOT_TTYRECDIR%%/%n",
|
||||
ifnxcp "%rdata/crawl-git.macro" "%rrcfiles/crawl-git/%n.macro",
|
||||
ifnxcp "%rdata/crawl-git-settings/init.txt" "%rrcfiles/crawl-git/%n.rc",
|
||||
ifnxcp "%rdata/crawl-git.macro" "%rrcfiles/crawl-0.22/%n.macro",
|
||||
ifnxcp "%rdata/crawl-0.22-settings/init.txt" "%rrcfiles/crawl-0.22/%n.rc"
|
||||
|
||||
commands[login] = mkdir "%%CHROOT_TTYRECDIR%%/%n",
|
||||
ifnxcp "%rdata/crawl-git.macro" "%rrcfiles/crawl-git/%n.macro",
|
||||
ifnxcp "%rdata/crawl-git-settings/init.txt" "%rrcfiles/crawl-git/%n.rc",
|
||||
ifnxcp "%rdata/crawl-git.macro" "%rrcfiles/crawl-0.22/%n.macro",
|
||||
ifnxcp "%rdata/crawl-0.22-settings/init.txt" "%rrcfiles/crawl-0.22/%n.rc"
|
||||
|
||||
# commands[gamestart] =
|
||||
# mkdir "%%CHROOT_TTYRECDIR%%/%n",
|
||||
# mkdir "%%CHROOT_TTYRECDIR%%/%n/sprint",
|
||||
# mkdir "%%CHROOT_TTYRECDIR%%/%n/zotdef",
|
||||
# setenv "SIMPLEMAIL" "1",
|
||||
# setenv "MAIL" "%%CHROOT_MAILSPOOL%%/%n"
|
||||
|
||||
menu["mainmenu_anon"] {
|
||||
bannerfile = "%%CHROOT_DGLDIR%%/data/menus/main_anon.txt"
|
||||
# cursor = (5,18)
|
||||
commands["lL"] = ask_login
|
||||
commands["rR"] = ask_register
|
||||
commands["wW"] = watch_menu
|
||||
commands["qQ"] = quit
|
||||
}
|
||||
|
||||
menu["mainmenu_admin"] {
|
||||
bannerfile = "%%CHROOT_DGLDIR%%/data/menus/main_admin.txt"
|
||||
commands["cC"] = chpasswd
|
||||
commands["eE"] = chmail
|
||||
commands["wW"] = watch_menu
|
||||
commands["tT"] = submenu "crawl-git"
|
||||
commands["0"] = submenu "crawl-0.22"
|
||||
commands["pP"] = play_game "dcss-0.22"
|
||||
commands["sS"] = play_game "spr-0.22"
|
||||
commands["qQ"] = quit
|
||||
}
|
||||
|
||||
menu["mainmenu_user"] {
|
||||
bannerfile = "%%CHROOT_DGLDIR%%/data/menus/main_user.txt"
|
||||
commands["cC"] = chpasswd
|
||||
commands["eE"] = chmail
|
||||
commands["wW"] = watch_menu
|
||||
commands["tT"] = submenu "crawl-git"
|
||||
commands["0"] = submenu "crawl-0.22"
|
||||
commands["pP"] = play_game "dcss-0.22"
|
||||
commands["sS"] = play_game "spr-0.22"
|
||||
commands["qQ"] = quit
|
||||
}
|
||||
|
||||
menu["watchmenu_help"] {
|
||||
bannerfile = "%%CHROOT_DGLDIR%%/data/menus/watchmenu_help.txt"
|
||||
commands["qQ "] = return
|
||||
}
|
||||
|
||||
menu["crawl-git"] {
|
||||
bannerfile = "%%CHROOT_DGLDIR%%/data/menus/crawl_git.txt"
|
||||
commands["o"] = exec "ee" "%rrcfiles/crawl-git/%n.rc"
|
||||
commands["O"] = exec "virus" "%rrcfiles/crawl-git/%n.rc"
|
||||
commands["m"] = exec "ee" "%rrcfiles/crawl-git/%n.macro"
|
||||
commands["M"] = exec "virus" "%rrcfiles/crawl-git/%n.macro"
|
||||
commands["v"] = exec "ee" "%%CHROOT_CRAWL_GAMEDIR%%/data/docs/crawl_changelog.txt"
|
||||
commands["V"] = exec "virus" "%%CHROOT_CRAWL_GAMEDIR%%/data/docs/crawl_changelog.txt"
|
||||
commands["pP"] = play_game "dcss-git"
|
||||
commands["tT"] = play_game "tut-git"
|
||||
commands["sS"] = play_game "spr-git"
|
||||
commands["A"] = submenu "crawl-git-adv"
|
||||
commands["wW"] = watch_menu
|
||||
commands["qQ"] = return
|
||||
}
|
||||
menu["crawl-0.22"] {
|
||||
bannerfile = "%%CHROOT_DGLDIR%%/data/menus/crawl-0.22.txt"
|
||||
commands["o"] = exec "ee" "%rrcfiles/crawl-0.22/%n.rc"
|
||||
commands["O"] = exec "virus" "%rrcfiles/crawl-0.22/%n.rc"
|
||||
commands["m"] = exec "ee" "%rrcfiles/crawl-0.22/%n.macro"
|
||||
commands["M"] = exec "virus" "%rrcfiles/crawl-0.22/%n.macro"
|
||||
commands["v"] = exec "ee" "%%CHROOT_CRAWL_GAMEDIR%%/crawl-0.22/data/docs/crawl_changelog.txt"
|
||||
commands["V"] = exec "virus" "%%CHROOT_CRAWL_GAMEDIR%%/crawl-0.22/data/docs/crawl_changelog.txt"
|
||||
commands["pP"] = play_game "dcss-0.22"
|
||||
commands["tT"] = play_game "tut-0.22"
|
||||
commands["sS"] = play_game "spr-0.22"
|
||||
commands["A"] = submenu "crawl-0.22-adv"
|
||||
commands["wW"] = watch_menu
|
||||
commands["qQ"] = return
|
||||
}
|
||||
|
||||
|
||||
|
||||
menu["crawl-git-adv"] {
|
||||
bannerfile = "%%CHROOT_DGLDIR%%/data/menus/crawl_git_adv.txt"
|
||||
commands["B"] =
|
||||
exec "/bin/savegame-backup.sh" "%n crawl-git %%CHROOT_CRAWL_BASEDIR%%",
|
||||
return
|
||||
commands["O"] =
|
||||
cp "%rdata/crawl-git-settings/init.txt" "%rrcfiles/crawl-git/%n.rc",
|
||||
return
|
||||
commands["M"] =
|
||||
cp "%rdata/crawl-git.macro" "%rrcfiles/crawl-git/%n.macro",
|
||||
return
|
||||
commands["qQ"] = return
|
||||
}
|
||||
menu["crawl-0.22-adv"] {
|
||||
bannerfile = "%%CHROOT_DGLDIR%%/data/menus/crawl-0.22_adv.txt"
|
||||
commands["B"] =
|
||||
exec "/bin/savegame-backup.sh" "%n crawl-0.22 %%CHROOT_CRAWL_BASEDIR%%",
|
||||
return
|
||||
commands["O"] =
|
||||
cp "%rdata/crawl-0.22-settings/init.txt" "%rrcfiles/crawl-0.22/%n.rc",
|
||||
return
|
||||
commands["M"] =
|
||||
cp "%rdata/crawl-git.macro" "%rrcfiles/crawl-0.22/%n.macro",
|
||||
return
|
||||
commands["qQ"] = return
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
##############################################################################
|
||||
## NON-CRAWL GAMES
|
||||
##############################################################################
|
||||
#DEFINE {
|
||||
# game_path = "/bin/atc-launcher.sh"
|
||||
# game_name = "atc"
|
||||
# short_name = "atc"
|
||||
# game_args = "/bin/atc-launcher.sh", "%n"
|
||||
# inprogressdir = "%rinprogress/atc/"
|
||||
# ttyrecdir = "%%CHROOT_TTYRECDIR%%-atc/"
|
||||
# encoding = "UTF-8"
|
||||
# spooldir = "%%CHROOT_MAILSPOOL%%/"
|
||||
#}
|
||||
#
|
||||
#DEFINE {
|
||||
# game_path = "/bin/boggle-launcher.sh"
|
||||
# game_name = "boggle"
|
||||
# short_name = "boggle"
|
||||
# game_args = "/bin/boggle-launcher.sh", "%n"
|
||||
# inprogressdir = "%rinprogress/boggle/"
|
||||
# ttyrecdir = "%%CHROOT_TTYRECDIR%%-boggle/"
|
||||
# encoding = "UTF-8"
|
||||
# spooldir = "%%CHROOT_MAILSPOOL%%/"
|
||||
#}
|
||||
#
|
||||
#DEFINE {
|
||||
# game_path = "/usr/games/robotfindskitten"
|
||||
# game_name = "robotfindskitten"
|
||||
# short_name = "rfk"
|
||||
# game_args = "/usr/games/robotfindskitten"
|
||||
# inprogressdir = "%rinprogress/rfk/"
|
||||
# ttyrecdir = "%%CHROOT_TTYRECDIR%%-rfk/"
|
||||
# encoding = "UTF-8"
|
||||
# spooldir = "%%CHROOT_MAILSPOOL%%/"
|
||||
#}
|
||||
|
||||
##############################################################################
|
||||
## GIT
|
||||
##############################################################################
|
||||
DEFINE {
|
||||
game_path = "/bin/crawl-git-launcher.sh"
|
||||
game_name = "Crawl (trunk)"
|
||||
short_name = "dcss-git"
|
||||
|
||||
game_args = "/bin/crawl-git-launcher.sh",
|
||||
"-name", "%n",
|
||||
"-rc", "%rrcfiles/crawl-git/%n.rc",
|
||||
"-macro", "%rrcfiles/crawl-git/%n.macro",
|
||||
"-webtiles-socket", "%%CHROOT_CRAWL_BASEDIR%%/webserver/sockets/%n:dcss-git.sock",
|
||||
"-morgue", "%rmorgue/%n/"
|
||||
|
||||
extra_info_file = "%rmorgue/%n/%n.dglwhere"
|
||||
|
||||
#
|
||||
# From inside the jail, where dgamelaunch should put mail - should
|
||||
# match up with the game's settings.
|
||||
spooldir = "%%CHROOT_MAILSPOOL%%/"
|
||||
|
||||
max_idle_time = 3600
|
||||
|
||||
# make sure the inprogress dir actually exists. default is "inprogress/"
|
||||
# each game you define here must have it's own.
|
||||
inprogressdir = "%rinprogress/crawl-git/"
|
||||
ttyrecdir = "%%CHROOT_TTYRECDIR%%/%n/"
|
||||
|
||||
commands =
|
||||
ifnxcp "%rdata/crawl-git.macro" "%rrcfiles/crawl-git/%n.macro",
|
||||
ifnxcp "%rdata/crawl-git-settings/init.txt" "%rrcfiles/crawl-git/%n.rc",
|
||||
setenv "MAIL" "%%CHROOT_MAILSPOOL%%/%n",
|
||||
setenv "SIMPLEMAIL" "1",
|
||||
unlink "%%CHROOT_MAILSPOOL%%/%n",
|
||||
mkdir "%rmorgue/%n/"
|
||||
|
||||
encoding = "UTF-8"
|
||||
}
|
||||
|
||||
##############################################################################
|
||||
DEFINE {
|
||||
game_path = "/bin/crawl-git-launcher.sh"
|
||||
game_name = "Sprint (trunk)"
|
||||
short_name = "spr-git"
|
||||
|
||||
game_args = "/bin/crawl-git-launcher.sh",
|
||||
"-name", "%n",
|
||||
"-rc", "%rrcfiles/crawl-git/%n.rc",
|
||||
"-macro", "%rrcfiles/crawl-git/%n.macro",
|
||||
"-webtiles-socket", "%%CHROOT_CRAWL_BASEDIR%%/webserver/sockets/%n:spr-git.sock",
|
||||
"-morgue", "%rmorgue/%n/",
|
||||
"-sprint"
|
||||
|
||||
extra_info_file = "%rmorgue/%n/%n.dglwhere"
|
||||
|
||||
#
|
||||
# From inside the jail, where dgamelaunch should put mail - should
|
||||
# match up with the game's settings.
|
||||
spooldir = "%%CHROOT_MAILSPOOL%%/"
|
||||
|
||||
max_idle_time = 3600
|
||||
|
||||
# make sure the inprogress dir actually exists. default is "inprogress/"
|
||||
# each game you define here must have it's own.
|
||||
inprogressdir = "%rinprogress/crawl-git-sprint/"
|
||||
ttyrecdir = "%%CHROOT_TTYRECDIR%%/%n/"
|
||||
|
||||
commands =
|
||||
ifnxcp "%rdata/crawl-git.macro" "%rrcfiles/crawl-git/%n.macro",
|
||||
ifnxcp "%rdata/crawl-git-settings/init.txt" "%rrcfiles/crawl-git/%n.rc",
|
||||
setenv "MAIL" "%%CHROOT_MAILSPOOL%%/%n",
|
||||
setenv "SIMPLEMAIL" "1",
|
||||
unlink "%%CHROOT_MAILSPOOL%%/%n",
|
||||
mkdir "%rmorgue/%n/"
|
||||
|
||||
encoding = "UTF-8"
|
||||
}
|
||||
|
||||
##############################################################################
|
||||
DEFINE {
|
||||
game_path = "/bin/crawl-git-launcher.sh"
|
||||
game_name = "Tutorial (trunk)"
|
||||
short_name = "tut-git"
|
||||
|
||||
game_args = "/bin/crawl-git-launcher.sh",
|
||||
"-name", "%n",
|
||||
"-rc", "%rrcfiles/crawl-git/%n.rc",
|
||||
"-macro", "%rrcfiles/crawl-git/%n.macro",
|
||||
"-webtiles-socket", "%%CHROOT_CRAWL_BASEDIR%%/webserver/sockets/%n:tut-git.sock",
|
||||
"-morgue", "%rmorgue/%n/",
|
||||
"-tutorial"
|
||||
|
||||
extra_info_file = "%rmorgue/%n/%n.dglwhere"
|
||||
|
||||
#
|
||||
# From inside the jail, where dgamelaunch should put mail - should
|
||||
# match up with the game's settings.
|
||||
spooldir = "%%CHROOT_MAILSPOOL%%/"
|
||||
|
||||
max_idle_time = 3600
|
||||
|
||||
# make sure the inprogress dir actually exists. default is "inprogress/"
|
||||
# each game you define here must have it's own.
|
||||
inprogressdir = "%rinprogress/crawl-git-tut/"
|
||||
ttyrecdir = "%%CHROOT_TTYRECDIR%%/%n/"
|
||||
|
||||
commands =
|
||||
ifnxcp "%rdata/crawl-git.macro" "%rrcfiles/crawl-git/%n.macro",
|
||||
ifnxcp "%rdata/crawl-git-settings/init.txt" "%rrcfiles/crawl-git/%n.rc",
|
||||
setenv "MAIL" "%%CHROOT_MAILSPOOL%%/%n",
|
||||
setenv "SIMPLEMAIL" "1",
|
||||
unlink "%%CHROOT_MAILSPOOL%%/%n",
|
||||
mkdir "%rmorgue/%n/"
|
||||
|
||||
encoding = "UTF-8"
|
||||
}
|
||||
|
||||
##############################################################################
|
||||
## 0.22
|
||||
##############################################################################
|
||||
DEFINE {
|
||||
game_path = "/bin/crawl-stable-launcher.sh"
|
||||
game_name = "Crawl (0.22)"
|
||||
short_name = "dcss-0.22"
|
||||
|
||||
game_args = "/bin/crawl-stable-launcher.sh", "0.22",
|
||||
"-name", "%n",
|
||||
"-rc", "%rrcfiles/crawl-0.22/%n.rc",
|
||||
"-macro", "%rrcfiles/crawl-0.22/%n.macro",
|
||||
"-webtiles-socket", "%%CHROOT_CRAWL_BASEDIR%%/webserver/sockets/%n:dcss-0.22.sock",
|
||||
"-morgue", "%rmorgue/%n/"
|
||||
|
||||
extra_info_file = "%rmorgue/%n/%n.dglwhere"
|
||||
|
||||
#
|
||||
# From inside the jail, where dgamelaunch should put mail - should
|
||||
# match up with the game's settings.
|
||||
spooldir = "%%CHROOT_MAILSPOOL%%/"
|
||||
|
||||
max_idle_time = 3600
|
||||
|
||||
# make sure the inprogress dir actually exists. default is "inprogress/"
|
||||
# each game you define here must have it's own.
|
||||
inprogressdir = "%rinprogress/crawl-0.22/"
|
||||
ttyrecdir = "%%CHROOT_TTYRECDIR%%/%n/"
|
||||
|
||||
commands =
|
||||
ifnxcp "%rdata/crawl-git.macro" "%rrcfiles/crawl-0.22/%n.macro",
|
||||
ifnxcp "%rdata/crawl-0.22-settings/init.txt" "%rrcfiles/crawl-0.22/%n.rc",
|
||||
setenv "MAIL" "%%CHROOT_MAILSPOOL%%/%n",
|
||||
setenv "SIMPLEMAIL" "1",
|
||||
unlink "%%CHROOT_MAILSPOOL%%/%n",
|
||||
mkdir "%rmorgue/%n/"
|
||||
|
||||
encoding = "UTF-8"
|
||||
}
|
||||
|
||||
##############################################################################
|
||||
DEFINE {
|
||||
game_path = "/bin/crawl-stable-launcher.sh"
|
||||
game_name = "Sprint (0.22)"
|
||||
short_name = "spr-0.22"
|
||||
|
||||
game_args = "/bin/crawl-stable-launcher.sh", "0.22",
|
||||
"-name", "%n",
|
||||
"-rc", "%rrcfiles/crawl-0.22/%n.rc",
|
||||
"-macro", "%rrcfiles/crawl-0.22/%n.macro",
|
||||
"-webtiles-socket", "%%CHROOT_CRAWL_BASEDIR%%/webserver/sockets/%n:spr-0.22.sock",
|
||||
"-morgue", "%rmorgue/%n/",
|
||||
"-sprint"
|
||||
|
||||
extra_info_file = "%rmorgue/%n/%n.dglwhere"
|
||||
|
||||
#
|
||||
# From inside the jail, where dgamelaunch should put mail - should
|
||||
# match up with the game's settings.
|
||||
spooldir = "%%CHROOT_MAILSPOOL%%/"
|
||||
|
||||
max_idle_time = 3600
|
||||
|
||||
# make sure the inprogress dir actually exists. default is "inprogress/"
|
||||
# each game you define here must have it's own.
|
||||
inprogressdir = "%rinprogress/crawl-0.22-sprint/"
|
||||
ttyrecdir = "%%CHROOT_TTYRECDIR%%/%n/"
|
||||
|
||||
commands =
|
||||
ifnxcp "%rdata/crawl-git.macro" "%rrcfiles/crawl-0.22/%n.macro",
|
||||
ifnxcp "%rdata/crawl-0.22-settings/init.txt" "%rrcfiles/crawl-0.22/%n.rc",
|
||||
setenv "MAIL" "%%CHROOT_MAILSPOOL%%/%n",
|
||||
setenv "SIMPLEMAIL" "1",
|
||||
unlink "%%CHROOT_MAILSPOOL%%/%n",
|
||||
mkdir "%rmorgue/%n/"
|
||||
|
||||
encoding = "UTF-8"
|
||||
}
|
||||
|
||||
##############################################################################
|
||||
DEFINE {
|
||||
game_path = "/bin/crawl-stable-launcher.sh"
|
||||
game_name = "Tutorial (0.22)"
|
||||
short_name = "tut-0.22"
|
||||
|
||||
game_args = "/bin/crawl-stable-launcher.sh", "0.22",
|
||||
"-name", "%n",
|
||||
"-rc", "%rrcfiles/crawl-0.22/%n.rc",
|
||||
"-macro", "%rrcfiles/crawl-0.22/%n.macro",
|
||||
"-webtiles-socket", "%%CHROOT_CRAWL_BASEDIR%%/webserver/sockets/%n:tut-0.22.sock",
|
||||
"-morgue", "%rmorgue/%n/",
|
||||
"-tutorial"
|
||||
|
||||
extra_info_file = "%rmorgue/%n/%n.dglwhere"
|
||||
|
||||
#
|
||||
# From inside the jail, where dgamelaunch should put mail - should
|
||||
# match up with the game's settings.
|
||||
spooldir = "%%CHROOT_MAILSPOOL%%/"
|
||||
|
||||
max_idle_time = 3600
|
||||
|
||||
# make sure the inprogress dir actually exists. default is "inprogress/"
|
||||
# each game you define here must have it's own.
|
||||
inprogressdir = "%rinprogress/crawl-0.22-tut/"
|
||||
ttyrecdir = "%%CHROOT_TTYRECDIR%%/%n/"
|
||||
|
||||
commands =
|
||||
ifnxcp "%rdata/crawl-git.macro" "%rrcfiles/crawl-0.22/%n.macro",
|
||||
ifnxcp "%rdata/crawl-0.22-settings/init.txt" "%rrcfiles/crawl-0.22/%n.rc",
|
||||
setenv "MAIL" "%%CHROOT_MAILSPOOL%%/%n",
|
||||
setenv "SIMPLEMAIL" "1",
|
||||
unlink "%%CHROOT_MAILSPOOL%%/%n",
|
||||
mkdir "%rmorgue/%n/"
|
||||
|
||||
encoding = "UTF-8"
|
||||
}
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
#! /bin/bash
|
||||
|
||||
export ANNOUNCEMENTS_FILE="/home/crawl-dev/logs/announcements.log"
|
||||
export DGL_CHROOT=/home/crawl/DGL
|
||||
|
||||
export CHROOT_DGLDIR=/dgldir
|
||||
export CHROOT_TTYRECDIR=/dgldir/ttyrec
|
||||
export CHROOT_MORGUEDIR=/dgldir/morgue
|
||||
export CHROOT_RCFILESDIR=/dgldir/rcfiles
|
||||
export CHROOT_INPROGRESSDIR=/dgldir/inprogress
|
||||
export CHROOT_LOGIN_DB=$CHROOT_DGLDIR/dgamelaunch.db
|
||||
export CHROOT_DGL_SETTINGS_DIR=$CHROOT_DGLDIR/data
|
||||
export CHROOT_SAVE_DUMPDIR=$CHROOT_DGLDIR/dumps
|
||||
export CHROOT_MAILSPOOL=/var/mail
|
||||
export CHROOT_CRAWL_BASEDIR=/crawl-master
|
||||
export CHROOT_WEBDIR=$CHROOT_CRAWL_BASEDIR/webserver
|
||||
|
||||
# User id that dgamelaunch uses when shedding root privileges.
|
||||
export DGL_USER=crawl
|
||||
export DGL_UID=1001
|
||||
|
||||
export CHROOT_COREDIR=/cores
|
||||
|
||||
# L27 OgRe; Shoals:5
|
||||
export DGL_INFO_MAX_LENGTH=
|
||||
|
||||
export DGL_SERVER=crawl.tildeverse.org
|
||||
export WEB_SAVEDUMP_URL="https://crawl.tildeverse.org/saves"
|
||||
|
||||
export LOGIN_DB=$DGL_CHROOT$CHROOT_LOGIN_DB
|
||||
export SAVE_DUMPDIR=$DGL_CHROOT$CHROOT_SAVE_DUMPDIR
|
||||
|
||||
export DGLDIR=$DGL_CHROOT$CHROOT_DGLDIR
|
||||
export TTYRECDIR=$DGL_CHROOT$CHROOT_TTYRECDIR
|
||||
export MORGUEDIR=$DGL_CHROOT$CHROOT_MORGUEDIR
|
||||
export RCFILESDIR=$DGL_CHROOT$CHROOT_RCFILESDIR
|
||||
export INPROGRESSDIR=$DGL_CHROOT$CHROOT_INPROGRESSDIR
|
||||
export WEBDIR=$DGL_CHROOT$CHROOT_WEBDIR
|
||||
export DGL_SETTINGS_DIR=$DGL_CHROOT$CHROOT_DGL_SETTINGS_DIR
|
|
@ -0,0 +1,5 @@
|
|||
;; -*- mode: emacs-lisp -*-
|
||||
;; fsc.el: Autogenerated on Sat Mar 26 13:26:28 2011
|
||||
(scala-fsc :classes "bin" :classpath
|
||||
'("lib/*.jar")
|
||||
:source "source")
|
|
@ -0,0 +1,7 @@
|
|||
|
||||
dgl admin: Manages dgamelaunch admin users.
|
||||
|
||||
Usage: dgl admin ls List admin users
|
||||
dgl admin add <user> Make <user> an admin
|
||||
dgl admin rm <user> Make <user> a regular (non-admin) user.
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
package DGLMan;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use base 'Exporter';
|
||||
|
||||
our @EXPORT = qw/say_good say_bad say_emphasized say_coloured
|
||||
coloured_text good_text bad_text neutral_text
|
||||
emphasized_text/;
|
||||
|
||||
use Term::ANSIColor;
|
||||
|
||||
sub emphasized_text(@) {
|
||||
coloured_text('bold', @_)
|
||||
}
|
||||
|
||||
# Neutral text that should be coloured differently.
|
||||
sub neutral_text(@) {
|
||||
coloured_text('blue', @_)
|
||||
}
|
||||
|
||||
sub good_text(@) {
|
||||
coloured_text('green', @_)
|
||||
}
|
||||
|
||||
sub bad_text(@) {
|
||||
coloured_text('red', @_)
|
||||
}
|
||||
|
||||
sub coloured_text($@) {
|
||||
my $color = shift;
|
||||
color($color) . join('', @_) . color('reset')
|
||||
}
|
||||
|
||||
sub say_coloured($@) {
|
||||
my $color = shift;
|
||||
print(color($color), @_, color('reset'));
|
||||
}
|
||||
|
||||
sub say_good(@) {
|
||||
print(good_text(@_));
|
||||
}
|
||||
|
||||
sub say_bad(@) {
|
||||
print(bad_text(@_));
|
||||
}
|
||||
|
||||
sub say_emphasized(@) {
|
||||
print(coloured_text('bold', @_));
|
||||
}
|
||||
|
||||
1
|
|
@ -0,0 +1,173 @@
|
|||
#! /bin/bash
|
||||
|
||||
source "$DGL_CONF_HOME/dgl-manage.conf"
|
||||
|
||||
DGL_CONF_LOCK_DIR="$DGL_CONF_HOME/locks"
|
||||
|
||||
declare -a DGL_LOCKS
|
||||
DGL_LOCKS=()
|
||||
|
||||
PROMPTS_ENABLED=
|
||||
GIVE_HELP=
|
||||
|
||||
help() {
|
||||
if [[ -n "$GIVE_HELP" ]]; then
|
||||
cat
|
||||
echo
|
||||
exit 0
|
||||
fi
|
||||
}
|
||||
|
||||
dgl-run() {
|
||||
"$0" "$@"
|
||||
}
|
||||
|
||||
say() {
|
||||
echo ";;;; $@"
|
||||
}
|
||||
|
||||
say-do() {
|
||||
echo "[EXEC] $@"
|
||||
"$@"
|
||||
}
|
||||
|
||||
running-as-root() {
|
||||
[[ "$UID" == "0" ]]
|
||||
}
|
||||
|
||||
assert-running-as-root() {
|
||||
if ! running-as-root; then
|
||||
abort-saying "$SCRIPT_NAME needs to be run as root"
|
||||
fi
|
||||
}
|
||||
|
||||
not-running-as-root() {
|
||||
[[ "$UID" != "0" ]]
|
||||
}
|
||||
|
||||
each-do() {
|
||||
local cmd="$1"
|
||||
shift
|
||||
for arg in "$@"; do
|
||||
$cmd "$arg"
|
||||
done
|
||||
}
|
||||
|
||||
announce() {
|
||||
echo
|
||||
echo "---------------------------------------------------------------------"
|
||||
echo "$@"
|
||||
echo "$@" >>$ANNOUNCEMENTS_FILE
|
||||
}
|
||||
|
||||
abort-saying() {
|
||||
echo -e "$@, aborting."
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Call with any argument to disable prompts
|
||||
enable-prompts() {
|
||||
local opt
|
||||
while getopts p opt; do
|
||||
PROMPTS_ENABLED=1
|
||||
done
|
||||
shift $((OPTIND - 1))
|
||||
|
||||
# Would be nice to be able to modify the caller's arguments...
|
||||
}
|
||||
|
||||
prompts-enabled() {
|
||||
[[ -n "$PROMPTS_ENABLED" && -t 0 ]]
|
||||
}
|
||||
|
||||
prompt() {
|
||||
if prompts-enabled; then
|
||||
echo "-- Press RETURN to $@ --"
|
||||
read
|
||||
else
|
||||
say "$@"
|
||||
fi
|
||||
}
|
||||
|
||||
unlock-dgl-locks() {
|
||||
if (( "${#DGL_LOCKS[@]}" > 0 )); then
|
||||
rm -f ${DGL_LOCKS[@]}
|
||||
fi
|
||||
}
|
||||
|
||||
unlock-on-error() {
|
||||
unlock-dgl-locks
|
||||
exit 1
|
||||
}
|
||||
|
||||
trap-lock-hook-cleanup() {
|
||||
if [[ -z "$DGL_TRAP_LOCK_CLEANUP_HOOKED" ]]; then
|
||||
trap unlock-on-error INT TERM
|
||||
trap unlock-dgl-locks EXIT
|
||||
DGL_TRAP_LOCK_CLEANUP_HOOKED=1
|
||||
fi
|
||||
}
|
||||
|
||||
lock-or-die() {
|
||||
local lock_name=$1
|
||||
mkdir -p "$DGL_CONF_LOCK_DIR"
|
||||
local lock_file="$DGL_CONF_LOCK_DIR/${lock_name}.lock"
|
||||
shift || true
|
||||
if ( set -o noclobber; echo "$$" > "$lock_file" ) 2>/dev/null; then
|
||||
DGL_LOCKS=(${DGL_LOCKS[@]} "$lock_file")
|
||||
trap-lock-hook-cleanup
|
||||
else
|
||||
echo "Could not lock $lock_file: $@"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
dgl-today() {
|
||||
date +%y%m%d-%H%M
|
||||
}
|
||||
|
||||
cat-error() {
|
||||
cat >&2
|
||||
}
|
||||
|
||||
assert-chroot-exists() {
|
||||
if [[ ! -d "$DGL_CHROOT" ]]; then
|
||||
cat-error <<ERROR
|
||||
DGL chroot $DGL_CHROOT doesn't exist.
|
||||
|
||||
Please create it, or edit $DGL_CONF_HOME/dgl-manage.conf to
|
||||
point at the real chroot.
|
||||
ERROR
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
assert-login-db-exists() {
|
||||
if [[ ! -f "$LOGIN_DB" ]]; then
|
||||
cat-error <<EOF
|
||||
DGL login db $LOGIN_DB is missing; please check that the chroot
|
||||
is correctly setup, and that $DGL_CONF_HOME/dgl-manage.conf points
|
||||
at the correct chroot path.
|
||||
EOF
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
login-query() {
|
||||
sqlite3 "$LOGIN_DB"
|
||||
}
|
||||
|
||||
dgl-user-exists() {
|
||||
local user="$1"
|
||||
local found="$(echo "SELECT username FROM dglusers WHERE username='$user';" |
|
||||
login-query)"
|
||||
[[ -n "$found" ]]
|
||||
}
|
||||
|
||||
dgl-user-is-admin() {
|
||||
local user="$1"
|
||||
local found="$(echo "SELECT username FROM dglusers
|
||||
WHERE username='$user' AND (flags & 1) = 1;" |
|
||||
login-query)"
|
||||
[[ -n "$found" ]]
|
||||
}
|
|
@ -0,0 +1,95 @@
|
|||
#! /usr/bin/perl
|
||||
#
|
||||
# Allows DGL admin users to download saves from CSZO's save dump directory.
|
||||
#
|
||||
|
||||
use CGI qw/:standard/;
|
||||
use MIME::Base64;
|
||||
|
||||
use DBI;
|
||||
|
||||
my $DB = "%%LOGIN_DB%%";
|
||||
my $CONTENT_DIR = '%%SAVE_DUMPDIR%%/';
|
||||
|
||||
my $AUTH_REALM = 'CSZO developer account';
|
||||
|
||||
sub request_auth() {
|
||||
print(header(-type => 'text/html',
|
||||
-status => '401 Authorization Required',
|
||||
-WWW_Authenticate => "Basic realm=\"$AUTH_REALM\""),
|
||||
start_html('CSZO save dumps'),
|
||||
p('Must authenticate to access saves'),
|
||||
end_html);
|
||||
return undef;
|
||||
}
|
||||
|
||||
sub match_password($$) {
|
||||
my ($plain, $crypt) = @_;
|
||||
my $cc = crypt($plain, $crypt);
|
||||
return crypt($plain, $crypt) eq $crypt;
|
||||
}
|
||||
|
||||
sub valid_user($$) {
|
||||
my ($user, $password) = @_;
|
||||
my $db = DBI->connect("dbi:SQLite:dbname=$DB", '', '')
|
||||
or die "Can't open auth db: $DB\n";
|
||||
my $st = $db->prepare(<<QUERY);
|
||||
SELECT username, password FROM dglusers
|
||||
WHERE username=? AND (flags & 1) = 1;
|
||||
QUERY
|
||||
$st->execute($user);
|
||||
my $row = $st->fetchrow_arrayref;
|
||||
|
||||
# Should have at least one row.
|
||||
return defined($row) && match_password($password, $row->[1]);
|
||||
}
|
||||
|
||||
sub valid_auth($) {
|
||||
my $header = shift;
|
||||
return unless $header =~ s/^Basic //;
|
||||
my $decoded = decode_base64($header);
|
||||
my ($user, $password) = $decoded =~ /(.*?):(.*)/;
|
||||
valid_user($user, $password)
|
||||
}
|
||||
|
||||
sub authenticate() {
|
||||
my $auth_header = http('Authorization');
|
||||
return request_auth() unless $auth_header && valid_auth($auth_header);
|
||||
1
|
||||
}
|
||||
|
||||
sub file_bytes($) {
|
||||
my $file = shift;
|
||||
open my $inf, '<', $file;
|
||||
binmode $inf;
|
||||
my $content = do { local $/; <$inf> };
|
||||
close $inf;
|
||||
$content
|
||||
}
|
||||
|
||||
sub serve_file() {
|
||||
my ($file) = param('file');
|
||||
|
||||
my $absfile = "$CONTENT_DIR/$file";
|
||||
if ($file =~ /[.]{2}/ ||
|
||||
$file !~ /^[a-zA-Z0-9._-]+$/ ||
|
||||
$file !~ /\.(?:tar\.bz2|cs|core)$/ ||
|
||||
!-r $absfile)
|
||||
{
|
||||
print(header(-status => '404 Not Found'),
|
||||
start_html,
|
||||
p("Could not find $absfile"),
|
||||
end_html);
|
||||
return;
|
||||
}
|
||||
|
||||
print(header(-type => 'application/octet-stream'),
|
||||
file_bytes($absfile));
|
||||
}
|
||||
|
||||
sub main() {
|
||||
return unless authenticate();
|
||||
serve_file();
|
||||
}
|
||||
|
||||
main();
|
|
@ -0,0 +1,165 @@
|
|||
#! /usr/bin/perl
|
||||
#
|
||||
# Allows DGL admin users to trigger rebuilds of trunk or stable.
|
||||
|
||||
use CGI qw/:standard/;
|
||||
use MIME::Base64;
|
||||
|
||||
use DBI;
|
||||
|
||||
my $DGL = "/home/crawl-dev/dgamelaunch-config/bin/dgl";
|
||||
my $DB = "%%LOGIN_DB%%";
|
||||
my $CONTENT_DIR = '%%SAVE_DUMPDIR%%/';
|
||||
|
||||
my $AUTH_REALM = 'CSZO developer account';
|
||||
|
||||
sub request_auth() {
|
||||
print(header(-type => 'text/html',
|
||||
-status => '401 Authorization Required',
|
||||
-WWW_Authenticate => "Basic realm=\"$AUTH_REALM\""),
|
||||
start_html('CSZO rebuild trigger'),
|
||||
p('Must authenticate to trigger rebuilds.'),
|
||||
end_html);
|
||||
return undef;
|
||||
}
|
||||
|
||||
sub match_password($$) {
|
||||
my ($plain, $crypt) = @_;
|
||||
my $cc = crypt($plain, $crypt);
|
||||
return crypt($plain, $crypt) eq $crypt;
|
||||
}
|
||||
|
||||
sub valid_user($$) {
|
||||
my ($user, $password) = @_;
|
||||
my $db = DBI->connect("dbi:SQLite:dbname=$DB", '', '')
|
||||
or die "Can't open auth db: $DB\n";
|
||||
my $st = $db->prepare(<<QUERY);
|
||||
SELECT username, password FROM dglusers
|
||||
WHERE username=? AND (flags & 1) = 1;
|
||||
QUERY
|
||||
$st->execute($user);
|
||||
my $row = $st->fetchrow_arrayref;
|
||||
|
||||
# Should have at least one row.
|
||||
return defined($row) && match_password($password, $row->[1]);
|
||||
}
|
||||
|
||||
sub valid_auth($) {
|
||||
my $header = shift;
|
||||
return unless $header =~ s/^Basic //;
|
||||
my $decoded = decode_base64($header);
|
||||
my ($user, $password) = $decoded =~ /(.*?):(.*)/;
|
||||
valid_user($user, $password)
|
||||
}
|
||||
|
||||
sub authenticate() {
|
||||
my $auth_header = http('Authorization');
|
||||
return request_auth() unless $auth_header && valid_auth($auth_header);
|
||||
1
|
||||
}
|
||||
|
||||
sub file_bytes($) {
|
||||
my $file = shift;
|
||||
open my $inf, '<', $file;
|
||||
binmode $inf;
|
||||
my $content = do { local $/; <$inf> };
|
||||
close $inf;
|
||||
$content
|
||||
}
|
||||
|
||||
sub serve_file() {
|
||||
my ($file) = param('file');
|
||||
|
||||
my $absfile = "$CONTENT_DIR/$file";
|
||||
if ($file =~ /[.]{2}/ ||
|
||||
$file !~ /^[a-zA-Z0-9._-]+$/ ||
|
||||
$file !~ /\.(?:tar\.bz2|cs)$/ ||
|
||||
!-r $absfile)
|
||||
{
|
||||
print(header(-status => '404 Not Found'),
|
||||
start_html,
|
||||
p("Could not find $absfile"),
|
||||
end_html);
|
||||
return;
|
||||
}
|
||||
|
||||
print(header(-type => 'application/octet-stream'),
|
||||
file_bytes($absfile));
|
||||
}
|
||||
|
||||
sub do_update($;$) {
|
||||
my $branch = shift;
|
||||
|
||||
my $specific = $_[0] or $branch;
|
||||
|
||||
local $| = 1;
|
||||
print(header(-type => 'text/html',
|
||||
-WWW_Authenticate => "Basic realm=\"$AUTH_REALM\""),
|
||||
start_html('CSZO rebuild trigger'),
|
||||
p("Rebuilding $specific. . ."));
|
||||
print "<pre>";
|
||||
open my $olderr, ">&STDERR";
|
||||
open STDERR, ">&STDOUT";
|
||||
system(qw(sudo -u crawl-dev), $DGL, "update-$branch", @_);
|
||||
print "</pre>";
|
||||
if ($?) {
|
||||
my $msg;
|
||||
if ($? == -1) {
|
||||
$msg = "could not execute: $?";
|
||||
} elsif ($? & 0xff) {
|
||||
$msg = "signal " . ($? & 0xff);
|
||||
} else {
|
||||
$msg = "returned " . ($? >> 8);
|
||||
}
|
||||
print p({-style => 'background-color: #ffcccc;'},
|
||||
"Failed: $msg");
|
||||
} else {
|
||||
print p("Done!");
|
||||
}
|
||||
print end_html;
|
||||
open STDERR, $olderr;
|
||||
}
|
||||
|
||||
sub do_prompt(@) {
|
||||
print(header(-type => 'text/html',
|
||||
-WWW_Authenticate => "Basic realm=\"$AUTH_REALM\""),
|
||||
start_html('CSZO rebuild trigger'),
|
||||
start_form,
|
||||
p('Select a version'),
|
||||
popup_menu(-name => 'v', -values => [ @_ ]),
|
||||
submit,
|
||||
end_form,
|
||||
end_html);
|
||||
}
|
||||
|
||||
sub do_fail($) {
|
||||
my $msg = shift;
|
||||
print(header(-type => 'text/html',
|
||||
-status => '403 Forbidden',
|
||||
-WWW_Authenticate => "Basic realm=\"$AUTH_REALM\""),
|
||||
start_html('CSZO rebuild trigger'),
|
||||
start_form,
|
||||
p({-style=>'background-color: #ffcccc;'}, $msg),
|
||||
popup_menu(-name => 'v', -values => @_),
|
||||
submit,
|
||||
end_form,
|
||||
end_html);
|
||||
}
|
||||
|
||||
sub main() {
|
||||
return unless authenticate();
|
||||
my $ver = param('v');
|
||||
|
||||
if (not $ver) {
|
||||
do_prompt 'trunk', '0.17', '0.16', '0.15', '0.14', '0.13', '0.12', '0.11', '0.10';
|
||||
} elsif ($ver eq 'trunk') {
|
||||
do_update 'trunk';
|
||||
} elsif ($ver =~ /^0.1[01234567]$/) {
|
||||
do_update 'stable', $ver;
|
||||
} else {
|
||||
do_fail "Unknown version " . escapeHTML($ver);
|
||||
}
|
||||
}
|
||||
|
||||
main();
|
||||
|
|
@ -0,0 +1,71 @@
|
|||
#!/bin/sh
|
||||
### BEGIN INIT INFO
|
||||
# Provides: webtiles
|
||||
# Required-Start: $local_fs $remote_fs $network $named
|
||||
# Required-Stop: $local_fs $remote_fs $network $named
|
||||
# Default-Start: 2 3 4 5
|
||||
# Default-Stop: 0 1 6
|
||||
# X-Interactive: true
|
||||
# Short-Description: Start/stop Dungeon Crawl webtiles server
|
||||
### END INIT INFO
|
||||
|
||||
. /lib/lsb/init-functions
|
||||
|
||||
# kill -TERM doesn't work
|
||||
signal=ABRT
|
||||
|
||||
announce() {
|
||||
echo "$@" >> %%ANNOUNCEMENTS_FILE%%
|
||||
}
|
||||
|
||||
quietly() {
|
||||
"$@" >/dev/null 2>&1
|
||||
}
|
||||
|
||||
stop_webtiles() {
|
||||
log_daemon_msg "Stopping webtiles server" "webtiles"
|
||||
|
||||
[ -z "$1" ] || ! quietly ps "$1" || kill -$signal "$1"
|
||||
local result=$?
|
||||
log_end_msg $result
|
||||
return $result
|
||||
}
|
||||
|
||||
start_webtiles() {
|
||||
log_daemon_msg "Starting webtiles server" "webtiles"
|
||||
ulimit -n 4096
|
||||
|
||||
PYTHONPATH=/home/crawl-dev/tornado/ python ./server.py
|
||||
local result=$?
|
||||
log_end_msg $result
|
||||
return $result
|
||||
}
|
||||
|
||||
cd %%CRAWL_BASEDIR%%/webserver
|
||||
|
||||
pid=$([ -e run/webtiles.pid ] && cat run/webtiles.pid)
|
||||
case $1 in
|
||||
start)
|
||||
if [ -n "$pid" ] && quietly ps "$pid"; then
|
||||
log_warning_msg "Webtiles was already running!"
|
||||
else
|
||||
start_webtiles && announce "Webtiles server started."
|
||||
fi
|
||||
;;
|
||||
stop)
|
||||
stop_webtiles "$pid" && announce "Webtiles server stopped."
|
||||
;;
|
||||
restart|reload)
|
||||
if stop_webtiles "$pid" && sleep 3; then
|
||||
if start_webtiles; then
|
||||
announce "Webtiles server restarted.";
|
||||
else
|
||||
announce "Webtiles server failed to restart.";
|
||||
fi
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
log_success_msg "Usage: /etc/init.d/webtiles {start|stop|restart}"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
Loading…
Reference in New Issue