From 42f854af7f5528dc39b911d2c60f9185d5af0f85 Mon Sep 17 00:00:00 2001 From: SgtMate Date: Mon, 29 Jun 2026 11:00:26 +0200 Subject: [PATCH 1/8] restructure updateGTNH, add updateGTNHRessource --- scripts/start-deployGTNH | 121 ++++++++++++++++++++++----------------- 1 file changed, 68 insertions(+), 53 deletions(-) diff --git a/scripts/start-deployGTNH b/scripts/start-deployGTNH index 820740023fe..11bb01cd270 100755 --- a/scripts/start-deployGTNH +++ b/scripts/start-deployGTNH @@ -70,79 +70,94 @@ function deleteGTNHbackup(){ fi } +function updateGTNHRessource(){ + local resource="$1" + local new_resource="$2" + log "Trying to update $resource" + + if [[ -z "$resource" ]]; then + logWarning "No resource specified for update" + return 0 + fi + + if [[ -d "$resource" ]]; then + log "Deleting folder: $resource" + if ! rm -rf "$resource"; then + logError "Failed to delete folder: $resource" + exit 1 + fi + if [[ -d "$new_resource" ]]; then + log "Copying $new_resource to /data" + if ! cp -r "$new_resource" "/data/"; then + logError "Failed to copy $new_resource to /data" + exit 1 + fi + else + logWarning "Folder $new_resource not found in the unzipped data!" + fi + return 0 + elif [[ -f "$resource" ]]; then + log "Deleting file: $resource" + if ! rm -f "$resource"; then + logError "Failed to delete file: $resource" + exit 1 + fi + if [[ -f "$new_resource" ]]; then + log "Copying $new_resource to /data" + if ! cp "$new_resource" "/data/"; then + logError "Failed to copy $new_resource to /data" + exit 1 + fi + else + logWarning "File $new_resource not found in the unzipped data!" + fi + return 0 + fi + + logWarning "Resource $resource does not exist" + return 0 +} + function updateGTNH(){ # Get the current date and time - current_datetime=$(date +%Y-%m-%dT%H:%M) + local current_datetime=$(date +%Y-%m-%dT%H:%M) # Define folders and files to update - folders_to_update=("libraries" "mods" "resources" "scripts") - files_to_update=("lwjgl3ify-forgePatches.jar" "java9args.txt" "startserver-java9.bat" "startserver-java9.sh" "forge-1.7.10-10.13.4.1614-1.7.10-universal.jar" "startserver.bat" "startserver.sh" "server-icon.png") - config_folder="config" - backup_folder="/data/gtnh-upgrade-$current_datetime" - journey_map_folder="JourneyMapServer" - - # Delete specified folders if they exist - for folder in "${folders_to_update[@]}"; do - folder_path="/data/$folder" - if [[ -d "$folder_path" ]]; then - log "Deleting folder: $folder_path" - rm -rf "$folder_path" - fi - done - - # Delete specific files if they exist - for file in "${files_to_update[@]}"; do - file_path="/data/$file" - if [[ -f "$file_path" ]]; then - log "Deleting file: $file_path" - rm -f "$file_path" - fi - done + # base_dir is already defined in handleGTNH function + local folders_to_update=("libraries" "mods" "resources" "scripts") + local files_to_update=("lwjgl3ify-forgePatches.jar" "java9args.txt" "startserver-java9.bat" "startserver-java9.sh" "forge-1.7.10-10.13.4.1614-1.7.10-universal.jar" "startserver.bat" "startserver.sh" "server-icon.png") + local config_folder="config" + local backup_folder="/data/gtnh-upgrade-$current_datetime" + local journey_map_folder="JourneyMapServer" # Backup the config folder if [[ -d "/data/$config_folder" ]]; then log "Creating backup of /data/$config_folder at $backup_folder" cp -r "/data/$config_folder" "$backup_folder" - log "Deleting original /data/$config_folder" - rm -rf "/data/$config_folder" fi - # Updating the required folders in data directory - for folder in "${folders_to_update[@]}" "$config_folder"; do - if [[ -d "$base_dir/$folder" ]]; then - log "Copying $folder to /data" - cp -r "$base_dir/$folder" "/data/" - else - logWarning "Folder $folder not found in the unzipped data!" - fi - done - - # Copy specific files to the /data directory - for file in "${files_to_update[@]}"; do - if [[ -f "$base_dir/$file" ]]; then - log "Copying $file to /data" - cp "$base_dir/$file" "/data/" - else - logWarning "File $file not found in the unzipped data!" - fi - done +# Update ressources from unpacked server files to /data + for ressource in "${folders_to_update[@]}" "$config_folder ${files_to_update[@]}"; do + local resource_path="/data/$ressource" + local new_resource_path="$base_dir/$ressource" - # Ensure the config folder exists - if [[ ! -d "$config_folder" ]]; then - log "$config_folder does not exist. Creating it now." - mkdir -p "$config_folder" - fi + updateGTNHRessource "$resource_path" "$new_resource_path" + done # Restore JourneyMapServer folder from backup if [[ -d "$backup_folder/$journey_map_folder" ]]; then - log "Restoring $journey_map_folder to $config_folder" - cp -r "$backup_folder/$journey_map_folder" "$config_folder/" + if [[ ! -d "/data/$config_folder" ]]; then + log "/data/$config_folder folder does not exist. Creating it now." + mkdir -p "/data/$config_folder" + fi + log "Restoring $journey_map_folder to /data/$config_folder" + cp -r "$backup_folder/$journey_map_folder" "/data/$config_folder/" else logWarning "$journey_map_folder not found in backup!" fi # Copy the changelog file to /data - gtnh_changelog_file=$(mc-image-helper find --max-depth=1 --type=file --name=changelog*.md "$base_dir") + local gtnh_changelog_file=$(mc-image-helper find --max-depth=1 --type=file --name=changelog*.md "$base_dir") if [[ -n "$gtnh_changelog_file" ]]; then log "Copying changelog file to /data" cp -f "$gtnh_changelog_file" /data/ From 460f976e429e1d7a2b80566b5fc7155db307f426 Mon Sep 17 00:00:00 2001 From: SgtMate Date: Mon, 29 Jun 2026 15:55:55 +0200 Subject: [PATCH 2/8] simplify handleGTNH, add downloadGTNH, better logs --- scripts/start-deployGTNH | 86 +++++++++++++++++++++++----------------- 1 file changed, 49 insertions(+), 37 deletions(-) diff --git a/scripts/start-deployGTNH b/scripts/start-deployGTNH index 11bb01cd270..db5c130e5b9 100755 --- a/scripts/start-deployGTNH +++ b/scripts/start-deployGTNH @@ -59,6 +59,10 @@ function getGTNHdownloadPath(){ fi + if [[ -z $gtnh_download_path ]]; then + logError "Server files not found! Please check if the selected GTNH_PACK_VERSION=$GTNH_PACK_VERSION is valid." + exit 1 + fi debug "Download source URL: $gtnh_download_path" } @@ -70,6 +74,41 @@ function deleteGTNHbackup(){ fi } +function downloadGTNH(){ + local gtnh_download="" + base_dir=/data/.tmp/gtnh_base + + debug "Creating temporary /data/.tmp/packs folder for GTNH download" + mkdir -p /data/.tmp/packs + trap 'rm -rf /data/.tmp' EXIT + + log "Downloading $gtnh_download_path." + if ! gtnh_download=$(mc-image-helper get -o /data/.tmp/packs --output-filename --skip-up-to-date "$gtnh_download_path"); then + logError "Failed to download $gtnh_download_path" + exit 1 + fi + debug "Downloaded GTNH server files to $gtnh_download" + + # Unpacking Server files into temporary directory + log "Unpacking Server Files into $base_dir" + mkdir -p "${base_dir}" + extract "${gtnh_download}" "${base_dir}" + + # Remove any eula file since container manages it + debug "Removing eula.txt from $base_dir" + rm -f "${base_dir}/eula.txt" + + # recalculate the actual base directory of content + if ! base_dir=$(mc-image-helper find \ + --max-depth=3 --type=directory --name=mods,config \ + --only-shallowest --fail-no-matches --format '%h' \ + "$base_dir"); then + logError "Unable to find content base of downloaded Server Files" + exit 1 + fi + debug "Base directory of unpacked Server Files: $base_dir" +} + function updateGTNHRessource(){ local resource="$1" local new_resource="$2" @@ -141,6 +180,7 @@ function updateGTNH(){ local resource_path="/data/$ressource" local new_resource_path="$base_dir/$ressource" + debug "Updating resource: $resource_path with new resource: $new_resource_path" updateGTNHRessource "$resource_path" "$new_resource_path" done @@ -159,6 +199,7 @@ function updateGTNH(){ # Copy the changelog file to /data local gtnh_changelog_file=$(mc-image-helper find --max-depth=1 --type=file --name=changelog*.md "$base_dir") if [[ -n "$gtnh_changelog_file" ]]; then + debug "Found changelog file: $gtnh_changelog_file" log "Copying changelog file to /data" cp -f "$gtnh_changelog_file" /data/ fi @@ -178,46 +219,15 @@ function handleGTNH() { if [[ -n "$GTNH_PACK_VERSION" ]] && isFalse "$SKIP_GTNH_UPDATE_CHECK" ; then getGTNHdownloadPath - - if [[ -z $gtnh_download_path ]]; then - logError "Server files not found for GTNH_PACK_VERSION=$GTNH_PACK_VERSION! Download not possible!" - exit 1 - fi log "Server files located! Will proceed update $gtnh_download_path." + # Decide if update or install is needed or not. - if [[ ! -f /data/.gtnh-version || "$(basename "$gtnh_download_path")" != "$(cat /data/.gtnh-version)" ]]; then + if [[ ! -f /data/.gtnh-version || "$(basename "$gtnh_dDecideownload_path")" != "$(cat /data/.gtnh-version)" ]]; then log "Update/Install required: /data/.gtnh-version is missing or does not match the selected version $(basename "$gtnh_download_path")." - mkdir -p /data/packs - log "Downloading $gtnh_download_path." - if ! gtnh_download=$(mc-image-helper get -o /data/packs --output-filename --skip-up-to-date "$gtnh_download_path"); then - logError "Failed to download $gtnh_download_path" - exit 1 - fi - - # Unpacking Server files into temporary directory - log "Unpacking Server Files..." - original_base_dir=/data/.tmp/gtnh_base - base_dir=$original_base_dir - rm -rf "${base_dir}" - mkdir -p "${base_dir}" - extract "${gtnh_download}" "${base_dir}" - trap 'rm -rf /data/.tmp' EXIT - # Removing downloaded zip - rm -f "$gtnh_download" - - # Remove any eula file since container manages it - rm -f "${base_dir}/eula.txt" - - # recalculate the actual base directory of content - if ! base_dir=$(mc-image-helper find \ - --max-depth=3 --type=directory --name=mods,config \ - --only-shallowest --fail-no-matches --format '%h' \ - "$base_dir"); then - logError "Unable to find content base of downloaded Server Files" - exit 1 - fi + # Download and unpack GTNH server files + downloadGTNH # Split installation from update path. Check for version file. if [[ -f /data/.gtnh-version ]]; then @@ -227,10 +237,12 @@ function handleGTNH() { log "No .gtnh-version file detected! Assuming no old server exists. Proceed installing new server..." cp -R -f "${base_dir}"/* /data fi + # Update .gtnh-version basename "$gtnh_download_path" > /data/.gtnh-version - # Cleaning up - rm -rf "$original_base_dir" + + # Cleaning up temporary files + rm -rf /data/.tmp else log "No update required: /data/.gtnh-version matches the selected version $(basename "$gtnh_download_path")." From af692ce7392c14315c3ed623b601cc0cb2a227cc Mon Sep 17 00:00:00 2001 From: SgtMate Date: Mon, 29 Jun 2026 16:16:14 +0200 Subject: [PATCH 3/8] small log addition --- scripts/start-deployGTNH | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/scripts/start-deployGTNH b/scripts/start-deployGTNH index db5c130e5b9..ed42f1aea88 100755 --- a/scripts/start-deployGTNH +++ b/scripts/start-deployGTNH @@ -228,6 +228,7 @@ function handleGTNH() { # Download and unpack GTNH server files downloadGTNH + log "GTNH server files downloaded and unpacked to $base_dir." # Split installation from update path. Check for version file. if [[ -f /data/.gtnh-version ]]; then @@ -240,7 +241,7 @@ function handleGTNH() { # Update .gtnh-version basename "$gtnh_download_path" > /data/.gtnh-version - + # Cleaning up temporary files rm -rf /data/.tmp From 2c27ae91ed0b10dd6403c5e2e8cd2ffebf74d2c8 Mon Sep 17 00:00:00 2001 From: Leon Kampwerth <77398841+SgtMate@users.noreply.github.com> Date: Tue, 30 Jun 2026 22:57:36 +0200 Subject: [PATCH 4/8] small fixes and improved ressource updating logic --- scripts/start-deployGTNH | 45 ++++++++++++++++------------------------ 1 file changed, 18 insertions(+), 27 deletions(-) diff --git a/scripts/start-deployGTNH b/scripts/start-deployGTNH index ed42f1aea88..df4b617ee35 100755 --- a/scripts/start-deployGTNH +++ b/scripts/start-deployGTNH @@ -119,41 +119,32 @@ function updateGTNHRessource(){ return 0 fi - if [[ -d "$resource" ]]; then - log "Deleting folder: $resource" + if [[ -e "$resource" ]]; then + log "Deleting existing resource: $resource" if ! rm -rf "$resource"; then - logError "Failed to delete folder: $resource" + logError "Failed to delete resource: $resource" exit 1 fi - if [[ -d "$new_resource" ]]; then - log "Copying $new_resource to /data" - if ! cp -r "$new_resource" "/data/"; then - logError "Failed to copy $new_resource to /data" - exit 1 - fi - else - logWarning "Folder $new_resource not found in the unzipped data!" + fi + + if [[ -d "$new_resource" ]]; then + log "Copying $new_resource to /data" + if ! cp -r "$new_resource" "/data/"; then + logError "Failed to copy $new_resource to /data" + exit 1 fi return 0 - elif [[ -f "$resource" ]]; then - log "Deleting file: $resource" - if ! rm -f "$resource"; then - logError "Failed to delete file: $resource" + fi + if [[ -f "$new_resource" ]]; then + log "Copying $new_resource to /data" + if ! cp "$new_resource" "/data/"; then + logError "Failed to copy $new_resource to /data" exit 1 fi - if [[ -f "$new_resource" ]]; then - log "Copying $new_resource to /data" - if ! cp "$new_resource" "/data/"; then - logError "Failed to copy $new_resource to /data" - exit 1 - fi - else - logWarning "File $new_resource not found in the unzipped data!" - fi return 0 fi - logWarning "Resource $resource does not exist" + logWarning "Resource $resource does not exist and $new_resource was not found in the unzipped data!" return 0 } @@ -176,7 +167,7 @@ function updateGTNH(){ fi # Update ressources from unpacked server files to /data - for ressource in "${folders_to_update[@]}" "$config_folder ${files_to_update[@]}"; do + for ressource in "${folders_to_update[@]}" "$config_folder" "${files_to_update[@]}"; do local resource_path="/data/$ressource" local new_resource_path="$base_dir/$ressource" @@ -223,7 +214,7 @@ function handleGTNH() { # Decide if update or install is needed or not. - if [[ ! -f /data/.gtnh-version || "$(basename "$gtnh_dDecideownload_path")" != "$(cat /data/.gtnh-version)" ]]; then + if [[ ! -f /data/.gtnh-version || "$(basename "$gtnh_download_path")" != "$(cat /data/.gtnh-version)" ]]; then log "Update/Install required: /data/.gtnh-version is missing or does not match the selected version $(basename "$gtnh_download_path")." # Download and unpack GTNH server files From 2cbef57c6026d642e7c2a5a0230dfe2d617aa503 Mon Sep 17 00:00:00 2001 From: Leon Kampwerth <77398841+SgtMate@users.noreply.github.com> Date: Tue, 30 Jun 2026 23:01:31 +0200 Subject: [PATCH 5/8] cosmetics for new variables --- scripts/start-deployGTNH | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/scripts/start-deployGTNH b/scripts/start-deployGTNH index df4b617ee35..7f23b215259 100755 --- a/scripts/start-deployGTNH +++ b/scripts/start-deployGTNH @@ -7,7 +7,8 @@ function getGTNHdownloadPath(){ gtnh_download_path="" local release_object="" - local current_java_version=$(mc-image-helper java-release) + local current_java_version="" + current_java_version=$(mc-image-helper java-release) # Select release JSON object if [ "$GTNH_PACK_VERSION" == "latest-dev" ]; then @@ -150,7 +151,8 @@ function updateGTNHRessource(){ function updateGTNH(){ # Get the current date and time - local current_datetime=$(date +%Y-%m-%dT%H:%M) + local current_datetime="" + current_datetime=$(date +%Y-%m-%dT%H:%M) # Define folders and files to update # base_dir is already defined in handleGTNH function @@ -188,7 +190,8 @@ function updateGTNH(){ fi # Copy the changelog file to /data - local gtnh_changelog_file=$(mc-image-helper find --max-depth=1 --type=file --name=changelog*.md "$base_dir") + local gtnh_changelog_file="" + gtnh_changelog_file=$(mc-image-helper find --max-depth=1 --type=file --name=changelog*.md "$base_dir") if [[ -n "$gtnh_changelog_file" ]]; then debug "Found changelog file: $gtnh_changelog_file" log "Copying changelog file to /data" From 779818ea1f74f121b20e5c9c2035465252e82b72 Mon Sep 17 00:00:00 2001 From: Leon Kampwerth <77398841+SgtMate@users.noreply.github.com> Date: Wed, 1 Jul 2026 00:46:48 +0200 Subject: [PATCH 6/8] small cosmetic changes and new checks --- compose-dev.yml | 9 +++++++++ scripts/start-deployGTNH | 21 +++++++++++++-------- 2 files changed, 22 insertions(+), 8 deletions(-) diff --git a/compose-dev.yml b/compose-dev.yml index d60a2ab4fc6..648c61b87dc 100644 --- a/compose-dev.yml +++ b/compose-dev.yml @@ -4,6 +4,15 @@ services: context: . environment: EULA: true + TYPE: GTNH + GTNH_PACK_VERSION: latest-dev + # Enable to delete old config backups + # GTNH_DELETE_BACKUPS: false + # Use to prevent updates + # SKIP_GTNH_UPDATE_CHECK: true + DEBUG: true + MEMORY: 6G + # Bring in st volumes: - ./scripts:/image/scripts:ro - data:/data diff --git a/scripts/start-deployGTNH b/scripts/start-deployGTNH index 7f23b215259..1b03ad36ff1 100755 --- a/scripts/start-deployGTNH +++ b/scripts/start-deployGTNH @@ -39,6 +39,11 @@ function getGTNHdownloadPath(){ log "Selected $(jq -r '.key' <<< "$release_object") as matching version for download." fi + + if [[ -z $release_object ]]; then + logError "No release found for GTNH_PACK_VERSION=$GTNH_PACK_VERSION. Please check if the version is valid." + exit 1 + fi # Select compatible server files for java version if (( current_java_version == 8 )); then @@ -110,7 +115,7 @@ function downloadGTNH(){ debug "Base directory of unpacked Server Files: $base_dir" } -function updateGTNHRessource(){ +function updateGTNHresource(){ local resource="$1" local new_resource="$2" log "Trying to update $resource" @@ -145,14 +150,14 @@ function updateGTNHRessource(){ return 0 fi - logWarning "Resource $resource does not exist and $new_resource was not found in the unzipped data!" + logWarning "Resource update failed: $new_resource does not exist!" return 0 } function updateGTNH(){ # Get the current date and time local current_datetime="" - current_datetime=$(date +%Y-%m-%dT%H:%M) + current_datetime=$(date +%Y-%m-%dT+%H%M) # Define folders and files to update # base_dir is already defined in handleGTNH function @@ -168,13 +173,13 @@ function updateGTNH(){ cp -r "/data/$config_folder" "$backup_folder" fi -# Update ressources from unpacked server files to /data - for ressource in "${folders_to_update[@]}" "$config_folder" "${files_to_update[@]}"; do - local resource_path="/data/$ressource" - local new_resource_path="$base_dir/$ressource" +# Update resources from unpacked server files to /data + for resource in "${folders_to_update[@]}" "$config_folder" "${files_to_update[@]}"; do + local resource_path="/data/$resource" + local new_resource_path="$base_dir/$resource" debug "Updating resource: $resource_path with new resource: $new_resource_path" - updateGTNHRessource "$resource_path" "$new_resource_path" + updateGTNHresource "$resource_path" "$new_resource_path" done # Restore JourneyMapServer folder from backup From ba2c652838da7a5ba8911a4c769bd41ecfe73c5a Mon Sep 17 00:00:00 2001 From: Leon Kampwerth <77398841+SgtMate@users.noreply.github.com> Date: Wed, 1 Jul 2026 00:47:34 +0200 Subject: [PATCH 7/8] change back compose-dev --- compose-dev.yml | 9 --------- 1 file changed, 9 deletions(-) diff --git a/compose-dev.yml b/compose-dev.yml index 648c61b87dc..d60a2ab4fc6 100644 --- a/compose-dev.yml +++ b/compose-dev.yml @@ -4,15 +4,6 @@ services: context: . environment: EULA: true - TYPE: GTNH - GTNH_PACK_VERSION: latest-dev - # Enable to delete old config backups - # GTNH_DELETE_BACKUPS: false - # Use to prevent updates - # SKIP_GTNH_UPDATE_CHECK: true - DEBUG: true - MEMORY: 6G - # Bring in st volumes: - ./scripts:/image/scripts:ro - data:/data From e6a5dd881d76521dc47adbb0447990b2ff2f9b41 Mon Sep 17 00:00:00 2001 From: Leon Kampwerth <77398841+SgtMate@users.noreply.github.com> Date: Wed, 1 Jul 2026 00:51:07 +0200 Subject: [PATCH 8/8] improve gtnh backup documentation --- docs/types-and-platforms/mod-platforms/gtnh.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/types-and-platforms/mod-platforms/gtnh.md b/docs/types-and-platforms/mod-platforms/gtnh.md index fdbaff6432f..8b9a6266ab4 100644 --- a/docs/types-and-platforms/mod-platforms/gtnh.md +++ b/docs/types-and-platforms/mod-platforms/gtnh.md @@ -35,7 +35,7 @@ For optimal performance choose java25 with GTNH 2.8.0 and later. ## Config backups -During version upgrade, the server will replace all config files to make sure all new features are setup as intended. The old config files are stored in a backup folder in the data directory, for you to use as reference for manual reapplication of your changed settings. Set the environment variable `GTNH_DELETE_BACKUPS` to true to delete all backup folders at startup. +During version upgrade, the server will replace all config files to make sure all new features are setup as intended. The old config files are stored in a backup folder in the data directory, for you to use as reference for manual reapplication of your changed settings. The folder name starts with `gtnh-upgrade-` followed by a timestamp. Set the environment variable `GTNH_DELETE_BACKUPS` to true to delete all backup folders at startup. ## server.properties defaults