mirror of
https://github.com/uprightbass360/AzerothCore-RealmMaster.git
synced 2026-01-13 00:58:34 +00:00
cleanup: validation and integrations for importing data
This commit is contained in:
@@ -1,57 +1,167 @@
|
||||
#!/bin/bash
|
||||
# Fix item import for backup-merged characters
|
||||
#
|
||||
# Usage:
|
||||
# fix-item-import.sh [OPTIONS]
|
||||
#
|
||||
# Options:
|
||||
# --backup-dir DIR Path to backup directory (required)
|
||||
# --account-ids IDS Comma-separated account IDs (e.g., "451,452")
|
||||
# --char-guids GUIDS Comma-separated character GUIDs (e.g., "4501,4502,4503")
|
||||
# --mysql-password PW MySQL root password (or use MYSQL_ROOT_PASSWORD env var)
|
||||
# --mysql-container NAME MySQL container name (default: ac-mysql)
|
||||
# --auth-db NAME Auth database name (default: acore_auth)
|
||||
# --characters-db NAME Characters database name (default: acore_characters)
|
||||
# -h, --help Show this help message
|
||||
#
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
cd "$SCRIPT_DIR"
|
||||
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
|
||||
|
||||
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'
|
||||
# Source common library
|
||||
if [ -f "$SCRIPT_DIR/lib/common.sh" ]; then
|
||||
source "$SCRIPT_DIR/lib/common.sh"
|
||||
else
|
||||
echo "ERROR: Common library not found at $SCRIPT_DIR/lib/common.sh" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
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; }
|
||||
# Default values (can be overridden by environment or command line)
|
||||
BACKUP_DIR="${BACKUP_DIR:-}"
|
||||
ACCOUNT_IDS="${ACCOUNT_IDS:-}"
|
||||
CHAR_GUIDS="${CHAR_GUIDS:-}"
|
||||
MYSQL_PW="${MYSQL_ROOT_PASSWORD:-}"
|
||||
MYSQL_CONTAINER="${MYSQL_CONTAINER:-ac-mysql}"
|
||||
AUTH_DB="${AUTH_DB:-acore_auth}"
|
||||
CHARACTERS_DB="${CHARACTERS_DB:-acore_characters}"
|
||||
|
||||
MYSQL_PW="azerothcore123"
|
||||
BACKUP_DIR="/nfs/containers/ac-backup"
|
||||
AUTH_DB="acore_auth"
|
||||
CHARACTERS_DB="acore_characters"
|
||||
# Show help message
|
||||
show_help() {
|
||||
cat << EOF
|
||||
Fix item import for backup-merged characters
|
||||
|
||||
# Verify parameters
|
||||
[[ -d "$BACKUP_DIR" ]] || fatal "Backup directory not found: $BACKUP_DIR"
|
||||
Usage:
|
||||
fix-item-import.sh [OPTIONS]
|
||||
|
||||
Options:
|
||||
--backup-dir DIR Path to backup directory (required)
|
||||
--account-ids IDS Comma-separated account IDs (e.g., "451,452")
|
||||
--char-guids GUIDS Comma-separated character GUIDs (e.g., "4501,4502,4503")
|
||||
--mysql-password PW MySQL root password (or use MYSQL_ROOT_PASSWORD env var)
|
||||
--mysql-container NAME MySQL container name (default: ac-mysql)
|
||||
--auth-db NAME Auth database name (default: acore_auth)
|
||||
--characters-db NAME Characters database name (default: acore_characters)
|
||||
-h, --help Show this help message
|
||||
|
||||
Environment Variables:
|
||||
BACKUP_DIR Alternative to --backup-dir
|
||||
ACCOUNT_IDS Alternative to --account-ids
|
||||
CHAR_GUIDS Alternative to --char-guids
|
||||
MYSQL_ROOT_PASSWORD Alternative to --mysql-password
|
||||
MYSQL_CONTAINER Alternative to --mysql-container
|
||||
AUTH_DB Alternative to --auth-db
|
||||
CHARACTERS_DB Alternative to --characters-db
|
||||
|
||||
Example:
|
||||
fix-item-import.sh \\
|
||||
--backup-dir /path/to/backup \\
|
||||
--account-ids "451,452" \\
|
||||
--char-guids "4501,4502,4503" \\
|
||||
--mysql-password "azerothcore123"
|
||||
|
||||
EOF
|
||||
exit 0
|
||||
}
|
||||
|
||||
# Parse command line arguments
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
--backup-dir)
|
||||
BACKUP_DIR="$2"
|
||||
shift 2
|
||||
;;
|
||||
--account-ids)
|
||||
ACCOUNT_IDS="$2"
|
||||
shift 2
|
||||
;;
|
||||
--char-guids)
|
||||
CHAR_GUIDS="$2"
|
||||
shift 2
|
||||
;;
|
||||
--mysql-password)
|
||||
MYSQL_PW="$2"
|
||||
shift 2
|
||||
;;
|
||||
--mysql-container)
|
||||
MYSQL_CONTAINER="$2"
|
||||
shift 2
|
||||
;;
|
||||
--auth-db)
|
||||
AUTH_DB="$2"
|
||||
shift 2
|
||||
;;
|
||||
--characters-db)
|
||||
CHARACTERS_DB="$2"
|
||||
shift 2
|
||||
;;
|
||||
-h|--help)
|
||||
show_help
|
||||
;;
|
||||
*)
|
||||
fatal "Unknown option: $1\nUse --help for usage information"
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Validate required parameters
|
||||
if [ -z "$BACKUP_DIR" ]; then
|
||||
fatal "Backup directory not specified. Use --backup-dir or set BACKUP_DIR environment variable."
|
||||
fi
|
||||
|
||||
if [ ! -d "$BACKUP_DIR" ]; then
|
||||
fatal "Backup directory not found: $BACKUP_DIR"
|
||||
fi
|
||||
|
||||
if [ -z "$ACCOUNT_IDS" ]; then
|
||||
fatal "Account IDs not specified. Use --account-ids or set ACCOUNT_IDS environment variable."
|
||||
fi
|
||||
|
||||
if [ -z "$CHAR_GUIDS" ]; then
|
||||
fatal "Character GUIDs not specified. Use --char-guids or set CHAR_GUIDS environment variable."
|
||||
fi
|
||||
|
||||
if [ -z "$MYSQL_PW" ]; then
|
||||
fatal "MySQL password not specified. Use --mysql-password or set MYSQL_ROOT_PASSWORD environment variable."
|
||||
fi
|
||||
|
||||
# Setup temp directory
|
||||
TEMP_DIR="$(mktemp -d)"
|
||||
trap 'rm -rf "$TEMP_DIR"' EXIT
|
||||
|
||||
# MySQL connection helper
|
||||
mysql_exec(){
|
||||
# MySQL connection helpers (override common.sh defaults with script-specific values)
|
||||
mysql_exec_local(){
|
||||
local db="$1"
|
||||
docker exec -i ac-mysql mysql -uroot -p"$MYSQL_PW" "$db" 2>/dev/null
|
||||
docker exec -i "$MYSQL_CONTAINER" mysql -uroot -p"$MYSQL_PW" "$db" 2>/dev/null
|
||||
}
|
||||
|
||||
mysql_query(){
|
||||
mysql_query_local(){
|
||||
local db="$1"
|
||||
local query="$2"
|
||||
docker exec ac-mysql mysql -uroot -p"$MYSQL_PW" -N -B "$db" -e "$query" 2>/dev/null
|
||||
docker exec "$MYSQL_CONTAINER" 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)
|
||||
# Find characters that were imported from the backup
|
||||
log "Finding characters that need item restoration..."
|
||||
IMPORTED_CHARS=$(mysql_query "$CHARACTERS_DB" "SELECT name, guid FROM characters WHERE account IN (451, 452);")
|
||||
info "Looking for characters with account IDs: $ACCOUNT_IDS"
|
||||
IMPORTED_CHARS=$(mysql_query_local "$CHARACTERS_DB" "SELECT name, guid FROM characters WHERE account IN ($ACCOUNT_IDS);")
|
||||
|
||||
if [[ -z "$IMPORTED_CHARS" ]]; then
|
||||
fatal "No imported characters found (accounts 451, 452)"
|
||||
fatal "No imported characters found with account IDs: $ACCOUNT_IDS"
|
||||
fi
|
||||
|
||||
info "Found imported characters:"
|
||||
@@ -60,7 +170,8 @@ echo "$IMPORTED_CHARS" | while read -r char_name char_guid; do
|
||||
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 "Checking existing items for character GUIDs: $CHAR_GUIDS"
|
||||
CURRENT_ITEM_COUNT=$(mysql_query_local "$CHARACTERS_DB" "SELECT COUNT(*) FROM item_instance WHERE owner_guid IN ($CHAR_GUIDS);")
|
||||
info "Current items for imported characters: $CURRENT_ITEM_COUNT"
|
||||
|
||||
if [[ "$CURRENT_ITEM_COUNT" != "0" ]]; then
|
||||
@@ -94,26 +205,26 @@ 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
|
||||
docker exec "$MYSQL_CONTAINER" 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
|
||||
docker exec "$MYSQL_CONTAINER" 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
|
||||
docker exec "$MYSQL_CONTAINER" 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
|
||||
sed "s/\`$CHARACTERS_DB\`/\`$STAGE_CHARS_DB\`/g; s/USE \`$CHARACTERS_DB\`;/USE \`$STAGE_CHARS_DB\`;/g" "$TEMP_DIR/characters.sql" | \
|
||||
docker exec -i "$MYSQL_CONTAINER" 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;")
|
||||
CURRENT_MAX_ITEM_GUID=$(mysql_query_local "$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"
|
||||
@@ -121,22 +232,32 @@ info "Item GUID offset: +$ITEM_OFFSET"
|
||||
|
||||
# Create character mapping for the imported characters
|
||||
log "Creating character mapping..."
|
||||
mysql_exec "$STAGE_CHARS_DB" <<EOF
|
||||
info "Building character GUID mapping from staging database..."
|
||||
|
||||
# Create mapping table dynamically based on imported characters
|
||||
mysql_exec_local "$STAGE_CHARS_DB" <<EOF
|
||||
CREATE TABLE character_guid_map (
|
||||
old_guid INT UNSIGNED PRIMARY KEY,
|
||||
new_guid INT UNSIGNED,
|
||||
name VARCHAR(12)
|
||||
);
|
||||
EOF
|
||||
|
||||
# Populate mapping by matching character names from staging to current database
|
||||
# This assumes character names are unique identifiers
|
||||
mysql_exec_local "$STAGE_CHARS_DB" <<EOF
|
||||
INSERT INTO character_guid_map (old_guid, new_guid, name)
|
||||
VALUES
|
||||
(1, 4501, 'Artimage'),
|
||||
(2, 4502, 'Flombey'),
|
||||
(3, 4503, 'Hammertime');
|
||||
SELECT
|
||||
s.guid as old_guid,
|
||||
c.guid as new_guid,
|
||||
c.name
|
||||
FROM $STAGE_CHARS_DB.characters s
|
||||
JOIN $CHARACTERS_DB.characters c ON s.name = c.name
|
||||
WHERE c.account IN ($ACCOUNT_IDS);
|
||||
EOF
|
||||
|
||||
# Create item GUID mapping
|
||||
mysql_exec "$STAGE_CHARS_DB" <<EOF
|
||||
mysql_exec_local "$STAGE_CHARS_DB" <<EOF
|
||||
CREATE TABLE item_guid_map (
|
||||
old_guid INT UNSIGNED PRIMARY KEY,
|
||||
new_guid INT UNSIGNED,
|
||||
@@ -153,7 +274,7 @@ INNER JOIN character_guid_map cm ON i.owner_guid = cm.old_guid;
|
||||
EOF
|
||||
|
||||
# Check how many items will be imported
|
||||
ITEMS_TO_IMPORT=$(mysql_query "$STAGE_CHARS_DB" "SELECT COUNT(*) FROM item_guid_map;")
|
||||
ITEMS_TO_IMPORT=$(mysql_query_local "$STAGE_CHARS_DB" "SELECT COUNT(*) FROM item_guid_map;")
|
||||
info "Items to import: $ITEMS_TO_IMPORT"
|
||||
|
||||
if [[ "$ITEMS_TO_IMPORT" == "0" ]]; then
|
||||
@@ -195,7 +316,7 @@ EOSQL
|
||||
)
|
||||
|
||||
ITEM_SQL_EXPANDED=$(echo "$ITEM_SQL" | sed "s/STAGE_CHARS_DB/$STAGE_CHARS_DB/g")
|
||||
ITEM_RESULT=$(echo "$ITEM_SQL_EXPANDED" | docker exec -i ac-mysql mysql -uroot -p"$MYSQL_PW" "$CHARACTERS_DB" 2>&1)
|
||||
ITEM_RESULT=$(echo "$ITEM_SQL_EXPANDED" | docker exec -i "$MYSQL_CONTAINER" mysql -uroot -p"$MYSQL_PW" "$CHARACTERS_DB" 2>&1)
|
||||
if echo "$ITEM_RESULT" | grep -q "ERROR"; then
|
||||
err "Item import failed:"
|
||||
echo "$ITEM_RESULT" | grep "ERROR" >&2
|
||||
@@ -217,7 +338,7 @@ EOSQL
|
||||
)
|
||||
|
||||
INV_SQL_EXPANDED=$(echo "$INV_SQL" | sed "s/STAGE_CHARS_DB/$STAGE_CHARS_DB/g")
|
||||
INV_RESULT=$(echo "$INV_SQL_EXPANDED" | docker exec -i ac-mysql mysql -uroot -p"$MYSQL_PW" "$CHARACTERS_DB" 2>&1)
|
||||
INV_RESULT=$(echo "$INV_SQL_EXPANDED" | docker exec -i "$MYSQL_CONTAINER" mysql -uroot -p"$MYSQL_PW" "$CHARACTERS_DB" 2>&1)
|
||||
if echo "$INV_RESULT" | grep -q "ERROR"; then
|
||||
err "Inventory import failed:"
|
||||
echo "$INV_RESULT" | grep "ERROR" >&2
|
||||
@@ -225,8 +346,8 @@ if echo "$INV_RESULT" | grep -q "ERROR"; then
|
||||
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);")
|
||||
ITEMS_IMPORTED=$(mysql_query_local "$CHARACTERS_DB" "SELECT COUNT(*) FROM item_instance WHERE owner_guid IN ($CHAR_GUIDS);")
|
||||
INV_IMPORTED=$(mysql_query_local "$CHARACTERS_DB" "SELECT COUNT(*) FROM character_inventory WHERE guid IN ($CHAR_GUIDS);")
|
||||
|
||||
info "Items imported: $ITEMS_IMPORTED"
|
||||
info "Inventory slots imported: $INV_IMPORTED"
|
||||
|
||||
Reference in New Issue
Block a user