KeyFansClub

首页 » - 特色讨论区 - » 土豆星 » 土卫三 » Planetarian 汉化测试第一版下载
亡灵之猫 - 2004/12/17 10:01:00
由于没时间用只能给楼主点建议:
1.如果楼主使用DC写屏建议改为DirectDraw写屏(加DoubleBuffer)这或许可以避免中日文重叠
具体方法为:
启动=======================================================================
查找程序进程->获取MainForm句柄->用DDraw建立两个Buffer(Buffer A、Bufer B)
===========================================================================
线程1(循环运行)==========================================================
封闭Buffer A -> 取内存识别游戏当前显示页(这个偶不懂)-> 在Buffer A中生成覆盖原文的背景 -> 将翻译文字写入Buffer A(用光栅运算抠像)-> 开放Buffer A -> 延时
===========================================================================
线程2(循环运行)==========================================================
判断buffer A是否封闭,当前buffer A是否已写入 Buffer B -> 如果buffer A已开放且buffer A未写入buffer B则将buffer A 复制到buffer B -> 将buffer B切换到游戏MainForm最前页覆盖当前屏幕
===========================================================================
线程2可防止游戏刷新屏幕造成重叠

2.本程序的兼容性问题与GDI版本和DirectX版本有关,编译时最好用VC++的编译器,另外不要使用GDI+和Win3.X的API,建议在DirectX9.0c环境下开发补丁,把DirectX9.0c客户端与补丁放在一起供人下载

这只是一个设想供楼主参考,如果楼主用的是更好的方法那么54以上内容,由于对线程、内存操作等API和DirectX8.1不太熟所以本人只有抬着嘴说的份,技术上看来是帮不了什么忙了。
scegg - 2004/12/17 10:07:00
我是来支持的,顺问一下,AIR的汉化什么时候好……
亡灵之猫 - 2004/12/17 10:14:00
以下引用scegg在2004-12-17 10:07:02的发言:
我是来支持的,顺问一下,AIR的汉化什么时候好……

某人说元旦前后或Air开播时
粘土火星 - 2004/12/17 10:16:00


来张图~v~
kkkklll - 2004/12/17 11:03:00
多谢大家的测试和意见。

不过DirectDraw这东西,老实说,偶不会,最近也没时间去学。据说是好繁的说。偶只会直接用CopyRect、OutText之类的写屏。因为我毕竟不是这方面的专业人员,比起系统,我更熟悉算法。

上面的那些日文的擦掉后是黑的的问题,估计可以用让它不显示日文来解决(正在进行中……)。还有我的屏幕从来都是800*600的,所以没有考虑其他分辨率……呵呵。下次看看能不能加上去。

全屏模式下显示出错的问题,我怀疑是用的Delphi版本有Bug(原来用的是6.0,正在下载最新版)或者是某些函数在某系统的全屏下无效?……(呵呵)

用到函数:CopyRect和Mask、GetDC。有哪位大侠知道吗?
Basara - 2004/12/17 11:55:00
严重支持......
顺便附上在下机器上的运行效果图...
[IMG=upload/KFCFile2084_untitled.JPG]上传文件2084[/IMG]
PS:拖动窗口的话字幕的位置也跟着一起动...
粘土火星 - 2004/12/17 11:58:00
恩……现在需要让窗口的位置适应字幕位置(笑),凭根性绝对能玩下去咯~v~
Basara - 2004/12/17 12:00:00
以下引用梦想残光霞在2004-12-16 21:47:41的发言:
=v=||||~~
现在才醒悟过来……
因为自己用的是日文XP……
所以需要安装一个中文字体才能测试……
得先去想办法解决这问题………………
…………………………
…………………………
…………………………
还请大家多帮忙测试一下啦
我也得加速翻译了
这个,把系统区域转到中文PRC就解决了...
亡灵之猫 - 2004/12/17 12:28:00
以下引用kkkklll在2004-12-17 11:03:37的发言:
多谢大家的测试和意见。

不过DirectDraw这东西,老实说,偶不会,最近也没时间去学。据说是好繁的说。偶只会直接用CopyRect、OutText之类的写屏。因为我毕竟不是这方面的专业人员,比起系统,我更熟悉算法。

上面的那些日文的擦掉后是黑的的问题,估计可以用让它不显示日文来解决(正在进行中……)。还有我的屏幕从来都是800*600的,所以没有考虑其他分辨率……呵呵。下次看看能不能加上去。

全屏模式下显示出错的问题,我怀疑是用的Delphi版本有Bug(原来用的是6.0,正在下载最新版)或者是某些函数在某系统的全屏下无效?……(呵呵)

用到函数:CopyRect和Mask、GetDC。有哪位大侠知道吗?


楼上用的函数在Win9X以上的系统中都能用(参考MSDN2003 Oct),但是问题是游戏是基于DirectX的程序,其优先级很高,而且是以缓存+换页的方式显示,自然在覆盖上会存在问题。不知道楼主会不会把文字写在一张位图上(反正我不会),位图字用颜色0xFFFFFF,底版用颜色0x000000,建立一个程序MainForm的DC,把位图载入DC中用光栅运算“AND”,这样就获得抠像后的文字DC,禁止日文显示后,反复将这个DC复制到窗体本生的DC中或许可以解决覆盖问题。至于文字移位的问题我建议统一一下DirectX的版本收集测试结果,如果确认是操作系统的兼容问题,那么就在启动时先识别操作系统版本,分别确定左上角位置。

我还有一种想法:继承游戏的主窗体再建一个子窗体,用SetWindowPos()函数(记不清是不是这个名字来着)将窗体置为最前,然后把文字显示在那个窗体上....
rockmanxy - 2004/12/17 12:57:00
看看
kkkklll - 2004/12/17 13:02:00
PS:拖动窗口的话字幕的位置也跟着一起动...


这个应该不可能吧,汗一个。我写屏的函数都是按屏幕的绝对坐标写的,而且,我也没得到Planetarian窗口的位置。可能是没更新。

其实,这些问题下个版本肯定不会有的(希望……呵呵).
亡灵之猫 - 2004/12/17 13:07:00
严重支持楼上的!
Basara - 2004/12/17 13:12:00
以下引用kkkklll在2004-12-17 13:02:51的发言:

这个应该不可能吧,汗一个。我写屏的函数都是按屏幕的绝对坐标写的,而且,我也没得到Planetarian窗口的位置。可能是没更新。

其实,这些问题下个版本肯定不会有的(希望……呵呵).
嗯,的确如此,偶记错了=v=
总之期待正式版了XD
Nowitzkiwc - 2004/12/17 17:11:00
有速度==||
明天回家实验= =
kkkklll - 2004/12/17 17:23:00
偶知道是虾米问题了,显不出是因为切换了屏幕后没有改变写的位置,结果写到外面去了,呵呵。

我的机器一直是800×600分辨率,所以可以显示。
亡灵之猫 - 2004/12/17 17:41:00
以下引用kkkklll在2004-12-17 17:23:54的发言:
偶知道是虾米问题了,显不出是因为切换了屏幕后没有改变写的位置,结果写到外面去了,呵呵。

我的机器一直是800×600分辨率,所以可以显示。


我想还是表用绝对坐标,因为窗体样式可改,容易引起误差。

以下引用亡灵之猫在2004-12-17 12:28:16 的发言:
我还有一种想法:继承游戏的主窗体再建一个子窗体,用SetWindowPos()函数(记不清是不是这个名字来着)将窗体置为最前,然后把文字显示在那个窗体上....


还有千万不要想用嵌入的方式写屏。我的想法就是因为这个而行不通的。
程序redraw时会把我的窗体也给覆盖了,只有通过不断Refersh来维持窗体,这会使得字幕不稳定,显示图之类的更是惨不忍睹,看来楼主只有在程序外部作文章了!
以下是程序草稿和源代码(Delphi7),虽然实现不了,但是也许对楼主有所帮助:

这里下载

先启动我的程序,再启动planetarian,用鼠标点击planetarian窗体任意位置即可看到实现的效果。

PS:看到寄生窗体中的那些数字了吗?他们是文字窗的相对坐标,依次代表x,y,cx,xy(从横行看起)
sizzflair - 2004/12/17 20:21:00
呵呵,Planetarian终于被破解了~
支持楼主~
wdx04 - 2004/12/18 0:38:00
问一下楼主,外挂字幕是如何实现和游戏同步的?是通过API Hook、调试API、硬件断点还是别的技术?
    我在做的对脚本引擎的逆向工程遇到了很大的阻碍。现在已经查明SEEN文件位于kineticdata.pak的
偏移29B00D8h处,大小为8506Ch字节,前面38h字节为头部,游戏初始化时读入内存并进行第一轮解密。
通过目录或存档进入游戏时还要再解密一次,才得到真正的脚本。最大的困难在于虚拟地址004F3210处
的一个子程序。这个子程序是整个解密算法的核心,两轮解密都要用到,长度为22F9h字节,有36个输入
参数,里面大量使用多层间接寻址和跳跃表,最后还有389个ret返回出口。看到这个样子我已经觉悟到
要在短期内还原它的算法是不可能了。下个月我考研,现在只有放弃。期待楼主早日做出正式版。
    另外游戏中的文字到底是用什么方法显示的也不清楚。SoftICE装载了ddraw.dll,d3d8.dll,d3d9.dll
之后,DirectDrawCreate、DirectDrawCreateEx、Direct3dCreate8、Direct3dCreate9及常规GDI中的
TextOut、ExtTextOut、DrawText、DrawTextEx等函数都拦截不到文本输出。
亡灵之猫 - 2004/12/18 1:54:00
以下引用wdx04在2004-12-18 0:38:19的发言:
    问一下楼主,外挂字幕是如何实现和游戏同步的?是通过API Hook、调试API、硬件断点还是别的技术?


我想没那么复杂吧,对基于DirectX编写的程序来说API Hook等钩子是不起作用的,因为对系统的调用都交给了DX。似乎要同步外挂字幕只需要监控程序内存,获得当前换页的相关参数就可以实现

以下引用wdx04在2004-12-18 0:38:19的发言:
    另外游戏中的文字到底是用什么方法显示的也不清楚。SoftICE装载了ddraw.dll,d3d8.dll,d3d9.dll
之后,DirectDrawCreate、DirectDrawCreateEx、Direct3dCreate8、Direct3dCreate9及常规GDI中的
TextOut、ExtTextOut、DrawText、DrawTextEx等函数都拦截不到文本输出。


wdx兄作个实验看看,直接用光栅运算为文字和图片作镂空(即“抠像”),发现问题了吗?直接镂空的文字和图片其曲线边缘有明显锯齿,而你看游戏中图像和文字(高品质下),边缘十分平滑,没有锯齿。
要实现这种效果有两种方法:
1. 3D实现法,将文字以贴图的方式画在一个面片上,打开平滑渲染模式,由硬件计算半透明镂空。
2. 2D实现法,将文字预先DRAW到一个Buffer中,用光栅运算镂空,在把Buffer中的图与背景叠加并计算一个半透明的边。

显然,无论以上哪种方法,写文字时都用不到绘图API函数,自然不能截取。既然已知文字的解密途径,不如监控文字Buffer的位置,这样便可以拦截到文字。
根据我的验证Planetarian的引擎使用了上述的“方法2”,因为在实验窗体时我发现文字是以块为单位画上去的,每个文字都是一个矩形块,而且这样做也方便了字幕滚动效果的生成。
kkkklll - 2004/12/18 11:12:00
以下引用wdx04在2004-12-18 0:38:19的发言:
    问一下楼主,外挂字幕是如何实现和游戏同步的?是通过API Hook、调试API、硬件断点还是别的技术?


其实很简单,那就是……读内存,每隔X毫秒读一次内存,变了就更新字幕。这个方法还是比较好用的,基本所有程序都可以通用。

不过在pl中其实是读不到正在显示的字符的(其他大多能读到),所以比较麻烦,得去找一个对应显示内容列表的内存位置(不同机器还可能不一样……)。API Hook等瓜瓜,我本身都不熟,不能熟练运用。呵呵。


  另外游戏中的文字到底是用什么方法显示的也不清楚。SoftICE装载了ddraw.dll,d3d8.dll,d3d9.dll
之后,DirectDrawCreate、DirectDrawCreateEx、Direct3dCreate8、Direct3dCreate9及常规GDI中的
TextOut、ExtTextOut、DrawText、DrawTextEx等函数都拦截不到文本输出。


还好没去找什么拦截,不然又白费时间了。

顺便问一下,有没有什么函数可以将程序的ProcessID转成它的窗口的HWND的。用其他方法,只要能得到Pl的窗口位置就行。
wdx04 - 2004/12/18 11:46:00
没有直接的方法。用EnumWindows枚举所有顶层窗口的HWND,然后用GetWindowThreadProcessId取得它的
ProcessID,一个一个验证。
如果限定于Pl的窗口的话,更好的办法可能是直接调用FindWindow,
使用窗口类名
"VisualArts_System2000_KINETIC_planetarian 乣偪偄偝側傎偟偺備傔乣"。

另外还有疑问:每隔X毫秒读取的内存区域是如何确定的?
kkkklll - 2004/12/18 13:08:00
在第一次读入字符数据(就是Pl的Load或New的时候)时,内存中会有某段是固定的字符,查找这些固定字符的位置就行了。

Findwindow的窗口名是什么?我实在不知道怎么把那几个字弄出来。
wdx04 - 2004/12/18 14:04:00
FindWindow不需要完全指定两个参数,窗口名NULL(0)就可以了。
其实可以用工具得到窗口名,如M$的Spy++和Borland的WinSight。

是这样啊。我也已经发现,虽然在Load或New的时候,整个脚本会被解密放到用GlobalAlloc
分配的内存中,但每隔一段时间就被GlobalFree了。之后再反复执行GlobalAlloc/GlobalFree,
分配到的虚拟地址可能发生改变,但一般会出现在02XXXXXXh处。如果每隔X毫秒搜索固定字符串
的话,中间会有一段时间找不到,然后可能在同一位置或另一个位置找到。
另外程序每次显示一小段字符都要单独用GlobalAlloc分配内存,
把字符复制过去,显示完就GlobalFree释放。
kkkklll - 2004/12/18 14:35:00
Findwindow Ok了,谢谢楼上了。

天哪,我本想用将内存中文字全部写成空格来让它不显示的,居然还要改地址。看来让它不显示还比较麻烦,估计查找一次就得N秒。(地址有一次我在07XXXXXX才找到,汗一个)

至于我找的内存,是在比较前面,和文本无关(应该和偏移地址有关)的一组数据,你用fpe去查一下就知道了。注意:前面四句的偏移地址比较后。
wdx04 - 2004/12/18 16:51:00
是以 00 00 00 00 38 00 00 00 开始的头部吗?
这38h字节的文件头中的大部分数据项(DWORD值)都在4F3210子程序里用到了。
又发现了一个问题,解密的脚本并没有被释放,只是改变了映射。而且,
如果游戏不被中断(比如Alt+Tab切换或调试器中断),有可能并不会发生地址映射改变。

地址在07XXXXXX是不是因为同时运行的程序太多?我每次都是启动Windows就开始调试,
每次都在03000000以下,一般用S命令搜索只到08000000,时间应该少于0.5秒。
kkkklll - 2004/12/18 18:25:00
以下引用wdx04在2004-12-18 16:51:17的发言:
是以 00 00 00 00 38 00 00 00 开始的头部吗?
这38h字节的文件头中的大部分数据项(DWORD值)都在4F3210子程序里用到了。


不是,不过不知道前面有没有这个。地址大约在7AXXXX附近。


又发现了一个问题,解密的脚本并没有被释放,只是改变了映射。而且,
如果游戏不被中断(比如Alt+Tab切换或调试器中断),有可能并不会发生地址映射改变。

地址在07XXXXXX是不是因为同时运行的程序太多?我每次都是启动Windows就开始调试,
每次都在03000000以下,一般用S命令搜索只到08000000,时间应该少于0.5秒。

的确,那次运行了N多程序。搜索时间长应该是我的算法问题,呵呵,可以改进。
canvas - 2004/12/19 21:02:00
Xp ok Ma ? ... ''
But Also Thx A Lot ^^
wdx04 - 2004/12/19 21:03:00
今天又遇到一个问题,我把游戏字体强制改为宋体,并在缓冲区中放入一些GB2312编码的中文字符,
发现一个奇怪的现象,所有放进来的中文字符都被当成日文内码转换为Unicode,而日文字符又被当成中文内码。
结果就是没有一个字符能正常显示,而且许多中文字符被当成日文转换为Unicode时失败,导致程序死锁。
问题的关键在于一个GDI函数GetGlyphOutline,此函数是根据一个给定DC中的字体,把一个字符转换为位图。
函数执行中调用了MultiByteToWideChar函数,搞不懂的是这个函数的CodePage参数一会儿中文(3C8H),
一会儿日文(3C4H),哪位熟悉这方面的知识朋友可以指点一下解决办法?
sizzflair - 2004/12/20 17:17:00
感谢下载中.......
hhb - 2004/12/21 0:10:00
首先我完全不了解DirectX……
不过我觉得能否用类似API Hook的方法直接把文字换掉呢。。。。(幻想中。。。)
12
查看完整版本: Planetarian 汉化测试第一版下载