upstream branch configs and docs

This commit is contained in:
uprightbass360
2025-10-25 18:57:16 -04:00
parent 51bc555dc0
commit ab7b982d9b
7 changed files with 577 additions and 312 deletions

View File

@@ -52,6 +52,13 @@ 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
# =====================
# Services (Module Build Tags)
# =====================
# Images used during module compilation and tagging
AC_AUTHSERVER_IMAGE_MODULES=uprightbass360/azerothcore-wotlk-playerbots:authserver-modules-latest
AC_WORLDSERVER_IMAGE_MODULES=uprightbass360/azerothcore-wotlk-playerbots:worldserver-modules-latest
# =====================
# Client Data
# =====================

View File

@@ -27,6 +27,8 @@ cd acore-compose
./deploy.sh
```
> **Image Sources:** Vanilla/standard profiles run the upstream `acore/*` images. As soon as you enable playerbots or any C++ module, the toolchain switches to the `uprightbass360/azerothcore-wotlk-playerbots` fork, rebuilds it locally when needed, and produces fresh `uprightbass360/...:modules-latest` tags.
**4. Create Admin Account**
Once the worldserver is running:
@@ -81,7 +83,7 @@ set realmlist 203.0.113.100 8215
### ✅ Core Server Components
- **AzerothCore 3.3.5a** - WotLK server application
- **MySQL 8.0** - Database with intelligent initialization and restoration
- **Smart Module System** - Automated module management and source builds
- **Smart Module System** - Automated module management and source builds (compiles the uprightbass360 playerbot fork whenever modules need C++ changes)
- **phpMyAdmin** - Web-based database administration
- **Keira3** - Game content editor and developer tools
@@ -207,7 +209,7 @@ Use this workflow to build locally, then push the same stack to a remote host:
--host docker-server \
--project-dir /home/sam/src/acore-compose
```
Adjust `--project-dir` (and `--identity`) to match your environment. The script copies the repo, `storage/`, and the `modules-latest` images to the remote machine.
Adjust `--project-dir` (and `--identity`) to match your environment. The script copies the repo, `storage/`, and the `uprightbass360/...:modules-latest` images to the remote machine.
3. **Deploy Remotely**
```bash
@@ -216,7 +218,7 @@ Use this workflow to build locally, then push the same stack to a remote host:
./deploy.sh --skip-rebuild --no-watch
'
```
Because the `.env` now points the playerbot services at the `modules-latest` tags, the remote compose run uses the build you just migrated—no additional rebuild required.
Because the `.env` now points the modules profile at the `uprightbass360/...:modules-latest` tags, the remote compose run uses the build you just migrated—no additional rebuild required.
4. **Verify**
```bash
@@ -237,7 +239,7 @@ Use this workflow to build locally, then push the same stack to a remote host:
--user sam \
--project-dir /home/sam/src/acore-compose
```
(Exports rebuilt images to `local-storage/images/acore-modules-images.tar`, including both `acore/...:modules-latest` and `uprightbass360/...:Playerbot` tags, then syncs `storage/` unless `--skip-storage` is provided.)
(Exports rebuilt images to `local-storage/images/acore-modules-images.tar`, bundling the `uprightbass360/...:modules-latest` and `uprightbass360/...:Playerbot` tags, then syncs `storage/` unless `--skip-storage` is provided.)
3. **Deploy on Remote Host**
```bash
ssh docker-server '
@@ -378,9 +380,9 @@ http://YOUR_SERVER_IP:4201
./deploy.sh --profile modules # Custom modules build
# Module staging and compilation
./scripts/stage-modules.sh # Download and stage enabled modules
./scripts/rebuild-with-modules.sh --yes # Force source rebuild with modules
./scripts/setup-source.sh # Initialize/update source repositories
./scripts/stage-modules.sh # Download and stage enabled modules (preps upright playerbot builds)
./scripts/rebuild-with-modules.sh --yes # Rebuild uprightbass360/playerbot images with your modules
./scripts/setup-source.sh # Initialize/update source repositories (auto-switches to playerbot fork for modules)
# Module configuration management
./scripts/copy-module-configs.sh # Create module .conf files

259
deploy.sh
View File

@@ -18,6 +18,16 @@ SKIP_REBUILD=0
WORLD_LOG_SINCE=""
ASSUME_YES=0
COMPILE_MODULE_VARS=(
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_CHALLENGE_MODES MODULE_OLLAMA_CHAT MODULE_PLAYER_BOT_LEVEL_BRACKETS MODULE_STATBOOSTER MODULE_DUNGEON_RESPAWN
MODULE_SKELETON_MODULE MODULE_BG_SLAVERYVALLEY MODULE_AZEROTHSHARD MODULE_WORGOBLIN
)
BLUE='\033[0;34m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'; RED='\033[0;31m'; NC='\033[0m'
info(){ printf '%b\n' "${BLUE} $*${NC}"; }
ok(){ printf '%b\n' "${GREEN}$*${NC}"; }
@@ -50,11 +60,18 @@ Options:
--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
--yes, -y Auto-confirm the deployment prompt
--yes, -y Auto-confirm deployment and rebuild prompts
-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).
This command automates the module workflow: sync modules, rebuild source if needed,
stage the correct compose profile, and optionally watch worldserver logs.
Rebuild Detection:
The script automatically detects when a module rebuild is required by checking:
• Module changes (sentinel file .requires_rebuild)
• C++ modules enabled but modules-latest Docker images missing
Set AUTO_REBUILD_ON_DEPLOY=1 in .env to skip rebuild prompts and auto-rebuild.
EOF
}
@@ -109,14 +126,16 @@ compose(){
}
ensure_source_repo(){
local module_playerbots
module_playerbots="$(read_env MODULE_PLAYERBOTS "0")"
local use_playerbot_source=0
if requires_playerbot_source; then
use_playerbot_source=1
fi
local local_root
local_root="$(read_env STORAGE_PATH_LOCAL "./local-storage")"
local_root="${local_root%/}"
[ -z "$local_root" ] && local_root="."
local default_source="${local_root}/source/azerothcore"
if [ "$module_playerbots" = "1" ]; then
if [ "$use_playerbot_source" = "1" ]; then
default_source="${local_root}/source/azerothcore-playerbots"
fi
@@ -163,6 +182,114 @@ modules_need_rebuild(){
[[ -f "$sentinel" ]]
}
check_auto_rebuild_setting(){
local auto_rebuild
auto_rebuild="$(read_env AUTO_REBUILD_ON_DEPLOY "0")"
[[ "$auto_rebuild" = "1" ]]
}
detect_rebuild_reasons(){
local reasons=()
# Check sentinel file
if modules_need_rebuild; then
reasons+=("Module changes detected (sentinel file present)")
fi
# Check if any C++ modules are enabled but modules-latest images don't exist
local any_cxx_modules=0
local var
for var in "${COMPILE_MODULE_VARS[@]}"; do
if [ "$(read_env "$var" "0")" = "1" ]; then
any_cxx_modules=1
break
fi
done
if [ "$any_cxx_modules" = "1" ]; then
local authserver_modules_image
local worldserver_modules_image
authserver_modules_image="$(read_env AC_AUTHSERVER_IMAGE_MODULES "uprightbass360/azerothcore-wotlk-playerbots:authserver-modules-latest")"
worldserver_modules_image="$(read_env AC_WORLDSERVER_IMAGE_MODULES "uprightbass360/azerothcore-wotlk-playerbots:worldserver-modules-latest")"
if ! docker image inspect "$authserver_modules_image" >/dev/null 2>&1; then
reasons+=("C++ modules enabled but authserver modules image $authserver_modules_image is missing")
fi
if ! docker image inspect "$worldserver_modules_image" >/dev/null 2>&1; then
reasons+=("C++ modules enabled but worldserver modules image $worldserver_modules_image is missing")
fi
fi
printf '%s\n' "${reasons[@]}"
}
requires_playerbot_source(){
if [ "$(read_env MODULE_PLAYERBOTS "0")" = "1" ]; then
return 0
fi
local var
for var in "${COMPILE_MODULE_VARS[@]}"; do
if [ "$(read_env "$var" "0")" = "1" ]; then
return 0
fi
done
return 1
}
confirm_rebuild(){
local reasons=("$@")
if [ ${#reasons[@]} -eq 0 ]; then
return 1 # No rebuild needed
fi
echo
warn "Module rebuild appears to be required:"
local reason
for reason in "${reasons[@]}"; do
warn "$reason"
done
echo
# Check auto-rebuild setting
if check_auto_rebuild_setting; then
info "AUTO_REBUILD_ON_DEPLOY is enabled; proceeding with automatic rebuild."
return 0
fi
# Skip prompt if --yes flag is provided
if [ "$ASSUME_YES" -eq 1 ]; then
info "Auto-confirming rebuild (--yes supplied)."
return 0
fi
# Interactive prompt
info "This will rebuild AzerothCore from source with your enabled modules."
warn "⏱️ This process typically takes 15-45 minutes depending on your system."
echo
if [ -t 0 ]; then
local reply
read -r -p "Proceed with module rebuild? [y/N]: " reply
reply="${reply:-n}"
case "$reply" in
[Yy]*)
info "Rebuild confirmed."
return 0
;;
*)
warn "Rebuild declined. You can:"
warn " • Run with --skip-rebuild to deploy without rebuilding"
warn " • Set AUTO_REBUILD_ON_DEPLOY=1 in .env for automatic rebuilds"
warn " • Run './scripts/rebuild-with-modules.sh' manually later"
return 1
;;
esac
else
warn "Standard input is not interactive; use --yes to auto-confirm or --skip-rebuild to skip."
return 1
fi
}
determine_profile(){
if [ -n "$TARGET_PROFILE" ]; then
echo "$TARGET_PROFILE"
@@ -178,49 +305,8 @@ determine_profile(){
return
fi
local compile_vars=(
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_CHALLENGE_MODES
MODULE_OLLAMA_CHAT
MODULE_PLAYER_BOT_LEVEL_BRACKETS
MODULE_STATBOOSTER
MODULE_DUNGEON_RESPAWN
MODULE_SKELETON_MODULE
MODULE_BG_SLAVERYVALLEY
MODULE_AZEROTHSHARD
MODULE_WORGOBLIN
)
local var
for var in "${compile_vars[@]}"; do
for var in "${COMPILE_MODULE_VARS[@]}"; do
if [ "$(read_env "$var" "0")" = "1" ]; then
echo "modules"
return
@@ -253,53 +339,29 @@ rebuild_source(){
}
tag_module_images(){
local source_world="acore/ac-wotlk-worldserver:master"
local source_auth="acore/ac-wotlk-authserver:master"
local source_auth
local source_world
local target_auth
local target_world
local targets_world=()
local targets_auth=()
source_auth="$(read_env AC_AUTHSERVER_IMAGE_PLAYERBOTS "uprightbass360/azerothcore-wotlk-playerbots:authserver-Playerbot")"
source_world="$(read_env AC_WORLDSERVER_IMAGE_PLAYERBOTS "uprightbass360/azerothcore-wotlk-playerbots:worldserver-Playerbot")"
target_auth="$(read_env AC_AUTHSERVER_IMAGE_MODULES "uprightbass360/azerothcore-wotlk-playerbots:authserver-modules-latest")"
target_world="$(read_env AC_WORLDSERVER_IMAGE_MODULES "uprightbass360/azerothcore-wotlk-playerbots:worldserver-modules-latest")"
targets_world+=("$(read_env AC_WORLDSERVER_IMAGE_MODULES "acore/ac-wotlk-worldserver:modules-latest")")
targets_world+=("$(read_env AC_WORLDSERVER_IMAGE_PLAYERBOTS "uprightbass360/azerothcore-wotlk-playerbots:worldserver-Playerbot")")
targets_auth+=("$(read_env AC_AUTHSERVER_IMAGE_MODULES "acore/ac-wotlk-authserver:modules-latest")")
targets_auth+=("$(read_env AC_AUTHSERVER_IMAGE_PLAYERBOTS "uprightbass360/azerothcore-wotlk-playerbots:authserver-Playerbot")")
local tagged_world=()
local tagged_auth=()
tag_image(){
local src="$1" target="$2" label="$3"
[[ -n "$target" ]] || return 0
case "$label" in
world) for image in "${tagged_world[@]}"; do [[ "$image" == "$target" ]] && return 0; done ;;
auth) for image in "${tagged_auth[@]}"; do [[ "$image" == "$target" ]] && return 0; done ;;
esac
case "$target" in
*modules-latest*)
if docker image inspect "$src" >/dev/null 2>&1; then
docker tag "$src" "$target"
ok "Tagged $target from $src ($label)"
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 $src not found; skipping tag for $label"
warn "Source authserver image $source_auth not found; skipping modules tag"
fi
;;
*)
info "Skipping tag for $label image $target (non modules-latest)"
return 0
;;
esac
case "$label" in
world) tagged_world+=("$target") ;;
auth) tagged_auth+=("$target") ;;
esac
}
for target in "${targets_world[@]}"; do
tag_image "$source_world" "$target" world
done
for target in "${targets_auth[@]}"; do
tag_image "$source_auth" "$target" auth
done
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 worldserver image $source_world not found; skipping modules tag"
fi
}
stage_runtime(){
@@ -396,13 +458,26 @@ main(){
sync_modules
local did_rebuild=0
if modules_need_rebuild; then
local rebuild_reasons
readarray -t rebuild_reasons < <(detect_rebuild_reasons)
if [ ${#rebuild_reasons[@]} -gt 0 ]; then
if [ "$SKIP_REBUILD" -eq 1 ]; then
warn "Modules require rebuild, but --skip-rebuild was provided."
warn "Modules require rebuild, but --skip-rebuild was provided:"
local reason
for reason in "${rebuild_reasons[@]}"; do
warn "$reason"
done
warn "Proceeding without rebuild; deployment may fail if modules-latest images are missing."
else
if confirm_rebuild "${rebuild_reasons[@]}"; then
show_step 4 5 "Building realm with modules (this may take 15-45 minutes)"
rebuild_source "$src_dir"
did_rebuild=1
else
err "Rebuild required but declined. Use --skip-rebuild to force deployment without rebuild."
exit 1
fi
fi
else
info "No module rebuild required."

View File

@@ -45,15 +45,15 @@ read_env(){
}
default_source_path(){
local module_playerbots
module_playerbots="$(read_env MODULE_PLAYERBOTS "0")"
local require_playerbot
require_playerbot="$(modules_require_playerbot_source)"
local local_root
local_root="$(read_env STORAGE_PATH_LOCAL "./local-storage")"
local_root="${local_root%/}"
if [[ -z "$local_root" ]]; then
local_root="."
fi
if [ "$module_playerbots" = "1" ]; then
if [ "$require_playerbot" = "1" ]; then
echo "${local_root}/source/azerothcore-playerbots"
else
echo "${local_root}/source/azerothcore"
@@ -84,6 +84,31 @@ ASSUME_YES=0
SOURCE_OVERRIDE=""
SKIP_STOP=0
COMPILE_MODULE_KEYS=(
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_CHALLENGE_MODES MODULE_OLLAMA_CHAT MODULE_PLAYER_BOT_LEVEL_BRACKETS MODULE_STATBOOSTER MODULE_DUNGEON_RESPAWN
MODULE_SKELETON_MODULE MODULE_BG_SLAVERYVALLEY MODULE_AZEROTHSHARD MODULE_WORGOBLIN
)
modules_require_playerbot_source(){
if [ "$(read_env MODULE_PLAYERBOTS "0")" = "1" ]; then
echo 1
return
fi
local key
for key in "${COMPILE_MODULE_KEYS[@]}"; do
if [ "$(read_env "$key" "0")" = "1" ]; then
echo 1
return
fi
done
echo 0
}
while [[ $# -gt 0 ]]; do
case "$1" in
--yes|-y) ASSUME_YES=1; shift;;
@@ -246,13 +271,41 @@ echo "🚀 Building AzerothCore with modules..."
docker compose build --no-cache
echo "🔖 Tagging modules-latest images"
docker tag acore/ac-wotlk-worldserver:master acore/ac-wotlk-worldserver:modules-latest
docker tag acore/ac-wotlk-authserver:master acore/ac-wotlk-authserver:modules-latest
if [ "$(read_env MODULE_PLAYERBOTS "0")" = "1" ]; then
echo "🔁 Tagging playerbot images uprightbass360/azerothcore-wotlk-playerbots:*"
docker tag acore/ac-wotlk-worldserver:modules-latest uprightbass360/azerothcore-wotlk-playerbots:worldserver-Playerbot
docker tag acore/ac-wotlk-authserver:modules-latest uprightbass360/azerothcore-wotlk-playerbots:authserver-Playerbot
# Get image names and tags from .env.template
TEMPLATE_FILE="$PROJECT_DIR/.env.template"
get_template_value() {
local key="$1"
local fallback="$2"
if [ -f "$TEMPLATE_FILE" ]; then
local value
value=$(grep "^${key}=" "$TEMPLATE_FILE" | head -1 | cut -d'=' -f2- | sed 's/^"\(.*\)"$/\1/')
if [[ "$value" =~ ^\$\{[^}]*:-([^}]*)\}$ ]]; then
value="${BASH_REMATCH[1]}"
fi
[ -n "$value" ] && echo "$value" || echo "$fallback"
else
echo "$fallback"
fi
}
TARGET_AUTHSERVER_IMAGE="$(read_env AC_AUTHSERVER_IMAGE_MODULES "$(get_template_value "AC_AUTHSERVER_IMAGE_MODULES")")"
TARGET_WORLDSERVER_IMAGE="$(read_env AC_WORLDSERVER_IMAGE_MODULES "$(get_template_value "AC_WORLDSERVER_IMAGE_MODULES")")"
PLAYERBOTS_AUTHSERVER_IMAGE="$(read_env AC_AUTHSERVER_IMAGE_PLAYERBOTS "$(get_template_value "AC_AUTHSERVER_IMAGE_PLAYERBOTS")")"
PLAYERBOTS_WORLDSERVER_IMAGE="$(read_env AC_WORLDSERVER_IMAGE_PLAYERBOTS "$(get_template_value "AC_WORLDSERVER_IMAGE_PLAYERBOTS")")"
echo "🔁 Tagging modules images from playerbot build artifacts"
if docker image inspect "$PLAYERBOTS_AUTHSERVER_IMAGE" >/dev/null 2>&1; then
docker tag "$PLAYERBOTS_AUTHSERVER_IMAGE" "$TARGET_AUTHSERVER_IMAGE"
else
echo "⚠️ Warning: $PLAYERBOTS_AUTHSERVER_IMAGE not found, skipping authserver tag"
fi
if docker image inspect "$PLAYERBOTS_WORLDSERVER_IMAGE" >/dev/null 2>&1; then
docker tag "$PLAYERBOTS_WORLDSERVER_IMAGE" "$TARGET_WORLDSERVER_IMAGE"
else
echo "⚠️ Warning: $PLAYERBOTS_WORLDSERVER_IMAGE not found, skipping worldserver tag"
fi
show_rebuild_step 5 5 "Cleaning up build containers"

View File

@@ -14,12 +14,32 @@ PROJECT_ROOT="$(pwd)"
# Default values
MODULE_PLAYERBOTS="${MODULE_PLAYERBOTS:-0}"
NEEDS_CXX_REBUILD="${NEEDS_CXX_REBUILD:-0}"
COMPILE_MODULE_KEYS=(
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_CHALLENGE_MODES MODULE_OLLAMA_CHAT MODULE_PLAYER_BOT_LEVEL_BRACKETS MODULE_STATBOOSTER MODULE_DUNGEON_RESPAWN
MODULE_SKELETON_MODULE MODULE_BG_SLAVERYVALLEY MODULE_AZEROTHSHARD MODULE_WORGOBLIN
)
if [ "$NEEDS_CXX_REBUILD" != "1" ]; then
for key in "${COMPILE_MODULE_KEYS[@]}"; do
if [ "${!key:-0}" = "1" ]; then
NEEDS_CXX_REBUILD=1
break
fi
done
fi
LOCAL_STORAGE_ROOT="${STORAGE_PATH_LOCAL:-./local-storage}"
DEFAULT_STANDARD_PATH="${LOCAL_STORAGE_ROOT%/}/source/azerothcore"
DEFAULT_PLAYERBOTS_PATH="${LOCAL_STORAGE_ROOT%/}/source/azerothcore-playerbots"
SOURCE_PATH_DEFAULT="$DEFAULT_STANDARD_PATH"
if [ "$MODULE_PLAYERBOTS" = "1" ]; then
if [ "$MODULE_PLAYERBOTS" = "1" ] || [ "$NEEDS_CXX_REBUILD" = "1" ]; then
SOURCE_PATH_DEFAULT="$DEFAULT_PLAYERBOTS_PATH"
fi
SOURCE_PATH="${MODULES_REBUILD_SOURCE_PATH:-$SOURCE_PATH_DEFAULT}"
@@ -53,7 +73,7 @@ ACORE_REPO_PLAYERBOTS="${ACORE_REPO_PLAYERBOTS:-https://github.com/uprightbass36
ACORE_BRANCH_PLAYERBOTS="${ACORE_BRANCH_PLAYERBOTS:-Playerbot}"
# Repository and branch selection based on playerbots mode
if [ "$MODULE_PLAYERBOTS" = "1" ]; then
if [ "$MODULE_PLAYERBOTS" = "1" ] || [ "$NEEDS_CXX_REBUILD" = "1" ]; then
REPO_URL="$ACORE_REPO_PLAYERBOTS"
BRANCH="$ACORE_BRANCH_PLAYERBOTS"
echo "📌 Playerbots mode: Using $REPO_URL, branch $BRANCH"

View File

@@ -182,10 +182,11 @@ echo "🎯 Target profile: services-$TARGET_PROFILE"
# Check if source rebuild is needed for modules profile
REBUILD_NEEDED=0
TARGET_WORLDSERVER_IMAGE_MODULES="$(read_env AC_WORLDSERVER_IMAGE_MODULES "uprightbass360/azerothcore-wotlk-playerbots:worldserver-modules-latest")"
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"
if ! docker image inspect "$TARGET_WORLDSERVER_IMAGE_MODULES" >/dev/null 2>&1; then
echo "📦 Modules image $TARGET_WORLDSERVER_IMAGE_MODULES not found - rebuild needed"
REBUILD_NEEDED=1
elif [ -f "$SENTINEL_FILE" ]; then
echo "🔄 Modules changed since last build - rebuild needed"

497
setup.sh
View File

@@ -6,6 +6,147 @@ set -e
# ==============================================
# Mirrors options from scripts/setup-server.sh but targets ac-compose/.env
# Get script directory for template reading
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# ==============================================
# Constants (auto-loaded from .env.template)
# ==============================================
# Function to read value from .env.template (required)
get_template_value() {
local key="$1"
local template_file="$SCRIPT_DIR/.env.template"
if [ ! -f "$template_file" ]; then
echo "ERROR: .env.template file not found at $template_file" >&2
echo "This file is required for setup.sh to function properly." >&2
exit 1
fi
# Extract value, handling variable expansion syntax like ${VAR:-default}
local value
value=$(grep "^${key}=" "$template_file" | head -1 | cut -d'=' -f2- | sed 's/^"\(.*\)"$/\1/')
# Handle ${VAR:-default} syntax by extracting the default value
if [[ "$value" =~ ^\$\{[^}]*:-([^}]*)\}$ ]]; then
value="${BASH_REMATCH[1]}"
fi
if [ -z "$value" ]; then
echo "ERROR: Required key '$key' not found in .env.template" >&2
exit 1
fi
echo "$value"
}
# Load constants from .env.template (required)
readonly DEFAULT_MYSQL_PASSWORD="$(get_template_value "MYSQL_ROOT_PASSWORD")"
readonly DEFAULT_REALM_PORT="$(get_template_value "WORLD_EXTERNAL_PORT")"
readonly DEFAULT_AUTH_PORT="$(get_template_value "AUTH_EXTERNAL_PORT")"
readonly DEFAULT_SOAP_PORT="$(get_template_value "SOAP_EXTERNAL_PORT")"
readonly DEFAULT_MYSQL_PORT="$(get_template_value "MYSQL_EXTERNAL_PORT")"
readonly DEFAULT_PLAYERBOT_MAX="$(get_template_value "PLAYERBOT_MAX_BOTS")"
readonly DEFAULT_LOCAL_STORAGE="$(get_template_value "STORAGE_PATH")"
# Permission schemes (hardcoded as not in template)
readonly PERMISSION_LOCAL_USER="0:0"
readonly PERMISSION_NFS_USER="1001:1000"
readonly DEFAULT_CUSTOM_UID="1000"
readonly DEFAULT_CUSTOM_GID="1000"
# Static values
readonly DEFAULT_LOCAL_ADDRESS="127.0.0.1"
readonly DEFAULT_FALLBACK_LAN_IP="192.168.1.100"
readonly DEFAULT_DOMAIN_PLACEHOLDER="your-domain.com"
readonly DEFAULT_BACKUP_DAYS="3"
readonly DEFAULT_BACKUP_HOURS="6"
readonly DEFAULT_BACKUP_TIME="09"
readonly DEFAULT_NFS_STORAGE="/nfs/azerothcore"
readonly DEFAULT_MOUNT_STORAGE="/mnt/azerothcore-data"
# Docker images (from .env.template)
readonly DEFAULT_MYSQL_IMAGE="$(get_template_value "MYSQL_IMAGE")"
readonly DEFAULT_AC_DB_IMPORT_IMAGE="$(get_template_value "AC_DB_IMPORT_IMAGE")"
readonly DEFAULT_AC_AUTHSERVER_IMAGE="$(get_template_value "AC_AUTHSERVER_IMAGE")"
readonly DEFAULT_AC_WORLDSERVER_IMAGE="$(get_template_value "AC_WORLDSERVER_IMAGE")"
readonly DEFAULT_AC_CLIENT_DATA_IMAGE="$(get_template_value "AC_CLIENT_DATA_IMAGE")"
readonly DEFAULT_AUTH_IMAGE_PLAYERBOTS="$(get_template_value "AC_AUTHSERVER_IMAGE_PLAYERBOTS")"
readonly DEFAULT_WORLD_IMAGE_PLAYERBOTS="$(get_template_value "AC_WORLDSERVER_IMAGE_PLAYERBOTS")"
readonly DEFAULT_CLIENT_DATA_IMAGE_PLAYERBOTS="$(get_template_value "AC_CLIENT_DATA_IMAGE_PLAYERBOTS")"
readonly DEFAULT_AUTH_IMAGE_MODULES="$(get_template_value "AC_AUTHSERVER_IMAGE_MODULES")"
readonly DEFAULT_WORLD_IMAGE_MODULES="$(get_template_value "AC_WORLDSERVER_IMAGE_MODULES")"
# Database names
readonly DEFAULT_DB_AUTH_NAME="$(get_template_value "DB_AUTH_NAME")"
readonly DEFAULT_DB_WORLD_NAME="$(get_template_value "DB_WORLD_NAME")"
readonly DEFAULT_DB_CHARACTERS_NAME="$(get_template_value "DB_CHARACTERS_NAME")"
readonly DEFAULT_DB_PLAYERBOTS_NAME="$(get_template_value "DB_PLAYERBOTS_NAME")"
# Container names
readonly DEFAULT_CONTAINER_MYSQL="$(get_template_value "CONTAINER_MYSQL")"
readonly DEFAULT_COMPOSE_PROJECT_NAME="$(get_template_value "COMPOSE_PROJECT_NAME")"
readonly DEFAULT_CLIENT_DATA_VOLUME="$(get_template_value "CLIENT_DATA_VOLUME")"
# Version constants
readonly DEFAULT_CLIENT_DATA_VERSION="$(get_template_value "CLIENT_DATA_VERSION")"
# Network configuration
readonly DEFAULT_NETWORK_NAME="$(get_template_value "NETWORK_NAME")"
readonly DEFAULT_NETWORK_SUBNET="$(get_template_value "NETWORK_SUBNET")"
readonly DEFAULT_NETWORK_GATEWAY="$(get_template_value "NETWORK_GATEWAY")"
# MySQL configuration
readonly DEFAULT_MYSQL_CHARACTER_SET="$(get_template_value "MYSQL_CHARACTER_SET")"
readonly DEFAULT_MYSQL_COLLATION="$(get_template_value "MYSQL_COLLATION")"
readonly DEFAULT_MYSQL_MAX_CONNECTIONS="$(get_template_value "MYSQL_MAX_CONNECTIONS")"
readonly DEFAULT_MYSQL_INNODB_BUFFER_POOL_SIZE="$(get_template_value "MYSQL_INNODB_BUFFER_POOL_SIZE")"
readonly DEFAULT_MYSQL_INNODB_LOG_FILE_SIZE="$(get_template_value "MYSQL_INNODB_LOG_FILE_SIZE")"
readonly DEFAULT_MYSQL_INNODB_REDO_LOG_CAPACITY="$(get_template_value "MYSQL_INNODB_REDO_LOG_CAPACITY")"
readonly DEFAULT_MYSQL_RUNTIME_TMPFS_SIZE="$(get_template_value "MYSQL_RUNTIME_TMPFS_SIZE")"
# Paths
readonly DEFAULT_HOST_ZONEINFO_PATH="$(get_template_value "HOST_ZONEINFO_PATH")"
readonly DEFAULT_ELUNA_SCRIPT_PATH="$(get_template_value "AC_ELUNA_SCRIPT_PATH")"
# Tool configuration
readonly DEFAULT_PMA_EXTERNAL_PORT="$(get_template_value "PMA_EXTERNAL_PORT")"
readonly DEFAULT_PMA_UPLOAD_LIMIT="$(get_template_value "PMA_UPLOAD_LIMIT")"
readonly DEFAULT_PMA_MEMORY_LIMIT="$(get_template_value "PMA_MEMORY_LIMIT")"
readonly DEFAULT_PMA_MAX_EXECUTION_TIME="$(get_template_value "PMA_MAX_EXECUTION_TIME")"
readonly DEFAULT_KEIRA3_EXTERNAL_PORT="$(get_template_value "KEIRA3_EXTERNAL_PORT")"
readonly DEFAULT_PMA_USER="$(get_template_value "PMA_USER")"
readonly DEFAULT_PMA_ARBITRARY="$(get_template_value "PMA_ARBITRARY")"
readonly DEFAULT_PMA_ABSOLUTE_URI="$(get_template_value "PMA_ABSOLUTE_URI")"
# Module preset names (not in template)
readonly DEFAULT_PRESET_SUGGESTED="suggested-modules"
readonly DEFAULT_PRESET_PLAYERBOTS="playerbots-suggested-modules"
# Internal ports
readonly DEFAULT_AUTH_INTERNAL_PORT="$(get_template_value "AUTH_PORT")"
readonly DEFAULT_WORLD_INTERNAL_PORT="$(get_template_value "WORLD_PORT")"
readonly DEFAULT_SOAP_INTERNAL_PORT="$(get_template_value "SOAP_PORT")"
readonly DEFAULT_MYSQL_INTERNAL_PORT="$(get_template_value "MYSQL_PORT")"
# System configuration
readonly DEFAULT_TZ="$(get_template_value "TZ")"
readonly DEFAULT_MYSQL_ROOT_HOST="$(get_template_value "MYSQL_ROOT_HOST")"
readonly DEFAULT_MYSQL_USER="$(get_template_value "MYSQL_USER")"
# Eluna configuration
readonly DEFAULT_ELUNA_ENABLED="$(get_template_value "AC_ELUNA_ENABLED")"
readonly DEFAULT_ELUNA_TRACE_BACK="$(get_template_value "AC_ELUNA_TRACE_BACK")"
readonly DEFAULT_ELUNA_AUTO_RELOAD="$(get_template_value "AC_ELUNA_AUTO_RELOAD")"
readonly DEFAULT_ELUNA_BYTECODE_CACHE="$(get_template_value "AC_ELUNA_BYTECODE_CACHE")"
readonly DEFAULT_ELUNA_AUTO_RELOAD_INTERVAL="$(get_template_value "AC_ELUNA_AUTO_RELOAD_INTERVAL")"
readonly DEFAULT_ELUNA_REQUIRE_PATHS="$(get_template_value "AC_ELUNA_REQUIRE_PATHS")"
readonly DEFAULT_ELUNA_REQUIRE_CPATHS="$(get_template_value "AC_ELUNA_REQUIRE_CPATHS")"
# Route detection IP (not in template)
readonly ROUTE_DETECTION_IP="1.1.1.1"
RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'; BLUE='\033[0;34m'; MAGENTA='\033[0;35m'; NC='\033[0m'
say(){ local t=$1; shift; case "$t" in
INFO) echo -e "${BLUE} $*${NC}";;
@@ -19,8 +160,6 @@ validate_ip(){ [[ $1 =~ ^[0-9]{1,3}(\.[0-9]{1,3}){3}$ ]]; }
validate_port(){ [[ $1 =~ ^[0-9]+$ ]] && [ $1 -ge 1 ] && [ $1 -le 65535 ]; }
validate_number(){ [[ $1 =~ ^[0-9]+$ ]]; }
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
NON_INTERACTIVE=0
ask(){
@@ -92,62 +231,6 @@ normalize_module_name(){
declare -A MODULE_ENABLE_SET=()
declare -a COMPOSE_CMD=()
resolve_compose_command(){
if [ ${#COMPOSE_CMD[@]} -gt 0 ]; then
return 0
fi
if command -v docker >/dev/null 2>&1; then
if docker compose version >/dev/null 2>&1; then
COMPOSE_CMD=(docker compose)
return 0
fi
fi
if command -v docker-compose >/dev/null 2>&1; then
COMPOSE_CMD=(docker-compose)
return 0
fi
COMPOSE_CMD=()
return 1
}
modules_directory_has_content(){
local dir="$1"
[ -d "$dir" ] || return 1
local first_entry
first_entry="$(find "$dir" -mindepth 1 -maxdepth 1 -type d -print -quit 2>/dev/null)"
[ -n "$first_entry" ]
}
ensure_modules_staged(){
local storage_abs="$1" needs_cxx="$2" run_now="$3"
if [ "$needs_cxx" != "1" ] || [ "$run_now" != "1" ]; then
return 0
fi
local modules_dir="${storage_abs}/modules"
local config_dir="${storage_abs}/config"
mkdir -p "$modules_dir" "$config_dir"
if modules_directory_has_content "$modules_dir"; then
return 0
fi
if ! resolve_compose_command; then
say WARNING "Docker Compose not detected; skipping automatic module staging."
return 1
fi
say INFO "Staging module repositories via ${COMPOSE_CMD[*]} run --rm --no-deps ac-modules"
if ! "${COMPOSE_CMD[@]}" --profile modules run --rm --no-deps ac-modules; then
say WARNING "Module staging failed; repositories may be incomplete."
return 1
fi
return 0
}
KNOWN_MODULE_VARS=(
MODULE_PLAYERBOTS
MODULE_AOE_LOOT
@@ -221,11 +304,11 @@ apply_module_preset(){
done
}
DEFAULT_PRESET_SUGGESTED="suggested-modules"
DEFAULT_PRESET_PLAYERBOTS="playerbots-suggested-modules"
show_wow_header() {
clear
if [ -t 1 ] && command -v clear >/dev/null 2>&1; then
clear >/dev/null 2>&1 || true
fi
echo -e "${RED}"
cat <<'EOF'
@@ -562,20 +645,20 @@ fi
if [ -n "$CLI_SERVER_ADDRESS" ]; then
SERVER_ADDRESS="$CLI_SERVER_ADDRESS"
elif [ "$DEPLOYMENT_TYPE" = "local" ]; then
SERVER_ADDRESS=127.0.0.1
SERVER_ADDRESS=$DEFAULT_LOCAL_ADDRESS
elif [ "$DEPLOYMENT_TYPE" = "lan" ]; then
local LAN_IP
LAN_IP=$(ip route get 1.1.1.1 2>/dev/null | awk 'NR==1{print $7}')
SERVER_ADDRESS=$(ask "Enter server IP address" "${CLI_SERVER_ADDRESS:-${LAN_IP:-192.168.1.100}}" validate_ip)
LAN_IP=$(ip route get $ROUTE_DETECTION_IP 2>/dev/null | awk 'NR==1{print $7}')
SERVER_ADDRESS=$(ask "Enter server IP address" "${CLI_SERVER_ADDRESS:-${LAN_IP:-$DEFAULT_FALLBACK_LAN_IP}}" validate_ip)
else
SERVER_ADDRESS=$(ask "Enter server address (IP or domain)" "${CLI_SERVER_ADDRESS:-your-domain.com}" )
SERVER_ADDRESS=$(ask "Enter server address (IP or domain)" "${CLI_SERVER_ADDRESS:-$DEFAULT_DOMAIN_PLACEHOLDER}" )
fi
local REALM_PORT AUTH_EXTERNAL_PORT SOAP_EXTERNAL_PORT MYSQL_EXTERNAL_PORT
REALM_PORT=$(ask "Enter client connection port" "${CLI_REALM_PORT:-8215}" validate_port)
AUTH_EXTERNAL_PORT=$(ask "Enter auth server port" "${CLI_AUTH_PORT:-3784}" validate_port)
SOAP_EXTERNAL_PORT=$(ask "Enter SOAP API port" "${CLI_SOAP_PORT:-7778}" validate_port)
MYSQL_EXTERNAL_PORT=$(ask "Enter MySQL external port" "${CLI_MYSQL_PORT:-64306}" validate_port)
REALM_PORT=$(ask "Enter client connection port" "${CLI_REALM_PORT:-$DEFAULT_REALM_PORT}" validate_port)
AUTH_EXTERNAL_PORT=$(ask "Enter auth server port" "${CLI_AUTH_PORT:-$DEFAULT_AUTH_PORT}" validate_port)
SOAP_EXTERNAL_PORT=$(ask "Enter SOAP API port" "${CLI_SOAP_PORT:-$DEFAULT_SOAP_PORT}" validate_port)
MYSQL_EXTERNAL_PORT=$(ask "Enter MySQL external port" "${CLI_MYSQL_PORT:-$DEFAULT_MYSQL_PORT}" validate_port)
# Permission scheme
say HEADER "PERMISSION SCHEME"
@@ -594,17 +677,17 @@ fi
fi
case "${PERMISSION_SCHEME_INPUT,,}" in
1|local)
CONTAINER_USER="0:0"
CONTAINER_USER="$PERMISSION_LOCAL_USER"
PERMISSION_SCHEME_NAME="local"
;;
2|nfs)
CONTAINER_USER="1001:1000"
CONTAINER_USER="$PERMISSION_NFS_USER"
PERMISSION_SCHEME_NAME="nfs"
;;
3|custom)
local uid gid
uid="${CLI_CUSTOM_UID:-$(ask "Enter PUID (user id)" 1000 validate_number)}"
gid="${CLI_CUSTOM_GID:-$(ask "Enter PGID (group id)" 1000 validate_number)}"
uid="${CLI_CUSTOM_UID:-$(ask "Enter PUID (user id)" $DEFAULT_CUSTOM_UID validate_number)}"
gid="${CLI_CUSTOM_GID:-$(ask "Enter PGID (group id)" $DEFAULT_CUSTOM_GID validate_number)}"
CONTAINER_USER="${uid}:${gid}"
PERMISSION_SCHEME_NAME="custom"
;;
@@ -625,7 +708,7 @@ fi
fi
# DB config
say HEADER "DATABASE CONFIGURATION"
local MYSQL_ROOT_PASSWORD; MYSQL_ROOT_PASSWORD=$(ask "Enter MySQL root password" "${CLI_MYSQL_PASSWORD:-azerothcore123}")
local MYSQL_ROOT_PASSWORD; MYSQL_ROOT_PASSWORD=$(ask "Enter MySQL root password" "${CLI_MYSQL_PASSWORD:-$DEFAULT_MYSQL_PASSWORD}")
# Storage
say HEADER "STORAGE CONFIGURATION"
@@ -633,10 +716,10 @@ fi
if [ -n "$CLI_STORAGE_PATH" ]; then
STORAGE_PATH="$CLI_STORAGE_PATH"
elif [ "$DEPLOYMENT_TYPE" = "local" ]; then
STORAGE_PATH=./storage
STORAGE_PATH=$DEFAULT_LOCAL_STORAGE
else
if [ "$NON_INTERACTIVE" = "1" ]; then
STORAGE_PATH=/mnt/azerothcore-data
STORAGE_PATH=$DEFAULT_MOUNT_STORAGE
else
echo "1) 💾 ./storage (local)"
echo "2) 🌐 /nfs/azerothcore (NFS)"
@@ -644,9 +727,9 @@ fi
while true; do
read -p "$(echo -e "${YELLOW}🔧 Select storage option [1-3]: ${NC}")" s
case "$s" in
1) STORAGE_PATH=./storage; break;;
2) STORAGE_PATH=/nfs/azerothcore; break;;
3) STORAGE_PATH=$(ask "Enter custom storage path" "/mnt/azerothcore-data"); break;;
1) STORAGE_PATH=$DEFAULT_LOCAL_STORAGE; break;;
2) STORAGE_PATH=$DEFAULT_NFS_STORAGE; break;;
3) STORAGE_PATH=$(ask "Enter custom storage path" "$DEFAULT_MOUNT_STORAGE"); break;;
*) say ERROR "Please select 1, 2, or 3";;
esac
done
@@ -656,11 +739,11 @@ fi
# Backup
say HEADER "BACKUP CONFIGURATION"
local BACKUP_RETENTION_DAYS BACKUP_RETENTION_HOURS BACKUP_DAILY_TIME
BACKUP_RETENTION_DAYS=$(ask "Daily backups retention (days)" "${CLI_BACKUP_DAYS:-3}" validate_number)
BACKUP_RETENTION_HOURS=$(ask "Hourly backups retention (hours)" "${CLI_BACKUP_HOURS:-6}" validate_number)
BACKUP_DAILY_TIME=$(ask "Daily backup hour (00-23, UTC)" "${CLI_BACKUP_TIME:-09}" validate_number)
BACKUP_RETENTION_DAYS=$(ask "Daily backups retention (days)" "${CLI_BACKUP_DAYS:-$DEFAULT_BACKUP_DAYS}" validate_number)
BACKUP_RETENTION_HOURS=$(ask "Hourly backups retention (hours)" "${CLI_BACKUP_HOURS:-$DEFAULT_BACKUP_HOURS}" validate_number)
BACKUP_DAILY_TIME=$(ask "Daily backup hour (00-23, UTC)" "${CLI_BACKUP_TIME:-$DEFAULT_BACKUP_TIME}" validate_number)
local MODE=""
local MODE_SELECTION=""
local MODE_PRESET_NAME=""
declare -A MODULE_PRESET_CONFIGS=()
declare -a MODULE_PRESET_ORDER=()
@@ -690,7 +773,7 @@ fi
if [ -n "$CLI_MODULE_PRESET" ]; then
if [ -n "${MODULE_PRESET_CONFIGS[$CLI_MODULE_PRESET]:-}" ]; then
MODE="preset"
MODE_SELECTION="preset"
MODE_PRESET_NAME="$CLI_MODULE_PRESET"
else
say ERROR "Unknown module preset: $CLI_MODULE_PRESET"
@@ -698,39 +781,38 @@ fi
fi
fi
if [ -n "$MODE" ] && [ "$MODE" != "preset" ]; then
if [ -n "$MODE_SELECTION" ] && [ "$MODE_SELECTION" != "preset" ]; then
MODE_PRESET_NAME=""
fi
if [ -n "$CLI_MODULE_MODE" ]; then
case "${CLI_MODULE_MODE,,}" in
1|suggested) MODE=1 ;;
2|playerbots) MODE=2 ;;
3|manual) MODE=3 ;;
4|none) MODE=4 ;;
1|suggested) MODE_SELECTION=1 ;;
2|playerbots) MODE_SELECTION=2 ;;
3|manual) MODE_SELECTION=3 ;;
4|none) MODE_SELECTION=4 ;;
*) say ERROR "Invalid module mode: ${CLI_MODULE_MODE}"; exit 1 ;;
esac
if [ "$MODE" = "1" ]; then
if [ "$MODE_SELECTION" = "1" ]; then
MODE_PRESET_NAME="$DEFAULT_PRESET_SUGGESTED"
elif [ "$MODE" = "2" ]; then
elif [ "$MODE_SELECTION" = "2" ]; then
MODE_PRESET_NAME="$DEFAULT_PRESET_PLAYERBOTS"
fi
fi
if [ -z "$MODE" ] && [ ${#MODULE_ENABLE_SET[@]} -gt 0 ]; then
MODE=3
if [ -z "$MODE_SELECTION" ] && [ ${#MODULE_ENABLE_SET[@]} -gt 0 ]; then
MODE_SELECTION=3
fi
if [ ${#MODULE_ENABLE_SET[@]} -gt 0 ] && [ -n "$MODE" ] && [ "$MODE" != "3" ] && [ "$MODE" != "4" ]; then
if [ ${#MODULE_ENABLE_SET[@]} -gt 0 ] && [ -n "$MODE_SELECTION" ] && [ "$MODE_SELECTION" != "3" ] && [ "$MODE_SELECTION" != "4" ]; then
say INFO "Switching module preset to manual to honor --enable-modules list."
MODE=3
MODE_SELECTION=3
fi
if [ "$MODE" = "4" ] && [ ${#MODULE_ENABLE_SET[@]} -gt 0 ]; then
if [ "$MODE_SELECTION" = "4" ] && [ ${#MODULE_ENABLE_SET[@]} -gt 0 ]; then
say ERROR "--enable-modules cannot be used together with module-mode=none."
exit 1
fi
local MODE_PRESET_NAME=""
if [ "$MODE" = "preset" ] && [ -n "$CLI_MODULE_PRESET" ]; then
if [ "$MODE_SELECTION" = "preset" ] && [ -n "$CLI_MODULE_PRESET" ]; then
MODE_PRESET_NAME="$CLI_MODULE_PRESET"
fi
@@ -757,30 +839,30 @@ fi
fi
local max_option=$((menu_index - 1))
if [ "$NON_INTERACTIVE" = "1" ] && [ -z "$MODE" ]; then
MODE=1
if [ "$NON_INTERACTIVE" = "1" ] && [ -z "$MODE_SELECTION" ]; then
MODE_SELECTION=1
fi
if [ -z "$MODE" ]; then
local MODE_SELECTION
if [ -z "$MODE_SELECTION" ]; then
local selection_input
while true; do
read -p "$(echo -e "${YELLOW}🔧 Select module configuration [1-${max_option}]: ${NC}")" MODE_SELECTION
if [[ "$MODE_SELECTION" =~ ^[0-9]+$ ]] && [ "$MODE_SELECTION" -ge 1 ] && [ "$MODE_SELECTION" -le "$max_option" ]; then
if [ -n "${MENU_PRESET_INDEX[$MODE_SELECTION]:-}" ]; then
MODE="preset"
MODE_PRESET_NAME="${MENU_PRESET_INDEX[$MODE_SELECTION]}"
read -p "$(echo -e "${YELLOW}🔧 Select module configuration [1-${max_option}]: ${NC}")" selection_input
if [[ "$selection_input" =~ ^[0-9]+$ ]] && [ "$selection_input" -ge 1 ] && [ "$selection_input" -le "$max_option" ]; then
if [ -n "${MENU_PRESET_INDEX[$selection_input]:-}" ]; then
MODE_SELECTION="preset"
MODE_PRESET_NAME="${MENU_PRESET_INDEX[$selection_input]}"
else
MODE="$MODE_SELECTION"
MODE_SELECTION="$selection_input"
fi
break
fi
say ERROR "Please select a number between 1 and ${max_option}"
done
else
if [ "$MODE" = "preset" ]; then
if [ "$MODE_SELECTION" = "preset" ]; then
say INFO "Module preset set to ${MODE_PRESET_NAME}."
else
say INFO "Module preset set to ${MODE}."
say INFO "Module preset set to ${MODE_SELECTION}."
fi
fi
@@ -793,10 +875,10 @@ fi
MODULE_INSTANCE_RESET=0 MODULE_LEVEL_GRANT=0 MODULE_ASSISTANT=0 MODULE_REAGENT_BANK=0 MODULE_BLACK_MARKET_AUCTION_HOUSE=0 MODULE_ARAC=0 \
MODULE_CHALLENGE_MODES=0 MODULE_OLLAMA_CHAT=0 MODULE_SKELETON_MODULE=0 MODULE_BG_SLAVERYVALLEY=0 MODULE_ELUNA_TS=0 \
MODULE_PLAYER_BOT_LEVEL_BRACKETS=0 MODULE_STATBOOSTER=0 MODULE_DUNGEON_RESPAWN=0 MODULE_AZEROTHSHARD=0 MODULE_WORGOBLIN=0
local DEFAULT_AUTH_IMAGE_PLAYERBOTS="uprightbass360/azerothcore-wotlk-playerbots:authserver-Playerbot"
local DEFAULT_WORLD_IMAGE_PLAYERBOTS="uprightbass360/azerothcore-wotlk-playerbots:worldserver-Playerbot"
local AC_AUTHSERVER_IMAGE_PLAYERBOTS_VALUE="$DEFAULT_AUTH_IMAGE_PLAYERBOTS"
local AC_WORLDSERVER_IMAGE_PLAYERBOTS_VALUE="$DEFAULT_WORLD_IMAGE_PLAYERBOTS"
local AC_AUTHSERVER_IMAGE_MODULES_VALUE="$DEFAULT_AUTH_IMAGE_MODULES"
local AC_WORLDSERVER_IMAGE_MODULES_VALUE="$DEFAULT_WORLD_IMAGE_MODULES"
local mod_var
for mod_var in "${!MODULE_ENABLE_SET[@]}"; do
@@ -825,13 +907,16 @@ fi
local RUN_REBUILD_NOW=$CLI_RUN_REBUILD
local NEEDS_CXX_REBUILD=0
if [ "$MODE" = "1" ]; then
local module_mode_label=""
if [ "$MODE_SELECTION" = "1" ]; then
MODE_PRESET_NAME="$DEFAULT_PRESET_SUGGESTED"
apply_module_preset "${MODULE_PRESET_CONFIGS[$DEFAULT_PRESET_SUGGESTED]}"
elif [ "$MODE" = "2" ]; then
module_mode_label="preset 1 (Suggested)"
elif [ "$MODE_SELECTION" = "2" ]; then
MODE_PRESET_NAME="$DEFAULT_PRESET_PLAYERBOTS"
apply_module_preset "${MODULE_PRESET_CONFIGS[$DEFAULT_PRESET_PLAYERBOTS]}"
elif [ "$MODE" = "3" ]; then
module_mode_label="preset 2 (Playerbots + Suggested)"
elif [ "$MODE_SELECTION" = "3" ]; then
MODE_PRESET_NAME=""
say INFO "Answer y/n for each module"
for key in "${!DISABLED_MODULE_REASONS[@]}"; do
@@ -884,7 +969,10 @@ fi
MODULE_GAIN_HONOR_GUARD=$(ask_yn "Gain Honor Guard - Honor from guard kills" "$(module_default MODULE_GAIN_HONOR_GUARD)")
MODULE_ARAC=$(ask_yn "All Races All Classes (requires client patch)" "$(module_default MODULE_ARAC)")
MODULE_WORGOBLIN=$(ask_yn "Worgoblin - Worgen & Goblin races (client patch required)" "$(module_default MODULE_WORGOBLIN)")
elif [ "$MODE" = "preset" ]; then
module_mode_label="preset 3 (Manual)"
elif [ "$MODE_SELECTION" = "4" ]; then
module_mode_label="preset 4 (No modules)"
elif [ "$MODE_SELECTION" = "preset" ]; then
local preset_modules="${MODULE_PRESET_CONFIGS[$MODE_PRESET_NAME]}"
if [ -n "$preset_modules" ]; then
apply_module_preset "$preset_modules"
@@ -892,6 +980,7 @@ fi
else
say WARNING "Preset '${MODE_PRESET_NAME}' did not contain any module selections."
fi
module_mode_label="preset (${MODE_PRESET_NAME})"
fi
if [ -n "$CLI_PLAYERBOT_ENABLED" ]; then
@@ -913,7 +1002,7 @@ fi
if [ -z "$CLI_PLAYERBOT_ENABLED" ]; then
PLAYERBOT_ENABLED=1
fi
PLAYERBOT_MAX_BOTS=$(ask "Maximum concurrent playerbots" "${CLI_PLAYERBOT_MAX:-40}" validate_number)
PLAYERBOT_MAX_BOTS=$(ask "Maximum concurrent playerbots" "${CLI_PLAYERBOT_MAX:-$DEFAULT_PLAYERBOT_MAX}" validate_number)
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_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 MODULE_PLAYER_BOT_LEVEL_BRACKETS MODULE_OLLAMA_CHAT MODULE_CHALLENGE_MODES MODULE_STATBOOSTER MODULE_DUNGEON_RESPAWN MODULE_SKELETON_MODULE MODULE_BG_SLAVERYVALLEY MODULE_AZEROTHSHARD MODULE_WORGOBLIN; do
@@ -924,20 +1013,17 @@ fi
fi
done
export NEEDS_CXX_REBUILD
if [ "$MODULE_PLAYERBOTS" = "1" ]; then
AC_AUTHSERVER_IMAGE_PLAYERBOTS_VALUE="$DEFAULT_AUTH_IMAGE_PLAYERBOTS"
AC_WORLDSERVER_IMAGE_PLAYERBOTS_VALUE="$DEFAULT_WORLD_IMAGE_PLAYERBOTS"
fi
local SUMMARY_MODE_TEXT
case "$MODE" in
1) SUMMARY_MODE_TEXT="preset 1 (Suggested)" ;;
2) SUMMARY_MODE_TEXT="preset 2 (Playerbots + Suggested)" ;;
3) SUMMARY_MODE_TEXT="preset 3 (Manual)" ;;
4) SUMMARY_MODE_TEXT="preset 4 (No modules)" ;;
preset) SUMMARY_MODE_TEXT="preset (${MODE_PRESET_NAME})" ;;
*) SUMMARY_MODE_TEXT="$MODE" ;;
esac
local SUMMARY_MODE_TEXT="$module_mode_label"
if [ -z "$SUMMARY_MODE_TEXT" ]; then
SUMMARY_MODE_TEXT="$MODE_SELECTION"
fi
# Summary
say HEADER "SUMMARY"
@@ -946,6 +1032,8 @@ fi
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 %s\n" "Source checkout:" "$default_source_rel"
printf " %-18s %s\n" "Modules images:" "$AC_AUTHSERVER_IMAGE_MODULES_VALUE | $AC_WORLDSERVER_IMAGE_MODULES_VALUE"
printf " %-18s %s\n" "Modules preset:" "$SUMMARY_MODE_TEXT"
printf " %-18s %s\n" "Playerbot Max Bots:" "$PLAYERBOT_MAX_BOTS"
@@ -1007,7 +1095,7 @@ fi
fi
local default_source_rel="${LOCAL_STORAGE_ROOT}/source/azerothcore"
if [ "$MODULE_PLAYERBOTS" = "1" ]; then
if [ "$NEEDS_CXX_REBUILD" = "1" ] || [ "$MODULE_PLAYERBOTS" = "1" ]; then
default_source_rel="${LOCAL_STORAGE_ROOT}/source/azerothcore-playerbots"
fi
@@ -1034,8 +1122,10 @@ fi
MODULES_REBUILD_SOURCE_PATH_VALUE="$rebuild_source_path"
export MODULES_REBUILD_SOURCE_PATH="$MODULES_REBUILD_SOURCE_PATH_VALUE"
if [ ! -f "$rebuild_source_path/docker-compose.yml" ]; then
say INFO "Preparing source repository via scripts/setup-source.sh (git clone/fetch can take a few minutes)"
if ! ./scripts/setup-source.sh >/dev/null 2>&1; then
say INFO "Preparing source repository via scripts/setup-source.sh (progress will stream below)"
if ! ( set -o pipefail; ./scripts/setup-source.sh 2>&1 | while IFS= read -r line; do
say INFO "[setup-source] $line"
done ); then
say WARNING "Source setup encountered issues; running interactively."
if ! ./scripts/setup-source.sh; then
say WARNING "Source setup failed; skipping automatic rebuild."
@@ -1056,9 +1146,19 @@ fi
export "$module_export_var"
done
# Set git config for module script
git config --global user.name "${GIT_USERNAME:-ac-compose}" 2>/dev/null || true
git config --global user.email "${GIT_EMAIL:-noreply@azerothcore.org}" 2>/dev/null || true
# Prepare isolated git config for the module script so we do not mutate user-level settings
local prev_git_config_global="${GIT_CONFIG_GLOBAL:-}"
local git_temp_config=""
if command -v mktemp >/dev/null 2>&1; then
if ! git_temp_config="$(mktemp)"; then
git_temp_config=""
fi
fi
if [ -z "$git_temp_config" ]; then
git_temp_config="$local_modules_dir/.gitconfig.tmp"
: > "$git_temp_config"
fi
export GIT_CONFIG_GLOBAL="$git_temp_config"
# Run module staging script in local modules directory
# Set environment variable to indicate we're running locally
@@ -1069,12 +1169,15 @@ fi
say WARNING "Module staging encountered issues, but continuing with rebuild"
fi
unset MODULES_LOCAL_RUN
fi
fi
if [ "$RUN_REBUILD_NOW" = "1" ]; then
if ! ./scripts/rebuild-with-modules.sh --yes --skip-stop; then
say WARNING "Module rebuild failed; run ./scripts/rebuild-with-modules.sh manually."
if [ -n "$git_temp_config" ]; then
rm -f "$git_temp_config"
fi
if [ -n "$prev_git_config_global" ]; then
export GIT_CONFIG_GLOBAL="$prev_git_config_global"
else
unset GIT_CONFIG_GLOBAL
fi
fi
fi
@@ -1096,63 +1199,65 @@ fi
MODULES_REBUILD_SOURCE_PATH_VALUE="$default_source_rel"
fi
DB_PLAYERBOTS_NAME=${DB_PLAYERBOTS_NAME:-acore_playerbots}
DB_PLAYERBOTS_NAME=${DB_PLAYERBOTS_NAME:-$DEFAULT_DB_PLAYERBOTS_NAME}
local CLIENT_DATA_CACHE_PATH_VALUE="${LOCAL_STORAGE_ROOT}/client-data-cache"
HOST_ZONEINFO_PATH=${HOST_ZONEINFO_PATH:-/usr/share/zoneinfo}
MYSQL_INNODB_REDO_LOG_CAPACITY=${MYSQL_INNODB_REDO_LOG_CAPACITY:-512M}
MYSQL_RUNTIME_TMPFS_SIZE=${MYSQL_RUNTIME_TMPFS_SIZE:-8G}
CLIENT_DATA_VOLUME=${CLIENT_DATA_VOLUME:-ac-client-data}
HOST_ZONEINFO_PATH=${HOST_ZONEINFO_PATH:-$DEFAULT_HOST_ZONEINFO_PATH}
MYSQL_INNODB_REDO_LOG_CAPACITY=${MYSQL_INNODB_REDO_LOG_CAPACITY:-$DEFAULT_MYSQL_INNODB_REDO_LOG_CAPACITY}
MYSQL_RUNTIME_TMPFS_SIZE=${MYSQL_RUNTIME_TMPFS_SIZE:-$DEFAULT_MYSQL_RUNTIME_TMPFS_SIZE}
CLIENT_DATA_VOLUME=${CLIENT_DATA_VOLUME:-$DEFAULT_CLIENT_DATA_VOLUME}
cat > "$ENV_OUT" <<EOF
# Generated by ac-compose/setup.sh
COMPOSE_PROJECT_NAME=ac-compose
COMPOSE_PROJECT_NAME=$DEFAULT_COMPOSE_PROJECT_NAME
STORAGE_PATH=$STORAGE_PATH
STORAGE_PATH_LOCAL=$LOCAL_STORAGE_ROOT
HOST_ZONEINFO_PATH=$HOST_ZONEINFO_PATH
TZ=UTC
HOST_ZONEINFO_PATH=${HOST_ZONEINFO_PATH:-$DEFAULT_HOST_ZONEINFO_PATH}
TZ=$DEFAULT_TZ
# Database
MYSQL_IMAGE=mysql:8.0
CONTAINER_MYSQL=ac-mysql
MYSQL_IMAGE=$DEFAULT_MYSQL_IMAGE
CONTAINER_MYSQL=$DEFAULT_CONTAINER_MYSQL
MYSQL_ROOT_PASSWORD=$MYSQL_ROOT_PASSWORD
MYSQL_ROOT_HOST=%
MYSQL_USER=root
MYSQL_PORT=3306
MYSQL_ROOT_HOST=$DEFAULT_MYSQL_ROOT_HOST
MYSQL_USER=$DEFAULT_MYSQL_USER
MYSQL_PORT=$DEFAULT_MYSQL_INTERNAL_PORT
MYSQL_EXTERNAL_PORT=$MYSQL_EXTERNAL_PORT
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
MYSQL_INNODB_REDO_LOG_CAPACITY=$MYSQL_INNODB_REDO_LOG_CAPACITY
MYSQL_RUNTIME_TMPFS_SIZE=$MYSQL_RUNTIME_TMPFS_SIZE
DB_AUTH_NAME=acore_auth
DB_WORLD_NAME=acore_world
DB_CHARACTERS_NAME=acore_characters
DB_PLAYERBOTS_NAME=$DB_PLAYERBOTS_NAME
AC_DB_IMPORT_IMAGE=acore/ac-wotlk-db-import:14.0.0-dev
MYSQL_CHARACTER_SET=$DEFAULT_MYSQL_CHARACTER_SET
MYSQL_COLLATION=$DEFAULT_MYSQL_COLLATION
MYSQL_MAX_CONNECTIONS=$DEFAULT_MYSQL_MAX_CONNECTIONS
MYSQL_INNODB_BUFFER_POOL_SIZE=$DEFAULT_MYSQL_INNODB_BUFFER_POOL_SIZE
MYSQL_INNODB_LOG_FILE_SIZE=$DEFAULT_MYSQL_INNODB_LOG_FILE_SIZE
MYSQL_INNODB_REDO_LOG_CAPACITY=${MYSQL_INNODB_REDO_LOG_CAPACITY:-$DEFAULT_MYSQL_INNODB_REDO_LOG_CAPACITY}
MYSQL_RUNTIME_TMPFS_SIZE=${MYSQL_RUNTIME_TMPFS_SIZE:-$DEFAULT_MYSQL_RUNTIME_TMPFS_SIZE}
DB_AUTH_NAME=$DEFAULT_DB_AUTH_NAME
DB_WORLD_NAME=$DEFAULT_DB_WORLD_NAME
DB_CHARACTERS_NAME=$DEFAULT_DB_CHARACTERS_NAME
DB_PLAYERBOTS_NAME=${DB_PLAYERBOTS_NAME:-$DEFAULT_DB_PLAYERBOTS_NAME}
AC_DB_IMPORT_IMAGE=$DEFAULT_AC_DB_IMPORT_IMAGE
# 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=$DEFAULT_AC_AUTHSERVER_IMAGE
AC_WORLDSERVER_IMAGE=$DEFAULT_AC_WORLDSERVER_IMAGE
AC_AUTHSERVER_IMAGE_PLAYERBOTS=${AC_AUTHSERVER_IMAGE_PLAYERBOTS_VALUE}
AC_WORLDSERVER_IMAGE_PLAYERBOTS=${AC_WORLDSERVER_IMAGE_PLAYERBOTS_VALUE}
AC_AUTHSERVER_IMAGE_MODULES=${AC_AUTHSERVER_IMAGE_MODULES_VALUE}
AC_WORLDSERVER_IMAGE_MODULES=${AC_WORLDSERVER_IMAGE_MODULES_VALUE}
# 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
AC_CLIENT_DATA_IMAGE=$DEFAULT_AC_CLIENT_DATA_IMAGE
AC_CLIENT_DATA_IMAGE_PLAYERBOTS=$DEFAULT_CLIENT_DATA_IMAGE_PLAYERBOTS
CLIENT_DATA_CACHE_PATH=$CLIENT_DATA_CACHE_PATH_VALUE
CLIENT_DATA_VOLUME=$CLIENT_DATA_VOLUME
CLIENT_DATA_VOLUME=${CLIENT_DATA_VOLUME:-$DEFAULT_CLIENT_DATA_VOLUME}
# Ports
AUTH_EXTERNAL_PORT=$AUTH_EXTERNAL_PORT
AUTH_PORT=3724
AUTH_PORT=$DEFAULT_AUTH_INTERNAL_PORT
WORLD_EXTERNAL_PORT=$REALM_PORT
WORLD_PORT=8085
WORLD_PORT=$DEFAULT_WORLD_INTERNAL_PORT
SOAP_EXTERNAL_PORT=$SOAP_EXTERNAL_PORT
SOAP_PORT=7878
SOAP_PORT=$DEFAULT_SOAP_INTERNAL_PORT
# Realm
SERVER_ADDRESS=$SERVER_ADDRESS
@@ -1210,7 +1315,7 @@ MODULE_REAGENT_BANK=$MODULE_REAGENT_BANK
MODULE_BLACK_MARKET_AUCTION_HOUSE=$MODULE_BLACK_MARKET_AUCTION_HOUSE
# Client data
CLIENT_DATA_VERSION=${CLIENT_DATA_VERSION:-v16}
CLIENT_DATA_VERSION=${CLIENT_DATA_VERSION:-$DEFAULT_CLIENT_DATA_VERSION}
# Playerbot runtime
PLAYERBOT_ENABLED=$PLAYERBOT_ENABLED
@@ -1221,33 +1326,33 @@ AUTO_REBUILD_ON_DEPLOY=$AUTO_REBUILD_ON_DEPLOY
MODULES_REBUILD_SOURCE_PATH=$MODULES_REBUILD_SOURCE_PATH_VALUE
# 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
AC_ELUNA_ENABLED=$DEFAULT_ELUNA_ENABLED
AC_ELUNA_TRACE_BACK=$DEFAULT_ELUNA_TRACE_BACK
AC_ELUNA_AUTO_RELOAD=$DEFAULT_ELUNA_AUTO_RELOAD
AC_ELUNA_BYTECODE_CACHE=$DEFAULT_ELUNA_BYTECODE_CACHE
AC_ELUNA_SCRIPT_PATH=$DEFAULT_ELUNA_SCRIPT_PATH
AC_ELUNA_REQUIRE_PATHS=$DEFAULT_ELUNA_REQUIRE_PATHS
AC_ELUNA_REQUIRE_CPATHS=$DEFAULT_ELUNA_REQUIRE_CPATHS
AC_ELUNA_AUTO_RELOAD_INTERVAL=$DEFAULT_ELUNA_AUTO_RELOAD_INTERVAL
# 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
PMA_HOST=$DEFAULT_CONTAINER_MYSQL
PMA_PORT=$DEFAULT_MYSQL_INTERNAL_PORT
PMA_USER=$DEFAULT_PMA_USER
PMA_EXTERNAL_PORT=$DEFAULT_PMA_EXTERNAL_PORT
PMA_ARBITRARY=$DEFAULT_PMA_ARBITRARY
PMA_ABSOLUTE_URI=$DEFAULT_PMA_ABSOLUTE_URI
PMA_UPLOAD_LIMIT=$DEFAULT_PMA_UPLOAD_LIMIT
PMA_MEMORY_LIMIT=$DEFAULT_PMA_MEMORY_LIMIT
PMA_MAX_EXECUTION_TIME=$DEFAULT_PMA_MAX_EXECUTION_TIME
KEIRA3_EXTERNAL_PORT=$DEFAULT_KEIRA3_EXTERNAL_PORT
KEIRA_DATABASE_HOST=$DEFAULT_CONTAINER_MYSQL
KEIRA_DATABASE_PORT=$DEFAULT_MYSQL_INTERNAL_PORT
# Networking
NETWORK_NAME=azerothcore
NETWORK_SUBNET=172.20.0.0/16
NETWORK_GATEWAY=172.20.0.1
NETWORK_NAME=$DEFAULT_NETWORK_NAME
NETWORK_SUBNET=$DEFAULT_NETWORK_SUBNET
NETWORK_GATEWAY=$DEFAULT_NETWORK_GATEWAY
EOF
say SUCCESS ".env written to $ENV_OUT"
@@ -1257,7 +1362,9 @@ EOF
echo ""
say HEADER "MODULE REBUILD"
if [ -n "$MODULES_REBUILD_SOURCE_PATH_VALUE" ]; then
if ./scripts/rebuild-with-modules.sh --yes --source "$MODULES_REBUILD_SOURCE_PATH_VALUE"; then
local rebuild_args=(--yes --skip-stop)
rebuild_args+=(--source "$MODULES_REBUILD_SOURCE_PATH_VALUE")
if ./scripts/rebuild-with-modules.sh "${rebuild_args[@]}"; then
say SUCCESS "Module rebuild completed"
else
say WARNING "Module rebuild failed; run ./scripts/rebuild-with-modules.sh manually once issues are resolved."