Files
moonwell-core/localize-playerbots-ru.sh

214 lines
7.8 KiB
Bash

#!/usr/bin/env bash
set -euo pipefail
SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
cd "$SCRIPT_DIR"
MODE="${1:---dry-run}"
CHARACTER_NAMES_SQL="modules/mod-playerbots/data/sql/characters/updates/2026_07_30_00_playerbots_russian_names.sql"
BOT_TEXTS_SQL="modules/mod-playerbots/data/sql/playerbots/updates/2026_07_30_00_ai_playerbot_russian_texts.sql"
case "$MODE" in
--dry-run | --apply) ;;
*)
echo "Usage: $0 [--dry-run|--apply]" >&2
exit 2
;;
esac
if ! docker compose ps --status running --services | grep -qx "ac-database"; then
echo "ac-database must be running." >&2
exit 1
fi
mysql_query() {
local database="$1"
local sql="$2"
docker compose exec -T ac-database bash -lc \
"mysql --default-character-set=utf8mb4 -N -s -uroot -p\"\$MYSQL_ROOT_PASSWORD\" \"$database\"" <<<"$sql"
}
import_sql() {
local database="$1"
local file_path="$2"
docker compose exec -T ac-database bash -lc \
"mysql --default-character-set=utf8mb4 -uroot -p\"\$MYSQL_ROOT_PASSWORD\" \"$database\"" <"$file_path"
}
read -r bot_count guild_count < <(
mysql_query acore_characters "
SELECT
COUNT(DISTINCT CASE
WHEN REGEXP_LIKE(c.name, '^[[:ascii:]]+$') THEN c.guid
END),
COUNT(DISTINCT CASE
WHEN REGEXP_LIKE(g.name, '^[[:ascii:]]+$') THEN g.guildid
END)
FROM characters c
JOIN acore_playerbots.playerbots_account_type pat
ON pat.account_id = c.account AND pat.account_type = 1
LEFT JOIN guild g ON g.leaderguid = c.guid;
"
)
echo "RNDbot characters to rename: $bot_count"
echo "RNDbot-led guilds to rename: $guild_count"
if [[ "$MODE" == "--dry-run" ]]; then
echo "Dry run only. Stop ac-worldserver and run '$0 --apply' to apply."
exit 0
fi
if docker compose ps --status running --services | grep -qx "ac-worldserver"; then
echo "Refusing to rename live characters while ac-worldserver is running." >&2
echo "Stop it with: docker compose stop ac-worldserver" >&2
exit 1
fi
import_sql acore_characters "$CHARACTER_NAMES_SQL"
import_sql acore_playerbots "$BOT_TEXTS_SQL"
mysql_query acore_characters "
SET NAMES utf8mb4;
CREATE TABLE IF NOT EXISTS moonwell_playerbot_name_backup (
guid INT UNSIGNED NOT NULL,
original_name VARCHAR(12) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL,
localized_name VARCHAR(12) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL,
changed_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (guid),
UNIQUE KEY uq_moonwell_playerbot_localized_name (localized_name)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
CREATE TABLE IF NOT EXISTS moonwell_playerbot_guild_name_backup (
guildid INT UNSIGNED NOT NULL,
original_name VARCHAR(24) NOT NULL,
localized_name VARCHAR(24) NOT NULL,
changed_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (guildid),
UNIQUE KEY uq_moonwell_playerbot_localized_guild_name (localized_name)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
DROP TEMPORARY TABLE IF EXISTS tmp_moonwell_available_names;
CREATE TEMPORARY TABLE tmp_moonwell_available_names AS
SELECT
n.gender,
n.name,
ROW_NUMBER() OVER (PARTITION BY n.gender ORDER BY n.name_id) AS row_number_in_category
FROM playerbots_names_ru n
LEFT JOIN characters used
ON used.name = CONVERT(n.name USING utf8mb4) COLLATE utf8mb4_bin
LEFT JOIN moonwell_playerbot_name_backup reserved
ON reserved.localized_name = CONVERT(n.name USING utf8mb4) COLLATE utf8mb4_bin
WHERE used.guid IS NULL
AND reserved.guid IS NULL;
DROP TEMPORARY TABLE IF EXISTS tmp_moonwell_bot_targets;
CREATE TEMPORARY TABLE tmp_moonwell_bot_targets AS
SELECT
c.guid,
c.name AS original_name,
CASE
WHEN c.race IN (1, 5) THEN c.gender
WHEN c.race = 7 THEN 2 + c.gender
WHEN c.race = 3 THEN 4 + c.gender
WHEN c.race = 4 THEN 6 + c.gender
WHEN c.race = 11 THEN 8 + c.gender
WHEN c.race = 2 THEN 10 + c.gender
WHEN c.race = 8 THEN 12 + c.gender
WHEN c.race = 6 THEN 14 + c.gender
WHEN c.race = 10 THEN 16 + c.gender
END AS name_category,
ROW_NUMBER() OVER (
PARTITION BY CASE
WHEN c.race IN (1, 5) THEN c.gender
WHEN c.race = 7 THEN 2 + c.gender
WHEN c.race = 3 THEN 4 + c.gender
WHEN c.race = 4 THEN 6 + c.gender
WHEN c.race = 11 THEN 8 + c.gender
WHEN c.race = 2 THEN 10 + c.gender
WHEN c.race = 8 THEN 12 + c.gender
WHEN c.race = 6 THEN 14 + c.gender
WHEN c.race = 10 THEN 16 + c.gender
END
ORDER BY c.guid
) AS row_number_in_category
FROM characters c
JOIN acore_playerbots.playerbots_account_type pat
ON pat.account_id = c.account AND pat.account_type = 1
WHERE REGEXP_LIKE(c.name, '^[[:ascii:]]+$');
DROP TEMPORARY TABLE IF EXISTS tmp_moonwell_character_renames;
CREATE TEMPORARY TABLE tmp_moonwell_character_renames AS
SELECT t.guid, t.original_name, n.name AS localized_name
FROM tmp_moonwell_bot_targets t
JOIN tmp_moonwell_available_names n
ON n.gender = t.name_category
AND n.row_number_in_category = t.row_number_in_category;
START TRANSACTION;
INSERT IGNORE INTO moonwell_playerbot_name_backup (guid, original_name, localized_name)
SELECT guid, original_name, localized_name
FROM tmp_moonwell_character_renames;
UPDATE characters c
JOIN moonwell_playerbot_name_backup b ON b.guid = c.guid
SET c.name = b.localized_name
WHERE c.name = b.original_name;
DELETE declined
FROM character_declinedname declined
JOIN moonwell_playerbot_name_backup b ON b.guid = declined.guid;
COMMIT;
DROP TEMPORARY TABLE IF EXISTS tmp_moonwell_available_guild_names;
CREATE TEMPORARY TABLE tmp_moonwell_available_guild_names AS
SELECT
n.name,
ROW_NUMBER() OVER (ORDER BY n.name_id) AS row_number_in_pool
FROM playerbots_guild_names_ru n
LEFT JOIN guild used ON used.name = n.name
LEFT JOIN moonwell_playerbot_guild_name_backup reserved
ON reserved.localized_name = n.name
WHERE used.guildid IS NULL
AND reserved.guildid IS NULL;
DROP TEMPORARY TABLE IF EXISTS tmp_moonwell_guild_targets;
CREATE TEMPORARY TABLE tmp_moonwell_guild_targets AS
SELECT
g.guildid,
g.name AS original_name,
ROW_NUMBER() OVER (ORDER BY g.guildid) AS row_number_in_pool
FROM guild g
JOIN characters leader ON leader.guid = g.leaderguid
JOIN acore_playerbots.playerbots_account_type pat
ON pat.account_id = leader.account AND pat.account_type = 1
WHERE REGEXP_LIKE(g.name, '^[[:ascii:]]+$');
START TRANSACTION;
INSERT IGNORE INTO moonwell_playerbot_guild_name_backup (guildid, original_name, localized_name)
SELECT t.guildid, t.original_name, n.name
FROM tmp_moonwell_guild_targets t
JOIN tmp_moonwell_available_guild_names n
ON n.row_number_in_pool = t.row_number_in_pool;
UPDATE guild g
JOIN moonwell_playerbot_guild_name_backup b ON b.guildid = g.guildid
SET g.name = b.localized_name
WHERE g.name = b.original_name;
COMMIT;
"
read -r renamed_bot_count renamed_guild_count < <(
mysql_query acore_characters "
SELECT
(SELECT COUNT(*) FROM moonwell_playerbot_name_backup),
(SELECT COUNT(*) FROM moonwell_playerbot_guild_name_backup);
"
)
echo "Localized RNDbot characters: $renamed_bot_count"
echo "Localized RNDbot-led guilds: $renamed_guild_count"
echo "Static ruRU texts and Russian name pools are installed."