From 4f253dd3fa56d44ca2ac50d23b425b1d22c4237e Mon Sep 17 00:00:00 2001 From: Muscle Date: Fri, 19 Apr 2024 16:31:14 +0900 Subject: [PATCH 1/4] RCON cannot handle multibyte strings, so the ShowPlayers and Broadcast commands prefer to use the REST API when it is enabled. --- scripts/helper_functions.sh | 50 +++++++++++++++++++++++++++++++------ scripts/player_logging.sh | 15 ++++++++--- scripts/start.sh | 2 +- 3 files changed, 56 insertions(+), 11 deletions(-) diff --git a/scripts/helper_functions.sh b/scripts/helper_functions.sh index c0a6ce42..4a2c3c4c 100644 --- a/scripts/helper_functions.sh +++ b/scripts/helper_functions.sh @@ -76,16 +76,31 @@ isExecutable() { return "$return_val" } +# Convert player list from JSON format +convert_JSON_to_CSV_players(){ + echo 'name,playeruid,steamid' + echo -n "${1}" | \ + jq -r '.players[] | [ .name, .playerId, .userId ] | @csv' | \ + sed -re 's/"None"/"00000000000000000000000000000000"/' \ + -re 's/"steam_/"/' \ + -re 's/"//g' +} + # Lists players -# Outputs nothing if RCON is not enabled and returns 1 -# Outputs player list if RCON is enabled and returns 0 +# Outputs nothing if REST API or RCON is not enabled and returns 1 +# Outputs player list if REST API or RCON is enabled and returns 0 get_players_list() { local return_val=0 - if [ "${RCON_ENABLED,,}" != true ]; then - return_val=1 - fi + # Prefer REST API + if [ "${REST_API_ENABLED,,}" != true ]; then + if [ "${RCON_ENABLED,,}" != true ]; then + return_val=1 + fi - RCON "ShowPlayers" + RCON "ShowPlayers" + return "$return_val" + fi + convert_JSON_to_CSV_players "$(REST_API players)" return "$return_val" } @@ -155,6 +170,19 @@ DiscordMessage() { fi } +# REST API Call +REST_API(){ + local DATA="${2}" + local URL="http://localhost:${REST_API_PORT}/v1/api/${1}" + local ACCEPT="Accept: application/json" + local USERPASS="admin:${ADMIN_PASSWORD}" + if [ "${DATA}" = "" ]; then + curl -s -L -X GET "${URL}" -H "${ACCEPT}" -u "${USERPASS}" + else + curl -s -L -X POST "${URL}" -H "${ACCEPT}" -u "${USERPASS}" --json "${DATA}" + fi +} + # RCON Call RCON() { local args="$1" @@ -167,6 +195,13 @@ RCON() { # Returns 1 if not able to broadcast broadcast_command() { local return_val=0 + if [ "${REST_API_ENABLED,,}" = true ]; then + local json="{\"message\":\"${1}\"}" + if ! REST_API announce "${json}"; then + return_val=1 + fi + return "$return_val" + fi # Replaces spaces with underscore local message="${1// /_}" if [[ $TEXT = *[![:ascii:]]* ]]; then @@ -283,4 +318,5 @@ get_latest_version() { latest_version=$(curl https://api.github.com/repos/thijsvanloef/palworld-server-docker/releases/latest -s | jq .name -r) echo "$latest_version" -} \ No newline at end of file +} + diff --git a/scripts/player_logging.sh b/scripts/player_logging.sh index 5ae80b93..966f3e85 100644 --- a/scripts/player_logging.sh +++ b/scripts/player_logging.sh @@ -12,10 +12,19 @@ get_playername(){ echo "${player_info}" | sed -E 's/,([0-9]+),[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]//g' } -# Wait until rcon port is open -while ! nc -z 127.0.0.1 "${RCON_PORT}"; do +# Prefer REST API +if [ "${REST_API_ENABLED,,}" = true ]; then + _PORT=${REST_API_PORT} + _LABEL="REST API" +else + _PORT=${RCON_PORT} + _LABEL="RCON" +fi + +# Wait until rcon/rest-api port is open +while ! nc -z localhost "${_PORT}"; do sleep 5 - LogInfo "Waiting for RCON port to open to show player logging..." + LogInfo "Waiting for ${_LABEL}(${_PORT}) port to open to show player logging..." done while true; do diff --git a/scripts/start.sh b/scripts/start.sh index 2063f941..c6d64e2f 100644 --- a/scripts/start.sh +++ b/scripts/start.sh @@ -168,7 +168,7 @@ default: password: "${ADMIN_PASSWORD}" EOL -if [ "${ENABLE_PLAYER_LOGGING,,}" = true ] && [[ "${PLAYER_LOGGING_POLL_PERIOD}" =~ ^[0-9]+$ ]] && [ "${RCON_ENABLED,,}" = true ]; then +if [ "${ENABLE_PLAYER_LOGGING,,}" = true ] && [[ "${PLAYER_LOGGING_POLL_PERIOD}" =~ ^[0-9]+$ ]] && ( [ "${REST_API_ENABLED,,}" = true ] || [ "${RCON_ENABLED,,}" = true ] ); then if [[ "$(id -u)" -eq 0 ]]; then su steam -c /home/steam/server/player_logging.sh & else From 3150a3911684436d7a1a5c579ab5bf2c55a1a774 Mon Sep 17 00:00:00 2001 From: Muscle Date: Sat, 20 Apr 2024 06:08:10 +0900 Subject: [PATCH 2/4] fix lint error --- scripts/start.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/start.sh b/scripts/start.sh index c6d64e2f..8563f76a 100644 --- a/scripts/start.sh +++ b/scripts/start.sh @@ -168,7 +168,7 @@ default: password: "${ADMIN_PASSWORD}" EOL -if [ "${ENABLE_PLAYER_LOGGING,,}" = true ] && [[ "${PLAYER_LOGGING_POLL_PERIOD}" =~ ^[0-9]+$ ]] && ( [ "${REST_API_ENABLED,,}" = true ] || [ "${RCON_ENABLED,,}" = true ] ); then +if [ "${ENABLE_PLAYER_LOGGING,,}" = true ] && [[ "${PLAYER_LOGGING_POLL_PERIOD}" =~ ^[0-9]+$ ]] && { [ "${REST_API_ENABLED,,}" = true ] || [ "${RCON_ENABLED,,}" = true ] ;} then if [[ "$(id -u)" -eq 0 ]]; then su steam -c /home/steam/server/player_logging.sh & else From 0d31f455869784bbb3dcb97bc5f03ff1d90c8af0 Mon Sep 17 00:00:00 2001 From: Muscle Date: Mon, 22 Apr 2024 18:27:23 +0900 Subject: [PATCH 3/4] fixed get_playername correctly for player logging. --- scripts/player_logging.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/scripts/player_logging.sh b/scripts/player_logging.sh index 966f3e85..a7636087 100644 --- a/scripts/player_logging.sh +++ b/scripts/player_logging.sh @@ -9,7 +9,7 @@ get_steamid(){ get_playername(){ local player_info="${1}" - echo "${player_info}" | sed -E 's/,([0-9]+),[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]//g' + echo "${player_info}" | sed -E 's/,([0-9A-Z]+),[0-9]+//g' } # Prefer REST API @@ -30,9 +30,9 @@ done while true; do server_pid=$(pidof PalServer-Linux-Shipping) if [ -n "${server_pid}" ]; then - # Player IDs are usally 9 or 10 digits however when a player joins for the first time for a given boot their ID is temporary 00000000 (8x zeros) while loading - # Player ID is also 00000000 (8x zeros) when in character creation - mapfile -t current_player_list < <( get_players_list | tail -n +2 | sed '/,00000000,[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]/d' | sort ) + # Player IDs are usally 9 or 10 digits however when a player joins for the first time for a given boot their ID is temporary 00000000 (8x zeros or 32x zeros) while loading + # Player ID is also 00000000 (8x zeros or 32x zeros) when in character creation + mapfile -t current_player_list < <( get_players_list | tail -n +2 | sed -E '/,(0{8}|0{32}),[0-9]+/d' | sort ) # If there are current players then some may have joined if [ "${#current_player_list[@]}" -gt 0 ]; then From 63eb8d6061398c1bd16d6c3e1d7d66b0a056c796 Mon Sep 17 00:00:00 2001 From: Thijs van Loef Date: Mon, 22 Apr 2024 15:32:15 +0200 Subject: [PATCH 4/4] set default rest api port --- Dockerfile | 1 + 1 file changed, 1 insertion(+) diff --git a/Dockerfile b/Dockerfile index 82bb0562..8cd778f1 100644 --- a/Dockerfile +++ b/Dockerfile @@ -88,6 +88,7 @@ ENV HOME=/home/steam \ RCON_ENABLED=true \ RCON_PORT=25575 \ QUERY_PORT=27015 \ + REST_API_PORT=8212 \ TZ=UTC \ SERVER_DESCRIPTION= \ BACKUP_ENABLED=true \