解决galgame读取中文-UIF+词典

前言

galgame汉化的最后一步是让galgame读取中文,传统方式是将翻译后的中文文本以GBK方式保存,注入封包后,修改字体脚本,修改exe编码,使得exe以GBK方式读取以GBK编码保存的文本。 这种方法从流程上看十分简单直观:我翻译得到了中文文本,自然用GBK编码保存,再修改游戏脚本、exe文件,使得exe以GBK方式读取文本。

问题及解决办法

这个方法有个致命的问题:修改游戏脚本的字体代码、修改exe编码的解法不通用,通用性差十分致命!这往往导致一个游戏一种修改exe、脚本代码的方法,在你花费大量时间、大量精力得到解往往是个特解,无法复用。10个游戏有10个特解,你总是在找特解的路上,十分辛苦,而且这种特解很少有人分享解法,你无法借鉴,一个人死磕的后果往往是时间花了,也不会得出特解。即使幸运,有人分享了解法,往往是解法步骤不清晰或者不全面,无法解决你的问题。

因此通解的寻找就显得尤为重要,这一个通解耗费的时间和一个特解想相同,但一个通解可以解十个问题,价值十分巨大!

在阅读cx2333大佬的GalTransl项目时,注意到了UniversalInjectorFramework(UIF)框架,该框架可以用来修改现有Windows应用程序的行为,替换游戏文本。这里给出UIF的github链接

用易于理解的话来解释UIF的作用,UIF可以hook游戏,根据用户自定义键值对映射key-value,每当游戏文本出现keyUIF便会将其替换为value而且与编码格式无关!!!

与编码格式无关这一特点价值十分巨大,这使得译者无需考虑各种编码的变化,而是简单的考虑key-value键值对。如此一来,我们放弃之前复杂多变的修改游戏exe和代码脚本,游戏便会以初始状态,以SJS(日文编码)读取文本,让UIF将日文字符替换成中文字符,便达到了让galgame读取中文的目的。

这样依然有个问题,如何设置键值对,或者说,日文字符和中文字符的对应关系是什么?

首先我们要知道,有些中文字符,在日文编码范围中也存在,比如模、式、的、与等字符,而有些中文字符显、约,在日文中有非常相像的字符顕、約

所以显、约就必须替换,否则SJS编码格式无法读取,模、式、的、与无需替换,SJS编码格式可以读取。

在理解了替换范围的定义之后,其实仍然不好确定键值对,毕竟SJS无别读取的汉字那么多,很难定义全面。

幸运的是cx2333大佬再次救场,它给出了SJS无法识别的汉字和相像的日文字符映射关系,定义了SJS替换词典,该词典十分全面,基本涵盖了所有SJS无法读取的汉字。给出词典链接

UIF实现流程

不妨设词典中中文为cn,日文为jp,映射关系确定后,流程是这样

  1. 翻译后的中文文本,遇到cn,将其替换成jp,如此一来,该中文文本便可以以SJS编码格式保存
  2. 注入、封包等常规流程后,在游戏根目录加入.dllUIF框架和UIFconfig,其中UIFconfig含有替换词典
  3. 打开游戏,UIF自动hook游戏,将ja替换成cn,于是完成闭环,实现了让galgame读取中文的目的

总结

UIF替换的方法通用性强,改变了复杂多变的修改游戏exe和代码脚本特解方向,用一种通解实现让galgame读取中文的目的。

强烈推荐这种办法!