diff --git a/.github/workflows/docker-publish.yml b/.github/workflows/docker-publish.yml index b650e6d..022cced 100644 --- a/.github/workflows/docker-publish.yml +++ b/.github/workflows/docker-publish.yml @@ -42,9 +42,9 @@ jobs: # https://github.com/sigstore/cosign-installer - name: Install cosign if: github.event_name != 'pull_request' - uses: sigstore/cosign-installer@6e04d228eb30da1757ee4e1dd75a0ec73a653e06 #v3.1.1 + uses: sigstore/cosign-installer@v3.3.0 with: - cosign-release: 'v2.1.1' + cosign-release: 'v2.2.2' # Set up BuildKit Docker container builder to be able to build # multi-platform images and export cache diff --git a/CHANGELOG.md b/CHANGELOG.md index c2ed838..55bdac4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,16 @@ [Back to main](README.md#changelog) +## 2024-04-06 + +- Disabled recursive Backups by default @Callum027 (#257) + +## 2024-04-04 + +- Fixed rcon-spaces by @Callum027 (#251) +- Added new config options from new default-settings-file +- Bugfix - Change pidof selector to current name "PalServer-Linux-Shipping" by @thijsvanloef + ## 2024-03-04 - Fixed typo diff --git a/Dockerfile b/Dockerfile index 84ac6e4..3be027d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -29,7 +29,7 @@ RUN apt-get update \ && apt-get clean \ && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* - RUN curl -fsSLO "$SUPERCRONIC_URL" \ +RUN curl -fsSLO "$SUPERCRONIC_URL" \ && echo "${SUPERCRONIC_SHA1SUM} ${SUPERCRONIC}" | sha1sum -c - \ && chmod +x "$SUPERCRONIC" \ && mv "$SUPERCRONIC" "/usr/local/bin/${SUPERCRONIC}" \ @@ -86,7 +86,7 @@ ENV DEBIAN_FRONTEND=noninteractive \ RESTART_ENABLED=false \ RESTART_DEBUG_OVERRIDE=false \ RESTART_CRON_EXPRESSION="0 18 * * *" \ - # RCON-Playerdection - NEEDS RCON ENABLED! + # RCON-Playerdetection - NEEDS RCON ENABLED! RCON_PLAYER_DETECTION=true \ RCON_PLAYER_DETECTION_STARTUP_DELAY=60 \ RCON_PLAYER_DETECTION_CHECK_INTERVAL=15 \ @@ -184,7 +184,11 @@ ENV DEBIAN_FRONTEND=noninteractive \ REGION= \ USEAUTH=true \ BAN_LIST_URL=https://api.palworldgame.com/api/banlist.txt \ - SHOW_PLAYER_LIST=false + RESTAPI_ENABLED=true \ + RESTAPI_PORT=8212 \ + SHOW_PLAYER_LIST=false \ + ALLOW_CONNECT_PLATFORM=Steam \ + ENABLE_WORLD_BACKUP=false EXPOSE 8211/udp EXPOSE 25575/tcp diff --git a/configs/PalWorldSettings.ini.template b/configs/PalWorldSettings.ini.template index 149f511..76c9aa4 100644 --- a/configs/PalWorldSettings.ini.template +++ b/configs/PalWorldSettings.ini.template @@ -1,2 +1,2 @@ [/Script/Pal.PalGameWorldSettings] -OptionSettings=(Difficulty=None,DayTimeSpeedRate=1.000000,NightTimeSpeedRate=1.000000,ExpRate=1.000000,PalCaptureRate=1.000000,PalSpawnNumRate=1.000000,PalDamageRateAttack=1.000000,PalDamageRateDefense=1.000000,PlayerDamageRateAttack=1.000000,PlayerDamageRateDefense=1.000000,PlayerStomachDecreaceRate=1.000000,PlayerStaminaDecreaceRate=1.000000,PlayerAutoHPRegeneRate=1.000000,PlayerAutoHpRegeneRateInSleep=1.000000,PalStomachDecreaceRate=1.000000,PalStaminaDecreaceRate=1.000000,PalAutoHPRegeneRate=1.000000,PalAutoHpRegeneRateInSleep=1.000000,BuildObjectDamageRate=1.000000,BuildObjectDeteriorationDamageRate=1.000000,CollectionDropRate=1.000000,CollectionObjectHpRate=1.000000,CollectionObjectRespawnSpeedRate=1.000000,EnemyDropItemRate=1.000000,DeathPenalty=All,bEnablePlayerToPlayerDamage=False,bEnableFriendlyFire=False,bEnableInvaderEnemy=True,bActiveUNKO=False,bEnableAimAssistPad=True,bEnableAimAssistKeyboard=False,DropItemMaxNum=3000,DropItemMaxNum_UNKO=100,BaseCampMaxNum=128,BaseCampWorkerMaxNum=15,DropItemAliveMaxHours=1.000000,bAutoResetGuildNoOnlinePlayers=False,AutoResetGuildTimeNoOnlinePlayers=72.000000,GuildPlayerMaxNum=20,PalEggDefaultHatchingTime=72.000000,WorkSpeedRate=1.000000,bIsMultiplay=False,bIsPvP=False,bCanPickupOtherGuildDeathPenaltyDrop=False,bEnableNonLoginPenalty=True,bEnableFastTravel=True,bIsStartLocationSelectByMap=True,bExistPlayerAfterLogout=False,bEnableDefenseOtherGuildPlayer=False,CoopPlayerMaxNum=4,ServerPlayerMaxNum=32,ServerName="Default Palworld Server",ServerDescription="",AdminPassword="",ServerPassword="",PublicPort=8211,PublicIP="",RCONEnabled=False,RCONPort=25575,Region="",bUseAuth=True,BanListURL="https://api.palworldgame.com/api/banlist.txt",bShowPlayerList=false) \ No newline at end of file +OptionSettings=(Difficulty=None,DayTimeSpeedRate=1.000000,NightTimeSpeedRate=1.000000,ExpRate=1.000000,PalCaptureRate=1.000000,PalSpawnNumRate=1.000000,PalDamageRateAttack=1.000000,PalDamageRateDefense=1.000000,PlayerDamageRateAttack=1.000000,PlayerDamageRateDefense=1.000000,PlayerStomachDecreaceRate=1.000000,PlayerStaminaDecreaceRate=1.000000,PlayerAutoHPRegeneRate=1.000000,PlayerAutoHpRegeneRateInSleep=1.000000,PalStomachDecreaceRate=1.000000,PalStaminaDecreaceRate=1.000000,PalAutoHPRegeneRate=1.000000,PalAutoHpRegeneRateInSleep=1.000000,BuildObjectDamageRate=1.000000,BuildObjectDeteriorationDamageRate=1.000000,CollectionDropRate=1.000000,CollectionObjectHpRate=1.000000,CollectionObjectRespawnSpeedRate=1.000000,EnemyDropItemRate=1.000000,DeathPenalty=All,bEnablePlayerToPlayerDamage=False,bEnableFriendlyFire=False,bEnableInvaderEnemy=True,bActiveUNKO=False,bEnableAimAssistPad=True,bEnableAimAssistKeyboard=False,DropItemMaxNum=3000,DropItemMaxNum_UNKO=100,BaseCampMaxNum=128,BaseCampWorkerMaxNum=15,DropItemAliveMaxHours=1.000000,bAutoResetGuildNoOnlinePlayers=False,AutoResetGuildTimeNoOnlinePlayers=72.000000,GuildPlayerMaxNum=20,PalEggDefaultHatchingTime=72.000000,WorkSpeedRate=1.000000,bIsMultiplay=False,bIsPvP=False,bCanPickupOtherGuildDeathPenaltyDrop=False,bEnableNonLoginPenalty=True,bEnableFastTravel=True,bIsStartLocationSelectByMap=True,bExistPlayerAfterLogout=False,bEnableDefenseOtherGuildPlayer=False,CoopPlayerMaxNum=4,ServerPlayerMaxNum=32,ServerName="Default Palworld Server",ServerDescription="",AdminPassword="",ServerPassword="",PublicPort=8211,PublicIP="",RCONEnabled=False,RCONPort=25575,Region="",bUseAuth=True,BanListURL="https://api.palworldgame.com/api/banlist.txt",RESTAPIEnabled=False,RESTAPIPort=8212,bShowPlayerList=False,AllowConnectPlatform=Steam,bIsUseBackupSaveData=True) \ No newline at end of file diff --git a/default.env b/default.env index 2c4cb9b..725e514 100644 --- a/default.env +++ b/default.env @@ -19,7 +19,7 @@ RESTART_ENABLED=false RESTART_COUNTDOWN=15 RESTART_DEBUG_OVERRIDE=false RESTART_CRON_EXPRESSION="0 18 * * *" -# RCON-Playerdection - NEEDS RCON ENABLED! +# RCON-Playerdetection - NEEDS RCON ENABLED! RCON_PLAYER_DETECTION=true RCON_PLAYER_DETECTION_STARTUP_DELAY=60 RCON_PLAYER_DETECTION_CHECK_INTERVAL=15 @@ -116,4 +116,8 @@ RCON_PORT=25575 REGION= USEAUTH=true BAN_LIST_URL=https://api.palworldgame.com/api/banlist.txt +RESTAPI_ENABLED=true +RESTAPI_PORT=8212 SHOW_PLAYER_LIST=false +ALLOW_CONNECT_PLATFORM=Steam +ENABLE_WORLD_BACKUP=false diff --git a/docker-compose.yml b/docker-compose.yml index 1dd1024..f5d1d95 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -12,6 +12,10 @@ services: published: 8211 # Gamerserver port on your host protocol: udp mode: host + - target: 8212 # Gameserver API port inside of the container + published: 8212 # Gameserver API port on your host + protocol: tcp + mode: host - target: 25575 # RCON port inside of the container published: 25575 # RCON port on your host protocol: tcp diff --git a/docs/ENV_VARS.md b/docs/ENV_VARS.md index e4e8857..e2125ee 100644 --- a/docs/ENV_VARS.md +++ b/docs/ENV_VARS.md @@ -81,7 +81,6 @@ Information sources and credits to the following websites: | ----------------------------------------- | ------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------ | ------------- | | MULTITHREAD_ENABLED | Sets options for "Improved multi-threaded CPU performance" | true | true | Boolean | | COMMUNITY_SERVER | Set to enabled, the server will appear in the Community-Serverlist | true | true | Boolean | -| SHOW_PLAYER_LIST | bShowPlayerList | Make the player list public on a community server | false | Boolean | | NETSERVERMAXTICKRATE | NetServerMaxTickRate | Changes the TickRate of the server, be very careful with this setting! | 120 | 30-120 | | DIFFICULTY | Difficulty | Choose one of the following:
`None`
`Normal`
`Difficult` | None | Enum | | DAYTIME_SPEEDRATE | DayTimeSpeedRate | Day Time Speed: The lower this number is, the longer each day will last. | 1.000000 | Float | @@ -145,6 +144,11 @@ Information sources and credits to the following websites: | REGION | Region | Area | | String | | USEAUTH | bUseAuth | Use authentication | true | Boolean | | BAN_LIST_URL | BanListURL | Which ban list to use | https://api.palworldgame.com/api/banlist.txt | String | +| RESTAPI_ENABLED | RESTAPIEnabled | Enables the RESTAPI | true | Boolean | +| RESTAPI_PORT | RESTAPIPort | Defines the port inside the container where the API should be hosted - RESTAPI: Needs Basic Auth; admin:ADMIN_PASSWORD | 8212 | UInt16 | +| SHOW_PLAYER_LIST | bShowPlayerList | Enables to view player-list ingame via the escape key | false | Boolean | +| ALLOW_CONNECT_PLATFORM | AllowConnectPlatform | Looks like Cross-Play, but according to official documentation, isnt working yet and no more infos given on this; See: https://tech.palworldgame.com/settings-and-operation/configuration | Steam | String | +| ENABLE_WORLD_BACKUP | bIsUseBackupSaveData | Enables internal world backup inside the game-server; off by default, because we have our own backup solution | false | Boolean | ** Updates to descriptions taken from [this reddit post](https://www.reddit.com/r/Palworld/comments/19bumby/settings_explanation/) ** diff --git a/includes/config.sh b/includes/config.sh index e4239f9..9c4281c 100644 --- a/includes/config.sh +++ b/includes/config.sh @@ -296,10 +296,26 @@ function setup_palworld_settings_ini() { e "> Setting BanListURL to '$BAN_LIST_URL'" sed -E -i "s~BanListURL=\"[^\"]*\"~BanListURL=\"$BAN_LIST_URL\"~" "$GAME_SETTINGS_FILE" fi + if [[ -n ${RESTAPI_ENABLED+x} ]]; then + e "> Setting RESTAPIEnabled to '$RESTAPI_ENABLED'" + sed -E -i "s/RESTAPIEnabled=[a-zA-Z]*/RESTAPIEnabled=$RESTAPI_ENABLED/" "$GAME_SETTINGS_FILE" + fi + if [[ -n ${RESTAPI_PORT+x} ]]; then + e "> Setting RESTAPIPort to '$RESTAPI_PORT'" + sed -E -i "s/RESTAPIPort=[0-9]*/RESTAPIPort=$RESTAPI_PORT/" "$GAME_SETTINGS_FILE" + fi if [[ -n ${SHOW_PLAYER_LIST+x} ]]; then e "> Setting bShowPlayerList to '$SHOW_PLAYER_LIST'" sed -E -i "s/bShowPlayerList=[a-zA-Z]*/bShowPlayerList=$SHOW_PLAYER_LIST/" "$GAME_SETTINGS_FILE" fi + if [[ -n ${ALLOW_CONNECT_PLATFORM+x} ]]; then + e "> Setting AllowConnectPlatform to '$ALLOW_CONNECT_PLATFORM'" + sed -E -i "s/AllowConnectPlatform=[a-zA-Z]*/AllowConnectPlatform=$ALLOW_CONNECT_PLATFORM/" "$GAME_SETTINGS_FILE" + fi + if [[ -n ${ENABLE_WORLD_BACKUP+x} ]]; then + e "> Setting bIsUseBackupSaveData to '$ENABLE_WORLD_BACKUP'" + sed -E -i "s/bIsUseBackupSaveData=[a-zA-Z]*/bIsUseBackupSaveData=$ENABLE_WORLD_BACKUP/" "$GAME_SETTINGS_FILE" + fi es ">>> Finished setting up PalWorldSettings.ini" } diff --git a/includes/playerdetection.sh b/includes/playerdetection.sh index dae6e41..0817b61 100644 --- a/includes/playerdetection.sh +++ b/includes/playerdetection.sh @@ -9,19 +9,19 @@ player_detection_loop() { while true; do compare_players sleep "$RCON_PLAYER_DETECTION_CHECK_INTERVAL" - done + done } # Function to compare current and previous player lists compare_players() { local old_players=("${current_players[@]}") - readarray -t current_players < <(rconcli showplayers | tail -n +2) + readarray -t current_players < <(rcon showplayers 2> /dev/null | tail -n +2) for player_info in "${current_players[@]}"; do # Extract player name, UID, and Steam ID from player info - # This part sets the Internal Field Separator (IFS) variable to ','. - # In Bash, the IFS variable determines how Bash recognizes word boundaries. - # By default, it includes space, tab, and newline characters. + # This part sets the Internal Field Separator (IFS) variable to ','. + # In Bash, the IFS variable determines how Bash recognizes word boundaries. + # By default, it includes space, tab, and newline characters. # By setting it to ',', we're telling Bash to split input lines at commas. # https://tldp.org/LDP/abs/html/internalvariables.html#IFSREF IFS=',' read -r -a player_data <<< "$player_info" @@ -82,39 +82,39 @@ compare_players() { # Function to announce a player join announce_join() { - time=$(date '+%H:%M:%S') + time=$(date '+[%H:%M:%S]') message="Player $1 has joined the server." echo "${time}: $message" if [[ -n $WEBHOOK_ENABLED ]] && [[ $WEBHOOK_ENABLED == "true" ]]; then send_info_notification "$message" fi if [[ -n $RCON_ENABLED ]] && [[ $RCON_ENABLED == "true" ]]; then - broadcast_player_join "${1// /\-}" + broadcast_player_join "${1}" fi } # Function to announce a player join announce_name_change() { - time=$(date '+%H:%M:%S') + time=$(date '+[%H:%M:%S]') message="Player $1 has changed their name to $2." echo "${time}: $message" if [[ -n $WEBHOOK_ENABLED ]] && [[ $WEBHOOK_ENABLED == "true" ]]; then send_info_notification "$message" fi if [[ -n $RCON_ENABLED ]] && [[ $RCON_ENABLED == "true" ]]; then - broadcast_player_name_change "${1// /\-}" "${2// /\-}" + broadcast_player_name_change "${1}" "${2}" fi } # Function to announce a player leave announce_leave() { - time=$(date '+%H:%M:%S') + time=$(date '+[%H:%M:%S]') message="Player $1 has left the server." echo "${time}: $message" if [[ -n $WEBHOOK_ENABLED ]] && [[ $WEBHOOK_ENABLED == "true" ]]; then send_info_notification "$message" fi if [[ -n $RCON_ENABLED ]] && [[ $RCON_ENABLED == "true" ]]; then - broadcast_player_leave "${1// /\-}" + broadcast_player_leave "${1}" fi -} \ No newline at end of file +} diff --git a/includes/rcon.sh b/includes/rcon.sh index 3dd1c6a..00aceb1 100644 --- a/includes/rcon.sh +++ b/includes/rcon.sh @@ -1,27 +1,29 @@ # shellcheck disable=SC2148 +function get_time() { + date '+[%H:%M:%S]' +} + function save_and_shutdown_server() { - rconcli 'broadcast Server-shutdown-was-requested-init-saving' - rconcli 'save' - rconcli 'broadcast Done-saving-server-shuts-down-now' + rconcli broadcast "$(get_time) Server shutdown requested. Saving..." + rconcli save + rconcli broadcast "$(get_time) Saving done. Server shutting down..." } function broadcast_automatic_restart() { - time=$(date '+%H:%M:%S') - for ((counter=1; counter<=15; counter++)); do if [[ $RCON_QUIET_RESTART == false ]]; then - rconcli "broadcast ${time}-AUTOMATIC-RESTART-IN-$counter-MINUTES" + rconcli "broadcast ${get_time}-AUTOMATIC-RESTART-IN-$counter-MINUTES" fi sleep 1 done if [[ $RCON_QUIET_RESTART == false ]]; then - rconcli 'broadcast Saving-world-before-restart...' + rconcli 'broadcast ${get_time} Saving world before restart...' fi rconcli 'save' - rconcli 'broadcast Saving-done' + rconcli 'broadcast ${get_time} Saving done' if [[ $RCON_QUIET_BACKUP == false ]]; then - rconcli 'broadcast Creating-backup' + rconcli 'broadcast ${get_time} Creating backup' fi rconcli "Shutdown 10" } @@ -30,44 +32,41 @@ function broadcast_backup_start() { time=$(date '+%H:%M:%S') if [[ $RCON_QUIET_SAVE == false ]]; then - rconcli "broadcast ${time}-Saving-in-5-seconds" + rconcli "broadcast ${get_time} Saving in 5 seconds..." fi sleep 5 if [[ $RCON_QUIET_SAVE == false ]]; then - rconcli 'broadcast Saving-world...' + rconcli 'broadcast ${get_time} Saving world...' fi rconcli 'save' if [[ $RCON_QUIET_SAVE == false ]]; then - rconcli 'broadcast Saving-done' + rconcli 'broadcast ${get_time} Saving done' fi if [[ $RCON_QUIET_BACKUP == false ]]; then - rconcli 'broadcast Creating-backup' + rconcli 'broadcast ${get_time} Creating backup' fi } function broadcast_backup_success() { if [[ $RCON_QUIET_BACKUP == false ]]; then - rconcli 'broadcast Backup-done' + rconcli 'broadcast ${get_time} Backup done' fi } function broadcast_backup_failed() { - rconcli 'broadcast Backup-failed' + rconcli broadcast "$(get_time) Backup failed" } function broadcast_player_join() { - time=$(date '+%H:%M:%S') - rconcli "broadcast ${time}-$1-joined-the-server" + rconcli broadcast "$(get_time) $1 joined the server" } function broadcast_player_name_change() { - time=$(date '+%H:%M:%S') - rconcli "broadcast ${time}-$1-renamed-to-$2" + rconcli broadcast "$(get_time) $1 renamed to $2" } function broadcast_player_leave() { - time=$(date '+%H:%M:%S') - rconcli "broadcast ${time}-$1-left-the-server" + rconcli broadcast "$(get_time) $1 left the server" } function check_is_server_empty() { @@ -77,4 +76,4 @@ function check_is_server_empty() { else return 1 # Server not empty fi -} \ No newline at end of file +} diff --git a/includes/security.sh b/includes/security.sh index 7265a74..ebc3d02 100644 --- a/includes/security.sh +++ b/includes/security.sh @@ -5,11 +5,11 @@ source /includes/colors.sh function check_for_default_credentials() { e "> Checking for existence of default credentials" if [[ -n $ADMIN_PASSWORD ]] && [[ $ADMIN_PASSWORD == "adminPasswordHere" ]]; then - ee ">>> Security thread detected: Please change the default admin password. Aborting server start ..." + ee ">>> Security threat detected: Please change the default admin password. Aborting server start ..." exit 1 fi if [[ -n $SERVER_PASSWORD ]] && [[ $SERVER_PASSWORD == "serverPasswordHere" ]]; then - ee ">>> Security thread detected: Please change the default server password. Aborting server start ..." + ee ">>> Security threat detected: Please change the default server password. Aborting server start ..." exit 1 fi es "> No default passwords found" diff --git a/scripts/backupmanager.sh b/scripts/backupmanager.sh index 07d9572..fb5193f 100644 --- a/scripts/backupmanager.sh +++ b/scripts/backupmanager.sh @@ -11,6 +11,10 @@ LOCAL_GAME_SAVE_PATH=${GAME_SAVE_PATH} # Directory where the game save files are LOCAL_BACKUP_RETENTION_POLICY=${BACKUP_RETENTION_POLICY} # Number of backup files to keep LOCAL_BACKUP_RETENTION_AMOUNT_TO_KEEP=${BACKUP_RETENTION_AMOUNT_TO_KEEP} # Number of backup files to keep +function get_time() { + date '+[%H:%M:%S]' +} + function print_usage() { script_name=$(basename "$0") echo "Usage:" @@ -128,23 +132,22 @@ function create_backup() { check_required_directories date=$(date +%Y%m%d_%H%M%S) - time=$(date +%H-%M-%S) backup_file_name="saved-${date}.tar.gz" mkdir -p "${LOCAL_BACKUP_PATH}" if [[ $RCON_QUIET_BACKUP == false ]]; then - rconcli "broadcast ${time}-Saving-in-5-seconds" + rconcli "broadcast $(get_time) Saving in 5 seconds..." fi sleep 5 if [[ $RCON_QUIET_BACKUP == false ]]; then - rconcli 'broadcast Saving-world...' + rconcli 'broadcast $(get_time) Saving-world...' fi rconcli 'save' if [[ $RCON_QUIET_BACKUP == false ]]; then - rconcli 'broadcast Saving-done' + rconcli 'broadcast $(get_time) Saving done' sleep 15 - rconcli 'broadcast Creating-backup' + rconcli 'broadcast $(get_time) Creating-backup' fi if ! tar cfz "${LOCAL_BACKUP_PATH}/${backup_file_name}" -C "${LOCAL_GAME_PATH}/" "Saved" ; then @@ -153,7 +156,7 @@ function create_backup() { else broadcast_backup_success es ">>> Backup '${backup_file_name}' created successfully" - fi + fi if [[ -n ${LOCAL_BACKUP_RETENTION_POLICY} ]] && [[ ${LOCAL_BACKUP_RETENTION_POLICY} == "true" ]] && [[ ${LOCAL_BACKUP_RETENTION_AMOUNT_TO_KEEP} =~ ^[0-9]+$ ]]; then ls -1t "${LOCAL_BACKUP_PATH}"/saved-*.tar.gz | tail -n +"$(($LOCAL_BACKUP_RETENTION_AMOUNT_TO_KEEP + 1))" | xargs -d '\n' rm -f -- @@ -214,7 +217,7 @@ function clean_backups() { ei "> No files in the backup directory ${LOCAL_BACKUP_PATH}. Exiting..." exit 0 fi - + files=$(ls -1t "${LOCAL_BACKUP_PATH}"/saved-*.tar.gz) files_to_delete=$(echo "${files}" | tail -n +"$(($num_files_to_keep + 1))") num_files=$(echo -n "${files}" | grep -c '^') diff --git a/scripts/rconcli.sh b/scripts/rconcli.sh index 3ad2dca..f494343 100644 --- a/scripts/rconcli.sh +++ b/scripts/rconcli.sh @@ -8,12 +8,20 @@ source /includes/colors.sh # Arguments: # Example: run_rcon_cli "showplayers" run_rcon_cli() { - local cmd=$* if [[ -z ${RCON_ENABLED+x} ]] || [[ "$RCON_ENABLED" != "true" ]]; then ew ">>> RCON is not enabled. Aborting RCON command ..." exit fi - output=$(rcon -c "$RCON_CONFIG_FILE" "${cmd}") + local command=$1 + shift + if [ $# -ge 1 ]; then + # In the command value, replace ASCII space characters with + # unicode non-breaking space characters. + full_command="$command $(echo "$@" | tr ' ' '\240')" + else + full_command=$command + fi + output=$(rcon -c "$RCON_CONFIG_FILE" "$full_command" | tr -d '\0') ei_nn "> RCON: "; e "${output}" } diff --git a/scripts/restart.sh b/scripts/restart.sh index 3c02273..c8ee70a 100644 --- a/scripts/restart.sh +++ b/scripts/restart.sh @@ -7,6 +7,10 @@ source /includes/colors.sh source /includes/server.sh source /includes/webhook.sh +function get_time() { + date '+[%H:%M:%S]' +} + function schedule_restart() { ew ">>> Automatic restart was triggered..." PLAYER_DETECTION_PID=$(<${GAME_ROOT}/PLAYER_DETECTION.PID) @@ -31,28 +35,27 @@ function schedule_restart() { send_restart_now_notification fi break - else + else ew ">>> Server has still players" fi if [[ $RCON_QUIET_RESTART == false ]]; then - time=$(date '+%H:%M:%S') - rconcli "broadcast ${time}-AUTOMATIC-RESTART-IN-$counter-MINUTES" + rconcli "broadcast $(get_time) AUTOMATIC RESTART IN $counter MINUTES" fi fi if [[ -n $RESTART_DEBUG_OVERRIDE ]] && [[ $RESTART_DEBUG_OVERRIDE == "true" ]]; then sleep 1 else sleep 60 - fi + fi done if [[ -n $RCON_ENABLED ]] && [[ $RCON_ENABLED == "true" ]]; then if [[ $RCON_QUIET_SAVE == false ]]; then - rconcli 'broadcast Saving-world-before-restart...' + rconcli 'broadcast $(get_time) Saving world before restart...' fi rconcli 'save' if [[ $RCON_QUIET_SAVE == false ]]; then - rconcli 'broadcast Saving-done' + rconcli 'broadcast $(get_time) Savingdone' fi sleep 15 kill -SIGTERM "${PLAYER_DETECTION_PID}" @@ -74,4 +77,4 @@ function schedule_restart() { fi } -schedule_restart \ No newline at end of file +schedule_restart