From 2ebbb38edab35053c9ffca1b6bd371d7aaf85b85 Mon Sep 17 00:00:00 2001 From: zyf722 <1124982772@qq.com> Date: Mon, 4 Mar 2024 14:35:04 +0800 Subject: [PATCH] feat: add update-histogram-only option --- examples/bf1chs/__main__.py | 135 +++++++++++++++++++++++++++++++++++ flamethrower/localization.py | 9 ++- 2 files changed, 143 insertions(+), 1 deletion(-) diff --git a/examples/bf1chs/__main__.py b/examples/bf1chs/__main__.py index b97e716..7cd2cd4 100644 --- a/examples/bf1chs/__main__.py +++ b/examples/bf1chs/__main__.py @@ -924,6 +924,136 @@ def _save_strings_binary_runner(file_path: str): f"[bold green]已完成本地化文件更新。导入 Chunk 时请一并修改 BinaryChunkSize 为 [underline]{strings_binary.chunk_size}[/] 。\n" ) + def _update_histogram(self): + """ + Update the histogram chunk file only. + """ + histogram_path = os.path.abspath(self.config["localization.histogramPath"]) + if not os.path.exists(histogram_path): + console.print(f"[yellow]码表路径 {histogram_path} 不存在。") + if self._rich_confirm(message="是否创建?"): + os.makedirs(histogram_path) + console.print( + f"[yellow]请将导出后的码表文件放入路径 {histogram_path} 后重新选择本项。\n" + ) + return + + strings_path = os.path.abspath(self.config["localization.stringsPath"]) + if not os.path.exists(strings_path): + console.print(f"[yellow]本地化文件路径 {strings_path} 不存在。") + if self._rich_confirm(message="是否创建?"): + os.makedirs(strings_path) + console.print( + f"[yellow]请将导出后的本地化文件放入路径 {strings_path} 后重新选择本项。\n" + ) + return + + original_histogram_path = self._rich_fuzzy_select_file( + directory=histogram_path, + types=[".chunk", ".bin"], + message="选择需要更新的原始码表文件", + ) + if original_histogram_path is None: + return + + extra_chars_path = self._rich_fuzzy_select_file( + directory=histogram_path, + types=[".txt"], + message="选择额外字符列表文件", + ) + if extra_chars_path is None: + return + + original_strings_path = self._rich_fuzzy_select_file( + directory=strings_path, + types=[".chunk", ".bin"], + message="选择需要更新的原始本地化文件", + ) + if original_strings_path is None: + return + + histogram = Histogram(original_histogram_path) + + console.print("[bold green]已读取原始码表文件。\n") + self._rich_show_object(histogram) + + def _create_strings_binary_runner( + original_histogram_path: str, original_strings_path: str + ) -> StringsBinary: + return StringsBinary( + Histogram(original_histogram_path), original_strings_path + ) + + strings_binary: StringsBinary = self._rich_indeterminate_progress( + task_name="读取本地化文件", + short_name="读取", + actor=_create_strings_binary_runner, + original_histogram_path=original_histogram_path, + original_strings_path=original_strings_path, + ) + if strings_binary is None: + return + + self._rich_show_object(strings_binary) + + # Load new chars file + with open(extra_chars_path, "r", encoding="utf-8") as f: + extra_chars = f.read().splitlines() + + added = histogram.add_chars_from_strings([], extra_chars) + console.print(f"[bold green]已添加 {added} 个字符至码表。\n") + + new_histogram_path = self._rich_text( + message="输入新的码表文件名", + default=f"new-{os.path.basename(original_histogram_path).rsplit('.', 1)[0]}.chunk", + filter=lambda x: os.path.join(histogram_path, x), + ) + if os.path.exists(new_histogram_path): + console.print(f"[yellow]码表文件 {new_histogram_path} 已存在。\n") + if not self._rich_confirm(message="是否覆盖?"): + return + console.print() + + histogram.save(new_histogram_path) + + histogram = Histogram(new_histogram_path) + self._rich_show_object(histogram) + console.print( + f"[bold green]已完成码表更新。导入 Chunk 时请一并修改 HistogramChunkSize 为 [underline]{histogram.chunk_size}[/] 。\n" + ) + + new_strings_path = self._rich_text( + message="输入新的本地化文件名", + default=f"new-{os.path.basename(original_strings_path).rsplit('.', 1)[0]}.chunk", + filter=lambda x: os.path.join(strings_path, x), + ) + if os.path.exists(new_strings_path): + console.print(f"[yellow]本地化文件 {new_strings_path} 已存在。\n") + if not self._rich_confirm(message="是否覆盖?"): + return + console.print() + + def _save_strings_binary_runner(file_path: str): + strings_binary.update(histogram) + strings_binary.save(file_path) + return True + + if ( + self._rich_indeterminate_progress( + task_name="保存本地化文件", + short_name="保存", + actor=_save_strings_binary_runner, + file_path=new_strings_path, + ) + is None + ): + return + + self._rich_show_object(strings_binary) + console.print( + f"[bold green]已完成本地化文件更新。导入 Chunk 时请一并修改 BinaryChunkSize 为 [underline]{strings_binary.chunk_size}[/] 。\n" + ) + def _update_twinkle(self): """ Generate twinkle dynamic files. @@ -1275,6 +1405,11 @@ def run(self): "desc": "根据替换后的 .json 汉化文件生成码表、更新导出的原始本地化文件,并生成新的本地化文件。", "actor": self._update_strings, }, + "update-histogram": { + "name": "生成 Frosty Editor 码表并更新静态本地化 chunk 文件(仅插入新字符)", + "desc": "将给定的字符列表文件中的字符序列加入码表、更新导出的原始本地化文件,并生成新的本地化文件。本功能仅基于输入的字符列表文件,不会对原有的码表和本地化文件进行修改。", + "actor": self._update_histogram, + }, "twinkle": { "name": "更新 Frosty Editor 动态本地化 chunk 文件", "desc": "根据替换后的 .json 汉化文件生成可读取的动态本地化文件。", diff --git a/flamethrower/localization.py b/flamethrower/localization.py index bd012a1..88f5525 100644 --- a/flamethrower/localization.py +++ b/flamethrower/localization.py @@ -118,12 +118,15 @@ def load(self, file_path: str) -> None: ): self.section.append(chr(char)) - def add_chars_from_strings(self, strings: Iterable[str]) -> int: + def add_chars_from_strings( + self, strings: Iterable[str], extra_chars: Optional[Iterable[str]] = None + ) -> int: """ Add chars to the histogram. Necessary shifts will be added automatically. Args: strings (Iterable[str]): The strings containing chars to add. + extra_chars (Optional[Iterable[str]]): Extra chars to add. Each str should only be one char. Returns: int: The amount of chars added. @@ -135,6 +138,10 @@ def add_chars_from_strings(self, strings: Iterable[str]) -> int: char_set: Set[str] = set() for value in strings: char_set.update(value) + + if extra_chars: + char_set.update(extra_chars) + chars = list(char_set.difference(self.section)) # Calculate needed indices