#!/bin/bash set -euo pipefail IFS=$'\n\t' # shellcheck source=start-utils . "$(dirname "$0")/start-utils" : "${EULA:=}" : "${PROXY:=}" : "${ENABLE_AUTOPAUSE:=false}" : "${ENABLE_AUTOSTOP:=false}" : "${RCON_CMDS_STARTUP:=}" : "${RCON_CMDS_ON_CONNECT:=}" : "${RCON_CMDS_ON_DISCONNECT:=}" : "${RCON_CMDS_FIRST_CONNECT:=}" : "${RCON_CMDS_LAST_DISCONNECT:=}" : "${RCON_CMDS_PERIOD:=10}" : "${ENABLE_RCON:=true}" : "${RCON_PORT:=25575}" export ENABLE_RCON RCON_PORT : "${MEMORY=1G}" : "${INIT_MEMORY=${MEMORY}}" : "${MAX_MEMORY=${MEMORY}}" export MEMORY INIT_MEMORY MAX_MEMORY shopt -s nullglob isDebugging && set -x if (( $(mc-image-helper java-release) >= 17 )); then MC_IMAGE_HELPER_OPTS+=" --enable-native-access=ALL-UNNAMED" export MC_IMAGE_HELPER_OPTS fi export HOME=/data log "Running as uid=$(id -u) gid=$(id -g) with /data as '$(ls -lnd /data)'" log "Image info: $(paste -d, -s /etc/image.properties)" if [ ! -e /data/eula.txt ]; then if ! isTrue "$EULA"; then log "" logError "Please accept the Minecraft EULA at" logError " https://account.mojang.com/documents/minecraft_eula" logError "by adding the following immediately after 'docker run':" logError " -e EULA=TRUE" log "" exit 1 fi writeEula fi if isTrue "${DEBUG_MEMORY:-false}"; then log "Memory usage and availability (in MB)" uname -pars free -m fi ########################################## # Setup RCON password if isTrue "${ENABLE_RCON:-true}"; then # turn off debug output set +x if [[ -v RCON_PASSWORD_FILE ]]; then if [ ! -e "${RCON_PASSWORD_FILE}" ]; then log "" logError "Initial RCON password file ${RCON_PASSWORD_FILE} does not seems to exist." logError "Please ensure your configuration." logError "If you are using Docker Secrets feature, please check this for further information: " logError " https://docs.docker.com/engine/swarm/secrets" log "" exit 1 else RCON_PASSWORD=$(cat "${RCON_PASSWORD_FILE}") export RCON_PASSWORD fi elif ! [[ -v RCON_PASSWORD ]]; then RCON_PASSWORD=$(openssl rand -hex 12) export RCON_PASSWORD fi # For rcon-cli access running via exec, which by default is running as root echo "password=${RCON_PASSWORD}" > "$HOME/.rcon-cli.env" echo "password: \"${RCON_PASSWORD}\"" > "$HOME/.rcon-cli.yaml" isDebugging && set -x else rm -f "$HOME/.rcon-cli.env" "$HOME/.rcon-cli.yaml" fi ########################################## # Auto-pause/stop if isTrue "${ENABLE_AUTOPAUSE}" && isTrue "${ENABLE_AUTOSTOP}"; then logError "ENABLE_AUTOPAUSE=true is incompatible with ENABLE_AUTOSTOP=true" exit 1 fi proxyArgs=() if [[ $PROXY ]]; then export http_proxy="$PROXY" export https_proxy="$PROXY" IFS=":" read -ra parts <<< "$PROXY" IFS=" " : "${PROXY_HOST=$(firstArrayElement parts)}" shiftArray parts : "${PROXY_PORT=$(firstArrayElement parts)}" fi # https://docs.oracle.com/javase/7/docs/api/java/net/doc-files/net-properties.html proxyArgs=() function addToProxyArgs() { if [[ $2 ]]; then proxyArgs+=("-D$1=$2") fi } addToProxyArgs http.proxyHost "${PROXY_HOST:-}" addToProxyArgs http.proxyPort "${PROXY_PORT:-}" addToProxyArgs http.nonProxyHosts "${PROXY_NON_PROXY_HOSTS:-}" export MC_IMAGE_HELPER_OPTS+=" ${proxyArgs[*]}" function fixJavaPath() { # Some Docker management UIs grab all the image declared variables and present them for configuration. # When upgrading images across Java versions, that creates parts mismatch in PATH's expected by base image. if ! which java > /dev/null; then logError " Your Docker provider has an annoying flaw where it" logError " tries to set PATH even though the container establishes" logError " parts very specific value." sleep 2 # now find where java might be for d in /opt/java/openjdk/bin /usr/bin; do if [ -x "${d}/java" ]; then PATH="${PATH}:${d}" return 0 fi done return 1 fi } if ! fixJavaPath; then logError "could not locate path that contains java" exit 1 fi cd /data || exit 1 export DECLARED_TYPE=${TYPE^^} export DECLARED_VERSION="$VERSION" if isTrue "${VERSION_FROM_MODRINTH_PROJECTS:-}" && [[ ${MODRINTH_PROJECTS:-} ]]; then if ! VERSION=$(mc-image-helper version-from-modrinth-projects --projects "${MODRINTH_PROJECTS}"); then logError "failed to resolve version from MODRINTH_PROJECTS: ${MODRINTH_PROJECTS}" exit 1 fi log "Resolved Minecraft version $VERSION from Modrinth projects" export VERSION fi if isTrue "${ENABLE_AUTOPAUSE}"; then "$(dirname "$0")/start-autopause" elif isTrue "${ENABLE_AUTOSTOP}"; then "$(dirname "$0")/start-autostop" fi if [[ "$RCON_CMDS_STARTUP" ]] || [[ "$RCON_CMDS_ON_CONNECT" ]] || [[ "$RCON_CMDS_ON_DISCONNECT" ]] || [[ "$RCON_CMDS_FIRST_CONNECT" ]] || [[ "$RCON_CMDS_LAST_DISCONNECT" ]] then log "Starting RCON commands" # shellcheck source=start-rconcmds "$(dirname "$0")/start-rconcmds" fi : "${MODPACK_PLATFORM:=${MOD_PLATFORM:-}}" if [[ $MODPACK_PLATFORM && $TYPE && $TYPE != VANILLA ]]; then logWarning "Avoid setting TYPE and MODPACK_PLATFORM" fi case "${TYPE^^}" in AUTO_CURSEFORGE|MODRINTH|CURSEFORGE|FTB|FTBA|GTNH) MODPACK_PLATFORM="$TYPE" ;; esac if [[ $MODPACK_PLATFORM ]]; then case "${MODPACK_PLATFORM^^}" in FTB|CURSEFORGE) exec "$(dirname "$0")/start-deployCF" "$@" ;; FTBA) exec "$(dirname "$0")/start-deployFTBA" "$@" ;; AUTO_CURSEFORGE) exec "$(dirname "$0")/start-deployAutoCF" "$@" ;; MODRINTH) exec "$(dirname "$0")/start-deployModrinth" "$@" ;; GTNH) exec "$(dirname "$0")/start-deployGTNH" "$@" ;; *) logError "Invalid MODPACK_PLATFORM: '$MODPACK_PLATFORM'" exit 1 ;; esac fi log "Resolving type given ${TYPE}" case "${TYPE^^}" in *BUKKIT|SPIGOT) exec "$(dirname "$0")/start-deployBukkitSpigot" "$@" ;; PAPER) exec "$(dirname "$0")/start-deployPaper" "$@" ;; FOLIA) exec "$(dirname "$0")/start-deployFolia" "$@" ;; FORGE) exec "$(dirname "$0")/start-deployForge" "$@" ;; NEOFORGE|NEOFORGED) exec "$(dirname "$0")/start-deployNeoForge" "$@" ;; FABRIC) exec "$(dirname "$0")/start-deployFabric" "$@" ;; QUILT) exec "$(dirname "$0")/start-deployQuilt" "$@" ;; VANILLA) exec "$(dirname "$0")/start-deployVanilla" "$@" ;; SPONGEVANILLA) exec "$(dirname "$0")/start-deploySpongeVanilla" "$@" ;; CUSTOM) exec "$(dirname "$0")/start-deployCustom" "$@" ;; MAGMA) exec "$(dirname "$0")/start-deployMagma" "$@" ;; MAGMA_MAINTAINED) exec "$(dirname "$0")/start-deployMagmaMaintained" "$@" ;; KETTING) exec "$(dirname "$0")/start-deployKetting" "$@" ;; MOHIST|YOUER|BANNER) exec "$(dirname "$0")/start-deployMohist" "$@" ;; PURPUR) exec "$(dirname "$0")/start-deployPurpur" "$@" ;; PUFFERFISH) exec "$(dirname "$0")/start-deployPufferfish" "$@" ;; CANYON) exec "$(dirname "$0")/start-deployCanyon" "$@" ;; LIMBO) exec "$(dirname "$0")/start-deployLimbo" "$@" ;; NANOLIMBO) exec "$(dirname "$0")/start-deployNanoLimbo" "$@" ;; CRUCIBLE) exec "$(dirname "$0")/start-deployCrucible" "$@" ;; LEAF) exec "$(dirname "$0")/start-deployLeaf" "$@" ;; ARCLIGHT) exec "$(dirname "$0")/start-deployArcLight" "$@" ;; POSEIDON) exec "$(dirname "$0")/start-deployPoseidon" "$@" ;; *) logError "Invalid TYPE: '$TYPE'" logError "Must be: VANILLA, FORGE, BUKKIT, SPIGOT, PAPER, FOLIA, PURPUR, FABRIC, QUILT," logError " SPONGEVANILLA, CUSTOM, MAGMA, MOHIST, GTNH, AIRPLANE, PUFFERFISH," logError " CANYON, LIMBO, NANOLIMBO, CRUCIBLE, LEAF, YOUER, BANNER, NEOFORGE" exit 1 ;; esac