From 9c297ab7b1c3ccac61e4432139bc581093c48dc4 Mon Sep 17 00:00:00 2001 From: scriptos Date: Thu, 18 Sep 2025 21:59:22 +0200 Subject: [PATCH] ANSI/MC-Farbcodes strippen, robustes Schreiben der Playerliste --- mc-ntfy-notify.v1.sh | 57 ++++++++++++++++++++++++++++++++++---------- 1 file changed, 44 insertions(+), 13 deletions(-) diff --git a/mc-ntfy-notify.v1.sh b/mc-ntfy-notify.v1.sh index 0b5b96e..fbb5d62 100644 --- a/mc-ntfy-notify.v1.sh +++ b/mc-ntfy-notify.v1.sh @@ -4,9 +4,9 @@ # Autor: Patrick Asmus # Web: https://www.cleveradmin.de # Repository: https://git.techniverse.net/scriptos/minecraft-ntfy-notify -# Version: 1.0 +# Version: 1.1 # Datum: 18.09.2025 -# Modifikation: Initial +# Modifikation: ANSI/MC-Farbcodes strippen, robustes Schreiben der Playerliste ##################################################### set -euo pipefail @@ -42,9 +42,13 @@ STATE_DIR="${STATE_DIR:-${SCRIPT_DIR}/state}" STATE_PLAYERS="${STATE_DIR}/players.prev" STATE_UP="${STATE_DIR}/server_up.prev" +# Optional Debug +DEBUG="${DEBUG:-false}" + # ===== Helpers ===== die() { echo "ERROR: $*" >&2; exit 1; } need_bin() { command -v "$1" >/dev/null 2>&1 || die "Benötigtes Tool fehlt: $1"; } +dbg() { [[ "$DEBUG" == "true" ]] && echo "DBG: $*" >&2 || true; } ntfy_notify() { local title="$1" body="$2" tags="$3" priority="$4" @@ -63,19 +67,46 @@ ensure_state() { [[ -f "$STATE_UP" ]] || echo "unknown" >"$STATE_UP" } +# Strippt ANSI-Escape-Sequenzen, MC-Farbcodes (§x), CR und Steuerzeichen +sanitize() { + # stdin -> stdout + sed -E $'s/\x1B\\[[0-9;]*[A-Za-z]//g' \ + | sed -E 's/§[0-9A-FK-ORa-fk-or]//g' \ + | tr -d '\r' \ + | sed -E 's/[\x00-\x1F\x7F]//g' +} + get_players() { local out if ! out=$(mcrcon -H "$MC_HOST" -P "$RCON_PORT" -p "$RCON_PASSWORD" "list" 2>/dev/null); then return 1 fi - if grep -q "players online:" <<<"$out"; then - local names="${out#*:}" - names="$(echo "$names" | sed 's/^ *//;s/ *$//')" - if [[ -n "$names" ]]; then - tr ',' '\n' <<<"$names" | sed 's/^ *//;s/ *$//' | sed '/^$/d' | sort -u - return 0 - fi + dbg "RAW: $out" + + # Normalisieren & Farbcodes raus + out="$(printf '%s' "$out" | sanitize)" + + # Erwartete Muster: + # "There are 0 of a max of 20 players online" + # "There are 2 of a max of 20 players online: Alice, Bob" + if ! grep -q "players online:" <<<"$out"; then + # Kein Spieler gelistet, aber kein Fehler + return 0 fi + + local names="${out#*:}" + names="$(echo "$names" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')" + if [[ -z "$names" ]]; then + return 0 + fi + + # Namen splitten, trimmen, doppelte raus, sortiert liefern + printf '%s\n' "$names" \ + | tr ',' '\n' \ + | sed 's/^[[:space:]]*//;s/[[:space:]]*$//' \ + | sed '/^$/d' \ + | LC_ALL=C sort -u + return 0 } @@ -90,9 +121,8 @@ prev_up="$(cat "$STATE_UP")" while :; do tmp_players="$(mktemp)" - if players=$(get_players); then + if get_players >"$tmp_players"; then server_up="true" - printf "%s\n" $players 2>/dev/null | sed '/^$/d' | sort -u >"$tmp_players" else server_up="false" : >"$tmp_players" @@ -111,7 +141,8 @@ while :; do fi if [[ "$server_up" == "true" ]]; then - sort -u "$STATE_PLAYERS" -o "$STATE_PLAYERS" + LC_ALL=C sort -u "$STATE_PLAYERS" -o "$STATE_PLAYERS" + joined="$(comm -13 "$STATE_PLAYERS" "$tmp_players" || true)" left="$(comm -23 "$STATE_PLAYERS" "$tmp_players" || true)" @@ -140,4 +171,4 @@ while :; do echo -n "$server_up" >"$STATE_UP" prev_up="$server_up" sleep "$POLL_SECONDS" -done \ No newline at end of file +done