WIP: Use new server_command wrapper func

Also improve download code to also download versions
This commit is contained in:
Marcus Whybrow 2012-08-10 02:41:49 +01:00
parent 5fbb6c649d
commit 5fa9d343fe
9 changed files with 372 additions and 435 deletions

556
init/msm
View File

@ -104,6 +104,15 @@ echoerr() {
echo "$@" 1>&2
}
# Echos the first non-empty string in the arguments list
# $1->: Candidate strings for echoing
echo_fallback() {
for arg in "$@"; do
[ -z "$arg" ] && continue
echo "$arg"
done
}
# Exit's the script
error_exit() {
case "$1" in
@ -697,7 +706,8 @@ server_worlds_to_disk() {
# Watches a server's log for a specific line
# $1: The ID for the server
# $2: A UNIX timestamp (seconds since 1970) which the $3 line must be after
# $3->: The line or lines in the log to wait for
# $3: The regex that matches log lines
# $4: A timeout in seconds
# returns: When the line is found
server_log_get_line() {
server_property "$1" USERNAME
@ -707,28 +717,25 @@ server_log_get_line() {
# Make sure there is a server log to check
as_user "${SERVER_USERNAME[$1]}" "touch ${SERVER_LOG_PATH[$1]}"
while read -t 30 line; do
local regex="${LOG_REGEX} ($3)"
while read line; do
line_time="$(log_line_get_time "$line")"
# If the entry is old enough
if [[ "$line_time" -ge "$2" ]]; then
for search_line in "${@:3}"; do
local regex="${LOG_REGEX} ${search_line}"
# and matches the regular expression
if [[ "$line" =~ $regex ]]; then
RETURN="${line}"
return 0
fi
done
if [[ "$line_time" -ge "$2" ]] && [[ "$line" =~ $regex ]]; then
# Return the line
RETURN="${line}"
return 0
fi
done < <(as_user "${SERVER_USERNAME[$1]}" "tail --pid=$$ --follow --lines=100 --sleep-interval=0.1 \"${SERVER_LOG_PATH[$1]}\"")
done < <(as_user "${SERVER_USERNAME[$1]}" "sleep $4 & tail --pid=$! --follow --lines=100 --sleep-interval=0.1 \"${SERVER_LOG_PATH[$1]}\"")
}
# The same as server_log_get_line, but prints a dot instead of the log line
# to stdout, and retruns when line is found.
# $1: the ID of the server
# $2: A UNIX timestamp (seconds since 1970) which the $3 line must be after
# $3->: The line or lines in the log to wait for
# $3: The regex that matches log lines
# $4: A timeout in seconds
# returns: When the line is found
server_log_dots_for_lines() {
server_property "$1" USERNAME
@ -737,7 +744,8 @@ server_log_dots_for_lines() {
# Make sure there is a server log to check
as_user "${SERVER_USERNAME[$1]}" "touch ${SERVER_LOG_PATH[$1]}"
while read -t 30 line; do
local regex="${LOG_REGEX} ($3)"
while read line; do
line_time="$(log_line_get_time "$line")"
# If the entry is old enough
@ -746,16 +754,12 @@ server_log_dots_for_lines() {
# Print a dot for this line
echo -n '.'
for search_line in "${@:3}"; do
local regex="${LOG_REGEX} ${search_line}"
# and matches the regular expression
if [[ "$line" =~ $regex ]]; then
# Return if this is the line being looked for
return 0
fi
done
# and if it matches the regular expression, return
if [[ "$line" =~ $regex ]]; then
return 0
fi
fi
done < <(as_user "${SERVER_USERNAME[$1]}" "tail --pid=$$ --follow --lines=100 --sleep-interval=0.1 \"${SERVER_LOG_PATH[$1]}\"")
done < <(as_user "${SERVER_USERNAME[$1]}" "sleep $4 & tail --pid=$! --follow --lines=100 --sleep-interval=0.1 \"${SERVER_LOG_PATH[$1]}\"")
}
# Sends as string to a server for execution
@ -771,14 +775,15 @@ server_eval() {
# The same as server_eval, but also waits for a log entry before returning
# $1: The ID of the server
# $2: A line of text to enter into the server console
# $3->: The line or lines of text in the log to wait for
# $3: The regex that matches log lines
# $4: A timeout in seconds
# RETURN: The full entry found in the logs
server_eval_and_get_line() {
unset RETURN
time_now="$(now)"
server_eval "$1" "$2"
server_log_get_line "$1" "$time_now" "${@:3}"
server_log_get_line "$1" "$time_now" "$3" "$4"
RETURN="$RETURN"
}
@ -789,9 +794,46 @@ server_eval_and_wait() {
unset RETURN # Do not return anything
}
# server_command() {
# Executes a "version correct" command in a server's console.
# If the command has output to watch for, then wait until that
# output is found and return it, or until the timeout for that
# command
# $1: The ID of the server
# $2: The name of the command
# $3->: Command arguments in the form "argname=argvalue"
# $RETURN: The output found, if any
server_command() {
unset RETURN
# }
# Load variables
eval server_property $1 CONSOLE_COMMAND_OUTPUT_$2
eval server_property $1 CONSOLE_COMMAND_PATTERN_$2
eval server_property $1 CONSOLE_COMMAND_TIMEOUT_$2
eval local output_regex=\"\${SERVER_CONSOLE_COMMAND_OUTPUT_$2[$1]}\"
eval local pattern=\"\${SERVER_CONSOLE_COMMAND_PATTERN_$2[$1]}\"
# Replace arguments in pattern
for arg in "${@:3}"; do
if [[ "$arg" =~ (.*)=(.*) ]]; then
pattern="${pattern//<${BASH_REMATCH[1]}>/${BASH_REMATCH[2]}}"
output_regex="${output_regex//<${BASH_REMATCH[1]}>/${BASH_REMATCH[2]}}"
fi
done
# If there is no output to watch for, execute the command immediately
# and return immediately
if [ -z "$output_regex" ]; then
server_eval "$1" "$pattern"
else
# Otherwise execute the command and wait for the specified output
# or the timeout
eval local timeout=\"\${SERVER_CONSOLE_COMMAND_TIMEOUT_$2[$1]}\"
server_eval_and_get_line "$1" "$pattern" "$output_regex" "$timeout"
RETURN="$RETURN"
fi
}
# Gets the process ID for a server if running, otherwise it outputs nothing
# $1: The ID of the server
@ -1184,7 +1226,7 @@ server_start() {
server_property "$1" USERNAME
server_property "$1" SCREEN_NAME
server_property "$1" INVOCATION
server_property "$1" CONFIRM_START
server_property "$1" CONSOLE_EVENT_START
if server_is_running "$1"; then
echo "Server \"${SERVER_NAME[$1]}\" is already running!"
@ -1197,7 +1239,7 @@ server_start() {
printf "Starting server..."
as_user "${SERVER_USERNAME[$1]}" "cd \"${SERVER_PATH[$1]}\" && screen -dmS \"${SERVER_SCREEN_NAME[$1]}\" ${SERVER_INVOCATION[$1]}"
server_log_dots_for_lines "$1" "$time_now" "${SERVER_CONFIRM_START[$1]}"
server_log_dots_for_lines "$1" "$time_now" "${SERVER_CONSOLE_EVENT_START[$1]}"
echo " Done."
fi
@ -1207,13 +1249,8 @@ server_start() {
# $1: The ID of the server
server_save_all() {
if server_is_running "$1"; then
server_property "$1" CONFIRM_SAVE_ALL
echo -n "Forcing save... "
# Send the "save-all" command and wait for it to finish
server_eval_and_wait "$1" "save-all" "${SERVER_CONFIRM_SAVE_ALL[$1]}"
server_command "$1" SAVE_ALL
echo "Done."
else
echo "Server \"${SERVER_NAME[$1]}\" is not running."
@ -1224,13 +1261,8 @@ server_save_all() {
# $1: The ID of the server
server_save_off() {
if server_is_running "$1"; then
server_property "$1" CONFIRM_SAVE_OFF
echo -n "Disabling level saving... "
# Send the "save-off" command and wait for it to finish
server_eval_and_wait "$1" "save-off" "${SERVER_CONFIRM_SAVE_OFF[$1]}"
server_command "$1" SAVE_OFF
echo "Done."
# Writes any in-memory data manged by the kernel to disk
@ -1244,13 +1276,8 @@ server_save_off() {
# $1: The ID of the server
server_save_on() {
if server_is_running "$1"; then
server_property "$1" CONFIRM_SAVE_ON
echo -n "Enabling level saving... "
# Send the "save-on" command and wait for it to finish
server_eval_and_wait "$1" "save-on" "${SERVER_CONFIRM_SAVE_ON[$1]}"
server_command "$1" SAVE_ON
echo "Done."
else
echo "Server \"${SERVER_NAME[$1]}\" is not running."
@ -1534,6 +1561,13 @@ server_property() {
server_set_property "$1" "$2" "${SERVER_PATH[$1]}/$SETTINGS_SERVER_PROPERTIES"
return 0
;;
VERSION_CONF)
manager_property VERSIONING_STORAGE_PATH
server_property "$1" VERSION
get_closest_version "${SERVER_VERSION[$1]}"
SERVER_VERSION_CONF[$1]="${SETTINGS_VERSIONING_STORAGE_PATH}/${RETURN}.${SETTINGS_VERSIONING_FILE_EXTENSION}"
return 0
;;
BACKUP_PATH)
manager_property BACKUP_ARCHIVE_PATH
server_set_property "$1" "$2" "$SETTINGS_BACKUP_ARCHIVE_PATH/${SERVER_NAME[$1]}"
@ -1556,15 +1590,14 @@ server_property() {
esac
# If its a command lookup, load from versioning files
if [[ "$2" =~ ^COMMAND_ ]]; then
to_properties_name "$2"
local name="$RETURN"
if [[ "$2" =~ ^CONSOLE_ ]]; then
server_property "$1" VERSION_CONF
server_property "$1" VERSION
echo ${SERVER_VERSION[$1]}
# local from_conf="$(sed -rn "s/^log-confirmations:.* commands:.* ${name}:(.+)( [\-\_a-zA-Z0-9]+:)?/\1/ip" "${SERVER_CONF[$1]}" | tail -n 1)"
if [[ -f "${SERVER_VERSION_CONF[$1]}" ]]; then
VERSIONING_SERVER_ID="$1"
source "${SERVER_VERSION_CONF[$1]}"
unset VERSIONING_SERVER_ID
fi
return 0
fi
@ -1929,7 +1962,20 @@ command_update() {
download_file() {
local dir_name="$(dirname "${output_dir}/${1}")"
as_user "root" "mkdir -p \"${dir_name}\""
as_user "root" "wget --quiet --trust-server-names --no-check-certificate ${SETTINGS_UPDATE_URL}/$1 -O ${output_dir}/$1"
as_user "root" "wget --trust-server-names --no-check-certificate ${SETTINGS_UPDATE_URL}/$1 -O ${output_dir}/$1"
}
# $1: The newly download file (relative to download dir)
# $2: The current file that may be overwritten
# $RETURN: The "current file" path if it should be overwritten
# since it is different to the new version
compare_file() {
unset RETURN
if diff -q "${output_dir}/$1" "$2" >/dev/null 2>/dev/null; then
return 1
else
RETURN="$2"
fi
}
# Download the latest MSM script and check its verison number
@ -1942,9 +1988,56 @@ command_update() {
else
echo "$latest_version is available."
echo "Updating will overwrite the following files:"
echo " > $COMPLETION"
echo " > $SCRIPT"
echo -n "Checking which files need to be updated... "
download_file "bash_completion/msm"
# download_file "versioning/versions.txt"
# Downloads all versioning files in the latest MSM version
download_upstream_versions() {
manager_property VERSIONING_FILE_EXTENSION
while read line; do
if [[ "$line" =~ ^([^#]{1}.*)$ ]]; then
download_file "versioning/${BASH_REMATCH[1]}.${SETTINGS_VERSIONING_FILE_EXTENSION}"
fi
done < "${output_dir}/versioning/versions.txt"
}
# $returns: 0 if at least one file needs updating, 1 otherwise
files_need_updating() {
compare_file "bash_completion/msm" "$COMPLETION"
[ ! -z "$RETURN" ] && return 0
compare_file "init/msm" "$SCRIPT"
[ ! -z "$RETURN" ] && return 0
while IFS= read -r -d $'\0' path; do
echo "$path"
done < <(find "${output_dir}/versioning/" -name .${SETTINGS_VERSIONING_FILE_EXTENSION} -mindepth 1 -type f -print0)
return 1
}
download_upstream_versions
echo "Done."
if files_need_updating; then
echo "Updating will overwrite the following files:"
compare_file "bash_completion/msm" "$COMPLETION"
[ ! -z "$RETURN" ] && echo " > The bash completion script: $COMPLETION"
compare_file "init/msm" "$SCRIPT"
[ ! -z "$RETURN" ] && echo " > The main MSM script: $SCRIPT"
else
echo "Strangely, no files need updating. Ah well."
fi
local v_full v_type v_version
for ((v=0; v<$VERSIONS_COUNT; v++)); do
echo " > Versioning file: ${VERSIONS_PATH[$v]}"
done
if [[ ! "$noinput" ]]; then
echo -n "Do you want to continue [y/N]: "
@ -1956,8 +2049,7 @@ command_update() {
if [[ "$answer" =~ ^(y|Y|yes)$ ]]; then
echo "Updating MSM to ${latest_version}:"
# Download and overwrite bash completion file
download_file "bash_completion/msm"
# Overwrite bash completion file
local dir="$(dirname "$COMPLETION")"
as_user "root" "mkdir -p \"${dir}\""
as_user "root" "mv -f \"${output_dir}/bash_completion/msm\" \"$COMPLETION\""
@ -1976,9 +2068,6 @@ command_update() {
echo "MSM was not updated."
fi
fi
# Clean up the temp directory created for downloads
as_user "root" "rm -rf \"${output_dir}\""
}
# Displays a list of servers
@ -2274,7 +2363,8 @@ command_server_jar() {
# $1: The server ID
command_server_whitelist_on() {
if server_is_running "$1"; then
server_eval "$1" "whitelist on"
server_command "$1" WHITELIST_ON
echo_fallback "$RETURN" "Whitelist enabled."
else
command_server_config "$1" "white-list" "true"
fi
@ -2285,7 +2375,8 @@ command_server_whitelist_on() {
# $1: The server ID
command_server_whitelist_off() {
if server_is_running "$1"; then
server_eval "$1" "whitelist off"
server_command "$1" WHITELIST_OFF
echo_fallback "$RETURN" "Whitelist disabled."
else
command_server_config "$1" "white-list" "false"
fi
@ -2300,7 +2391,8 @@ command_server_whitelist_add() {
if server_is_running "$1"; then
# Whitelist players
for player in "${@:2}"; do
server_eval "$1" "whitelist add $player"
server_command "$1" WHITELIST_ADD player="$player"
echo_fallback "$RETURN" "Player $player is now whitelisted."
done
else
server_property "$1" WHITELIST_PATH
@ -2308,21 +2400,10 @@ command_server_whitelist_add() {
for player in "${@:2}"; do
if ! grep "^$player\$" "${SERVER_WHITELIST_PATH[$1]}" >/dev/null; then
echo "$player" >> "${SERVER_WHITELIST_PATH[$1]}"
echo_fallback "$RETURN" "Player $player is now whitelisted."
fi
done
fi
# Confirmation display
if [[ $# -gt 2 ]]; then
echo -n "Added the following players to the whitelist: "
echo -n "$2"
for player in "${@:3}"; do
echo -n ", $player"
done
echo "."
else
echo "Added \"$2\" to the whitelist."
fi
}
# Removes a player name from a server's whitelist
@ -2332,27 +2413,17 @@ command_server_whitelist_remove() {
# TODO: Support multiple player names
if server_is_running "$1"; then
for player in "${@:2}"; do
server_eval "$1" "whitelist remove $player"
server_command "$1" WHITELIST_REMOVE player="$player"
echo_fallback "$RETURN" "Player $player is no longer whitelisted."
done
else
server_property "$1" WHITELIST_PATH
for player in "${@:2}"; do
sed -ri "/^$player\$/d" "${SERVER_WHITELIST_PATH[$1]}"
echo_fallback "$RETURN" "Player $player is no longer whitelisted."
done
fi
# Confirmation display
if [[ $# -gt 2 ]]; then
echo -n "Removed the following players from the whitelist: "
echo -n "$2"
for player in "${@:3}"; do
echo -n ", $player"
done
echo "."
else
echo "Removed \"$2\" from the whitelist."
fi
}
# Displays a list of whitelisted players for an individual server
@ -2379,7 +2450,8 @@ command_server_whitelist_list() {
command_server_blacklist_player_add() {
if server_is_running "$1"; then
for player in "${@:2}"; do
server_eval "$1" "ban $player"
server_command "$1" BLACKLIST_PLAYER_ADD player="$player"
echo_fallback "$RETURN" "Player $player is now blacklisted."
done
else
server_property "$1" BANNED_PLAYERS_PATH
@ -2387,20 +2459,10 @@ command_server_blacklist_player_add() {
for player in "${@:2}"; do
if ! grep "^$player\$" "${SERVER_BANNED_PLAYERS_PATH[$1]}" >/dev/null; then
echo "$player" >> "${SERVER_BANNED_PLAYERS_PATH[$1]}"
echo "Player $player is now blacklisted."
fi
done
fi
if [[ $# -gt 2 ]]; then
echo -n "Added the following players to the blacklist: "
echo -n "$2"
for player in "${@:3}"; do
echo -n ", $player"
done
echo "."
else
echo "Added \"$2\" to the blacklist."
fi
}
# Removes player names from a server's ban list
@ -2409,26 +2471,17 @@ command_server_blacklist_player_add() {
command_server_blacklist_player_remove() {
if server_is_running "$1"; then
for player in "${@:2}"; do
server_eval "$1" "pardon $player"
server_command "$1" BLACKLIST_PLAYER_REMOVE player="$player"
echo_fallback "$RETURN" "Player $player is no longer blacklisted."
done
else
server_property "$1" BANNED_PLAYERS_PATH
for player in "${@:2}"; do
sed -ri "/^$player\$/d" "${SERVER_BANNED_PLAYERS_PATH[$1]}"
echo "Player $player is no longer blacklisted."
done
fi
if [[ $# -gt 2 ]]; then
echo -n "Removed the following players from the blacklist: "
echo -n "$2"
for player in "${@:3}"; do
echo -n ", $player"
done
echo "."
else
echo "Removed \"$2\" from the blacklist."
fi
}
# Adds ip addresses to a server's ban list
@ -2437,7 +2490,8 @@ command_server_blacklist_player_remove() {
command_server_blacklist_ip_add() {
if server_is_running "$1"; then
for address in "${@:2}"; do
server_eval "$1" "ban-ip $address"
server_command "$1" BLACKLIST_IP_ADD address="$address"
echo_fallback "$RETURN" "IP address $address is now blacklisted."
done
else
server_property "$1" BANNED_IPS_PATH
@ -2445,20 +2499,10 @@ command_server_blacklist_ip_add() {
for address in "${@:2}"; do
if ! grep "^$address\$" "${SERVER_BANNED_IPS_PATH[$1]}" >/dev/null; then
echo "$address" >> "${SERVER_BANNED_IPS_PATH[$1]}"
echo "IP address $address is now blacklisted."
fi
done
fi
if [[ $# -gt 2 ]]; then
echo -n "Added the following ip addresses to the blacklist: "
echo -n "$2"
for address in "${@:3}"; do
echo -n ", $address"
done
echo "."
else
echo "Added \"$2\" to the blacklist."
fi
}
# Removes ip addresses to a server's ban list
@ -2467,26 +2511,17 @@ command_server_blacklist_ip_add() {
command_server_blacklist_ip_remove() {
if server_is_running "$1"; then
for address in "${@:2}"; do
server_eval "$1" "pardon-ip $address"
server_command "$1" BLACKLIST_IP_REMOVE address="$address"
echo_fallback "$RETURN" "IP address $address is no longer blacklisted."
done
else
server_property "$1" BANNED_PLAYERS_PATH
for address in "${@:2}"; do
sed -ri "/^$address\$/d" "${SERVER_BANNED_PLAYERS_PATH[$1]}"
echo "IP address $address is no longer blacklisted."
done
fi
if [[ $# -gt 2 ]]; then
echo -n "Removed the following players from the blacklist: "
echo -n "$2"
for address in "${@:3}"; do
echo -n ", $address"
done
echo "."
else
echo "Removed \"$2\" from the blacklist."
fi
}
# Displays a server's banned player names and ip addresses
@ -2531,7 +2566,8 @@ command_server_blacklist_list() {
command_server_operator_add() {
if server_is_running "$1"; then
for player in "${@:2}"; do
server_eval "$1" "op $player"
server_command "$1" OP_ADD player="$player"
echo_fallback "$RETURN" "Player $player is now an operator."
done
else
server_property "$1" OPS_PATH
@ -2562,7 +2598,8 @@ command_server_operator_remove() {
# TODO: Support multiple player names
if server_is_running "$1"; then
for player in "${@:2}"; do
server_eval "$1" "deop $player"
server_command "$1" OP_REMOVE player="$player"
echo_fallback "$RETURN" "Player $player is no longer an operator."
done
else
server_property "$1" OPS_PATH
@ -2609,34 +2646,9 @@ command_server_operator_list() {
# $3->: The player name
command_server_gamemode() {
if server_is_running "$1"; then
local mode line regex
case "$2" in
creative|1) mode=1;;
survival|0) mode=0;;
*) error_exit INVALID_ARGUMENT "Invalid gamemode type \"$2\" options are \"survival\", \"creative\", \"0\" or \"1\".";;
esac
server_property "$1" CONFIRM_GAMEMODE
server_property "$1" CONFIRM_GAMEMODE_FAIL_NO_USER
server_property "$1" CONFIRM_GAMEMODE_FAIL_NO_CHANGE
for player in "${@:3}"; do
server_eval_and_get_line "$1" "gamemode $player $mode" "${SERVER_CONFIRM_GAMEMODE[$1]}" "${SERVER_CONFIRM_GAMEMODE_FAIL_NO_USER[$1]}" "${SERVER_CONFIRM_GAMEMODE_FAIL_NO_CHANGE[$1]}"
line="$RETURN"
regex="${LOG_REGEX} ${SERVER_CONFIRM_GAMEMODE[$1]}"
if [[ "$line" =~ $regex ]]; then
echo "Changed game mode of \"$player\" to \"$2\"."
fi
regex="${LOG_REGEX} ${SERVER_CONFIRM_GAMEMODE_FAIL_NO_USER[$1]}"
if [[ "$line" =~ $regex ]]; then
echo "The player \"$player\" was not found to be logged on."
fi
regex="${LOG_REGEX} ${SERVER_CONFIRM_GAMEMODE_FAIL_NO_CHANGE[$1]}"
if [[ "$line" =~ $regex ]]; then
echo "The player \"$player\" was already in mode \"$2\"."
fi
server_command "$1" GAMEMODE player="$player" mode="$2"
echo_fallback "$RETURN" "Player $player has been kicked."
done
else
error_exit SERVER_STOPPED "Server \"${SERVER_NAME[$1]}\" is not running."
@ -2648,23 +2660,9 @@ command_server_gamemode() {
# $2->: The player name
command_server_kick() {
if server_is_running "$1"; then
local line regex
server_property "$1" CONFIRM_KICK
server_property "$1" CONFIRM_KICK_FAIL
for player in "${@:2}"; do
server_eval_and_get_line "$1" "kick $player" "${SERVER_CONFIRM_KICK[$1]}" "${SERVER_CONFIRM_KICK_FAIL[$1]}"
line="$RETURN"
regex="${LOG_REGEX} ${SERVER_CONFIRM_KICK[$1]}"
if [[ "$line" =~ $regex ]]; then
echo "Kicked \"$player\" from game."
fi
regex="${LOG_REGEX} ${SERVER_CONFIRM_KICK_FAIL[$1]}"
if [[ "$line" =~ $regex ]]; then
echo "The player \"$player\" is not connected."
fi
server_command "$1" KICK player="$player"
echo_fallback "$RETURN" "Player $player has been kicked."
done
else
error_exit SERVER_STOPPED "Server \"${SERVER_NAME[$1]}\" is not running."
@ -2676,8 +2674,8 @@ command_server_kick() {
# $2->: Words of the message, will be concatinated with spaces
command_server_say() {
if server_is_running "$1"; then
server_eval "$1" "say ${*:2}"
echo "Message sent to players."
server_command "$1" SAY message="${*:2}"
echo_fallback "$RETURN" "Message sent to players."
else
error_exit SERVER_STOPPED "Server \"${SERVER_NAME[$1]}\" is not running."
fi
@ -2688,22 +2686,8 @@ command_server_say() {
# $2: The time
command_server_time_set() {
if server_is_running "$1"; then
local line regex
server_property "$1" CONFIRM_TIME_SET
server_property "$1" CONFIRM_TIME_SET_FAIL
server_eval_and_get_line "$1" "time set $2" "${SERVER_CONFIRM_TIME_SET[$1]}" "${SERVER_CONFIRM_TIME_SET_FAIL[$1]}"
line="$RETURN"
regex="${LOG_REGEX} ${SERVER_CONFIRM_TIME_SET[$1]}"
if [[ "$line" =~ $regex ]]; then
echo "Set time to \"$2\"."
fi
regex="${LOG_REGEX} ${SERVER_CONFIRM_TIME_SET_FAIL[$1]}"
if [[ "$line" =~ $regex ]]; then
error_exit INVALID_ARGUMENT "Unable to convert \"$2\" to a time."
fi
server_command "$1" TIME_SET time="$2"
echo_fallback "$RETURN" "Time set to $2."
else
error_exit SERVER_STOPPED "Server \"${SERVER_NAME[$1]}\" is not running."
fi
@ -2714,22 +2698,8 @@ command_server_time_set() {
# $2: The time to add
command_server_time_add() {
if server_is_running "$1"; then
local line regex
server_property "$1" CONFIRM_TIME_ADD
server_property "$1" CONFIRM_TIME_ADD_FAIL
server_eval_and_get_line "$1" "time add $2" "${SERVER_CONFIRM_TIME_ADD[$1]}" "${SERVER_CONFIRM_TIME_ADD_FAIL[$1]}"
line="$RETURN"
regex="${LOG_REGEX} ${SERVER_CONFIRM_TIME_ADD[$1]}"
if [[ "$line" =~ $regex ]]; then
echo "Added \"$2\" to time."
fi
regex="${LOG_REGEX} ${SERVER_CONFIRM_TIME_ADD_FAIL[$1]}"
if [[ "$line" =~ $regex ]]; then
error_exit INVALID_ARGUMENT "Unable to convert \"$2\" to a time."
fi
server_command "$1" TIME_ADD time="$2"
echo_fallback "$RETURN" "Time increased by $2."
else
error_exit SERVER_STOPPED "Server \"${SERVER_NAME[$1]}\" is not running."
fi
@ -2739,22 +2709,8 @@ command_server_time_add() {
# $1: The server ID
command_server_toggledownfall() {
if server_is_running "$1"; then
local line regex
server_property "$1" CONFIRM_TOGGLEDOWNFALL
server_property "$1" CONFIRM_TOGGLEDOWNFALL_FAIL
server_eval_and_get_line "$1" "toggledownfall" "${SERVER_CONFIRM_TOGGLEDOWNFALL[$1]}" "${SERVER_CONFIRM_TOGGLEDOWNFALL_FAIL[$1]}"
line="$RETURN"
regex="${LOG_REGEX} ${SERVER_CONFIRM_TOGGLEDOWNFALL[$1]}"
if [[ "$line" =~ $regex ]]; then
echo "${line:36}"
fi
regex="${LOG_REGEX} ${SERVER_CONFIRM_TOGGLEDOWNFALL_FAIL[$1]}"
if [[ "$line" =~ $regex ]]; then
echo "${line:34}"
fi
server_command "$1" TOGGLEDOWNFALL
echo_fallback "$RETURN" "Downfall toggled."
else
error_exit SERVER_STOPPED "Server \"${SERVER_NAME[$1]}\" is not running."
fi
@ -2768,31 +2724,10 @@ command_server_toggledownfall() {
# $5: The entity damage value
command_server_give() {
if server_is_running "$1"; then
local line regex
if [[ "$3" =~ ^\-[0-9]+$ ]]; then
error_exit INVALID_ARGUMENT "Item ID \"$3\" must be a positive integer or string."
fi
server_property "$1" CONFIRM_GIVE
server_property "$1" CONFIRM_GIVE_FAIL_NO_USER
server_property "$1" CONFIRM_GIVE_FAIL_NO_ITEM
server_eval_and_get_line "$1" "give $2 $3 $4 $5" "${SERVER_CONFIRM_GIVE[$1]}" "${SERVER_CONFIRM_GIVE_FAIL_NO_USER[$1]}" "${SERVER_CONFIRM_GIVE_FAIL_NO_ITEM[$1]}"
line="$RETURN"
regex="${LOG_REGEX} ${SERVER_CONFIRM_GIVE[$1]}"
if [[ "$line" =~ $regex ]]; then
echo "${line:36}"
fi
regex="${LOG_REGEX} ${SERVER_CONFIRM_GIVE_FAIL_NO_USER[$1]}"
if [[ "$line" =~ $regex ]]; then
echo "${line:27}"
fi
regex="${LOG_REGEX} ${SERVER_CONFIRM_GIVE_FAIL_NO_ITEM[$1]}"
if [[ "$line" =~ $regex ]]; then
echo "${line:27}"
fi
server_command "$1" GIVE player="$2" item="$3" amount="$4" damage="$5"
local amount="x1"
[ ! -z "$4" ] && amount="x$4"
echo_fallback "$RETURN" "Given item $3 ${amount} to $2."
else
error_exit SERVER_STOPPED "Server \"${SERVER_NAME[$1]}\" is not running."
fi
@ -2804,27 +2739,8 @@ command_server_give() {
# $3: The amount of XP to give (can be negative)
command_server_xp() {
if server_is_running "$1"; then
local line regex
server_property "$1" CONFIRM_XP
server_property "$1" CONFIRM_XP_FAIL_NO_USER
server_property "$1" CONFIRM_XP_FAIL_INVALID_AMOUNT
server_eval_and_get_line "$1" "xp $2 $3" "${SERVER_CONFIRM_XP[$1]}" "${SERVER_CONFIRM_XP_FAIL_NO_USER[$1]}" "${SERVER_CONFIRM_XP_FAIL_INVALID_AMOUNT[$1]}"
line="$RETURN"
regex="${LOG_REGEX} ${SERVER_CONFIRM_XP[$1]}"
if [[ "$line" =~ $regex ]]; then
echo "${line:36}"
fi
regex="${LOG_REGEX} ${SERVER_CONFIRM_XP_FAIL_NO_USER[$1]}"
if [[ "$line" =~ $regex ]]; then
echo "${line:27}"
fi
regex="${LOG_REGEX} ${SERVER_CONFIRM_XP_FAIL_INVALID_AMOUNT[$1]}"
if [[ "$line" =~ $regex ]]; then
echo "${line:27}"
fi
server_command "$1" XP player="$2" amount="$3"
echo_fallback "$RETURN" "Given $3 experience to $2."
else
error_exit SERVER_STOPPED "Server \"${SERVER_NAME[$1]}\" is not running."
fi
@ -2870,8 +2786,9 @@ command_server_cmdlog() {
server_property "$1" USERNAME
echo "Now watching logs (press Ctrl+C to exit):"
echo "..."
server_eval "$1" "${*:2}"
as_user "${SERVER_USERNAME[$1]}" "tail --pid=$$ --follow --lines=0 --sleep-interval=0.1 ${SERVER_LOG_PATH[$1]}"
as_user "${SERVER_USERNAME[$1]}" "tail --pid=$$ --follow --lines=5 --sleep-interval=0.1 ${SERVER_LOG_PATH[$1]}"
else
error_exit SERVER_STOPPED "Server \"${SERVER_NAME[$1]}\" is not running."
fi
@ -2987,6 +2904,7 @@ register_settings() {
register_setting SERVER_STORAGE_PATH "/opt/msm/servers"
register_setting JAR_STORAGE_PATH "/opt/msm/jars"
register_setting VERSIONING_STORAGE_PATH "/opt/msm/versioning"
register_setting VERSIONING_FILE_EXTENSION "sh"
register_setting RAMDISK_STORAGE_PATH "/dev/shm/msm"
register_setting UPDATE_URL "https://raw.github.com/marcuswhybrow/minecraft-server-manager/latest"
@ -3566,6 +3484,7 @@ load_versions() {
local version_type="$(basename "$dir")"
VERSIONS[$VERSIONS_COUNT]="${version_type}/$version"
VERSIONS_PATH[$VERSIONS_COUNT]="$path"
VERSIONS_COUNT=$(( $VERSIONS_COUNT + 1 ))
done < <(find "$SETTINGS_VERSIONING_STORAGE_PATH" -mindepth 1 -type f -print0)
@ -3582,9 +3501,6 @@ get_closest_version() {
local given_type="${1%/*}"
local given_version="${1##*/}"
echo $given_type
echo $given_version
local closest_version cv_val
local v v_version v_type v_full v_val given_val
@ -3675,6 +3591,10 @@ interrupt() {
echo "Server \"${SERVER_NAME[$i]}\" restart was aborted."
fi
done
# Clean up the temp directory created for downloads
# as_user "root" "rm -rf \"${output_dir}\""
exit
}
@ -3687,6 +3607,70 @@ interrupt() {
### Versioning Functions
### --------------------
# Sources another versioning file
# $1: The name of the versioning file
extends() {
manager_property VERSIONING_STORAGE_PATH
source "${SETTINGS_VERSIONING_STORAGE_PATH}/$1.${SETTINGS_VERSIONING_FILE_EXTENSION}"
}
# Defines a servers console event variables, VERSIONING_SERVER_ID
# must be set before calling this function
# $1: The name of the event
# $2->: The log lines to accept as confirmation
console_event() {
# Build a regex with all lines in
local lines="$2"
for line in "${@:3}"; do
lines="$lines|$line"
done
# Set server variable
eval SERVER_CONSOLE_EVENT_$1[$VERSIONING_SERVER_ID]=\"$lines\"
}
# Defines a servers console command variables, VERSIONING_SERVER_ID
# must be set before calling this function
# $1: The name of the command
# $2: The command pattern
# $3->: The log lines ot accept as confirmation
console_command() {
local command_name command_timeout
if [[ "$1" =~ (.*):(.*) ]]; then
# If there is a colon in the name, use that
# to extract the included delay
command_name="${BASH_REMATCH[1]}"
command_timeout="${BASH_REMATCH[2]}"
else
command_name="$1"
command_timeout="1"
fi
eval SERVER_CONSOLE_COMMAND_PATTERN_${command_name}[$VERSIONING_SERVER_ID]=\"$2\"
# Build a regex with all lines in
local lines="$3"
for line in "${@:4}"; do
lines="$lines|$line"
done
eval SERVER_CONSOLE_COMMAND_OUTPUT_${command_name}[$VERSIONING_SERVER_ID]=\"$lines\"
eval SERVER_CONSOLE_COMMAND_TIMEOUT_${command_name}[$VERSIONING_SERVER_ID]=\"$command_timeout\"
}
### Starting Code
### -------------
@ -3700,7 +3684,6 @@ main() {
# 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 command's handler function with positional
# arguments containing any "variable" strings.
@ -3720,5 +3703,6 @@ else
# Just register settings instead.
register_settings
load_versions
allocate
fi

View File

@ -0,0 +1,3 @@
# MSM version file for CraftBukkit 1.2.0 and above
extends "minecraft/1.2.0"

View File

@ -1 +0,0 @@
extends: minecraft/1.2.0

View File

@ -0,0 +1,3 @@
# MSM version file for CraftBukkit 1.3.0 and above
extends "minecraft/1.3.0"

View File

@ -1 +0,0 @@
extends: minecraft/1.3.0

View File

@ -0,0 +1,54 @@
# MSM version file for Minecraft 1.2.0 and above
console_event start "Done"
console_command WHITELIST_ON "whitelist on"
console_command WHITELIST_OFF "whitelist off"
console_command WHITELIST_ADD "whitelist add <player>"
console_command WHITELIST_REMOVE "whitelist remove <player>"
console_command WHITELIST_LIST "whitelist list"
console_command WHITELIST_RELOAD "whitelist reload"
console_command BLACKLIST_PLAYER_ADD "ban <player>"
console_command BLACKLIST_PLAYER_REMOVE "pardon <player>"
console_command BLACKLIST_PLAYER_LIST "banlist"
console_command BLACKLIST_IP_ADD "ban-ip <address>"
console_command BLACKLIST_IP_REMOVE "pardon-ip <address>"
console_command BLACKLIST_IP_LIST "banlist ips"
console_command OP_ADD "op <player>"
console_command OP_REMOVE "deop <player>"
console_command GAMEMODE "gamemode <player> <mode>" \
"CONSOLE: Setting <player> to game mode (1|0)" \
"Can't find user <player>" \
"<player> already has game mode (1|0)"
console_command KICK "kick <player>" \
"CONSOLE: Kicking <player>" \
"Can't find user <player>"
console_command SAY "say <message>"
console_command TOGGLEDOWNFALL "toggledownfall" \
"CONSOLE: Toggling downfall (on|off) for world" \
"No world exists with the name"
console_command GIVE "give <player> <item> <amount> <damage>" \
"CONSOLE: Giving <player> some .+ (.+)" \
"Can't find user <player>" \
"There's no item called <item>"
console_command XP "xp <player> <amount>" \
"CONSOLE: Giving <amount> exp to <player>" \
"Can't find user <player>" \
"Invalid exp count: <amount>"
console_command TIME_SET "time set <time>" \
"CONSOLE: Set time to <time>" \
"Unable to convert time value"
console_command TIME_ADD "time add <time>" \
"CONSOLE: Added <time> to time" \
"Unable to convert time value"
console_command SAVE_ON "save-on" \
"CONSOLE: Enabling level saving.."
console_command SAVE_OFF "save-off" \
"CONSOLE: Disabling level saving.."
console_command SAVE_ALL:10 "save-all" \
"CONSOLE: Save complete."

View File

@ -1,92 +0,0 @@
log-confirmations:
events:
start: "Done"
commands:
whitelist-on:
pattern: "whitelist on"
whitelist-off:
pattern: "whitelist off"
whitelist-add:
pattern: "whitelist add <player>"
whitelist-remove:
pattern: "whitelist remove <player>"
whitelist-list:
pattern: "whitelist list"
whitelist-reload:
pattern: "whitelist reload"
blacklist-player-add:
pattern: "ban <player>"
blacklist-player-remove:
pattern: "pardon <player>"
blacklist-player-list:
pattern: "banlist"
blacklist-ip-add:
pattern: "ban-ip <address>"
blacklist-ip-remove:
pattern: "pardon-ip <address>"
blacklist-ip-list:
pattern: "banlist ips"
op-add:
pattern: "op <player>"
op-remove:
pattern: "deop <player>"
gamemode:
pattern: "gamemode <player> <mode>"
output:
- "CONSOLE: Setting <player> to game mode (1|0)"
- "Can't find user <player>"
- "<player> already has game mode (1|0)"
kick:
pattern: "kick <player>"
output:
- "CONSOLE: Kicking <player>"
- "Can't find user <player>"
say:
pattern: "say <message>"
time-set:
pattern: "time set <time>"
output:
- "CONSOLE: Set time to <time>"
- "Unable to convert time value"
time-add:
pattern: "time add <time>"
output:
- "CONSOLE: Added <time> to time"
- "Unable to convert time value"
toggledownfall:
pattern: "toggledownfall"
output:
- "CONSOLE: Toggling downfall (on|off) for world"
- "No world exists with the name"
give:
pattern: "give <player> <item> <amount> <damage>"
output:
- "CONSOLE: Giving <player> some .+ (.+)"
- "Can't find user <player>"
- "There's no item called <item>"
xp:
pattern: "xp <player> <amount>"
output:
- "CONSOLE: Giving <amount> exp to <player>"
- "Can't find user <player>"
- "Invalid exp count: <amount>"
save-on:
pattern: "save-on"
output: "CONSOLE: Enabling level saving.."
save-off:
pattern: "save-off"
output: "CONSOLE: Disabling level saving.."
save-all:
pattern: "save-all"
output: "CONSOLE: Save complete."
timeout: 10

View File

@ -0,0 +1,42 @@
# MSM version file for Minecraft 1.3.0 and above
extends "minecraft/1.2.0"
console_command GAMEMODE "gamemode <mode> <player>" \
"That player cannot be found" \
"The number you have entered (<mode>) is too big, it must be at most 2" \
"The number you have entered (<mode>) is too small, it must be at least 0"
console_command KICK "kick <player>" \
"Kicked <player> from the game" \
"That player cannot be found"
console_command TIME_SET "time set <time>" \
"Set the time to <time>" \
"The number you have entered (<time>) is too small, it must be at least 0" \
"'<time>' is not a valid number"
console_command TIME_ADD "time add <time>" \
"Added <time> to the time" \
"The number you have entered (<time>) is too small, it must be at least 0" \
"'<time>' is not a valid number"
console_command TOGGLEDOWNFALL "toggledownfall" \
"Toggled downfall"
console_command GIVE "give <player> <item> <amount> <damage>" \
"Given .+ (ID <item>) \* <amount> to <player>" \
"That player cannot be found" \
"'<item>' is not a valid number"
console_command XP "xp <amount> <player>" \
"Given <amount> experience to <player>" \
"That player cannot be found" \
"'<amount>' is not a valid number" \
"The number you have entered (<amount>) is too small, it must be at least 0"
console_command SAVE_ON "save-on" \
"Turned on world auto-saving"
console_command SAVE_OFF "save-off" \
"Turned off world auto-saving"
console_command SAVE_ALL:10 "save-all" \
"Saved the world"

View File

@ -1,55 +0,0 @@
extends: minecraft/1.2.0
log-confirmations:
commands:
gamemode:
pattern: "gamemode <mode> <player>"
output: "That player cannot be found"
kick:
pattern: "kick <player>"
output:
- "Kicked <player> from the game"
- "That player cannot be found"
time-set:
pattern: "time set <time>"
output:
- "Set the time to <time>"
- "The number you have entered (<time>) is too small, it must be at least 0"
- "'<time>' is not a valid number"
time-add:
pattern: "time add <time>"
output:
- "Added <time> to the time"
- "The number you have entered (<time>) is too small, it must be at least 0"
- "'<time>' is not a valid number"
toggledownfall:
pattern: "toggledownfall"
output: "Toggled downfall"
give:
pattern: "give <player> <item> <amount> <damage>"
output:
- "Given .+ (ID <item>) * <amount> to <player>"
- "That player cannot be found"
- "'<item>' is not a valid number"
xp:
pattern: "xp <amount> <player>"
output:
- "Given <amount> experience to <player>"
- "That player cannot be found"
- "'<amount>' is not a valid number"
- "The number you have entered (<amount>) is too small, it must be at least 0"
save-on:
pattern: "save-on"
output: "Turned on world auto-saving"
save-off:
pattern: "save-off"
output: "Turned off world auto-saving"
save-all:
pattern: "save-all"
output: "Saved the world"
timeout: 10