mirror of
https://github.com/uprightbass360/AzerothCore-RealmMaster.git
synced 2026-01-13 09:07:20 +00:00
adding module functionality and final setup
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1,3 +1,4 @@
|
||||
data/
|
||||
backups/
|
||||
local-data-tools/
|
||||
storage/
|
||||
|
||||
270
MODULE_MANAGEMENT.md
Normal file
270
MODULE_MANAGEMENT.md
Normal file
@@ -0,0 +1,270 @@
|
||||
# AzerothCore Module Management System
|
||||
|
||||
This document describes the automated module management system for AzerothCore Docker deployments.
|
||||
|
||||
## Overview
|
||||
|
||||
The module management system provides:
|
||||
- ✅ Automated Git-based module installation
|
||||
- ✅ Automatic database script execution (SQL imports)
|
||||
- ✅ Configuration file management (.conf.dist → .conf)
|
||||
- ✅ Module state tracking and rebuild detection
|
||||
- ✅ Comprehensive rebuild automation
|
||||
- ✅ Pre-compilation configuration analysis
|
||||
|
||||
## Architecture
|
||||
|
||||
### Components
|
||||
|
||||
1. **Module Manager Container** (`ac-modules`)
|
||||
- Handles module downloading, SQL execution, and state tracking
|
||||
- Runs as one-time setup during stack initialization
|
||||
- Monitors module configuration changes
|
||||
|
||||
2. **Rebuild Detection System**
|
||||
- Tracks module enable/disable state changes
|
||||
- Automatically detects when compilation is required
|
||||
- Provides detailed rebuild instructions
|
||||
|
||||
3. **Automated Rebuild Script** (`rebuild-with-modules.sh`)
|
||||
- Orchestrates full compilation workflow
|
||||
- Integrates with source-based Docker builds
|
||||
- Handles module synchronization
|
||||
|
||||
## Module Types
|
||||
|
||||
### Pre-built Compatible
|
||||
**None currently available** - All 28 analyzed modules require C++ compilation.
|
||||
|
||||
### Compilation Required
|
||||
All current modules require source-based compilation:
|
||||
- mod-playerbots (CRITICAL: Requires custom AzerothCore branch)
|
||||
- mod-aoe-loot
|
||||
- mod-learn-spells
|
||||
- mod-fireworks-on-level
|
||||
- mod-individual-progression (Auto-configures accounts)
|
||||
- All other modules...
|
||||
|
||||
## Configuration
|
||||
|
||||
### Environment Variables
|
||||
|
||||
Modules are controlled via environment variables in `docker-compose-azerothcore-services.env`:
|
||||
|
||||
```bash
|
||||
# Enable/disable modules (1 = enabled, 0 = disabled)
|
||||
MODULE_PLAYERBOTS=1
|
||||
MODULE_AOE_LOOT=1
|
||||
MODULE_LEARN_SPELLS=1
|
||||
# ... etc
|
||||
```
|
||||
|
||||
### Critical Module Requirements
|
||||
|
||||
#### mod-playerbots
|
||||
- **INCOMPATIBLE** with standard AzerothCore
|
||||
- Requires custom branch: `liyunfan1223/azerothcore-wotlk/tree/Playerbot`
|
||||
- Will not function with standard compilation
|
||||
|
||||
#### mod-individual-progression
|
||||
- Auto-configures new accounts for individual progression
|
||||
- Requires account creation after server setup
|
||||
|
||||
## Database Integration
|
||||
|
||||
### Automatic SQL Execution
|
||||
|
||||
The system automatically executes SQL scripts for enabled modules:
|
||||
|
||||
```bash
|
||||
# SQL execution locations searched:
|
||||
/modules/mod-name/data/sql/world/*.sql → acore_world database
|
||||
/modules/mod-name/data/sql/auth/*.sql → acore_auth database
|
||||
/modules/mod-name/data/sql/characters/*.sql → acore_characters database
|
||||
/modules/mod-name/data/sql/*.sql → acore_world database (fallback)
|
||||
/modules/mod-name/sql/*.sql → acore_world database (alternative)
|
||||
```
|
||||
|
||||
### Error Handling
|
||||
|
||||
- ✅ Uses proper MySQL client with SSL verification disabled
|
||||
- ✅ Implements exit code checking (not stderr redirection)
|
||||
- ✅ Provides detailed success/failure feedback
|
||||
- ✅ Continues processing if optional scripts fail
|
||||
|
||||
## Rebuild System
|
||||
|
||||
### Detection Logic
|
||||
|
||||
1. **Module State Tracking**
|
||||
- Creates hash of all module enable/disable states
|
||||
- Stores in `/modules/.modules_state`
|
||||
- Compares current vs previous state on each run
|
||||
|
||||
2. **Change Detection**
|
||||
```bash
|
||||
# First run
|
||||
📝 First run - establishing module state baseline
|
||||
|
||||
# No changes
|
||||
✅ No module changes detected
|
||||
|
||||
# Changes detected
|
||||
🔄 Module configuration has changed - rebuild required
|
||||
```
|
||||
|
||||
### Rebuild Requirements
|
||||
|
||||
When modules are enabled, the system provides:
|
||||
|
||||
```bash
|
||||
🚨 REBUILD REQUIRED 🚨
|
||||
Module configuration has changed. To integrate C++ modules into AzerothCore:
|
||||
|
||||
1. Stop current services:
|
||||
docker compose -f docker-compose-azerothcore-services.yml down
|
||||
|
||||
2. Build with source-based compilation:
|
||||
docker compose -f /tmp/acore-dev-test/docker-compose.yml build
|
||||
docker compose -f /tmp/acore-dev-test/docker-compose.yml up -d
|
||||
|
||||
3. Or use the automated rebuild script (if available):
|
||||
./rebuild-with-modules.sh
|
||||
```
|
||||
|
||||
### Automated Rebuild Script
|
||||
|
||||
The `rebuild-with-modules.sh` script provides:
|
||||
|
||||
1. **Pre-flight Checks**
|
||||
- Verifies source repository availability
|
||||
- Counts enabled modules
|
||||
- Confirms rebuild necessity
|
||||
|
||||
2. **Build Process**
|
||||
- Stops current services
|
||||
- Syncs modules to source build
|
||||
- Executes `docker compose build --no-cache`
|
||||
- Starts services with compiled modules
|
||||
|
||||
3. **Error Handling**
|
||||
- Build failure detection
|
||||
- Service startup verification
|
||||
- Detailed status reporting
|
||||
|
||||
## Usage Examples
|
||||
|
||||
### Enable New Module
|
||||
|
||||
1. Edit `docker-compose-azerothcore-services.env`:
|
||||
```bash
|
||||
MODULE_TRANSMOG=1
|
||||
```
|
||||
|
||||
2. Restart module manager:
|
||||
```bash
|
||||
docker compose -f docker-compose-azerothcore-services.yml up ac-modules
|
||||
```
|
||||
|
||||
3. Follow rebuild instructions or run:
|
||||
```bash
|
||||
./rebuild-with-modules.sh
|
||||
```
|
||||
|
||||
### Disable Module
|
||||
|
||||
1. Edit environment file:
|
||||
```bash
|
||||
MODULE_TRANSMOG=0
|
||||
```
|
||||
|
||||
2. Restart and rebuild (module code will be removed from compilation)
|
||||
|
||||
### Bulk Module Management
|
||||
|
||||
Enable multiple modules simultaneously:
|
||||
```bash
|
||||
# Edit .env file with multiple changes
|
||||
MODULE_AUTOBALANCE=1
|
||||
MODULE_TRANSMOG=1
|
||||
MODULE_SOLO_LFG=1
|
||||
|
||||
# Single rebuild handles all changes
|
||||
./rebuild-with-modules.sh
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Common Issues
|
||||
|
||||
1. **SQL Execution Failures**
|
||||
- Check MySQL container health
|
||||
- Verify database credentials
|
||||
- Review specific SQL script syntax
|
||||
|
||||
2. **Build Failures**
|
||||
- Ensure adequate disk space (>10GB recommended)
|
||||
- Check module compatibility
|
||||
- Review Docker build logs
|
||||
|
||||
3. **Module Not Loading**
|
||||
- Verify module appears in compilation output
|
||||
- Check worldserver logs for load errors
|
||||
- Confirm configuration files copied correctly
|
||||
|
||||
### Performance Considerations
|
||||
|
||||
- **Build Time**: 15-45 minutes depending on system performance
|
||||
- **Storage**: Source builds require ~5-10GB additional space
|
||||
- **Memory**: Compilation may require 4GB+ RAM
|
||||
- **CPU**: Multi-core systems significantly faster
|
||||
|
||||
## Technical Implementation
|
||||
|
||||
### Module Installation Flow
|
||||
|
||||
```
|
||||
1. Environment Variable Check → Module Enabled?
|
||||
↓
|
||||
2. Git Clone/Pull → Download Latest Module Source
|
||||
↓
|
||||
3. SQL Script Discovery → Find Database Scripts
|
||||
↓
|
||||
4. Database Connection → Execute Scripts with Error Handling
|
||||
↓
|
||||
5. Configuration Files → Copy .conf.dist to .conf
|
||||
↓
|
||||
6. State Tracking → Update Module State Hash
|
||||
↓
|
||||
7. Rebuild Detection → Compare Previous vs Current State
|
||||
↓
|
||||
8. User Notification → Provide Rebuild Instructions
|
||||
```
|
||||
|
||||
### Database Script Execution
|
||||
|
||||
```sql
|
||||
-- Example execution pattern:
|
||||
mysql --skip-ssl-verify -h ac-database -P 3306 -u root -p"password" acore_world < module.sql
|
||||
|
||||
-- Success detection via exit codes:
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "✅ Successfully executed $(basename $sql_file)"
|
||||
else
|
||||
echo "❌ Failed to execute $sql_file"
|
||||
fi
|
||||
```
|
||||
|
||||
## Future Enhancements
|
||||
|
||||
- [ ] Support for pure configuration modules (no compilation)
|
||||
- [ ] Module dependency resolution
|
||||
- [ ] Incremental compilation for faster rebuilds
|
||||
- [ ] Integration with CI/CD pipelines
|
||||
- [ ] Module version management and rollback
|
||||
- [ ] Health checks for module functionality
|
||||
|
||||
## Support
|
||||
|
||||
For issues with specific modules, refer to their individual GitHub repositories.
|
||||
For system-level issues, check Docker Compose logs and module manager output.
|
||||
@@ -3,6 +3,14 @@
|
||||
# ==============================================
|
||||
# Environment variables for auth server, world server, client data, modules, and optional services
|
||||
|
||||
# ==============================================
|
||||
# DEPLOYMENT CONFIGURATION (REQUIRED)
|
||||
# ==============================================
|
||||
# Storage root path - local: ./storage, production: /nfs/containers or custom mount
|
||||
STORAGE_ROOT=./storage
|
||||
# Storage configuration (must match database layer)
|
||||
STORAGE_PATH=${STORAGE_ROOT}/azerothcore
|
||||
|
||||
# ==============================================
|
||||
# DATABASE CONNECTION (REQUIRED)
|
||||
# ==============================================
|
||||
@@ -62,14 +70,6 @@ AUTH_PORT=3724
|
||||
WORLD_PORT=8085
|
||||
SOAP_PORT=7878
|
||||
|
||||
# ==============================================
|
||||
# DEPLOYMENT CONFIGURATION (REQUIRED)
|
||||
# ==============================================
|
||||
# Storage root path - local: ./storage, production: /nfs/containers or custom mount
|
||||
STORAGE_ROOT=./storage
|
||||
# Storage configuration (must match database layer)
|
||||
STORAGE_PATH=${STORAGE_ROOT}/azerothcore
|
||||
|
||||
# ==============================================
|
||||
# CONTAINER NAMES (REQUIRED)
|
||||
# ==============================================
|
||||
@@ -90,19 +90,52 @@ NETWORK_NAME=azerothcore
|
||||
# ==============================================
|
||||
# CUSTOM MODULE SETTINGS
|
||||
# ==============================================
|
||||
# GIT
|
||||
GIT_EMAIL=uprightbass360@gmail.com
|
||||
GIT_USERNAME=uprightbass360
|
||||
GIT_PAT=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
|
||||
|
||||
# Playerbot settings
|
||||
PLAYERBOT_ENABLED=1
|
||||
PLAYERBOT_MAX_BOTS=40
|
||||
|
||||
# Module configuration
|
||||
MODULE_PLAYERBOTS=1
|
||||
MODULE_AOE_LOOT=0
|
||||
MODULE_LEARN_SPELLS=0
|
||||
MODULE_FIREWORKS=0
|
||||
MODULE_INDIVIDUAL_PROGRESSION=0
|
||||
MODULE_AOE_LOOT=1
|
||||
MODULE_LEARN_SPELLS=1
|
||||
MODULE_FIREWORKS=1
|
||||
MODULE_INDIVIDUAL_PROGRESSION=1
|
||||
|
||||
# Deployment mode
|
||||
DEPLOYMENT_MODE=portainer
|
||||
# Quality of Life Modules
|
||||
MODULE_AHBOT=1
|
||||
MODULE_AUTOBALANCE=1
|
||||
MODULE_TRANSMOG=1
|
||||
MODULE_NPC_BUFFER=1
|
||||
|
||||
# Gameplay Enhancement Modules
|
||||
MODULE_DYNAMIC_XP=1
|
||||
MODULE_SOLO_LFG=1
|
||||
MODULE_1V1_ARENA=1
|
||||
MODULE_PHASED_DUELS=1
|
||||
|
||||
# Server Management Modules
|
||||
MODULE_BREAKING_NEWS=1
|
||||
MODULE_BOSS_ANNOUNCER=1
|
||||
MODULE_ACCOUNT_ACHIEVEMENTS=1
|
||||
|
||||
# Additional Modules Found in Config
|
||||
MODULE_AUTO_REVIVE=1
|
||||
MODULE_GAIN_HONOR_GUARD=1
|
||||
MODULE_ELUNA=1
|
||||
MODULE_TIME_IS_TIME=1
|
||||
MODULE_POCKET_PORTAL=1
|
||||
MODULE_RANDOM_ENCHANTS=1
|
||||
MODULE_SOLOCRAFT=1
|
||||
MODULE_PVP_TITLES=1
|
||||
MODULE_NPC_BEASTMASTER=1
|
||||
MODULE_NPC_ENCHANTER=1
|
||||
MODULE_INSTANCE_RESET=1
|
||||
MODULE_LEVEL_GRANT=1
|
||||
|
||||
# ==============================================
|
||||
# ADDITIONAL CONTAINER NAMES (OPTIONAL)
|
||||
|
||||
@@ -286,54 +286,790 @@ services:
|
||||
user: "0:0" # Run as root to handle NFS permissions
|
||||
volumes:
|
||||
- ${STORAGE_PATH}/modules:/modules
|
||||
- ${STORAGE_PATH}/config:/azerothcore/env/dist/etc
|
||||
environment:
|
||||
- GIT_EMAIL=${GIT_EMAIL}
|
||||
- GIT_PAT=${GIT_PAT}
|
||||
- GIT_USERNAME=${GIT_USERNAME}
|
||||
- MODULE_PLAYERBOTS=${MODULE_PLAYERBOTS}
|
||||
- MODULE_AOE_LOOT=${MODULE_AOE_LOOT}
|
||||
- MODULE_LEARN_SPELLS=${MODULE_LEARN_SPELLS}
|
||||
- MODULE_FIREWORKS=${MODULE_FIREWORKS}
|
||||
- MODULE_INDIVIDUAL_PROGRESSION=${MODULE_INDIVIDUAL_PROGRESSION}
|
||||
- DEPLOYMENT_MODE=${DEPLOYMENT_MODE}
|
||||
# Quality of Life Modules
|
||||
- MODULE_AHBOT=${MODULE_AHBOT}
|
||||
- MODULE_AUTOBALANCE=${MODULE_AUTOBALANCE}
|
||||
- MODULE_TRANSMOG=${MODULE_TRANSMOG}
|
||||
- MODULE_NPC_BUFFER=${MODULE_NPC_BUFFER}
|
||||
# Gameplay Enhancement Modules
|
||||
- MODULE_DYNAMIC_XP=${MODULE_DYNAMIC_XP}
|
||||
- MODULE_SOLO_LFG=${MODULE_SOLO_LFG}
|
||||
- MODULE_1V1_ARENA=${MODULE_1V1_ARENA}
|
||||
- MODULE_PHASED_DUELS=${MODULE_PHASED_DUELS}
|
||||
# Server Management Modules
|
||||
- MODULE_BREAKING_NEWS=${MODULE_BREAKING_NEWS}
|
||||
- MODULE_BOSS_ANNOUNCER=${MODULE_BOSS_ANNOUNCER}
|
||||
- MODULE_ACCOUNT_ACHIEVEMENTS=${MODULE_ACCOUNT_ACHIEVEMENTS}
|
||||
# Additional Modules Found in Config
|
||||
- MODULE_AUTO_REVIVE=${MODULE_AUTO_REVIVE}
|
||||
- MODULE_GAIN_HONOR_GUARD=${MODULE_GAIN_HONOR_GUARD}
|
||||
- MODULE_ELUNA=${MODULE_ELUNA}
|
||||
- MODULE_TIME_IS_TIME=${MODULE_TIME_IS_TIME}
|
||||
- MODULE_POCKET_PORTAL=${MODULE_POCKET_PORTAL}
|
||||
- MODULE_RANDOM_ENCHANTS=${MODULE_RANDOM_ENCHANTS}
|
||||
- MODULE_SOLOCRAFT=${MODULE_SOLOCRAFT}
|
||||
- MODULE_PVP_TITLES=${MODULE_PVP_TITLES}
|
||||
- MODULE_NPC_BEASTMASTER=${MODULE_NPC_BEASTMASTER}
|
||||
- MODULE_NPC_ENCHANTER=${MODULE_NPC_ENCHANTER}
|
||||
- MODULE_INSTANCE_RESET=${MODULE_INSTANCE_RESET}
|
||||
- MODULE_LEVEL_GRANT=${MODULE_LEVEL_GRANT}
|
||||
# Database connection for SQL execution
|
||||
- CONTAINER_MYSQL=${CONTAINER_MYSQL}
|
||||
- MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD}
|
||||
- DB_AUTH_NAME=${DB_AUTH_NAME}
|
||||
- DB_WORLD_NAME=${DB_WORLD_NAME}
|
||||
- DB_CHARACTERS_NAME=${DB_CHARACTERS_NAME}
|
||||
entrypoint: ["/bin/sh", "-c"]
|
||||
command:
|
||||
- |
|
||||
echo 'Setting up git user'
|
||||
git config --global user.name "$GIT_USERNAME"
|
||||
git config --global user.email "$GIT_EMAIL"
|
||||
git config --global url.https://$GIT_PAT@github.com/.insteadOf https://github.com/
|
||||
|
||||
echo 'Initializing module management...'
|
||||
cd /modules
|
||||
|
||||
if [ "$DEPLOYMENT_MODE" = "portainer" ]; then
|
||||
echo 'Simple module setup for Portainer deployment...'
|
||||
mkdir -p mod-playerbots
|
||||
echo '✅ Playerbot module directory created'
|
||||
echo 'Cleaning up disabled modules...'
|
||||
|
||||
# Remove modules if disabled
|
||||
if [ "$MODULE_PLAYERBOTS" != "1" ] && [ -d "mod-playerbots" ]; then
|
||||
echo 'Removing mod-playerbots (disabled)...'
|
||||
rm -rf mod-playerbots
|
||||
fi
|
||||
|
||||
if [ "$MODULE_AOE_LOOT" != "1" ] && [ -d "mod-aoe-loot" ]; then
|
||||
echo 'Removing mod-aoe-loot (disabled)...'
|
||||
rm -rf mod-aoe-loot
|
||||
fi
|
||||
|
||||
if [ "$MODULE_LEARN_SPELLS" != "1" ] && [ -d "mod-learn-spells" ]; then
|
||||
echo 'Removing mod-learn-spells (disabled)...'
|
||||
rm -rf mod-learn-spells
|
||||
fi
|
||||
|
||||
if [ "$MODULE_FIREWORKS" != "1" ] && [ -d "mod-fireworks-on-level" ]; then
|
||||
echo 'Removing mod-fireworks-on-level (disabled)...'
|
||||
rm -rf mod-fireworks-on-level
|
||||
fi
|
||||
|
||||
if [ "$MODULE_INDIVIDUAL_PROGRESSION" != "1" ] && [ -d "mod-individual-progression" ]; then
|
||||
echo 'Removing mod-individual-progression (disabled)...'
|
||||
rm -rf mod-individual-progression
|
||||
fi
|
||||
|
||||
if [ "$MODULE_AHBOT" != "1" ] && [ -d "mod-ahbot" ]; then
|
||||
echo 'Removing mod-ahbot (disabled)...'
|
||||
rm -rf mod-ahbot
|
||||
fi
|
||||
|
||||
if [ "$MODULE_AUTOBALANCE" != "1" ] && [ -d "mod-autobalance" ]; then
|
||||
echo 'Removing mod-autobalance (disabled)...'
|
||||
rm -rf mod-autobalance
|
||||
fi
|
||||
|
||||
if [ "$MODULE_TRANSMOG" != "1" ] && [ -d "mod-transmog" ]; then
|
||||
echo 'Removing mod-transmog (disabled)...'
|
||||
rm -rf mod-transmog
|
||||
fi
|
||||
|
||||
if [ "$MODULE_NPC_BUFFER" != "1" ] && [ -d "mod-npc-buffer" ]; then
|
||||
echo 'Removing mod-npc-buffer (disabled)...'
|
||||
rm -rf mod-npc-buffer
|
||||
fi
|
||||
|
||||
if [ "$MODULE_DYNAMIC_XP" != "1" ] && [ -d "mod-dynamic-xp" ]; then
|
||||
echo 'Removing mod-dynamic-xp (disabled)...'
|
||||
rm -rf mod-dynamic-xp
|
||||
fi
|
||||
|
||||
if [ "$MODULE_SOLO_LFG" != "1" ] && [ -d "mod-solo-lfg" ]; then
|
||||
echo 'Removing mod-solo-lfg (disabled)...'
|
||||
rm -rf mod-solo-lfg
|
||||
fi
|
||||
|
||||
if [ "$MODULE_1V1_ARENA" != "1" ] && [ -d "mod-1v1-arena" ]; then
|
||||
echo 'Removing mod-1v1-arena (disabled)...'
|
||||
rm -rf mod-1v1-arena
|
||||
fi
|
||||
|
||||
if [ "$MODULE_PHASED_DUELS" != "1" ] && [ -d "mod-phased-duels" ]; then
|
||||
echo 'Removing mod-phased-duels (disabled)...'
|
||||
rm -rf mod-phased-duels
|
||||
fi
|
||||
|
||||
if [ "$MODULE_BREAKING_NEWS" != "1" ] && [ -d "mod-breaking-news-override" ]; then
|
||||
echo 'Removing mod-breaking-news-override (disabled)...'
|
||||
rm -rf mod-breaking-news-override
|
||||
fi
|
||||
|
||||
if [ "$MODULE_BOSS_ANNOUNCER" != "1" ] && [ -d "mod-boss-announcer" ]; then
|
||||
echo 'Removing mod-boss-announcer (disabled)...'
|
||||
rm -rf mod-boss-announcer
|
||||
fi
|
||||
|
||||
if [ "$MODULE_ACCOUNT_ACHIEVEMENTS" != "1" ] && [ -d "mod-account-achievements" ]; then
|
||||
echo 'Removing mod-account-achievements (disabled)...'
|
||||
rm -rf mod-account-achievements
|
||||
fi
|
||||
|
||||
if [ "$MODULE_AUTO_REVIVE" != "1" ] && [ -d "mod-auto-revive" ]; then
|
||||
echo 'Removing mod-auto-revive (disabled)...'
|
||||
rm -rf mod-auto-revive
|
||||
fi
|
||||
|
||||
if [ "$MODULE_GAIN_HONOR_GUARD" != "1" ] && [ -d "mod-gain-honor-guard" ]; then
|
||||
echo 'Removing mod-gain-honor-guard (disabled)...'
|
||||
rm -rf mod-gain-honor-guard
|
||||
fi
|
||||
|
||||
if [ "$MODULE_ELUNA" != "1" ] && [ -d "mod-eluna" ]; then
|
||||
echo 'Removing mod-eluna (disabled)...'
|
||||
rm -rf mod-eluna
|
||||
fi
|
||||
|
||||
if [ "$MODULE_TIME_IS_TIME" != "1" ] && [ -d "mod-TimeIsTime" ]; then
|
||||
echo 'Removing mod-TimeIsTime (disabled)...'
|
||||
rm -rf mod-TimeIsTime
|
||||
fi
|
||||
|
||||
if [ "$MODULE_POCKET_PORTAL" != "1" ] && [ -d "mod-pocket-portal" ]; then
|
||||
echo 'Removing mod-pocket-portal (disabled)...'
|
||||
rm -rf mod-pocket-portal
|
||||
fi
|
||||
|
||||
if [ "$MODULE_RANDOM_ENCHANTS" != "1" ] && [ -d "mod-random-enchants" ]; then
|
||||
echo 'Removing mod-random-enchants (disabled)...'
|
||||
rm -rf mod-random-enchants
|
||||
fi
|
||||
|
||||
if [ "$MODULE_SOLOCRAFT" != "1" ] && [ -d "mod-solocraft" ]; then
|
||||
echo 'Removing mod-solocraft (disabled)...'
|
||||
rm -rf mod-solocraft
|
||||
fi
|
||||
|
||||
if [ "$MODULE_PVP_TITLES" != "1" ] && [ -d "mod-pvp-titles" ]; then
|
||||
echo 'Removing mod-pvp-titles (disabled)...'
|
||||
rm -rf mod-pvp-titles
|
||||
fi
|
||||
|
||||
if [ "$MODULE_NPC_BEASTMASTER" != "1" ] && [ -d "mod-npc-beastmaster" ]; then
|
||||
echo 'Removing mod-npc-beastmaster (disabled)...'
|
||||
rm -rf mod-npc-beastmaster
|
||||
fi
|
||||
|
||||
if [ "$MODULE_NPC_ENCHANTER" != "1" ] && [ -d "mod-npc-enchanter" ]; then
|
||||
echo 'Removing mod-npc-enchanter (disabled)...'
|
||||
rm -rf mod-npc-enchanter
|
||||
fi
|
||||
|
||||
if [ "$MODULE_INSTANCE_RESET" != "1" ] && [ -d "mod-instance-reset" ]; then
|
||||
echo 'Removing mod-instance-reset (disabled)...'
|
||||
rm -rf mod-instance-reset
|
||||
fi
|
||||
|
||||
if [ "$MODULE_LEVEL_GRANT" != "1" ] && [ -d "mod-quest-count-level" ]; then
|
||||
echo 'Removing mod-quest-count-level (disabled)...'
|
||||
rm -rf mod-quest-count-level
|
||||
fi
|
||||
|
||||
echo 'Installing enabled modules...'
|
||||
|
||||
# Install Playerbots if enabled
|
||||
if [ "$MODULE_PLAYERBOTS" = "1" ] && [ ! -d "mod-playerbots" ]; then
|
||||
echo '🤖 Installing mod-playerbots...'
|
||||
echo ' 📖 Project: https://github.com/liyunfan1223/mod-playerbots'
|
||||
echo ' 🚨 CRITICAL: REQUIRES Custom AzerothCore branch (liyunfan1223/azerothcore-wotlk/tree/Playerbot)'
|
||||
echo ' 🚨 INCOMPATIBLE with standard AzerothCore - module will not function properly'
|
||||
echo ' 🔧 REBUILD REQUIRED: Container must be rebuilt with source-based compilation'
|
||||
echo ' 📋 POST-INSTALL: Requires manual account/character configuration'
|
||||
git clone https://github.com/liyunfan1223/mod-playerbots.git mod-playerbots
|
||||
fi
|
||||
|
||||
# Install AOE Loot if enabled
|
||||
if [ "$MODULE_AOE_LOOT" = "1" ] && [ ! -d "mod-aoe-loot" ]; then
|
||||
echo '💰 Installing mod-aoe-loot...'
|
||||
echo ' 📖 Project: https://github.com/azerothcore/mod-aoe-loot'
|
||||
echo ' ℹ️ Allows looting multiple corpses with one action'
|
||||
echo ' 🔧 REBUILD REQUIRED: Container must be rebuilt with source-based compilation'
|
||||
git clone https://github.com/azerothcore/mod-aoe-loot.git mod-aoe-loot
|
||||
fi
|
||||
|
||||
# Install Learn Spells if enabled
|
||||
if [ "$MODULE_LEARN_SPELLS" = "1" ] && [ ! -d "mod-learn-spells" ]; then
|
||||
echo '📚 Installing mod-learn-spells...'
|
||||
echo ' 📖 Project: https://github.com/azerothcore/mod-learn-spells'
|
||||
echo ' ℹ️ Automatically teaches class spells on level up'
|
||||
echo ' 🔧 REBUILD REQUIRED: Container must be rebuilt with source-based compilation'
|
||||
git clone https://github.com/azerothcore/mod-learn-spells.git mod-learn-spells
|
||||
fi
|
||||
|
||||
# Install Fireworks on Level if enabled
|
||||
if [ "$MODULE_FIREWORKS" = "1" ] && [ ! -d "mod-fireworks-on-level" ]; then
|
||||
echo '🎆 Installing mod-fireworks-on-level...'
|
||||
echo ' 📖 Project: https://github.com/azerothcore/mod-fireworks-on-level'
|
||||
echo ' ℹ️ Displays fireworks when players level up'
|
||||
echo ' 🔧 REBUILD REQUIRED: Container must be rebuilt with source-based compilation'
|
||||
git clone https://github.com/azerothcore/mod-fireworks-on-level.git mod-fireworks-on-level
|
||||
fi
|
||||
|
||||
# Install Individual Progression if enabled
|
||||
if [ "$MODULE_INDIVIDUAL_PROGRESSION" = "1" ] && [ ! -d "mod-individual-progression" ]; then
|
||||
echo '⏳ Installing mod-individual-progression...'
|
||||
echo ' 📖 Project: https://github.com/ZhengPeiRu21/mod-individual-progression'
|
||||
echo ' ℹ️ Simulates authentic Vanilla→TBC→WotLK progression per player'
|
||||
echo ' ✅ AUTO-CONFIG: Automatically sets EnablePlayerSettings=1 and DBC.EnforceItemAttributes=0'
|
||||
echo ' 🔧 REBUILD REQUIRED: Container must be rebuilt with source-based compilation'
|
||||
echo ' 📁 Optional client files available in optional/ directory'
|
||||
git clone https://github.com/ZhengPeiRu21/mod-individual-progression.git mod-individual-progression
|
||||
fi
|
||||
|
||||
# Quality of Life Modules
|
||||
if [ "$MODULE_AHBOT" = "1" ] && [ ! -d "mod-ahbot" ]; then
|
||||
echo '🏪 Installing mod-ahbot...'
|
||||
echo ' 📖 Project: https://github.com/azerothcore/mod-ahbot'
|
||||
echo ' ℹ️ Auction house bot that buys and sells items automatically'
|
||||
echo ' 🔧 REBUILD REQUIRED: Container must be rebuilt with source-based compilation'
|
||||
echo ' 📋 POST-INSTALL: Requires manual account/character setup in mod_ahbot.conf'
|
||||
git clone https://github.com/azerothcore/mod-ahbot.git mod-ahbot
|
||||
fi
|
||||
|
||||
if [ "$MODULE_AUTOBALANCE" = "1" ] && [ ! -d "mod-autobalance" ]; then
|
||||
echo '⚖️ Installing mod-autobalance...'
|
||||
echo ' 📖 Project: https://github.com/azerothcore/mod-autobalance'
|
||||
echo ' ℹ️ Automatically adjusts dungeon difficulty based on party size'
|
||||
echo ' 🔧 REBUILD REQUIRED: Container must be rebuilt with source-based compilation'
|
||||
git clone https://github.com/azerothcore/mod-autobalance.git mod-autobalance
|
||||
fi
|
||||
|
||||
if [ "$MODULE_TRANSMOG" = "1" ] && [ ! -d "mod-transmog" ]; then
|
||||
echo 'Installing mod-transmog...'
|
||||
git clone https://github.com/azerothcore/mod-transmog.git mod-transmog
|
||||
fi
|
||||
|
||||
if [ "$MODULE_NPC_BUFFER" = "1" ] && [ ! -d "mod-npc-buffer" ]; then
|
||||
echo 'Installing mod-npc-buffer...'
|
||||
git clone https://github.com/azerothcore/mod-npc-buffer.git mod-npc-buffer
|
||||
fi
|
||||
|
||||
# Gameplay Enhancement Modules
|
||||
if [ "$MODULE_DYNAMIC_XP" = "1" ] && [ ! -d "mod-dynamic-xp" ]; then
|
||||
echo 'Installing mod-dynamic-xp...'
|
||||
git clone https://github.com/azerothcore/mod-dynamic-xp.git mod-dynamic-xp
|
||||
fi
|
||||
|
||||
if [ "$MODULE_SOLO_LFG" = "1" ] && [ ! -d "mod-solo-lfg" ]; then
|
||||
echo '🔍 Installing mod-solo-lfg...'
|
||||
echo ' 📖 Project: https://github.com/azerothcore/mod-solo-lfg'
|
||||
echo ' ℹ️ Allows dungeon finder for solo players and small groups'
|
||||
echo ' 🔧 REBUILD REQUIRED: Container must be rebuilt with source-based compilation'
|
||||
echo ' 💡 Pairs perfectly with mod-solocraft and mod-autobalance'
|
||||
git clone https://github.com/azerothcore/mod-solo-lfg.git mod-solo-lfg
|
||||
fi
|
||||
|
||||
if [ "$MODULE_1V1_ARENA" = "1" ] && [ ! -d "mod-1v1-arena" ]; then
|
||||
echo 'Installing mod-1v1-arena...'
|
||||
git clone https://github.com/azerothcore/mod-1v1-arena.git mod-1v1-arena
|
||||
fi
|
||||
|
||||
if [ "$MODULE_PHASED_DUELS" = "1" ] && [ ! -d "mod-phased-duels" ]; then
|
||||
echo 'Installing mod-phased-duels...'
|
||||
git clone https://github.com/azerothcore/mod-phased-duels.git mod-phased-duels
|
||||
fi
|
||||
|
||||
# Server Management Modules
|
||||
if [ "$MODULE_BREAKING_NEWS" = "1" ] && [ ! -d "mod-breaking-news-override" ]; then
|
||||
echo '📰 Installing mod-breaking-news-override...'
|
||||
echo ' 📖 Project: https://github.com/azerothcore/mod-breaking-news-override'
|
||||
echo ' ℹ️ Displays custom breaking news on character selection screen'
|
||||
echo ' 🔧 REBUILD REQUIRED: Container must be rebuilt with source-based compilation'
|
||||
echo ' 📋 POST-INSTALL: Requires custom HTML file creation and path configuration'
|
||||
git clone https://github.com/azerothcore/mod-breaking-news-override.git mod-breaking-news-override
|
||||
fi
|
||||
|
||||
if [ "$MODULE_BOSS_ANNOUNCER" = "1" ] && [ ! -d "mod-boss-announcer" ]; then
|
||||
echo 'Installing mod-boss-announcer...'
|
||||
git clone https://github.com/azerothcore/mod-boss-announcer.git mod-boss-announcer
|
||||
fi
|
||||
|
||||
if [ "$MODULE_ACCOUNT_ACHIEVEMENTS" = "1" ] && [ ! -d "mod-account-achievements" ]; then
|
||||
echo 'Installing mod-account-achievements...'
|
||||
git clone https://github.com/azerothcore/mod-account-achievements.git mod-account-achievements
|
||||
fi
|
||||
|
||||
# Additional Modules Found in Config
|
||||
if [ "$MODULE_AUTO_REVIVE" = "1" ] && [ ! -d "mod-auto-revive" ]; then
|
||||
echo 'Installing mod-auto-revive...'
|
||||
git clone https://github.com/azerothcore/mod-auto-revive.git mod-auto-revive
|
||||
fi
|
||||
|
||||
if [ "$MODULE_GAIN_HONOR_GUARD" = "1" ] && [ ! -d "mod-gain-honor-guard" ]; then
|
||||
echo 'Installing mod-gain-honor-guard...'
|
||||
git clone https://github.com/azerothcore/mod-gain-honor-guard.git mod-gain-honor-guard
|
||||
fi
|
||||
|
||||
if [ "$MODULE_ELUNA" = "1" ] && [ ! -d "mod-eluna" ]; then
|
||||
echo 'Installing mod-eluna...'
|
||||
git clone https://github.com/azerothcore/mod-eluna.git mod-eluna
|
||||
fi
|
||||
|
||||
if [ "$MODULE_TIME_IS_TIME" = "1" ] && [ ! -d "mod-TimeIsTime" ]; then
|
||||
echo 'Installing mod-TimeIsTime...'
|
||||
git clone https://github.com/dunjeon/mod-TimeIsTime.git mod-TimeIsTime
|
||||
fi
|
||||
|
||||
if [ "$MODULE_POCKET_PORTAL" = "1" ] && [ ! -d "mod-pocket-portal" ]; then
|
||||
echo 'Installing mod-pocket-portal...'
|
||||
git clone https://github.com/azerothcore/mod-pocket-portal.git mod-pocket-portal
|
||||
fi
|
||||
|
||||
if [ "$MODULE_RANDOM_ENCHANTS" = "1" ] && [ ! -d "mod-random-enchants" ]; then
|
||||
echo 'Installing mod-random-enchants...'
|
||||
git clone https://github.com/azerothcore/mod-random-enchants.git mod-random-enchants
|
||||
fi
|
||||
|
||||
if [ "$MODULE_SOLOCRAFT" = "1" ] && [ ! -d "mod-solocraft" ]; then
|
||||
echo '🎯 Installing mod-solocraft...'
|
||||
echo ' 📖 Project: https://github.com/azerothcore/mod-solocraft'
|
||||
echo ' ℹ️ Scales dungeon/raid difficulty for solo players'
|
||||
echo ' 🔧 REBUILD REQUIRED: Container must be rebuilt with source-based compilation'
|
||||
echo ' 💡 Works well with mod-autobalance and mod-solo-lfg'
|
||||
git clone https://github.com/azerothcore/mod-solocraft.git mod-solocraft
|
||||
fi
|
||||
|
||||
if [ "$MODULE_PVP_TITLES" = "1" ] && [ ! -d "mod-pvp-titles" ]; then
|
||||
echo 'Installing mod-pvp-titles...'
|
||||
git clone https://github.com/azerothcore/mod-pvp-titles.git mod-pvp-titles
|
||||
fi
|
||||
|
||||
if [ "$MODULE_NPC_BEASTMASTER" = "1" ] && [ ! -d "mod-npc-beastmaster" ]; then
|
||||
echo 'Installing mod-npc-beastmaster...'
|
||||
git clone https://github.com/azerothcore/mod-npc-beastmaster.git mod-npc-beastmaster
|
||||
fi
|
||||
|
||||
if [ "$MODULE_NPC_ENCHANTER" = "1" ] && [ ! -d "mod-npc-enchanter" ]; then
|
||||
echo 'Installing mod-npc-enchanter...'
|
||||
git clone https://github.com/azerothcore/mod-npc-enchanter.git mod-npc-enchanter
|
||||
fi
|
||||
|
||||
if [ "$MODULE_INSTANCE_RESET" = "1" ] && [ ! -d "mod-instance-reset" ]; then
|
||||
echo 'Installing mod-instance-reset...'
|
||||
git clone https://github.com/azerothcore/mod-instance-reset.git mod-instance-reset
|
||||
fi
|
||||
|
||||
if [ "$MODULE_LEVEL_GRANT" = "1" ] && [ ! -d "mod-quest-count-level" ]; then
|
||||
echo 'Installing mod-quest-count-level...'
|
||||
git clone https://github.com/michaeldelago/mod-quest-count-level.git mod-quest-count-level
|
||||
fi
|
||||
|
||||
echo 'Managing configuration files...'
|
||||
|
||||
# Remove configuration files for disabled modules
|
||||
if [ "$MODULE_PLAYERBOTS" != "1" ]; then
|
||||
rm -f /azerothcore/env/dist/etc/playerbots.conf*
|
||||
fi
|
||||
|
||||
if [ "$MODULE_AOE_LOOT" != "1" ]; then
|
||||
rm -f /azerothcore/env/dist/etc/mod_aoe_loot.conf*
|
||||
fi
|
||||
|
||||
if [ "$MODULE_LEARN_SPELLS" != "1" ]; then
|
||||
rm -f /azerothcore/env/dist/etc/mod_learnspells.conf*
|
||||
fi
|
||||
|
||||
if [ "$MODULE_FIREWORKS" != "1" ]; then
|
||||
rm -f /azerothcore/env/dist/etc/mod_fireworks.conf*
|
||||
fi
|
||||
|
||||
if [ "$MODULE_INDIVIDUAL_PROGRESSION" != "1" ]; then
|
||||
rm -f /azerothcore/env/dist/etc/individual_progression.conf*
|
||||
fi
|
||||
|
||||
if [ "$MODULE_AHBOT" != "1" ]; then
|
||||
rm -f /azerothcore/env/dist/etc/mod_ahbot.conf*
|
||||
fi
|
||||
|
||||
if [ "$MODULE_AUTOBALANCE" != "1" ]; then
|
||||
rm -f /azerothcore/env/dist/etc/AutoBalance.conf*
|
||||
fi
|
||||
|
||||
if [ "$MODULE_TRANSMOG" != "1" ]; then
|
||||
rm -f /azerothcore/env/dist/etc/transmog.conf*
|
||||
fi
|
||||
|
||||
if [ "$MODULE_NPC_BUFFER" != "1" ]; then
|
||||
rm -f /azerothcore/env/dist/etc/npc_buffer.conf*
|
||||
fi
|
||||
|
||||
if [ "$MODULE_DYNAMIC_XP" != "1" ]; then
|
||||
rm -f /azerothcore/env/dist/etc/Individual-XP.conf*
|
||||
fi
|
||||
|
||||
if [ "$MODULE_SOLO_LFG" != "1" ]; then
|
||||
rm -f /azerothcore/env/dist/etc/SoloLfg.conf*
|
||||
fi
|
||||
|
||||
if [ "$MODULE_1V1_ARENA" != "1" ]; then
|
||||
rm -f /azerothcore/env/dist/etc/1v1arena.conf*
|
||||
fi
|
||||
|
||||
if [ "$MODULE_PHASED_DUELS" != "1" ]; then
|
||||
rm -f /azerothcore/env/dist/etc/phasedduels.conf*
|
||||
fi
|
||||
|
||||
if [ "$MODULE_BREAKING_NEWS" != "1" ]; then
|
||||
rm -f /azerothcore/env/dist/etc/breaking_news.conf*
|
||||
fi
|
||||
|
||||
if [ "$MODULE_BOSS_ANNOUNCER" != "1" ]; then
|
||||
rm -f /azerothcore/env/dist/etc/boss_announcer.conf*
|
||||
fi
|
||||
|
||||
if [ "$MODULE_ACCOUNT_ACHIEVEMENTS" != "1" ]; then
|
||||
rm -f /azerothcore/env/dist/etc/account_achievements.conf*
|
||||
fi
|
||||
|
||||
if [ "$MODULE_AUTO_REVIVE" != "1" ]; then
|
||||
rm -f /azerothcore/env/dist/etc/AutoRevive.conf*
|
||||
fi
|
||||
|
||||
if [ "$MODULE_GAIN_HONOR_GUARD" != "1" ]; then
|
||||
rm -f /azerothcore/env/dist/etc/GainHonorGuard.conf*
|
||||
fi
|
||||
|
||||
if [ "$MODULE_ELUNA" != "1" ]; then
|
||||
rm -f /azerothcore/env/dist/etc/mod_LuaEngine.conf*
|
||||
fi
|
||||
|
||||
if [ "$MODULE_TIME_IS_TIME" != "1" ]; then
|
||||
rm -f /azerothcore/env/dist/etc/mod-time_is_time.conf*
|
||||
fi
|
||||
|
||||
if [ "$MODULE_POCKET_PORTAL" != "1" ]; then
|
||||
rm -f /azerothcore/env/dist/etc/pocketportal.conf*
|
||||
fi
|
||||
|
||||
if [ "$MODULE_RANDOM_ENCHANTS" != "1" ]; then
|
||||
rm -f /azerothcore/env/dist/etc/RandomEnchants.conf*
|
||||
fi
|
||||
|
||||
if [ "$MODULE_SOLOCRAFT" != "1" ]; then
|
||||
rm -f /azerothcore/env/dist/etc/Solocraft.conf*
|
||||
fi
|
||||
|
||||
if [ "$MODULE_PVP_TITLES" != "1" ]; then
|
||||
rm -f /azerothcore/env/dist/etc/mod_pvptitles.conf*
|
||||
fi
|
||||
|
||||
if [ "$MODULE_NPC_BEASTMASTER" != "1" ]; then
|
||||
rm -f /azerothcore/env/dist/etc/npc_beastmaster.conf*
|
||||
fi
|
||||
|
||||
if [ "$MODULE_NPC_ENCHANTER" != "1" ]; then
|
||||
rm -f /azerothcore/env/dist/etc/npc_enchanter.conf*
|
||||
fi
|
||||
|
||||
if [ "$MODULE_INSTANCE_RESET" != "1" ]; then
|
||||
rm -f /azerothcore/env/dist/etc/instance-reset.conf*
|
||||
fi
|
||||
|
||||
if [ "$MODULE_LEVEL_GRANT" != "1" ]; then
|
||||
rm -f /azerothcore/env/dist/etc/levelGrant.conf*
|
||||
fi
|
||||
|
||||
# Install configuration files for enabled modules
|
||||
for module_dir in mod-*; do
|
||||
if [ -d "$$module_dir" ]; then
|
||||
echo "Installing config files for $$module_dir..."
|
||||
find "$$module_dir" -name "*.conf.dist" -exec cp {} /azerothcore/env/dist/etc/ \; 2>/dev/null || true
|
||||
fi
|
||||
done
|
||||
|
||||
echo 'Configuration file management complete.'
|
||||
|
||||
echo 'Executing module SQL scripts...'
|
||||
|
||||
# Function to execute SQL files for a module
|
||||
execute_module_sql() {
|
||||
local module_dir="$$1"
|
||||
local module_name="$$2"
|
||||
|
||||
echo "Processing SQL scripts for $$module_name..."
|
||||
|
||||
# Find and execute SQL files in the module
|
||||
if [ -d "$$module_dir/data/sql" ]; then
|
||||
# Execute world database scripts
|
||||
if [ -d "$$module_dir/data/sql/world" ]; then
|
||||
find "$$module_dir/data/sql/world" -name "*.sql" -type f | while read sql_file; do
|
||||
echo " Executing world SQL: $$(basename "$$sql_file")"
|
||||
if mysql --skip-ssl-verify -h "${CONTAINER_MYSQL}" -P 3306 -u root -p"${MYSQL_ROOT_PASSWORD}" "${DB_WORLD_NAME}" < "$$sql_file" >/dev/null 2>&1; then
|
||||
echo " ✅ Successfully executed $$(basename "$$sql_file")"
|
||||
else
|
||||
echo " ❌ Failed to execute $$sql_file"
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
# Execute auth database scripts
|
||||
if [ -d "$$module_dir/data/sql/auth" ]; then
|
||||
find "$$module_dir/data/sql/auth" -name "*.sql" -type f | while read sql_file; do
|
||||
echo " Executing auth SQL: $$(basename "$$sql_file")"
|
||||
if mysql --skip-ssl-verify -h "${CONTAINER_MYSQL}" -P 3306 -u root -p"${MYSQL_ROOT_PASSWORD}" "${DB_AUTH_NAME}" < "$$sql_file" >/dev/null 2>&1; then
|
||||
echo " ✅ Successfully executed $$(basename "$$sql_file")"
|
||||
else
|
||||
echo " ❌ Failed to execute $$sql_file"
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
# Execute character database scripts
|
||||
if [ -d "$$module_dir/data/sql/characters" ]; then
|
||||
find "$$module_dir/data/sql/characters" -name "*.sql" -type f | while read sql_file; do
|
||||
echo " Executing characters SQL: $$(basename "$$sql_file")"
|
||||
if mysql --skip-ssl-verify -h "${CONTAINER_MYSQL}" -P 3306 -u root -p"${MYSQL_ROOT_PASSWORD}" "${DB_CHARACTERS_NAME}" < "$$sql_file" >/dev/null 2>&1; then
|
||||
echo " ✅ Successfully executed $$(basename "$$sql_file")"
|
||||
else
|
||||
echo " ❌ Failed to execute $$sql_file"
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
# Execute base SQL files (common pattern)
|
||||
find "$$module_dir/data/sql" -maxdepth 1 -name "*.sql" -type f | while read sql_file; do
|
||||
echo " Executing base SQL: $$(basename "$$sql_file")"
|
||||
mysql -h "${CONTAINER_MYSQL}" -P 3306 -u root -p"${MYSQL_ROOT_PASSWORD}" "${DB_WORLD_NAME}" < "$$sql_file" 2>/dev/null || echo " Warning: Failed to execute $$sql_file"
|
||||
done
|
||||
fi
|
||||
|
||||
# Look for SQL files in other common locations
|
||||
if [ -d "$$module_dir/sql" ]; then
|
||||
find "$$module_dir/sql" -name "*.sql" -type f | while read sql_file; do
|
||||
echo " Executing SQL: $$(basename "$$sql_file")"
|
||||
mysql -h "${CONTAINER_MYSQL}" -P 3306 -u root -p"${MYSQL_ROOT_PASSWORD}" "${DB_WORLD_NAME}" < "$$sql_file" 2>/dev/null || echo " Warning: Failed to execute $$sql_file"
|
||||
done
|
||||
fi
|
||||
}
|
||||
|
||||
# Install MySQL client if not available
|
||||
which mysql >/dev/null 2>&1 || {
|
||||
echo "Installing MySQL client..."
|
||||
apk add --no-cache mysql-client >/dev/null 2>&1 || echo "Warning: Could not install MySQL client"
|
||||
}
|
||||
|
||||
# Execute SQL for enabled modules only
|
||||
if [ "$MODULE_PLAYERBOTS" = "1" ] && [ -d "mod-playerbots" ]; then
|
||||
execute_module_sql "mod-playerbots" "Playerbots"
|
||||
fi
|
||||
|
||||
if [ "$MODULE_AOE_LOOT" = "1" ] && [ -d "mod-aoe-loot" ]; then
|
||||
execute_module_sql "mod-aoe-loot" "AoE Loot"
|
||||
fi
|
||||
|
||||
if [ "$MODULE_LEARN_SPELLS" = "1" ] && [ -d "mod-learn-spells" ]; then
|
||||
execute_module_sql "mod-learn-spells" "Learn Spells"
|
||||
fi
|
||||
|
||||
if [ "$MODULE_FIREWORKS" = "1" ] && [ -d "mod-fireworks-on-level" ]; then
|
||||
execute_module_sql "mod-fireworks-on-level" "Fireworks"
|
||||
fi
|
||||
|
||||
if [ "$MODULE_INDIVIDUAL_PROGRESSION" = "1" ] && [ -d "mod-individual-progression" ]; then
|
||||
execute_module_sql "mod-individual-progression" "Individual Progression"
|
||||
fi
|
||||
|
||||
if [ "$MODULE_AHBOT" = "1" ] && [ -d "mod-ahbot" ]; then
|
||||
execute_module_sql "mod-ahbot" "AHBot"
|
||||
fi
|
||||
|
||||
if [ "$MODULE_AUTOBALANCE" = "1" ] && [ -d "mod-autobalance" ]; then
|
||||
execute_module_sql "mod-autobalance" "AutoBalance"
|
||||
fi
|
||||
|
||||
if [ "$MODULE_TRANSMOG" = "1" ] && [ -d "mod-transmog" ]; then
|
||||
execute_module_sql "mod-transmog" "Transmog"
|
||||
fi
|
||||
|
||||
if [ "$MODULE_NPC_BUFFER" = "1" ] && [ -d "mod-npc-buffer" ]; then
|
||||
execute_module_sql "mod-npc-buffer" "NPC Buffer"
|
||||
fi
|
||||
|
||||
if [ "$MODULE_DYNAMIC_XP" = "1" ] && [ -d "mod-dynamic-xp" ]; then
|
||||
execute_module_sql "mod-dynamic-xp" "Dynamic XP"
|
||||
fi
|
||||
|
||||
if [ "$MODULE_SOLO_LFG" = "1" ] && [ -d "mod-solo-lfg" ]; then
|
||||
execute_module_sql "mod-solo-lfg" "Solo LFG"
|
||||
fi
|
||||
|
||||
if [ "$MODULE_1V1_ARENA" = "1" ] && [ -d "mod-1v1-arena" ]; then
|
||||
execute_module_sql "mod-1v1-arena" "1v1 Arena"
|
||||
fi
|
||||
|
||||
if [ "$MODULE_PHASED_DUELS" = "1" ] && [ -d "mod-phased-duels" ]; then
|
||||
execute_module_sql "mod-phased-duels" "Phased Duels"
|
||||
fi
|
||||
|
||||
if [ "$MODULE_BREAKING_NEWS" = "1" ] && [ -d "mod-breaking-news-override" ]; then
|
||||
execute_module_sql "mod-breaking-news-override" "Breaking News"
|
||||
fi
|
||||
|
||||
if [ "$MODULE_BOSS_ANNOUNCER" = "1" ] && [ -d "mod-boss-announcer" ]; then
|
||||
execute_module_sql "mod-boss-announcer" "Boss Announcer"
|
||||
fi
|
||||
|
||||
if [ "$MODULE_ACCOUNT_ACHIEVEMENTS" = "1" ] && [ -d "mod-account-achievements" ]; then
|
||||
execute_module_sql "mod-account-achievements" "Account Achievements"
|
||||
fi
|
||||
|
||||
if [ "$MODULE_AUTO_REVIVE" = "1" ] && [ -d "mod-auto-revive" ]; then
|
||||
execute_module_sql "mod-auto-revive" "Auto Revive"
|
||||
fi
|
||||
|
||||
if [ "$MODULE_GAIN_HONOR_GUARD" = "1" ] && [ -d "mod-gain-honor-guard" ]; then
|
||||
execute_module_sql "mod-gain-honor-guard" "Gain Honor Guard"
|
||||
fi
|
||||
|
||||
if [ "$MODULE_ELUNA" = "1" ] && [ -d "mod-eluna" ]; then
|
||||
execute_module_sql "mod-eluna" "Eluna"
|
||||
fi
|
||||
|
||||
if [ "$MODULE_TIME_IS_TIME" = "1" ] && [ -d "mod-TimeIsTime" ]; then
|
||||
execute_module_sql "mod-TimeIsTime" "Time Is Time"
|
||||
fi
|
||||
|
||||
if [ "$MODULE_POCKET_PORTAL" = "1" ] && [ -d "mod-pocket-portal" ]; then
|
||||
execute_module_sql "mod-pocket-portal" "Pocket Portal"
|
||||
fi
|
||||
|
||||
if [ "$MODULE_RANDOM_ENCHANTS" = "1" ] && [ -d "mod-random-enchants" ]; then
|
||||
execute_module_sql "mod-random-enchants" "Random Enchants"
|
||||
fi
|
||||
|
||||
if [ "$MODULE_SOLOCRAFT" = "1" ] && [ -d "mod-solocraft" ]; then
|
||||
execute_module_sql "mod-solocraft" "Solocraft"
|
||||
fi
|
||||
|
||||
if [ "$MODULE_PVP_TITLES" = "1" ] && [ -d "mod-pvp-titles" ]; then
|
||||
execute_module_sql "mod-pvp-titles" "PvP Titles"
|
||||
fi
|
||||
|
||||
if [ "$MODULE_NPC_BEASTMASTER" = "1" ] && [ -d "mod-npc-beastmaster" ]; then
|
||||
execute_module_sql "mod-npc-beastmaster" "NPC Beastmaster"
|
||||
fi
|
||||
|
||||
if [ "$MODULE_NPC_ENCHANTER" = "1" ] && [ -d "mod-npc-enchanter" ]; then
|
||||
execute_module_sql "mod-npc-enchanter" "NPC Enchanter"
|
||||
fi
|
||||
|
||||
if [ "$MODULE_INSTANCE_RESET" = "1" ] && [ -d "mod-instance-reset" ]; then
|
||||
execute_module_sql "mod-instance-reset" "Instance Reset"
|
||||
fi
|
||||
|
||||
if [ "$MODULE_LEVEL_GRANT" = "1" ] && [ -d "mod-quest-count-level" ]; then
|
||||
execute_module_sql "mod-quest-count-level" "Level Grant"
|
||||
fi
|
||||
|
||||
echo 'SQL execution complete.'
|
||||
|
||||
# Module state tracking and rebuild logic
|
||||
echo 'Checking for module changes that require rebuild...'
|
||||
|
||||
MODULES_STATE_FILE="/modules/.modules_state"
|
||||
CURRENT_STATE=""
|
||||
REBUILD_REQUIRED=0
|
||||
|
||||
# Create current module state hash
|
||||
for module_var in MODULE_PLAYERBOTS 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; do
|
||||
eval "value=\$$module_var"
|
||||
CURRENT_STATE="$CURRENT_STATE$module_var=$value|"
|
||||
done
|
||||
|
||||
# Check if state has changed
|
||||
if [ -f "$MODULES_STATE_FILE" ]; then
|
||||
PREVIOUS_STATE=$(cat "$MODULES_STATE_FILE")
|
||||
if [ "$CURRENT_STATE" != "$PREVIOUS_STATE" ]; then
|
||||
echo "🔄 Module configuration has changed - rebuild required"
|
||||
REBUILD_REQUIRED=1
|
||||
else
|
||||
echo "✅ No module changes detected"
|
||||
fi
|
||||
else
|
||||
echo 'Advanced module setup for local development...'
|
||||
# Install Playerbots if enabled
|
||||
if [ "$MODULE_PLAYERBOTS" = "1" ] && [ ! -d "mod-playerbots" ]; then
|
||||
echo 'Installing mod-playerbots...'
|
||||
git clone https://github.com/liyunfan1223/mod-playerbots.git mod-playerbots
|
||||
fi
|
||||
echo "📝 First run - establishing module state baseline"
|
||||
REBUILD_REQUIRED=1
|
||||
fi
|
||||
|
||||
# Install AOE Loot if enabled
|
||||
if [ "$MODULE_AOE_LOOT" = "1" ] && [ ! -d "mod-aoe-loot" ]; then
|
||||
echo 'Installing mod-aoe-loot...'
|
||||
git clone https://github.com/azerothcore/mod-aoe-loot.git mod-aoe-loot
|
||||
fi
|
||||
# Save current state
|
||||
echo "$CURRENT_STATE" > "$MODULES_STATE_FILE"
|
||||
|
||||
# Install Learn Spells if enabled
|
||||
if [ "$MODULE_LEARN_SPELLS" = "1" ] && [ ! -d "mod-learn-spells" ]; then
|
||||
echo 'Installing mod-learn-spells...'
|
||||
git clone https://github.com/azerothcore/mod-learn-spells.git mod-learn-spells
|
||||
fi
|
||||
# Check if any C++ modules are enabled (all current modules require compilation)
|
||||
ENABLED_MODULES=""
|
||||
[ "$MODULE_PLAYERBOTS" = "1" ] && ENABLED_MODULES="$ENABLED_MODULES mod-playerbots"
|
||||
[ "$MODULE_AOE_LOOT" = "1" ] && ENABLED_MODULES="$ENABLED_MODULES mod-aoe-loot"
|
||||
[ "$MODULE_LEARN_SPELLS" = "1" ] && ENABLED_MODULES="$ENABLED_MODULES mod-learn-spells"
|
||||
[ "$MODULE_FIREWORKS" = "1" ] && ENABLED_MODULES="$ENABLED_MODULES mod-fireworks-on-level"
|
||||
[ "$MODULE_INDIVIDUAL_PROGRESSION" = "1" ] && ENABLED_MODULES="$ENABLED_MODULES mod-individual-progression"
|
||||
[ "$MODULE_AHBOT" = "1" ] && ENABLED_MODULES="$ENABLED_MODULES mod-ahbot"
|
||||
[ "$MODULE_AUTOBALANCE" = "1" ] && ENABLED_MODULES="$ENABLED_MODULES mod-autobalance"
|
||||
[ "$MODULE_TRANSMOG" = "1" ] && ENABLED_MODULES="$ENABLED_MODULES mod-transmog"
|
||||
[ "$MODULE_NPC_BUFFER" = "1" ] && ENABLED_MODULES="$ENABLED_MODULES mod-npc-buffer"
|
||||
[ "$MODULE_DYNAMIC_XP" = "1" ] && ENABLED_MODULES="$ENABLED_MODULES mod-dynamic-xp"
|
||||
[ "$MODULE_SOLO_LFG" = "1" ] && ENABLED_MODULES="$ENABLED_MODULES mod-solo-lfg"
|
||||
[ "$MODULE_1V1_ARENA" = "1" ] && ENABLED_MODULES="$ENABLED_MODULES mod-1v1-arena"
|
||||
[ "$MODULE_PHASED_DUELS" = "1" ] && ENABLED_MODULES="$ENABLED_MODULES mod-phased-duels"
|
||||
[ "$MODULE_BREAKING_NEWS" = "1" ] && ENABLED_MODULES="$ENABLED_MODULES mod-breaking-news-override"
|
||||
[ "$MODULE_BOSS_ANNOUNCER" = "1" ] && ENABLED_MODULES="$ENABLED_MODULES mod-boss-announcer"
|
||||
[ "$MODULE_ACCOUNT_ACHIEVEMENTS" = "1" ] && ENABLED_MODULES="$ENABLED_MODULES mod-account-achievements"
|
||||
[ "$MODULE_AUTO_REVIVE" = "1" ] && ENABLED_MODULES="$ENABLED_MODULES mod-auto-revive"
|
||||
[ "$MODULE_GAIN_HONOR_GUARD" = "1" ] && ENABLED_MODULES="$ENABLED_MODULES mod-gain-honor-guard"
|
||||
[ "$MODULE_ELUNA" = "1" ] && ENABLED_MODULES="$ENABLED_MODULES mod-eluna"
|
||||
[ "$MODULE_TIME_IS_TIME" = "1" ] && ENABLED_MODULES="$ENABLED_MODULES mod-time-is-time"
|
||||
[ "$MODULE_POCKET_PORTAL" = "1" ] && ENABLED_MODULES="$ENABLED_MODULES mod-pocket-portal"
|
||||
[ "$MODULE_RANDOM_ENCHANTS" = "1" ] && ENABLED_MODULES="$ENABLED_MODULES mod-random-enchants"
|
||||
[ "$MODULE_SOLOCRAFT" = "1" ] && ENABLED_MODULES="$ENABLED_MODULES mod-solocraft"
|
||||
[ "$MODULE_PVP_TITLES" = "1" ] && ENABLED_MODULES="$ENABLED_MODULES mod-pvp-titles"
|
||||
[ "$MODULE_NPC_BEASTMASTER" = "1" ] && ENABLED_MODULES="$ENABLED_MODULES mod-npc-beastmaster"
|
||||
[ "$MODULE_NPC_ENCHANTER" = "1" ] && ENABLED_MODULES="$ENABLED_MODULES mod-npc-enchanter"
|
||||
[ "$MODULE_INSTANCE_RESET" = "1" ] && ENABLED_MODULES="$ENABLED_MODULES mod-instance-reset"
|
||||
[ "$MODULE_LEVEL_GRANT" = "1" ] && ENABLED_MODULES="$ENABLED_MODULES mod-quest-count-level"
|
||||
|
||||
# Install Fireworks on Level if enabled
|
||||
if [ "$MODULE_FIREWORKS" = "1" ] && [ ! -d "mod-fireworks-on-level" ]; then
|
||||
echo 'Installing mod-fireworks-on-level...'
|
||||
git clone https://github.com/azerothcore/mod-fireworks-on-level.git mod-fireworks-on-level
|
||||
fi
|
||||
if [ -n "$ENABLED_MODULES" ]; then
|
||||
ENABLED_COUNT=$(echo $ENABLED_MODULES | wc -w)
|
||||
echo "🔧 Detected $ENABLED_COUNT enabled C++ modules requiring compilation:"
|
||||
for mod in $ENABLED_MODULES; do
|
||||
echo " • $mod"
|
||||
done
|
||||
|
||||
# Install Individual Progression if enabled
|
||||
if [ "$MODULE_INDIVIDUAL_PROGRESSION" = "1" ] && [ ! -d "mod-individual-progression" ]; then
|
||||
echo 'Installing mod-individual-progression...'
|
||||
git clone https://github.com/azerothcore/mod-individual-progression.git mod-individual-progression
|
||||
if [ "$REBUILD_REQUIRED" = "1" ]; then
|
||||
echo ""
|
||||
echo "🚨 REBUILD REQUIRED 🚨"
|
||||
echo "Module configuration has changed. To integrate C++ modules into AzerothCore:"
|
||||
echo ""
|
||||
echo "1. Stop current services:"
|
||||
echo " docker compose -f docker-compose-azerothcore-services.yml down"
|
||||
echo ""
|
||||
echo "2. Build with source-based compilation:"
|
||||
echo " docker compose -f /tmp/acore-dev-test/docker-compose.yml build"
|
||||
echo " docker compose -f /tmp/acore-dev-test/docker-compose.yml up -d"
|
||||
echo ""
|
||||
echo "3. Or use the automated rebuild script (if available):"
|
||||
echo " ./rebuild-with-modules.sh"
|
||||
echo ""
|
||||
echo "📋 NOTE: Source-based build will compile AzerothCore with all enabled modules"
|
||||
echo "⏱️ Expected build time: 15-45 minutes depending on system performance"
|
||||
echo ""
|
||||
fi
|
||||
else
|
||||
echo "✅ No C++ modules enabled - pre-built containers can be used"
|
||||
fi
|
||||
|
||||
echo 'Module management complete. Keeping container alive...'
|
||||
|
||||
@@ -21,7 +21,7 @@ MYSQL_PORT=3306
|
||||
# Storage root path - local: ./storage, production: /nfs/containers or custom mount
|
||||
STORAGE_ROOT=./storage
|
||||
# Storage for tools (unified with core stack)
|
||||
STORAGE_PATH_TOOLS=${STORAGE_ROOT}/azerothcore
|
||||
STORAGE_PATH=${STORAGE_ROOT}/azerothcore
|
||||
|
||||
# ==============================================
|
||||
# NETWORK CONFIGURATION (REQUIRED)
|
||||
|
||||
@@ -82,7 +82,7 @@ services:
|
||||
ports:
|
||||
- "${INFLUXDB_EXTERNAL_PORT:-8087}:8086"
|
||||
volumes:
|
||||
- ${STORAGE_PATH_TOOLS:-./storage/azerothcore}/azerothcore/influxdb:/var/lib/influxdb2
|
||||
- ${STORAGE_PATH:-./storage/azerothcore}/azerothcore/influxdb:/var/lib/influxdb2
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
- azerothcore
|
||||
@@ -110,7 +110,7 @@ services:
|
||||
ports:
|
||||
- "${GF_EXTERNAL_PORT:-3001}:3000"
|
||||
volumes:
|
||||
- ${STORAGE_PATH_TOOLS:-./storage/azerothcore}/azerothcore/grafana:/var/lib/grafana
|
||||
- ${STORAGE_PATH:-./storage/azerothcore}/azerothcore/grafana:/var/lib/grafana
|
||||
entrypoint: ["/bin/bash", "-c"]
|
||||
command:
|
||||
- |
|
||||
|
||||
75
docker-compose-test-worldserver.env
Normal file
75
docker-compose-test-worldserver.env
Normal file
@@ -0,0 +1,75 @@
|
||||
# ==============================================
|
||||
# TEST WORLDSERVER ENVIRONMENT CONFIGURATION
|
||||
# ==============================================
|
||||
# This configuration is for testing worldserver with
|
||||
# local game files vs. external volume mount
|
||||
|
||||
# ==============================================
|
||||
# IMAGE CONFIGURATION (REQUIRED)
|
||||
# ==============================================
|
||||
AC_WORLDSERVER_IMAGE=acore/ac-wotlk-worldserver:14.0.0-dev
|
||||
IMAGE_PULL_POLICY=if_not_present
|
||||
|
||||
# ==============================================
|
||||
# PLAYERBOT CONFIGURATION (OPTIONAL)
|
||||
# ==============================================
|
||||
# Playerbot settings for AI-controlled bots
|
||||
PLAYERBOT_ENABLED=1
|
||||
PLAYERBOT_MAX_BOTS=40
|
||||
|
||||
# ==============================================
|
||||
# HEALTH CHECK CONFIGURATION
|
||||
# ==============================================
|
||||
# World server health check - extended for download time
|
||||
WORLD_HEALTHCHECK_INTERVAL=30s
|
||||
WORLD_HEALTHCHECK_TIMEOUT=10s
|
||||
WORLD_HEALTHCHECK_RETRIES=3
|
||||
WORLD_HEALTHCHECK_START_PERIOD=1800s # 30 minutes for download/extraction
|
||||
|
||||
# ==============================================
|
||||
# NETWORK CONFIGURATION (REQUIRED)
|
||||
# ==============================================
|
||||
# Test external ports (different from main deployment)
|
||||
WORLD_EXTERNAL_PORT_TEST=8216 # Different port to avoid conflict
|
||||
SOAP_EXTERNAL_PORT_TEST=7779 # Different port to avoid conflict
|
||||
|
||||
# Internal ports (container side)
|
||||
WORLD_PORT=8085
|
||||
SOAP_PORT=7878
|
||||
|
||||
# ==============================================
|
||||
# DEPLOYMENT CONFIGURATION (REQUIRED)
|
||||
# ==============================================
|
||||
# Storage root path - local: ./storage, production: /nfs/containers or custom mount
|
||||
STORAGE_ROOT=./storage
|
||||
# Storage configuration (same as other layers for config/logs)
|
||||
STORAGE_PATH=${STORAGE_ROOT}/azerothcore
|
||||
|
||||
# ==============================================
|
||||
# CONTAINER NAMES (REQUIRED)
|
||||
# ==============================================
|
||||
# Test container name to avoid conflicts
|
||||
CONTAINER_WORLDSERVER_TEST=ac-worldserver-test
|
||||
|
||||
# Database container name (for external linking)
|
||||
CONTAINER_MYSQL=ac-mysql
|
||||
|
||||
# ==============================================
|
||||
# NETWORK SETTINGS (REQUIRED)
|
||||
# ==============================================
|
||||
# Network must already exist from database layer
|
||||
NETWORK_NAME=azerothcore
|
||||
|
||||
# ==============================================
|
||||
# DATABASE CONFIGURATION (REQUIRED)
|
||||
# ==============================================
|
||||
# Database credentials and connection info
|
||||
MYSQL_HOST=ac-mysql
|
||||
MYSQL_PORT=3306
|
||||
MYSQL_USER=root
|
||||
MYSQL_ROOT_PASSWORD=azerothcore123
|
||||
|
||||
# Database names
|
||||
DB_AUTH_NAME=acore_auth
|
||||
DB_WORLD_NAME=acore_world
|
||||
DB_CHARACTERS_NAME=acore_characters
|
||||
192
docker-compose-test-worldserver.yml
Normal file
192
docker-compose-test-worldserver.yml
Normal file
@@ -0,0 +1,192 @@
|
||||
# ==============================================
|
||||
# TEST WORLDSERVER WITH LOCAL GAME FILES
|
||||
# ==============================================
|
||||
# This is a test configuration to compare performance
|
||||
# of worldserver with game files stored locally within
|
||||
# the container vs. external volume mount
|
||||
|
||||
services:
|
||||
# Test world server with local game files (no external data volume)
|
||||
ac-worldserver-test:
|
||||
image: ${AC_WORLDSERVER_IMAGE}
|
||||
pull_policy: ${IMAGE_PULL_POLICY}
|
||||
container_name: ${CONTAINER_WORLDSERVER_TEST}
|
||||
user: "0:0" # Run as root to handle permissions
|
||||
stdin_open: true
|
||||
tty: true
|
||||
# depends_on:
|
||||
# - ac-authserver # Assumes authserver is already running from main deployment
|
||||
environment:
|
||||
AC_LOGIN_DATABASE_INFO: "${CONTAINER_MYSQL};${MYSQL_PORT};${MYSQL_USER};${MYSQL_ROOT_PASSWORD};${DB_AUTH_NAME}"
|
||||
AC_WORLD_DATABASE_INFO: "${CONTAINER_MYSQL};${MYSQL_PORT};${MYSQL_USER};${MYSQL_ROOT_PASSWORD};${DB_WORLD_NAME}"
|
||||
AC_CHARACTER_DATABASE_INFO: "${CONTAINER_MYSQL};${MYSQL_PORT};${MYSQL_USER};${MYSQL_ROOT_PASSWORD};${DB_CHARACTERS_NAME}"
|
||||
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"
|
||||
PLAYERBOT_ENABLED: "${PLAYERBOT_ENABLED}"
|
||||
PLAYERBOT_MAX_BOTS: "${PLAYERBOT_MAX_BOTS}"
|
||||
# Logger configuration - Use config file defaults with proper log level
|
||||
AC_LOG_LEVEL: "2"
|
||||
ports:
|
||||
- "${WORLD_EXTERNAL_PORT_TEST}:${WORLD_PORT}"
|
||||
- "${SOAP_EXTERNAL_PORT_TEST}:${SOAP_PORT}"
|
||||
volumes:
|
||||
# Only mount config and logs, NOT the data directory (game files will be internal)
|
||||
- ${STORAGE_PATH}/config:/azerothcore/env/dist/etc
|
||||
- ${STORAGE_PATH}/logs-test:/azerothcore/logs
|
||||
- ${STORAGE_PATH}/modules:/azerothcore/modules
|
||||
# Mount cache directory to persist downloaded files across container restarts
|
||||
- ${STORAGE_PATH}/cache-test:/cache
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
- azerothcore
|
||||
cap_add:
|
||||
- SYS_NICE
|
||||
entrypoint: ["/bin/bash", "-c"]
|
||||
command:
|
||||
- |
|
||||
echo "🧪 Starting TEST worldserver with local game files..."
|
||||
|
||||
# Install required packages for downloading
|
||||
echo "📦 Installing download tools..."
|
||||
apt-get update > /dev/null 2>&1
|
||||
apt-get install -y curl wget unzip ca-certificates > /dev/null 2>&1
|
||||
|
||||
# Create cache and data directories
|
||||
mkdir -p /cache /azerothcore/data
|
||||
|
||||
echo "🧪 Starting TEST worldserver with cached local game files..."
|
||||
echo "📂 Cache directory: /cache (persistent across restarts)"
|
||||
echo "🎯 Game files will be copied to local container storage for performance testing"
|
||||
|
||||
cd /tmp
|
||||
|
||||
# Get the latest release info from wowgaming/client-data
|
||||
echo '📡 Fetching latest client data release info...'
|
||||
RELEASE_INFO=$$(wget -qO- https://api.github.com/repos/wowgaming/client-data/releases/latest 2>/dev/null)
|
||||
|
||||
if [ -n "$$RELEASE_INFO" ]; then
|
||||
LATEST_URL=$$(echo "$$RELEASE_INFO" | grep '"browser_download_url":' | grep '\.zip' | cut -d'"' -f4 | head -1)
|
||||
LATEST_TAG=$$(echo "$$RELEASE_INFO" | grep '"tag_name":' | cut -d'"' -f4)
|
||||
fi
|
||||
|
||||
if [ -z "$$LATEST_URL" ]; then
|
||||
echo '❌ Could not fetch latest release URL'
|
||||
echo '📥 Using fallback: direct download from v16 release'
|
||||
LATEST_URL='https://github.com/wowgaming/client-data/releases/download/v16/data.zip'
|
||||
LATEST_TAG='v16'
|
||||
fi
|
||||
|
||||
echo "📍 Latest release: $$LATEST_TAG"
|
||||
echo "📥 Download URL: $$LATEST_URL"
|
||||
|
||||
# Cache file paths
|
||||
CACHE_FILE="/cache/client-data-$$LATEST_TAG.zip"
|
||||
VERSION_FILE="/cache/client-data-version.txt"
|
||||
|
||||
# Check if we have a cached version
|
||||
if [ -f "$$CACHE_FILE" ] && [ -f "$$VERSION_FILE" ]; then
|
||||
CACHED_VERSION=$$(cat "$$VERSION_FILE" 2>/dev/null)
|
||||
if [ "$$CACHED_VERSION" = "$$LATEST_TAG" ]; then
|
||||
echo "🎉 Found cached client data for $$LATEST_TAG"
|
||||
echo "📊 Cached file size: $$(ls -lh "$$CACHE_FILE" | awk '{print $$5}')"
|
||||
echo "⚡ Using cached download (no internet download needed)"
|
||||
cp "$$CACHE_FILE" data.zip
|
||||
else
|
||||
echo "🔄 Cached version ($$CACHED_VERSION) differs from latest ($$LATEST_TAG)"
|
||||
echo "📥 Downloading new version..."
|
||||
wget --progress=dot:giga -O "$$CACHE_FILE.tmp" "$$LATEST_URL"
|
||||
if [ $$? -eq 0 ]; then
|
||||
mv "$$CACHE_FILE.tmp" "$$CACHE_FILE"
|
||||
echo "$$LATEST_TAG" > "$$VERSION_FILE"
|
||||
echo "✅ Download completed and cached"
|
||||
cp "$$CACHE_FILE" data.zip
|
||||
else
|
||||
echo "❌ Download failed!"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
else
|
||||
echo "💾 No cache found, downloading and caching..."
|
||||
echo "⏱️ Download started at: $(date)"
|
||||
wget --progress=dot:giga -O "$$CACHE_FILE.tmp" "$$LATEST_URL"
|
||||
if [ $$? -eq 0 ]; then
|
||||
mv "$$CACHE_FILE.tmp" "$$CACHE_FILE"
|
||||
echo "$$LATEST_TAG" > "$$VERSION_FILE"
|
||||
echo "✅ Download completed and cached at: $(date)"
|
||||
echo "📊 File size: $$(ls -lh "$$CACHE_FILE" | awk '{print $$5}')"
|
||||
cp "$$CACHE_FILE" data.zip
|
||||
else
|
||||
echo "❌ Download failed!"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# Extract game files to local container storage for performance testing
|
||||
echo "📂 Extracting client data to local container storage..."
|
||||
echo "🎯 This tests performance with files stored locally vs. external volume"
|
||||
echo "⏱️ Extraction started at: $(date)"
|
||||
|
||||
# Clear any existing data
|
||||
rm -rf /azerothcore/data/maps /azerothcore/data/vmaps /azerothcore/data/mmaps /azerothcore/data/dbc
|
||||
|
||||
# Extract with progress monitoring
|
||||
unzip -o -q data.zip -d /azerothcore/data/ &
|
||||
UNZIP_PID=$!
|
||||
|
||||
# Simple progress indicator
|
||||
while kill -0 "$$UNZIP_PID" 2>/dev/null; do
|
||||
echo "⏳ Extracting... ($(date '+%H:%M:%S'))"
|
||||
sleep 30
|
||||
done
|
||||
|
||||
wait $$UNZIP_PID
|
||||
UNZIP_EXIT_CODE=$$?
|
||||
|
||||
if [ $$UNZIP_EXIT_CODE -ne 0 ]; then
|
||||
echo "❌ Extraction failed!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Clean up zip file
|
||||
rm -f data.zip
|
||||
|
||||
echo "✅ Extraction completed at: $(date)"
|
||||
echo "💾 Game files are now stored locally in container for performance testing"
|
||||
|
||||
# Verify required directories exist and have content
|
||||
echo '📁 Verifying extracted directories:'
|
||||
ALL_GOOD=true
|
||||
for dir in maps vmaps mmaps dbc; do
|
||||
if [ -d "/azerothcore/data/$$dir" ] && [ -n "$$(ls -A /azerothcore/data/$$dir 2>/dev/null)" ]; then
|
||||
DIR_SIZE=$$(du -sh /azerothcore/data/$$dir 2>/dev/null | cut -f1)
|
||||
echo "✅ $$dir directory: OK ($$DIR_SIZE)"
|
||||
else
|
||||
echo "❌ $$dir directory: MISSING or EMPTY"
|
||||
ALL_GOOD=false
|
||||
fi
|
||||
done
|
||||
|
||||
if [ "$$ALL_GOOD" != "true" ]; then
|
||||
echo "❌ Game data verification failed!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "🎉 Local game data setup complete!"
|
||||
echo "🚀 Starting worldserver..."
|
||||
echo "⏱️ Worldserver startup time: $(date)"
|
||||
|
||||
# Start the worldserver
|
||||
exec /azerothcore/env/dist/bin/worldserver
|
||||
healthcheck:
|
||||
test: ["CMD", "sh", "-c", "ps aux | grep '[w]orldserver' | grep -v grep || exit 1"]
|
||||
interval: ${WORLD_HEALTHCHECK_INTERVAL}
|
||||
timeout: ${WORLD_HEALTHCHECK_TIMEOUT}
|
||||
retries: ${WORLD_HEALTHCHECK_RETRIES}
|
||||
start_period: 1800s # 30 minutes to allow for download and extraction
|
||||
|
||||
networks:
|
||||
azerothcore:
|
||||
external: true
|
||||
110
readme.md
110
readme.md
@@ -24,6 +24,7 @@ This project is a Docker/Podman implementation based on:
|
||||
## Table of Contents
|
||||
- [Overview](#overview)
|
||||
- [Features](#features)
|
||||
- [Available Modules](#available-modules)
|
||||
- [Requirements](#requirements)
|
||||
- [Project Structure](#project-structure)
|
||||
- [Container Architecture](#container-architecture)
|
||||
@@ -76,6 +77,103 @@ This project provides a production-ready AzerothCore deployment using Docker/Pod
|
||||
- ✅ **Network Isolation**: Custom bridge network for container communication
|
||||
- ✅ **Persistent Storage**: Named volumes for data persistence
|
||||
|
||||
## Available Modules
|
||||
|
||||
This deployment includes an automated module management system that supports 28 AzerothCore modules. All modules are automatically downloaded from GitHub when enabled and include proper configuration files.
|
||||
|
||||
### Quality of Life Modules
|
||||
|
||||
| Module | Description | Repository | README | Post-Install Notes |
|
||||
|--------|-------------|------------|--------|-------------------|
|
||||
| **AutoBalance** | Dynamic difficulty scaling for dungeons/raids | [mod-autobalance](https://github.com/azerothcore/mod-autobalance) | [📖](https://github.com/azerothcore/mod-autobalance/blob/master/README.md) | Requires AutoBalance.conf configuration |
|
||||
| **AHBot** | Auction House bot for populated auctions | [mod-ahbot](https://github.com/azerothcore/mod-ahbot) | [📖](https://github.com/azerothcore/mod-ahbot/blob/master/README.md) | Requires mod_ahbot.conf configuration |
|
||||
| **Transmog** | Transmogrification system | [mod-transmog](https://github.com/azerothcore/mod-transmog) | [📖](https://github.com/azerothcore/mod-transmog/blob/master/README.md) | Requires transmog.conf configuration |
|
||||
| **NPC Buffer** | Buff NPC services | [mod-npc-buffer](https://github.com/azerothcore/mod-npc-buffer) | [📖](https://github.com/azerothcore/mod-npc-buffer/blob/master/README.md) | Requires npc_buffer.conf configuration |
|
||||
| **AoE Loot** | Area of effect looting feature | [mod-aoe-loot](https://github.com/azerothcore/mod-aoe-loot) | [📖](https://github.com/azerothcore/mod-aoe-loot/blob/master/.github/README.md) | No additional configuration required |
|
||||
| **Learn Spells** | Automatic spell learning | [mod-learn-spells](https://github.com/azerothcore/mod-learn-spells) | [📖](https://github.com/azerothcore/mod-learn-spells/blob/master/README.md) | Requires mod_learnspells.conf configuration |
|
||||
| **Auto Revive** | Auto-revive functionality for GMs | [mod-auto-revive](https://github.com/azerothcore/mod-auto-revive) | [📖](https://github.com/azerothcore/mod-auto-revive/blob/master/README.md) | Requires AutoRevive.conf configuration |
|
||||
| **NPC Enchanter** | NPC-based gear enchantment services | [mod-npc-enchanter](https://github.com/azerothcore/mod-npc-enchanter) | [📖](https://github.com/azerothcore/mod-npc-enchanter/blob/master/README.md) | Requires npc_enchanter.conf configuration |
|
||||
| **Instance Reset** | NPC-based instance reset functionality | [mod-instance-reset](https://github.com/azerothcore/mod-instance-reset) | [📖](https://github.com/azerothcore/mod-instance-reset/blob/master/README.md) | Requires instance-reset.conf configuration |
|
||||
|
||||
### Gameplay Enhancement Modules
|
||||
|
||||
| Module | Description | Repository | README | Post-Install Notes |
|
||||
|--------|-------------|------------|--------|-------------------|
|
||||
| **Individual Progression** | Custom character progression system | [mod-individual-progression](https://github.com/ZhengPeiRu21/mod-individual-progression) | [📖](https://github.com/ZhengPeiRu21/mod-individual-progression/blob/master/README.md) | Complex SQL imports required |
|
||||
| **Dynamic XP** | Configurable experience rates | [mod-dynamic-xp](https://github.com/azerothcore/mod-dynamic-xp) | [📖](https://github.com/azerothcore/mod-dynamic-xp/blob/master/README.md) | Requires Individual-XP.conf configuration |
|
||||
| **Solo LFG** | Solo dungeon finder system | [mod-solo-lfg](https://github.com/azerothcore/mod-solo-lfg) | [📖](https://github.com/azerothcore/mod-solo-lfg/blob/master/README.md) | Requires SoloLfg.conf configuration |
|
||||
| **1v1 Arena** | Arena combat system | [mod-1v1-arena](https://github.com/azerothcore/mod-1v1-arena) | [📖](https://github.com/azerothcore/mod-1v1-arena/blob/master/README.md) | Database tables auto-created |
|
||||
| **Phased Duels** | Isolated dueling system | [mod-phased-duels](https://github.com/azerothcore/mod-phased-duels) | [📖](https://github.com/azerothcore/mod-phased-duels/blob/master/README.md) | No additional configuration required |
|
||||
| **Solocraft** | Solo dungeon scaling | [mod-solocraft](https://github.com/azerothcore/mod-solocraft) | [📖](https://github.com/azerothcore/mod-solocraft/blob/master/.github/README.md) | Requires Solocraft.conf configuration |
|
||||
| **Random Enchants** | Random item enchantments | [mod-random-enchants](https://github.com/azerothcore/mod-random-enchants) | [📖](https://github.com/azerothcore/mod-random-enchants/blob/master/README.md) | Requires RandomEnchants.conf configuration |
|
||||
| **Level Grant** | Quest-based level granting | [mod-quest-count-level](https://github.com/michaeldelago/mod-quest-count-level) | [📖](https://github.com/michaeldelago/mod-quest-count-level/blob/main/README.md) | Requires levelGrant.conf configuration |
|
||||
|
||||
### Server Management Modules
|
||||
|
||||
| Module | Description | Repository | README | Post-Install Notes |
|
||||
|--------|-------------|------------|--------|-------------------|
|
||||
| **Breaking News Override** | Server announcement system | [mod-breaking-news-override](https://github.com/azerothcore/mod-breaking-news-override) | [📖](https://github.com/azerothcore/mod-breaking-news-override/blob/master/README.md) | No additional configuration required |
|
||||
| **Boss Announcer** | Raid boss kill notifications | [mod-boss-announcer](https://github.com/azerothcore/mod-boss-announcer) | [📖](https://github.com/azerothcore/mod-boss-announcer/blob/master/README.md) | No additional configuration required |
|
||||
| **Account Achievements** | Cross-character achievements | [mod-account-achievements](https://github.com/azerothcore/mod-account-achievements) | [📖](https://github.com/azerothcore/mod-account-achievements/blob/master/README.md) | Database tables auto-created |
|
||||
| **Gain Honor Guard** | Honor system for killing guards | [mod-gain-honor-guard](https://github.com/azerothcore/mod-gain-honor-guard) | [📖](https://github.com/azerothcore/mod-gain-honor-guard/blob/master/.github/README.md) | Requires GainHonorGuard.conf configuration |
|
||||
| **PvP Titles** | Honor-based PvP title system | [mod-pvp-titles](https://github.com/azerothcore/mod-pvp-titles) | [📖](https://github.com/azerothcore/mod-pvp-titles/blob/master/README.md) | Requires mod_pvptitles.conf configuration |
|
||||
| **Pocket Portal** | Teleportation portal system | [mod-pocket-portal](https://github.com/azerothcore/mod-pocket-portal) | [📖](https://github.com/azerothcore/mod-pocket-portal/blob/master/README.md) | Requires pocketportal.conf configuration |
|
||||
|
||||
### Core System Modules
|
||||
|
||||
| Module | Description | Repository | README | Post-Install Notes |
|
||||
|--------|-------------|------------|--------|-------------------|
|
||||
| **Playerbots** | AI-controlled bot system | [mod-playerbots](https://github.com/liyunfan1223/mod-playerbots) | [📖](https://github.com/liyunfan1223/mod-playerbots/blob/master/README.md) | Enabled by default, extensive configuration |
|
||||
| **Fireworks** | Fireworks on level up | [mod-fireworks-on-level](https://github.com/azerothcore/mod-fireworks-on-level) | [📖](https://github.com/azerothcore/mod-fireworks-on-level/blob/master/README.md) | No additional configuration required |
|
||||
| **Eluna** | Lua scripting engine | [mod-eluna](https://github.com/azerothcore/mod-eluna) | [📖](https://github.com/azerothcore/mod-eluna/blob/master/README.md) | Requires mod_LuaEngine.conf configuration |
|
||||
| **Time Is Time** | Realistic day/night cycle | [mod-TimeIsTime](https://github.com/dunjeon/mod-TimeIsTime) | [📖](https://github.com/dunjeon/mod-TimeIsTime/blob/main/README.md) | Requires mod-time_is_time.conf configuration |
|
||||
| **NPC Beastmaster** | Cross-class pet system | [mod-npc-beastmaster](https://github.com/azerothcore/mod-npc-beastmaster) | [📖](https://github.com/azerothcore/mod-npc-beastmaster/blob/master/README.md) | Requires npc_beastmaster.conf configuration |
|
||||
|
||||
### Module Configuration
|
||||
|
||||
Enable modules by setting their environment variables to `1` in `docker-compose-azerothcore-services.env`:
|
||||
|
||||
```bash
|
||||
# Example: Enable AutoBalance and Transmog
|
||||
MODULE_AUTOBALANCE=1
|
||||
MODULE_TRANSMOG=1
|
||||
```
|
||||
|
||||
After enabling/disabling modules:
|
||||
1. Restart the module container: `docker-compose up -d ac-modules`
|
||||
2. **Enabled modules** will be automatically downloaded to `storage/azerothcore/modules/`
|
||||
3. **Disabled modules** will be automatically removed from the modules directory
|
||||
4. **Configuration files** (`.conf.dist`) are automatically managed:
|
||||
- **Enabled modules**: Config files copied to `storage/azerothcore/config/`
|
||||
- **Disabled modules**: Config files removed from config directory
|
||||
5. **Important**: Modules require server recompilation to be active
|
||||
6. Some modules require database imports (check individual module README files)
|
||||
|
||||
### Module Management Behavior
|
||||
|
||||
The module management system provides complete automation:
|
||||
|
||||
- **Enable Module** (`MODULE_NAME=1`):
|
||||
- Downloads module source code if not present
|
||||
- Copies `.conf.dist` files to config directory
|
||||
- **Disable Module** (`MODULE_NAME=0`):
|
||||
- Removes module directory completely
|
||||
- Removes associated configuration files
|
||||
- **Module Persistence**: Only enabled modules and their configs remain
|
||||
- **Clean Slate**: Disabling and re-enabling ensures fresh download and config
|
||||
- **Zero Manual Setup**: No need to manually copy configuration files
|
||||
|
||||
### Post-Installation Requirements
|
||||
|
||||
⚠️ **Critical**: Most modules require additional steps after download:
|
||||
|
||||
1. **Server Recompilation**: Modules need to be compiled into the server
|
||||
2. **Configuration Files**: Copy `.conf` files to config directory
|
||||
3. **Database Imports**: Some modules include SQL files for database schema
|
||||
4. **Module-Specific Setup**: Check each module's README for specific requirements
|
||||
|
||||
See the [AzerothCore Module Documentation](https://www.azerothcore.org/wiki/installing-a-module) for complete installation procedures.
|
||||
|
||||
## Requirements
|
||||
|
||||
### System Requirements
|
||||
@@ -241,11 +339,11 @@ Configuration is managed through separate `.env` files for each layer:
|
||||
- **Local development**: `./storage`
|
||||
- **Production NFS**: `/nfs/containers`
|
||||
- **Custom mount**: `/mnt/azerothcore-data`
|
||||
- All layers derive their storage paths from `STORAGE_ROOT`:
|
||||
- Database: `${STORAGE_ROOT}/azerothcore`
|
||||
- Services: `${STORAGE_ROOT}/azerothcore`
|
||||
- Tools: `${STORAGE_ROOT}/azerothcore`
|
||||
- Optional: `${STORAGE_ROOT}/azerothcore`
|
||||
- All layers use the same `STORAGE_PATH` variable derived from `STORAGE_ROOT`:
|
||||
- Database: `STORAGE_PATH=${STORAGE_ROOT}/azerothcore`
|
||||
- Services: `STORAGE_PATH=${STORAGE_ROOT}/azerothcore`
|
||||
- Tools: `STORAGE_PATH=${STORAGE_ROOT}/azerothcore`
|
||||
- Optional: `STORAGE_PATH=${STORAGE_ROOT}/azerothcore`
|
||||
|
||||
#### Database Layer (`docker-compose-azerothcore-database.env`)
|
||||
- `MYSQL_ROOT_PASSWORD`: Database root password (default: azerothcore123)
|
||||
@@ -270,7 +368,7 @@ Configuration is managed through separate `.env` files for each layer:
|
||||
- `GF_EXTERNAL_PORT`: Grafana monitoring port (3001)
|
||||
- `INFLUXDB_EXTERNAL_PORT`: InfluxDB metrics port (8087)
|
||||
- `STORAGE_ROOT`: Root storage path (default: ./storage)
|
||||
- `STORAGE_PATH_TOOLS`: Derived storage path (${STORAGE_ROOT}/azerothcore)
|
||||
- `STORAGE_PATH`: Derived storage path (${STORAGE_ROOT}/azerothcore)
|
||||
|
||||
### Realm Configuration
|
||||
|
||||
|
||||
128
rebuild-with-modules.sh
Executable file
128
rebuild-with-modules.sh
Executable file
@@ -0,0 +1,128 @@
|
||||
#!/bin/bash
|
||||
|
||||
# AzerothCore Module Rebuild Script
|
||||
# Automates the process of rebuilding AzerothCore with enabled modules
|
||||
|
||||
set -e
|
||||
|
||||
echo "🔧 AzerothCore Module Rebuild Script"
|
||||
echo "==================================="
|
||||
echo ""
|
||||
|
||||
# Check if source repository exists
|
||||
SOURCE_COMPOSE="/tmp/acore-dev-test/docker-compose.yml"
|
||||
if [ ! -f "$SOURCE_COMPOSE" ]; then
|
||||
echo "❌ Error: Source-based Docker Compose file not found at $SOURCE_COMPOSE"
|
||||
echo "Please ensure AzerothCore source repository is available for compilation."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check current module configuration
|
||||
echo "📋 Checking current module configuration..."
|
||||
|
||||
MODULES_ENABLED=0
|
||||
ENABLED_MODULES=""
|
||||
|
||||
# Read environment file to check enabled modules
|
||||
if [ -f "docker-compose-azerothcore-services.env" ]; then
|
||||
while IFS= read -r line; do
|
||||
if echo "$line" | grep -q "^MODULE_.*=1$"; then
|
||||
MODULE_NAME=$(echo "$line" | cut -d'=' -f1)
|
||||
MODULES_ENABLED=$((MODULES_ENABLED + 1))
|
||||
ENABLED_MODULES="$ENABLED_MODULES $MODULE_NAME"
|
||||
fi
|
||||
done < docker-compose-azerothcore-services.env
|
||||
else
|
||||
echo "⚠️ Warning: Environment file not found, checking default configuration..."
|
||||
fi
|
||||
|
||||
echo "🔍 Found $MODULES_ENABLED enabled modules"
|
||||
|
||||
if [ $MODULES_ENABLED -eq 0 ]; then
|
||||
echo "✅ No modules enabled - rebuild not required"
|
||||
echo "You can use pre-built containers for better performance."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "📦 Enabled modules:$ENABLED_MODULES"
|
||||
echo ""
|
||||
|
||||
# Confirm rebuild
|
||||
read -p "🤔 Proceed with rebuild? This will take 15-45 minutes. (y/N): " -n 1 -r
|
||||
echo ""
|
||||
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
||||
echo "❌ Rebuild cancelled"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "🛑 Stopping current services..."
|
||||
docker compose -f docker-compose-azerothcore-services.yml down || echo "⚠️ Services may not be running"
|
||||
|
||||
echo ""
|
||||
echo "🔧 Starting source-based compilation..."
|
||||
echo "⏱️ This will take 15-45 minutes depending on your system..."
|
||||
echo ""
|
||||
|
||||
# Build with source
|
||||
cd /tmp/acore-dev-test
|
||||
echo "📁 Switched to source directory: $(pwd)"
|
||||
|
||||
# Copy modules to source build
|
||||
echo "📋 Copying modules to source build..."
|
||||
if [ -d "/home/upb/src/acore-compose2/storage/azerothcore/modules" ]; then
|
||||
# Ensure modules directory exists in source
|
||||
mkdir -p modules
|
||||
|
||||
# Copy enabled modules only
|
||||
echo "🔄 Syncing enabled modules..."
|
||||
for module_dir in /home/upb/src/acore-compose2/storage/azerothcore/modules/*/; do
|
||||
if [ -d "$module_dir" ]; then
|
||||
module_name=$(basename "$module_dir")
|
||||
echo " Copying $module_name..."
|
||||
cp -r "$module_dir" modules/
|
||||
fi
|
||||
done
|
||||
else
|
||||
echo "⚠️ Warning: No modules directory found"
|
||||
fi
|
||||
|
||||
# Start build process
|
||||
echo ""
|
||||
echo "🚀 Building AzerothCore with modules..."
|
||||
docker compose build --no-cache
|
||||
|
||||
if [ $? -eq 0 ]; then
|
||||
echo ""
|
||||
echo "✅ Build completed successfully!"
|
||||
echo ""
|
||||
|
||||
# Start services
|
||||
echo "🟢 Starting services with compiled modules..."
|
||||
docker compose up -d
|
||||
|
||||
if [ $? -eq 0 ]; then
|
||||
echo ""
|
||||
echo "🎉 SUCCESS! AzerothCore is now running with compiled modules."
|
||||
echo ""
|
||||
echo "📊 Service status:"
|
||||
docker compose ps
|
||||
echo ""
|
||||
echo "📝 To monitor logs:"
|
||||
echo " docker compose logs -f"
|
||||
echo ""
|
||||
echo "🌐 Server should be available on configured ports once fully started."
|
||||
else
|
||||
echo "❌ Failed to start services"
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
echo "❌ Build failed"
|
||||
echo ""
|
||||
echo "🔍 Check build logs for errors:"
|
||||
echo " docker compose logs"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "✅ Rebuild process complete!"
|
||||
172
scripts/TEST-LOCAL-WORLDSERVER.md
Normal file
172
scripts/TEST-LOCAL-WORLDSERVER.md
Normal file
@@ -0,0 +1,172 @@
|
||||
# Test Local Worldserver Performance
|
||||
|
||||
This test setup allows you to compare the performance of worldserver with game files stored locally within the container vs. external volume mount.
|
||||
|
||||
## What This Tests
|
||||
|
||||
### 🧪 **Test Configuration**: Local Game Files with NFS Caching
|
||||
- Game files (maps, vmaps, mmaps, DBC) cached on NFS and copied to local container storage
|
||||
- **No external volume mount** for `/azerothcore/data` (files stored locally for performance)
|
||||
- **NFS cache** for downloaded files (persistent across container restarts)
|
||||
- First run: ~15GB download and extraction time
|
||||
- Subsequent runs: ~5-10 minutes (extraction only from cache)
|
||||
|
||||
### 📊 **Comparison with Standard Configuration**: External Volume
|
||||
- Game files stored in external volume mount
|
||||
- Persistent across container restarts
|
||||
- One-time download, reused across deployments
|
||||
|
||||
## Quick Start
|
||||
|
||||
### Prerequisites
|
||||
Make sure the database and authserver are running first:
|
||||
|
||||
```bash
|
||||
# Start database layer
|
||||
docker-compose --env-file docker-compose-azerothcore-database.env -f docker-compose-azerothcore-database.yml up -d
|
||||
|
||||
# Start authserver (minimal requirement)
|
||||
docker-compose --env-file docker-compose-azerothcore-services.env -f docker-compose-azerothcore-services.yml up -d ac-authserver
|
||||
```
|
||||
|
||||
### Run the Test
|
||||
|
||||
```bash
|
||||
cd scripts
|
||||
|
||||
# Start test worldserver (downloads files locally)
|
||||
./test-local-worldserver.sh
|
||||
|
||||
# Monitor logs
|
||||
./test-local-worldserver.sh --logs
|
||||
|
||||
# Cleanup when done
|
||||
./test-local-worldserver.sh --cleanup
|
||||
```
|
||||
|
||||
## Test Details
|
||||
|
||||
### Port Configuration
|
||||
- **Test Worldserver**: `localhost:8216` (game), `localhost:7779` (SOAP)
|
||||
- **Regular Worldserver**: `localhost:8215` (game), `localhost:7778` (SOAP)
|
||||
|
||||
Both can run simultaneously without conflicts.
|
||||
|
||||
### Download Process
|
||||
The test worldserver will:
|
||||
1. Check for cached client data in NFS storage
|
||||
2. If cached: Copy from cache (fast)
|
||||
3. If not cached: Download ~15GB client data from GitHub releases and cache it
|
||||
4. Extract maps, vmaps, mmaps, and DBC files to local container storage
|
||||
5. Verify all required directories exist
|
||||
6. Start the worldserver
|
||||
|
||||
**Expected startup time**:
|
||||
- First run: 20-30 minutes (download + extraction)
|
||||
- Subsequent runs: 5-10 minutes (extraction only from cache)
|
||||
|
||||
### Storage Locations
|
||||
- **Game Files**: `/azerothcore/data` (inside container, not mounted - for performance testing)
|
||||
- **Cache**: External mount at `storage/azerothcore/cache-test/` (persistent across restarts)
|
||||
- **Config**: External mount (shared with regular deployment)
|
||||
- **Logs**: External mount at `storage/azerothcore/logs-test/`
|
||||
|
||||
## Performance Metrics to Compare
|
||||
|
||||
### Startup Time
|
||||
- **Regular**: ~2-3 minutes (files already extracted in external volume)
|
||||
- **Test (first run)**: ~20-30 minutes (download + extraction + cache)
|
||||
- **Test (cached)**: ~5-10 minutes (extraction only from cache)
|
||||
|
||||
### Runtime Performance
|
||||
Compare these during gameplay:
|
||||
- Map loading times
|
||||
- Zone transitions
|
||||
- Server responsiveness
|
||||
- Memory usage
|
||||
- CPU utilization
|
||||
|
||||
### Storage Usage
|
||||
- **Regular**: Persistent ~15GB in external volume
|
||||
- **Test**: ~15GB cache in external volume + ~15GB ephemeral inside container
|
||||
- **Test Total**: ~30GB during operation (cache + local copy)
|
||||
|
||||
## Monitoring Commands
|
||||
|
||||
```bash
|
||||
# Check container status
|
||||
docker ps | grep test
|
||||
|
||||
# Monitor logs
|
||||
docker logs ac-worldserver-test -f
|
||||
|
||||
# Check game data size (local in container)
|
||||
docker exec ac-worldserver-test du -sh /azerothcore/data/*
|
||||
|
||||
# Check cache size (persistent)
|
||||
ls -la storage/azerothcore/cache-test/
|
||||
du -sh storage/azerothcore/cache-test/*
|
||||
|
||||
# Check cached version
|
||||
cat storage/azerothcore/cache-test/client-data-version.txt
|
||||
|
||||
# Check server processes
|
||||
docker exec ac-worldserver-test ps aux | grep worldserver
|
||||
|
||||
# Monitor resource usage
|
||||
docker stats ac-worldserver-test
|
||||
```
|
||||
|
||||
## Testing Scenarios
|
||||
|
||||
### 1. Startup Performance
|
||||
```bash
|
||||
# Time the full startup
|
||||
time ./test-local-worldserver.sh
|
||||
|
||||
# Compare with regular worldserver restart
|
||||
docker restart ac-worldserver
|
||||
```
|
||||
|
||||
### 2. Runtime Performance
|
||||
Connect a game client to both servers and compare:
|
||||
- Zone loading times
|
||||
- Combat responsiveness
|
||||
- Large area rendering
|
||||
|
||||
### 3. Resource Usage
|
||||
```bash
|
||||
# Compare memory usage
|
||||
docker stats ac-worldserver ac-worldserver-test --no-stream
|
||||
|
||||
# Compare disk I/O
|
||||
docker exec ac-worldserver-test iostat 1 5
|
||||
docker exec ac-worldserver iostat 1 5
|
||||
```
|
||||
|
||||
## Cleanup
|
||||
|
||||
```bash
|
||||
# Stop and remove test container
|
||||
./test-local-worldserver.sh --cleanup
|
||||
|
||||
# Remove test logs
|
||||
rm -rf storage/azerothcore/logs-test/
|
||||
```
|
||||
|
||||
## Expected Results
|
||||
|
||||
### Pros of Local Files
|
||||
- Potentially faster file I/O (no network mount overhead)
|
||||
- Self-contained container
|
||||
- No external volume dependencies
|
||||
|
||||
### Cons of Local Files
|
||||
- Much longer startup time (20-30 minutes)
|
||||
- Re-download on every container recreation
|
||||
- Larger container footprint
|
||||
- No persistence across restarts
|
||||
|
||||
## Conclusion
|
||||
|
||||
This test will help determine if the performance benefits of local file storage outweigh the significant startup time and storage overhead costs.
|
||||
225
scripts/test-local-worldserver.sh
Executable file
225
scripts/test-local-worldserver.sh
Executable file
@@ -0,0 +1,225 @@
|
||||
#!/bin/bash
|
||||
|
||||
# ==============================================
|
||||
# TEST LOCAL WORLDSERVER DEPLOYMENT SCRIPT
|
||||
# ==============================================
|
||||
# This script tests worldserver performance with local game files
|
||||
# vs. external volume mount
|
||||
|
||||
set -e # Exit on any error
|
||||
|
||||
# Colors for output
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
MAGENTA='\033[0;35m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# Function to print colored output
|
||||
print_status() {
|
||||
local status=$1
|
||||
local message=$2
|
||||
case $status in
|
||||
"INFO")
|
||||
echo -e "${BLUE}ℹ️ ${message}${NC}"
|
||||
;;
|
||||
"SUCCESS")
|
||||
echo -e "${GREEN}✅ ${message}${NC}"
|
||||
;;
|
||||
"WARNING")
|
||||
echo -e "${YELLOW}⚠️ ${message}${NC}"
|
||||
;;
|
||||
"ERROR")
|
||||
echo -e "${RED}❌ ${message}${NC}"
|
||||
;;
|
||||
"HEADER")
|
||||
echo -e "\n${MAGENTA}=== ${message} ===${NC}"
|
||||
;;
|
||||
"TEST")
|
||||
echo -e "${YELLOW}🧪 ${message}${NC}"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
# Parse command line arguments
|
||||
CLEANUP=false
|
||||
LOGS=false
|
||||
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case $1 in
|
||||
--cleanup)
|
||||
CLEANUP=true
|
||||
shift
|
||||
;;
|
||||
--logs)
|
||||
LOGS=true
|
||||
shift
|
||||
;;
|
||||
-h|--help)
|
||||
echo "Test Local Worldserver Deployment Script"
|
||||
echo ""
|
||||
echo "Usage: $0 [OPTIONS]"
|
||||
echo ""
|
||||
echo "OPTIONS:"
|
||||
echo " --cleanup Stop and remove test worldserver"
|
||||
echo " --logs Follow test worldserver logs"
|
||||
echo " --help Show this help message"
|
||||
echo ""
|
||||
echo "EXAMPLES:"
|
||||
echo " $0 # Deploy test worldserver"
|
||||
echo " $0 --logs # Follow logs of running test"
|
||||
echo " $0 --cleanup # Clean up test deployment"
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
echo "Unknown option $1"
|
||||
echo "Use --help for usage information"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Change to parent directory for compose commands
|
||||
cd "$(dirname "$0")/.."
|
||||
|
||||
if [ "$CLEANUP" = true ]; then
|
||||
print_status "HEADER" "CLEANING UP TEST WORLDSERVER"
|
||||
|
||||
print_status "INFO" "Stopping test worldserver..."
|
||||
docker-compose --env-file docker-compose-test-worldserver.env -f docker-compose-test-worldserver.yml down
|
||||
|
||||
print_status "INFO" "Removing test container if exists..."
|
||||
docker rm -f ac-worldserver-test 2>/dev/null || true
|
||||
|
||||
print_status "SUCCESS" "Test cleanup completed"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [ "$LOGS" = true ]; then
|
||||
print_status "HEADER" "FOLLOWING TEST WORLDSERVER LOGS"
|
||||
docker logs ac-worldserver-test -f
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Main deployment
|
||||
print_status "HEADER" "DEPLOYING TEST WORLDSERVER WITH LOCAL GAME FILES"
|
||||
|
||||
# Check if docker is available
|
||||
if ! command -v docker &> /dev/null; then
|
||||
print_status "ERROR" "Docker is not installed or not in PATH"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check if main database is running
|
||||
if ! docker ps | grep ac-mysql > /dev/null; then
|
||||
print_status "ERROR" "Main database (ac-mysql) is not running"
|
||||
print_status "INFO" "Please start the database layer first:"
|
||||
print_status "INFO" " docker-compose --env-file docker-compose-azerothcore-database.env -f docker-compose-azerothcore-database.yml up -d"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check if authserver is running
|
||||
if ! docker ps | grep ac-authserver > /dev/null; then
|
||||
print_status "ERROR" "Auth server (ac-authserver) is not running"
|
||||
print_status "INFO" "Please start the services layer first (or at least authserver):"
|
||||
print_status "INFO" " docker-compose --env-file docker-compose-azerothcore-services.env -f docker-compose-azerothcore-services.yml up -d ac-authserver"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check if regular worldserver is running (warn about port conflicts)
|
||||
if docker ps | grep ac-worldserver | grep -v test > /dev/null; then
|
||||
print_status "WARNING" "Regular worldserver is running - test uses different ports"
|
||||
print_status "INFO" "Test worldserver ports: 8216 (world), 7779 (SOAP)"
|
||||
print_status "INFO" "Regular worldserver ports: 8215 (world), 7778 (SOAP)"
|
||||
fi
|
||||
|
||||
print_status "INFO" "Prerequisites check passed"
|
||||
|
||||
# Check for cached files
|
||||
if [ -f "storage/azerothcore/cache-test/client-data-version.txt" ]; then
|
||||
CACHED_VERSION=$(cat storage/azerothcore/cache-test/client-data-version.txt 2>/dev/null)
|
||||
print_status "INFO" "Found cached game files (version: $CACHED_VERSION)"
|
||||
print_status "SUCCESS" "No internet download needed - using cached files!"
|
||||
print_status "INFO" "Expected startup time: 5-10 minutes (extraction only)"
|
||||
else
|
||||
print_status "WARNING" "No cached files found - will download ~15GB from internet"
|
||||
print_status "INFO" "Expected startup time: 20-30 minutes (download + extraction)"
|
||||
fi
|
||||
|
||||
# Start test worldserver
|
||||
print_status "TEST" "Starting test worldserver with cached local game files..."
|
||||
print_status "INFO" "Cache location: storage/azerothcore/cache-test/"
|
||||
print_status "INFO" "Game files will be copied to local container storage for performance testing"
|
||||
print_status "INFO" "Test worldserver will be available on port 8216"
|
||||
|
||||
# Record start time
|
||||
START_TIME=$(date +%s)
|
||||
print_status "INFO" "Deployment started at: $(date)"
|
||||
|
||||
# Start the test container
|
||||
docker-compose --env-file docker-compose-test-worldserver.env -f docker-compose-test-worldserver.yml up -d
|
||||
|
||||
print_status "SUCCESS" "Test worldserver container started"
|
||||
print_status "INFO" "Container name: ac-worldserver-test"
|
||||
|
||||
print_status "HEADER" "MONITORING TEST DEPLOYMENT"
|
||||
|
||||
print_status "INFO" "Following logs for the first few minutes..."
|
||||
print_status "INFO" "Press Ctrl+C to stop following logs (container will continue running)"
|
||||
print_status "INFO" ""
|
||||
print_status "TEST" "=== LIVE LOG OUTPUT ==="
|
||||
|
||||
# Follow logs for a bit
|
||||
timeout 300 docker logs ac-worldserver-test -f 2>/dev/null || true
|
||||
|
||||
print_status "INFO" ""
|
||||
print_status "HEADER" "TEST DEPLOYMENT STATUS"
|
||||
|
||||
# Check if container is still running
|
||||
if docker ps | grep ac-worldserver-test > /dev/null; then
|
||||
print_status "SUCCESS" "Test container is running"
|
||||
|
||||
# Calculate elapsed time
|
||||
CURRENT_TIME=$(date +%s)
|
||||
ELAPSED=$((CURRENT_TIME - START_TIME))
|
||||
ELAPSED_MIN=$((ELAPSED / 60))
|
||||
|
||||
print_status "INFO" "Elapsed time: ${ELAPSED_MIN} minutes"
|
||||
print_status "INFO" "Container status: $(docker ps --format '{{.Status}}' --filter name=ac-worldserver-test)"
|
||||
|
||||
print_status "HEADER" "USEFUL COMMANDS"
|
||||
echo -e "${BLUE}Monitor logs:${NC}"
|
||||
echo " $0 --logs"
|
||||
echo " docker logs ac-worldserver-test -f"
|
||||
echo ""
|
||||
echo -e "${BLUE}Check container status:${NC}"
|
||||
echo " docker ps | grep test"
|
||||
echo " docker exec ac-worldserver-test ps aux | grep worldserver"
|
||||
echo ""
|
||||
echo -e "${BLUE}Check game data (local in container):${NC}"
|
||||
echo " docker exec ac-worldserver-test ls -la /azerothcore/data/"
|
||||
echo " docker exec ac-worldserver-test du -sh /azerothcore/data/*"
|
||||
echo ""
|
||||
echo -e "${BLUE}Check cached files (persistent):${NC}"
|
||||
echo " ls -la storage/azerothcore/cache-test/"
|
||||
echo " du -sh storage/azerothcore/cache-test/*"
|
||||
echo " cat storage/azerothcore/cache-test/client-data-version.txt"
|
||||
echo ""
|
||||
echo -e "${BLUE}Connect to test server:${NC}"
|
||||
echo " Game Port: localhost:8216"
|
||||
echo " SOAP Port: localhost:7779"
|
||||
echo ""
|
||||
echo -e "${BLUE}Performance comparison:${NC}"
|
||||
echo " docker stats ac-worldserver ac-worldserver-test --no-stream"
|
||||
echo ""
|
||||
echo -e "${BLUE}Cleanup test:${NC}"
|
||||
echo " $0 --cleanup"
|
||||
echo " rm -rf storage/azerothcore/cache-test/ # Remove cache"
|
||||
|
||||
else
|
||||
print_status "ERROR" "Test container has stopped or failed"
|
||||
print_status "INFO" "Check logs for details:"
|
||||
print_status "INFO" " docker logs ac-worldserver-test"
|
||||
exit 1
|
||||
fi
|
||||
Reference in New Issue
Block a user