diff --git a/bash_completion/msm b/bash_completion/msm index 42f15df..db6625a 100644 --- a/bash_completion/msm +++ b/bash_completion/msm @@ -1,60 +1,57 @@ ### Utility Functions -CONFIG="/etc/msm.conf" +MSM="/etc/init.d/msm" # Loads variables __init() { - source "$CONFIG" + source "$MSM" } # Loads server variables # $1: The name of a server __init_server() { - SERVER_PATH="$SERVER_STORAGE_PATH/$1" - SERVER_CONF="$SERVER_STORAGE_PATH/$1/$DEFAULT_PROPERTIES" + # Load some useful defaults + SERVER_NAME="$1" + SERVER_CONF="$SETTINGS_SERVER_STORAGE_PATH/$SERVER_NAME/$SETTINGS_SERVER_PROPERTIES" - 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" + SERVER_PATH="$SETTINGS_SERVER_STORAGE_PATH/$SERVER_NAME" + WORLD_STORAGE_PATH="$SERVER_PATH/$SETTINGS_DEFAULT_WORLD_STORAGE_PATH" + WORLD_STORAGE_INACTIVE_PATH="$SERVER_PATH/$SETTINGS_DEFAULT_WORLD_STORAGE_INACTIVE_PATH" - WHITELIST="$SERVER_PATH/$DEFAULT_WHITELIST" - BANNED_PLAYERS="$SERVER_PATH/$DEFAULT_BANNED_PLAYERS" - BANNED_IPS="$SERVER_PATH/$DEFAULT_BANNED_IPS" - OPS="$SERVER_PATH/$DEFAULT_OPS" - - JAR="$DEFAULT_JAR" - RAM="$DEFAULT_RAM" - INVOCATION="$DEFAULT_INVOCATION" + WHITELIST_PATH="$SERVER_PATH/$SETTINGS_DEFAULT_WHITELIST_PATH" + BANNED_PLAYERS_PATH="$SERVER_PATH/$SETTINGS_DEFAULT_BANNED_PLAYERS_PATH" + BANNED_IPS_PATH="$SERVER_PATH/$SETTINGS_DEFAULT_BANNED_IPS_PATH" + OPS_PATH="$SERVER_PATH/$SETTINGS_DEFAULT_OPS_PATH" if [[ -f "$SERVER_CONF" ]]; then - local name value + local name value name_upper_case while read line; do # ignore comment lines - echo "$line" | grep "^#" >/dev/null 2>&1 && continue - - # if not empty, get the name and value of the setting - if [ ! -z "$line" ]; then - name="$(echo $line | awk -F '=' '{print $1}')" - value="$(echo $line | awk -F '\"' '{print $2}')" + if [[ "$line" =~ ^# ]]; then + continue + fi + + if [[ "$line" =~ ^msm-([\-\_a-zA-Z0-9]+)\=(\"(.*)\"|\'(.*)\'|(.*)$) ]]; then + name="${BASH_REMATCH[1]}" + value="${BASH_REMATCH[3]}${BASH_REMATCH[4]}${BASH_REMATCH[5]}" + + if is_bash_version 4; then + name="${name//-/_}" + name="${name//./_}" + name="${name^^}" + else + name="$(echo "$name" | tr '[\-\.a-z]' '[\_\_A-Z]')" + fi + + # Make relative paths absolute by combining with server directory + if [[ "$name" =~ \-path$ ]] && [[ ! "$value" =~ ^\/ ]]; then + value="${SERVER_PATH[$1]}/$value" + fi + + # Create the variable + eval ${name}=\"$value\" fi - - case "$name" in - SERVER_USER) SERVER_USER="$value";; - SCREEN_NAME) SCREEN_NAME="$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";; - BANNED_IPS) BANNED_IPS="$SERVER_PATH/$value";; - OPS) OPS="$SERVER_PATH/$value";; - - JAR) JAR="$SERVER_PATH/$value";; - RAM) RAM="$value";; - INVOCATION) INVOCATION="$value";; - esac done < "$SERVER_CONF" fi } @@ -71,8 +68,8 @@ _msm() { current="${COMP_WORDS[$COMP_CWORD]}" if [[ $COMP_CWORD == 1 ]]; then - if [ -d "$SERVER_STORAGE_PATH" ]; then - local servers="$(ls -1 "$SERVER_STORAGE_PATH")" + if [ -d "$SETTINGS_SERVER_STORAGE_PATH" ]; then + local servers="$(ls -1 "$SETTINGS_SERVER_STORAGE_PATH")" fi options="help start stop restart version server jargroup all config $servers" else @@ -88,8 +85,8 @@ _msm() { else case "${COMP_WORDS[2]}" in delete|rename) - if [[ $COMP_CWORD == 3 && -d "$SERVER_STORAGE_PATH" ]]; then - options="$(ls -1 "$SERVER_STORAGE_PATH")" + if [[ $COMP_CWORD == 3 && -d "$SETTINGS_SERVER_STORAGE_PATH" ]]; then + options="$(ls -1 "$SETTINGS_SERVER_STORAGE_PATH")" fi ;; esac @@ -101,8 +98,8 @@ _msm() { else case "${COMP_WORDS[2]}" in delete|rename|changeurl|getlatest) - if [[ $COMP_CWORD == 3 && -d "$JAR_STORAGE_PATH" ]]; then - options="$(ls -1 "$JAR_STORAGE_PATH")" + if [[ $COMP_CWORD == 3 && -d "$SETTINGS_JAR_STORAGE_PATH" ]]; then + options="$(ls -1 "$SETTINGS_JAR_STORAGE_PATH")" fi ;; esac @@ -111,7 +108,7 @@ _msm() { *) # Server options - local server_path="$SERVER_STORAGE_PATH/${COMP_WORDS[1]}" + local server_path="$SETTINGS_SERVER_STORAGE_PATH/${COMP_WORDS[1]}" if [[ "${COMP_WORDS[1]}" == "all" ]] || [ -e "$server_path" ]; then # If the server exists @@ -156,12 +153,12 @@ _msm() { fi ;; jar) - if [[ $COMP_CWORD == 3 && -d "$JAR_STORAGE_PATH" ]]; then - options="$(ls -1 "$JAR_STORAGE_PATH")" + if [[ $COMP_CWORD == 3 && -d "$SETTINGS_JAR_STORAGE_PATH" ]]; then + options="$(ls -1 "$SETTINGS_JAR_STORAGE_PATH")" fi - if [[ $COMP_CWORD == 4 && -d "$JAR_STORAGE_PATH/${COMP_WORDS[3]}" ]]; then - options="$(find "$JAR_STORAGE_PATH/${COMP_WORDS[3]}" -type f -name "*.jar" -exec basename {} \;)" + if [[ $COMP_CWORD == 4 && -d "$SETTINGS_JAR_STORAGE_PATH/${COMP_WORDS[3]}" ]]; then + options="$(find "$SETTINGS_JAR_STORAGE_PATH/${COMP_WORDS[3]}" -type f -name "*.jar" -exec basename {} \;)" fi ;; whitelist|wl) @@ -171,8 +168,8 @@ _msm() { case "${COMP_WORDS[3]}" in remove) if [[ $COMP_CWORD == 4 ]]; then - if [ -f "$WHITELIST" ]; then - options="$(cat "$WHITELIST")" + if [ -f "$WHITELIST_PATH" ]; then + options="$(cat "$WHITELIST_PATH")" fi fi ;; @@ -191,8 +188,8 @@ _msm() { case "${COMP_WORDS[4]}" in remove) if [[ $COMP_CWORD == 5 ]]; then - if [ -f "$BANNED_PLAYERS" ]; then - options="$(cat "$BANNED_PLAYERS")" + if [ -f "$BANNED_PLAYERS_PATH" ]; then + options="$(cat "$BANNED_PLAYERS_PATH")" fi fi ;; @@ -206,8 +203,8 @@ _msm() { case "${COMP_WORDS[4]}" in remove) if [[ $COMP_CWORD == 5 ]]; then - if [ -f "$BANNED_IPS" ]; then - options="$(cat "$BANNED_IPS")" + if [ -f "$BANNED_IPS_PATH" ]; then + options="$(cat "$BANNED_IPS_PATH")" fi fi ;; @@ -224,8 +221,8 @@ _msm() { case "${COMP_WORDS[3]}" in remove) if [[ $COMP_CWORD == 4 ]]; then - if [ -f "$OPS" ]; then - options="$(cat "$OPS")" + if [ -f "$OPS_PATH" ]; then + options="$(cat "$OPS_PATH")" fi fi ;; diff --git a/init/msm b/init/msm index 168ee79..b12e7b5 100755 --- a/init/msm +++ b/init/msm @@ -31,16 +31,7 @@ VERSION="0.6.4" ### Config variables the user should not need/want to change # The start of a regex to find a log line -declare -r LOG_REGEX="^[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2} \[.*\]" - - -### Script State Variables - -# "true" whilst the script is counting down a delay to stop the server -declare STOP_COUNTDOWN - -# "true" whilst the script is counting down a delay to restart the server -declare RESTART_COUNTDOWN +LOG_REGEX="^[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2} \[.*\]" # Variables used for registration COMMAND_COUNT=0 @@ -96,6 +87,16 @@ error_exit() { exit "${code:-$1}" } +# Tests the bash version installed +# $1: The bash version required +is_bash_version() { + if [[ "$BASH_VERSION" =~ ^$1 ]]; then + return 0; + fi + + return 1; +} + # 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. @@ -113,11 +114,11 @@ debug() { # $1: The name to check is_valid_name() { local valid="^[a-zA-Z0-9\_\-]+$" - local invalid="^(start|stop|restart|version|server|jargroup|all|config)$" + local invalid="^(start|stop|restart|version|server|jargroup|all|config|\-\-.*)$" if [[ "$1" =~ $valid ]]; then if [[ "$1" =~ $invalid ]]; then - error_exit INVALID_ARGUMENT "Invalid name \"$1\": A name may not be any of the following reserved worlds \"start\", \"stop\", \"restart\", \"server\", \"version\", \"jargroup\", \"all\" or \"config\"." + error_exit INVALID_ARGUMENT "Invalid name \"$1\": A name may not be any of the following reserved worlds \"start\", \"stop\", \"restart\", \"server\", \"version\", \"jargroup\", \"all\", \"config\" or start with two dashes (--)." else return 0 fi @@ -1641,7 +1642,12 @@ command_server_whitelist_add() { server_eval "$1" "whitelist add $2" echo "Added \"$2\" to the whitelist." else - error_exit SERVER_STOPPED "Server \"${SERVER_NAME[$1]}\" is not running." + if grep "$2" "${SERVER_WHITELIST_PATH[$1]}" >/dev/null; then + echo "Player \"$2\" is already whitelisted for server \"${SERVER_NAME[$1]}\"." + else + echo "$2" >> "${SERVER_WHITELIST_PATH[$1]}" + echo "Player \"$2\" has been added to the whitelisted for server \"${SERVER_NAME[$1]}\"." + fi fi } @@ -1654,7 +1660,12 @@ command_server_whitelist_remove() { server_eval "$1" "whitelist remove $2" echo "Removed \"$2\" from the whitelist." else - error_exit SERVER_STOPPED "Server \"${SERVER_NAME[$1]}\" is not running." + if grep "$2" "${SERVER_WHITELIST_PATH[$1]}" >/dev/null; then + sed -i "/$2/d" "${SERVER_WHITELIST_PATH[$1]}" + echo "Player \"$2\" has been removed from the whitelisted for server \"${SERVER_NAME[$1]}\"." + else + echo "Player \"$2\" is not whitelisted for server \"${SERVER_NAME[$1]}\"." + fi fi } @@ -2168,29 +2179,37 @@ server_load_properties() { fi # if not empty, get the name and value of the setting - if [[ "$line" =~ ^(.*)=(.*)$ ]]; then + if [[ "$line" =~ ^([\-\_a-zA-Z0-9]+)\=(\"(.*)\"|\'(.*)\'|(.*)$) ]]; then name="${BASH_REMATCH[1]}" - value="${BASH_REMATCH[2]}" + # Only one of 3,4 or 5 will match: + value="${BASH_REMATCH[3]}${BASH_REMATCH[4]}${BASH_REMATCH[5]}" + + # Translate to uppercase, and replace dashes with underscores + if is_bash_version 4; then + # Much faster than the `tr` command + name="${name//-/_}" + name="${name//./_}" + name="${name^^}" + else + name="$(echo "$name" | tr '[\-\.a-z]' '[\_\_A-Z]')" + fi # Create variables if [[ "$name" =~ ^msm-[\-\_a-zA-Z0-9]+$ ]]; then - local name_upper_case="$(echo ${name:4} | tr '[a-z\-]' '[A-Z\_]')" + # Regex for MSM custom variables - if [[ "$name" =~ ^msm-[\-\_a-zA-Z0-9]+-path$ ]]; then - if [[ ! "$value" =~ ^\/ ]]; then - value="${SERVER_PATH[$1]}/$value" - fi + # Make relative paths absolute to server directory + if [[ "$name" =~ ^msm-[\-\_a-zA-Z0-9]+-path$ ]] && [[ ! "$value" =~ ^\/ ]]; then + value="${SERVER_PATH[$1]}/$value" fi - if [[ "$value" =~ ^\"(.*)\"$ ]] || [[ "$value" =~ ^\'(.*)\'$ ]]; then - value="${BASH_REMATCH[1]}" - fi - - eval SERVER_${name_upper_case}[$1]=\"$value\" + # Create the variable + eval SERVER_${name}[$1]=\"$value\" else if [[ "$name" =~ ^[\-\_a-zA-Z0-9]+$ ]]; then - local name_upper_case="$(echo $name | tr '[a-z\-\.]' '[A-Z\_\_]')" - eval SERVER_PROPERTIES_${name_upper_case}[$1]=\"$value\" + # Regex for standard Minecraft variables + + eval SERVER_PROPERTIES_${name}[$1]=\"$value\" fi fi fi @@ -2219,10 +2238,8 @@ server_init() { # Make relative paths absolute, assuming the server directory # as the current directory. - if [[ "$name" =~ _PATH$ ]]; then - if [[ ! "$value" =~ ^\/ ]]; then - value="${SERVER_PATH[$1]}/$value" - fi + if [[ "$name" =~ _PATH$ ]] && [[ ! "$value" =~ ^\/ ]]; then + value="${SERVER_PATH[$1]}/$value" fi eval SERVER_${name}[$1]=\"${value}\" @@ -2390,28 +2407,22 @@ register_settings() { load_conf() { if [[ -f "$CONF" ]]; then while read line; do - # ignore comment lines - if [[ "$line" =~ ^# ]]; then - continue - fi - - # if not empty, get the name and value of the setting - if [[ "$line" =~ ^(.*)=(.*)$ ]]; then + # Get the name and value of the setting + if [[ "$line" =~ ^([\-\_a-zA-Z0-9]+)\=(\"(.*)\"|\'(.*)\'|(.*)$) ]]; then name="${BASH_REMATCH[1]}" - value="${BASH_REMATCH[2]}" + # Only one of 3,4 or 5 will match: + value="${BASH_REMATCH[3]}${BASH_REMATCH[4]}${BASH_REMATCH[5]}" - # If the value is wrapped in double or single quotations - # remove them from the value. - if [[ "$value" =~ ^\".*\"$ ]] || [[ "$value" =~ ^\'.*\'$ ]]; then - value="${value:1:${#value}-2}" + # Translate to uppercase, and replace dashes with underscores + if is_bash_version 4; then + name="${name//-/_}" + name="${name^^}" + else + name="$(echo "$name" | tr '[\-a-z]' '[\_A-Z]')" fi - name="$(echo "$name" | tr '[\-a-z]' '[\_A-Z]')" - - # Create variables - if [[ "$name" =~ ^[\_A-Z0-9]+$ ]]; then - eval SETTINGS_${name}=\"$value\" - fi + # Create variables in uppercase + eval SETTINGS_${name}=\"$value\" fi done < "$CONF" fi @@ -2840,5 +2851,15 @@ main() { ### Start point -main "$@" -exit 0 +if [[ "${BASH_SOURCE[0]}" == "$0" ]]; then + # MSM was called from the command line + + main "$@" + exit 0 +else + # MSM was sourced from another script. + # Just load registered settings instead. + + register_settings + load_conf +fi