#!/bin/bash # shellcheck source=start-utils . "${SCRIPTS:-$(dirname "$0")}/start-utils" set -o pipefail set -e isDebugging && set -x # Pumpkin is released as a native executable per platform case "$(uname -m)" in x86_64 | amd64) pumpkinArch=X64 ;; aarch64 | arm64) pumpkinArch=ARM64 ;; *) logError "Pumpkin does not provide a Linux build for $(uname -m)" exit 1 ;; esac pumpkinAsset="pumpkin-${pumpkinArch}-Linux" # The Alpine based image needs the musl linked build if [[ $(getDistro) == alpine ]]; then pumpkinAsset+="-musl" fi if isTrue "${FORCE_REDOWNLOAD:-false}"; then log "Forcing re-download of ${pumpkinAsset}" rm -f "/data/${pumpkinAsset}" fi if ! SERVER=$(mc-image-helper github download-latest-asset \ --output-directory=/data \ --name-pattern="^${pumpkinAsset}$" \ Pumpkin-MC/Pumpkin ); then logError "Failed to download ${pumpkinAsset} from the latest Pumpkin release" exit 1 fi log "Using Pumpkin server executable ${SERVER}" if [[ ! -x "${SERVER}" ]]; then chmod +x "${SERVER}" fi export SERVER # Native executable, so the final exec skips the JVM handling export FAMILY=NATIVE pumpkinConfig=/data/pumpkin.toml # Narrow booleans to the values that the patch bool conversion accepts function exportBoolean() { local target=$1 local source=$2 if [[ -v $source ]]; then local value=false if isTrue "${!source}"; then value=true fi printf -v "$target" '%s' "$value" export "$target" fi } function exportInteger() { local target=$1 local source=$2 if [[ -v $source ]] && isNumeric "${!source}"; then printf -v "$target" '%s' "${!source}" export "$target" fi } function normalizeGamemode() { case "${1,,}" in 0 | su*) echo Survival ;; 1 | c*) echo Creative ;; 2 | a*) echo Adventure ;; 3 | sp*) echo Spectator ;; *) echo "$1" ;; esac } function normalizeDifficulty() { case "${1,,}" in 0 | p*) echo Peaceful ;; 1 | e*) echo Easy ;; 2 | n*) echo Normal ;; 3 | h*) echo Hard ;; *) echo "$1" ;; esac } exportBoolean PUMPKIN_ONLINE_MODE ONLINE_MODE exportBoolean PUMPKIN_HARDCORE HARDCORE exportBoolean PUMPKIN_ALLOW_NETHER ALLOW_NETHER exportBoolean PUMPKIN_FORCE_GAMEMODE FORCE_GAMEMODE exportBoolean PUMPKIN_ENFORCE_WHITELIST ENFORCE_WHITELIST exportBoolean PUMPKIN_ACCEPTS_TRANSFERS ACCEPTS_TRANSFERS exportBoolean PUMPKIN_PREVENT_PROXY_CONNECTIONS PREVENT_PROXY_CONNECTIONS exportBoolean PUMPKIN_PVP PVP exportBoolean PUMPKIN_ENABLE_RCON ENABLE_RCON exportBoolean PUMPKIN_ENABLE_QUERY ENABLE_QUERY exportBoolean PUMPKIN_RESOURCE_PACK_ENFORCE RESOURCE_PACK_ENFORCE exportInteger PUMPKIN_MAX_PLAYERS MAX_PLAYERS exportInteger PUMPKIN_VIEW_DISTANCE VIEW_DISTANCE exportInteger PUMPKIN_SIMULATION_DISTANCE SIMULATION_DISTANCE exportInteger PUMPKIN_OP_PERMISSION_LEVEL OP_PERMISSION_LEVEL exportInteger PUMPKIN_SPAWN_PROTECTION SPAWN_PROTECTION if [[ -v MODE ]]; then PUMPKIN_GAMEMODE=$(normalizeGamemode "$MODE") export PUMPKIN_GAMEMODE fi if [[ -v DIFFICULTY ]]; then PUMPKIN_DIFFICULTY=$(normalizeDifficulty "$DIFFICULTY") export PUMPKIN_DIFFICULTY fi # The image enables the whitelist whenever one is provided if [[ -v WHITELIST || -v WHITELIST_FILE ]]; then export PUMPKIN_WHITE_LIST=true else exportBoolean PUMPKIN_WHITE_LIST ENABLE_WHITELIST fi if [[ -v RESOURCE_PACK ]]; then export PUMPKIN_RESOURCE_PACK_ENABLED=true fi # Only override the listening addresses when a port was declared if [[ -v SERVER_PORT ]]; then export PUMPKIN_JAVA_ADDRESS="0.0.0.0:${SERVER_PORT}" fi if [[ -v RCON_PORT ]]; then export PUMPKIN_RCON_ADDRESS="0.0.0.0:${RCON_PORT}" fi if [[ -v QUERY_PORT ]]; then export PUMPKIN_QUERY_ADDRESS="0.0.0.0:${QUERY_PORT}" fi if [[ ! -f "$pumpkinConfig" ]]; then log "Creating initial Pumpkin configuration" cp /image/pumpkin.toml "$pumpkinConfig" fi log "Applying Pumpkin configuration from environment variables" # Undeclared variables only warn, so only surface failures if ! pumpkinPatchResult=$(mc-image-helper patch --patch-env-prefix "" /image/pumpkin-config-patch.json 2>&1); then logWarning "Failed to apply one or more settings to ${pumpkinConfig}" echo "$pumpkinPatchResult" | applyLogPrefix fi exec "$(dirname "$0")/start-setupWorld" "$@"