127 lines
5.3 KiB
Bash
Executable file
127 lines
5.3 KiB
Bash
Executable file
#!/bin/bash
|
|
|
|
# Lade globale Konfiguration
|
|
CONFIG_FILE_PATH="$(dirname "$0")/config.sh"
|
|
if [ -f "$CONFIG_FILE_PATH" ]; then
|
|
source "$CONFIG_FILE_PATH"
|
|
else
|
|
echo "FEHLER: Globale config.sh nicht unter ${CONFIG_FILE_PATH} gefunden!"
|
|
exit 1
|
|
fi
|
|
|
|
# Prüfe Abhängigkeiten, bevor irgendetwas anderes passiert
|
|
/opt/luweb/check_dependencies.sh || exit 1
|
|
|
|
# Welt-Schlüssel (Verzeichnisname) aus Argument oder Standardwert
|
|
WORLD_KEY="${1:-$DEFAULT_WORLD_NAME_KEY}"
|
|
CURRENT_MINETEST_WORLD_DATA_PATH="${MINETESTMAPPER_WORLD_DATA_BASE_PATH}${WORLD_KEY}/"
|
|
|
|
# === Abgeleitete Variablen ===
|
|
SCRIPT_BASENAME=$(basename "$0" .sh)
|
|
LOG_FILE="${LOG_DIR_BASE}/${SCRIPT_BASENAME}_${WORLD_KEY}.log"
|
|
LOCK_FILE="${LOCK_FILE_BASE_DIR}/${SCRIPT_BASENAME}_${WORLD_KEY}.lock"
|
|
|
|
# Pfade zu den Datenbanken und der Zieldatei
|
|
PLAYERS_DB_PATH="${CURRENT_MINETEST_WORLD_DATA_PATH}players.sqlite"
|
|
AUTH_DB_PATH="${CURRENT_MINETEST_WORLD_DATA_PATH}auth.sqlite"
|
|
PLAYERS_JSON_TARGET_DIR="${WEB_ROOT_PATH}/${WEB_MAPS_BASE_SUBDIR}/${WORLD_KEY}"
|
|
PLAYERS_JSON_FILE_PATH="${PLAYERS_JSON_TARGET_DIR}/players.txt"
|
|
PLAYERS_JSON_TMP_FILE_PATH="${PLAYERS_JSON_FILE_PATH}.tmp"
|
|
|
|
# SQLite-Befehl
|
|
SQLITE_CMD="sqlite3 -readonly"
|
|
|
|
# === Logging Funktion ===
|
|
log_message() {
|
|
local message_to_log; message_to_log="$(date '+%Y-%m-%d %H:%M:%S') - [${WORLD_KEY}] - $1"
|
|
echo "${message_to_log}" | tee -a "$LOG_FILE"
|
|
}
|
|
|
|
# === Hauptlogik ===
|
|
exec 200>"$LOCK_FILE"
|
|
flock -n 200 || { log_message "Script ${SCRIPT_BASENAME}.sh ist bereits aktiv (Lock: ${LOCK_FILE}). Beende."; exit 1; }
|
|
trap 'rm -f "$LOCK_FILE"; log_message "Skript beendet."' EXIT
|
|
|
|
mkdir -p "$LOG_DIR_BASE"
|
|
log_message "Script gestartet für Welt: ${WORLD_KEY}"
|
|
|
|
# Prüfen, ob die Datenbanken existieren
|
|
if [ ! -f "$PLAYERS_DB_PATH" ] || [ ! -f "$AUTH_DB_PATH" ]; then
|
|
log_message "FEHLER: players.sqlite oder auth.sqlite nicht gefunden. Pfade prüfen:"
|
|
log_message "-> ${PLAYERS_DB_PATH}"
|
|
log_message "-> ${AUTH_DB_PATH}"
|
|
exit 1
|
|
fi
|
|
|
|
# Beginne mit dem Schreiben der temporären JSON-Datei
|
|
echo "{" > "$PLAYERS_JSON_TMP_FILE_PATH"
|
|
|
|
first_entry=true
|
|
|
|
# Lese alle Spieler aus der auth-Datenbank (ID, Name, Letzter Login)
|
|
player_list_query="SELECT id, name, last_login FROM auth;"
|
|
$SQLITE_CMD "$AUTH_DB_PATH" "$player_list_query" | while IFS='|' read -r player_id name last_login; do
|
|
|
|
log_message "Verarbeite Spieler: ${name} (ID: ${player_id})"
|
|
|
|
player_data_query="SELECT posX, posY, posZ, hp, breath, pitch, yaw, creation_date FROM player WHERE name = '${name}';"
|
|
player_data=$($SQLITE_CMD "$PLAYERS_DB_PATH" "$player_data_query")
|
|
|
|
if [ -z "$player_data" ]; then
|
|
log_message "WARNUNG: Spieler '${name}' hat keine Positionsdaten in players.sqlite. Wird übersprungen."
|
|
continue
|
|
fi
|
|
|
|
IFS='|' read -r posX posY posZ hp breath pitch yaw creation_date <<< "$player_data"
|
|
|
|
posX_rounded=$(printf "%.0f" "$(echo "$posX / 10" | bc)")
|
|
posY_rounded=$(printf "%.0f" "$(echo "$posY / 10" | bc)")
|
|
posZ_rounded=$(printf "%.0f" "$(echo "$posZ / 10" | bc)")
|
|
pitch_rounded=$(printf "%.0f" "$pitch")
|
|
yaw_rounded=$(printf "%.0f" "$yaw")
|
|
|
|
stamina_query="SELECT value FROM player_metadata WHERE player = '${name}' AND metadata = 'hunger_ng:hunger_value';"
|
|
stamina_val=$($SQLITE_CMD "$PLAYERS_DB_PATH" "$stamina_query")
|
|
stamina_rounded=$(printf "%.0f" "${stamina_val:-0}")
|
|
|
|
privs_query="SELECT privilege FROM user_privileges WHERE id = ${player_id};"
|
|
privs_string=$($SQLITE_CMD "$AUTH_DB_PATH" "$privs_query" | tr '\n' ',' | sed 's/,$//')
|
|
|
|
# Komma vor dem Eintrag hinzufügen, außer beim ersten
|
|
if [ "$first_entry" = true ]; then
|
|
first_entry=false
|
|
else
|
|
echo "," >> "$PLAYERS_JSON_TMP_FILE_PATH"
|
|
fi
|
|
|
|
# JSON-Objekt für den Spieler erstellen und in die Datei schreiben
|
|
printf ' "%s": {\n' "$player_id" >> "$PLAYERS_JSON_TMP_FILE_PATH"
|
|
printf ' "name": "%s",\n' "$name" >> "$PLAYERS_JSON_TMP_FILE_PATH"
|
|
printf ' "pitch": %d,\n' "$pitch_rounded" >> "$PLAYERS_JSON_TMP_FILE_PATH"
|
|
printf ' "yaw": %d,\n' "$yaw_rounded" >> "$PLAYERS_JSON_TMP_FILE_PATH"
|
|
printf ' "posX": %d,\n' "$posX_rounded" >> "$PLAYERS_JSON_TMP_FILE_PATH"
|
|
printf ' "posY": %d,\n' "$posY_rounded" >> "$PLAYERS_JSON_TMP_FILE_PATH"
|
|
printf ' "posZ": %d,\n' "$posZ_rounded" >> "$PLAYERS_JSON_TMP_FILE_PATH"
|
|
printf ' "hp": %d,\n' "$hp" >> "$PLAYERS_JSON_TMP_FILE_PATH"
|
|
printf ' "breath": %d,\n' "$breath" >> "$PLAYERS_JSON_TMP_FILE_PATH"
|
|
printf ' "stamina": %d,\n' "$stamina_rounded" >> "$PLAYERS_JSON_TMP_FILE_PATH"
|
|
printf ' "creation_date": "%s",\n' "$(echo "$creation_date" | sed 's/ /T/')Z" >> "$PLAYERS_JSON_TMP_FILE_PATH"
|
|
printf ' "last_login": %s,\n' "$last_login" >> "$PLAYERS_JSON_TMP_FILE_PATH"
|
|
# KORREKTUR: Kein Komma nach dem letzten Element
|
|
printf ' "privilege": "%s"\n' "$privs_string" >> "$PLAYERS_JSON_TMP_FILE_PATH"
|
|
printf ' }' >> "$PLAYERS_JSON_TMP_FILE_PATH"
|
|
|
|
done
|
|
|
|
# JSON-Datei abschließen
|
|
# KORREKTUR: Die überflüssige schließende Klammer wird hier entfernt
|
|
echo "" >> "$PLAYERS_JSON_TMP_FILE_PATH"
|
|
echo "}" >> "$PLAYERS_JSON_TMP_FILE_PATH"
|
|
|
|
# Temporäre Datei an den Zielort verschieben
|
|
mkdir -p "$PLAYERS_JSON_TARGET_DIR"
|
|
mv "$PLAYERS_JSON_TMP_FILE_PATH" "$PLAYERS_JSON_FILE_PATH"
|
|
|
|
log_message "players.txt erfolgreich synchronisiert nach ${PLAYERS_JSON_FILE_PATH}"
|
|
|
|
exit 0
|