#!/bin/bash # Fix item import for backup-merged characters set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" cd "$SCRIPT_DIR" COLOR_RED='\033[0;31m' COLOR_GREEN='\033[0;32m' COLOR_YELLOW='\033[1;33m' COLOR_BLUE='\033[0;34m' COLOR_CYAN='\033[0;36m' COLOR_RESET='\033[0m' log(){ printf '%b\n' "${COLOR_GREEN}$*${COLOR_RESET}"; } info(){ printf '%b\n' "${COLOR_CYAN}$*${COLOR_RESET}"; } warn(){ printf '%b\n' "${COLOR_YELLOW}$*${COLOR_RESET}"; } err(){ printf '%b\n' "${COLOR_RED}$*${COLOR_RESET}"; } fatal(){ err "$*"; exit 1; } MYSQL_PW="azerothcore123" BACKUP_DIR="/nfs/containers/ac-backup" AUTH_DB="acore_auth" CHARACTERS_DB="acore_characters" # Verify parameters [[ -d "$BACKUP_DIR" ]] || fatal "Backup directory not found: $BACKUP_DIR" # Setup temp directory TEMP_DIR="$(mktemp -d)" trap 'rm -rf "$TEMP_DIR"' EXIT # MySQL connection helper mysql_exec(){ local db="$1" docker exec -i ac-mysql mysql -uroot -p"$MYSQL_PW" "$db" 2>/dev/null } mysql_query(){ local db="$1" local query="$2" docker exec ac-mysql mysql -uroot -p"$MYSQL_PW" -N -B "$db" -e "$query" 2>/dev/null } log "═══════════════════════════════════════════════════════════" log " FIXING ITEM IMPORT FOR BACKUP-MERGED CHARACTERS" log "═══════════════════════════════════════════════════════════" # Find characters that were imported from the backup (accounts 451, 452) log "Finding characters that need item restoration..." IMPORTED_CHARS=$(mysql_query "$CHARACTERS_DB" "SELECT name, guid FROM characters WHERE account IN (451, 452);") if [[ -z "$IMPORTED_CHARS" ]]; then fatal "No imported characters found (accounts 451, 452)" fi info "Found imported characters:" echo "$IMPORTED_CHARS" | while read -r char_name char_guid; do info " $char_name (guid: $char_guid)" done # Check current item count for these characters CURRENT_ITEM_COUNT=$(mysql_query "$CHARACTERS_DB" "SELECT COUNT(*) FROM item_instance WHERE owner_guid IN (4501, 4502, 4503);") info "Current items for imported characters: $CURRENT_ITEM_COUNT" if [[ "$CURRENT_ITEM_COUNT" != "0" ]]; then warn "Characters already have items. Exiting." exit 0 fi # Extract backup files log "Extracting backup files..." CHARACTERS_DUMP="" for pattern in "acore_characters.sql.gz" "characters.sql.gz" "acore_characters.sql" "characters.sql"; do if [[ -f "$BACKUP_DIR/$pattern" ]]; then CHARACTERS_DUMP="$BACKUP_DIR/$pattern" break fi done [[ -n "$CHARACTERS_DUMP" ]] || fatal "Characters database dump not found in $BACKUP_DIR" info "Found characters dump: ${CHARACTERS_DUMP##*/}" # Extract dump to temp file if [[ "$CHARACTERS_DUMP" == *.gz ]]; then zcat "$CHARACTERS_DUMP" > "$TEMP_DIR/characters.sql" else cp "$CHARACTERS_DUMP" "$TEMP_DIR/characters.sql" fi # Create staging database log "Creating staging database..." STAGE_CHARS_DB="fix_stage_chars_$$" # Drop any existing staging database docker exec ac-mysql mysql -uroot -p"$MYSQL_PW" -e "DROP DATABASE IF EXISTS $STAGE_CHARS_DB;" 2>/dev/null || true # Create staging database docker exec ac-mysql mysql -uroot -p"$MYSQL_PW" -e "CREATE DATABASE $STAGE_CHARS_DB;" 2>/dev/null # Cleanup staging database on exit cleanup_staging(){ if [[ -n "${STAGE_CHARS_DB:-}" ]]; then docker exec ac-mysql mysql -uroot -p"$MYSQL_PW" -e "DROP DATABASE IF EXISTS $STAGE_CHARS_DB;" 2>/dev/null || true fi } trap 'cleanup_staging; rm -rf "$TEMP_DIR"' EXIT # Load backup into staging database info "Loading backup into staging database..." sed "s/\`acore_characters\`/\`$STAGE_CHARS_DB\`/g; s/USE \`acore_characters\`;/USE \`$STAGE_CHARS_DB\`;/g" "$TEMP_DIR/characters.sql" | \ docker exec -i ac-mysql mysql -uroot -p"$MYSQL_PW" 2>/dev/null # Get current database state CURRENT_MAX_ITEM_GUID=$(mysql_query "$CHARACTERS_DB" "SELECT COALESCE(MAX(guid), 0) FROM item_instance;") ITEM_OFFSET=$((CURRENT_MAX_ITEM_GUID + 10000)) info "Current max item GUID: $CURRENT_MAX_ITEM_GUID" info "Item GUID offset: +$ITEM_OFFSET" # Create character mapping for the imported characters log "Creating character mapping..." mysql_exec "$STAGE_CHARS_DB" </dev/null 2>&1 || warn "Services already stopped" # Import items log "Importing character items..." # Import item_instance ITEM_SQL=$(cat <&1) if echo "$ITEM_RESULT" | grep -q "ERROR"; then err "Item import failed:" echo "$ITEM_RESULT" | grep "ERROR" >&2 fatal "Item import failed" fi # Import character_inventory INV_SQL=$(cat <&1) if echo "$INV_RESULT" | grep -q "ERROR"; then err "Inventory import failed:" echo "$INV_RESULT" | grep "ERROR" >&2 fatal "Inventory import failed" fi # Report counts ITEMS_IMPORTED=$(mysql_query "$CHARACTERS_DB" "SELECT COUNT(*) FROM item_instance WHERE owner_guid IN (4501, 4502, 4503);") INV_IMPORTED=$(mysql_query "$CHARACTERS_DB" "SELECT COUNT(*) FROM character_inventory WHERE guid IN (4501, 4502, 4503);") info "Items imported: $ITEMS_IMPORTED" info "Inventory slots imported: $INV_IMPORTED" # Restart services log "Restarting services..." docker restart ac-authserver ac-worldserver >/dev/null 2>&1 log "Waiting for services to initialize..." sleep 5 for i in {1..30}; do if docker exec ac-worldserver pgrep worldserver >/dev/null 2>&1 && docker exec ac-authserver pgrep authserver >/dev/null 2>&1; then log "✓ Services running" break fi if [ $i -eq 30 ]; then warn "Services took longer than expected to start" fi sleep 2 done log "" log "═══════════════════════════════════════════════════════════" log " ITEM IMPORT FIX COMPLETE" log "═══════════════════════════════════════════════════════════" log "Items successfully restored for imported characters!" log "Players can now log in with their complete characters and items."