#!/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."