Skip to content

Commit

Permalink
Merge pull request #356 from Phelms215/feature-utility-functions
Browse files Browse the repository at this point in the history
Introduced Utility Functions - Remove duplicate code snippets
  • Loading branch information
thijsvanloef authored Feb 17, 2024
2 parents f15075d + ce5e967 commit f709084
Show file tree
Hide file tree
Showing 9 changed files with 270 additions and 189 deletions.
47 changes: 25 additions & 22 deletions scripts/auto_reboot.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,29 +2,32 @@
# shellcheck source=/dev/null
source "/home/steam/server/helper_functions.sh"

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

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

if [ -z "${AUTO_REBOOT_WARN_MINUTES}" ]; then
echo "Unable to auto reboot, AUTO_REBOOT_WARN_MINUTES is empty."
elif [[ "${AUTO_REBOOT_WARN_MINUTES}" =~ ^[0-9]+$ ]]; then
for ((i = "${AUTO_REBOOT_WARN_MINUTES}" ; i > 0 ; i--)); do
rcon-cli -c /home/steam/server/rcon.yaml "broadcast The_Server_will_reboot_in_${i}_Minutes"
sleep "1m"
done
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

rcon-cli -c /home/steam/server/rcon.yaml save
rcon-cli -c /home/steam/server/rcon.yaml "shutdown 1"
else
echo "Unable to auto reboot, AUTO_REBOOT_WARN_MINUTES is not an integer: ${AUTO_REBOOT_WARN_MINUTES}"
fi
else
echo "Unable to reboot. RCON is required."
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
fi

LogError "Unable to auto reboot, AUTO_REBOOT_WARN_MINUTES is not an integer: ${AUTO_REBOOT_WARN_MINUTES}"
58 changes: 26 additions & 32 deletions scripts/backup.sh
Original file line number Diff line number Diff line change
@@ -1,49 +1,43 @@
#!/bin/bash
# shellcheck source=/dev/null
source "/home/steam/server/helper_functions.sh"

if [ -n "${DISCORD_WEBHOOK_URL}" ]; then
/home/steam/server/discord.sh "Creating backup..." "in-progress" &
fi

DiscordMessage "Creating backup..." "in-progress"
if [ "${RCON_ENABLED,,}" = true ]; then
rcon-cli -c /home/steam/server/rcon.yaml save
RCON save
fi

DATE=$(date +"%Y-%m-%d_%H-%M-%S")
FILE_PATH="/palworld/backups/palworld-save-${DATE}.tar.gz"
cd /palworld/Pal/ || exit

echo "Creating backup"
LogAction "Creating backup"
tar -zcf "$FILE_PATH" "Saved/"

if [ "$(id -u)" -eq 0 ]; then
chown steam:steam "$FILE_PATH"
fi
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
fi

echo "Backup created at ${FILE_PATH}"
if [ -n "${DISCORD_WEBHOOK_URL}" ]; then
/home/steam/server/discord.sh "Backup created at ${FILE_PATH}" "success"
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

if [ "${DELETE_OLD_BACKUPS,,}" = true ]; then

if [ -z "${OLD_BACKUP_DAYS}" ]; then
echo "Unable to delete old backups, OLD_BACKUP_DAYS is empty."
if [ -n "${DISCORD_WEBHOOK_URL}" ]; then
/home/steam/server/discord.sh "Unable to delete old backups, OLD_BACKUP_DAYS is empty." "warn"
fi
elif [[ "${OLD_BACKUP_DAYS}" =~ ^[0-9]+$ ]]; then
echo "Removing backups older than ${OLD_BACKUP_DAYS} days"
if [ -n "${DISCORD_WEBHOOK_URL}" ] && [ -n "${DISCORD_PRE_BACKUP_DELETE_MESSAGE}" ]; then
/home/steam/server/discord.sh "Removing backups older than ${OLD_BACKUP_DAYS} days..." "in-progress" &
fi
find /palworld/backups/ -mindepth 1 -maxdepth 1 -mtime "+${OLD_BACKUP_DAYS}" -type f -name 'palworld-save-*.tar.gz' -print -delete
if [ -n "${DISCORD_WEBHOOK_URL}" ]; then
/home/steam/server/discord.sh "Removed backups older than ${OLD_BACKUP_DAYS} days" "success"
fi
else
echo "Unable to delete old backups, OLD_BACKUP_DAYS is not an integer. OLD_BACKUP_DAYS=${OLD_BACKUP_DAYS}"
if [ -n "${DISCORD_WEBHOOK_URL}" ]; then
/home/steam/server/discord.sh "Unable to delete old backups, OLD_BACKUP_DAYS is not an integer. OLD_BACKUP_DAYS=${OLD_BACKUP_DAYS}" "failure"
fi
fi
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"
8 changes: 4 additions & 4 deletions scripts/compile-settings.sh
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,17 @@ mkdir -p "$config_dir" || exit
# If file exists then check if it is writable
if [ -f "$config_file" ]; then
if ! isWritable "$config_file"; then
echo "Unable to create $config_file"
LogError "Unable to create $config_file"
exit 1
fi
# If file does not exist then check if the directory is writable
elif ! isWritable "$config_dir"; then
# Exiting since the file does not exist and the directory is not writable.
echo "Unable to create $config_file"
LogError "Unable to create $config_file"
exit 1
fi

echo "Compiling PalWorldSettings.ini..."
LogAction "Compiling PalWorldSettings.ini"

export DIFFICULTY=${DIFFICULTY:-None}
export DAYTIME_SPEEDRATE=${DAYTIME_SPEEDRATE:-1.000000}
Expand Down Expand Up @@ -158,4 +158,4 @@ cat > "$config_file" <<EOF
$(envsubst < /home/steam/server/files/PalWorldSettings.ini.template | tr -d "\n\r")
EOF

echo "Compiling PalWorldSettings.ini done!"
LogSuccess "Compiling PalWorldSettings.ini done!"
10 changes: 6 additions & 4 deletions scripts/discord.sh
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
#!/bin/bash
# shellcheck source=/dev/null
source "/home/steam/server/helper_functions.sh"

# Defaults
DEFAULT_CONNECT_TIMEOUT=30
Expand All @@ -17,14 +19,14 @@ LEVEL=$2
if [ -n "${DISCORD_CONNECT_TIMEOUT}" ] && [[ "${DISCORD_CONNECT_TIMEOUT}" =~ ^[0-9]+$ ]]; then
CONNECT_TIMEOUT=$DISCORD_CONNECT_TIMEOUT
else
echo "CONNECT_TIMEOUT is not an integer, using default ${DEFAULT_CONNECT_TIMEOUT} seconds."
LogWarn "CONNECT_TIMEOUT is not an integer, using default ${DEFAULT_CONNECT_TIMEOUT} seconds."
CONNECT_TIMEOUT=$DEFAULT_CONNECT_TIMEOUT
fi

if [ -n "${DISCORD_MAX_TIMEOUT}" ] && [[ "${DISCORD_MAX_TIMEOUT}" =~ ^[0-9]+$ ]]; then
MAX_TIMEOUT=$DISCORD_MAX_TIMEOUT
else
echo "MAX_TIMEOUT is not an integer, using default ${DEFAULT_MAX_TIMEOUT} seconds."
LogWarn "MAX_TIMEOUT is not an integer, using default ${DEFAULT_MAX_TIMEOUT} seconds."
MAX_TIMEOUT=$DEFAULT_MAX_TIMEOUT
fi

Expand All @@ -46,7 +48,7 @@ if [ -n "${LEVEL}" ]; then
COLOR=$DISCORD_GREEN
;;
* )
echo "Could not find \"${LEVEL}\", using \"${DEFAULT_LEVEL}\""
LogWarn "Could not find \"${LEVEL}\", using \"${DEFAULT_LEVEL}\""
COLOR=$DISCORD_BLUE
;;
esac
Expand All @@ -55,5 +57,5 @@ else
fi

JSON=$(jo embeds[]="$(jo title="$MESSAGE" color=$COLOR)")
echo "Sending Discord json: ${JSON}"
LogInfo "Sending Discord json: ${JSON}"
curl -sfSL --connect-timeout "$CONNECT_TIMEOUT" --max-time "$MAX_TIMEOUT" -H "Content-Type: application/json" -d "$JSON" "$DISCORD_WEBHOOK_URL"
110 changes: 109 additions & 1 deletion scripts/helper_functions.sh
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,114 @@ get_player_count() {
echo 0
return 0
fi
player_list=$(rcon-cli -c /home/steam/server/rcon.yaml "ShowPlayers")
player_list=$(RCON "ShowPlayers")
echo -n "${player_list}" | wc -l
}

#
# Log Definitions
#
export LINE='\n'
export RESET='\033[0m' # Text Reset
export WhiteText='\033[0;37m' # White

# Bold
export RedBoldText='\033[1;31m' # Red
export GreenBoldText='\033[1;32m' # Green
export YellowBoldText='\033[1;33m' # Yellow
export CyanBoldText='\033[1;36m' # Cyan

LogInfo() {
Log "$1" "$WhiteText"
}
LogWarn() {
Log "$1" "$YellowBoldText"
}
LogError() {
Log "$1" "$RedBoldText"
}
LogSuccess() {
Log "$1" "$GreenBoldText"
}
LogAction() {
Log "$1" "$CyanBoldText" "****" "****"
}
Log() {
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
}

# RCON Call
RCON() {
local args="$1"
echo rcon-cli -c /home/steam/server/rcon.yaml "$args"
}


# Returns 0 if Update Required
# Returns 1 if Update NOT Required
# Returns 2 if Check Failed
UpdateRequired() {
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/')

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 [ -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

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"
}

# 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
}
18 changes: 9 additions & 9 deletions scripts/init.sh
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
#!/bin/bash
# shellcheck source=/dev/null
source "/home/steam/server/helper_functions.sh"

if [[ ! "${PUID}" -eq 0 ]] && [[ ! "${PGID}" -eq 0 ]]; then
printf "\e[0;32m*****EXECUTING USERMOD*****\e[0m\n"
LogAction "EXECUTING USERMOD"
usermod -o -u "${PUID}" steam
groupmod -o -g "${PGID}" steam
else
printf "\033[31m%s\n" "Running as root is not supported, please fix your PUID and PGID!"
LogError "Running as root is not supported, please fix your PUID and PGID!"
exit 1
fi

Expand All @@ -14,13 +16,11 @@ chown -R steam:steam /palworld /home/steam/

# shellcheck disable=SC2317
term_handler() {
if [ -n "${DISCORD_WEBHOOK_URL}" ] && [ -n "${DISCORD_PRE_SHUTDOWN_MESSAGE}" ]; then
su steam -c "/home/steam/server/discord.sh '${DISCORD_PRE_SHUTDOWN_MESSAGE}' in-progress" &
fi
DiscordMessage "${DISCORD_PRE_SHUTDOWN_MESSAGE}" "in-progress"

if [ "${RCON_ENABLED,,}" = true ]; then
rcon-cli save
rcon-cli "shutdown 1"
RCON save
RCON "shutdown 1"
else # Does not save
kill -SIGTERM "$(pidof PalServer-Linux-Test)"
fi
Expand All @@ -37,15 +37,15 @@ wait "$killpid"

mapfile -t backup_pids < <(pgrep backup)
if [ "${#backup_pids[@]}" -ne 0 ]; then
echo "Waiting for backup to finish"
LogInfo "Waiting for backup to finish"
for pid in "${backup_pids[@]}"; do
tail --pid="$pid" -f 2>/dev/null
done
fi

mapfile -t restore_pids < <(pgrep restore)
if [ "${#restore_pids[@]}" -ne 0 ]; then
echo "Waiting for restore to finish"
LogInfo "Waiting for restore to finish"
for pid in "${restore_pids[@]}"; do
tail --pid="$pid" -f 2>/dev/null
done
Expand Down
Loading

0 comments on commit f709084

Please sign in to comment.