diff --git a/src/i18n/locales/zh_CN/LC_MESSAGES/game_configs.mo b/src/i18n/locales/zh_CN/LC_MESSAGES/game_configs.mo index 182077a..98733d0 100644 Binary files a/src/i18n/locales/zh_CN/LC_MESSAGES/game_configs.mo and b/src/i18n/locales/zh_CN/LC_MESSAGES/game_configs.mo differ diff --git a/src/i18n/locales/zh_CN/LC_MESSAGES/game_configs.po b/src/i18n/locales/zh_CN/LC_MESSAGES/game_configs.po index 2abc0f4..d94e801 100644 --- a/src/i18n/locales/zh_CN/LC_MESSAGES/game_configs.po +++ b/src/i18n/locales/zh_CN/LC_MESSAGES/game_configs.po @@ -2843,7 +2843,7 @@ msgstr "孔雀翎" msgid "WEAPON_1077_DESC" msgstr "虽然只是暗器,但其美艳不可方物。当它绽放时,便是敌人的死期。" -#. world_info.csv: +#. world_info.csv: 简介 msgid "WORLD_INFO_INTRO_NAME" msgstr "简介" @@ -2851,7 +2851,11 @@ msgstr "简介" msgid "WORLD_INFO_INTRO_DESC" msgstr "这是一个诸多修士竞相修行的修仙世界。" -#. world_info.csv: +#. world_info.csv: 简介 +msgid "WORLD_INFO_INTRO_TITLE" +msgstr "简介" + +#. world_info.csv: 境界 msgid "WORLD_INFO_REALM_NAME" msgstr "境界" @@ -2859,15 +2863,23 @@ msgstr "境界" msgid "WORLD_INFO_REALM_DESC" msgstr "修仙的境界从弱到强:练气、筑基、金丹、元婴。每个境界分前期、中期、后期。境界间差距很大。" -#. world_info.csv: +#. world_info.csv: 境界 +msgid "WORLD_INFO_REALM_TITLE" +msgstr "境界" + +#. world_info.csv: 寿元 msgid "WORLD_INFO_LIFESPAN_NAME" msgstr "寿元" -#. world_info.csv: 每个角色均有寿元上限。在大限将至的前20年身体会逐渐衰弱,有几率老死;一旦达到或超过寿元上限,... +#. world_info.csv: 每个角色均有寿元上限。在大限将至的前20年身体会逐渐衰弱,有几率老死;一旦达到或超过寿元上限,则必死无疑。提升境界和某些宝物、丹药能提高寿元上限。 msgid "WORLD_INFO_LIFESPAN_DESC" msgstr "每个角色均有寿元上限。在大限将至的前20年身体会逐渐衰弱,有几率老死;一旦达到或超过寿元上限,则必死无疑。提升境界和某些宝物、丹药能提高寿元上限。" -#. world_info.csv: +#. world_info.csv: 寿元 +msgid "WORLD_INFO_LIFESPAN_TITLE" +msgstr "寿元" + +#. world_info.csv: 死亡 msgid "WORLD_INFO_DEATH_NAME" msgstr "死亡" @@ -2875,7 +2887,11 @@ msgstr "死亡" msgid "WORLD_INFO_DEATH_DESC" msgstr "HP降至0以下也会死亡。" -#. world_info.csv: +#. world_info.csv: 死亡 +msgid "WORLD_INFO_DEATH_TITLE" +msgstr "死亡" + +#. world_info.csv: 区域 msgid "WORLD_INFO_REGION_NAME" msgstr "区域" @@ -2883,7 +2899,11 @@ msgstr "区域" msgid "WORLD_INFO_REGION_DESC" msgstr "不同区域有不同效果,在适当的区域做适当的事情事半功倍。" -#. world_info.csv: +#. world_info.csv: 区域 +msgid "WORLD_INFO_REGION_TITLE" +msgstr "区域" + +#. world_info.csv: 修炼 msgid "WORLD_INFO_CULTIVATION_NAME" msgstr "修炼" @@ -2891,15 +2911,23 @@ msgstr "修炼" msgid "WORLD_INFO_CULTIVATION_DESC" msgstr "修炼可以增加经验,直到到达突破前的瓶颈。突破是概率事件,突破后会进入下一个境界。" -#. world_info.csv: +#. world_info.csv: 修炼 +msgid "WORLD_INFO_CULTIVATION_TITLE" +msgstr "修炼" + +#. world_info.csv: 灵根 msgid "WORLD_INFO_ROOT_NAME" msgstr "灵根" -#. world_info.csv: 灵根由五行元素(金、木、水、火、土)组成,分为单灵根、双灵根和天灵根。五行相克:金克木,木克土... +#. world_info.csv: 灵根由五行元素(金、木、水、火、土)组成,分为单灵根、双灵根和天灵根。五行相克:金克木,木克土,土克水,水克火,火克金。天灵根包含全部五行元素且突破时有额外加成。在与自身灵根属性匹配的区域修炼效率最高。 msgid "WORLD_INFO_ROOT_DESC" msgstr "灵根由五行元素(金、木、水、火、土)组成,分为单灵根、双灵根和天灵根。五行相克:金克木,木克土,土克水,水克火,火克金。天灵根包含全部五行元素且突破时有额外加成。在与自身灵根属性匹配的区域修炼效率最高。" -#. world_info.csv: +#. world_info.csv: 灵根 +msgid "WORLD_INFO_ROOT_TITLE" +msgstr "灵根" + +#. world_info.csv: 天地灵机 msgid "WORLD_INFO_WORLD_QI_NAME" msgstr "天地灵机" @@ -2907,7 +2935,11 @@ msgstr "天地灵机" msgid "WORLD_INFO_WORLD_QI_DESC" msgstr "世界每隔数年会有一次天象变动(如灵气潮汐),影响角色能力。" -#. world_info.csv: +#. world_info.csv: 天地灵机 +msgid "WORLD_INFO_WORLD_QI_TITLE" +msgstr "天地灵机" + +#. world_info.csv: 灵石 msgid "WORLD_INFO_SPIRIT_STONE_NAME" msgstr "灵石" @@ -2915,7 +2947,11 @@ msgstr "灵石" msgid "WORLD_INFO_SPIRIT_STONE_DESC" msgstr "修仙界的通用货币。可用于购买法宝丹药,通过采集、交易或掠夺获取。" -#. world_info.csv: +#. world_info.csv: 灵石 +msgid "WORLD_INFO_SPIRIT_STONE_TITLE" +msgstr "灵石" + +#. world_info.csv: 宗门 msgid "WORLD_INFO_SECT_NAME" msgstr "宗门" @@ -2923,7 +2959,11 @@ msgstr "宗门" msgid "WORLD_INFO_SECT_DESC" msgstr "修士的庇护所。加入宗门可习得独门功法、获同门庇护;散修自由但资源匮乏。" -#. world_info.csv: +#. world_info.csv: 宗门 +msgid "WORLD_INFO_SECT_TITLE" +msgstr "宗门" + +#. world_info.csv: 战斗 msgid "WORLD_INFO_BATTLE_NAME" msgstr "战斗" @@ -2931,7 +2971,11 @@ msgstr "战斗" msgid "WORLD_INFO_BATTLE_DESC" msgstr "弱肉强食,境界压制极大,高境界者对低境界者有绝对优势。若对方死亡,胜者可掠夺败者财物。" -#. world_info.csv: +#. world_info.csv: 战斗 +msgid "WORLD_INFO_BATTLE_TITLE" +msgstr "战斗" + +#. world_info.csv: 动作 msgid "WORLD_INFO_ACTION_NAME" msgstr "动作" @@ -2939,23 +2983,35 @@ msgstr "动作" msgid "WORLD_INFO_ACTION_DESC" msgstr "你有一系列可以执行的动作。要注意动作的效果、限制条件、区域和时间。" -#. world_info.csv: +#. world_info.csv: 动作 +msgid "WORLD_INFO_ACTION_TITLE" +msgstr "动作" + +#. world_info.csv: 装备与丹药 msgid "WORLD_INFO_EQUIPMENT_AND_ELIXIR_NAME" msgstr "装备与丹药" -#. world_info.csv: 通过兵器、辅助装备、丹药等装备,可以获得额外的属性加成,获得或小或大的增益。拥有好的装备或者服... +#. world_info.csv: 通过兵器、辅助装备、丹药等装备,可以获得额外的属性加成,获得或小或大的增益。拥有好的装备或者服用好的丹药,能获得很大好处。 msgid "WORLD_INFO_EQUIPMENT_AND_ELIXIR_DESC" msgstr "通过兵器、辅助装备、丹药等装备,可以获得额外的属性加成,获得或小或大的增益。拥有好的装备或者服用好的丹药,能获得很大好处。" -#. world_info.csv: +#. world_info.csv: 装备与丹药 +msgid "WORLD_INFO_EQUIPMENT_AND_ELIXIR_TITLE" +msgstr "装备与丹药" + +#. world_info.csv: 购物 msgid "WORLD_INFO_SHOPPING_NAME" msgstr "购物" -#. world_info.csv: 在城市区域可以购买练气级别丹药、兵器。购买丹药后会立刻服用强化自身。购买兵器可以帮自己切换兵器... +#. world_info.csv: 在城市区域可以购买练气级别丹药、兵器。购买丹药后会立刻服用强化自身。购买兵器可以帮自己切换兵器类型为顺手的类型。 msgid "WORLD_INFO_SHOPPING_DESC" msgstr "在城市区域可以购买练气级别丹药、兵器。购买丹药后会立刻服用强化自身。购买兵器可以帮自己切换兵器类型为顺手的类型。" -#. world_info.csv: +#. world_info.csv: 购物 +msgid "WORLD_INFO_SHOPPING_TITLE" +msgstr "购物" + +#. world_info.csv: 拍卖会 msgid "WORLD_INFO_AUCTION_NAME" msgstr "拍卖会" @@ -2963,10 +3019,18 @@ msgstr "拍卖会" msgid "WORLD_INFO_AUCTION_DESC" msgstr "每隔一段不确定的时间会有神秘人组织的拍卖会,或许有好货出售。" -#. world_info.csv: +#. world_info.csv: 拍卖会 +msgid "WORLD_INFO_AUCTION_TITLE" +msgstr "拍卖会" + +#. world_info.csv: 秘境 msgid "WORLD_INFO_SECRET_REALM_NAME" msgstr "秘境" #. world_info.csv: 每隔数年会有秘境开启。进入秘境可能遭遇凶险,也可能获得高阶法宝和功法。 msgid "WORLD_INFO_SECRET_REALM_DESC" msgstr "每隔数年会有秘境开启。进入秘境可能遭遇凶险,也可能获得高阶法宝和功法。" + +#. world_info.csv: 秘境 +msgid "WORLD_INFO_SECRET_REALM_TITLE" +msgstr "秘境" diff --git a/src/server/main.py b/src/server/main.py index 945b672..132f8cd 100644 --- a/src/server/main.py +++ b/src/server/main.py @@ -204,7 +204,9 @@ def serialize_active_domains(world: World) -> List[dict]: "max_realm": str(d.max_realm), "danger_prob": d.danger_prob, "drop_prob": d.drop_prob, - "is_open": is_open + "is_open": is_open, + "cd_years": d.cd_years, + "open_prob": d.open_prob }) return domains_data diff --git a/tests/test_i18n_integrity.py b/tests/test_i18n_integrity.py new file mode 100644 index 0000000..2c84e82 --- /dev/null +++ b/tests/test_i18n_integrity.py @@ -0,0 +1,48 @@ +import pytest +from src.utils.df import load_game_configs +from src.i18n import t + +def test_all_csv_ids_have_translations(): + """ + 遍历加载的所有游戏配置 CSV,检查所有以 _id 结尾的字段(如 name_id, desc_id, title_id), + 确保它们在中文环境下都有对应的翻译。 + + 如果 t(key) 返回的结果等于 key 本身,且 key 是全大写(典型的 ID 格式),则视为缺失翻译。 + """ + # 1. 加载配置 (force_chinese_language fixture 已经在 session 级别生效) + configs = load_game_configs() + + missing_keys = [] + + # 需要检查的 ID 后缀 + target_suffixes = ('_id', '_ID') + # 一些已知的例外或不需要翻译的字段可以加在这里 + ignored_keys = set() + + # 2. 遍历所有配置表 + for config_name, rows in configs.items(): + if not rows: + continue + + print(f"Checking config: {config_name}.csv ({len(rows)} rows)") + + for i, row in enumerate(rows): + # 遍历行中的所有键值对 + for key, value in row.items(): + # 检查 Key 是否以 _id 结尾 (例如 title_id) + # 并且 Value 是字符串且非空 + if key.lower().endswith("id") and isinstance(value, str) and value.strip(): + # 也可以进一步过滤,例如只检查全大写的 Value,或者特定前缀 + # 这里假设所有需要翻译的 ID 都是全大写且包含下划线 + if value.isupper() and "_" in value: + translated = t(value) + + # 如果翻译结果和原文一样,且原文不是空的,视为缺失 + # 注意:有些 ID 本身就是英文显示(极少),这里主要针对需要转中文的情况 + if translated == value: + missing_keys.append(f"[{config_name}.csv Row {i+1}] {key}={value}") + + # 3. 断言 + if missing_keys: + error_msg = f"Found {len(missing_keys)} missing translations in zh-CN:\n" + "\n".join(missing_keys) + pytest.fail(error_msg) diff --git a/web/src/components/layout/StatusWidget.vue b/web/src/components/layout/StatusWidget.vue index 6f7498c..59a2391 100644 --- a/web/src/components/layout/StatusWidget.vue +++ b/web/src/components/layout/StatusWidget.vue @@ -1,7 +1,10 @@