Implemented a server "worlds on|off" command.

Moves a world between the "worldstorage" and "worldstorage_inactive"
directories. Inactive worlds do not get loaded (symlinked) or backed up
etc. but are include in complete server backups.

Bit of a monster commit here, refactored the init code to bring this
change.
This commit is contained in:
Marcus Whybrow 2012-06-02 19:11:33 +01:00
parent bfe1e07d64
commit a7978d535c
3 changed files with 426 additions and 194 deletions

View File

@ -16,6 +16,7 @@ __init_server() {
SERVER_USER="$DEFAULT_SERVER_USER"
SCREEN_NAME="${DEFAULT_SCREEN_NAME//\{SERVER_NAME\}/${1}}"
WORLD_STORAGE_PATH="$SERVER_PATH/$DEFAULT_WORLD_STORAGE_PATH"
WORLD_STORAGE_INACTIVE_PATH="$SERVER_PATH/$DEFAULT_WORLD_STORAGE_INACTIVE_PATH"
WHITELIST="$SERVER_PATH/$DEFAULT_WHITELIST"
BANNED_PLAYERS="$SERVER_PATH/$DEFAULT_BANNED_PLAYERS"
@ -42,7 +43,8 @@ __init_server() {
case "$name" in
SERVER_USER) SERVER_USER="$value";;
SCREEN_NAME) SCREEN_NAME="$value";;
WORLD_STORAGE_PATH) WORLD_STORAGE_DIR="$SERVER_PATH/$value";;
WORLD_STORAGE_PATH) WORLD_STORAGE_PATH="$SERVER_PATH/$value";;
WORLD_STORAGE_INACTIVE_PATH) WORLD_STORAGE_INACTIVE_PATH="$SERVER_PATH/$value";;
WHITELIST) WHITELIST="$SERVER_PATH/$value";;
BANNED_PLAYERS) BANNED_PLAYERS="$SERVER_PATH/$value";;
@ -126,7 +128,7 @@ _msm() {
;;
worlds)
if [[ $COMP_CWORD == 3 ]]; then
options="list load ram todisk backup"
options="list load ram todisk backup on off"
else
case "${COMP_WORDS[3]}" in
ram)
@ -136,6 +138,20 @@ _msm() {
fi
fi
;;
on)
if [[ $COMP_CWORD == 4 ]]; then
if [ -d "$WORLD_STORAGE_INACTIVE_PATH" ]; then
options="$(ls -1 "$WORLD_STORAGE_INACTIVE_PATH")"
fi
fi
;;
off)
if [[ $COMP_CWORD == 4 ]]; then
if [ -d "$WORLD_STORAGE_PATH" ]; then
options="$(ls -1 "$WORLD_STORAGE_PATH")"
fi
fi
;;
esac
fi
;;

595
init/msm
View File

@ -76,6 +76,16 @@ echoerr() {
echo "$@" 1>&2
}
# A function used to print debug messages to stdout. Prevents messages from
# appearing unless in debug mode, and allows debug statements to be easily
# distinguished from necessary echo statements.
# $1: The message to output
debug() {
if [[ $DEBUG == "true" ]]; then
echoerr "$1"
fi
}
# Determines whether "$1" is a valid name for a server or jar group directory
# It must only contain upper or lower case letters, digits, dashes or
# underscores.
@ -184,11 +194,53 @@ world_backup() {
file_name="$(date "+%F-%H-%M-%S").zip"
local server_id=${world_server_id[$1]}
as_user ${server_user_name[$server_id]} "mkdir -p \"${world_backup_path[$1]}\" && cd \"${server_world_storage[$server_id]}\" && zip -rq \"${world_backup_path[$1]}/${file_name}\" \"${world_name[$1]}\""
local containing_dir="$(dirname "${world_path[$1]}")"
local dir_name="$(basename "${world_path[$1]}")"
as_user ${server_user_name[$server_id]} "mkdir -p \"${world_backup_path[$1]}\" && cd \"$containing_dir\" && zip -rq \"${world_backup_path[$1]}/${file_name}\" \"${dir_name}\""
echo "Done."
}
# Activates a world
# $1: The ID of the world
world_activate() {
if [ -d "${world_inactive_path[$1]}" ]; then
echo -n "Moving world \"${world_name[$1]}\" to the active worldstorage directory... "
local new_path="${world_active_path[$1]}"
as_user "${server_user_name[${world_server_id[$1]}]}" "mkdir -p \"$new_path\" && mv \"${world_inactive_path[$1]}\" \"$new_path\""
echo "Done."
else
if [ -d "${world_active_path[$1]}" ]; then
echo "World \"${world_name[$1]}\" is already activate."
else
echoerr "Error: Directory \"${world_inactive_path[$1]}\" could not be found."
return 1
fi
fi
}
# Deactivates a world
# $1: The ID of the world
world_deactivate() {
if server_is_running "${world_server_id[$1]}"; then
echoerr "Error: Worlds cannot be deactivated whilst the server is running."
return 1
else
if [ -d "${world_active_path[$1]}" ]; then
echo -n "Moving world \"${world_name[$1]}\" to the inactive worldstorage directory... "
local new_path="${world_inactive_path[$1]}"
as_user "${server_user_name[${world_server_id[$1]}]}" "mkdir -p \"$new_path\" && mv \"${world_path[$1]}\" \"$new_path\""
echo "Done."
else
if [ -d "${world_inactive_path[$1]}" ]; then
echo "World \"${world_name[$1]}\" is already deactivate."
else
echoerr "Error: Directory \"${world_active_path[$1]}\" could not be found."
return 1
fi
fi
fi
}
### Server Utility Functions
@ -214,18 +266,20 @@ server_get_id() {
# $1: The ID of the server
# $2: The name of the world
server_world_get_id() {
local i=${server_world_offset[$1]}
local max=$(( $i + ${server_num_worlds[$1]} ))
# For each of the servers worlds:
while [[ $i -lt $max ]]; do
if [[ "${world_name[$i]}" == "$2" ]]; then
echo $i
return 0
fi
if [ -d "${server_world_storage[$1]}/$2" ] || [ -d "${server_world_storage_inactive[$1]}/$2" ]; then
# If the directory exists
i=$(( $i + 1 ))
done
local start=${server_world_offset[$1]}
local max=$(( $i + ${server_num_worlds[$1]} ))
# For each of the servers worlds:
for ((i=$start; i<$max; i++)); do
if [[ "${world_name[$i]}" == "$2" ]]; then
echo $i
return 0
fi
done
fi
return 1
}
@ -246,11 +300,17 @@ server_is_running() {
# $1: The id of the server for which links should be ensured
server_ensure_links() {
echo -n "Maintaining world symbolic links... "
local i=${server_world_offset[$1]}
local max=$(( $i + ${server_num_worlds[$1]} ))
local start=${server_world_offset[$1]}
local max=$(( $start + ${server_num_worlds[$1]} ))
local output="false"
while [[ $i -lt $max ]]; do
for ((i=$start; i<$max; i++)); do
if [[ ${world_status[$i]} != "active" ]]; then
# Remove the symbolic link if it exists
as_user "${server_user_name[$1]}" "rm -f \"${world_link[$i]}\""
continue
fi
# -L checks for the path being a link rather than a file
# ! -a, since it is within double square brackets means: the negation of
# the existence of the file. In other words: true if does not exist
@ -291,8 +351,6 @@ server_ensure_links() {
echoerr -en "\n Error: Could not create link for world \"${world_name[$i]}\". The file \"${world_link[$i]}\" already exists, and should not be overwritten automatically. Either remove this file, or rename \"${world_name[$i]}\"."
output="true"
fi
i=$(( $i + 1 ))
done
if [[ $output == "true" ]]; then
@ -1127,185 +1185,323 @@ manager_stop_all_servers_now() {
### Main Functions
# Initialises a server's world
# $1: The server id
# $2: The world id to use
# $3: The name of the world
server_world_init() {
world_server_id[$2]="$1"
world_name[$2]="$3"
world_active_path[$2]="${server_world_storage[$1]}/${world_name[$2]}"
world_inactive_path[$2]="${server_world_storage_inactive[$1]}/${world_name[$2]}"
# Set the status of this world (active/inactive)
if [ -d "${world_active_path[$2]}" ]; then
world_status[$2]="active"
world_path[$2]="${world_active_path[$2]}"
else
if [ -d "${world_inactive_path[$2]}" ]; then
world_status[$2]="inactive"
world_path[$2]="${world_inactive_path[$2]}"
else
world_status[$2]="unknown"
echoerr "Error: World cannot be found in either \"${world_active_path[$2]}\" or \"${world_inactive_path[$2]}\"."
return 1
fi
fi
world_link[$2]="${server_path[$1]}/${world_name[$2]}"
world_flag_inram[$2]="${world_path[$2]}/$WORLD_FLAG_INRAM"
world_backup_path[$2]="$WORLD_ARCHIVE_PATH/${server_name[$1]}/${world_name[$2]}"
# If the ramdisk path is set, get the path for this world
if [ ! -z "$RAMDISK_STORAGE_PATH" ]; then
world_ramdisk_path[$2]="${RAMDISK_STORAGE_PATH}/${server_name[$1]}/${world_name[$2]}"
fi
# Detect whether this world should be in ram
if [[ -e "${world_path[$2]}/$WORLD_FLAG_INRAM" ]]; then
world_inram[$2]="true"
else
world_inram[$2]="false"
fi
}
# Load a config file for a server
# $1: The id of the server to laod
server_load_config() {
local name value
if [[ -f "${server_conf[$1]}" ]]; then
while read line; do
# ignore comment lines
echo "$line" | grep "^#" >/dev/null 2>&1 && continue
# if not empty, set the property using declare
if [ ! -z "$line" ]; then
name="$(echo $line | awk -F '=' '{print $1}')"
value="$(echo $line | awk -F '\"' '{print $2}')"
fi
case "$name" in
SERVER_USER) server_user_name[$1]="$value";;
SCREEN_NAME) server_screen_name[$1]="$value";;
WORLD_STORAGE_PATH) server_world_storage[$1]="${server_path[$1]}/$value";;
WORLD_STORAGE_INACTIVE_PATH) server_world_storage_inactive[$1]="${server_path[$1]}/$value";;
LOG) server_log[$1]="${server_path[$1]}/$value";;
PROPERTIES) server_properties[$1]="$value";;
WHITELIST) server_whitelist[$1]="$value";;
BANNED_PLAYERS) server_banned_players[$1]="$value";;
BANNED_IPS) server_banned_ips[$1]="$value";;
OPS) server_ops[$1]="$value";;
JAR) server_jar[$1]="${server_path[$1]}/$value";;
RAM) server_ram[$1]="$value";;
INVOCATION) server_invocation[$1]="$value";;
STOP_DELAY) server_stop_delay[$1]="$value";;
RESTART_DELAY) server_restart_delay[$1]="$value";;
STOP_MESSAGE) server_stop_message[$1]="$value";;
STOP_ABORT) server_stop_abort[$1]="$value";;
RESTART_MESSAGE) server_restart_message[$1]="$value";;
RESTART_ABORT) server_restart_abort[$1]="$value";;
WORLD_BACKUP_STARTED) server_world_backup_started[$1]="$value";;
WORLD_BACKUP_FINISHED) server_world_backup_finished[$1]="$value";;
COMPLETE_BACKUP_STARTED) server_complete_backup_started[$1]="$value";;
COMPLETE_BACKUP_FINISHED) server_complete_backup_finished[$1]="$value";;
CONFIRM_SAVE_ON) server_confirm_save_on[$1]="$value";;
CONFIRM_SAVE_OFF) server_confirm_save_off[$1]="$value";;
CONFIRM_SAVE_ALL) server_confrim_save_all[$1]="$value";;
CONFIRM_START) server_confrim_start[$1]="$value";;
CONFIRM_WHITELIST_LIST) server_confirm_whitelist_list[$1]="$value";;
CONFIRM_KICK) server_confirm_kick[$1]="$value";;
CONFIRM_KICK_FAIL) server_confirm_kick_fail[$1]="$value";;
CONFIRM_TIME_SET) server_confirm_time_set[$1]="$value";;
CONFIRM_TIME_SET_FAIL) server_confirm_time_set_fail[$1]="$value";;
CONFIRM_TIME_ADD) server_confirm_time_add[$1]="$value";;
CONFIRM_TIME_ADD_FAIL) server_confirm_time_add_fail[$1]="$value";;
CONFIRM_TOGGLEDOWNFALL) server_confirm_toggledownfall[$1]="$value";;
CONFIRM_TOGGLEDOWNFALL_FAIL) server_confirm_toggledownfall_fail[$1]="$value";;
CONFIRM_GAMEMODE) server_confirm_gamemode[$1]="$value";;
CONFIRM_GAMEMODE_FAIL_NO_USER) server_confirm_gamemode_fail_no_user[$1]="$value";;
CONFIRM_GAMEMODE_FAIL_NO_CHANGE) server_confirm_gamemode_fail_no_change[$1]="$value";;
COMPLETE_BACKUP_FOLLOW_SYMLINKS) server_complete_backup_follow_symlinks[$1]="$value";;
esac
done < "${server_conf[$1]}"
fi
}
# Initialise a server's variables
# $1: The id to use for this server
# $2: The name of the server
server_init() {
server_name[$1]="$2"
server_path[$1]="$SERVER_STORAGE_PATH/$2"
server_conf[$1]="${server_path[$1]}/$DEFAULT_SERVER_CONF"
server_flag_active[$1]="${server_path[$1]}/$SERVER_FLAG_ACTIVE"
server_backup_path[$1]="$BACKUP_ARCHIVE_PATH/${server_name[$1]}"
server_log_archive_path[$1]="$LOG_ARCHIVE_PATH/${server_name[$1]}"
if [[ -e "${server_flag_active[$1]}" ]]; then
server_active[$1]="true"
else
server_active[$1]="false"
fi
# Setup defaults
# Note: screen_name will at this stage have the {SERVER_NAME} tag in it
# which needs to be replaced.
# Invocation may also the {RAM} and {JAR} tags.
server_user_name[$1]="$DEFAULT_SERVER_USER"
server_screen_name[$1]="${DEFAULT_SCREEN_NAME//\{SERVER_NAME\}/${server_name[$1]}}" # Replace tags now, they cannot change
server_world_storage[$1]="${server_path[$1]}/$DEFAULT_WORLD_STORAGE_PATH"
server_world_storage_inactive[$1]="${server_path[$1]}/$DEFAULT_WORLD_STORAGE_INACTIVE_PATH"
server_log[$1]="${server_path[$1]}/$DEFAULT_LOG"
server_properties[$1]="${server_path[$1]}/$DEFAULT_PROPERTIES"
server_whitelist[$1]="${server_path[$1]}/$DEFAULT_WHITELIST"
server_banned_players[$1]="${server_path[$1]}/$DEFAULT_BANNED_PLAYERS"
server_banned_ips[$1]="${server_path[$1]}/$DEFAULT_BANNED_IPS"
server_ops[$1]="${server_path[$1]}/$DEFAULT_OPS"
server_jar[$1]="${server_path[$1]}/$DEFAULT_JAR"
server_ram[$1]="$DEFAULT_RAM"
server_invocation[$1]="$DEFAULT_INVOCATION" # Don't replace tags yet, they may change
server_stop_delay[$1]="$DEFAULT_STOP_DELAY"
server_restart_delay[$1]="$DEFAULT_RESTART_DELAY"
server_stop_message[$1]="$DEFAULT_STOP_MESSAGE"
server_stop_abort[$1]="$DEFAULT_STOP_ABORT"
server_restart_message[$1]="$DEFAULT_RESTART_MESSAGE"
server_restart_abort[$1]="$DEFAULT_RESTART_ABORT"
server_world_backup_started[$1]="$DEFAULT_WORLD_BACKUP_STARTED"
server_world_backup_finished[$1]="$DEFAULT_WORLD_BACKUP_FINISHED"
server_complete_backup_started[$1]="$DEFAULT_COMPLETE_BACKUP_STARTED"
server_complete_backup_finished[$1]="$DEFAULT_COMPLETE_BACKUP_FINISHED"
server_confirm_save_on[$1]="$DEFAULT_CONFIRM_SAVE_ON"
server_confirm_save_off[$1]="$DEFAULT_CONFIRM_SAVE_OFF"
server_confirm_save_all[$1]="$DEFAULT_CONFIRM_SAVE_ALL"
server_confirm_start[$1]="$DEFAULT_CONFIRM_START"
server_confirm_kick[$1]="$DEFAULT_CONFIRM_KICK"
server_confirm_kick_fail[$1]="$DEFAULT_CONFIRM_KICK_FAIL"
server_confirm_time_set[$1]="$DEFAULT_CONFIRM_TIME_SET"
server_confirm_time_set_fail[$1]="$DEFAULT_CONFIRM_TIME_SET_FAIL"
server_confirm_time_add[$1]="$DEFAULT_CONFIRM_TIME_ADD"
server_confirm_time_add_fail[$1]="$DEFAULT_CONFIRM_TIME_ADD_FAIL"
server_confirm_toggledownfall[$1]="$DEFAULT_CONFIRM_TOGGLEDOWNFALL"
server_confirm_toggledownfall_fail[$1]="$DEFAULT_CONFIRM_TOGGLEDOWNFALL_FAIL"
server_confirm_gamemode[$1]="$DEFAULT_CONFIRM_GAMEMODE"
server_confirm_gamemode_fail_no_user[$1]="$DEFAULT_CONFIRM_GAMEMODE_FAIL_NO_USER"
server_confirm_gamemode_fail_no_change[$1]="$DEFAULT_CONFIRM_GAMEMODE_FAIL_NO_CHANGE"
server_complete_backup_follow_symlinks[$1]="$DEFAULT_COMPLETE_BACKUP_FOLLOW_SYMLINKS"
# Load config overrides from server config file if present
server_load_config $1
# Replace tags in delay messages
server_stop_message[$1]="${server_stop_message[$1]//\{DELAY\}/${server_stop_delay[$1]}}"
server_restart_message[$1]="${server_restart_message[$1]//\{DELAY\}/${server_restart_delay[$1]}}"
# Replace tags in server invocation
server_invocation[$1]="${server_invocation[$1]//\{RAM\}/${server_ram[$1]}}"
server_invocation[$1]="${server_invocation[$1]//\{JAR\}/${server_jar[$1]}}"
# Load worlds if there is a world storage directory present
server_world_offset[$1]=0
server_num_worlds[$1]=0
# Start world id's for this server's worlds at the end of the array
local world_id=$num_worlds
# Record the index at which worlds for this server start
server_world_offset[$1]=$world_id
if [[ -d "${server_world_storage[$1]}" ]]; then
# Load active worlds
while IFS= read -r -d $'\0' world_path; do
local name=$(basename $world_path)
server_world_init $1 $world_id $name
# Build the server_worlds comma separated list
if [[ $world_id == $server_world_offset[$1] ]]; then
server_worlds[$1]="$name"
else
server_worlds[$1]="${server_worlds[$1]}, $name"
fi
world_id=$(($world_id+1))
num_worlds=$world_id
done < <(find "${server_world_storage[$1]}" -mindepth 1 -maxdepth 1 -type d -print0)
fi
if [[ -d "${server_world_storage_inactive[$1]}" ]]; then
# Load inactive worlds
while IFS= read -r -d $'\0' world_path; do
local name=$(basename $world_path)
server_world_init $1 $world_id $name
# Build the server_worlds_inactive comma separated list
if [[ $world_id == $server_world_offset[$1] ]]; then
server_worlds[$1]="$name"
else
server_worlds[$1]="${server_worlds[$1]}, $name"
fi
world_id=$(($world_id+1))
num_worlds=$world_id
done < <(find "${server_world_storage_inactive[$1]}" -mindepth 1 -maxdepth 1 -type d -print0)
fi
# Record the number of worlds this server has
server_num_worlds[$1]=$(( $world_id - ${server_world_offset[$1]} ))
}
# Asserts that a variable has been set in the config file
# $1: The name of the variable to test
# $2: The message to print to stderr if the variable is unset
assert_is_set_in_config() {
[[ ! ${!1} && ${!1-_} ]] && {
echoerr "Error: $1 must be set in $CONFIG"
exit 1
}
}
# Ensures all non-optional settings have been set
init_ensure_settings() {
assert_is_set_in_config USERNAME
assert_is_set_in_config SERVER_STORAGE_PATH
assert_is_set_in_config JAR_STORAGE_PATH
assert_is_set_in_config RAMDISK_STORAGE_PATH
assert_is_set_in_config WORLD_ARCHIVE_PATH
assert_is_set_in_config LOG_ARCHIVE_PATH
assert_is_set_in_config BACKUP_ARCHIVE_PATH
assert_is_set_in_config DEFAULT_SERVER_CONF
assert_is_set_in_config DEFAULT_SERVER_USER
assert_is_set_in_config DEFAULT_SCREEN_NAME
assert_is_set_in_config DEFAULT_WORLD_STORAGE_PATH
assert_is_set_in_config DEFAULT_WORLD_STORAGE_INACTIVE_PATH
assert_is_set_in_config DEFAULT_COMPLETE_BACKUP_FOLLOW_SYMLINKS
assert_is_set_in_config DEFAULT_LOG
assert_is_set_in_config DEFAULT_PROPERTIES
assert_is_set_in_config DEFAULT_WHITELIST
assert_is_set_in_config DEFAULT_BANNED_PLAYERS
assert_is_set_in_config DEFAULT_BANNED_IPS
assert_is_set_in_config DEFAULT_OPS
assert_is_set_in_config DEFAULT_JAR
assert_is_set_in_config DEFAULT_RAM
assert_is_set_in_config DEFAULT_INVOCATION
assert_is_set_in_config DEFAULT_STOP_DELAY
assert_is_set_in_config DEFAULT_RESTART_DELAY
assert_is_set_in_config DEFAULT_STOP_MESSAGE
assert_is_set_in_config DEFAULT_STOP_ABORT
assert_is_set_in_config DEFAULT_RESTART_MESSAGE
assert_is_set_in_config DEFAULT_RESTART_ABORT
assert_is_set_in_config DEFAULT_WORLD_BACKUP_STARTED
assert_is_set_in_config DEFAULT_WORLD_BACKUP_FINISHED
assert_is_set_in_config DEFAULT_COMPLETE_BACKUP_STARTED
assert_is_set_in_config DEFAULT_COMPLETE_BACKUP_FINISHED
assert_is_set_in_config DEFAULT_CONFIRM_SAVE_ON
assert_is_set_in_config DEFAULT_CONFIRM_SAVE_OFF
assert_is_set_in_config DEFAULT_CONFIRM_SAVE_ALL
assert_is_set_in_config DEFAULT_CONFIRM_START
assert_is_set_in_config DEFAULT_CONFIRM_KICK
assert_is_set_in_config DEFAULT_CONFIRM_KICK_FAIL
assert_is_set_in_config DEFAULT_CONFIRM_TIME_SET
assert_is_set_in_config DEFAULT_CONFIRM_TIME_SET_FAIL
assert_is_set_in_config DEFAULT_CONFIRM_TIME_ADD
assert_is_set_in_config DEFAULT_CONFIRM_TIME_ADD_FAIL
assert_is_set_in_config DEFAULT_CONFIRM_TOGGLEDOWNFALL
assert_is_set_in_config DEFAULT_CONFIRM_TOGGLEDOWNFALL_FAIL
assert_is_set_in_config DEFAULT_CONFIRM_GAMEMODE
assert_is_set_in_config DEFAULT_CONFIRM_GAMEMODE_FAIL_NO_USER
assert_is_set_in_config DEFAULT_CONFIRM_GAMEMODE_FAIL_NO_CHANGE
}
init() {
# Sourcing $CONFIG will override the previous defaults, with new values
source "$CONFIG"
init_ensure_settings
num_worlds=0
num_servers=0
local i=0
local j=0
for server in $(ls -1 "$SERVER_STORAGE_PATH"); do
server_name[$i]="$server"
server_path[$i]="$SERVER_STORAGE_PATH/$server"
server_conf[$i]="${server_path[$i]}/$DEFAULT_SERVER_CONF"
server_flag_active[$i]="${server_path[$i]}/$SERVER_FLAG_ACTIVE"
server_backup_path[$i]="$BACKUP_ARCHIVE_PATH/${server_name[$i]}"
server_log_archive_path[$i]="$LOG_ARCHIVE_PATH/${server_name[$i]}"
if [[ -e "${server_flag_active[$i]}" ]]; then
server_active[$i]="true"
else
server_active[$i]="false"
fi
# Setup defaults
# Note: screen_name will at this stage have the {SERVER_NAME} tag in it
# which needs to be replaced.
# Invocation may also the {RAM} and {JAR} tags.
server_user_name[$i]="$DEFAULT_SERVER_USER"
server_screen_name[$i]="${DEFAULT_SCREEN_NAME//\{SERVER_NAME\}/${server_name[$i]}}" # Replace tags now, they cannot change
server_world_storage[$i]="${server_path[$i]}/$DEFAULT_WORLD_STORAGE_PATH"
server_log[$i]="${server_path[$i]}/$DEFAULT_LOG"
server_properties[$i]="${server_path[$i]}/$DEFAULT_PROPERTIES"
server_whitelist[$i]="${server_path[$i]}/$DEFAULT_WHITELIST"
server_banned_players[$i]="${server_path[$i]}/$DEFAULT_BANNED_PLAYERS"
server_banned_ips[$i]="${server_path[$i]}/$DEFAULT_BANNED_IPS"
server_ops[$i]="${server_path[$i]}/$DEFAULT_OPS"
server_jar[$i]="${server_path[$i]}/$DEFAULT_JAR"
server_ram[$i]="$DEFAULT_RAM"
server_invocation[$i]="$DEFAULT_INVOCATION" # Don't replace tags yet, they may change
server_stop_delay[$i]="$DEFAULT_STOP_DELAY"
server_restart_delay[$i]="$DEFAULT_RESTART_DELAY"
server_stop_message[$i]="$DEFAULT_STOP_MESSAGE"
server_stop_abort[$i]="$DEFAULT_STOP_ABORT"
server_restart_message[$i]="$DEFAULT_RESTART_MESSAGE"
server_restart_abort[$i]="$DEFAULT_RESTART_ABORT"
server_world_backup_started[$i]="$DEFAULT_WORLD_BACKUP_STARTED"
server_world_backup_finished[$i]="$DEFAULT_WORLD_BACKUP_FINISHED"
server_complete_backup_started[$i]="$DEFAULT_COMPLETE_BACKUP_STARTED"
server_complete_backup_finished[$i]="$DEFAULT_COMPLETE_BACKUP_FINISHED"
server_confirm_save_on[$i]="$DEFAULT_CONFIRM_SAVE_ON"
server_confirm_save_off[$i]="$DEFAULT_CONFIRM_SAVE_OFF"
server_confirm_save_all[$i]="$DEFAULT_CONFIRM_SAVE_ALL"
server_confirm_start[$i]="$DEFAULT_CONFIRM_START"
server_confirm_kick[$i]="$DEFAULT_CONFIRM_KICK"
server_confirm_kick_fail[$i]="$DEFAULT_CONFIRM_KICK_FAIL"
server_confirm_time_set[$i]="$DEFAULT_CONFIRM_TIME_SET"
server_confirm_time_set_fail[$i]="$DEFAULT_CONFIRM_TIME_SET_FAIL"
server_confirm_time_add[$i]="$DEFAULT_CONFIRM_TIME_ADD"
server_confirm_time_add_fail[$i]="$DEFAULT_CONFIRM_TIME_ADD_FAIL"
server_confirm_toggledownfall[$i]="$DEFAULT_CONFIRM_TOGGLEDOWNFALL"
server_confirm_toggledownfall_fail[$i]="$DEFAULT_CONFIRM_TOGGLEDOWNFALL_FAIL"
server_confirm_gamemode[$i]="$DEFAULT_CONFIRM_GAMEMODE"
server_confirm_gamemode_fail_no_user[$i]="$DEFAULT_CONFIRM_GAMEMODE_FAIL_NO_USER"
server_confirm_gamemode_fail_no_change[$i]="$DEFAULT_CONFIRM_GAMEMODE_FAIL_NO_CHANGE"
server_complete_backup_follow_symlinks[$i]="$DEFAULT_COMPLETE_BACKUP_FOLLOW_SYMLINKS"
# Load config overrides from server config file if present
if [[ -e "${server_conf[$i]}" ]]; then
local name
local value
while read line; do
# ignore comment lines
echo "$line" | grep "^#" >/dev/null 2>&1 && continue
# if not empty, set the property using declare
if [ ! -z "$line" ]; then
name="$(echo $line | awk -F '=' '{print $1}')"
value="$(echo $line | awk -F '\"' '{print $2}')"
fi
case "$name" in
SERVER_USER) server_user_name[$i]="$value";;
SCREEN_NAME) server_screen_name[$i]="$value";;
WORLD_STORAGE_PATH) server_world_storage[$i]="${server_path[$i]}/$value";;
LOG) server_log[$i]="${server_path[$i]}/$value";;
PROPERTIES) server_properties[$i]="$value";;
WHITELIST) server_whitelist[$i]="$value";;
BANNED_PLAYERS) server_banned_players[$i]="$value";;
BANNED_IPS) server_banned_ips[$i]="$value";;
OPS) server_ops[$i]="$value";;
JAR) server_jar[$i]="${server_path[$i]}/$value";;
RAM) server_ram[$i]="$value";;
INVOCATION) server_invocation[$i]="$value";;
STOP_DELAY) server_stop_delay[$i]="$value";;
RESTART_DELAY) server_restart_delay[$i]="$value";;
STOP_MESSAGE) server_stop_message[$i]="$value";;
STOP_ABORT) server_stop_abort[$i]="$value";;
RESTART_MESSAGE) server_restart_message[$i]="$value";;
RESTART_ABORT) server_restart_abort[$i]="$value";;
WORLD_BACKUP_STARTED) server_world_backup_started[$i]="$value";;
WORLD_BACKUP_FINISHED) server_world_backup_finished[$i]="$value";;
COMPLETE_BACKUP_STARTED) server_complete_backup_started[$i]="$value";;
COMPLETE_BACKUP_FINISHED) server_complete_backup_finished[$i]="$value";;
CONFIRM_SAVE_ON) server_confirm_save_on[$i]="$value";;
CONFIRM_SAVE_OFF) server_confirm_save_off[$i]="$value";;
CONFIRM_SAVE_ALL) server_confrim_save_all[$i]="$value";;
CONFIRM_START) server_confrim_start[$i]="$value";;
CONFIRM_WHITELIST_LIST) server_confirm_whitelist_list[$i]="$value";;
CONFIRM_KICK) server_confirm_kick[$i]="$value";;
CONFIRM_KICK_FAIL) server_confirm_kick_fail[$i]="$value";;
CONFIRM_TIME_SET) server_confirm_time_set[$i]="$value";;
CONFIRM_TIME_SET_FAIL) server_confirm_time_set_fail[$i]="$value";;
CONFIRM_TIME_ADD) server_confirm_time_add[$i]="$value";;
CONFIRM_TIME_ADD_FAIL) server_confirm_time_add_fail[$i]="$value";;
CONFIRM_TOGGLEDOWNFALL) server_confirm_toggledownfall[$i]="$value";;
CONFIRM_TOGGLEDOWNFALL_FAIL) server_confirm_toggledownfall_fail[$i]="$value";;
CONFIRM_GAMEMODE) server_confirm_gamemode[$i]="$value";;
CONFIRM_GAMEMODE_FAIL_NO_USER) server_confirm_gamemode_fail_no_user[$i]="$value";;
CONFIRM_GAMEMODE_FAIL_NO_CHANGE) server_confirm_gamemode_fail_no_change[$i]="$value";;
COMPLETE_BACKUP_FOLLOW_SYMLINKS) server_complete_backup_follow_symlinks[$i]="$value";;
esac
done < "${server_conf[$i]}"
fi
# Replace tags in delay messages
server_stop_message[$i]="${server_stop_message[$i]//\{DELAY\}/${server_stop_delay[$i]}}"
server_restart_message[$i]="${server_restart_message[$i]//\{DELAY\}/${server_restart_delay[$i]}}"
# Replace tags in server invocation
server_invocation[$i]="${server_invocation[$i]//\{RAM\}/${server_ram[$i]}}"
server_invocation[$i]="${server_invocation[$i]//\{JAR\}/${server_jar[$i]}}"
# Load worlds if there is a world storage directory present
server_world_offset[$i]=0
server_num_worlds[$i]=0
if [[ -e "${server_world_storage[$i]}" ]]; then
server_worlds[$i]=$(ls -1 "${server_world_storage[$i]}")
# Record the index at which worlds for this server start
server_world_offset[$i]=$j
for world in ${server_worlds[$i]}; do
world_server_id[$j]="$i"
world_name[$j]="$world"
world_path[$j]="${server_world_storage[$i]}/${world_name[$j]}"
world_link[$j]="${server_path[$i]}/${world_name[$j]}"
world_flag_inram[$j]="${world_path[$j]}/$WORLD_FLAG_INRAM"
world_backup_path[$j]="$WORLD_ARCHIVE_PATH/${server_name[$i]}/${world_name[$j]}"
if [ ! -z $RAMDISK_STORAGE_PATH ]; then
world_ramdisk_path[$j]="${RAMDISK_STORAGE_PATH}/${server_name[$i]}/${world_name[$j]}"
fi
if [[ -e "${world_path[$j]}/$WORLD_FLAG_INRAM" ]]; then
world_inram[$j]="true"
else
world_inram[$j]="false"
fi
j=$(($j+1))
done
# Record the number of worlds this server has
server_num_worlds[$i]=$(( $j - ${server_world_offset[$i]} ))
fi
i=$(($i+1))
done
num_servers=$i
num_worlds=$j
local server_id=0
while IFS= read -r -d $'\0' server_path; do
local name=$(basename $server_path)
server_init $server_id $name
server_id=$(($server_id+1))
num_servers=$server_id
done < <(find "$SERVER_STORAGE_PATH" -mindepth 1 -maxdepth 1 -type d -print0)
}
# Called if the script is interrupted before exiting naturally
@ -1489,6 +1685,7 @@ main() {
echo -e " <server> worlds ram <world> Toggles a world's \"in RAM\" status"
echo -e " <server> worlds todisk Synchronises any \"in RAM\" worlds to disk a server has"
echo -e " <server> worlds backup Makes a backup of all worlds a server has"
echo -e " <server> worlds on|off <world> Activate or deactivate a world, inactive worlds are not backed up"
echo -e " <server> logroll Move a server log to a gziped archive, to reduce lag"
echo -e " <server> backup Makes a backup of an entire server directory"
echo -e " <server> jar <jargroup> [<file>] Sets a server's jar file"
@ -1608,6 +1805,20 @@ main() {
echo "Backup took $SECONDS seconds".
;;
on)
if [ -z "$4" ]; then
echo "Invalid command."
else
world_activate "$(server_world_get_id "$id" "$4")"
fi
;;
off)
if [ -z "$4" ]; then
echo "Invalid command."
else
world_deactivate "$(server_world_get_id "$id" "$4")"
fi
;;
*)
echo "Invalid command."
;;

View File

@ -78,6 +78,11 @@ DEFAULT_SCREEN_NAME="msm-{SERVER_NAME}"
# A directory name relative to the server directory where worlds are stored
DEFAULT_WORLD_STORAGE_PATH="worldstorage"
# A directory name relative to the server directory where old worlds are stored
# These worlds will cannot be used by the server and will not be saved when
# backing up all worlds. But will be inclued in a complete server backup.
DEFAULT_WORLD_STORAGE_INACTIVE_PATH="worldstorage_inactive"
# "true" and symlinks are followed when performing a complete backup,
# "false" and symlinks are replaced in the zip with a file containing the
# path to the original symlink larget, this saves space.