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

Feat: Add pre and post update, start, backup, and shutdown discord hooks. #172

Merged
merged 32 commits into from
Feb 6, 2024
Merged
Show file tree
Hide file tree
Changes from 23 commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
4a25061
add hooks
zick-debug Jan 28, 2024
4010579
-X is assumed when using -d arg for curl
zick-debug Jan 28, 2024
2bc3df6
Merge branch 'main' into feature/discord-webhooks
zick-debug Jan 28, 2024
aa26185
Merge branch 'main' into feature/discord-webhooks
zick-debug Jan 31, 2024
65aae40
testing new discord vars
zick-debug Feb 1, 2024
58b2033
Merge branch 'main' into feature/discord-webhooks
zick-debug Feb 4, 2024
5ed5522
solve linting errors
zick-debug Feb 4, 2024
96e73b9
dockerfile linting
zick-debug Feb 4, 2024
cd04e85
remove comments
zick-debug Feb 4, 2024
97bd840
define max_timeout
zick-debug Feb 4, 2024
a39eca7
testing new discord msgs
zick-debug Feb 4, 2024
be93af2
update printf formatting to interpret escapes
zick-debug Feb 4, 2024
c1bcdc9
update help msg
zick-debug Feb 4, 2024
b932e6d
update help params
zick-debug Feb 4, 2024
54be46f
validate timeout integer and update discord cmd
zick-debug Feb 4, 2024
1a8ae98
tested basic discord functionality
zick-debug Feb 5, 2024
896c041
updated docs
zick-debug Feb 5, 2024
0a2ec77
gramma error in backup webhooks
zick-debug Feb 5, 2024
1ca842d
fix unintentional indirect expansion syntax
zick-debug Feb 5, 2024
619a143
fix linting error
thijsvanloef Feb 5, 2024
72c61fa
move discord from usr/local/bin
thijsvanloef Feb 5, 2024
4464ba0
fix some more linting
thijsvanloef Feb 5, 2024
34470e6
revert printf
thijsvanloef Feb 5, 2024
21d7fec
updated hooks to use less args, use webhook url var, default webhook …
zick-debug Feb 5, 2024
14e2571
dont set discord update status to run in background
zick-debug Feb 5, 2024
5dc0234
no bare url in md
zick-debug Feb 5, 2024
2b647ce
url is in wrong position in readme
zick-debug Feb 5, 2024
4126e26
added allowed vals for discord msgs
zick-debug Feb 5, 2024
5d2d591
check for new URL var instead of ID
zick-debug Feb 5, 2024
956f4ad
resolve connect-timeout and max-timeout not an integer logs
zick-debug Feb 5, 2024
56f20b7
remove "The" as other messages do not include it.
zick-debug Feb 6, 2024
587b346
change text
thijsvanloef Feb 6, 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
26 changes: 17 additions & 9 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
procps=2:3.3.17-5 \
wget=1.21-1+deb11u1 \
xdg-user-dirs=0.17-2 \
jo=1.3-2 \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*

Expand All @@ -27,16 +28,16 @@ ENV RCON_MD5SUM="8601c70dcab2f90cd842c127f700e398" \
SHELL ["/bin/bash", "-o", "pipefail", "-c"]

RUN wget --progress=dot:giga https://github.com/gorcon/rcon-cli/releases/download/v${RCON_VERSION}/rcon-${RCON_VERSION}-amd64_linux.tar.gz -O rcon.tar.gz \
&& echo "${RCON_MD5SUM}" rcon.tar.gz | md5sum -c - \
&& tar -xzvf rcon.tar.gz \
&& rm rcon.tar.gz \
&& mv rcon-${RCON_VERSION}-amd64_linux/rcon /usr/bin/rcon-cli \
&& rmdir /tmp/dumps
&& echo "${RCON_MD5SUM}" rcon.tar.gz | md5sum -c - \
&& tar -xzvf rcon.tar.gz \
&& rm rcon.tar.gz \
&& mv rcon-${RCON_VERSION}-amd64_linux/rcon /usr/bin/rcon-cli \
&& rmdir /tmp/dumps
thijsvanloef marked this conversation as resolved.
Show resolved Hide resolved

RUN wget --progress=dot:giga https://github.com/aptible/supercronic/releases/download/v${SUPERCRONIC_VERSION}/supercronic-linux-amd64 -O supercronic \
&& echo "${SUPERCRONIC_SHA1SUM}" supercronic | sha1sum -c - \
&& chmod +x supercronic \
&& mv supercronic /usr/local/bin/supercronic
&& echo "${SUPERCRONIC_SHA1SUM}" supercronic | sha1sum -c - \
&& chmod +x supercronic \
&& mv supercronic /usr/local/bin/supercronic
thijsvanloef marked this conversation as resolved.
Show resolved Hide resolved

ENV PORT= \
PUID=1000 \
Expand Down Expand Up @@ -64,7 +65,14 @@ ENV PORT= \
AUTO_UPDATE_WARN_MINUTES=30 \
AUTO_REBOOT_ENABLED=false \
AUTO_REBOOT_WARN_MINUTES=5 \
AUTO_REBOOT_CRON_EXPRESSION="0 0 * * *"
AUTO_REBOOT_CRON_EXPRESSION="0 0 * * *" \
DISCORD_CONNECT_TIMEOUT=30 \
DISCORD_MAX_TIMEOUT=30 \
DISCORD_PRE_UPDATE_BOOT_MESSAGE="Server is updating..." \
DISCORD_POST_UPDATE_BOOT_MESSAGE="Server update complete!" \
DISCORD_PRE_START_MESSAGE="Server is started!" \
DISCORD_PRE_SHUTDOWN_MESSAGE="Server is shutting down..." \
DISCORD_POST_SHUTDOWN_MESSAGE="Server is stopped!"

COPY ./scripts/* /home/steam/server/

Expand Down
32 changes: 30 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -155,8 +155,8 @@ It is highly recommended you set the following environment values before startin
* PUID
* PGID

| Variable | Info | Default Values | Allowed Values |
|--------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------------|------------------------------------------------------------------------------------------------------------|
| Variable | Info | Default Values | Allowed Values |
|--------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------------|---------------------------------------------------------------------------------------|
| TZ | Timezone used for time stamping backup server | UTC | See [TZ Identifiers](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones#Time_Zone_abbreviations) |
| PLAYERS* | Max amount of players that are able to join the server | 16 | 1-32 |
| PORT* | UDP port that the server will expose | 8211 | 1024-65535 |
Expand Down Expand Up @@ -184,6 +184,14 @@ It is highly recommended you set the following environment values before startin
| AUTO_REBOOT_CRON_EXPRESSION | Setting affects frequency of automatic updates. | 0 0 \* \* \* | Needs a Cron-Expression - See [Configuring Automatic Backups with Cron](#configuring-automatic-reboots-with-cron) |
| AUTO_REBOOT_ENABLED | Enables automatic reboots | false | true/false |
| AUTO_REBOOT_WARN_MINUTES | How long to wait to reboot the server, after the player were informed. | 5 | !0 |
| DISCORD_WEBHOOK_ID | Discord webhook id found after creating a webhook on a discord server ex: discord.com/api/webhooks/<webhook_id> | 0123456789012345678/xxxxxxxxxxxxxxxxxxxxxx | |
v4de marked this conversation as resolved.
Show resolved Hide resolved
| DISCORD_CONNECT_TIMEOUT | Discord command initial connection timeout | 30 | !0 |
| DISCORD_MAX_TIMEOUT | Discord total hook timeout | 30 | !0 |
| DISCORD_PRE_UPDATE_BOOT_MESSAGE | Discord message sent when server begins updating | Server is updating... | |
| DISCORD_POST_UPDATE_BOOT_MESSAGE | Discord message sent when server completes updating | Server update complete! | |
| DISCORD_PRE_START_MESSAGE | Discord message sent when server begins to start | Server is started! | |
| DISCORD_PRE_SHUTDOWN_MESSAGE | Discord message sent when server begins to shutdown | Server is shutting down... | |
| DISCORD_POST_SHUTDOWN_MESSAGE | Discord message sent when server has stopped | Server is stopped! | |

*highly recommended to set

Expand Down Expand Up @@ -425,6 +433,26 @@ Please keep in mind that the ENV variables will always overwrite the changes mad

For a more detailed list of explanations of server settings go to: [shockbyte](https://shockbyte.com/billing/knowledgebase/1189/How-to-Configure-your-Palworld-server.html)

## Using discord webhooks

1. Generate a webhook url for your discord server in your discord's server settings.

2. Set the environment variable with the unique token at the end of the discord webhook url example: discord.com/api/webhooks/<webhook_id>

send discord messages with docker run:

```sh
-e DISCORD_WEBHOOK="xxxx/xxxxx" \
-e DISCORD_PRE_UPDATE_BOOT_MESSAGE="Server is updating..." \
```

send discord messages with docker compose:

```yaml
- DISCORD_WEBHOOK=xxxx/xxxxx
- DISCORD_PRE_UPDATE_BOOT_MESSAGE=Server is updating...
```

## Reporting Issues/Feature Requests

Issues/Feature requests can be submitted by using [this link](https://github.com/thijsvanloef/palworld-server-docker/issues/new/choose).
Expand Down
48 changes: 24 additions & 24 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,25 +1,25 @@
services:
palworld:
image: thijsvanloef/palworld-server-docker:latest
restart: unless-stopped
container_name: palworld-server
stop_grace_period: 30s # Set to however long you are willing to wait for the container to gracefully stop
ports:
- 8211:8211/udp
- 27015:27015/udp # Required if you want your server to show up in the community servers tab
environment:
- PUID=1000
- PGID=1000
- PORT=8211 # Optional but recommended
- PLAYERS=16 # Optional but recommended
- SERVER_PASSWORD=worldofpals # Optional but recommended
- MULTITHREADING=true
- RCON_ENABLED=true
- RCON_PORT=25575
- TZ=UTC
- ADMIN_PASSWORD=adminPasswordHere
- COMMUNITY=false # Enable this if you want your server to show up in the community servers tab, USE WITH SERVER_PASSWORD!
- SERVER_NAME=World of Pals
- SERVER_DESCRIPTION=palworld-server-docker by Thijs van Loef
volumes:
- ./palworld:/palworld/
palworld:
image: thijsvanloef/palworld-server-docker:latest
restart: unless-stopped
container_name: palworld-server
stop_grace_period: 30s # Set to however long you are willing to wait for the container to gracefully stop
ports:
- 8211:8211/udp
- 27015:27015/udp # Required if you want your server to show up in the community servers tab
environment:
- PUID=1000
- PGID=1000
- PORT=8211 # Optional but recommended
- PLAYERS=16 # Optional but recommended
- SERVER_PASSWORD=worldofpals # Optional but recommended
- MULTITHREADING=true
- RCON_ENABLED=true
- RCON_PORT=25575
- TZ=UTC
- ADMIN_PASSWORD=adminPasswordHere
- COMMUNITY=false # Enable this if you want your server to show up in the community servers tab, USE WITH SERVER_PASSWORD!
- SERVER_NAME=World of Pals
- SERVER_DESCRIPTION=palworld-server-docker by Thijs van Loef
volumes:
- ./palworld:/palworld/
thijsvanloef marked this conversation as resolved.
Show resolved Hide resolved
30 changes: 25 additions & 5 deletions scripts/backup.sh
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
#!/bin/bash

if [ -n "${DISCORD_WEBHOOK_ID}" ]; then
/home/steam/server/discord.sh -i "{$DISCORD_WEBHOOK_ID}" -c "{$DISCORD_CONNECT_TIMEOUT}" -M "{$DISCORD_MAX_TIMEOUT}" -m "Creating backup..." -l "in-progress" &
fi

if [ "${RCON_ENABLED,,}" = true ]; then
rcon-cli -c /home/steam/server/rcon.yaml save
fi
Expand All @@ -15,15 +19,31 @@ if [ "$(id -u)" -eq 0 ]; then
chown steam:steam "$FILE_PATH"
fi

echo "backup created at $FILE_PATH"
echo "Backup created at ${FILE_PATH}"
if [ -n "${DISCORD_WEBHOOK_ID}" ]; then
/home/steam/server/discord.sh -i "{$DISCORD_WEBHOOK_ID}" -c "{$DISCORD_CONNECT_TIMEOUT}" -M "{$DISCORD_MAX_TIMEOUT}" -m "Backup created at ${FILE_PATH}" -l "success"
fi

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

if [ -z "${OLD_BACKUP_DAYS}" ]; then
echo "Unable to deleted old backups, OLD_BACKUP_DAYS is empty."
echo "Unable to delete old backups, OLD_BACKUP_DAYS is empty."
if [ -n "${DISCORD_WEBHOOK_ID}" ]; then
/home/steam/server/discord.sh -i "{$DISCORD_WEBHOOK_ID}" -c "{$DISCORD_CONNECT_TIMEOUT}" -M "{$DISCORD_MAX_TIMEOUT}" -m "Unable to delete old backups, OLD_BACKUP_DAYS is empty." -l "warn"
fi
elif [[ "${OLD_BACKUP_DAYS}" =~ ^[0-9]+$ ]]; then
echo "removing backups older than ${OLD_BACKUP_DAYS} days"
echo "Removing backups older than ${OLD_BACKUP_DAYS} days"
if [ -n "${DISCORD_WEBHOOK_ID}" ] && [ -n "${DISCORD_PRE_BACKUP_DELETE_MESSAGE}" ]; then
/home/steam/server/discord.sh -i "{$DISCORD_WEBHOOK_ID}" -c "{$DISCORD_CONNECT_TIMEOUT}" -M "{$DISCORD_MAX_TIMEOUT}" -m "Removing backups older than ${OLD_BACKUP_DAYS} days..." -l "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_ID}" ]; then
/home/steam/server/discord.sh -i "{$DISCORD_WEBHOOK_ID}" -c "{$DISCORD_CONNECT_TIMEOUT}" -M "{$DISCORD_MAX_TIMEOUT}" -m "Removed backups older than ${OLD_BACKUP_DAYS} days" -l "success"
fi
else
echo "Unable to deleted old backups, OLD_BACKUP_DAYS is not an integer. OLD_BACKUP_DAYS=${OLD_BACKUP_DAYS}"
echo "Unable to delete old backups, OLD_BACKUP_DAYS is not an integer. OLD_BACKUP_DAYS=${OLD_BACKUP_DAYS}"
if [ -n "${DISCORD_WEBHOOK_ID}" ]; then
/home/steam/server/discord.sh -i "{$DISCORD_WEBHOOK_ID}" -c "{$DISCORD_CONNECT_TIMEOUT}" -M "{$DISCORD_MAX_TIMEOUT}" -m "Unable to delete old backups, OLD_BACKUP_DAYS is not an integer. OLD_BACKUP_DAYS=${OLD_BACKUP_DAYS}" -l "failure"
fi
fi
fi
fi
143 changes: 143 additions & 0 deletions scripts/discord.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
#!/bin/bash

# Command usage
usage() {
cat << EOH
Usage: $0 [OPTION]... -i WEBHOOK_ID -c CONNECT_TIMEOUT -M MAX_TIMEOUT -m MESSAGE -l level
Post a discord message via a discord webhook. Webhook id and message are required to send a discord webhook. By default uses a 30s connect-timeout and 30s max-timeout and level is info.
A good example for discord json formatting is located here: https://birdie0.github.io/discord-webhooks-guide/discord_webhook.html
Package requirement: curl

Examples:
$0 -i 01234/56789 -c 30 -M 30 -m "Server is started!" -l success
$0 --webhook-id 01234/56789 --connect-timeout 30 --max-timeout 30 --message "Server is started!" --level success

Options:
-i, --webhook-id The unique id that is used by discord to determine what server/channel/thread to post. ex: https://discord.com/api/webhooks/<your id>
-c, --connect-timeout The timeout for connecting to the discord webhook (Default: 30)
-M, --max-timeout The maximum time curl will wait for a response (Default: 30)
-m, --message The json message body sent to the discord webhook
-l, --level The level affects the color of the embeds sidebar, available choices are: info, in-progress, warn, failure, success (Default: info)
-h, --help Display help text and exit
EOH
}

# Defaults
RED='\033[0;31m'
NC='\033[0m'
REQ=2
REQ_FLAG=0
DEFAULT_CONNECT_TIMEOUT=30
DEFAULT_MAX_TIMEOUT=30
DEFAULT_LEVEL="info"
DISCORD_BLUE=1127128
DISCORD_YELLOW=15258703
DISCORD_ORANGE=14177041
DISCORD_RED=14614528
DISCORD_GREEN=52224

# Show usage if no arguments specified
if [[ $# -eq 0 ]]; then
usage
exit 0
fi

# Parse arguments
POSITIONAL=()
while [[ $# -gt 0 ]]; do
key="$1"

case $key in
-i|--webhook-id )
WEBHOOK_ID="$2"
((REQ_FLAG++))
shift
shift
;;
-c|--connect-timeout )
CONNECT_TIMEOUT="$2"
shift
shift
;;
-M|--max-timeout )
MAX_TIMEOUT="$2"
shift
shift
;;
-m|--message )
MESSAGE="$2"
((REQ_FLAG++))
shift
shift
;;
-l|--level )
LEVEL="$2"
shift
shift
;;
-h|--help )
usage
exit 0
;;
* )
POSITIONAL+=("$1")
shift
;;
esac
done
set -- "${POSITIONAL[@]}"

# Check required options
if [ $REQ_FLAG -lt $REQ ]; then
printf "%b\n" "${RED}webhook-id and message are required${NC}"
usage
exit 1
fi

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

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


if [ -n "${LEVEL}" ]; then
case $LEVEL in
info )
COLOR=$DISCORD_BLUE
;;
in-progress )
COLOR=$DISCORD_YELLOW
;;
warn )
COLOR=$DISCORD_ORANGE
;;
failure )
COLOR=$DISCORD_RED
;;
success )
COLOR=$DISCORD_GREEN
;;
* )
echo "Could not find \"${LEVEL}\", using \"${DEFAULT_LEVEL}\""
COLOR=$DISCORD_BLUE
;;
esac
else
COLOR=$DISCORD_BLUE
fi

# Set discord webhook
DISCORD_WEBHOOK="https://discord.com/api/webhooks/$WEBHOOK_ID"

JSON=$(jo embeds[]="$(jo title="$MESSAGE" color=$COLOR)")
echo "Sending Discord json: ${JSON}"
curl -sfSL --connect-timeout "$CONNECT_TIMEOUT" --max-time "$MAX_TIMEOUT" -H "Content-Type: application/json" -d "$JSON" "$DISCORD_WEBHOOK"
7 changes: 6 additions & 1 deletion scripts/init.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ if [[ ! "${PUID}" -eq 0 ]] && [[ ! "${PGID}" -eq 0 ]]; then
usermod -o -u "${PUID}" steam
groupmod -o -g "${PGID}" steam
else
printf "\033[31mRunning as root is not supported, please fix your PUID and PGID!\n"
printf "\033[31m%s\n" "Running as root is not supported, please fix your PUID and PGID!"
exit 1
fi

Expand All @@ -14,12 +14,17 @@ chown -R steam:steam /palworld /home/steam/

# shellcheck disable=SC2317
term_handler() {
if [ -n "${DISCORD_WEBHOOK_ID}" ] && [ -n "${DISCORD_PRE_SHUTDOWN_MESSAGE}" ]; then
su steam -c "/home/steam/server/discord.sh -i ${DISCORD_WEBHOOK_ID} -c ${DISCORD_CONNECT_TIMEOUT} -M ${DISCORD_MAX_TIMEOUT} -m '${DISCORD_PRE_SHUTDOWN_MESSAGE}' -l in-progress" &
fi

if [ "${RCON_ENABLED,,}" = true ]; then
rcon-cli save
rcon-cli "shutdown 1"
else # Does not save
kill -SIGTERM "$(pidof PalServer-Linux-Test)"
fi

tail --pid="$killpid" -f 2>/dev/null
}

Expand Down
Loading
Loading