docker-minecraft-server/scripts/start-setupModpack

303 lines
8.6 KiB
Bash
Executable File

#!/bin/bash
set -e -o pipefail
: "${REMOVE_OLD_MODS:=false}"
: "${MODS:=}"
: "${MODS_OUT_DIR:=/data/mods}"
: "${MODS_FILE:=}"
: "${PLUGINS:=}"
: "${PLUGINS_OUT_DIR:=/data/plugins}"
: "${PLUGINS_FILE:=}"
: "${REMOVE_OLD_MODS_DEPTH:=1} "
: "${REMOVE_OLD_MODS_INCLUDE:=*.jar,*-version.json}"
sum_file=/data/.generic_pack.sum
# shellcheck source=start-utils
. "${SCRIPTS:-/}start-utils"
isDebugging && set -x
# CURSE_URL_BASE used in manifest downloads below
CURSE_URL_BASE=${CURSE_URL_BASE:-https://minecraft.curseforge.com/projects}
# Remove old mods/plugins
if isTrue "${REMOVE_OLD_MODS}" && [ -z "${MODS_FILE}" ]; then
removeOldMods "$MODS_OUT_DIR"
removeOldMods "$PLUGINS_OUT_DIR"
rm -f "$sum_file"
fi
function handlePackwiz() {
# If packwiz url passed, bootstrap packwiz and update mods before other modpack processing
if [[ "${PACKWIZ_URL:-}" ]]; then
if ! packwizInstaller=$(mc-image-helper maven-download \
--maven-repo=https://maven.packwiz.infra.link/repository/release/ \
--group=link.infra.packwiz --artifact=packwiz-installer --classifier=dist \
--skip-existing); then
log "ERROR: failed to get packwiz installer"
exit 1
fi
log "Running packwiz installer against URL: ${PACKWIZ_URL}"
if ! java -cp "${packwizInstaller}" link.infra.packwiz.installer.Main -s server "${PACKWIZ_URL}"; then
log "ERROR failed to run packwiz installer"
exit 1
fi
fi
}
function handleModpackZip() {
# If supplied with a URL for a modpack (simple zip of jars), download it and unpack
if [[ "$MODPACK" ]]; then
if isURL "${MODPACK}"; then
log "Downloading mod/plugin pack"
if ! get -o /tmp/modpack.zip "${MODPACK}"; then
log "ERROR: failed to download from ${MODPACK}"
exit 2
fi
elif [[ "$MODPACK" =~ .*\.zip ]]; then
if ! cp "$MODPACK" /tmp/modpack.zip; then
log "ERROR: failed to copy from $MODPACK"
exit 2
fi
else
log "ERROR Invalid URL or Path given for MODPACK: $MODPACK"
exit 1
fi
if [ "$FAMILY" = "SPIGOT" ]; then
mkdir -p "$PLUGINS_OUT_DIR"
if ! unzip -o -d "$PLUGINS_OUT_DIR" /tmp/modpack.zip; then
log "ERROR: failed to unzip the modpack from ${MODPACK}"
fi
else
mkdir -p "$MODS_OUT_DIR"
if ! unzip -o -d "$MODS_OUT_DIR" /tmp/modpack.zip; then
log "ERROR: failed to unzip the modpack from ${MODPACK}"
fi
fi
rm -f /tmp/modpack.zip
fi
}
function handleListings() {
if usesMods && usesPlugins; then
if [[ "$MODS" ]]; then
mkdir -p "$MODS_OUT_DIR"
mc-image-helper mcopy \
--glob=*.jar \
--scope=var-list \
--to="$MODS_OUT_DIR" \
"$MODS"
fi
if [[ "$PLUGINS" ]]; then
mkdir -p "$PLUGINS_OUT_DIR"
mc-image-helper mcopy \
--glob=*.jar \
--scope=var-list \
--to="$PLUGINS_OUT_DIR" \
"$PLUGINS"
fi
if [[ "$MODS_FILE" ]]; then
mkdir -p "$MODS_OUT_DIR"
mc-image-helper mcopy \
--file-is-listing \
--scope=file-list \
--to="$MODS_OUT_DIR" \
"$MODS_FILE"
fi
if [[ "$PLUGINS_FILE" ]]; then
mkdir -p "$PLUGINS_OUT_DIR"
mc-image-helper mcopy \
--file-is-listing \
--scope=file-list \
--to="$PLUGINS_OUT_DIR" \
"$PLUGINS_FILE"
fi
elif usesPlugins || usesMods; then
outDir="$MODS_OUT_DIR"
if usesPlugins; then
outDir="$PLUGINS_OUT_DIR"
fi
if [[ "$MODS" || "$PLUGINS" ]]; then
mkdir -p "$outDir"
mc-image-helper mcopy \
--glob=*.jar \
--scope=var-list \
--to="$outDir" \
"$MODS" "$PLUGINS"
fi
if [[ "$MODS_FILE" || "$PLUGINS_FILE" ]]; then
mkdir -p "$outDir"
mc-image-helper mcopy \
--file-is-listing \
--scope=file-list \
--to="$outDir" \
"$MODS_FILE" "$PLUGINS_FILE"
fi
fi
}
function handleGenericPacks() {
: "${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
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}"
done
# Remove any eula file since container manages it
rm -f "${base_dir}/eula.txt"
# recalculate the actual base directory of content
if ! base_dir=$(mc-image-helper find \
--max-depth=3 --type=directory --name=mods,plugins,config \
--only-shallowest --fail-no-matches --format '%h' \
"$base_dir"); then
log "ERROR: Unable to find content base of generic packs ${GENERIC_PACKS}. Directories:"
mc-image-helper find --name=* --max-depth=3 --type=directory --format '- %P' "$original_base_dir"
exit 1
fi
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
if isTrue "${SKIP_GENERIC_PACK_CHECKSUM:-false}"; then
log "Skipping generic pack(s) checksum"
else
log "Saving generic pack(s) checksum"
sha1sum "${packFiles[@]}" > "${sum_file}"
if isDebugging; then
cat "$sum_file"
fi
fi
fi
fi
}
function handleModrinthProjects() {
: "${MODRINTH_PROJECTS:=}"
: "${MODRINTH_ALLOWED_VERSION_TYPE:=release}"
: "${MODRINTH_DOWNLOAD_DEPENDENCIES:=none}"
if [[ -v MODRINTH_DOWNLOAD_OPTIONAL_DEPENDENCIES ]]; then
log "WARNING The variable MODRINTH_DOWNLOAD_OPTIONAL_DEPENDENCIES is removed."
log " Use MODRINTH_DOWNLOAD_DEPENDENCIES=optional instead"
fi
if [[ $MODRINTH_PROJECTS ]] && isFamily HYBRID FORGE FABRIC SPIGOT; then
if isFamily HYBRID FORGE; then
loader=forge
else
loader="${TYPE,,}"
fi
mc-image-helper modrinth \
--output-directory=/data \
--projects="${MODRINTH_PROJECTS}" \
--game-version="${VERSION}" \
--loader="$loader" \
--download-dependencies="$MODRINTH_DOWNLOAD_DEPENDENCIES" \
--allowed-version-type="$MODRINTH_ALLOWED_VERSION_TYPE"
fi
}
function handleCurseForgeFiles() {
args=()
if usesMods && ! usesPlugins; then
args+=(--default-category mc-mods)
elif usesPlugins && ! usesMods; then
args+=(--default-category bukkit-plugins)
fi
case "${TYPE,,}" in
forge|fabric|quilt)
args+=(--mod-loader "$TYPE")
;;
esac
# shellcheck disable=SC2086
# since we want CURSEFORGE_FILES to expand
mc-image-helper curseforge-files \
"${args[@]}" \
${CURSEFORGE_FILES}
}
handlePackwiz
handleModpackZip
handleListings
if [[ $MANIFEST ]]; then
log "ERROR: MANIFEST is no longer supported."
log " Use MOD_PLATFORM=AUTO_CURSEFORGE and CF_MODPACK_MANIFEST instead"
exit 1
fi
if [[ $MODS_FORGEAPI_KEY || $MODS_FORGEAPI_FILE || $MODS_FORGEAPI_PROJECTIDS ]]; then
log "ERROR the MODS_FORGEAPI_FILE / MODS_FORGEAPI_PROJECTIDS feature is no longer supported"
log " Use CURSEFORGE_FILES instead."
exit 1
fi
handleGenericPacks
handleModrinthProjects
if usesMods || usesPlugins; then
handleCurseForgeFiles
fi
exec "${SCRIPTS:-/}start-setupModconfig" "$@"