Compare commits

..

2 Commits

Author SHA1 Message Date
scriptos
363a76504a - SERVER_NAME im Titel
- GAME_HOST/GAME_PORT im Body
- MESSAGE_EXTRA als zusätzliche Body-Zeile (optional)
- Body-Layout mehrzeilig: Event, Server,
Port, [Extra]
2025-09-19 21:20:37 +02:00
scriptos
67cd245a0a Tags entfernt; Titel statisch (kein Join/Leave im Titel); DNS:Port im Body ergänzt 2025-09-19 19:47:58 +02:00
2 changed files with 58 additions and 37 deletions

10
.env
View File

@ -7,9 +7,15 @@ export RCON_PASSWORD=""
export POLL_SECONDS="10"
export ANNOUNCE_SERVER_UPDOWN="true"
# Anzeigename/Tag
# Spiel-Adresse:
export GAME_HOST="mc.techniverse.net"
export GAME_PORT="25573"
# Anzeigename:
SERVER_NAME="[GER] Blockventure | ⌁25573"
SERVER_TAG="blockventure-25573"
# Optionale Zusatzzeile im Body
MESSAGE_EXTRA="Whitelist aktiv"
# ntfy
export NTFY_SERVER="https://ntfy.pushservice.techniverse.net"

View File

@ -4,19 +4,20 @@
# Autor: Patrick Asmus
# Web: https://www.cleveradmin.de
# Repository: https://git.techniverse.net/scriptos/minecraft-ntfy-notify
# Version: 1.4
# Datum: 18.09.2025
# Modifikation:
# - Serverlabel/Tags (SERVER_NAME/SERVER_TAG) in Titel & ntfy-Tags
# - State-Verzeichnis per Instanz (Host:Port:Topic)
# - Optionales ENV_FILE zum Laden einer spezifischen .env
# Version: 1.8
# Datum: 19.09.2025
# Änderungen:
# - SERVER_NAME im Titel
# - GAME_HOST/GAME_PORT im Body
# - MESSAGE_EXTRA als zusätzliche Body-Zeile (optional)
# - Body-Layout mehrzeilig: Event, Server, Port, [Extra]
#####################################################
set -euo pipefail
export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
# --- .env laden: zuerst ENV_FILE (falls gesetzt), sonst ./.env ---
# .env laden: bevorzugt ENV_FILE, sonst ./.env
if [[ -n "${ENV_FILE:-}" && -f "${ENV_FILE}" ]]; then
set -a; . "${ENV_FILE}"; set +a
elif [[ -f "${SCRIPT_DIR}/.env" ]]; then
@ -24,10 +25,15 @@ elif [[ -f "${SCRIPT_DIR}/.env" ]]; then
fi
# ===== Konfiguration via ENV =====
# RCON (für Polling)
MC_HOST="${MC_HOST:-127.0.0.1}"
RCON_PORT="${RCON_PORT:-25575}"
RCON_PASSWORD="${RCON_PASSWORD:-changeme}"
# Spiel-Adresse (DNS:Port zum Joinen, nur Anzeige)
GAME_HOST="${GAME_HOST:-${MC_HOST}}"
GAME_PORT="${GAME_PORT:-25565}"
POLL_SECONDS="${POLL_SECONDS:-10}"
ANNOUNCE_SERVER_UPDOWN="${ANNOUNCE_SERVER_UPDOWN:-true}"
@ -36,33 +42,28 @@ NTFY_SERVER="${NTFY_SERVER:-}"
NTFY_TOPIC="${NTFY_TOPIC:-}"
NTFY_TOKEN="${NTFY_TOKEN:-}"
NTFY_TITLE_PREFIX="${NTFY_TITLE_PREFIX:-Minecraft}"
NTFY_TAGS_BASE="${NTFY_TAGS_BASE:-minecraft}"
NTFY_PRIORITY_JOIN="${NTFY_PRIORITY_JOIN:-3}"
NTFY_PRIORITY_LEAVE="${NTFY_PRIORITY_LEAVE:-3}"
NTFY_PRIORITY_UP="${NTFY_PRIORITY_UP:-4}"
NTFY_PRIORITY_DOWN="${NTFY_PRIORITY_DOWN:-5}"
NTFY_MARKDOWN="${NTFY_MARKDOWN:-false}"
# Server-Label/Tag
SERVER_NAME="${SERVER_NAME:-}" # z. B. "[GER] Blockventure | ⌁25573"
SERVER_LABEL="${SERVER_NAME:-${MC_HOST}:${RCON_PORT}}"
# Maschinenfreundlicher Tag, wenn nicht gesetzt: aus Name oder Host:Port ableiten
SERVER_TAG="${SERVER_TAG:-$(printf '%s' "${SERVER_NAME:-${MC_HOST}-${RCON_PORT}}" \
| tr '[:upper:]' '[:lower:]' | sed -E 's/[^a-z0-9]+/-/g;s/^-+|-+$//g')}"
# Anzeigename für den Titel
SERVER_NAME="${SERVER_NAME:-}"
# ==== Lock & State (pro Instanz eindeutig nach Host:Port:Topic) ====
# Optionale Zusatzzeile im Body
MESSAGE_EXTRA="${MESSAGE_EXTRA:-}"
# Lock & State je Instanz (Host:Port:Topic)
LOCK_KEY="$(printf '%s' "${MC_HOST}_${RCON_PORT}_${NTFY_TOPIC}" | tr -c 'A-Za-z0-9._-' '_')"
# eigenes State-Verzeichnis je Instanz (damit mehrere Server parallel sauber laufen)
STATE_DIR="${STATE_DIR:-${SCRIPT_DIR}/state.${LOCK_KEY}}"
STATE_PLAYERS="${STATE_DIR}/players.prev"
STATE_UP="${STATE_DIR}/server_up.prev"
RUN_DIR="${RUN_DIR:-${STATE_DIR}}"
LOCK_DIR="${RUN_DIR}/lock.${LOCK_KEY}"
PID_FILE="${LOCK_DIR}/pid"
RUN_MARK="${RUN_DIR}/running.${LOCK_KEY}"
# Optional Debug
DEBUG="${DEBUG:-false}"
# ===== Helpers =====
@ -84,7 +85,6 @@ acquire_lock() {
if [[ -f "$PID_FILE" ]]; then
oldpid="$(cat "$PID_FILE" 2>/dev/null || true)"
if [[ -n "${oldpid:-}" ]] && kill -0 "$oldpid" 2>/dev/null; then
dbg "Bereits laufend (PID $oldpid), beende."
exit 0
fi
fi
@ -95,11 +95,34 @@ acquire_lock() {
fi
}
build_title() {
if [[ -n "$SERVER_NAME" ]]; then
printf '%s - %s' "$NTFY_TITLE_PREFIX" "$SERVER_NAME"
else
printf '%s' "$NTFY_TITLE_PREFIX"
fi
}
# Baut den Body in gewünschtem Layout:
# <eventline>\nServer: <GAME_HOST>\nPort: <GAME_PORT>\n[<MESSAGE_EXTRA>]
build_body() {
local event="$1"
if [[ -n "$MESSAGE_EXTRA" ]]; then
printf '%s\n\nServer: %s\nPort: %s\n%s' \
"$event" "$GAME_HOST" "$GAME_PORT" "$MESSAGE_EXTRA"
else
printf '%s\nServer: %s\nPort: %s' \
"$event" "$GAME_HOST" "$GAME_PORT"
fi
}
ntfy_notify() {
local title="$1" body="$2" tags="$3" priority="$4"
# ntfy_notify "Body" PRIORITY
local body="$1" priority="$2"
[[ -z "$NTFY_SERVER" || -z "$NTFY_TOPIC" ]] && { echo "ntfy Server/Topic fehlt skip"; return 1; }
local url="${NTFY_SERVER%/}/${NTFY_TOPIC}"
local args=(-sS -X POST "$url" -H "Title: ${title}" -H "Priority: ${priority}" -H "Tags: ${tags}")
local title; title="$(build_title)"
local args=(-sS -X POST "$url" -H "Title: ${title}" -H "Priority: ${priority}")
[[ "$NTFY_MARKDOWN" == "true" ]] && args+=(-H "Markdown: yes")
[[ -n "$NTFY_TOKEN" ]] && args+=(-H "Authorization: Bearer ${NTFY_TOKEN}")
curl "${args[@]}" --data-raw "$body" >/dev/null 2>&1 || return 1
@ -112,7 +135,7 @@ ensure_state() {
[[ -f "$STATE_UP" ]] || echo "unknown" >"$STATE_UP"
}
# Strippt ANSI-Escape-Sequenzen, MC-Farbcodes (§x), CR und Steuerzeichen
# ANSI- & MC-Farbcodes entfernen
sanitize() {
sed -E $'s/\x1B\\[[0-9;]*[A-Za-z]//g' \
| sed -E 's/§[0-9A-FK-ORa-fk-or]//g' \
@ -150,7 +173,7 @@ need_bin mcrcon
ensure_state
acquire_lock
echo "Starte Polling ${MC_HOST}:${RCON_PORT} ntfy ${NTFY_SERVER}/${NTFY_TOPIC} (PID $$) [${SERVER_LABEL}]"
echo "Starte Polling RCON ${MC_HOST}:${RCON_PORT} -> ntfy ${NTFY_SERVER}/${NTFY_TOPIC} (PID $$)"
prev_up="$(cat "$STATE_UP")"
# ===== Main Loop =====
@ -167,13 +190,9 @@ while :; do
if [[ "$ANNOUNCE_SERVER_UPDOWN" == "true" && "$prev_up" != "unknown" && "$server_up" != "$prev_up" ]]; then
if [[ "$server_up" == "true" ]]; then
ntfy_notify "${NTFY_TITLE_PREFIX}: Server up — ${SERVER_LABEL}" \
"Server ist wieder erreichbar (${MC_HOST}:${RCON_PORT})." \
"${NTFY_TAGS_BASE},${SERVER_TAG},up" "$NTFY_PRIORITY_UP" || true
ntfy_notify "$(build_body "Server ist wieder erreichbar.")" "$NTFY_PRIORITY_UP" || true
else
ntfy_notify "${NTFY_TITLE_PREFIX}: Server down — ${SERVER_LABEL}" \
"Server ist nicht erreichbar (${MC_HOST}:${RCON_PORT})." \
"${NTFY_TAGS_BASE},${SERVER_TAG},down" "$NTFY_PRIORITY_DOWN" || true
ntfy_notify "$(build_body "Server ist nicht erreichbar.")" "$NTFY_PRIORITY_DOWN" || true
fi
fi
@ -185,17 +204,13 @@ while :; do
if [[ -n "$joined" ]]; then
while IFS= read -r name; do
[[ -z "$name" ]] && continue
ntfy_notify "${NTFY_TITLE_PREFIX}: Join — ${SERVER_LABEL}" \
"Player \"${name}\" ist beigetreten." \
"${NTFY_TAGS_BASE},${SERVER_TAG},join" "$NTFY_PRIORITY_JOIN" || true
ntfy_notify "$(build_body "Player \"${name}\" ist beigetreten.")" "$NTFY_PRIORITY_JOIN" || true
done <<<"$joined"
fi
if [[ -n "$left" ]]; then
while IFS= read -r name; do
[[ -z "$name" ]] && continue
ntfy_notify "${NTFY_TITLE_PREFIX}: Leave — ${SERVER_LABEL}" \
"Player \"${name}\" hat den Server verlassen." \
"${NTFY_TAGS_BASE},${SERVER_TAG},leave" "$NTFY_PRIORITY_LEAVE" || true
ntfy_notify "$(build_body "Player \"${name}\" hat den Server verlassen.")" "$NTFY_PRIORITY_LEAVE" || true
done <<<"$left"
fi