2018-01-07 23:18:45 +00:00
|
|
|
#!/bin/bash
|
|
|
|
|
2022-08-21 20:31:54 +00:00
|
|
|
function get_from_gh() {
|
|
|
|
if [[ "${GH_TOKEN:-}" ]]; then
|
|
|
|
# User has provided a Personal Access Token to mitigate rate-limiting issues
|
|
|
|
if [[ -z "${oAuthScopes}" ]]; then
|
|
|
|
oAuthScopes=$(curl -s -H "Authorization: token $GH_TOKEN" https://api.github.com/users/codertocat -I | grep x-oauth-scopes)
|
|
|
|
fi
|
|
|
|
if [[ ! "$oAuthScopes" =~ ^x-oauth-scopes:[[:space:]]*$ ]]; then
|
|
|
|
# Don't use what you don't have to...
|
|
|
|
log "ERROR: GH_TOKEN has permissions it doesn't need. Recreate or update this personal access token and disable ALL scopes."
|
|
|
|
exit 1
|
|
|
|
else
|
2022-09-09 01:23:34 +00:00
|
|
|
curl -fsSL -H "Authorization: token $GH_TOKEN" "${@:2}" "$1"
|
2022-08-21 20:31:54 +00:00
|
|
|
fi
|
|
|
|
else
|
2022-09-09 01:23:34 +00:00
|
|
|
curl -fsSL "${@:2}" "$1"
|
2022-08-21 20:31:54 +00:00
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
2020-12-12 21:22:07 +00:00
|
|
|
function join_by() {
|
|
|
|
local d=$1
|
|
|
|
shift
|
|
|
|
echo -n "$1"
|
|
|
|
shift
|
|
|
|
printf "%s" "${@/#/$d}"
|
|
|
|
}
|
2020-07-18 23:31:29 +00:00
|
|
|
|
2022-03-06 20:57:00 +00:00
|
|
|
function get_major_version() {
|
|
|
|
version=$1
|
|
|
|
echo "$version" | cut -d. -f 1-2
|
|
|
|
}
|
|
|
|
|
2020-12-12 21:22:07 +00:00
|
|
|
function isURL() {
|
2018-01-07 23:18:45 +00:00
|
|
|
local value=$1
|
|
|
|
|
2021-04-28 21:44:39 +00:00
|
|
|
if [[ ${value:0:8} == "https://" || ${value:0:7} == "http://" || ${value:0:6} == "ftp://" ]]; then
|
2018-01-07 23:18:45 +00:00
|
|
|
return 0
|
|
|
|
else
|
|
|
|
return 1
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
2020-12-12 21:22:07 +00:00
|
|
|
function isValidFileURL() {
|
|
|
|
suffix=${1:?Missing required suffix arg}
|
|
|
|
url=${2:?Missing required url arg}
|
|
|
|
|
|
|
|
[[ "$url" == http*://*.${suffix} || "$url" == http*://*.${suffix}\?* ]]
|
|
|
|
}
|
|
|
|
|
|
|
|
function resolveEffectiveUrl() {
|
|
|
|
url="${1:?Missing required url argument}"
|
2022-09-09 01:23:34 +00:00
|
|
|
if ! curl -Ls -o /dev/null -w "%{url_effective}" "$url"; then
|
2020-12-12 21:22:07 +00:00
|
|
|
log "ERROR failed to resolve effective URL from $url"
|
|
|
|
exit 2
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
|
|
|
function getFilenameFromUrl() {
|
|
|
|
url="${1:?Missing required url argument}"
|
|
|
|
strippedOfQuery="${url%\?*}"
|
|
|
|
basename "$strippedOfQuery"
|
|
|
|
}
|
|
|
|
|
|
|
|
function isTrue() {
|
2022-09-10 19:39:44 +00:00
|
|
|
case "${1,,}" in
|
2022-09-10 17:58:32 +00:00
|
|
|
true | on | 1)
|
|
|
|
return 0
|
2020-12-12 21:22:07 +00:00
|
|
|
;;
|
|
|
|
*)
|
2022-09-10 17:58:32 +00:00
|
|
|
return 1
|
2020-12-12 21:22:07 +00:00
|
|
|
;;
|
2018-01-07 23:18:45 +00:00
|
|
|
esac
|
2019-02-03 15:49:59 +00:00
|
|
|
}
|
|
|
|
|
2022-06-05 20:16:12 +00:00
|
|
|
function isFalse() {
|
2022-09-10 19:39:44 +00:00
|
|
|
case "${1,,}" in
|
2022-09-10 17:58:32 +00:00
|
|
|
false | off | 0)
|
|
|
|
return 0
|
2022-06-05 20:16:12 +00:00
|
|
|
;;
|
|
|
|
*)
|
2022-09-10 17:58:32 +00:00
|
|
|
return 1
|
2022-06-05 20:16:12 +00:00
|
|
|
;;
|
|
|
|
esac
|
|
|
|
}
|
|
|
|
|
2020-12-12 21:22:07 +00:00
|
|
|
function isDebugging() {
|
2021-03-21 16:43:21 +00:00
|
|
|
if isTrue "${DEBUG:-false}"; then
|
2019-02-03 15:49:59 +00:00
|
|
|
return 0
|
|
|
|
else
|
|
|
|
return 1
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
2021-03-21 16:43:21 +00:00
|
|
|
function handleDebugMode() {
|
|
|
|
if isDebugging; then
|
|
|
|
set -x
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
2020-12-12 21:22:07 +00:00
|
|
|
function debug() {
|
2019-02-03 15:49:59 +00:00
|
|
|
if isDebugging; then
|
2020-03-06 15:52:17 +00:00
|
|
|
log "DEBUG: $*"
|
2019-02-03 15:49:59 +00:00
|
|
|
fi
|
2019-11-21 19:50:06 +00:00
|
|
|
}
|
2020-03-06 15:52:17 +00:00
|
|
|
|
2020-12-12 21:22:07 +00:00
|
|
|
function logn() {
|
2020-03-06 15:52:17 +00:00
|
|
|
echo -n "[init] $*"
|
|
|
|
}
|
|
|
|
|
2020-12-12 21:22:07 +00:00
|
|
|
function log() {
|
2022-02-05 18:27:17 +00:00
|
|
|
local oldState
|
|
|
|
# The return status when listing options is zero if all optnames are enabled, non- zero otherwise.
|
|
|
|
oldState=$(shopt -po xtrace || true)
|
|
|
|
shopt -u -o xtrace
|
|
|
|
|
|
|
|
if isDebugging || isTrue "${LOG_TIMESTAMP:-false}"; then
|
|
|
|
ts=" $(date --rfc-3339=seconds)"
|
|
|
|
else
|
|
|
|
ts=
|
|
|
|
fi
|
|
|
|
echo "[init]${ts} $*"
|
|
|
|
eval "$oldState"
|
2020-03-06 15:52:17 +00:00
|
|
|
}
|
2020-04-11 15:41:20 +00:00
|
|
|
|
2020-12-12 21:22:07 +00:00
|
|
|
function logAutopause() {
|
2020-05-23 14:15:10 +00:00
|
|
|
echo "[Autopause loop] $*"
|
|
|
|
}
|
|
|
|
|
2020-12-12 21:22:07 +00:00
|
|
|
function logAutopauseAction() {
|
2020-05-23 14:15:10 +00:00
|
|
|
echo "[$(date -Iseconds)] [Autopause] $*"
|
|
|
|
}
|
|
|
|
|
2021-12-21 00:27:27 +00:00
|
|
|
function logAutostop() {
|
|
|
|
echo "[Autostop loop] $*"
|
|
|
|
}
|
|
|
|
|
|
|
|
function logAutostopAction() {
|
|
|
|
echo "[$(date -Iseconds)] [Autostop] $*"
|
|
|
|
}
|
|
|
|
|
2022-03-02 17:29:12 +00:00
|
|
|
function logRcon() {
|
|
|
|
echo "[Rcon loop] $*"
|
|
|
|
}
|
|
|
|
|
2020-12-12 21:22:07 +00:00
|
|
|
function normalizeMemSize() {
|
2020-04-11 15:41:20 +00:00
|
|
|
local scale=1
|
|
|
|
case ${1,,} in
|
2020-12-12 21:22:07 +00:00
|
|
|
*k)
|
|
|
|
scale=1024
|
|
|
|
;;
|
|
|
|
*m)
|
|
|
|
scale=1048576
|
|
|
|
;;
|
|
|
|
*g)
|
|
|
|
scale=1073741824
|
|
|
|
;;
|
2020-04-11 15:41:20 +00:00
|
|
|
esac
|
|
|
|
|
2020-12-12 21:22:07 +00:00
|
|
|
val=${1:0:-1}
|
|
|
|
echo $((val * scale))
|
2020-04-11 15:41:20 +00:00
|
|
|
}
|
2020-04-13 23:29:44 +00:00
|
|
|
|
2020-12-12 21:22:07 +00:00
|
|
|
function versionLessThan() {
|
2022-09-09 01:23:34 +00:00
|
|
|
# Use if-else since strict mode might be enabled
|
2023-06-17 18:00:22 +00:00
|
|
|
if mc-image-helper compare-versions "${VERSION}" lt "${1?}"; then
|
2022-09-09 01:23:34 +00:00
|
|
|
return 0
|
|
|
|
else
|
|
|
|
return 1
|
|
|
|
fi
|
2020-06-19 16:31:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
requireVar() {
|
2022-09-09 01:23:34 +00:00
|
|
|
if [ ! -v "$1" ]; then
|
2020-06-19 16:31:56 +00:00
|
|
|
log "ERROR: $1 is required to be set"
|
|
|
|
exit 1
|
|
|
|
fi
|
2020-07-19 20:01:19 +00:00
|
|
|
if [ -z "${!1}" ]; then
|
|
|
|
log "ERROR: $1 is required to be set"
|
|
|
|
exit 1
|
|
|
|
fi
|
2020-06-19 16:31:56 +00:00
|
|
|
}
|
2020-07-26 18:19:45 +00:00
|
|
|
|
2021-02-09 02:42:54 +00:00
|
|
|
requireEnum() {
|
|
|
|
var=${1?}
|
|
|
|
shift
|
|
|
|
|
2022-09-09 01:23:34 +00:00
|
|
|
for allowed in "$@"; do
|
|
|
|
if [[ ${!var} = "$allowed" ]]; then
|
2021-02-09 02:42:54 +00:00
|
|
|
return 0
|
|
|
|
fi
|
|
|
|
done
|
|
|
|
|
2021-12-11 02:50:40 +00:00
|
|
|
log "ERROR: $var must be set to one of $*"
|
2021-02-09 02:42:54 +00:00
|
|
|
# exit 1
|
|
|
|
}
|
|
|
|
|
2020-07-26 18:19:45 +00:00
|
|
|
function writeEula() {
|
2021-01-20 03:36:21 +00:00
|
|
|
if ! echo "# Generated via Docker
|
|
|
|
# $(date)
|
2020-07-26 18:19:45 +00:00
|
|
|
eula=${EULA,,}
|
2020-12-12 21:22:07 +00:00
|
|
|
" >/data/eula.txt; then
|
|
|
|
log "ERROR: unable to write eula to /data. Please make sure attached directory is writable by uid=${UID}"
|
|
|
|
exit 2
|
|
|
|
fi
|
2020-07-26 18:19:45 +00:00
|
|
|
}
|
2021-04-28 21:29:47 +00:00
|
|
|
|
|
|
|
function removeOldMods {
|
|
|
|
if [ -d "$1" ]; then
|
2022-07-30 02:28:04 +00:00
|
|
|
log "Removing old mods including:${REMOVE_OLD_MODS_INCLUDE} excluding:${REMOVE_OLD_MODS_EXCLUDE}"
|
2023-08-03 18:04:26 +00:00
|
|
|
args=(
|
|
|
|
--delete
|
|
|
|
--type file
|
|
|
|
--min-depth=1 --max-depth "${REMOVE_OLD_MODS_DEPTH:-16}"
|
|
|
|
--name "${REMOVE_OLD_MODS_INCLUDE:-*}"
|
|
|
|
--exclude-name "${REMOVE_OLD_MODS_EXCLUDE:-}"
|
|
|
|
)
|
|
|
|
if ! isDebugging; then
|
|
|
|
args+=(--quiet)
|
|
|
|
fi
|
|
|
|
mc-image-helper find "${args[@]}" "$1"
|
2021-04-28 21:29:47 +00:00
|
|
|
fi
|
|
|
|
}
|
2021-10-09 20:22:42 +00:00
|
|
|
|
|
|
|
function get() {
|
2022-06-27 14:08:21 +00:00
|
|
|
mc-image-helper get "$@"
|
2021-12-11 02:50:40 +00:00
|
|
|
}
|
|
|
|
|
2022-03-16 01:56:25 +00:00
|
|
|
function get_silent() {
|
|
|
|
local flags=(-s)
|
|
|
|
if isTrue "${DEBUG_GET:-false}"; then
|
|
|
|
flags+=("--debug")
|
|
|
|
fi
|
|
|
|
mc-image-helper "${flags[@]}" get "$@"
|
|
|
|
}
|
|
|
|
|
2021-12-11 02:50:40 +00:00
|
|
|
function isFamily() {
|
|
|
|
for f in "${@}"; do
|
2022-02-09 01:24:38 +00:00
|
|
|
if [[ ${FAMILY^^} == "${f^^}" ]]; then
|
2021-12-11 02:50:40 +00:00
|
|
|
return 0
|
|
|
|
fi
|
|
|
|
done
|
2022-01-17 02:49:15 +00:00
|
|
|
return 1
|
|
|
|
}
|
2022-02-09 01:24:38 +00:00
|
|
|
|
2022-01-17 02:49:15 +00:00
|
|
|
function isType() {
|
|
|
|
for t in "${@}"; do
|
2022-01-29 20:53:34 +00:00
|
|
|
# shellcheck disable=SC2153
|
2022-01-17 02:49:15 +00:00
|
|
|
if [[ $TYPE == "$t" ]]; then
|
|
|
|
return 0
|
|
|
|
fi
|
|
|
|
done
|
2021-12-11 02:50:40 +00:00
|
|
|
return 1
|
2022-01-24 04:19:25 +00:00
|
|
|
}
|
|
|
|
|
2022-01-29 20:53:34 +00:00
|
|
|
function evaluateJavaCompatibilityForForge() {
|
|
|
|
javaRelease=$(mc-image-helper java-release)
|
|
|
|
if versionLessThan 1.18 && (( javaRelease > 8 )); then
|
|
|
|
log "**********************************************************************"
|
|
|
|
log "WARNING: Some mods and modpacks may require Java 8."
|
|
|
|
log " Please use itzg/minecraft-server:java8"
|
|
|
|
log "**********************************************************************"
|
|
|
|
sleep 5
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
2022-01-24 04:19:25 +00:00
|
|
|
function extract() {
|
|
|
|
src=${1?}
|
|
|
|
destDir=${2?}
|
|
|
|
|
|
|
|
type=$(file -b --mime-type "${src}")
|
2022-01-25 22:19:15 +00:00
|
|
|
case "${type}" in
|
|
|
|
application/zip)
|
2022-03-15 02:07:06 +00:00
|
|
|
unzip -o -q -d "${destDir}" "${src}"
|
2022-01-25 22:19:15 +00:00
|
|
|
;;
|
2022-07-16 16:05:32 +00:00
|
|
|
application/x-tar|application/gzip|application/x-gzip|application/x-bzip2)
|
2022-01-25 22:19:15 +00:00
|
|
|
tar -C "${destDir}" -xf "${src}"
|
|
|
|
;;
|
2022-07-16 16:05:32 +00:00
|
|
|
application/zstd|application/x-zstd)
|
|
|
|
tar -C "${destDir}" --use-compress-program=unzstd -xf "${src}"
|
|
|
|
;;
|
2022-01-25 22:19:15 +00:00
|
|
|
*)
|
|
|
|
log "ERROR: unsupported archive type: $type"
|
|
|
|
return 1
|
|
|
|
;;
|
|
|
|
esac
|
|
|
|
}
|
2022-02-09 01:17:26 +00:00
|
|
|
|
2022-02-12 03:00:24 +00:00
|
|
|
function getDistro() {
|
2022-09-09 01:23:34 +00:00
|
|
|
grep -E "^ID=" /etc/os-release | cut -d= -f2 | sed -e 's/"//g'
|
2022-02-12 03:00:24 +00:00
|
|
|
}
|
|
|
|
|
2022-02-09 01:17:26 +00:00
|
|
|
function checkSum() {
|
|
|
|
local sum_file=${1?}
|
|
|
|
|
|
|
|
# Get distro
|
2022-02-12 03:00:24 +00:00
|
|
|
distro=$(getDistro)
|
2022-08-21 20:31:54 +00:00
|
|
|
|
2022-02-09 01:17:26 +00:00
|
|
|
if [ "${distro}" == "debian" ] && sha1sum -c "${sum_file}" --status 2> /dev/null; then
|
|
|
|
return 0
|
|
|
|
elif [ "${distro}" == "ubuntu" ] && sha1sum -c "${sum_file}" --status 2> /dev/null; then
|
|
|
|
return 0
|
|
|
|
elif [ "${distro}" == "alpine" ] && sha1sum -c "${sum_file}" -s 2> /dev/null; then
|
|
|
|
return 0
|
2022-07-16 15:11:11 +00:00
|
|
|
elif [ "${distro}" == "ol" ] && sha1sum -c "${sum_file}" --status 2> /dev/null; then
|
|
|
|
return 0
|
2022-02-09 01:17:26 +00:00
|
|
|
else
|
|
|
|
return 1
|
|
|
|
fi
|
|
|
|
}
|
2023-06-10 17:51:49 +00:00
|
|
|
|
|
|
|
function usesMods() {
|
|
|
|
case "$FAMILY" in
|
|
|
|
FORGE|FABRIC|HYBRID|SPONGE)
|
|
|
|
return 0
|
|
|
|
esac
|
|
|
|
return 1
|
|
|
|
}
|
|
|
|
|
|
|
|
function usesPlugins() {
|
|
|
|
case "$FAMILY" in
|
|
|
|
SPIGOT|HYBRID)
|
|
|
|
return 0
|
|
|
|
esac
|
|
|
|
return 1
|
2023-06-17 18:00:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
function resolveVersion() {
|
|
|
|
givenVersion="$VERSION"
|
|
|
|
# shellcheck disable=SC2153
|
|
|
|
if ! VERSION=$(mc-image-helper resolve-minecraft-version "$VERSION"); then
|
|
|
|
exit 2
|
|
|
|
fi
|
|
|
|
log "Resolved version given ${givenVersion} into ${VERSION}"
|
|
|
|
}
|
|
|
|
|
|
|
|
function resolveFamily() {
|
|
|
|
case "$TYPE" in
|
|
|
|
PAPER|SPIGOT|BUKKIT|CANYON|PUFFERFISH|PURPUR)
|
|
|
|
FAMILY=SIGOT
|
|
|
|
;;
|
|
|
|
FORGE)
|
|
|
|
FAMILY=FORGE
|
|
|
|
;;
|
|
|
|
FABRIC|QUILT)
|
|
|
|
FAMILY=FABRIC
|
|
|
|
;;
|
|
|
|
esac
|
|
|
|
export FAMILY
|
2023-06-10 17:51:49 +00:00
|
|
|
}
|