Update README.md, check_dependencies.sh, colors.txt, and 3 more files for new alpha, get rid of IMagick for vips

This commit is contained in:
Rainer 2025-06-28 20:14:08 +02:00
parent 33f64cc57d
commit a3556c44e1
6 changed files with 1317 additions and 1048 deletions

View file

@ -29,7 +29,6 @@ if [ -z "$1" ]; then
if [ -f "${world_dir}web.conf" ]; then
world_key_to_process=$(basename "$world_dir")
log_message "main" "--- Starte Durchlauf für '${world_key_to_process}' ---"
# Rufe das Skript für die gefundene Welt rekursiv auf
bash "$0" "$world_key_to_process"
fi
done
@ -38,17 +37,14 @@ if [ -z "$1" ]; then
exit 0
fi
# #############################################################################
# Ab hier beginnt die Logik für eine EINZELNE Welt
# #############################################################################
# Prüfe Abhängigkeiten, bevor irgendetwas anderes passiert
/opt/luweb/check_dependencies.sh || exit 1
WORLD_KEY=$1
# Pfad zum Verzeichnis der aktuellen Welt
CURRENT_MINETEST_WORLD_DATA_PATH="${MINETESTMAPPER_WORLD_DATA_BASE_PATH}${WORLD_KEY}/"
if [ ! -d "$CURRENT_MINETEST_WORLD_DATA_PATH" ]; then
@ -94,105 +90,97 @@ ARCHIVE_BASE_WEB_PATH="${WEB_CURRENT_WORLD_DIR}/${ARCHIVE_SUBDIR_NAME}"
# === Funktion zur Archivbereinigung ===
prune_archives() {
log_message "${WORLD_KEY}" "Starte Archivbereinigung für Welt '${WORLD_KEY}' im Pfad '${ARCHIVE_BASE_WEB_PATH}'..."
if [ ! -d "$ARCHIVE_BASE_WEB_PATH" ]; then log_message "${WORLD_KEY}" "Archiv-Basispfad ${ARCHIVE_BASE_WEB_PATH} nicht gefunden."; return; fi
local today_seconds=$(date +%s); local cutoff_date_14_days=$(date -d "today - 14 days" +%Y-%m-%d)
local cutoff_seconds_14_days=$(date -d "$cutoff_date_14_days" +%s)
log_message "${WORLD_KEY}" "Archivbereinigung: Behalte tägliche Bilder bis einschl. ${cutoff_date_14_days}. Ältere nur Montage."
local images_processed=0; local images_deleted=0
log_message "${WORLD_KEY}" "Starte Archivbereinigung..."
if [ ! -d "$ARCHIVE_BASE_WEB_PATH" ]; then return; fi
local cutoff_date_14_days=$(date -d "today - 14 days" +%Y-%m-%d)
find "$ARCHIVE_BASE_WEB_PATH" -type f -name "*.png" | while IFS= read -r archive_file_path; do
((images_processed++))
if [[ "$archive_file_path" =~ /([0-9]{4})/([0-9]{2})/([0-9]{2})\.png$ ]]; then
local year="${BASH_REMATCH[1]}"; local month="${BASH_REMATCH[2]}"; local day="${BASH_REMATCH[3]}"
local img_date_str="${year}-${month}-${day}"; local img_date_seconds; local day_of_week
if ! date -d "$img_date_str" "+%s" >/dev/null 2>&1; then log_message "${WORLD_KEY}" "WARNUNG: Ungültiges Datum: '${img_date_str}' ('${archive_file_path}')."; continue; fi
img_date_seconds=$(date -d "$img_date_str" +%s)
if [ "$img_date_seconds" -ge "$cutoff_seconds_14_days" ]; then log_message "${WORLD_KEY}" "BEHALTE (<=14 Tage): ${archive_file_path}"
else day_of_week=$(date -d "$img_date_str" +%u); if [ "$day_of_week" -eq 1 ]; then log_message "${WORLD_KEY}" "BEHALTE (>14 Tage, Montag): ${archive_file_path}"; else log_message "${WORLD_KEY}" "LÖSCHE (>14 Tage, kein Montag): ${archive_file_path}"; if rm -f "$archive_file_path"; then ((images_deleted++)); else log_message "${WORLD_KEY}" "FEHLER Löschen: ${archive_file_path}"; fi; fi; fi
else log_message "${WORLD_KEY}" "WARNUNG: Pfad '${archive_file_path}' passt nicht zu JJJJ/MM/TT.png."; fi
local img_date_str="${BASH_REMATCH[1]}-${BASH_REMATCH[2]}-${BASH_REMATCH[3]}"
if ! date -d "$img_date_str" "+%s" >/dev/null 2>&1; then continue; fi
if [ "$(date -d "$img_date_str" +%s)" -ge "$(date -d "$cutoff_date_14_days" +%s)" ]; then continue; fi
if [ "$(date -d "$img_date_str" +%u)" -ne 1 ]; then
log_message "${WORLD_KEY}" "LÖSCHE (>14 Tage, kein Montag): ${archive_file_path}"
rm -f "$archive_file_path"
fi
fi
done
log_message "${WORLD_KEY}" "Archivbereinigung: ${images_processed} geprüft, ${images_deleted} gelöscht."
log_message "${WORLD_KEY}" "Räume leere Archiv-Unterverzeichnisse auf..."; find "$ARCHIVE_BASE_WEB_PATH" -mindepth 1 -type d -empty -print -delete >> "$LOG_FILE" 2>&1
find "$ARCHIVE_BASE_WEB_PATH" -mindepth 1 -type d -empty -delete
}
# === Hauptlogik für eine einzelne Welt ===
exec 200>"$LOCK_FILE"
flock -n 200 || { log_message "${WORLD_KEY}" "Script ${SCRIPT_BASENAME}.sh ist bereits für diese Welt aktiv (Lock: ${LOCK_FILE}). Beende."; exit 1; }
flock -n 200 || { log_message "${WORLD_KEY}" "Script bereits aktiv. Beende."; exit 1; }
trap 'rm -f "$LOCK_FILE"; log_message "${WORLD_KEY}" "Skript beendet."' EXIT
log_message "${WORLD_KEY}" "Skript gestartet."
mkdir -p "${RAW_MAP_OUTPUT_DIR_ABSOLUTE}"
# 1. Generiere die map.png
log_message "${WORLD_KEY}" "Starte minetestmapper zur Kartengenerierung..."
MM_ALL_OPTIONS_STR="--zoom ${MM_OPT_ZOOM_LEVEL}"; if [ "${MM_CFG_DRAWALPHA}" = "true" ]; then MM_ALL_OPTIONS_STR="${MM_ALL_OPTIONS_STR} --drawalpha"; fi
if [ "${MM_CFG_DRAWORIGIN}" = "true" ]; then MM_ALL_OPTIONS_STR="${MM_ALL_OPTIONS_STR} --draworigin"; fi
log_message "${WORLD_KEY}" "Starte minetestmapper..."
MM_ALL_OPTIONS_STR="--zoom ${MM_OPT_ZOOM_LEVEL} --min-y ${MM_OPT_MIN_Y}"
if [ "${MM_CFG_DRAWALPHA}" = "true" ]; then MM_ALL_OPTIONS_STR="${MM_ALL_OPTIONS_STR} --drawalpha"; fi
if [ "${MM_CFG_DRAWPLAYERS}" = "true" ]; then MM_ALL_OPTIONS_STR="${MM_ALL_OPTIONS_STR} --drawplayers"; fi
if [ "${MM_CFG_DRAWSCALE}" = "true" ]; then MM_ALL_OPTIONS_STR="${MM_ALL_OPTIONS_STR} --drawscale"; fi
MM_ALL_OPTIONS_STR="${MM_ALL_OPTIONS_STR} --origincolor '${MM_OPT_ORIGINCOLOR}' --playercolor '${MM_OPT_PLAYERCOLOR}'"
MM_ALL_OPTIONS_STR="${MM_ALL_OPTIONS_STR} --scalecolor '${MM_OPT_SCALECOLOR}' --bgcolor '${MM_OPT_BGCOLOR}'"
MM_ALL_OPTIONS_STR="${MM_ALL_OPTIONS_STR} --min-y ${MM_OPT_MIN_Y}"
MAP_GENERATION_COMMAND="'${MINETESTMAPPER_PATH}' -i '${CURRENT_MINETEST_WORLD_DATA_PATH}' -o '${RAW_MAP_ABSOLUTE_PATH}' ${MM_ALL_OPTIONS_STR}"
MAPPER_RUN_OUTPUT_CAPTURE_FILE=$(mktemp)
(set -o pipefail; eval "${MAP_GENERATION_COMMAND}" 2>&1 | tee -a "$LOG_FILE" > "$MAPPER_RUN_OUTPUT_CAPTURE_FILE"); MAPPER_EXIT_STATUS=$?
if [ ${MAPPER_EXIT_STATUS} -ne 0 ]; then log_message "${WORLD_KEY}" "FEHLER: minetestmapper (Status: ${MAPPER_EXIT_STATUS})."; rm -f "$MAPPER_RUN_OUTPUT_CAPTURE_FILE"; exit 1; fi
if [ ! -f "$RAW_MAP_ABSOLUTE_PATH" ]; then log_message "${WORLD_KEY}" "FEHLER: ${RAW_MAP_ABSOLUTE_PATH} nicht gefunden."; rm -f "$MAPPER_RUN_OUTPUT_CAPTURE_FILE"; exit 1; fi
if [ ${MAPPER_EXIT_STATUS} -ne 0 ] || [ ! -f "$RAW_MAP_ABSOLUTE_PATH" ]; then
log_message "${WORLD_KEY}" "FEHLER: minetestmapper (Status: ${MAPPER_EXIT_STATUS})."
rm -f "$MAPPER_RUN_OUTPUT_CAPTURE_FILE"; exit 1;
fi
log_message "${WORLD_KEY}" "map.png erfolgreich generiert."
# 2. Erstelle map_info.txt
log_message "${WORLD_KEY}" "Erstelle map_info.txt..."
MAP_DIMENSIONS=$(identify -format "%wx%h" "$RAW_MAP_ABSOLUTE_PATH" 2>/dev/null)
# KORREKTUR: Die komplizierte Fallback-Logik wird durch den einfachen, funktionierenden vipsheader-Befehl ersetzt.
IMG_WIDTH=$(vipsheader -f width "$RAW_MAP_ABSOLUTE_PATH" 2>/dev/null)
IMG_HEIGHT=$(vipsheader -f height "$RAW_MAP_ABSOLUTE_PATH" 2>/dev/null)
EXTENT_COMMAND="'${MINETESTMAPPER_PATH}' -i '${CURRENT_MINETEST_WORLD_DATA_PATH}' --extent ${MM_ALL_OPTIONS_STR}"
MAP_EXTENT=$(eval "${EXTENT_COMMAND}" 2>/dev/null | sed 's/Map extent: //')
if [ -n "$MAP_DIMENSIONS" ] && [ -n "$MAP_EXTENT" ]; then
if [[ "$IMG_WIDTH" =~ ^[0-9]+$ ]] && [ "$IMG_WIDTH" -gt 0 ] && [ -n "$MAP_EXTENT" ]; then
MAP_DIMENSIONS="${IMG_WIDTH}x${IMG_HEIGHT}"
{ echo "map_dimension=${MAP_DIMENSIONS}"; echo "map_extent=${MAP_EXTENT}"; } > "$MAP_INFO_FILE_ABSOLUTE_PATH"
log_message "${WORLD_KEY}" "map_info.txt erstellt: Dim=${MAP_DIMENSIONS}, Extent=${MAP_EXTENT}"
else
log_message "${WORLD_KEY}" "FEHLER: map_info.txt konnte nicht erstellt werden."
log_message "${WORLD_KEY}" "-> Ermittelte Bild-Breite: '${IMG_WIDTH}'"
log_message "${WORLD_KEY}" "-> Ermittelter Karten-Extent: '${MAP_EXTENT}'"
fi
# 3. Verarbeite unknown_nodes.txt
awk ' /Unknown nodes:/ {b=1;next} b&&NF==0 {b=0} b&&!/^[ \t]/ {b=0} b{n=$0;sub(/^[ \t]+/,"",n);sub(/[ \t]+$/,"",n);if(n~/:/&&n!="")print n} ' "$MAPPER_RUN_OUTPUT_CAPTURE_FILE" > "${UNKNOWN_NODES_FILE_ABSOLUTE_PATH}.new"
if [ -s "${UNKNOWN_NODES_FILE_ABSOLUTE_PATH}.new" ]; then
log_message "${WORLD_KEY}" "Neue 'Unknown nodes' gefunden. Füge zu bestehender Datei hinzu."
cat "${UNKNOWN_NODES_FILE_ABSOLUTE_PATH}.new" >> "${UNKNOWN_NODES_FILE_ABSOLUTE_PATH}"
sort -u "${UNKNOWN_NODES_FILE_ABSOLUTE_PATH}" -o "${UNKNOWN_NODES_FILE_ABSOLUTE_PATH}"
fi
rm -f "${UNKNOWN_NODES_FILE_ABSOLUTE_PATH}.new" "$MAPPER_RUN_OUTPUT_CAPTURE_FILE"
# 4. Erzeuge Web-Vorschaukarte mit vips
log_message "${WORLD_KEY}" "Erzeuge Web-Version von map.png (max ${RESIZED_MAX_DIMENSION}px) mit 'vips'..."
mkdir -p "$(dirname "$WEB_MAP_PNG_FULL_PATH")"
(set -o pipefail; vips thumbnail "$RAW_MAP_ABSOLUTE_PATH" "$WEB_MAP_PNG_FULL_PATH" "${RESIZED_MAX_DIMENSION}" --height "${RESIZED_MAX_DIMENSION}" --size "down" 2>&1 | tee -a "$LOG_FILE")
if [ $? -ne 0 ]; then log_message "${WORLD_KEY}" "FEHLER: Skalierung mit 'vips' fehlgeschlagen."; else log_message "${WORLD_KEY}" "Verkleinerte Web-map.png erstellt."; fi
# 5. Generiere Kacheln
log_message "${WORLD_KEY}" "Generiere Kacheln (Zoom: ${GDAL2TILES_ZOOM_LEVELS})..."
TEMP_TILES_DIR="${TILES_FULL_OUTPUT_PATH}_temp_$(date +%s)"; rm -rf "$TEMP_TILES_DIR";
TEMP_TILES_DIR="${TILES_FULL_OUTPUT_PATH}_temp_$(date +%s)";
(set -o pipefail; gdal2tiles.py --profile=raster --xyz --zoom="${GDAL2TILES_ZOOM_LEVELS}" -r near "${RAW_MAP_ABSOLUTE_PATH}" "${TEMP_TILES_DIR}" 2>&1 | tee -a "$LOG_FILE")
if [ $? -ne 0 ]; then log_message "${WORLD_KEY}" "FEHLER: gdal2tiles.py fehlgeschlagen."; rm -rf "$TEMP_TILES_DIR"; exit 1; fi
rm -rf "$TILES_FULL_OUTPUT_PATH"
if ! mv "$TEMP_TILES_DIR" "$TILES_FULL_OUTPUT_PATH"; then log_message "${WORLD_KEY}" "FEHLER: Verschieben der Kacheln fehlgeschlagen."; exit 1; fi
mv "$TEMP_TILES_DIR" "$TILES_FULL_OUTPUT_PATH"
log_message "${WORLD_KEY}" "Kacheln erfolgreich generiert."
# 6. Archiv-Management
prune_archives
ARCHIVE_YEAR=$(date '+%Y'); ARCHIVE_MONTH=$(date '+%m'); ARCHIVE_DAY=$(date '+%d')
ARCHIVE_DAILY_TARGET_DIR="${ARCHIVE_BASE_WEB_PATH}/${ARCHIVE_YEAR}/${ARCHIVE_MONTH}"
ARCHIVE_DAILY_FILE_PATH="${ARCHIVE_DAILY_TARGET_DIR}/${ARCHIVE_DAY}.png"
if [ ! -f "$ARCHIVE_DAILY_FILE_PATH" ]; then
log_message "${WORLD_KEY}" "Erzeuge Archivbild für ${ARCHIVE_DAILY_FILE_PATH}..."
mkdir -p "$ARCHIVE_DAILY_TARGET_DIR"
(set -o pipefail; vips thumbnail "$RAW_MAP_ABSOLUTE_PATH" "$ARCHIVE_DAILY_FILE_PATH" "${RESIZED_MAX_DIMENSION}" --height "${RESIZED_MAX_DIMENSION}" --size "down" 2>&1 | tee -a "$LOG_FILE")
if [ $? -eq 0 ]; then log_message "${WORLD_KEY}" "Verkleinertes Archivbild erstellt."; else log_message "${WORLD_KEY}" "FEHLER: Archivbild nicht erstellt.";fi
vips thumbnail "$RAW_MAP_ABSOLUTE_PATH" "$ARCHIVE_DAILY_FILE_PATH" "${RESIZED_MAX_DIMENSION}" --height "${RESIZED_MAX_DIMENSION}" --size "down"
fi
# 7. Finale Info-Dateien kopieren
log_message "${WORLD_KEY}" "Kopiere finale Info-Dateien ins Web-Verzeichnis..."
mkdir -p "$WEB_CURRENT_WORLD_DIR"
echo "$(date '+%Y-%m-%d %H:%M:%S %Z')" > "${WEB_CURRENT_WORLD_DIR}/last_update.txt"
cp "$UNKNOWN_NODES_FILE_ABSOLUTE_PATH" "${WEB_CURRENT_WORLD_DIR}/unknown_nodes.txt"
cp "$MAP_INFO_FILE_ABSOLUTE_PATH" "${WEB_CURRENT_WORLD_DIR}/map_info.txt"
[ -f "$UNKNOWN_NODES_FILE_ABSOLUTE_PATH" ] && cp "$UNKNOWN_NODES_FILE_ABSOLUTE_PATH" "${WEB_CURRENT_WORLD_DIR}/unknown_nodes.txt"
[ -f "$MAP_INFO_FILE_ABSOLUTE_PATH" ] && cp "$MAP_INFO_FILE_ABSOLUTE_PATH" "${WEB_CURRENT_WORLD_DIR}/map_info.txt"
exit 0