diff --git a/Dockerfile b/Dockerfile index 4753a65e..1b57c2b7 100644 --- a/Dockerfile +++ b/Dockerfile @@ -42,7 +42,7 @@ RUN easy-add --var os=${TARGETOS} --var arch=${TARGETARCH}${TARGETVARIANT} \ --var version=1.9.0 --var app=mc-server-runner --file {{.app}} \ --from https://github.com/itzg/{{.app}}/releases/download/{{.version}}/{{.app}}_{{.version}}_{{.os}}_{{.arch}}.tar.gz -ARG MC_HELPER_VERSION=1.36.0 +ARG MC_HELPER_VERSION=1.36.1 ARG MC_HELPER_BASE_URL=https://github.com/itzg/mc-image-helper/releases/download/${MC_HELPER_VERSION} # used for cache busting local copy of mc-image-helper ARG MC_HELPER_REV=1 @@ -61,9 +61,7 @@ ENV TYPE=VANILLA VERSION=LATEST EULA="" UID=1000 GID=1000 COPY --chmod=755 scripts/start* / COPY --chmod=755 bin/ /usr/local/bin/ COPY --chmod=755 bin/mc-health /health.sh -COPY --chmod=644 files/log4j2.xml /image/log4j2.xml -# By default this file gets retrieved from repo, but bundle in image as potential fallback -COPY --chmod=644 files/cf-exclude-include.json /image/cf-exclude-include.json +COPY --chmod=644 files/* /image/ COPY --chmod=755 files/auto /auto RUN curl -fsSL -o /image/Log4jPatcher.jar https://github.com/CreeperHost/Log4jPatcher/releases/download/v1.0.1/Log4jPatcher-1.0.1.jar diff --git a/docs/configuration/server-properties.md b/docs/configuration/server-properties.md index f8670fff..ebd21371 100644 --- a/docs/configuration/server-properties.md +++ b/docs/configuration/server-properties.md @@ -353,10 +353,28 @@ If you must, the server port can be set like: **however**, be sure to change your port mapping accordingly and be prepared for some features to break. +### Custom server properties + +Some mods/plugins utilize custom `server.properties` entries which can be declared via the `CUSTOM_SERVER_PROPERTIES` environment variable. The contents must be newline delimited `name=value` pairs. + +Within a compose file, newline delimited entries can be declared as shown here: + +```yaml + CUSTOM_SERVER_PROPERTIES: | + custom1=value1 + defaultworldgenerator-port=f8c04631-f744-11ec-b260-f02f74b094e0 +``` + +When using `docker run` from a bash shell, the entries must be quoted with the `$'` syntax, such as + +``` +-e CUSTOM_SERVER_PROPERTIES=$'k1=v1\nk2=v2' +``` + ### Other server property mappings | Environment Variable | Server Property | -| --------------------------------- | --------------------------------- | +|-----------------------------------|-----------------------------------| | BROADCAST_CONSOLE_TO_OPS | broadcast-console-to-ops | | BROADCAST_RCON_TO_OPS | broadcast-rcon-to-ops | | ENABLE_STATUS | enable-status | diff --git a/files/property-definitions.json b/files/property-definitions.json new file mode 100644 index 00000000..32498b01 --- /dev/null +++ b/files/property-definitions.json @@ -0,0 +1,58 @@ +{ + "motd": {"env": "MOTD"}, + "gamemode": {"env": "MODE"}, + "difficulty": {"env": "DIFFICULTY"}, + "white-list": {"env": "WHITELIST_PROP"}, + "enforce-whitelist": {"env": "ENFORCE_WHITELIST"}, + "level-type": {"env": "LEVEL_TYPE"}, + "server-name": {"env": "SERVER_NAME"}, + "server-ip": {"env": "SERVER_IP"}, + "server-port": {"env": "SERVER_PORT"}, + "allow-nether": {"env": "ALLOW_NETHER"}, + "announce-player-achievements": {"env": "ANNOUNCE_PLAYER_ACHIEVEMENTS"}, + "enable-command-block": {"env": "ENABLE_COMMAND_BLOCK"}, + "spawn-animals": {"env": "SPAWN_ANIMALS"}, + "spawn-monsters": {"env": "SPAWN_MONSTERS"}, + "spawn-npcs": {"env": "SPAWN_NPCS"}, + "spawn-protection": {"env": "SPAWN_PROTECTION"}, + "generate-structures": {"env": "GENERATE_STRUCTURES"}, + "view-distance": {"env": "VIEW_DISTANCE"}, + "hardcore": {"env": "HARDCORE"}, + "snooper-enabled": {"env": "SNOOPER_ENABLED"}, + "max-build-height": {"env": "MAX_BUILD_HEIGHT"}, + "force-gamemode": {"env": "FORCE_GAMEMODE"}, + "max-tick-time": {"env": "MAX_TICK_TIME"}, + "enable-query": {"env": "ENABLE_QUERY"}, + "query.port": {"env": "QUERY_PORT"}, + "enable-rcon": {"env": "ENABLE_RCON"}, + "rcon.password": {"env": "RCON_PASSWORD"}, + "rcon.port": {"env": "RCON_PORT"}, + "max-players": {"env": "MAX_PLAYERS"}, + "max-world-size": {"env": "MAX_WORLD_SIZE"}, + "level-name": {"env": "LEVEL"}, + "level-seed": {"env": "SEED"}, + "pvp": {"env": "PVP"}, + "generator-settings": {"env": "GENERATOR_SETTINGS"}, + "online-mode": {"env": "ONLINE_MODE"}, + "allow-flight": {"env": "ALLOW_FLIGHT"}, + "resource-pack": {"env": "RESOURCE_PACK"}, + "resource-pack-sha1": {"env": "RESOURCE_PACK_SHA1"}, + "require-resource-pack": {"env": "RESOURCE_PACK_ENFORCE"}, + "player-idle-timeout": {"env": "PLAYER_IDLE_TIMEOUT"}, + "broadcast-console-to-ops": {"env": "BROADCAST_CONSOLE_TO_OPS"}, + "broadcast-rcon-to-ops": {"env": "BROADCAST_RCON_TO_OPS"}, + "enable-jmx-monitoring": {"env": "ENABLE_JMX"}, + "sync-chunk-writes": {"env": "SYNC_CHUNK_WRITES"}, + "enable-status": {"env": "ENABLE_STATUS"}, + "entity-broadcast-range-percentage": {"env": "ENTITY_BROADCAST_RANGE_PERCENTAGE"}, + "function-permission-level": {"env": "FUNCTION_PERMISSION_LEVEL"}, + "network-compression-threshold": {"env": "NETWORK_COMPRESSION_THRESHOLD"}, + "op-permission-level": {"env": "OP_PERMISSION_LEVEL"}, + "prevent-proxy-connections": {"env": "PREVENT_PROXY_CONNECTIONS"}, + "use-native-transport": {"env": "USE_NATIVE_TRANSPORT"}, + "simulation-distance": {"env": "SIMULATION_DISTANCE"}, + "previews-chat": {"env": "PREVIEWS_CHAT"}, + "enforce-secure-profile": {"env": "ENFORCE_SECURE_PROFILE"}, + "initial-enabled-packs": {"env": "INITIAL_ENABLED_PACKS"}, + "initial-disabled-packs": {"env": "INITIAL_DISABLED_PACKS"} +} \ No newline at end of file diff --git a/scripts/start-setupServerProperties b/scripts/start-setupServerProperties index 673179ce..1f1628a3 100755 --- a/scripts/start-setupServerProperties +++ b/scripts/start-setupServerProperties @@ -8,49 +8,18 @@ : "${SKIP_SERVER_PROPERTIES:=false}" : "${ENABLE_WHITELIST:=}" -# FUNCTIONS -function setServerPropValue { - local prop=$1 - local value=$2 - # normalize booleans - case ${value^^} in - TRUE|FALSE) - value=${value,,} ;; - esac - if [[ $prop =~ password ]]; then - showValue="*****" - else - showValue="$value" - fi - if [ -f "$SERVER_PROPERTIES" ] && grep "${prop}" "$SERVER_PROPERTIES" > /dev/null; then - debug "Setting ${prop} to '${showValue}' in ${SERVER_PROPERTIES}" - sed -i "/^${prop}\s*=/ c ${prop}=${value//\\/\\\\}" "$SERVER_PROPERTIES" - else - debug "Adding ${prop} with '${showValue}' in ${SERVER_PROPERTIES}" - echo "${prop}=${value}" >> "$SERVER_PROPERTIES" - fi -} - -function setServerProp { - local prop=$1 - local varName=$2 - - if [ -v $varName ]; then - setServerPropValue "$prop" "${!varName}" - fi -} - function customizeServerProps { local firstSetup=$1 # Whitelist processing if [ -n "$WHITELIST" ] || [ -n "$WHITELIST_FILE" ] || isTrue "${ENABLE_WHITELIST}"; then log "Enabling whitelist functionality" - setServerPropValue "white-list" "true" - setServerPropValue "enforce-whitelist" "true" + WHITELIST_PROP=true + ENFORCE_WHITELIST=true + export WHITELIST_PROP ENFORCE_WHITELIST elif isTrue "$firstSetup" || isFalse "${ENABLE_WHITELIST}"; then log "Disabling whitelist functionality" - setServerPropValue "white-list" "false" - setServerProp "enforce-whitelist" ENFORCE_WHITELIST + WHITELIST_PROP=false + export WHITELIST_PROP fi # normalize MOTD @@ -59,101 +28,11 @@ function customizeServerProps { MOTD="{\"text\":\"${MOTD}\"}" fi fi - - setServerProp "server-name" SERVER_NAME - setServerProp "server-ip" SERVER_IP - setServerProp "server-port" SERVER_PORT - setServerProp "allow-nether" ALLOW_NETHER - setServerProp "announce-player-achievements" ANNOUNCE_PLAYER_ACHIEVEMENTS - setServerProp "enable-command-block" ENABLE_COMMAND_BLOCK - setServerProp "spawn-animals" SPAWN_ANIMALS - setServerProp "spawn-monsters" SPAWN_MONSTERS - setServerProp "spawn-npcs" SPAWN_NPCS - setServerProp "spawn-protection" SPAWN_PROTECTION - setServerProp "generate-structures" GENERATE_STRUCTURES - setServerProp "view-distance" VIEW_DISTANCE - setServerProp "hardcore" HARDCORE - setServerProp "snooper-enabled" SNOOPER_ENABLED - setServerProp "max-build-height" MAX_BUILD_HEIGHT - setServerProp "force-gamemode" FORCE_GAMEMODE - setServerProp "max-tick-time" MAX_TICK_TIME - setServerProp "enable-query" ENABLE_QUERY - setServerProp "query.port" QUERY_PORT - setServerProp "enable-rcon" ENABLE_RCON - setServerProp "rcon.password" RCON_PASSWORD - setServerProp "rcon.port" RCON_PORT - setServerProp "max-players" MAX_PLAYERS - setServerProp "max-world-size" MAX_WORLD_SIZE - setServerProp "level-name" LEVEL - setServerProp "level-seed" SEED - setServerProp "pvp" PVP - setServerProp "generator-settings" GENERATOR_SETTINGS - setServerProp "online-mode" ONLINE_MODE - setServerProp "allow-flight" ALLOW_FLIGHT - setServerProp "resource-pack" RESOURCE_PACK - setServerProp "resource-pack-sha1" RESOURCE_PACK_SHA1 - setServerProp "require-resource-pack" RESOURCE_PACK_ENFORCE - setServerProp "player-idle-timeout" PLAYER_IDLE_TIMEOUT - setServerProp "broadcast-console-to-ops" BROADCAST_CONSOLE_TO_OPS - setServerProp "broadcast-rcon-to-ops" BROADCAST_RCON_TO_OPS - setServerProp "enable-jmx-monitoring" ENABLE_JMX - setServerProp "sync-chunk-writes" SYNC_CHUNK_WRITES - setServerProp "enable-status" ENABLE_STATUS - setServerProp "entity-broadcast-range-percentage" ENTITY_BROADCAST_RANGE_PERCENTAGE - setServerProp "function-permission-level" FUNCTION_PERMISSION_LEVEL - setServerProp "network-compression-threshold" NETWORK_COMPRESSION_THRESHOLD - setServerProp "op-permission-level" OP_PERMISSION_LEVEL - setServerProp "prevent-proxy-connections" PREVENT_PROXY_CONNECTIONS - setServerProp "use-native-transport" USE_NATIVE_TRANSPORT - setServerProp "simulation-distance" SIMULATION_DISTANCE - setServerProp "previews-chat" PREVIEWS_CHAT - setServerProp "enforce-secure-profile" ENFORCE_SECURE_PROFILE - setServerProp "initial-enabled-packs" INITIAL_ENABLED_PACKS - setServerProp "initial-disabled-packs" INITIAL_DISABLED_PACKS if [[ $MOTD ]]; then - setServerPropValue "motd" "$(echo "$MOTD" | mc-image-helper asciify)" - fi - [[ $LEVEL_TYPE ]] && setServerPropValue "level-type" "${LEVEL_TYPE^^}" - - if [ -n "$DIFFICULTY" ]; then - case ${DIFFICULTY,,} in - peaceful|0) - if versionLessThan 1.13; then - DIFFICULTY=0 - else - DIFFICULTY=peaceful - fi - ;; - easy|1) - if versionLessThan 1.13; then - DIFFICULTY=1 - else - DIFFICULTY=easy - fi - ;; - normal|2) - if versionLessThan 1.13; then - DIFFICULTY=2 - else - DIFFICULTY=normal - fi - ;; - hard|3) - if versionLessThan 1.13; then - DIFFICULTY=3 - else - DIFFICULTY=hard - fi - ;; - *) - log "DIFFICULTY must be peaceful, easy, normal, or hard." - exit 1 - ;; - esac - setServerPropValue "difficulty" "$DIFFICULTY" + MOTD="$(echo "$MOTD" | mc-image-helper asciify)" fi - if [ -n "$MODE" ]; then + if [[ -v MODE ]]; then log "Setting mode" case ${MODE,,} in su*|0) @@ -189,8 +68,58 @@ function customizeServerProps { exit 1 ;; esac - setServerPropValue "gamemode" "$MODE" fi + + if [[ -v DIFFICULTY ]]; then + case ${DIFFICULTY,,} in + peaceful|0) + if versionLessThan 1.13; then + DIFFICULTY=0 + else + DIFFICULTY=peaceful + fi + ;; + easy|1) + if versionLessThan 1.13; then + DIFFICULTY=1 + else + DIFFICULTY=easy + fi + ;; + normal|2) + if versionLessThan 1.13; then + DIFFICULTY=2 + else + DIFFICULTY=normal + fi + ;; + hard|3) + if versionLessThan 1.13; then + DIFFICULTY=3 + else + DIFFICULTY=hard + fi + ;; + *) + log "DIFFICULTY must be peaceful, easy, normal, or hard." + exit 1 + ;; + esac + fi + + if [[ -v LEVEL_TYPE ]]; then + LEVEL_TYPE="${LEVEL_TYPE^^}" + fi + + setPropertiesArgs=( + --definitions "/image/property-definitions.json" + ) + if [[ -v CUSTOM_SERVER_PROPERTIES ]]; then + setPropertiesArgs+=(--custom-properties "$CUSTOM_SERVER_PROPERTIES") + fi + + mc-image-helper set-properties "${setPropertiesArgs[@]}" "$SERVER_PROPERTIES" + } # Deploy server.properties file