mirror of
https://github.com/itzg/docker-minecraft-server.git
synced 2024-06-07 19:40:43 +00:00
7dbd8256ea
Co-authored-by: christopher blodgett <christopher.blodgett@gmail.com> Co-authored-by: Geoff Bourne <itzgeoff@gmail.com>
222 lines
8.1 KiB
Bash
222 lines
8.1 KiB
Bash
#!/bin/bash
|
|
|
|
set -e -o pipefail
|
|
|
|
: "${MODS_FORGEAPI_KEY:=}"
|
|
: "${REMOVE_OLD_FORGEAPI_MODS:=false}"
|
|
: "${MODS_FORGEAPI_PROJECTIDS:=}"
|
|
: "${MODS_FORGEAPI_FILE:=}"
|
|
: "${MODS_FORGEAPI_RELEASES:=RELEASE}"
|
|
: "${MODS_FORGEAPI_DOWNLOAD_DEPENDENCIES:=false}"
|
|
: "${REMOVE_OLD_MODS_DEPTH:=1} "
|
|
: "${REMOVE_OLD_MODS_INCLUDE:=*.jar}"
|
|
|
|
# FORGEAPI_BASE_URL used in manifest downloads below
|
|
FORGEAPI_BASE_URL=${FORGEAPI_BASE_URL:-https://api.curseforge.com/v1}
|
|
RELEASE_NUMBER_FILTER=1
|
|
MINECRAFT_GAME_ID=432
|
|
out_dir=/data/mods
|
|
|
|
# shellcheck source=start-utils
|
|
. "${SCRIPTS:-/}start-utils"
|
|
isDebugging && set -x
|
|
|
|
# Remove old mods/plugins
|
|
if isTrue "${REMOVE_OLD_FORGEAPI_MODS}" && [ -z "${MODS_FORGEAPI_FILE}" ]; then
|
|
removeOldMods /data/mods
|
|
fi
|
|
|
|
ensureModKey(){
|
|
if [ -z "$MODS_FORGEAPI_KEY" ]; then
|
|
log "ERROR: MODS_FORGEAPI_KEY REQUIRED to Connect to FORGE API, you supplied: ${MODS_FORGEAPI_KEY}"
|
|
exit 2
|
|
fi
|
|
}
|
|
|
|
# Set the global release type per the text.
|
|
# NOTE: downcasing release type for comparing types.
|
|
updateReleaseNumber(){
|
|
releaseType=$1
|
|
if [ "release" = "${releaseType,,}" ] || [ 1 = "${releaseType,,}" ]; then
|
|
RELEASE_NUMBER_FILTER=1
|
|
elif [ "beta" = "${releaseType,,}" ] || [ 2 = "${releaseType,,}" ]; then
|
|
RELEASE_NUMBER_FILTER=2
|
|
elif [ "alpha" = "${releaseType,,}" ] || [ 3 = "${releaseType,,}" ]; then
|
|
RELEASE_NUMBER_FILTER=3
|
|
fi
|
|
}
|
|
|
|
retrieveVersionTypeNumber(){
|
|
VERSION_NAME="Minecraft ${VANILLA_VERSION%.*}"
|
|
minecraft_types=$(curl -X GET -s \
|
|
"${FORGEAPI_BASE_URL}/games/${MINECRAFT_GAME_ID}/version-types" \
|
|
-H 'Accept: application/json' -H 'x-api-key: '${MODS_FORGEAPI_KEY}'')
|
|
|
|
if [ ! "$minecraft_types" ]; then
|
|
log "ERROR: unable to retrieve version types for ${VERSION_NAME} from ForgeAPI. Check Forge API key or supplied Minecraft version"
|
|
exit 2
|
|
fi
|
|
|
|
TYPE_ID=$(jq -n "$minecraft_types" | jq --arg VERSION_NAME "$VERSION_NAME" -jc '
|
|
.data[]? | select(.name==$VERSION_NAME) | .id')
|
|
|
|
if [ ! "$TYPE_ID" ]; then
|
|
log "ERROR: unable to retrieve version types for ${VERSION_NAME} from ForgeAPI"
|
|
exit 2
|
|
fi
|
|
}
|
|
|
|
modFileByProjectID(){
|
|
project_id=$(echo $1 | tr -d '"')
|
|
project_id_release_type=$2
|
|
project_id_file_name=$3
|
|
unset PROJECT_FILE
|
|
|
|
# if Type id isn't defined use minecraft version to go get it.
|
|
if [ ! "$TYPE_ID" ]; then
|
|
retrieveVersionTypeNumber
|
|
fi
|
|
|
|
# JQ is struggling with larger page sizes so having to pagination for mods with a lot of releases
|
|
pageSize=42
|
|
index=0
|
|
total_count=1
|
|
|
|
while [ $index -lt $total_count ]; do
|
|
project_files=$(curl -X GET -s \
|
|
"${FORGEAPI_BASE_URL}/mods/${project_id}/files?gameVersionTypeId=${TYPE_ID}&index=${index}&pageSize=${pageSize}" \
|
|
-H 'Accept: application/json' -H 'x-api-key: '${MODS_FORGEAPI_KEY}'')
|
|
|
|
if [ ! "$project_files" ]; then
|
|
log "ERROR: unable to retrieve any project id files for ${project_id} from ForgeAPI"
|
|
exit 2
|
|
fi
|
|
# Use project files to grab out the total count of mods.
|
|
total_count=$(jq -n "$project_files" | jq -c '.pagination.totalCount' )
|
|
|
|
# Checking for a individual release type input, if not use global
|
|
if [ $project_id_release_type ]; then
|
|
updateReleaseNumber $project_id_release_type
|
|
else
|
|
updateReleaseNumber $MODS_FORGEAPI_RELEASES
|
|
fi
|
|
# grabs the highest ID of the releaseTypes selected.
|
|
# Default is 1 for Release, Beta is 2, and Alpha is 3. Using less than we can validate highest release.
|
|
if [ $project_id_file_name ]; then
|
|
current_project_file=$(jq -n "$project_files" | jq --arg FILE_NAME "$project_id_file_name" -jc '
|
|
.data | map(select(.fileName<=($FILE_NAME))) | .[0]')
|
|
else
|
|
current_project_file=$(jq -n "$project_files" | jq --arg RELEASE_FILTER "$RELEASE_NUMBER_FILTER" -jc '
|
|
.data | sort_by(.id) | reverse | map(select(.releaseType<=($RELEASE_FILTER|tonumber))) | .[0]')
|
|
fi
|
|
# Logic to grab the latest release over the entire pagination
|
|
if [ ! "$PROJECT_FILE" ]; then
|
|
PROJECT_FILE=$current_project_file
|
|
elif [ "$current_project_file" ]; then
|
|
current_project_file_id=$(jq -n "$current_project_file" | jq -jc '.id' )
|
|
PROJECT_FILE_ID=$(jq -n "$PROJECT_FILE" | jq -jc '.id' )
|
|
if (( current_project_file_id > PROJECT_FILE_ID )); then
|
|
PROJECT_FILE=$current_project_file
|
|
fi
|
|
fi
|
|
|
|
# check to see if we have gone to far or lost our index and exit with an error
|
|
if [ -z "$index" ] || [ -z "$total_count" ] || [ $index -ge $total_count ]; then
|
|
log "ERROR: Unable to retrieve any files for ${project_id} from ForgeAPI also Validate files have release type associated with no. ${RELEASE_NUMBER_FILTER}"
|
|
exit 2
|
|
fi
|
|
# Increment start index to new set.
|
|
index=$(($index + $pageSize))
|
|
done
|
|
}
|
|
|
|
downloadModPackfromModFile() {
|
|
if [ ! "$PROJECT_FILE" ]; then
|
|
log "ERROR: Project File not found from the ForgeAPI"
|
|
exit 2
|
|
fi
|
|
|
|
# grabs needed values from our json return
|
|
file_name=$(jq -n "$PROJECT_FILE" | jq -jc '.fileName' )
|
|
download_url=$(jq -n "$PROJECT_FILE" | jq -jc '.downloadUrl' )
|
|
|
|
# trys to make the output directory incase it doesnt exist.
|
|
mkdir -p "$out_dir"
|
|
echo "Downloading ${download_url}"
|
|
if ! get -o "${out_dir}/${file_name}" $download_url ; then
|
|
log "ERROR: failed to download from ${download_url}"
|
|
exit 2
|
|
fi
|
|
}
|
|
|
|
downloadDependencies(){
|
|
if [ "$PROJECT_FILE" ]; then
|
|
dependencies=$(jq -n "$PROJECT_FILE" | jq -jc '.dependencies' )
|
|
required_dependencies=$(jq -n "$dependencies" | jq --arg REQUIRED_FILTER "3" -jc '
|
|
map(select(.relationType==($REQUIRED_FILTER|tonumber)))')
|
|
if [ "$required_dependencies" ]; then
|
|
jq -n "$required_dependencies" | jq -c '.[]?' | while read current_dependency; do
|
|
mod_id=$(jq -n "$current_dependency" | jq -jc '.modId' )
|
|
|
|
# BROKEN: Example Voice mod keeps returning the voice mod file id instead of the mod file id.
|
|
# file_id=$(jq -n "$current_dependency" | jq -jc '.fileId' )
|
|
# dependency_data=$(curl -X GET -s \
|
|
# "${FORGEAPI_BASE_URL}/mods/${mod_id}/files/${file_id}/download-url" \
|
|
# -H 'Accept: application/json' -H 'x-api-key: '${MODS_FORGEAPI_KEY}'')
|
|
# if [ ! "$dependency_data" ]; then
|
|
# log "ERROR: unable to retrieve dependency data files for ${project_id} from ForgeAPI"
|
|
# exit 2
|
|
# fi
|
|
# dependency_download_url=$(jq -n "$dependency_data" | jq -jc '.data' )
|
|
# echo "Downloading dependency ${dependency_download_url}"
|
|
# if ! get -o "${out_dir}/" $dependency_download_url ; then
|
|
# log "ERROR: failed to download dependency from ${dependency_download_url}"
|
|
# exit 2
|
|
# fi
|
|
|
|
# Using current mod path and release to go get the REQUIRED DEPENDENCY
|
|
# NOTE: we are ASUMING it will be release.
|
|
modFileByProjectID $mod_id "release"
|
|
downloadModPackfromModFile
|
|
done
|
|
fi
|
|
fi
|
|
}
|
|
|
|
# Use forge api json file to filter and download the correct mods
|
|
if [ "$MODS_FORGEAPI_FILE" ] && [ -z "$MODS_FORGEAPI_PROJECTIDS" ]; then
|
|
ensureModKey
|
|
if [ ! -f "$MODS_FORGEAPI_FILE" ]; then
|
|
log "ERROR: given MODS_FORGEAPI_FILE file does not exist"
|
|
exit 2
|
|
fi
|
|
|
|
# Needs loop here to look up release types befor calling download.
|
|
jq -n "$required_dependencies" | jq -c '.[]?' | while read current_project; do
|
|
# Per stack overflow we can use //empty to return empty string that works with -z
|
|
project_id=$(jq -n "$current_project" | jq -jc '.projectId // empty' )
|
|
current_release_type=$(jq -n "$current_project" | jq -jc '.releaseType // empty' )
|
|
current_file_name=$(jq -n "$current_project" | jq -jc '.fileName // empty' )
|
|
|
|
modFileByProjectID $project_id $current_release_type $current_file_name
|
|
downloadModPackfromModFile
|
|
if isTrue "${MODS_FORGEAPI_DOWNLOAD_DEPENDENCIES}"; then
|
|
downloadDependencies
|
|
fi
|
|
done
|
|
fi
|
|
|
|
# Use only project ids and global release data.
|
|
if [ "$MODS_FORGEAPI_PROJECTIDS" ] && [ -z "$MODS_FORGEAPI_FILE" ]; then
|
|
ensureModKey
|
|
for project_id in ${MODS_FORGEAPI_PROJECTIDS//,/ }; do
|
|
modFileByProjectID $project_id
|
|
downloadModPackfromModFile
|
|
if isTrue "${MODS_FORGEAPI_DOWNLOAD_DEPENDENCIES}"; then
|
|
downloadDependencies
|
|
fi
|
|
done
|
|
fi
|
|
|
|
exec "${SCRIPTS:-/}start-setupModpack" "$@"
|