scripts/mcjar
2024-05-03 16:32:12 -04:00

322 lines
7.1 KiB
Bash
Executable file

#!/bin/sh
set -e
lower() {
echo "$1" | tr '[:upper:]' '[:lower:]'
}
upper() {
echo "$1" | tr '[:lower:]' '[:upper:]'
}
# global
MC_TYPE="$(lower "${MC_TYPE:-vanilla}")"
MC_VERSION="$(lower "${MC_VERSION:-latest}")"
# papermc
PAPERMC_BUILD="$(lower "${PAPERMC_BUILD:-latest}")"
# fabric
FABRIC_LOADER="$(lower "${FABRIC_LOADER:-latest}")"
FABRIC_INSTALLER="$(lower "${FABRIC_INSTALLER:-latest}")"
# forge
FORGE_VERSION="$(lower "${FORGE_VERSION:-recommended}")"
# other
QUIET=1
req() {
res=$(curl --fail --silent "$1")
code=$?
if [ $code -ne 0 ] || [ "$res" = "" ]; then
echo "null";
else
echo "$res";
fi
}
error() {
printf '\x1b[31m[ERROR]\t\x1b[0m%s\n' "$*" > /dev/stderr
exit 1;
}
log() {
if [ "$QUIET" -eq 0 ]; then
printf '\x1b[0m[LOG]\t%s\n' "$*" > /dev/stderr
fi
}
index_array() {
array="$1"
key="$2"
type="$3"
if [ "$key" = "latest" ]; then
index=$(echo "$array" | jq ". | index( last )");
else
index=$(echo "$array" | jq ". | index( \"$key\" )");
fi
if [ "$index" = "null" ]; then
error "Invalid $type: $key"
else
echo "$array" | jq -r ".[$index]";
fi
}
#https://api.papermc.io/v2/projects/velocity/versions/3.3.0-SNAPSHOT/
papermc() {
api="https://api.papermc.io/v2/projects"
log "Using papermc api v2"
get_version() {
log "Getting VERSION for '$MC_TYPE'"
versions=$(req "$api/$MC_TYPE" | jq -r '.versions')
if [ "$versions" = "null" ]; then
error "Invalid TYPE: $MC_TYPE (no versions)"
fi
MC_VERSION=$(index_array "$versions" "$MC_VERSION" "VERSION")
log "VERSION: $MC_VERSION"
}
get_build() {
log "Getting BUILD for '$MC_TYPE@$MC_VERSION'"
builds=$(req "$api/$MC_TYPE/versions/$MC_VERSION" | jq -r ".builds")
if [ "$builds" = "null" ]; then
error "Invalid VERSION: $MC_TYPE@$MC_TYPE (no builds)"
fi
PAPERMC_BUILD=$(index_array "$builds" "$PAPERMC_BUILD" "BUILD")
log "BUILD: $PAPERMC_BUILD"
}
get_version
get_build
echo "$api/$MC_TYPE/versions/$MC_VERSION/builds/$PAPERMC_BUILD/downloads/$MC_TYPE-$MC_VERSION-$PAPERMC_BUILD.jar"
}
fabric() {
api="https://meta.fabricmc.net/v2/versions"
log "Using fabric api v2"
get_fabric_impl() {
type="$1"
value="$2"
res=""
if [ "$value" = "latest" ]; then
res=$(req "$api/$type" | jq -r 'map(select(.stable == true) | .version) | reverse')
else
res=$(req "$api/$type" | jq -r 'map(.version) | reverse')
fi;
echo $res;
}
get_game() {
log "Getting VERSION for '$MC_TYPE'"
games=$(get_fabric_impl "game" "$MC_VERSION")
MC_VERSION=$(index_array "$games" "$MC_VERSION" "VERSION")
log "VERSION: $MC_VERSION"
}
get_loader() {
log "Getting LOADER for '$MC_TYPE'"
loaders=$(get_fabric_impl "loader" "$FABRIC_LOADER")
FABRIC_LOADER=$(index_array "$loaders" "$FABRIC_LOADER" "LOADER")
log "LOADER: $FABRIC_LOADER"
}
get_installer() {
log "Getting INSTALLER for '$MC_TYPE'"
installers=$(get_fabric_impl "installer" "$FABRIC_INSTALLER")
FABRIC_INSTALLER=$(index_array "$installers" "$FABRIC_INSTALLER" "INSTALLER")
log "INSTALLER: $FABRIC_INSTALLER"
}
get_game
get_loader
get_installer
echo "$api/loader/$MC_VERSION/$FABRIC_LOADER/$FABRIC_INSTALLER/server/jar"
}
vanilla() {
versions=$(req 'https://launchermeta.mojang.com/mc/game/version_manifest.json' | jq '.versions | map({ "id": .id, "type": .type, "url": .url }) | reverse');
map_type_impl() {
type="$1"
echo "$versions" | jq -r "map(select(.type == \"$type\"))"
}
get_version() {
log "Getting VERSION for '$MC_TYPE'"
version=""
case "$MC_VERSION" in
"latest")
version=$(map_type_impl "release" | jq -r 'last')
;;
"snapshot")
version=$(map_type_impl "snapshot" | jq -r 'last')
;;
*)
version=$(echo "$versions" | jq ".[] | select(.id == \"$MC_VERSION\")")
;;
esac
if [ "$version" = "null" ] || [ "$version" = "" ]; then
error "Invalid VERSION: $MC_VERSION"
fi
log "VERSION: $(echo "$version" | jq -r '.id')"
json=$(echo "$version" | jq -r '.url')
url=$(req "$json" | jq -r '.downloads.server.url')
if [ "$url" = "null" ]; then
error "Cannot get server jar for VERSION: $MC_VERSION"
fi
echo "$url"
}
get_version
}
forge() {
versions=$(req "https://files.minecraftforge.net/net/minecraftforge/forge/promotions_slim.json" | jq -r '.promos');
log "Using forge promotions slim json"
get_forge_url() {
url="https://maven.minecraftforge.net/net/minecraftforge/forge/$1/forge-$1-installer.jar"
code=0
wget -q --spider "$url" || code=$?
if [ $code -eq 0 ]; then
echo "$url";
fi
}
get_version() {
log "Getting VERSION for '$MC_TYPE'"
if [ "$MC_VERSION" = "latest" ]; then
MC_VERSION=$(echo "$versions" | jq -r '. | keys | .[]' | awk -F '-' '{print $1}' | sort -t "." -n -k1,1 -k2,2 -k3,3 | tail -n1)
fi
log "VERSION: $MC_VERSION"
}
try_forge_version() {
ver=$(echo "$versions" | jq -r ".\"$MC_VERSION-$FORGE_VERSION\"")
if [ "$ver" = "null" ] && [ "$FORGE_VERSION" != "latest" ]; then
FORGE_VERSION=latest
try_forge_version
else
echo "$ver"
fi
}
get_forge_version() {
log "Getting FORGE VERSION for '$MC_TYPE'"
if [ "$FORGE_VERSION" != "latest" ] && [ "$FORGE_VERSION" != "recommended" ]; then
return;
fi
ver=$(try_forge_version)
if [ "$ver" = "null" ]; then
error "Invalid VERSION: $MC_VERSION-$FORGE_VERSION"
fi
FORGE_VERSION="$ver"
log "FORGE VERSION: $FORGE_VERSION"
}
search_for_url() {
log "Searching for forge URL"
log "Trying MC_VERSION-FORGE_VERSION"
ver=$(get_forge_url "$MC_VERSION-$FORGE_VERSION")
if [ "$ver" != "" ]; then echo "$ver"; return 0; fi
log "Trying MC_VERSION-FORGE_VERSION-MC_VERSION"
ver=$(get_forge_url "$MC_VERSION-$FORGE_VERSION-$MC_VERSION")
if [ "$ver" != "" ]; then echo "$ver"; return 0; fi
log "Trying MC_VERSION-FORGE_VERSION-mc172"
ver=$(get_forge_url "$MC_VERSION-$FORGE_VERSION-mc172")
if [ "$ver" != "" ]; then echo "$ver"; return 0; fi
error "Invalid VERSION: $MC_VERSION-$FORGE_VERSION"
}
get_version
get_forge_version
search_for_url
}
get_url() {
log "TYPE: $MC_TYPE"
case "$MC_TYPE" in
"vanilla")
vanilla
;;
"paper" | "waterfall" | "velocity" | "folia")
papermc
;;
"fabric")
fabric
;;
"forge")
forge
;;
*)
error "Invalid TYPE: $MC_TYPE"
;;
esac
}
usage() {
printf "usage: mcjar [options]\n"
}
help() {
printf "usage: mcjar [options]\n\n"
printf "options:\n"
printf "\t-h\tshow this message\n"
printf "\t-l\tshow logging (verbose)\n\n"
printf "\t-t TYPE\t\tset the mc server type\n"
printf "\t [vanilla,fabric,forge,paper,folia,velocity,waterfall]\n\n"
printf "\t-v VERSION\tset the mc server version\n"
printf "\t [latest,snapshot,<version>]\n\n"
printf "environment:\n"
printf "\tMC_TYPE\t\tsets the mc server type (same as -t TYPE)\n"
printf "\tMC_VERSION\tsets the mc server version (same as -v VERSION)\n\n"
printf "\tPAPERMC_BUILD\tsets the papermc build\n\n"
printf "\tFABRIC_LOADER\t\tsets the fabric loder version\n"
printf "\tFABRIC_INSTALLER\tsets the fabric installer version\n\n"
}
while getopts "hlt:v:" arg > /dev/null; do
case $arg in
h)
help
exit 0
;;
l)
QUIET=0
;;
t)
MC_TYPE=${OPTARG}
;;
v)
MC_VERSION=${OPTARG}
;;
?)
error "unknown option"
;;
esac;
done;
get_url