summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xbuilder.sh187
-rwxr-xr-xrunner.sh109
2 files changed, 296 insertions, 0 deletions
diff --git a/builder.sh b/builder.sh
new file mode 100755
index 0000000..5f647f8
--- /dev/null
+++ b/builder.sh
@@ -0,0 +1,187 @@
+#!/bin/bash
+
+# Minecraft Java serverdir builder
+
+function fail(){
+ >&2 echo $@
+ exit 1
+}
+
+# 1: file 2: attribute
+function serverprop_get() {
+ sed -n "s/$2=\(.*\)$/\1/p" "$1"
+}
+
+# 1: file 2: attribute 3: value
+function serverprop_set() {
+ if grep -s "^$2=.*$" "$1"; then
+ sed -i "s/$2=.*$/$2=$3/g" "$1"
+ else
+ echo "$2=$3" >> "$1"
+ fi
+}
+
+function confirm() {
+ [ -z "$NO_INTERACTIVE" ] || return 1
+
+ read -p "$@ [y/N] " choice
+ case $choice in
+ [yY]*)
+ return 0;;
+ *)
+ return 1
+ esac
+}
+
+# Sub Commands
+
+## world
+
+function world() {
+ local CMD="$1"
+ case $CMD in
+ list) ;&
+ create) ;&
+ clone) ;&
+ backup) ;&
+ delete) ;&
+ assign)
+ shift
+ eval 'world_$CMD "$@"'
+ ;;
+ *)
+ fail "world: Unknown argument $CMD"
+ esac
+
+ exit $?
+}
+
+function world_exists() {
+ [ -d "$WORLDS/$1" ]
+ return $?
+}
+
+# 1: world 2: instance
+function world_assign() {
+ local WORLD="$1"
+ local INSTANCE="$2"
+
+ world_exists "$WORLD" \
+ || ( confirm "World not found. Create?" \
+ && world_create "$WORLD" \
+ || fail "World $WORLD not found." )
+
+ [ -f "$WORLDS/$WORLD.lock" ] && fail "$WORLD is already used by another instance."
+
+ echo "ASSIGNED_TO=\"$INSTANCE\"" > "$WORLDS/$WORLD.lock"
+
+ ln -s "$WORLDS/$WORLD" "$INSTANCES/$INSTANCE"
+ serverprop_set "$INSTANCES/$INSTANCE/server.properties" level-name "$WORLD"
+}
+
+
+# 1: name
+function world_create() {
+ world_exists "$1" && fail "World already exists"
+ mkdir "$WORLDS/$1"
+}
+
+## instance
+
+function instance() {
+ local CMD="$1"
+ case $CMD in
+ list) ;&
+ create) ;&
+ delete) ;&
+ start) ;&
+ stop) ;&
+ status)
+ shift
+ eval 'instance_$CMD "$@"'
+ ;;
+ *)
+ fail "instance: Unknown argument $CMD"
+ esac
+
+ exit $?
+}
+
+function instance_exists() {
+ [ -d "$INSTANCES/$1" ]
+ return $?
+}
+
+# 1: name 2: world 3: version
+function instance_create() {
+ local NAME="$1"
+ local WORLD="$2"
+ local VERSION="$3"
+
+ instance_exists "$NAME" && fail "$NAME already exists."
+ mkdir "$INSTANCES/$NAME"
+
+ version_install "$NAME" "$VERSION"
+ confirm "Accept minecraft EULA?" && serverprop_set "$INSTANCES/$NAME/eula.txt" eula true
+
+ world_assign "$WORLD" "$NAME"
+}
+
+function instance_start() {
+ instance_exists "$1" || fail "instance $1 not found."
+
+
+ # TODO
+}
+
+## version
+
+function version() {
+ fail "not implemented"
+}
+
+function version_exists() {
+ [ -f "$VERSIONS/$1.jar" ]
+ return $?
+}
+
+# 1: instance 2: version
+function version_install() {
+ instance_exists "$1" || fail "instance $1 not found."
+ version_exists "$2" || fail "version $2 not found."
+
+ local PWD=$(pwd)
+ cd "$INSTANCES/$1"
+
+ [ -e "$2.jar" ] && rm "$2.jar"
+
+ ln -s "$VERSIONS/$2.jar" "$2.jar"
+
+ serverprop_set settings.sh MCJAR "$2.jar"
+
+ cd "$PWD"
+}
+
+# NO_INTERACTIVE=1
+
+PREFIX=$(pwd)
+VERSIONS="$PREFIX/versions"
+WORLDS="$PREFIX/worlds"
+INSTANCES="$PREFIX/instances"
+
+RUNNER="$PREFIX/runner.sh"
+
+[ -x ./settings.sh ] || fail "settings.sh not found."
+source ./settings.sh
+
+CMD="$1"
+case $CMD in
+ world) ;&
+ instance) ;&
+ version)
+ shift
+ eval '$CMD "$@"'
+ ;;
+ *)
+ fail "Unknown option $1"
+esac
diff --git a/runner.sh b/runner.sh
new file mode 100755
index 0000000..1ec1fbc
--- /dev/null
+++ b/runner.sh
@@ -0,0 +1,109 @@
+#!/bin/bash
+
+# Minecraft Java runner script
+
+function stop() {
+ running || exit 0
+ test -p stdin || exit 1
+ echo stop > stdin
+
+ >&2 echo -n Waiting for server to stop
+ while kill -s 0 $PID > /dev/null 2>&1; do
+ sleep 1
+ >&2 echo -n .
+ done
+
+ >&2 echo Done!
+
+ rm server.pid stdin
+
+ exit 0
+}
+
+function start() {
+ running && fail "Server appears to already be running. PID: $PID"
+
+ [ -z "$JVMARGS" ] && echo 'WARNING: $JVMARGS not set'
+ [ -e stdin -a ! -p stdin ] && rm stdin
+
+ mkfifo stdin
+
+ "$JAVA" $JVMARGS -jar "$MCJAR" -nogui $MCARGS \
+ < <(while [ -p stdin ]; do timeout 10s cat stdin; done) \
+ > /dev/null &
+ PID=$!
+
+ echo $PID > server.pid
+ echo "Started server with PID $PID"
+
+ exit 0
+}
+
+function attach() {
+ running || fail "Server is not running."
+
+ echo "CTRL-D (EOF) to exit."
+
+ tail -f logs/latest.log &
+ TAILPID=$!
+
+ while read line; do
+ echo "$line" > stdin
+ done
+
+ kill -s SIGKILL $TAILPID
+
+ exit 0
+}
+
+function running() {
+ [ -e server.pid ] || return 1
+
+ PID=$(cat server.pid)
+ kill -s 0 $PID && return 0
+
+ rm server.pid stdin
+ return 1
+} > /dev/null 2>&1
+
+function fail() {
+ >&2 echo $@
+ exit 1
+}
+
+function stdin_redirector(){
+ while [ -p stdin ]; do
+ cat stdin
+ done
+}
+
+[ -e settings.sh ] && source settings.sh \
+ || >&2 echo "WARNING: settings.sh not found."
+# settings.sh
+# JVMARGS, JAVA, MCARGS, MCJAR
+
+JAVA=${JAVA:-java}
+MCJAR=${MCJAR:-server.jar}
+
+which "$JAVA" > /dev/null 2>&1 || fail "No java executable."
+
+case $1 in
+ start)
+ start;;
+ stop)
+ stop;;
+ status)
+ running || fail "Server is not running."
+ >&2 echo "Server is running"
+ exit 0;;
+ attach)
+ attach;;
+ command)
+ running || fail "Server is not running."
+ shift
+ echo $@ > stdin;;
+ *)
+ >&2 echo "Minecraft Java server runner"
+ >&2 echo "$0 start|stop|status|attach|command ..."
+ fail "Invalid argument $1"
+esac