Stopped loading all config files all the time.

Now server confs are only loaded when a command needs it.
This commit is contained in:
Marcus Whybrow
2012-07-18 07:42:26 +01:00
parent 7ac5827948
commit c46db621e0

218
init/msm
View File

@ -50,6 +50,10 @@ COMMAND_COUNT=0
SETTING_COUNT=0 SETTING_COUNT=0
SERVER_SETTING_COUNT=0 SERVER_SETTING_COUNT=0
# Other global variables
NUM_WORLDS=0
NUM_SERVERS=0
### Utility Functions ### Utility Functions
@ -112,7 +116,7 @@ is_bash_version() {
# Converts a string to be ready for use as a global # Converts a string to be ready for use as a global
# variable name. # variable name.
# $1: The string to convert # $1: The string to convert
# returns: The name in uppercase and with underscores # RETURN: The name in uppercase and with underscores
to_global_name() { to_global_name() {
unset RETURN unset RETURN
# Translate to uppercase, and replace dashes with underscores # Translate to uppercase, and replace dashes with underscores
@ -121,7 +125,7 @@ to_global_name() {
# Much faster than the `tr` command # Much faster than the `tr` command
result="${result//-/_}" result="${result//-/_}"
result="${result//./_}" result="${result//./_}"
result="${result^^}" result="${result^^}" # to uppercase
else else
result="$(echo "$result" | tr '[\-\.a-z]' '[\_\_A-Z]')" result="$(echo "$result" | tr '[\-\.a-z]' '[\_\_A-Z]')"
fi fi
@ -129,12 +133,42 @@ to_global_name() {
RETURN="$result" RETURN="$result"
} }
# Converts a global BASH variable name to a server.properties file
# varibale name.
# $1: The string to convert
# RETURN: The name in lowercase and with dashes
to_properties_name() {
unset RETURN
# Translate to uppercase, and replace dashes with underscores
local result="$1"
if is_bash_version 4; then
# Much faster than the `tr` command
result="${result//_/-}"
result="${result,,}" # to lowercase
else
result="$(echo "$result" | tr '[\_A-Z]' '[\-a-z]')"
fi
RETURN="$result"
}
# A custom basename function which is faster
# than opening a subshell
# $1: The path to get the basename of
# RETURN: The basename of the path
quick_basename() {
unset RETURN
if [[ "$1" =~ \/([^\/]*)$ ]]; then
RETURN="${BASH_REMATCH[1]}"
fi
}
# A function used to print debug messages to stdout. Prevents messages from # A function used to print debug messages to stdout. Prevents messages from
# appearing unless in debug mode, and allows debug statements to be easily # appearing unless in debug mode, and allows debug statements to be easily
# distinguished from necessary echo statements. # distinguished from necessary echo statements.
# $1: The message to output # $1: The message to output
debug() { debug() {
if [[ "$DEBUG" == "true" ]]; then if [[ "$SETTINGS_DEBUG" == "true" ]]; then
echoerr "$1" echoerr "$1"
fi fi
} }
@ -302,9 +336,9 @@ world_deactivate() {
# $1: The name of the server # $1: The name of the server
server_get_id() { server_get_id() {
unset RETURN unset RETURN
for ((i=0; i<$NUM_SERVERS; i++)); do for ((server=0; server<$NUM_SERVERS; server++)); do
if [[ "${SERVER_NAME[$i]}" == "$1" ]]; then if [[ "${SERVER_NAME[$server]}" == "$1" ]]; then
RETURN="$i" RETURN="$server"
return 0 return 0
fi fi
done done
@ -822,9 +856,9 @@ server_create() {
as_user "$USERNAME" "echo \"MSM requires all your worlds be moved into this directory.\" > '$SETTINGS_SERVER_STORAGE_PATH/$1/$SETTINGS_DEFAULT_WORLD_STORAGE_PATH/readme.txt'" as_user "$USERNAME" "echo \"MSM requires all your worlds be moved into this directory.\" > '$SETTINGS_SERVER_STORAGE_PATH/$1/$SETTINGS_DEFAULT_WORLD_STORAGE_PATH/readme.txt'"
echo "Done." echo "Done."
# Now that the new server has been created, we must call init again # Now that the new server has been created, we must call load_all again
# to ensure it is recognised. # to ensure it is recognised.
init load_all
# TODO: Handle server default setup stuff better than just using # TODO: Handle server default setup stuff better than just using
# the "minecraft" jar group. And make it configurable. # the "minecraft" jar group. And make it configurable.
@ -867,6 +901,7 @@ server_rename() {
server_get_id "$1" server_get_id "$1"
local existing_id="$RETURN" local existing_id="$RETURN"
if server_is_running "$existing_id"; then if server_is_running "$existing_id"; then
error_exit SERVER_RUNNING "Can only rename a stopped server." error_exit SERVER_RUNNING "Can only rename a stopped server."
else else
@ -2206,8 +2241,8 @@ command_server_config() {
if [ -z "$2" ]; then if [ -z "$2" ]; then
# List all parameters # List all parameters
for ((i=0; i<$SERVER_SETTING_COUNT; i++)); do for ((i=0; i<$SERVER_SETTING_COUNT; i++)); do
to_global_name "${SERVER_SETTING_NAME[$i]}" to_properties_name "${SERVER_SETTING_NAME[$i]}"
echo "msm-$setting_name=\"$(server_property "$1" "$RETURN")\"" echo "msm-$RETURN=\"$(server_property "$1" "${SERVER_SETTING_NAME[$i]}")\""
done done
fi fi
} }
@ -2224,11 +2259,11 @@ command_server_config() {
### Init and Misc Functions ### Init and Misc Functions
### ----------------------- ### -----------------------
# Initialises a server's world # Load a server's world
# $1: The server id # $1: The server id
# $2: The world id to use # $2: The world id to use
# $3: The name of the world # $3: The name of the world
server_world_init() { load_server_world() {
WORLD_SERVER_ID[$2]="$1" WORLD_SERVER_ID[$2]="$1"
WORLD_NAME[$2]="$3" WORLD_NAME[$2]="$3"
WORLD_ACTIVE_PATH[$2]="${SERVER_WORLD_STORAGE_PATH[$1]}/${WORLD_NAME[$2]}" WORLD_ACTIVE_PATH[$2]="${SERVER_WORLD_STORAGE_PATH[$1]}/${WORLD_NAME[$2]}"
@ -2267,57 +2302,47 @@ server_world_init() {
fi fi
} }
# Load a the server.properties file for a server # Load the server.properties file for a server
# $1: The id of the server to load # $1: The id of the server to load
server_load_properties() { load_server_properties() {
local name value local name value name_prefix
if [[ -f "${SERVER_PATH[$1]}/$SETTINGS_SERVER_PROPERTIES" ]]; then if [[ -f "${SERVER_PATH[$1]}/$SETTINGS_SERVER_PROPERTIES" ]]; then
while read line; do while read line; do
# ignore comment lines
if [[ "$line" =~ ^# ]]; then
continue
fi
# if not empty, get the name and value of the setting # if not empty, get the name and value of the setting
if [[ "$line" =~ ^([\-\_a-zA-Z0-9]+)\=(\"(.*)\"|\'(.*)\'|(.*)$) ]]; then if [[ "$line" =~ ^(msm\-)?([\-\_a-zA-Z0-9]+)\=(\"(.*)\"|\'(.*)\'|(.*)$) ]]; then
name="${BASH_REMATCH[1]}" msm_prefix="${BASH_REMATCH[1]}"
name="${BASH_REMATCH[2]}"
# Only one of 3,4 or 5 will match: # Only one of 3,4 or 5 will match:
value="${BASH_REMATCH[3]}${BASH_REMATCH[4]}${BASH_REMATCH[5]}" value="${BASH_REMATCH[4]}${BASH_REMATCH[5]}${BASH_REMATCH[6]}"
to_global_name "$name" to_global_name "$name"
name="$RETURN" name="$RETURN"
# Create variables # Create variables
if [[ "$name" =~ ^msm-[\-\_a-zA-Z0-9]+$ ]]; then if [ ! -z "$msm_prefix" ]; then
# Regex for MSM custom variables
# Make relative paths absolute to server directory # Make relative paths absolute to server directory
if [[ "$name" =~ ^msm-[\-\_a-zA-Z0-9]+-path$ ]] && [[ ! "$value" =~ ^\/ ]]; then if [[ "$name" =~ \_PATH$ ]] && [ "${value:0:1}" != '/' ]; then
value="${SERVER_PATH[$1]}/$value" value="${SERVER_PATH[$1]}/$value"
fi fi
# Create the variable name_prefix="SERVER_"
eval SERVER_${name}[$1]=\"$value\"
else else
if [[ "$name" =~ ^[\-\_a-zA-Z0-9]+$ ]]; then name_prefix="SERVER_PROPERTIES_"
# Regex for standard Minecraft variables
eval SERVER_PROPERTIES_${name}[$1]=\"$value\"
fi
fi fi
# Create the variable
eval ${name_prefix}${name}[$1]=\"$value\"
fi fi
done < "${SERVER_PATH[$1]}/$SETTINGS_SERVER_PROPERTIES" done < "${SERVER_PATH[$1]}/$SETTINGS_SERVER_PROPERTIES"
fi fi
} }
# Initialise a server's variables # Load a server's variables
# $1: The id to use for this server # $1: The id of the server to load
# $2: The name of the server load_server() {
server_init() {
# Non-configurable Variables # Non-configurable Variables
SERVER_NAME[$1]="$2" SERVER_PATH[$1]="$SETTINGS_SERVER_STORAGE_PATH/${SERVER_NAME[$1]}"
SERVER_PATH[$1]="$SETTINGS_SERVER_STORAGE_PATH/$2"
SERVER_BACKUP_PATH[$1]="$SETTINGS_BACKUP_ARCHIVE_PATH/${SERVER_NAME[$1]}" SERVER_BACKUP_PATH[$1]="$SETTINGS_BACKUP_ARCHIVE_PATH/${SERVER_NAME[$1]}"
SERVER_LOG_ARCHIVE_PATH[$1]="$SETTINGS_LOG_ARCHIVE_PATH/${SERVER_NAME[$1]}" SERVER_LOG_ARCHIVE_PATH[$1]="$SETTINGS_LOG_ARCHIVE_PATH/${SERVER_NAME[$1]}"
@ -2326,9 +2351,10 @@ server_init() {
# from /etc/msm.conf # from /etc/msm.conf
local name value local name value
for ((i=0; i<$SERVER_SETTING_COUNT; i++)); do # Make a server version of all default server settings
name="${SERVER_SETTING_NAME[$i]}" for ((server_setting=0; server_setting<$SERVER_SETTING_COUNT; server_setting++)); do
value="$(eval echo \$SETTINGS_DEFAULT_${name})" name="${SERVER_SETTING_NAME[$server_setting]}"
eval value=\"\$SETTINGS_DEFAULT_${name}\"
# Make relative paths absolute, assuming the server directory # Make relative paths absolute, assuming the server directory
# as the current directory. # as the current directory.
@ -2346,7 +2372,7 @@ server_init() {
fi fi
# Load setting overrides from server.properties # Load setting overrides from server.properties
server_load_properties "$1" load_server_properties "$1"
# Perform tag replacements on specific variables # Perform tag replacements on specific variables
SERVER_SCREEN_NAME[$1]="${SERVER_SCREEN_NAME[$1]//\{SERVER_NAME\}/${SERVER_NAME[$1]}}" # Replace tags now, they cannot change SERVER_SCREEN_NAME[$1]="${SERVER_SCREEN_NAME[$1]//\{SERVER_NAME\}/${SERVER_NAME[$1]}}" # Replace tags now, they cannot change
@ -2374,7 +2400,7 @@ server_init() {
# Load active worlds # Load active worlds
while IFS= read -r -d $'\0' path; do while IFS= read -r -d $'\0' path; do
local name="$(basename "$path")" local name="$(basename "$path")"
server_world_init "$1" "$id" "$name" load_server_world "$1" "$id" "$name"
# Build the server_worlds comma separated list # Build the server_worlds comma separated list
if [[ "$id" == "${SERVER_WORLD_OFFSET[$1]}" ]]; then if [[ "$id" == "${SERVER_WORLD_OFFSET[$1]}" ]]; then
@ -2392,7 +2418,7 @@ server_init() {
# Load inactive worlds # Load inactive worlds
while IFS= read -r -d $'\0' path; do while IFS= read -r -d $'\0' path; do
local name="$(basename "$path")" local name="$(basename "$path")"
server_world_init "$1" "$id" "$name" load_server_world "$1" "$id" "$name"
# Build the server_worlds_inactive comma separated list # Build the server_worlds_inactive comma separated list
if [[ "$id" == "${SERVER_WORLD_OFFSET[$1]}" ]]; then if [[ "$id" == "${SERVER_WORLD_OFFSET[$1]}" ]]; then
@ -2410,7 +2436,11 @@ server_init() {
SERVER_NUM_WORLDS[$1]="$(( $id - ${SERVER_WORLD_OFFSET[$1]} ))" SERVER_NUM_WORLDS[$1]="$(( $id - ${SERVER_WORLD_OFFSET[$1]} ))"
} }
load_conf() { # Load settings for MSM
load_msm() {
register_settings
# Override settings with values from /etc/msm.conf
if [[ -f "$CONF" ]]; then if [[ -f "$CONF" ]]; then
while read line; do while read line; do
# Get the name and value of the setting # Get the name and value of the setting
@ -2427,26 +2457,32 @@ load_conf() {
fi fi
done < "$CONF" done < "$CONF"
fi fi
}
init() { # Dermine server names (but don't load them)
register_settings
load_conf
NUM_WORLDS=0
NUM_SERVERS=0
if [ -d "$SETTINGS_SERVER_STORAGE_PATH" ]; then if [ -d "$SETTINGS_SERVER_STORAGE_PATH" ]; then
local id=0 local id=0
while IFS= read -r -d $'\0' path; do while IFS= read -r -d $'\0' path; do
local name="$(basename "$path")" quick_basename "$path"
server_init "$id" "$name" SERVER_NAME[$id]="$RETURN"
id="$(($id+1))" id="$(($id+1))"
NUM_SERVERS="$id"
done < <(find "$SETTINGS_SERVER_STORAGE_PATH" -mindepth 1 -maxdepth 1 -type d -print0) done < <(find "$SETTINGS_SERVER_STORAGE_PATH" -mindepth 1 -maxdepth 1 -type d -print0)
NUM_SERVERS="$id"
fi fi
} }
# Load settings for all servers
load_all_servers() {
for ((server=0; server<$NUM_SERVERS; server++)); do
load_server "$server"
done
}
# Load settings for MSM and all servers
load_all() {
load_msm
load_all_servers
}
@ -2482,6 +2518,8 @@ register_server_setting() {
# Register possible settings # Register possible settings
register_settings() { register_settings() {
register_setting DEBUG "false"
register_setting USERNAME "minecraft" register_setting USERNAME "minecraft"
register_setting SERVER_STORAGE_PATH "/opt/msm/servers" register_setting SERVER_STORAGE_PATH "/opt/msm/servers"
register_setting JAR_STORAGE_PATH "/opt/msm/jars" register_setting JAR_STORAGE_PATH "/opt/msm/jars"
@ -2551,6 +2589,7 @@ register_settings() {
# $1: The command signature, a coded string describing the structure of the # $1: The command signature, a coded string describing the structure of the
# command. # command.
# $2: The handler function to call, if this command is identified. # $2: The handler function to call, if this command is identified.
# $3: Optional flags
register_command() { register_command() {
# Here we build a regular expression which will match any user input # Here we build a regular expression which will match any user input
# that could be passed to the given handler function. It is derrived # that could be passed to the given handler function. It is derrived
@ -2592,6 +2631,12 @@ register_command() {
COMMAND_SIGNATURE[$COMMAND_COUNT]="$1" COMMAND_SIGNATURE[$COMMAND_COUNT]="$1"
COMMAND_REGEX[$COMMAND_COUNT]="$regex" COMMAND_REGEX[$COMMAND_COUNT]="$regex"
COMMAND_HANDLER[$COMMAND_COUNT]="$2" COMMAND_HANDLER[$COMMAND_COUNT]="$2"
if [[ "$3" =~ \<load_all_servers\> ]]; then
COMMAND_LOAD_ALL_SERVERS[$COMMAND_COUNT]="true"
else
COMMAND_LOAD_ALL_SERVERS[$COMMAND_COUNT]="false"
fi
COMMAND_COUNT=$(( $COMMAND_COUNT + 1 )) COMMAND_COUNT=$(( $COMMAND_COUNT + 1 ))
else else
@ -2602,7 +2647,6 @@ register_command() {
# Match and call a command from user input # Match and call a command from user input
# $*: User input # $*: User input
call_command() { call_command() {
local args local args
local space="\ " local space="\ "
for arg in "$@"; do for arg in "$@"; do
@ -2617,8 +2661,15 @@ call_command() {
args="${args:0:${#args}-1}" args="${args:0:${#args}-1}"
fi fi
for ((i=0; i<$COMMAND_COUNT; i++)); do for ((command=0; command<$COMMAND_COUNT; command++)); do
if [[ "$args" =~ ${COMMAND_REGEX[$i]} ]]; then if [[ "$args" =~ ${COMMAND_REGEX[$command]} ]]; then
# If this command has the load_all_servers flag set
# load all server configuration
if [[ "${COMMAND_LOAD_ALL_SERVERS[$command]}" == "true" ]]; then
load_all_servers
fi
unset args unset args
local word_offset=1 local word_offset=1
local args local args
@ -2637,7 +2688,7 @@ call_command() {
# matched command handler function. Rather than passing all args # matched command handler function. Rather than passing all args
# given to the script, to the handler (which may contain constant # given to the script, to the handler (which may contain constant
# strings), it only includes variables. # strings), it only includes variables.
for word in ${COMMAND_SIGNATURE[$i]}; do for word in ${COMMAND_SIGNATURE[$command]}; do
# Whether a positional argument is a varibale or not is # Whether a positional argument is a varibale or not is
# determined by the respective element in the command signature # determined by the respective element in the command signature
# given when registering. # given when registering.
@ -2750,7 +2801,15 @@ call_command() {
# built. But there are several ways to call a handler. Either just # built. But there are several ways to call a handler. Either just
# once, or multiple times based upon if multiple servers or worlds # once, or multiple times based upon if multiple servers or worlds
# were specified. # were specified.
# Load server variables if a server has been specified
if [[ "$sid" == "server:all" ]]; then
load_all_servers
fi
if [[ "$sid" =~ ^[0-9]+$ ]]; then
load_server "$sid"
fi
# This code block calls the handler for all possible servers and # This code block calls the handler for all possible servers and
# all possible worlds. # all possible worlds.
@ -2764,7 +2823,7 @@ call_command() {
done done
# Call the function with the specific replaced args # Call the function with the specific replaced args
${COMMAND_HANDLER[$i]} "${replaced_args[@]}" ${COMMAND_HANDLER[$command]} "${replaced_args[@]}"
done done
# Prevent the default singular call later on. # Prevent the default singular call later on.
@ -2780,7 +2839,7 @@ call_command() {
replaced_args[$k]="${args[$k]//server\:all/$j}" replaced_args[$k]="${args[$k]//server\:all/$j}"
done done
${COMMAND_HANDLER[$i]} "${replaced_args[@]}" ${COMMAND_HANDLER[$command]} "${replaced_args[@]}"
done done
return return
@ -2795,14 +2854,14 @@ call_command() {
replaced_args[$k]="${args[$k]//world:all/$j}" replaced_args[$k]="${args[$k]//world:all/$j}"
done done
${COMMAND_HANDLER[$i]} "${replaced_args[@]}" ${COMMAND_HANDLER[$command]} "${replaced_args[@]}"
done done
return return
fi fi
# Otherwise it's a simple single call of the handler. # Otherwise it's a simple single call of the handler.
${COMMAND_HANDLER[$i]} "${args[@]}" ${COMMAND_HANDLER[$command]} "${args[@]}"
return return
fi fi
done done
@ -2846,9 +2905,9 @@ interrupt() {
# The main function which starts the script # The main function which starts the script
main() { main() {
# Initialises variables that represent system state # Loads MSM variables
init load_msm
# Trap interrupts to the script by calling the interrupt function # Trap interrupts to the script by calling the interrupt function
trap interrupt EXIT trap interrupt EXIT
@ -2887,17 +2946,17 @@ main() {
# Variables passed to handler functions are of course positional and there # Variables passed to handler functions are of course positional and there
# position matches the position of that element in the command signature. # position matches the position of that element in the command signature.
register_command "start" "command_start" register_command "start" "command_start" "<load_all_servers>"
register_command "stop" "command_stop" register_command "stop" "command_stop" "<load_all_servers>"
register_command "stop now" "command_stop_now" register_command "stop now" "command_stop_now" "<load_all_servers>"
register_command "restart" "command_restart" register_command "restart" "command_restart" "<load_all_servers>"
register_command "restart now" "command_restart_now" register_command "restart now" "command_restart_now" "<load_all_servers>"
register_command "version" "command_version" register_command "version" "command_version"
register_command "config" "command_config" register_command "config" "command_config"
register_command "server list" "command_server_list" register_command "server list" "command_server_list" "<load_all_servers>"
register_command "server create <name>" "command_server_create" register_command "server create <name>" "command_server_create"
register_command "server delete <name>" "command_server_delete" register_command "server delete <name>" "command_server_delete"
register_command "server rename <name> <name>" "command_server_rename" register_command "server rename <name> <name>" "command_server_rename" "<load_all_servers>"
register_command "jargroup list" "command_jargroup_list" register_command "jargroup list" "command_jargroup_list"
register_command "jargroup create <name> <string>" "command_jargroup_create" register_command "jargroup create <name> <string>" "command_jargroup_create"
register_command "jargroup delete <name>" "command_jargroup_delete" register_command "jargroup delete <name>" "command_jargroup_delete"
@ -2972,6 +3031,5 @@ else
# MSM was sourced from another script. # MSM was sourced from another script.
# Just load registered settings instead. # Just load registered settings instead.
register_settings load_msm
load_conf
fi fi