commit cd56493ae2d8e2f961e394bae045b86080ee8833 Author: Flerp Date: Sat Oct 25 03:44:34 2025 -0700 Initial commit diff --git a/README.MD b/README.MD new file mode 100644 index 0000000..b64bff8 --- /dev/null +++ b/README.MD @@ -0,0 +1,37 @@ +# Azerothcore Updater + +This is a script that will help with incremental updates, and adding/removing modules from your server + +This script checks for updates to Azerothcore, or any of your specified modules +If there's an update it'll perform a dirty build + +If you remove or comment out module git links from your modules.list it will purge them from the azerothcore-wotlk/modules folder and trigger a build to remove said module + +It's mostly currently penned to my install setup, but I plan on making it more extensible and configurable for people not familiar with shell scripts with a config file + +This script does not perform initial installs, and assumes you have your environment already setup + +Script was written and tested on Debian 12 + +## Arguments + +### -h or --help + +Prints a list of all of the arguments, outlined here + +### --reset-database + +Nukes your databases, then re-adds them along with permissions for the acore@% account +Then reimports the sql files using the dbimport utility from azerothcore + +### --setup-configs + +Wipes out old configs, not super useful, going to clean up the logic here for the .dist configs + +### --clean-build + +Forces a clean build by purging the build folder before the cmake and make process. Useful for when dirty builds are failing + +### --force-build + +Forces the script to rebuild Azerothcore, mostly for in the event you have interrupted the build process or if you want to generate a full clean build where the script does not detect any updates diff --git a/modules.list b/modules.list new file mode 100644 index 0000000..1e6fb98 --- /dev/null +++ b/modules.list @@ -0,0 +1 @@ +#Place modile git links here, one per line diff --git a/update-acore.sh b/update-acore.sh new file mode 100644 index 0000000..7c27a2d --- /dev/null +++ b/update-acore.sh @@ -0,0 +1,197 @@ +#!/usr/bin/env bash +set -Eeuo pipefail + +RESET_DB=0 +SETUP_CFG=0 +CLEAN_BUILD=0 +FORCE_BUILD=0 +ANY_REPO_UPDATED=0 + +usage() { + cat <<'USAGE' +Usage: ./update-acore.sh [OPTIONS] + +Options: + --reset-databases Drop & recreate acore_* DBs and run ./dbimport + --setup-configs Convert *.dist -> *.conf and apply basic settings + --clean-build Does a full clean build, if needed + --force-build Forces a build even if the script would otherwise skip it + -h, --help Show this help + + Module repositories are not hard-coded in this script. Instead, they are read + from a file named 'modules.list' located in the same directory as this script. + Each non-empty line of that file (ignoring lines starting with '#') should + contain a single Git repository URL to be cloned or updated. +USAGE +} + +while [[ $# -gt 0 ]]; do + case "$1" in + --reset-databases) RESET_DB=1; shift ;; + --setup-configs) SETUP_CFG=1; shift ;; + --clean-build) CLEAN_BUILD=1; shift ;; + --force-build) FORCE_BUILD=1; shift ;; + -h|--help) usage; exit 0 ;; + *) echo "Unknown option: $1"; usage; exit 1 ;; + esac +done + +timestamp() { date +"%Y%m%d-%H%M%S"; } + +ensure_repo() { + local target="$1" + local url="$2" + + if [[ -d "$target" ]]; then + if [[ -d "$target/.git" ]]; then + echo "[update] $target" + git -C "$target" fetch --all --prune + local branch local_rev remote_rev + branch=$(git -C "$target" symbolic-ref --short HEAD || echo "") + if [[ -n "$branch" ]]; then + local_rev=$(git -C "$target" rev-parse "$branch") + remote_rev=$(git -C "$target" rev-parse "origin/$branch") + if [[ "$local_rev" != "$remote_rev" ]]; then + ANY_REPO_UPDATED=1 + echo "[info] New commits detected for $target; pulling updates." + git -C "$target" pull --rebase --autostash + else + echo "[info] $target is already up to date." + fi + else + ANY_REPO_UPDATED=1 + git -C "$target" pull --rebase --autostash + fi + return + else + local bak="${target}.bak-$(timestamp)" + echo "[warn] $target exists but is not a git repo. Moving to $bak" + mv -- "$target" "$bak" + fi + fi + + echo "[clone] $url -> $target" + git clone "$url" "$target" + ANY_REPO_UPDATED=1 +} + +HOME_DIR="/home/acore" +AC_DIR="${HOME_DIR}/azerothcore-wotlk" +MOD_DIR="${AC_DIR}/modules" +BUILD_DIR="${AC_DIR}/build" +INSTALL_PREFIX="${HOME_DIR}/acore_server" +ETC_DIR="${INSTALL_PREFIX}/etc" + +mkdir -p "${HOME_DIR}" +ensure_repo "${AC_DIR}" "https://github.com/mod-playerbots/azerothcore-wotlk.git" + +mkdir -p "${MOD_DIR}" + + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +REPO_FILE="${SCRIPT_DIR}/modules.list" + +if [[ -f "${REPO_FILE}" ]]; then + mapfile -t REPOS < <(grep -Ev '^[[:space:]]*(#|$)' "${REPO_FILE}") + for url in "${REPOS[@]}"; do + name="$(basename "$url" .git)" + ensure_repo "${MOD_DIR}/${name}" "$url" + done + for dir in "${MOD_DIR}"/*; do + [[ -d "$dir" ]] || continue + base="$(basename "$dir")" + keep=0 + for url in "${REPOS[@]}"; do + name="$(basename "$url" .git)" + if [[ "$name" == "$base" ]]; then + keep=1 + break + fi + done + if [[ $keep -eq 0 ]]; then + echo "[cleanup] Removing ${dir} (not listed in modules.list)" + rm -rf "$dir" + ANY_REPO_UPDATED=1 + fi + done +fi + +SKIP_BUILD=0 +if [[ "${ANY_REPO_UPDATED}" -eq 0 ]] && \ + [[ -x "${INSTALL_PREFIX}/bin/worldserver" && -x "${INSTALL_PREFIX}/bin/authserver" ]]; then + SKIP_BUILD=1 + echo "[info] All repositories are current and binaries exist; skipping compilation." +fi + +if [[ "${SKIP_BUILD}" -eq 0 ]] || [[ "${FORCE_BUILD}" -eq 1 ]]; then + echo "[build] Configuring and compiling..." + if [[ "${CLEAN_BUILD}" -eq 1 ]]; then + rm -rf "${BUILD_DIR}" + fi + mkdir -p "${BUILD_DIR}" + cd "${BUILD_DIR}" + cmake ../ \ + -DCMAKE_INSTALL_PREFIX="${INSTALL_PREFIX}/" \ + -DCMAKE_C_COMPILER=/usr/bin/clang \ + -DCMAKE_CXX_COMPILER=/usr/bin/clang++ \ + -DWITH_WARNINGS=1 \ + -DTOOLS_BUILD=all \ + -DSCRIPTS=static \ + -DMODULES=static + make -j "$(nproc)" install +else + echo "[build] Skipping CMake and make since everything is up to date." +fi + +if [[ ! -d "${ETC_DIR}" ]]; then + echo "[info] Config directory not found, enabling setup-configs automatically." + SETUP_CFG=1 +fi + +if [[ "${SETUP_CFG}" -eq 1 ]]; then + echo "[cfg] Setting up configs..." + + if [[ -d "${ETC_DIR}" ]]; then + echo "[cfg] Removing existing config directory..." + rm -rf "${ETC_DIR}" + fi + + echo "[cfg] Reinstalling configuration templates..." + cd "${BUILD_DIR}" + make install + cd - >/dev/null 2>&1 + + mkdir -p "${ETC_DIR}" + + find "${ETC_DIR}/" -type f -name "*.dist" \ + -exec bash -c 'mv -- "$0" "${0%.dist}"' {} \; + + grep -rl --include="*.conf" 'acore;acore' "${ETC_DIR}/" \ + | xargs -r sed -i 's/acore;acore/acore;mysecretsqlpassword/g' + + sed -i 's|^DataDir = "\\."|DataDir = "../data/"|' \ + "${ETC_DIR}/worldserver.conf" || true +fi + +if [[ "${RESET_DB}" -eq 1 ]]; then + echo "[db] Resetting databases..." + mysql <<'EOF' +DROP DATABASE acore_auth; +DROP DATABASE acore_characters; +DROP DATABASE acore_world; +DROP DATABASE acore_playerbots; +CREATE DATABASE IF NOT EXISTS `acore_world` DEFAULT CHARACTER SET UTF8MB4 COLLATE utf8mb4_unicode_ci; +CREATE DATABASE IF NOT EXISTS `acore_characters` DEFAULT CHARACTER SET UTF8MB4 COLLATE utf8mb4_unicode_ci; +CREATE DATABASE IF NOT EXISTS `acore_auth` DEFAULT CHARACTER SET UTF8MB4 COLLATE utf8mb4_unicode_ci; +CREATE DATABASE IF NOT EXISTS `acore_playerbots` DEFAULT CHARACTER SET UTF8MB4 COLLATE utf8mb4_unicode_ci; +GRANT ALL PRIVILEGES ON `acore_world`.* TO 'acore'@'%' WITH GRANT OPTION; +GRANT ALL PRIVILEGES ON `acore_characters`.* TO 'acore'@'%' WITH GRANT OPTION; +GRANT ALL PRIVILEGES ON `acore_auth`.* TO 'acore'@'%' WITH GRANT OPTION; +GRANT ALL PRIVILEGES ON `acore_playerbots`.* TO 'acore'@'%' WITH GRANT OPTION; +EOF + + cd "${INSTALL_PREFIX}/bin" + ./dbimport +fi + +echo "[done] All requested operations completed."