From 60a6af24c2086ba874907aca1bc137d0d1720ba9 Mon Sep 17 00:00:00 2001 From: Marcus Whybrow Date: Fri, 20 Jul 2012 02:41:37 +0100 Subject: [PATCH] Introduced lazy config loading. Faster in general. Instead of allocating all memory up front for every possible command option this new approach just expects certain variable names. If those variables are used in a function the manager_property, server_property or world_property command ensures that the variable has been loaded from config files. This approach uses sed to retrieve a single line from a config file when necessary, instead of reading every line at startup. --- init/msm | 934 +++++++++++++++++++++++++++++++++++++++---------------- test.sh | 6 +- 2 files changed, 674 insertions(+), 266 deletions(-) diff --git a/init/msm b/init/msm index bc95155..bb35342 100755 --- a/init/msm +++ b/init/msm @@ -168,6 +168,8 @@ quick_basename() { # distinguished from necessary echo statements. # $1: The message to output debug() { + manager_property DEBUG + if [[ "$SETTINGS_DEBUG" == "true" ]]; then echoerr "$1" fi @@ -237,11 +239,26 @@ log_line_get_time() { } + + + + + + + + ### World Utility Functions +### ----------------------- # Moves a world to RAM # $1: the ID of the world to move world_to_ram() { + manager_property RAMDISK_STORAGE_PATH + server_property "${WORLD_SERVER_ID[$1]}" USERNAME + world_property "$1" RAMDISK_PATH + world_property "$1" FLAG_INRAM + world_property "$1" PATH + if [ ! -z "$SETTINGS_RAMDISK_STORAGE_PATH" ]; then as_user "${SERVER_USERNAME[${WORLD_SERVER_ID[$1]}]}" "mkdir -p \"${WORLD_RAMDISK_PATH[$1]}\" && rsync -rt --exclude '$(basename "${WORLD_FLAG_INRAM[$1]}")' \"${WORLD_PATH[$1]}/\" \"${WORLD_RAMDISK_PATH[$1]}\"" fi @@ -250,23 +267,34 @@ world_to_ram() { # Moves a world in RAM to disk # $1: the ID of the world to move world_to_disk() { + server_property "{$WORLD_SERVER_ID[$1]}" USERNAME + world_property "$1" FLAG_INRAM + world_property "$1" RAMDISK_PATH + world_property "$1" PATH + as_user "${SERVER_USERNAME[${WORLD_SERVER_ID[$1]}]}" "rsync -rt --exclude '$(basename "${WORLD_FLAG_INRAM[$1]}")' \"${WORLD_RAMDISK_PATH[$1]}/\" \"${WORLD_PATH[$1]}\"" } # Toggles a worlds ramdisk state # $1: The ID of the world world_toggle_ramdisk_state() { + world_property "$1" FLAG_INRAM + world_property "$1" RAMDISK_PATH + local sid="${WORLD_SERVER_ID[$1]}" + server_property "$sid" USERNAME + + if [ -f "${WORLD_FLAG_INRAM[$1]}" ]; then echo -n "Removing RAM flag from world \"${WORLD_NAME[$1]}\"... " - as_user "${SERVER_USERNAME[${WORLD_SERVER_ID[$1]}]}" "rm -f \"${WORLD_FLAG_INRAM[$1]}\"" + as_user "${SERVER_USERNAME[$sid]}" "rm -f \"${WORLD_FLAG_INRAM[$1]}\"" echo "Done." echo -n "Removing world \"${WORLD_NAME[$1]}\" from RAM... " - as_user "${SERVER_USERNAME[${WORLD_SERVER_ID[$1]}]}" "rm -r \"${WORLD_RAMDISK_PATH[$1]}\"" + as_user "${SERVER_USERNAME[$sid]}" "rm -r \"${WORLD_RAMDISK_PATH[$1]}\"" echo "Done." else echo -n "Adding RAM flag to world \"${WORLD_NAME[$1]}\"... " - as_user "${SERVER_USERNAME[${WORLD_SERVER_ID[$1]}]}" "touch \"${WORLD_FLAG_INRAM[$1]}\"" + as_user "${SERVER_USERNAME[$sid]}" "touch \"${WORLD_FLAG_INRAM[$1]}\"" echo "Done." echo -n "Copying world to RAM... " @@ -279,6 +307,9 @@ world_toggle_ramdisk_state() { # Backs up a world # $1: The ID of the world world_backup() { + world_property "$1" PATH + world_property "$1" BACKUP_PATH + echo -n "Backing up world \"${WORLD_NAME[$1]}\"... " file_name="$(date "+%F-%H-%M-%S").zip" @@ -293,6 +324,9 @@ world_backup() { # Activates a world # $1: The ID of the world world_activate() { + world_property "$1" INACTIVE_PATH + world_property "$1" ACTIVE_PATH + 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]}" @@ -310,6 +344,10 @@ world_activate() { # Deactivates a world # $1: The ID of the world world_deactivate() { + world_property "$1" ACTIVE_PATH + world_property "$1" INACTIVE_PATH + world_property "$1" PATH + if server_is_running "${WORLD_SERVER_ID[$1]}"; then exit_error 68 "Worlds cannot be deactivated whilst the server is running." else @@ -328,7 +366,96 @@ world_deactivate() { fi } +# Get the value of a world property +# $1: The world ID +# $2: The property name +world_property() { + # Get the current value + eval local value=\"\${WORLD_$2[$1]}\" + + # If it is empty, then set it + if [ -z "$value" ]; then + local sid="${WORLD_SERVER_ID[$1]}" + case "$2" in + ACTIVE_PATH) + server_property "$sid" WORLD_STORAGE_PATH + WORLD_ACTIVE_PATH[$1]="${SERVER_WORLD_STORAGE_PATH[$sid]}/${WORLD_NAME[$1]}" + ;; + INACTIVE_PATH) + server_property "$sid" WORLD_STORAGE_INACTIVE_PATH + WORLD_INACTIVE_PATH[$1]="${SERVER_WORLD_STORAGE_INACTIVE_PATH[$sid]}/${WORLD_NAME[$1]}" + ;; + STATUS) + world_property "$1" ACTIVE_PATH + + if [ -d "${WORLD_ACTIVE_PATH[$1]}" ]; then + WORLD_STATUS[$1]="active" + else + world_property "$1" INACTIVE_PATH + if [ -d "${WORLD_INACTIVE_PATH[$1]}" ]; then + WORLD_STATUS[$1]="inactive" + else + WORLD_STATUS[$1]="unknown" + fi + fi + ;; + PATH) + world_property "$1" STATUS + world_property "$1" WORLD_ACTIVE_PATH + world_property "$1" WORLD_INACTIVE_PATH + + case "${WORLD_STATUS[$1]}" in + active) WORLD_PATH[$1]="${WORLD_ACTIVE_PATH[$1]}";; + inactive) WORLD_PATH[$1]="${WORLD_INACTIVE_PATH[$1]}";; + *) error_exit NAME_NOT_FOUND "World cannot be found in either \"${WORLD_ACTIVE_PATH[$1]}\" or \"${WORLD_INACTIVE_PATH[$1]}\"." + esac + ;; + FLAG_INRAM) + world_property "$1" PATH + server_property "$sid" WORLD_FLAG_INRAM + WORLD_FLAG_INRAM[$1]="${WORLD_PATH[$1]}/${SERVER_WORLD_FLAG_INRAM[$sid]}" + ;; + LINK) + server_property "$sid" PATH + WORLD_LINK[$1]="${SERVER_PATH[$sid]}/${WORLD_NAME[$1]}" + ;; + BACKUP_PATH) + manager_property WORLD_ARCHIVE_PATH + WORLD_BACKUP_PATH[$1]="$SETTINGS_WORLD_ARCHIVE_PATH/${SERVER_NAME[$sid]}/${WORLD_NAME[$1]}" + ;; + RAMDISK_PATH) + manager_property RAMDISK_STORAGE_PATH + # If the ramdisk path is set, get the path for this world + if [ ! -z "$SETTINGS_RAMDISK_STORAGE_PATH" ]; then + WORLD_RAMDISK_PATH[$2]="${SETTINGS_RAMDISK_STORAGE_PATH}/${SERVER_NAME[$sid]}/${WORLD_NAME[$1]}" + fi + ;; + INRAM) + world_property "$1" FLAG_INRAM + # Detect whether this world should be in ram + if [[ -e "${WORLD_FLAG_INRAM[$1]}" ]]; then + WORLD_INRAM[$1]="true" + else + WORLD_INRAM[$1]="false" + fi + ;; + esac + fi + + eval debug \"world_property\($1, $2\) \: \${WORLD_$2[$1]}\" +} + + + + + + + + + + ### Server Utility Functions +### ------------------------ # Returns the ID for a server. # An ID is given to a server when loaded into memory, and can be used to lookup @@ -350,6 +477,9 @@ server_get_id() { # $1: The ID of the server # $2: The name of the world server_world_get_id() { + server_property "$1" WORLD_STORAGE_PATH + server_property "$1" WORLD_STORAGE_INACTIVE_PATH + unset RETURN if [ -d "${SERVER_WORLD_STORAGE_PATH[$1]}/$2" ] || [ -d "${SERVER_WORLD_STORAGE_INACTIVE_PATH[$1]}/$2" ]; then # If the directory exists @@ -372,6 +502,9 @@ server_world_get_id() { # Returns 0 if the server $1 is running and 1 if not # $1: The ID of the server server_is_running() { + server_property "$1" SCREEN_NAME + server_property "$1" INVOCATION + if ps ax | grep -v grep | grep "${SERVER_SCREEN_NAME[$1]} ${SERVER_INVOCATION[$1]}" > /dev/null then return 0 @@ -383,6 +516,8 @@ server_is_running() { # Ensures the server has a jar file where it is expected to be # $1: The id of the server server_ensure_jar() { + server_property "$1" JAR_PATH + if [ -f "${SERVER_JAR_PATH[$1]}" ]; then return 0 fi @@ -394,17 +529,24 @@ server_ensure_jar() { # of the Minecraft worlds located in the world storage directory. # $1: The id of the server for which links should be ensured server_ensure_links() { + server_property "$1" USERNAME + echo -n "Maintaining world symbolic links... " local start="${SERVER_WORLD_OFFSET[$1]}" local max="$(( $start + ${SERVER_NUM_WORLDS[$1]} ))" local output="false" for ((i=$start; i<$max; i++)); do + world_property "$i" STATUS + world_property "$i" LINK + if [[ "${WORLD_STATUS[$i]}" != "active" ]]; then # Remove the symbolic link if it exists as_user "${SERVER_USERNAME[$1]}" "rm -f \"${WORLD_LINK[$i]}\"" continue fi + + world_property "$i" INRAM # -L checks for the path being a link rather than a file # ! -a, since it is within double square brackets means: the negation of @@ -420,6 +562,8 @@ server_ensure_links() { if "${WORLD_INRAM[$i]}"; then # If this world is marked as loaded into RAM + world_property "$i" RAMDISK_PATH + if [ "${link_target}" != "${WORLD_RAMDISK_PATH[$i]}" ]; then # If the symbolic link does not point to the RAM version of the world @@ -432,6 +576,8 @@ server_ensure_links() { else # Otherwise the world is not loaded into RAM, and is just on disk + world_property "$i" PATH + if [ "${link_target}" != "${WORLD_PATH[$i]}" ]; then # If the symbolic link does not point to the disk version of the world @@ -458,6 +604,8 @@ server_ensure_links() { # Moves a servers worlds into RAM # $1: The ID of the server server_worlds_to_ram() { + manager_property RAMDISK_STORAGE_PATH + # Only proceed if there is a ramdisk path set in config if [ ! -z "$SETTINGS_RAMDISK_STORAGE_PATH" ]; then echo -n "Synchronising flagged worlds on disk to RAM... " @@ -466,6 +614,9 @@ server_worlds_to_ram() { # For each of the servers worlds: while [[ "$i" -lt "$max" ]]; do + world_property "$i" INRAM + world_property "$i" LINK + if "${WORLD_INRAM[$i]}" && [ -L "${WORLD_LINK[$i]}" ]; then world_to_ram "$i" fi @@ -479,6 +630,8 @@ server_worlds_to_ram() { # Moves a servers "in RAM" worlds back to disk # $1: The ID of the server server_worlds_to_disk() { + manager_property RAMDISK_STORAGE_PATH + if [ ! -z "$SETTINGS_RAMDISK_STORAGE_PATH" ]; then echo -n "Synchronising worlds in RAM to disk... " local i="${SERVER_WORLD_OFFSET[$1]}" @@ -486,6 +639,7 @@ server_worlds_to_disk() { # For each of the servers worlds: while [[ "$i" -lt "$max" ]]; do + world_property "$i" RAMDISK_PATH if [ -d "${WORLD_RAMDISK_PATH[$i]}" ]; then world_to_disk "$i" fi @@ -502,6 +656,9 @@ server_worlds_to_disk() { # $3->: The line or lines in the log to wait for # returns: When the line is found server_log_get_line() { + server_property "$1" USERNAME + server_property "$1" LOG_PATH + unset RETURN # Make sure there is a server log to check as_user "${SERVER_USERNAME[$1]}" "touch ${SERVER_LOG_PATH[$1]}" @@ -530,6 +687,9 @@ server_log_get_line() { # $3->: The line or lines in the log to wait for # returns: When the line is found server_log_dots_for_lines() { + server_property "$1" USERNAME + server_property "$1" LOG_PATH + # Make sure there is a server log to check as_user "${SERVER_USERNAME[$1]}" "touch ${SERVER_LOG_PATH[$1]}" @@ -558,6 +718,9 @@ server_log_dots_for_lines() { # $1: The ID of the server # $2: The line of text to enter into the server console server_eval() { + server_property "$1" USERNAME + server_property "$1" SCREEN_NAME + as_user "${SERVER_USERNAME[$1]}" "screen -p 0 -S ${SERVER_SCREEN_NAME[$1]} -X eval 'stuff \"$2\"\015'" } @@ -585,6 +748,9 @@ server_eval_and_wait() { # Gets the process ID for a server if running, otherwise it outputs nothing # $1: The ID of the server server_pid() { + server_property "$1" SCREEN_NAME + server_property "$1" INVOCATION + ps ax | grep -v grep | grep "${SERVER_SCREEN_NAME[$1]} ${SERVER_INVOCATION[$1]}" | awk '{print $1}' } @@ -607,6 +773,9 @@ server_wait_for_stop() { # $1: The ID of the server # $2: A string containing "active" or "inactive" server_set_active() { + server_property "$1" USERNAME + server_property "$1" FLAG_ACTIVE_PATH + case "$2" in active) as_user "${SERVER_USERNAME[$1]}" "touch \"${SERVER_FLAG_ACTIVE_PATH[$1]}\"" @@ -636,6 +805,8 @@ server_set_active() { # Lists the jar files grouped by jar groups. jargroup_list() { + manager_property JAR_STORAGE_PATH + if [[ -d "${SETTINGS_JAR_STORAGE_PATH}" ]]; then local jargroup_name local jar_name @@ -657,6 +828,10 @@ jargroup_list() { # $1: The name for the jargroup jargroup_create() { if is_valid_name "$1"; then + manager_property JAR_STORAGE_PATH + manager_property USERNAME + manager_property JARGROUP_TARGET + if [[ ! -d "$SETTINGS_JAR_STORAGE_PATH/$1" ]]; then printf "Creating jar group... " @@ -686,6 +861,11 @@ jargroup_create() { # $1: The jargroup name to download the latest version for jargroup_getlatest() { if is_valid_name "$1"; then + manager_property JAR_STORAGE_PATH + manager_property JARGROUP_TARGET + manager_property USERNAME + manager_property JARGROUP_DOWNLOAD_DIR + if [[ -d "$SETTINGS_JAR_STORAGE_PATH/$1" ]]; then if [[ -f "$SETTINGS_JAR_STORAGE_PATH/$1/$SETTINGS_JARGROUP_TARGET" ]]; then printf "Downloading latest version... " @@ -754,6 +934,9 @@ jargroup_getlatest() { # $1: The name of the existing jargroup jargroup_delete() { if is_valid_name "$1"; then + manager_property JAR_STORAGE_PATH + manager_property USERNAME + if [[ -d "$SETTINGS_JAR_STORAGE_PATH/$1" ]]; then printf "Are you sure you want to delete this jar group [y/N]: " @@ -775,6 +958,9 @@ jargroup_delete() { # $2: The new name jargroup_rename() { if is_valid_name "$1"; then + manager_property JAR_STORAGE_PATH + manager_property USERNAME + if [[ -d "$SETTINGS_JAR_STORAGE_PATH/$1" ]]; then # If the jar group name is valid, # and there is no other jar group with the name $1 @@ -810,6 +996,8 @@ jargroup_rename() { server_list() { if [ "$NUM_SERVERS" -gt 0 ]; then for ((server=0; server<$NUM_SERVERS; server++)); do + server_property "$server" ACTIVE + if "${SERVER_ACTIVE[$server]}"; then echo -n "[ ACTIVE ] " else @@ -842,6 +1030,16 @@ server_list() { # $1: The server name to create server_create() { if is_valid_name "$1"; then + manager_property USERNAME + manager_property SERVER_STORAGE_PATH + manager_property DEFAULT_WHITELIST_PATH + manager_property DEFAULT_BANNED_IPS_PATH + manager_property DEFAULT_BANNED_PLAYERS_PATH + manager_property DEFAULT_OPS_PATH + manager_property SERVER_PROPERTIES + manager_property DEFAULT_WORLD_STORAGE_PATH + manager_property JAR_STORAGE_PATH + if [[ -d "$SETTINGS_SERVER_STORAGE_PATH/$1" ]]; then error_exit DUPLICATE_NAME "A server with that name already exists." else @@ -855,10 +1053,14 @@ server_create() { as_user "$SETTINGS_USERNAME" "mkdir -p '$SETTINGS_SERVER_STORAGE_PATH/$1/$SETTINGS_DEFAULT_WORLD_STORAGE_PATH'" 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." - - # Now that the new server has been created, we must call load_all again - # to ensure it is recognised. - load_all + + # Creates a server stub in memory, enough to use server_properties for. + SERVER_NAME[$NUM_SERVERS]="$1" + SERVER_PATH[$NUM_SERVERS]="$SETTINGS_SERVER_STORAGE_PATH/$1" + SERVER_CONF[$NUM_SERVERS]="$SETTINGS_SERVER_STORAGE_PATH/$1/$SETTINGS_SERVER_PROPERTIES" + NUM_SERVERS=$(($NUM_SERVERS+1)) + + # TODO: Dirty all server varibales, or don't allow further in script access # TODO: Handle server default setup stuff better than just using # the "minecraft" jar group. And make it configurable. @@ -874,6 +1076,9 @@ server_create() { # $1: The server name to delete server_delete() { if is_valid_name "$1"; then + manager_property SERVER_STORAGE_PATH + manager_property USERNAME + if [[ -d "$SETTINGS_SERVER_STORAGE_PATH/$1" ]]; then printf "Are you sure you want to delete this server and its worlds (note: backups are preserved) [y/N]: " @@ -896,6 +1101,9 @@ server_delete() { # $2: The new name for the server server_rename() { if is_valid_name "$1"; then + manager_property SERVER_STORAGE_PATH + manager_property USERNAME + if [ -d "$SETTINGS_SERVER_STORAGE_PATH/$1" ]; then # If the server name is valid and exists @@ -925,6 +1133,11 @@ server_rename() { # Starts a single server # $1: The ID of the server server_start() { + server_property "$1" USERNAME + server_property "$1" SCREEN_NAME + server_property "$1" INVOCATION + server_property "$1" CONFIRM_START + if server_is_running "$1"; then echo "Server \"${SERVER_NAME[$1]}\" is already running!" else @@ -945,6 +1158,8 @@ server_start() { # Sends the "save-all" command to a server # $1: The ID of the server server_save_all() { + server_property "$1" CONFIRM_SAVE_ALL + if server_is_running "$1"; then echo -n "Forcing save... " @@ -960,6 +1175,8 @@ server_save_all() { # Sends the "save-off" command to a server # $1: The ID of the server server_save_off() { + server_property "$1" CONFIRM_SAVE_OFF + if server_is_running "$1"; then echo -n "Disabling level saving... " @@ -978,6 +1195,8 @@ server_save_off() { # Sends the "save-on" command to a server # $1: The ID of the server server_save_on() { + server_property "$1" CONFIRM_SAVE_ON + if server_is_running "$1"; then echo -n "Enabling level saving... " @@ -993,6 +1212,9 @@ server_save_on() { # Stops a single server after a delay # $1: The ID of the server server_stop() { + server_property "$1" MESSAGE_STOP + server_property "$1" STOP_DELAY + if server_is_running "$1"; then # Change the state of the script STOP_COUNTDOWN[$1]="true" @@ -1043,6 +1265,9 @@ server_stop_now() { # Restarts a single server after a delay # $1: The ID of the server server_restart() { + server_property "$1" MESSAGE_RESTART + server_property "$1" RESTART_DELAY + # Restarts the server if it is already running if server_is_running "$1"; then # Change the state of the script @@ -1053,7 +1278,7 @@ server_restart() { echo -n "Restarting... " - for ((i="${SERVER_STOP_DELAY[$1]}"; i>0; i--)); do + for ((i="${SERVER_RESTART_DELAY[$1]}"; i>0; i--)); do tput sc # Save cursor position echo -n "in $i seconds." sleep 1 @@ -1089,6 +1314,7 @@ server_worlds_list() { # For each of the servers worlds: while [[ "$i" -lt "$max" ]]; do + world_property "$i" INRAM if "${WORLD_INRAM[$i]}"; then echo "[RAM] ${WORLD_NAME[$i]}" else @@ -1107,6 +1333,7 @@ server_worlds_backup() { # For each of the servers worlds: while [[ "$i" -lt "$max" ]]; do + world_property "$i" STATUS if [[ "${WORLD_STATUS[$i]}" == "active" ]]; then world_backup "$i" fi @@ -1117,6 +1344,10 @@ server_worlds_backup() { # Moves a servers log into another file, leaving the original log file empty # $1: The ID of the server server_log_roll() { + server_property "$1" LOG_PATH + server_property "$1" USERNAME + server_property "$1" LOG_ARCHIVE_PATH + # Moves and Gzips the logfile, a big log file slows down the # server A LOT (what was notch thinking?) @@ -1141,6 +1372,10 @@ server_log_roll() { # Backups a server's directory # $1: The ID of the server server_backup() { + manager_property SERVER_STORAGE_PATH + server_property "$1" COMPLETE_BACKUP_FOLLOW_SYMLINKS + server_property "$1" BACKUP_PATH + echo -n "Backing up the entire server directory... " zip_flags="-rq" @@ -1161,6 +1396,9 @@ server_backup() { # $2: The name of the jar group # $3: Optionally, a specific jar to use. server_set_jar() { + manager_property JAR_STORAGE_PATH + server_property "$1" JAR_PATH + if [ -d "$SETTINGS_JAR_STORAGE_PATH/$2" ]; then if [ -z "$3" ]; then @@ -1208,11 +1446,102 @@ server_connected() { fi } +# Sets the valud of a server property +# $1: The ID of the server +# $2: The name of the server property +# $3: The value for the property +server_set_property() { + eval SERVER_$2[$1]=\"$3\" +} + # Get the value of a server property # $1: The ID of the server # $2: The name of the server property server_property() { - eval echo "\${SERVER_$2[$1]}" + eval local value=\"\${SERVER_$2[$1]}\" + if [ -z "$value" ]; then + # If the value is empty it has not been loaded yet + + # These properties are not overridable + case "$2" in + NAME) + # Name is already set + return 0 + ;; + PATH) + manager_property SERVER_STORAGE_PATH + server_set_property "$1" "$2" "$SETTINGS_SERVER_STORAGE_PATH/${SERVER_NAME[$1]}" + return 0 + ;; + BACKUP_PATH) + manager_property BACKUP_ARCHIVE_PATH + server_set_property "$1" "$2" "$SETTINGS_BACKUP_ARCHIVE_PATH/${SERVER_NAME[$1]}" + return 0 + ;; + LOG_ARCHIVE_PATH) + manager_property LOG_ARCHIVE_PATH + server_set_property "$1" "$2" "$SETTINGS_LOG_ARCHIVE_PATH/${SERVER_NAME[$1]}" + return 0 + ;; + ACTIVE) + server_property "$1" FLAG_ACTIVE_PATH + if [[ -e "${SERVER_FLAG_ACTIVE_PATH[$1]}" ]]; then + server_set_property "$1" "$2" "true" + else + server_set_property "$1" "$2" "false" + fi + return 0 + ;; + esac + + # If not a non-overridable load from conf + to_properties_name "$2" + local name="$RETURN" + + if [[ ! "$2" =~ ^PROPERTIES_ ]]; then + name="msm-$name" + fi + + local from_conf="$(sed -rn "s/^$name=('|\"|)(.*)\1/\2/ip" "${SERVER_CONF[$1]}" | tail -n 1)" + + if [ ! -z "$from_conf" ]; then + # If the value is found in the server conf file (server.properties) + # then set that as value for the property + eval SERVER_$2[$1]=\"$from_conf\" + else + # Otherwise use the default value + manager_property "DEFAULT_$2" + eval SERVER_$2[$1]=\"\$SETTINGS_DEFAULT_$2\" + fi + + ### Post-changes to varibales after loading + + # If it is a path + if [[ "$2" =~ _PATH$ ]]; then + server_property "$1" PATH + eval SERVER_$2[$1]=\"${SERVER_PATH[$1]}/\${SERVER_$2[$1]}\" + fi + + case "$2" in + SCREEN_NAME) + server_set_property "$1" "$2" "${SERVER_SCREEN_NAME[$1]//\{SERVER_NAME\}/${SERVER_NAME[$1]}}" + ;; + MESSAGE_STOP) + server_property "$1" STOP_DELAY + server_set_property "$1" "$2" "${SERVER_MESSAGE_STOP[$1]//\{DELAY\}/${SERVER_STOP_DELAY[$1]}}" + ;; + MESSAGE_RESTART) + server_property "$1" RESTART_DELAY + server_set_property "$1" "$2" "${SERVER_MESSAGE_RESTART[$1]//\{DELAY\}/${SERVER_RESTART_DELAY[$1]}}" + ;; + INVOCATION) + server_property "$1" RAM + server_property "$1" JAR_PATH + server_set_property "$1" "$2" "${SERVER_INVOCATION[$1]//\{RAM\}/${SERVER_RAM[$1]}}" + server_set_property "$1" "$2" "${SERVER_INVOCATION[$1]//\{JAR\}/${SERVER_JAR_PATH[$1]}}" + ;; + esac + fi } @@ -1360,8 +1689,19 @@ manager_stop_all_servers_now() { # Get the value of a global manager property # $1: The name of the property manager_property() { - unset RETURN - eval RETURN=\"\$SETTINGS_$1\" + local from_conf="$(sed -rn "s/^$1=('|\"|)(.*)\1/\2/ip" "$CONF" | tail -n 1)" + + # If this property has not yet been loaded, load it: + eval local loaded=\"\$LOADED_$1\" + if ! "$loaded"; then + if [ ! -z "$from_conf" ]; then + # Override the default value + eval SETTINGS_$1=\"$from_conf\" + fi + + # State that this property has now been loaded + eval LOADED_$1=\"true\" + fi } @@ -1442,7 +1782,9 @@ command_version() { command_config() { for ((i=0; i<$SETTING_COUNT; i++)); do manager_property "${SETTING_NAME[$i]}" - echo "${SETTING_NAME[$i]}=\"$RETURN\"" + echo -n "${SETTING_NAME[$i]}=\"" + eval echo -n \"\$SETTINGS_${SETTING_NAME[$i]}\" + echo '"' done } @@ -2241,8 +2583,10 @@ command_server_config() { if [ -z "$2" ]; then # List all parameters for ((i=0; i<$SERVER_SETTING_COUNT; i++)); do + server_property "$1" "${SERVER_SETTING_NAME[$i]}" + to_properties_name "${SERVER_SETTING_NAME[$i]}" - echo "msm-$RETURN=\"$(server_property "$1" "${SERVER_SETTING_NAME[$i]}")\"" + eval echo "msm-$RETURN=\\\"\${SERVER_${SERVER_SETTING_NAME[$i]}[$1]}\\\"" done fi } @@ -2263,226 +2607,300 @@ command_server_config() { # $1: The server id # $2: The world id to use # $3: The name of the world -load_server_world() { - WORLD_SERVER_ID[$2]="$1" - WORLD_NAME[$2]="$3" - WORLD_ACTIVE_PATH[$2]="${SERVER_WORLD_STORAGE_PATH[$1]}/${WORLD_NAME[$2]}" - WORLD_INACTIVE_PATH[$2]="${SERVER_WORLD_STORAGE_INACTIVE_PATH[$1]}/${WORLD_NAME[$2]}" +# load_server_world() { +# manager_property WORLD_ARCHIVE_PATH +# manager_property RAMDISK_STORAGE_PATH + +# WORLD_SERVER_ID[$2]="$1" +# WORLD_NAME[$2]="$3" +# WORLD_ACTIVE_PATH[$2]="${SERVER_WORLD_STORAGE_PATH[$1]}/${WORLD_NAME[$2]}" +# WORLD_INACTIVE_PATH[$2]="${SERVER_WORLD_STORAGE_INACTIVE_PATH[$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" +# # 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" - error_exit NAME_NOT_FOUND "World cannot be found in either \"${WORLD_ACTIVE_PATH[$2]}\" or \"${WORLD_INACTIVE_PATH[$2]}\"." - fi - fi +# error_exit NAME_NOT_FOUND "World cannot be found in either \"${WORLD_ACTIVE_PATH[$2]}\" or \"${WORLD_INACTIVE_PATH[$2]}\"." +# fi +# fi - # TODO: Allow the inram flag location to be overridable. - WORLD_FLAG_INRAM[$2]="${WORLD_PATH[$2]}/inram" - WORLD_LINK[$2]="${SERVER_PATH[$1]}/${WORLD_NAME[$2]}" - WORLD_BACKUP_PATH[$2]="$SETTINGS_WORLD_ARCHIVE_PATH/${SERVER_NAME[$1]}/${WORLD_NAME[$2]}" +# # TODO: Allow the inram flag location to be overridable. +# WORLD_FLAG_INRAM[$2]="${WORLD_PATH[$2]}/inram" +# WORLD_LINK[$2]="${SERVER_PATH[$1]}/${WORLD_NAME[$2]}" +# WORLD_BACKUP_PATH[$2]="$SETTINGS_WORLD_ARCHIVE_PATH/${SERVER_NAME[$1]}/${WORLD_NAME[$2]}" - # If the ramdisk path is set, get the path for this world - if [ ! -z "$SETTINGS_RAMDISK_STORAGE_PATH" ]; then - WORLD_RAMDISK_PATH[$2]="${SETTINGS_RAMDISK_STORAGE_PATH}/${SERVER_NAME[$1]}/${WORLD_NAME[$2]}" - fi +# # If the ramdisk path is set, get the path for this world +# if [ ! -z "$SETTINGS_RAMDISK_STORAGE_PATH" ]; then +# WORLD_RAMDISK_PATH[$2]="${SETTINGS_RAMDISK_STORAGE_PATH}/${SERVER_NAME[$1]}/${WORLD_NAME[$2]}" +# fi - # Detect whether this world should be in ram - if [[ -e "${WORLD_FLAG_INRAM[$2]}" ]]; then - WORLD_INRAM[$2]="true" - else - WORLD_INRAM[$2]="false" - fi -} +# # Detect whether this world should be in ram +# if [[ -e "${WORLD_FLAG_INRAM[$2]}" ]]; then +# WORLD_INRAM[$2]="true" +# else +# WORLD_INRAM[$2]="false" +# fi +# } -# Load the server.properties file for a server -# $1: The id of the server to load -load_server_properties() { - local name value name_prefix +# # Load the server.properties file for a server +# # $1: The id of the server to load +# load_server_properties() { +# manager_property SERVER_PROPERTIES + +# local name value name_prefix - if [[ -f "${SERVER_PATH[$1]}/$SETTINGS_SERVER_PROPERTIES" ]]; then - while read line; do - # if not empty, get the name and value of the setting - if [[ "$line" =~ ^(msm\-)?([\-\_a-zA-Z0-9]+)\=(\"(.*)\"|\'(.*)\'|(.*)$) ]]; then - msm_prefix="${BASH_REMATCH[1]}" - name="${BASH_REMATCH[2]}" - # Only one of 3,4 or 5 will match: - value="${BASH_REMATCH[4]}${BASH_REMATCH[5]}${BASH_REMATCH[6]}" +# if [[ -f "${SERVER_PATH[$1]}/$SETTINGS_SERVER_PROPERTIES" ]]; then +# while read line; do +# # if not empty, get the name and value of the setting +# if [[ "$line" =~ ^(msm\-)?([\-\_a-zA-Z0-9]+)\=(\"(.*)\"|\'(.*)\'|(.*)$) ]]; then +# msm_prefix="${BASH_REMATCH[1]}" +# name="${BASH_REMATCH[2]}" +# # Only one of 3,4 or 5 will match: +# value="${BASH_REMATCH[4]}${BASH_REMATCH[5]}${BASH_REMATCH[6]}" - to_global_name "$name" - name="$RETURN" +# to_global_name "$name" +# name="$RETURN" - # Create variables - if [ ! -z "$msm_prefix" ]; then - # Make relative paths absolute to server directory - if [[ "$name" =~ \_PATH$ ]] && [ "${value:0:1}" != '/' ]; then - value="${SERVER_PATH[$1]}/$value" - fi +# # Create variables +# if [ ! -z "$msm_prefix" ]; then +# # Make relative paths absolute to server directory +# if [[ "$name" =~ \_PATH$ ]] && [ "${value:0:1}" != '/' ]; then +# value="${SERVER_PATH[$1]}/$value" +# fi - name_prefix="SERVER_" - else - name_prefix="SERVER_PROPERTIES_" - fi +# name_prefix="SERVER_" +# else +# name_prefix="SERVER_PROPERTIES_" +# fi - # Create the variable - eval ${name_prefix}${name}[$1]=\"$value\" - fi - done < "${SERVER_PATH[$1]}/$SETTINGS_SERVER_PROPERTIES" - fi -} +# # Create the variable +# eval ${name_prefix}${name}[$1]=\"$value\" +# fi +# done < "${SERVER_PATH[$1]}/$SETTINGS_SERVER_PROPERTIES" +# fi +# } # Load a server's variables # $1: The id of the server to load -load_server() { - # Non-configurable Variables - SERVER_PATH[$1]="$SETTINGS_SERVER_STORAGE_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]}" +# load_server() { + # manager_property SERVER_STORAGE_PATH + # manager_property BACKUP_ARCHIVE_PATH + # manager_property LOG_ARCHIVE_PATH + + # # Non-configurable Variables + # SERVER_PATH[$1]="$SETTINGS_SERVER_STORAGE_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]}" - # Setup default values for this server's variables using default settings - # from /etc/msm.conf - local name value + # # Setup default values for this server's variables using default settings + # # from /etc/msm.conf + # local name value - # Make a server version of all default server settings - for ((server_setting=0; server_setting<$SERVER_SETTING_COUNT; server_setting++)); do - name="${SERVER_SETTING_NAME[$server_setting]}" - eval value=\"\$SETTINGS_DEFAULT_${name}\" + # # Make a server version of all default server settings + # for ((server_setting=0; server_setting<$SERVER_SETTING_COUNT; server_setting++)); do + # name="${SERVER_SETTING_NAME[$server_setting]}" + # eval value=\"\$SETTINGS_DEFAULT_${name}\" - # Make relative paths absolute, assuming the server directory - # as the current directory. - if [[ "$name" =~ _PATH$ ]] && [[ ! "$value" =~ ^\/ ]]; then - value="${SERVER_PATH[$1]}/$value" - fi + # # Make relative paths absolute, assuming the server directory + # # as the current directory. + # if [[ "$name" =~ _PATH$ ]] && [[ ! "$value" =~ ^\/ ]]; then + # value="${SERVER_PATH[$1]}/$value" + # fi - eval SERVER_${name}[$1]=\"${value}\" - done + # eval SERVER_${name}[$1]=\"${value}\" + # done - if [[ -e "${SERVER_FLAG_ACTIVE_PATH[$1]}" ]]; then - SERVER_ACTIVE[$1]="true" - else - SERVER_ACTIVE[$1]="false" - fi + # if [[ -e "${SERVER_FLAG_ACTIVE_PATH[$1]}" ]]; then + # SERVER_ACTIVE[$1]="true" + # else + # SERVER_ACTIVE[$1]="false" + # fi - # Load setting overrides from server.properties - load_server_properties "$1" + # # Load setting overrides from server.properties + # load_server_properties "$1" - # 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 + # # 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 - # Replace tags in delay messages - SERVER_MESSAGE_STOP[$1]="${SERVER_MESSAGE_STOP[$1]//\{DELAY\}/${SERVER_STOP_DELAY[$1]}}" - SERVER_MESSAGE_RESTART[$1]="${SERVER_MESSAGE_RESTART[$1]//\{DELAY\}/${SERVER_RESTART_DELAY[$1]}}" + # # Replace tags in delay messages + # SERVER_MESSAGE_STOP[$1]="${SERVER_MESSAGE_STOP[$1]//\{DELAY\}/${SERVER_STOP_DELAY[$1]}}" + # SERVER_MESSAGE_RESTART[$1]="${SERVER_MESSAGE_RESTART[$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_PATH[$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_PATH[$1]}}" # Load worlds if there is a world storage directory present - SERVER_WORLD_OFFSET[$1]=0 - SERVER_NUM_WORLDS[$1]=0 +# 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 id="$NUM_WORLDS" +# # Start world id's for this server's worlds at the end of the array +# local id="$NUM_WORLDS" - # Record the index at which worlds for this server start - SERVER_WORLD_OFFSET[$1]="$id" +# # Record the index at which worlds for this server start +# SERVER_WORLD_OFFSET[$1]="$id" - if [[ -d "${SERVER_WORLD_STORAGE_PATH[$1]}" ]]; then - # Load active worlds - while IFS= read -r -d $'\0' path; do - local name="$(basename "$path")" - load_server_world "$1" "$id" "$name" +# if [[ -d "${SERVER_WORLD_STORAGE_PATH[$1]}" ]]; then +# # Load active worlds +# while IFS= read -r -d $'\0' path; do +# local name="$(basename "$path")" +# load_server_world "$1" "$id" "$name" - # Build the server_worlds comma separated list - if [[ "$id" == "${SERVER_WORLD_OFFSET[$1]}" ]]; then - SERVER_WORLDS[$1]="$name" - else - SERVER_WORLDS[$1]="${SERVER_WORLDS[$1]}, $name" - fi +# # Build the server_worlds comma separated list +# if [[ "$id" == "${SERVER_WORLD_OFFSET[$1]}" ]]; then +# SERVER_WORLDS[$1]="$name" +# else +# SERVER_WORLDS[$1]="${SERVER_WORLDS[$1]}, $name" +# fi - id="$(($id+1))" - NUM_WORLDS="$id" - done < <(find "${SERVER_WORLD_STORAGE_PATH[$1]}" -mindepth 1 -maxdepth 1 -type d -print0) - fi +# id="$(($id+1))" +# NUM_WORLDS="$id" +# done < <(find "${SERVER_WORLD_STORAGE_PATH[$1]}" -mindepth 1 -maxdepth 1 -type d -print0) +# fi - if [[ -d "${SERVER_WORLD_STORAGE_INACTIVE_PATH[$1]}" ]]; then - # Load inactive worlds - while IFS= read -r -d $'\0' path; do - local name="$(basename "$path")" - load_server_world "$1" "$id" "$name" +# if [[ -d "${SERVER_WORLD_STORAGE_INACTIVE_PATH[$1]}" ]]; then +# # Load inactive worlds +# while IFS= read -r -d $'\0' path; do +# local name="$(basename "$path")" +# load_server_world "$1" "$id" "$name" - # Build the server_worlds_inactive comma separated list - if [[ "$id" == "${SERVER_WORLD_OFFSET[$1]}" ]]; then - SERVER_WORLDS[$1]="$name" - else - SERVER_WORLDS[$1]="${SERVER_WORLDS[$1]}, $name" - fi +# # Build the server_worlds_inactive comma separated list +# if [[ "$id" == "${SERVER_WORLD_OFFSET[$1]}" ]]; then +# SERVER_WORLDS[$1]="$name" +# else +# SERVER_WORLDS[$1]="${SERVER_WORLDS[$1]}, $name" +# fi - id="$(($id+1))" - NUM_WORLDS="$id" - done < <(find "${SERVER_WORLD_STORAGE_INACTIVE_PATH[$1]}" -mindepth 1 -maxdepth 1 -type d -print0) - fi +# id="$(($id+1))" +# NUM_WORLDS="$id" +# done < <(find "${SERVER_WORLD_STORAGE_INACTIVE_PATH[$1]}" -mindepth 1 -maxdepth 1 -type d -print0) +# fi - # Record the number of worlds this server has - SERVER_NUM_WORLDS[$1]="$(( $id - ${SERVER_WORLD_OFFSET[$1]} ))" -} +# # Record the number of worlds this server has +# SERVER_NUM_WORLDS[$1]="$(( $id - ${SERVER_WORLD_OFFSET[$1]} ))" +# } -# Load settings for MSM -load_msm() { - register_settings +# # Load settings for MSM +# load_msm() { +# manager_property SERVER_STORAGE_PATH - # Override settings with values from /etc/msm.conf - if [[ -f "$CONF" ]]; then - while read line; do - # Get the name and value of the setting - if [[ "$line" =~ ^([\-\_a-zA-Z0-9]+)\=(\"(.*)\"|\'(.*)\'|(.*)$) ]]; then - name="${BASH_REMATCH[1]}" - # Only one of 3,4 or 5 will match: - value="${BASH_REMATCH[3]}${BASH_REMATCH[4]}${BASH_REMATCH[5]}" +# register_settings - to_global_name "$name" - name="$RETURN" +# # Override settings with values from /etc/msm.conf +# if [[ -f "$CONF" ]]; then +# while read line; do +# # Get the name and value of the setting +# if [[ "$line" =~ ^([\-\_a-zA-Z0-9]+)\=(\"(.*)\"|\'(.*)\'|(.*)$) ]]; then +# name="${BASH_REMATCH[1]}" +# # Only one of 3,4 or 5 will match: +# value="${BASH_REMATCH[3]}${BASH_REMATCH[4]}${BASH_REMATCH[5]}" - # Create variables in uppercase - eval SETTINGS_${name}=\"$value\" - fi - done < "$CONF" - fi +# to_global_name "$name" +# name="$RETURN" + +# # Create variables in uppercase +# eval SETTINGS_${name}=\"$value\" +# fi +# done < "$CONF" +# fi + +# # Dermine server names (but don't load them) +# if [ -d "$SETTINGS_SERVER_STORAGE_PATH" ]; then +# local id=0 +# while IFS= read -r -d $'\0' path; do +# quick_basename "$path" +# SERVER_NAME[$id]="$RETURN" +# id="$(($id+1))" +# done < <(find "$SETTINGS_SERVER_STORAGE_PATH" -mindepth 1 -maxdepth 1 -type d -print0) +# NUM_SERVERS="$id" +# 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 +# } + +allocate() { + manager_property SERVER_STORAGE_PATH + manager_property SERVER_PROPERTIES # Dermine server names (but don't load them) if [ -d "$SETTINGS_SERVER_STORAGE_PATH" ]; then - local id=0 + local server_id=0 while IFS= read -r -d $'\0' path; do quick_basename "$path" - SERVER_NAME[$id]="$RETURN" - id="$(($id+1))" + + # Set some inexpensive variables + SERVER_NAME[$server_id]="$RETURN" + SERVER_PATH[$server_id]="$path" + SERVER_CONF[$server_id]="${SERVER_PATH[$server_id]}/$SETTINGS_SERVER_PROPERTIES" + + # 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[$server_id]="$world_id" + + server_property "$server_id" WORLD_STORAGE_PATH + server_property "$server_id" WORLD_STORAGE_INACTIVE_PATH + + # Allocate memory for active worlds + if [[ -d "${SERVER_WORLD_STORAGE_PATH[$server_id]}" ]]; then + while IFS= read -r -d $'\0' path; do + quick_basename "$path" + local name="$RETURN" + + WORLD_SERVER_ID[$world_id]="$server_id" + WORLD_NAME[$world_id]="$name" + + world_id="$(($id+1))" + done < <(find "${SERVER_WORLD_STORAGE_PATH[$server_id]}" -mindepth 1 -maxdepth 1 -type d -print0) + fi + + # Allocate memory for inactive worlds + if [[ -d "${SERVER_WORLD_STORAGE_INACTIVE_PATH[$server_id]}" ]]; then + while IFS= read -r -d $'\0' path; do + quick_basename "$path" + local name="$RETURN" + + WORLD_SERVER_ID[$world_id]="$server_id" + WORLD_NAME[$world_id]="$name" + + world_id="$(($id+1))" + done < <(find "${SERVER_WORLD_STORAGE_INACTIVE_PATH[$server_id]}" -mindepth 1 -maxdepth 1 -type d -print0) + fi + + # Update the total number of worlds + NUM_WORLDS="$world_id" + + # Record the number of worlds this server has + SERVER_NUM_WORLDS[$server_id]="$(( $world_id - ${SERVER_WORLD_OFFSET[$server_id]} ))" + + server_id="$(($server_id+1))" done < <(find "$SETTINGS_SERVER_STORAGE_PATH" -mindepth 1 -maxdepth 1 -type d -print0) - NUM_SERVERS="$id" + + NUM_SERVERS="$server_id" 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 -} - @@ -2501,7 +2919,10 @@ load_all() { register_setting() { # Create the default version of the variable eval SETTINGS_$1=\"$2\" + # State that the variable has not yet been loaded + eval LOADED_$1=\"false\" + # Keep track of the setting name in a list SETTING_NAME[$SETTING_COUNT]="$1" SETTING_COUNT=$(( $SETTING_COUNT + 1 )) } @@ -2548,6 +2969,8 @@ register_settings() { register_server_setting FLAG_ACTIVE_PATH "active" register_server_setting COMPLETE_BACKUP_FOLLOW_SYMLINKS "false" + register_server_setting WORLDS_FLAG_INRAM "inram" + register_server_setting RAM "1024" register_server_setting INVOCATION "java -Xms{RAM}M -Xmx{RAM}M -XX:+UseConcMarkSweepGC -XX:+CMSIncrementalPacing -XX:+AggressiveOpts -jar {JAR} nogui" register_server_setting STOP_DELAY "10" @@ -2589,7 +3012,6 @@ register_settings() { # $1: The command signature, a coded string describing the structure of the # command. # $2: The handler function to call, if this command is identified. -# $3: Optional flags register_command() { # Here we build a regular expression which will match any user input # that could be passed to the given handler function. It is derrived @@ -2631,12 +3053,6 @@ register_command() { COMMAND_SIGNATURE[$COMMAND_COUNT]="$1" COMMAND_REGEX[$COMMAND_COUNT]="$regex" COMMAND_HANDLER[$COMMAND_COUNT]="$2" - - if [[ "$3" =~ \ ]]; then - COMMAND_LOAD_ALL_SERVERS[$COMMAND_COUNT]="true" - else - COMMAND_LOAD_ALL_SERVERS[$COMMAND_COUNT]="false" - fi COMMAND_COUNT=$(( $COMMAND_COUNT + 1 )) else @@ -2647,6 +3063,8 @@ register_command() { # Match and call a command from user input # $*: User input call_command() { + manager_property SERVER_STORAGE_PATH + local args local space="\ " for arg in "$@"; do @@ -2663,13 +3081,6 @@ call_command() { for ((command=0; command<$COMMAND_COUNT; command++)); do 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 local word_offset=1 local args @@ -2779,7 +3190,10 @@ call_command() { if [[ "$sid" -ge "0" ]]; then if is_valid_name "$specified_name"; then - if [ -d "${SERVER_WORLD_STORAGE_PATH[$sid]}/$specified_name" ] || [ -d "${SERVER_WORLD_STORAGE_INACTIVE_PATH2[$sid]}/$specified_name" ]; then + server_property "$sid" WORLD_STORAGE_PATH + server_property "$sid" WORLD_STORAGE_INACTIVE_PATH + + if [ -d "${SERVER_WORLD_STORAGE_PATH[$sid]}/$specified_name" ] || [ -d "${SERVER_WORLD_STORAGE_INACTIVE_PATH[$sid]}/$specified_name" ]; then server_world_get_id "$sid" "$specified_name" wid="$RETURN" fi @@ -2802,15 +3216,6 @@ call_command() { # once, or multiple times based upon if multiple servers or worlds # 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 # all possible worlds. if [[ "$sid" == "server:all" ]] && [[ "$wid" == "world:all" ]]; then @@ -2869,48 +3274,8 @@ call_command() { echo "No such command. See $0 help" } - - - - - - - - - -# Called if the script is interrupted before exiting naturally -interrupt() { - local exit_message="false" - for ((i=0; $i<$NUM_SERVERS; i++)); do - if [[ "${STOP_COUNTDOWN[$i]}" == "true" ]] && server_is_running "$i"; then - if [[ "$exit_message" == "false" ]]; then - echo -e "\nInterrupted..." - exit_message="true" - fi - server_eval "$i" "say ${SERVER_MESSAGE_STOP_ABORT[$i]}" - echo "Server \"${SERVER_NAME[$i]}\" shutdown was aborted." - fi - - if [[ "${RESTART_COUNTDOWN[$i]}" == "true" ]] && server_is_running "$i"; then - if [[ "$exit_message" == "false" ]]; then - echo -e "\nInterrupted..." - exit_message="true" - fi - server_eval "$i" "say ${SERVER_MESSAGE_RESTART_ABORT[$i]}" - echo "Server \"${SERVER_NAME[$i]}\" restart was aborted." - fi - done - exit -} - -# The main function which starts the script -main() { - # Loads MSM variables - load_msm - - # Trap interrupts to the script by calling the interrupt function - trap interrupt EXIT - +# Defines every MSM command. +register_commands() { # The following section registers commands to be available for use. The # register_command function accepts a command_signature and a # command_handler_function_name as positional arguments 1 and 2 @@ -2946,17 +3311,17 @@ main() { # Variables passed to handler functions are of course positional and there # position matches the position of that element in the command signature. - register_command "start" "command_start" "" - register_command "stop" "command_stop" "" - register_command "stop now" "command_stop_now" "" - register_command "restart" "command_restart" "" - register_command "restart now" "command_restart_now" "" + register_command "start" "command_start" + register_command "stop" "command_stop" + register_command "stop now" "command_stop_now" + register_command "restart" "command_restart" + register_command "restart now" "command_restart_now" register_command "version" "command_version" register_command "config" "command_config" - register_command "server list" "command_server_list" "" + register_command "server list" "command_server_list" register_command "server create " "command_server_create" register_command "server delete " "command_server_delete" - register_command "server rename " "command_server_rename" "" + register_command "server rename " "command_server_rename" register_command "jargroup list" "command_jargroup_list" register_command "jargroup create " "command_jargroup_create" register_command "jargroup delete " "command_jargroup_delete" @@ -3013,9 +3378,56 @@ main() { register_command " console" "command_server_console" register_command " config" "command_server_config" register_command " config " "command_server_config" +} + + + + + + + + + + +# Called if the script is interrupted before exiting naturally +interrupt() { + local exit_message="false" + + for ((i=0; $i<$NUM_SERVERS; i++)); do + if [[ "${STOP_COUNTDOWN[$i]}" == "true" ]] && server_is_running "$i"; then + if [[ "$exit_message" == "false" ]]; then + echo -e "\nInterrupted..." + exit_message="true" + fi + server_eval "$i" "say ${SERVER_MESSAGE_STOP_ABORT[$i]}" + echo "Server \"${SERVER_NAME[$i]}\" shutdown was aborted." + fi + + if [[ "${RESTART_COUNTDOWN[$i]}" == "true" ]] && server_is_running "$i"; then + if [[ "$exit_message" == "false" ]]; then + echo -e "\nInterrupted..." + exit_message="true" + fi + server_eval "$i" "say ${SERVER_MESSAGE_RESTART_ABORT[$i]}" + echo "Server \"${SERVER_NAME[$i]}\" restart was aborted." + fi + done + exit +} + +# The main function which starts the script +main() { + register_settings + register_commands + allocate + + # Trap interrupts to the script by calling the interrupt function + trap interrupt EXIT + + # This function call matches the user input to a registered command - # signature, and then calls that commands handler function with positional - # arguments containing any variable strings. + # signature, and then calls that command's handler function with positional + # arguments containing any "variable" strings. call_command "$@" } @@ -3029,7 +3441,7 @@ if [[ "${BASH_SOURCE[0]}" == "$0" ]]; then exit 0 else # MSM was sourced from another script. - # Just load registered settings instead. + # Just register settings instead. - load_msm + register_settings fi diff --git a/test.sh b/test.sh index 1536abb..e785d84 100644 --- a/test.sh +++ b/test.sh @@ -27,13 +27,11 @@ oneTimeSetUp() { setUp() { - source "$DEFUALT_CONF" - # Create the testing conf from the default one mkdir -p "$TMP_DIR" && chown "$USERNAME" "$TMP_DIR" cp "$DEFUALT_CONF" "$MSM_CONF" && chown "$USERNAME" "$MSM_CONF" - # Overwrite the directories to use for testin purposes + # Overwrite the directories to use for testing purposes echo "" >> "$MSM_CONF" echo "# Auto appended by test script:" >> "$MSM_CONF" echo "SERVER_STORAGE_PATH=\"${TMP_DIR}/servers\"" >> "$MSM_CONF" @@ -46,8 +44,6 @@ setUp() { echo "DEFAULT_SCREEN_NAME=\"msmtest-{SERVER_NAME}\"" >> "$MSM_CONF" echo "DEFAULT_INVOCATION=\"java -Xmx${TEST_RAM}M -XX:+UseConcMarkSweepGC -XX:+CMSIncrementalPacing -XX:+AggressiveOpts -jar {JAR} nogui\"" >> "$MSM_CONF" - source "$MSM_CONF" - # Variables accessible by all tests, which are set by the stdall, stderr, # stdout and quiet utility functions. declare OUTPUT