diff --git a/games/factorio_manager.sh b/games/factorio_manager.sh index 7010d0b6a94f44b34513993ae1dde7f8c3821957..41e7f53b70d8f24c7d09925c3591f9940bb758a3 100755 --- a/games/factorio_manager.sh +++ b/games/factorio_manager.sh @@ -843,10 +843,22 @@ function read_server_settings() { # instance_directory_new # Checks if path is unused and can be used for new instance. # +# instance_directory +# Checks if path contains a valid instance. +# +# backup_directory_new +# Checks if path is usable as destination for a new backup. +# +# backup_directory +# Checks if path contains a valid backup. +# +# instance_import_source +# Checks if path is usable as source for importing an instance. +# # $2 (path) # Path that should be validated. # -# $3 (exit_code0 +# $3 (exit_code) # Exit code to use when terminating the program. # # Exits: @@ -877,6 +889,57 @@ function validate_path_or_terminate() { error "Instance directory already exists, but does not contain a valid Factorio instance: $path." exit "$exit_code" fi + + elif [[ $path_test == "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 + + elif [[ $path_test == "backup_directory_new" ]]; then + if [[ -e $path/config.ini ]]; then + error "Backup already exists under directory: $path" + exit "$exit_code" + elif [[ -e $path ]]; then + error "Backup directory already exists, but does not contain a valid backup: $path" + exit "$exit_code" + fi + + elif [[ $path_test == "backup_directory" ]]; then + + if [[ ! -d $path ]]; then + error "Specified backup not available under: $path" + exit "$ERROR_ARGUMENTS" + fi + + if [[ ! -f $path/instance.conf ]]; then + error "Backup missing instance configuration file: $path/instance.conf" + exit "$exit_code" + fi + + if [[ ! -f $path/config.ini ]]; then + error "Backup missing game configuration file: $path/config.ini" + exit "$exit_code" + fi + + elif [[ $path_test == "instance_import_source" ]]; then + if [[ ! -f $path/bin/x64/factorio ]]; then + error "Could not locate Factorio binary in directory under: $path/bin/x64/factorio" + error "Factorio Manager natively supports instance imports only when all game data (savegames etc) are stored within Factorio installation directory." + exit "$ERROR_ARGUMENTS" + fi + else error "Unable to validate path '$path', unsupported test requested: '$path_test'." exit "$ERROR_GENERAL" @@ -1010,6 +1073,7 @@ fi command="$1" shift + #==============# # set-game-dir # #==============# @@ -1054,11 +1118,13 @@ if [[ $command == set-game-dir ]]; then exit "$ERROR_GENERAL" fi + #==========# # versions # #==========# elif [[ $command == versions ]]; then + # Make sure game installations directory has been set. validate_path_or_terminate "game_installations_directory" "$game_installations_directory" "$ERROR_CONFIGURATION" echo "Locally available Factorio versions:" @@ -1072,10 +1138,15 @@ elif [[ $command == versions ]]; then done echo + #======# # list # #======# elif [[ $command == list ]]; then + + # Make sure game installations directory has been set. + validate_path_or_terminate "game_installations_directory" "$game_installations_directory" "$ERROR_CONFIGURATION" + echo "Available instances:" echo @@ -1088,10 +1159,13 @@ elif [[ $command == list ]]; then done echo + #========# # create # #========# elif [[ $command == create ]]; then + + # Make sure game installations directory has been set. validate_path_or_terminate "game_installations_directory" "$game_installations_directory" "$ERROR_CONFIGURATION" # Read positional arguments. @@ -1109,6 +1183,7 @@ elif [[ $command == create ]]; then exit "$ERROR_ARGUMENTS" fi + # Make sure new instance directory can be used. validate_path_or_terminate "instance_directory_new" "$instance_directory" "$ERROR_ARGUMENTS" select_factorio_version "$game_installations_directory" || exit "$ERROR_GENERAL" @@ -1159,8 +1234,15 @@ EOF warning "Factorio will offer to fix the corrupted configuration file by filling-in the missing information during the first startup." warning "It should be safe to accept this. This warning will be shown by Factorio only the first time." + +#========# +# launch # +#========# elif [[ $command == launch ]]; 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 @@ -1177,19 +1259,12 @@ elif [[ $command == launch ]]; then exit "$ERROR_ARGUMENTS" fi - if [[ ! -f $instance_config ]]; then - error "Missing instance configuration file: $instance_config" - exit "$ERROR_GENERAL" - fi - - if [[ ! -f $game_config ]]; then - error "Missing game configuration file: $game_config" - exit "$ERROR_GENERAL" - fi + # Validate that instance directory contains valid instance. + validate_path_or_terminate "instance_directory" "$instance_directory" "$ERROR_ARGUMENTS" # Update instance write directory prior to launching - this is a - # failsafe in case it got changed by hand through some other means - # (or maybe it was copied over from another instance). + # 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}" @@ -1227,7 +1302,15 @@ elif [[ $command == launch ]]; then "$factorio_bin" --config "$game_config" fi + +#========# +# backup # +#========# elif [[ $command == backup ]]; 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-}" description="${2-}" @@ -1252,22 +1335,11 @@ elif [[ $command == backup ]]; then exit "$ERROR_ARGUMENTS" fi - # Verify that we are trying to backup an actual instance. - if [[ ! -f $instance_config ]]; then - error "Missing instance configuration file: $instance_config" - exit "$ERROR_GENERAL" - fi - - if [[ ! -f $game_config ]]; then - error "Missing game configuration file: $game_config" - exit "$ERROR_GENERAL" - fi + # Validate that instance directory contains valid instance. + validate_path_or_terminate "instance_directory" "$instance_directory" "$ERROR_ARGUMENTS" - # Make sure we do not overwrite the backup destination by mistake - # - although highly unlikely unless user spams the backup command. - if [[ -e $backup_destination ]]; then - error "Backup already exists: $backup_destination" - fi + # Validate destination path for backup directory can be used. + validate_path_or_terminate "backup_directory_new" "$backup_destination" "$ERROR_GENERAL" ( @@ -1302,6 +1374,7 @@ elif [[ $command == backup ]]; then ) 200>"$lock_file" + #==============# # list-backups # #==============# @@ -1323,21 +1396,8 @@ elif [[ $command == list-backups ]]; then exit "$ERROR_ARGUMENTS" fi - # Verify instance. - if [[ ! -d $instance_directory ]]; then - error "No such instance: $instance" - exit "$ERROR_ARGUMENTS" - fi - - if [[ ! -f $instance_config ]]; then - error "Missing instance configuration file: $instance_config" - exit "$ERROR_GENERAL" - fi - - if [[ ! -f $game_config ]]; then - error "Missing game configuration file: $game_config" - exit "$ERROR_GENERAL" - fi + # Validate that instance directory contains valid instance. + validate_path_or_terminate "instance_directory" "$instance_directory" "$ERROR_ARGUMENTS" # Extended regular expression for matching YYYY-MM-DD-hh:mm:ss format. backup_destination_name_pattern="[[:digit:]]{4}-[[:digit:]]{2}-[[:digit:]]{2}_[[:digit:]]{2}:[[:digit:]]{2}:[[:digit:]]{2}" @@ -1377,11 +1437,15 @@ elif [[ $command == list-backups ]]; then fi + #=========# # restore # #=========# elif [[ $command == restore ]]; 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-}" backup_name="${2-}" @@ -1405,26 +1469,11 @@ elif [[ $command == restore ]]; then exit "$ERROR_ARGUMENTS" fi - # Verify we are working with legitimate instance and backup. - if [[ ! -d $instance_directory ]]; then - error "No such instance: $instance" - exit "$ERROR_ARGUMENTS" - fi - - if [[ ! -d $restore_source ]]; then - error "Specified backup not available under: $restore_source" - exit "$ERROR_ARGUMENTS" - fi + # Validate that instance directory contains valid instance. + validate_path_or_terminate "instance_directory" "$instance_directory" "$ERROR_ARGUMENTS" - if [[ ! -f $backup_instance_config ]]; then - error "Invalid backup, missing instance configuration file: $backup_instance_config" - exit "$ERROR_GENERAL" - fi - - if [[ ! -f $backup_game_config ]]; then - error "Invalid backup, missing game configuration file: $backup_game_config" - exit "$ERROR_GENERAL" - fi + # Validate that backup directory contains valid backup. + validate_path_or_terminate "backup_directory" "$restore_source" "$ERROR_ARGUMENTS" ( # Obtain lock - Factorio uses the same mechanism, so we should @@ -1502,11 +1551,15 @@ elif [[ $command == restore ]]; then ) 200>"$lock_file" + #===============# # remove-backup # #===============# elif [[ $command == remove-backup ]]; 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-}" backup_name="${2-}" @@ -1530,26 +1583,11 @@ elif [[ $command == remove-backup ]]; then backup_game_config="$removal_target/config.ini" lock_file="$instance_directory/.lock" - # Verify we are working with legitimate instance and backup. - if [[ ! -d $instance_directory ]]; then - error "No such instance: $instance" - exit "$ERROR_ARGUMENTS" - fi + # Validate that instance directory contains valid instance. + validate_path_or_terminate "instance_directory" "$instance_directory" "$ERROR_ARGUMENTS" - if [[ ! -d $removal_target ]]; then - error "Specified backup not available under: $removal_target" - exit "$ERROR_ARGUMENTS" - fi - - if [[ ! -f $backup_instance_config ]]; then - error "Invalid backup, missing instance configuration file: $backup_instance_config" - exit "$ERROR_GENERAL" - fi - - if [[ ! -f $backup_game_config ]]; then - error "Invalid backup, missing game configuration file: $backup_game_config" - exit "$ERROR_GENERAL" - fi + # Validate that backup directory contains valid backup. + validate_path_or_terminate "backup_directory" "$removal_target" "$ERROR_ARGUMENTS" # Present user with warning. echo @@ -1583,10 +1621,15 @@ elif [[ $command == remove-backup ]]; then success "Backup removed." + #=============# # set-version # #=============# elif [[ $command == set-version ]]; 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 @@ -1597,33 +1640,13 @@ elif [[ $command == set-version ]]; then exit "$ERROR_ARGUMENTS" fi - # Make sure user has set directory with game installations - test - # both symlink and target destination. - if [[ ! -L $game_installations_directory ]]; then - error "Game installations directory has not been properly set. Please run the set-game-dir command first." - exit "$ERROR_CONFIGURATION" - fi - - if [[ ! -d $game_installations_directory ]]; then - error "Game installations directory has not been properly set. Please run the set-game-dir command first." - exit "$ERROR_CONFIGURATION" - fi - # Set-up derived variables. instance_directory="$manager_directory/$instance" instance_config="$instance_directory/instance.conf" game_config="$instance_directory/config.ini" - # Verify we are working with legitimate instance. - if [[ ! -f $instance_config ]]; then - error "Missing instance configuration file: $instance_config" - exit "$ERROR_GENERAL" - fi - - if [[ ! -f $game_config ]]; then - error "Missing game configuration file: $game_config" - exit "$ERROR_GENERAL" - fi + # Validate that instance directory contains valid instance. + validate_path_or_terminate "instance_directory" "$instance_directory" "$ERROR_ARGUMENTS" # Load instance configuration. source "$instance_config" @@ -1642,21 +1665,14 @@ elif [[ $command == set-version ]]; then success "Version changed to: $(colorecho -n green "$game_version_selected")" fi + #======# # info # #======# elif [[ $command == info ]]; then - # Make sure user has set directory with game installations - test - # both symlink and target destination. - if [[ ! -L $game_installations_directory ]]; then - error "Game installations directory has not been properly set. Please run the set-game-dir command first." - exit "$ERROR_CONFIGURATION" - fi - if [[ ! -d $game_installations_directory ]]; then - error "Game installations directory has not been properly set. Please run the set-game-dir command first." - exit "$ERROR_CONFIGURATION" - fi + # 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-}" @@ -1673,16 +1689,8 @@ elif [[ $command == info ]]; then instance_config="$instance_directory/instance.conf" game_config="$instance_directory/config.ini" - # Verify we are working with legitimate instance. - if [[ ! -f $instance_config ]]; then - error "Missing instance configuration file: $instance_config" - exit "$ERROR_GENERAL" - fi - - if [[ ! -f $game_config ]]; then - error "Missing game configuration file: $game_config" - exit "$ERROR_GENERAL" - fi + # Validate that instance directory contains valid instance. + validate_path_or_terminate "instance_directory" "$instance_directory" "$ERROR_ARGUMENTS" # Load instance configuration. source "$instance_config" @@ -1708,7 +1716,7 @@ elif [[ $command == info ]]; then if [[ ${#mod_files[@]} == 0 ]]; then echo "Available mods: none" - # Plain listing. + # Listing using just regular tools. elif ! hash jqs 2>/dev/null; then echo "Available mods:" echo @@ -1748,7 +1756,7 @@ elif [[ $command == info ]]; then done - # Fancy listing with detection for enabled mods using jq. + # Listing using the jq utility. elif hash jq 2>/dev/null; then echo "Available mods (enabled/${_text_yellow}disabled${_text_reset}):" echo @@ -1804,6 +1812,9 @@ elif [[ $command == info ]]; then #========# elif [[ $command == remove ]]; 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 @@ -1819,16 +1830,8 @@ elif [[ $command == remove ]]; then instance_config="$instance_directory/instance.conf" lock_file="$instance_directory/.lock" - # Verify we are working with legitimate instance and backup. - if [[ ! -d $instance_directory ]]; then - error "No such instance: $instance" - exit "$ERROR_ARGUMENTS" - fi - - if [[ ! -f $instance_config ]]; then - error "Missing instance configuration file: $instance_config" - exit "$ERROR_GENERAL" - fi + # Validate that instance directory contains valid instance. + validate_path_or_terminate "instance_directory" "$instance_directory" "$ERROR_ARGUMENTS" ( # Obtain lock - Factorio uses the same mechanism, so we should @@ -1912,17 +1915,8 @@ elif [[ $command == remove ]]; then #======# elif [[ $command == copy ]]; then - # Make sure user has set directory with game installations - test - # both symlink and target destination. - if [[ ! -L $game_installations_directory ]]; then - error "Game installations directory has not been properly set. Please run the set-game-dir command first." - exit "$ERROR_CONFIGURATION" - fi - - if [[ ! -d $game_installations_directory ]]; then - error "Game installations directory has not been properly set. Please run the set-game-dir command first." - exit "$ERROR_CONFIGURATION" - fi + # Make sure game installations directory has been set. + validate_path_or_terminate "game_installations_directory" "$game_installations_directory" "$ERROR_CONFIGURATION" # Read positional arguments. source_instance="${1-}" @@ -1949,22 +1943,10 @@ elif [[ $command == copy ]]; then destination_instance_directory="$manager_directory/$destination_instance" destination_instance_config="$destination_instance_directory/instance.conf" - # Verify we are working with legitimate source and destination. - if [[ ! -d $source_instance_directory ]]; then - error "No such instance: $source_instance" - exit "$ERROR_ARGUMENTS" - fi - - if [[ ! -f $source_instance_config ]]; then - error "Missing instance configuration file: $source_instance_config" - exit "$ERROR_GENERAL" - fi - - if [[ ! -f $source_game_config ]]; then - error "Missing game configuration file: $source_game_config" - exit "$ERROR_GENERAL" - fi + # Validate that source instance directory contains valid instance. + validate_path_or_terminate "instance_directory" "$source_instance_directory" "$ERROR_ARGUMENTS" + # Make sure destination instance directory can be used. validate_path_or_terminate "instance_directory_new" "$destination_instance_directory" "$ERROR_ARGUMENTS" ( @@ -2031,22 +2013,14 @@ elif [[ $command == copy ]]; then ) 200>"$source_lock_file" + #========# # import # #========# elif [[ $command == import ]]; then - # Make sure user has set directory with game installations - test - # both symlink and target destination. - if [[ ! -L $game_installations_directory ]]; then - error "Game installations directory has not been properly set. Please run the set-game-dir command first." - exit "$ERROR_CONFIGURATION" - fi - - if [[ ! -d $game_installations_directory ]]; then - error "Game installations directory has not been properly set. Please run the set-game-dir command first." - exit "$ERROR_CONFIGURATION" - fi + # 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-}" @@ -2072,6 +2046,13 @@ elif [[ $command == import ]]; then source_config="$source_directory/config/config.ini" source_lock_file="$source_directory/.lock" + # Make sure new instance directory can be used. + validate_path_or_terminate "instance_directory_new" "$instance_directory" "$ERROR_ARGUMENTS" + + # Make sure that the import source is valid (should be Factorio + # installation directory). + validate_path_or_terminate "instance_import_source" "$source_directory" "$ERROR_ARGUMENTS" + # List of entries to import from the source directory. declare -A import_entries=() import_entries["achievements-modded.dat"]="contains achivement information for modded plays" @@ -2086,14 +2067,6 @@ elif [[ $command == import ]]; then import_entries["player-data.json"]="contains global information about the player, such as username, login token, chat history, etc." import_entries["saves"]="contains savegames" - validate_path_or_terminate "instance_directory_new" "$instance_directory" "$ERROR_ARGUMENTS" - - if [[ ! -f $source_directory/bin/x64/factorio ]]; then - error "Could not locate Factorio binary in source directory under: $source_directory/bin/x64/factorio" - error "Factorio Manager natively supports instance imports only when all game data (savegames etc) are stored within Factorio installation directory." - exit "$ERROR_ARGUMENTS" - fi - # Display list of available Factorio versions and let user pick one. echo "Factorio version must be selected manually for imported instances." echo @@ -2172,19 +2145,11 @@ EOF # create-server # #===============# elif [[ $command == create-server ]]; then - instance="${1-}" - # Make sure user has set directory with game installations - test - # both symlink and target destination. - if [[ ! -L $game_installations_directory ]]; then - error "Game installations directory has not been properly set. Please run the set-game-dir command first." - exit "$ERROR_CONFIGURATION" - fi + # Make sure game installations directory has been set. + validate_path_or_terminate "game_installations_directory" "$game_installations_directory" "$ERROR_CONFIGURATION" - if [[ ! -d $game_installations_directory ]]; then - error "Game installations directory has not been properly set. Please run the set-game-dir command first." - exit "$ERROR_CONFIGURATION" - fi + instance="${1-}" # Read positional arguments. instance="${1-}" @@ -2204,6 +2169,7 @@ elif [[ $command == create-server ]]; then exit "$ERROR_ARGUMENTS" fi + # Make sure new instance directory can be used. validate_path_or_terminate "instance_directory_new" "$instance_directory" "$ERROR_ARGUMENTS" select_factorio_version "$game_installations_directory" || exit "$ERROR_GENERAL"