From e76068e63ec9894a351ba3e8103c0433d8377c51 Mon Sep 17 00:00:00 2001 From: Steve Shipway Date: Tue, 22 Dec 2015 19:47:42 +1300 Subject: [PATCH] Many improvements to help it work with automated schedulers - Allow -e WORLD=http://xxxx/world.zip to download archived world and unpack - Allow 'adventure' and 'spectator' game modes - Allow /mods and /config mounts for shared Forge mods without using /data - Quote many strings in case of blank values - Let VERSION take lowercase options, and set to LATEST if blank or invalid - Enable command blocks by default (needed for adventure worlds) - Allow DIFFICULTY to be given numerically - default to empty banned-players and banned-ip files to avoid error message --- minecraft-server/README.md | 42 ++++++++++++++++++++++++++++- minecraft-server/start-minecraft.sh | 36 ++++++++++++++++--------- 2 files changed, 65 insertions(+), 13 deletions(-) diff --git a/minecraft-server/README.md b/minecraft-server/README.md index 3e57f472..19ba7391 100644 --- a/minecraft-server/README.md +++ b/minecraft-server/README.md @@ -104,7 +104,13 @@ but you can also choose to run a specific version with `-e FORGEVERSION=10.13.4. -e TYPE=FORGE -e FORGEVERSION=10.13.4.1448 \ -p 25565:25565 -e EULA=TRUE --name mc itzg/minecraft-server -In order to add mods, you will need to attach the container's `/data` directory +In order to add mods, you have two options. + +### Using the /data volume + +This is the easiest way if you are using a persistent `/data` mount. + +To do this, you will need to attach the container's `/data` directory (see "Attaching data directory to host filesystem”). Then, you can add mods to the `/path/on/host/mods` folder you chose. From the example above, the `/path/on/host` folder contents look like: @@ -127,6 +133,19 @@ up: docker stop mc docker start mc +### Using separate mounts + +This is the easiest way if you are using an ephemeral `/data` filesystem, +or downloading a world with the `WORLD` option. + +There are two additional volumes that can be mounted; `/mods` and `/config`. +Any files in either of these filesystems will be copied over to the main +`/data` filesystem before starting Minecraft. + +This works well if you want to have a common set of modules in a separate +location, but still have multiple worlds with different server requirements +in either persistent volumes or a downloadable archive. + ## Using Docker Compose Rather than type the server options below, the port mappings above, etc @@ -206,6 +225,8 @@ shortcut values: * creative * survival +* adventure +* spectator (only for Minecraft 1.8 or later) For example: @@ -258,6 +279,25 @@ where the default is "world": **NOTE:** if running multiple containers be sure to either specify a different `-v` host directory for each `LEVEL` in use or don't use `-v` and the container's filesystem will keep things encapsulated. +### 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. + + 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. + + ## JVM Configuration ### Memory Limit diff --git a/minecraft-server/start-minecraft.sh b/minecraft-server/start-minecraft.sh index 65df7ce4..2a2b4527 100755 --- a/minecraft-server/start-minecraft.sh +++ b/minecraft-server/start-minecraft.sh @@ -16,22 +16,25 @@ if [ ! -e /data/eula.txt ]; then fi echo "Checking version information." -case $VERSION in - LATEST) +case "X$VERSION" in + X|XLATEST|Xlatest) VANILLA_VERSION=`wget -O - https://s3.amazonaws.com/Minecraft.Download/versions/versions.json | jsawk -n 'out(this.latest.release)'` ;; - SNAPSHOT) + XSNAPSHOT|Xsnapshot) VANILLA_VERSION=`wget -O - https://s3.amazonaws.com/Minecraft.Download/versions/versions.json | jsawk -n 'out(this.latest.snapshot)'` ;; - *) + X[1-9]*) VANILLA_VERSION=$VERSION ;; + *) + VANILLA_VERSION=`wget -O - https://s3.amazonaws.com/Minecraft.Download/versions/versions.json | jsawk -n 'out(this.latest.release)'` + ;; esac cd /data echo "Checking minecraft / forge type information." -case $TYPE in +case "$TYPE" in VANILLA) SERVER="minecraft_server.$VANILLA_VERSION.jar" @@ -49,7 +52,7 @@ case $TYPE in ;; *) - norm=`echo $VANILLA_VERSION | sed 's/^\([0-9]\+\.[0-9]\+\).*/\1/'` + norm=`echo "$VANILLA_VERSION" | sed 's/^\([0-9]\+\.[0-9]\+\).*/\1/'` ;; esac @@ -76,7 +79,7 @@ case $TYPE in FORGE_INSTALLER="forge-$normForgeVersion-installer.jar" SERVER="forge-$normForgeVersion-universal.jar" - if [ ! -e $SERVER ]; then + if [ ! -e "$SERVER" ]; then echo "Downloading $FORGE_INSTALLER ..." wget -q http://files.minecraftforge.net/maven/net/minecraftforge/forge/$normForgeVersion/$FORGE_INSTALLER echo "Installing $SERVER" @@ -88,7 +91,7 @@ esac # If supplied with a URL for a world, download it and unpack case "X$WORLD" in - Xhttp*) + X[Hh][Tt][Tt][Pp]*[Zz][iI][pP]) echo "Downloading world via HTTP" wget -q -O - "$WORLD" > /data/world.zip echo "Unzipping word" @@ -104,6 +107,9 @@ case "X$WORLD" in done fi ;; + *) + echo "Invalid URL given for world: Must be HTTP or HTTPS and a ZIP file" + ;; esac if [ ! -e server.properties ]; then @@ -151,16 +157,16 @@ if [ ! -e server.properties ]; then if [ -n "$DIFFICULTY" ]; then case $DIFFICULTY in - peaceful) + peaceful|0) DIFFICULTY=0 ;; - easy) + easy|1) DIFFICULTY=1 ;; - normal) + normal|2) DIFFICULTY=2 ;; - hard) + hard|3) DIFFICULTY=3 ;; *) @@ -181,6 +187,12 @@ if [ ! -e server.properties ]; then c*) MODE=1 ;; + a*) + MODE=2 + ;; + s*) + MODE=3 + ;; *) echo "ERROR: Invalid game mode: $MODE" exit 1