adding automatic module inclusion features and bugfixes

This commit is contained in:
uprightbass360
2025-11-01 00:13:34 -04:00
parent 718af64dae
commit d59c785f11
16 changed files with 3064 additions and 1132 deletions

View File

@@ -6,6 +6,75 @@ trap 'echo " ❌ SQL helper error (line ${LINENO}): ${BASH_COMMAND}" >&2' ERR
CUSTOM_SQL_ROOT="/tmp/scripts/sql/custom"
ALT_CUSTOM_SQL_ROOT="/scripts/sql/custom"
SQL_SUCCESS_LOG=()
SQL_FAILURE_LOG=()
TEMP_SQL_FILES=()
render_sql_file_for_execution(){
local src="$1"
local pb_db="${DB_PLAYERBOTS_NAME:-acore_playerbots}"
local rendered="$src"
if command -v python3 >/dev/null 2>&1; then
local temp
temp="$(mktemp)"
local result
result="$(python3 - "$src" "$temp" "$pb_db" <<'PY'
import sys, pathlib, re
src, dest, pb_db = sys.argv[1:]
text = pathlib.Path(src).read_text()
original = text
text = text.replace("{{PLAYERBOTS_DB}}", pb_db)
pattern = re.compile(r'(?<![.`])\bplayerbots\b')
text = pattern.sub(f'`{pb_db}`.playerbots', text)
pathlib.Path(dest).write_text(text)
print("changed" if text != original else "unchanged", end="")
PY
)"
if [ "$result" = "changed" ]; then
rendered="$temp"
TEMP_SQL_FILES+=("$temp")
else
rm -f "$temp"
fi
fi
echo "$rendered"
}
log_sql_success(){
local target_db="$1"
local sql_file="$2"
SQL_SUCCESS_LOG+=("${target_db}::${sql_file}")
}
log_sql_failure(){
local target_db="$1"
local sql_file="$2"
SQL_FAILURE_LOG+=("${target_db}::${sql_file}")
}
mysql_exec(){
local mysql_port="${MYSQL_PORT:-3306}"
if command -v mariadb >/dev/null 2>&1; then
mariadb --ssl=false -h "${CONTAINER_MYSQL}" -P "$mysql_port" -u root -p"${MYSQL_ROOT_PASSWORD}" "$@"
return
fi
if command -v mysql >/dev/null 2>&1; then
mysql --ssl-mode=DISABLED -h "${CONTAINER_MYSQL}" -P "$mysql_port" -u root -p"${MYSQL_ROOT_PASSWORD}" "$@"
return
fi
echo " ❌ Neither mariadb nor mysql client is available for SQL execution" >&2
return 127
}
playerbots_table_exists(){
local pb_db="${DB_PLAYERBOTS_NAME:-acore_playerbots}"
local count
count="$(mysql_exec -N -e "SELECT COUNT(*) FROM information_schema.tables WHERE table_schema='${pb_db}' AND table_name='playerbots';" 2>/dev/null || echo 0)"
[ "${count}" != "0" ]
}
run_custom_sql_group(){
local subdir="$1" target_db="$2" label="$3"
local dir="${CUSTOM_SQL_ROOT}/${subdir}"
@@ -13,25 +82,76 @@ run_custom_sql_group(){
dir="${ALT_CUSTOM_SQL_ROOT}/${subdir}"
fi
[ -d "$dir" ] || return 0
LC_ALL=C find "$dir" -type f -name "*.sql" | sort | while read -r sql_file; do
while IFS= read -r sql_file; do
local base_name
base_name="$(basename "$sql_file")"
local rendered
rendered="$(render_sql_file_for_execution "$sql_file")"
if grep -q '\bplayerbots\b' "$rendered"; then
if ! playerbots_table_exists; then
echo " Skipping ${label}: ${base_name} (playerbots table missing)"
continue
fi
fi
echo " Executing ${label}: ${base_name}"
if mariadb --ssl=false -h "${CONTAINER_MYSQL}" -P 3306 -u root -p"${MYSQL_ROOT_PASSWORD}" "${target_db}" < "$sql_file" >/dev/null 2>&1; then
local sql_output
sql_output="$(mktemp)"
if mysql_exec "${target_db}" < "$rendered" >"$sql_output" 2>&1; then
echo " ✅ Successfully executed ${base_name}"
log_sql_success "$target_db" "$sql_file"
else
echo " ❌ Failed to execute $sql_file"
sed 's/^/ /' "$sql_output"
log_sql_failure "$target_db" "$sql_file"
fi
done || true
rm -f "$sql_output"
done < <(LC_ALL=C find "$dir" -type f -name "*.sql" | sort) || true
}
# Function to execute SQL files for a module
execute_module_sql() {
local module_dir="$1"
local module_name="$2"
module_sql_run_module(){
local module_key="$1"
local module_dir="$2"
local module_name="${MODULE_NAME[$module_key]:-}"
if [ -z "$module_name" ]; then
module_name="$module_dir"
fi
local world_db="${DB_WORLD_NAME:-acore_world}"
local auth_db="${DB_AUTH_NAME:-acore_auth}"
local characters_db="${DB_CHARACTERS_NAME:-acore_characters}"
local playerbots_db="${DB_PLAYERBOTS_NAME:-acore_playerbots}"
local character_set="${MYSQL_CHARACTER_SET:-utf8mb4}"
local collation="${MYSQL_COLLATION:-utf8mb4_unicode_ci}"
execute_sql_file_in_db(){
local target_db="$1"
local sql_file="$2"
local label="$3"
local rendered
rendered="$(render_sql_file_for_execution "$sql_file")"
if grep -q '\bplayerbots\b' "$rendered"; then
if ! playerbots_table_exists; then
echo " Skipping ${label}: ${base_name} (playerbots table missing)"
return 0
fi
fi
local base_name
base_name="$(basename "$sql_file")"
echo " Executing ${label}: ${base_name}"
local sql_output
sql_output="$(mktemp)"
if mysql_exec "${target_db}" < "$rendered" >"$sql_output" 2>&1; then
echo " ✅ Successfully executed ${base_name}"
log_sql_success "$target_db" "$sql_file"
else
echo " ❌ Failed to execute $sql_file"
sed 's/^/ /' "$sql_output"
log_sql_failure "$target_db" "$sql_file"
fi
rm -f "$sql_output"
}
local run_sorted_sql
run_sorted_sql() {
@@ -40,27 +160,22 @@ execute_module_sql() {
local label="$3"
local skip_regex="${4:-}"
[ -d "$dir" ] || return
LC_ALL=C find "$dir" -type f -name "*.sql" | sort | while read -r sql_file; do
while IFS= read -r sql_file; do
local base_name
base_name="$(basename "$sql_file")"
if [ -n "$skip_regex" ] && [[ "$base_name" =~ $skip_regex ]]; then
echo " Skipping ${label}: ${base_name}"
continue
fi
echo " Executing ${label}: ${base_name}"
if mariadb --ssl=false -h "${CONTAINER_MYSQL}" -P 3306 -u root -p"${MYSQL_ROOT_PASSWORD}" "${target_db}" < "$sql_file" >/dev/null 2>&1; then
echo " ✅ Successfully executed ${base_name}"
else
echo " ❌ Failed to execute $sql_file"
fi
done || true
execute_sql_file_in_db "$target_db" "$sql_file" "$label"
done < <(LC_ALL=C find "$dir" -type f -name "*.sql" | sort) || true
}
echo "Processing SQL scripts for $module_name..."
if [ "$module_name" = "Playerbots" ]; then
if [ "$module_key" = "MODULE_PLAYERBOTS" ]; then
echo " Ensuring database ${playerbots_db} exists..."
if mariadb --ssl=false -h "${CONTAINER_MYSQL}" -P 3306 -u root -p"${MYSQL_ROOT_PASSWORD}" -e "CREATE DATABASE IF NOT EXISTS \`${playerbots_db}\` CHARACTER SET ${character_set} COLLATE ${collation};" >/dev/null 2>&1; then
if mysql_exec -e "CREATE DATABASE IF NOT EXISTS \`${playerbots_db}\` CHARACTER SET ${character_set} COLLATE ${collation};" >/dev/null 2>&1; then
echo " ✅ Playerbots database ready"
else
echo " ❌ Failed to ensure playerbots database"
@@ -71,45 +186,30 @@ execute_module_sql() {
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 mariadb --ssl=false -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
while IFS= read -r sql_file; do
execute_sql_file_in_db "$world_db" "$sql_file" "world SQL"
done < <(find "$module_dir/data/sql/world" -type f -name "*.sql") || true
fi
run_sorted_sql "$module_dir/data/sql/db-world" "${DB_WORLD_NAME}" "world SQL"
run_sorted_sql "$module_dir/data/sql/db-world" "${world_db}" "world SQL"
# 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 mariadb --ssl=false -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
while IFS= read -r sql_file; do
execute_sql_file_in_db "$auth_db" "$sql_file" "auth SQL"
done < <(find "$module_dir/data/sql/auth" -type f -name "*.sql") || true
fi
run_sorted_sql "$module_dir/data/sql/db-auth" "${DB_AUTH_NAME}" "auth SQL"
run_sorted_sql "$module_dir/data/sql/db-auth" "${auth_db}" "auth SQL"
# 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 mariadb --ssl=false -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
while IFS= read -r sql_file; do
execute_sql_file_in_db "$characters_db" "$sql_file" "characters SQL"
done < <(find "$module_dir/data/sql/characters" -type f -name "*.sql") || true
fi
run_sorted_sql "$module_dir/data/sql/db-characters" "${DB_CHARACTERS_NAME}" "characters SQL"
run_sorted_sql "$module_dir/data/sql/db-characters" "${characters_db}" "characters SQL"
# Execute playerbots database scripts
if [ "$module_name" = "Playerbots" ] && [ -d "$module_dir/data/sql/playerbots" ]; then
if [ "$module_key" = "MODULE_PLAYERBOTS" ] && [ -d "$module_dir/data/sql/playerbots" ]; then
local pb_root="$module_dir/data/sql/playerbots"
run_sorted_sql "$pb_root/base" "$playerbots_db" "playerbots SQL"
run_sorted_sql "$pb_root/custom" "$playerbots_db" "playerbots SQL"
@@ -119,18 +219,16 @@ execute_module_sql() {
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
while IFS= read -r sql_file; do
execute_sql_file_in_db "$world_db" "$sql_file" "base SQL"
done < <(find "$module_dir/data/sql" -maxdepth 1 -type f -name "*.sql") || true
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
while IFS= read -r sql_file; do
execute_sql_file_in_db "$world_db" "$sql_file" "module SQL"
done < <(find "$module_dir/sql" -type f -name "*.sql") || true
fi
return 0
@@ -144,76 +242,60 @@ execute_module_sql_scripts() {
apk add --no-cache mariadb-client >/dev/null 2>&1 || echo "Warning: Could not install MariaDB client"
}
# Iterate modules from staging directory to catch new modules automatically
for module_dir in */; do
[[ -d "$module_dir" ]] || continue
[[ "$module_dir" == "." || "$module_dir" == ".." ]] && continue
module_dir="${module_dir%/}"
# Only process directories that follow mod-* convention or known module names
if [[ "$module_dir" != mod-* && "$module_dir" != StatBooster && "$module_dir" != DungeonRespawn && "$module_dir" != eluna-ts ]]; then
SQL_SUCCESS_LOG=()
SQL_FAILURE_LOG=()
# Iterate modules from manifest metadata
local key module_dir enabled
local world_db="${DB_WORLD_NAME:-acore_world}"
local auth_db="${DB_AUTH_NAME:-acore_auth}"
local characters_db="${DB_CHARACTERS_NAME:-acore_characters}"
for key in "${MODULE_KEYS[@]}"; do
module_dir="${MODULE_NAME[$key]:-}"
[ -n "$module_dir" ] || continue
[ -d "$module_dir" ] || continue
enabled="${MODULE_ENABLED[$key]:-0}"
if [ "$enabled" != "1" ]; then
continue
fi
local enabled=0
case "$module_dir" in
mod-playerbots) enabled="$MODULE_PLAYERBOTS" ;;
mod-aoe-loot) enabled="$MODULE_AOE_LOOT" ;;
mod-learn-spells) enabled="$MODULE_LEARN_SPELLS" ;;
mod-fireworks-on-level) enabled="$MODULE_FIREWORKS" ;;
mod-individual-progression) enabled="$MODULE_INDIVIDUAL_PROGRESSION" ;;
mod-ahbot) enabled="$MODULE_AHBOT" ;;
mod-autobalance) enabled="$MODULE_AUTOBALANCE" ;;
mod-transmog) enabled="$MODULE_TRANSMOG" ;;
mod-npc-buffer) enabled="$MODULE_NPC_BUFFER" ;;
mod-dynamic-xp) enabled="$MODULE_DYNAMIC_XP" ;;
mod-solo-lfg) enabled="$MODULE_SOLO_LFG" ;;
mod-1v1-arena) enabled="$MODULE_1V1_ARENA" ;;
mod-phased-duels) enabled="$MODULE_PHASED_DUELS" ;;
mod-breaking-news-override) enabled="$MODULE_BREAKING_NEWS" ;;
mod-boss-announcer) enabled="$MODULE_BOSS_ANNOUNCER" ;;
mod-account-achievements) enabled="$MODULE_ACCOUNT_ACHIEVEMENTS" ;;
mod-auto-revive) enabled="$MODULE_AUTO_REVIVE" ;;
mod-gain-honor-guard) enabled="$MODULE_GAIN_HONOR_GUARD" ;;
mod-ale) enabled="$MODULE_ELUNA" ;;
mod-TimeIsTime) enabled="$MODULE_TIME_IS_TIME" ;;
mod-pocket-portal) enabled="$MODULE_POCKET_PORTAL" ;;
mod-random-enchants) enabled="$MODULE_RANDOM_ENCHANTS" ;;
mod-solocraft) enabled="$MODULE_SOLOCRAFT" ;;
mod-pvp-titles) enabled="$MODULE_PVP_TITLES" ;;
mod-npc-beastmaster) enabled="$MODULE_NPC_BEASTMASTER" ;;
mod-npc-enchanter) enabled="$MODULE_NPC_ENCHANTER" ;;
mod-instance-reset) enabled="$MODULE_INSTANCE_RESET" ;;
mod-quest-count-level) enabled="$MODULE_LEVEL_GRANT" ;;
mod-arac) enabled="$MODULE_ARAC" ;;
mod-assistant) enabled="$MODULE_ASSISTANT" ;;
mod-reagent-bank) enabled="$MODULE_REAGENT_BANK" ;;
mod-black-market) enabled="$MODULE_BLACK_MARKET_AUCTION_HOUSE" ;;
mod-challenge-modes) enabled="$MODULE_CHALLENGE_MODES" ;;
mod-ollama-chat) enabled="$MODULE_OLLAMA_CHAT" ;;
mod-player-bot-level-brackets) enabled="$MODULE_PLAYER_BOT_LEVEL_BRACKETS" ;;
StatBooster) enabled="$MODULE_STATBOOSTER" ;;
DungeonRespawn) enabled="$MODULE_DUNGEON_RESPAWN" ;;
skeleton-module) enabled="$MODULE_SKELETON_MODULE" ;;
mod-bg-slaveryvalley) enabled="$MODULE_BG_SLAVERYVALLEY" ;;
mod-azerothshard) enabled="$MODULE_AZEROTHSHARD" ;;
mod-worgoblin) enabled="$MODULE_WORGOBLIN" ;;
eluna-ts) enabled="$MODULE_ELUNA_TS" ;;
*) enabled=1 ;; # Default to enabled for unknown module directories
esac
if [ "${enabled:-0}" = "1" ]; then
# Skip modules explicitly disabled for SQL
if [ "$module_dir" = "mod-pocket-portal" ]; then
echo '⚠️ Skipping mod-pocket-portal SQL: module disabled until C++20 patch is applied.'
continue
fi
execute_module_sql "$module_dir" "$module_dir"
if [ "$module_dir" = "mod-pocket-portal" ]; then
echo '⚠️ Skipping mod-pocket-portal SQL: module disabled until C++20 patch is applied.'
continue
fi
module_sql_run_module "$key" "$module_dir"
done
run_custom_sql_group world "${DB_WORLD_NAME}" "custom world SQL"
run_custom_sql_group auth "${DB_AUTH_NAME}" "custom auth SQL"
run_custom_sql_group characters "${DB_CHARACTERS_NAME}" "custom characters SQL"
run_custom_sql_group world "${world_db}" "custom world SQL"
run_custom_sql_group auth "${auth_db}" "custom auth SQL"
run_custom_sql_group characters "${characters_db}" "custom characters SQL"
echo "SQL execution summary:"
if [ ${#SQL_SUCCESS_LOG[@]} -gt 0 ]; then
echo " ✅ Applied:"
for entry in "${SQL_SUCCESS_LOG[@]}"; do
IFS='::' read -r db file <<< "$entry"
echo " • [$db] $file"
done
else
echo " ✅ Applied: none"
fi
if [ ${#SQL_FAILURE_LOG[@]} -gt 0 ]; then
echo " ❌ Failed:"
for entry in "${SQL_FAILURE_LOG[@]}"; do
IFS='::' read -r db file <<< "$entry"
echo " • [$db] $file"
done
else
echo " ❌ Failed: none"
fi
if [ ${#TEMP_SQL_FILES[@]} -gt 0 ]; then
rm -f "${TEMP_SQL_FILES[@]}" 2>/dev/null || true
TEMP_SQL_FILES=()
fi
return 0
}