diff --git a/check_dependencies.sh b/check_dependencies.sh new file mode 100755 index 0000000..b126722 --- /dev/null +++ b/check_dependencies.sh @@ -0,0 +1,90 @@ +#!/bin/bash +# check_dependencies.sh - Prüft, ob alle benötigten Programme und Build-Abhängigkeiten installiert sind. + +# Lade die Projekt-Konfiguration, um den Pfad zu minetestmapper zu kennen +CONFIG_FILE_PATH="$(dirname "$0")/config.sh" +if [ ! -f "$CONFIG_FILE_PATH" ]; then + echo "FEHLER: Konfigurationsdatei config.sh nicht unter ${CONFIG_FILE_PATH} gefunden!" + exit 1 +fi +source "$CONFIG_FILE_PATH" + +echo "Starte Überprüfung der System-Abhängigkeiten..." +echo "" + +declare -i missing_count=0 + +# --- Teil 1: Kritische Laufzeit-Programme --- +echo "--- Prüfe Laufzeit-Programme ---" + +# Spezieller Check für minetestmapper am Projekt-Pfad +MINETESTMAPPER_FULL_PATH="${BASE_SCRIPT_DIR}/${MINETESTMAPPER_EXEC_NAME}" +if [ -f "$MINETESTMAPPER_FULL_PATH" ]; then + if [ -x "$MINETESTMAPPER_FULL_PATH" ]; then + echo "[+] OK: '${MINETESTMAPPER_EXEC_NAME}' ist verfügbar und ausführbar unter: ${MINETESTMAPPER_FULL_PATH}" + else + echo "[-] FEHLER: '${MINETESTMAPPER_EXEC_NAME}' gefunden, aber NICHT AUSFÜHRBAR unter: ${MINETESTMAPPER_FULL_PATH}" + echo " -> Bitte mit 'chmod +x ${MINETESTMAPPER_FULL_PATH}' korrigieren." + missing_count=$((missing_count + 1)) + fi +else + echo "[-] FEHLER: Das Hauptprogramm '${MINETESTMAPPER_EXEC_NAME}' wurde nicht unter dem erwarteten Pfad ${MINETESTMAPPER_FULL_PATH} gefunden." + missing_count=$((missing_count + 1)) +fi + +# Checks für andere Programme, die im PATH sein sollten +# KORREKTUR: 'convert' und 'identify' entfernt, 'vips' hinzugefügt +declare -a runtime_deps_in_path=("gdal2tiles.py" "vips" "ss") +for dep in "${runtime_deps_in_path[@]}"; do + if ! command -v "$dep" &> /dev/null; then + echo "[-] FEHLER: Das benötigte Programm '$dep' wurde nicht im System-Pfad gefunden." + missing_count=$((missing_count + 1)) + else + found_path=$(command -v "$dep") + echo "[+] OK: '$dep' ist verfügbar unter: ${found_path}" + fi +done + +echo "" +# --- Teil 2: Build-Abhängigkeiten für minetestmapper --- +echo "--- Prüfe Build-Abhängigkeiten (für Debian/Ubuntu-basierte Systeme) ---" +declare -a build_deps=("cmake" "libgd-dev" "libhiredis-dev" "libleveldb-dev" "libpq-dev" "libsqlite3-dev" "zlib1g-dev" "libzstd-dev") + +# Prüfen, ob dpkg verfügbar ist, sonst diesen Teil überspringen +if ! command -v "dpkg" &> /dev/null; then + echo "[!] WARNUNG: 'dpkg' Kommando nicht gefunden. Kann Build-Abhängigkeiten nicht prüfen. (Dies ist normal auf nicht-Debian-Systemen)" +else + for pkg in "${build_deps[@]}"; do + # dpkg -s gibt einen Fehlercode zurück, wenn das Paket nicht installiert ist + if ! dpkg -s "$pkg" &> /dev/null; then + echo "[-] FEHLER: Das benötigte Build-Paket '$pkg' scheint nicht installiert zu sein." + missing_count=$((missing_count + 1)) + else + echo "[+] OK: Build-Paket '$pkg' ist installiert." + fi + done +fi + +echo "-----------------------------------------------------" + +# --- Fazit --- +if [ "$missing_count" -gt 0 ]; then + echo "" + echo "Prüfung fehlgeschlagen. Es fehlen ${missing_count} Abhängigkeit(en)." + echo "Bitte die oben als FEHLER markierten Programme und/oder Pakete installieren bzw. korrigieren." + echo "" + echo "Hinweise zur Installation (Beispiele für Debian/Ubuntu):" + echo " Laufzeit-Programme:" + echo " - minetestmapper: Muss manuell kompiliert oder aus einer anderen Quelle bezogen werden." + echo " - gdal-bin: Enthält 'gdal2tiles.py'." + echo " - libvips-tools: Enthält 'vips' für die Bildbearbeitung." + echo " - iproute2: Enthält 'ss' (meist vorinstalliert)." + echo "" + echo " Build-Pakete (zum Kompilieren von minetestmapper):" + echo " - sudo apt-get install cmake libgd-dev libhiredis-dev libleveldb-dev libpq-dev libsqlite3-dev zlib1g-dev libzstd-dev" + exit 1 +else + echo "" + echo "Alle geprüften Abhängigkeiten sind vorhanden. Das System ist startklar." + exit 0 +fi diff --git a/check_server_status.sh b/check_server_status.sh index d559709..94f170a 100755 --- a/check_server_status.sh +++ b/check_server_status.sh @@ -1,5 +1,8 @@ #!/bin/bash +# Prüfe Abhängigkeiten, bevor irgendetwas anderes passiert +./check_dependencies.sh || exit 1 + # Lade globale Konfiguration # Annahme: config.sh liegt im selben Verzeichnis wie dieses Skript CONFIG_FILE_PATH="$(dirname "$0")/config.sh" diff --git a/colors.txt b/colors.txt index 0122b12..cdb7ada 100644 --- a/colors.txt +++ b/colors.txt @@ -1,461 +1,3 @@ -# beds -beds:bed_bottom 130 3 3 -beds:bed_top 185 162 163 -beds:fancy_bed_bottom 136 49 28 -beds:fancy_bed_top 179 153 148 - -# bones -bones:bones 117 117 117 - -# butterflies - -# carts -carts:brakerail 150 121 102 -carts:powerrail 160 145 102 -carts:rail 146 128 108 - -# default -default:acacia_bush_leaves 109 133 87 -default:acacia_bush_sapling 85 121 61 -default:acacia_bush_stem 84 77 70 -default:acacia_leaves 126 153 101 -default:acacia_sapling 87 120 64 -default:acacia_tree 195 119 97 -default:acacia_wood 150 61 39 -default:apple 161 34 19 -default:aspen_leaves 72 105 29 -default:aspen_sapling 85 123 45 -default:aspen_tree 218 198 168 -default:aspen_wood 210 199 170 -default:blueberry_bush_leaves 63 99 22 -default:blueberry_bush_leaves_with_berries 63 99 22 -default:blueberry_bush_sapling 81 112 33 -default:bookshelf 131 102 57 -default:brick 123 99 95 -default:bronzeblock 186 111 15 -default:bush_leaves 35 55 29 -default:bush_sapling 66 64 40 -default:bush_stem 46 34 24 -default:cactus 70 119 52 -default:cave_ice 168 206 247 -default:chest 149 115 69 -default:chest_locked 149 115 69 -default:chest_locked_open 149 115 69 -default:chest_open 149 115 69 -default:clay 183 183 183 -default:cloud 255 255 255 -default:coalblock 58 58 58 -default:cobble 89 86 84 -default:copperblock 193 126 65 -default:coral_brown 146 113 77 -default:coral_cyan 235 230 215 -default:coral_green 235 230 215 -default:coral_orange 197 68 17 -default:coral_pink 235 230 215 -default:coral_skeleton 235 230 215 -default:desert_cobble 110 67 50 -default:desert_sand 206 165 98 -default:desert_sandstone 195 152 92 -default:desert_sandstone_block 193 152 94 -default:desert_sandstone_brick 191 151 95 -default:desert_stone 130 79 61 -default:desert_stone_block 131 80 61 -default:desert_stonebrick 131 80 61 -default:diamondblock 140 218 223 -default:dirt 97 67 43 -default:dirt_with_coniferous_litter 109 90 71 -default:dirt_with_dry_grass 187 148 78 -default:dirt_with_grass 64 111 26 -default:dirt_with_grass_footsteps 64 111 26 -default:dirt_with_rainforest_litter 76 39 10 -default:dirt_with_snow 225 225 238 -default:dry_dirt 178 136 90 -default:dry_dirt_with_dry_grass 187 148 78 -default:dry_grass_1 208 172 87 -default:dry_grass_2 210 174 87 -default:dry_grass_3 210 174 87 -default:dry_grass_4 211 175 88 -default:dry_grass_5 214 178 92 -default:dry_shrub 103 67 18 -default:emergent_jungle_sapling 51 40 16 -default:fence_acacia_wood 151 62 39 -default:fence_aspen_wood 210 199 170 -default:fence_junglewood 57 39 14 -default:fence_pine_wood 221 185 131 -default:fence_rail_acacia_wood 150 61 39 -default:fence_rail_aspen_wood 209 198 170 -default:fence_rail_junglewood 56 39 14 -default:fence_rail_pine_wood 221 184 130 -default:fence_rail_wood 131 102 57 -default:fence_wood 132 103 57 -default:fern_1 85 118 51 -default:fern_2 90 123 53 -default:fern_3 91 125 54 -default:furnace 101 98 96 -default:furnace_active 101 98 96 -default:glass 247 247 247 64 16 -default:goldblock 231 203 35 -default:grass_1 100 140 54 -default:grass_2 98 139 55 -default:grass_3 94 136 53 -default:grass_4 89 133 48 -default:grass_5 86 126 48 -default:gravel 132 132 132 -default:ice 168 206 247 -default:junglegrass 67 110 28 -default:jungleleaves 22 31 16 -default:junglesapling 51 39 15 -default:jungletree 121 97 62 -default:junglewood 56 39 14 -default:ladder_steel 132 132 132 -default:ladder_wood 125 93 43 -default:large_cactus_seedling 67 107 52 -default:lava_flowing 255 100 0 -default:lava_source 255 100 0 -default:leaves 36 55 29 -default:marram_grass_1 113 139 96 -default:marram_grass_2 102 131 90 -default:marram_grass_3 99 130 88 -default:mese 222 222 0 -default:mese_post_light 132 103 57 -default:mese_post_light_acacia_wood 151 62 39 -default:mese_post_light_aspen_wood 210 199 170 -default:mese_post_light_junglewood 57 39 14 -default:mese_post_light_pine_wood 221 185 131 -default:meselamp 213 215 143 -default:mossycobble 88 91 73 -default:obsidian 21 24 29 -default:obsidian_block 23 25 30 -default:obsidian_glass 20 23 27 64 16 -default:obsidianbrick 23 25 29 -default:papyrus 97 134 38 -default:permafrost 71 66 61 -default:permafrost_with_moss 108 150 51 -default:permafrost_with_stones 71 66 61 -default:pine_bush_needles 16 50 19 -default:pine_bush_sapling 58 51 40 -default:pine_bush_stem 73 62 53 -default:pine_needles 16 50 19 -default:pine_sapling 41 48 26 -default:pine_tree 191 165 132 -default:pine_wood 221 185 130 -default:river_water_flowing 39 66 106 128 224 -default:river_water_source 39 66 106 128 224 -default:sand 214 207 158 -default:sand_with_kelp 214 207 158 -default:sandstone 198 193 143 -default:sandstone_block 195 191 142 -default:sandstonebrick 194 190 141 -default:sapling 67 63 41 -default:sign_wall_steel 147 147 147 -default:sign_wall_wood 148 103 66 -default:silver_sand 193 191 179 -default:silver_sandstone 195 192 181 -default:silver_sandstone_block 192 190 180 -default:silver_sandstone_brick 191 189 179 -default:snow 225 225 238 -default:snowblock 225 225 238 -default:steelblock 195 195 195 - -# default stone and ores -default:stone 97 94 93 -default:stone_block 100 97 96 -default:stone_with_coal 77 75 74 # Stein mit einem deutlichen Graustich von Kohle (dunkler) -default:stone_with_copper 128 102 86 # Stein mit einem bräunlich-orangen Kupferstich -default:stone_with_diamond 119 135 142 # Stein mit einem hellen, leicht bläulichen Diamantstich -default:stone_with_gold 144 130 80 # Stein mit einem gelblichen Goldstich -default:stone_with_iron 119 96 86 # Stein mit einem rostbraunen/gräulichen Eisenstich -default:stone_with_mese 144 120 71 # Stein mit einem kräftigen orangegelben Mesestich -default:stone_with_tin 125 126 128 -default:stonebrick 102 99 98 -default:tinblock 150 150 150 -default:torch 141 123 93 -default:torch_ceiling 141 123 93 -default:torch_wall 141 123 93 -default:tree 179 145 99 -default:water_flowing 39 66 106 128 224 -default:water_source 39 66 106 128 224 -default:wood 131 102 57 - -# doors -doors:door_glass_a 245 245 245 64 16 -doors:door_glass_b 245 245 245 64 16 -doors:door_glass_c 245 245 245 64 16 -doors:door_glass_d 245 245 245 64 16 -doors:door_obsidian_glass_a 48 49 50 64 16 -doors:door_obsidian_glass_b 48 49 50 64 16 -doors:door_obsidian_glass_c 48 49 50 64 16 -doors:door_obsidian_glass_d 48 49 50 64 16 -doors:door_steel_a 203 203 203 -doors:door_steel_b 203 203 203 -doors:door_steel_c 203 203 203 -doors:door_steel_d 203 203 203 -doors:door_wood_a 89 68 37 -doors:door_wood_b 89 68 37 -doors:door_wood_c 89 68 37 -doors:door_wood_d 89 68 37 -doors:gate_acacia_wood_closed 150 61 39 -doors:gate_acacia_wood_open 150 61 39 -doors:gate_aspen_wood_closed 210 199 170 -doors:gate_aspen_wood_open 210 199 170 -doors:gate_junglewood_closed 56 39 14 -doors:gate_junglewood_open 56 39 14 -doors:gate_pine_wood_closed 221 185 130 -doors:gate_pine_wood_open 221 185 130 -doors:gate_wood_closed 131 102 57 -doors:gate_wood_open 131 102 57 -doors:trapdoor 130 100 51 -doors:trapdoor_open 68 53 30 -doors:trapdoor_steel 200 200 200 -doors:trapdoor_steel_open 97 97 97 - -# farming -farming:cotton_1 89 117 39 -farming:cotton_2 89 116 38 -farming:cotton_3 99 121 41 -farming:cotton_4 108 114 47 -farming:cotton_5 116 105 53 -farming:cotton_6 121 95 59 -farming:cotton_7 94 70 37 -farming:cotton_8 122 108 93 -farming:cotton_wild 111 111 101 -farming:desert_sand_soil 161 132 72 -farming:desert_sand_soil_wet 120 99 53 -farming:dry_soil 178 136 90 -farming:dry_soil_wet 178 136 90 -farming:seed_cotton 92 87 60 -farming:seed_wheat 177 161 96 -farming:soil 97 67 43 -farming:soil_wet 97 67 43 -farming:straw 212 184 68 -farming:wheat_1 110 175 36 -farming:wheat_2 136 177 53 -farming:wheat_3 163 182 84 -farming:wheat_4 170 188 95 -farming:wheat_5 171 179 97 -farming:wheat_6 173 177 87 -farming:wheat_7 193 181 83 -farming:wheat_8 187 162 40 - -# fire -fire:basic_flame 223 136 44 -fire:permanent_flame 223 136 44 - -# fireflies -fireflies:firefly_bottle 191 194 202 - -# flowers -flowers:chrysanthemum_green 118 152 44 -flowers:dandelion_white 199 191 176 -flowers:dandelion_yellow 212 167 31 -flowers:geranium 77 91 168 -flowers:mushroom_brown 109 84 78 -flowers:mushroom_red 195 102 102 -flowers:rose 130 68 33 -flowers:tulip 156 101 44 -flowers:tulip_black 78 120 72 -flowers:viola 115 69 184 -flowers:waterlily 107 160 68 -flowers:waterlily_waving 107 160 68 - -# stairs -stairs:slab_acacia_wood 150 61 39 -stairs:slab_aspen_wood 210 199 170 -stairs:slab_brick 123 99 95 -stairs:slab_bronzeblock 186 111 15 -stairs:slab_cobble 89 86 84 -stairs:slab_copperblock 193 126 65 -stairs:slab_desert_cobble 110 67 50 -stairs:slab_desert_sandstone 195 152 92 -stairs:slab_desert_sandstone_block 193 152 94 -stairs:slab_desert_sandstone_brick 191 151 95 -stairs:slab_desert_stone 130 79 61 -stairs:slab_desert_stone_block 131 80 61 -stairs:slab_desert_stonebrick 131 80 61 -stairs:slab_glass 247 247 247 -stairs:slab_goldblock 231 203 35 -stairs:slab_ice 168 206 247 -stairs:slab_junglewood 56 39 14 -stairs:slab_mossycobble 88 91 73 -stairs:slab_obsidian 21 24 29 -stairs:slab_obsidian_block 23 25 30 -stairs:slab_obsidian_glass 20 23 27 -stairs:slab_obsidianbrick 23 25 29 -stairs:slab_pine_wood 221 185 130 -stairs:slab_sandstone 198 193 143 -stairs:slab_sandstone_block 195 191 142 -stairs:slab_sandstonebrick 194 190 141 -stairs:slab_silver_sandstone 195 192 181 -stairs:slab_silver_sandstone_block 192 190 180 -stairs:slab_silver_sandstone_brick 191 189 179 -stairs:slab_snowblock 225 225 238 -stairs:slab_steelblock 195 195 195 -stairs:slab_stone 97 94 93 -stairs:slab_stone_block 100 97 96 -stairs:slab_stonebrick 102 99 98 -stairs:slab_straw 212 184 68 -stairs:slab_tinblock 150 150 150 -stairs:slab_wood 131 102 57 -stairs:stair_acacia_wood 150 61 39 -stairs:stair_aspen_wood 210 199 170 -stairs:stair_brick 123 99 95 -stairs:stair_bronzeblock 186 111 15 -stairs:stair_cobble 89 86 84 -stairs:stair_copperblock 193 126 65 -stairs:stair_desert_cobble 110 67 50 -stairs:stair_desert_sandstone 195 152 92 -stairs:stair_desert_sandstone_block 193 152 94 -stairs:stair_desert_sandstone_brick 191 151 95 -stairs:stair_desert_stone 130 79 61 -stairs:stair_desert_stone_block 131 80 61 -stairs:stair_desert_stonebrick 131 80 61 -stairs:stair_glass 249 249 249 -stairs:stair_goldblock 231 203 35 -stairs:stair_ice 168 206 247 -stairs:stair_inner_acacia_wood 150 61 39 -stairs:stair_inner_aspen_wood 210 199 170 -stairs:stair_inner_brick 123 99 95 -stairs:stair_inner_bronzeblock 186 111 15 -stairs:stair_inner_cobble 89 86 84 -stairs:stair_inner_copperblock 193 126 65 -stairs:stair_inner_desert_cobble 110 67 50 -stairs:stair_inner_desert_sandstone 195 152 92 -stairs:stair_inner_desert_sandstone_block 193 152 94 -stairs:stair_inner_desert_sandstone_brick 191 151 95 -stairs:stair_inner_desert_stone 130 79 61 -stairs:stair_inner_desert_stone_block 131 80 61 -stairs:stair_inner_desert_stonebrick 131 80 61 -stairs:stair_inner_glass 250 250 250 -stairs:stair_inner_goldblock 231 203 35 -stairs:stair_inner_ice 168 206 247 -stairs:stair_inner_junglewood 56 39 14 -stairs:stair_inner_mossycobble 88 91 73 -stairs:stair_inner_obsidian 21 24 29 -stairs:stair_inner_obsidian_block 23 25 30 -stairs:stair_inner_obsidian_glass 20 22 27 -stairs:stair_inner_obsidianbrick 23 25 29 -stairs:stair_inner_pine_wood 221 185 130 -stairs:stair_inner_sandstone 198 193 143 -stairs:stair_inner_sandstone_block 195 191 142 -stairs:stair_inner_sandstonebrick 194 190 141 -stairs:stair_inner_silver_sandstone 195 192 181 -stairs:stair_inner_silver_sandstone_block 192 190 180 -stairs:stair_inner_silver_sandstone_brick 191 189 179 -stairs:stair_inner_snowblock 225 225 238 -stairs:stair_inner_steelblock 195 195 195 -stairs:stair_inner_stone 97 94 93 -stairs:stair_inner_stone_block 100 97 96 -stairs:stair_inner_stonebrick 102 99 98 -stairs:stair_inner_straw 212 184 68 -stairs:stair_inner_tinblock 150 150 150 -stairs:stair_inner_wood 131 102 57 -stairs:stair_junglewood 56 39 14 -stairs:stair_mossycobble 88 91 73 -stairs:stair_obsidian 21 24 29 -stairs:stair_obsidian_block 23 25 30 -stairs:stair_obsidian_glass 20 22 27 -stairs:stair_obsidianbrick 23 25 29 -stairs:stair_outer_acacia_wood 150 61 39 -stairs:stair_outer_aspen_wood 210 199 170 -stairs:stair_outer_brick 123 99 95 -stairs:stair_outer_bronzeblock 186 111 15 -stairs:stair_outer_cobble 89 86 84 -stairs:stair_outer_copperblock 193 126 65 -stairs:stair_outer_desert_cobble 110 67 50 -stairs:stair_outer_desert_sandstone 195 152 92 -stairs:stair_outer_desert_sandstone_block 193 152 94 -stairs:stair_outer_desert_sandstone_brick 191 151 95 -stairs:stair_outer_desert_stone 130 79 61 -stairs:stair_outer_desert_stone_block 131 80 61 -stairs:stair_outer_desert_stonebrick 131 80 61 -stairs:stair_outer_glass 250 250 250 -stairs:stair_outer_goldblock 231 203 35 -stairs:stair_outer_ice 168 206 247 -stairs:stair_outer_junglewood 56 39 14 -stairs:stair_outer_mossycobble 88 91 73 -stairs:stair_outer_obsidian 21 24 29 -stairs:stair_outer_obsidian_block 23 25 30 -stairs:stair_outer_obsidian_glass 20 22 27 -stairs:stair_outer_obsidianbrick 23 25 29 -stairs:stair_outer_pine_wood 221 185 130 -stairs:stair_outer_sandstone 198 193 143 -stairs:stair_outer_sandstone_block 195 191 142 -stairs:stair_outer_sandstonebrick 194 190 141 -stairs:stair_outer_silver_sandstone 195 192 181 -stairs:stair_outer_silver_sandstone_block 192 190 180 -stairs:stair_outer_silver_sandstone_brick 191 189 179 -stairs:stair_outer_snowblock 225 225 238 -stairs:stair_outer_steelblock 195 195 195 -stairs:stair_outer_stone 97 94 93 -stairs:stair_outer_stone_block 100 97 96 -stairs:stair_outer_stonebrick 102 99 98 -stairs:stair_outer_straw 212 184 68 -stairs:stair_outer_tinblock 150 150 150 -stairs:stair_outer_wood 131 102 57 -stairs:stair_pine_wood 221 185 130 -stairs:stair_sandstone 198 193 143 -stairs:stair_sandstone_block 195 191 142 -stairs:stair_sandstonebrick 194 190 141 -stairs:stair_silver_sandstone 195 192 181 -stairs:stair_silver_sandstone_block 192 190 180 -stairs:stair_silver_sandstone_brick 191 189 179 -stairs:stair_snowblock 225 225 238 -stairs:stair_steelblock 195 195 195 -stairs:stair_stone 97 94 93 -stairs:stair_stone_block 100 97 96 -stairs:stair_stonebrick 102 99 98 -stairs:stair_straw 212 184 68 -stairs:stair_tinblock 150 150 150 -stairs:stair_wood 131 102 57 - -# tnt -tnt:gunpowder 12 12 12 -tnt:gunpowder_burning 156 143 7 -tnt:tnt 196 0 0 -tnt:tnt_burning 201 41 0 - -# vessels -vessels:drinking_glass 207 214 228 -vessels:glass_bottle 189 192 204 -vessels:shelf 131 102 57 -vessels:steel_bottle 194 193 193 - -# walls -walls:cobble 89 86 84 -walls:desertcobble 110 67 50 -walls:mossycobble 88 91 73 - -# wool -wool:black 30 30 30 -wool:blue 0 73 146 -wool:brown 88 44 0 -wool:cyan 0 132 140 -wool:dark_green 33 103 0 -wool:dark_grey 60 60 60 -wool:green 93 218 28 -wool:grey 133 133 133 -wool:magenta 201 3 112 -wool:orange 214 83 22 -wool:pink 255 133 133 -wool:red 170 18 18 -wool:violet 93 5 169 -wool:white 220 220 220 -wool:yellow 254 226 16 - -# xpanes -xpanes:bar 114 114 114 64 16 -xpanes:bar_flat 114 114 114 64 16 -xpanes:door_steel_bar_a 133 133 133 64 16 -xpanes:door_steel_bar_b 133 133 133 64 16 -xpanes:door_steel_bar_c 133 133 133 64 16 -xpanes:door_steel_bar_d 133 133 133 64 16 -xpanes:obsidian_pane 16 17 18 64 16 -xpanes:obsidian_pane_flat 16 17 18 64 16 -xpanes:pane 249 249 249 64 16 -xpanes:pane_flat 249 249 249 64 16 -xpanes:trapdoor_steel_bar 127 127 127 64 16 -xpanes:trapdoor_steel_bar_open 77 77 77 64 16 - # animalworld animalworld:animalworld_tundrashrub1 102 128 102 animalworld:animalworld_tundrashrub2 95 120 95 @@ -463,9 +5,34 @@ animalworld:animalworld_tundrashrub3 110 135 110 animalworld:animalworld_tundrashrub4 100 125 100 animalworld:animalworld_tundrashrub5 115 140 115 animalworld:anthill 139 115 85 # Earthy brown +animalworld:beaver_nest 120 90 60 # Muddy brown for beaver nest animalworld:termitemould 160 130 100 # Lighter earthy brown animalworld:waspnest 210 180 140 # Papery light brown/yellowish +# anvil +anvil:anvil 80 80 85 # Dark iron/steel color + +# bakedclay +bakedclay:brown 139 76 57 # Terracotta Brown +bakedclay:grey 130 130 130 # Clay Grey +bakedclay:orange 198 112 56 # Terracotta Orange +bakedclay:red 161 63 45 # Terracotta Red + +# bank_accounts +bank_accounts:atm 110 115 120 # Metallic grey for ATM +bank_accounts:pin_terminal 60 60 65 # Dark plastic/metal grey +bank_accounts:teller_computer 200 200 210 # Light grey computer case +bank_accounts:wtm 110 115 120 # Metallic grey + +# banisters +banisters:desertstone_basic_diagonal_left 130 79 61 # Match default:desert_stone +banisters:desertstone_basic_diagonal_right 130 79 61 # Match default:desert_stone +banisters:desertstone_fancy_horizontal 130 79 61 # Match default:desert_stone + +# bathfurniture +bathfurniture:sink 230 230 235 # White ceramic +bathfurniture:taps 190 190 195 # Chrome/steel color + # beautiflowers beautiflowers:ada 255 105 180 # Hot Pink beautiflowers:agnes 255 20 147 # Deep Pink @@ -567,58 +134,521 @@ beautiflowers:xena 255 165 0 # Orange beautiflowers:xenia 173 216 230 # Light Blue beautiflowers:zaida 255 182 193 # Light Pink +# beds +beds:bed_bottom 130 3 3 +beds:bed_top 185 162 163 +beds:fancy_bed_bottom 136 49 28 +beds:fancy_bed_top 179 153 148 + +# bones +bones:bones 117 117 117 + # butterflies butterflies:butterfly_red 255 0 0 # Red butterflies:butterfly_violet 138 43 226 # Violet butterflies:butterfly_white 255 250 250 # White +butterflies:hidden_butterfly_red 220 20 20 # Darker Red for hidden +butterflies:hidden_butterfly_violet 110 35 200 # Darker Violet for hidden +butterflies:hidden_butterfly_white 220 220 220 # Ein sehr helles Grau, fast weiß, für einen "versteckten" weißen Schmetterling + +# carpet +carpet:wool_black 30 30 30 +carpet:wool_blue 0 0 205 +carpet:wool_brown 139 69 19 +carpet:wool_cyan 0 255 255 +carpet:wool_dark_green 0 100 0 +carpet:wool_dark_grey 70 70 70 +carpet:wool_green 0 128 0 +carpet:wool_grey 128 128 128 +carpet:wool_magenta 255 0 255 +carpet:wool_orange 255 165 0 +carpet:wool_pink 255 192 203 +carpet:wool_red 255 0 0 +carpet:wool_violet 138 43 226 +carpet:wool_white 250 250 250 + +# carts +carts:brakerail 150 121 102 +carts:powerrail 160 145 102 +carts:rail 146 128 108 + +# castle_gates +castle_gates:steel_gate_hinge 170 170 180 # Stahlgrau +castle_gates:steel_gate_panel 170 170 180 # Stahlgrau +castle_gates:steel_portcullis_bars 170 170 180 # Stahlgrau für Gitterstäbe +castle_gates:steel_portcullis_bars_bottom 160 160 170 # Etwas dunkleres Stahlgrau für den unteren Teil +castle_gates:stonebrick_gate_slot 120 120 120 # Steinziegelgrau +castle_gates:stonebrick_gate_slot_reverse 120 120 120 # Steinziegelgrau +castle_gates:wood_gate_edge 139 90 43 # Allgemeines Holzbraun +castle_gates:wood_gate_edge_handle 120 70 30 # Dunkleres Holzbraun für den Griff + +# caverealms +caverealms:stone_with_algae 85 95 80 # Mossy-green stone + +# crops +crops:melon_plant_4 132 231 112 # Pale green for melon plant +crops:melon_plant_5 118 205 98 # Riper green for melon plant +crops:pumpkin_plant_4 245 150 20 # Orangey green for pumpkin plant + +# currency +currency:barter 160 140 110 # Generic stand/wood color + +# default +default:acacia_bush_leaves 109 133 87 +default:acacia_bush_sapling 85 121 61 +default:acacia_bush_stem 84 77 70 +default:acacia_leaves 126 153 101 +default:acacia_sapling 87 120 64 +default:acacia_tree 195 119 97 +default:acacia_wood 150 61 39 +default:apple 161 34 19 +default:aspen_leaves 72 105 29 +default:aspen_sapling 85 123 45 +default:aspen_tree 218 198 168 +default:aspen_wood 210 199 170 +default:blueberry_bush_leaves 63 99 22 +default:blueberry_bush_leaves_with_berries 63 99 22 +default:blueberry_bush_sapling 81 112 33 +default:bookshelf 131 102 57 +default:brick 123 99 95 +default:bronzeblock 186 111 15 +default:bush_leaves 35 55 29 +default:bush_sapling 66 64 40 +default:bush_stem 46 34 24 +default:cactus 70 119 52 +default:cave_ice 168 206 247 +default:chest 149 115 69 +default:chest_locked 149 115 69 +default:chest_locked_open 149 115 69 +default:chest_open 149 115 69 +default:clay 183 183 183 +default:cloud 255 255 255 +default:coalblock 58 58 58 +default:cobble 89 86 84 +default:copperblock 193 126 65 +default:coral_brown 146 113 77 +default:coral_cyan 235 230 215 +default:coral_green 235 230 215 +default:coral_orange 197 68 17 +default:coral_pink 235 230 215 +default:coral_skeleton 235 230 215 +default:desert_cobble 110 67 50 +default:desert_sand 206 165 98 +default:desert_sandstone 195 152 92 +default:desert_sandstone_block 193 152 94 +default:desert_sandstone_brick 191 151 95 +default:desert_stone 130 79 61 +default:desert_stone_block 131 80 61 +default:desert_stonebrick 131 80 61 +default:diamondblock 140 218 223 +default:dirt 97 67 43 +default:dirt_with_coniferous_litter 109 90 71 +default:dirt_with_dry_grass 187 148 78 +default:dirt_with_grass 64 111 26 +default:dirt_with_grass_footsteps 64 111 26 +default:dirt_with_rainforest_litter 76 39 10 +default:dirt_with_snow 225 225 238 +default:dry_dirt 178 136 90 +default:dry_dirt_with_dry_grass 187 148 78 +default:dry_grass_1 208 172 87 +default:dry_grass_2 210 174 87 +default:dry_grass_3 210 174 87 +default:dry_grass_4 211 175 88 +default:dry_grass_5 214 178 92 +default:dry_shrub 103 67 18 +default:emergent_jungle_sapling 51 40 16 +default:fence_acacia_wood 151 62 39 +default:fence_aspen_wood 210 199 170 +default:fence_junglewood 57 39 14 +default:fence_pine_wood 221 185 131 +default:fence_pine_wood_end 221 185 131 # Match pine wood +default:fence_rail_acacia_wood 150 61 39 +default:fence_rail_aspen_wood 209 198 170 +default:fence_rail_junglewood 56 39 14 +default:fence_rail_pine_wood 221 184 130 +default:fence_rail_wood 131 102 57 +default:fence_wood 132 103 57 +default:fern_1 85 118 51 +default:fern_2 90 123 53 +default:fern_3 91 125 54 +default:furnace 101 98 96 +default:furnace_active 101 98 96 +default:glass 247 247 247 64 16 +default:goldblock 231 203 35 +default:grass_1 100 140 54 +default:grass_2 98 139 55 +default:grass_3 94 136 53 +default:grass_4 89 133 48 +default:grass_5 86 126 48 +default:gravel 132 132 132 +default:ice 168 206 247 +default:junglegrass 67 110 28 +default:jungleleaves 22 31 16 +default:junglesapling 51 39 15 +default:jungletree 121 97 62 +default:junglewood 56 39 14 +default:ladder_steel 132 132 132 +default:ladder_wood 125 93 43 +default:large_cactus_seedling 67 107 52 +default:lava_flowing 255 100 0 +default:lava_source 255 100 0 +default:leaves 36 55 29 +default:marram_grass_1 113 139 96 +default:marram_grass_2 102 131 90 +default:marram_grass_3 99 130 88 +default:mese 222 222 0 +default:mese_post_light 132 103 57 +default:mese_post_light_acacia_wood 151 62 39 +default:mese_post_light_aspen_wood 210 199 170 +default:mese_post_light_junglewood 57 39 14 +default:mese_post_light_pine_wood 221 185 131 +default:meselamp 213 215 143 +default:mossycobble 88 91 73 +default:obsidian 21 24 29 +default:obsidian_block 23 25 30 +default:obsidian_glass 20 23 27 64 16 +default:obsidianbrick 23 25 29 +default:papyrus 97 134 38 +default:permafrost 71 66 61 +default:permafrost_with_moss 108 150 51 +default:permafrost_with_stones 71 66 61 +default:pine_bush_needles 16 50 19 +default:pine_bush_sapling 58 51 40 +default:pine_bush_stem 73 62 53 +default:pine_needles 16 50 19 +default:pine_sapling 41 48 26 +default:pine_tree 191 165 132 +default:pine_wood 221 185 130 +default:river_water_flowing 39 66 106 128 224 +default:river_water_source 39 66 106 128 224 +default:sand 214 207 158 +default:sand_with_kelp 214 207 158 +default:sandstone 198 193 143 +default:sandstone_block 195 191 142 +default:sandstonebrick 194 190 141 +default:sapling 67 63 41 +default:sign_wall_steel 147 147 147 +default:sign_wall_wood 148 103 66 +default:silver_sand 193 191 179 +default:silver_sandstone 195 192 181 +default:silver_sandstone_block 192 190 180 +default:silver_sandstone_brick 191 189 179 +default:snow 225 225 238 +default:snowblock 225 225 238 +default:steelblock 195 195 195 +default:stone 97 94 93 +default:stone_block 100 97 96 +default:stone_with_coal 77 75 74 # Stein mit einem deutlichen Graustich von Kohle (dunkler) +default:stone_with_copper 128 102 86 # Stein mit einem bräunlich-orangen Kupferstich +default:stone_with_diamond 119 135 142 # Stein mit einem hellen, leicht bläulichen Diamantstich +default:stone_with_gold 144 130 80 # Stein mit einem gelblichen Goldstich +default:stone_with_iron 119 96 86 # Stein mit einem rostbraunen/gräulichen Eisenstich +default:stone_with_mese 144 120 71 # Stein mit einem kräftigen orangegelben Mesestich +default:stone_with_tin 125 126 128 +default:stonebrick 102 99 98 +default:tinblock 150 150 150 +default:torch 141 123 93 +default:torch_ceiling 141 123 93 +default:torch_wall 141 123 93 +default:tree 179 145 99 +default:water_flowing 39 66 106 128 224 +default:water_source 39 66 106 128 224 +default:wood 131 102 57 # doors +doors:door_glass_a 245 245 245 64 16 +doors:door_glass_b 245 245 245 64 16 +doors:door_glass_c 245 245 245 64 16 +doors:door_glass_d 245 245 245 64 16 +doors:door_obsidian_glass_a 48 49 50 64 16 +doors:door_obsidian_glass_b 48 49 50 64 16 +doors:door_obsidian_glass_c 48 49 50 64 16 +doors:door_obsidian_glass_d 48 49 50 64 16 +doors:door_phiwari_a 139 69 19 # Generic wood color +doors:door_steel_a 203 203 203 +doors:door_steel_b 203 203 203 +doors:door_steel_c 203 203 203 +doors:door_steel_d 203 203 203 +doors:door_wood_a 89 68 37 +doors:door_wood_b 89 68 37 +doors:door_wood_c 89 68 37 +doors:door_wood_d 89 68 37 +doors:gate_acacia_wood_closed 150 61 39 +doors:gate_acacia_wood_open 150 61 39 +doors:gate_aspen_wood_closed 210 199 170 +doors:gate_aspen_wood_open 210 199 170 +doors:gate_junglewood_closed 56 39 14 +doors:gate_junglewood_open 56 39 14 +doors:gate_pine_wood_closed 221 185 130 +doors:gate_pine_wood_open 221 185 130 +doors:gate_wood_closed 131 102 57 +doors:gate_wood_open 131 102 57 doors:hidden 192 192 192 # Light Grey (for hidden things, to be inconspicuous) +doors:trapdoor 130 100 51 +doors:trapdoor_oak 200 160 100 # Oak wood color +doors:trapdoor_oak_open 160 128 80 # Darker oak for open trapdoor +doors:trapdoor_open 68 53 30 +doors:trapdoor_steel 200 200 200 +doors:trapdoor_steel_open 97 97 97 # drawers drawers:pine_wood1 222 184 135 # BurlyWood (Pine color) drawers:pine_wood2 210 180 140 # Tan (Slightly different Pine color) +drawers:wood4 131 102 57 # Generic wood color # ethereal +ethereal:bamboo 140 180 80 # Bamboo green +ethereal:bamboo_dirt 97 67 43 # Same as default:dirt +ethereal:bamboo_leaves 100 160 60 # Bamboo leafy green +ethereal:banana 255 220 50 # Banana yellow +ethereal:bananaleaves 80 140 30 # Large tropical leaves +ethereal:banana_trunk 120 100 70 # Banana tree trunk color +ethereal:basandra_bush_leaves 70 110 30 # Generic bush leaves +ethereal:basandra_bush_stem 84 77 70 # Generic stem color +ethereal:birch_leaves 150 170 100 # Birch leaf green +ethereal:birch_trunk 225 220 210 # Light birch trunk +ethereal:blue_marble 120 140 180 # Bluish marble +ethereal:bush 55 90 40 # Darker bush green +ethereal:bush2 65 100 50 # Lighter bush green +ethereal:coconut 90 70 50 # Coconut brown +ethereal:cold_dirt 110 100 95 # Greyish cold dirt +ethereal:coral2_rooted 235 230 215 # Same as default coral +ethereal:coral3_rooted 197 68 17 # Same as default coral +ethereal:coral4_rooted 146 113 77 # Same as default coral +ethereal:coral5_rooted 235 230 215 # Same as default coral +ethereal:crystal_dirt 120 115 130 # Purplish dirt +ethereal:crystalgrass 180 220 255 # Light glowing blue-green +ethereal:crystal_spike 200 240 255 48 12 # Translucent light blue +ethereal:dry_dirt 178 136 90 # Same as default:dry_dirt +ethereal:dry_shrub 103 67 18 # Same as default:dry_shrub +ethereal:etherium_ore 180 170 220 # Light purple ore +ethereal:fern 85 118 51 # Generic fern green +ethereal:fiery_dirt 140 80 60 # Reddish, warm dirt +ethereal:frost_leaves 190 240 255 # Icy light blue leaves +ethereal:frost_tree 210 230 240 # Icy white trunk +ethereal:gray_dirt 120 120 120 # Grey dirt +ethereal:grove_dirt 80 60 40 # Dark, rich dirt +ethereal:lemon 250 250 100 # Lemon yellow +ethereal:lemon_leaves 100 150 50 # Lemon tree leaves +ethereal:lightstring 220 220 220 # Neutral color for the string +ethereal:lilac 200 162 200 # Lilac purple +ethereal:mushroom 195 102 102 # Same as flowers:mushroom_red +ethereal:mushroom_brown 109 84 78 # Same as flowers:mushroom_brown +ethereal:mushroom_dirt 85 75 80 # Fungal dirt +ethereal:mushroom_pore 210 200 190 # Mushroom pore color +ethereal:mushroom_trunk 190 180 170 # Mushroom stem/trunk +ethereal:olive 128 128 0 # Olive green +ethereal:olive_leaves 100 130 80 # Olive tree leaves +ethereal:olive_trunk 110 95 70 # Olive trunk +ethereal:onion_4 240 230 210 # Ripe onion +ethereal:orange 255 165 0 # Orange fruit +ethereal:orange_leaves 90 140 40 # Orange tree leaves +ethereal:palm_trunk 140 110 80 # Palm trunk +ethereal:palmleaves 80 130 30 # Palm leaves +ethereal:pond 60 90 120 # Murky pond water 128 224 +ethereal:prairie_dirt 130 100 60 # Prairie dirt color +ethereal:quicksand2 196 168 123 # Quicksand color +ethereal:redwood_leaves 40 80 30 # Dark redwood leaves +ethereal:redwood_trunk 90 50 40 # Redwood trunk +ethereal:sakura_leaves 255 182 193 # Pink sakura leaves +ethereal:sakura_trunk 120 100 90 # Sakura tree trunk +ethereal:sandy 214 207 158 # Sandy dirt, same as default sand +ethereal:scorched_tree 60 55 50 # Blackened, scorched wood +ethereal:seaweed_rooted 40 100 45 # Seaweed green +ethereal:slime_mold 120 150 80 # Slimy green/yellow +ethereal:snowygrass 200 230 210 # Grass with snow hints +ethereal:sponge_wet 220 210 130 # Wet sponge yellow +ethereal:spore_grass 130 120 140 # Fungal purple grass ethereal:strawberry_7 255 0 0 # Red (ripe strawberry) +ethereal:thin_ice 190 220 250 48 12 # Translucent ice +ethereal:vine 60 110 25 # Green vine +ethereal:willow_trunk 100 90 80 # Willow trunk color +ethereal:willow_twig 80 70 60 # Thin willow twig + +# fachwerk +fachwerk:cobble 89 86 84 # Match default:cobble +fachwerk:cobble_cross 89 86 84 # Match default:cobble +fachwerk:stone 97 94 93 # Match default:stone + +# fake_fire +fake_fire:chimney_desert_stone 130 79 61 # Match default:desert_stone +fake_fire:chimney_sandstone_d 198 193 143 # Match default:sandstone +fake_fire:chimney_stone_d 97 94 93 # Match default:stone +fake_fire:embers 255 100 0 # Tiefes, glühendes Orange für Glut +fake_fire:fake_stable_fire 255 100 0 # Same as embers # farming +farming:artichoke_4 110 140 100 # Artichoke green farming:asparagus_4 143 188 143 # Dark Sea Green (Asparagus spears) farming:beanbush 50 150 50 # Green (Bean plant leaves) +farming:beanpole_5 139 69 19 # Brown pole, match saddle brown farming:beetroot_5 139 0 0 # Dark Red (Beetroot) +farming:blackberry_1 80 90 30 # Unripe blackberry bush farming:blackberry_4 40 0 50 # Dark Purple/Black (Blackberry) farming:blueberry_4 70 0 130 # Indigo (Blueberry) farming:cabbage_6 127 255 0 # Chartreuse (Cabbage green) farming:carrot_7 255 140 0 # Dark Orange (Carrot) +farming:cocoa_2 110 140 50 # Cocoa plant stage +farming:cocoa_3 90 120 40 # Cocoa plant stage +farming:cocoa_4 180 110 60 # Ripe cocoa pod farming:coffee_5 0 100 0 # Dark Green (Coffee plant) farming:corn_7 154 205 50 # YellowGreen (Corn plant, some yellow) +farming:cotton_1 89 117 39 +farming:cotton_2 89 116 38 +farming:cotton_3 99 121 41 +farming:cotton_4 108 114 47 +farming:cotton_5 116 105 53 +farming:cotton_6 121 95 59 +farming:cotton_7 94 70 37 +farming:cotton_8 122 108 93 +farming:cotton_wild 111 111 101 farming:cucumber_4 0 128 0 # Green (Cucumber) +farming:desert_sand_soil 161 132 72 +farming:desert_sand_soil_wet 120 99 53 +farming:dry_soil 178 136 90 +farming:dry_soil_wet 178 136 90 farming:eggplant_3 75 0 130 # Indigo (Eggplant purple) +farming:garlic_5 245 245 230 # Off-white garlic farming:ginger_3 210 180 140 # Tan (Ginger root) farming:grapebush 60 80 20 # Dark Green (Grape leaves) +farming:hemp_7 70 110 60 # Hemp plant green farming:lettuce_5 144 238 144 # Light Green (Lettuce) farming:melon_8 152 251 152 # Pale Green (Melon rind) farming:mint_4 60 179 113 # Medium Sea Green (Mint leaves) +farming:oat_8 210 190 120 # Oat color farming:onion_5 255 224 180 # Light Brown/Yellow (Onion skin) farming:parsley_3 34 139 34 # Forest Green (Parsley) farming:pea_5 0 128 0 # Green (Pea pod/plant) +farming:pepper_6 200 30 30 # Red pepper farming:pineapple_8 255 215 0 # Gold (Pineapple body) farming:potato_3 139 69 19 # Saddle Brown (Potato) farming:pumpkin_8 255 165 0 # Orange (Pumpkin) farming:raspberry_4 227 23 67 # Raspberry Red farming:rhubarb_3 220 20 60 # Crimson (Rhubarb stalks) +farming:salt_crystal 240 240 250 # Off-white salt +farming:seed_cotton 92 87 60 +farming:seed_wheat 177 161 96 +farming:soil 97 67 43 +farming:soil_wet 97 67 43 farming:soy_6 107 142 35 # Olive Drab (Soy plant) farming:spinach_3 0 100 0 # Dark Green (Spinach) +farming:straw 212 184 68 farming:sunflower_8 255 215 0 # Gold (Sunflower petals) farming:tomato_7 255 0 0 # Red (Tomato) farming:vanilla_7 143 188 143 # Dark Sea Green (Vanilla plant/bean pod) +farming:weed 80 100 40 # Generic weed green +farming:wheat_1 110 175 36 +farming:wheat_2 136 177 53 +farming:wheat_3 163 182 84 +farming:wheat_4 170 188 95 +farming:wheat_5 171 179 97 +farming:wheat_6 173 177 87 +farming:wheat_7 193 181 83 +farming:wheat_8 187 162 40 + +# fire +fire:basic_flame 223 136 44 +fire:permanent_flame 223 136 44 # fireflies +fireflies:firefly 220 255 100 # Helles, gelb-grünliches Leuchten für Glühwürmchen +fireflies:firefly_bottle 191 194 202 fireflies:hidden_firefly 40 40 40 # Dark Grey (for hidden, night context) +# flowerbeds +flowerbeds:basic_wood 131 102 57 # Match default:wood + +# flowerpot +flowerpot:beautiflowers_agnes 255 20 147 # Match flower color +flowerpot:beautiflowers_bonsai_1 34 139 34 # Match flower color +flowerpot:beautiflowers_erica 255 182 193 # Match flower color +flowerpot:beautiflowers_gloria 255 182 193 # Match flower color +flowerpot:beautiflowers_ivette 238 130 238 # Match flower color +flowerpot:beautiflowers_lucia 218 112 214 # Match flower color +flowerpot:beautiflowers_nerea 255 20 147 # Match flower color +flowerpot:beautiflowers_pasto_4 60 179 113 # Match flower color +flowerpot:default_papyrus 97 134 38 # Match plant color +flowerpot:flowers_geranium 77 91 168 # Match flower color +flowerpot:flowers_tulip 156 101 44 # Match flower color + +# flowers +flowers:chrysanthemum_green 118 152 44 +flowers:dandelion_white 199 191 176 +flowers:dandelion_yellow 212 167 31 +flowers:geranium 77 91 168 +flowers:mushroom_brown 109 84 78 +flowers:mushroom_red 195 102 102 +flowers:rose 130 68 33 +flowers:tulip 156 101 44 +flowers:tulip_black 78 120 72 +flowers:viola 115 69 184 +flowers:waterlily 107 160 68 +flowers:waterlily_waving 107 160 68 + # gates_long +gates_long:fence_gate_closed_acacia 205 92 92 # Rötlich-oranges Akazienholz +gates_long:fence_gate_closed_junglewood 139 76 57 # Sattes Dschungelholzbraun +gates_long:fence_gate_closed_pine 222 184 135 # Helles Kiefernholz +gates_long:fence_gate_closed_tree 160 82 45 # Standard Holzfarbe (wie default wood) gates_long:fence_gate_closed_wood 160 82 45 # Sienna (Wood color) +# generic_flags +generic_flags:lower_mast 140 110 80 # Wooden mast color +generic_flags:upper_mast 140 110 80 # Wooden mast color +generic_flags:upper_mast_hidden_1 140 110 80 # Wooden mast color + +# irrigation +irrigation:water_barrel_holding_3 131 102 57 # Wood color for barrel +irrigation:well 97 94 93 # Stone color for well + +# itemshelf +itemshelf:large_shelf 131 102 57 # Wood color for shelf + +# laptop +laptop:bell_crossover_on 195 195 195 # Steel color +laptop:printer_on 220 220 225 # Off-white plastic for printer + +# lrfurn +lrfurn:armchair_green 33 103 0 # Match wool:dark_green + +# mailbox +mailbox:letterbox 200 30 30 # Red postbox color +mailbox:mailbox 200 30 30 # Red postbox color + +# ma_pops_furniture +ma_pops_furniture:bath_faucet 200 200 200 # Chrome/steel color +ma_pops_furniture:blinds 230 230 220 # Off-white blinds +ma_pops_furniture:chair_junglewood 56 39 14 # Match default:junglewood +ma_pops_furniture:coffee_maker 50 50 50 # Black coffee maker +ma_pops_furniture:counter1_dark_green 33 103 0 # Match wool:dark_green +ma_pops_furniture:counter2_dark_green 33 103 0 # Match wool:dark_green +ma_pops_furniture:counter3_black 30 30 30 # Match wool:black +ma_pops_furniture:counter3_dark_green 33 103 0 # Match wool:dark_green +ma_pops_furniture:curtains_2_tall_dark_green 33 103 0 # Match wool:dark_green +ma_pops_furniture:curtains_dark_green 33 103 0 # Match wool:dark_green +ma_pops_furniture:doorbell 210 200 180 # Light plastic doorbell +ma_pops_furniture:fan_on 220 220 220 # White fan +ma_pops_furniture:fridge_top_white 235 235 235 # White appliance +ma_pops_furniture:fridge_white 235 235 235 # White appliance +ma_pops_furniture:jOyBoX_cart 255 0 0 # Red plastic cart +ma_pops_furniture:microwave 230 230 230 # White microwave +ma_pops_furniture:oven 90 90 90 # Dark grey oven +ma_pops_furniture:sink_black 40 40 40 # Black sink +ma_pops_furniture:stereo 50 50 50 # Black stereo +ma_pops_furniture:stone_path_1 120 120 120 # Stone path tile +ma_pops_furniture:stone_path_2 110 110 110 # Stone path tile +ma_pops_furniture:stone_path_3 130 130 130 # Stone path tile +ma_pops_furniture:stone_path_4 125 125 125 # Stone path tile +ma_pops_furniture:table_c_junglewood 56 39 14 # Match default:junglewood +ma_pops_furniture:table_center_junglewood 56 39 14 # Match default:junglewood +ma_pops_furniture:table_junglewood 56 39 14 # Match default:junglewood +ma_pops_furniture:toilet_close 240 240 245 # White ceramic toilet +ma_pops_furniture:toilet_paper_roll_dispenser 210 210 210 # Light grey plastic +ma_pops_furniture:tv_cube 50 50 50 # Black TV +ma_pops_furniture:tv_off 30 30 30 # Black screen +ma_pops_furniture:tv_rainbow 255 0 255 # Magenta to represent rainbow +ma_pops_furniture:upcabinet_black 30 30 30 # Black cabinet + # marinara marinara:coastrock 169 169 169 # Dark Gray (Coast rock) marinara:coastrock_alage 102 139 102 # Grayish Green (Rock with algae) @@ -628,9 +658,15 @@ marinara:hardcoral_blue 100 149 237 # Cornflower Blue marinara:hardcoral_brown 160 82 45 # Sienna marinara:hardcoral_green 60 179 113 # Medium Sea Green marinara:hardcoral_pink 255 182 193 # Light Pink +marinara:hardcoral_red 220 40 40 # Ein kräftiges Rot für rote Hartkoralle marinara:hardcoral_yellow 255 255 102 # Light Yellow marinara:mussels 47 79 79 # Dark Slate Gray (Mussel shells) marinara:oisterbank 220 220 220 # Gainsboro (Oyster bank) +marinara:reed_root 100 80 60 # Dunkles, schlammiges Braun für Schilfwurzeln +marinara:sand_with_alage 175 193 140 # Sandfarbe mit einem deutlichen Grünstich durch Algen +marinara:sand_with_kelp 171 185 144 # Sandfarbe mit einem dunkleren Grün/Braun-Ton von Kelp +marinara:sand_with_seagrass 183 205 148 # Sandfarbe mit hellem Seegrasgrün +marinara:sand_with_seagrass2 191 209 156 # Eine leicht variierende Seegras-Sand-Farbe marinara:sand_with_seashells 238 221 180 # Light Sand with whitish hint marinara:sand_with_seashells_broken 220 200 160 # Sand color marinara:sand_with_seashells_brown 210 190 150 # Brownish Sand @@ -638,33 +674,270 @@ marinara:sand_with_seashells_orange 240 200 150 # Orangey Sand marinara:sand_with_seashells_pink 240 210 200 # Pinkish Sand marinara:sand_with_seashells_white 245 235 215 # Very Light Sand marinara:sand_with_seashells_yellow 240 230 180 # Yellowish Sand -marinara:seaanemone_tentacle3 255 127 80 # Coral (Anemone color) -marinara:seapocks 240 240 240 # Whitish Grey (Sea Pocks/Barnacles) -marinara:seaworm2 255 170 170 # Light Fleshy Pink (Seaworm) -marinara:seaworm3 240 160 160 # Darker Fleshy Pink (Seaworm) -marinara:softcoral_white 250 250 250 # White -marinara:softcoral_yellow 255 255 224 # Light Yellow -marinara:hardcoral_red 220 40 40 # Ein kräftiges Rot für rote Hartkoralle -marinara:reed_root 100 80 60 # Dunkles, schlammiges Braun für Schilfwurzeln -marinara:sand_with_alage 175 193 140 # Sandfarbe mit einem deutlichen Grünstich durch Algen -marinara:sand_with_kelp 171 185 144 # Sandfarbe mit einem dunkleren Grün/Braun-Ton von Kelp -marinara:sand_with_seagrass 183 205 148 # Sandfarbe mit hellem Seegrasgrün -marinara:sand_with_seagrass2 191 209 156 # Eine leicht variierende Seegras-Sand-Farbe marinara:seaanemone_tentacle 255 182 193 # Helles Rosa für Seeanemonen-Tentakel marinara:seaanemone_tentacle2 173 216 230 # Helles Blau für Seeanemonen-Tentakel +marinara:seaanemone_tentacle3 255 127 80 # Coral (Anemone color) marinara:seaanemone_tentacle4 255 255 150 # Blasses Gelb für Seeanemonen-Tentakel -marinara:seaworm 230 150 140 # Ein fleischiges Rosa/Braun für Seewürmer -marinara:softcoral 255 240 220 # Cremefarben/hellbeige für generische Weichkoralle +marinara:seapocks 240 240 240 # Whitish Grey (Sea Pocks/Barnacles) +marinara:seaworm 230 150 140 # Ein fleischiges Rosa/Braun für Seewürmer +marinara:seaworm2 255 170 170 # Light Fleshy Pink (Seaworm) +marinara:seaworm3 240 160 160 # Darker Fleshy Pink (Seaworm) +marinara:softcoral 255 240 220 # Cremefarben/hellbeige für generische Weichkoralle marinara:softcoral_brown 160 120 80 # Ein gedämpftes Braun für braune Weichkoralle marinara:softcoral_green 140 190 150 # Ein blasses Meerschaumgrün für grüne Weichkoralle marinara:softcoral_red 240 100 100 # Ein gedämpftes Rot für rote Weichkoralle +marinara:softcoral_white 250 250 250 # White +marinara:softcoral_yellow 255 255 224 # Light Yellow # markers markers:stone 128 128 128 # Grey (Stone marker) +# mesecons_lightstone +mesecons_lightstone:lightstone_cyan_off 0 100 100 # Dark cyan off state +mesecons_lightstone:lightstone_cyan_on 0 255 255 # Bright cyan on state +mesecons_lightstone:lightstone_darkgray_off 50 50 50 # Dark grey off state + # moreblocks +moreblocks:all_faces_tree 101 67 33 # Rindenbraun +moreblocks:cactus_brick 120 150 100 # Gedämpftes Kaktusgrün für Ziegel +moreblocks:circle_stone_bricks 115 115 115 # Kreissteinziegel, ähnlich Steinziegelgrau +moreblocks:clean_glass 250 250 250 64 16 # Clean glass +moreblocks:coal_stone 50 50 50 # Sehr dunkles Grau, fast schwarz (Kohlegestein) +moreblocks:coal_stone_bricks 60 60 60 # Ziegel aus Kohlegestein, sehr dunkelgrau +moreblocks:cobble_compressed 110 110 110 # Verdichteter Bruchstein, etwas dunkler +moreblocks:desert_cobble_compressed 190 170 130 # Verdichteter Wüstenbruchstein, sandig-grau +moreblocks:dirt_compressed 100 70 50 # Verdichtete Erde, dunkleres Braun +moreblocks:grey_bricks 140 140 140 # Standard graue Ziegel +moreblocks:iron_stone 100 90 85 # Eisengestein, dunkel-metallisch mit Rosthauch +moreblocks:iron_stone_bricks 105 95 90 # Ziegel aus Eisengestein +moreblocks:slab_coal_stone_bricks 60 60 60 # Match coal stone bricks +moreblocks:slab_cobble 130 130 130 # Cobblestone Grey +moreblocks:slab_desert_stone_block 131 80 61 # Match desert stone block +moreblocks:slab_obsidian_glass_quarter 20 23 27 64 16 # Match obsidian glass +moreblocks:slab_silver_sandstone 195 192 181 # Match silver sandstone +moreblocks:slab_silver_sandstone_block 192 190 180 # Match silver sandstone block +moreblocks:slab_stonebrick 102 99 98 # Match stonebrick +moreblocks:slab_wood 131 102 57 # Match wood +moreblocks:slab_wood_quarter 131 102 57 # Match wood +moreblocks:slope_iron_stone 100 90 85 # Match iron stone +moreblocks:slope_iron_stone_inner_cut_half_raised 100 90 85 # Match iron stone +moreblocks:stair_aspen_wood 245 228 190 # Sehr helles, fast weißliches Gelb-Braun für Espenholz +moreblocks:stair_coal_stone_bricks 60 60 60 # Match coal stone bricks moreblocks:stair_cobble 130 130 130 # Cobblestone Grey -moreblocks:stair_aspen_wood 245 228 190 # Sehr helles, fast weißliches Gelb-Braun für Espenholz +moreblocks:stair_desert_cobble 110 67 50 # Match desert cobble +moreblocks:stair_desert_cobble_outer 110 67 50 # Match desert cobble +moreblocks:stair_desert_sandstone 195 152 92 # Match desert sandstone +moreblocks:stair_desert_stone 130 79 61 # Match desert stone +moreblocks:stair_sandstone 198 193 143 # Match sandstone + +# morelights_extras +morelights_extras:stairlight 255 255 200 # Light yellow light +morelights_extras:stone_block 100 97 96 # Standard Steinblockfarbe + +# morelights_modern +morelights_modern:barlight_c 240 240 240 # Light fixture color +morelights_modern:barlight_s 240 240 240 # Light fixture color +morelights_modern:block 245 245 245 # Light block +morelights_modern:canlight_d 180 180 180 # Grey can light +morelights_modern:pathlight_d 80 80 80 # Dark pathlight +morelights_modern:post_d 90 90 90 # Dark post +morelights_modern:tablelamp_d 200 200 200 # Grey tablelamp +morelights_modern:walllamp 210 210 210 # Light grey wall lamp + +# morelights_vintage +morelights_vintage:lantern_w 100 80 60 # Dark wood lantern + +# mydeck +mydeck:rail_corners_black 30 30 30 # Match black +mydeck:rail_corners_grey 133 133 133 # Match grey +mydeck:rails_black 30 30 30 # Match black +mydeck:rails_grey 133 133 133 # Match grey + +# myfurniture +myfurniture:pine_wood_shelf 221 185 130 # Match pine wood + +# myglass +myglass:myglass_bars 80 80 80 64 16 # Dark grey bars +myglass:myglass_black 30 30 30 100 16 # Black glass +myglass:myglass_grid 100 100 100 64 16 # Grey grid +myglass:window_plus_white 240 240 240 # White window frame + +# myroofs +myroofs:asphalt_shingle_dark_grey 70 70 75 # Dark grey asphalt +myroofs:asphalt_shingle_dark_grey_bundle 70 70 75 # Dark grey asphalt +myroofs:asphalt_shingle_dark_grey_icorner 70 70 75 # Dark grey asphalt +myroofs:asphalt_shingle_dark_grey_ocorner 70 70 75 # Dark grey asphalt +myroofs:asphalt_shingle_red_bundle 140 50 50 # Red shingle +myroofs:asphalt_shingle_red_long 140 50 50 # Red shingle +myroofs:asphalt_shingle_red_long_ocorner 140 50 50 # Red shingle + +# mysheetmetal +mysheetmetal:fascia 180 180 185 # Light metallic grey +mysheetmetal:fascia_L_L 180 180 185 # Light metallic grey +mysheetmetal:fascia_R_L 180 180 185 # Light metallic grey +mysheetmetal:fascia_R_U 180 180 185 # Light metallic grey + +# mysiding +mysiding:light_wide_corner_default_pine_wood 221 185 130 # Match pine wood +mysiding:light_wide_default_pine_wood 221 185 130 # Match pine wood +mysiding:wide_corner_default_stone 97 94 93 # Match stone +mysiding:wide_default_stone 97 94 93 # Match stone + +# mystreets +mystreets:asphalt 55 55 60 # Dark asphalt +mystreets:asphalt_center_dashed 55 55 60 # Dark asphalt +mystreets:asphalt_icorner 55 55 60 # Dark asphalt +mystreets:asphalt_ocorner 55 55 60 # Dark asphalt +mystreets:asphalt_parking 55 55 60 # Dark asphalt +mystreets:asphalt_side_dashed 55 55 60 # Dark asphalt +mystreets:asphalt_side_solid 55 55 60 # Dark asphalt +mystreets:asphalt_yellow_arrows 55 55 60 # Dark asphalt +mystreets:lead 90 90 100 # Lead grey +mystreets:lightpost 100 100 100 # Concrete post +mystreets:lightpost_l 100 100 100 # Concrete post +mystreets:manhole 80 80 80 # Iron manhole +mystreets:manhole_shaft 70 70 70 # Dark shaft +mystreets:nickel 200 200 210 # Nickel color +mystreets:pylon 255 100 0 # Orange pylon +mystreets:sidewalk 150 150 150 # Concrete sidewalk +mystreets:sign_pedestrian_crossing_post 110 110 110 # Metal sign post +mystreets:street_light 90 90 90 # Dark metal street light +mystreets:zinc 210 210 220 # Zinc color + +# myworkshop +myworkshop:bench_long 131 102 57 # Wood color +myworkshop:bench_long_right 131 102 57 # Wood color +myworkshop:bench_wood_top 131 102 57 # Wood color +myworkshop:pegboard 160 140 120 # Brown pegboard +myworkshop:stool 195 195 195 # Steel stool + +# naturalbiomes +naturalbiomes:acacia_leaves 126 153 101 # Match default:acacia_leaves +naturalbiomes:acacia_trapdoor 150 61 39 # Match default:acacia_wood +naturalbiomes:acacia_trunk 195 119 97 # Match default:acacia_tree +naturalbiomes:acacia_wood 150 61 39 # Match default:acacia_wood +naturalbiomes:alder_leaves 80 115 40 # Alder leaf green +naturalbiomes:alderswamp_brownreed 140 110 80 # Brown reed +naturalbiomes:alderswamp_dirt 80 60 45 # Swampy dirt +naturalbiomes:alderswamp_litter 70 50 35 # Swampy litter +naturalbiomes:alderswamp_reed 100 130 90 # Green reed +naturalbiomes:alderswamp_reed2 105 135 95 # Green reed +naturalbiomes:alderswamp_reed3 110 140 100 # Green reed +naturalbiomes:alderswamp_yellowflower 255 255 0 # Match yellow flower +naturalbiomes:alder_trunk 100 90 80 # Alder trunk +naturalbiomes:alpine_cowberrybush_leaves 70 100 60 # Alpine bush leaves +naturalbiomes:alpine_cowberrybush_stem 84 77 70 # Alpine stem +naturalbiomes:alpine_dandelion 212 167 31 # Match flower +naturalbiomes:alpine_edelweiss 245 245 240 # White Edelweiss +naturalbiomes:alpine_grass1 110 150 90 # Alpine grass +naturalbiomes:alpine_grass2 115 155 95 # Alpine grass +naturalbiomes:alpine_grass3 120 160 100 # Alpine grass +naturalbiomes:alpine_litter 100 90 70 # Alpine ground litter +naturalbiomes:alpine_mushroom 109 84 78 # Match mushroom +naturalbiomes:alpine_rock 140 140 145 # Grey alpine rock +naturalbiomes:alppine1_leaves 16 50 19 # Match pine_needles +naturalbiomes:alppine1_trunk 191 165 132 # Match pine_tree +naturalbiomes:alppine2_leaves 16 50 19 # Match pine_needles +naturalbiomes:alppine2_trunk 191 165 132 # Match pine_tree +naturalbiomes:bambooforest_groundgrass 80 120 60 # Bamboo forest grass +naturalbiomes:bambooforest_groundgrass2 85 125 65 # Bamboo forest grass +naturalbiomes:bambooforest_litter 75 90 60 # Bamboo forest litter +naturalbiomes:bambooforest_rock 110 115 110 # Mossy rock +naturalbiomes:bamboo_leaves 100 160 60 # Bamboo leafy green +naturalbiomes:bamboo_trunk 140 180 80 # Bamboo green +naturalbiomes:banana_bunch 255 220 50 # Banana yellow +naturalbiomes:banana_leaves 80 140 30 # Large tropical leaves +naturalbiomes:banana_sapling 80 140 30 # Banana leaf color +naturalbiomes:banana_trunk 120 100 70 # Banana tree trunk color +naturalbiomes:beach_bush_leaves 90 120 70 # Beach bush leaves +naturalbiomes:beach_bush_stem 90 80 70 # Beach bush stem +naturalbiomes:blackberry 40 0 50 # Ripe blackberry +naturalbiomes:bushland_blackberry_leaves 60 90 30 # Blackberry bush +naturalbiomes:bushland_blackberry_leaves2 65 95 35 # Blackberry bush +naturalbiomes:bushland_blackberry_stem 84 77 70 # Stem color +naturalbiomes:bushland_bushlandlitter 90 70 50 # Bushland litter +naturalbiomes:bushland_bushlandlitter2 95 75 55 # Bushland litter +naturalbiomes:bushland_bushlandlitter3 100 80 60 # Bushland litter +naturalbiomes:bushland_deadbush_leaves 140 110 80 # Dead leaves +naturalbiomes:bushland_grass 100 140 54 # Normal grass +naturalbiomes:bushland_grass2 98 139 55 # Normal grass +naturalbiomes:bushland_grass3 94 136 53 # Normal grass +naturalbiomes:bushland_grass4 89 133 48 # Normal grass +naturalbiomes:bushland_grass5 86 126 48 # Normal grass +naturalbiomes:bushland_grass6 80 120 45 # Normal grass +naturalbiomes:bushland_grass7 75 115 40 # Normal grass +naturalbiomes:bushland_hazelnutbush_sapling 81 112 33 # Sapling green +naturalbiomes:bushland_hazelnut_leaves 70 100 40 # Hazelnut leaves +naturalbiomes:bushland_hazelnut_leaves2 75 105 45 # Hazelnut leaves +naturalbiomes:bushland_hazelnut_stem 90 80 70 # Hazelnut stem +naturalbiomes:bushland_wildrose_leaves 70 100 40 # Rose leaves +naturalbiomes:bushland_wildrose_leaves2 75 105 45 # Rose leaves +naturalbiomes:bushland_wildrose_stem 90 80 70 # Rose stem +naturalbiomes:coconut 90 70 50 # Coconut brown +naturalbiomes:heath_birch_leaves 150 170 100 # Birch leaf green +naturalbiomes:heath_birch_trunk 225 220 210 # Light birch trunk +naturalbiomes:heatherflower 218 112 214 # Heather purple/orchid +naturalbiomes:heatherflower2 220 120 210 # Heather purple/orchid +naturalbiomes:heatherflower3 215 110 212 # Heather purple/orchid +naturalbiomes:heatherflower3node 218 112 214 # Heather purple/orchid +naturalbiomes:heatherflower4 210 100 200 # Heather purple/orchid +naturalbiomes:heatherflowernode 218 112 214 # Heather purple/orchid +naturalbiomes:heath_grass 130 150 90 # Heathland grass +naturalbiomes:heath_grass2 135 155 95 # Heathland grass +naturalbiomes:heath_grass3 140 160 100 # Heathland grass +naturalbiomes:heath_juniper_leaves 60 90 50 # Juniper leaves +naturalbiomes:heath_juniper_trunk 100 85 70 # Juniper trunk +naturalbiomes:heath_litter 120 100 70 # Heathland litter +naturalbiomes:heath_litter2 125 105 75 # Heathland litter +naturalbiomes:heath_litter3 130 110 80 # Heathland litter +naturalbiomes:heath_willow_leaves2 90 120 70 # Willow leaves +naturalbiomes:heath_willow_trunk 100 90 80 # Willow trunk +naturalbiomes:med_bush_leaves 80 110 60 # Mediterranean bush +naturalbiomes:med_bush_stem 95 85 75 # Mediterranean stem +naturalbiomes:med_flower2 255 105 180 # Pink flower +naturalbiomes:med_flower3 255 255 0 # Yellow flower +naturalbiomes:med_grass1 160 170 100 # Dry-ish grass +naturalbiomes:med_grass2 165 175 105 # Dry-ish grass +naturalbiomes:mediterran_litter 150 130 100 # Dry litter +naturalbiomes:mediterran_rock 160 150 140 # Light grey/tan rock +naturalbiomes:mediterran_ruin 150 140 130 # Ruin stone +naturalbiomes:mediterran_ruin2 145 135 125 # Ruin stone +naturalbiomes:olive_leaves 100 130 80 # Olive tree leaves +naturalbiomes:olives 100 100 0 # Ripe olive color +naturalbiomes:olive_sapling 100 130 80 # Olive leaf color +naturalbiomes:olive_trunk 110 95 70 # Olive trunk +naturalbiomes:outback_bush_leaves 130 120 80 # Dry outback leaves +naturalbiomes:outback_bush_stem 110 95 75 # Dry outback stem +naturalbiomes:outback_grass 187 148 78 # Dry grass color +naturalbiomes:outback_grass2 190 150 80 # Dry grass color +naturalbiomes:outback_grass3 185 145 75 # Dry grass color +naturalbiomes:outback_grass4 192 152 82 # Dry grass color +naturalbiomes:outback_grass5 188 149 79 # Dry grass color +naturalbiomes:outback_grass6 186 147 77 # Dry grass color +naturalbiomes:outback_ground 190 160 120 # Outback ground/dirt +naturalbiomes:outback_leaves 150 130 90 # Dry outback leaves +naturalbiomes:outback_litter 160 140 110 # Dry outback litter +naturalbiomes:outback_rock 170 140 110 # Reddish outback rock +naturalbiomes:outback_trunk 120 100 80 # Dry outback trunk +naturalbiomes:palmbeach_grass1 100 140 54 # Beach grass +naturalbiomes:palmbeach_grass2 98 139 55 # Beach grass +naturalbiomes:palmbeach_grass3 94 136 53 # Beach grass +naturalbiomes:palmbeach_rock 150 150 145 # Sandy rock +naturalbiomes:palmbeach_sand 220 213 164 # Beach sand +naturalbiomes:palm_leaves 80 130 30 # Palm leaves +naturalbiomes:palm_trunk 140 110 80 # Palm trunk +naturalbiomes:pine_leaves 16 50 19 # Match default:pine_needles +naturalbiomes:pine_trunk 191 165 132 # Match default:pine_tree +naturalbiomes:savanna_flowergrass 180 170 100 # Savanna grass with flowers +naturalbiomes:savannagrass 187 148 78 # Match default:dirt_with_dry_grass +naturalbiomes:savanna_grass2 190 150 80 # Dry grass +naturalbiomes:savanna_grass3 185 145 75 # Dry grass +naturalbiomes:savannagrasssmall 187 148 78 # Dry grass +naturalbiomes:savannalitter 160 130 90 # Savanna litter +naturalbiomes:smallbamboo 140 180 80 # Bamboo green +naturalbiomes:swampgrass 90 120 70 # Darker swamp grass +naturalbiomes:swampgrass2 95 125 75 # Darker swamp grass +naturalbiomes:waterlily 107 160 68 # Match flowers:waterlily # nether nether:airlike_darkness 10 10 10 # Very Dark Grey / Near Black @@ -684,26 +957,256 @@ nether:rack_deep 100 40 40 # Darker Netherrack nether:sand 80 65 60 # Soul Sand Brownish Grey # ontime_clocks +ontime_clocks:frameless_black 30 30 30 # Match black ontime_clocks:frameless_gold 255 215 0 # Gold ontime_clocks:green_digital 0 255 0 # Bright Green (Digital LED) ontime_clocks:white 250 250 250 # White +# pillars +pillars:stone_block_bot 100 97 96 # Match stone_block +pillars:stone_block_top 100 97 96 # Match stone_block + +# potted_farming +potted_farming:wild_basil 80 120 70 # Basil green +potted_farming:wild_mint 60 179 113 # Mint green +potted_farming:wild_oregano 70 130 60 # Oregano green +potted_farming:wild_parsley 34 139 34 # Parsley green +potted_farming:wild_rosemary 60 90 50 # Rosemary green +potted_farming:wild_sage 120 130 110 # Sage green + +# ropes +ropes:ladder_steel 132 132 132 # Match default:ladder_steel +ropes:ladder_wood 125 93 43 # Match default:ladder_wood + # signs signs:wooden_sign 160 82 45 # Sienna (Wood color) +# signs_extra +signs_extra:billboard 240 235 220 # Light wood/paper color +signs_extra:blue_banner 0 0 205 # Match wool:blue +signs:label_medium 245 245 245 # White label +signs:paper_poster 250 250 240 # Paper color + # signs_road signs_road:blue_sign 0 0 205 # Medium Blue signs_road:blue_street_sign 70 130 180 # Steel Blue +signs_road:green_sign 0 100 0 # Dark Green +signs_road:white_sign 245 245 245 # White +signs_road:yellow_sign 254 226 16 # Yellow + +# smartshop +smartshop:shop 131 102 57 # Wooden shop front # stairs +stairs:slab_acacia_wood 150 61 39 +stairs:slab_aspen_wood 210 199 170 +stairs:slab_brick 123 99 95 +stairs:slab_bronzeblock 186 111 15 +stairs:slab_cobble 89 86 84 +stairs:slab_copperblock 193 126 65 +stairs:slab_desert_cobble 110 67 50 +stairs:slab_desert_sandstone 195 152 92 +stairs:slab_desert_sandstone_block 193 152 94 +stairs:slab_desert_sandstone_brick 191 151 95 +stairs:slab_desert_stone 130 79 61 +stairs:slab_desert_stone_block 131 80 61 +stairs:slab_desert_stonebrick 131 80 61 +stairs:slab_glass 247 247 247 +stairs:slab_goldblock 231 203 35 +stairs:slab_ice 168 206 247 +stairs:slab_junglewood 56 39 14 +stairs:slab_mossycobble 88 91 73 +stairs:slab_obsidian 21 24 29 +stairs:slab_obsidian_block 23 25 30 +stairs:slab_obsidian_glass 20 23 27 +stairs:slab_obsidianbrick 23 25 29 +stairs:slab_pine_wood 221 185 130 +stairs:slab_sandstone 198 193 143 +stairs:slab_sandstone_block 195 191 142 +stairs:slab_sandstonebrick 194 190 141 +stairs:slab_silver_sandstone 195 192 181 +stairs:slab_silver_sandstone_block 192 190 180 +stairs:slab_silver_sandstone_brick 191 189 179 +stairs:slab_snowblock 225 225 238 +stairs:slab_steelblock 195 195 195 +stairs:slab_stone 97 94 93 +stairs:slab_stone_block 100 97 96 +stairs:slab_stonebrick 102 99 98 +stairs:slab_straw 212 184 68 +stairs:slab_tinblock 150 150 150 +stairs:slab_wood 131 102 57 +stairs:stair_acacia_wood 150 61 39 +stairs:stair_aspen_wood 210 199 170 +stairs:stair_brick 123 99 95 +stairs:stair_bronzeblock 186 111 15 +stairs:stair_cobble 89 86 84 +stairs:stair_copperblock 193 126 65 +stairs:stair_desert_cobble 110 67 50 +stairs:stair_desert_sandstone 195 152 92 +stairs:stair_desert_sandstone_block 193 152 94 +stairs:stair_desert_sandstone_brick 191 151 95 +stairs:stair_desert_stone 130 79 61 +stairs:stair_desert_stone_block 131 80 61 +stairs:stair_desert_stonebrick 131 80 61 +stairs:stair_glass 249 249 249 +stairs:stair_goldblock 231 203 35 +stairs:stair_ice 168 206 247 +stairs:stair_inner_acacia_wood 150 61 39 +stairs:stair_inner_aspen_wood 210 199 170 +stairs:stair_inner_brick 123 99 95 +stairs:stair_inner_bronzeblock 186 111 15 +stairs:stair_inner_cobble 89 86 84 +stairs:stair_inner_copperblock 193 126 65 +stairs:stair_inner_desert_cobble 110 67 50 +stairs:stair_inner_desert_sandstone 195 152 92 +stairs:stair_inner_desert_sandstone_block 193 152 94 +stairs:stair_inner_desert_sandstone_brick 191 151 95 +stairs:stair_inner_desert_stone 130 79 61 +stairs:stair_inner_desert_stone_block 131 80 61 +stairs:stair_inner_desert_stonebrick 131 80 61 +stairs:stair_inner_glass 250 250 250 +stairs:stair_inner_goldblock 231 203 35 +stairs:stair_inner_ice 168 206 247 +stairs:stair_inner_junglewood 56 39 14 +stairs:stair_inner_mossycobble 88 91 73 +stairs:stair_inner_obsidian 21 24 29 +stairs:stair_inner_obsidian_block 23 25 30 +stairs:stair_inner_obsidian_glass 20 22 27 +stairs:stair_inner_obsidianbrick 23 25 29 +stairs:stair_inner_pine_wood 221 185 130 +stairs:stair_inner_sandstone 198 193 143 +stairs:stair_inner_sandstone_block 195 191 142 +stairs:stair_inner_sandstonebrick 194 190 141 +stairs:stair_inner_silver_sandstone 195 192 181 +stairs:stair_inner_silver_sandstone_block 192 190 180 +stairs:stair_inner_silver_sandstone_brick 191 189 179 +stairs:stair_inner_snowblock 225 225 238 +stairs:stair_inner_steelblock 195 195 195 +stairs:stair_inner_stone 97 94 93 +stairs:stair_inner_stone_block 100 97 96 +stairs:stair_inner_stonebrick 102 99 98 +stairs:stair_inner_straw 212 184 68 +stairs:stair_inner_tinblock 150 150 150 +stairs:stair_inner_wood 131 102 57 +stairs:stair_junglewood 56 39 14 +stairs:stair_mossycobble 88 91 73 +stairs:stair_naturalbiomes_savannaacacia_wood 150 61 39 # Match acacia wood stairs:stair_netherrack 120 50 50 # Netherrack Red/Maroon +stairs:stair_obsidian 21 24 29 +stairs:stair_obsidian_block 23 25 30 +stairs:stair_obsidian_glass 20 22 27 +stairs:stair_obsidianbrick 23 25 29 +stairs:stair_outer_acacia_wood 150 61 39 +stairs:stair_outer_aspen_wood 210 199 170 +stairs:stair_outer_brick 123 99 95 +stairs:stair_outer_bronzeblock 186 111 15 +stairs:stair_outer_cobble 89 86 84 +stairs:stair_outer_copperblock 193 126 65 +stairs:stair_outer_desert_cobble 110 67 50 +stairs:stair_outer_desert_sandstone 195 152 92 +stairs:stair_outer_desert_sandstone_block 193 152 94 +stairs:stair_outer_desert_sandstone_brick 191 151 95 +stairs:stair_outer_desert_stone 130 79 61 +stairs:stair_outer_desert_stone_block 131 80 61 +stairs:stair_outer_desert_stonebrick 131 80 61 +stairs:stair_outer_glass 250 250 250 +stairs:stair_outer_goldblock 231 203 35 +stairs:stair_outer_ice 168 206 247 +stairs:stair_outer_junglewood 56 39 14 +stairs:stair_outer_mossycobble 88 91 73 +stairs:stair_outer_obsidian 21 24 29 +stairs:stair_outer_obsidian_block 23 25 30 +stairs:stair_outer_obsidian_glass 20 22 27 +stairs:stair_outer_obsidianbrick 23 25 29 +stairs:stair_outer_pine_wood 221 185 130 +stairs:stair_outer_sandstone 198 193 143 +stairs:stair_outer_sandstone_block 195 191 142 +stairs:stair_outer_sandstonebrick 194 190 141 +stairs:stair_outer_silver_sandstone 195 192 181 +stairs:stair_outer_silver_sandstone_block 192 190 180 +stairs:stair_outer_silver_sandstone_brick 191 189 179 +stairs:stair_outer_snowblock 225 225 238 +stairs:stair_outer_steelblock 195 195 195 +stairs:stair_outer_stone 97 94 93 +stairs:stair_outer_stone_block 100 97 96 +stairs:stair_outer_stonebrick 102 99 98 +stairs:stair_outer_straw 212 184 68 +stairs:stair_outer_tinblock 150 150 150 +stairs:stair_outer_wood 131 102 57 +stairs:stair_pine_wood 221 185 130 +stairs:stair_sandstone 198 193 143 +stairs:stair_sandstone_block 195 191 142 +stairs:stair_sandstonebrick 194 190 141 +stairs:stair_silver_sandstone 195 192 181 +stairs:stair_silver_sandstone_block 192 190 180 +stairs:stair_silver_sandstone_brick 191 189 179 +stairs:stair_snowblock 225 225 238 +stairs:stair_steelblock 195 195 195 +stairs:stair_stone 97 94 93 +stairs:stair_stone_block 100 97 96 +stairs:stair_stonebrick 102 99 98 +stairs:stair_straw 212 184 68 +stairs:stair_tinblock 150 150 150 +stairs:stair_wood 131 102 57 + +# steles +steles:desert_stone_stele 210 180 140 # Wüstenstein (Tan) +steles:sandstone_stele 230 190 150 # Sandstein (helles Tan/Sandorange) +steles:stone_stele 97 94 93 # Standard Steingrau + +# tables_chairs +tables_chairs:palm_wood_tiny_table 140 110 80 # Match palm_trunk +tables_chairs:scorched_tree_chair 60 55 50 # Match ethereal:scorched_tree +tables_chairs:scorched_tree_small_table 60 55 50 # Match ethereal:scorched_tree + +# tnt +tnt:gunpowder 12 12 12 +tnt:gunpowder_burning 156 143 7 +tnt:tnt 196 0 0 +tnt:tnt_burning 201 41 0 # tpad tpad:tpad 70 70 100 # Dark Bluish Grey (Teleporter Pad) +# vessels +vessels:drinking_glass 207 214 228 +vessels:glass_bottle 189 192 204 +vessels:shelf 131 102 57 +vessels:steel_bottle 194 193 193 + +# walls +walls:cobble 89 86 84 +walls:desertcobble 110 67 50 +walls:mossycobble 88 91 73 + +# wielded_light +wielded_light:10 255 255 224 # Light yellow color for light source + +# wool +wool:black 30 30 30 +wool:blue 0 73 146 +wool:brown 88 44 0 +wool:cyan 0 132 140 +wool:dark_green 33 103 0 +wool:dark_grey 60 60 60 +wool:green 93 218 28 +wool:grey 133 133 133 +wool:magenta 201 3 112 +wool:orange 214 83 22 +wool:pink 255 133 133 +wool:red 170 18 18 +wool:violet 93 5 169 +wool:white 220 220 220 +wool:yellow 254 226 16 + +# xanadu +xanadu:poppy 255 0 0 # Red poppy color + # xnether xnether:blue_leaves 0 0 200 # Blue xnether:blue_tree 80 60 40 # Dark Brown/Grey (Nether wood trunk) +xnether:fence_blue 60 50 150 # Blaues Nether-Holz für Zaun +xnether:fence_purple 100 50 100 # Lilanes Nether-Holz für Zaun xnether:fruit 128 0 128 # Purple (Generic xnether fruit) xnether:grass_blue_1 100 100 255 # Light Blue Grass xnether:grass_blue_2 80 80 220 # Medium Blue Grass @@ -716,76 +1219,19 @@ xnether:purple_tree 70 50 30 # Dark Brown/Grey (Nether wood trunk) xnether:rack_deep_with_mese 100 60 50 # Netherrack with Mese Tint xnether:rack_with_gold 120 80 50 # Netherrack with Gold Tint -# butterflies -butterflies:hidden_butterfly_white 220 220 220 # Ein sehr helles Grau, fast weiß, für einen "versteckten" weißen Schmetterling - -# carpet -carpet:wool_black 30 30 30 -carpet:wool_blue 0 0 205 -carpet:wool_brown 139 69 19 -carpet:wool_cyan 0 255 255 -carpet:wool_dark_green 0 100 0 -carpet:wool_dark_grey 70 70 70 -carpet:wool_green 0 128 0 -carpet:wool_grey 128 128 128 -carpet:wool_magenta 255 0 255 -carpet:wool_orange 255 165 0 -carpet:wool_pink 255 192 203 -carpet:wool_red 255 0 0 -carpet:wool_violet 138 43 226 -carpet:wool_white 250 250 250 - -# castle_gates -castle_gates:steel_gate_hinge 170 170 180 # Stahlgrau -castle_gates:steel_gate_panel 170 170 180 # Stahlgrau -castle_gates:steel_portcullis_bars 170 170 180 # Stahlgrau für Gitterstäbe -castle_gates:steel_portcullis_bars_bottom 160 160 170 # Etwas dunkleres Stahlgrau für den unteren Teil -castle_gates:stonebrick_gate_slot 120 120 120 # Steinziegelgrau -castle_gates:stonebrick_gate_slot_reverse 120 120 120 # Steinziegelgrau -castle_gates:wood_gate_edge 139 90 43 # Allgemeines Holzbraun -castle_gates:wood_gate_edge_handle 120 70 30 # Dunkleres Holzbraun für den Griff - -# doors -doors:trapdoor_oak 200 160 100 # Eichenholzfarbe - -# fake_fire -fake_fire:embers 255 100 0 # Tiefes, glühendes Orange für Glut - -# fireflies -fireflies:firefly 220 255 100 # Helles, gelb-grünliches Leuchten für Glühwürmchen - -# gates_long -gates_long:fence_gate_closed_acacia 205 92 92 # Rötlich-oranges Akazienholz -gates_long:fence_gate_closed_junglewood 139 76 57 # Sattes Dschungelholzbraun -gates_long:fence_gate_closed_pine 222 184 135 # Helles Kiefernholz -gates_long:fence_gate_closed_tree 160 82 45 # Standard Holzfarbe (wie default wood) - -# moreblocks -moreblocks:all_faces_tree 101 67 33 # Rindenbraun -moreblocks:cactus_brick 120 150 100 # Gedämpftes Kaktusgrün für Ziegel -moreblocks:circle_stone_bricks 115 115 115 # Kreissteinziegel, ähnlich Steinziegelgrau -moreblocks:coal_stone 50 50 50 # Sehr dunkles Grau, fast schwarz (Kohlegestein) -moreblocks:coal_stone_bricks 60 60 60 # Ziegel aus Kohlegestein, sehr dunkelgrau -moreblocks:cobble_compressed 110 110 110 # Verdichteter Bruchstein, etwas dunkler -moreblocks:desert_cobble_compressed 190 170 130 # Verdichteter Wüstenbruchstein, sandig-grau -moreblocks:dirt_compressed 100 70 50 # Verdichtete Erde, dunkleres Braun -moreblocks:grey_bricks 140 140 140 # Standard graue Ziegel -moreblocks:iron_stone 100 90 85 # Eisengestein, dunkel-metallisch mit Rosthauch -moreblocks:iron_stone_bricks 105 95 90 # Ziegel aus Eisengestein - -# morelights_extras -morelights_extras:stone_block 100 97 96 # Standard Steinblockfarbe - -# steles -steles:desert_stone_stele 210 180 140 # Wüstenstein (Tan) -steles:sandstone_stele 230 190 150 # Sandstein (helles Tan/Sandorange) -steles:stone_stele 97 94 93 # Standard Steingrau - -# xnether -xnether:fence_blue 60 50 150 # Blaues Nether-Holz für Zaun -xnether:fence_purple 100 50 100 # Lilanes Nether-Holz für Zaun - # xpanes -xpanes:jailbars_flat 80 80 90 # Dunkles Metallgrau für Gitterstäbe -xpanes:nether_crystal_pane_flat 120 80 150 # Lilafarbene Kristallglasscheibe - +xpanes:bar 114 114 114 64 16 +xpanes:bar_flat 114 114 114 64 16 +xpanes:door_steel_bar_a 133 133 133 64 16 +xpanes:door_steel_bar_b 133 133 133 64 16 +xpanes:door_steel_bar_c 133 133 133 64 16 +xpanes:door_steel_bar_d 133 133 133 64 16 +xpanes:jailbars_flat 80 80 90 # Dunkles Metallgrau für Gitterstäbe +xpanes:myglass:glass_pane_black_flat 40 40 40 100 16 # Dark, semi-transparent glass +xpanes:nether_crystal_pane_flat 120 80 150 64 16 # Lilafarbene Kristallglasscheibe +xpanes:obsidian_pane 16 17 18 64 16 +xpanes:obsidian_pane_flat 16 17 18 64 16 +xpanes:pane 249 249 249 64 16 +xpanes:pane_flat 249 249 249 64 16 +xpanes:trapdoor_steel_bar 127 127 127 64 16 +xpanes:trapdoor_steel_bar_open 77 77 77 64 16 diff --git a/config.sh b/config.sh index d6bbc93..5e330c4 100755 --- a/config.sh +++ b/config.sh @@ -4,7 +4,7 @@ # === Globale Skript- und Pfad-Einstellungen === BASE_SCRIPT_DIR="/opt/luweb" SITE_GENERATOR_BASE_PATH="${BASE_SCRIPT_DIR}/site_generator" # Basis für Generator-Komponenten -TEMPLATE_DIR_PATH="${SITE_GENERATOR_BASE_PATH}/templates" # Unterordner für Templates +TEMPLATE_DIR_PATH="${SITE_GENERATOR_BASE_PATH}/templates" # Unterordner für Templates EXAMPLE_TEMPLATE_DIR_PATH="${SITE_GENERATOR_BASE_PATH}/examples" # NEU: Für Beispiel-Konfigs LOG_DIR_BASE="/var/log/luweb" TEMP_MARKER_DIR="/tmp" @@ -16,7 +16,7 @@ MINETESTMAPPER_EXEC_NAME="minetestmapper" MINETESTMAPPER_WORLD_DATA_BASE_PATH="/opt/luanti/data/worlds/" DEFAULT_MM_OPT_ZOOM_LEVEL="2"; DEFAULT_MM_OPT_MIN_Y="-25" DEFAULT_MM_OPT_ORIGINCOLOR="#ff0000"; DEFAULT_MM_OPT_PLAYERCOLOR="#ff0000" -DEFAULT_MM_OPT_SCALECOLOR="#ff0000"; DEFAULT_MM_OPT_BGCOLOR="#111111" +DEFAULT_MM_OPT_SCALECOLOR="#ff0000"; DEFAULT_MM_OPT_BGCOLOR="#dddddd" DEFAULT_MM_CFG_DRAWALPHA="true"; DEFAULT_MM_CFG_DRAWORIGIN="true" DEFAULT_MM_CFG_DRAWPLAYERS="true"; DEFAULT_MM_CFG_DRAWSCALE="true" @@ -30,7 +30,7 @@ WEB_MAPS_BASE_SUBDIR="worldmaps" # --- Standard-Einstellungen für generierte Dateien (überschreibbar in web.conf) --- DEFAULT_TILES_SUBDIR_NAME="map_tiles" -DEFAULT_GDAL2TILES_ZOOM_LEVELS="1-6" +DEFAULT_GDAL2TILES_ZOOM_LEVELS="1-7" DEFAULT_WEB_MAP_PNG_FILENAME="map.png" DEFAULT_RESIZED_MAX_DIMENSION=4096 DEFAULT_ARCHIVE_SUBDIR_NAME="archive" @@ -48,9 +48,8 @@ FALLBACK_BANNER_IMG_URL="/images/default_banner.png" # Fallback-Werte für Serverdetails (falls in web.conf nicht spezifiziert) DEFAULT_SERVER_DISPLAY_NAME_PREFIX="unbekannt"; DEFAULT_SERVER_ADDRESS="unbekannt"; DEFAULT_SERVER_PORT="30000" DEFAULT_SERVER_ACCESS_INFO="Keine Angaben"; DEFAULT_SERVER_STATUS_TEXT_FALLBACK="Status wird ermittelt..." -DEFAULT_LEAFLET_BOUNDS_SOUTH="-85.05112878"; DEFAULT_LEAFLET_BOUNDS_WEST="-180" -DEFAULT_LEAFLET_BOUNDS_NORTH="85.05112878"; DEFAULT_LEAFLET_BOUNDS_EAST="180" -DEFAULT_LEAFLET_ZOOM_AFTER_FIT="2"; DEFAULT_GAMEID="minetest" +# Veraltete Leaflet-Variablen wurden entfernt. +DEFAULT_GAMEID="minetest" DEFAULT_WORLD_SHORT_DESCRIPTION="Keine Kurzbeschreibung vorhanden." DEFAULT_WORLD_LONG_DESCRIPTION="

Für diese Welt wurde noch keine detaillierte Beschreibung hinterlegt.

" diff --git a/generate_map.sh b/generate_map.sh index 007d608..0708dd1 100755 --- a/generate_map.sh +++ b/generate_map.sh @@ -9,11 +9,15 @@ else exit 1 fi -# Welt-Schlüssel (Verzeichnisname) aus Argument oder Standardwert -WORLD_KEY="${1:-$DEFAULT_WORLD_NAME_KEY}" # Nutzt DEFAULT_WORLD_NAME_KEY aus config.sh +# Prüfe Abhängigkeiten, bevor irgendetwas anderes passiert +# Annahme: check_dependencies.sh wurde um 'vips' erweitert +/opt/luweb/check_dependencies.sh || exit 1 -# Pfad zum Verzeichnis der aktuellen Welt (verwendet jetzt MINETESTMAPPER_WORLD_DATA_BASE_PATH) -CURRENT_MINETEST_WORLD_DATA_PATH="${MINETESTMAPPER_WORLD_DATA_BASE_PATH}${WORLD_KEY}/" # Für -i Option und world.mt/web.conf +# Welt-Schlüssel (Verzeichnisname) aus Argument oder Standardwert +WORLD_KEY="${1:-$DEFAULT_WORLD_NAME_KEY}" + +# 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 echo "$(date '+%Y-%m-%d %H:%M:%S') - [${WORLD_KEY}] - FEHLER: Das Welt-Datenverzeichnis '${CURRENT_MINETEST_WORLD_DATA_PATH}' wurde nicht gefunden!" @@ -48,12 +52,10 @@ 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" -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 - 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" +MAP_INFO_FILE_ABSOLUTE_PATH="${RAW_MAP_OUTPUT_DIR_ABSOLUTE}/map_info.txt" WEB_CURRENT_WORLD_DIR="${WEB_ROOT_PATH}/${WEB_MAPS_BASE_SUBDIR}/${WORLD_KEY}" TILES_FULL_OUTPUT_PATH="${WEB_CURRENT_WORLD_DIR}/${TILES_SUBDIR_NAME}" @@ -66,7 +68,7 @@ log_message() { echo "${message_to_log}" | tee -a "$LOG_FILE" } -# === Funktion zur Archivbereinigung (unverändert) === +# === Funktion zur Archivbereinigung === prune_archives() { log_message "Starte Archivbereinigung für Welt '${WORLD_KEY}' im Pfad '${ARCHIVE_BASE_WEB_PATH}'..." if [ ! -d "$ARCHIVE_BASE_WEB_PATH" ]; then log_message "Archiv-Basispfad ${ARCHIVE_BASE_WEB_PATH} nicht gefunden."; return; fi @@ -110,29 +112,40 @@ MM_ALL_OPTIONS_STR="${MM_ALL_OPTIONS_STR} --scalecolor '${MM_OPT_SCALECOLOR}'"; MM_ALL_OPTIONS_STR="${MM_ALL_OPTIONS_STR} --min-y ${MM_OPT_MIN_Y}" MAP_GENERATION_COMMAND_TO_EVAL="'${MINETESTMAPPER_PATH}' -i '${CURRENT_MINETEST_WORLD_DATA_PATH}' -o '${RAW_MAP_ABSOLUTE_PATH}' ${MM_ALL_OPTIONS_STR}" -log_message "Starte minetestmapper (Optionen: ${MM_ALL_OPTIONS_STR}). Ausgaben folgen:" +log_message "Starte minetestmapper zur Kartengenerierung (Optionen: ${MM_ALL_OPTIONS_STR})." 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 [ ${MAPPER_EXIT_STATUS} -ne 0 ]; then log_message "FEHLER: minetestmapper Kartengenerierung (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}..." +log_message "Erstelle map_info.txt..." +MAP_DIMENSIONS=""; MAP_EXTENT="" if ! command -v identify &> /dev/null; then - log_message "WARNUNG: 'identify' (Teil von ImageMagick) nicht gefunden. map_info.txt kann nicht erstellt werden." + log_message "WARNUNG: 'identify' (Teil von ImageMagick) nicht gefunden. map_dimension kann nicht ermittelt 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 + MAP_DIMENSIONS=$(identify -format "%wx%h" "$RAW_MAP_ABSOLUTE_PATH" 2>/dev/null) +fi + +EXTENT_COMMAND_TO_EVAL="'${MINETESTMAPPER_PATH}' -i '${CURRENT_MINETEST_WORLD_DATA_PATH}' --extent ${MM_ALL_OPTIONS_STR}" +log_message "Ermittle Map Extent mit: --extent" +MAP_EXTENT_OUTPUT=$(eval "${EXTENT_COMMAND_TO_EVAL}" 2>/dev/null) +if [ -n "$MAP_EXTENT_OUTPUT" ]; then + MAP_EXTENT=$(echo "$MAP_EXTENT_OUTPUT" | sed 's/Map extent: //') +fi + +if [ -n "$MAP_DIMENSIONS" ] && [ -n "$MAP_EXTENT" ]; then + { + echo "map_dimension=${MAP_DIMENSIONS}" + echo "map_extent=${MAP_EXTENT}" + } > "$MAP_INFO_FILE_ABSOLUTE_PATH" + log_message "map_info.txt erfolgreich erstellt: Dimension=${MAP_DIMENSIONS}, Extent=${MAP_EXTENT}" +else + log_message "FEHLER: map_info.txt konnte nicht erstellt werden, da Informationen fehlen!" + [ -z "$MAP_DIMENSIONS" ] && log_message "-> Bild-Dimensionen konnten nicht ermittelt werden." + [ -z "$MAP_EXTENT" ] && log_message "-> Karten-Extent konnte nicht ermittelt werden." fi -# Unknown Nodes Verarbeitung if [ -f "$MAPPER_RUN_OUTPUT_CAPTURE_FILE" ]; then TEMP_NEW_UNKNOWN_NODES_FILE="${UNKNOWN_NODES_FILE_ABSOLUTE_PATH}.new_found" 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" > "$TEMP_NEW_UNKNOWN_NODES_FILE" @@ -141,25 +154,28 @@ 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 -log_message "Erzeuge Web-Version von ${RAW_MAP_FILENAME} (max ${RESIZED_MAX_DIMENSION}px) nach ${WEB_MAP_PNG_FULL_PATH}..." +# === Web-Vorschaukarte (verkleinert) erstellen mit VIPS === +log_message "Erzeuge Web-Version von ${RAW_MAP_FILENAME} (max ${RESIZED_MAX_DIMENSION}px) mit 'vips' 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 - if ! command -v convert &> /dev/null; then log_message "WARNUNG: convert nicht gefunden. Kopiere Karte." - (set -o pipefail; cp "$RAW_MAP_ABSOLUTE_PATH" "$WEB_MAP_PNG_FULL_PATH" 2>&1 | tee -a "$LOG_FILE" ) - if [ $? -ne 0 ]; then log_message "FEHLER: Kopieren fehlgeschlagen."; else log_message "Rohkarte kopiert."; fi - else log_message "Führe convert aus..." - (set -o pipefail; convert "$RAW_MAP_ABSOLUTE_PATH" -resize "${RESIZED_MAX_DIMENSION}x${RESIZED_MAX_DIMENSION}>" "$WEB_MAP_PNG_FULL_PATH" 2>&1 | tee -a "$LOG_FILE") - if [ $? -ne 0 ]; then log_message "FEHLER: Verkleinern fehlgeschlagen."; else log_message "Verkleinerte Web-map.png erstellt."; fi +if [ ! -f "$RAW_MAP_ABSOLUTE_PATH" ]; then + log_message "FEHLER: Quelldatei ${RAW_MAP_ABSOLUTE_PATH} für Web-Vorschau nicht gefunden!" +else + # KORREKTUR: --size "down" statt ">" + (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 "FEHLER: Skalierung mit 'vips' fehlgeschlagen." + else + log_message "Verkleinerte Web-map.png mit 'vips' erfolgreich erstellt." fi fi -# 3. Tiles generieren +# === Tiles generieren === 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")" log_message "Führe gdal2tiles.py aus..." - (set -o pipefail; gdal2tiles.py --profile=raster --xyz --zoom="${GDAL2TILES_ZOOM_LEVELS}" "${RAW_MAP_ABSOLUTE_PATH}" "${TEMP_TILES_DIR}" 2>&1 | tee -a "$LOG_FILE") + # KORREKTUR: -r "near" statt "nearest" + (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 "FEHLER: gdal2tiles.py fehlgeschlagen."; rm -rf "$TEMP_TILES_DIR"; exit 1; fi log_message "Kacheln in ${TEMP_TILES_DIR} generiert." log_message "Entferne altes Kachel-Verzeichnis: ${TILES_FULL_OUTPUT_PATH}"; rm -rf "$TILES_FULL_OUTPUT_PATH" @@ -171,29 +187,36 @@ fi # === Archivbereinigung === prune_archives -# 4. Tägliches Archivbild +# === Tägliches Archivbild === 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" log_message "Prüfe Notwendigkeit für Archivbild für ${ARCHIVE_YEAR}-${ARCHIVE_MONTH}-${ARCHIVE_DAY}..." if [ ! -f "$ARCHIVE_DAILY_FILE_PATH" ]; then log_message "Archivbild ${ARCHIVE_DAILY_FILE_PATH} existiert noch nicht. Versuche Erstellung..." - if [ ! -f "$RAW_MAP_ABSOLUTE_PATH" ]; then log_message "FEHLER: Quelldatei (${RAW_MAP_ABSOLUTE_PATH}) nicht gefunden! Archiv nicht erstellt."; + if [ ! -f "$RAW_MAP_ABSOLUTE_PATH" ]; then + log_message "FEHLER: Quelldatei (${RAW_MAP_ABSOLUTE_PATH}) nicht gefunden! Archiv nicht erstellt." else mkdir -p "$ARCHIVE_DAILY_TARGET_DIR" - if [ ! -d "$ARCHIVE_DAILY_TARGET_DIR" ]; then log_message "FEHLER: Archiv-Zielverzeichnis ${ARCHIVE_DAILY_TARGET_DIR} nicht erstellt."; + if [ ! -d "$ARCHIVE_DAILY_TARGET_DIR" ]; then + log_message "FEHLER: Archiv-Zielverzeichnis ${ARCHIVE_DAILY_TARGET_DIR} nicht erstellt." else - log_message "Erzeuge Archivbild (max ${RESIZED_MAX_DIMENSION}px) für ${ARCHIVE_DAILY_FILE_PATH}..." - if ! command -v convert &> /dev/null; then log_message "WARNUNG: convert nicht gefunden. Kopiere Originalgröße." - if cp "$RAW_MAP_ABSOLUTE_PATH" "$ARCHIVE_DAILY_FILE_PATH"; then log_message "Archivbild (Originalgröße) erstellt."; else log_message "FEHLER: Archivbild (cp) nicht erstellt.";fi - else - (set -o pipefail; convert "$RAW_MAP_ABSOLUTE_PATH" -resize "${RESIZED_MAX_DIMENSION}x${RESIZED_MAX_DIMENSION}>" "$ARCHIVE_DAILY_FILE_PATH" 2>&1 | tee -a "$LOG_FILE") - if [ $? -eq 0 ]; then log_message "Verkleinertes Archivbild erstellt."; if [ ! -s "$ARCHIVE_DAILY_FILE_PATH" ]; then log_message "WARNUNG: Archivbild ${ARCHIVE_DAILY_FILE_PATH} ist leer.";fi - else log_message "FEHLER: Verkleinertes Archivbild nicht erstellt (convert).";fi - fi; fi; fi -else log_message "Archivbild ${ARCHIVE_DAILY_FILE_PATH} existiert bereits."; fi + log_message "Erzeuge Archivbild (max ${RESIZED_MAX_DIMENSION}px) mit 'vips' für ${ARCHIVE_DAILY_FILE_PATH}..." + # KORREKTUR: --size "down" statt ">" + (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 "Verkleinertes Archivbild erstellt." + if [ ! -s "$ARCHIVE_DAILY_FILE_PATH" ]; then log_message "WARNUNG: Archivbild ${ARCHIVE_DAILY_FILE_PATH} ist leer."; fi + else + log_message "FEHLER: Verkleinertes Archivbild nicht erstellt (vips)." + fi + fi + fi +else + log_message "Archivbild ${ARCHIVE_DAILY_FILE_PATH} existiert bereits." +fi -# 5. Status- und Info-Dateien im Webverzeichnis +# === Status- und Info-Dateien im Webverzeichnis === 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,9 +224,8 @@ 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 +if [ -f "$MAP_INFO_FILE_ABSOLUTE_PATH" ]; then + if cp "$MAP_INFO_FILE_ABSOLUTE_PATH" "${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." diff --git a/generate_site.sh b/generate_site.sh index 7424cea..bb56241 100755 --- a/generate_site.sh +++ b/generate_site.sh @@ -1,5 +1,8 @@ #!/bin/bash +# Prüfe Abhängigkeiten, bevor irgendetwas anderes passiert +./check_dependencies.sh || exit 1 + # Lade globale Konfiguration CONFIG_FILE_PATH="$(dirname "$0")/config.sh" if [ -f "$CONFIG_FILE_PATH" ]; then @@ -9,473 +12,49 @@ else exit 1 fi -# === Abgeleitete Variablen === +# === Abgeleitete Haupt-Variablen === SCRIPT_BASENAME=$(basename "$0" .sh) 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) +FUNCTIONS_DIR="${SITE_GENERATOR_BASE_PATH}/functions" +GENERATORS_DIR="${FUNCTIONS_DIR}/generators" CURRENT_YEAR=$(date '+%Y') -ACTUAL_BANNER_IMG_URL_PATH="${FALLBACK_BANNER_IMG_URL}" +CACHE_BUSTER=$(date +%s) +WEB_CONTENT_STATIC_PATH="${WEB_CONTENT_BASE_PATH}/${WEB_CONTENT_STATIC_SUBDIR}" -# === Logging Funktion === -log_message() { local msg; msg="$(date '+%Y-%m-%d %H:%M:%S') - $1"; echo "${msg}" | tee -a "$LOG_FILE"; } +# --- Lade alle Funktions-Skripte aus den Unterverzeichnissen --- +if [ ! -d "$FUNCTIONS_DIR" ] || [ ! -d "$GENERATORS_DIR" ]; then + echo "FEHLER: Funktions-Verzeichnisse (${FUNCTIONS_DIR}, ${GENERATORS_DIR}) nicht gefunden!" + exit 1 +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: $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; 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;} - -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 "FEHLER: 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" +# Lade Hilfsfunktionen und dann die Generatoren +for func_file in "$FUNCTIONS_DIR"/*.sh "$GENERATORS_DIR"/*.sh; do + if [ -f "$func_file" ]; then + source "$func_file" fi -} - -# === Template Rendering Funktion (FINAL, ROBUST) === -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" -} - -# === HTML/CSS Erzeugungsfunktionen === -generate_css() { - local css_file_path="${WEB_ROOT_PATH}/style.css" - log_message "Erzeuge/Aktualisiere ${css_file_path} aus Template..." - render_template "${TEMPLATE_DIR_PATH}/css.template" "$css_file_path" \ - "css_banner_image_path" "$ACTUAL_BANNER_IMG_URL_PATH" \ - "CACHE_BUSTER" "$CACHE_BUSTER" - if [ $? -eq 0 ]; then log_message "CSS-Datei erfolgreich erstellt."; else log_message "FEHLER CSS."; fi -} - -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" -} - -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_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_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 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" - 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="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" - - discovered_worlds_count=$((discovered_worlds_count + 1)) - 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_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 "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") - - 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 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 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+="" - 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_last_update_rel_path="${WEB_MAPS_BASE_SUBDIR}/${current_world_key}/last_update.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 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 - - local ADMIN_BOXES_HTML="" - local num_admins=${#ADMIN_NAME[@]} - if [ $num_admins -eq 0 ]; then - 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]}" - local contact_links_html="" - [ -n "$email" ] && contact_links_html+="Email" - [ -n "$discord" ] && contact_links_html+="Discord" - [ -n "$matrix" ] && contact_links_html+="Matrix" - [ -n "$steam" ] && contact_links_html+="Steam" - [ -n "$teamspeak" ] && contact_links_html+="Teamspeak" - [ -n "$mumble" ] && contact_links_html+="Mumble" - 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" - - 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 -} - +done # === Hauptlogik für Webseitengenerierung === exec 200>"$LOCK_FILE" flock -n 200 || { echo "$(date '+%Y-%m-%d %H:%M:%S') - Script ${SCRIPT_BASENAME}.sh ist bereits aktiv (Lock: ${LOCK_FILE}). Beende." | tee -a "$LOG_FILE"; exit 1; } 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}" +# --- Führe die ausgelagerten Funktionen in der richtigen Reihenfolge aus --- -DEFAULT_MINETEST_WORLD_DATA_DIR_FOR_CONF="${MINETESTMAPPER_WORLD_DATA_BASE_PATH}${DEFAULT_WORLD_NAME_KEY}" -if [ -d "$DEFAULT_MINETEST_WORLD_DATA_DIR_FOR_CONF" ] && [ -f "${DEFAULT_MINETEST_WORLD_DATA_DIR_FOR_CONF}/world.mt" ]; then - if [ ! -f "${DEFAULT_MINETEST_WORLD_DATA_DIR_FOR_CONF}/web.conf" ]; then log_message "Erstelle Beispiel web.conf für '${DEFAULT_WORLD_NAME_KEY}'..."; create_placeholder_web_conf "${DEFAULT_MINETEST_WORLD_DATA_DIR_FOR_CONF}/web.conf"; fi; fi -create_placeholder_file "${WEB_CONTENT_STATIC_PATH}/startseite_content.html" "

Willkommen!

Inhalt hier.

" -create_placeholder_file "${WEB_CONTENT_STATIC_PATH}/impressum_content.html" "

Impressum

Impressum. Betreiber: ${SITE_OWNER_NAME}, Kontakt: ${SITE_OWNER_EMAIL}

" -create_placeholder_file "${WEB_CONTENT_STATIC_PATH}/downloads_content.html" "

Downloads

Infos. Offiziell: luanti.org

" -create_placeholder_file "${WEB_CONTENT_STATIC_PATH}/datenschutz_content.html" "

Datenschutzerklärung

Hier deinen Datenschutztext einfügen.

" +# 1. Initialisierung: Verzeichnisse und Assets vorbereiten +initialize_site_structure_and_assets -log_message "Starte Generierung der statischen Webseiten-Dateien..." -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" -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 +# 2. Globale CSS-Datei generieren +generate_css -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 +# 3. Statische Seiten generieren +generate_static_pages -generate_css; generate_homepage; generate_impressum; generate_downloads_page; generate_datenschutz_page; generate_worlds_overview +# 4. Welt-spezifische Seiten generieren +generate_all_world_pages -processed_world_count=0; shopt -s nullglob -site_world_key_dirs_detail_loop=("${MINETESTMAPPER_WORLD_DATA_BASE_PATH}"/*/) -shopt -u nullglob -if [ ${#site_world_key_dirs_detail_loop[@]} -gt 0 ]; then - for site_world_data_dir_item in "${site_world_key_dirs_detail_loop[@]}"; do - site_current_world_key_item=$(basename "$site_world_data_dir_item") - if [ -z "$site_current_world_key_item" ]; then log_message "WARNUNG: Leerer Welt-Schlüssel '${site_world_data_dir_item}'."; continue; fi - if [ -f "${site_world_data_dir_item}world.mt" ] && [ -f "${site_world_data_dir_item}web.conf" ]; then - target_web_world_dir_item="${WEB_ROOT_PATH}/${WEB_MAPS_BASE_SUBDIR}/${site_current_world_key_item}" - mkdir -p "$target_web_world_dir_item" - touch "${target_web_world_dir_item}/areas.txt"; touch "${target_web_world_dir_item}/players.txt"; touch "${target_web_world_dir_item}/weather.txt" - log_message "Platzhalter areas.txt, players.txt, weather.txt für Welt '${site_current_world_key_item}' sichergestellt." - generate_world_detail_page "$site_current_world_key_item"; processed_world_count=$((processed_world_count + 1)) - else log_message "WARNUNG: Für ${site_world_data_dir_item} (Key: ${site_current_world_key_item}) fehlt world.mt oder web.conf.";fi - done - log_message "${processed_world_count} Welt-Detailseiten generiert/aktualisiert." -else log_message "Keine Weltverzeichnisse in ${MINETESTMAPPER_WORLD_DATA_BASE_PATH} gefunden."; fi log_message "Webseiten-Generierung abgeschlossen." exit 0 diff --git a/site_generator/functions/01_utils.sh b/site_generator/functions/01_utils.sh new file mode 100644 index 0000000..4bcaa7e --- /dev/null +++ b/site_generator/functions/01_utils.sh @@ -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 $? +} diff --git a/site_generator/functions/02_init.sh b/site_generator/functions/02_init.sh new file mode 100644 index 0000000..7cd892c --- /dev/null +++ b/site_generator/functions/02_init.sh @@ -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" "

Willkommen!

Inhalt hier.

" + create_placeholder_file "${WEB_CONTENT_STATIC_PATH}/impressum_content.html" "

Impressum

Impressum. Betreiber: ${SITE_OWNER_NAME}, Kontakt: ${SITE_OWNER_EMAIL}

" + create_placeholder_file "${WEB_CONTENT_STATIC_PATH}/downloads_content.html" "

Downloads

Infos. Offiziell: luanti.org

" + create_placeholder_file "${WEB_CONTENT_STATIC_PATH}/datenschutz_content.html" "

Datenschutzerklärung

Hier deinen Datenschutztext einfügen.

" + + 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 +} diff --git a/site_generator/functions/03_html_helpers.sh b/site_generator/functions/03_html_helpers.sh new file mode 100644 index 0000000..898b4e9 --- /dev/null +++ b/site_generator/functions/03_html_helpers.sh @@ -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" +} diff --git a/site_generator/functions/generators/css_generator.sh b/site_generator/functions/generators/css_generator.sh new file mode 100644 index 0000000..839afdb --- /dev/null +++ b/site_generator/functions/generators/css_generator.sh @@ -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 +} diff --git a/site_generator/functions/generators/main_orchestrator.sh b/site_generator/functions/generators/main_orchestrator.sh new file mode 100644 index 0000000..dc7b36f --- /dev/null +++ b/site_generator/functions/generators/main_orchestrator.sh @@ -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." +} diff --git a/site_generator/functions/generators/static_pages_generator.sh b/site_generator/functions/generators/static_pages_generator.sh new file mode 100644 index 0000000..3f50553 --- /dev/null +++ b/site_generator/functions/generators/static_pages_generator.sh @@ -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 "

Willkommen!

"; 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 "

Impressum

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

"; 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 <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" + { + generate_html_header "Datenschutz" "." + if [ -f "$c" ]; then cat "$c"; else echo "

Datenschutzerklärung

Platzhalter.

"; 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 +} diff --git a/site_generator/functions/generators/world_detail_generator.sh b/site_generator/functions/generators/world_detail_generator.sh new file mode 100644 index 0000000..3e07154 --- /dev/null +++ b/site_generator/functions/generators/world_detail_generator.sh @@ -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

${name}

"; if [ -n "$contact_links_html" ]; then ADMIN_BOXES_HTML+=""; fi; ADMIN_BOXES_HTML+="" + 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="Fehlende Map-Nodes" + else + map_sub_info_link=" " + 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." +} diff --git a/site_generator/functions/generators/world_overview_generator.sh b/site_generator/functions/generators/world_overview_generator.sh new file mode 100644 index 0000000..dcbad28 --- /dev/null +++ b/site_generator/functions/generators/world_overview_generator.sh @@ -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 "

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" + 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="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" + + discovered_worlds_count=$((discovered_worlds_count + 1)) + 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" +} diff --git a/site_generator/templates/css.template b/site_generator/templates/css.template index 4c3f45c..40c70af 100755 --- a/site_generator/templates/css.template +++ b/site_generator/templates/css.template @@ -100,7 +100,14 @@ 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;} +/* KORREKTUR: Klasse umbenannt von .leaflet-map zu .map-view-container */ +.map-view-container { + width: 100%; + height: 600px; + 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; } @@ -119,7 +126,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-grow: 0; flex-shrink: 1; flex-basis: calc(50% - 8px); box-sizing: border-box; @@ -181,7 +188,7 @@ a.world-preview:hover { border: 1px solid #555; border-radius: 5px; padding: 10px; - width: calc((100% - 30px) / 3); /* KORREKTUR: Max 3 Boxen pro Zeile */ + width: calc((100% - 30px) / 3); box-sizing: border-box; display: flex; flex-direction: column; @@ -429,57 +436,6 @@ 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; -} - @media (max-width: 768px) { /* Responsive Stile für Burger-Menü */ .responsive-nav { @@ -525,7 +481,7 @@ a.read-more-link { margin-right: 0; margin-bottom: 15px; } - .leaflet-map { + .map-view-container { /* KORREKTUR: Klasse umbenannt */ height: auto; aspect-ratio: 4 / 3; max-height: 70vh; @@ -535,3 +491,66 @@ a.read-more-link { .player-box { width: 100%; } /* 1 Spalte auf Handys */ .admin-box { flex-basis: 100%; } /* 1 Spalte auf Handys */ } + +/* Stile für OpenLayers Popups (Leaflet-Look-and-Feel) */ +.ol-popup { + position: absolute; + background-color: #303030; + box-shadow: 0 1px 4px rgba(0,0,0,0.4); + padding: 1px; + border-radius: 5px; + bottom: 12px; + left: -50px; + min-width: 280px; + border: 1px solid #555; + color: #ddd; +} +.ol-popup:after, .ol-popup:before { + top: 100%; + border: solid transparent; + content: " "; + height: 0; + width: 0; + position: absolute; + pointer-events: none; +} +.ol-popup:after { + border-top-color: #303030; + border-width: 10px; + left: 48px; + margin-left: -10px; +} +.ol-popup:before { + border-top-color: #555; + border-width: 11px; + left: 48px; + margin-left: -11px; +} +.ol-popup-closer { + text-decoration: none; + position: absolute; + top: 2px; + right: 8px; + color: #ddd; + font-size: 1.5em; + font-weight: bold; +} +.ol-popup-closer:hover { + color: #fff; +} +.ol-popup-content { + font-size: 13px; + line-height: 1.5; + padding: 10px; + margin: 0; +} +/* Stile für den Inhalt innerhalb des Popups */ +.popup-player-box .player-header { display: flex; align-items: center; margin-bottom: 8px; } +.popup-player-box .player-identity { display: flex; align-items: center; } +.popup-player-box .player-icon { width: 40px; height: 40px; margin-right: 10px; border-radius: 3px; flex-shrink: 0;} +.popup-player-box .player-name-status { display: flex; align-items: center; } +.popup-player-box .player-name { font-weight: bold; font-size: 1.2em; color: #FFD700; margin-left: 5px; } +.popup-player-box .privilege-separator { height: 1px; background-color: #555; border: 0; margin: 8px 0; } +.popup-player-box .popup-player-vitals { display: flex; justify-content: space-around; gap: 10px; align-items: center; margin-top: 8px; } +.popup-player-box .popup-player-vitals .vital { display: flex; align-items: center; gap: 5px; } +.popup-player-box .popup-player-vitals .icon { font-size: 1.2em; } diff --git a/site_generator/templates/html_header.template b/site_generator/templates/html_header.template index 8cc4f1b..458fad9 100755 --- a/site_generator/templates/html_header.template +++ b/site_generator/templates/html_header.template @@ -5,16 +5,13 @@ %%current_page_title%% - %%SITE_TITLE%% - - - - + + + diff --git a/site_generator/templates/world_detail_page.template b/site_generator/templates/world_detail_page.template index 63f6245..2e24b36 100755 --- a/site_generator/templates/world_detail_page.template +++ b/site_generator/templates/world_detail_page.template @@ -1,18 +1,11 @@

%%WORLD_DISPLAY_NAME_PAGE%%

-
X
-
- - +
-
-

Server-Info

-

Status: %%STATUS_TEXT_FALLBACK_PAGE%%

-

Spiel: %%MT_GAMEID%%

-

Kreativmodus: %%creative_text%%

-

Schaden: %%damage_text%%

+

Server-Info

+

Status: %%STATUS_TEXT_FALLBACK_PAGE%%

+

Spiel: %%MT_GAMEID%%

+

Kreativmodus: %%creative_text%%

+

Schaden: %%damage_text%%

+
-

Server-Verbindung

-

Adresse: %%SERVER_ADDRESS_PAGE%%

-

Port: %%SERVER_PORT_PAGE%%

-

Passwort: %%SERVER_ACCESS_INFO_PAGE%%

+

Server-Verbindung

+

Adresse: %%SERVER_ADDRESS_PAGE%%

+

Port: %%SERVER_PORT_PAGE%%

+

Passwort: %%SERVER_ACCESS_INFO_PAGE%%

-

Welt-Admin

-
- %%ADMIN_BOXES_HTML%% -
+

Welt-Admin

+
%%ADMIN_BOXES_HTML%%
- - -
-

Beschreibung

-
- %%WORLD_LONG_DESCRIPTION_PAGE%% -
- -
- -
-

Spielregeln

-
-
- %%WORLD_GAME_RULES_PAGE%% -
- -
-
- -

- Weltradar -
- - -
-

- -
-
-
-
- %%map_sub_info_link%% - Letzte Kartenaktualisierung: wird geladen... -
-
- - -

Verwendete Mods

-
%%MODS_HTML%%
- -

- Spielerliste -
- -
- -
- - - - - - - - - - - -
-
-

-
-

Spielerdaten werden geladen...

-
diff --git a/site_generator/templates/world_detail_playerlist.template b/site_generator/templates/world_detail_playerlist.template new file mode 100644 index 0000000..44313f7 --- /dev/null +++ b/site_generator/templates/world_detail_playerlist.template @@ -0,0 +1,164 @@ +

+ Spielerliste +
+ +
+ +
+ + + + + + + + + + + +
+
+

+
+

Spielerdaten werden geladen...

+
+ + diff --git a/site_generator/templates/world_detail_radar.template b/site_generator/templates/world_detail_radar.template new file mode 100644 index 0000000..ee83e08 --- /dev/null +++ b/site_generator/templates/world_detail_radar.template @@ -0,0 +1,202 @@ +

+ Weltradar +
+ + +
+

+ +
+
+ + +
+ %%map_sub_info_link%% + Letzte Kartenaktualisierung: wird geladen... +
+
+ + + diff --git a/web_content/images/luanti_main_banner.png.old b/web_content/images/luanti_main_banner.png.old deleted file mode 100644 index 970ef5b..0000000 Binary files a/web_content/images/luanti_main_banner.png.old and /dev/null differ diff --git a/web_content/images/players/user_icon.png b/web_content/images/user_icon.png similarity index 100% rename from web_content/images/players/user_icon.png rename to web_content/images/user_icon.png