finalizing source rebuild process, docs in progress

This commit is contained in:
Deckard
2025-10-19 01:14:54 -04:00
parent 859a214e12
commit 3426acae6d
12 changed files with 816 additions and 162 deletions

128
.env
View File

@@ -1,128 +0,0 @@
# Generated by ac-compose/setup.sh
COMPOSE_PROJECT_NAME=ac-compose
STORAGE_PATH=./storage
TZ=UTC
# Database
MYSQL_IMAGE=mysql:8.0
CONTAINER_MYSQL=ac-mysql
MYSQL_ROOT_PASSWORD=azerothcore123
MYSQL_ROOT_HOST=%
MYSQL_USER=root
MYSQL_PORT=3306
MYSQL_EXTERNAL_PORT=64306
MYSQL_CHARACTER_SET=utf8mb4
MYSQL_COLLATION=utf8mb4_unicode_ci
MYSQL_MAX_CONNECTIONS=1000
MYSQL_INNODB_BUFFER_POOL_SIZE=256M
MYSQL_INNODB_LOG_FILE_SIZE=64M
DB_AUTH_NAME=acore_auth
DB_WORLD_NAME=acore_world
DB_CHARACTERS_NAME=acore_characters
AC_DB_IMPORT_IMAGE=acore/ac-wotlk-db-import:14.0.0-dev
# Services (images)
AC_AUTHSERVER_IMAGE=acore/ac-wotlk-authserver:14.0.0-dev
AC_WORLDSERVER_IMAGE=acore/ac-wotlk-worldserver:14.0.0-dev
AC_AUTHSERVER_IMAGE_PLAYERBOTS=uprightbass360/azerothcore-wotlk-playerbots:authserver-Playerbot
AC_WORLDSERVER_IMAGE_PLAYERBOTS=uprightbass360/azerothcore-wotlk-playerbots:worldserver-Playerbot
# Client data images
AC_CLIENT_DATA_IMAGE=acore/ac-wotlk-client-data:14.0.0-dev
AC_CLIENT_DATA_IMAGE_PLAYERBOTS=uprightbass360/azerothcore-wotlk-playerbots:client-data-Playerbot
# Ports
AUTH_EXTERNAL_PORT=3784
AUTH_PORT=3724
WORLD_EXTERNAL_PORT=8215
WORLD_PORT=8085
SOAP_EXTERNAL_PORT=7778
SOAP_PORT=7878
# Realm
SERVER_ADDRESS=127.0.0.1
REALM_PORT=8215
# Backups
BACKUP_RETENTION_DAYS=3
BACKUP_RETENTION_HOURS=6
BACKUP_DAILY_TIME=09
# Container user
CONTAINER_USER=0:0
# Modules
MODULE_PLAYERBOTS=1
MODULE_AOE_LOOT=0
MODULE_LEARN_SPELLS=1
MODULE_FIREWORKS=1
MODULE_INDIVIDUAL_PROGRESSION=0
MODULE_AHBOT=1
MODULE_AUTOBALANCE=1
MODULE_TRANSMOG=1
MODULE_NPC_BUFFER=1
MODULE_DYNAMIC_XP=0
MODULE_SOLO_LFG=1
MODULE_1V1_ARENA=0
MODULE_PHASED_DUELS=0
MODULE_BREAKING_NEWS=0
MODULE_BOSS_ANNOUNCER=0
MODULE_ACCOUNT_ACHIEVEMENTS=0
MODULE_AUTO_REVIVE=0
MODULE_GAIN_HONOR_GUARD=0
MODULE_ELUNA=1
MODULE_ARAC=0
MODULE_TIME_IS_TIME=0
MODULE_POCKET_PORTAL=0
MODULE_RANDOM_ENCHANTS=0
MODULE_SOLOCRAFT=1
MODULE_PVP_TITLES=0
MODULE_NPC_BEASTMASTER=0
MODULE_NPC_ENCHANTER=0
MODULE_INSTANCE_RESET=0
MODULE_LEVEL_GRANT=0
MODULE_ASSISTANT=0
MODULE_REAGENT_BANK=0
MODULE_BLACK_MARKET_AUCTION_HOUSE=0
# Client data
CLIENT_DATA_VERSION=v16
# Playerbot runtime
PLAYERBOT_ENABLED=0
PLAYERBOT_MAX_BOTS=40
# Rebuild automation
AUTO_REBUILD_ON_DEPLOY=0
MODULES_REBUILD_SOURCE_PATH=
# Eluna
AC_ELUNA_ENABLED=1
AC_ELUNA_TRACE_BACK=1
AC_ELUNA_AUTO_RELOAD=1
AC_ELUNA_BYTECODE_CACHE=1
AC_ELUNA_SCRIPT_PATH=lua_scripts
AC_ELUNA_REQUIRE_PATHS=
AC_ELUNA_REQUIRE_CPATHS=
AC_ELUNA_AUTO_RELOAD_INTERVAL=1
# Tools
PMA_HOST=ac-mysql
PMA_PORT=3306
PMA_USER=root
PMA_EXTERNAL_PORT=8081
PMA_ARBITRARY=1
PMA_ABSOLUTE_URI=
PMA_UPLOAD_LIMIT=300M
PMA_MEMORY_LIMIT=512M
PMA_MAX_EXECUTION_TIME=600
KEIRA3_EXTERNAL_PORT=4201
KEIRA_DATABASE_HOST=ac-mysql
KEIRA_DATABASE_PORT=3306
# Networking
NETWORK_NAME=azerothcore
NETWORK_SUBNET=172.20.0.0/16
NETWORK_GATEWAY=172.20.0.1

View File

@@ -91,6 +91,7 @@ MODULE_PLAYERBOTS=0
MODULE_AOE_LOOT=0
MODULE_LEARN_SPELLS=0
MODULE_FIREWORKS=0
# Requires worldserver.conf tweaks (EnablePlayerSettings=1, DBC.EnforceItemAttributes=0)
MODULE_INDIVIDUAL_PROGRESSION=0
MODULE_AHBOT=0
MODULE_AUTOBALANCE=0
@@ -100,21 +101,26 @@ MODULE_DYNAMIC_XP=0
MODULE_SOLO_LFG=0
MODULE_1V1_ARENA=0
MODULE_PHASED_DUELS=0
# Needs BreakingNews HTML asset configured (BreakingNews.HtmlPath)
MODULE_BREAKING_NEWS=0
MODULE_BOSS_ANNOUNCER=0
MODULE_ACCOUNT_ACHIEVEMENTS=0
MODULE_AUTO_REVIVE=0
MODULE_GAIN_HONOR_GUARD=0
MODULE_ELUNA=1
MODULE_ARAC=0
# Requires optional SQL/DBC patches; leave off by default
MODULE_TIME_IS_TIME=0
# Requires in-game NPC placement/config; leave off by default
MODULE_POCKET_PORTAL=0
# Pending upstream verification; leave disabled until tested
MODULE_RANDOM_ENCHANTS=0
MODULE_SOLOCRAFT=0
MODULE_PVP_TITLES=0
# Custom NPC modules pending compatibility validation
MODULE_NPC_BEASTMASTER=0
MODULE_NPC_ENCHANTER=0
MODULE_INSTANCE_RESET=0
# mod-quest-count-level currently fails (uses removed sConfigMgr::GetBoolDefault)
MODULE_LEVEL_GRANT=0
MODULE_ASSISTANT=0
MODULE_REAGENT_BANK=0
@@ -124,12 +130,12 @@ MODULE_BLACK_MARKET_AUCTION_HOUSE=0
# Rebuild automation
# =====================
AUTO_REBUILD_ON_DEPLOY=0
MODULES_REBUILD_SOURCE_PATH=
MODULES_REBUILD_SOURCE_PATH=./source/azerothcore
# =====================
# Eluna runtime (worldserver.conf overrides)
# =====================
AC_ELUNA_ENABLED=1
AC_ELUNA_ENABLED=1 # Power users may set to 0 to turn off bundled Eluna runtime
AC_ELUNA_TRACE_BACK=1
AC_ELUNA_AUTO_RELOAD=1
AC_ELUNA_BYTECODE_CACHE=1

4
.gitignore vendored
View File

@@ -2,5 +2,7 @@ data/
backups/
local-data-tools/
storage/
source/
.claude/
*custom.env
.env

148
README.md Normal file
View File

@@ -0,0 +1,148 @@
# ac-compose Deployment Guide
This guide walks through the end-to-end deployment workflow for the `ac-compose` stack. It focuses on the supported automation scripts, the order in which to run them, the default services/ports that come online, and the optional manual steps you may need when enabling additional modules.
## 1. Prerequisites
Before you begin:
- **Docker** and **Docker Compose v2** installed on the host.
- A POSIX-compatible shell (the provided scripts target Bash).
- Sufficient disk space for game assets, module clones, and source builds (20GB recommended).
- Network access to GitHub (or a local mirror) for cloning AzerothCore source and modules.
> Tip: If you use a distinct user/group mapping (e.g., NFS-backed storage) the setup wizard will let you pick non-root UIDs/GIDs.
## 2. Generate `.env` via `setup.sh`
All environment configuration lives in `ac-compose/.env`. Generate or refresh it by running:
```bash
./setup.sh
```
The wizard will ask you to confirm:
1. **Deployment type** (local, LAN, or public) sets bind address and default ports.
2. **Filesystem ownership** for container volumes.
3. **Exterior ports** for Auth (default 3784), World (8215), SOAP (7778), and MySQL (64306).
4. **Storage path** (default `./storage`) and backup retention.
5. **Module preset**. The wizard defaults to a safe set (Solo LFG, Solocraft, Autobalance, Transmog, NPC Buffer, Learn Spells, Fireworks). Manual mode lets you toggle more modules, while warning you about unsafe or incompatible ones.
### Module notes from the wizard
- **AHBot** remains disabled until the upstream module exports `Addmod_ahbotScripts()` (linker failure otherwise).
- **Quest Count Level** disabled: relies on deprecated ConfigMgr calls and fails to compile.
- **Eluna** bundled with AzerothCore by default. To disable the runtime later, edit the `AC_ELUNA_ENABLED` flag under “Eluna runtime” in `.env`.
- Other disabled modules (Individual Progression, Breaking News, TimeIsTime, Pocket Portal, Random Enchants, NPC Beastmaster/Enchanter, Instance Reset, etc.) require additional SQL, DBC, or in-game configuration. Inline comments in `.env` describe these requirements.
When the wizard completes, it writes the fully populated `.env`. Re-run `./setup.sh` anytime you want to regenerate the file; make backups first if you have custom edits.
## 3. (Optional) Clone AzerothCore Source
Certain modules require recompiling the AzerothCore core. If you plan to enable any of them, clone/update the source repository first:
```bash
./scripts/setup-source.sh
```
This script:
- Reads `MODULES_REBUILD_SOURCE_PATH` (default `./source/azerothcore`).
- Clones or updates the repository (uses the Playerbot fork if `MODULE_PLAYERBOTS=1`).
- Ensures the desired branch is checked out.
You can rerun it whenever you need to pull upstream updates.
## 4. Deploy with `deploy.sh`
Use `deploy.sh` to perform a full module-aware deployment. Example:
```bash
./deploy.sh --profile modules
```
What the script does:
1. Stops any running stack (unless `--keep-running` is supplied) to avoid container-name conflicts.
2. Runs the modules manager (`docker compose --profile db --profile modules up ac-modules`) to clone missing modules, apply configuration, and execute module SQL.
3. Rebuilds AzerothCore from source if any C++ modules are enabled. The helper also tags the freshly-built images as `acore/ac-wotlk-{worldserver,authserver}:modules-latest` for subsequent compose runs.
4. Stages the runtime profile by invoking `./scripts/stage-modules.sh --yes`.
5. Tails the `ac-worldserver` logs by default (omit with `--no-watch`).
Useful flags:
- `--profile {standard|playerbots|modules}` force a specific services profile instead of auto-detecting by module toggles.
- `--skip-rebuild` skip the source rebuild even if modules demand it (not recommended unless you are certain rebuilt images already exist).
- `--keep-running` do not stop existing containers before syncing modules (use sparingly; stale `ac-db-import` containers can block the rebuild stage).
- `--no-watch` exit after staging without tailing worldserver logs.
All Docker Compose commands run with the project name derived from `COMPOSE_PROJECT_NAME` in `.env` (default `ac-compose`).
### If you prefer a health check after deployment
Run:
```bash
./verify-deployment.sh --skip-deploy --quick
```
This script inspects container health states and key ports without altering the running stack.
## 5. Service Inventory & Default Ports
| Service / Container | Role | Ports (host → container) | Profile(s) |
|----------------------------|-------------------------------------|--------------------------|----------------------------|
| `ac-mysql` | MySQL 8.0 database | `64306 → 3306` | `db` |
| `ac-db-import` | One-shot DB import/update | | `db` |
| `ac-db-init` | Schema bootstrap helper | | `db` |
| `ac-authserver` | Auth server (no modules) | `3784 → 3724` | `services-standard` |
| `ac-worldserver` | World server (no modules) | `8215 → 8085`, `7778 → 7878` (SOAP) | `services-standard` |
| `ac-authserver-modules` | Auth server w/ custom build | `3784 → 3724` | `services-modules` |
| `ac-worldserver-modules` | World server w/ custom build | `8215 → 8085`, `7778 → 7878` | `services-modules` |
| `ac-authserver-playerbots` | Playerbots auth image | `3784 → 3724` | `services-playerbots` |
| `ac-worldserver-playerbots`| Playerbots world image | `8215 → 8085`, `7778 → 7878` | `services-playerbots` |
| `ac-client-data-standard` | Client-data fetcher | | `client-data` |
| `ac-modules` | Module management / SQL executor | | `modules` |
| `ac-phpmyadmin` | phpMyAdmin UI | `8081 → 80` | `tools` |
| `ac-keira3` | Keira3 world editor | `4201 → 8080` | `tools` |
Additional services (e.g., backups, monitoring) can be enabled by editing `.env` and the compose file as needed.
## 6. Manual Tasks & Advanced Options
- **Disabling Eluna**: Elunas runtime flags live near the end of `.env`. Set `AC_ELUNA_ENABLED=0` if you do not want Lua scripting loaded.
- **Enabling experimental modules**: Edit `.env` toggles. Review the inline comments carefully—some modules require additional SQL, DBC patches, or configuration files before they work safely.
- **Custom `.env` variants**: You can create `.env.custom` files and run `docker compose --env-file` if you maintain multiple environments. The setup wizard always writes `./.env`.
- **Manual source rebuild**: If you prefer to rebuild without staging services, run `./scripts/rebuild-with-modules.sh --yes`. The script now stops and cleans up its own compose project to avoid lingering containers.
- **Health check**: `verify-deployment.sh` can also be run without `--skip-deploy` to bring up a stack and verify container states using the default profiles.
## 7. Clean-Up & Re-running
- To tear down everything: `docker compose --profile db --profile services-standard --profile services-playerbots --profile services-modules --profile client-data --profile modules --profile tools down`.
- To force the module manager to re-run (e.g., after toggling modules in `.env`): `docker compose --profile db --profile modules up --build ac-modules`.
- Storage (logs, configs, client data) lives under `./storage` by default; remove directories carefully if you need a clean slate.
## 8. Further Reading
For a full description of individual modules, sample workflows, or deeper dive into AzerothCore internals, consult the original **V1 README** and linked documentation inside the `V1/` directory. Those docs provide module-specific CMake and SQL references you can adapt if you decide to maintain custom forks.
---
You now have a repeatable, script-driven deployment process:
1. Configure once with `setup.sh`.
2. (Optional) Pull upstream source via `scripts/setup-source.sh`.
3. Deploy and stage via `deploy.sh`.
4. Verify with `verify-deployment.sh` or directly inspect `docker compose ps`.
Happy adventuring!

View File

@@ -30,20 +30,18 @@ print_status() {
usage(){
cat <<EOF
ac-compose Cleanup
Usage: $0 [CLEANUP_LEVEL] [OPTIONS]
CLEANUP LEVELS:
--soft Stop project containers (preserves data)
--hard Remove containers + networks (preserves volumes/images)
--nuclear Complete removal: containers, networks, volumes, images (DESTROYS DATA)
--soft Stop project containers (preserves data)
--hard Remove containers + networks (preserves volumes/images)
--nuclear Complete removal: containers, networks, volumes, images (DESTROYS DATA)
OPTIONS:
--dry-run Show actions without executing
--force Skip confirmation prompts
--preserve-backups Keep backups when nuking storage (moves them aside and restores)
-h, --help Show this help
--dry-run Show actions without executing
--force Skip confirmation prompts
--preserve-backups Keep backups when nuking storage (moves them aside and restores)
-h, --help Show this help
EOF
}
@@ -105,18 +103,38 @@ fi
STORAGE_PATH="${STORAGE_PATH:-$STORAGE_PATH_DEFAULT}"
soft_cleanup() {
print_status HEADER "SOFT CLEANUP - Stop containers"
print_status HEADER "SOFT CLEANUP - Stop runtime stack"
confirm "This will stop all project containers (data preserved)."
execute_command "Stopping containers" docker compose -f "$COMPOSE_FILE" down
local profiles=(
--profile services-standard
--profile services-playerbots
--profile services-modules
--profile client-data
--profile client-data-bots
--profile modules
--profile tools
--profile db
)
execute_command "Stopping runtime profiles" docker compose -f "$COMPOSE_FILE" "${profiles[@]}" down
print_status SUCCESS "Soft cleanup complete"
}
hard_cleanup() {
print_status HEADER "HARD CLEANUP - Remove containers + networks"
confirm "This will remove containers and networks (volumes/images preserved)."
execute_command "Removing containers and networks" docker compose -f "$COMPOSE_FILE" down --remove-orphans
# Remove straggler containers matching ac-* (defensive)
execute_command "Remove stray ac-* containers" "docker ps -a --format '{{.Names}}' | grep -E '^ac-' | xargs -r docker rm -f"
local profiles=(
--profile services-standard
--profile services-playerbots
--profile services-modules
--profile client-data
--profile client-data-bots
--profile modules
--profile tools
--profile db
)
execute_command "Removing containers and networks" docker compose -f "$COMPOSE_FILE" "${profiles[@]}" down --remove-orphans
# Remove straggler containers matching project name (defensive)
execute_command "Remove stray project containers" "docker ps -a --format '{{.Names}}' | grep -E '^ac-' | xargs -r docker rm -f"
# Remove project network if present and not automatically removed
if [ -n "${NETWORK_NAME:-}" ]; then
execute_command "Remove project network ${NETWORK_NAME}" "docker network rm ${NETWORK_NAME} 2>/dev/null || true"
@@ -130,7 +148,17 @@ nuclear_cleanup() {
confirm "Proceed with complete removal?"
# Down with volumes
execute_command "Removing containers, networks and volumes" docker compose -f "$COMPOSE_FILE" down --volumes --remove-orphans
local profiles=(
--profile services-standard
--profile services-playerbots
--profile services-modules
--profile client-data
--profile client-data-bots
--profile modules
--profile tools
--profile db
)
execute_command "Removing containers, networks and volumes" docker compose -f "$COMPOSE_FILE" "${profiles[@]}" down --volumes --remove-orphans
# Remove project images (server/tool images typical to this project)
execute_command "Remove acore images" "docker images --format '{{.Repository}}:{{.Tag}}' | grep -E '^acore/' | xargs -r docker rmi"

View File

@@ -366,6 +366,41 @@ services:
retries: ${AUTH_HEALTHCHECK_RETRIES:-3}
start_period: ${AUTH_HEALTHCHECK_START_PERIOD:-60s}
ac-authserver-modules:
profiles: ["services-modules"]
image: ${AC_AUTHSERVER_IMAGE_MODULES:-acore/ac-wotlk-authserver:modules-latest}
container_name: ac-authserver
user: "${CONTAINER_USER:-0:0}"
depends_on:
ac-mysql:
condition: service_healthy
ac-db-import:
condition: service_completed_successfully
ac-db-init:
condition: service_completed_successfully
environment:
AC_LOGIN_DATABASE_INFO: "${CONTAINER_MYSQL:-ac-mysql};${MYSQL_PORT:-3306};${MYSQL_USER:-root};${MYSQL_ROOT_PASSWORD:-azerothcore123};${DB_AUTH_NAME:-acore_auth}"
AC_UPDATES_ENABLE_DATABASES: "0"
AC_BIND_IP: "0.0.0.0"
AC_LOG_LEVEL: "1"
AC_LOGGER_ROOT_CONFIG: "1,Console"
AC_LOGGER_SERVER_CONFIG: "1,Console"
AC_APPENDER_CONSOLE_CONFIG: "1,2,0"
ports:
- "${AUTH_EXTERNAL_PORT:-3784}:${AUTH_PORT:-3724}"
restart: unless-stopped
networks:
- azerothcore
volumes:
- ${STORAGE_PATH:-./storage}/config:/azerothcore/env/dist/etc
cap_add: ["SYS_NICE"]
healthcheck:
test: ["CMD", "sh", "-c", "ps aux | grep '[a]uthserver' | grep -v grep || exit 1"]
interval: ${AUTH_HEALTHCHECK_INTERVAL:-30s}
timeout: ${AUTH_HEALTHCHECK_TIMEOUT:-10s}
retries: ${AUTH_HEALTHCHECK_RETRIES:-3}
start_period: ${AUTH_HEALTHCHECK_START_PERIOD:-60s}
ac-worldserver-playerbots:
profiles: ["services-playerbots"]
image: ${AC_WORLDSERVER_IMAGE_PLAYERBOTS:-uprightbass360/azerothcore-wotlk-playerbots:worldserver-Playerbot}
@@ -416,6 +451,56 @@ services:
retries: ${WORLD_HEALTHCHECK_RETRIES:-3}
start_period: ${WORLD_HEALTHCHECK_START_PERIOD:-120s}
ac-worldserver-modules:
profiles: ["services-modules"]
image: ${AC_WORLDSERVER_IMAGE_MODULES:-acore/ac-wotlk-worldserver:modules-latest}
container_name: ac-worldserver
user: "${CONTAINER_USER:-0:0}"
stdin_open: true
tty: true
depends_on:
- ac-authserver-modules
- ac-client-data-standard
environment:
AC_LOGIN_DATABASE_INFO: "${CONTAINER_MYSQL:-ac-mysql};${MYSQL_PORT:-3306};${MYSQL_USER:-root};${MYSQL_ROOT_PASSWORD:-azerothcore123};${DB_AUTH_NAME:-acore_auth}"
AC_WORLD_DATABASE_INFO: "${CONTAINER_MYSQL:-ac-mysql};${MYSQL_PORT:-3306};${MYSQL_USER:-root};${MYSQL_ROOT_PASSWORD:-azerothcore123};${DB_WORLD_NAME:-acore_world}"
AC_CHARACTER_DATABASE_INFO: "${CONTAINER_MYSQL:-ac-mysql};${MYSQL_PORT:-3306};${MYSQL_USER:-root};${MYSQL_ROOT_PASSWORD:-azerothcore123};${DB_CHARACTERS_NAME:-acore_characters}"
AC_UPDATES_ENABLE_DATABASES: "0"
AC_BIND_IP: "0.0.0.0"
AC_DATA_DIR: "/azerothcore/data"
AC_SOAP_PORT: "7878"
AC_PROCESS_PRIORITY: "0"
AC_ELUNA_ENABLED: "${AC_ELUNA_ENABLED:-1}"
AC_ELUNA_TRACE_BACK: "${AC_ELUNA_TRACE_BACK:-1}"
AC_ELUNA_AUTO_RELOAD: "${AC_ELUNA_AUTO_RELOAD:-1}"
AC_ELUNA_BYTECODE_CACHE: "${AC_ELUNA_BYTECODE_CACHE:-1}"
AC_ELUNA_SCRIPT_PATH: "${AC_ELUNA_SCRIPT_PATH:-lua_scripts}"
AC_ELUNA_REQUIRE_PATHS: "${AC_ELUNA_REQUIRE_PATHS:-}"
AC_ELUNA_REQUIRE_CPATHS: "${AC_ELUNA_REQUIRE_CPATHS:-}"
AC_ELUNA_AUTO_RELOAD_INTERVAL: "${AC_ELUNA_AUTO_RELOAD_INTERVAL:-1}"
PLAYERBOT_ENABLED: "${PLAYERBOT_ENABLED:-0}"
PLAYERBOT_MAX_BOTS: "${PLAYERBOT_MAX_BOTS:-40}"
AC_LOG_LEVEL: "2"
volumes:
- ${STORAGE_PATH:-./storage}/data:/azerothcore/data
- ${STORAGE_PATH:-./storage}/config:/azerothcore/env/dist/etc
- ${STORAGE_PATH:-./storage}/logs:/azerothcore/logs
- ${STORAGE_PATH:-./storage}/modules:/azerothcore/modules
- ${STORAGE_PATH:-./storage}/lua_scripts:/azerothcore/lua_scripts
networks:
- azerothcore
ports:
- "${WORLD_EXTERNAL_PORT:-8215}:${WORLD_PORT:-8085}"
- "${SOAP_EXTERNAL_PORT:-7778}:${SOAP_PORT:-7878}"
restart: unless-stopped
cap_add: ["SYS_NICE"]
healthcheck:
test: ["CMD", "sh", "-c", "ps aux | grep '[w]orldserver' | grep -v grep || exit 1"]
interval: ${WORLD_HEALTHCHECK_INTERVAL:-30s}
timeout: ${WORLD_HEALTHCHECK_TIMEOUT:-10s}
retries: ${WORLD_HEALTHCHECK_RETRIES:-3}
start_period: ${WORLD_HEALTHCHECK_START_PERIOD:-120s}
# =====================
# Modules & Post-install (modules)
# =====================

220
deploy.sh Executable file
View File

@@ -0,0 +1,220 @@
#!/bin/bash
#
# High-level orchestrator for module-aware deployments.
# 1. Ensures AzerothCore source repo is present
# 2. Runs ac-modules to sync/clean module checkout and configs
# 3. Rebuilds source images when C++ modules demand it
# 4. Stages target compose profile and optionally tails worldserver logs
set -euo pipefail
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
COMPOSE_FILE="$ROOT_DIR/compose.yml"
ENV_PATH="$ROOT_DIR/.env"
TARGET_PROFILE=""
WATCH_LOGS=1
KEEP_RUNNING=0
SKIP_REBUILD=0
BLUE='\033[0;34m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'; RED='\033[0;31m'; NC='\033[0m'
info(){ echo -e "${BLUE} $*${NC}"; }
ok(){ echo -e "${GREEN}$*${NC}"; }
warn(){ echo -e "${YELLOW}⚠️ $*${NC}"; }
err(){ echo -e "${RED}$*${NC}"; }
usage(){
cat <<EOF
Usage: $(basename "$0") [options]
Options:
--profile {standard|playerbots|modules} Force target profile (default: auto-detect)
--no-watch Do not tail worldserver logs after staging
--keep-running Do not pre-stop runtime stack before rebuild
--skip-rebuild Skip source rebuild even if modules require it
-h, --help Show this help
This command automates the module workflow (sync modules, rebuild source if needed,
stage the correct compose profile, and optionally watch worldserver logs).
EOF
}
while [[ $# -gt 0 ]]; do
case "$1" in
--profile) TARGET_PROFILE="$2"; shift 2;;
--no-watch) WATCH_LOGS=0; shift;;
--keep-running) KEEP_RUNNING=1; shift;;
--skip-rebuild) SKIP_REBUILD=1; shift;;
-h|--help) usage; exit 0;;
*) err "Unknown option: $1"; usage; exit 1;;
esac
done
require_cmd(){
command -v "$1" >/dev/null 2>&1 || { err "Missing required command: $1"; exit 1; }
}
require_cmd docker
read_env(){
local key="$1" default="${2:-}"
local value=""
if [ -f "$ENV_PATH" ]; then
value="$(grep -E "^${key}=" "$ENV_PATH" | tail -n1 | cut -d'=' -f2- | tr -d '\r')"
fi
if [ -z "$value" ]; then
value="$default"
fi
echo "$value"
}
resolve_project_name(){
local raw_name="$(read_env COMPOSE_PROJECT_NAME "acore-compose")"
local sanitized
sanitized="$(echo "$raw_name" | tr '[:upper:]' '[:lower:]')"
sanitized="${sanitized// /-}"
sanitized="$(echo "$sanitized" | tr -cd 'a-z0-9_-')"
if [[ -z "$sanitized" ]]; then
sanitized="acore-compose"
elif [[ ! "$sanitized" =~ ^[a-z0-9] ]]; then
sanitized="ac${sanitized}"
fi
echo "$sanitized"
}
compose(){
local project_name
project_name="$(resolve_project_name)"
docker compose --project-name "$project_name" -f "$COMPOSE_FILE" "$@"
}
ensure_source_repo(){
local src_path
src_path="$(read_env MODULES_REBUILD_SOURCE_PATH "./source/azerothcore")"
if [[ "$src_path" != /* ]]; then
src_path="$ROOT_DIR/$src_path"
fi
if [ -d "$src_path/.git" ]; then
echo "$src_path"
return
fi
warn "AzerothCore source not found at $src_path; running setup-source.sh"
(cd "$ROOT_DIR" && ./scripts/setup-source.sh)
echo "$src_path"
}
stop_runtime_stack(){
info "Stopping runtime stack to avoid container name conflicts"
compose \
--profile services-standard \
--profile services-playerbots \
--profile services-modules \
--profile db \
--profile client-data \
--profile client-data-bots \
--profile modules \
down 2>/dev/null || true
}
sync_modules(){
info "Synchronising modules (ac-modules)"
compose --profile db --profile modules up ac-modules
compose --profile db --profile modules down >/dev/null 2>&1 || true
}
modules_need_rebuild(){
local storage_path
storage_path="$(read_env STORAGE_PATH "./storage")"
if [[ "$storage_path" != /* ]]; then
storage_path="$ROOT_DIR/$storage_path"
fi
local sentinel="$storage_path/modules/.requires_rebuild"
[[ -f "$sentinel" ]]
}
rebuild_source(){
local src_dir="$1"
local compose_file="$src_dir/docker-compose.yml"
if [ ! -f "$compose_file" ]; then
err "Source docker-compose.yml missing at $compose_file"
return 1
fi
info "Rebuilding AzerothCore source with modules (this may take a while)"
docker compose -f "$compose_file" down --remove-orphans >/dev/null 2>&1 || true
if (cd "$ROOT_DIR" && ./scripts/rebuild-with-modules.sh --yes); then
ok "Source rebuild completed"
else
err "Source rebuild failed"
return 1
fi
docker compose -f "$compose_file" down --remove-orphans >/dev/null 2>&1 || true
}
tag_module_images(){
local source_world="acore/ac-wotlk-worldserver:master"
local source_auth="acore/ac-wotlk-authserver:master"
local target_world
local target_auth
target_world="$(read_env AC_WORLDSERVER_IMAGE_MODULES "acore/ac-wotlk-worldserver:modules-latest")"
target_auth="$(read_env AC_AUTHSERVER_IMAGE_MODULES "acore/ac-wotlk-authserver:modules-latest")"
if docker image inspect "$source_world" >/dev/null 2>&1; then
docker tag "$source_world" "$target_world"
ok "Tagged $target_world from $source_world"
else
warn "Source image $source_world not found; skipping tag"
fi
if docker image inspect "$source_auth" >/dev/null 2>&1; then
docker tag "$source_auth" "$target_auth"
ok "Tagged $target_auth from $source_auth"
else
warn "Source image $source_auth not found; skipping tag"
fi
}
stage_runtime(){
local args=(--yes)
if [ -n "$TARGET_PROFILE" ]; then
args+=("$TARGET_PROFILE")
fi
info "Staging runtime environment via stage-modules.sh ${args[*]}"
(cd "$ROOT_DIR" && ./scripts/stage-modules.sh "${args[@]}")
}
tail_world_logs(){
info "Tailing worldserver logs (Ctrl+C to stop)"
compose logs -f ac-worldserver
}
main(){
local src_dir
src_dir="$(ensure_source_repo)"
if [ "$KEEP_RUNNING" -ne 1 ]; then
stop_runtime_stack
fi
sync_modules
if modules_need_rebuild; then
if [ "$SKIP_REBUILD" -eq 1 ]; then
warn "Modules require rebuild, but --skip-rebuild was provided."
else
rebuild_source "$src_dir"
tag_module_images
fi
else
info "No module rebuild required."
tag_module_images
fi
stage_runtime
if [ "$WATCH_LOGS" -eq 1 ]; then
tail_world_logs
else
ok "Deployment completed. Logs not tailed (--no-watch)."
fi
}
main

View File

@@ -122,7 +122,6 @@ declare -A MODULE_REPO_MAP=(
[MODULE_ACCOUNT_ACHIEVEMENTS]=mod-account-achievements
[MODULE_AUTO_REVIVE]=mod-auto-revive
[MODULE_GAIN_HONOR_GUARD]=mod-gain-honor-guard
[MODULE_ELUNA]=mod-eluna
[MODULE_TIME_IS_TIME]=mod-TimeIsTime
[MODULE_POCKET_PORTAL]=mod-pocket-portal
[MODULE_RANDOM_ENCHANTS]=mod-random-enchants
@@ -184,8 +183,8 @@ fi
echo "🚀 Building AzerothCore with modules..."
docker compose build --no-cache
echo "🟢 Starting source services..."
docker compose up -d
echo "🧹 Cleaning up source build containers..."
docker compose down --remove-orphans >/dev/null 2>&1 || true
popd >/dev/null

78
scripts/setup-source.sh Executable file
View File

@@ -0,0 +1,78 @@
#!/bin/bash
# ac-compose source repository setup
set -e
echo '🔧 Setting up AzerothCore source repository...'
# Load environment variables if .env exists
if [ -f .env ]; then
source .env
fi
# Default values
SOURCE_PATH="${MODULES_REBUILD_SOURCE_PATH:-./source/azerothcore}"
# Convert to absolute path if relative
if [[ "$SOURCE_PATH" != /* ]]; then
SOURCE_PATH="$(pwd)/$SOURCE_PATH"
fi
MODULE_PLAYERBOTS="${MODULE_PLAYERBOTS:-0}"
# Repository and branch selection based on playerbots mode
if [ "$MODULE_PLAYERBOTS" = "1" ]; then
REPO_URL="https://github.com/liyunfan1223/azerothcore-wotlk.git"
BRANCH="Playerbot"
echo "📌 Playerbots mode: Using liyunfan1223 fork, Playerbot branch"
else
REPO_URL="https://github.com/azerothcore/azerothcore-wotlk.git"
BRANCH="master"
echo "📌 Standard mode: Using official AzerothCore, master branch"
fi
echo "📍 Repository: $REPO_URL"
echo "🌿 Branch: $BRANCH"
echo "📂 Source path: $SOURCE_PATH"
# Create source directory if it doesn't exist
mkdir -p "$(dirname "$SOURCE_PATH")"
# Clone or update repository
if [ -d "$SOURCE_PATH/.git" ]; then
echo "📂 Existing repository found, updating..."
cd "$SOURCE_PATH"
# Check if we're on the correct repository
CURRENT_REMOTE=$(git remote get-url origin 2>/dev/null || echo "")
if [ "$CURRENT_REMOTE" != "$REPO_URL" ]; then
echo "🔄 Repository URL changed, re-cloning..."
cd ..
rm -rf "$(basename "$SOURCE_PATH")"
git clone "$REPO_URL" "$(basename "$SOURCE_PATH")"
cd "$(basename "$SOURCE_PATH")"
fi
# Fetch latest changes
git fetch origin
# Switch to target branch
git checkout "$BRANCH"
git pull origin "$BRANCH"
echo "✅ Repository updated to latest $BRANCH"
else
echo "📥 Cloning repository..."
git clone -b "$BRANCH" "$REPO_URL" "$SOURCE_PATH"
echo "✅ Repository cloned successfully"
fi
cd "$SOURCE_PATH"
# Display current status
CURRENT_COMMIT=$(git rev-parse --short HEAD)
CURRENT_BRANCH=$(git branch --show-current)
echo "📊 Current status:"
echo " Branch: $CURRENT_BRANCH"
echo " Commit: $CURRENT_COMMIT"
echo " Last commit: $(git log -1 --pretty=format:'%s (%an, %ar)')"
echo '🎉 Source repository setup complete!'

211
scripts/stage-modules.sh Executable file
View File

@@ -0,0 +1,211 @@
#!/bin/bash
# ac-compose helper to automatically stage modules and trigger source builds when needed.
set -e
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_DIR="$(dirname "$SCRIPT_DIR")"
ENV_FILE="$PROJECT_DIR/.env"
usage(){
cat <<EOF
Usage: $(basename "$0") [options] [PROFILE]
Automatically detect and stage modules for AzerothCore.
Arguments:
PROFILE Target profile (standard, playerbots, or auto-detect)
Options:
--force-rebuild Force a source rebuild even if not needed
--yes, -y Skip interactive confirmation prompts
-h, --help Show this help
Examples:
$(basename "$0") # Auto-detect profile based on enabled modules
$(basename "$0") playerbots # Force playerbots profile
$(basename "$0") --force-rebuild # Force rebuild and auto-detect
EOF
}
read_env(){
local key="$1" default="$2" env_path="$ENV_FILE" value
if [ -f "$env_path" ]; then
value="$(grep -E "^${key}=" "$env_path" | tail -n1 | cut -d'=' -f2- | tr -d '\r')"
fi
if [ -z "$value" ]; then
value="$default"
fi
echo "$value"
}
confirm(){
local prompt="$1" default="$2" reply
if [ "$ASSUME_YES" = "1" ]; then
return 0
fi
while true; do
if [ "$default" = "y" ]; then
read -r -p "$prompt [Y/n]: " reply
reply="${reply:-y}"
else
read -r -p "$prompt [y/N]: " reply
reply="${reply:-n}"
fi
case "$reply" in
[Yy]*) return 0 ;;
[Nn]*) return 1 ;;
esac
done
}
# Parse arguments
ASSUME_YES=0
FORCE_REBUILD=0
TARGET_PROFILE=""
while [[ $# -gt 0 ]]; do
case "$1" in
--yes|-y) ASSUME_YES=1; shift;;
--force-rebuild) FORCE_REBUILD=1; shift;;
-h|--help) usage; exit 0;;
standard|playerbots) TARGET_PROFILE="$1"; shift;;
*) echo "Unknown option: $1" >&2; usage; exit 1;;
esac
done
if ! command -v docker >/dev/null 2>&1; then
echo "❌ Docker CLI not found in PATH."
exit 1
fi
STORAGE_PATH="$(read_env STORAGE_PATH "./storage")"
if [[ "$STORAGE_PATH" != /* ]]; then
STORAGE_PATH="$PROJECT_DIR/$STORAGE_PATH"
fi
MODULES_DIR="$STORAGE_PATH/modules"
SENTINEL_FILE="$MODULES_DIR/.requires_rebuild"
# Define module mappings (from rebuild-with-modules.sh)
declare -A MODULE_REPO_MAP=(
[MODULE_AOE_LOOT]=mod-aoe-loot
[MODULE_LEARN_SPELLS]=mod-learn-spells
[MODULE_FIREWORKS]=mod-fireworks-on-level
[MODULE_INDIVIDUAL_PROGRESSION]=mod-individual-progression
[MODULE_AHBOT]=mod-ahbot
[MODULE_AUTOBALANCE]=mod-autobalance
[MODULE_TRANSMOG]=mod-transmog
[MODULE_NPC_BUFFER]=mod-npc-buffer
[MODULE_DYNAMIC_XP]=mod-dynamic-xp
[MODULE_SOLO_LFG]=mod-solo-lfg
[MODULE_1V1_ARENA]=mod-1v1-arena
[MODULE_PHASED_DUELS]=mod-phased-duels
[MODULE_BREAKING_NEWS]=mod-breaking-news-override
[MODULE_BOSS_ANNOUNCER]=mod-boss-announcer
[MODULE_ACCOUNT_ACHIEVEMENTS]=mod-account-achievements
[MODULE_AUTO_REVIVE]=mod-auto-revive
[MODULE_GAIN_HONOR_GUARD]=mod-gain-honor-guard
[MODULE_TIME_IS_TIME]=mod-TimeIsTime
[MODULE_POCKET_PORTAL]=mod-pocket-portal
[MODULE_RANDOM_ENCHANTS]=mod-random-enchants
[MODULE_SOLOCRAFT]=mod-solocraft
[MODULE_PVP_TITLES]=mod-pvp-titles
[MODULE_NPC_BEASTMASTER]=mod-npc-beastmaster
[MODULE_NPC_ENCHANTER]=mod-npc-enchanter
[MODULE_INSTANCE_RESET]=mod-instance-reset
[MODULE_LEVEL_GRANT]=mod-quest-count-level
)
# Check for enabled C++ modules that require compilation
compile_modules=()
for key in "${!MODULE_REPO_MAP[@]}"; do
if [ "$(read_env "$key" "0")" = "1" ]; then
compile_modules+=("${MODULE_REPO_MAP[$key]}")
fi
done
# Check for playerbots mode
PLAYERBOT_ENABLED="$(read_env PLAYERBOT_ENABLED "0")"
MODULE_PLAYERBOTS="$(read_env MODULE_PLAYERBOTS "0")"
# Determine target profile if not specified
if [ -z "$TARGET_PROFILE" ]; then
if [ ${#compile_modules[@]} -gt 0 ]; then
echo "🔧 Detected ${#compile_modules[@]} C++ modules requiring compilation:"
for mod in "${compile_modules[@]}"; do
echo "$mod"
done
TARGET_PROFILE="modules"
echo "🧩 Using modules profile for custom source build"
elif [ "$MODULE_PLAYERBOTS" = "1" ] || [ "$PLAYERBOT_ENABLED" = "1" ]; then
TARGET_PROFILE="playerbots"
echo "🤖 Playerbot profile enabled"
else
TARGET_PROFILE="standard"
echo "✅ No special modules detected - using standard profile"
fi
fi
echo "🎯 Target profile: services-$TARGET_PROFILE"
# Check if source rebuild is needed for modules profile
REBUILD_NEEDED=0
if [ "$TARGET_PROFILE" = "modules" ]; then
# Check if source image exists
if ! docker image inspect "acore/ac-wotlk-worldserver:modules-latest" >/dev/null 2>&1; then
echo "📦 Custom worldserver image not found - rebuild needed"
REBUILD_NEEDED=1
elif [ -f "$SENTINEL_FILE" ]; then
echo "🔄 Modules changed since last build - rebuild needed"
REBUILD_NEEDED=1
elif [ "$FORCE_REBUILD" = "1" ]; then
echo "🔧 Force rebuild requested"
REBUILD_NEEDED=1
fi
if [ "$REBUILD_NEEDED" = "1" ]; then
echo "🚀 Triggering source rebuild with modules..."
if confirm "Proceed with source rebuild? (15-45 minutes)" n; then
"$SCRIPT_DIR/rebuild-with-modules.sh" ${ASSUME_YES:+--yes}
else
echo "❌ Rebuild cancelled"
exit 1
fi
else
echo "✅ Custom worldserver image up to date"
fi
fi
# Stage the services
echo "🎬 Staging services with profile: services-$TARGET_PROFILE"
# Stop any currently running services
echo "🛑 Stopping current services..."
docker compose \
--profile services-standard \
--profile services-playerbots \
--profile services-modules \
--profile client-data \
--profile client-data-bots \
down 2>/dev/null || true
# Build list of profiles to start
PROFILE_ARGS=(--profile "services-$TARGET_PROFILE" --profile db --profile modules)
case "$TARGET_PROFILE" in
standard) PROFILE_ARGS+=(--profile client-data) ;;
playerbots) PROFILE_ARGS+=(--profile client-data-bots) ;;
modules) PROFILE_ARGS+=(--profile client-data) ;;
esac
# Start the target profile
echo "🟢 Starting services-$TARGET_PROFILE profile..."
docker compose "${PROFILE_ARGS[@]}" up -d
echo ""
echo "🎉 SUCCESS! AzerothCore staged with profile: services-$TARGET_PROFILE"
# Show status
echo ""
echo "📊 Service Status:"
docker compose ps --format "table {{.Name}}\t{{.Status}}\t{{.Ports}}" | grep -E "(ac-worldserver|ac-authserver|NAME)" || true

View File

@@ -52,7 +52,7 @@ Description:
Notes:
- The generated .env is read automatically by docker compose.
- Run deploy with: deploy-and-check.sh or docker compose --profile ... up -d
- Run deploy with: deploy.sh or docker compose --profile ... up -d
EOF
exit 0
;;
@@ -162,10 +162,15 @@ EOF
local MODULE_PLAYERBOTS=0 MODULE_AOE_LOOT=0 MODULE_LEARN_SPELLS=0 MODULE_FIREWORKS=0 MODULE_INDIVIDUAL_PROGRESSION=0 \
MODULE_AHBOT=0 MODULE_AUTOBALANCE=0 MODULE_TRANSMOG=0 MODULE_NPC_BUFFER=0 MODULE_DYNAMIC_XP=0 MODULE_SOLO_LFG=0 \
MODULE_1V1_ARENA=0 MODULE_PHASED_DUELS=0 MODULE_BREAKING_NEWS=0 MODULE_BOSS_ANNOUNCER=0 MODULE_ACCOUNT_ACHIEVEMENTS=0 \
MODULE_AUTO_REVIVE=0 MODULE_GAIN_HONOR_GUARD=0 MODULE_ELUNA=1 MODULE_TIME_IS_TIME=0 MODULE_POCKET_PORTAL=0 \
MODULE_AUTO_REVIVE=0 MODULE_GAIN_HONOR_GUARD=0 MODULE_TIME_IS_TIME=0 MODULE_POCKET_PORTAL=0 \
MODULE_RANDOM_ENCHANTS=0 MODULE_SOLOCRAFT=0 MODULE_PVP_TITLES=0 MODULE_NPC_BEASTMASTER=0 MODULE_NPC_ENCHANTER=0 \
MODULE_INSTANCE_RESET=0 MODULE_LEVEL_GRANT=0 MODULE_ASSISTANT=0 MODULE_REAGENT_BANK=0 MODULE_BLACK_MARKET_AUCTION_HOUSE=0 MODULE_ARAC=0
declare -A DISABLED_MODULE_REASONS=(
[MODULE_AHBOT]="Requires upstream Addmod_ahbotScripts symbol (fails link)"
[MODULE_LEVEL_GRANT]="QuestCountLevel module relies on removed ConfigMgr APIs and fails to build"
)
local PLAYERBOT_ENABLED=0 PLAYERBOT_MAX_BOTS=40
local AUTO_REBUILD_ON_DEPLOY=0
@@ -174,11 +179,14 @@ EOF
local NEEDS_CXX_REBUILD=0
if [ "$MODE" = "1" ]; then
MODULE_SOLO_LFG=1; MODULE_SOLOCRAFT=1; MODULE_AUTOBALANCE=1; MODULE_AHBOT=1; MODULE_TRANSMOG=1; MODULE_NPC_BUFFER=1; MODULE_LEARN_SPELLS=1; MODULE_FIREWORKS=1
MODULE_SOLO_LFG=1; MODULE_SOLOCRAFT=1; MODULE_AUTOBALANCE=1; MODULE_TRANSMOG=1; MODULE_NPC_BUFFER=1; MODULE_LEARN_SPELLS=1; MODULE_FIREWORKS=1
elif [ "$MODE" = "2" ]; then
MODULE_PLAYERBOTS=1; MODULE_SOLO_LFG=1; MODULE_SOLOCRAFT=1; MODULE_AUTOBALANCE=1; MODULE_AHBOT=1; MODULE_TRANSMOG=1; MODULE_NPC_BUFFER=1; MODULE_LEARN_SPELLS=1; MODULE_FIREWORKS=1
MODULE_PLAYERBOTS=1; MODULE_SOLO_LFG=1; MODULE_SOLOCRAFT=1; MODULE_AUTOBALANCE=1; MODULE_TRANSMOG=1; MODULE_NPC_BUFFER=1; MODULE_LEARN_SPELLS=1; MODULE_FIREWORKS=1
elif [ "$MODE" = "3" ]; then
say INFO "Answer y/n for each module"
for key in "${!DISABLED_MODULE_REASONS[@]}"; do
say WARNING "${key#MODULE_}: ${DISABLED_MODULE_REASONS[$key]}"
done
# Core Gameplay
MODULE_PLAYERBOTS=$(ask_yn "Playerbots - AI companions" n)
MODULE_SOLO_LFG=$(ask_yn "Solo LFG - Solo dungeon finder" n)
@@ -202,7 +210,6 @@ EOF
# Progression
MODULE_INDIVIDUAL_PROGRESSION=$(ask_yn "Individual Progression (Vanilla→TBC→WotLK)" n)
MODULE_DYNAMIC_XP=$(ask_yn "Dynamic XP" n)
MODULE_LEVEL_GRANT=$(ask_yn "Level Grant" n)
MODULE_ACCOUNT_ACHIEVEMENTS=$(ask_yn "Account Achievements" n)
# Server Features
MODULE_BREAKING_NEWS=$(ask_yn "Breaking News" n)
@@ -219,7 +226,7 @@ EOF
MODULE_ARAC=$(ask_yn "All Races All Classes (requires client patch)" n)
fi
for mod_var in MODULE_AOE_LOOT MODULE_LEARN_SPELLS MODULE_FIREWORKS MODULE_INDIVIDUAL_PROGRESSION MODULE_AHBOT MODULE_AUTOBALANCE MODULE_TRANSMOG MODULE_NPC_BUFFER MODULE_DYNAMIC_XP MODULE_SOLO_LFG MODULE_1V1_ARENA MODULE_PHASED_DUELS MODULE_BREAKING_NEWS MODULE_BOSS_ANNOUNCER MODULE_ACCOUNT_ACHIEVEMENTS MODULE_AUTO_REVIVE MODULE_GAIN_HONOR_GUARD MODULE_ELUNA MODULE_TIME_IS_TIME MODULE_POCKET_PORTAL MODULE_RANDOM_ENCHANTS MODULE_SOLOCRAFT MODULE_PVP_TITLES MODULE_NPC_BEASTMASTER MODULE_NPC_ENCHANTER MODULE_INSTANCE_RESET MODULE_LEVEL_GRANT MODULE_ARAC MODULE_ASSISTANT MODULE_REAGENT_BANK MODULE_BLACK_MARKET_AUCTION_HOUSE; do
for mod_var in MODULE_AOE_LOOT MODULE_LEARN_SPELLS MODULE_FIREWORKS MODULE_INDIVIDUAL_PROGRESSION MODULE_AHBOT MODULE_AUTOBALANCE MODULE_TRANSMOG MODULE_NPC_BUFFER MODULE_DYNAMIC_XP MODULE_SOLO_LFG MODULE_1V1_ARENA MODULE_PHASED_DUELS MODULE_BREAKING_NEWS MODULE_BOSS_ANNOUNCER MODULE_ACCOUNT_ACHIEVEMENTS MODULE_AUTO_REVIVE MODULE_GAIN_HONOR_GUARD MODULE_TIME_IS_TIME MODULE_POCKET_PORTAL MODULE_RANDOM_ENCHANTS MODULE_SOLOCRAFT MODULE_PVP_TITLES MODULE_NPC_BEASTMASTER MODULE_NPC_ENCHANTER MODULE_INSTANCE_RESET MODULE_LEVEL_GRANT MODULE_ARAC MODULE_ASSISTANT MODULE_REAGENT_BANK MODULE_BLACK_MARKET_AUCTION_HOUSE; do
eval "value=\$$mod_var"
if [ "$value" = "1" ]; then
NEEDS_CXX_REBUILD=1
@@ -234,9 +241,8 @@ EOF
printf " %-18s %s\n" "Storage Path:" "$STORAGE_PATH"
printf " %-18s %s\n" "Container User:" "$CONTAINER_USER"
printf " %-18s Daily %s:00 UTC, keep %sd/%sh\n" "Backups:" "$BACKUP_DAILY_TIME" "$BACKUP_RETENTION_DAYS" "$BACKUP_RETENTION_HOURS"
printf " %-18s preset %s (playerbots=%s solo_lfg=%s autobalance=%s transmog=%s ahbot=%s npc_buffer=%s learn_spells=%s fireworks=%s)\n" \
"Modules:" "$MODE" "$MODULE_PLAYERBOTS" "$MODULE_SOLO_LFG" "$MODULE_AUTOBALANCE" "$MODULE_TRANSMOG" "$MODULE_AHBOT" "$MODULE_NPC_BUFFER" "$MODULE_LEARN_SPELLS" "$MODULE_FIREWORKS"
printf " %-18s enabled by default (edit .env to disable)\n" "Eluna:"
printf " %-18s preset %s (playerbots=%s solo_lfg=%s autobalance=%s transmog=%s npc_buffer=%s learn_spells=%s fireworks=%s)\n" \
"Modules:" "$MODE" "$MODULE_PLAYERBOTS" "$MODULE_SOLO_LFG" "$MODULE_AUTOBALANCE" "$MODULE_TRANSMOG" "$MODULE_NPC_BUFFER" "$MODULE_LEARN_SPELLS" "$MODULE_FIREWORKS"
if [ "$NEEDS_CXX_REBUILD" = "1" ]; then
printf " %-18s detected (source rebuild required)\n" "C++ modules:"
fi
@@ -340,7 +346,6 @@ MODULE_BOSS_ANNOUNCER=$MODULE_BOSS_ANNOUNCER
MODULE_ACCOUNT_ACHIEVEMENTS=$MODULE_ACCOUNT_ACHIEVEMENTS
MODULE_AUTO_REVIVE=$MODULE_AUTO_REVIVE
MODULE_GAIN_HONOR_GUARD=$MODULE_GAIN_HONOR_GUARD
MODULE_ELUNA=$MODULE_ELUNA
MODULE_ARAC=$MODULE_ARAC
MODULE_TIME_IS_TIME=$MODULE_TIME_IS_TIME
MODULE_POCKET_PORTAL=$MODULE_POCKET_PORTAL
@@ -415,10 +420,10 @@ EOF
say INFO "Run with profiles (examples):"
if [ "$MODULE_PLAYERBOTS" = "1" ]; then
echo " docker compose -f compose.yml --profile db --profile services-playerbots --profile client-data-bots --profile modules --profile tools up -d"
echo " ./deploy-and-check.sh --profiles db,services-playerbots,client-data-bots,modules,tools"
echo " ./deploy.sh --profile modules --no-watch"
else
echo " docker compose -f compose.yml --profile db --profile services-standard --profile client-data --profile modules --profile tools up -d"
echo " ./deploy-and-check.sh --profiles db,services-standard,client-data,modules,tools"
echo " ./deploy.sh --profile modules --no-watch"
fi
}