Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ RUN easy-add --var os=${TARGETOS} --var arch=${TARGETARCH}${TARGETVARIANT} \
--var version=0.1.1 --var app=maven-metadata-release --file {{.app}} \
--from https://github.com/itzg/{{.app}}/releases/download/{{.version}}/{{.app}}_{{.version}}_{{.os}}_{{.arch}}.tar.gz

ARG MC_HELPER_VERSION=1.17.0
ARG MC_HELPER_VERSION=1.18.3
ARG MC_HELPER_BASE_URL=https://github.com/itzg/mc-image-helper/releases/download/v${MC_HELPER_VERSION}
RUN curl -fsSL ${MC_HELPER_BASE_URL}/mc-image-helper-${MC_HELPER_VERSION}.tgz \
| tar -C /usr/share -zxf - \
Expand Down
16 changes: 15 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -684,6 +684,20 @@ For example, the following will auto-download the [EssentialsX](https://www.spig

-e SPIGET_RESOURCES=9089,34315

### Auto-download mods from Modrinth

[Modrinth](https://modrinth.com/) is an open source modding platform with a clean, easy to use website for finding [Fabric and Forge mods](https://modrinth.com/mods). At startup, the container will automatically locate and download the newest versions of mod files that correspond to the `TYPE` and `VERSION` in use. Older file versions downloaded previously will automatically be cleaned up.

- **MODRINTH_PROJECTS** : comma separated list of project slugs (short name) or IDs. The project ID can be located in the "Technical information" section. The slug is the part of the page URL that follows `/mod/`:
```
https://modrinth.com/mod/fabric-api
----------
|
+-- project slug
```
- **MODRINTH_DOWNLOAD_OPTIONAL_DEPENDENCIES**=true : required dependencies of the project will _always_ be downloaded and optional dependencies can also be downloaded by setting this to `true`
- **MODRINTH_ALLOWED_VERSION_TYPE**=release : the version type is used to determine the newest version to use from each project. The allowed values are `release`, `beta`, `alpha`.

### Downloadable mod/plugin pack for Forge, Fabric, and Bukkit-like Servers

Like the `WORLD` option above, you can specify the URL or path of a "mod pack"
Expand Down Expand Up @@ -899,7 +913,7 @@ Datapacks Json:
"packs": {
"survival": [
"graves",
"multiplayer sleep",
"multiplayer sleep"
],
"items": ["armored elytra"]
}
Expand Down
18 changes: 18 additions & 0 deletions examples/docker-compose-modrinth.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
version: "3.8"

services:
mc:
image: itzg/minecraft-server
tty: true
stdin_open: true
ports:
- "25565:25565"
environment:
EULA: "TRUE"
TYPE: FABRIC
MODRINTH_PROJECTS: fallingtree
volumes:
- data:/data

volumes:
data: {}
151 changes: 89 additions & 62 deletions scripts/start-setupModpack
Original file line number Diff line number Diff line change
Expand Up @@ -195,75 +195,102 @@ case "X$EFFECTIVE_MANIFEST_FILE" in
esac
fi

: "${GENERIC_PACKS:=${GENERIC_PACK}}"
: "${GENERIC_PACKS_PREFIX:=}"
: "${GENERIC_PACKS_SUFFIX:=}"

if [[ "${GENERIC_PACKS}" ]]; then
IFS=',' read -ra packs <<< "${GENERIC_PACKS}"

packFiles=()
for packEntry in "${packs[@]}"; do
pack="${GENERIC_PACKS_PREFIX}${packEntry}${GENERIC_PACKS_SUFFIX}"
if isURL "${pack}"; then
mkdir -p /data/packs
log "Downloading generic pack from $pack"
if ! outfile=$(get -o /data/packs --output-filename --skip-up-to-date "$pack"); then
log "ERROR: failed to download $pack"
exit 2
fi
packFiles+=("$outfile")
else
packFiles+=("$pack")
fi
done
function genericPacks() {
: "${GENERIC_PACKS:=${GENERIC_PACK}}"
: "${GENERIC_PACKS_PREFIX:=}"
: "${GENERIC_PACKS_SUFFIX:=}"

if [[ "${GENERIC_PACKS}" ]]; then
IFS=',' read -ra packs <<< "${GENERIC_PACKS}"

isDebugging && [ -f "$sum_file}" ] && cat "$sum_file"

log "Checking if generic packs are up to date"
if isTrue "${SKIP_GENERIC_PACK_UPDATE_CHECK:-false}" && [ -f "$sum_file" ]; then
log "Skipping generic pack update check"
elif isTrue "${FORCE_GENERIC_PACK_UPDATE}" || ! checkSum "${sum_file}"; then
log "Generic pack(s) are out of date. Re-applying..."

original_base_dir=/data/.tmp/generic_pack_base
base_dir=$original_base_dir
rm -rf "${base_dir}"
mkdir -p "${base_dir}"
for pack in "${packFiles[@]}"; do
isDebugging && ls -l "${pack}"
extract "${pack}" "${base_dir}"
packFiles=()
for packEntry in "${packs[@]}"; do
pack="${GENERIC_PACKS_PREFIX}${packEntry}${GENERIC_PACKS_SUFFIX}"
if isURL "${pack}"; then
mkdir -p /data/packs
log "Downloading generic pack from $pack"
if ! outfile=$(get -o /data/packs --output-filename --skip-up-to-date "$pack"); then
log "ERROR: failed to download $pack"
exit 2
fi
packFiles+=("$outfile")
else
packFiles+=("$pack")
fi
done

# recalculate the actual base directory of content
base_dir=$(find "$base_dir" -maxdepth 3 -type d \( -name mods -o -name plugins -o -name config \) -printf '%h' -quit)
if [[ ! $base_dir ]]; then
log "ERROR: Unable to find content base of generic packs ${GENERIC_PACKS}. Directories:"
find $original_base_dir -maxdepth 3 -type d -printf ' - %P\n'
exit 1
fi
isDebugging && [ -f "$sum_file}" ] && cat "$sum_file"

if [ -f /data/manifest.txt ]; then
log "Manifest exists from older generic pack, cleaning up ..."
while read -r f; do
rm -rf "/data/${f}"
done < /data/manifest.txt
# prune empty dirs
find /data -mindepth 1 -depth -type d -empty -delete
rm -f /data/manifest.txt
fi
log "Checking if generic packs are up to date"
if isTrue "${SKIP_GENERIC_PACK_UPDATE_CHECK:-false}" && [ -f "$sum_file" ]; then
log "Skipping generic pack update check"
elif isTrue "${FORCE_GENERIC_PACK_UPDATE}" || ! checkSum "${sum_file}"; then
log "Generic pack(s) are out of date. Re-applying..."

log "Writing generic pack manifest ... "
find "${base_dir}" -type f -printf "%P\n" > /data/manifest.txt
original_base_dir=/data/.tmp/generic_pack_base
base_dir=$original_base_dir
rm -rf "${base_dir}"
mkdir -p "${base_dir}"
for pack in "${packFiles[@]}"; do
isDebugging && ls -l "${pack}"
extract "${pack}" "${base_dir}"
done

log "Applying generic pack ..."
cp -R -f "${base_dir}"/* /data
rm -rf $original_base_dir
# recalculate the actual base directory of content
base_dir=$(find "$base_dir" -maxdepth 3 -type d \( -name mods -o -name plugins -o -name config \) -printf '%h' -quit)
if [[ ! $base_dir ]]; then
log "ERROR: Unable to find content base of generic packs ${GENERIC_PACKS}. Directories:"
find $original_base_dir -maxdepth 3 -type d -printf ' - %P\n'
exit 1
fi

log "Saving generic pack(s) checksum"
sha1sum "${packFiles[@]}" > "${sum_file}"
isDebugging && cat "$sum_file"
if [ -f /data/manifest.txt ]; then
log "Manifest exists from older generic pack, cleaning up ..."
while read -r f; do
rm -rf "/data/${f}"
done < /data/manifest.txt
# prune empty dirs
find /data -mindepth 1 -depth -type d -empty -delete
rm -f /data/manifest.txt
fi

log "Writing generic pack manifest ... "
find "${base_dir}" -type f -printf "%P\n" > /data/manifest.txt

log "Applying generic pack ..."
cp -R -f "${base_dir}"/* /data
rm -rf $original_base_dir

log "Saving generic pack(s) checksum"
sha1sum "${packFiles[@]}" > "${sum_file}"
isDebugging && cat "$sum_file"
fi
fi
fi
}

function modrinthProjects() {
: "${MODRINTH_PROJECTS:=}"
: "${MODRINTH_DOWNLOAD_OPTIONAL_DEPENDENCIES:=true}"
: "${MODRINTH_ALLOWED_VERSION_TYPE:=release}"

if [[ $MODRINTH_PROJECTS ]] && isFamily HYBRID FABRIC; then
if [[ ${FAMILY^^} = HYBRID ]]; then
loader=forge
else
loader="${FAMILY,,}"
fi
mc-image-helper modrinth \
--output-directory=/data \
--projects="${MODRINTH_PROJECTS}" \
--game-version="${VANILLA_VERSION}" \
--loader="$loader" \
--download-optional-dependencies="$MODRINTH_DOWNLOAD_OPTIONAL_DEPENDENCIES" \
--allowed-version-type="$MODRINTH_ALLOWED_VERSION_TYPE"
fi
}

genericPacks

modrinthProjects

exec "${SCRIPTS:-/}start-setupModconfig" "$@"
6 changes: 1 addition & 5 deletions scripts/start-utils
Original file line number Diff line number Diff line change
Expand Up @@ -212,11 +212,7 @@ function removeOldMods {
}

function get() {
local flags=()
if isTrue "${DEBUG_GET:-false}"; then
flags+=("--debug")
fi
mc-image-helper "${flags[@]}" get "$@"
mc-image-helper get "$@"
}

function get_silent() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ services:
GENERIC_PACKS: testing
GENERIC_PACKS_PREFIX: /packs/
GENERIC_PACKS_SUFFIX: .zip
DEBUG: "true"
volumes:
- ./packs:/packs
- ./data:/data
1 change: 1 addition & 0 deletions tests/setuponlytests/generic-packs/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ services:
TYPE: CUSTOM
CUSTOM_SERVER: /servers/fake.jar
VERSION: 1.18.1
DEBUG: "true"
volumes:
- ./packs:/packs
- ./data:/data
Expand Down
15 changes: 15 additions & 0 deletions tests/setuponlytests/modrinth/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
version: "3"

services:
mc:
image: ${IMAGE_TO_TEST:-itzg/minecraft-server}
environment:
EULA: "true"
SETUP_ONLY: "true"
TYPE: FABRIC
FABRIC_LAUNCHER: /servers/fake.jar
CUSTOM_SERVER: /servers/fake.jar
MODRINTH_PROJECTS: fabric-api,cloth-config
volumes:
- ./data:/data
- ./fake.jar:/servers/fake.jar
Empty file.
1 change: 1 addition & 0 deletions tests/setuponlytests/modrinth/verify.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
mc-image-helper assert fileExists "mods/cloth-config-*.jar" "mods/fabric-api-*.jar"