i18n 與 OCR 配置流程
本文區分兩套用途不同的語言資源:
i18n/<locale>/LC_MESSAGES/ok.po:GUI/gettext 翻譯。assets/lang/<module>.json:任務 OCR 匹配器和本地化業務文本。
兩者不能互相替代。
1. 執行鏈路
flowchart TD
A[executor.locale 或 task.locale] --> B[BaseEfTask.runtime_locale]
A --> C[get_lang_accessor]
C --> D[规范化为活动 locale]
D --> E[assets/lang/module.json]
E --> F[选择 key 下的 locale 节点]
F --> G[self.lang.module.key]
G --> H[ocr / wait_ocr / 业务比较]
I[assets/ocr_fix/ocr_text_fix.json] --> J[install_ocr_text_fix_patch]
J --> K[扩展 OCR match 参数]
K --> H
入口 main.py/main_debug.py 在匯入並啟動 ok 應用前呼叫 install_startup_patches()。OCR 補丁對 TaskExecutor.__init__ 和 OCR.fix_match_regex 安裝一次性 monkey patch。
2. 活動 locale
活動 OCR locale 由 src/data/lang/__init__.py 的 ACTIVE_LOCALES_CONFIG 明確控制:
ACTIVE_LOCALES_CONFIG = {
"zh_CN": True,
"zh_TW": True,
"en_US": False,
"ja_JP": False,
"ko_KR": False,
"es_ES": False,
}
因此當前 SUPPORTED_LOCALES == ("zh_CN", "zh_TW")。JSON 和 gettext 目錄中存在英語、日語、韓語、西班牙語內容,不代表這些語言已啟用為任務 OCR locale。
locale 來源和規範化規則:
- 有 executor 時讀取
self.executor.locale;否則讀取self.locale。 - 支援
Enum、帶name屬性/方法的 locale 物件和字串。 -轉為_,並對活動 locale 做大小寫寬容匹配。- 非活動、未知或空 locale 回退
zh_CN。
BaseEfTask.runtime_locale 只暴露提取到的原始字串;真正的活動 locale 規範化發生在 LangAccessor 中。
3. 統一 JSON schema
資源路徑是單檔案:
assets/lang/<module>.json
不存在執行時使用的 assets/lang/<module>/<locale>.json 目錄結構。統一檔案以業務 key 為第一層,以 locale 為第二層:
{
"k_confirm": {
"zh_CN": {"string": "确认"},
"zh_TW": {"string": "確認"},
"en_US": {"string": "Confirm"}
},
"k_number": {
"zh_CN": {"pattern": "^\\d+$"},
"zh_TW": {"pattern": "^\\d+$"}
},
"k_accept": {
"zh_CN": {"terms": ["接取", "接受"]},
"zh_TW": {"terms": ["接取", "接受"]}
}
}
每個 locale 節點應只使用一種值:
| 節點 | 訪問結果 | 用途 |
|---|---|---|
{"string": "确认"} |
str |
固定文本或業務顯示文本 |
{"pattern": "^\\d+$"} |
編譯後的 re.Pattern |
正則 OCR 匹配 |
{"terms": ["A", "B"]} |
list |
多個候選值 |
如果 locale 節點本身不是字典,則原樣返回。直接屬性解析檢查順序為 string、pattern、terms;build_matcher 檢查順序為 pattern、string、terms。不要在同一個 locale 節點混放這些欄位。
載入一個 key 時的值回退順序:
- 當前規範化 locale。
- 當前為
zh_TW時仍回退zh_TW,否則回退zh_CN。 - 該 key 下第一個可用 locale 值。
模組檔案不存在、JSON 讀取失敗或 key 不存在時返回空模組/None;不會按舊目錄結構尋找其它檔案。
4. 程式碼訪問
result = self.wait_ocr(
match=self.lang.DeliveryTask.k_ae8fb114,
box=self.box.bottom,
time_out=5,
)
self.wait_click_ocr(
match=self.lang.daily_battle_mixin.k_b56d9ac6,
box=self.box.bottom_right,
time_out=5,
)
安全讀取並提供程式碼級 fallback:
from src.data.lang import get_lang_module_value
matcher = get_lang_module_value(
self.lang,
"DeliveryTask",
"k_ae8fb114",
fallback="确认",
)
業務資料仍以中文 canonical key 儲存時,使用現有工具轉換:
src/data/world_map_utils.py:get_world_map_matcher、get_world_map_text、is_world_map_text。src/data/characters_utils.py:get_localized_name_by_canonical、get_contact_list_with_feature_list。
5. OCR 混淆補丁
配置檔案:
assets/ocr_fix/ocr_text_fix.json
schema 是完整文本的 OCR 错误文本 -> 正确文本:
{
"乾員聯絡": "幹員聯絡"
}
當前補丁 不會替換 OCR 輸出文本,也不會寫入 TaskExecutor.text_fix。實際行為是:
- 只讀取長度相同的錯誤/正確文本對。
- 對每個不同字元構建
正确字符 -> OCR 错误字符,例如幹 -> 乾。 - 同一正確字元對映到多個不同錯字時,保留先前對映並跳過沖突。
- 在框架原有
OCR.fix_match_regex處理後,擴充套件呼叫方的match。
不同 match 型別的行為:
| 輸入 | 補丁行為 |
|---|---|
str |
生成原文和混淆變體,最多 4 個;有多個時返回列表 |
re.Pattern |
只擴充套件安全的字面字元;字元類內追加錯字,保留 flags |
list |
遞迴擴充套件並攤平結果 |
| 其它 | 原樣返回 |
正則轉義、量詞、分組和其它結構標記不會被重寫;混淆字元本身是正則元字元時跳過。編譯或處理失敗會返回原始 match。這是一層匹配相容,不是 OCR 結果標準化,因此業務程式碼讀取 box.name 時仍可能看到原始誤識文本。
舊 src/data/ocr_normalize_map.py 機制已不存在。若需要業務輸出標準化,應在明確的業務解析層實現,不能假定全域性補丁已改寫文本。
6. 新增 OCR 文本
- 確定模組名,通常與使用它的任務類或 Python 模組一致,例如
DeliveryTask、login_mixin。 - 編輯
assets/lang/<module>.json,新增頂層 key。 - 至少為當前活動 locale
zh_CN、zh_TW增加同名節點。 - 節點只選
string、pattern、terms之一。 - 在程式碼中引用
self.lang.<module>.<key>。 - 執行語言引用測試並實測 OCR 區域。
.\.venv\Scripts\python.exe -m unittest tests.TestCheckLang
TestCheckLang 當前只掃描形如 self.lang.<module>.k_xxx 的引用,只校驗 zh_CN 和 zh_TW:
- 模組檔案不存在或兩個 locale 都缺 key:失敗。
- 只缺一個活動 locale:記錄 warning,不導致失敗。
- 非
k_命名的訪問(例如self.lang.login_mixin.ms)不在該測試正則的覆蓋範圍內,需要人工檢查。
7. GUI gettext
GUI 文本使用:
i18n/<locale>/LC_MESSAGES/ok.po
當前倉庫有 zh_CN、zh_TW、en_US、ja_JP、ko_KR、es_ES catalog。相關驗證:
.\.venv\Scripts\python.exe -m unittest tests.TestGuiI18n
.\.venv\Scripts\python.exe -m unittest tests.TestPoLocaleConsistency
TestPoLocaleConsistency 檢查 catalog 重複/空翻譯、佔位符一致性、部分語言不應複製英文 fallback,以及已知執行時汙染 msgid。它不決定 OCR SUPPORTED_LOCALES。
8. 工具狀態
tools/lang_batch_translate.py 當前仍按舊的 assets/lang/<module>/<locale>.json 目錄結構掃描,並且只列舉目錄;它與執行時統一單檔案 schema 不相容。不要對當前資源執行該指令碼,否則不能正確發現或更新模組。scripts/migrate_lang.py 是舊格式遷移用途,也不是日常維護入口。
當前可靠流程是手工編輯統一 JSON,使用 TestCheckLang 校驗引用,再人工複核正則和遊戲專有名詞。
9. 排查清單
語言節點未生效時依次檢查:
- 檔案是否為
assets/lang/<module>.json。 - 頂層 key 和程式碼屬性是否完全一致。
- 執行時 locale 是否在
ACTIVE_LOCALES_CONFIG中啟用。 - locale 節點是否只包含一個合法型別欄位。
- 正則字串是否為有效 Python 正則。
TestCheckLang未覆蓋的非k_key 是否人工補齊。
OCR 穩定誤識時,先確認是否只是匹配問題。只有等長字元混淆適合加入 ocr_text_fix.json;長度變化、詞序變化或僅某一業務成立的糾錯應在語言 pattern 或業務解析中處理。