lawless/scripts/seed.sh

161 行
6.4 KiB
Bash
可执行文件

此文件含有模棱两可的 Unicode 字符

此文件含有可能会与其他字符混淆的 Unicode 字符。 如果您是想特意这样的,可以安全地忽略该警告。 使用 Escape 按钮显示他们。

#!/usr/bin/env bash
# 洪荒大陆 · 开发测试数据种子脚本
# 插入:测试玩家、角色、种族状态、境界进度、基础货币
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
# 加载 .env若存在,也允许通过环境变量直接传入 DATABASE_URL
if [ -f "$PROJECT_ROOT/.env" ]; then
set -a
# shellcheck source=/dev/null
source "$PROJECT_ROOT/.env"
set +a
fi
if [ -z "${DATABASE_URL:-}" ]; then
echo "Error: DATABASE_URL is not set. Please create .env from .env.example or export DATABASE_URL." >&2
exit 1
fi
if ! command -v psql >/dev/null 2>&1; then
echo "Error: psql command not found. Please install PostgreSQL client." >&2
exit 1
fi
# 等待数据库可达
wait_for_db() {
local timeout="${DB_WAIT_TIMEOUT:-30}"
local elapsed=0
echo "Waiting for database to be available..."
until psql "$DATABASE_URL" -c "SELECT 1;" >/dev/null 2>&1; do
if [ "$elapsed" -ge "$timeout" ]; then
echo "Error: database not available after ${timeout}s" >&2
exit 1
fi
printf "."
sleep 1
elapsed=$((elapsed + 1))
done
echo " OK"
}
wait_for_db
# 确保静态参考数据已存在(迁移 up.sql 已包含,此处做幂等兜底)
echo "Ensuring static reference data exists..."
psql "$DATABASE_URL" -v ON_ERROR_STOP=1 <<'EOF'
INSERT INTO realms (tier, minor_realm_max, name, world_tier, main_currency_code, is_tribulation_required, base_success_rate, attr_growth_template) VALUES
(1, 3, '炼气期', 1, 'copper', false, 1.0, '{"hp":10,"atk":2,"def":1}'),
(2, 3, '筑基期', 2, 'copper', true, 0.55, '{"hp":20,"atk":4,"def":2}'),
(3, 3, '金丹期', 3, 'spirit_stone_low', true, 0.50, '{"hp":35,"atk":7,"def":4}'),
(4, 3, '元婴期', 4, 'soul_crystal', true, 0.45, '{"hp":55,"atk":11,"def":6}'),
(5, 3, '化神期', 5, 'immortal_crystal', true, 0.40, '{"hp":80,"atk":16,"def":9}'),
(6, 3, '合体期', 6, 'chaos_crystal', true, 0.35, '{"hp":110,"atk":22,"def":12}')
ON CONFLICT (tier) DO NOTHING;
INSERT INTO currencies (code, name, world_tier, is_premium, exchange_rules) VALUES
('copper', '铜钱', 1, false, '{}'),
('silver', '银两', 2, false, '{}'),
('spirit_stone_low', '下品灵石', 3, false, '{}'),
('spirit_stone_mid', '中品灵石', 3, false, '{}'),
('soul_crystal', '魂晶', 4, false, '{}'),
('immortal_crystal', '仙晶', 5, false, '{}'),
('chaos_crystal', '混沌灵石', 6, false, '{}'),
('purple_gas', '鸿蒙紫气', 1, true, '{}')
ON CONFLICT (code) DO NOTHING;
EOF
# 插入开发测试账号与角色
psql "$DATABASE_URL" -v ON_ERROR_STOP=1 <<'EOF'
DO $$
DECLARE
v_player_id UUID;
v_character_id UUID;
BEGIN
-- 测试玩家甲
SELECT id INTO v_player_id FROM players WHERE device_id_hash = 'dev_seed_001';
IF v_player_id IS NULL THEN
INSERT INTO players (id, nakama_user_id, platform, device_id_hash, status)
VALUES (gen_random_uuid(), gen_random_uuid(), 'guest', 'dev_seed_001', 'active')
RETURNING id INTO v_player_id;
END IF;
SELECT id INTO v_character_id FROM characters WHERE name = '测试修士·甲';
IF v_character_id IS NULL THEN
INSERT INTO characters (
id, player_id, name, race_id, birth_race_id, birth_world_tier, world_tier, realm_tier, minor_realm,
level, exp, power, status, base_stats, battle_stats, san_current, san_max
) VALUES (
gen_random_uuid(), v_player_id, '测试修士·甲', 'tiger_yao', 'tiger_yao', 1, 1, 1, 1,
1, 0, 100, 'active',
'{"str":12,"vit":11,"wis":9,"agi":13,"spi":10,"luk":10}'::jsonb,
'{"hp_max":1100,"atk":110,"def":55,"speed":105}'::jsonb,
100, 100
)
RETURNING id INTO v_character_id;
END IF;
IF NOT EXISTS (SELECT 1 FROM character_race_states WHERE character_id = v_character_id) THEN
INSERT INTO character_race_states (character_id, main_race_id, is_rare_race)
VALUES (v_character_id, 'tiger_yao', false);
END IF;
IF NOT EXISTS (SELECT 1 FROM character_realms WHERE character_id = v_character_id AND is_current = true) THEN
INSERT INTO character_realms (id, character_id, realm_tier, max_minor_reached, exp_in_tier, is_current)
VALUES (gen_random_uuid(), v_character_id, 1, 1, 0, true);
END IF;
INSERT INTO currency_balances (character_id, currency_code, amount, total_earned)
VALUES
(v_character_id, 'copper', 10000, 10000),
(v_character_id, 'purple_gas', 100, 100)
ON CONFLICT (character_id, currency_code) DO UPDATE
SET amount = EXCLUDED.amount, total_earned = EXCLUDED.total_earned, updated_at = NOW();
-- 测试玩家乙(用于 PVP/结义/道侣等双人玩法验证)
SELECT id INTO v_player_id FROM players WHERE device_id_hash = 'dev_seed_002';
IF v_player_id IS NULL THEN
INSERT INTO players (id, nakama_user_id, platform, device_id_hash, status)
VALUES (gen_random_uuid(), gen_random_uuid(), 'guest', 'dev_seed_002', 'active')
RETURNING id INTO v_player_id;
END IF;
SELECT id INTO v_character_id FROM characters WHERE name = '测试修士·乙';
IF v_character_id IS NULL THEN
INSERT INTO characters (
id, player_id, name, race_id, birth_race_id, birth_world_tier, world_tier, realm_tier, minor_realm,
level, exp, power, status, base_stats, battle_stats, san_current, san_max
) VALUES (
gen_random_uuid(), v_player_id, '测试修士·乙', 'elf_light', 'elf_light', 1, 1, 1, 2,
5, 450, 120, 'active',
'{"str":9,"vit":10,"wis":14,"agi":12,"spi":12,"luk":11}'::jsonb,
'{"hp_max":1050,"atk":95,"def":60,"speed":115}'::jsonb,
100, 100
)
RETURNING id INTO v_character_id;
END IF;
IF NOT EXISTS (SELECT 1 FROM character_race_states WHERE character_id = v_character_id) THEN
INSERT INTO character_race_states (character_id, main_race_id, is_rare_race)
VALUES (v_character_id, 'elf_light', false);
END IF;
IF NOT EXISTS (SELECT 1 FROM character_realms WHERE character_id = v_character_id AND is_current = true) THEN
INSERT INTO character_realms (id, character_id, realm_tier, max_minor_reached, exp_in_tier, is_current)
VALUES (gen_random_uuid(), v_character_id, 1, 2, 450, true);
END IF;
INSERT INTO currency_balances (character_id, currency_code, amount, total_earned)
VALUES
(v_character_id, 'copper', 5000, 5000),
(v_character_id, 'purple_gas', 50, 50)
ON CONFLICT (character_id, currency_code) DO UPDATE
SET amount = EXCLUDED.amount, total_earned = EXCLUDED.total_earned, updated_at = NOW();
END $$;
EOF
echo "Seed data inserted successfully."