diff --git a/README.md b/README.md index 917e3c2..2bad1cb 100644 --- a/README.md +++ b/README.md @@ -37,11 +37,7 @@ To run this system, the following software packages must be installed on your se ### 1. Clone the Repository -Download the **latest build** from the [Releases-Page](https://git.geigernet.eu/rainer/luanti-web/releases) and save it to your server's base directory, such as `/opt/luweb/`. - -OR - -Clone all project files to a base directory on your server. +First, clone or copy all project files to a base directory on your server, such as `/opt/luweb/`. ``` git clone https://git.geigernet.eu/rainer/luanti-web.git /opt/luweb diff --git a/generate_map.sh b/generate_map.sh index 007d608..4de8461 100755 --- a/generate_map.sh +++ b/generate_map.sh @@ -33,8 +33,10 @@ MM_CFG_DRAWPLAYERS="$DEFAULT_MM_CFG_DRAWPLAYERS"; MM_CFG_DRAWSCALE="$DEFAULT_MM_ TILES_SUBDIR_NAME="$DEFAULT_TILES_SUBDIR_NAME"; GDAL2TILES_ZOOM_LEVELS="$DEFAULT_GDAL2TILES_ZOOM_LEVELS" WEB_MAP_PNG_FILENAME="$DEFAULT_WEB_MAP_PNG_FILENAME"; RESIZED_MAX_DIMENSION="$DEFAULT_RESIZED_MAX_DIMENSION" ARCHIVE_SUBDIR_NAME="$DEFAULT_ARCHIVE_SUBDIR_NAME" +# RAW_MAP_FILENAME ist global aus config.sh +# RAW_MAP_BASE_SUBDIR ist global aus config.sh (wird für den Output im BASE_SCRIPT_DIR verwendet) -WORLD_WEB_CONFIG_FILE="${CURRENT_MINETEST_WORLD_DATA_PATH}web.conf" +WORLD_WEB_CONFIG_FILE="${CURRENT_MINETEST_WORLD_DATA_PATH}web.conf" # web.conf im Minetest Weltordner if [ -f "$WORLD_WEB_CONFIG_FILE" ]; then echo "$(date '+%Y-%m-%d %H:%M:%S') - [${WORLD_KEY}] - Lade Web-Konfiguration aus ${WORLD_WEB_CONFIG_FILE}" source "$WORLD_WEB_CONFIG_FILE" @@ -48,13 +50,16 @@ MINETESTMAPPER_PATH="${BASE_SCRIPT_DIR}/${MINETESTMAPPER_EXEC_NAME}" LOG_FILE="${LOG_DIR_BASE}/${SCRIPT_BASENAME}_${WORLD_KEY}.log" LOCK_FILE="${LOCK_FILE_BASE_DIR}/${SCRIPT_BASENAME}_${WORLD_KEY}.lock" +# Wichtige Prüfungen für Pfadkomponenten für den Output von minetestmapper if [ -z "$RAW_MAP_BASE_SUBDIR" ]; then echo "FEHLER: RAW_MAP_BASE_SUBDIR ist in config.sh nicht gesetzt oder leer!"; exit 1; fi if [ -z "$RAW_MAP_FILENAME" ]; then echo "FEHLER: RAW_MAP_FILENAME ist in config.sh nicht gesetzt oder leer!"; exit 1; fi +# Ausgabepfade für rohe Kartendaten (im BASE_SCRIPT_DIR) RAW_MAP_OUTPUT_DIR_ABSOLUTE="${BASE_SCRIPT_DIR}/${RAW_MAP_BASE_SUBDIR}/${WORLD_KEY}" RAW_MAP_ABSOLUTE_PATH="${RAW_MAP_OUTPUT_DIR_ABSOLUTE}/${RAW_MAP_FILENAME}" UNKNOWN_NODES_FILE_ABSOLUTE_PATH="${RAW_MAP_OUTPUT_DIR_ABSOLUTE}/unknown_nodes.txt" +# Web-Pfade (nutzen den WORLD_KEY für die Verzeichnisstruktur) WEB_CURRENT_WORLD_DIR="${WEB_ROOT_PATH}/${WEB_MAPS_BASE_SUBDIR}/${WORLD_KEY}" TILES_FULL_OUTPUT_PATH="${WEB_CURRENT_WORLD_DIR}/${TILES_SUBDIR_NAME}" WEB_MAP_PNG_FULL_PATH="${WEB_CURRENT_WORLD_DIR}/${WEB_MAP_PNG_FILENAME}" @@ -96,8 +101,14 @@ flock -n 200 || { echo "$(date '+%Y-%m-%d %H:%M:%S') - [${WORLD_KEY}] Script ${S trap 'rm -f "$LOCK_FILE"; log_message "Skript ${SCRIPT_BASENAME}.sh beendet."' EXIT mkdir -p "$LOG_DIR_BASE"; log_message "Skript ${SCRIPT_BASENAME}.sh gestartet für Welt-Schlüssel: ${WORLD_KEY}" +log_message "DEBUG: MINETESTMAPPER_WORLD_DATA_BASE_PATH = '${MINETESTMAPPER_WORLD_DATA_BASE_PATH}'" # Neuer Debug-Log +log_message "DEBUG: CURRENT_MINETEST_WORLD_DATA_PATH (für -i Option) = '${CURRENT_MINETEST_WORLD_DATA_PATH}'" # Neuer Debug-Log +log_message "DEBUG: RAW_MAP_ABSOLUTE_PATH (für -o Option) = '${RAW_MAP_ABSOLUTE_PATH}'" + mkdir -p "${RAW_MAP_OUTPUT_DIR_ABSOLUTE}" if [ ! -d "${RAW_MAP_OUTPUT_DIR_ABSOLUTE}" ]; then log_message "FEHLER: Rohkarten-Ausgabeverz. (${RAW_MAP_OUTPUT_DIR_ABSOLUTE}) nicht erstellt."; exit 1; fi +log_message "DEBUG: Rohkarten-Ausgabeverzeichnis (${RAW_MAP_OUTPUT_DIR_ABSOLUTE}) existiert." +ls -ld "${RAW_MAP_OUTPUT_DIR_ABSOLUTE}" >> "$LOG_FILE" 2>/dev/null # 1. Generiere die map.png if [ ! -x "$MINETESTMAPPER_PATH" ]; then log_message "FEHLER: minetestmapper (${MINETESTMAPPER_PATH}) nicht ausführbar."; exit 1; fi @@ -108,30 +119,15 @@ if [ "${MM_CFG_DRAWSCALE}" = "true" ]; then MM_ALL_OPTIONS_STR="${MM_ALL_OPTIONS MM_ALL_OPTIONS_STR="${MM_ALL_OPTIONS_STR} --origincolor '${MM_OPT_ORIGINCOLOR}'"; MM_ALL_OPTIONS_STR="${MM_ALL_OPTIONS_STR} --playercolor '${MM_OPT_PLAYERCOLOR}'" MM_ALL_OPTIONS_STR="${MM_ALL_OPTIONS_STR} --scalecolor '${MM_OPT_SCALECOLOR}'"; MM_ALL_OPTIONS_STR="${MM_ALL_OPTIONS_STR} --bgcolor '${MM_OPT_BGCOLOR}'" MM_ALL_OPTIONS_STR="${MM_ALL_OPTIONS_STR} --min-y ${MM_OPT_MIN_Y}" - +# Verwendet CURRENT_MINETEST_WORLD_DATA_PATH für -i (korrekt mit / am Ende aus config.sh und WORLD_KEY) MAP_GENERATION_COMMAND_TO_EVAL="'${MINETESTMAPPER_PATH}' -i '${CURRENT_MINETEST_WORLD_DATA_PATH}' -o '${RAW_MAP_ABSOLUTE_PATH}' ${MM_ALL_OPTIONS_STR}" +log_message "DEBUG: Eval-Befehl: ${MAP_GENERATION_COMMAND_TO_EVAL}" log_message "Starte minetestmapper (Optionen: ${MM_ALL_OPTIONS_STR}). Ausgaben folgen:" MAPPER_RUN_OUTPUT_CAPTURE_FILE=$(mktemp); MAPPER_EXIT_STATUS=0 (set -o pipefail; eval "${MAP_GENERATION_COMMAND_TO_EVAL}" 2>&1 | tee -a "$LOG_FILE" > "$MAPPER_RUN_OUTPUT_CAPTURE_FILE"); MAPPER_EXIT_STATUS=$? if [ ${MAPPER_EXIT_STATUS} -ne 0 ]; then log_message "FEHLER: minetestmapper (Status: ${MAPPER_EXIT_STATUS})."; tail -n 15 "$MAPPER_RUN_OUTPUT_CAPTURE_FILE" | while IFS= read -r line; do log_message " ${line}"; done; rm -f "$MAPPER_RUN_OUTPUT_CAPTURE_FILE"; exit 1; fi if [ ! -f "$RAW_MAP_ABSOLUTE_PATH" ]; then log_message "FEHLER: ${RAW_MAP_ABSOLUTE_PATH} nicht gefunden (minetestmapper Status ${MAPPER_EXIT_STATUS})."; rm -f "$MAPPER_RUN_OUTPUT_CAPTURE_FILE"; exit 1; fi log_message "${RAW_MAP_FILENAME} erfolgreich generiert nach ${RAW_MAP_ABSOLUTE_PATH}." - -# === Karten-Dimensionen auslesen und in map_info.txt speichern === -log_message "Ermittle Dimensionen von ${RAW_MAP_ABSOLUTE_PATH}..." -if ! command -v identify &> /dev/null; then - log_message "WARNUNG: 'identify' (Teil von ImageMagick) nicht gefunden. map_info.txt kann nicht erstellt werden." -else - dimensions=$(identify -format "%wx%h" "$RAW_MAP_ABSOLUTE_PATH" 2>/dev/null) - if [ -n "$dimensions" ]; then - map_info_file="${RAW_MAP_OUTPUT_DIR_ABSOLUTE}/map_info.txt" - echo "$dimensions" > "$map_info_file" - log_message "Dimensionen (${dimensions}) erfolgreich in ${map_info_file} gespeichert." - else - log_message "FEHLER: Konnte Dimensionen von ${RAW_MAP_ABSOLUTE_PATH} nicht ermitteln." - fi -fi - # Unknown Nodes Verarbeitung if [ -f "$MAPPER_RUN_OUTPUT_CAPTURE_FILE" ]; then TEMP_NEW_UNKNOWN_NODES_FILE="${UNKNOWN_NODES_FILE_ABSOLUTE_PATH}.new_found" @@ -141,7 +137,8 @@ if [ -f "$MAPPER_RUN_OUTPUT_CAPTURE_FILE" ]; then else log_message "WARNUNG: minetestmapper-Ausgabe nicht verarbeitbar."; fi rm -f "$MAPPER_RUN_OUTPUT_CAPTURE_FILE" -# 2. Web-Vorschaukarte (verkleinert) erstellen +# 2. Web-Vorschaukarte (verkleinert) erstellen (wie zuvor) +# ... log_message "Erzeuge Web-Version von ${RAW_MAP_FILENAME} (max ${RESIZED_MAX_DIMENSION}px) nach ${WEB_MAP_PNG_FULL_PATH}..." mkdir -p "$(dirname "$WEB_MAP_PNG_FULL_PATH")" if [ ! -f "$RAW_MAP_ABSOLUTE_PATH" ]; then log_message "FEHLER: Quelldatei ${RAW_MAP_ABSOLUTE_PATH} für Web-Vorschau nicht gefunden!"; else @@ -154,7 +151,8 @@ if [ ! -f "$RAW_MAP_ABSOLUTE_PATH" ]; then log_message "FEHLER: Quelldatei ${RAW fi fi -# 3. Tiles generieren +# 3. Tiles generieren (wie zuvor) +# ... log_message "Generiere Kacheln (Zoom: ${GDAL2TILES_ZOOM_LEVELS}) nach ${TILES_FULL_OUTPUT_PATH}..." if [ ! -f "$RAW_MAP_ABSOLUTE_PATH" ]; then log_message "FEHLER: Quelldatei ${RAW_MAP_ABSOLUTE_PATH} für Tiling nicht gefunden!"; else TEMP_TILES_DIR="${TILES_FULL_OUTPUT_PATH}_temp_$(date +%s)"; rm -rf "$TEMP_TILES_DIR"; mkdir -p "$(dirname "$TILES_FULL_OUTPUT_PATH")" @@ -171,7 +169,8 @@ fi # === Archivbereinigung === prune_archives -# 4. Tägliches Archivbild +# 4. Tägliches Archivbild (wie zuvor) +# ... 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" @@ -193,7 +192,8 @@ if [ ! -f "$ARCHIVE_DAILY_FILE_PATH" ]; then fi; fi; fi else log_message "Archivbild ${ARCHIVE_DAILY_FILE_PATH} existiert bereits."; fi -# 5. Status- und Info-Dateien im Webverzeichnis +# 5. Status- und Info-Dateien im Webverzeichnis (wie zuvor) +# ... log_message "Erstelle Status- und Info-Dateien im Webverzeichnis ${WEB_CURRENT_WORLD_DIR}..." mkdir -p "$WEB_CURRENT_WORLD_DIR" echo "$(date '+%Y-%m-%d %H:%M:%S %Z')" > "${WEB_CURRENT_WORLD_DIR}/last_update.txt" && log_message "last_update.txt erstellt." || log_message "FEHLER: last_update.txt nicht erstellt." @@ -201,15 +201,4 @@ if [ -f "$UNKNOWN_NODES_FILE_ABSOLUTE_PATH" ]; then if cp "$UNKNOWN_NODES_FILE_ABSOLUTE_PATH" "${WEB_CURRENT_WORLD_DIR}/unknown_nodes.txt"; then log_message "unknown_nodes.txt nach Web kopiert."; else log_message "FEHLER: unknown_nodes.txt nicht nach Web kopiert."; fi else log_message "WARNUNG: ${UNKNOWN_NODES_FILE_ABSOLUTE_PATH} für Web-Kopie nicht gefunden."; fi -# NEU: Kopiere map_info.txt in das Web-Verzeichnis -if [ -f "${RAW_MAP_OUTPUT_DIR_ABSOLUTE}/map_info.txt" ]; then - if cp "${RAW_MAP_OUTPUT_DIR_ABSOLUTE}/map_info.txt" "${WEB_CURRENT_WORLD_DIR}/map_info.txt"; then - log_message "map_info.txt nach Web kopiert." - else - log_message "FEHLER: map_info.txt konnte nicht nach Web kopiert werden." - fi -else - log_message "WARNUNG: Quelldatei map_info.txt für Web-Kopie nicht gefunden." -fi - exit 0 diff --git a/generate_site.sh b/generate_site.sh index 7424cea..cc1d735 100755 --- a/generate_site.sh +++ b/generate_site.sh @@ -15,7 +15,6 @@ LOG_FILE="${LOG_DIR_BASE}/${SCRIPT_BASENAME}.log" LOCK_FILE="${LOCK_FILE_BASE_DIR}/${SCRIPT_BASENAME}.lock" WEB_CONTENT_STATIC_PATH="${WEB_CONTENT_BASE_PATH}/${WEB_CONTENT_STATIC_SUBDIR}" CACHE_BUSTER=$(date +%s) -CURRENT_YEAR=$(date '+%Y') ACTUAL_BANNER_IMG_URL_PATH="${FALLBACK_BANNER_IMG_URL}" # === Logging Funktion === @@ -39,51 +38,22 @@ create_placeholder_web_conf() { fi } -# === Template Rendering Funktion (FINAL, ROBUST) === +# === Template Rendering Funktion === render_template() { local template_path="$1" - local output_path="$2" - shift 2 - local replacements=("$@") - - if [ ! -f "$template_path" ]; then - log_message "FEHLER: Template-Datei nicht gefunden: ${template_path}" - return 1 - fi - - local template_content - template_content=$(<"$template_path") - - # Wende jede Ersetzung nacheinander an. - # Diese Methode ist robuster als eine einzelne große Ersetzung. - for ((i=0; i<${#replacements[@]}; i+=2)); do - local key_name="${replacements[i]}" - local key="%%${key_name}%%" - local value="${replacements[i+1]}" - - local new_content="" - # Wir zerlegen den String manuell, um mehrzeilige Ersetzungen zu ermöglichen. - # Dies ersetzt alle Vorkommen des Schlüssels. - while [[ "$template_content" == *"$key"* ]]; do - # Füge den Teil vor dem Schlüssel und den Ersatzwert hinzu - new_content+="${template_content%%$key*}${value}" - # Entferne den Teil, der bereits verarbeitet wurde - template_content="${template_content#*$key}" - done - # Füge den verbleibenden Rest des Inhalts hinzu - template_content="${new_content}${template_content}" - done - - echo "$template_content" > "$output_path" + if [ ! -f "$template_path" ]; then log_message "FEHLER: Template-Datei nicht gefunden: ${template_path}"; return 1; fi + local template_content; template_content=$(<"$template_path") + eval "cat < "$css_file_path" if [ $? -eq 0 ]; then log_message "CSS-Datei erfolgreich erstellt."; else log_message "FEHLER CSS."; fi } @@ -93,83 +63,48 @@ generate_html_header() { local active_page_id="${3:-}" local active_class_home=""; local active_class_worlds=""; local active_class_downloads="" case "$active_page_id" in - home) active_class_home="active" ;; - worlds) active_class_worlds="active" ;; - downloads) active_class_downloads="active" ;; + home) active_class_home="active" ;; + worlds) active_class_worlds="active" ;; + downloads)active_class_downloads="active" ;; esac - - local header_file - header_file=$(mktemp) - render_template "${TEMPLATE_DIR_PATH}/html_header.template" "$header_file" \ - "current_page_title" "$current_page_title" \ - "relative_path_prefix" "$relative_path_prefix" \ - "active_class_home" "$active_class_home" \ - "active_class_worlds" "$active_class_worlds" \ - "active_class_downloads" "$active_class_downloads" \ - "CACHE_BUSTER" "$CACHE_BUSTER" \ - "SITE_TITLE" "$SITE_TITLE" - cat "$header_file" - rm "$header_file" + render_template "${TEMPLATE_DIR_PATH}/html_header.template" } +# --- ANGEPASST: Nutzt jetzt die neue Template-Datei --- generate_html_footer() { - local footer_file - footer_file=$(mktemp) - render_template "${TEMPLATE_DIR_PATH}/html_footer.template" "$footer_file" \ - "CURRENT_YEAR" "$CURRENT_YEAR" \ - "SITE_TITLE" "$SITE_TITLE" \ - "SITE_OWNER_NAME" "$SITE_OWNER_NAME" - cat "$footer_file" - rm "$footer_file" + render_template "${TEMPLATE_DIR_PATH}/html_footer.template" } generate_homepage() { local p="${WEB_ROOT_PATH}/index.html"; local c="${WEB_CONTENT_STATIC_PATH}/startseite_content.html"; log_message "Erzeuge ${p}..."; generate_html_header "Willkommen" "." "home" > "$p"; if [ -f "$c" ]; then cat "$c" >> "$p"; else echo "

Willkommen!

" >> "$p"; fi; generate_html_footer >> "$p"; } -generate_impressum() { local p="${WEB_ROOT_PATH}/impressum.html"; local c="${WEB_CONTENT_STATIC_PATH}/impressum_content.html"; log_message "Erzeuge ${p}..."; generate_html_header "Impressum" "" > "$p"; if [ -f "$c" ]; then cat "$c" >> "$p"; else echo "

Impressum

Betreiber: ${SITE_OWNER_NAME}
Kontakt: ${SITE_OWNER_EMAIL}

" >> "$p"; fi; generate_html_footer >> "$p"; } +generate_impressum() { local p="${WEB_ROOT_PATH}/impressum.html"; local c="${WEB_CONTENT_STATIC_PATH}/impressum_content.html"; log_message "Erzeuge ${p}..."; generate_html_header "Impressum" > "$p"; if [ -f "$c" ]; then cat "$c" >> "$p"; else echo "

Impressum

Betreiber: ${SITE_OWNER_NAME}
Kontakt: ${SITE_OWNER_EMAIL}

" >> "$p"; fi; generate_html_footer >> "$p"; } generate_downloads_page() { local p="${WEB_ROOT_PATH}/downloads.html"; local c="${WEB_CONTENT_STATIC_PATH}/downloads_content.html"; log_message "Erzeuge ${p}..."; generate_html_header "Downloads" "." "downloads" > "$p"; if [ -f "$c" ]; then cat "$c" >> "$p"; else cat >>"$p" <Downloads

Offizielle Seite: luanti.org

EOF fi; generate_html_footer >> "$p"; } -generate_datenschutz_page() { local p="${WEB_ROOT_PATH}/datenschutz.html"; local c="${WEB_CONTENT_STATIC_PATH}/datenschutz_content.html"; log_message "Erzeuge ${p}..."; generate_html_header "Datenschutz" "" > "$p"; if [ -f "$c" ]; then cat "$c" >> "$p"; else echo "

Datenschutzerklärung

Platzhalter.

" >> "$p"; fi; generate_html_footer >> "$p"; } +generate_datenschutz_page() { local p="${WEB_ROOT_PATH}/datenschutz.html"; local c="${WEB_CONTENT_STATIC_PATH}/datenschutz_content.html"; log_message "Erzeuge ${p}..."; generate_html_header "Datenschutz" > "$p"; if [ -f "$c" ]; then cat "$c" >> "$p"; else echo "

Datenschutzerklärung

Platzhalter.

" >> "$p"; fi; generate_html_footer >> "$p"; } generate_worlds_overview() { - local overview_file="${WEB_ROOT_PATH}/worlds.html" - log_message "Erzeuge Weltenübersicht: ${overview_file}..." - generate_html_header "Weltenübersicht" "." "worlds" > "$overview_file" - echo "

Unsere Welten

" >> "$overview_file" - + local overview_file="${WEB_ROOT_PATH}/worlds.html"; log_message "Erzeuge Weltenübersicht: ${overview_file}..." + generate_html_header "Weltenübersicht" "." "worlds" > "$overview_file"; echo "

Unsere Welten

" >> "$overview_file" local discovered_worlds_count=0; shopt -s nullglob local world_key_dirs=("${MINETESTMAPPER_WORLD_DATA_BASE_PATH}"/*/) shopt -u nullglob - - if [ ${#world_key_dirs[@]} -eq 0 ]; then - log_message "WARNUNG: Keine Welt-Verzeichnisse in ${MINETESTMAPPER_WORLD_DATA_BASE_PATH}." - echo "

Keine Welten verfügbar.

" >> "$overview_file" + if [ ${#world_key_dirs[@]} -eq 0 ]; then log_message "WARNUNG: Keine Welt-Verzeichnisse in ${MINETESTMAPPER_WORLD_DATA_BASE_PATH}."; echo "

Keine Welten verfügbar.

" >> "$overview_file"; else - local overview_entry_template_path="${TEMPLATE_DIR_PATH}/worlds_overview_entry.template" for world_data_dir_loop_overview in "${world_key_dirs[@]}"; do - local current_world_key - current_world_key=$(basename "$world_data_dir_loop_overview") - local world_mt_file="${world_data_dir_loop_overview}world.mt" - local web_conf_file="${world_data_dir_loop_overview}web.conf" + local current_world_key=$(basename "$world_data_dir_loop_overview"); local world_mt_file="${world_data_dir_loop_overview}world.mt"; local web_conf_file="${world_data_dir_loop_overview}web.conf" if [ ! -f "$world_mt_file" ] || [ ! -f "$web_conf_file" ]; then continue; fi - local world_display_name_ov - world_display_name_ov=$(get_config_value_from_file "$web_conf_file" "WORLD_DISPLAY_NAME") - local world_short_desc_ov - world_short_desc_ov=$(get_config_value_from_file "$web_conf_file" "WORLD_SHORT_DESCRIPTION" "$DEFAULT_WORLD_SHORT_DESCRIPTION") + local world_display_name_ov; world_display_name_ov=$(get_config_value_from_file "$web_conf_file" "WORLD_DISPLAY_NAME") + local world_short_desc_ov; world_short_desc_ov=$(get_config_value_from_file "$web_conf_file" "WORLD_SHORT_DESCRIPTION" "$DEFAULT_WORLD_SHORT_DESCRIPTION") - unset ADMIN_NAME; source "$web_conf_file" &>/dev/null - local admin_name_ov - if [ ${#ADMIN_NAME[@]} -gt 0 ]; then admin_name_ov=$(IFS=', '; echo "${ADMIN_NAME[*]}"); else admin_name_ov="$SITE_OWNER_NAME"; fi - - local current_map_png_filename_for_preview_ov - current_map_png_filename_for_preview_ov=$(get_config_value_from_file "$web_conf_file" "WEB_MAP_PNG_FILENAME" "$DEFAULT_WEB_MAP_PNG_FILENAME") + local admin_name_ov; unset ADMIN_NAME; source "$web_conf_file" &>/dev/null; if [ ${#ADMIN_NAME[@]} -gt 0 ]; then admin_name_ov=$(IFS=', '; echo "${ADMIN_NAME[*]}"); else admin_name_ov="$SITE_OWNER_NAME"; fi + local current_map_png_filename_for_preview_ov; current_map_png_filename_for_preview_ov=$(get_config_value_from_file "$web_conf_file" "WEB_MAP_PNG_FILENAME" "$DEFAULT_WEB_MAP_PNG_FILENAME") if [ -z "$world_display_name_ov" ]; then - local mt_world_name_from_mt_ov - mt_world_name_from_mt_ov=$(grep -E "^\s*world_name\s*=" "$world_mt_file" | tail -n 1 | cut -d'=' -f2 | xargs) + local mt_world_name_from_mt_ov; mt_world_name_from_mt_ov=$(grep -E "^\s*world_name\s*=" "$world_mt_file" | tail -n 1 | cut -d'=' -f2 | xargs) if [ -n "$mt_world_name_from_mt_ov" ]; then world_display_name_ov="$mt_world_name_from_mt_ov"; - else world_display_name_ov="Welt ${current_world_key}"; fi + else world_display_name_ov="${DEFAULT_SERVER_DISPLAY_NAME_PREFIX}${current_world_key}"; if [[ "$world_display_name_ov" == "${DEFAULT_SERVER_DISPLAY_NAME_PREFIX}"* && "$DEFAULT_SERVER_DISPLAY_NAME_PREFIX" == "n/a" ]]; then world_display_name_ov="Welt ${current_world_key}"; fi; fi fi local detail_page_filename="world_${current_world_key}.html" @@ -177,38 +112,18 @@ generate_worlds_overview() { local preview_img_abs_path="${WEB_ROOT_PATH}/${preview_img_rel_path}" local online_status_text="offline"; local online_status_class="offline" local status_file_for_overview="${WEB_ROOT_PATH}/${WEB_MAPS_BASE_SUBDIR}/${current_world_key}/online_status.txt" - if [ -f "$status_file_for_overview" ]; then - local status_line_overview - status_line_overview=$(cat "$status_file_for_overview") - if [[ "$status_line_overview" == "online"* ]]; then online_status_text="online"; online_status_class="online"; fi - fi + if [ -f "$status_file_for_overview" ]; then local status_line_overview; status_line_overview=$(cat "$status_file_for_overview"); if [[ "$status_line_overview" == "online"* ]]; then online_status_text="online"; online_status_class="online"; fi; fi local preview_img_html - if [ -f "$preview_img_abs_path" ]; then - preview_img_html="Vorschau ${world_display_name_ov}" - else - preview_img_html="Keine Vorschau für ${world_display_name_ov}" - fi - - local temp_overview_entry_file - temp_overview_entry_file=$(mktemp) - render_template "$overview_entry_template_path" "$temp_overview_entry_file" \ - "detail_page_filename" "$detail_page_filename" \ - "preview_img_html" "$preview_img_html" \ - "world_display_name_ov" "$world_display_name_ov" \ - "online_status_class" "$online_status_class" \ - "online_status_text" "$online_status_text" \ - "admin_name_ov" "$admin_name_ov" \ - "world_short_desc_ov" "$world_short_desc_ov" - cat "$temp_overview_entry_file" >> "$overview_file" - rm "$temp_overview_entry_file" + if [ -f "$preview_img_abs_path" ]; then preview_img_html="Vorschau ${world_display_name_ov}"; + else preview_img_html="Keine Vorschau für ${world_display_name_ov}"; fi discovered_worlds_count=$((discovered_worlds_count + 1)) + render_template "${TEMPLATE_DIR_PATH}/worlds_overview_entry.template" >> "$overview_file" done if [ "$discovered_worlds_count" -eq 0 ]; then echo "

Keine Welten mit gültiger Konfiguration gefunden.

" >> "$overview_file"; fi fi - generate_html_footer >> "$overview_file" - if [ $? -eq 0 ]; then log_message "Weltenübersicht erstellt."; else log_message "FEHLER Weltenübersicht."; fi + generate_html_footer >> "$overview_file"; if [ $? -eq 0 ]; then log_message "Weltenübersicht erstellt."; else log_message "FEHLER Weltenübersicht."; fi } generate_world_detail_page() { @@ -217,35 +132,10 @@ generate_world_detail_page() { local world_mt_file="${current_minetest_world_path}/world.mt"; local web_conf_file="${current_minetest_world_path}/web.conf" if [ ! -f "$world_mt_file" ] || [ ! -f "$web_conf_file" ]; then log_message "FEHLER: world.mt oder web.conf für ${current_world_key} fehlt."; return 1; fi - local map_info_file="${BASE_SCRIPT_DIR}/${RAW_MAP_BASE_SUBDIR}/${current_world_key}/map_info.txt" - local MAP_WIDTH=0; local MAP_HEIGHT=0; local MAP_EXTENT_MIN_X=0; local MAP_EXTENT_MIN_Z=0; local MAP_EXTENT_WIDTH=0; local MAP_EXTENT_HEIGHT=0 - if [ -f "$map_info_file" ]; then - local map_dim_val; map_dim_val=$(get_config_value_from_file "$map_info_file" "map_dimension") - if [[ "$map_dim_val" == *"x"* ]]; then - MAP_WIDTH=$(echo "$map_dim_val" | cut -d'x' -f1) - MAP_HEIGHT=$(echo "$map_dim_val" | cut -d'x' -f2) - fi - local map_ext_val; map_ext_val=$(get_config_value_from_file "$map_info_file" "map_extent") - if [[ "$map_ext_val" == *":"* && "$map_ext_val" == *"+"* ]]; then - local min_coords; min_coords=$(echo "$map_ext_val" | cut -d'+' -f1) - local extent_dims; extent_dims=$(echo "$map_ext_val" | cut -d'+' -f2,3) - MAP_EXTENT_MIN_X=$(echo "$min_coords" | cut -d':' -f1) - MAP_EXTENT_MIN_Z=$(echo "$min_coords" | cut -d':' -f2) - MAP_EXTENT_WIDTH=$(echo "$extent_dims" | cut -d'+' -f1) - MAP_EXTENT_HEIGHT=$(echo "$extent_dims" | cut -d'+' -f2) - fi - else - log_message "WARNUNG: ${map_info_file} für '${current_world_key}' nicht gefunden." - fi - - local WORLD_DISPLAY_NAME_PAGE; WORLD_DISPLAY_NAME_PAGE=$(get_config_value_from_file "$web_conf_file" "WORLD_DISPLAY_NAME") - if [ -z "$WORLD_DISPLAY_NAME_PAGE" ]; then - WORLD_DISPLAY_NAME_PAGE=$(get_config_value_from_file "$world_mt_file" "world_name" "Welt ${current_world_key}") - fi - - local SERVER_ADDRESS_PAGE; SERVER_ADDRESS_PAGE=$(get_config_value_from_file "$web_conf_file" "SERVER_ADDRESS" "$DEFAULT_SERVER_ADDRESS") - local SERVER_PORT_PAGE; SERVER_PORT_PAGE=$(get_config_value_from_file "$web_conf_file" "SERVER_PORT" "$DEFAULT_SERVER_PORT") - local SERVER_ACCESS_INFO_PAGE; SERVER_ACCESS_INFO_PAGE=$(get_config_value_from_file "$web_conf_file" "SERVER_ACCESS_INFO" "$DEFAULT_SERVER_ACCESS_INFO") + local WORLD_DISPLAY_NAME_PAGE=$(get_config_value_from_file "$web_conf_file" "WORLD_DISPLAY_NAME") + local SERVER_ADDRESS_PAGE=$(get_config_value_from_file "$web_conf_file" "SERVER_ADDRESS" "$DEFAULT_SERVER_ADDRESS") + local SERVER_PORT_PAGE=$(get_config_value_from_file "$web_conf_file" "SERVER_PORT" "$DEFAULT_SERVER_PORT") + local SERVER_ACCESS_INFO_PAGE=$(get_config_value_from_file "$web_conf_file" "SERVER_ACCESS_INFO" "$DEFAULT_SERVER_ACCESS_INFO") unset ADMIN_NAME ADMIN_SKIN_URL ADMIN_EMAIL ADMIN_DISCORD ADMIN_MATRIX ADMIN_STEAM ADMIN_TEAMSPEAK ADMIN_MUMBLE WORLD_LONG_DESCRIPTION WORLD_GAME_RULES source "$web_conf_file" @@ -253,102 +143,40 @@ generate_world_detail_page() { local WORLD_GAME_RULES_PAGE="${WORLD_GAME_RULES:-}" local STATUS_TEXT_FALLBACK_PAGE="$DEFAULT_SERVER_STATUS_TEXT_FALLBACK" - local CURRENT_WEB_MAP_PNG_FILENAME; CURRENT_WEB_MAP_PNG_FILENAME=$(get_config_value_from_file "$web_conf_file" "WEB_MAP_PNG_FILENAME" "$DEFAULT_WEB_MAP_PNG_FILENAME") - local CURRENT_ARCHIVE_SUBDIR_NAME; CURRENT_ARCHIVE_SUBDIR_NAME=$(get_config_value_from_file "$web_conf_file" "ARCHIVE_SUBDIR_NAME" "$DEFAULT_ARCHIVE_SUBDIR_NAME") + local CURRENT_TILES_SUBDIR_NAME=$(get_config_value_from_file "$web_conf_file" "TILES_SUBDIR_NAME" "$DEFAULT_TILES_SUBDIR_NAME") + local CURRENT_GDAL2TILES_ZOOM_LEVELS=$(get_config_value_from_file "$web_conf_file" "GDAL2TILES_ZOOM_LEVELS" "$DEFAULT_GDAL2TILES_ZOOM_LEVELS") + local CURRENT_WEB_MAP_PNG_FILENAME=$(get_config_value_from_file "$web_conf_file" "WEB_MAP_PNG_FILENAME" "$DEFAULT_WEB_MAP_PNG_FILENAME") + local CURRENT_ARCHIVE_SUBDIR_NAME=$(get_config_value_from_file "$web_conf_file" "ARCHIVE_SUBDIR_NAME" "$DEFAULT_ARCHIVE_SUBDIR_NAME") + local LEAFLET_BOUNDS_SOUTH=$(get_config_value_from_file "$web_conf_file" "LEAFLET_BOUNDS_SOUTH" "$DEFAULT_LEAFLET_BOUNDS_SOUTH") + local LEAFLET_BOUNDS_WEST=$(get_config_value_from_file "$web_conf_file" "LEAFLET_BOUNDS_WEST" "$DEFAULT_LEAFLET_BOUNDS_WEST") + local LEAFLET_BOUNDS_NORTH=$(get_config_value_from_file "$web_conf_file" "LEAFLET_BOUNDS_NORTH" "$DEFAULT_LEAFLET_BOUNDS_NORTH") + local LEAFLET_BOUNDS_EAST=$(get_config_value_from_file "$web_conf_file" "LEAFLET_BOUNDS_EAST" "$DEFAULT_LEAFLET_BOUNDS_EAST") + local LEAFLET_ZOOM_AFTER_FIT=$(get_config_value_from_file "$web_conf_file" "LEAFLET_ZOOM_AFTER_FIT" "$DEFAULT_LEAFLET_ZOOM_AFTER_FIT") - local MT_GAMEID="$DEFAULT_GAMEID"; local MT_ENABLE_DAMAGE="false"; local MT_CREATIVE_MODE="false" - declare -A parsed_mod_packs; declare -a parsed_standalone_mods + local MT_WORLD_NAME_FROM_MT="$current_world_key"; local MT_GAMEID="$DEFAULT_GAMEID"; local MT_ENABLE_DAMAGE="false"; local MT_CREATIVE_MODE="false" + declare -A parsed_mod_packs; declare -a parsed_standalone_mods while IFS='=' read -r key value || [ -n "$key" ]; do key=$(echo "$key"|xargs); value=$(echo "$value"|xargs) case "$key" in - gameid) MT_GAMEID="$value" ;; - enable_damage) MT_ENABLE_DAMAGE="$value" ;; - creative_mode) MT_CREATIVE_MODE="$value" ;; + world_name) MT_WORLD_NAME_FROM_MT="$value" ;; gameid) MT_GAMEID="$value" ;; + enable_damage) MT_ENABLE_DAMAGE="$value" ;; creative_mode) MT_CREATIVE_MODE="$value" ;; load_mod_*) local mod_id="${key#load_mod_}"; mod_id=$(echo "$mod_id"|xargs) if [[ "$value" =~ ^mods/([^/]+)/.+ ]]; then local pack_n="${BASH_REMATCH[1]}"; parsed_mod_packs["$pack_n"]="${parsed_mod_packs[$pack_n]} ${mod_id}"; elif [[ "$value" =~ ^mods/([^/]+)$ ]]; then parsed_standalone_mods+=("$mod_id"); elif [ -n "$value" ]; then parsed_standalone_mods+=("$mod_id"); fi ;; - esac; - done < "$world_mt_file" + esac; done < "$world_mt_file" + if [ -z "$WORLD_DISPLAY_NAME_PAGE" ]; then if [ -n "$MT_WORLD_NAME_FROM_MT" ] && [ "$MT_WORLD_NAME_FROM_MT" != "$current_world_key" ]; then WORLD_DISPLAY_NAME_PAGE="$MT_WORLD_NAME_FROM_MT"; else WORLD_DISPLAY_NAME_PAGE="${DEFAULT_SERVER_DISPLAY_NAME_PREFIX}${current_world_key}"; if [[ "$WORLD_DISPLAY_NAME_PAGE" == "${DEFAULT_SERVER_DISPLAY_NAME_PREFIX}"* && "$DEFAULT_SERVER_DISPLAY_NAME_PREFIX" == "n/a" ]]; then WORLD_DISPLAY_NAME_PAGE="Welt ${current_world_key}"; fi;fi;fi - local MODS_HTML="" - if [ ${#parsed_mod_packs[@]} -gt 0 ] || [ ${#parsed_standalone_mods[@]} -gt 0 ]; then - MODS_HTML+="" - else - MODS_HTML="

Keine Mod-Informationen in world.mt gefunden.

" - fi - - # KORREKTUR: Logik zur Archiv-Suche wiederhergestellt (wie im Original-Skript) - local ARCHIVE_HTML=""; local available_archive_dates_js_array="[]"; local -a available_archive_dates_bash=(); - local archive_scan_base_path="${WEB_ROOT_PATH}/${WEB_MAPS_BASE_SUBDIR}/${current_world_key}/${CURRENT_ARCHIVE_SUBDIR_NAME}"; - if [ -d "$archive_scan_base_path" ]; then - shopt -s nullglob; - for y_d in "${archive_scan_base_path}"/*/; do - if [ -d "$y_d" ]; then - local y=$(basename "$y_d"); - for m_d in "${y_d}"*/; do - if [ -d "$m_d" ]; then - local m=$(basename "$m_d"); - for d_f in "${m_d}"*.png; do - if [ -f "$d_f" ]; then - local d=$(basename "$d_f" .png); - if [[ "$y" =~ ^[0-9]{4}$ && "$m" =~ ^[0-9]{2}$ && "$d" =~ ^[0-9]{2}$ ]]; then - available_archive_dates_bash+=("${y}-${m}-${d}"); - fi; - fi; - done; - fi; - done; - fi; - done; - shopt -u nullglob; - fi; - if [ ${#available_archive_dates_bash[@]} -gt 0 ]; then - local sorted_dates_str; sorted_dates_str=$(printf '%s\n' "${available_archive_dates_bash[@]}" | sort -r); - local js_dates_temp_array=(); if [ -n "$sorted_dates_str" ]; then mapfile -t js_dates_temp_array < <(echo "$sorted_dates_str"); fi; - local js_array_content=""; - if [ ${#js_dates_temp_array[@]} -gt 0 ]; then - for date_str_loop in "${js_dates_temp_array[@]}"; do - if [ -n "$date_str_loop" ]; then js_array_content+="\"${date_str_loop}\","; fi; - done; - js_array_content=${js_array_content%,}; - fi; - available_archive_dates_js_array="[${js_array_content}]"; - local temp_archive_html_file; temp_archive_html_file=$(mktemp) - local archive_world_rel_to_webroot="/${WEB_MAPS_BASE_SUBDIR}/${current_world_key}/${CURRENT_ARCHIVE_SUBDIR_NAME}" - render_template "${TEMPLATE_DIR_PATH}/world_detail_archive.template" "$temp_archive_html_file" \ - "current_world_key" "$current_world_key" \ - "available_archive_dates_js_array" "$available_archive_dates_js_array" \ - "archive_world_rel_to_webroot" "$archive_world_rel_to_webroot" \ - "CACHE_BUSTER" "$CACHE_BUSTER" - ARCHIVE_HTML=$(<"$temp_archive_html_file") - rm "$temp_archive_html_file" - else - ARCHIVE_HTML="

Keine Archivbilder für diese Welt verfügbar.

"; - fi - local web_map_preview_rel_path="${WEB_MAPS_BASE_SUBDIR}/${current_world_key}/${CURRENT_WEB_MAP_PNG_FILENAME}" - local web_online_status_rel_path="${WEB_MAPS_BASE_SUBDIR}/${current_world_key}/online_status.txt" + local web_tiles_rel_path="${WEB_MAPS_BASE_SUBDIR}/${current_world_key}/${CURRENT_TILES_SUBDIR_NAME}" local web_last_update_rel_path="${WEB_MAPS_BASE_SUBDIR}/${current_world_key}/last_update.txt" + local web_unknown_nodes_rel_path="${WEB_MAPS_BASE_SUBDIR}/${current_world_key}/unknown_nodes.txt" + local web_online_status_rel_path="${WEB_MAPS_BASE_SUBDIR}/${current_world_key}/online_status.txt" local web_players_txt_rel_path="${WEB_MAPS_BASE_SUBDIR}/${current_world_key}/players.txt" local web_weather_txt_rel_path="${WEB_MAPS_BASE_SUBDIR}/${current_world_key}/weather.txt" - local web_unknown_nodes_rel_path="${WEB_MAPS_BASE_SUBDIR}/${current_world_key}/unknown_nodes.txt" - local unknown_nodes_abs_path="${WEB_ROOT_PATH}/${web_unknown_nodes_rel_path}" + local archive_world_rel_to_webroot="/${WEB_MAPS_BASE_SUBDIR}/${current_world_key}/${CURRENT_ARCHIVE_SUBDIR_NAME}" + local map_preview_abs_path="${WEB_ROOT_PATH}/${web_map_preview_rel_path}"; local last_update_abs_path="${WEB_ROOT_PATH}/${web_last_update_rel_path}" + local unknown_nodes_abs_path="${WEB_ROOT_PATH}/${web_unknown_nodes_rel_path}"; local min_zoom="${CURRENT_GDAL2TILES_ZOOM_LEVELS%%-*}"; local max_zoom="${CURRENT_GDAL2TILES_ZOOM_LEVELS##*-}" local creative_text="Aus"; local creative_text_class="offline"; if [ "$MT_CREATIVE_MODE" = "true" ]; then creative_text="An"; creative_text_class="online"; fi local damage_text="Aus"; local damage_text_class="online"; if [ "$MT_ENABLE_DAMAGE" = "true" ]; then damage_text="An"; damage_text_class="offline"; fi @@ -356,7 +184,7 @@ generate_world_detail_page() { local ADMIN_BOXES_HTML="" local num_admins=${#ADMIN_NAME[@]} if [ $num_admins -eq 0 ]; then - ADMIN_BOXES_HTML="
Admin Skin

${SITE_OWNER_NAME}

" + ADMIN_BOXES_HTML="
Admin Skin

${SITE_OWNER_NAME}

" else for i in "${!ADMIN_NAME[@]}"; do local name="${ADMIN_NAME[$i]}"; local skin_url="${ADMIN_SKIN_URL[$i]:-$DEFAULT_PLAYER_SKIN_URL}"; local email="${ADMIN_EMAIL[$i]}"; local discord="${ADMIN_DISCORD[$i]}"; local matrix="${ADMIN_MATRIX[$i]}"; local steam="${ADMIN_STEAM[$i]}"; local teamspeak="${ADMIN_TEAMSPEAK[$i]}"; local mumble="${ADMIN_MUMBLE[$i]}" @@ -370,56 +198,14 @@ generate_world_detail_page() { ADMIN_BOXES_HTML+="
Admin Skin ${name}

${name}

"; if [ -n "$contact_links_html" ]; then ADMIN_BOXES_HTML+=""; fi; ADMIN_BOXES_HTML+="
" done fi - - local map_sub_info_link="" - if [ -f "$unknown_nodes_abs_path" ]; then - map_sub_info_link="Fehlende Map-Nodes" - else - map_sub_info_link=" " - fi - { - generate_html_header "Welt: ${WORLD_DISPLAY_NAME_PAGE}" "" - - local temp_body_file - temp_body_file=$(mktemp) - render_template "${TEMPLATE_DIR_PATH}/world_detail_page.template" "$temp_body_file" \ - "WORLD_DISPLAY_NAME_PAGE" "$WORLD_DISPLAY_NAME_PAGE" \ - "current_world_key" "$current_world_key" \ - "STATUS_TEXT_FALLBACK_PAGE" "$STATUS_TEXT_FALLBACK_PAGE" \ - "MT_GAMEID" "$MT_GAMEID" \ - "creative_text_class" "$creative_text_class" \ - "creative_text" "$creative_text" \ - "damage_text_class" "$damage_text_class" \ - "damage_text" "$damage_text" \ - "SERVER_ADDRESS_PAGE" "$SERVER_ADDRESS_PAGE" \ - "SERVER_PORT_PAGE" "$SERVER_PORT_PAGE" \ - "SERVER_ACCESS_INFO_PAGE" "$SERVER_ACCESS_INFO_PAGE" \ - "ADMIN_BOXES_HTML" "$ADMIN_BOXES_HTML" \ - "web_online_status_rel_path" "$web_online_status_rel_path" \ - "web_last_update_rel_path" "$web_last_update_rel_path" \ - "CACHE_BUSTER" "$CACHE_BUSTER" \ - "web_players_txt_rel_path" "$web_players_txt_rel_path" \ - "MAP_WIDTH" "$MAP_WIDTH" \ - "MAP_HEIGHT" "$MAP_HEIGHT" \ - "MAP_EXTENT_MIN_X" "$MAP_EXTENT_MIN_X" \ - "MAP_EXTENT_MIN_Z" "$MAP_EXTENT_MIN_Z" \ - "MAP_EXTENT_WIDTH" "$MAP_EXTENT_WIDTH" \ - "MAP_EXTENT_HEIGHT" "$MAP_EXTENT_HEIGHT" \ - "DEFAULT_PLAYER_SKIN_URL" "$DEFAULT_PLAYER_SKIN_URL" \ - "web_map_preview_rel_path" "$web_map_preview_rel_path" \ - "web_weather_txt_rel_path" "$web_weather_txt_rel_path" \ - "WORLD_LONG_DESCRIPTION_PAGE" "$WORLD_LONG_DESCRIPTION_PAGE" \ - "WORLD_GAME_RULES_PAGE" "$WORLD_GAME_RULES_PAGE" \ - "web_unknown_nodes_rel_path" "$web_unknown_nodes_rel_path" \ - "ARCHIVE_HTML" "$ARCHIVE_HTML" \ - "MODS_HTML" "$MODS_HTML" \ - "map_sub_info_link" "$map_sub_info_link" - cat "$temp_body_file" - rm "$temp_body_file" + local MAP_HTML=""; if [ -d "${WEB_ROOT_PATH}/${web_tiles_rel_path}" ]; then local map_sub_info_link=""; if [ -f "$unknown_nodes_abs_path" ]; then map_sub_info_link="Fehlende Map-Nodes"; else map_sub_info_link=" "; fi; MAP_HTML=$(render_template "${TEMPLATE_DIR_PATH}/world_detail_map.template"); else MAP_HTML="

Kartenkacheln nicht verfügbar.

"; [ -f "$map_preview_abs_path" ] && MAP_HTML+="

Statische Vorschau:

Vorschau ${WORLD_DISPLAY_NAME_PAGE}"; fi + local ARCHIVE_HTML=""; local available_archive_dates_js_array="[]"; local -a available_archive_dates_bash=(); local archive_scan_base_path="${WEB_ROOT_PATH}/${WEB_MAPS_BASE_SUBDIR}/${current_world_key}/${CURRENT_ARCHIVE_SUBDIR_NAME}"; if [ -d "$archive_scan_base_path" ]; then shopt -s nullglob; for y_d in "${archive_scan_base_path}"/*/; do if [ -d "$y_d" ]; then local y=$(basename "$y_d"); for m_d in "${y_d}"*/; do if [ -d "$m_d" ]; then local m=$(basename "$m_d"); for d_f in "${m_d}"*.png; do if [ -f "$d_f" ]; then local d=$(basename "$d_f" .png); if [[ "$y" =~ ^[0-9]{4}$ && "$m" =~ ^[0-9]{2}$ && "$d" =~ ^[0-9]{2}$ ]]; then available_archive_dates_bash+=("${y}-${m}-${d}");fi;fi;done;fi;done;fi;done; shopt -u nullglob;fi; if [ ${#available_archive_dates_bash[@]} -gt 0 ]; then local sorted_dates_str; sorted_dates_str=$(printf '%s\n' "${available_archive_dates_bash[@]}" | sort -r); local js_dates_temp_array=(); if [ -n "$sorted_dates_str" ]; then mapfile -t js_dates_temp_array < <(echo "$sorted_dates_str"); fi; local js_array_content=""; if [ ${#js_dates_temp_array[@]} -gt 0 ]; then for date_str_loop in "${js_dates_temp_array[@]}"; do if [ -n "$date_str_loop" ]; then js_array_content+="\"${date_str_loop}\","; fi; done; js_array_content=${js_array_content%,}; fi; available_archive_dates_js_array="[${js_array_content}]"; ARCHIVE_HTML=$(render_template "${TEMPLATE_DIR_PATH}/world_detail_archive.template"); else ARCHIVE_HTML="

Keine Archivbilder für diese Welt verfügbar.

"; fi + local MODS_HTML=""; if [ ${#parsed_mod_packs[@]} -gt 0 ] || [ ${#parsed_standalone_mods[@]} -gt 0 ]; then MODS_HTML+=""; else MODS_HTML="

Keine Mod-Informationen in world.mt gefunden.

"; fi - generate_html_footer - } > "$detail_page_file" + generate_html_header "Welt: ${WORLD_DISPLAY_NAME_PAGE}" "" "" > "$detail_page_file" + render_template "${TEMPLATE_DIR_PATH}/world_detail_page.template" >> "$detail_page_file" + generate_html_footer >> "$detail_page_file" if [ $? -eq 0 ]; then log_message "Detailseite ${WORLD_DISPLAY_NAME_PAGE} erstellt."; else log_message "FEHLER Detailseite ${WORLD_DISPLAY_NAME_PAGE}."; fi } @@ -431,7 +217,6 @@ flock -n 200 || { echo "$(date '+%Y-%m-%d %H:%M:%S') - Script ${SCRIPT_BASENAME} trap 'rm -f "$LOCK_FILE"; log_message "Script ${SCRIPT_BASENAME}.sh beendet."' EXIT mkdir -p "$LOG_DIR_BASE"; mkdir -p "${WEB_ROOT_PATH}" log_message "Script ${SCRIPT_BASENAME}.sh gestartet." - log_message "Prüfe und erstelle Webseiten-Inhaltsverzeichnisse und Platzhalter..." mkdir -p "${WEB_CONTENT_BASE_PATH}"; mkdir -p "${WEB_CONTENT_STATIC_PATH}"; mkdir -p "${TEMPLATE_DIR_PATH}"; mkdir -p "${EXAMPLE_TEMPLATE_DIR_PATH}" @@ -444,16 +229,18 @@ create_placeholder_file "${WEB_CONTENT_STATIC_PATH}/downloads_content.html" "

Datenschutzerklärung

Hier deinen Datenschutztext einfügen.

" log_message "Starte Generierung der statischen Webseiten-Dateien..." +# --- Asset Copying --- log_message "Kopiere Webseiten-Assets (Bilder, Icons)..." WEB_IMAGES_TARGET_DIR="${WEB_ROOT_PATH}/images" WEB_PLAYER_IMAGES_TARGET_DIR="${WEB_IMAGES_TARGET_DIR}/players" SOURCE_IMAGES_DIR="${WEB_CONTENT_BASE_PATH}/${WEB_CONTENT_IMAGES_SOURCE_SUBDIR:-images_source}" -SOURCE_PLAYER_IMAGES_TARGET_DIR="${SOURCE_IMAGES_DIR}/players" +SOURCE_PLAYER_IMAGES_DIR="${SOURCE_IMAGES_DIR}/players" mkdir -p "$WEB_IMAGES_TARGET_DIR"; mkdir -p "$WEB_PLAYER_IMAGES_TARGET_DIR" if [ -d "$SOURCE_IMAGES_DIR" ]; then shopt -s nullglob; for src_file in "$SOURCE_IMAGES_DIR"/* ; do [ -f "$src_file" ] && cp -u "$src_file" "$WEB_IMAGES_TARGET_DIR/"; done; shopt -u nullglob; log_message "Allgemeine Bilder kopiert/aktualisiert."; else log_message "WARNUNG: Quellverz. allgemeine Bilder nicht gefunden: ${SOURCE_IMAGES_DIR}"; fi if [ -d "$SOURCE_PLAYER_IMAGES_DIR" ]; then shopt -s nullglob; for src_file in "$SOURCE_PLAYER_IMAGES_DIR"/*.png ; do [ -f "$src_file" ] && cp -u "$src_file" "$WEB_PLAYER_IMAGES_TARGET_DIR/"; done; shopt -u nullglob; log_message "Spieler-Skins kopiert/aktualisiert."; else log_message "WARNUNG: Quellverz. Spieler-Skins nicht gefunden: ${SOURCE_PLAYER_IMAGES_DIR}"; fi +# --- Ende Asset Copying --- if [ -n "$STATIC_BANNER_FILENAME" ]; then ACTUAL_BANNER_IMG_URL_PATH="/images/${STATIC_BANNER_FILENAME}"; if [ ! -f "${WEB_ROOT_PATH}${ACTUAL_BANNER_IMG_URL_PATH}" ]; then log_message "WARNUNG: Statisches Banner '${STATIC_BANNER_FILENAME}' nicht in '${WEB_ROOT_PATH}/images/' gefunden. Fallback: ${FALLBACK_BANNER_IMG_URL}"; ACTUAL_BANNER_IMG_URL_PATH="${FALLBACK_BANNER_IMG_URL}"; else log_message "Verwende statisches Banner: ${ACTUAL_BANNER_IMG_URL_PATH}"; fi else log_message "Kein STATIC_BANNER_FILENAME, verwende Fallback: ${FALLBACK_BANNER_IMG_URL}"; ACTUAL_BANNER_IMG_URL_PATH="${FALLBACK_BANNER_IMG_URL}"; fi diff --git a/site_generator/templates/css.template b/site_generator/templates/css.template index 4c3f45c..6d43183 100755 --- a/site_generator/templates/css.template +++ b/site_generator/templates/css.template @@ -53,7 +53,7 @@ a:hover { text-decoration: underline; color: #FFC500; } .header-banner { width: 100%; height: 240px; - background-image: url('%%css_banner_image_path%%?v=%%CACHE_BUSTER%%'); + background-image: url('${css_banner_image_path}?v=${CACHE_BUSTER}'); background-size: cover; background-position: center 45%; border-bottom: 2px solid #4A2E0A; @@ -100,13 +100,11 @@ a.world-preview:hover { .page-nav-buttons { text-align: right; margin-top: 10px; margin-bottom: 15px; } .page-nav-buttons .button { background-color: #555; color: #FFA500; border: 1px solid #666; padding: 5px 10px; margin-left: 5px; margin-bottom: 5px; border-radius: 3px; text-decoration: none; font-size: 0.9em; display: inline-block; } .page-nav-buttons .button:hover { background-color: #666; color: #FFC500; } -.leaflet-map { width: 100%; height: 600px; border: 1px solid #666; margin-bottom: 5px; border-radius: 3px; background-color: #111;} +.leaflet-map { width: 100%; height: 500px; border: 1px solid #666; margin-bottom: 5px; border-radius: 3px;} .map-sub-info { display: flex; justify-content: space-between; align-items: center; font-size: 0.9em; color: #aaa; margin-bottom: 20px; padding: 5px 0; } -.map-sub-info .map-file-link { text-align: left; } -.map-sub-info .map-last-update { text-align: right; } +.map-sub-info .map-file-link { text-align: left; } .map-sub-info .map-last-update { text-align: right; } .info-box { background-color: #3a3a3a; border: 1px solid #555; padding: 15px; margin-bottom: 20px; border-left: 5px solid #FFD700; border-radius: 3px;} .info-box h3 { margin-top: 0; border-bottom: none; padding-bottom: 0.2em; } - /* Admin Sektion */ .admin-section h3 { margin-top: 2.5em !important; } .admin-grid { @@ -119,10 +117,7 @@ a.world-preview:hover { padding: 15px; border-radius: 5px; border: 1px solid #4a4a4a; - flex-grow: 0; /* KORREKTUR: Verhindert das Strecken der letzten Box */ - flex-shrink: 1; - flex-basis: calc(50% - 8px); - box-sizing: border-box; + flex: 1; min-width: 280px; } .admin-contact-block { display: flex; align-items: center; } @@ -176,16 +171,7 @@ a.world-preview:hover { .copy-button:hover { background: #666; } .player-list-container { margin-top: 1em; } .player-list-grid { display: flex; flex-wrap: wrap; gap: 15px; box-sizing: border-box; } -.player-box { - background-color: #303030; - border: 1px solid #555; - border-radius: 5px; - padding: 10px; - width: calc((100% - 30px) / 3); /* KORREKTUR: Max 3 Boxen pro Zeile */ - box-sizing: border-box; - display: flex; - flex-direction: column; -} +.player-box { background-color: #303030; border: 1px solid #555; border-radius: 5px; padding: 10px; width: calc(33.333% - 10px); box-sizing: border-box; display: flex; flex-direction: column;} .player-box.has-server-priv { border-left: 5px solid #FFD700; } .player-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 8px; } .player-identity { display: flex; align-items: center; } @@ -429,56 +415,8 @@ a.read-more-link { display: block; } -/* KORREKTUR: Leaflet Fullscreen Button Icon */ -.leaflet-control-fullscreen a { - background: #fff url('data:image/svg+xml;charset=utf8,%3Csvg viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"%3E%3Cpath d="M2 9H0v7h7v-2H2V9zM0 7h2V2h5V0H0v7zm14 2v5h-5v2h7V9h-2zm0-2V0h-7v2h5v5h2z" fill="%23333"/%3E%3C/svg%3E') no-repeat center center; - background-size: 16px 16px; - font-size: 0; /* Versteckt fehlerhafte Text-Icons */ -} -.leaflet-control-fullscreen a.leaflet-fullscreen-on { - background-image: url('data:image/svg+xml;charset=utf8,%3Csvg viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"%3E%3Cpath d="M0 11h5v5h2V9H0v2zm11 5h5V9h-2v5h-3v2zM5 0H0v7h2V2h3V0zm9 2V0h-2v7h7V5h-5z" fill="%23333"/%3E%3C/svg%3E'); -} - -/* KORREKTUR: Stile für Marker-Popup */ -.leaflet-popup-content-wrapper, .leaflet-popup-content { - background-color: #303030 !important; - color: #ddd !important; - border-radius: 5px; -} -.leaflet-popup-content { - margin: 0 !important; - padding: 0 !important; - line-height: 1.5; -} -.leaflet-container a.leaflet-popup-close-button { - color: #ddd; - padding: 8px 8px 0 0; -} -.leaflet-container a.leaflet-popup-close-button:hover { - color: #fff; - background-color: transparent; -} -.popup-player-box { - padding: 10px; -} -.popup-player-box .player-name { - font-size: 1.2em; /* Schriftgröße für Namen im Popup erhöht */ -} -.popup-player-vitals { - display: flex; - justify-content: space-around; - gap: 10px; - align-items: center; - margin-top: 8px; -} -.popup-player-vitals .vital { - display: flex; - align-items: center; - gap: 5px; -} -.popup-player-vitals .icon { - font-size: 1.2em; -} +.leaflet-control-fullscreen a { background:#fff url('data:image/svg+xml;charset=utf8,%3Csvg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32"%3E%3Cpath d="M4 14h6v6h4v-4h6v-4h-6v-4h-4v4H4zm17 2h12v-2H21zm0 4h12v-2H21zm5 1h7v-2h-7zM10 23h12v4h-4v-4h-4v4H10zm15 0h7v-2h-7z"/%3E%3C/svg%3E') no-repeat 0 0 !important; background-size: 16px 16px !important; } +.leaflet-control-fullscreen a.leaflet-fullscreen-on { background-image: url('data:image/svg+xml;charset=utf8,%3Csvg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32"%3E%3Cpath d="M7 13h2V7h6V5H7zm11-2h7v7h-2v-5h-5z"/%3E%3C/svg%3E') no-repeat 0 0 !important; background-size: 16px 16px !important; } @media (max-width: 768px) { /* Responsive Stile für Burger-Menü */ @@ -511,7 +449,7 @@ a.read-more-link { margin: 5px; width: auto; } - .player-box { width: calc((100% - 15px) / 2); } /* 2 Spalten auf Tablets */ + .player-box { width: calc(50% - 10px); } .page-nav-buttons .button { margin-top: 5px;} /* Responsive Stile für Welt-Vorschau */ @@ -525,13 +463,12 @@ a.read-more-link { margin-right: 0; margin-bottom: 15px; } + + /* NEU: Responsive Höhe für Leaflet-Karte */ .leaflet-map { - height: auto; - aspect-ratio: 4 / 3; - max-height: 70vh; + height: auto; /* Deaktiviert die feste Höhe von 500px */ + aspect-ratio: 1 / 1; /* Erzwingt ein quadratisches Seitenverhältnis */ + max-height: 70vh; /* Stellt sicher, dass die Karte nicht den ganzen Bildschirm füllt */ } } -@media (max-width: 480px) { - .player-box { width: 100%; } /* 1 Spalte auf Handys */ - .admin-box { flex-basis: 100%; } /* 1 Spalte auf Handys */ -} +@media (max-width: 480px) { .player-box { width: 100%; } } diff --git a/site_generator/templates/html_footer.template b/site_generator/templates/html_footer.template index 2bea999..2699a3b 100755 --- a/site_generator/templates/html_footer.template +++ b/site_generator/templates/html_footer.template @@ -1,6 +1,6 @@ diff --git a/site_generator/templates/html_header.template b/site_generator/templates/html_header.template index 8cc4f1b..067b15d 100755 --- a/site_generator/templates/html_header.template +++ b/site_generator/templates/html_header.template @@ -3,8 +3,8 @@ - %%current_page_title%% - %%SITE_TITLE%% - + ${current_page_title} - ${SITE_TITLE} + @@ -40,13 +40,13 @@
-

%%SITE_TITLE%%

+

${SITE_TITLE}

diff --git a/site_generator/templates/world_detail_archive.template b/site_generator/templates/world_detail_archive.template index 0061929..af96c9c 100755 --- a/site_generator/templates/world_detail_archive.template +++ b/site_generator/templates/world_detail_archive.template @@ -1,70 +1,3 @@ -
- - - -
- -
- -

Bitte ein Datum auswählen, um die Karte anzuzeigen.

-
- - +
+
+ diff --git a/site_generator/templates/world_detail_page.template b/site_generator/templates/world_detail_page.template index 63f6245..1dda627 100755 --- a/site_generator/templates/world_detail_page.template +++ b/site_generator/templates/world_detail_page.template @@ -1,5 +1,5 @@
-

%%WORLD_DISPLAY_NAME_PAGE%%

+

${WORLD_DISPLAY_NAME_PAGE}

@@ -13,7 +13,7 @@ -