diff --git a/lgsm/functions/core_dl.sh b/lgsm/functions/core_dl.sh new file mode 100644 index 000000000..405e9dc6b --- /dev/null +++ b/lgsm/functions/core_dl.sh @@ -0,0 +1,627 @@ +#!/bin/bash +# LinuxGSM core_dl.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Deals with all downloads for LinuxGSM. + +# remote_fileurl: The URL of the file: http://example.com/dl/File.tar.bz2 +# local_filedir: location the file is to be saved: /home/server/lgsm/tmp +# local_filename: name of file (this can be different from the url name): file.tar.bz2 +# chmodx: Optional, set to "chmodx" to make file executable using chmod +x +# run: Optional, set run to execute the file after download +# forcedl: Optional, force re-download of file even if exists +# hash: Optional, set an hash sum and will compare it against the file. +# +# Downloads can be defined in code like so: +# fn_fetch_file "${remote_fileurl}" "${remote_fileurl_backup}" "${remote_fileurl_name}" "${remote_fileurl_backup_name}" "${local_filedir}" "${local_filename}" "${chmodx}" "${run}" "${forcedl}" "${hash}" +# fn_fetch_file "http://example.com/file.tar.bz2" "http://example.com/file2.tar.bz2" "file.tar.bz2" "file2.tar.bz2" "/some/dir" "file.tar.bz2" "chmodx" "run" "forcedl" "10cd7353aa9d758a075c600a6dd193fd" + +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" + +fn_dl_steamcmd() { + fn_print_start_nl "${remotelocation}" + fn_script_log_info "${commandaction} ${selfname}: ${remotelocation}" + if [ -n "${branch}" ]; then + echo -e "Branch: ${branch}" + fn_script_log_info "Branch: ${branch}" + fi + if [ -n "${betapassword}" ]; then + echo -e "Branch password: ${betapassword}" + fn_script_log_info "Branch password: ${betapassword}" + fi + if [ -d "${steamcmddir}" ]; then + cd "${steamcmddir}" || exit + fi + + # Unbuffer will allow the output of steamcmd not buffer allowing a smooth output. + # unbuffer us part of the expect package. + if [ "$(command -v unbuffer)" ]; then + unbuffer="unbuffer" + fi + + # Validate will be added as a parameter if required. + if [ "${commandname}" == "VALIDATE" ] || [ "${commandname}" == "INSTALL" ]; then + validate="validate" + fi + + # To do error checking for SteamCMD the output of steamcmd will be saved to a log. + steamcmdlog="${lgsmlogdir}/${selfname}-steamcmd.log" + + # clear previous steamcmd log + if [ -f "${steamcmdlog}" ]; then + rm -f "${steamcmdlog:?}" + fi + counter=0 + while [ "${counter}" == "0" ] || [ "${exitcode}" != "0" ]; do + counter=$((counter + 1)) + # Select SteamCMD parameters + # If GoldSrc (appid 90) servers. GoldSrc (appid 90) require extra commands. + if [ "${appid}" == "90" ]; then + # If using a specific branch. + if [ -n "${branch}" ] && [ -n "${betapassword}" ]; then + ${unbuffer} ${steamcmdcommand} +force_install_dir "${serverfiles}" +login "${steamuser}" "${steampass}" +app_set_config 90 mod "${appidmod}" +app_update "${appid}" -beta "${branch}" -betapassword "${betapassword}" ${validate} +quit | uniq | tee -a "${lgsmlog}" "${steamcmdlog}" + elif [ -n "${branch}" ]; then + ${unbuffer} ${steamcmdcommand} +force_install_dir "${serverfiles}" +login "${steamuser}" "${steampass}" +app_set_config 90 mod "${appidmod}" +app_update "${appid}" -beta "${branch}" ${validate} +quit | uniq | tee -a "${lgsmlog}" "${steamcmdlog}" + else + ${unbuffer} ${steamcmdcommand} +force_install_dir "${serverfiles}" +login "${steamuser}" "${steampass}" +app_set_config 90 mod "${appidmod}" +app_update "${appid}" ${validate} +quit | uniq | tee -a "${lgsmlog}" "${steamcmdlog}" + fi + # Force Windows Platform type. + elif [ "${steamcmdforcewindows}" == "yes" ]; then + if [ -n "${branch}" ] && [ -n "${betapassword}" ]; then + ${unbuffer} ${steamcmdcommand} +@sSteamCmdForcePlatformType windows +force_install_dir "${serverfiles}" +login "${steamuser}" "${steampass}" +app_update "${appid}" -beta "${branch}" -betapassword "${betapassword}" ${validate} +quit | uniq | tee -a "${lgsmlog}" "${steamcmdlog}" + elif [ -n "${branch}" ]; then + ${unbuffer} ${steamcmdcommand} +@sSteamCmdForcePlatformType windows +force_install_dir "${serverfiles}" +login "${steamuser}" "${steampass}" +app_update "${appid}" -beta "${branch}" ${validate} +quit | uniq | tee -a "${lgsmlog}" "${steamcmdlog}" + else + ${unbuffer} ${steamcmdcommand} +@sSteamCmdForcePlatformType windows +force_install_dir "${serverfiles}" +login "${steamuser}" "${steampass}" +app_update "${appid}" ${validate} +quit | uniq | tee -a "${lgsmlog}" "${steamcmdlog}" + fi + # All other servers. + else + if [ -n "${branch}" ] && [ -n "${betapassword}" ]; then + ${unbuffer} ${steamcmdcommand} +force_install_dir "${serverfiles}" +login "${steamuser}" "${steampass}" +app_update "${appid}" -beta "${branch}" -betapassword "${betapassword}" ${validate} +quit | uniq | tee -a "${lgsmlog}" "${steamcmdlog}" + elif [ -n "${branch}" ]; then + ${unbuffer} ${steamcmdcommand} +force_install_dir "${serverfiles}" +login "${steamuser}" "${steampass}" +app_update "${appid}" -beta "${branch}" ${validate} +quit | uniq | tee -a "${lgsmlog}" "${steamcmdlog}" + else + ${unbuffer} ${steamcmdcommand} +force_install_dir "${serverfiles}" +login "${steamuser}" "${steampass}" +app_update "${appid}" ${validate} +quit | uniq | tee -a "${lgsmlog}" "${steamcmdlog}" + fi + fi + + # Error checking for SteamCMD. Some errors will loop to try again and some will just exit. + # Check also if we have more errors than retries to be sure that we do not loop to many times and error out. + exitcode=$? + if [ -n "$(grep -i "Error!" "${steamcmdlog}" | tail -1)" ] && [ "$(grep -ic "Error!" "${steamcmdlog}")" -ge "${counter}" ]; then + # Not enough space. + if [ -n "$(grep "0x202" "${steamcmdlog}" | tail -1)" ]; then + fn_print_failure_nl "${commandaction} ${selfname}: ${remotelocation}: Not enough disk space to download server files" + fn_script_log_fatal "${commandaction} ${selfname}: ${remotelocation}: Not enough disk space to download server files" + core_exit.sh + # Not enough space. + elif [ -n "$(grep "0x212" "${steamcmdlog}" | tail -1)" ]; then + fn_print_failure_nl "${commandaction} ${selfname}: ${remotelocation}: Not enough disk space to download server files" + fn_script_log_fatal "${commandaction} ${selfname}: ${remotelocation}: Not enough disk space to download server files" + core_exit.sh + # Need tp purchase game. + elif [ -n "$(grep "No subscription" "${steamcmdlog}" | tail -1)" ]; then + fn_print_failure_nl "${commandaction} ${selfname}: ${remotelocation}: Steam account does not have a license for the required game" + fn_script_log_fatal "${commandaction} ${selfname}: ${remotelocation}: Steam account does not have a license for the required game" + core_exit.sh + # Two-factor authentication failure + elif [ -n "$(grep "Two-factor code mismatch" "${steamcmdlog}" | tail -1)" ]; then + fn_print_failure_nl "${commandaction} ${selfname}: ${remotelocation}: Two-factor authentication failure" + fn_script_log_fatal "${commandaction} ${selfname}: ${remotelocation}: Two-factor authentication failure" + core_exit.sh + # Incorrect Branch password + elif [ -n "$(grep "Password check for AppId" "${steamcmdlog}" | tail -1)" ]; then + fn_print_failure_nl "${commandaction} ${selfname}: ${remotelocation}: betapassword is incorrect" + fn_script_log_fatal "${commandaction} ${selfname}: ${remotelocation}: betapassword is incorrect" + core_exit.sh + # Update did not finish. + elif [ -n "$(grep "0x402" "${steamcmdlog}" | tail -1)" ] || [ -n "$(grep "0x602" "${steamcmdlog}" | tail -1)" ]; then + fn_print_error2_nl "${commandaction} ${selfname}: ${remotelocation}: Update required but not completed - check network" + fn_script_log_error "${commandaction} ${selfname}: ${remotelocation}: Update required but not completed - check network" + else + fn_print_error2_nl "${commandaction} ${selfname}: ${remotelocation}: Unknown error occured" + echo -en "Please provide content log to LinuxGSM developers https://linuxgsm.com/steamcmd-error" + fn_script_log_error "${commandaction} ${selfname}: ${remotelocation}: Unknown error occured" + fi + elif [ "${exitcode}" != 0 ]; then + fn_print_error2_nl "${commandaction} ${selfname}: ${remotelocation}: Exit code: ${exitcode}" + fn_script_log_error "${commandaction} ${selfname}: ${remotelocation}: Exit code: ${exitcode}" + else + fn_print_complete_nl "${commandaction} ${selfname}: ${remotelocation}" + fn_script_log_pass "${commandaction} ${selfname}: ${remotelocation}" + fi + + if [ "${counter}" -gt "10" ]; then + fn_print_failure_nl "${commandaction} ${selfname}: ${remotelocation}: Did not complete the download, too many retrys" + fn_script_log_fatal "${commandaction} ${selfname}: ${remotelocation}: Did not complete the download, too many retrys" + core_exit.sh + fi + done +} + +# Emptys contents of the LinuxGSM tmpdir. +fn_clear_tmp() { + echo -en "clearing LinuxGSM tmp directory..." + if [ -d "${tmpdir}" ]; then + rm -rf "${tmpdir:?}/"* + local exitcode=$? + if [ "${exitcode}" != 0 ]; then + fn_print_error_eol_nl + fn_script_log_error "clearing LinuxGSM tmp directory" + else + fn_print_ok_eol_nl + fn_script_log_pass "clearing LinuxGSM tmp directory" + fi + fi +} + +fn_dl_hash() { + # Runs Hash Check if available. + if [ "${hash}" != "0" ] && [ "${hash}" != "nohash" ] && [ "${hash}" != "nomd5" ]; then + # MD5 + if [ "${#hash}" == "32" ]; then + hashbin="md5sum" + hashtype="MD5" + # SHA1 + elif [ "${#hash}" == "40" ]; then + hashbin="sha1sum" + hashtype="SHA1" + # SHA256 + elif [ "${#hash}" == "64" ]; then + hashbin="sha256sum" + hashtype="SHA256" + # SHA512 + elif [ "${#hash}" == "128" ]; then + hashbin="sha512sum" + hashtype="SHA512" + else + fn_script_log_error "hash lengh not known for hash type" + fn_print_error_nl "hash lengh not known for hash type" + core_exit.sh + fi + echo -en "verifying ${local_filename} with ${hashtype}..." + fn_sleep_time + hashsumcmd=$(${hashbin} "${local_filedir}/${local_filename}" | awk '{print $1}') + if [ "${hashsumcmd}" != "${hash}" ]; then + fn_print_fail_eol_nl + echo -e "${local_filename} returned ${hashtype} checksum: ${hashsumcmd}" + echo -e "expected ${hashtype} checksum: ${hash}" + fn_script_log_fatal "Verifying ${local_filename} with ${hashtype}" + fn_script_log_info "${local_filename} returned ${hashtype} checksum: ${hashsumcmd}" + fn_script_log_info "Expected ${hashtype} checksum: ${hash}" + core_exit.sh + else + fn_print_ok_eol_nl + fn_script_log_pass "Verifying ${local_filename} with ${hashtype}" + fn_script_log_info "${local_filename} returned ${hashtype} checksum: ${hashsumcmd}" + fn_script_log_info "Expected ${hashtype} checksum: ${hash}" + fi + fi +} + +# Extracts bzip2, gzip or zip files. +# Extracts can be defined in code like so: +# fn_dl_extract "${local_filedir}" "${local_filename}" "${extractdest}" "${extractsrc}" +# fn_dl_extract "/home/gameserver/lgsm/tmp" "file.tar.bz2" "/home/gamserver/serverfiles" +fn_dl_extract() { + local_filedir="${1}" + local_filename="${2}" + extractdest="${3}" + extractsrc="${4}" + # Extracts archives. + echo -en "extracting ${local_filename}..." + + if [ ! -d "${extractdest}" ]; then + mkdir "${extractdest}" + fi + if [ ! -f "${local_filedir}/${local_filename}" ]; then + fn_print_fail_eol_nl + echo -en "file ${local_filedir}/${local_filename} not found" + fn_script_log_fatal "Extracting ${local_filename}" + fn_script_log_fatal "File ${local_filedir}/${local_filename} not found" + core_exit.sh + fi + mime=$(file -b --mime-type "${local_filedir}/${local_filename}") + if [ "${mime}" == "application/gzip" ] || [ "${mime}" == "application/x-gzip" ]; then + if [ -n "${extractsrc}" ]; then + extractcmd=$(tar -zxf "${local_filedir}/${local_filename}" -C "${extractdest}" --strip-components=1 "${extractsrc}") + else + extractcmd=$(tar -zxf "${local_filedir}/${local_filename}" -C "${extractdest}") + fi + elif [ "${mime}" == "application/x-bzip2" ]; then + if [ -n "${extractsrc}" ]; then + extractcmd=$(tar -jxf "${local_filedir}/${local_filename}" -C "${extractdest}" --strip-components=1 "${extractsrc}") + else + extractcmd=$(tar -jxf "${local_filedir}/${local_filename}" -C "${extractdest}") + fi + elif [ "${mime}" == "application/x-xz" ]; then + if [ -n "${extractsrc}" ]; then + extractcmd=$(tar -Jxf "${local_filedir}/${local_filename}" -C "${extractdest}" --strip-components=1 "${extractsrc}") + else + extractcmd=$(tar -Jxf "${local_filedir}/${local_filename}" -C "${extractdest}") + fi + elif [ "${mime}" == "application/zip" ]; then + if [ -n "${extractsrc}" ]; then + extractcmd=$(unzip -qoj -d "${extractdest}" "${local_filedir}/${local_filename}" "${extractsrc}"/*) + else + extractcmd=$(unzip -qo -d "${extractdest}" "${local_filedir}/${local_filename}") + fi + fi + local exitcode=$? + if [ "${exitcode}" != 0 ]; then + fn_print_fail_eol_nl + fn_script_log_fatal "Extracting ${local_filename}" + if [ -f "${lgsmlog}" ]; then + echo -e "${extractcmd}" >> "${lgsmlog}" + fi + echo -e "${extractcmd}" + core_exit.sh + else + fn_print_ok_eol_nl + fn_script_log_pass "Extracting ${local_filename}" + fi +} + +# Trap to remove file download if canceled before completed. +fn_fetch_trap() { + echo -e "" + echo -en "downloading ${local_filename}..." + fn_print_canceled_eol_nl + fn_script_log_info "Downloading ${local_filename}...CANCELED" + fn_sleep_time + rm -f "${local_filedir:?}/${local_filename}" + echo -en "downloading ${local_filename}..." + fn_print_removed_eol_nl + fn_script_log_info "Downloading ${local_filename}...REMOVED" + core_exit.sh +} + +# Will check a file exists and download it. Will not exit if fails to download. +fn_check_file() { + remote_fileurl="${1}" + remote_fileurl_backup="${2}" + remote_fileurl_name="${3}" + remote_fileurl_backup_name="${4}" + remote_filename="${5}" + # If backup fileurl exists include it. + if [ -n "${remote_fileurl_backup}" ]; then + # counter set to 0 to allow second try + counter=0 + remote_fileurls_array=(remote_fileurl remote_fileurl_backup) + else + # counter set to 1 to not allow second try + counter=1 + remote_fileurls_array=(remote_fileurl) + fi + for remote_fileurl_array in "${remote_fileurls_array[@]}"; do + if [ "${remote_fileurl_array}" == "remote_fileurl" ]; then + fileurl="${remote_fileurl}" + fileurl_name="${remote_fileurl_name}" + elif [ "${remote_fileurl_array}" == "remote_fileurl_backup" ]; then + fileurl="${remote_fileurl_backup}" + fileurl_name="${remote_fileurl_backup_name}" + fi + counter=$((counter + 1)) + echo -en "checking ${fileurl_name} ${remote_filename}...\c" + curlcmd=$(curl --output /dev/null --silent --head --fail "${fileurl}" 2>&1) + local exitcode=$? + + # On first try will error. On second try will fail. + if [ "${exitcode}" != 0 ]; then + if [ ${counter} -ge 2 ]; then + fn_print_fail_eol_nl + if [ -f "${lgsmlog}" ]; then + fn_script_log_fatal "Checking ${remote_filename}" + fn_script_log_fatal "${fileurl}" + checkflag=1 + fi + else + fn_print_error_eol_nl + if [ -f "${lgsmlog}" ]; then + fn_script_log_error "Checking ${remote_filename}" + fn_script_log_error "${fileurl}" + checkflag=2 + fi + fi + else + fn_print_ok_eol + echo -en "\033[2K\\r" + if [ -f "${lgsmlog}" ]; then + fn_script_log_pass "Checking ${remote_filename}" + checkflag=0 + fi + break + fi + done + + if [ -f "${local_filedir}/${local_filename}" ]; then + fn_dl_hash + # Execute file if run is set. + if [ "${run}" == "run" ]; then + # shellcheck source=/dev/null + source "${local_filedir}/${local_filename}" + fi + fi +} + +fn_fetch_file() { + remote_fileurl="${1}" + remote_fileurl_backup="${2}" + remote_fileurl_name="${3}" + remote_fileurl_backup_name="${4}" + local_filedir="${5}" + local_filename="${6}" + chmodx="${7:-0}" + run="${8:-0}" + forcedl="${9:-0}" + hash="${10:-0}" + + # Download file if missing or download forced. + if [ ! -f "${local_filedir}/${local_filename}" ] || [ "${forcedl}" == "forcedl" ]; then + # If backup fileurl exists include it. + if [ -n "${remote_fileurl_backup}" ]; then + # counter set to 0 to allow second try + counter=0 + remote_fileurls_array=(remote_fileurl remote_fileurl_backup) + else + # counter set to 1 to not allow second try + counter=1 + remote_fileurls_array=(remote_fileurl) + fi + for remote_fileurl_array in "${remote_fileurls_array[@]}"; do + if [ "${remote_fileurl_array}" == "remote_fileurl" ]; then + fileurl="${remote_fileurl}" + fileurl_name="${remote_fileurl_name}" + elif [ "${remote_fileurl_array}" == "remote_fileurl_backup" ]; then + fileurl="${remote_fileurl_backup}" + fileurl_name="${remote_fileurl_backup_name}" + fi + counter=$((counter + 1)) + if [ ! -d "${local_filedir}" ]; then + mkdir -p "${local_filedir}" + fi + # Trap will remove part downloaded files if canceled. + trap fn_fetch_trap INT + curlcmd=(curl --connect-timeout 10 --fail -L -o "${local_filedir}/${local_filename}" --retry 2) + + # if is large file show progress, else be silent + local exitcode="" + large_files=("bz2" "gz" "zip" "jar" "xz") + if grep -qE "(^|\s)${local_filename##*.}(\s|$)" <<< "${large_files[@]}"; then + echo -en "downloading ${local_filename}..." + fn_sleep_time + echo -en "\033[1K" + "${curlcmd[@]}" --progress-bar "${fileurl}" 2>&1 + exitcode="$?" + else + echo -en "fetching ${fileurl_name} ${local_filename}...\c" + "${curlcmd[@]}" --silent --show-error "${fileurl}" 2>&1 + exitcode="$?" + fi + + # Download will fail if downloads a html file. + if [ -f "${local_filedir}/${local_filename}" ]; then + if head -n 1 "${local_filedir}/${local_filename}" | grep -q "DOCTYPE"; then + rm "${local_filedir:?}/${local_filename:?}" + local exitcode=2 + fi + fi + + # On first try will error. On second try will fail. + if [ "${exitcode}" != 0 ]; then + if [ ${counter} -ge 2 ]; then + fn_print_fail_eol_nl + if [ -f "${lgsmlog}" ]; then + fn_script_log_fatal "Downloading ${local_filename}..." + fn_script_log_fatal "${fileurl}" + fi + core_exit.sh + else + fn_print_error_eol_nl + if [ -f "${lgsmlog}" ]; then + fn_script_log_error "Downloading ${local_filename}..." + fn_script_log_error "${fileurl}" + fi + fi + else + fn_print_ok_eol_nl + if [ -f "${lgsmlog}" ]; then + fn_script_log_pass "Downloading ${local_filename}..." + fi + + # Make file executable if chmodx is set. + if [ "${chmodx}" == "chmodx" ]; then + chmod +x "${local_filedir}/${local_filename}" + fi + + # Remove trap. + trap - INT + + break + fi + done + fi + + if [ -f "${local_filedir}/${local_filename}" ]; then + fn_dl_hash + # Execute file if run is set. + if [ "${run}" == "run" ]; then + # shellcheck source=/dev/null + source "${local_filedir}/${local_filename}" + fi + fi +} + +# GitHub file download modules. +# Used to simplify downloading specific files from GitHub. + +# github_file_url_dir: the directory of the file in the GitHub: lgsm/modules +# github_file_url_name: the filename of the file to download from GitHub: core_messages.sh +# github_file_url_dir: the directory of the file in the GitHub: lgsm/modules +# github_file_url_name: the filename of the file to download from GitHub: core_messages.sh +# githuburl: the full GitHub url + +# remote_fileurl: The URL of the file: http://example.com/dl/File.tar.bz2 +# local_filedir: location the file is to be saved: /home/server/lgsm/tmp +# local_filename: name of file (this can be different from the url name): file.tar.bz2 +# chmodx: Optional, set to "chmodx" to make file executable using chmod +x +# run: Optional, set run to execute the file after download +# forcedl: Optional, force re-download of file even if exists +# hash: Optional, set an hash sum and will compare it against the file. + +# Fetches files from the Git repo. +fn_fetch_file_github() { + github_file_url_dir="${1}" + github_file_url_name="${2}" + # For legacy versions - code can be removed at a future date + if [ "${legacymode}" == "1" ]; then + remote_fileurl="https://raw.githubusercontent.com/${githubuser}/${githubrepo}/${githubbranch}/${github_file_url_dir}/${github_file_url_name}" + remote_fileurl_backup="https://bitbucket.org/${githubuser}/${githubrepo}/raw/${githubbranch}/${github_file_url_dir}/${github_file_url_name}" + # If master branch will currently running LinuxGSM version to prevent "version mixing". This is ignored if a fork. + elif [ "${githubbranch}" == "master" ] && [ "${githubuser}" == "GameServerManagers" ] && [ "${commandname}" != "UPDATE-LGSM" ]; then + remote_fileurl="https://raw.githubusercontent.com/${githubuser}/${githubrepo}/${version}/${github_file_url_dir}/${github_file_url_name}" + remote_fileurl_backup="https://bitbucket.org/${githubuser}/${githubrepo}/raw/${version}/${github_file_url_dir}/${github_file_url_name}" + else + remote_fileurl="https://raw.githubusercontent.com/${githubuser}/${githubrepo}/${githubbranch}/${github_file_url_dir}/${github_file_url_name}" + remote_fileurl_backup="https://bitbucket.org/${githubuser}/${githubrepo}/raw/${githubbranch}/${github_file_url_dir}/${github_file_url_name}" + fi + remote_fileurl_name="GitHub" + remote_fileurl_backup_name="Bitbucket" + local_filedir="${3}" + local_filename="${github_file_url_name}" + chmodx="${4:-0}" + run="${5:-0}" + forcedl="${6:-0}" + hash="${7:-0}" + # Passes vars to the file download module. + fn_fetch_file "${remote_fileurl}" "${remote_fileurl_backup}" "${remote_fileurl_name}" "${remote_fileurl_backup_name}" "${local_filedir}" "${local_filename}" "${chmodx}" "${run}" "${forcedl}" "${hash}" +} + +fn_check_file_github() { + github_file_url_dir="${1}" + github_file_url_name="${2}" + if [ "${githubbranch}" == "master" ] && [ "${githubuser}" == "GameServerManagers" ] && [ "${commandname}" != "UPDATE-LGSM" ]; then + remote_fileurl="https://raw.githubusercontent.com/${githubuser}/${githubrepo}/${version}/${github_file_url_dir}/${github_file_url_name}" + remote_fileurl_backup="https://bitbucket.org/${githubuser}/${githubrepo}/raw/${version}/${github_file_url_dir}/${github_file_url_name}" + else + remote_fileurl="https://raw.githubusercontent.com/${githubuser}/${githubrepo}/${githubbranch}/${github_file_url_dir}/${github_file_url_name}" + remote_fileurl_backup="https://bitbucket.org/${githubuser}/${githubrepo}/raw/${githubbranch}/${github_file_url_dir}/${github_file_url_name}" + fi + remote_fileurl_name="GitHub" + remote_fileurl_backup_name="Bitbucket" + fn_check_file "${remote_fileurl}" "${remote_fileurl_backup}" "${remote_fileurl_name}" "${remote_fileurl_backup_name}" "${github_file_url_name}" +} + +# Fetches config files from the Git repo. +fn_fetch_config() { + github_file_url_dir="${1}" + github_file_url_name="${2}" + # If master branch will currently running LinuxGSM version to prevent "version mixing". This is ignored if a fork. + if [ "${githubbranch}" == "master" ] && [ "${githubuser}" == "GameServerManagers" ] && [ "${commandname}" != "UPDATE-LGSM" ]; then + remote_fileurl="https://raw.githubusercontent.com/${githubuser}/${githubrepo}/${version}/${github_file_url_dir}/${github_file_url_name}" + remote_fileurl_backup="https://bitbucket.org/${githubuser}/${githubrepo}/raw/${version}/${github_file_url_dir}/${github_file_url_name}" + else + remote_fileurl="https://raw.githubusercontent.com/${githubuser}/${githubrepo}/${githubbranch}/${github_file_url_dir}/${github_file_url_name}" + remote_fileurl_backup="https://bitbucket.org/${githubuser}/${githubrepo}/raw/${githubbranch}/${github_file_url_dir}/${github_file_url_name}" + fi + remote_fileurl_name="GitHub" + remote_fileurl_backup_name="Bitbucket" + local_filedir="${3}" + local_filename="${4}" + chmodx="nochmodx" + run="norun" + forcedl="noforce" + hash="nohash" + # Passes vars to the file download module. + fn_fetch_file "${remote_fileurl}" "${remote_fileurl_backup}" "${remote_fileurl_name}" "${remote_fileurl_backup_name}" "${local_filedir}" "${local_filename}" "${chmodx}" "${run}" "${forcedl}" "${hash}" +} + +# Fetches modules from the Git repo during first download. +fn_fetch_module() { + github_file_url_dir="lgsm/modules" + github_file_url_name="${modulefile}" + # If master branch will currently running LinuxGSM version to prevent "version mixing". This is ignored if a fork. + if [ "${githubbranch}" == "master" ] && [ "${githubuser}" == "GameServerManagers" ] && [ "${commandname}" != "UPDATE-LGSM" ]; then + remote_fileurl="https://raw.githubusercontent.com/${githubuser}/${githubrepo}/${version}/${github_file_url_dir}/${github_file_url_name}" + remote_fileurl_backup="https://bitbucket.org/${githubuser}/${githubrepo}/raw/${version}/${github_file_url_dir}/${github_file_url_name}" + else + remote_fileurl="https://raw.githubusercontent.com/${githubuser}/${githubrepo}/${githubbranch}/${github_file_url_dir}/${github_file_url_name}" + remote_fileurl_backup="https://bitbucket.org/${githubuser}/${githubrepo}/raw/${githubbranch}/${github_file_url_dir}/${github_file_url_name}" + fi + remote_fileurl_name="GitHub" + remote_fileurl_backup_name="Bitbucket" + local_filedir="${modulesdir}" + local_filename="${github_file_url_name}" + chmodx="chmodx" + run="run" + forcedl="noforce" + hash="nohash" + # Passes vars to the file download module. + fn_fetch_file "${remote_fileurl}" "${remote_fileurl_backup}" "${remote_fileurl_name}" "${remote_fileurl_backup_name}" "${local_filedir}" "${local_filename}" "${chmodx}" "${run}" "${forcedl}" "${hash}" +} + +# Fetches modules from the Git repo during update-lgsm. +fn_update_module() { + github_file_url_dir="lgsm/modules" + github_file_url_name="${modulefile}" + # If master branch will currently running LinuxGSM version to prevent "version mixing". This is ignored if a fork. + if [ "${githubbranch}" == "master" ] && [ "${githubuser}" == "GameServerManagers" ] && [ "${commandname}" != "UPDATE-LGSM" ]; then + remote_fileurl="https://raw.githubusercontent.com/${githubuser}/${githubrepo}/${version}/${github_file_url_dir}/${github_file_url_name}" + remote_fileurl_backup="https://bitbucket.org/${githubuser}/${githubrepo}/raw/${version}/${github_file_url_dir}/${github_file_url_name}" + else + remote_fileurl="https://raw.githubusercontent.com/${githubuser}/${githubrepo}/${githubbranch}/${github_file_url_dir}/${github_file_url_name}" + remote_fileurl_backup="https://bitbucket.org/${githubuser}/${githubrepo}/raw/${githubbranch}/${github_file_url_dir}/${github_file_url_name}" + fi + remote_fileurl_name="GitHub" + remote_fileurl_backup_name="Bitbucket" + local_filedir="${modulesdir}" + local_filename="${github_file_url_name}" + chmodx="chmodx" + run="norun" + forcedl="noforce" + hash="nohash" + # Passes vars to the file download module. + fn_fetch_file "${remote_fileurl}" "${remote_fileurl_backup}" "${remote_fileurl_name}" "${remote_fileurl_backup_name}" "${local_filedir}" "${local_filename}" "${chmodx}" "${run}" "${forcedl}" "${hash}" + +} + +# Function to download latest github release. +# $1 GitHub user / organisation. +# $2 Repo name. +# $3 Destination for download. +# $4 Search string in releases (needed if there are more files that can be downloaded from the release pages). +fn_dl_latest_release_github() { + local githubreleaseuser="${1}" + local githubreleaserepo="${2}" + local githubreleasedownloadpath="${3}" + local githubreleasesearch="${4}" + local githublatestreleaseurl="https://api.github.com/repos/${githubreleaseuser}/${githubreleaserepo}/releases/latest" + + # Get last github release. + # If no search for the release filename is set, just get the first file from the latest release. + if [ -z "${githubreleasesearch}" ]; then + githubreleaseassets=$(curl -s "${githublatestreleaseurl}" | jq '[ .assets[] ]') + else + githubreleaseassets=$(curl -s "${githublatestreleaseurl}" | jq "[ .assets[]|select(.browser_download_url | contains(\"${githubreleasesearch}\")) ]") + fi + + # Check how many releases we got from the api and exit if we have more then one. + if [ "$(echo -e "${githubreleaseassets}" | jq '. | length')" -gt 1 ]; then + fn_print_fatal_nl "Found more than one release to download - Please report this to the LinuxGSM issue tracker" + fn_script_log_fatal "Found more than one release to download - Please report this to the LinuxGSM issue tracker" + else + # Set variables for download via fn_fetch_file. + githubreleasefilename=$(echo -e "${githubreleaseassets}" | jq -r '.[]name') + githubreleasedownloadlink=$(echo -e "${githubreleaseassets}" | jq -r '.[]browser_download_url') + + # Error if no version is there. + if [ -z "${githubreleasefilename}" ]; then + fn_print_fail_nl "Cannot get version from GitHub API for ${githubreleaseuser}/${githubreleaserepo}" + fn_script_log_fatal "Cannot get version from GitHub API for ${githubreleaseuser}/${githubreleaserepo}" + else + # Fetch file from the remote location from the existing module to the ${tmpdir} for now. + fn_fetch_file "${githubreleasedownloadlink}" "" "${githubreleasefilename}" "" "${githubreleasedownloadpath}" "${githubreleasefilename}" + fi + fi +} diff --git a/lgsm/functions/core_exit.sh b/lgsm/functions/core_exit.sh new file mode 100644 index 000000000..a8686c2a8 --- /dev/null +++ b/lgsm/functions/core_exit.sh @@ -0,0 +1,61 @@ +#!/bin/bash +# LinuxGSM core_exit.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Handles exiting of LinuxGSM by running and reporting an exit code. + +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" + +fn_exit_dev_debug() { + if [ -f "${rootdir}/.dev-debug" ]; then + echo -e "" + echo -e "${moduleselfname} exiting with code: ${exitcode}" + if [ -f "${rootdir}/dev-debug.log" ]; then + grep "modulefile=" "${rootdir}/dev-debug.log" | sed 's/modulefile=//g' > "${rootdir}/dev-debug-module-order.log" + fi + fi +} + +# If running dependency check as root will remove any files that belong to root user. +if [ "$(whoami)" == "root" ] && [ ! -f /.dockerenv ]; then + find "${lgsmdir}"/ -group root -prune -exec rm -rf {} + > /dev/null 2>&1 + find "${logdir}"/ -group root -prune -exec rm -rf {} + > /dev/null 2>&1 +fi + +if [ "${exitbypass}" ]; then + unset exitbypass +elif [ "${exitcode}" != "0" ]; then + # List LinuxGSM version in logs + fn_script_log_info "LinuxGSM version: ${version}" + if [ "${exitcode}" == "1" ]; then + fn_script_log_fatal "${moduleselfname} exiting with code: ${exitcode}" + elif [ "${exitcode}" == "2" ]; then + fn_script_log_error "${moduleselfname} exiting with code: ${exitcode}" + elif [ "${exitcode}" == "3" ]; then + fn_script_log_warn "${moduleselfname} exiting with code: ${exitcode}" + else + fn_script_log_warn "${moduleselfname} exiting with code: ${exitcode}" + fi + fn_exit_dev_debug + # remove trap. + trap - INT + exit "${exitcode}" +elif [ "${exitcode}" ] && [ "${exitcode}" == "0" ]; then + # List LinuxGSM version in logs + fn_script_log_info "LinuxGSM version: ${version}" + fn_script_log_pass "${moduleselfname} exiting with code: ${exitcode}" + fn_exit_dev_debug + # remove trap. + trap - INT + exit "${exitcode}" +else + # List LinuxGSM version in logs + fn_script_log_info "LinuxGSM version: ${version}" + fn_print_error "No exit code set" + fn_script_log_pass "${moduleselfname} exiting with code: NOT SET" + fn_exit_dev_debug + # remove trap. + trap - INT + exit "${exitcode}" +fi diff --git a/lgsm/functions/core_functions.sh b/lgsm/functions/core_functions.sh new file mode 100755 index 000000000..07a2ebd09 --- /dev/null +++ b/lgsm/functions/core_functions.sh @@ -0,0 +1,816 @@ +#!/bin/bash +# LinuxGSM core_functions.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Defines all functions to allow download and execution of functions using fn_fetch_function. +# This function is called first before any other function. Without this file other functions will not load. + +module_selfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" + +modulesversion="v23.2.0" + +# Core + +core_dl.sh() { + functionfile="${FUNCNAME[0]}" + if [ "$(type fn_fetch_core_dl 2> /dev/null)" ]; then + fn_fetch_core_dl "lgsm/functions" "core_dl.sh" "${functionsdir}" "chmodx" "run" "noforcedl" "nohash" + else + fn_bootstrap_fetch_file_github "lgsm/functions" "core_dl.sh" "${functionsdir}" "chmodx" "run" "noforcedl" "nohash" + fi +} + +core_messages.sh() { + functionfile="${FUNCNAME[0]}" + if [ "$(type fn_fetch_core_dl 2> /dev/null)" ]; then + fn_fetch_core_dl "lgsm/functions" "core_messages.sh" "${functionsdir}" "chmodx" "run" "noforcedl" "nohash" + else + fn_bootstrap_fetch_file_github "lgsm/functions" "core_messages.sh" "${functionsdir}" "chmodx" "run" "noforcedl" "nohash" + fi +} + +core_legacy.sh() { + functionfile="${FUNCNAME[0]}" + if [ "$(type fn_fetch_core_dl 2> /dev/null)" ]; then + fn_fetch_core_dl "lgsm/functions" "core_legacy.sh" "${functionsdir}" "chmodx" "run" "noforcedl" "nohash" + else + fn_bootstrap_fetch_file_github "lgsm/functions" "core_legacy.sh" "${functionsdir}" "chmodx" "run" "noforcedl" "nohash" + fi +} + +core_exit.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} + +core_getopt.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} + +core_trap.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} + +core_steamcmd.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} + +core_github.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} + +# Commands + +command_backup.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} + +command_console.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} + +command_debug.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} + +command_details.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} + +command_sponsor.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} + +command_postdetails.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} + +command_test_alert.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} + +command_monitor.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} + +command_start.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} + +command_stop.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} + +command_validate.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} + +command_install.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} + +command_install_resources_mta.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} + +install_squad_license.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} + +command_mods_install.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} + +command_mods_update.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} + +command_mods_remove.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} + +command_fastdl.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} + +command_ts3_server_pass.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} + +command_restart.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} + +command_skeleton.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} + +command_wipe.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} + +command_send.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} + +# Checks + +check.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} + +check_config.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} + +check_deps.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} + +check_executable.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} + +check_glibc.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} + +check_ip.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} + +check_last_update.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} + +check_logs.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} + +check_permissions.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} + +check_root.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} + +check_status.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} + +check_steamcmd.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} + +check_system_dir.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} + +check_system_requirements.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} + +check_tmuxception.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} + +check_version.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} + +# Compress + +compress_unreal2_maps.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} + +compress_ut99_maps.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} + +# Mods + +mods_list.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} + +mods_core.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} + +# Dev + +command_dev_clear_functions.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} + +command_dev_debug.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} + +command_dev_detect_deps.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} + +command_dev_detect_glibc.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} + +command_dev_detect_ldd.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} + +command_dev_query_raw.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} + +# Fix + +fix.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} + +fix_ark.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} + +fix_av.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} + +fix_arma3.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} + +fix_armar.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} + +fix_bt.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} + +fix_bo.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} + +fix_cmw.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} + +fix_csgo.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} + +fix_dst.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} + +fix_hw.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} + +fix_ins.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} + +fix_kf.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} + +fix_kf2.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} + +fix_lo.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} + +fix_mcb.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} + +fix_mta.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} + +fix_nmrih.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} + +fix_onset.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} + +fix_ro.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} + +fix_rust.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} + +fix_rw.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} + +fix_sfc.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} + +fix_st.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} + +fix_steamcmd.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} + +fix_terraria.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} + +fix_tf2.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} + +fix_ut3.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} + +fix_rust.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} + +fix_samp.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} + +fix_sdtd.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} + +fix_sof2.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} + +fix_squad.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} + +fix_ts3.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} + +fix_ut2k4.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} + +fix_ut.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} + +fix_unt.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} + +fix_vh.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} + +fix_wurm.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} + +fix_zmr.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} + +# Info + +info_distro.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} + +info_game.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} + +info_messages.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} + +info_stats.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} + +# Alert + +alert.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} + +alert_discord.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} + +alert_email.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} + +alert_ifttt.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} + +alert_mailgun.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} + +alert_pushbullet.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} + +alert_pushover.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} + +alert_gotify.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} + +alert_telegram.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} + +alert_rocketchat.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} + +alert_slack.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} +# Logs + +core_logs.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} + +# Query + +query_gamedig.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} + +# Update + +command_update_functions.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} + +command_update_linuxgsm.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} + +command_update.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} + +command_check_update.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} + +update_ts3.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} + +update_minecraft.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} + +update_minecraft_bedrock.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} + +update_papermc.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} + +update_mta.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} + +update_factorio.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} + +update_jediknight2.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} + +update_steamcmd.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} + +update_vintagestory.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} + +update_ut99.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} + +fn_update_functions.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} + +# +## Installer functions +# + +fn_autoinstall() { + autoinstall=1 + command_install.sh +} + +install_complete.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} + +install_config.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} + +install_factorio_save.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} + +install_dst_token.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} + +install_eula.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} + +install_gsquery.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} + +install_gslt.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} + +install_header.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} + +install_logs.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} + +install_retry.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} + +install_server_dir.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} +install_server_files.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} + +install_stats.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} + +install_steamcmd.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} + +install_ts3.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} + +install_ts3db.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} + +install_ut2k4.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} + +install_dl_ut2k4.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} + +install_ut2k4_key.sh() { + functionfile="${FUNCNAME[0]}" + fn_fetch_function +} + +# Calls code required for legacy servers +core_legacy.sh + +# Creates tmp dir if missing +if [ ! -d "${tmpdir}" ]; then + mkdir -p "${tmpdir}" +fi + +# Creates lock dir if missing +if [ ! -d "${lockdir}" ]; then + mkdir -p "${lockdir}" +fi + +# Calls on-screen messages (bootstrap) +core_messages.sh + +#Calls file downloader (bootstrap) +core_dl.sh + +# Calls the global Ctrl-C trap +core_trap.sh diff --git a/lgsm/functions/core_getopt.sh b/lgsm/functions/core_getopt.sh new file mode 100644 index 000000000..222ad0cf8 --- /dev/null +++ b/lgsm/functions/core_getopt.sh @@ -0,0 +1,215 @@ +#!/bin/bash +# LinuxGSM core_getopt.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: getopt arguments. + +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" + +### Define all commands here. +## User commands | Trigger commands | Description +# Standard commands. +cmd_install=("i;install" "command_install.sh" "Install the server.") +cmd_auto_install=("ai;auto-install" "fn_autoinstall" "Install the server without prompts.") +cmd_start=("st;start" "command_start.sh" "Start the server.") +cmd_stop=("sp;stop" "command_stop.sh" "Stop the server.") +cmd_restart=("r;restart" "command_restart.sh" "Restart the server.") +cmd_details=("dt;details" "command_details.sh" "Display server information.") +cmd_postdetails=("pd;postdetails" "command_postdetails.sh" "Post details to termbin.com (removing passwords).") +cmd_backup=("b;backup" "command_backup.sh" "Create backup archives of the server.") +cmd_update_linuxgsm=("ul;update-lgsm;uf;update-modules" "command_update_linuxgsm.sh" "Check and apply any LinuxGSM updates.") +cmd_test_alert=("ta;test-alert" "command_test_alert.sh" "Send a test alert.") +cmd_monitor=("m;monitor" "command_monitor.sh" "Check server status and restart if crashed.") +cmd_skeleton=("sk;skeleton" "command_skeleton.sh" "Create a skeleton directory.") +cmd_sponso=("s;sponsor" "command_sponsor.sh" "Donation options.") +cmd_send=("sd;send" "command_send.sh" "Send command to game server console.") +# Console servers only. +cmd_console=("c;console" "command_console.sh" "Access server console.") +cmd_debug=("d;debug" "command_debug.sh" "Start server directly in your terminal.") +# Update servers only. +cmd_update=("u;update" "command_update.sh" "Check and apply any server updates.") +cmd_check_update=("cu;check-update" "command_check_update.sh" "Check if a gameserver update is available") +cmd_force_update=("fu;force-update;update-restart;ur" "forceupdate=1; command_update.sh" "Apply server updates bypassing check.") +# SteamCMD servers only. +cmd_validate=("v;validate" "command_validate.sh" "Validate server files with SteamCMD.") +# Server with mods-install. +cmd_mods_install=("mi;mods-install" "command_mods_install.sh" "View and install available mods/addons.") +cmd_mods_remove=("mr;mods-remove" "command_mods_remove.sh" "View and remove an installed mod/addon.") +cmd_mods_update=("mu;mods-update" "command_mods_update.sh" "Update installed mods/addons.") +# Server specific. +cmd_change_password=("pw;change-password" "command_ts3_server_pass.sh" "Change TS3 serveradmin password.") +cmd_install_default_resources=("ir;install-default-resources" "command_install_resources_mta.sh" "Install the MTA default resources.") +cmd_fullwipe=("fw;full-wipe;wa;wipeall" "serverwipe=1; command_wipe.sh" "Reset the map and remove blueprint data.") +cmd_mapwipe=("mw;map-wipe;w;wipe;wi" "mapwipe=1; command_wipe.sh" "Reset the map and keep blueprint data.") +cmd_map_compressor_u99=("mc;map-compressor" "compress_ut99_maps.sh" "Compresses all ${gamename} server maps.") +cmd_map_compressor_u2=("mc;map-compressor" "compress_unreal2_maps.sh" "Compresses all ${gamename} server maps.") +cmd_install_cdkey=("cd;server-cd-key" "install_ut2k4_key.sh" "Add your server cd key.") +cmd_install_dst_token=("ct;cluster-token" "install_dst_token.sh" "Configure cluster token.") +cmd_install_squad_license=("li;license" "install_squad_license.sh" "Add your Squad server license.") +cmd_fastdl=("fd;fastdl" "command_fastdl.sh" "Build a FastDL directory.") +# Dev commands. +cmd_dev_debug=("dev;developer" "command_dev_debug.sh" "Enable developer Mode.") +cmd_dev_detect_deps=("dd;detect-deps" "command_dev_detect_deps.sh" "Detect required dependencies.") +cmd_dev_detect_glibc=("dg;detect-glibc" "command_dev_detect_glibc.sh" "Detect required glibc.") +cmd_dev_detect_ldd=("dl;detect-ldd" "command_dev_detect_ldd.sh" "Detect required dynamic dependencies.") +cmd_dev_query_raw=("qr;query-raw" "command_dev_query_raw.sh" "The raw output of gamedig and gsquery.") +cmd_dev_clear_modules=("cf;clear-modules" "command_dev_clear_modules.sh" "Delete the contents of the modules dir.") + +### Set specific opt here. + +currentopt=("${cmd_start[@]}" "${cmd_stop[@]}" "${cmd_restart[@]}" "${cmd_monitor[@]}" "${cmd_test_alert[@]}" "${cmd_details[@]}" "${cmd_postdetails[@]}" "${cmd_skeleton[@]}") + +# Update LinuxGSM. +currentopt+=("${cmd_update_linuxgsm[@]}") + +# Exclude noupdate games here. +if [ "${shortname}" == "jk2" ] || [ "${engine}" != "idtech3" ]; then + if [ "${shortname}" != "bf1942" ] && [ "${shortname}" != "bfv" ] && [ "${engine}" != "idtech2" ] && [ "${engine}" != "iw2.0" ] && [ "${engine}" != "iw3.0" ] && [ "${engine}" != "quake" ] && [ "${shortname}" != "samp" ] && [ "${shortname}" != "ut2k4" ]; then + currentopt+=("${cmd_update[@]}" "${cmd_check_update[@]}") + # force update for SteamCMD or Multi Theft Auto only. + if [ "${appid}" ] || [ "${shortname}" == "mta" ]; then + currentopt+=("${cmd_force_update[@]}") + fi + fi +fi + +# Validate and check-update command. +if [ "${appid}" ]; then + currentopt+=("${cmd_validate[@]}") +fi + +# Backup. +currentopt+=("${cmd_backup[@]}") + +# Console & Debug. +currentopt+=("${cmd_console[@]}" "${cmd_debug[@]}") + +# Console send. +if [ "${consoleinteract}" == "yes" ]; then + currentopt+=("${cmd_send[@]}") +fi + +## Game server exclusive commands. + +# FastDL command. +if [ "${engine}" == "source" ]; then + currentopt+=("${cmd_fastdl[@]}") +fi + +# TeamSpeak exclusive. +if [ "${shortname}" == "ts3" ]; then + currentopt+=("${cmd_change_password[@]}") +fi + +# Rust exclusive. +if [ "${shortname}" == "rust" ]; then + currentopt+=("${cmd_fullwipe[@]}" "${cmd_mapwipe[@]}") +fi + +# Unreal exclusive. +if [ "${engine}" == "unreal2" ]; then + if [ "${shortname}" == "ut2k4" ]; then + currentopt+=("${cmd_install_cdkey[@]}" "${cmd_map_compressor_u2[@]}") + else + currentopt+=("${cmd_map_compressor_u2[@]}") + fi +fi +if [ "${engine}" == "unreal" ]; then + currentopt+=("${cmd_map_compressor_u99[@]}") +fi + +# DST exclusive. +if [ "${shortname}" == "dst" ]; then + currentopt+=("${cmd_install_dst_token[@]}") +fi + +# MTA exclusive. +if [ "${shortname}" == "mta" ]; then + currentopt+=("${cmd_install_default_resources[@]}") +fi + +# Squad license exclusive. +if [ "${shortname}" == "squad" ]; then + currentopt+=("${cmd_install_squad_license[@]}") +fi + +## Mods commands. +if [ "${engine}" == "source" ] || [ "${shortname}" == "rust" ] || [ "${shortname}" == "hq" ] || [ "${shortname}" == "sdtd" ] || [ "${shortname}" == "cs" ] || [ "${shortname}" == "dod" ] || [ "${shortname}" == "tfc" ] || [ "${shortname}" == "ns" ] || [ "${shortname}" == "ts" ] || [ "${shortname}" == "hldm" ] || [ "${shortname}" == "vh" ]; then + currentopt+=("${cmd_mods_install[@]}" "${cmd_mods_remove[@]}" "${cmd_mods_update[@]}") +fi + +## Installer. +currentopt+=("${cmd_install[@]}" "${cmd_auto_install[@]}") + +## Developer commands. +currentopt+=("${cmd_dev_debug[@]}") +if [ -f ".dev-debug" ]; then + currentopt+=("${cmd_dev_detect_deps[@]}" "${cmd_dev_detect_glibc[@]}" "${cmd_dev_detect_ldd[@]}" "${cmd_dev_query_raw[@]}" "${cmd_dev_clear_modules[@]}") +fi + +## Sponsor. +currentopt+=("${cmd_sponsor[@]}") + +### Build list of available commands. +optcommands=() +index="0" +for ((index = "0"; index < ${#currentopt[@]}; index += 3)); do + cmdamount=$(echo -e "${currentopt[index]}" | awk -F ';' '{ print NF }') + for ((cmdindex = 1; cmdindex <= cmdamount; cmdindex++)); do + optcommands+=("$(echo -e "${currentopt[index]}" | awk -F ';' -v x=${cmdindex} '{ print $x }')") + done +done + +# Shows LinuxGSM usage. +fn_opt_usage() { + echo -e "Usage: $0 [option]" + echo -e "" + echo -e "LinuxGSM - ${gamename} - Version ${version}" + echo -e "https://linuxgsm.com/${gameservername}" + echo -e "" + echo -e "${lightyellow}Commands${default}" + # Display available commands. + index="0" + { + for ((index = "0"; index < ${#currentopt[@]}; index += 3)); do + # Hide developer commands. + if [ "${currentopt[index + 2]}" != "DEVCOMMAND" ]; then + echo -e "${cyan}$(echo -e "${currentopt[index]}" | awk -F ';' '{ print $2 }')\t${default}$(echo -e "${currentopt[index]}" | awk -F ';' '{ print $1 }')\t| ${currentopt[index + 2]}" + fi + done + } | column -s $'\t' -t + fn_script_log_pass "Display commands" + core_exit.sh +} + +# Check if command existw and run corresponding scripts, or display script usage. +if [ -z "${getopt}" ]; then + fn_opt_usage +fi +# If command exists. +for i in "${optcommands[@]}"; do + if [ "${i}" == "${getopt}" ]; then + # Seek and run command. + index="0" + for ((index = "0"; index < ${#currentopt[@]}; index += 3)); do + currcmdamount=$(echo -e "${currentopt[index]}" | awk -F ';' '{ print NF }') + for ((currcmdindex = 1; currcmdindex <= currcmdamount; currcmdindex++)); do + if [ "$(echo -e "${currentopt[index]}" | awk -F ';' -v x=${currcmdindex} '{ print $x }')" == "${getopt}" ]; then + # Run command. + eval "${currentopt[index + 1]}" + # Exit should occur in modules. Should this not happen print an error + fn_print_error2_nl "Command did not exit correctly: ${getopt}" + fn_script_log_error "Command did not exit correctly: ${getopt}" + core_exit.sh + fi + done + done + fi +done + +# If we're executing this, it means command was not found. +fn_print_error2_nl "Unknown command: $0 ${getopt}" +fn_script_log_error "Unknown command: $0 ${getopt}" +fn_opt_usage +core_exit.sh diff --git a/lgsm/functions/core_github.sh b/lgsm/functions/core_github.sh new file mode 100644 index 000000000..228fe1078 --- /dev/null +++ b/lgsm/functions/core_github.sh @@ -0,0 +1,114 @@ +#!/bin/bash +# LinuxGSM core_github.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: core module file for updates via github + +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" + +github_api="https://api.github.com" + +fn_githublocalversionfile() { + local githubreleaseuser="${1}" + local githubreleaserepo="${2}" + + githublocalversionfile="${datadir}/github-${githubreleaseuser}-${githubreleaserepo}-version" +} + +# $1 githubuser/group +# $2 github repo name +fn_github_get_latest_release_version() { + local githubreleaseuser="${1}" + local githubreleaserepo="${2}" + local githublatestreleaseurl="${github_api}/repos/${githubreleaseuser}/${githubreleaserepo}/releases/latest" + + githubreleaseversion=$(curl -s --connect-timeout 10 "${githublatestreleaseurl}" | jq '.tag_name') + + # error if no version is there + if [ -z "${githubreleaseversion}" ]; then + fn_print_fail_nl "Cannot get version from GitHub API for ${githubreleaseuser}/${githubreleaserepo}" + fn_script_log_fatal "Cannot get version from GitHub API for ${githubreleaseuser}/${githubreleaserepo}" + fi +} + +# $1 githubuser/group +# $2 github repo name +fn_github_set_latest_release_version() { + local githubreleaseuser="${1}" + local githubreleaserepo="${2}" + + fn_githublocalversionfile "${githubreleaseuser}" "${githubreleaserepo}" + + local githublatestreleaseurl="${github_api}/repos/${githubreleaseuser}/${githubreleaserepo}/releases/latest" + githubreleaseversion=$(curl -s "${githublatestreleaseurl}" | jq -r '.tag_name') + + # error if no version is there + if [ -z "${githubreleaseversion}" ]; then + fn_print_fail_nl "Cannot get version from GitHub API for ${githubreleaseuser}/${githubreleaserepo}" + fn_script_log_fatal "Cannot get version from GitHub API for ${githubreleaseuser}/${githubreleaserepo}" + else + echo "${githubreleaseversion}" > "${githublocalversionfile}" + fi +} + +# $1 githubuser/group +# $2 github repo name +fn_github_get_installed_version() { + local githubreleaseuser="${1}" + local githubreleaserepo="${2}" + + fn_githublocalversionfile "${githubreleaseuser}" "${githubreleaserepo}" + + githublocalversion=$(cat "${githublocalversionfile}") +} + +# $1 githubuser/group +# $2 github repo name +# if a update needs to be downloaded - updateneeded is set to 1 +fn_github_compare_version() { + local githubreleaseuser="${1}" + local githubreleaserepo="${2}" + exitcode=0 + updateneeded=0 + + fn_githublocalversionfile "${githubreleaseuser}" "${githubreleaserepo}" + local githublatestreleaseurl="${github_api}/repos/${githubreleaseuser}/${githubreleaserepo}/releases/latest" + + githublocalversion=$(cat "${githublocalversionfile}") + githubreleaseversion=$(curl -s "${githublatestreleaseurl}" | jq '.tag_name') + + # error if no version is there + if [ -z "${githubreleaseversion}" ]; then + fn_print_fail_nl "Can not get version from Github Api for ${githubreleaseuser}/${githubreleaserepo}" + fn_script_log_fatal "Can not get version from Github Api for ${githubreleaseuser}/${githubreleaserepo}" + else + if [ "${githublocalversion}" == "${githubreleaseversion}" ]; then + echo -en "\n" + echo -e "No update from github.com/${githubreleaseuser}/${githubreleaserepo}/ available:" + echo -e "* Local build: ${red}${githublocalversion}${default}" + echo -e "* Remote build: ${green}${githubreleaseversion}${default}" + echo -en "\n" + else + # check if version that is installed is higher than the remote version to not override it + last_version=$(echo -e "${githublocalversion}\n${githubreleaseversion}" | sort -V | head -n1) + if [ "${githubreleaseversion}" == "${last_version}" ]; then + echo -en "\n" + echo -e "Update from github.com/${githubreleaseuser}/${githubreleaserepo}/ available:" + echo -e "* Local build: ${red}${githublocalversion}${default}" + echo -e "* Remote build: ${green}${githubreleaseversion}${default}" + echo -en "\n" + updateneeded=1 + else + # local version is higher than the remote version output this to the user + # strange case but could be possible, as a release could be removed from github + echo -en "\n" + echo -e "Local version is newer than the remote version" + echo -e "* Local version: ${green}${githublocalversion}${default}" + echo -e "* Remote version: ${green}${githubreleaseversion}${default}" + echo -en "\n" + exitcode=1 + fi + fi + fi +} diff --git a/lgsm/functions/core_legacy.sh b/lgsm/functions/core_legacy.sh new file mode 100644 index 000000000..2ed942abd --- /dev/null +++ b/lgsm/functions/core_legacy.sh @@ -0,0 +1,93 @@ +#!/bin/bash +# LinuxGSM core_legacy.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Code for backwards compatability with older versions of LinuxGSM. + +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" + +# This is to help the transition to v20.3.0 and above +legacy_versions_array=(v20.2.1 v20.2.0 v20.1.5 v20.1.4 v20.1.3 v20.1.2 v20.1.1 v20.1.0 v19.12.5 v19.12.4 v19.12.3 v19.12.2 v19.12.1 v19.12.0) +for legacy_version in "${legacy_versions_array[@]}"; do + if [ "${version}" == "${legacy_version}" ]; then + legacymode=1 + fi +done + +if [ -z "${serverfiles}" ]; then + serverfiles="${filesdir}" +fi + +if [ -z "${logdir}" ]; then + logdir="${rootdir}/log" +fi + +if [ -z "${lgsmlogdir}" ]; then + lgsmlogdir="${scriptlogdir}" +fi + +if [ -z "${lgsmlog}" ]; then + lgsmlog="${scriptlog}" +fi + +if [ -z "${lgsmlogdate}" ]; then + lgsmlogdate="${scriptlogdate}" +fi + +if [ -z "${steamcmddir}" ]; then + steamcmddir="${HOME}/.steam/steamcmd" +fi + +if [ -z "${lgsmdir}" ]; then + lgsmdir="${rootdir}/lgsm" +fi + +if [ -z "${tmpdir}" ]; then + tmpdir="${lgsmdir}/tmp" +fi + +if [ -z "${alertlog}" ]; then + alertlog="${emaillog}" +fi + +if [ -z "${servicename}" ]; then + servicename="${selfname}" +fi + +# Alternations to workshop variables. +if [ -z "${wsapikey}" ]; then + if [ "${workshopauth}" ]; then + wsapikey="${workshopauth}" + elif [ "${authkey}" ]; then + wsapikey="${authkey}" + fi +fi + +if [ -z "${wscollectionid}" ]; then + if [ "${workshopauth}" ]; then + wscollectionid="${ws_collection_id}" + elif [ "${authkey}" ]; then + wscollectionid="${workshopcollectionid}" + fi +fi + +if [ -z "${wsstartmap}" ]; then + if [ "${ws_start_map}" ]; then + wscollectionid="${ws_start_map}" + fi +fi + +# Added as part of migrating functions dir to modules dir. +# Will remove functions dir if files in modules dir older than 14 days +functionsdir="${lgsmdir}/modules" +if [ -d "${lgsmdir}/functions" ]; then + if [ "$(find "${lgsmdir}/modules"/ -type f -mtime +"14" | wc -l)" -ne "0" ]; then + rm -rf "${lgsmdir:?}/functions" + fi +fi + +fn_parms() { + fn_reload_startparameters + parms="${startparameters}" +} diff --git a/lgsm/functions/core_logs.sh b/lgsm/functions/core_logs.sh new file mode 100644 index 000000000..8057f30f7 --- /dev/null +++ b/lgsm/functions/core_logs.sh @@ -0,0 +1,110 @@ +#!/bin/bash +# LinuxGSM core_logs.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Acts as a log rotator, removing old logs. + +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" + +# Check if logfile variable and file exist, create logfile if it doesn't exist. +if [ "${consolelog}" ]; then + if [ ! -f "${consolelog}" ]; then + touch "${consolelog}" + fi +fi + +# For games not displaying a console, and having logs into their game directory. +check_status.sh +if [ "${status}" != "0" ] && [ "${commandname}" == "START" ] && [ -n "${gamelogfile}" ]; then + if [ "$(find "${systemdir}" -name "gamelog*.log")" ]; then + fn_print_info "Moving game logs to ${gamelogdir}" + fn_script_log_info "Moving game logs to ${gamelogdir}" + echo -en "\n" + fn_sleep_time + mv "${systemdir}"/gamelog*.log "${gamelogdir}" + fi +fi + +# Log manager will start the cleanup if it finds logs older than "${logdays}". +if [ "$(find "${lgsmlogdir}"/ -type f -mtime +"${logdays}" | wc -l)" -ne "0" ]; then + fn_print_dots "Starting" + # Set common logs directories + commonlogs="${systemdir}/logs" + commonsourcelogs="${systemdir}/*/logs" + # Set addon logs directories + sourcemodlogdir="${systemdir}/addons/sourcemod/logs" + ulxlogdir="${systemdir}/data/ulx_logs" + darkrplogdir="${systemdir}/data/darkrp_logs" + legacyserverlogdir="${logdir}/server" + # Setting up counting variables + scriptcount="0" + consolecount="0" + gamecount="0" + srcdscount="0" + smcount="0" + ulxcount="0" + darkrpcount="0" + legacycount="0" + fn_sleep_time + fn_print_info "Removing logs older than ${logdays} days" + fn_script_log_info "Removing logs older than ${logdays} days" + # Logging logfiles to be removed according to "${logdays}", counting and removing them. + # Script logfiles. + find "${lgsmlogdir}"/ -type f -mtime +"${logdays}" | tee >> "${lgsmlog}" + scriptcount=$(find "${lgsmlogdir}"/ -type f -mtime +"${logdays}" | wc -l) + find "${lgsmlogdir}"/ -mtime +"${logdays}" -type f -exec rm -f {} \; + # SRCDS and unreal logfiles. + if [ "${engine}" == "unreal2" ] || [ "${engine}" == "source" ]; then + find "${gamelogdir}"/ -type f -mtime +"${logdays}" | tee >> "${lgsmlog}" + gamecount=$(find "${gamelogdir}"/ -type f -mtime +"${logdays}" | wc -l) + find "${gamelogdir}"/ -mtime +"${logdays}" -type f -exec rm -f {} \; + fi + # Console logfiles. + if [ "${consolelog}" ]; then + find "${consolelogdir}"/ -type f -mtime +"${logdays}" | tee >> "${lgsmlog}" + consolecount=$(find "${consolelogdir}"/ -type f -mtime +"${logdays}" | wc -l) + find "${consolelogdir}"/ -mtime +"${logdays}" -type f -exec rm -f {} \; + fi + # Common logfiles. + if [ -d "${commonlogs}" ]; then + find "${commonlogs}"/ -type f -mtime +"${logdays}" | tee >> "${lgsmlog}" + smcount=$(find "${commonlogs}"/ -type f -mtime +"${logdays}" | wc -l) + find "${commonlogs}"/ -mtime +"${logdays}" -type f -exec rm -f {} \; + fi + if [ -d "${commonsourcelogs}" ]; then + find "${commonsourcelogs}"/* -type f -mtime +"${logdays}" | tee >> "${lgsmlog}" + smcount=$(find "${commonsourcelogs}"/* -type f -mtime +"${logdays}" | wc -l) + find "${commonsourcelogs}"/* -mtime +"${logdays}" -type f -exec rm -f {} \; + fi + # Source addons logfiles. + if [ "${engine}" == "source" ]; then + # SourceMod logfiles. + if [ -d "${sourcemodlogdir}" ]; then + find "${sourcemodlogdir}"/ -type f -mtime +"${logdays}" | tee >> "${lgsmlog}" + smcount=$(find "${sourcemodlogdir}"/ -type f -mtime +"${logdays}" | wc -l) + find "${sourcemodlogdir}"/ -mtime +"${logdays}" -type f -exec rm -f {} \; + fi + # Garry's Mod logfiles. + if [ "${shortname}" == "gmod" ]; then + # ULX logfiles. + if [ -d "${ulxlogdir}" ]; then + find "${ulxlogdir}"/ -type f -mtime +"${logdays}" | tee >> "${lgsmlog}" + ulxcount=$(find "${ulxlogdir}"/ -type f -mtime +"${logdays}" | wc -l) + find "${ulxlogdir}"/ -mtime +"${logdays}" -type f -exec rm -f {} \; + fi + # DarkRP logfiles. + if [ -d "${darkrplogdir}" ]; then + find "${darkrplogdir}"/ -type f -mtime +"${logdays}" | tee >> "${lgsmlog}" + darkrpcount=$(find "${darkrplogdir}"/ -type f -mtime +"${logdays}" | wc -l) + find "${darkrplogdir}"/ -mtime +"${logdays}" -type f -exec rm -f {} \; + fi + fi + fi + + # Count total amount of files removed. + countlogs=$((scriptcount + consolecount + gamecount + srcdscount + smcount + ulxcount + darkrpcount)) + # Job done. + fn_print_ok "Removed ${countlogs} log files" + fn_script_log "Removed ${countlogs} log files" +fi diff --git a/lgsm/functions/core_messages.sh b/lgsm/functions/core_messages.sh new file mode 100644 index 000000000..6d3ca9a25 --- /dev/null +++ b/lgsm/functions/core_messages.sh @@ -0,0 +1,598 @@ +#!/bin/bash +# LinuxGSM core_messages.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Defines on-screen messages such as [ OK ] and how script logs look. + +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" + +# nl: new line: message is following by a new line. +# eol: end of line: message is placed at the end of the current line. +fn_ansi_loader() { + if [ "${ansi}" != "off" ]; then + # echo colors + default="\e[0m" + black="\e[30m" + red="\e[31m" + lightred="\e[91m" + green="\e[32m" + lightgreen="\e[92m" + yellow="\e[33m" + lightyellow="\e[93m" + blue="\e[34m" + lightblue="\e[94m" + magenta="\e[35m" + lightmagenta="\e[95m" + cyan="\e[36m" + lightcyan="\e[96m" + darkgrey="\e[90m" + lightgrey="\e[37m" + white="\e[97m" + fi + # carriage return & erase to end of line. + creeol="\r\033[K" +} + +fn_sleep_time() { + if [ "${sleeptime}" != "0" ] || [ "${travistest}" != "1" ]; then + if [ -z "${sleeptime}" ]; then + sleeptime=0.5 + fi + sleep "${sleeptime}" + fi +} + +# Log display +######################## +## Feb 28 14:56:58 ut99-server: Monitor: +fn_script_log() { + if [ -d "${lgsmlogdir}" ]; then + if [ -n "${commandname}" ]; then + echo -e "$(date '+%b %d %H:%M:%S.%3N') ${selfname}: ${commandname}: ${1}" >> "${lgsmlog}" + else + echo -e "$(date '+%b %d %H:%M:%S.%3N') ${selfname}: ${1}" >> "${lgsmlog}" + fi + fi +} + +## Feb 28 14:56:58 ut99-server: Monitor: PASS: +fn_script_log_pass() { + if [ -d "${lgsmlogdir}" ]; then + + if [ -n "${commandname}" ]; then + echo -e "$(date '+%b %d %H:%M:%S.%3N') ${selfname}: ${commandname}: PASS: ${1}" >> "${lgsmlog}" + else + echo -e "$(date '+%b %d %H:%M:%S.%3N') ${selfname}: PASS: ${1}" >> "${lgsmlog}" + fi + fi + exitcode=0 +} + +## Feb 28 14:56:58 ut99-server: Monitor: FATAL: +fn_script_log_fatal() { + if [ -d "${lgsmlogdir}" ]; then + if [ -n "${commandname}" ]; then + echo -e "$(date '+%b %d %H:%M:%S.%3N') ${selfname}: ${commandname}: FATAL: ${1}" >> "${lgsmlog}" + else + echo -e "$(date '+%b %d %H:%M:%S.%3N') ${selfname}: FATAL: ${1}" >> "${lgsmlog}" + fi + fi + exitcode=1 +} + +## Feb 28 14:56:58 ut99-server: Monitor: ERROR: +fn_script_log_error() { + if [ -d "${lgsmlogdir}" ]; then + if [ -n "${commandname}" ]; then + echo -e "$(date '+%b %d %H:%M:%S.%3N') ${selfname}: ${commandname}: ERROR: ${1}" >> "${lgsmlog}" + else + echo -e "$(date '+%b %d %H:%M:%S.%3N') ${selfname}: ERROR: ${1}" >> "${lgsmlog}" + fi + fi + exitcode=2 +} + +## Feb 28 14:56:58 ut99-server: Monitor: WARN: +fn_script_log_warn() { + if [ -d "${lgsmlogdir}" ]; then + if [ -n "${commandname}" ]; then + echo -e "$(date '+%b %d %H:%M:%S.%3N') ${selfname}: ${commandname}: WARN: ${1}" >> "${lgsmlog}" + else + echo -e "$(date '+%b %d %H:%M:%S.%3N') ${selfname}: WARN: ${1}" >> "${lgsmlog}" + fi + fi + exitcode=3 +} + +## Feb 28 14:56:58 ut99-server: Monitor: INFO: +fn_script_log_info() { + if [ -d "${lgsmlogdir}" ]; then + if [ -n "${commandname}" ]; then + echo -e "$(date '+%b %d %H:%M:%S.%3N') ${selfname}: ${commandname}: INFO: ${1}" >> "${lgsmlog}" + else + echo -e "$(date '+%b %d %H:%M:%S.%3N') ${selfname}: INFO: ${1}" >> "${lgsmlog}" + fi + fi +} + +## Feb 28 14:56:58 ut99-server: Monitor: UPDATE: +fn_script_log_update() { + if [ -d "${lgsmlogdir}" ]; then + if [ -n "${commandname}" ]; then + echo -e "$(date '+%b %d %H:%M:%S.%3N') ${selfname}: ${commandname}: UPDATE: ${1}" >> "${lgsmlog}" + else + echo -e "$(date '+%b %d %H:%M:%S.%3N') ${selfname}: UPDATE: ${1}" >> "${lgsmlog}" + fi + fi +} + +# On-Screen - Automated functions +################################## + +# [ .... ] +fn_print_dots() { + if [ "${commandaction}" ]; then + echo -en "${creeol}[ .... ] ${commandaction} ${selfname}: $*" + else + echo -en "${creeol}[ .... ] $*" + fi + fn_sleep_time +} + +fn_print_dots_nl() { + if [ "${commandaction}" ]; then + echo -e "${creeol}[ .... ] ${commandaction} ${selfname}: $*" + else + echo -e "${creeol}[ .... ] $*" + fi + fn_sleep_time + echo -en "\n" +} + +# [ OK ] +fn_print_ok() { + if [ "${commandaction}" ]; then + echo -en "${creeol}[${green} OK ${default}] ${commandaction} ${selfname}: $*" + else + echo -en "${creeol}[${green} OK ${default}] $*" + fi + fn_sleep_time +} + +fn_print_ok_nl() { + if [ "${commandaction}" ]; then + echo -en "${creeol}[${green} OK ${default}] ${commandaction} ${selfname}: $*" + else + echo -en "${creeol}[${green} OK ${default}] $*" + fi + fn_sleep_time + echo -en "\n" +} + +# [ FAIL ] +fn_print_fail() { + if [ "${commandaction}" ]; then + echo -en "${creeol}[${red} FAIL ${default}] ${commandaction} ${selfname}: $*" + else + echo -en "${creeol}[${red} FAIL ${default}] $*" + fi + fn_sleep_time +} + +fn_print_fail_nl() { + if [ "${commandaction}" ]; then + echo -en "${creeol}[${red} FAIL ${default}] ${commandaction} ${selfname}: $*" + else + echo -en "${creeol}[${red} FAIL ${default}] $*" + fi + fn_sleep_time + echo -en "\n" +} + +# [ ERROR ] +fn_print_error() { + if [ "${commandaction}" ]; then + echo -en "${creeol}[${red} ERROR ${default}] ${commandaction} ${selfname}: $*" + else + echo -en "${creeol}[${red} ERROR ${default}] $*" + fi + fn_sleep_time +} + +fn_print_error_nl() { + if [ "${commandaction}" ]; then + echo -en "${creeol}[${red} ERROR ${default}] ${commandaction} ${selfname}: $*" + else + echo -en "${creeol}[${red} ERROR ${default}] $*" + fi + fn_sleep_time + echo -en "\n" +} + +# [ WARN ] +fn_print_warn() { + if [ "${commandaction}" ]; then + echo -en "${creeol}[${lightyellow} WARN ${default}] ${commandaction} ${selfname}: $*" + else + echo -en "${creeol}[${lightyellow} WARN ${default}] $*" + fi + fn_sleep_time +} + +fn_print_warn_nl() { + if [ "${commandaction}" ]; then + echo -en "${creeol}[${lightyellow} WARN ${default}] ${commandaction} ${selfname}: $*" + else + echo -en "${creeol}[${lightyellow} WARN ${default}] $*" + fi + fn_sleep_time + echo -en "\n" +} + +# [ INFO ] +fn_print_info() { + if [ "${commandaction}" ]; then + echo -en "${creeol}[${cyan} INFO ${default}] ${commandaction} ${selfname}: $*" + else + echo -en "${creeol}[${cyan} INFO ${default}] $*" + fi + fn_sleep_time +} + +fn_print_info_nl() { + if [ "${commandaction}" ]; then + echo -en "${creeol}[${cyan} INFO ${default}] ${commandaction} ${selfname}: $*" + else + echo -en "${creeol}[${cyan} INFO ${default}] $*" + fi + fn_sleep_time + echo -en "\n" +} + +# [ START ] +fn_print_start() { + if [ "${commandaction}" ]; then + echo -en "${creeol}[${lightgreen} START ${default}] ${commandaction} ${selfname}: $*" + else + echo -en "${creeol}[${lightgreen} START ${default}] $*" + fi + fn_sleep_time +} + +fn_print_start_nl() { + if [ "${commandaction}" ]; then + echo -en "${creeol}[${lightgreen} START ${default}] ${commandaction} ${selfname}: $*" + else + echo -en "${creeol}[${lightgreen} START ${default}] $*" + fi + fn_sleep_time + echo -en "\n" +} + +# On-Screen - Interactive messages +################################## + +# No More Room in Hell Debug +# ================================= +fn_print_header() { + echo -e "" + echo -e "${lightyellow}${gamename} ${commandaction}${default}" + echo -e "=================================${default}" +} + +# Complete! +fn_print_complete() { + echo -en "${green}Complete!${default} $*" + fn_sleep_time +} + +fn_print_complete_nl() { + echo -e "${green}Complete!${default} $*" + fn_sleep_time +} + +# Failure! +fn_print_failure() { + echo -en "${red}Failure!${default} $*" + fn_sleep_time +} + +fn_print_failure_nl() { + echo -e "${red}Failure!${default} $*" + fn_sleep_time +} + +# Error! +fn_print_error2() { + echo -en "${red}Error!${default} $*" + fn_sleep_time +} + +fn_print_error2_nl() { + echo -e "${red}Error!${default} $*" + fn_sleep_time +} + +# Warning! +fn_print_warning() { + echo -en "${lightyellow}Warning!${default} $*" + fn_sleep_time +} + +fn_print_warning_nl() { + echo -e "${lightyellow}Warning!${default} $*" + fn_sleep_time +} + +# Information! +fn_print_information() { + echo -en "${cyan}Information!${default} $*" + fn_sleep_time +} + +fn_print_information_nl() { + echo -e "${cyan}Information!${default} $*" + fn_sleep_time +} + +# Y/N Prompt +fn_prompt_yn() { + local prompt="$1" + local initial="$2" + + if [ "${initial}" == "Y" ]; then + prompt+=" [Y/n] " + elif [ "${initial}" == "N" ]; then + prompt+=" [y/N] " + else + prompt+=" [y/n] " + fi + + while true; do + read -e -i "${initial}" -p "${prompt}" -r yn + case "${yn}" in + [Yy] | [Yy][Ee][Ss]) return 0 ;; + [Nn] | [Nn][Oo]) return 1 ;; + *) echo -e "Please answer yes or no." ;; + esac + done +} + +# Prompt for message +fn_prompt_message() { + while true; do + unset prompt + local prompt="$1" + read -e -p "${prompt}" -r answer + if fn_prompt_yn "Continue" Y; then + break + fi + done + echo "${answer}" +} + +# On-Screen End of Line +################################## + +# YES +fn_print_yes_eol() { + echo -en "${cyan}YES${default}" + fn_sleep_time +} + +fn_print_yes_eol_nl() { + echo -e "${cyan}YES${default}" + fn_sleep_time +} + +# NO +fn_print_no_eol() { + echo -en "${red}NO${default}" + fn_sleep_time +} + +fn_print_no_eol_nl() { + echo -e "${red}NO${default}" + fn_sleep_time +} + +# OK +fn_print_ok_eol() { + echo -en "${green}OK${default}" + fn_sleep_time +} + +fn_print_ok_eol_nl() { + echo -e "${green}OK${default}" + fn_sleep_time +} + +# FAIL +fn_print_fail_eol() { + echo -en "${red}FAIL${default}" + fn_sleep_time +} + +fn_print_fail_eol_nl() { + echo -e "${red}FAIL${default}" + fn_sleep_time +} + +# ERROR +fn_print_error_eol() { + echo -en "${red}ERROR${default}" + fn_sleep_time +} + +fn_print_error_eol_nl() { + echo -e "${red}ERROR${default}" + fn_sleep_time +} + +# WAIT +fn_print_wait_eol() { + echo -en "${cyan}WAIT${default}" + fn_sleep_time +} + +fn_print_wait_eol_nl() { + echo -e "${cyan}WAIT${default}" + fn_sleep_time +} + +# WARN +fn_print_warn_eol() { + echo -en "${lightyellow}WARN${default}" + fn_sleep_time +} + +fn_print_warn_eol_nl() { + echo -e "${lightyellow}WARN${default}" + fn_sleep_time +} + +# INFO +fn_print_info_eol() { + echo -en "${cyan}INFO${default}" + fn_sleep_time +} + +fn_print_info_eol_nl() { + echo -e "${cyan}INFO${default}" + fn_sleep_time +} + +# QUERYING +fn_print_querying_eol() { + echo -en "${cyan}QUERYING${default}" + fn_sleep_time +} + +fn_print_querying_eol_nl() { + echo -e "${cyan}QUERYING${default}" + fn_sleep_time +} + +# CHECKING +fn_print_checking_eol() { + echo -en "${cyan}CHECKING${default}" + fn_sleep_time +} + +fn_print_checking_eol_nl() { + echo -e "${cyan}CHECKING${default}" + fn_sleep_time +} + +# DELAY +fn_print_delay_eol() { + echo -en "${green}DELAY${default}" + fn_sleep_time +} + +fn_print_delay_eol_nl() { + echo -e "${green}DELAY${default}" + fn_sleep_time +} + +# CANCELED +fn_print_canceled_eol() { + echo -en "${lightyellow}CANCELED${default}" + fn_sleep_time +} + +fn_print_canceled_eol_nl() { + echo -e "${lightyellow}CANCELED${default}" + fn_sleep_time +} + +# REMOVED +fn_print_removed_eol() { + echo -en "${red}REMOVED${default}" + fn_sleep_time +} + +fn_print_removed_eol_nl() { + echo -e "${red}REMOVED${default}" + fn_sleep_time +} + +# UPDATE +fn_print_update_eol() { + echo -en "${cyan}UPDATE${default}" + fn_sleep_time +} + +fn_print_update_eol_nl() { + echo -e "${cyan}UPDATE${default}" + fn_sleep_time +} + +fn_print_ascii_logo() { + echo -e "" + echo -e " mdMMMMbm" + echo -e " mMMMMMMMMMMm" + echo -e " mMMMMMMMMMMMMm" + echo -e " mMMMMMMMMMMMMMMm" + echo -e " hMMMV^VMMV^VMMMh" + echo -e " MMMMM MM MMMMM" + echo -e " hMMs vv sMMh" + echo -e " hMMM: :MMMh" + echo -e " .hMMMh hMMMh." + echo -e " -dMMMh ${lightgrey}__${default} hMMMd-" + echo -e " :mMMMs ${lightgrey}||${default} sMMMm:" + echo -e " :MMMM+ ${lightgrey}||${default} ${red}_${default} +NMMN:" + echo -e " .mMMM+ ${lightgrey}========${default} +MMMm." + echo -e " yMMMy ${darkgrey}##############${default} yMMMy" + echo -e " mMMM: ${darkgrey}##############${default} :MMMm" + echo -e " mMM ${lightyellow}nn${default} ${lightyellow}nn${default} ${lightyellow}nn${default} ${lightyellow}nn${default} MMm" + echo -e " o ${lightyellow}nNNNNNNNn${default} ${lightyellow}nNNNNNNNn${default} o" + echo -e " ${lightyellow}nNNNNNNNNNn${default} ${lightyellow}nNNNNNNNNNn${default}" + echo -e " ${lightyellow}nNNNNNNNNNNN${default} ${lightyellow}NNNNNNNNNNNn${default}" + echo -e " ${lightyellow}+NNNNNNNNN:${default} ${lightyellow}:NNNNNNNNN+${default}" + echo -e " ${lightyellow}nNNNNNNN${default} /\ ${lightyellow}NNNNNNNn${default}" + echo -e " ${lightyellow}nnnnn${default} db ${lightyellow}nnnnn${default}" + echo -e "" + echo -e "${lightyellow}888${default} ${lightyellow}d8b${default} ${default}.d8888b. .d8888b. 888b d888" + echo -e "${lightyellow}888 Y8P ${default}d88P Y88b d88P Y88b 8888b d8888" + echo -e "${lightyellow}888${default} ${default}888${default} 888 Y88b. 88888b.d88888" + echo -e "${lightyellow}888${default} ${lightyellow}888${default} ${lightyellow}88888b.${default} ${lightyellow}888${default} ${lightyellow}888${default} ${lightyellow}888${default} ${lightyellow}888${default} 888 Y888b. 888Y88888P888" + echo -e "${lightyellow}888${default} ${lightyellow}888${default} ${lightyellow}888${default} ${lightyellow}88b${default} ${lightyellow}888${default} ${lightyellow}888${default} ${lightyellow}Y8bd8P${default} 888 88888 Y88b. 888 Y888P 888" + echo -e "${lightyellow}888${default} ${lightyellow}888${default} ${lightyellow}888${default} ${lightyellow}888${default} ${lightyellow}888${default} ${lightyellow}888${default} ${lightyellow}X88K${default} 888 888 888 888 Y8P 888" + echo -e "${lightyellow}888${default} ${lightyellow}888${default} ${lightyellow}888${default} ${lightyellow}888${default} ${lightyellow}Y88b${default} ${lightyellow}88Y${default} ${lightyellow}.d8pq8b.${default} Y88b d88P Y88b d88P 888 * 888" + echo -e "${lightyellow}LinuxGSM${default} ${lightyellow}888${default} ${lightyellow}888${default} ${lightyellow}888${default} ${lightyellow}Y8888Y${default} ${lightyellow}888${default} ${lightyellow}888${default} Y2012P88 Y8888P 888 888" + echo -e "" +} + +fn_print_restart_warning() { + fn_print_warn "${selfname} will be restarted" + fn_script_log_warn "${selfname} will be restarted" + totalseconds=3 + for seconds in {3..1}; do + fn_print_warn "${selfname} will be restarted: ${totalseconds}" + totalseconds=$((totalseconds - 1)) + sleep 1 + if [ "${seconds}" == "0" ]; then + break + fi + done + fn_print_warn_nl "${selfname} will be restarted" +} + +# Functions below are used to ensure that logs and UI correctly reflect the command it is actually running. +# Useful when a command has to call upon another command causing the other command to overrite commandname variables + +# Used to remember the command that ran first. +fn_firstcommand_set() { + if [ -z "${firstcommandname}" ]; then + firstcommandname="${commandname}" + firstcommandaction="${commandaction}" + fi +} + +# Used to reset commandname variables to the command the script ran first. +fn_firstcommand_reset() { + commandname="${firstcommandname}" + commandaction="${firstcommandaction}" +} diff --git a/lgsm/functions/core_modules.sh b/lgsm/functions/core_modules.sh new file mode 100644 index 000000000..8eb843b5a --- /dev/null +++ b/lgsm/functions/core_modules.sh @@ -0,0 +1,816 @@ +#!/bin/bash +# LinuxGSM core_modules.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Defines all modules to allow download and execution of modules using fn_fetch_module. +# This module is called first before any other module. Without this file other modules will not load. + +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" + +modulesversion="v23.2.0" + +# Core + +core_dl.sh() { + modulefile="${FUNCNAME[0]}" + if [ "$(type fn_fetch_core_dl 2> /dev/null)" ]; then + fn_fetch_core_dl "lgsm/modules" "core_dl.sh" "${modulesdir}" "chmodx" "run" "noforcedl" "nohash" + else + fn_bootstrap_fetch_file_github "lgsm/modules" "core_dl.sh" "${modulesdir}" "chmodx" "run" "noforcedl" "nohash" + fi +} + +core_messages.sh() { + modulefile="${FUNCNAME[0]}" + if [ "$(type fn_fetch_core_dl 2> /dev/null)" ]; then + fn_fetch_core_dl "lgsm/modules" "core_messages.sh" "${modulesdir}" "chmodx" "run" "noforcedl" "nohash" + else + fn_bootstrap_fetch_file_github "lgsm/modules" "core_messages.sh" "${modulesdir}" "chmodx" "run" "noforcedl" "nohash" + fi +} + +core_legacy.sh() { + modulefile="${FUNCNAME[0]}" + if [ "$(type fn_fetch_core_dl 2> /dev/null)" ]; then + fn_fetch_core_dl "lgsm/modules" "core_legacy.sh" "${modulesdir}" "chmodx" "run" "noforcedl" "nohash" + else + fn_bootstrap_fetch_file_github "lgsm/modules" "core_legacy.sh" "${modulesdir}" "chmodx" "run" "noforcedl" "nohash" + fi +} + +core_exit.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +core_getopt.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +core_trap.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +core_steamcmd.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +core_github.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +# Commands + +command_backup.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +command_console.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +command_debug.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +command_details.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +command_sponsor.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +command_postdetails.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +command_test_alert.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +command_monitor.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +command_start.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +command_stop.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +command_validate.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +command_install.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +command_install_resources_mta.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +install_squad_license.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +command_mods_install.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +command_mods_update.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +command_mods_remove.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +command_fastdl.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +command_ts3_server_pass.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +command_restart.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +command_skeleton.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +command_wipe.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +command_send.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +# Checks + +check.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +check_config.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +check_deps.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +check_executable.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +check_glibc.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +check_ip.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +check_last_update.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +check_logs.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +check_permissions.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +check_root.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +check_status.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +check_steamcmd.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +check_system_dir.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +check_system_requirements.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +check_tmuxception.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +check_version.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +# Compress + +compress_unreal2_maps.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +compress_ut99_maps.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +# Mods + +mods_list.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +mods_core.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +# Dev + +command_dev_clear_modules.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +command_dev_debug.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +command_dev_detect_deps.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +command_dev_detect_glibc.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +command_dev_detect_ldd.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +command_dev_query_raw.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +# Fix + +fix.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +fix_ark.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +fix_av.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +fix_arma3.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +fix_armar.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +fix_bt.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +fix_bo.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +fix_cmw.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +fix_csgo.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +fix_dst.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +fix_hw.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +fix_ins.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +fix_kf.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +fix_kf2.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +fix_lo.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +fix_mcb.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +fix_mta.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +fix_nmrih.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +fix_onset.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +fix_ro.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +fix_rust.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +fix_rw.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +fix_sfc.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +fix_st.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +fix_steamcmd.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +fix_terraria.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +fix_tf2.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +fix_ut3.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +fix_rust.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +fix_samp.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +fix_sdtd.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +fix_sof2.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +fix_squad.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +fix_ts3.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +fix_ut2k4.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +fix_ut.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +fix_unt.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +fix_vh.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +fix_wurm.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +fix_zmr.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +# Info + +info_distro.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +info_game.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +info_messages.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +info_stats.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +# Alert + +alert.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +alert_discord.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +alert_email.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +alert_ifttt.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +alert_mailgun.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +alert_pushbullet.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +alert_pushover.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +alert_gotify.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +alert_telegram.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +alert_rocketchat.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +alert_slack.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} +# Logs + +core_logs.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +# Query + +query_gamedig.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +# Update + +command_update_modules.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +command_update_linuxgsm.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +command_update.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +command_check_update.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +update_ts3.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +update_minecraft.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +update_minecraft_bedrock.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +update_papermc.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +update_mta.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +update_factorio.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +update_jediknight2.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +update_steamcmd.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +update_vintagestory.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +update_ut99.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +fn_update_modules.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +# +## Installer modules +# + +fn_autoinstall() { + autoinstall=1 + command_install.sh +} + +install_complete.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +install_config.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +install_factorio_save.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +install_dst_token.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +install_eula.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +install_gsquery.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +install_gslt.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +install_header.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +install_logs.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +install_retry.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +install_server_dir.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} +install_server_files.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +install_stats.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +install_steamcmd.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +install_ts3.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +install_ts3db.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +install_ut2k4.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +install_dl_ut2k4.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +install_ut2k4_key.sh() { + modulefile="${FUNCNAME[0]}" + fn_fetch_module +} + +# Calls code required for legacy servers +core_legacy.sh + +# Creates tmp dir if missing +if [ ! -d "${tmpdir}" ]; then + mkdir -p "${tmpdir}" +fi + +# Creates lock dir if missing +if [ ! -d "${lockdir}" ]; then + mkdir -p "${lockdir}" +fi + +# Calls on-screen messages (bootstrap) +core_messages.sh + +#Calls file downloader (bootstrap) +core_dl.sh + +# Calls the global Ctrl-C trap +core_trap.sh diff --git a/lgsm/functions/core_steamcmd.sh b/lgsm/functions/core_steamcmd.sh new file mode 100644 index 000000000..78c30f60a --- /dev/null +++ b/lgsm/functions/core_steamcmd.sh @@ -0,0 +1,330 @@ +#!/bin/bash +# LinuxGSM core_steamcmd.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Core modules for SteamCMD + +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" + +fn_install_steamcmd() { + if [ "${shortname}" == "ark" ] && [ "${installsteamcmd}" == "1" ]; then + steamcmddir="${serverfiles}/Engine/Binaries/ThirdParty/SteamCMD/Linux" + fi + if [ ! -d "${steamcmddir}" ]; then + mkdir -p "${steamcmddir}" + fi + fn_fetch_file "http://media.steampowered.com/client/steamcmd_linux.tar.gz" "" "" "" "${tmpdir}" "steamcmd_linux.tar.gz" "nochmodx" "norun" "noforce" "nohash" + fn_dl_extract "${tmpdir}" "steamcmd_linux.tar.gz" "${steamcmddir}" + chmod +x "${steamcmddir}/steamcmd.sh" +} + +fn_check_steamcmd_user() { + # Checks if steamuser is setup. + if [ "${steamuser}" == "username" ]; then + fn_print_fail_nl "Steam login not set. Update steamuser in ${configdirserver}" + echo -e " * Change steamuser=\"username\" to a valid steam login." + if [ -d "${lgsmlogdir}" ]; then + fn_script_log_fatal "Steam login not set. Update steamuser in ${configdirserver}" + fi + core_exit.sh + fi + # Anonymous user is set if steamuser is missing. + if [ -z "${steamuser}" ]; then + if [ -d "${lgsmlogdir}" ]; then + fn_script_log_info "Using anonymous Steam login" + fi + steamuser="anonymous" + steampass='' + fi +} + +fn_check_steamcmd() { + # Checks if SteamCMD exists when starting or updating a server. + # Only install if steamcmd package is missing or steamcmd dir is missing. + if [ ! -f "${steamcmddir}/steamcmd.sh" ] && [ -z "$(command -v steamcmd 2> /dev/null)" ]; then + if [ "${commandname}" == "INSTALL" ]; then + fn_install_steamcmd + else + fn_print_warn_nl "SteamCMD is missing" + fn_script_log_warn "SteamCMD is missing" + fn_install_steamcmd + fi + elif [ "${commandname}" == "INSTALL" ]; then + fn_print_information "SteamCMD is already installed..." + fn_print_ok_eol_nl + fi +} + +fn_check_steamcmd_dir() { + # Worksround that pre-installs the correct steam directories to ensure all packages use the correct Standard. + # https://github.com/ValveSoftware/steam-for-linux/issues/6976#issuecomment-610446347 + + # Create Steam installation directory. + if [ ! -d "${XDG_DATA_HOME:="${HOME}/.local/share"}/Steam" ]; then + mkdir -p "${XDG_DATA_HOME:="${HOME}/.local/share"}/Steam" + fi + + # Create common Steam directory. + if [ ! -d "${HOME}/.steam" ]; then + mkdir -p "${HOME}/.steam" + fi + + # Symbolic links to Steam installation directory. + if [ ! -L "${HOME}/.steam/root" ]; then + if [ -d "${HOME}/.steam/root" ]; then + rm -f "${HOME:?}/.steam/root" + fi + ln -s "${XDG_DATA_HOME:="${HOME}/.local/share"}/Steam" "${HOME}/.steam/root" + fi + + if [ ! -L "${HOME}/.steam/steam" ]; then + if [ -d "${HOME}/.steam/steam" ]; then + rm -rf "${HOME}/.steam/steam" + fi + ln -s "${XDG_DATA_HOME:="${HOME}/.local/share"}/Steam" "${HOME}/.steam/steam" + fi +} + +fn_check_steamcmd_dir_legacy() { + # Remove old Steam installation directories ~/Steam and ${rootdir}/steamcmd + if [ -d "${rootdir}/steamcmd" ] && [ "${steamcmddir}" == "${XDG_DATA_HOME:="${HOME}/.local/share"}/Steam" ]; then + rm -rf "${rootdir:?}/steamcmd" + fi + + if [ -d "${HOME}/Steam" ] && [ "${steamcmddir}" == "${XDG_DATA_HOME:="${HOME}/.local/share"}/Steam" ]; then + rm -rf "${HOME}/Steam" + fi +} + +fn_check_steamcmd_steamapp() { + # Check that steamapp directory fixes issue #3481 + if [ ! -d "${serverfiles}/steamapps" ]; then + mkdir -p "${serverfiles}/steamapps" + fi +} + +fn_check_steamcmd_ark() { + # Checks if SteamCMD exists in + # Engine/Binaries/ThirdParty/SteamCMD/Linux + # to allow ark mods to work + if [ ! -f "${serverfiles}/Engine/Binaries/ThirdParty/SteamCMD/Linux/steamcmd.sh" ]; then + installsteamcmd=1 + if [ "${commandname}" == "INSTALL" ]; then + fn_install_steamcmd + else + fn_print_warn_nl "ARK mods SteamCMD is missing" + fn_script_log_warn "ARK mods SteamCMD is missing" + fn_install_steamcmd + fi + elif [ "${commandname}" == "INSTALL" ]; then + fn_print_information "ARK mods SteamCMD is already installed..." + fn_print_ok_eol_nl + fi +} + +fn_check_steamcmd_clear() { + # Will remove steamcmd dir if steamcmd package is installed. + if [ "$(command -v steamcmd 2> /dev/null)" ] && [ -d "${rootdir}/steamcmd" ]; then + rm -rf "${steamcmddir:?}" + exitcode=$? + if [ "${exitcode}" != 0 ]; then + fn_script_log_fatal "Removing ${rootdir}/steamcmd" + else + fn_script_log_pass "Removing ${rootdir}/steamcmd" + fi + fi +} + +fn_check_steamcmd_exec() { + if [ "$(command -v steamcmd 2> /dev/null)" ]; then + steamcmdcommand="steamcmd" + else + steamcmdcommand="./steamcmd.sh" + fi +} + +fn_update_steamcmd_localbuild() { + # Gets local build info. + fn_print_dots "Checking local build: ${remotelocation}" + fn_appmanifest_check + # Uses appmanifest to find local build. + localbuild=$(grep buildid "${appmanifestfile}" | tr '[:blank:]"' ' ' | tr -s ' ' | cut -d\ -f3) + + # Set branch to public if no custom branch. + if [ -z "${branch}" ]; then + branch="public" + fi + + # Checks if localbuild variable has been set. + if [ -z "${localbuild}" ]; then + fn_print_fail "Checking local build: ${remotelocation}: missing local build info" + fn_script_log_fatal "Missing local build info" + core_exit.sh + else + fn_print_ok "Checking local build: ${remotelocation}" + fn_script_log_pass "Checking local build" + fi +} + +fn_update_steamcmd_remotebuild() { + # Get remote build info. + if [ -d "${steamcmddir}" ]; then + cd "${steamcmddir}" || exit + fi + + # Removes appinfo.vdf as a fix for not always getting up to date version info from SteamCMD. + if [ "$(find "${HOME}" -type f -name "appinfo.vdf" | wc -l)" -ne "0" ]; then + find "${HOME}" -type f -name "appinfo.vdf" -exec rm -f {} \; + fi + + # password for branch not needed to check the buildid + remotebuildversion=$(${steamcmdcommand} +login "${steamuser}" "${steampass}" +app_info_update 1 +app_info_print "${appid}" +quit | sed -e '/"branches"/,/^}/!d' | sed -n "/\"${branch}\"/,/}/p" | grep -m 1 buildid | tr -cd '[:digit:]') + + if [ "${firstcommandname}" != "INSTALL" ]; then + fn_print_dots "Checking remote build: ${remotelocation}" + # Checks if remotebuildversion variable has been set. + if [ -z "${remotebuildversion}" ] || [ "${remotebuildversion}" == "null" ]; then + fn_print_fail "Checking remote build: ${remotelocation}" + fn_script_log_fatal "Checking remote build" + core_exit.sh + else + fn_print_ok "Checking remote build: ${remotelocation}" + fn_script_log_pass "Checking remote build" + fi + else + # Checks if remotebuild variable has been set. + if [ -z "${remotebuildversion}" ] || [ "${remotebuildversion}" == "null" ]; then + fn_print_failure "Unable to get remote build" + fn_script_log_fatal "Unable to get remote build" + core_exit.sh + fi + fi +} + +fn_update_steamcmd_compare() { + fn_print_dots "Checking for update: ${remotelocation}" + if [ "${localbuild}" != "${remotebuildversion}" ] || [ "${forceupdate}" == "1" ]; then + fn_print_ok_nl "Checking for update: ${remotelocation}" + echo -en "\n" + echo -e "Update available" + echo -e "* Local build: ${red}${localbuild}${default}" + echo -e "* Remote build: ${green}${remotebuildversion}${default}" + if [ -n "${branch}" ]; then + echo -e "* Branch: ${branch}" + fi + if [ -n "${betapassword}" ]; then + echo -e "* Branch password: ${betapassword}" + fi + echo -e "https://steamdb.info/app/${appid}/" + echo -en "\n" + fn_script_log_info "Update available" + fn_script_log_info "Local build: ${localbuild}" + fn_script_log_info "Remote build: ${remotebuildversion}" + if [ -n "${branch}" ]; then + fn_script_log_info "Branch: ${branch}" + fi + if [ -n "${betapassword}" ]; then + fn_script_log_info "Branch password: ${betapassword}" + fi + fn_script_log_info "${localbuild} > ${remotebuildversion}" + + if [ "${commandname}" == "UPDATE" ]; then + unset updateonstart + check_status.sh + # If server stopped. + if [ "${status}" == "0" ]; then + fn_dl_steamcmd + # If server started. + else + fn_print_restart_warning + exitbypass=1 + command_stop.sh + fn_firstcommand_reset + exitbypass=1 + fn_dl_steamcmd + exitbypass=1 + command_start.sh + fn_firstcommand_reset + fi + unset exitbypass + date +%s > "${lockdir}/lastupdate.lock" + alert="update" + elif [ "${commandname}" == "CHECK-UPDATE" ]; then + alert="check-update" + fi + alert.sh + else + fn_print_ok_nl "Checking for update: ${remotelocation}" + echo -en "\n" + echo -e "No update available" + echo -e "* Local build: ${green}${localbuild}${default}" + echo -e "* Remote build: ${green}${remotebuildversion}${default}" + if [ -n "${branch}" ]; then + echo -e "* Branch: ${branch}" + fi + if [ -n "${betapassword}" ]; then + echo -e "* Branch password: ${betapassword}" + fi + echo -e "https://steamdb.info/app/${appid}/" + echo -en "\n" + fn_script_log_info "No update available" + fn_script_log_info "Local build: ${localbuild}" + fn_script_log_info "Remote build: ${remotebuildversion}" + if [ -n "${branch}" ]; then + fn_script_log_info "Branch: ${branch}" + fi + if [ -n "${betapassword}" ]; then + fn_script_log_info "Branch password: ${betapassword}" + fi + fi +} + +fn_appmanifest_info() { + appmanifestfile=$(find -L "${serverfiles}" -type f -name "appmanifest_${appid}.acf") + appmanifestfilewc=$(find -L "${serverfiles}" -type f -name "appmanifest_${appid}.acf" | wc -l) +} + +fn_appmanifest_check() { + fn_appmanifest_info + # Multiple or no matching appmanifest files may sometimes be present. + # This error is corrected if required. + if [ "${appmanifestfilewc}" -ge "2" ]; then + fn_print_error "Multiple appmanifest_${appid}.acf files found" + fn_script_log_error "Multiple appmanifest_${appid}.acf files found" + fn_print_dots "Removing x${appmanifestfilewc} appmanifest_${appid}.acf files" + for appfile in ${appmanifestfile}; do + rm -f "${appfile:?}" + done + appmanifestfilewc1="${appmanifestfilewc}" + fn_appmanifest_info + # if error can not be resolved. + if [ "${appmanifestfilewc}" -ge "2" ]; then + fn_print_fail "Unable to remove x${appmanifestfilewc} appmanifest_${appid}.acf files" + fn_script_log_fatal "Unable to remove x${appmanifestfilewc} appmanifest_${appid}.acf files" + echo -e "* Check user permissions" + for appfile in ${appmanifestfile}; do + echo -e " ${appfile}" + done + core_exit.sh + else + fn_print_ok "Removed x${appmanifestfilewc1} appmanifest_${appid}.acf files" + fn_script_log_pass "Removed x${appmanifestfilewc1} appmanifest_${appid}.acf files" + fn_print_info_nl "Forcing update to correct issue" + fn_script_log_info "Forcing update to correct issue" + fn_dl_steamcmd + fi + elif [ "${appmanifestfilewc}" -eq "0" ]; then + fn_print_error_nl "No appmanifest_${appid}.acf found" + fn_script_log_error "No appmanifest_${appid}.acf found" + fn_print_info_nl "Forcing update to correct issue" + fn_script_log_info "Forcing update to correct issue" + fn_dl_steamcmd + fn_appmanifest_info + if [ "${appmanifestfilewc}" -eq "0" ]; then + fn_print_fail_nl "Still no appmanifest_${appid}.acf found" + fn_script_log_fatal "Still no appmanifest_${appid}.acf found" + core_exit.sh + fi + fi +} diff --git a/lgsm/functions/core_trap.sh b/lgsm/functions/core_trap.sh new file mode 100644 index 000000000..ea6fce869 --- /dev/null +++ b/lgsm/functions/core_trap.sh @@ -0,0 +1,22 @@ +#!/bin/bash +# LinuxGSM core_trap.sh module +# Author: Daniel Gibbs +# Contributors: http://linuxgsm.com/contrib +# Website: https://linuxgsm.com +# Description: Handles CTRL-C trap to give an exit code. + +moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" + +fn_exit_trap() { + if [ -z "${exitcode}" ]; then + exitcode=$? + fi + echo -e "" + if [ -z "${exitcode}" ]; then + exitcode=0 + fi + core_exit.sh +} + +# trap to give an exit code. +trap fn_exit_trap INT