second alpha (v0.2)

This commit is contained in:
Rainer 2025-06-21 15:58:52 +02:00
parent 7a343254e2
commit 7a1094c733
22 changed files with 2343 additions and 1511 deletions

View file

@ -0,0 +1,69 @@
#!/bin/bash
# 01_utils.sh - Grundlegende Hilfsfunktionen
# === Logging Funktion ===
log_message() {
local msg
msg="$(date '+%Y-%m-%d %H:%M:%S') - $1"
# Prüft, ob stdout ein Terminal ist, um "tee" nur bei interaktiver Ausführung zu nutzen
if [ -t 1 ]; then
echo "${msg}" | tee -a "$LOG_FILE"
else
echo "${msg}" >> "$LOG_FILE"
fi
}
# === Hilfsfunktionen für Platzhalter ===
create_placeholder_file() {
local fp="$1"
local dc="$2"
if [ ! -f "$fp" ]; then
mkdir -p "$(dirname "$fp")"
echo -e "$dc" > "$fp"
log_message "Platzhalterdatei erstellt: $fp"
fi
}
get_config_value_from_file() {
local cf="$1"
local k="$2"
local dv="${3:-}"
local v
if [ ! -f "$cf" ]; then echo "$dv"; return; fi
# Robuste Extraktion, die Kommentare, Leerzeichen und Anführungszeichen berücksichtigt
v=$(grep -E "^\s*${k}\s*=" "$cf" | tail -n 1 | sed -e 's/\s*#.*//' -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//' | cut -d'=' -f2- | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//' -e 's/^"//' -e 's/"$//' -e "s/^'//" -e "s/'$//")
if [ -n "$v" ]; then echo "$v"; else echo "$dv"; fi
}
# === 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")
for ((i=0; i<${#replacements[@]}; i+=2)); do
local key_name="${replacements[i]}"
local key="%%${key_name}%%"
local value="${replacements[i+1]}"
# Manuelle Ersetzung in einer Schleife, um mehrzeilige Inhalte und mehrfache Vorkommen zu unterstützen
local new_content=""
while [[ "$template_content" == *"$key"* ]]; do
new_content+="${template_content%%$key*}${value}"
template_content="${template_content#*$key}"
done
template_content="${new_content}${template_content}"
done
echo "$template_content" > "$output_path"
return $?
}

View file

@ -0,0 +1,54 @@
#!/bin/bash
# 02_init.sh - Initialisierungsfunktionen für Verzeichnisse und Assets
create_placeholder_web_conf() {
local target_path="$1"
local template_file="${EXAMPLE_TEMPLATE_DIR_PATH}/web.conf.template"
if [ -f "$template_file" ]; then
cp "$template_file" "$target_path"
log_message "Beispiel-Konfiguration web.conf von Template nach ${target_path} kopiert."
else
log_message "WARNUNG: Beispiel-Konfigurations-Template nicht gefunden unter ${template_file}!"
local world_key=$(basename "$(dirname "$target_path")")
local content="# Minimale Konfiguration für die Welt '${world_key}'\n\nWORLD_DISPLAY_NAME=\"${world_key}\""
create_placeholder_file "$target_path" "$content"
fi
}
initialize_site_structure_and_assets() {
log_message "Prüfe und erstelle Webseiten-Inhaltsverzeichnisse und Platzhalter..."
mkdir -p "${WEB_ROOT_PATH}"
mkdir -p "${WEB_CONTENT_BASE_PATH}"
mkdir -p "${WEB_CONTENT_STATIC_PATH}"
mkdir -p "${TEMPLATE_DIR_PATH}"
mkdir -p "${EXAMPLE_TEMPLATE_DIR_PATH}"
create_placeholder_file "${WEB_CONTENT_STATIC_PATH}/startseite_content.html" "<h2>Willkommen!</h2><p>Inhalt hier.</p>"
create_placeholder_file "${WEB_CONTENT_STATIC_PATH}/impressum_content.html" "<h2>Impressum</h2><p>Impressum. Betreiber: ${SITE_OWNER_NAME}, Kontakt: ${SITE_OWNER_EMAIL}</p>"
create_placeholder_file "${WEB_CONTENT_STATIC_PATH}/downloads_content.html" "<h2>Downloads</h2><p>Infos. Offiziell: <a href='https://www.luanti.org/downloads/'>luanti.org</a></p>"
create_placeholder_file "${WEB_CONTENT_STATIC_PATH}/datenschutz_content.html" "<h2>Datenschutzerklärung</h2><p>Hier deinen Datenschutztext einfügen.</p>"
local default_world_data_dir="${MINETESTMAPPER_WORLD_DATA_BASE_PATH}${DEFAULT_WORLD_NAME_KEY}"
if [ -d "$default_world_data_dir" ] && [ -f "${default_world_data_dir}/world.mt" ]; then
if [ ! -f "${default_world_data_dir}/web.conf" ]; then
log_message "Erstelle Beispiel web.conf für '${DEFAULT_WORLD_NAME_KEY}'..."
create_placeholder_web_conf "${default_world_data_dir}/web.conf"
fi
fi
log_message "Kopiere Webseiten-Assets (Bilder, Icons)..."
local web_images_target_dir="${WEB_ROOT_PATH}/images"
local source_images_dir="${WEB_CONTENT_BASE_PATH}/${WEB_CONTENT_IMAGES_SOURCE_SUBDIR:-images_source}"
mkdir -p "$web_images_target_dir"
mkdir -p "${web_images_target_dir}/players"
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
for src_file in "$source_images_dir"/players/*.png ; do [ -f "$src_file" ] && cp -u "$src_file" "${web_images_target_dir}/players/"; done
shopt -u nullglob
log_message "Bilder und Spieler-Skins kopiert/aktualisiert."
else
log_message "WARNUNG: Quellverzeichnis für Bilder nicht gefunden: ${source_images_dir}"
fi
}

View file

@ -0,0 +1,38 @@
#!/bin/bash
# 03_html_helpers.sh - Funktionen zum Erstellen von Header und Footer
generate_html_header() {
local current_page_title="$1"
local relative_path_prefix="${2:-.}"
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" ;;
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"
}
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"
}

View file

@ -0,0 +1,25 @@
#!/bin/bash
# css_generator.sh - Erzeugt die zentrale CSS-Datei
generate_css() {
local css_file_path="${WEB_ROOT_PATH}/style.css"
local actual_banner_img_url_path="${FALLBACK_BANNER_IMG_URL}"
if [ -n "$STATIC_BANNER_FILENAME" ]; then
local banner_web_path="/images/${STATIC_BANNER_FILENAME}"
if [ -f "${WEB_ROOT_PATH}${banner_web_path}" ]; then
actual_banner_img_url_path="$banner_web_path"
log_message "Verwende statisches Banner: ${actual_banner_img_url_path}"
else
log_message "WARNUNG: Statisches Banner '${STATIC_BANNER_FILENAME}' nicht gefunden. Fallback: ${FALLBACK_BANNER_IMG_URL}"
fi
else
log_message "Kein STATIC_BANNER_FILENAME definiert, verwende Fallback: ${FALLBACK_BANNER_IMG_URL}"
fi
log_message "Erzeuge/Aktualisiere ${css_file_path}..."
render_template "${TEMPLATE_DIR_PATH}/css.template" "$css_file_path" \
"css_banner_image_path" "$actual_banner_img_url_path" \
"CACHE_BUSTER" "$CACHE_BUSTER"
if [ $? -ne 0 ]; then log_message "FEHLER bei der CSS-Generierung."; fi
}

View file

@ -0,0 +1,37 @@
#!/bin/bash
# main_orchestrator.sh - Ruft die Generatoren für alle weltspezifischen Seiten auf
generate_all_world_pages() {
log_message "Starte Generierung der Weltenübersicht und aller Detailseiten..."
generate_worlds_overview
local processed_world_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 "Keine Weltverzeichnisse für Detailseiten gefunden."
return
fi
for world_data_dir in "${world_key_dirs[@]}"; do
local world_key=$(basename "$world_data_dir")
if [ -z "$world_key" ]; then continue; fi
if [ -f "${world_data_dir}world.mt" ] && [ -f "${world_data_dir}web.conf" ]; then
# Platzhalter für zukünftige sync-Skripte sicherstellen
local web_world_dir="${WEB_ROOT_PATH}/${WEB_MAPS_BASE_SUBDIR}/${world_key}"
mkdir -p "$web_world_dir"
touch "${web_world_dir}/areas.txt"
touch "${web_world_dir}/players.txt"
touch "${web_world_dir}/weather.txt"
generate_world_detail_page "$world_key"
processed_world_count=$((processed_world_count + 1))
else
log_message "[${world_key}] WARNUNG: world.mt oder web.conf fehlt. Detailseite nicht erstellt."
fi
done
log_message "${processed_world_count} Welt-Detailseiten generiert/aktualisiert."
}

View file

@ -0,0 +1,53 @@
#!/bin/bash
# static_pages_generator.sh - Erzeugt alle einfachen, statischen Seiten
generate_homepage() {
local p="${WEB_ROOT_PATH}/index.html"
local c="${WEB_CONTENT_STATIC_PATH}/startseite_content.html"
{
generate_html_header "Willkommen" "." "home"
if [ -f "$c" ]; then cat "$c"; else echo "<h2>Willkommen!</h2>"; fi
generate_html_footer
} > "$p"
}
generate_impressum() {
local p="${WEB_ROOT_PATH}/impressum.html"
local c="${WEB_CONTENT_STATIC_PATH}/impressum_content.html"
{
generate_html_header "Impressum" "."
if [ -f "$c" ]; then cat "$c"; else echo "<h2>Impressum</h2><p>Betreiber: ${SITE_OWNER_NAME}<br>Kontakt: <a href='mailto:${SITE_OWNER_EMAIL}'>${SITE_OWNER_EMAIL}</a></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"
{
generate_html_header "Downloads" "." "downloads"
if [ -f "$c" ]; then cat "$c"; else cat >&1 <<EOF
<h2>Downloads</h2><p>Offizielle Seite: <a href="https://www.luanti.org/downloads/" target="_blank">luanti.org</a></p>
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"
{
generate_html_header "Datenschutz" "."
if [ -f "$c" ]; then cat "$c"; else echo "<h2>Datenschutzerklärung</h2><p>Platzhalter.</p>"; fi
generate_html_footer
} > "$p"
}
generate_static_pages() {
log_message "Generiere statische Seiten (Homepage, Impressum etc.)..."
generate_homepage
generate_impressum
generate_downloads_page
generate_datenschutz_page
}

View file

@ -0,0 +1,221 @@
#!/bin/bash
# world_detail_generator.sh - Erzeugt die komplexe Detailseite für eine einzelne Welt
generate_world_detail_page() {
local current_world_key="$1"
local detail_page_file="${WEB_ROOT_PATH}/world_${current_world_key}.html"
local current_minetest_world_path="${MINETESTMAPPER_WORLD_DATA_BASE_PATH}${current_world_key}"
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 "[${current_world_key}] FEHLER: world.mt oder web.conf fehlt."; return 1; fi
log_message "[${current_world_key}] Starte Generierung der Detailseite..."
# --- DATEN SAMMELN ---
local gdal_zoom_levels; gdal_zoom_levels=$(get_config_value_from_file "$web_conf_file" "GDAL2TILES_ZOOM_LEVELS" "$DEFAULT_GDAL2TILES_ZOOM_LEVELS")
local min_zoom_val; min_zoom_val=$(echo "$gdal_zoom_levels" | cut -d- -f1)
local max_zoom_val; max_zoom_val=$(echo "$gdal_zoom_levels" | cut -d- -f2)
if [ -z "$max_zoom_val" ]; then max_zoom_val="$min_zoom_val"; fi
local resolutions_array=""
local num_zooms=$((max_zoom_val - min_zoom_val + 1))
for (( i=0; i<num_zooms; i++ )); do
local current_zoom_level=$((min_zoom_val + i))
local res=$((2**(max_zoom_val - current_zoom_level)))
resolutions_array+="${res},"
done
resolutions_array="[${resolutions_array%,}]"
local tiles_subdir_name; tiles_subdir_name=$(get_config_value_from_file "$web_conf_file" "TILES_SUBDIR_NAME" "$DEFAULT_TILES_SUBDIR_NAME")
local web_tiles_rel_path="${WEB_MAPS_BASE_SUBDIR}/${current_world_key}/${tiles_subdir_name}"
# HINZUGEFÜGT: Hintergrundfarbe auslesen
local map_background_color; map_background_color=$(get_config_value_from_file "$web_conf_file" "MM_OPT_BGCOLOR" "$DEFAULT_MM_OPT_BGCOLOR")
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")
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"
local WORLD_LONG_DESCRIPTION_PAGE="${WORLD_LONG_DESCRIPTION:-$DEFAULT_WORLD_LONG_DESCRIPTION}"
local WORLD_GAME_RULES_PAGE="${WORLD_GAME_RULES:-}"
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" ;;
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"
local MODS_HTML=""
if [ ${#parsed_mod_packs[@]} -gt 0 ] || [ ${#parsed_standalone_mods[@]} -gt 0 ]; then
MODS_HTML+="<ul class='mod-list'>"
local sorted_pack_names=(); if [ ${#parsed_mod_packs[@]} -gt 0 ]; then mapfile -t sorted_pack_names < <(printf '%s\n' "${!parsed_mod_packs[@]}" | sort); fi
for pack_name in "${sorted_pack_names[@]}"; do
MODS_HTML+="<li>+ <a href='https://content.luanti.org/packages/?q=${pack_name}' target='_blank' rel='noopener noreferrer'>${pack_name}</a><ul>"
local mods_in_pack_str="${parsed_mod_packs[$pack_name]}"
local sorted_mods_in_pack=(); if [ -n "$mods_in_pack_str" ]; then mapfile -t sorted_mods_in_pack < <(echo "$mods_in_pack_str" | tr ' ' '\n' | grep -v '^\s*$' | sort); fi
for mod_in_pack in "${sorted_mods_in_pack[@]}"; do
[ -n "$mod_in_pack" ] && MODS_HTML+="<li>- <a href='https://content.luanti.org/packages/?q=${mod_in_pack}' target='_blank' rel='noopener noreferrer'>${mod_in_pack}</a></li>"
done
MODS_HTML+="</ul></li>"
done
local sorted_standalone_mods=(); if [ ${#parsed_standalone_mods[@]} -gt 0 ]; then mapfile -t sorted_standalone_mods < <(printf '%s\n' "${parsed_standalone_mods[@]}" | sort); fi
for solo_mod in "${sorted_standalone_mods[@]}"; do
[ -n "$solo_mod" ] && MODS_HTML+="<li>- <a href='https://content.luanti.org/packages/?q=${solo_mod}' target='_blank' rel='noopener noreferrer'>${solo_mod}</a></li>"
done
MODS_HTML+="</ul>"
else
MODS_HTML="<p>Keine Mod-Informationen in world.mt gefunden.</p>"
fi
local ARCHIVE_HTML=""; local available_archive_dates_js_array="[]"; local -a available_archive_dates_bash=();
local CURRENT_ARCHIVE_SUBDIR_NAME=$(get_config_value_from_file "$web_conf_file" "ARCHIVE_SUBDIR_NAME" "$DEFAULT_ARCHIVE_SUBDIR_NAME")
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}]";
fi
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_archiv.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"
local ADMIN_BOXES_HTML=""
local num_admins=${#ADMIN_NAME[@]}
if [ $num_admins -eq 0 ]; then
ADMIN_BOXES_HTML="<div class='admin-box'><div class='admin-contact-block'><img src='/${SITE_OWNER_ADMIN_SKIN_URL:-$DEFAULT_PLAYER_SKIN_URL}?v=${CACHE_BUSTER}' alt='Admin Skin' class='admin-skin-icon'><div class='admin-text-details'><p><strong class='admin-player-name'>${SITE_OWNER_NAME}</strong></p><div class='contact-links'><a href='mailto:${SITE_OWNER_EMAIL}' class='contact-button' data-title='E-Mail: ${SITE_OWNER_EMAIL}'>Email</a></div></div></div></div>"
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]}"
local contact_links_html=""
[ -n "$email" ] && contact_links_html+="<a href='mailto:${email}' class='contact-button' data-title='E-Mail: ${email}'>Email</a>"
[ -n "$discord" ] && contact_links_html+="<a href='https://discordapp.com/users/${discord}' target='_blank' rel='noopener noreferrer' class='contact-button' data-title='Discord: ${discord}'>Discord</a>"
[ -n "$matrix" ] && contact_links_html+="<a href='https://matrix.to/#/${matrix}' target='_blank' rel='noopener noreferrer' class='contact-button' data-title='Matrix: ${matrix}'>Matrix</a>"
[ -n "$steam" ] && contact_links_html+="<a href='${steam}' target='_blank' rel='noopener noreferrer' class='contact-button' data-title='Steam Profil'>Steam</a>"
[ -n "$teamspeak" ] && contact_links_html+="<a href='ts3server://${teamspeak}' class='contact-button' data-title='Teamspeak: ${teamspeak}'>Teamspeak</a>"
[ -n "$mumble" ] && contact_links_html+="<a href='mumble://${mumble}' class='contact-button' data-title='Mumble: ${mumble}'>Mumble</a>"
ADMIN_BOXES_HTML+="<div class='admin-box'><div class='admin-contact-block'><img src='/${skin_url}?v=${CACHE_BUSTER}' alt='Admin Skin ${name}' class='admin-skin-icon' onerror=\"this.onerror=null;this.src='/${DEFAULT_PLAYER_SKIN_URL}?v=${CACHE_BUSTER}';\"><div class='admin-text-details'><p><strong class='admin-player-name'>${name}</strong></p></div></div>"; if [ -n "$contact_links_html" ]; then ADMIN_BOXES_HTML+="<div class='contact-links'>${contact_links_html}</div>"; fi; ADMIN_BOXES_HTML+="</div>"
done
fi
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 map_sub_info_link=""
if [ -f "$unknown_nodes_abs_path" ]; then
map_sub_info_link="<span class='map-file-link'><a href='/${web_unknown_nodes_rel_path}?v=${CACHE_BUSTER}' target='_blank'>Fehlende Map-Nodes</a></span>"
else
map_sub_info_link="<span class='map-file-link'>&nbsp;</span>"
fi
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
# --- TEMPLATES RENDERN ---
local temp_radar_file; temp_radar_file=$(mktemp)
render_template "${TEMPLATE_DIR_PATH}/world_detail_radar.template" "$temp_radar_file" \
"current_world_key" "$current_world_key" \
"map_sub_info_link" "$map_sub_info_link" \
"web_last_update_rel_path" "${WEB_MAPS_BASE_SUBDIR}/${current_world_key}/last_update.txt" \
"CACHE_BUSTER" "$CACHE_BUSTER" \
"ARCHIVE_HTML" "$ARCHIVE_HTML" \
"RESOLUTIONS_JS_ARRAY" "$resolutions_array" \
"web_tiles_rel_path" "$web_tiles_rel_path" \
"web_map_info_rel_path" "${WEB_MAPS_BASE_SUBDIR}/${current_world_key}/map_info.txt" \
"map_background_color" "$map_background_color"
local WORLD_RADAR_HTML; WORLD_RADAR_HTML=$(<"$temp_radar_file")
rm "$temp_radar_file"
local temp_playerlist_file; temp_playerlist_file=$(mktemp)
render_template "${TEMPLATE_DIR_PATH}/world_detail_playerlist.template" "$temp_playerlist_file" \
"current_world_key" "$current_world_key" \
"DEFAULT_PLAYER_SKIN_URL" "$DEFAULT_PLAYER_SKIN_URL" \
"CACHE_BUSTER" "$CACHE_BUSTER"
local WORLD_PLAYERLIST_HTML; WORLD_PLAYERLIST_HTML=$(<"$temp_playerlist_file")
rm "$temp_playerlist_file"
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" "$DEFAULT_SERVER_STATUS_TEXT_FALLBACK" \
"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" \
"WORLD_LONG_DESCRIPTION_PAGE" "$WORLD_LONG_DESCRIPTION_PAGE" \
"WORLD_GAME_RULES_PAGE" "$WORLD_GAME_RULES_PAGE" \
"MODS_HTML" "$MODS_HTML" \
"WORLD_RADAR_HTML" "$WORLD_RADAR_HTML" \
"WORLD_PLAYERLIST_HTML" "$WORLD_PLAYERLIST_HTML" \
"web_online_status_rel_path" "${WEB_MAPS_BASE_SUBDIR}/${current_world_key}/online_status.txt" \
"web_last_update_rel_path" "${WEB_MAPS_BASE_SUBDIR}/${current_world_key}/last_update.txt" \
"web_players_txt_rel_path" "${WEB_MAPS_BASE_SUBDIR}/${current_world_key}/players.txt" \
"web_weather_txt_rel_path" "${WEB_MAPS_BASE_SUBDIR}/${current_world_key}/weather.txt" \
"CACHE_BUSTER" "$CACHE_BUSTER"
{
generate_html_header "Welt: ${WORLD_DISPLAY_NAME_PAGE}" "."
cat "$temp_body_file"
generate_html_footer
} > "$detail_page_file"
rm "$temp_body_file"
log_message "[${current_world_key}] Detailseite erstellt."
}

View file

@ -0,0 +1,85 @@
#!/bin/bash
# world_overview_generator.sh - Erzeugt die Welten-Übersichtsseite
generate_worlds_overview() {
local overview_file="${WEB_ROOT_PATH}/worlds.html"
log_message "Erzeuge Weltenübersicht: ${overview_file}..."
{
generate_html_header "Weltenübersicht" "." "worlds"
echo "<h2>Unsere Welten</h2>"
} > "$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 "<p>Keine Welten verfügbar.</p>" >> "$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"
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")
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")
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)
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
fi
local detail_page_filename="world_${current_world_key}.html"
local preview_img_rel_path="${WEB_MAPS_BASE_SUBDIR}/${current_world_key}/${current_map_png_filename_for_preview_ov}"
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
local preview_img_html
if [ -f "$preview_img_abs_path" ]; then
preview_img_html="<img src='${preview_img_rel_path}?v=${CACHE_BUSTER}' alt='Vorschau ${world_display_name_ov}'>"
else
preview_img_html="<img src='images/placeholder_map.png?v=${CACHE_BUSTER}' alt='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"
discovered_worlds_count=$((discovered_worlds_count + 1))
done
if [ "$discovered_worlds_count" -eq 0 ]; then echo "<p>Keine Welten mit gültiger Konfiguration gefunden.</p>" >> "$overview_file"; fi
fi
generate_html_footer >> "$overview_file"
}