From e3469b4d532f2f69cfd3710851af08d9545e5044 2021-02-10 21:22:57 From: Branko Majic <branko@majic.rs> Date: 2021-02-10 21:22:57 Subject: [PATCH] Noticket: [factorio_manager.sh] Added commands for renaming and resetting the server map: - Bumped the version as well. - Added check for validating that a directory contains a server instance. - Minor cleanup of an extra blank line and variable assignment. --- diff --git a/games/factorio_manager.sh b/games/factorio_manager.sh index 9b6393607c3a5fcd11ec9644e5fec6321947469f..2a904054b45b1b250fd61507bb5d0e841311a266 100755 --- a/games/factorio_manager.sh +++ b/games/factorio_manager.sh @@ -22,7 +22,7 @@ set -u program="factorio_manager.sh" -version="0.3.1" +version="0.4.0" function synopsis() { cat <<EOF @@ -35,10 +35,12 @@ Usage: $program [OPTIONS] create INSTANCE $program [OPTIONS] create-server INSTANCE + $program [OPTIONS] rename CURRENT_NAME NEW_NAME $program [OPTIONS] copy SOURCE_INSTANCE DESTINATION_INSTANCE $program [OPTIONS] remove INSTANCE $program [OPTIONS] import INSTANCE SOURCE_DIRECTORY $program [OPTIONS] set-version INSTANCE + $program [OPTIONS] reset-server-map INSTANCE $program [OPTIONS] versions $program [OPTIONS] install GAME_ARCHIVE @@ -96,7 +98,6 @@ backup INSTANCE [DESCRIPTION] easier to distinguish between different backups. Hidden files (names starting with '.') will be omitted from the backup. - copy SOURCE_INSTANCE DESTINATION_INSTANCE Creates a copy of an existing instance. Requires name of an @@ -175,6 +176,12 @@ remove INSTANCE Removes the specified instance. User must confirm the action prior to any files being removed. +rename CURRENT_NAME NEW_NAME + + Renames an existing instnace. Requires current name of an + instance, as well as a new name. Command will refuse to rename the + instance if an instance with specified new name already exists. + restore INSTANCE BACKUP_NAME Restores the specified instance from the specified backup. User @@ -940,6 +947,9 @@ function read_server_settings() { # game_archive # Checks if file at designated path is a valid game archive. # +# server_instance_directory +# Checks if path contains a valid server instance. +# # $2 (path) # Path that should be validated. # @@ -1035,6 +1045,28 @@ function validate_path_or_terminate() { error "Supplied path does not point to a valid game archive." exit "$ERROR_ARGUMENTS" fi + + elif [[ $path_test == "server_instance_directory" ]]; then + if [[ ! -d $path ]]; then + error "Missing instance directory: $path" + error "Perhaps you have misstyped the instance name or forgot to create one first?" + exit "$exit_code" + fi + + if [[ ! -f $path/instance.conf ]]; then + error "Missing instance configuration file: $path/instance.conf" + exit "$exit_code" + fi + + if [[ ! -f $path/config.ini ]]; then + error "Missing game configuration file: $path/config.ini" + exit "$exit_code" + fi + + if [[ ! -f $path/server-settings.json ]]; then + error "Missing server settings file: $path/server-settings.json" + exit "$exit_code" + fi else error "Unable to validate path '$path', unsupported test requested: '$path_test'." exit "$ERROR_GENERAL" @@ -2287,8 +2319,6 @@ elif [[ $command == create-server ]]; then # Make sure game installations directory has been set. validate_path_or_terminate "game_installations_directory" "$game_installations_directory" "$ERROR_CONFIGURATION" - instance="${1-}" - # Read positional arguments. instance="${1-}" shift @@ -2500,6 +2530,148 @@ elif [[ $command == install ]]; then fi success "Successfully installed game version: $(colorecho -n green "$game_version")" + + +#==================# +# reset-server-map # +#==================# +elif [[ $command == reset-server-map ]]; then + + # Make sure game installations directory has been set. + validate_path_or_terminate "game_installations_directory" "$game_installations_directory" "$ERROR_CONFIGURATION" + + # Read positional arguments. + instance="${1-}" + shift + + # Calculate derived variables. + instance_directory="$manager_directory/$instance" + instance_config="$instance_directory/instance.conf" + game_config="$instance_directory/config.ini" + server_config="$instance_directory/server-settings.json" + main_save="$instance_directory/saves/default.zip" + + # Verify arguments. + if [[ -z $instance ]]; then + error "Missing argument: INSTANCE" + exit "$ERROR_ARGUMENTS" + fi + + # Validate that instance directory contains valid instance. + validate_path_or_terminate "server_instance_directory" "$instance_directory" "$ERROR_ARGUMENTS" + + # Update instance write directory prior to launching - this is a + # failsafe in case it got changed by hand or perhaps the value + # comes from backups of a copied instance. + current_write_data=$(grep "^write-data=" "$game_config") + expected_write_data="write-data=${instance_directory}" + + if [[ $current_write_data != "$expected_write_data" ]]; then + warning "Incorrect path specified for write-data in game configuration file: $game_config" + warning "Current configuration is: $current_write_data" + warning "Configuration will be replaced with: $expected_write_data" + sed -i -e "s#^write-data=.*#$expected_write_data#" "$game_config" + fi + + # Read launcher configuration for the instance. + # shellcheck source=/dev/null + source "$instance_config" + + if [[ -z $game_version ]]; then + error "Missing game version information in $game_config." + exit "$ERROR_CONFIGURATION" + fi + + # Set-up paths for launching the game, and ensure they still exist + # (versions can be removed by user). + game_directory="${game_installations_directory}/${game_version}" + factorio_bin="$game_directory/bin/x64/factorio" + + if [[ ! -e $factorio_bin ]]; then + error "Could not locate Factorio binary under: $factorio_bin" + error "Factorio $game_version installation may have been removed from game installations directory:" + error " $(readlink -f "$game_installations_directory")" + exit "$ERROR_CONFIGURATION" + fi + + # Request from user to confirm the destructive action. + critical_confirmation "Resetting the server map will wipe the default save game as well." \ + "Aborted server map reset, no changes have been made to instance files." \ + "$ERROR_GENERAL" + + if ! rm -f "$main_save"; then + error "Could not remove the default save game." + exit "$ERROR_GENERAL" + fi + + if ! "$factorio_bin" --config "$game_config" --create "$main_save"; then + error "Failed to generate default savegame/map under: $main_save" + exit "$ERROR_GENERAL" + fi + + +#========# +# rename # +#========# +elif [[ $command == rename ]]; then + + # Make sure game installations directory has been set. + validate_path_or_terminate "game_installations_directory" "$game_installations_directory" "$ERROR_CONFIGURATION" + + # Read positional arguments. + current_name="${1-}" + new_name="${2-}" + shift 2 + + # Verify positional arguments. + if [[ -z $current_name ]]; then + error "Missing argument: CURRENT_NAME" + exit "$ERROR_ARGUMENTS" + fi + + if [[ -z $new_name ]]; then + error "Missing argument: NEW_NAME" + exit "$ERROR_ARGUMENTS" + fi + + if [[ $current_name == "$new_name" ]]; then + error "New name must differ from current name." + + exit "$ERROR_ARGUMENTS" + fi + + # Calculate derived variables. + current_instance_directory="$manager_directory/$current_name" + current_instance_config="$current_instance_directory/instance.conf" + current_instance_lock_file="$current_instance_directory/.lock" + new_instance_directory="$manager_directory/$new_name" + + # Validate that source instance directory contains valid instance. + validate_path_or_terminate "instance_directory" "$current_instance_directory" "$ERROR_ARGUMENTS" + + # Make sure destination instance directory can be used. + validate_path_or_terminate "instance_directory_new" "$new_instance_directory" "$ERROR_ARGUMENTS" + + ( + # shellcheck disable=SC2094 # Lock file is not being read from. + lock "$current_instance_lock_file" 200 + + # Load source instance configuration. + # shellcheck source=/dev/null + source "$current_instance_config" + + # Rename the instance. + mv "$current_instance_directory" "$new_instance_directory" + + # Update write-data directory of destination instance, + # including the backups. + write_data="write-data=${new_instance_directory}" + find "$new_instance_directory/" -type f -name config.ini -exec \ + sed -i -e "s#^write-data=.*#$write_data#" '{}' \; + + success "Renamed instance $(colorecho -n green "$current_name") to $(colorecho -n green "$new_name")." + + ) 200>"$current_instance_lock_file" else error "Invalid command: $command"