diff --git a/README.md b/README.md index f1ae909..9bbe842 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ [![uk](https://img.shields.io/badge/українська-blue.svg)](https://github.com/PanVena/SteamAchievementLocalizer/blob/main/readmes/README.uk.md) [![pl](https://img.shields.io/badge/polski-green.svg)](https://github.com/PanVena/SteamAchievementLocalizer/blob/main/readmes/README.pl.md) - +[![zh](https://img.shields.io/badge/中文-red.svg)](https://github.com/PanVena/SteamAchievementLocalizer/blob/main/readmes/README.zh.md)

🏆 Steam Achievement Localizer by Vena

@@ -293,4 +293,4 @@ Translator / discussion community: Ideas / questions / bugs → Issue or Telegram. Like the project? — Share with localization communities & drop a ⭐. -

Made with love for localization & games 💛💙

\ No newline at end of file +

Made with love for localization & games 💛💙

diff --git a/assets/locales/lang_zh.json b/assets/locales/lang_zh.json new file mode 100644 index 0000000..f9dc5ea --- /dev/null +++ b/assets/locales/lang_zh.json @@ -0,0 +1,247 @@ +{ + "_locale_info": { + "name": "简体中文", + "native_name": "简体中文 (Simplified Chinese)", + "code": "zh", + "priority": 40 + }, + "app_title": "Steam 成就本地化工具 by Pan_Vena ver ", + "restart_steam": "重启 Steam", + "tooltip_restart_steam": "关闭并重启 Steam 客户端(Ctrl+R)", + "q_restart_steam": "重启 Steam?", + "msg_restart_steam": "是否要重启 Steam 以应用更改?", + "warning_title_achtung": "注意", + "warning_message": "可能存在 bug,如有问题请前往 GitHub 页面反馈,或通过以下方式联系:Telegram: @Pan_Vena,Discord: pan_vena
或发送邮件至: pan.vena@ukr.net
其他联系方式可在「关于应用」中查看", + "load_icons_option": "加载成就图标", + "man_select_file_label": "选择 UserGameStatsSchema_XXXXXX.bin 文件路径", + "man_select_file": "选择文件", + "get_ach": "获取成就!!!", + "man_file_sel_label": "手动选择文件", + "OR": "或", + "steam_folder_label": "选择 Steam 文件夹路径(例如:C:\\Program Files (x86)\\Steam)", + "select_steam_folder": "选择 Steam 文件夹", + "game_id_label": "输入游戏 ID 或 Steam 商店链接(例如:https://store.steampowered.com/app/257510/The_Talos_Principle/)", + "clear_and_paste": "清空并从剪贴板粘贴", + "indirect_file_sel_label": "通过 ID 间接选择文件", + "gamename": "游戏名称或代号:", + "file_version": "成就文件版本:", + "unknown": "未知", + "translation_lang": "翻译至:", + "fetch_missing_names": "从 Steam API 获取缺失名称", + "fetch_missing_names_hint": "点击以从 Steam API 获取所有显示「未知」的游戏名称。此操作需要网络连接。", + "lang_sel": "语言选择:", + "lang_sel_dia": "语言选择", + "in_column_search": "搜索:", + "in_column_search_placeholder": "输入文本搜索...", + "save": "保存", + "save_bin_unknown": "保存 bin 文件到 Steam 文件夹", + "tooltip_save_bin_unknown": "直接将 bin 文件保存到 Steam 文件夹", + "tooltip_show_user_game_stats": "显示所有可用成就文件列表(Ctrl+O)", + "save_bin_known": "保存 bin 文件(本地备份)", + "tools": "工具", + "export_import": "导出/导入", + "export_bin": "在资源管理器中打开当前 bin 文件", + "export_all": "导出为 CSV(所有语言)", + "export_for_translate": "导出为 CSV(用于翻译)", + "import_csv": "从 CSV 导入", + "file": "文件", + "language": "语言", + "exit": "退出", + "save_changes_title": "保存更改?", + "save_changes_msg": "是否要保存更改?", + "save_where_title": "保存位置?", + "save_where_msg": "要将更改保存到哪里?
", + "save_for_self": "本地备份", + "save_to_steam": "保存到 Steam 文件夹", + "about": "关于", + "about_app": "关于应用", + "about_message": "本应用用于翻译 Steam 成就名称。

如有疑问:
- Telegram: @Pan_Vena
- Discord: pan_vena
- GitHub: PanVena
- E-mail: pan.vena@ukr.net

感谢以下贡献者的 pull request:VadkoZergatulNick Defrunctveydzh3r♡Cutie Patootie♡MrIkso", + "info": "信息", + "error": "错误", + "success": "成功", + "records_loaded": "已加载 {count} 条记录:{countby2} 个成就及其描述。", + "error_cannot_open": "无法打开文件:
", + "error_cannot_save": "无法保存文件:
", + "error_UserGameStatsSchema_sel": "请先选择 UserGameStatsSchema 文件", + "error_no_id": "请输入游戏 ID 或 Steam 商店链接", + "error_no_path": "请先选择 Steam 文件夹", + "error_no_file": "未找到文件:
", + "export_csv_all_file_dialog": "保存 CSV", + "export_csv_for_translate_file_dialog": "保存 CSV(用于翻译)", + "csv_saved": "CSV 文件已保存", + "export_csv_for_translate_info": "导出用于翻译的 CSV 包含以下列:key、english、translation 和所选上下文语言
翻译完成后,填写 'translation' 列,将文件导回程序并选择 'english' 作为替换语言。", + "error_no_english": "缺少 'english' 列。
这意味着文件未加载。", + "error_no_context": "请选择上下文语言", + "import_csv_info": "导入 CSV 将用 'translation' 列中的值替换所选语言(如果已填写)。
导入前请选择 'english' 或其他语言作为替换目标。", + "import_csv_file_dialog": "打开 CSV 以导入", + "error_no_lang_for_import": "请选择要替换的语言", + "import_csv_file_dialog_select": "选择要导入的 CSV 文件", + "import_failed": "导入失败", + "import_no_changes": "CSV 已导入,但没有数据被更改", + "import_details": "已导入:{imported},已更改:{changed},已跳过:{skipped}", + "reason": "原因", + "save_no_game_id": "无法保存到 Steam:未指定游戏 ID。请输入游戏 ID 或从列表中选择游戏。", + "export_csv_file_dialog": "保存 CSV 文件", + "error_empty": "CSV 为空", + "import_success": "CSV 已导入,数据已更新", + "error_doesnt_imported": "无法导入 CSV:
", + "error_no_column_choosen_to_replace": "未选择要替换的列
", + "error_no_end_was_found": "找不到行尾。
", + "error_nothing_after_english": "在 'english' 之后找不到字符串结尾。", + "error_manually_selected_file": "你已从其他文件夹加载了文件,请将其保存到别处", + "error_no_data_to_save": "请先加载成就文件", + "in_steam_folder_saved": "文件已保存到 Steam 文件夹。重启 Steam 即可看到更改。", + "file_saving_file_dialog": "保存修改后的文件", + "file_saved": "文件已成功保存至:
{save_path}

将此文件放回 Steam 文件夹后,别忘了重启 Steam。
各平台存放路径:
C:\\Program Files (x86)\\Steam\\appcache\\stats(Windows)
~/.steam/steam/appcache/stats(Linux)", + "attention": "注意", + "folder_not_found_auto": "无法自动找到 Steam 文件夹", + "man_select_file_file_dialog": "选择 UserGameStatsSchema 文件", + "cannot_decode_json": "无法解码 JSON 文件:
", + "copy": "复制", + "paste": "粘贴", + "edit": "编辑", + "undo": "撤销", + "redo": "重做", + "cut": "剪切", + "delete": "删除", + "select_all": "全选", + "deselect_all": "取消全选", + "replace_in_column": "替换", + "search_replace": "查找并替换", + "search": "查找", + "seeeking_for_what": "查找内容", + "by_what": "替换为", + "search_text": "查找:", + "replace_text": "替换为:", + "column": "选择列:", + "replace_all": "全部替换", + "found_nothing": "未找到任何结果", + "found": "找到匹配项:{match_count}", + "close": "关闭", + "cancel": "取消", + "columns": "列:", + "yes": "是", + "no": "否", + "user_game_stats_list": "可用成就文件列表", + "show_user_game_stats": "可用文件", + "file_name": "文件名", + "version": "文件版本", + "gamename_list": "游戏名称或代号", + "game_id": "游戏 ID", + "achievements_count": "成就数量", + "choose_export": "选择导出时的上下文语言:", + "choose_import": "选择要替换的语言:", + "delete_stats_file_confirm": "你即将删除游戏 {gamename} 的成就名称 bin 文件。是否先保存 CSV 备份再删除?", + "delete_stats_file": "删除 bin 文件(如遇问题可尝试)", + "CSV": "不保存 CSV", + "delete_stats_file_done": "游戏 {gamename} 的成就名称 bin 文件已删除。", + "delete_stats_file_failed": "无法删除 bin 文件:{error}", + "appearance": "外观", + "font_size": "字号", + "font_xsmall": "很小", + "font_small": "较小", + "font_standard": "标准", + "font_medium": "较大", + "font_large": "很大", + "theme": "主题", + "theme_system": "跟随系统", + "theme_light": "浅色", + "theme_dark": "深色", + "accent_color": "强调色", + "system": "系统", + "theme_default": "主题默认", + "custom": "自定义...", + "select_accent_color": "选择强调色", + "font_weight": "字体粗细", + "font_normal": "常规", + "font_bold": "粗体", + "button_ok": "确定", + "button_yes": "是", + "button_no": "否", + "button_cancel": "取消", + "auto": "自动", + "ach_number": "成就数量:", + "main_window_group": "主窗口", + "help_tooltips": "工具提示", + "help_tooltips_desc": "

应用中所有工具提示的说明。

", + "tooltip_copy": "将选中内容复制到剪贴板", + "tooltip_paste": "从剪贴板粘贴", + "tooltip_cut": "将选中内容剪切到剪贴板", + "tooltip_delete": "删除选中内容", + "tooltip_select_all": "全选所有单元格", + "tooltip_select_all_columns": "显示所有列", + "tooltip_deselect_all_columns": "隐藏所有列(必选列除外)", + "tooltip_redo": "重做上一步操作", + "tooltip_undo": "撤销上一步操作", + "tooltip_replace_in_column": "在列中查找并替换文本", + "tooltip_switch_lang": "切换到 {} 语言", + "tooltip_select_theme": "选择 {} 主题", + "tooltip_set_font_weight": "设置字体粗细为 {}", + "tooltip_set_font_size": "设置字号为 {}", + "tooltip_toggle_column": "切换 {} 列的显示", + "tooltip_accent_default": "使用主题默认强调色", + "tooltip_accent_custom": "选择自定义强调色", + "tooltip_menu_columns": "切换表格列的显示", + "tooltip_menu_language": "更改应用语言", + "tooltip_menu_appearance": "更改应用外观(主题、字体、颜色)", + "tooltip_menu_theme": "选择颜色主题", + "tooltip_menu_accent": "选择强调色", + "tooltip_menu_font_weight": "选择字体粗细", + "tooltip_menu_font_size": "选择字号", + "file_search_section": "文件搜索", + "file_search_section_expanded": "▼ 文件搜索(已展开)", + "file_search_section_collapsed": "▶ 文件搜索(已折叠)", + "drag_drop_hint": "将 .bin 或 .csv 文件拖放到此处", + "file_dropped_msg": "已拖放文件:{path}", + "tooltip_fetch_missing_names": "扫描所有成就文件并从 Steam API 获取缺失的游戏名称(需要网络连接)", + "fetching_names_progress": "正在获取游戏名称...", + "fetch_complete": "获取完成。已更新 {count} 个名称。", + "fetch_in_progress": "正在获取名称中...", + "loading": "加载中...", + "processing": "正在处理 {game_id}", + "api_block_warning_title": "检测到 Steam API 限制", + "api_block_warning_message": "Steam API 似乎正在限制请求(请求过于频繁)。已暂停加载游戏名称以避免进一步限制。您可以稍后重试。", + "update_steam_app_list": "更新 Steam 应用列表", + "tooltip_update_steam_app_list": "下载完整的 Steam 游戏列表以加快离线查询速度", + "open_in_steam_store": "在 Steam 商店中打开", + "open_in_file_manager": "在文件管理器中打开", + "tooltip_open_in_steam_store": "在浏览器中打开游戏的 Steam 商店页面", + "tooltip_open_in_file_manager": "在文件管理器中打开成就文件所在文件夹", + "store_btn": "在商店中打开", + "tooltip_store_btn": "打开商店页面", + "help": "帮助", + "check_for_updates": "检查更新...", + "tooltip_check_for_updates": "检查是否有新版本可用", + "update_available": "发现新版本", + "update_new_version_available": "有新版本可用!", + "update_current_version": "当前版本", + "update_new_version": "新版本", + "update_whats_new": "更新内容:", + "update_check_automatically": "自动检查更新", + "update_skip_version": "跳过此版本", + "update_remind_later": "稍后提醒", + "update_now": "立即更新", + "update_downloading": "正在下载更新...", + "update_installing": "正在安装更新...", + "update_success": "更新成功", + "update_restart_message": "应用将重启以完成更新。", + "update_install_failed": "更新安装失败", + "update_download_failed": "更新下载失败", + "update_no_download": "没有适用于您平台的可下载文件。", + "update_check": "检查更新", + "update_up_to_date": "您正在使用最新版本。", + "update_check_failed": "检查更新失败", + "fetch_rate_limited": "\n\n⚠️ 在获取 {count} 个请求后被 Steam 限制频率。请稍后再试以获取其余游戏。", + "fetch_error_count": "\n\n{count} 个游戏名称无法获取(可能已从 Steam 下架)。", + "loading_icons": "正在加载图标...", + "update_ready_title": "更新就绪", + "update_restart_confirm": "更新已下载。是否立即重启应用以安装?", + "get_ach_UI": "按名称查找", + "tooltip_get_ach_UI": "从列表中选择,或按游戏名称查找。(Ctrl+O)", + "total_files_count": "文件总数:{count}", + "drag_drop_csv_hint": "拖放行至:", + "imported_to": "已导入到 {lang_name}", + "csv_load_game_needed": "请先加载游戏,或使用包含游戏 ID 的 CSV", + "import_csv_auto_load": "正在自动加载游戏 {game_id}...", + "drag_drop_open_game_hint": "打开游戏 {gamename} ({game_id}) 并导入到:" +} diff --git a/plugins/binary_parser.py b/plugins/binary_parser.py index b628c49..2d9f3c3 100644 --- a/plugins/binary_parser.py +++ b/plugins/binary_parser.py @@ -10,10 +10,10 @@ class BinaryParser: """Handles parsing of Steam binary achievement files""" EXCLUDE_WORDS = { - b'max', b'maxchange', b'min', b'token', b'name', b'hidden', - b'icon_gray', b'Hidden', b'', b'russian', b'Default', b'gamename', - b'id', b'incrementonly', b'max_val', b'min_val', b'operand1', - b'operation', b'type', b'version', b'schinese', b'tchinese' + b'max', b'maxchange', b'min', b'token', b'name', b'hidden', + b'icon_gray', b'Hidden', b'', b'russian', b'Default', b'gamename', + b'id', b'incrementonly', b'max_val', b'min_val', b'operand1', + b'operation', b'type', b'version', b'tchinese' } def __init__(self): @@ -141,6 +141,11 @@ def parse_binary_data(self, data: bytes) -> Tuple[List[Dict[str, str]], List[str for row in all_rows: if 'english' not in row: row['english'] = '' + + # Ensure schinese column exists (Simplified Chinese) + for row in all_rows: + if 'schinese' not in row: + row['schinese'] = '' # Define headers - icon first (if exists), then key, then other columns sorted all_columns = set() @@ -199,4 +204,4 @@ def get_gamename(self, data: bytes) -> Optional[str]: def get_achievement_count(self, data: bytes) -> int: """Count achievements in binary data""" chunks = self.split_chunks(data) - return sum(1 for chunk in chunks if b'\x01english\x00' in chunk and chunk.count(b'\x01english\x00') >= 2) \ No newline at end of file + return sum(1 for chunk in chunks if b'\x01english\x00' in chunk and chunk.count(b'\x01english\x00') >= 2) diff --git a/plugins/steam_lang_codes.py b/plugins/steam_lang_codes.py index e8838ea..981059b 100644 --- a/plugins/steam_lang_codes.py +++ b/plugins/steam_lang_codes.py @@ -25,6 +25,7 @@ 'portuguese': 'Português (Portuguese)', 'brazilian': 'Português-Brasil (Portuguese - Brazil)', 'romanian': 'Română (Romanian)', + 'schinese': '简体中文', 'spanish': 'Español-España (Spanish)', 'latam': 'Español-Latinoamérica (Spanish - Latin America)', 'swedish': 'Svenska (Swedish)', @@ -53,4 +54,4 @@ def get_available_languages_for_selection() -> list: languages = [(code, display) for code, display in STEAM_LANGUAGE_CODES.items()] languages.sort(key=lambda x: x[1]) # Sort by display name - return [code for code, _ in languages] \ No newline at end of file + return [code for code, _ in languages] diff --git a/readmes/README.zh.md b/readmes/README.zh.md new file mode 100644 index 0000000..24391e9 --- /dev/null +++ b/readmes/README.zh.md @@ -0,0 +1,299 @@ +[![en](https://img.shields.io/badge/English-blue.svg)](https://github.com/PanVena/SteamAchievementLocalizer/blob/main/README.md) +[![uk](https://img.shields.io/badge/українська-blue.svg)](https://github.com/PanVena/SteamAchievementLocalizer/blob/main/readmes/README.uk.md) +[![pl](https://img.shields.io/badge/polski-green.svg)](https://github.com/PanVena/SteamAchievementLocalizer/blob/main/readmes/README.pl.md) +[![zh](https://img.shields.io/badge/中文-red.svg)](https://github.com/PanVena/SteamAchievementLocalizer/blob/main/readmes/README.zh.md) + + +

🏆 Steam 成就本地化工具 by Vena

+

+一款基于 PyQt6 的图形化工具,用于查看、编辑和本地化 Steam 成就文件 UserGameStatsSchema_*.bin。 +

+

+⬇️ 下载最新版本 +

+ +

+ Windows + Linux + macOS + Downloads +

+ +

+ 中文界面截图 +

+ +--- + +## 目录 +- [✨ 功能特性](#-功能特性) +- [⚠️ 编辑警告](#️-编辑警告) +- [🚀 快速上手](#-快速上手) +- [📂 文件位置](#-文件位置) +- [📝 导出与导入](#-导出与导入) +- [🧠 处理算法](#-处理算法) +- [🛠 架构与技术细节](#-架构与技术细节) +- [❓ 常见问题](#-常见问题) +- [🎨 主题开发](#-主题开发) +- [🌍 本地化翻译](#-本地化翻译) +- [🤝 参与贡献](#-参与贡献) +- [🔐 许可证](#-许可证) +- [👤 作者与社区](#-作者与社区) +- [💬 联系方式](#-联系方式) + +--- + +## ✨ 功能特性 +- **🚀 自动检测 Steam 路径**(Windows 注册表 / Linux / Snap 版;macOS 部分支持)。 +- **📂 两种加载模式:** + - 手动模式(选择一个 `.bin` 文件); + - 通过游戏 ID 加载(可粘贴完整链接,如 `https://store.steampowered.com/app/123456/`)。 +- **🏆 成就解析与表格生成:** + - 如区块中存在重复项,自动为描述创建单独行(`*_opis`); + - 缺少 `ukrainian` 列时自动补充; + - 确保 `english` 列始终存在(文件中缺失则为空)。 +- **✏️ 表格编辑**:可在应用内直接编辑。 +- **🔍 全局搜索**:支持高亮 + 行过滤。 +- **🔄 查找与替换**:针对选定列的对话框式查找替换。 +- **👁️ 列显隐切换**。 +- **📤 CSV 导出:** + - 完整导出(文件中的所有语言); + - 翻译格式导出(english + translation + context)。 +- **📥 CSV 导入**:将翻译数据导入到指定语言列。 +- **💾 保存本地化内容**到二进制文件内。 +- **📁 在文件管理器中查看并打开**原始二进制文件。 +- **📋 Steam 中所有 `UserGameStatsSchema_*.bin` 文件列表**,包含: + - 游戏名称(`gamename`); + - 版本(`version`); + - 大致成就数量(通过 English 条目数估算)。 +- **⚙️ 设置缓存**(通过 `QSettings`):界面语言、路径、上次 ID、上次版本(用于更新提醒)。 +- **🌍 可扩展的多语言界面**:目前支持 English / Українська / Polski / 简体中文。 +- **🎨 动态主题系统**:主题从 JSON 文件自动加载。 +- **🔌 插件式架构**:模块化组件设计。 + +--- + +## ⚠️ 编辑警告 +编辑 `.bin` 文件可能导致: +- Steam 缓存冲突; +- 显示文本不正确; +- 需要重新生成文件。 + +如果游戏中未显示你的翻译: +1. 关闭 Steam。 +2. 删除目标文件 `UserGameStatsSchema_XXXX.bin`。 +3. 打开该游戏的商店/社区页面(文件会重新生成)。 +4. 重新应用你的翻译。 + +建议:修改前务必备份原始 `.bin` 文件。 + +--- + +## 🚀 快速上手 +1. 下载[最新版本](https://github.com/PanVena/SteamAchievementLocalizer/releases/latest)。 +2. 运行可执行程序。 +3. 输入游戏 ID 或手动选择 `.bin` 文件。 +4. 进行翻译 / 编辑。 +5. (可选)导出 CSV → 发给翻译人员 → 导入回来。 +6. 保存: + - 直接保存到 Steam 目录(立即生效); + - 或保存到自定义路径(用作备份 / 分发)。 + +--- + +## 📂 文件位置 +Windows 典型路径: +``` +C:\Program Files (x86)\Steam\appcache\stats\UserGameStatsSchema_XXXX.bin +``` +Linux(其中一种): +``` +~/.local/share/Steam/appcache/stats/UserGameStatsSchema_XXXX.bin +``` +Snap 版路径会自动搜索。 +macOS 目前无法保证自动检测(如需请手动选择)。 + +--- + +## 📝 导出与导入 + +### 完整导出 +CSV 包含所有列(包括可能的内部/服务列),适合分析或存档。 + +### 翻译导出 +结构: +``` +key,english,translation, +``` +- `translation` — 翻译人员编辑的列。 +- `` — 额外选择的上下文列(通过对话框选择),如 `polish`、`german` 或描述列等。 + +### 导入 +1. 在对话框中选择目标列(数据将写入该列)。 +2. 加载包含 `key`、`translation` 字段的 CSV。 +3. 空的 `translation` 单元格将被忽略(保留现有值)。 + +### 备注:有意替换 english 列 +如果你希望用(例如)最终定稿的本地化版本或编辑后的文本覆盖内建的 `english` 字符串: +- 以翻译格式导出(保留原始 english)。 +- 编辑 `translation` 列,填入应成为新 "english" 的文本。 +- 导入时选择 `english` 作为目标列。 +- 工具将清除每个区块中的旧 English 条目并注入新内容。 +这样你可以将 english 列改造为规范化 / 清理后 / 社区认可的基准文本。请注意其他本地化内容可能依赖原始英语的语义;建议先用完整导出 CSV 进行归档。 + +--- + +## 🧠 处理算法 +1. 读取原始文件字节。 +2. 通过标记 `\x00bits\x00 | \x02bit\x00` 分割为区块。 +3. 在区块内通过模式 `\x00\x01name\x00(.*?)\x00` 查找成就键。 +4. 丢弃不含 `\x01english\x00` 的区块(确保基本可本地化性)。 +5. 通过模式 `\x01\x00\x00` 提取语言标签。 +6. 过滤服务词(`EXCLUDE_WORDS` 集合)。 +7. 生成两个潜在行: + - 主行(`key`); + - 描述行(`key_opis`),当出现重复语言键时。 +8. 确保 `ukrainian` 和 `english` 列存在(缺失则插入空值)。 +9. 构建表格并排序列头:`key`、`ukrainian`、`english`,其余按字母排序。 +10. 保存时: + - 清除先前的语言片段(针对正在重写的特定语言); + - 在 `english` 标记后插入新片段,若编辑 English 本身则替换; + - 输出重建的二进制区块。 + +--- + +## 🛠 架构与技术细节 +| 组件 | 说明 | +|------|------| +| 界面 | PyQt6(`QMainWindow`、`QTableWidget`) | +| 状态持久化 | `QSettings`(语言、路径、版本、上次 ID) | +| **本地化** | **从 `assets/locales/` 自动加载带元数据的 JSON** | +| **主题** | **从 `assets/themes/` 自动加载 JSON,按优先级排序** | +| **插件系统** | **模块化组件:`theme_manager`、`ui_builder`、`file_manager` 等** | +| 搜索高亮 | 自定义 `HighlightDelegate` | +| 对话框 | `FindReplaceDialog`、`ContextLangDialog`、`UserGameStatsListDialog` | +| 界面框架 | 自定义 JSON 本地化系统(非 Qt Linguist) | +| 插入算法 | 位置扫描 + 逐字节 `bytearray` 组装 | +| 行生成 | 启发式去重算法(描述归入 `_opis`) | + +--- + +## ❓ 常见问题 + +| 问题 | 解答 | +|------|------| +| Steam 中看不到翻译 | 关闭 Steam → 删除文件 → 打开游戏页面 | +| 列表为空 | 文件错误或缺少 `english` 标记 | +| 显示乱码 | 确保使用 UTF-8 编码和正确的 CSV 格式 | +| 导入后无法撤销 | 导入会完全重建表格,这是预期行为 | +| 支持多少种语言? | `.bin` 文件中存在的语言均可支持,外加强制添加的 `ukrainian` | +| 如何添加新的界面语言? | 在 `assets/locales/` 中添加 JSON 文件即可 | + +--- + +## 🤝 参与贡献 +1. Fork → 创建分支 → 提交修改 → 发起 Pull Request。 +2. 明确说明 PR 的修改内容(界面 / 逻辑 / 本地化)。 +3. **贡献主题** — 直接将 JSON 文件添加到 `assets/themes/` 目录(详见[主题指南](readmes/contribution/THEMES.md))。 +4. **贡献语言** — 直接将 JSON 文件添加到 `assets/locales/` 目录(详见[本地化指南](readmes/contribution/LOCALES.md))。 +5. 验证要点: + - 文件加载是否正常; + - 导出 / 导入功能是否正常; + - 保存到 Steam 和保存到独立文件是否正常; + - 切换界面语言时是否不崩溃。 + +无需编写代码即可提出建议 — 直接发起 Issue 即可。 + +--- + +## 🎨 主题开发 + +想为应用创建自定义主题?**无需修改代码!** + +只需在 `assets/themes/` 目录中创建一个 JSON 文件,你的主题就会自动出现在菜单中。 + +**📖 文档:** +- **[主题创建指南(英文)](readmes/contribution/THEMES.md)** — 创建自定义主题的完整说明 +- **[Посібник зі створення тем(乌克兰语)](readmes/contribution/THEMES_UA.md)** — 乌克兰语完整说明 + +**✨ 特性:** +- 🎨 **自动发现**:放入 JSON 主题文件 → 自动出现在菜单中 +- 🌍 **多语言支持**:主题名称支持多种语言 +- 📊 **智能排序**:通过优先级值控制主题显示位置 +- 🎯 **无需编程**:纯 JSON 配置,无需修改源码 + +**主题结构示例:** +```json +{ + "name": "MyTheme", + "display_names": { + "en": "🌙 Dark Blue", + "ua": "🌙 Темно-синя" + }, + "priority": 50, + "palette": { /* 颜色 */ }, + "styles": { /* CSS样式 */ } +} +``` + +--- + +## 🌍 本地化翻译 + +想为应用添加你的语言?**无需修改代码!** + +只需在 `assets/locales/` 目录中创建一个 JSON 文件,你的语言就会自动出现在菜单中。 + +**📖 文档:** +- **[语言添加指南(英文)](readmes/contribution/LOCALES.md)** — 添加新语言的完整说明 +- **[Посібник з додавання мов(乌克兰语)](readmes/contribution/LOCALES_UA.md)** — 乌克兰语完整说明 + +**✨ 特性:** +- 🌐 **自动发现**:放入 JSON 语言文件 → 自动出现在语言菜单中 +- 📊 **智能排序**:通过优先级值控制语言显示位置 +- 🔄 **回退系统**:缺失的翻译自动回退到英文 +- 🎯 **无需编程**:纯 JSON 配置,无需修改源码 + +**语言文件结构示例:** +```json +{ + "_locale_info": { + "name": "Español", + "native_name": "Español (Spanish)", + "code": "es", + "priority": 40 + }, + "app_title": "Localizador de Logros...", + "language": "Idioma" + // ... 其他翻译 +} +``` + +**当前支持语言:** +- 🇬🇧 **English**(priority: 10) +- 🇺🇦 **Українська**(priority: 20) +- 🇵🇱 **Polski**(priority: 30) +- 🇨🇳 **简体中文**(priority: 40) + +--- + +## 🔐 许可证 +MIT — 自由使用、修改、翻译。欢迎给个 ⭐ 和注明作者。 + +--- + +## 👤 作者与社区 +作者:**Vena** +- [GitHub](https://github.com/PanVena) +- Telegram: [@Pan_Vena](https://t.me/Pan_Vena) + +翻译 / 讨论社区: +- 频道:[Ліниві ШІ](https://t.me/linyvi_sh_ji) + +--- + +## 💬 联系方式 +想法 / 问题 / bug 反馈 → 发起 Issue 或 Telegram 联系。 +喜欢这个项目? — 分享给本地化社区并点个 ⭐。 + +

为本地化与游戏而生 💛💙

diff --git a/readmes/screens/scrn_zh.png b/readmes/screens/scrn_zh.png new file mode 100644 index 0000000..a954e93 Binary files /dev/null and b/readmes/screens/scrn_zh.png differ