2013-06-25 21:04:02 -07:00
|
|
|
#!/bin/sh
|
2013-06-24 11:26:09 -07:00
|
|
|
### BEGIN INIT INFO
|
|
|
|
# Provides: minecraft_server
|
|
|
|
# Required-Start: $remote_fs $syslog
|
|
|
|
# Required-Stop: $remote_fs $syslog
|
2013-06-27 09:06:00 -07:00
|
|
|
# Default-Start: 2 3 4 5
|
|
|
|
# Default-Stop: 0 1 6
|
2013-06-24 11:26:09 -07:00
|
|
|
# chkconfig: 345 50 50
|
2013-06-24 13:20:10 -07:00
|
|
|
# Description: Minecraft Server Control Script
|
2013-06-24 11:26:09 -07:00
|
|
|
### END INIT INFO
|
|
|
|
|
2013-06-24 13:25:27 -07:00
|
|
|
|
2013-06-24 14:30:46 -07:00
|
|
|
# ---------------------------------------------------------------------------
|
|
|
|
# Copyright (c) 2013, Jason M. Wood <sandain@hotmail.com>
|
|
|
|
#
|
|
|
|
# All rights reserved.
|
|
|
|
#
|
|
|
|
# Redistribution and use in source and binary forms, with or without
|
|
|
|
# modification, are permitted provided that the following conditions are met:
|
|
|
|
#
|
|
|
|
# 1. Redistributions of source code must retain the above copyright notice,
|
|
|
|
# this list of conditions and the following disclaimer.
|
|
|
|
# 2. Redistributions in binary form must reproduce the above copyright
|
|
|
|
# notice, this list of conditions and the following disclaimer in the
|
|
|
|
# documentation and/or other materials provided with the distribution.
|
|
|
|
#
|
|
|
|
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
|
|
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
|
|
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
|
|
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
|
|
|
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
|
|
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
|
|
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
|
|
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
|
|
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
|
|
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
|
|
# POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
# ---------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
2013-06-24 13:11:34 -07:00
|
|
|
# ---------------------------------------------------------------------------
|
|
|
|
# Minecraft Server Control Script
|
2013-06-24 11:26:09 -07:00
|
|
|
#
|
2013-06-24 13:11:34 -07:00
|
|
|
# A powerful command-line control script for Linux-powered Minecraft servers.
|
|
|
|
# ---------------------------------------------------------------------------
|
|
|
|
|
2013-06-24 13:20:10 -07:00
|
|
|
|
|
|
|
# Script Usage
|
|
|
|
# ---------------------------------------------------------------------------
|
|
|
|
|
2013-06-24 13:11:34 -07:00
|
|
|
USAGE=$(cat <<EOF
|
2013-12-02 21:49:55 -07:00
|
|
|
Usage: $0 <option>
|
2013-06-24 13:11:34 -07:00
|
|
|
|
|
|
|
Options:
|
2013-10-20 18:38:03 -07:00
|
|
|
|
|
|
|
start <world>
|
|
|
|
Start the Minecraft world server. Start all world servers by default.
|
|
|
|
|
|
|
|
stop <world>
|
|
|
|
Stop the Minecraft world server. Stop all world servers by default.
|
|
|
|
|
|
|
|
force-stop <world>
|
|
|
|
Forcibly stop the Minecraft world server. Forcibly stop all world
|
|
|
|
servers by default.
|
|
|
|
|
|
|
|
restart <world>
|
|
|
|
Restart the Minecraft world server. Restart all world servers by default.
|
|
|
|
|
|
|
|
force-restart <world>
|
|
|
|
Forcibly restart the Minecraft world server. Forcibly restart all world
|
|
|
|
servers by default.
|
|
|
|
|
|
|
|
create <world> <port> <ip>
|
|
|
|
Create a Minecraft world server. The world name and port must be
|
|
|
|
provided, the IP addressis usually blank.
|
|
|
|
|
|
|
|
delete <world>
|
|
|
|
Delete a Minecraft world server.
|
|
|
|
|
|
|
|
disable <world>
|
|
|
|
Temporarily disable a world server.
|
|
|
|
|
|
|
|
enable <world>
|
|
|
|
Enable a disabled world server.
|
|
|
|
|
2013-12-02 19:27:52 -07:00
|
|
|
list
|
|
|
|
Display a list of enabled worlds.
|
|
|
|
|
2013-10-20 18:38:03 -07:00
|
|
|
status <world>
|
|
|
|
Display the status of the Minecraft world server. Display the status of
|
|
|
|
all world servers by default.
|
|
|
|
|
|
|
|
sync <world>
|
|
|
|
Synchronize the data stored in the mirror images of the Minecraft world
|
|
|
|
server. Synchronizes all of the world servers by default. This option
|
|
|
|
is only available when the mirror image option is enabled.
|
|
|
|
|
2013-11-01 10:19:32 -07:00
|
|
|
send <world> <command>
|
2013-10-20 18:38:03 -07:00
|
|
|
Send a command to a Minecraft world server.
|
|
|
|
|
|
|
|
screen <world>
|
|
|
|
Display the Screen for the Minecraft world server.
|
|
|
|
|
|
|
|
watch <world>
|
|
|
|
Watch the log file for the Minecraft world server.
|
|
|
|
|
|
|
|
logrotate <world>
|
2013-11-09 17:09:19 -07:00
|
|
|
Rotate the latest.log file. Rotate the latest.log file for all worlds by
|
2013-10-20 18:38:03 -07:00
|
|
|
default.
|
|
|
|
|
|
|
|
backup <world>
|
|
|
|
Backup the Minecraft world. Backup all worlds by default.
|
|
|
|
|
|
|
|
map <world>
|
|
|
|
Run the Minecraft Overviewer mapping software on the Minecraft world.
|
|
|
|
Map all worlds by default.
|
|
|
|
|
2013-12-02 21:34:39 -07:00
|
|
|
update <world>
|
2013-12-02 21:47:57 -07:00
|
|
|
Update the server software for the Minecraft world server. Update
|
|
|
|
server software for all worlds by default.
|
2013-10-20 18:38:03 -07:00
|
|
|
|
2013-06-24 13:11:34 -07:00
|
|
|
EOF
|
|
|
|
)
|
2013-06-24 11:26:09 -07:00
|
|
|
|
2013-06-24 13:25:27 -07:00
|
|
|
|
2013-06-24 13:20:10 -07:00
|
|
|
# User Account & Server Location
|
|
|
|
# ---------------------------------------------------------------------------
|
|
|
|
# Who we run as and where we run from.
|
2013-06-24 11:26:09 -07:00
|
|
|
|
2013-06-24 13:25:27 -07:00
|
|
|
# User name used to run all commands. Be sure to create this user if it
|
|
|
|
# doesn't already exist (sudo adduser minecraft).
|
2013-06-24 11:26:09 -07:00
|
|
|
USER_NAME="minecraft"
|
|
|
|
|
|
|
|
# The location of server software and data.
|
|
|
|
LOCATION="/home/$USER_NAME"
|
|
|
|
|
|
|
|
|
2013-06-24 13:20:10 -07:00
|
|
|
# Required Software
|
|
|
|
# ---------------------------------------------------------------------------
|
|
|
|
# Detect its presence and location for later.
|
2013-06-24 11:26:09 -07:00
|
|
|
|
|
|
|
JAVA=$(which java)
|
|
|
|
PERL=$(which perl)
|
|
|
|
PYTHON=$(which python)
|
|
|
|
RSYNC=$(which rsync)
|
|
|
|
SCREEN=$(which screen)
|
|
|
|
WGET=$(which wget)
|
|
|
|
RDIFF_BACKUP=$(which rdiff-backup)
|
2013-12-01 10:57:09 -07:00
|
|
|
SOCAT=$(which socat)
|
2013-06-24 11:26:09 -07:00
|
|
|
|
|
|
|
|
2013-06-24 13:20:10 -07:00
|
|
|
# Global Server Configuration
|
|
|
|
# ---------------------------------------------------------------------------
|
2013-06-24 11:26:09 -07:00
|
|
|
|
|
|
|
|
2013-08-04 10:56:44 -07:00
|
|
|
# Mojang Versions information
|
|
|
|
# ---------------------------------------------------------------------------
|
|
|
|
# Detect the latest version.
|
|
|
|
|
2013-11-01 11:12:20 -07:00
|
|
|
CURRENT_VERSION=$(
|
|
|
|
wget -q -O - https://s3.amazonaws.com/Minecraft.Download/versions/versions.json |
|
|
|
|
$PERL -ne 'if ($_ =~ /^\s+\"release\": \"([0-9\.]+)\"/) { print $1; }'
|
|
|
|
)
|
2013-08-04 10:56:44 -07:00
|
|
|
|
|
|
|
|
2013-06-24 13:20:10 -07:00
|
|
|
# Minecraft Server Settings
|
|
|
|
# ---------------------------------------------------------------------------
|
2013-06-24 11:26:09 -07:00
|
|
|
# Choose only one server distribution, leave the other commented out.
|
|
|
|
|
|
|
|
# Default Mojang server distribution.
|
|
|
|
SERVER_JAR="minecraft_server.jar"
|
2013-11-01 11:12:20 -07:00
|
|
|
SERVER_URL="https://s3.amazonaws.com/Minecraft.Download/versions/$CURRENT_VERSION/minecraft_server.$CURRENT_VERSION.jar"
|
2013-06-24 11:26:09 -07:00
|
|
|
SERVER_ARGS="nogui"
|
|
|
|
|
|
|
|
# CraftBukkit server distribution.
|
2013-10-19 19:07:46 -07:00
|
|
|
# SERVER_URL="http://dl.bukkit.org/latest-rb/craftbukkit.jar"
|
2013-06-24 11:26:09 -07:00
|
|
|
# SERVER_JAR="craftbukkit.jar"
|
|
|
|
# SERVER_ARGS=""
|
|
|
|
|
|
|
|
# Generic server options.
|
|
|
|
INITIAL_MEMORY="128M"
|
|
|
|
MAXIMUM_MEMORY="2048M"
|
|
|
|
SERVER_LOCATION="$LOCATION/minecraft_server"
|
|
|
|
SERVER_COMMAND="$JAVA -Xms$INITIAL_MEMORY -Xmx$MAXIMUM_MEMORY -jar $SERVER_LOCATION/$SERVER_JAR $SERVER_ARGS"
|
|
|
|
|
|
|
|
|
2013-06-24 13:20:10 -07:00
|
|
|
# Minecraft Client Settings
|
|
|
|
# ---------------------------------------------------------------------------
|
2013-06-25 21:18:56 -07:00
|
|
|
# Used by Minecraft Overviewer mapping software.
|
2013-06-24 13:20:10 -07:00
|
|
|
|
2013-11-03 20:02:41 -07:00
|
|
|
CLIENT_JAR="$CURRENT_VERSION.jar"
|
2013-11-01 11:12:20 -07:00
|
|
|
CLIENT_URL="https://s3.amazonaws.com/Minecraft.Download/versions/$CURRENT_VERSION/$CURRENT_VERSION.jar"
|
2013-11-03 20:02:41 -07:00
|
|
|
CLIENT_LOCATION="$LOCATION/.minecraft/versions/$CURRENT_VERSION"
|
2013-06-24 11:26:09 -07:00
|
|
|
|
|
|
|
|
2013-06-24 13:20:10 -07:00
|
|
|
# World (Server Instance) Configuration
|
|
|
|
# ---------------------------------------------------------------------------
|
2013-06-24 11:26:09 -07:00
|
|
|
|
|
|
|
# The location to store files for each world server.
|
|
|
|
WORLDS_LOCATION="$LOCATION/worlds"
|
|
|
|
|
2013-10-19 10:47:23 -07:00
|
|
|
# The location to store disabled world server files.
|
|
|
|
DISABLED_WORLDS_LOCATION="$LOCATION/worlds-disabled"
|
|
|
|
|
2013-06-24 13:25:27 -07:00
|
|
|
# Default world name, port, and IP address if the worlds.conf file is
|
|
|
|
# missing.
|
2013-06-24 11:26:09 -07:00
|
|
|
DEFAULT_WORLD="world"
|
|
|
|
DEFAULT_PORT="25565"
|
|
|
|
DEFAULT_IP=""
|
|
|
|
|
|
|
|
|
2013-06-24 13:20:10 -07:00
|
|
|
# Global Message Of The Day file (MOTD)
|
|
|
|
# ---------------------------------------------------------------------------
|
2013-06-24 11:26:09 -07:00
|
|
|
|
|
|
|
# Location of the file to display to users on login. Nothing will be done if
|
|
|
|
# this file does not exist.
|
|
|
|
MOTD="$LOCATION/motd.txt"
|
|
|
|
|
|
|
|
|
2013-06-25 21:18:56 -07:00
|
|
|
# NOTE: MOTD can contain color codes as follows:
|
2013-06-24 11:26:09 -07:00
|
|
|
# §0 - black
|
|
|
|
# §1 - blue
|
|
|
|
# §2 - dark green
|
|
|
|
# §3 - aqua
|
|
|
|
# §4 - dark red
|
|
|
|
# §5 - purple
|
|
|
|
# §6 - gold
|
|
|
|
# §7 - gray
|
|
|
|
# §8 - dark gray
|
|
|
|
# §9 - light blue
|
|
|
|
# §a - green
|
|
|
|
# §b - teal
|
|
|
|
# §c - red
|
|
|
|
# §d - magenta
|
|
|
|
# §e - yellow
|
|
|
|
# §f - white
|
|
|
|
|
|
|
|
|
2013-06-24 13:20:10 -07:00
|
|
|
# Backup Configuration
|
|
|
|
# ---------------------------------------------------------------------------
|
2013-06-24 11:26:09 -07:00
|
|
|
|
|
|
|
# Location to store backups.
|
|
|
|
BACKUP_LOCATION="$LOCATION/backups"
|
|
|
|
|
|
|
|
# Location of the backup log file.
|
|
|
|
BACKUP_LOG="$BACKUP_LOCATION/backup.log"
|
|
|
|
|
|
|
|
# Length in days that backups survive.
|
2013-06-26 16:20:21 -07:00
|
|
|
BACKUP_DURATION=15
|
2013-06-24 11:26:09 -07:00
|
|
|
|
2013-06-24 13:20:10 -07:00
|
|
|
|
|
|
|
# Server Log Configuration
|
|
|
|
# ---------------------------------------------------------------------------
|
2013-06-24 11:26:09 -07:00
|
|
|
|
2013-11-09 17:09:19 -07:00
|
|
|
# How many rotations of latest.log to keep
|
2013-06-24 11:26:09 -07:00
|
|
|
LOG_COUNT=10
|
|
|
|
|
|
|
|
|
2013-06-26 15:28:52 -07:00
|
|
|
# Mirror Image Options
|
2013-06-24 13:20:10 -07:00
|
|
|
# ---------------------------------------------------------------------------
|
2013-06-24 11:26:09 -07:00
|
|
|
|
|
|
|
# Create a mirror image of the world data on system startup, and
|
|
|
|
# update that mirror image on system shutdown.
|
|
|
|
#
|
|
|
|
# IMPORTANT: If using this option, the admin should schedule
|
|
|
|
# periodic synchronizations of the mirror image using cron
|
2013-06-26 15:48:37 -07:00
|
|
|
# to avoid data loss. To do this, add a cron task to call
|
|
|
|
# the "sync" option on a VERY regular basis (e.g.,
|
|
|
|
# every 5-10 minutes).
|
2013-06-24 11:26:09 -07:00
|
|
|
#
|
|
|
|
# 0 - Do not use a mirror image, default.
|
|
|
|
# 1 - Use a mirror image.
|
|
|
|
ENABLE_MIRROR=0
|
|
|
|
|
|
|
|
# The location to store the mirror image.
|
|
|
|
#
|
2013-06-25 21:18:56 -07:00
|
|
|
# NOTE: This is usually a ramdisk, e.g. /dev/shm on Debian/Ubuntu.
|
2013-06-24 11:26:09 -07:00
|
|
|
MIRROR_PATH="/dev/shm/minecraft"
|
|
|
|
|
|
|
|
|
2013-06-24 13:20:10 -07:00
|
|
|
# Mincecraft Overviewer Mapping Software Options
|
|
|
|
# ---------------------------------------------------------------------------
|
|
|
|
|
2013-06-24 11:26:09 -07:00
|
|
|
OVERVIEWER_BIN=$(which overviewer.py)
|
|
|
|
MAPS_URL="http://minecraft.server.com/maps"
|
|
|
|
MAPS_LOCATION="$LOCATION/maps"
|
|
|
|
|
2013-06-24 13:20:10 -07:00
|
|
|
|
|
|
|
# Lib-Notify Configuration
|
|
|
|
# ---------------------------------------------------------------------------
|
2013-06-24 11:26:09 -07:00
|
|
|
|
2013-06-24 13:25:27 -07:00
|
|
|
# Use lib-notify to print a message on your desktop of important server
|
|
|
|
# events.
|
2013-06-24 11:26:09 -07:00
|
|
|
# 0 - Do not use lib-notify.
|
|
|
|
# 1 - Display server events using lib-notify.
|
|
|
|
USE_LIBNOTIFY=0
|
|
|
|
|
|
|
|
# The username and display that messages will be routed to.
|
|
|
|
LIBNOTIFY_USER_NAME=$USER_NAME
|
|
|
|
LIBNOTIFY_DISPLAY=":0.0"
|
|
|
|
|
|
|
|
|
2013-06-24 13:20:10 -07:00
|
|
|
# ---------------------------------------------------------------------------
|
|
|
|
# Internal Methods
|
|
|
|
# ---------------------------------------------------------------------------
|
|
|
|
#
|
|
|
|
# NOTE: Nothing below this point should need to be edited directly.
|
|
|
|
# ---------------------------------------------------------------------------
|
|
|
|
|
2013-06-24 11:26:09 -07:00
|
|
|
|
2013-06-24 13:20:10 -07:00
|
|
|
# ---------------------------------------------------------------------------
|
2013-06-24 11:26:09 -07:00
|
|
|
# Execute the given command.
|
|
|
|
#
|
|
|
|
# @param 1 The command to execute.
|
|
|
|
# @param 2 The user name to execute the command with.
|
2013-06-24 13:20:10 -07:00
|
|
|
# ---------------------------------------------------------------------------
|
2013-06-24 11:26:09 -07:00
|
|
|
execute() {
|
2013-08-04 09:09:40 -07:00
|
|
|
if [ $(id -u) -eq 0 ]; then
|
|
|
|
# Script is running as root, switch user and execute
|
|
|
|
# the command.
|
|
|
|
su -c "$1" $2
|
|
|
|
else
|
|
|
|
# Script is running as a user, just execute the command.
|
|
|
|
sh -c "$1"
|
|
|
|
fi
|
2013-06-24 11:26:09 -07:00
|
|
|
}
|
|
|
|
|
2013-06-24 13:20:10 -07:00
|
|
|
# ---------------------------------------------------------------------------
|
2013-06-24 11:26:09 -07:00
|
|
|
# Get the PIDs of the Screen and Java process for the world server.
|
|
|
|
#
|
|
|
|
# @param 1 The world server of interest.
|
2013-06-26 15:28:52 -07:00
|
|
|
# @return The Screen and Java PIDs.
|
2013-06-24 13:20:10 -07:00
|
|
|
# ---------------------------------------------------------------------------
|
2013-06-24 11:26:09 -07:00
|
|
|
getProcessIDs() {
|
2013-08-04 09:09:40 -07:00
|
|
|
local SCREEN_PID JAVA_PID
|
|
|
|
SCREEN_PID=$(execute "$SCREEN -ls" $USER_NAME | $PERL -ne 'if ($_ =~ /^\t(\d+)\.minecraft-'$1'\s+/) { print $1; }')
|
|
|
|
JAVA_PID=$(ps -a -u $USER_NAME -o pid,ppid,comm | $PERL -ne 'if ($_ =~ /^\s*(\d+)\s+'$SCREEN_PID'\s+java/) { print $1; }')
|
|
|
|
echo "$SCREEN_PID $JAVA_PID"
|
2013-06-24 11:26:09 -07:00
|
|
|
}
|
|
|
|
|
2013-06-24 13:20:10 -07:00
|
|
|
# ---------------------------------------------------------------------------
|
2013-06-24 11:26:09 -07:00
|
|
|
# Check to see if the world server is running.
|
|
|
|
#
|
|
|
|
# @param 1 The world server of interest.
|
|
|
|
# @return A 1 if the server is thought to be running, a 0 otherwise.
|
2013-06-24 13:20:10 -07:00
|
|
|
# ---------------------------------------------------------------------------
|
2013-06-24 11:26:09 -07:00
|
|
|
serverRunning() {
|
2013-11-01 15:58:04 -07:00
|
|
|
local PIDS SCREEN_PID JAVA_PID
|
2013-08-04 09:09:40 -07:00
|
|
|
PIDS=$(getProcessIDs $1)
|
2013-11-01 15:58:04 -07:00
|
|
|
SCREEN_PID=$(echo "$PIDS" | cut -d ' ' -f1)
|
|
|
|
JAVA_PID=$(echo "$PIDS" | cut -d ' ' -f2)
|
2013-08-04 09:09:40 -07:00
|
|
|
# Try to determine if the world is running.
|
2013-11-01 15:58:04 -07:00
|
|
|
if [ -n "$SCREEN_PID" ] && [ $SCREEN_PID -gt 0 ] &&
|
|
|
|
[ -n "$JAVA_PID" ] && [ $JAVA_PID -gt 0 ]; then
|
2013-08-04 09:09:40 -07:00
|
|
|
echo 1
|
|
|
|
else
|
|
|
|
echo 0
|
|
|
|
fi
|
2013-06-24 11:26:09 -07:00
|
|
|
}
|
|
|
|
|
2013-06-24 13:20:10 -07:00
|
|
|
# ---------------------------------------------------------------------------
|
2013-06-24 11:26:09 -07:00
|
|
|
# Send a command to the world server.
|
|
|
|
#
|
|
|
|
# @param 1 The world server of interest.
|
|
|
|
# @param 2 The command to send.
|
2013-06-24 13:20:10 -07:00
|
|
|
# ---------------------------------------------------------------------------
|
2013-06-24 11:26:09 -07:00
|
|
|
sendCommand() {
|
2013-08-04 09:09:40 -07:00
|
|
|
local COMMAND PID
|
|
|
|
COMMAND=$(printf "$2\r")
|
|
|
|
PID=$(echo $(getProcessIDs $1) | cut -d ' ' -f1)
|
|
|
|
execute "$SCREEN -S $PID.minecraft-$1 -p 0 -X stuff \"$COMMAND\"" $USER_NAME
|
|
|
|
if [ $? -ne 0 ]; then
|
|
|
|
printf "Error sending command to server $1.\n"
|
|
|
|
exit 1
|
|
|
|
fi
|
2013-06-24 11:26:09 -07:00
|
|
|
}
|
|
|
|
|
2013-06-24 13:20:10 -07:00
|
|
|
# ---------------------------------------------------------------------------
|
2013-06-24 11:26:09 -07:00
|
|
|
# Connect to the Screen of a world server.
|
|
|
|
#
|
|
|
|
# @param 1 The world server of interest.
|
2013-06-24 13:20:10 -07:00
|
|
|
# ---------------------------------------------------------------------------
|
2013-06-24 11:26:09 -07:00
|
|
|
displayScreen() {
|
2013-08-04 09:09:40 -07:00
|
|
|
local PID TTY_PERMISSIONS
|
|
|
|
PID=$(echo $(getProcessIDs $1) | cut -d ' ' -f1)
|
|
|
|
TTY_PERMISSIONS=$($PERL -e 'printf "%04o", ((stat(shift))[2] & 07777);' $(tty))
|
|
|
|
# Make sure that we have read/write access to the tty.
|
|
|
|
execute "chmod o+rw $(tty)" > /dev/null 2>&1
|
|
|
|
if [ $? -ne 0 ]; then
|
|
|
|
printf "Error changing the permissions of the tty.\n"
|
|
|
|
printf "Try giving user '$USER_NAME' access to the tty with:\n"
|
|
|
|
printf " chmod o+rw $(tty)\n"
|
|
|
|
printf "\n"
|
|
|
|
printf "Attempting to load the screen anyway.\n"
|
|
|
|
fi
|
|
|
|
# Connect to the screen of the world server.
|
|
|
|
execute "$SCREEN -x $PID.minecraft-$1" $USER_NAME
|
|
|
|
if [ $? -ne 0 ]; then
|
|
|
|
printf "Error connecting to Screen.\n"
|
|
|
|
execute "chmod $TTY_PERMISSIONS $(tty)" > /dev/null 2>&1
|
|
|
|
exit 1
|
|
|
|
fi
|
|
|
|
execute "chmod $TTY_PERMISSIONS $(tty)" > /dev/null 2>&1
|
2013-06-24 11:26:09 -07:00
|
|
|
}
|
|
|
|
|
2013-06-24 13:20:10 -07:00
|
|
|
# ---------------------------------------------------------------------------
|
2013-06-24 11:26:09 -07:00
|
|
|
# Check whether the item is in the list.
|
|
|
|
#
|
|
|
|
# @param 1 The item being searched for.
|
|
|
|
# @param 2 The list being searched.
|
|
|
|
# @return A 1 if the list contains the item, a 0 otherwise.
|
2013-06-24 13:20:10 -07:00
|
|
|
# ---------------------------------------------------------------------------
|
2013-06-24 11:26:09 -07:00
|
|
|
listContains() {
|
2013-08-04 09:09:40 -07:00
|
|
|
local MATCH ITEM
|
|
|
|
MATCH=0
|
|
|
|
for ITEM in $2; do
|
|
|
|
if [ "$ITEM" = "$1" ]; then
|
|
|
|
MATCH=1
|
|
|
|
fi
|
|
|
|
done
|
|
|
|
echo $MATCH
|
2013-06-24 11:26:09 -07:00
|
|
|
}
|
|
|
|
|
2013-10-19 09:57:29 -07:00
|
|
|
# ---------------------------------------------------------------------------
|
|
|
|
# Create a world.
|
|
|
|
#
|
|
|
|
# @param 1 The world server to create.
|
|
|
|
# @param 2 The port of the world server.
|
|
|
|
# @param 3 The IP address of the world server.
|
|
|
|
# ---------------------------------------------------------------------------
|
|
|
|
createWorld() {
|
|
|
|
# Create a basic server.properties file. Values not supplied here
|
|
|
|
# will use default values when the world server is first started.
|
|
|
|
execute "mkdir -p $WORLDS_LOCATION/$1" $USER_NAME
|
2013-11-01 17:02:51 -07:00
|
|
|
setPropertiesValue "$1" "level-name" "$1"
|
|
|
|
setPropertiesValue "$1" "server-port" "$2"
|
|
|
|
setPropertiesValue "$1" "server-ip" "$3"
|
|
|
|
setPropertiesValue "$1" "enable-query" "true"
|
|
|
|
setPropertiesValue "$1" "query.port" "$2"
|
2013-10-19 09:57:29 -07:00
|
|
|
}
|
|
|
|
|
2013-10-19 10:15:16 -07:00
|
|
|
# ---------------------------------------------------------------------------
|
|
|
|
# Delete a world.
|
|
|
|
#
|
|
|
|
# @param 1 The world server to delete.
|
|
|
|
# ---------------------------------------------------------------------------
|
|
|
|
deleteWorld() {
|
|
|
|
# Delete the world directory.
|
|
|
|
execute "rm -Rf $WORLDS_LOCATION/$1" $USER_NAME
|
|
|
|
}
|
|
|
|
|
2013-10-19 10:47:23 -07:00
|
|
|
# ---------------------------------------------------------------------------
|
|
|
|
# Disable a world.
|
|
|
|
#
|
|
|
|
# @param 1 The world server to disable.
|
|
|
|
# ---------------------------------------------------------------------------
|
|
|
|
disableWorld() {
|
2013-12-02 20:54:12 -07:00
|
|
|
# Make sure the disabled world location exists.
|
|
|
|
execute "mkdir -p $DISABLED_WORLDS_LOCATION" $USER_NAME
|
2013-10-19 10:47:23 -07:00
|
|
|
# Disable the world.
|
|
|
|
execute "mv $WORLDS_LOCATION/$1 $DISABLED_WORLDS_LOCATION/$1" $USER_NAME
|
|
|
|
}
|
|
|
|
|
2013-10-19 10:57:04 -07:00
|
|
|
# ---------------------------------------------------------------------------
|
|
|
|
# Enable a world.
|
|
|
|
#
|
|
|
|
# @param 1 The world server to enable.
|
|
|
|
# ---------------------------------------------------------------------------
|
|
|
|
enableWorld() {
|
|
|
|
# Enable the world.
|
|
|
|
execute "mv $DISABLED_WORLDS_LOCATION/$1 $WORLDS_LOCATION/$1" $USER_NAME
|
|
|
|
}
|
|
|
|
|
2013-06-24 13:20:10 -07:00
|
|
|
# ---------------------------------------------------------------------------
|
2013-06-24 11:26:09 -07:00
|
|
|
# Grab the first line of the Message of the Day file as a summary, and strip
|
|
|
|
# any color codes from it.
|
2013-07-18 21:12:55 -07:00
|
|
|
#
|
|
|
|
# @param 1 The world server of interest.
|
|
|
|
# @return The global message of the day or the specifued world
|
2013-06-24 13:20:10 -07:00
|
|
|
# ---------------------------------------------------------------------------
|
2013-06-24 11:26:09 -07:00
|
|
|
getMOTD() {
|
2013-08-04 09:09:40 -07:00
|
|
|
local MOTD_SUMMARY WORLD_MOTD
|
|
|
|
MOTD_SUMMARY=""
|
|
|
|
WORLD_MOTD="$WORLDS_LOCATION/$1.motd"
|
|
|
|
if [ -e $WORLD_MOTD ]; then
|
2013-08-05 18:10:52 -07:00
|
|
|
MOTD_SUMMARY=$(head -n 1 $WORLD_MOTD | $PERL -ne '$_ =~ s/§[0-9a-fA-F]//g; print;')
|
2013-08-04 09:09:40 -07:00
|
|
|
elif [ -e $MOTD ]; then
|
2013-08-05 18:10:52 -07:00
|
|
|
MOTD_SUMMARY=$(head -n 1 $MOTD | $PERL -ne '$_ =~ s/§[0-9a-fA-F]//g; print;')
|
2013-08-04 09:09:40 -07:00
|
|
|
fi
|
|
|
|
echo $MOTD_SUMMARY
|
2013-06-24 11:26:09 -07:00
|
|
|
}
|
|
|
|
|
2013-06-24 13:20:10 -07:00
|
|
|
# ---------------------------------------------------------------------------
|
2013-12-03 14:49:45 -07:00
|
|
|
# Grab the list of enabled worlds.
|
2013-06-24 11:26:09 -07:00
|
|
|
#
|
2013-12-03 14:49:45 -07:00
|
|
|
# @return The list of enabled worlds.
|
2013-06-24 13:20:10 -07:00
|
|
|
# ---------------------------------------------------------------------------
|
2013-12-03 14:49:45 -07:00
|
|
|
getEnabledWorlds() {
|
2013-10-05 17:30:57 -07:00
|
|
|
local WORLD WORLDS
|
|
|
|
WORLDS=""
|
|
|
|
for WORLD in $(ls $WORLDS_LOCATION); do
|
|
|
|
if [ -f $WORLDS_LOCATION/$WORLD/server.properties ]; then
|
|
|
|
WORLDS="$WORLDS $WORLD"
|
|
|
|
fi
|
|
|
|
done
|
2013-08-04 09:09:40 -07:00
|
|
|
echo $WORLDS
|
2013-06-24 11:26:09 -07:00
|
|
|
}
|
|
|
|
|
2013-12-03 14:51:57 -07:00
|
|
|
# ---------------------------------------------------------------------------
|
|
|
|
# Grab the list of disabled worlds.
|
|
|
|
#
|
|
|
|
# @return The list of disabled worlds.
|
|
|
|
# ---------------------------------------------------------------------------
|
|
|
|
getDisabledWorlds() {
|
|
|
|
local WORLD WORLDS
|
|
|
|
WORLDS=""
|
|
|
|
for WORLD in $(ls $DISABLED_WORLDS_LOCATION); do
|
|
|
|
if [ -f $DISABLED_WORLDS_LOCATION/$WORLD/server.properties ]; then
|
|
|
|
WORLDS="$WORLDS $WORLD"
|
|
|
|
fi
|
|
|
|
done
|
|
|
|
echo $WORLDS
|
|
|
|
}
|
|
|
|
|
2013-07-18 20:57:42 -07:00
|
|
|
# ---------------------------------------------------------------------------
|
2013-10-07 20:04:37 -07:00
|
|
|
# Get the value of a key in a world properties file.
|
2013-07-18 20:57:42 -07:00
|
|
|
#
|
|
|
|
# @param 1 The world server of interest.
|
|
|
|
# @param 2 The key to get.
|
2013-11-01 17:05:42 -07:00
|
|
|
# @param 3 The default value.
|
2013-07-18 20:57:42 -07:00
|
|
|
# ---------------------------------------------------------------------------
|
2013-11-01 17:02:51 -07:00
|
|
|
getPropertiesValue() {
|
2013-10-17 15:06:35 -07:00
|
|
|
local PROPERTY_FILE KEY VALUE
|
2013-08-04 09:09:40 -07:00
|
|
|
PROPERTY_FILE=$WORLDS_LOCATION/$1/server.properties
|
|
|
|
# Make sure the properties file exists
|
|
|
|
if [ -e "$PROPERTY_FILE" ]; then
|
2013-10-17 15:06:35 -07:00
|
|
|
# Find the key/value combo.
|
2013-12-01 13:12:01 -07:00
|
|
|
KEY=$($PERL -ne 'if ($_ =~ /^('$2')=.*$/i) { print lc $1; }' $PROPERTY_FILE)
|
|
|
|
VALUE=$($PERL -ne 'if ($_ =~ /^'$2'=(.*)$/i) { print lc $1; }' $PROPERTY_FILE)
|
2013-08-04 09:09:40 -07:00
|
|
|
if [ -n "$KEY" ] && [ -n "$VALUE" ]; then
|
|
|
|
echo "$VALUE"
|
|
|
|
else
|
2013-11-01 17:05:42 -07:00
|
|
|
echo "$3"
|
2013-08-04 09:09:40 -07:00
|
|
|
fi
|
|
|
|
fi
|
2013-07-16 23:11:37 -07:00
|
|
|
}
|
|
|
|
|
2013-06-24 13:20:10 -07:00
|
|
|
# ---------------------------------------------------------------------------
|
2013-10-17 15:08:37 -07:00
|
|
|
# Modify the value of a key/value combo in a world properties file.
|
2013-06-24 11:26:09 -07:00
|
|
|
#
|
2013-10-17 15:08:37 -07:00
|
|
|
# @param 1 The world server of interest.
|
2013-06-24 11:26:09 -07:00
|
|
|
# @param 2 The key to modify.
|
|
|
|
# @param 3 The value to assign to the key.
|
2013-06-24 13:20:10 -07:00
|
|
|
# ---------------------------------------------------------------------------
|
2013-11-01 17:02:51 -07:00
|
|
|
setPropertiesValue() {
|
2013-10-17 15:08:37 -07:00
|
|
|
local PROPERTY_FILE KEY_VALUE
|
|
|
|
PROPERTY_FILE=$WORLDS_LOCATION/$1/server.properties
|
2013-08-04 09:09:40 -07:00
|
|
|
# Make sure that the properties file exists.
|
2013-10-17 15:08:37 -07:00
|
|
|
execute "touch $PROPERTY_FILE" $USER_NAME
|
2013-08-04 09:09:40 -07:00
|
|
|
# Replace the key/value combo if it already exists, otherwise just
|
|
|
|
# append it to the end of the file.
|
2013-10-17 15:08:37 -07:00
|
|
|
KEY_VALUE=$($PERL -ne 'if ($_ =~ /^('$2'=.*)$/) { print "$1"; }' $PROPERTY_FILE)
|
2013-08-04 09:09:40 -07:00
|
|
|
if [ -n "$KEY_VALUE" ]; then
|
2013-10-17 15:08:37 -07:00
|
|
|
execute "$PERL -i -ne 'if (\$_ =~ /^$2=.*$/) { print \"$2=$3\\n\"; } else { print; }' $PROPERTY_FILE" $USER_NAME
|
2013-08-04 09:09:40 -07:00
|
|
|
else
|
2013-10-17 15:08:37 -07:00
|
|
|
execute "printf \"$2=$3\\n\" >> $PROPERTY_FILE" $USER_NAME
|
2013-08-04 09:09:40 -07:00
|
|
|
fi
|
2013-06-24 11:26:09 -07:00
|
|
|
}
|
|
|
|
|
2013-06-24 13:20:10 -07:00
|
|
|
# ---------------------------------------------------------------------------
|
2013-06-24 11:26:09 -07:00
|
|
|
# Send a message to the desktop using lib-notify, if it is available.
|
|
|
|
#
|
|
|
|
# @param 1 The summary of the message to send.
|
|
|
|
# @param 2 The body of the message to send.
|
2013-06-24 13:20:10 -07:00
|
|
|
# ---------------------------------------------------------------------------
|
2013-06-24 11:26:09 -07:00
|
|
|
libNotify() {
|
2013-08-04 09:09:40 -07:00
|
|
|
local NOTIFY
|
|
|
|
NOTIFY=$(which notify-send)
|
|
|
|
if [ -e "$NOTIFY" ]; then
|
|
|
|
execute "DISPLAY=$LIBNOTIFY_DISPLAY $NOTIFY \"$1\" \"$2\"" $LIBNOTIFY_USER_NAME > /dev/null 2>&1
|
|
|
|
fi
|
2013-06-24 11:26:09 -07:00
|
|
|
}
|
|
|
|
|
2013-06-24 13:20:10 -07:00
|
|
|
# ---------------------------------------------------------------------------
|
2013-06-24 11:26:09 -07:00
|
|
|
# Send the contents of the Message Of The Day (MOTD) to the user.
|
|
|
|
#
|
|
|
|
# @param 1 The world server of interest.
|
|
|
|
# @param 2 The user being told the contents of the motd file.
|
2013-06-24 13:20:10 -07:00
|
|
|
# ---------------------------------------------------------------------------
|
2013-06-24 11:26:09 -07:00
|
|
|
tellMOTD() {
|
2013-08-04 09:09:40 -07:00
|
|
|
local LINE WORLD_MOTD
|
|
|
|
WORLD_MOTD="$WORLDS_LOCATION/$1.motd"
|
|
|
|
if [ -e $WORLD_MOTD ]; then
|
|
|
|
while read LINE; do
|
|
|
|
sendCommand $1 "tell $2 $LINE"
|
|
|
|
done < $WORLD_MOTD
|
|
|
|
elif [ -e $MOTD ]; then
|
|
|
|
while read LINE; do
|
|
|
|
sendCommand $1 "tell $2 $LINE"
|
|
|
|
done < $MOTD
|
|
|
|
fi
|
2013-06-24 11:26:09 -07:00
|
|
|
}
|
|
|
|
|
2013-12-02 19:26:56 -07:00
|
|
|
# ---------------------------------------------------------------------------
|
|
|
|
# Check to see if the user running this script has the correct permissions.
|
|
|
|
# ---------------------------------------------------------------------------
|
|
|
|
checkPermission() {
|
|
|
|
# Make sure that the minecraft user exists.
|
|
|
|
if [ ! -n "$(grep $USER_NAME /etc/passwd)" ]; then
|
|
|
|
printf "ERROR: This script requires that a user account named "
|
|
|
|
printf "$USER_NAME exist on this system.\nEither modify the "
|
|
|
|
printf "USER_NAME variable in this script, or try adding this "
|
|
|
|
printf "user:\n"
|
|
|
|
printf "sudo adduser $USER_NAME\n"
|
|
|
|
exit 1
|
|
|
|
fi
|
|
|
|
# Check to see if the user is root or is the minecraft user.
|
|
|
|
if [ $(id -u) -gt 0 ] && [ "$(whoami)" != "$USER_NAME" ]; then
|
|
|
|
# Script is running with the wrong user.
|
|
|
|
printf "WARNING: This script appears to have been started by the "
|
|
|
|
printf "wrong user.\n"
|
|
|
|
printf "Expected to find the user: $USER_NAME. You can try to log "
|
|
|
|
printf "on to this user:\n"
|
|
|
|
printf "su $USER_NAME\n"
|
|
|
|
exit 1
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
2013-06-24 13:20:10 -07:00
|
|
|
# ---------------------------------------------------------------------------
|
2013-06-24 11:26:09 -07:00
|
|
|
# Check to see if the user is in the ops.txt file of the specified world.
|
|
|
|
#
|
|
|
|
# @param 1 The world server of interest.
|
|
|
|
# @param 2 The user being checked.
|
2013-06-24 13:20:10 -07:00
|
|
|
# ---------------------------------------------------------------------------
|
2013-06-24 11:26:09 -07:00
|
|
|
checkUserIsAdmin() {
|
2013-08-04 09:09:40 -07:00
|
|
|
local IS_ADMIN
|
|
|
|
IS_ADMIN=$(cat $WORLDS_LOCATION/$1/ops.txt | $PERL -ne 'if ($_ =~ /^'$2'$/i) { print "1"; }')
|
|
|
|
echo $IS_ADMIN
|
2013-06-24 11:26:09 -07:00
|
|
|
}
|
|
|
|
|
2013-06-24 13:20:10 -07:00
|
|
|
# ---------------------------------------------------------------------------
|
2013-11-09 17:09:19 -07:00
|
|
|
# Rotates the world latest.log file.
|
2013-06-24 11:26:09 -07:00
|
|
|
#
|
|
|
|
# @param 1 The world server generating the log to rotate.
|
2013-06-24 13:20:10 -07:00
|
|
|
# ---------------------------------------------------------------------------
|
2013-06-24 11:26:09 -07:00
|
|
|
rotateLog() {
|
2013-08-04 09:09:40 -07:00
|
|
|
local WORLD_DIR LOG_LIST LOG_LINES LOG_NUMBER
|
|
|
|
WORLD_DIR="$WORLDS_LOCATION/$1"
|
2013-11-09 17:09:19 -07:00
|
|
|
# Make sure that the latest.log file exists.
|
|
|
|
execute "touch $WORLD_DIR/logs/latest.log" $USER_NAME
|
2013-08-04 09:09:40 -07:00
|
|
|
# Scan the log for entires and skip rotate is none are found.
|
2013-11-09 17:09:19 -07:00
|
|
|
LOG_LINES="$(cat "$WORLD_DIR/logs/latest.log" | wc -l )"
|
2013-08-04 09:09:40 -07:00
|
|
|
if [ $LOG_LINES -le 1 ]; then
|
|
|
|
printf "\nNo new log entries to rotate. No changes made.\n"
|
|
|
|
return 0
|
|
|
|
fi
|
|
|
|
# Server logfiles in chronological order.
|
2013-11-09 17:09:19 -07:00
|
|
|
LOGLIST=$(ls -r $WORLD_DIR/logs/latest.log* | grep -v lck)
|
2013-08-04 09:09:40 -07:00
|
|
|
# Look at all the logfiles
|
|
|
|
for i in $LOGLIST; do
|
|
|
|
LOG_NUMBER=$(ls $i | cut -d "." -f 3)
|
2013-11-09 17:09:19 -07:00
|
|
|
# If we're working with latest.log, append .1 then compress
|
2013-08-04 09:09:40 -07:00
|
|
|
# it.
|
|
|
|
if [ -z $LOG_NUMBER ]; then
|
|
|
|
LOG_NUMBER="1"
|
2013-11-09 17:09:19 -07:00
|
|
|
execute "cp $WORLD_DIR/logs/latest.log $WORLD_DIR/logs/latest.log.$LOG_NUMBER" $USER_NAME
|
|
|
|
execute "gzip $WORLD_DIR/logs/latest.log.$LOG_NUMBER" $USER_NAME
|
2013-08-04 09:09:40 -07:00
|
|
|
# Otherwise, check if the file number is under $LOG_COUNT.
|
|
|
|
elif [ $LOG_NUMBER -ge $LOG_COUNT ]; then
|
|
|
|
# If so, delete it.
|
|
|
|
execute "rm -f $i" $USER_NAME
|
|
|
|
else
|
|
|
|
# Otherwise, add one to the number.
|
|
|
|
LOG_NUMBER=$(($LOG_NUMBER+1))
|
2013-11-09 17:09:19 -07:00
|
|
|
execute "mv -f $i $WORLD_DIR/logs/latest.log.$LOG_NUMBER.gz" $USER_NAME
|
2013-08-04 09:09:40 -07:00
|
|
|
fi
|
|
|
|
done
|
|
|
|
# Blank the existing logfile to renew it.
|
2013-11-09 17:09:19 -07:00
|
|
|
execute "cp /dev/null $WORLD_DIR/logs/latest.log" $USER_NAME
|
2013-06-24 11:26:09 -07:00
|
|
|
}
|
|
|
|
|
2013-06-24 13:20:10 -07:00
|
|
|
# ---------------------------------------------------------------------------
|
2013-11-09 17:09:19 -07:00
|
|
|
# Watch the world latest.log file.
|
2013-06-24 11:26:09 -07:00
|
|
|
#
|
|
|
|
# @param 1 The world server generating the log to watch.
|
2013-06-24 13:20:10 -07:00
|
|
|
# ---------------------------------------------------------------------------
|
2013-06-24 11:26:09 -07:00
|
|
|
watchLog() {
|
2013-08-04 09:09:40 -07:00
|
|
|
local PID WORLD_DIR
|
|
|
|
WORLD_DIR="$WORLDS_LOCATION/$1"
|
2013-11-09 17:09:19 -07:00
|
|
|
# Make sure that the latest.log file exists.
|
|
|
|
if [ -e "$WORLD_DIR/logs/latest.log" ]; then
|
2013-08-04 09:09:40 -07:00
|
|
|
# Watch the log.
|
|
|
|
PID=$(echo $(getProcessIDs $1) | cut -d ' ' -f2)
|
2013-11-09 17:09:19 -07:00
|
|
|
tail -n0 -f --pid=$PID $WORLD_DIR/logs/latest.log
|
2013-08-04 09:09:40 -07:00
|
|
|
fi
|
2013-06-24 11:26:09 -07:00
|
|
|
}
|
|
|
|
|
2013-06-24 13:20:10 -07:00
|
|
|
# ---------------------------------------------------------------------------
|
2013-06-24 11:26:09 -07:00
|
|
|
# Synchronizes the data stored in the mirror images.
|
|
|
|
#
|
|
|
|
# @param 1 The world server to sync.
|
2013-06-24 13:20:10 -07:00
|
|
|
# ---------------------------------------------------------------------------
|
2013-06-24 11:26:09 -07:00
|
|
|
syncMirrorImage() {
|
2013-08-04 09:09:40 -07:00
|
|
|
# Sync the world server.
|
2013-08-04 10:33:58 -07:00
|
|
|
execute "cp -Ru $WORLDS_LOCATION/$1/$1/* $WORLDS_LOCATION/$1/$1-original" $USER_NAME
|
2013-08-04 09:09:40 -07:00
|
|
|
if [ $? -ne 0 ]; then
|
|
|
|
printf "Error synchronizing mirror images for world $1.\n"
|
|
|
|
exit 1
|
|
|
|
fi
|
2013-06-24 11:26:09 -07:00
|
|
|
}
|
|
|
|
|
2013-06-24 13:20:10 -07:00
|
|
|
# ---------------------------------------------------------------------------
|
2013-08-05 16:32:23 -07:00
|
|
|
# Start the world server. Generate the appropriate environment for the
|
|
|
|
# server if it doesn't already exist.
|
2013-06-24 11:26:09 -07:00
|
|
|
#
|
|
|
|
# @param 1 The world server to start.
|
2013-06-24 13:20:10 -07:00
|
|
|
# ---------------------------------------------------------------------------
|
2013-06-24 11:26:09 -07:00
|
|
|
start() {
|
2013-08-04 09:09:40 -07:00
|
|
|
local PID WORLD_DIR
|
2013-12-02 22:10:56 -07:00
|
|
|
# Make sure that the server software exists.
|
|
|
|
updateServerSoftware "$1"
|
2013-08-04 09:09:40 -07:00
|
|
|
# Make sure that the world's directory exists.
|
|
|
|
WORLD_DIR="$WORLDS_LOCATION/$1"
|
|
|
|
execute "mkdir -p $WORLD_DIR" $USER_NAME
|
|
|
|
# Make a mirror image of the world directory if requested.
|
2013-08-04 10:33:58 -07:00
|
|
|
if [ $ENABLE_MIRROR -eq 1 ]; then
|
2013-08-04 09:09:40 -07:00
|
|
|
execute "mkdir -p $MIRROR_PATH/$1" $USER_NAME
|
2013-08-04 10:33:58 -07:00
|
|
|
if [ $? -ne 0 ]; then
|
|
|
|
printf "Error copying world data, path %s not found.\n" $MIRROR_PATH/$1
|
|
|
|
exit 1
|
|
|
|
fi
|
|
|
|
# Check for a clean dismount from the previous server run. If we have a
|
|
|
|
# <world>-original directory within <world> we didn't stop cleanly.
|
|
|
|
if [ -d "WORLDS_LOCATION/$1/$1-original" ]; then
|
|
|
|
# Remove the symlink to the world-file mirror image.
|
|
|
|
execute "rm -r $WORLDS_LOCATION/$1/$1" $USER_NAME
|
|
|
|
# Move the world files back to their original path name.
|
|
|
|
execute "mv $WORLDS_LOCATION/$1/$1-original $WORLDS_LOCATION/$1/$1" $USER_NAME
|
|
|
|
fi
|
|
|
|
# Copy the world files over to the mirror.
|
|
|
|
execute "cp -R $WORLDS_LOCATION/$1/$1/* $MIRROR_PATH/$1" $USER_NAME
|
|
|
|
# Rename the original world file directory.
|
|
|
|
execute "mv $WORLDS_LOCATION/$1/$1 $WORLDS_LOCATION/$1/$1-original" $USER_NAME
|
|
|
|
# Create a symlink from the world file directory's original name to the mirrored files.
|
|
|
|
execute "ln -s $MIRROR_PATH/$1 $WORLDS_LOCATION/$1/$1" $USER_NAME
|
2013-08-04 09:09:40 -07:00
|
|
|
fi
|
|
|
|
# Change to the world's directory.
|
|
|
|
cd $WORLD_DIR
|
|
|
|
# Start the server.
|
|
|
|
execute "$SCREEN -dmS minecraft-$1 $SERVER_COMMAND" $USER_NAME
|
|
|
|
if [ $? -ne 0 ]; then
|
|
|
|
printf "Error starting the server.\n"
|
|
|
|
exit 1
|
|
|
|
fi
|
|
|
|
# Grab the Screen Process ID of the server.
|
|
|
|
PID=$(echo $(getProcessIDs $1) | cut -d ' ' -f1)
|
|
|
|
if [ ! -n "$PID" ]; then
|
|
|
|
printf "Error starting the server: SCREEN failed to create a screen for the server.\n"
|
|
|
|
exit 1
|
|
|
|
fi
|
|
|
|
# Grab the Java Process ID of the server.
|
|
|
|
PID=$(echo $(getProcessIDs $1) | cut -d ' ' -f2)
|
|
|
|
if [ ! -n "$PID" ]; then
|
|
|
|
printf "Error starting the server: couldn't retrieve the server's process ID.\n"
|
|
|
|
exit 1
|
|
|
|
fi
|
2013-12-03 11:39:13 -07:00
|
|
|
# Start the Query handler if enabled.
|
2013-12-01 12:29:39 -07:00
|
|
|
if [ "$(getPropertiesValue $1 'enable-query')" = "true" ]; then
|
2013-12-03 11:39:13 -07:00
|
|
|
queryStart "$1" &
|
2013-12-01 12:29:39 -07:00
|
|
|
fi
|
2013-08-04 09:09:40 -07:00
|
|
|
# Create a lock file on RedHat and derivatives.
|
|
|
|
if [ -d "/var/lock/subsys" ]; then
|
|
|
|
touch /var/lock/subsys/minecraft_server
|
|
|
|
fi
|
2013-06-24 11:26:09 -07:00
|
|
|
}
|
|
|
|
|
2013-06-24 13:20:10 -07:00
|
|
|
# ---------------------------------------------------------------------------
|
2013-06-24 11:26:09 -07:00
|
|
|
# Stop the world server.
|
|
|
|
#
|
|
|
|
# @param 1 The world server to stop.
|
2013-06-24 13:20:10 -07:00
|
|
|
# ---------------------------------------------------------------------------
|
2013-06-24 11:26:09 -07:00
|
|
|
stop() {
|
2013-08-04 09:09:40 -07:00
|
|
|
local WORLD NUM
|
|
|
|
sendCommand $1 "stop"
|
|
|
|
# Synchronize the mirror image of the world prior to closing, if
|
|
|
|
# required.
|
|
|
|
if [ $ENABLE_MIRROR -eq 1 ] && [ -d $MIRROR_PATH ]; then
|
|
|
|
syncMirrorImage $1
|
2013-08-04 10:33:58 -07:00
|
|
|
# Remove the symlink to the world-file mirror image.
|
|
|
|
execute "rm -r $WORLDS_LOCATION/$1/$1" $USER_NAME
|
|
|
|
# Move the world files back to their original path name.
|
|
|
|
execute "mv $WORLDS_LOCATION/$1/$1-original $WORLDS_LOCATION/$1/$1" $USER_NAME
|
2013-08-04 09:09:40 -07:00
|
|
|
fi
|
|
|
|
# Remove the lock file on Redhat and derivatives if all world servers
|
|
|
|
# are stopped.
|
|
|
|
if [ -e "/var/lock/subsys/minecraft_server" ]; then
|
|
|
|
NUM=0
|
|
|
|
for WORLD in $ALL_WORLDS; do
|
|
|
|
if [ "$1" != "$WORLD" ] && [ $(serverRunning $WORLD) -eq 1 ]; then
|
|
|
|
NUM=$(($NUM + 1))
|
|
|
|
fi
|
|
|
|
done
|
|
|
|
if [ $NUM -eq 0 ]; then
|
|
|
|
rm -f /var/lock/subsys/minecraft_server
|
|
|
|
fi
|
|
|
|
fi
|
2013-06-24 11:26:09 -07:00
|
|
|
}
|
|
|
|
|
2013-06-24 13:20:10 -07:00
|
|
|
# ---------------------------------------------------------------------------
|
2013-06-24 11:26:09 -07:00
|
|
|
# Forcibly stop the world server.
|
|
|
|
#
|
|
|
|
# @param 1 The world server to forcibly stop.
|
2013-06-24 13:20:10 -07:00
|
|
|
# ---------------------------------------------------------------------------
|
2013-06-24 11:26:09 -07:00
|
|
|
forceStop() {
|
2013-08-04 09:09:40 -07:00
|
|
|
local PIDS
|
|
|
|
PIDS=$(getProcessIDs $1)
|
|
|
|
# Try to stop the server cleanly first.
|
|
|
|
stop $1
|
|
|
|
sleep 5
|
|
|
|
# Kill the process ids of the world server.
|
|
|
|
kill -9 $PIDS > /dev/null 2>&1
|
2013-11-01 16:18:29 -07:00
|
|
|
# Cleanup the dead screen.
|
|
|
|
execute "$SCREEN -wipe" $USER_NAME > /dev/null 2>&1
|
2013-08-04 09:09:40 -07:00
|
|
|
# Remove the lock file on Redhat and derivatives if it is still
|
|
|
|
# around.
|
|
|
|
rm -f /var/lock/subsys/minecraft_server
|
2013-06-24 11:26:09 -07:00
|
|
|
}
|
|
|
|
|
2013-06-24 13:20:10 -07:00
|
|
|
# ---------------------------------------------------------------------------
|
2013-06-24 11:26:09 -07:00
|
|
|
# Backup the world server.
|
|
|
|
#
|
|
|
|
# @param 1 The world server to backup.
|
2013-06-24 13:20:10 -07:00
|
|
|
# ---------------------------------------------------------------------------
|
2013-06-24 11:26:09 -07:00
|
|
|
worldBackup() {
|
2013-08-04 09:09:40 -07:00
|
|
|
# Make sure that the backup location exists.
|
|
|
|
execute "mkdir -p $BACKUP_LOCATION" $USER_NAME
|
|
|
|
# Create the backup.
|
|
|
|
execute "$RDIFF_BACKUP -v5 --print-statistics $WORLDS_LOCATION/$1 $BACKUP_LOCATION/$1 >> $BACKUP_LOG" $USER_NAME
|
|
|
|
# Cleanup old backups.
|
|
|
|
if [ $BACKUP_DURATION -gt 0 ]; then
|
|
|
|
execute "$RDIFF_BACKUP --remove-older-than ${BACKUP_DURATION}D --force $BACKUP_LOCATION/$1 >> $BACKUP_LOG" $USER_NAME
|
|
|
|
fi
|
2013-06-24 11:26:09 -07:00
|
|
|
}
|
|
|
|
|
2013-06-24 13:20:10 -07:00
|
|
|
# ---------------------------------------------------------------------------
|
2013-11-03 20:02:41 -07:00
|
|
|
# Update the Minecraft client software.
|
2013-06-24 13:20:10 -07:00
|
|
|
# ---------------------------------------------------------------------------
|
2013-06-24 11:26:09 -07:00
|
|
|
updateClientSoftware() {
|
2013-08-04 09:09:40 -07:00
|
|
|
# Make sure the client software directory exists.
|
|
|
|
execute "mkdir -p $CLIENT_LOCATION" $USER_NAME
|
2013-11-03 20:02:41 -07:00
|
|
|
# Download the Minecraft client software.
|
|
|
|
if [ ! -e "$CLIENT_LOCATION/$CLIENT_JAR" ]; then
|
|
|
|
execute "$WGET -qO \"$CLIENT_LOCATION/$CLIENT_JAR\" \"$CLIENT_URL\"" $USER_NAME
|
|
|
|
# Report any errors.
|
|
|
|
if [ $? -ne 0 ]; then
|
|
|
|
printf "\nError updating the Minecraft client software.\n"
|
|
|
|
exit 1
|
2013-08-04 09:09:40 -07:00
|
|
|
fi
|
|
|
|
fi
|
2013-06-24 11:26:09 -07:00
|
|
|
}
|
|
|
|
|
2013-06-24 13:20:10 -07:00
|
|
|
# ---------------------------------------------------------------------------
|
2013-06-24 11:26:09 -07:00
|
|
|
# Update the Minecraft server software.
|
2013-12-02 22:25:55 -07:00
|
|
|
#
|
|
|
|
# @param 1 The world server to update.
|
2013-06-24 13:20:10 -07:00
|
|
|
# ---------------------------------------------------------------------------
|
2013-06-24 11:26:09 -07:00
|
|
|
updateServerSoftware() {
|
2013-08-04 09:09:40 -07:00
|
|
|
execute "mkdir -p $SERVER_LOCATION" $USER_NAME
|
2013-12-02 22:24:07 -07:00
|
|
|
if [ ! -e "$SERVER_LOCATION/$SERVER_JAR" ]; then
|
|
|
|
# Download the new minecraft server software.
|
|
|
|
execute "$WGET -qO \"$SERVER_LOCATION/$SERVER_JAR\" \"$SERVER_URL\"" $USER_NAME
|
|
|
|
# Report any errors.
|
|
|
|
if [ $? -ne 0 ]; then
|
|
|
|
printf "\nError updating the Minecraft server software.\n"
|
|
|
|
exit 1
|
2013-08-04 09:09:40 -07:00
|
|
|
fi
|
|
|
|
fi
|
2013-06-24 11:26:09 -07:00
|
|
|
}
|
|
|
|
|
2013-06-24 13:20:10 -07:00
|
|
|
# ---------------------------------------------------------------------------
|
2013-06-24 11:26:09 -07:00
|
|
|
# Run Minecraft Overviewer mapping software on the world. Generates an
|
|
|
|
# index.html file using the Google Maps API.
|
|
|
|
#
|
|
|
|
# @param 1 The world server to map with Overviewer.
|
2013-06-24 13:20:10 -07:00
|
|
|
# ---------------------------------------------------------------------------
|
2013-06-24 11:26:09 -07:00
|
|
|
overviewer() {
|
2013-08-04 09:09:40 -07:00
|
|
|
# Make sure the maps directory exists.
|
|
|
|
execute "mkdir -p $MAPS_LOCATION/$1" $USER_NAME
|
|
|
|
# Make sure the Minecraft client is available.
|
2013-11-03 20:02:41 -07:00
|
|
|
updateClientSoftware
|
2013-08-04 09:09:40 -07:00
|
|
|
# Make sure that the world files are actually there before mapping.
|
|
|
|
if [ -e "$WORLDS_LOCATION/$1/server.properties" ]; then
|
|
|
|
# Check for Overviewer settings file.
|
|
|
|
if [ -e "$WORLDS_LOCATION/$1/overviewer-settings.py" ]; then
|
|
|
|
# Generate map and POI with custom settings.
|
|
|
|
execute "$OVERVIEWER_BIN --config=$WORLDS_LOCATION/$1/overviewer-settings.py" $USER_NAME
|
|
|
|
execute "$OVERVIEWER_BIN --config=$WORLDS_LOCATION/$1/overviewer-settings.py --genpoi" $USER_NAME
|
|
|
|
else
|
|
|
|
# Generate map with default settings.
|
|
|
|
execute "$OVERVIEWER_BIN --rendermodes=normal,lighting,cave --processes 1 $WORLDS_LOCATION/$1/$1 $MAPS_LOCATION/$1" $USER_NAME > /dev/null 2>&1
|
|
|
|
fi
|
|
|
|
fi
|
2013-06-24 11:26:09 -07:00
|
|
|
}
|
|
|
|
|
2013-12-03 11:39:13 -07:00
|
|
|
# ---------------------------------------------------------------------------
|
|
|
|
# Start a Query handler for a world server.
|
|
|
|
#
|
2013-12-03 12:00:37 -07:00
|
|
|
# @param 1 The world server to start a Query handler for.
|
2013-12-03 11:39:13 -07:00
|
|
|
# ---------------------------------------------------------------------------
|
|
|
|
queryStart() {
|
|
|
|
local PID WORLD_DIR
|
2013-12-03 12:00:37 -07:00
|
|
|
# Grab the location of the world's directory.
|
2013-12-03 11:39:13 -07:00
|
|
|
WORLD_DIR="$WORLDS_LOCATION/$1"
|
2013-12-03 12:00:37 -07:00
|
|
|
# Grab the Java Process ID of the world server.
|
2013-12-03 11:39:13 -07:00
|
|
|
PID=$(echo $(getProcessIDs $1) | cut -d ' ' -f2)
|
2013-12-03 12:00:37 -07:00
|
|
|
# Delete any old query.dat or response.dat buffer files.
|
2013-12-03 11:39:13 -07:00
|
|
|
execute "rm -Rf $WORLD_DIR/query.dat $WORLD_DIR/response.dat" $USER_NAME
|
|
|
|
# Give the server a moment to start before initializing the
|
|
|
|
# Query handler.
|
|
|
|
sleep 10
|
2013-12-03 12:00:37 -07:00
|
|
|
# Initialize the query.dat and response.dat buffer files.
|
2013-12-03 11:39:13 -07:00
|
|
|
execute "printf '' > $WORLD_DIR/query.dat" $USER_NAME
|
|
|
|
execute "printf '' > $WORLD_DIR/response.dat" $USER_NAME
|
|
|
|
# Start a tail process to watch for changes to the query.dat file to pipe
|
|
|
|
# to the Minecraft query server via socat. The response from the query
|
|
|
|
# server is piped into the response.dat file.
|
|
|
|
execute "
|
|
|
|
tail -f --pid=$PID $WORLD_DIR/query.dat | \
|
|
|
|
$SOCAT - UDP:127.0.0.1:$(getPropertiesValue $1 'server-port') > \
|
|
|
|
$WORLD_DIR/response.dat
|
|
|
|
" $USER_NAME
|
|
|
|
}
|
|
|
|
|
2013-08-05 16:32:23 -07:00
|
|
|
# ---------------------------------------------------------------------------
|
|
|
|
# Pack a hex string into a buffer file that is piped to the Minecraft query
|
|
|
|
# server.
|
|
|
|
#
|
|
|
|
# @param 1 The world server of interest.
|
|
|
|
# @param 2 The packet type.
|
|
|
|
# @param 3 The packet ID.
|
|
|
|
# @param 4 The packet payload.
|
|
|
|
# @param 5 The response format.
|
2013-08-09 20:42:42 -07:00
|
|
|
# @return The response from the Query server in the requested format.
|
2013-08-05 16:32:23 -07:00
|
|
|
# ---------------------------------------------------------------------------
|
|
|
|
querySendPacket() {
|
2013-11-14 14:44:57 -07:00
|
|
|
local PACKET RESPONSE WORLD_DIR
|
2013-08-05 16:32:23 -07:00
|
|
|
# The world's directory.
|
|
|
|
WORLD_DIR="$WORLDS_LOCATION/$1"
|
2013-12-03 11:43:31 -07:00
|
|
|
# Make sure the query.dat and response.dat buffer files exist before
|
|
|
|
# preparing and sending the packet to the Query server.
|
|
|
|
if [ -e $WORLD_DIR/query.dat ] && [ -e $WORLD_DIR/response.dat ]; then
|
|
|
|
# Add the magic bytes to the incoming packet.
|
|
|
|
PACKET=$(printf "FEFD%s%s%s" "$2" "$3" "$4")
|
|
|
|
# Remove any old responses from the response.dat buffer file.
|
|
|
|
execute "printf '' > $WORLD_DIR/response.dat" $USER_NAME
|
|
|
|
# Pack the hex string packet and write it to the query.dat buffer file.
|
|
|
|
execute "$PERL -e '
|
|
|
|
print map { pack (\"C\", hex(\$_)) } (\"'$PACKET'\" =~ /(..)/g);
|
|
|
|
' >> $WORLD_DIR/query.dat" $USER_NAME
|
|
|
|
# Give the Query server a moment to respond.
|
|
|
|
sleep 1
|
|
|
|
# Unpack the token from the response.dat buffer file. There are a
|
|
|
|
# variable amount of null bytes at the start of the response string, so
|
|
|
|
# find the start of the packet by searching for the packet type and ID.
|
|
|
|
RESPONSE=$($PERL -ne '
|
|
|
|
$hex .= sprintf "%.2x", $_ foreach (unpack "C*", $_);
|
|
|
|
$hex =~ s/^0*'$2$3'/'$2$3'/;
|
|
|
|
print $hex;
|
|
|
|
' $WORLD_DIR/response.dat)
|
|
|
|
fi
|
2013-08-05 16:32:23 -07:00
|
|
|
# Return the response in the format requested.
|
|
|
|
$PERL -e '
|
|
|
|
$packed = join "", map { pack ("C", hex($_)) } ("'$RESPONSE'" =~ /(..)/g);
|
|
|
|
printf "%s\n", join "\t", unpack ("'$5'", $packed);
|
|
|
|
'
|
|
|
|
}
|
|
|
|
|
|
|
|
# ---------------------------------------------------------------------------
|
|
|
|
# Send a challenge packet to the Minecraft query server.
|
|
|
|
#
|
|
|
|
# @param 1 The world server of interest.
|
2013-08-09 20:42:42 -07:00
|
|
|
# @return Tab separated values:
|
|
|
|
# type - The packet type.
|
|
|
|
# id - The packet identifier.
|
|
|
|
# token - The token.
|
2013-08-05 16:32:23 -07:00
|
|
|
# ---------------------------------------------------------------------------
|
|
|
|
querySendChallengePacket() {
|
2013-08-06 08:35:46 -07:00
|
|
|
local ID PACKET RESPONSE
|
2013-08-05 16:32:23 -07:00
|
|
|
# The packet identifier.
|
|
|
|
ID="00000001"
|
|
|
|
# Use an empty packet.
|
|
|
|
PACKET="00000000"
|
|
|
|
# Send the challenge packet to the Minecraft query server.
|
2013-08-06 08:35:46 -07:00
|
|
|
RESPONSE=$(querySendPacket "$1" "09" "$ID" "$PACKET" "Cl>Z*")
|
|
|
|
# Return the response.
|
|
|
|
printf "$RESPONSE\n"
|
2013-08-05 16:32:23 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
# ---------------------------------------------------------------------------
|
|
|
|
# Send an information request packet to the Minecraft query server.
|
|
|
|
#
|
|
|
|
# @param 1 The world server of interest.
|
|
|
|
# @param 2 The challenge token.
|
2013-08-09 20:42:42 -07:00
|
|
|
# @return Tab separated values:
|
|
|
|
# type - The packet type.
|
|
|
|
# id - The packet identifier.
|
|
|
|
# MOTD - The world's message of the day.
|
|
|
|
# gametype - The world's game type, hardcoded to 'SMP'.
|
|
|
|
# map - The world's name.
|
|
|
|
# numplayers - The world's current number of players.
|
|
|
|
# maxplayers - The world's maximum number of players.
|
|
|
|
# hostport - The world's host port.
|
|
|
|
# hostip - The world's host IP address.
|
2013-08-05 16:32:23 -07:00
|
|
|
# ---------------------------------------------------------------------------
|
|
|
|
querySendInformationPacket() {
|
|
|
|
local ID PACKET RESPONSE
|
|
|
|
# The packet identifier.
|
|
|
|
ID="00000001"
|
|
|
|
# Use the challenge token for the packet.
|
|
|
|
PACKET=$(printf "%.8x" $2)
|
|
|
|
# Send the information request packet to the Minecraft query server.
|
|
|
|
RESPONSE=$(querySendPacket "$1" "00" "$ID" "$PACKET" "Cl>Z*Z*Z*Z*Z*s<Z*")
|
|
|
|
# Return the response.
|
|
|
|
printf "$RESPONSE\n"
|
|
|
|
}
|
|
|
|
|
2013-08-08 09:06:16 -07:00
|
|
|
# ---------------------------------------------------------------------------
|
|
|
|
# Send a detailed information request packet to the Minecraft query server.
|
|
|
|
#
|
|
|
|
# @param 1 The world server of interest.
|
|
|
|
# @param 2 The challenge token.
|
2013-08-09 20:42:42 -07:00
|
|
|
# @return Tab separated values:
|
|
|
|
# type - The packet type.
|
|
|
|
# id - The packet identifier.
|
|
|
|
# * - The string 'splitnum'.
|
|
|
|
# * - The value 128.
|
|
|
|
# * - The value 0.
|
|
|
|
# * - The string 'hostname'.
|
|
|
|
# MOTD - The world's message of the day.
|
|
|
|
# * - The string 'gametype'.
|
|
|
|
# gametype - The world's game type, hardcoded to 'SMP'.
|
|
|
|
# * - The string 'game_id'.
|
|
|
|
# gameid - The world's game ID, hardcoded to 'MINECRAFT'.
|
|
|
|
# * - The string 'version'.
|
|
|
|
# version - The world's Minecraft version.
|
|
|
|
# * - The string 'plugins'.
|
|
|
|
# plugins - The world's plugins.
|
|
|
|
# * - The string 'map'.
|
|
|
|
# map - The world's name.
|
|
|
|
# * - The string 'numplayers'.
|
|
|
|
# numplayers - The world's current number of players.
|
|
|
|
# * - The string 'maxplayers'.
|
|
|
|
# maxplayers - The world's maximum number of players.
|
|
|
|
# * - The string 'hostport'.
|
|
|
|
# hostport - The world's host port.
|
|
|
|
# * - The string 'hostip'.
|
|
|
|
# hostip - The world's host IP address.
|
|
|
|
# * - The value 0.
|
|
|
|
# * - The value 1.
|
|
|
|
# * - The string 'player_'.
|
|
|
|
# * - The value 0.
|
|
|
|
# players - The players currently logged onto the world.
|
2013-08-08 09:06:16 -07:00
|
|
|
# ---------------------------------------------------------------------------
|
|
|
|
querySendDetailedInformationPacket() {
|
|
|
|
local ID PACKET RESPONSE
|
|
|
|
# The packet identifier.
|
|
|
|
ID="00000001"
|
|
|
|
# Use the challenge token for the packet, with the ID on the end.
|
|
|
|
PACKET=$(printf "%.8x%s" $2 $ID)
|
|
|
|
# Send the information request packet to the Minecraft query server.
|
|
|
|
RESPONSE=$(querySendPacket "$1" "00" "$ID" "$PACKET" \
|
|
|
|
"Cl>Z*CCZ*Z*Z*Z*Z*Z*Z*Z*Z*Z*Z*Z*Z*Z*Z*Z*Z*Z*Z*Z*CCZ*C(Z*)*")
|
|
|
|
# Return the response.
|
|
|
|
printf "$RESPONSE\n"
|
|
|
|
}
|
|
|
|
|
2013-08-05 16:32:23 -07:00
|
|
|
# ---------------------------------------------------------------------------
|
|
|
|
# Send a status query to the Minecraft query server.
|
|
|
|
#
|
|
|
|
# @param 1 The world server of interest.
|
2013-08-09 20:42:42 -07:00
|
|
|
# @return Tab separated values:
|
|
|
|
# type - The packet type.
|
|
|
|
# id - The packet identifier.
|
|
|
|
# MOTD - The world's message of the day.
|
|
|
|
# gametype - The world's game type.
|
|
|
|
# map - The name of the world.
|
|
|
|
# numplayers - The current number of players.
|
|
|
|
# maxplayers - The maximum number of players.
|
|
|
|
# hostport - The host's port
|
|
|
|
# hostip - The host's IP address.
|
2013-08-05 16:32:23 -07:00
|
|
|
# ---------------------------------------------------------------------------
|
|
|
|
queryStatus() {
|
|
|
|
local TOKEN RESPONSE
|
2013-12-01 12:29:39 -07:00
|
|
|
if [ "$(getPropertiesValue $1 'enable-query')" = "true" ]; then
|
|
|
|
# Send a challenge packet to the Minecraft query server.
|
|
|
|
TOKEN=$(querySendChallengePacket $1 | cut -f 3)
|
2013-12-03 11:22:48 -07:00
|
|
|
if [ -n "$TOKEN" ]; then
|
|
|
|
# Send an information request packet to the Minecraft query server.
|
|
|
|
RESPONSE=$(querySendInformationPacket $1 $TOKEN)
|
|
|
|
fi
|
2013-12-01 12:29:39 -07:00
|
|
|
fi
|
2013-08-05 16:32:23 -07:00
|
|
|
# Return the response.
|
|
|
|
printf "$RESPONSE\n"
|
|
|
|
}
|
|
|
|
|
2013-08-08 09:06:16 -07:00
|
|
|
# ---------------------------------------------------------------------------
|
|
|
|
# Send a detailed status query to the Minecraft query server.
|
|
|
|
#
|
|
|
|
# @param 1 The world server of interest.
|
2013-08-09 20:42:42 -07:00
|
|
|
# @return Tab separated values:
|
|
|
|
# type - The packet type.
|
|
|
|
# id - The packet identifier.
|
|
|
|
# * - The string 'splitnum'.
|
|
|
|
# * - The value 128.
|
|
|
|
# * - The value 0.
|
|
|
|
# * - The string 'hostname'.
|
|
|
|
# MOTD - The world's message of the day.
|
|
|
|
# * - The string 'gametype'.
|
|
|
|
# gametype - The world's game type, hardcoded to 'SMP'.
|
|
|
|
# * - The string 'game_id'.
|
|
|
|
# gameid - The world's game ID, hardcoded to 'MINECRAFT'.
|
|
|
|
# * - The string 'version'.
|
|
|
|
# version - The world's Minecraft version.
|
|
|
|
# * - The string 'plugins'.
|
|
|
|
# plugins - The world's plugins.
|
|
|
|
# * - The string 'map'.
|
|
|
|
# map - The world's name.
|
|
|
|
# * - The string 'numplayers'.
|
|
|
|
# numplayers - The world's current number of players.
|
|
|
|
# * - The string 'maxplayers'.
|
|
|
|
# maxplayers - The world's maximum number of players.
|
|
|
|
# * - The string 'hostport'.
|
|
|
|
# hostport - The world's host port.
|
|
|
|
# * - The string 'hostip'.
|
|
|
|
# hostip - The world's host IP address.
|
|
|
|
# * - The value 0.
|
|
|
|
# * - The value 1.
|
|
|
|
# * - The string 'player_'.
|
|
|
|
# * - The value 0.
|
|
|
|
# players - The players currently logged onto the world.
|
2013-08-08 09:06:16 -07:00
|
|
|
# ---------------------------------------------------------------------------
|
|
|
|
queryDetailedStatus() {
|
|
|
|
local TOKEN RESPONSE
|
2013-12-01 12:29:39 -07:00
|
|
|
if [ "$(getPropertiesValue $1 'enable-query')" = "true" ]; then
|
|
|
|
# Send a challenge packet to the Minecraft query server.
|
|
|
|
TOKEN=$(querySendChallengePacket $1 | cut -f 3)
|
2013-12-03 12:23:42 -07:00
|
|
|
if [ -n "$TOKEN" ]; then
|
|
|
|
# Send an information request packet to the Minecraft query server.
|
|
|
|
RESPONSE=$(querySendDetailedInformationPacket $1 $TOKEN)
|
|
|
|
fi
|
2013-12-01 12:29:39 -07:00
|
|
|
fi
|
2013-08-08 09:06:16 -07:00
|
|
|
# Return the response.
|
|
|
|
printf "$RESPONSE\n"
|
|
|
|
}
|
|
|
|
|
2013-08-05 16:32:23 -07:00
|
|
|
# ---------------------------------------------------------------------------
|
|
|
|
# Display the status of a Minecraft world server.
|
|
|
|
#
|
|
|
|
# @param 1 The world server of interest.
|
|
|
|
# ---------------------------------------------------------------------------
|
|
|
|
worldStatus() {
|
|
|
|
local STATUS
|
|
|
|
if [ $(serverRunning $1) -eq 1 ]; then
|
2013-12-01 13:13:52 -07:00
|
|
|
STATUS=$(queryStatus $1)
|
|
|
|
if [ -n "$STATUS" ]; then
|
|
|
|
printf "running (%d of %d users online).\n" $(echo "$STATUS" | cut -f6) $(echo "$STATUS" | cut -f7)
|
2013-12-01 12:29:39 -07:00
|
|
|
else
|
2013-12-01 13:13:52 -07:00
|
|
|
printf "running (query server offline).\n"
|
2013-12-01 12:29:39 -07:00
|
|
|
fi
|
2013-08-05 16:32:23 -07:00
|
|
|
printf " Process IDs: Screen %d, Java %d.\n" $(getProcessIDs $1)
|
|
|
|
else
|
|
|
|
printf "not running.\n"
|
|
|
|
fi
|
|
|
|
}
|
2013-06-24 11:26:09 -07:00
|
|
|
|
2013-06-24 13:20:10 -07:00
|
|
|
# ---------------------------------------------------------------------------
|
|
|
|
# Begin.
|
|
|
|
# ---------------------------------------------------------------------------
|
2013-06-24 11:26:09 -07:00
|
|
|
|
|
|
|
|
2013-06-24 13:25:27 -07:00
|
|
|
# Make sure that Java, Perl, Python, Rsync, GNU Screen, and GNU Wget are
|
|
|
|
# installed.
|
2013-06-24 11:26:09 -07:00
|
|
|
if [ ! -e "$JAVA" ]; then
|
2013-08-04 09:09:40 -07:00
|
|
|
printf "ERROR: Java not found!\n"
|
|
|
|
printf "Try installing this with:\n"
|
2013-08-09 21:04:24 -07:00
|
|
|
printf "sudo apt-get install default-jre"
|
2013-08-04 09:09:40 -07:00
|
|
|
exit 1
|
2013-06-24 11:26:09 -07:00
|
|
|
fi
|
|
|
|
if [ ! -e "$PERL" ]; then
|
2013-08-04 09:09:40 -07:00
|
|
|
printf "ERROR: Perl not found!\n"
|
|
|
|
printf "Try installing this with:\n"
|
|
|
|
printf "sudo apt-get install perl\n"
|
|
|
|
exit 1
|
2013-06-24 11:26:09 -07:00
|
|
|
fi
|
|
|
|
if [ ! -e "$PYTHON" ]; then
|
2013-08-04 09:09:40 -07:00
|
|
|
printf "ERROR: Python not found!\n"
|
|
|
|
printf "Try installing this with:\n"
|
|
|
|
printf "sudo apt-get install python\n"
|
|
|
|
exit 1
|
2013-06-24 11:26:09 -07:00
|
|
|
fi
|
|
|
|
if [ ! -e "$RSYNC" ] && [ $ENABLE_MIRROR -eq 1 ]; then
|
2013-08-04 09:09:40 -07:00
|
|
|
printf "ERROR: Rsync not found!\n"
|
|
|
|
printf "Try installing this with:\n"
|
|
|
|
printf "sudo apt-get install rsync\n"
|
|
|
|
exit 1
|
2013-06-24 11:26:09 -07:00
|
|
|
fi
|
|
|
|
if [ ! -e "$SCREEN" ]; then
|
2013-08-04 09:09:40 -07:00
|
|
|
printf "ERROR: GNU Screen not found!\n"
|
|
|
|
printf "Try installing this with:\n"
|
|
|
|
printf "sudo apt-get install screen\n"
|
|
|
|
exit 1
|
2013-06-24 11:26:09 -07:00
|
|
|
fi
|
|
|
|
if [ ! -e "$WGET" ]; then
|
2013-08-04 09:09:40 -07:00
|
|
|
printf "ERROR: GNU Wget not found!\n"
|
|
|
|
printf "Try installing this with:\n"
|
|
|
|
printf "sudo apt-get install wget\n"
|
|
|
|
exit 1
|
2013-06-24 11:26:09 -07:00
|
|
|
fi
|
|
|
|
if [ ! -e "$RDIFF_BACKUP" ]; then
|
2013-08-04 09:09:40 -07:00
|
|
|
printf "ERROR: rdiff-backup not found!\n"
|
|
|
|
printf "Try installing this with:\n"
|
|
|
|
printf "sudo apt-get install rdiff-backup\n"
|
|
|
|
exit 1
|
2013-06-24 11:26:09 -07:00
|
|
|
fi
|
2013-12-01 10:57:09 -07:00
|
|
|
if [ ! -e "$SOCAT" ]; then
|
|
|
|
printf "ERROR: socat not found!\n"
|
|
|
|
printf "Try installing this with:\n"
|
|
|
|
printf "sudo apt-get install socat\n"
|
|
|
|
exit 1
|
|
|
|
fi
|
2013-06-24 11:26:09 -07:00
|
|
|
|
2013-12-03 14:49:45 -07:00
|
|
|
# Grab the list of enabled worlds.
|
|
|
|
ALL_WORLDS=$(getEnabledWorlds)
|
2013-06-24 11:26:09 -07:00
|
|
|
|
|
|
|
# Respond to the command line arguments.
|
|
|
|
case "$1" in
|
2013-08-04 09:09:40 -07:00
|
|
|
start)
|
2013-12-02 19:26:56 -07:00
|
|
|
checkPermission
|
2013-08-04 09:09:40 -07:00
|
|
|
# Figure out which worlds to start.
|
2013-10-19 19:38:54 -07:00
|
|
|
WORLDS="$ALL_WORLDS"
|
2013-10-30 10:50:06 -07:00
|
|
|
# If there are no worlds in the list, then use the default world.
|
|
|
|
if [ ! -n "$WORLDS" ]; then
|
|
|
|
WORLDS="$DEFAULT_WORLD"
|
|
|
|
createWorld "$DEFAULT_WORLD" "$DEFAULT_PORT" "$DEFAULT_IP"
|
|
|
|
fi
|
|
|
|
# If an optional argument was supplied, verify it is a valid world.
|
2013-10-19 19:38:54 -07:00
|
|
|
if [ -n "$2" ] && [ $(listContains "$2" "$ALL_WORLDS") -eq 1 ]; then
|
|
|
|
WORLDS="$2"
|
|
|
|
elif [ -n "$2" ]; then
|
|
|
|
printf "World '$2' not recognized.\n"
|
|
|
|
printf " Usage: $0 $1 <world>\n"
|
|
|
|
exit 1
|
|
|
|
fi
|
2013-08-04 09:09:40 -07:00
|
|
|
# Start each world requested, if not already running.
|
|
|
|
printf "Starting Minecraft Server:"
|
|
|
|
for WORLD in $WORLDS; do
|
|
|
|
if [ $(serverRunning $WORLD) -eq 0 ]; then
|
|
|
|
printf " $WORLD"
|
|
|
|
start $WORLD
|
|
|
|
fi
|
|
|
|
done
|
|
|
|
printf ".\n"
|
|
|
|
;;
|
|
|
|
stop|force-stop)
|
2013-12-02 19:26:56 -07:00
|
|
|
checkPermission
|
2013-08-04 09:09:40 -07:00
|
|
|
# Figure out which worlds to stop.
|
2013-10-19 19:38:54 -07:00
|
|
|
WORLDS="$ALL_WORLDS"
|
|
|
|
if [ -n "$2" ] && [ $(listContains "$2" "$ALL_WORLDS") -eq 1 ]; then
|
|
|
|
WORLDS="$2"
|
|
|
|
elif [ -n "$2" ]; then
|
|
|
|
printf "World '$2' not recognized.\n"
|
|
|
|
printf " Usage: $0 $1 <world>\n"
|
|
|
|
exit 1
|
|
|
|
fi
|
2013-08-04 09:09:40 -07:00
|
|
|
# Stop each world requested, if running.
|
|
|
|
printf "Stopping Minecraft Server:"
|
|
|
|
for WORLD in $WORLDS; do
|
|
|
|
# Try to stop the world cleanly.
|
|
|
|
if [ $(serverRunning $WORLD) -eq 1 ]; then
|
|
|
|
printf " $WORLD"
|
2013-10-19 11:50:50 -07:00
|
|
|
if [ $(printf "%d" $(queryStatus $WORLD | cut -f6)) -gt 0 ]; then
|
2013-08-05 21:28:55 -07:00
|
|
|
sendCommand $WORLD "say The server admin has initiated a server shut down."
|
|
|
|
sendCommand $WORLD "say The server will shut down in 1 minute..."
|
|
|
|
sleep 60
|
|
|
|
sendCommand $WORLD "say The server is now shutting down."
|
|
|
|
fi
|
2013-08-04 09:09:40 -07:00
|
|
|
sendCommand $WORLD "save-all"
|
|
|
|
sendCommand $WORLD "save-off"
|
|
|
|
if [ "$1" = "force-stop" ]; then
|
|
|
|
forceStop $WORLD
|
|
|
|
else
|
|
|
|
stop $WORLD
|
|
|
|
fi
|
2013-11-01 16:08:07 -07:00
|
|
|
elif [ "$1" = "force-stop" ]; then
|
|
|
|
printf " $WORLD"
|
|
|
|
forceStop $WORLD
|
2013-08-04 09:09:40 -07:00
|
|
|
fi
|
|
|
|
done
|
|
|
|
printf ".\n"
|
|
|
|
;;
|
|
|
|
restart|reload|force-restart|force-reload)
|
2013-12-02 19:26:56 -07:00
|
|
|
checkPermission
|
2013-08-04 09:09:40 -07:00
|
|
|
# Figure out which worlds to restart.
|
2013-10-19 19:38:54 -07:00
|
|
|
WORLDS="$ALL_WORLDS"
|
|
|
|
if [ -n "$2" ] && [ $(listContains "$2" "$ALL_WORLDS") -eq 1 ]; then
|
|
|
|
WORLDS="$2"
|
|
|
|
elif [ -n "$2" ]; then
|
|
|
|
printf "World '$2' not recognized.\n"
|
|
|
|
printf " Usage: $0 $1 <world>\n"
|
|
|
|
exit 1
|
|
|
|
fi
|
2013-08-04 09:09:40 -07:00
|
|
|
# Restart each world requested, start those not already
|
|
|
|
# running.
|
|
|
|
printf "Restarting Minecraft Server:"
|
|
|
|
for WORLD in $WORLDS; do
|
|
|
|
printf " $WORLD"
|
|
|
|
if [ $(serverRunning $WORLD) -eq 1 ]; then
|
2013-10-19 11:50:50 -07:00
|
|
|
if [ $(printf "%d" $(queryStatus $WORLD | cut -f6)) -gt 0 ]; then
|
2013-08-06 07:09:18 -07:00
|
|
|
sendCommand $WORLD "say The server admin has initiated a server restart."
|
2013-08-05 21:28:55 -07:00
|
|
|
sendCommand $WORLD "say The server will restart in 1 minute..."
|
|
|
|
sleep 60
|
|
|
|
sendCommand $WORLD "say The server is now restarting."
|
|
|
|
fi
|
2013-08-04 09:09:40 -07:00
|
|
|
sendCommand $WORLD "save-all"
|
|
|
|
sendCommand $WORLD "save-off"
|
|
|
|
if [ "$(echo \"$1\" | cut -d '-' -f1)" = "force" ]; then
|
|
|
|
forceStop $WORLD
|
|
|
|
else
|
|
|
|
stop $WORLD
|
|
|
|
fi
|
|
|
|
sleep 5
|
|
|
|
fi
|
|
|
|
start $WORLD
|
|
|
|
done
|
|
|
|
printf ".\n"
|
|
|
|
;;
|
2013-10-19 09:57:29 -07:00
|
|
|
create|new)
|
2013-12-02 19:26:56 -07:00
|
|
|
checkPermission
|
2013-10-19 09:57:29 -07:00
|
|
|
if [ ! -n "$2" ]; then
|
|
|
|
printf "A name for the new world must be supplied.\n"
|
|
|
|
exit 1
|
|
|
|
fi
|
|
|
|
if [ ! -n "$3" ]; then
|
|
|
|
printf "A port for the new world must be supplied.\n"
|
|
|
|
exit 1
|
|
|
|
fi
|
2013-10-30 11:44:27 -07:00
|
|
|
printf "Creating Minecraft world: $2"
|
2013-10-19 09:57:29 -07:00
|
|
|
createWorld "$2" "$3" "$4"
|
2013-10-30 11:44:27 -07:00
|
|
|
printf ".\n"
|
2013-10-19 09:57:29 -07:00
|
|
|
;;
|
2013-10-19 10:15:16 -07:00
|
|
|
delete|remove)
|
2013-12-02 19:26:56 -07:00
|
|
|
checkPermission
|
2013-10-19 10:59:01 -07:00
|
|
|
if [ ! -n "$2" ] || [ $(listContains "$2" "$ALL_WORLDS") -eq 0 ]; then
|
2013-10-19 10:15:16 -07:00
|
|
|
printf "World not found, unable to delete world '$2'.\n"
|
|
|
|
exit 1
|
|
|
|
fi
|
2013-10-30 11:44:27 -07:00
|
|
|
printf "Deleting Minecraft world: $2"
|
2013-10-19 10:39:44 -07:00
|
|
|
if [ $(serverRunning "$2") -eq 1 ]; then
|
|
|
|
# If the world server has users logged in, announce that the world is
|
|
|
|
# being deleted.
|
2013-10-19 11:58:47 -07:00
|
|
|
if [ $(printf "%d" $(queryStatus $2 | cut -f6)) -gt 0 ]; then
|
2013-10-19 10:39:44 -07:00
|
|
|
sendCommand "$2" "say The server admin is deleting this world."
|
|
|
|
sendCommand "$2" "say The server will be deleted in 1 minute..."
|
|
|
|
sleep 60
|
|
|
|
sendCommand "$2" "say The server is now shutting down."
|
|
|
|
fi
|
|
|
|
# Stop the world server.
|
|
|
|
stop "$2"
|
|
|
|
sleep 5
|
|
|
|
fi
|
2013-10-19 10:15:16 -07:00
|
|
|
# Delete the world.
|
|
|
|
deleteWorld "$2"
|
2013-10-30 11:44:27 -07:00
|
|
|
printf ".\n"
|
2013-10-19 10:15:16 -07:00
|
|
|
;;
|
2013-10-19 10:47:23 -07:00
|
|
|
disable)
|
2013-12-02 19:26:56 -07:00
|
|
|
checkPermission
|
2013-10-19 10:59:01 -07:00
|
|
|
if [ ! -n "$2" ] || [ $(listContains "$2" "$ALL_WORLDS") -eq 0 ]; then
|
2013-10-19 10:47:23 -07:00
|
|
|
printf "World not found, unable to disable world '$2'.\n"
|
|
|
|
exit 1
|
|
|
|
fi
|
2013-10-30 11:44:27 -07:00
|
|
|
printf "Disabling Minecraft world: $2"
|
2013-10-19 10:47:23 -07:00
|
|
|
if [ $(serverRunning "$2") -eq 1 ]; then
|
|
|
|
# If the world server has users logged in, announce that the world is
|
|
|
|
# being disabled.
|
2013-10-19 11:58:47 -07:00
|
|
|
if [ $(printf "%d" $(queryStatus $2 | cut -f6)) -gt 0 ]; then
|
2013-10-19 10:47:23 -07:00
|
|
|
sendCommand "$2" "say The server admin is disabling this world."
|
|
|
|
sendCommand "$2" "say The server will be disabled in 1 minute..."
|
|
|
|
sleep 60
|
|
|
|
sendCommand "$2" "say The server is now shutting down."
|
|
|
|
fi
|
|
|
|
# Stop the world server.
|
|
|
|
stop "$2"
|
|
|
|
sleep 5
|
|
|
|
fi
|
|
|
|
# Disable the world.
|
|
|
|
disableWorld "$2"
|
2013-10-30 11:44:27 -07:00
|
|
|
printf ".\n"
|
2013-10-19 10:47:23 -07:00
|
|
|
;;
|
2013-10-19 10:57:04 -07:00
|
|
|
enable)
|
2013-12-02 19:26:56 -07:00
|
|
|
checkPermission
|
2013-10-19 10:57:04 -07:00
|
|
|
if [ ! -n "$2" ] || [ ! -f "$DISABLED_WORLDS_LOCATION/$2/server.properties" ]; then
|
|
|
|
printf "World not found, unable to enable world '$2'.\n"
|
|
|
|
exit 1
|
|
|
|
fi
|
2013-10-30 11:44:27 -07:00
|
|
|
printf "Enabling Minecraft world: $2"
|
2013-10-19 10:57:04 -07:00
|
|
|
# Enable the world.
|
|
|
|
enableWorld "$2"
|
2013-10-19 11:37:00 -07:00
|
|
|
# Start the world.
|
|
|
|
start "$2"
|
2013-10-30 11:44:27 -07:00
|
|
|
printf ".\n"
|
2013-10-19 10:57:04 -07:00
|
|
|
;;
|
2013-12-02 19:27:52 -07:00
|
|
|
ls|list)
|
|
|
|
# Display a list of enabled worlds.
|
|
|
|
printf "$ALL_WORLDS\n"
|
|
|
|
;;
|
2013-08-04 09:09:40 -07:00
|
|
|
status|show)
|
2013-12-02 19:26:56 -07:00
|
|
|
checkPermission
|
2013-08-04 09:09:40 -07:00
|
|
|
# Figure out which worlds to show the status for.
|
2013-10-19 19:38:54 -07:00
|
|
|
WORLDS="$ALL_WORLDS"
|
|
|
|
if [ -n "$2" ] && [ $(listContains "$2" "$ALL_WORLDS") -eq 1 ]; then
|
|
|
|
WORLDS="$2"
|
|
|
|
elif [ -n "$2" ]; then
|
|
|
|
printf "World '$2' not recognized.\n"
|
|
|
|
printf " Usage: $0 $1 <world>\n"
|
|
|
|
exit 1
|
|
|
|
fi
|
2013-08-04 09:09:40 -07:00
|
|
|
# Show the status of each world requested.
|
|
|
|
printf "Minecraft Server Status:\n"
|
|
|
|
for WORLD in $WORLDS; do
|
|
|
|
printf " $WORLD: "
|
2013-08-05 16:32:23 -07:00
|
|
|
worldStatus $WORLD
|
2013-08-04 09:09:40 -07:00
|
|
|
done
|
|
|
|
;;
|
|
|
|
sync|synchronize)
|
2013-12-02 19:26:56 -07:00
|
|
|
checkPermission
|
2013-08-04 09:09:40 -07:00
|
|
|
# Figure out which worlds to synchronize.
|
2013-10-19 19:38:54 -07:00
|
|
|
WORLDS="$ALL_WORLDS"
|
|
|
|
if [ -n "$2" ] && [ $(listContains "$2" "$ALL_WORLDS") -eq 1 ]; then
|
|
|
|
WORLDS="$2"
|
|
|
|
elif [ -n "$2" ]; then
|
|
|
|
printf "World '$2' not recognized.\n"
|
|
|
|
printf " Usage: $0 $1 <world>\n"
|
|
|
|
exit 1
|
|
|
|
fi
|
2013-08-04 09:09:40 -07:00
|
|
|
# Synchronize the images for each world.
|
|
|
|
printf "Synchronizing Minecraft Server:"
|
|
|
|
for WORLD in $WORLDS; do
|
|
|
|
if [ $(serverRunning $WORLD) -eq 1 ]; then
|
|
|
|
printf " $WORLD"
|
|
|
|
sendCommand $WORLD "save-all"
|
|
|
|
if [ $ENABLE_MIRROR -eq 1 ]; then
|
|
|
|
sendCommand $WORLD "save-off"
|
|
|
|
sleep 20
|
|
|
|
syncMirrorImage $WORLD
|
|
|
|
sendCommand $WORLD "save-on"
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
done
|
|
|
|
printf ".\n"
|
|
|
|
;;
|
|
|
|
send)
|
2013-12-02 19:26:56 -07:00
|
|
|
checkPermission
|
2013-08-04 09:09:40 -07:00
|
|
|
# Check for the world command line argument.
|
|
|
|
if [ -n "$2" ] && [ $(listContains $2 "$ALL_WORLDS") -eq 1 ] && [ -n "$3" ]; then
|
|
|
|
WORLD=$2
|
|
|
|
shift 2
|
|
|
|
printf "Sending command to world: $WORLD - '$*'.\n"
|
|
|
|
sendCommand $WORLD "$*"
|
|
|
|
else
|
|
|
|
printf "Usage: $0 $1 <world> <command>\n"
|
|
|
|
printf " ie: $0 $1 world say Hello World!\n"
|
|
|
|
exit 1
|
|
|
|
fi
|
|
|
|
;;
|
|
|
|
screen)
|
2013-12-02 19:26:56 -07:00
|
|
|
checkPermission
|
2013-08-04 09:09:40 -07:00
|
|
|
# Check for the world command line argument.
|
|
|
|
if [ -n "$2" ] && [ $(listContains $2 "$ALL_WORLDS") -eq 1 ]; then
|
|
|
|
printf "About to load the screen for world: $2.\n"
|
|
|
|
printf "To exit the screen, hit Ctrl+A then type the letter d.\n"
|
|
|
|
sleep 5
|
|
|
|
displayScreen $2
|
|
|
|
else
|
|
|
|
if [ -n "$2" ]; then
|
|
|
|
printf "Minecraft world $2 not found!\n"
|
|
|
|
else
|
|
|
|
printf "Minecraft world not provided!\n"
|
|
|
|
fi
|
|
|
|
printf " Usage: $0 $1 <world>\n"
|
|
|
|
exit 1
|
|
|
|
fi
|
|
|
|
;;
|
|
|
|
watch)
|
2013-12-02 19:26:56 -07:00
|
|
|
checkPermission
|
2013-08-04 09:09:40 -07:00
|
|
|
# Check for the world command line argument.
|
|
|
|
if [ -n "$2" ] && [ $(listContains $2 "$ALL_WORLDS") -eq 1 ]; then
|
|
|
|
printf "Monitoring Minecraft Server: $2.\n"
|
|
|
|
watchLog $2
|
|
|
|
else
|
|
|
|
if [ -n "$2" ]; then
|
|
|
|
printf "Minecraft world $2 not found!\n"
|
|
|
|
else
|
|
|
|
printf "Minecraft world not provided!\n"
|
|
|
|
fi
|
|
|
|
printf " Usage: $0 $1 <world>\n"
|
|
|
|
exit 1
|
|
|
|
fi
|
|
|
|
;;
|
|
|
|
logrotate)
|
2013-12-02 19:26:56 -07:00
|
|
|
checkPermission
|
2013-08-04 09:09:40 -07:00
|
|
|
# Figure out which worlds to rotate the log.
|
2013-10-19 19:38:54 -07:00
|
|
|
WORLDS="$ALL_WORLDS"
|
|
|
|
if [ -n "$2" ] && [ $(listContains "$2" "$ALL_WORLDS") -eq 1 ]; then
|
|
|
|
WORLDS="$2"
|
|
|
|
elif [ -n "$2" ]; then
|
|
|
|
printf "World '$2' not recognized.\n"
|
|
|
|
printf " Usage: $0 $1 <world>\n"
|
|
|
|
exit 1
|
|
|
|
fi
|
2013-08-04 09:09:40 -07:00
|
|
|
# Backup each world requested.
|
|
|
|
printf "Rotating Minecraft Server Log:"
|
|
|
|
for WORLD in $WORLDS; do
|
|
|
|
printf " $WORLD"
|
|
|
|
rotateLog $WORLD
|
|
|
|
done
|
|
|
|
printf ".\n"
|
|
|
|
;;
|
|
|
|
backup)
|
2013-12-02 19:26:56 -07:00
|
|
|
checkPermission
|
2013-08-04 09:09:40 -07:00
|
|
|
# Figure out which worlds to backup.
|
2013-10-19 19:38:54 -07:00
|
|
|
WORLDS="$ALL_WORLDS"
|
|
|
|
if [ -n "$2" ] && [ $(listContains "$2" "$ALL_WORLDS") -eq 1 ]; then
|
|
|
|
WORLDS="$2"
|
|
|
|
elif [ -n "$2" ]; then
|
|
|
|
printf "World '$2' not recognized.\n"
|
|
|
|
printf " Usage: $0 $1 <world>\n"
|
|
|
|
exit 1
|
|
|
|
fi
|
2013-08-04 09:09:40 -07:00
|
|
|
# Backup each world requested.
|
|
|
|
printf "Backing up Minecraft Server:"
|
|
|
|
for WORLD in $WORLDS; do
|
|
|
|
printf " $WORLD"
|
|
|
|
if [ $(serverRunning $WORLD) -eq 1 ]; then
|
|
|
|
sendCommand $WORLD "say Backing up the world."
|
|
|
|
sendCommand $WORLD "save-all"
|
|
|
|
sendCommand $WORLD "save-off"
|
|
|
|
sleep 20
|
|
|
|
worldBackup $WORLD
|
|
|
|
sendCommand $WORLD "save-on"
|
|
|
|
sendCommand $WORLD "say Backup complete."
|
|
|
|
else
|
|
|
|
worldBackup $WORLD
|
|
|
|
fi
|
|
|
|
done
|
|
|
|
printf ".\n"
|
|
|
|
;;
|
|
|
|
update)
|
2013-12-02 19:26:56 -07:00
|
|
|
checkPermission
|
2013-12-02 21:30:26 -07:00
|
|
|
# Figure out which worlds to update.
|
|
|
|
WORLDS="$ALL_WORLDS"
|
|
|
|
if [ -n "$2" ] && [ $(listContains "$2" "$ALL_WORLDS") -eq 1 ]; then
|
|
|
|
WORLDS="$2"
|
|
|
|
elif [ -n "$2" ]; then
|
|
|
|
printf "World '$2' not recognized.\n"
|
2013-12-02 21:49:55 -07:00
|
|
|
printf " Usage: $0 $1 <world>\n"
|
2013-12-02 21:30:26 -07:00
|
|
|
exit 1
|
|
|
|
fi
|
2013-08-04 09:09:40 -07:00
|
|
|
# Stop all of the world servers and backup the worlds.
|
|
|
|
printf "Stopping Minecraft Server:"
|
2013-12-02 21:30:26 -07:00
|
|
|
for WORLD in $WORLDS; do
|
2013-08-04 09:09:40 -07:00
|
|
|
if [ $(serverRunning $WORLD) -eq 1 ]; then
|
|
|
|
printf " $WORLD"
|
2013-10-19 11:50:50 -07:00
|
|
|
if [ $(printf "%d" $(queryStatus $WORLD | cut -f6)) -gt 0 ]; then
|
2013-08-05 21:28:55 -07:00
|
|
|
sendCommand $WORLD "say The server admin has initiated a software update."
|
|
|
|
sendCommand $WORLD "say The server will restart and update in 1 minute..."
|
|
|
|
sleep 60
|
|
|
|
sendCommand $WORLD "say The server is now restarting."
|
|
|
|
fi
|
2013-08-04 09:09:40 -07:00
|
|
|
sendCommand $WORLD "save-all"
|
|
|
|
sendCommand $WORLD "save-off"
|
|
|
|
stop $WORLD
|
|
|
|
fi
|
|
|
|
done
|
|
|
|
printf ".\n"
|
|
|
|
printf "Backing up Minecraft Server:"
|
2013-12-02 21:34:39 -07:00
|
|
|
for WORLD in $WORLDS; do
|
2013-08-04 09:09:40 -07:00
|
|
|
printf " $WORLD"
|
|
|
|
worldBackup $WORLD
|
|
|
|
done
|
|
|
|
printf ".\n"
|
2013-12-02 22:32:20 -07:00
|
|
|
# Update the server software.
|
2013-12-02 22:24:07 -07:00
|
|
|
printf "Updating Server Software:"
|
|
|
|
for WORLD in $WORLDS; do
|
|
|
|
printf " $WORLD"
|
|
|
|
updateServerSoftware "$WORLD"
|
|
|
|
done
|
2013-08-04 09:09:40 -07:00
|
|
|
printf ".\n"
|
|
|
|
printf "Restarting Minecraft Server:"
|
2013-12-02 21:34:39 -07:00
|
|
|
for WORLD in $WORLDS; do
|
2013-08-04 09:09:40 -07:00
|
|
|
printf " $WORLD"
|
|
|
|
start $WORLD
|
|
|
|
done
|
|
|
|
printf ".\n"
|
|
|
|
;;
|
|
|
|
map|overviewer)
|
2013-12-02 19:26:56 -07:00
|
|
|
checkPermission
|
2013-08-04 09:09:40 -07:00
|
|
|
# Make sure that the Minecraft Overviewer software exists.
|
|
|
|
if [ ! -e "$OVERVIEWER_BIN" ]; then
|
|
|
|
printf "Mincraft Overviewer software not found.\n"
|
|
|
|
exit 1
|
|
|
|
fi
|
|
|
|
# Figure out which worlds to map.
|
2013-10-19 19:38:54 -07:00
|
|
|
WORLDS="$ALL_WORLDS"
|
|
|
|
if [ -n "$2" ] && [ $(listContains "$2" "$ALL_WORLDS") -eq 1 ]; then
|
|
|
|
WORLDS="$2"
|
|
|
|
elif [ -n "$2" ]; then
|
|
|
|
printf "World '$2' not recognized.\n"
|
|
|
|
printf " Usage: $0 $1 <world>\n"
|
|
|
|
exit 1
|
|
|
|
fi
|
2013-08-04 09:09:40 -07:00
|
|
|
# Run Minecraft Overviewer on each world requested.
|
|
|
|
printf "Running Minecraft Overviewer mapping:"
|
|
|
|
for WORLD in $WORLDS; do
|
|
|
|
printf " $WORLD"
|
|
|
|
if [ $(serverRunning $WORLD) -eq 1 ]; then
|
|
|
|
sendCommand $WORLD "say The world is about to be mapped with Minecraft Overviewer."
|
|
|
|
sendCommand $WORLD "save-all"
|
|
|
|
sendCommand $WORLD "save-off"
|
|
|
|
sleep 20
|
|
|
|
worldBackup $WORLD
|
|
|
|
overviewer $WORLD
|
|
|
|
sendCommand $WORLD "save-on"
|
|
|
|
sendCommand $WORLD "say Mapping is complete. You can access the maps at:"
|
|
|
|
sendCommand $WORLD "say $MAPS_URL/$WORLD"
|
|
|
|
else
|
|
|
|
worldBackup $WORLD
|
|
|
|
overviewer $WORLD
|
|
|
|
fi
|
|
|
|
done
|
|
|
|
printf ".\n"
|
|
|
|
;;
|
|
|
|
*)
|
|
|
|
printf "Error, in command line usage.\n"
|
|
|
|
printf "\n"
|
|
|
|
printf "$USAGE\n"
|
|
|
|
exit 1
|
|
|
|
;;
|
2013-06-24 11:26:09 -07:00
|
|
|
esac
|
|
|
|
exit 0
|