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 \ 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..a7636087 100644 --- a/scripts/player_logging.sh +++ b/scripts/player_logging.sh @@ -9,21 +9,30 @@ 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' } -# 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 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 diff --git a/scripts/start.sh b/scripts/start.sh index 2063f941..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]+$ ]] && [ "${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