diff --git a/README.md b/README.md index de89422a..0109f739 100644 --- a/README.md +++ b/README.md @@ -984,30 +984,19 @@ where the default is "world": ### Downloadable world -Instead of mounting the `/data` volume, you can instead specify the URL of -a ZIP file containing an archived world. This will be downloaded, and -unpacked in the `/data` directory; if it does not contain a subdirectory -called `world/` then it will be searched for a file `level.dat` and the -containing subdirectory renamed to `world`. This means that most of the -archived Minecraft worlds downloadable from the Internet will already be in -the correct format. - -The ZIP file may also contain a `server.properties` file and `modules` -directory, if required. +Instead of mounting the `/data` volume, you can instead specify the URL of a ZIP file containing an archived world. It will be searched for a file `level.dat` and the containing subdirectory moved to the directory named by `$LEVEL`. This means that most of the archived Minecraft worlds downloadable from the Internet will already be in the correct format. docker run -d -e WORLD=http://www.example.com/worlds/MySave.zip ... -**NOTE:** Unless you also mount `/data` as an external volume, this world -will be deleted when the container is deleted. - **NOTE:** This URL must be accessible from inside the container. Therefore, -you should use an IP address or a globally resolveable FQDN, or else the +you should use an IP address or a globally resolvable FQDN, or else the name of a linked container. +**NOTE:** If the archive contains more than one `level.dat`, then the one to select can be picked with `WORLD_INDEX`, which defaults to 1. + ### Cloning world from a container path -The `WORLD` option can also be used to reference a directory that will be used -as a source to clone the world directory. +The `WORLD` option can also be used to reference a directory or zip file that will be used as a source to clone or unzip the world directory. For example, the following would initially clone the world's content from `/worlds/basic`. Also notice in the example that you can use a diff --git a/examples/docker-compose-world-download.yml b/examples/docker-compose-world-download.yml new file mode 100644 index 00000000..5b334f67 --- /dev/null +++ b/examples/docker-compose-world-download.yml @@ -0,0 +1,11 @@ +version: "3.7" + +services: + mc: + image: itzg/minecraft-server + ports: + - 25565:25565 + environment: + EULA: "TRUE" + VERSION: 1.7.2 + WORLD: https://www.minecraftmaps.com/survival-maps/cube-survival/download diff --git a/start-deployVanilla b/start-deployVanilla index e5dd91c3..0c161639 100644 --- a/start-deployVanilla +++ b/start-deployVanilla @@ -1,6 +1,7 @@ #!/bin/bash . /start-utils +isDebugging && set -x set -o pipefail export SERVER="minecraft_server.${VANILLA_VERSION// /_}.jar" @@ -39,5 +40,7 @@ if [ ! -e $SERVER ] || [ -n "$FORCE_REDOWNLOAD" ]; then fi fi +isDebugging && ls -l + # Continue to Final Setup exec /start-finalSetup01World $@ diff --git a/start-finalSetup01World b/start-finalSetup01World index 6ef57f19..1a0bd753 100644 --- a/start-finalSetup01World +++ b/start-finalSetup01World @@ -1,6 +1,8 @@ #!/bin/bash . /start-utils +set -e +isDebugging && set -x if [ $TYPE = "FEED-THE-BEAST" ]; then worldDest=$FTB_BASE_DIR/$LEVEL @@ -8,46 +10,45 @@ else worldDest=/data/$LEVEL fi -# If no world exists and a URL for a world is supplied, download it and unpack if [[ "$WORLD" ]] && [ ! -d "$worldDest" ]; then -case "X$WORLD" in - X[Hh][Tt][Tt][Pp]*) - log "Downloading world from $WORLD" - curl -sSL -o - "$WORLD" > /data/world.zip + if isURL $WORLD; then + curl -fsSL "$WORLD" -o /tmp/world.zip + zipSrc=/tmp/world.zip + elif [[ "$WORLD" =~ .*\.zip ]]; then + zipSrc="$WORLD" + fi + + if [[ "$zipSrc" ]]; then log "Unzipping world" - unzip -o -q /data/world.zip - rm -f /data/world.zip - if [ ! -d $worldDest ]; then - log World directory not found - for i in /data/*/level.dat; do - if [ -f "$i" ]; then - d=`dirname "$i"` - log Renaming world directory from $d - mv -f "$d" $worldDest - fi - done - fi - if [ "$TYPE" = "SPIGOT" ]; then - # Reorganise if a Spigot server - log "Moving End and Nether maps to Spigot location" - [ -d "$worldDest/DIM1" ] && mv -f "$worldDest/DIM1" "/data/${LEVEL}_the_end" - [ -d "$worldDest/DIM-1" ] && mv -f "$worldDest/DIM-1" "/data/${LEVEL}_nether" - fi - ;; - *) - if [[ -d "$WORLD" ]]; then - if [[ ! -d "$worldDest" ]]; then - log "Cloning world directory from $WORLD ..." - cp -r "$WORLD" "$worldDest" - else - log "Skipping clone from $WORLD since $worldDest exists" - fi + + # Stage contents so that the correct subdirectory can be picked off + mkdir -p /tmp/world-data + (cd /tmp/world-data && unzip -o -q "$zipSrc") + + baseDirs=$(find /tmp/world-data -name "level.dat" -exec dirname "{}" \;) + count=$(echo "$baseDirs" | wc -l) + if [[ $count -gt 1 ]]; then + baseDir="$(echo "$baseDirs" | sed -n ${WORLD_INDEX:-1}p)" + baseName=$(basename "$baseDir") + log "WARN multiple levels found, picking: $baseName" + elif [[ $count -gt 0 ]]; then + baseDir="$baseDirs" else - log "World cloning source '$WORLD' doesn't seem to exist" + log "ERROR invalid world content" exit 1 fi - ;; -esac + mv "$baseDir" "$worldDest" + else + log "Cloning world directory from $WORLD ..." + cp -r "$WORLD" "$worldDest" + fi + + if [ "$TYPE" = "SPIGOT" ]; then + # Reorganise if a Spigot server + log "Moving End and Nether maps to Spigot location" + [ -d "$worldDest/DIM1" ] && mv -f "$worldDest/DIM1" "/data/${LEVEL}_the_end" + [ -d "$worldDest/DIM-1" ] && mv -f "$worldDest/DIM-1" "/data/${LEVEL}_nether" + fi fi exec /start-finalSetup02Modpack $@