Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move countdown to function for auto update and auto reboot #392

Closed
wants to merge 55 commits into from
Closed
Show file tree
Hide file tree
Changes from 40 commits
Commits
Show all changes
55 commits
Select commit Hold shift + click to select a range
019fe45
Fixed spacing
Dashboy1998 Feb 14, 2024
9d6b106
Added countdown loop
Dashboy1998 Feb 14, 2024
fd1a2de
Added validation for AUTO_UPDATE_WARN_MINUTES
Dashboy1998 Feb 14, 2024
595f0a3
Moved countdown to helper function and added seconds
Dashboy1998 Feb 16, 2024
ed56e0f
Removed/Added extra lines
Dashboy1998 Feb 16, 2024
98f9c1e
Update scripts/helper_functions.sh
Dashboy1998 Feb 16, 2024
2d34179
Update scripts/helper_functions.sh
Dashboy1998 Feb 16, 2024
22683fd
Implemented skip when empty, resolves #393
Dashboy1998 Feb 16, 2024
8bef267
Moved in_ to countdown message
Dashboy1998 Feb 16, 2024
5471fb4
Moved integer validation to countdown
Dashboy1998 Feb 16, 2024
58a611c
Fixed spacing in auto_reboot.sh
Dashboy1998 Feb 16, 2024
7e54379
Update auto_reboot so AUTO_REBOOT_WARN_MINUTES needs to only be valid…
Dashboy1998 Feb 16, 2024
b79edce
Split messages in update
Dashboy1998 Feb 16, 2024
80d4b1c
No longer creating update discord message if AUTO_UPDATE_WARN_MINUTES…
Dashboy1998 Feb 16, 2024
e73c9f2
Updated messages in update.sh
Dashboy1998 Feb 16, 2024
098818a
Updated messages in update and reboot
Dashboy1998 Feb 16, 2024
600313f
Merge branch 'main' into update-countdown
Dashboy1998 Feb 16, 2024
25450e2
Added save function
Dashboy1998 Feb 17, 2024
5fe4b8d
Added shutdown function
Dashboy1998 Feb 17, 2024
fa9735c
Added save to shutdown function
Dashboy1998 Feb 17, 2024
2c8dbf6
Changed mtime, message_prefix, return_val to local vars
Dashboy1998 Feb 17, 2024
396a9fb
Removed rcon-cli save/shutdown in init.sh
Dashboy1998 Feb 17, 2024
ace7b18
Fixed shutdown
Dashboy1998 Feb 17, 2024
5962579
Merge branch 'Add-save-and-shutdown-functions' into update-countdown
Dashboy1998 Feb 17, 2024
dc66c8b
Merge branch 'main' into update-countdown
Dashboy1998 Feb 17, 2024
53986bd
Removed echo in RCON
Dashboy1998 Feb 17, 2024
043af58
Fixed spacing
Dashboy1998 Feb 17, 2024
6e7751c
Moved RCON check to RCON function in all helper functions
Dashboy1998 Feb 17, 2024
624d9ee
Removed checking exit code in update.sh
Dashboy1998 Feb 17, 2024
a35af01
Fixed update.sh issues from merge
Dashboy1998 Feb 17, 2024
0847f7b
Changed if in update.sh
Dashboy1998 Feb 17, 2024
ca6b52f
Changed shutdown to DoExit, resolves #395
Dashboy1998 Feb 17, 2024
381d845
Updated structure of backup.sh
Dashboy1998 Feb 17, 2024
75021bd
Updated exit code in update.sh
Dashboy1998 Feb 17, 2024
9b075a0
Updated start.sh
Dashboy1998 Feb 17, 2024
18ddb66
Fixed spacing in init.sh
Dashboy1998 Feb 17, 2024
4da9a05
Merge branch 'main' into update-countdown
Dashboy1998 Feb 17, 2024
24e045b
Fixed merge issue
Dashboy1998 Feb 17, 2024
e3ae137
Fixed update/install in start
Dashboy1998 Feb 17, 2024
b089211
Added broadcast function. Partially Resolves #400
Dashboy1998 Feb 17, 2024
82536b4
Update scripts/start.sh
Dashboy1998 Feb 18, 2024
131638d
Changed exit codes for countdown_message
Dashboy1998 Feb 18, 2024
958a930
Moved player count check
Dashboy1998 Feb 18, 2024
1baeb04
Moved case when 1
Dashboy1998 Feb 18, 2024
27c1466
Added comment
Dashboy1998 Feb 18, 2024
3e38a6e
Reordered cases
Dashboy1998 Feb 18, 2024
9fb677c
Merge branch 'main' into update-countdown
Dashboy1998 Feb 18, 2024
5d72e7c
Merge branch 'main' into update-countdown
Dashboy1998 Feb 19, 2024
a718120
Checking if broadcast contains non-ascii characters.
Dashboy1998 Feb 19, 2024
408617b
Reverted spacing changes
Dashboy1998 Feb 19, 2024
43ca7a2
Added missing fi
Dashboy1998 Feb 19, 2024
acdf259
Moved source helper_install.sh out of helper_functions.sh
Dashboy1998 Feb 19, 2024
e58143e
Merge branch 'main' into update-countdown
Dashboy1998 Feb 19, 2024
f96ef24
Only broadcast valid messages
Dashboy1998 Feb 19, 2024
635d201
Fixed merge issue
Dashboy1998 Feb 19, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 19 additions & 26 deletions scripts/auto_reboot.sh
Dashboy1998 marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -2,32 +2,25 @@
# shellcheck source=/dev/null
source "/home/steam/server/helper_functions.sh"

if [ "${RCON_ENABLED,,}" != true ]; then
LogWarn "Unable to reboot. RCON is required."
exit 0
fi
if [ "${RCON_ENABLED,,}" = true ]; then
if [ "${AUTO_REBOOT_EVEN_IF_PLAYERS_ONLINE,,}" != true ]; then
players_count=$(get_player_count)

if [ -z "${AUTO_REBOOT_WARN_MINUTES}" ]; then
LogError "Unable to auto reboot, AUTO_REBOOT_WARN_MINUTES is empty."
exit 0
fi
if [ "$players_count" -gt 0 ]; then
LogWarn "There are ${players_count} players online. Skipping auto reboot."
exit 0
fi
fi

if [ "${AUTO_REBOOT_EVEN_IF_PLAYERS_ONLINE,,}" != true ]; then
players_count=$(get_player_count)
if [ "$players_count" -gt 0 ]; then
LogWarn "There are ${players_count} players online. Skipping auto reboot."
exit 0
fi
fi

if [[ "${AUTO_REBOOT_WARN_MINUTES}" =~ ^[0-9]+$ ]]; then
for ((i = "${AUTO_REBOOT_WARN_MINUTES}" ; i > 0 ; i--)); do
RCON "broadcast The_Server_will_reboot_in_${i}_Minutes"
sleep "1m"
done
RCON save
RCON "shutdown 1"
exit 0
if countdown_message "${AUTO_REBOOT_WARN_MINUTES}" "The_Server_will_reboot"; then
shutdown_server
elif [ -z "${AUTO_REBOOT_WARN_MINUTES}" ]; then
LogError "Unable to auto reboot, the server is not empty and AUTO_REBOOT_WARN_MINUTES is empty"
exit 1
else
LogError "Unable to auto reboot, the server is not empty and AUTO_REBOOT_WARN_MINUTES is not an integer: ${AUTO_REBOOT_WARN_MINUTES}"
fi
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you can do these checks before you start the countdown. Would make it a bit cleaner in my opinion.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have it like that because if you so choose you could run the reboot script with no one in the server and it will reboot.

Also if it is a cron job and there is no one why not just reboot? The timer is supposed to just let players know and not prevent the reboot as that's what the enable flag is for

else
LogWarn "Unable to reboot. RCON is required."
exit 1
fi

LogError "Unable to auto reboot, AUTO_REBOOT_WARN_MINUTES is not an integer: ${AUTO_REBOOT_WARN_MINUTES}"
39 changes: 17 additions & 22 deletions scripts/backup.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,7 @@
source "/home/steam/server/helper_functions.sh"

DiscordMessage "Creating backup..." "in-progress"
if [ "${RCON_ENABLED,,}" = true ]; then
RCON save
fi
save_server

DATE=$(date +"%Y-%m-%d_%H-%M-%S")
FILE_PATH="/palworld/backups/palworld-save-${DATE}.tar.gz"
Expand All @@ -21,23 +19,20 @@ LogInfo "Backup created at ${FILE_PATH}"
DiscordMessage "Backup created at ${FILE_PATH}" "success"

if [ "${DELETE_OLD_BACKUPS,,}" != true ]; then
exit 0
fi

if [ -z "${OLD_BACKUP_DAYS}" ]; then
LogWarn "Unable to delete old backups, OLD_BACKUP_DAYS is empty."
DiscordMessage "Unable to delete old backups, OLD_BACKUP_DAYS is empty." "warn"
exit 0
if [ -z "${OLD_BACKUP_DAYS}" ]; then
LogWarn "Unable to delete old backups, OLD_BACKUP_DAYS is empty."
DiscordMessage "Unable to delete old backups, OLD_BACKUP_DAYS is empty." "warn"
exit 1
fi

if [[ "${OLD_BACKUP_DAYS}" =~ ^[0-9]+$ ]]; then
LogAction "Removing Old Backups"
LogInfo "Removing backups older than ${OLD_BACKUP_DAYS} days"
DiscordMessage "Removing backups older than ${OLD_BACKUP_DAYS} days..." "in-progress"
find /palworld/backups/ -mindepth 1 -maxdepth 1 -mtime "+${OLD_BACKUP_DAYS}" -type f -name 'palworld-save-*.tar.gz' -print -delete
DiscordMessage "Removed backups older than ${OLD_BACKUP_DAYS} days" "success"
else
LogError "Unable to delete old backups, OLD_BACKUP_DAYS is not an integer. OLD_BACKUP_DAYS=${OLD_BACKUP_DAYS}"
DiscordMessage "Unable to delete old backups, OLD_BACKUP_DAYS is not an integer. OLD_BACKUP_DAYS=${OLD_BACKUP_DAYS}" "failure"
fi
fi

if [[ "${OLD_BACKUP_DAYS}" =~ ^[0-9]+$ ]]; then
LogAction "Removing Old Backups"
LogInfo "Removing backups older than ${OLD_BACKUP_DAYS} days"
DiscordMessage "Removing backups older than ${OLD_BACKUP_DAYS} days..." "in-progress"
find /palworld/backups/ -mindepth 1 -maxdepth 1 -mtime "+${OLD_BACKUP_DAYS}" -type f -name 'palworld-save-*.tar.gz' -print -delete
DiscordMessage "Removed backups older than ${OLD_BACKUP_DAYS} days" "success"
exit 0
fi

LogError "Unable to delete old backups, OLD_BACKUP_DAYS is not an integer. OLD_BACKUP_DAYS=${OLD_BACKUP_DAYS}"
DiscordMessage "Unable to delete old backups, OLD_BACKUP_DAYS is not an integer. OLD_BACKUP_DAYS=${OLD_BACKUP_DAYS}" "failure"
211 changes: 155 additions & 56 deletions scripts/helper_functions.sh
Original file line number Diff line number Diff line change
Expand Up @@ -71,12 +71,15 @@ isExecutable() {
# Outputs the player count if rcon is enabled
get_player_count() {
local player_list
if [ "${RCON_ENABLED,,}" != true ]; then
local return_val=0
if player_list=$(RCON "ShowPlayers"); then
echo -n "${player_list}" | wc -l
else
echo 0
return 0
return_val=1
fi
player_list=$(RCON "ShowPlayers")
echo -n "${player_list}" | wc -l

return "$return_val"
}

#
Expand All @@ -93,96 +96,192 @@ export YellowBoldText='\033[1;33m' # Yellow
export CyanBoldText='\033[1;36m' # Cyan

LogInfo() {
Log "$1" "$WhiteText"
Log "$1" "$WhiteText"
}
LogWarn() {
Log "$1" "$YellowBoldText"
Log "$1" "$YellowBoldText"
}
LogError() {
Log "$1" "$RedBoldText"
Log "$1" "$RedBoldText"
}
LogSuccess() {
Log "$1" "$GreenBoldText"
Log "$1" "$GreenBoldText"
}
LogAction() {
Log "$1" "$CyanBoldText" "****" "****"
Log "$1" "$CyanBoldText" "****" "****"
}
Log() {
local message="$1"
local color="$2"
local prefix="$3"
local suffix="$4"
printf "$color%s$RESET$LINE" "$prefix$message$suffix"
local message="$1"
local color="$2"
local prefix="$3"
local suffix="$4"
printf "$color%s$RESET$LINE" "$prefix$message$suffix"
}

# Send Discord Message
# Level is optional variable defaulting to info
DiscordMessage() {
local message="$1"
local level="$2"
if [ -n "$level" ]; then
level="info"
fi
if [ -n "${DISCORD_WEBHOOK_URL}" ]; then
/home/steam/server/discord.sh "$message" "$level" &
fi
local message="$1"
local level="$2"
if [ -n "$level" ]; then
level="info"
fi
if [ -n "${DISCORD_WEBHOOK_URL}" ]; then
/home/steam/server/discord.sh "$message" "$level" &
fi
}

# RCON Call
RCON() {
local args="$1"
echo rcon-cli -c /home/steam/server/rcon.yaml "$args"
local return_val=0
local args="$1"
if [ "${RCON_ENABLED,,}" = true ]; then
rcon-cli -c /home/steam/server/rcon.yaml "$args"
else
return_val=1
fi
return "$return_val"
}


# Returns 0 if Update Required
# Returns 1 if Update NOT Required
# Returns 2 if Check Failed
UpdateRequired() {
LogAction "Checking for new update"
LogAction "Checking for new update"

temp_file=$(mktemp)
http_code=$(curl https://api.steamcmd.net/v1/info/2394010 --output "$temp_file" --silent --location --write-out "%{http_code}")
TARGET_MANIFEST=$(grep -Po '"2394012".*"gid": "\d+"' <"$temp_file" | sed -r 's/.*("[0-9]+")$/\1/')
temp_file=$(mktemp)
http_code=$(curl https://api.steamcmd.net/v1/info/2394010 --output "$temp_file" --silent --location --write-out "%{http_code}")
TARGET_MANIFEST=$(grep -Po '"2394012".*"gid": "\d+"' <"$temp_file" | sed -r 's/.*("[0-9]+")$/\1/')

CURRENT_MANIFEST=$(awk '/manifest/{count++} count==2 {print $2; exit}' /palworld/steamapps/appmanifest_2394010.acf)
rm "$temp_file"
CURRENT_MANIFEST=$(awk '/manifest/{count++} count==2 {print $2; exit}' /palworld/steamapps/appmanifest_2394010.acf)
rm "$temp_file"

if [ "$http_code" -ne 200 ]; then
LogError "There was a problem reaching the Steam api. Unable to check for updates!"
DiscordMessage "There was a problem reaching the Steam api. Unable to check for updates!" "failure"
return 2
fi
if [ "$http_code" -ne 200 ]; then
LogError "There was a problem reaching the Steam api. Unable to check for updates!"
DiscordMessage "There was a problem reaching the Steam api. Unable to check for updates!" "failure"
return 2
fi

if [ -z "$TARGET_MANIFEST" ]; then
LogError "The server response does not contain the expected BuildID. Unable to check for updates!"
DiscordMessage "Steam servers response does not contain the expected BuildID. Unable to check for updates!" "failure"
return 2
fi
if [ -z "$TARGET_MANIFEST" ]; then
LogError "The server response does not contain the expected BuildID. Unable to check for updates!"
DiscordMessage "Steam servers response does not contain the expected BuildID. Unable to check for updates!" "failure"
return 2
fi

if [ "$CURRENT_MANIFEST" != "$TARGET_MANIFEST" ]; then
LogInfo "An Update Is Available."
LogInfo "Current Version: $CURRENT_MANIFEST"
LogInfo "Latest Version: $TARGET_MANIFEST."
return 0
fi
if [ "$CURRENT_MANIFEST" != "$TARGET_MANIFEST" ]; then
LogInfo "An Update Is Available."
LogInfo "Current Version: $CURRENT_MANIFEST"
LogInfo "Latest Version: $TARGET_MANIFEST."
return 0
fi

LogSuccess "The Server is up to date!"
return 1
LogSuccess "The Server is up to date!"
return 1

}

InstallServer() {
DiscordMessage "${DISCORD_PRE_UPDATE_BOOT_MESSAGE}" "in-progress"
/home/steam/steamcmd/steamcmd.sh +@sSteamCmdForcePlatformType linux +@sSteamCmdForcePlatformBitness 64 +force_install_dir "/palworld" +login anonymous +app_update 2394010 validate +quit
DiscordMessage "${DISCORD_POST_UPDATE_BOOT_MESSAGE}" "success"
DiscordMessage "${DISCORD_PRE_UPDATE_BOOT_MESSAGE}" "in-progress"
/home/steam/steamcmd/steamcmd.sh +@sSteamCmdForcePlatformType linux +@sSteamCmdForcePlatformBitness 64 +force_install_dir "/palworld" +login anonymous +app_update 2394010 validate +quit
DiscordMessage "${DISCORD_POST_UPDATE_BOOT_MESSAGE}" "success"
}

# Returns 0 if game is installed
# Returns 1 if game is not installed
IsInstalled() {
if [ -e /palworld/PalServer.sh ] && [ -e /palworld/steamapps/appmanifest_2394010.acf ]; then
return 0
fi
return 1
}
if [ -e /palworld/PalServer.sh ] && [ -e /palworld/steamapps/appmanifest_2394010.acf ]; then
return 0
fi
return 1
}

# Saves the server
# Returns 0 if it saves
# Returns 1 if it is not able to save
save_server() {
local return_val=0
if ! RCON save; then
return_val=1
fi
return "$return_val"
}

# Saves then shutdowns the server
# Returns 0 if it is shutdown
# Returns 1 if it is not able to be shutdown
shutdown_server() {
local return_val=0
# Do not shutdown if not able to save
if save_server; then
if ! RCON "DoExit"; then
return_val=1
fi
else
return_val=1
fi
return "$return_val"
}

# Given a message this will broadcast in game
# Since RCON does not support spaces this will replace all spaces with underscores
# Returns 0 on success
# Returns 1 if not able to broadcast
broadcast_command() {
local return_val=0
# Replaces spaces with underscore
local message="${1// /_}"
if ! RCON "broadcast ${message}"; then
return_val=1
fi
return "$return_val"
}

# Given an amount of time in minutes and a message prefix
# Returns 0 on success
# If mtime is not an integer and there are players in game then return 1
countdown_message() {
local mtime="$1"
local message_prefix="$2"
local return_val=0

if [[ "${mtime}" =~ ^[0-9]+$ ]]; then
for ((i = "${mtime}" ; i > 0 ; i--)); do
if [ "$(get_player_count)" -eq 0 ]; then
break
fi
if [ "$i" -eq 1 ]; then
broadcast_command "${message_prefix}_in_${i}_minute"
sleep 30s
broadcast_command "${message_prefix}_in_30_seconds"
sleep 20s
broadcast_command "${message_prefix}_in_10_seconds"
sleep 10s
else
case "$i" in
"$mtime" )
;&
15 )
;&
10 )
;&
5 )
;&
2 )
broadcast_command "${message_prefix}_in_${i}_minutes"
;&
* )
sleep 1m
;;
esac
fi
done
return 0
else
# mtime is not an integer so check if there are no players
if [ "$(get_player_count)" -gt 0 ]; then
return_val=1
fi
fi
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would suggest to negate if [[ "${mtime}" =~ ^[0-9]+$ ]]; then to reduce nested code.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have that because the only time this is called is during a shutdown for update or reboot.
I believe both of those should happen regardless if there's a timer or not as the timer is just to let players know. If there is no timer set and there are no players I believe the action should proceed.

return "$return_val"
}
8 changes: 3 additions & 5 deletions scripts/init.sh
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,10 @@ chown -R steam:steam /palworld /home/steam/

# shellcheck disable=SC2317
term_handler() {
DiscordMessage "${DISCORD_PRE_SHUTDOWN_MESSAGE}" "in-progress"
DiscordMessage "${DISCORD_PRE_SHUTDOWN_MESSAGE}" "in-progress"

if [ "${RCON_ENABLED,,}" = true ]; then
RCON save
RCON "shutdown 1"
else # Does not save
if ! shutdown_server; then
# If it fails then kill the server
kill -SIGTERM "$(pidof PalServer-Linux-Test)"
fi

Expand Down
3 changes: 1 addition & 2 deletions scripts/restore.sh
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,7 @@ if [ -f "$BACKUP_FILE" ]; then

if [ "${RCON_ENABLED}" = true ]; then
LogAction "Shutting Down Server"
RCON save
RCON "shutdown 1"
shutdown_server
else
LogWarn "RCON is not enabled. Please enable RCON to use this feature. Unable to restore backup."
exit 1
Expand Down
Loading