Update Hytale egg startup, downloader, and AOT handling

- Pin Java runtime to Temurin 25.0.2 JRE for current server compatibility
- Generate HytaleServer.aot locally from HytaleServer.aot.config
- Add configurable AOT JVM arguments for Pelican and Pterodactyl
- Use AOT cache only when the generated cache exists
- Detect Hytale jar/AOT config timestamp mismatch and show a clear warning
- Add hytale-downloader self-update support
- Force the egg-managed start.sh back into place before startup runs
- Preserve panel startup overrides through the STARTUP command
- Preserve hidden files when moving extracted Server contents
- Update README and egg metadata for generated AOT cache behavior
This commit is contained in:
NATroutter
2026-06-18 00:17:53 +03:00
parent 30284d1b01
commit a98ab6465a
8 changed files with 166 additions and 23 deletions

View File

@@ -1,5 +1,4 @@
# Use Eclipse Temurin JDK 25 on Ubuntu Noble as the base image
FROM --platform=$TARGETOS/$TARGETARCH eclipse-temurin:25-jdk-noble
FROM --platform=$TARGETOS/$TARGETARCH eclipse-temurin:25.0.2_10-jre-noble
# Metadata
LABEL author="NATroutter" maintainer="contact@natroutter.fi"

View File

@@ -31,7 +31,7 @@ Both Pelican Panel and Pterodactyl Panel are fully supported with dedicated egg
- Multi-architecture support (x86_64 & ARM64)
- Automatic `hytale-sourcequery` plugin installation (Optional)
- Built-in server validation tools (World, Assets, Prefabs)
- Performance optimizations via AOT Cache support
- Performance optimizations via locally generated AOT cache support
- Configurable server parameters and JVM arguments
- Integrated backup management system
- Multiple authentication modes (Standard & GSP)
@@ -112,7 +112,8 @@ The following options can be configured:
| `Event Debug` | Enables detailed debug logging for the internal event system. | `false` |
| `Force Network Flush` | Forces the network buffer to flush immediately. Can help with latency debugging. | `false` |
| `JVM Arguments` | Additional Java Virtual Machine arguments for advanced configuration. | See egg config |
| `Leverage Ahead-Of-Time Cache` | The server ships with a pre-trained AOT cache (HytaleServer.aot) that improves boot times by skipping JIT warmup | `true` |
| `AOT JVM Arguments` | JVM arguments used only while generating `HytaleServer.aot` from `HytaleServer.aot.config`. | See egg config |
| `Leverage Ahead-Of-Time Cache` | Generates and uses a local AOT cache (`HytaleServer.aot`) from the server-provided `HytaleServer.aot.config` to improve boot and warmup time. | `true` |
| `Disable Sentry Crash Reporting` | Disable Sentry during active plugin development. Hytale uses Sentry to track crashes. Disable it to avoid submitting your development errors | `true` |
| `Enable Backups` | Enable automatic backups | `false` |
| `Backup Frequency` | Backup interval in minutes | `30` |

File diff suppressed because one or more lines are too long

View File

@@ -114,7 +114,17 @@
"name": "JVM Arguments",
"description": "Additional Java Virtual Machine arguments for advanced configuration.\r\n\r\nWarning: Improper JVM settings can lead to poor performance, crashes, or failure to start. Only modify if you understand what these parameters do.",
"env_variable": "JVM_ARGS",
"default_value": "-XX:+UseCompressedOops -XX:+UseCompressedClassPointers -XX:-UseCompactObjectHeaders -XX:+UseG1GC -XX:+UseStringDeduplication -Xlog:aot",
"default_value": "-XX:+UseCompressedOops -XX:+UseCompressedClassPointers -XX:+UseCompactObjectHeaders -XX:+UseG1GC -XX:+UseStringDeduplication -Xlog:aot",
"user_viewable": true,
"user_editable": true,
"rules": "nullable|string",
"field_type": "text"
},
{
"name": "AOT JVM Arguments",
"description": "Java Virtual Machine arguments used only while generating HytaleServer.aot from HytaleServer.aot.config. Keep these compatible with production JVM arguments that affect class loading, linking, object layout, agents, or module access.",
"env_variable": "AOT_JVM_ARGS",
"default_value": "-XX:+UseCompressedOops -XX:+UseCompressedClassPointers -XX:+UseCompactObjectHeaders -XX:+UseG1GC -XX:+UseStringDeduplication -Xlog:aot",
"user_viewable": true,
"user_editable": true,
"rules": "nullable|string",
@@ -122,7 +132,7 @@
},
{
"name": "Leverage Ahead-Of-Time Cache",
"description": "The server ships with a pre-trained AOT cache (HytaleServer.aot) that improves boot times by skipping JIT warmup. See https:\/\/openjdk.org\/jeps\/514",
"description": "Generate and use a local AOT cache (HytaleServer.aot) from the server-provided HytaleServer.aot.config to improve boot and warmup time. See https:\/\/openjdk.org\/jeps\/514",
"env_variable": "LEVERAGE_AHEAD_OF_TIME_CACHE",
"default_value": "1",
"user_viewable": true,
@@ -301,4 +311,4 @@
"field_type": "text"
}
]
}
}

View File

@@ -5,6 +5,12 @@ source "/egg-hytale/lib/system.sh"
source "/egg-hytale/lib/downloader.sh"
source "/egg-hytale/lib/plugins.sh"
copy_startup_template() {
logger info "Copying start.sh template to /home/container..."
cp -f /usr/local/bin/start.sh start.sh
chmod 755 start.sh
}
DOWNLOAD_URL="https://downloader.hytale.com/hytale-downloader.zip"
PATCHLINE_CACHE_FILE=".patchline-cache.txt"
DOWNLOAD_FILE="hytale-downloader.zip"
@@ -21,13 +27,9 @@ echo " "
detect_architecture
setup_environment
# Copy start.sh template to /home/container
logger info "Copying start.sh template to /home/container..."
cp -f /usr/local/bin/start.sh start.sh
chmod 755 start.sh
setup_backup_directory
ensure_downloader
update_downloader
create_system_files
@@ -35,6 +37,7 @@ ensure_system_file_permissions
run_update_process
validate_server_files
ensure_aot_cache
install_sourcequery
@@ -80,8 +83,11 @@ export IDENTITY_TOKEN
# Enforce file and folder permissions if enabled
enforce_permissions
copy_startup_template
logger info "Starting Hytale server..."
# Convert startup variables to from {{VARIABLE}} to ${VARIABLE} for the evaluating
# Convert startup variables from {{VARIABLE}} to ${VARIABLE} for evaluation.
# The managed start.sh is copied after updates, so the default ./start.sh stays egg-owned.
PARSED=$(echo "$STARTUP" | sed -e 's/{{/${/g' -e 's/}}/}/g')
eval "$PARSED"
eval "$PARSED"

View File

@@ -13,6 +13,120 @@ ensure_downloader() {
fi
}
update_downloader() {
local UPDATE_OUTPUT=""
local TEMP_DIR=""
local UPDATED=0
logger info "Checking hytale-downloader for updates..."
UPDATE_OUTPUT=$($DOWNLOADER -check-update 2>&1)
if [ $? -ne 0 ]; then
logger warn "Failed to check hytale-downloader updates; continuing with installed downloader."
return 0
fi
if ! printf "%s" "$UPDATE_OUTPUT" | grep -q "A new version of hytale-downloader is available"; then
logger info "hytale-downloader is up to date."
return 0
fi
logger warn "A newer hytale-downloader is available, updating..."
TEMP_DIR=$(mktemp -d)
if [ -z "$TEMP_DIR" ] || [ ! -d "$TEMP_DIR" ]; then
logger warn "Failed to create temporary directory for hytale-downloader update."
return 0
fi
if curl -fsSL -o "$TEMP_DIR/$DOWNLOAD_FILE" "$DOWNLOAD_URL" \
&& unzip -oq "$TEMP_DIR/$DOWNLOAD_FILE" -d "$TEMP_DIR"; then
if [ -f "$TEMP_DIR/hytale-downloader-linux-amd64" ]; then
cp -f "$TEMP_DIR/hytale-downloader-linux-amd64" ./hytale-downloader-linux-amd64
chmod +x ./hytale-downloader-linux-amd64
UPDATED=1
fi
if [ -f "$TEMP_DIR/hytale-downloader-linux-arm64" ]; then
cp -f "$TEMP_DIR/hytale-downloader-linux-arm64" ./hytale-downloader-linux-arm64
chmod +x ./hytale-downloader-linux-arm64
UPDATED=1
elif [ -f ./hytale-downloader-linux-arm64 ]; then
chmod +x ./hytale-downloader-linux-arm64
fi
else
logger warn "Failed to download or extract hytale-downloader update; continuing with installed downloader."
fi
rm -rf "$TEMP_DIR"
if [ "$UPDATED" = "1" ]; then
logger success "hytale-downloader updated successfully."
else
logger warn "hytale-downloader update did not include an expected linux binary; continuing with installed downloader."
fi
}
ensure_aot_cache() {
local AOT_CONFIG_FILE="HytaleServer.aot.config"
local AOT_CACHE_FILE="HytaleServer.aot"
local AOT_LOG_FILE=""
local AOT_STATUS=0
if [ "$LEVERAGE_AHEAD_OF_TIME_CACHE" != "1" ]; then
return 0
fi
if [ ! -f "$AOT_CONFIG_FILE" ]; then
logger warn "AOT config not found, skipping AOT cache generation."
return 0
fi
if [ -f "$AOT_CACHE_FILE" ] && [ "$AOT_CACHE_FILE" -nt "$AOT_CONFIG_FILE" ]; then
logger info "AOT cache is up to date."
return 0
fi
logger info "Generating AOT cache from $AOT_CONFIG_FILE..."
rm -f "$AOT_CACHE_FILE"
AOT_LOG_FILE=$(mktemp)
if [ -z "$AOT_LOG_FILE" ]; then
logger warn "Failed to create temporary AOT log file."
return 0
fi
java ${AOT_JVM_ARGS} -XX:-AOTClassLinking -XX:AOTMode=create -XX:AOTConfiguration="$AOT_CONFIG_FILE" -XX:AOTCacheOutput="$AOT_CACHE_FILE" -cp HytaleServer.jar 2>&1 | tee "$AOT_LOG_FILE"
AOT_STATUS=${PIPESTATUS[0]}
if [ "$AOT_STATUS" -eq 0 ]; then
logger success "AOT cache generated successfully."
else
if grep -q "timestamp has changed" "$AOT_LOG_FILE"; then
printc "{MAGENTA}╔═════════════════════════════════════════════════════════════════════════════╗"
printc "{MAGENTA}║ {YELLOW}AOT CACHE SKIPPED: HYTALE FILE MISMATCH {MAGENTA}║"
printc "{MAGENTA}╠═════════════════════════════════════════════════════════════════════════════╣"
printc "{MAGENTA}║ ║"
printc "{MAGENTA}║ {CYAN}The Hytale server files include an AOT config that does not match {MAGENTA}║"
printc "{MAGENTA}║ {CYAN}the server jar shipped in this download. {MAGENTA}║"
printc "{MAGENTA}║ ║"
printc "{MAGENTA}║ {CYAN}This usually means the Hytale developers updated HytaleServer.jar {MAGENTA}║"
printc "{MAGENTA}║ {CYAN}but shipped an older or mismatched HytaleServer.aot.config file. {MAGENTA}║"
printc "{MAGENTA}║ ║"
printc "{MAGENTA}║ {CYAN}This is not an egg issue. The server will continue without AOT cache {MAGENTA}║"
printc "{MAGENTA}║ {CYAN}and AOT should work once Hytale ships matching files. {MAGENTA}║"
printc "{MAGENTA}║ ║"
printc "{MAGENTA}╚═════════════════════════════════════════════════════════════════════════════╝"
fi
logger warn "AOT cache generation failed; the server will start without AOT cache."
rm -f "$AOT_CACHE_FILE"
fi
rm -f "$AOT_LOG_FILE"
}
run_update_process() {
local INITIAL_SETUP=0
@@ -115,7 +229,7 @@ run_auto_update() {
if [ -n "$LOCAL_VERSION" ]; then
logger info "Local version: $LOCAL_VERSION"
fi
logger info "Downloader version: $DOWNLOADER_VERSION"
logger info "Available version: $DOWNLOADER_VERSION"
if [ "$LOCAL_VERSION" != "$DOWNLOADER_VERSION" ]; then
logger warn "Version mismatch, running update..."
@@ -155,4 +269,4 @@ validate_server_files() {
logger error "Server files were not downloaded correctly."
exit 1
fi
}
}

View File

@@ -66,7 +66,7 @@ extract_server_files() {
# Move contents from Server folder to current directory
if [ -d "Server" ]; then
logger info "Moving server files from Server directory..."
cp -rf Server/* .
cp -a Server/. .
rm -rf ./Server
logger success "Server files moved to root directory."
fi

View File

@@ -14,7 +14,7 @@
JAVA_CMD="java"
# Add AOT cache if enabled
if [ "${LEVERAGE_AHEAD_OF_TIME_CACHE}" = "1" ]; then
if [ "${LEVERAGE_AHEAD_OF_TIME_CACHE}" = "1" ] && [ -f "HytaleServer.aot" ]; then
JAVA_CMD="${JAVA_CMD} -XX:AOTCache=HytaleServer.aot"
fi
@@ -104,4 +104,4 @@ JAVA_CMD="${JAVA_CMD} --bind 0.0.0.0:${SERVER_PORT}"
# Execute the command
#echo $JAVA_CMD
eval $JAVA_CMD
eval $JAVA_CMD