设为首页收藏本站官方微博

汉化教程 【转】DirectX 9 游戏汉化详解

[复制链接]
查看: 3003|回复: 3
打印 上一主题 下一主题

[汉化教程] 【转】DirectX 9 游戏汉化详解

跳转到指定楼层
楼主
发表于 2011-1-30 14:12 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

【转】DirectX 9 游戏汉化详解

本帖最后由 shane007 于 2011-1-30 14:13 编辑
- X& R8 s8 O$ V) y6 K" s
2 H; ?* ?' w7 f/ u, J3 W3 d3 ?作 者: noword_forever+ C* x) F$ F3 U
时 间: 2010-05-25,14:52:51
8 T  \- Y8 e2 p, e链 接: http://bbs.pediy.com/showthread.php?t=113739
9 Z# E  c; W% z. J0 [/ E' k9 U& U. m. n/ r; K" G
【文章标题】: DirectX 9 游戏汉化详解
6 U6 n2 M/ f, Y. ~' Q; U+ G" X【文章作者】: noword3 @0 _( T' F) X# H+ t7 [, |
【软件名称】: 无厘头太空战役' Z& E, Z( [% \1 V# m5 g: n
【下载地址】: http://www.verycd.com/topics/2819995/% f' \1 g1 V. Y8 x' t
--------------------------------------------------------------------------------0 w+ J2 s) n7 X7 Y, G
  【前言】- f9 d4 G' [7 t+ n+ `7 }9 c. ^
  先copy一段此游戏介绍:
; \& H4 i/ C2 ]( L6 q4 V+ z8 M  , V# e6 |2 B7 a7 }$ O* Z- a0 t
  这是一个独特的战略游戏,具有即时战略与塔防的混合风格,玩家将扮演庞大太空舰队的最高指挥官,你可以自定飞船的构造,摆放飞船的位置,下达命令,然后观看绚丽的射击与爆炸。移动和爆炸时会有动态模糊效果。支持自定义地图。' D0 `8 B3 l- w0 U# w& ?
  0 a" Z3 [! v. `! M5 B% Z
  想玩中文版,两个游戏论坛,3DM和YX上,都有人说要汉化,等了几个月,没有下文,说是技术原因。于是决定自己来试试看。2 Z! D& @5 T- E+ J3 o, y
  
, y% \( g" W) Y: D2 k) S' c  
- A3 S0 I+ \1 }- n0 V7 K7 e$ N) S  【困难何在】
* ]" k4 J# Q( R3 b  E/ E  此游戏的文本都在data目录下,都是明文的文本文件。修改data\strings.ini,将  [: S0 M" u' a5 x8 @3 o. t% X
  
/ [/ F  z9 |/ K- {. Q' A代码:
; z% e: _, t/ g  MAINMENU_QUIT        = "Exit": U# v! ~9 M6 x( {: `
  
" e7 w  o! T$ L& c0 Q  改成
) G: `: F0 P" L: ^6 x  {    v8 H+ P+ g: |5 J
代码:; Q& q. e6 J$ A, D/ d( u% J
  MAINMENU_QUIT        = "退出"  O# d) G/ r( a" V
  - a4 @& ~9 Y5 {3 s% A
  5 z0 P2 L6 ^6 A' Y
  进入游戏后,不出所料,无法显示此中文。- o9 I+ h1 ?0 ]' k8 F0 ^9 }: ^+ E. z
  
& a- h' L) l, C8 l- r+ @+ P( Y  茫茫多的游戏爱好者,在尝试汉化某款自己心仪的游戏时,都是死在了这一步——找了半天文本资源,然后翻成中文,满心欢喜和期待的进入游戏,面对的却是一堆乱码或一片空白。满腔热情,化为乌有,无可奈何,黯然神伤。
# n7 p* ?4 @6 C, a7 Q4 ~$ M7 q  
' ?  g& \8 {* }, Z! F7 H  本文的目的,就是希望能够帮助这些有志于游戏汉化的同学,主要介绍了如何让一个英文的游戏,能够正确的显示出中文。
* {6 F) {0 `8 x/ u7 v( C  
* l, V" q) i, M9 t8 e( m+ [7 U: a' O  
4 H. y- f7 a7 Y/ K' T' J" M  【调试分析】& P! ], P& {( t; p1 q+ P
  DirectX 9游戏的启动流程是这样的,先执行Direct3DCreate9,返回值是一个IDirect3D9句柄,然后执行IDirect3D9->CreateDevice,得到IDirect3DDevice9句柄。% e$ T) V; Q; y) a, p
  有了IDirect3DDevice9就能使用DirectX 9的一切绘图手段,而我们最关心的就是能够使用D3DXCreateFont来创建ID3DXFont,继而能够非常方便快捷的在游戏中显示文字。
& |0 l9 X, E3 j( |  
$ I7 b5 o4 |, [  |. y, a. x2 I  L  用ODBG载入游戏的exe文件,“查找所有模块间的调用”,找“d3d9.Direct3DCreate9”:
  d; T( x! r! O2 G' N+ [  
3 e) Z0 i* Y5 Z% T8 f代码:0 {% m+ o. N: G
  00501974   .  BB 500A5400        mov     ebx, 00540A50                   ;  ASCII "Initialising 3D Engine"
' [) D+ ?) F! |9 ^! R  [- m  00501979   .  E8 22130000        call    00502CA0
3 m, u+ m. R8 h/ \  0050197E   .  6A 20              push    20
! N3 h- H! Z0 p/ ~0 m  00501980   .  8977 18            mov     dword ptr [edi+18], esi) b  N) ~$ H$ B& y" @) m1 Y
  00501983   .  E8 2E8B0100        call    <jmp.&d3d9.Direct3DCreate9>9 y# v) r- j: D) o; E
  00501988   .  85C0               test    eax, eax
, b5 [) _7 W8 N; h  0050198A   .  8947 10            mov     dword ptr [edi+10], eax         ;  edi+10 = 58d550$ Y/ ^5 Z% r  X6 y
  
; T$ g/ Q/ D9 u$ \  往下找,就能找到IDirect3D9->CreateDevice:
# W- _4 `$ N& {9 p0 j5 ?% j1 C+ L6 k  
4 X& f6 U8 w) o代码:
' p* |9 {6 P/ S# V: g2 L  00501B4C   .  8D77 14            lea     esi, dword ptr [edi+14]
- t; V2 `9 M# E: U- j, H  00501B4F   .  56                 push    esi                              ;  58d554  => IDirect3DDevice9
1 d) |  `; O9 F' ]  @& O5 s  00501B50   .  8D4F 40            lea     ecx, dword ptr [edi+40]
3 M* @: O9 X# y5 L5 q  B7 P  00501B53   .  51                 push    ecx0 v+ v) G0 J/ l
  00501B54   .  6A 40              push    40
/ Q. |- V/ S! J5 T  00501B56   .  EB 14              jmp     short 00501B6C
9 L6 f$ _" N4 y) `# i  ...
1 p  _! r3 @0 x: n  00501B6C   >  8B4F 18            mov     ecx, dword ptr [edi+18]
! P: h( C7 R  k# S& m/ d  00501B6F   .  8B47 10            mov     eax, dword ptr [edi+10]" q. }: i+ ~" I& H0 ^4 z0 D
  00501B72   .  8B10               mov     edx, dword ptr [eax]& b' n7 r: O% u/ ?
  00501B74   .  8B52 40            mov     edx, dword ptr [edx+40]
' \7 P& a$ b9 Y. P5 g  00501B77   .  51                 push    ecx  u- L9 Y, b* Z
  00501B78   .  8B4C24 24          mov     ecx, dword ptr [esp+24]
4 i) ^8 z* y9 s- }' X. I  00501B7C   .  51                 push    ecx3 K) ^0 W. I$ L2 _! J. E0 i
  00501B7D   .  55                 push    ebp
: A" {" i! G% [& D3 ^  00501B7E   .  50                 push    eax+ z+ d6 ^! i! y! n
  00501B7F   .  FFD2               call    edx                             ;  IDirect3D9::CreateDevice
* i) h! h- V" Q  % b- M5 ~0 I2 n$ z( Z6 `' R
  
% b3 m1 t" y$ }  t  h  由于是所谓的COM接口,没有十分明显的标志,不是很好找。
: Q4 P# A0 h2 s5 k0 V  
" E: ~( z5 E; G2 @7 T! l; d  在微软的DirectX SDK d3d9.h文件中,IDirect3D9的接口是这样的:
0 K1 W  ]8 c( x) A  % t) X* x" u6 @6 o, O
  ' n% ^' O6 _' d8 e, X
代码:9 `4 }" F5 W9 V
  DECLARE_INTERFACE_(IDirect3D9, IUnknown)
9 B$ J. N4 E  E% q  {
( X* x2 A. ~9 H$ o4 n      /*** IUnknown methods ***/
0 Y  T9 V  H9 A! p5 i6 N  T      STDMETHOD(QueryInterface)(THIS_ REFIID riid, void** ppvObj) PURE;
- }4 U- K% m! x! T* C4 {6 h      STDMETHOD_(ULONG,AddRef)(THIS) PURE;4 c5 h2 |) j+ l/ U% n0 w
      STDMETHOD_(ULONG,Release)(THIS) PURE;/ f% D; K! Q: A; C( e% C
  
5 r* J( g6 B8 Q& c$ |      /*** IDirect3D9 methods ***/  t" T  Y. ~8 q, z
      STDMETHOD(RegisterSoftwareDevice)(THIS_ void* pInitializeFunction) PURE;
2 _5 d2 D  c  I0 w7 A, p- L% X0 }; j      STDMETHOD_(UINT, GetAdapterCount)(THIS) PURE;& `; h% K7 W# D
      STDMETHOD(GetAdapterIdentifier)(THIS_ UINT Adapter,DWORD Flags,D3DADAPTER_IDENTIFIER9* pIdentifier) PURE;
. m; c! `5 L% l4 v) ^% L5 P      STDMETHOD_(UINT, GetAdapterModeCount)(THIS_ UINT Adapter,D3DFORMAT Format) PURE;
9 X7 Y) x0 c9 F0 D( f) n      STDMETHOD(EnumAdapterModes)(THIS_ UINT Adapter,D3DFORMAT Format,UINT Mode,D3DDISPLAYMODE* pMode) PURE;
9 A. |3 R4 `9 P& Y( Y4 Y! Y! d" P3 S. j% r  V      STDMETHOD(GetAdapterDisplayMode)(THIS_ UINT Adapter,D3DDISPLAYMODE* pMode) PURE;
8 r6 G. s0 o" M$ Q" o! _. p; Q* ?      STDMETHOD(CheckDeviceType)(THIS_ UINT Adapter,D3DDEVTYPE DevType,D3DFORMAT AdapterFormat,D3DFORMAT BackBufferFormat,BOOL bWindowed) PURE;  [8 I  H3 f; A2 K' l, m& g
      STDMETHOD(CheckDeviceFormat)(THIS_ UINT Adapter,D3DDEVTYPE DeviceType,D3DFORMAT AdapterFormat,DWORD Usage,D3DRESOURCETYPE RType,D3DFORMAT CheckFormat) PURE;- d( G8 ?' O7 s2 Y- F7 p
      STDMETHOD(CheckDeviceMultiSampleType)(THIS_ UINT Adapter,D3DDEVTYPE DeviceType,D3DFORMAT SurfaceFormat,BOOL Windowed,D3DMULTISAMPLE_TYPE MultiSampleType,DWORD* pQualityLevels) PURE;& }. e; r9 J: Z) [" e( `7 q
      STDMETHOD(CheckDepthStencilMatch)(THIS_ UINT Adapter,D3DDEVTYPE DeviceType,D3DFORMAT AdapterFormat,D3DFORMAT RenderTargetFormat,D3DFORMAT DepthStencilFormat) PURE;
; K' C) h# h" {+ T      STDMETHOD(CheckDeviceFormatConversion)(THIS_ UINT Adapter,D3DDEVTYPE DeviceType,D3DFORMAT SourceFormat,D3DFORMAT TargetFormat) PURE;2 f8 _1 Z6 ]$ ~
      STDMETHOD(GetDeviceCaps)(THIS_ UINT Adapter,D3DDEVTYPE DeviceType,D3DCAPS9* pCaps) PURE;
4 ?# z1 h  A4 L4 q; _      STDMETHOD_(HMONITOR, GetAdapterMonitor)(THIS_ UINT Adapter) PURE;% U) q# E" h2 x+ U0 g' p; O' y
      STDMETHOD(CreateDevice)(THIS_ UINT Adapter,D3DDEVTYPE DeviceType,HWND hFocusWindow,DWORD BehaviorFlags,D3DPRESENT_PARAMETERS* pPresentationParameters,IDirect3DDevice9** ppReturnedDeviceInterface) PURE;) w" G; ~0 Q% ]. y
      + `. u/ N& ~' _5 j1 y3 w  f) O# |
      #ifdef D3D_DEBUG_INFO
$ ~+ B% o' w6 L# ]$ s2 A6 x      LPCWSTR Version;
+ g+ N2 I& i# {. h* m5 H5 {* O/ x      #endif! X8 K6 s' s/ S4 B5 H' [4 Z7 r* a
  };1 G5 r1 e7 }& o" I& c+ T" z
  
2 z" ~5 Z9 `" q- s& Z# R  
5 J. U6 a* S+ h! ^  CreateDevice是第17个函数,所以它的地址是(17-1)*4 = 0x40,
' P2 |( _! w  R; ~/ T  00501B74   .  8B52 40            mov     edx, dword ptr [edx+40]( W. I9 W: [) v$ o6 ]+ X6 K- c
  这里的edx+40就是这么来的。
# C8 N$ z% @& n7 u/ E4 X  
" h3 N# J2 W9 V# w1 C4 G4 p  如果觉得算起来很麻烦的话,还有一个简单的方法,可以自己编译一个d3d9的程序,然后反汇编看看。
' j3 O5 |4 S* F  ( y! l* `& c. k) r* H
  如果还觉得麻烦,还有个更简单的方法,直接往下找,通常会有一些调试文本能够帮助定位,例如:; L' |! }! `3 U6 W! O3 f! u
  00501B86   .  BB 600B5400        mov     ebx, 00540B60                   ;  ASCII "CreateDevice"
1 F0 ]+ U1 p6 D( u: O0 }  ...* I/ |& y& c, S+ P  |( R" H
  00501BBB   .  BB 700B5400        mov     ebx, 00540B70                   ;  ASCII "CreateDevice failed again"
9 A0 b6 z( y" k  当然,这个办法并不通用,有效与否完全要看游戏作者的脸色。7 v, ~3 [9 F- Y9 k5 C( S
  
6 i# C. S% ?! u9 E. B- u  知道了IDirect3DDevice9的地址,就能植入我们自己的初始化ID3DXFont的代码。
- d) f4 `: K3 P& h5 g! Q  0 }, Y- j9 Q/ n+ w9 ~
  有了ID3DXFont,下面就是要找到用于显示文字的函数,并用我们自己的代码来替换实现。
3 }8 L$ ]$ Y9 O) H/ U: q5 R  4 r" D/ |! a. u
  随便找一段游戏中出现的文字,比如开始菜单上出现的“Full 1.37”,ALT-M,进入内存窗口,在所有搜到的该字符串上下“内存访问”断点,最终会找到地址在4FFF50的一个函数。
9 ?8 R- W! u) T' `6 j  
( C. m3 P) q2 f6 ]% H  该函数返回时,用的是“retn 14”,在4FFF50处用“retn 14”改写,切回到游戏后没有任何字符出现,说明这个函数正是用来显示字符的。+ T5 R' h( g9 d; w0 c) ?; ?. q8 i" J
  
. O/ c* F7 F8 B7 Z& p; D  原谅我在这里对于怎么找到4FFF50的过程含糊其辞,一笔带过了。确实没有什么取巧的方法,完全取决于破解的功力,良好的耐力,以及一点点好运气。而这也正是游戏汉化的难点所在。+ L, p; i7 E+ f, ?
  
1 `  p4 \& P& D  找到字符串显示的函数后,还要弄清楚该函数的接口。
, B9 p7 H" E) q  ( r7 r  b/ b- G3 s0 m
  在屏幕上显示一个字符串,通常需要知道这些要素:字符串、显示的位置(X,Y坐标)、颜色、字符的大小,以及一些flag用于表示左对齐,右对齐,居中,加粗,倾斜等。
0 f, e9 O4 N1 x2 _% v# n9 S- ]8 \  7 Y' c/ A! J# o& C. g5 s
  前面说过,返回用的是“retn 14”,说明栈里有20(10进制的14h)/4=5个参数,当进入该函数时,栈上的数据是这样的:
5 L4 i  k- r$ l/ ~, G& m: c& ^) f  
! l' g' N6 g  q2 e/ [代码:; [3 |- Q3 {3 _" _7 A: ?- ~& g
  0012FE84   00453C48  返回到 GSB_1_37.00453C48 来自 GSB_1_37.004FFF50
1 K+ \& j. w3 z% E+ g" d  0012FE88   0012FEB8  ASCII "Full 1.37"
6 Z: k3 r% y, Z2 J( P, A9 @( t  0012FE8C   00000000* d. R5 ]* E' G+ R: C. A! j7 ^, q; s" B
  0012FE90   404000002 `  I0 H  ~/ A/ M% u
  0012FE94   FFFFFFFF& }) E: P5 h, m% H  {/ m7 U
  0012FE98   447D8000
% r# S! ?" [+ F9 O( L1 E( i0 e2 H. D  
3 p- U1 U6 W+ D5 }  v  第一个,很明显就是要显示的字符串,后面几个是什么玩意儿呢?, Z( t* Z$ k9 Y; k) G0 z
  , g1 ~+ c9 w% C) D9 c: I; M
  回到调用004FFF50的地方,在00453C1D下断点:& y) @4 D0 s7 [. L; D- N
  # b( W) f# j1 B% N9 x
代码:8 F" W/ m' D+ Z: T) b  U
  00453C1D  |> \D94424 14          fld     dword ptr [esp+14]; `" O& w* x; |) X, R
  00453C21  |.  51                 push    ecx
8 ]6 h* w% X( f: {  00453C22  |.  D91C24             fstp    dword ptr [esp]                  ;  参数5  1024.07 M2 P' U6 ^  k( p$ e7 a- ?7 E
  00453C25  |.  6A FF              push    -1                               ;  参数41 w" ^/ ^: ]4 H' A
  00453C27  |.  D905 F4125400      fld     dword ptr [5412F4]2 S: C# B% M, }* n8 x+ n
  00453C2D  |.  83EC 08            sub     esp, 8
  D" f8 Y# ?" Y  00453C30  |.  D95C24 04          fstp    dword ptr [esp+4]                ;  参数3  3.0. A# h& E. O- Z- \
  00453C34  |.  8BD0               mov     edx, eax: J1 s. i5 `9 g3 W
  00453C36  |.  D9EE               fldz' a# E  T9 Y# L
  00453C38  |.  D91C24             fstp    dword ptr [esp]                  ;  参数2  0.0
5 S- m! h, ]3 H& S/ b  00453C3B  |.  56                 push    esi                              ;  参数1. U# r; W& o: `
  00453C3C  |.  BE 01000000        mov     esi, 1
, J) f7 v+ e* z8 i! o6 h" F3 L  00453C41  |.  8BCE               mov     ecx, esi
$ n$ ~1 t3 B7 P# r- u; e8 v  00453C43  |.  E8 08C30A00        call    004FFF505 \+ `# S# @: B$ {
  6 K* w6 D7 [4 l. ]
  * R, ?9 N, }* t; s7 E
  可以看到,参数4是一个固定值,第二、三、五参数都是浮点数。
5 G, ^& m9 l0 s6 B  
' u0 L: c& i5 f% J: G1 i- X/ Q! Q  这里有一个技巧,在函数开始的地方修改参数的值,看看会发生什么变化,很快就能知道参数的作用。
' k* N& o2 R! @) c  " f# F* H$ {/ a
  参数4是颜色值,Alpha和RGB值都是FF,就是白色,与在游戏中看到的字符颜色相同。
( i3 V; b  X4 i+ ?5 j+ `  参数2是X坐标,参数3是Y坐标,参数5用于调整。) V0 H4 p& N+ t/ [- C& Q
  需要注意的是,还有两个参数是通过寄存器ECX和EDX传递的,ECX用于表示左对齐(0),右对齐(1)和居中(2),EDX是固定值58D6D0,一个全局的结构或类。
/ }. z6 l- t% i; y: Q- b  
: N: C) F8 L% `9 K! m  此游戏有两种字体,因此用于显示字符的几大要素,现在还缺一个,就是不知道如何判断字符的大小。# k7 v1 C  p" h
  8 E  m" c% Q1 E# z, D7 Y% r
  在用于显示文字的004FFF50的上下断点,多跟几次,就会发现,每次调用以前,都会调用一个call:
. u3 }6 I9 {- _' c9 I  8 Q  H# {! V6 j& f: Z7 n
代码:/ x: L1 p% [: [: n4 ?0 ]4 W
  00453BD5  |.  BE 44035300        mov     esi, 00530344                    ;  ASCII "zekton16.dds"% E, \1 }& z5 C+ V; |0 _, {
  00453BDA  |.  E8 91B50A00        call    004FF170
6 _, d# q$ H% j( J; \) K  
! F* `; ?7 j9 G5 G  004479E7  |.  BE 54035300        mov     esi, 00530354                    ;  ASCII "cwfont20.dds"
" w6 F  F) {7 j7 p6 d  004479EC  |.  E8 7F770B00        call    004FF170* ^9 x/ c6 p: w( o2 z, E
  
2 {: n  ^2 P( p4 b6 C  在游戏目录data\font下面有两个文件zekton16.dds.dat和cwfont20.dds.dat,由此判断004FF170应该是用于选择字体的函数。* T; _5 Y9 L* L  v: f$ m' g
  " J! Z* d9 m: a3 W, c
  总结一下:! J, G; l& O& @( P
  第一步,找到IDirect3DDevice9句柄,用于初始化ID3DXFont。! T, v* b6 ^" m$ L
  第二步,找到显示文字的函数,用自己的代码实现之。% Z5 o7 y$ x; B2 [7 a* ]
  第三步,逐步找到其他需要修改的地方,比如用于得到字符串宽度、高度,指定宽度的字符串换行显示等函数。
: m1 [# P" L! {* F  
5 A: K( O2 k- c& O1 J( h  ( n: {; k  f" q4 |+ [; r
  【具体实现】
2 Y4 _. `" [- }  我用的是注入dll,然后打内存补丁的方式。这样的好处是便于更新,可以任意修改实现过程,以后游戏出了新版本,也只要修改几个地址变量,重新编译一下就可以了。0 }$ z7 j& L% @" ?
  另外一个好处是,不以文件补丁的形式发布,没有版权问题。(有人关心这个吗?)
4 S4 j+ W% n* r/ E  $ W; i4 t& u, }3 {; @
  源码在这里:
! Y5 ~1 {2 W$ }' _+ F* V, ^2 M  http://gsbzhcn.googlecode.com/svn/trunk/src
3 j* h0 L' [+ B; y. Y  ; w' L% r4 K& I1 V# L. Y
  简单的介绍一下流程:
( g. ~4 b7 t5 v/ N2 x% _  1.CreateProcess启动游戏的exe,并使之处于挂起状态。
& C- s# w; d) D; M% O4 f0 X  2.VirtualAllocEx在游戏进程上申请一块内存,WriteProcessMemory往里写入要注入的dll名称。6 h& ?6 y/ a5 L7 H, K9 ?  M
  3.GetProcAddress得到LoadLibraryA的地址。
! j/ P7 \% Q! o$ ^7 S  4.CreateRemoteThread运行LoadLibraryA,注入dll,dll载入时会为游戏进程打上补丁。
5 A: M7 `# c+ Z! ^, Z  6.WaitForSingleObject等候dll载入完成。
" V1 v9 [9 [2 P  7.VirtualFreeEx清理掉之前申请的内存。
; V: ?  Q& m  l" H/ o  8.ResumeThread让打过补丁的游戏进程运行起来。$ L$ a) h7 E! S" `9 b2 \* ?
  
  a8 S! G2 i& j  内存补丁主要是让游戏在关键的地方跳转到我们的dll,执行一段代码后再跳回去,或者直接用dll里的函数代替之。; T1 O7 }  B8 v3 x1 L$ N
  
2 S/ y4 J+ I6 |. E4 _) T  
! \  p4 V% F- Q! x* ?" ]& E: s6 P  【结尾】" k. s5 q# |" B$ y4 `
  此游戏的汉化正在http://code.google.com/p/gsbzhcn/ 进行,文本不多,奈何翻译人手也不多,希望有兴趣的同学能够参与。
0 p+ ~- p1 C$ ^. o) E  
6 y2 o1 Q- U, _2 T+ W4 n* l--------------------------------------------------------------------------------0 [* c* _7 S) I, b3 r) l, T
【版权声明】: 本文原创于看雪技术论坛, 转载请注明作者并保持文章的完整, 谢谢!
6 @, ]$ C# W  `1 Y0 k+ j  ^  v9 u- H  W* ~/ O& r! k
                                                       2010年05月25日 14:52:11
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏1 分享分享 很美好很美好 很差劲很差劲
回复

使用道具 举报

沙发
发表于 2011-2-6 20:47 | 只看该作者
楼主忒牛了
回复 支持 反对

使用道具 举报

板凳
发表于 2011-3-10 15:19 | 只看该作者
高手啊,仰望。
回复 支持 反对

使用道具 举报

笨蛋狐狸 该用户已被删除
地板
发表于 2011-3-11 10:19 | 只看该作者
仰慕,学习了,也感谢007的转载。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

冒险解谜游戏中文网 ChinaAVG

官方微博官方微信号小黑屋 微信玩家群  

(C) ChinaAVG 2004 - 2019 All Right Reserved. Powered by Discuz! X3.2
辽ICP备11008827号 | 桂公网安备 45010702000051号

冒险,与你同在。 冒险解谜游戏中文网ChinaAVG诞生于2004年9月9日,是全球华人共同的冒险解谜类游戏家园。我们致力于提供各类冒险游戏资讯供大家学习交流。本站所有资源均不用于商业用途。

快速回复 返回顶部 返回列表