| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307 |
- #!/bin/bash
- # LinuxGSM update_hyt.sh module
- # Author: Andrew dos Santos
- # Contributors: https://linuxgsm.com/contrib
- # Website: https://linuxgsm.com
- # Description: Handles updating of Hytale servers.
- moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")"
- fn_update_hyt_downloader_arch() {
- case "${arch}" in
- x86_64 | amd64)
- hytaledownloaderfile="hytale-downloader-linux-amd64"
- ;;
- aarch64 | arm64)
- fn_print_failure "Hytale supports arm64 servers, but the official downloader archive currently used by LinuxGSM does not include a Linux arm64 downloader."
- fn_script_log_fail "Unsupported Hytale downloader architecture: ${arch}"
- core_exit.sh
- ;;
- *)
- fn_print_failure "Unknown or unsupported hytale-downloader architecture: ${arch}"
- fn_script_log_fail "Unknown or unsupported hytale-downloader architecture: ${arch}"
- core_exit.sh
- ;;
- esac
- hytaledownloader="${serverfiles}/${hytaledownloaderfile}"
- }
- fn_update_downloader() {
- fn_update_hyt_downloader_arch
- if [ ! -f "${hytaledownloader}" ] || [ "${forceupdate}" == "1" ]; then
- fn_fetch_file "https://downloader.hytale.com/hytale-downloader.zip" "" "" "" "${tmpdir}" "hytale-downloader.zip" "nochmodx" "norun" "forcedl" "nohash"
- echo -en "extracting hytale-downloader..."
- unzip -oq "${tmpdir}/hytale-downloader.zip" "${hytaledownloaderfile}" "QUICKSTART.md" -d "${serverfiles}"
- exitcode=$?
- if [ "${exitcode}" -ne 0 ]; then
- fn_print_fail_eol_nl
- fn_script_log_fail "Extracting hytale-downloader"
- core_exit.sh
- else
- chmod +x "${hytaledownloader}"
- fn_print_ok_eol_nl
- fn_script_log_pass "Extracting hytale-downloader"
- fi
- fi
- }
- fn_update_hyt_patchline_args() {
- hytalepatchline="${hytalepatchline:-release}"
- hytalepatchlineargs=()
- if [ "${hytalepatchline}" != "release" ]; then
- hytalepatchlineargs=(-patchline "${hytalepatchline}")
- fi
- }
- # The downloader needs a Hytale account login (OAuth device code) the first time it runs, and again
- # if the saved credentials stop working. It waits for the login with no time limit, so it must
- # never run unattended without credentials, otherwise cron jobs hang.
- # Install always shows the login and waits: someone is watching, either in a terminal or in the
- # container logs (e.g. docker logs) during the first install.
- fn_update_hyt_auth() {
- hytalecredentials="${serverfiles}/.hytale-downloader-credentials.json"
- if [ "${firstcommandname}" == "INSTALL" ] || { [ -t 0 ] && [ -t 1 ]; }; then
- hytaledownloadertimeout="900"
- if [ ! -f "${hytalecredentials}" ]; then
- echo -e ""
- echo -e "${bold}${lightyellow}Hytale account login required${default}"
- echo -e "The Hytale downloader needs you to log in with a Hytale account that owns the game."
- echo -e "Open the URL shown below in a browser and approve the code within 15 minutes. This is only needed once."
- echo -e "Running in Docker? The URL is also shown in the container logs (docker logs)."
- echo -e ""
- fn_script_log_info "Hytale downloader login required"
- fi
- else
- hytaledownloadertimeout="300"
- if [ ! -f "${hytalecredentials}" ]; then
- fn_print_failure_nl "Hytale downloader is not logged in"
- echo -e "* Run ./${selfname} update in a terminal and approve the Hytale account login once."
- fn_script_log_fail "Hytale downloader is not logged in: ${hytalecredentials} not found"
- core_exit.sh
- fi
- fi
- }
- # Report a downloader timeout, which usually means it was waiting for a login.
- fn_update_hyt_timeout_check() {
- if [ "${exitcode}" -eq 124 ]; then
- fn_print_failure_nl "Hytale downloader timed out, it is probably waiting for a Hytale account login"
- echo -e "* The saved credentials may have expired. Run ./${selfname} update in a terminal to log in again."
- fn_script_log_fail "Hytale downloader timed out after ${hytaledownloadertimeout}s"
- core_exit.sh
- fi
- }
- fn_update_extract() {
- extractdir="${tmpdir}/hytale-game"
- rm -rf "${extractdir:?}"
- mkdir -p "${extractdir}"
- echo -en "extracting ${remotebuildfilename}..."
- unzip -oq "${tmpdir}/${remotebuildfilename}" -d "${extractdir}"
- exitcode=$?
- if [ "${exitcode}" -ne 0 ]; then
- fn_print_fail_eol_nl
- fn_script_log_fail "Extracting ${remotebuildfilename}"
- core_exit.sh
- fi
- if [ -d "${extractdir}/game/Server" ]; then
- extractedroot="${extractdir}/game"
- else
- extractedroot="${extractdir}"
- fi
- mkdir -p "${serverfiles}"
- if [ "${firstcommandname}" == "INSTALL" ]; then
- cp -a "${extractedroot}/." "${serverfiles}/"
- else
- for item in "${extractedroot}"/*; do
- [ -e "${item}" ] || continue
- itemname="$(basename "${item}")"
- case "${itemname}" in
- Server | .hytale-downloader-credentials.json)
- continue
- ;;
- jvm.options)
- if [ -f "${serverfiles}/jvm.options" ]; then
- continue
- fi
- ;;
- esac
- cp -a "${item}" "${serverfiles}/"
- done
- mkdir -p "${serverfiles}/Server"
- for item in "${extractedroot}/Server"/*; do
- [ -e "${item}" ] || continue
- itemname="$(basename "${item}")"
- case "${itemname}" in
- backups | bans.json | config.json | logs | mods | permissions.json | universe | whitelist.json)
- continue
- ;;
- esac
- cp -a "${item}" "${serverfiles}/Server/"
- done
- fi
- [ -f "${serverfiles}/start.sh" ] && chmod +x "${serverfiles}/start.sh"
- fn_print_ok_eol_nl
- fn_script_log_pass "Extracting ${remotebuildfilename}"
- rm -rf "${extractdir:?}"
- }
- fn_update_dl() {
- fn_update_downloader
- fn_update_hyt_patchline_args
- remotebuildfilename="hytale-server-${remotebuild:-latest}.zip"
- echo -e "downloading file [ ${italic}${remotebuildfilename}${default} ]"
- fn_sleep_time
- cd "${serverfiles}" || exit
- fn_update_hyt_auth
- timeout --foreground "${hytaledownloadertimeout}" "${hytaledownloader}" -download-path "${tmpdir}/${remotebuildfilename}" "${hytalepatchlineargs[@]}" -skip-update-check
- exitcode=$?
- fn_update_hyt_timeout_check
- if [ "${exitcode}" -ne 0 ]; then
- fn_print_failure_nl "Downloading ${remotebuildfilename}"
- fn_script_log_fail "Downloading ${remotebuildfilename}"
- core_exit.sh
- fi
- fn_update_extract
- if [ -n "${remotebuild}" ]; then
- echo "${remotebuild}" > "${localbuildfile}"
- fi
- fn_clear_tmp
- }
- fn_update_hyt_check_localbuild_tracking() {
- if [ -f "${localbuildfile}" ] && [ -f "${serverfiles}/Server/HytaleServer.jar" ] && [ "${serverfiles}/Server/HytaleServer.jar" -nt "${localbuildfile}" ]; then
- fn_print_warn_nl "Hytale server files are newer than LinuxGSM build tracking"
- echo -e "* Hytale may have updated itself outside LinuxGSM."
- echo -e "* Run ./${selfname} update to refresh LinuxGSM version tracking."
- fn_script_log_warn "Hytale server files are newer than LinuxGSM build tracking"
- fi
- }
- fn_update_localbuild() {
- fn_print_dots "Checking local build: ${remotelocation}"
- if [ -f "${localbuildfile}" ]; then
- localbuild="$(cat "${localbuildfile}")"
- fi
- if [ -z "${localbuild}" ]; then
- fn_print_error "Checking local build: ${remotelocation}: missing local build info"
- fn_script_log_error "Missing local build info"
- fn_script_log_error "Set localbuild to 0"
- localbuild="0"
- else
- fn_print_ok "Checking local build: ${remotelocation}"
- fn_script_log_pass "Checking local build"
- fn_update_hyt_check_localbuild_tracking
- fi
- }
- fn_update_remotebuild() {
- fn_update_downloader
- fn_update_hyt_patchline_args
- cd "${serverfiles}" || exit
- remotebuildresponsefile="${tmpdir}/hytale-print-version-response.txt"
- rm -f "${remotebuildresponsefile}"
- fn_update_hyt_auth
- timeout --foreground "${hytaledownloadertimeout}" "${hytaledownloader}" -print-version "${hytalepatchlineargs[@]}" -skip-update-check 2>&1 | tee "${remotebuildresponsefile}"
- exitcode=${PIPESTATUS[0]}
- fn_update_hyt_timeout_check
- remotebuildresponse="$(cat "${remotebuildresponsefile}")"
- if [ -f "${lgsmlog}" ]; then
- cat "${remotebuildresponsefile}" >> "${lgsmlog}"
- fi
- remotebuild=$(echo "${remotebuildresponse}" | grep -Eo "[0-9]{4}\.[0-9]{2}\.[0-9]{2}-[A-Za-z0-9]+" | tail -1)
- if [ -z "${remotebuild}" ]; then
- remotebuild=$(echo "${remotebuildresponse}" | tail -1)
- fi
- if [ "${firstcommandname}" != "INSTALL" ]; then
- fn_print_dots "Checking remote build: ${remotelocation}"
- if [ "${exitcode}" -ne 0 ] || [ -z "${remotebuild}" ] || [ "${remotebuild}" == "null" ]; then
- fn_print_fail "Checking remote build: ${remotelocation}"
- fn_script_log_fail "Checking remote build"
- core_exit.sh
- else
- fn_print_ok "Checking remote build: ${remotelocation}"
- fn_script_log_pass "Checking remote build"
- fi
- else
- if [ "${exitcode}" -ne 0 ] || [ -z "${remotebuild}" ] || [ "${remotebuild}" == "null" ]; then
- fn_print_failure "Unable to get remote build"
- fn_script_log_fail "Unable to get remote build"
- core_exit.sh
- fi
- fi
- }
- fn_update_compare() {
- fn_print_dots "Checking for update: ${remotelocation}"
- if [ "${localbuild}" != "${remotebuild}" ] || [ "${forceupdate}" == "1" ]; then
- date '+%s' > "${lockdir:?}/update.lock"
- fn_print_ok_nl "Checking for update: ${remotelocation}"
- fn_print "\n"
- fn_print_nl "${bold}${underline}Update${default} available"
- fn_print_nl "* Local build: ${red}${localbuild}${default}"
- fn_print_nl "* Remote build: ${green}${remotebuild}${default}"
- fn_print_nl "* Patchline: ${hytalepatchline}"
- fn_print "\n"
- fn_script_log_info "Update available"
- fn_script_log_info "Local build: ${localbuild}"
- fn_script_log_info "Remote build: ${remotebuild}"
- fn_script_log_info "Patchline: ${hytalepatchline}"
- if [ "${commandname}" == "UPDATE" ]; then
- date +%s > "${lockdir:?}/last-updated.lock"
- unset updateonstart
- check_status.sh
- if [ "${status}" == "0" ]; then
- fn_update_dl
- else
- fn_print_restart_warning
- exitbypass=1
- command_stop.sh
- fn_firstcommand_reset
- exitbypass=1
- fn_update_dl
- exitbypass=1
- command_start.sh
- fn_firstcommand_reset
- fi
- unset exitbypass
- alert="update"
- elif [ "${commandname}" == "CHECK-UPDATE" ]; then
- alert="check-update"
- fi
- alert.sh
- else
- fn_print_ok_nl "Checking for update: ${remotelocation}"
- fn_print "\n"
- fn_print_nl "${bold}${underline}No update${default} available"
- fn_print_nl "* Local build: ${green}${localbuild}${default}"
- fn_print_nl "* Remote build: ${green}${remotebuild}${default}"
- fn_print_nl "* Patchline: ${hytalepatchline}"
- fn_print "\n"
- fn_script_log_info "No update available"
- fn_script_log_info "Local build: ${localbuild}"
- fn_script_log_info "Remote build: ${remotebuild}"
- fn_script_log_info "Patchline: ${hytalepatchline}"
- fi
- }
- info_distro.sh
- localbuildfile="${datadir}/${selfname}-hytale-version"
- remotelocation="hytale.com"
- if [ "${firstcommandname}" == "INSTALL" ]; then
- fn_update_remotebuild
- fn_update_dl
- else
- fn_print_dots "Checking for update"
- fn_print_dots "Checking for update: ${remotelocation}"
- fn_script_log_info "Checking for update: ${remotelocation}"
- fn_update_localbuild
- fn_update_remotebuild
- fn_update_compare
- fi
|