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

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

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

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

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

【转】DirectX 9 游戏汉化详解

本帖最后由 shane007 于 2011-1-30 14:13 编辑 3 g4 [4 s; C* \! y

" }$ m( i0 j1 q+ a作 者: noword_forever
; \6 i$ r  Y* P/ y/ G时 间: 2010-05-25,14:52:51- }! U% S1 W2 h$ e# u: g6 {
链 接: http://bbs.pediy.com/showthread.php?t=113739
: J7 d$ C. l1 I! |9 Z+ p
2 x# O/ r" R5 E6 w6 T! c【文章标题】: DirectX 9 游戏汉化详解0 q5 t  c  B. P- R% I9 S- ?* z
【文章作者】: noword. W( _4 w% o4 O. b  M0 S
【软件名称】: 无厘头太空战役
) ~7 E& H; w" ^【下载地址】: http://www.verycd.com/topics/2819995/
* {: _, H) i& R: T" ?--------------------------------------------------------------------------------
, A; }5 M1 q' w) y; Q& T2 l  【前言】
1 I1 f, X0 f2 [* R2 w  先copy一段此游戏介绍:' J  o8 p2 Y2 k& b
  $ _  w8 n: o% e8 Y+ ], B
  这是一个独特的战略游戏,具有即时战略与塔防的混合风格,玩家将扮演庞大太空舰队的最高指挥官,你可以自定飞船的构造,摆放飞船的位置,下达命令,然后观看绚丽的射击与爆炸。移动和爆炸时会有动态模糊效果。支持自定义地图。3 D4 v" @" V, ?
  
( O) F1 \4 m5 T0 q% [2 ~8 m, ?9 y  想玩中文版,两个游戏论坛,3DM和YX上,都有人说要汉化,等了几个月,没有下文,说是技术原因。于是决定自己来试试看。" H1 ~' W3 p* b
  8 ?& S! ?3 d% |- H  \
  * k- q% e7 q4 ]# r+ e, A
  【困难何在】# ?! K, H6 ?, K* e
  此游戏的文本都在data目录下,都是明文的文本文件。修改data\strings.ini,将% y4 `  b) u9 N5 R- U
  
4 I1 `- q# y7 c" F. b  b1 s+ B代码:
* e) o3 l- m: U& p) r! \2 t) P  MAINMENU_QUIT        = "Exit"! c$ v0 f& u/ L
  
- L7 l# b6 G6 Y2 w2 S, y5 g  改成
1 X' }) @* a$ d9 i  ^  - i7 c# M( H! ^" `$ N, a
代码:
/ G: g3 o$ P* {# J  p0 Y, ?- d0 Q  MAINMENU_QUIT        = "退出"9 U- u" o( s$ H7 b* E( x
  
6 O+ L5 p8 _7 F0 X  
; U& t8 v6 c1 [  进入游戏后,不出所料,无法显示此中文。
# t0 `  Q$ S) D7 L( ~" [2 [1 w) E  8 D. n+ x3 l: C% x8 h7 a
  茫茫多的游戏爱好者,在尝试汉化某款自己心仪的游戏时,都是死在了这一步——找了半天文本资源,然后翻成中文,满心欢喜和期待的进入游戏,面对的却是一堆乱码或一片空白。满腔热情,化为乌有,无可奈何,黯然神伤。
8 g4 t4 s  q- `% Q  \# l  / d$ D; S3 I: N# Y8 n& f
  本文的目的,就是希望能够帮助这些有志于游戏汉化的同学,主要介绍了如何让一个英文的游戏,能够正确的显示出中文。: ^0 G4 O8 n  b
  $ F9 J* w: Q) D. h' q& j- t# @
  
# ^% U6 X& v. l, [4 J: d  【调试分析】
, d) D& M9 p& ?' z0 e& r- @6 ^  DirectX 9游戏的启动流程是这样的,先执行Direct3DCreate9,返回值是一个IDirect3D9句柄,然后执行IDirect3D9->CreateDevice,得到IDirect3DDevice9句柄。
/ R& v! m1 Q* o0 |  有了IDirect3DDevice9就能使用DirectX 9的一切绘图手段,而我们最关心的就是能够使用D3DXCreateFont来创建ID3DXFont,继而能够非常方便快捷的在游戏中显示文字。
% g, R# ~; l! c! |# o8 G  
: b9 ?3 |: w6 L) K% @( \" d  用ODBG载入游戏的exe文件,“查找所有模块间的调用”,找“d3d9.Direct3DCreate9”:" g9 q5 Y* S' i
  7 S3 E) A) I* h  W
代码:
; E3 u, H4 [- A" w  p0 s+ x  00501974   .  BB 500A5400        mov     ebx, 00540A50                   ;  ASCII "Initialising 3D Engine"" D2 H3 x5 i1 t. r, ~- K2 ], [
  00501979   .  E8 22130000        call    00502CA07 j# A2 z% |5 t, N1 b3 K
  0050197E   .  6A 20              push    20
/ b5 h& v( {  A' {" e; @! S- J' y  00501980   .  8977 18            mov     dword ptr [edi+18], esi+ Y' c0 `" V/ w/ c" r
  00501983   .  E8 2E8B0100        call    <jmp.&d3d9.Direct3DCreate9>' @, \7 S( o0 @/ W5 E0 @
  00501988   .  85C0               test    eax, eax
  k. ]8 N, V7 U$ }" g: n" @) C  0050198A   .  8947 10            mov     dword ptr [edi+10], eax         ;  edi+10 = 58d550
' o& p$ m) G7 A5 H; L8 C  2 ~/ \- a+ B3 z, d: M; ?
  往下找,就能找到IDirect3D9->CreateDevice:# L+ U$ @2 G3 G; J, ]5 m$ r
  1 y6 V) v/ q/ f5 w9 C7 H
代码:
/ T7 n3 |7 S) d  00501B4C   .  8D77 14            lea     esi, dword ptr [edi+14]% l! V' L  S" L% C
  00501B4F   .  56                 push    esi                              ;  58d554  => IDirect3DDevice9
4 \( H+ ~: z- u: V& q2 H  w  00501B50   .  8D4F 40            lea     ecx, dword ptr [edi+40], {1 C' x. R  ^3 F' M/ a
  00501B53   .  51                 push    ecx
& g& ?/ ^* y$ V2 ]/ P. g$ J* P  00501B54   .  6A 40              push    40
( G, Q$ `, _& i; x4 t  00501B56   .  EB 14              jmp     short 00501B6C
6 P7 ?$ _; ~5 x# C6 _5 j6 \  ...2 h. e: [! j' s: J& _
  00501B6C   >  8B4F 18            mov     ecx, dword ptr [edi+18]
3 h, w  F) d0 W1 V# `) i5 C) t  00501B6F   .  8B47 10            mov     eax, dword ptr [edi+10]
0 p# r( v" v1 I. ]8 N0 g  00501B72   .  8B10               mov     edx, dword ptr [eax]
! Y: ?( b" x1 n% r' t3 D  00501B74   .  8B52 40            mov     edx, dword ptr [edx+40]
  Z, _, ?) h" X! ?7 k  00501B77   .  51                 push    ecx+ H; o" V) p" D) a2 ?5 e0 E
  00501B78   .  8B4C24 24          mov     ecx, dword ptr [esp+24]
6 T' L# i  l9 G. @' Q$ [; O5 o  00501B7C   .  51                 push    ecx% W4 Q6 `6 b# k! _
  00501B7D   .  55                 push    ebp
% G0 z1 x( t2 n0 V, v8 w* L  00501B7E   .  50                 push    eax, s1 [7 t& H9 }6 }5 u& z. i/ o
  00501B7F   .  FFD2               call    edx                             ;  IDirect3D9::CreateDevice
+ J; W7 h/ H, I) @( V! ]  o  7 Z) s8 I+ }0 J, m. O6 G
  * Q7 c4 t* s7 e
  由于是所谓的COM接口,没有十分明显的标志,不是很好找。
- ?" p0 g" w/ U, P3 _) D  
% X" S# n% K: p: G6 t/ N  在微软的DirectX SDK d3d9.h文件中,IDirect3D9的接口是这样的:
" I- T! e% c2 s1 c: L  
! S* C/ X! l$ G& J4 E$ i  
+ x/ P9 h  x  o# R! s- X$ U" t代码:
4 h& g/ s$ K2 g+ t  y  DECLARE_INTERFACE_(IDirect3D9, IUnknown), i3 e2 c: g$ r' [4 Q' a( H2 y
  {" t0 j$ y" Q" n4 L+ u1 x
      /*** IUnknown methods ***/
) P2 z- }$ r# O9 {2 z, B7 k9 }      STDMETHOD(QueryInterface)(THIS_ REFIID riid, void** ppvObj) PURE;
& U% }7 L/ _4 E, v' t9 F      STDMETHOD_(ULONG,AddRef)(THIS) PURE;9 K3 S5 k% B- Y0 o; n" H& v
      STDMETHOD_(ULONG,Release)(THIS) PURE;# w6 e; w; X6 o" k/ F& S
  ! h; Z5 e6 X- d, O. Y# D
      /*** IDirect3D9 methods ***/
7 y) S/ X/ A3 r% S% v$ u      STDMETHOD(RegisterSoftwareDevice)(THIS_ void* pInitializeFunction) PURE;
7 j& h% \4 o" J, x2 o      STDMETHOD_(UINT, GetAdapterCount)(THIS) PURE;
% E3 `1 C9 m" o1 @& B: j6 q# D      STDMETHOD(GetAdapterIdentifier)(THIS_ UINT Adapter,DWORD Flags,D3DADAPTER_IDENTIFIER9* pIdentifier) PURE;8 q" e8 T; ~! Z, y
      STDMETHOD_(UINT, GetAdapterModeCount)(THIS_ UINT Adapter,D3DFORMAT Format) PURE;
" Q+ y+ ~" u( t      STDMETHOD(EnumAdapterModes)(THIS_ UINT Adapter,D3DFORMAT Format,UINT Mode,D3DDISPLAYMODE* pMode) PURE;
- N- W  r: u% v7 l) K2 r      STDMETHOD(GetAdapterDisplayMode)(THIS_ UINT Adapter,D3DDISPLAYMODE* pMode) PURE;
' `2 W6 R4 Z. s+ a9 h9 E4 q      STDMETHOD(CheckDeviceType)(THIS_ UINT Adapter,D3DDEVTYPE DevType,D3DFORMAT AdapterFormat,D3DFORMAT BackBufferFormat,BOOL bWindowed) PURE;
9 W  }$ w! F2 p      STDMETHOD(CheckDeviceFormat)(THIS_ UINT Adapter,D3DDEVTYPE DeviceType,D3DFORMAT AdapterFormat,DWORD Usage,D3DRESOURCETYPE RType,D3DFORMAT CheckFormat) PURE;: W9 c5 a% `5 G1 L* D3 p
      STDMETHOD(CheckDeviceMultiSampleType)(THIS_ UINT Adapter,D3DDEVTYPE DeviceType,D3DFORMAT SurfaceFormat,BOOL Windowed,D3DMULTISAMPLE_TYPE MultiSampleType,DWORD* pQualityLevels) PURE;
  O% M4 ^/ m9 }, n/ i1 ]      STDMETHOD(CheckDepthStencilMatch)(THIS_ UINT Adapter,D3DDEVTYPE DeviceType,D3DFORMAT AdapterFormat,D3DFORMAT RenderTargetFormat,D3DFORMAT DepthStencilFormat) PURE;) z$ R. K; I9 T
      STDMETHOD(CheckDeviceFormatConversion)(THIS_ UINT Adapter,D3DDEVTYPE DeviceType,D3DFORMAT SourceFormat,D3DFORMAT TargetFormat) PURE;
5 k3 ^/ s8 ^5 j1 \, t9 n' ~* h      STDMETHOD(GetDeviceCaps)(THIS_ UINT Adapter,D3DDEVTYPE DeviceType,D3DCAPS9* pCaps) PURE;0 a: e* e5 G# {$ E- e7 n
      STDMETHOD_(HMONITOR, GetAdapterMonitor)(THIS_ UINT Adapter) PURE;  g6 @3 H9 I* x5 [8 C
      STDMETHOD(CreateDevice)(THIS_ UINT Adapter,D3DDEVTYPE DeviceType,HWND hFocusWindow,DWORD BehaviorFlags,D3DPRESENT_PARAMETERS* pPresentationParameters,IDirect3DDevice9** ppReturnedDeviceInterface) PURE;( C% |) ]4 r7 G& T  c" c
      
5 s& R5 i& l) ^/ ]2 ^, R. t4 }      #ifdef D3D_DEBUG_INFO+ R5 Z/ A3 e7 @4 W+ z
      LPCWSTR Version;
8 K5 Y; V% M4 l      #endif: p# g# r1 T* e, _
  };) i) s$ A/ z9 ]6 ~: M
  5 O4 M7 B6 _, l( x& Q  d0 T
  $ o" z9 v% E0 a2 z' Y& l% H  m
  CreateDevice是第17个函数,所以它的地址是(17-1)*4 = 0x40,
( [7 o4 B# q/ Y+ N$ l" k& ?  00501B74   .  8B52 40            mov     edx, dword ptr [edx+40]1 k: b; y- n2 R1 P1 E8 |7 V
  这里的edx+40就是这么来的。
6 d+ b  K& s# `9 w  J    K* n0 r; Y# e6 r* }4 E
  如果觉得算起来很麻烦的话,还有一个简单的方法,可以自己编译一个d3d9的程序,然后反汇编看看。
9 y. q( m  z8 |+ w7 y5 f7 l) m  I  4 Z  z/ t2 j( n1 `8 L/ `7 _4 L
  如果还觉得麻烦,还有个更简单的方法,直接往下找,通常会有一些调试文本能够帮助定位,例如:& b( x. O$ r! a4 q( |
  00501B86   .  BB 600B5400        mov     ebx, 00540B60                   ;  ASCII "CreateDevice"2 M: M4 f) z) g2 d2 E
  ...
( m! L# q% w/ }6 a' G  00501BBB   .  BB 700B5400        mov     ebx, 00540B70                   ;  ASCII "CreateDevice failed again"
) J$ h0 I* V; l( L/ Q2 h8 E" N/ \  |$ [  当然,这个办法并不通用,有效与否完全要看游戏作者的脸色。
' S, s# o* M4 e# s. Q! u  
2 A0 f5 @0 a" v/ p9 T5 ]% G  知道了IDirect3DDevice9的地址,就能植入我们自己的初始化ID3DXFont的代码。9 S) h- z) i, b+ d
  
5 p0 s: y1 l# U. k  有了ID3DXFont,下面就是要找到用于显示文字的函数,并用我们自己的代码来替换实现。
) e8 @9 D- d$ l4 l( F  2 T, K( i" H: T: {
  随便找一段游戏中出现的文字,比如开始菜单上出现的“Full 1.37”,ALT-M,进入内存窗口,在所有搜到的该字符串上下“内存访问”断点,最终会找到地址在4FFF50的一个函数。
9 T! D2 ?4 M' r  ' g& M# b7 G. y1 P: R% K
  该函数返回时,用的是“retn 14”,在4FFF50处用“retn 14”改写,切回到游戏后没有任何字符出现,说明这个函数正是用来显示字符的。
0 M2 _9 H5 m4 l8 D  + i4 t0 o+ E4 ?8 V% {: S( {
  原谅我在这里对于怎么找到4FFF50的过程含糊其辞,一笔带过了。确实没有什么取巧的方法,完全取决于破解的功力,良好的耐力,以及一点点好运气。而这也正是游戏汉化的难点所在。7 V; {! B7 t! H0 l1 s1 A' u
  . B# V5 m$ k- `3 L; x) J" w& @
  找到字符串显示的函数后,还要弄清楚该函数的接口。
! x1 x, B( B9 g0 Z) o  
% f5 ?8 v5 ^- S0 p7 U  在屏幕上显示一个字符串,通常需要知道这些要素:字符串、显示的位置(X,Y坐标)、颜色、字符的大小,以及一些flag用于表示左对齐,右对齐,居中,加粗,倾斜等。
+ I% O$ s6 f1 V  l0 L  2 i& m' r3 B$ |5 n" `
  前面说过,返回用的是“retn 14”,说明栈里有20(10进制的14h)/4=5个参数,当进入该函数时,栈上的数据是这样的:
4 w1 s, V) f& S+ |. P. r# o  * M7 [0 Q0 }2 W, B  j" ^3 k  B- C* b
代码:/ P" Y1 y* Q! Z! O8 w- [# c9 D% ^
  0012FE84   00453C48  返回到 GSB_1_37.00453C48 来自 GSB_1_37.004FFF506 d- n+ L' {( d. o. e$ r9 e
  0012FE88   0012FEB8  ASCII "Full 1.37"
% ~) b4 g" d9 A: M  0012FE8C   00000000. B  V! ^  i7 G
  0012FE90   40400000
+ D5 V6 J, |0 p  0012FE94   FFFFFFFF
8 X; C" ^$ o* L  0012FE98   447D80004 D/ z' B$ s6 f! Y) [. ]4 C: e
  
$ H1 C# r3 G+ i# B7 d  第一个,很明显就是要显示的字符串,后面几个是什么玩意儿呢?
; H3 ~) _. F2 F& j# w8 c0 R3 l& ]  
: s1 p8 w9 f* Q4 x  回到调用004FFF50的地方,在00453C1D下断点:
$ P. q: P) N4 S5 s6 P( I4 f& t" X3 N  2 o! D: ]) O- r/ K& T
代码:
) O& N5 F+ n) Q# J4 ^  00453C1D  |> \D94424 14          fld     dword ptr [esp+14]
+ M1 {; j+ D3 u  [) v2 [$ j" o7 Y  00453C21  |.  51                 push    ecx. p; n/ t' d" N( @) Y& u3 k
  00453C22  |.  D91C24             fstp    dword ptr [esp]                  ;  参数5  1024.0
  r7 |( O9 p" H2 b( I8 l  00453C25  |.  6A FF              push    -1                               ;  参数4
8 q% I  q0 G4 N9 K1 X  00453C27  |.  D905 F4125400      fld     dword ptr [5412F4]
( e  r) Z  d) H! }9 c( Q: f  00453C2D  |.  83EC 08            sub     esp, 8
+ D+ ~; b/ I4 E( i8 x  00453C30  |.  D95C24 04          fstp    dword ptr [esp+4]                ;  参数3  3.0
/ X, D! v; l/ e2 h" v  00453C34  |.  8BD0               mov     edx, eax
) }: g8 K  X- F& v  00453C36  |.  D9EE               fldz
" G  J4 U/ c5 q1 f9 N  00453C38  |.  D91C24             fstp    dword ptr [esp]                  ;  参数2  0.0: b) k7 C$ T3 F  U: O
  00453C3B  |.  56                 push    esi                              ;  参数1
3 x# C; h5 C6 H7 \, K: ~  00453C3C  |.  BE 01000000        mov     esi, 14 j) O7 u8 E) U
  00453C41  |.  8BCE               mov     ecx, esi
/ Y$ n9 ^+ k; r! N& t9 A- |  00453C43  |.  E8 08C30A00        call    004FFF50
2 V9 m! R! `& h0 k- o  
" [; Q0 E- S8 b  W" F; b+ z0 t  5 ^- I. T: _1 s+ g% v5 q, C
  可以看到,参数4是一个固定值,第二、三、五参数都是浮点数。
0 r, a: y+ M- w; z! ]% ?3 p  
+ W, a  @: M; O7 G  这里有一个技巧,在函数开始的地方修改参数的值,看看会发生什么变化,很快就能知道参数的作用。
: n- y3 q- Y/ [3 W  
9 U5 A( y- p6 z8 w5 ~4 _$ @1 x  参数4是颜色值,Alpha和RGB值都是FF,就是白色,与在游戏中看到的字符颜色相同。: a! D  c) P: i4 l
  参数2是X坐标,参数3是Y坐标,参数5用于调整。; a# B; ]* @$ r7 [7 D
  需要注意的是,还有两个参数是通过寄存器ECX和EDX传递的,ECX用于表示左对齐(0),右对齐(1)和居中(2),EDX是固定值58D6D0,一个全局的结构或类。# P- L9 c' n& u8 O1 t
  
; d- `/ V! ?- _# I  X+ O- b1 Z5 b2 ?  此游戏有两种字体,因此用于显示字符的几大要素,现在还缺一个,就是不知道如何判断字符的大小。
0 y7 S! }5 {" [: m3 G, w  
' i8 l: Z& L1 j  在用于显示文字的004FFF50的上下断点,多跟几次,就会发现,每次调用以前,都会调用一个call:
0 \& D& }0 _$ _: A  
  f  I, O9 Y5 |  _' I代码:
. V! o6 ^$ U) j) _' m  00453BD5  |.  BE 44035300        mov     esi, 00530344                    ;  ASCII "zekton16.dds"3 W- x1 q3 s5 _2 G- v
  00453BDA  |.  E8 91B50A00        call    004FF170
1 ]/ V& S7 }4 i9 t; \  2 O( n" |+ x1 M7 c+ L2 W
  004479E7  |.  BE 54035300        mov     esi, 00530354                    ;  ASCII "cwfont20.dds"
6 Y: R; p2 b; C. z) o  004479EC  |.  E8 7F770B00        call    004FF170
: J% D+ T- u( A' l0 v  ; V, A% e& n" x2 B' R
  在游戏目录data\font下面有两个文件zekton16.dds.dat和cwfont20.dds.dat,由此判断004FF170应该是用于选择字体的函数。3 u" L6 I9 r6 K5 {! k  t$ }2 K
  
, c3 p$ C; `* y( K' M9 W! S& @8 R  总结一下:
' Z% O9 p2 g+ _% `  第一步,找到IDirect3DDevice9句柄,用于初始化ID3DXFont。# S1 {: @& {& Z. C8 d
  第二步,找到显示文字的函数,用自己的代码实现之。) M  J0 }) o2 O) Y  ]. Q' {: h! |
  第三步,逐步找到其他需要修改的地方,比如用于得到字符串宽度、高度,指定宽度的字符串换行显示等函数。
! J( P2 e0 k4 U  R% f( J  
# F# H3 L$ G: P  
- y9 Z/ B' A! ?. P  【具体实现】% i1 A+ b) \; v! q$ f5 x, V' F
  我用的是注入dll,然后打内存补丁的方式。这样的好处是便于更新,可以任意修改实现过程,以后游戏出了新版本,也只要修改几个地址变量,重新编译一下就可以了。
" }, U) M% j3 m: `8 v  另外一个好处是,不以文件补丁的形式发布,没有版权问题。(有人关心这个吗?)
# J5 ?  F+ A. i4 y6 E  
3 `) Z3 g' ?# p/ S# @# f6 @  源码在这里:
) P* _8 a4 o% H* v1 v0 H, P  http://gsbzhcn.googlecode.com/svn/trunk/src
/ w5 K3 k0 r7 a* ]& I) L  % f9 i0 L/ {, Q/ M& j9 b. {
  简单的介绍一下流程:
  d( A6 N/ c, T0 N& n9 i' S. g2 y  1.CreateProcess启动游戏的exe,并使之处于挂起状态。
% {& e6 ^1 m( D+ h$ L) f  2.VirtualAllocEx在游戏进程上申请一块内存,WriteProcessMemory往里写入要注入的dll名称。& m* Q+ l% q* ^# U2 o/ Z7 l( a* _
  3.GetProcAddress得到LoadLibraryA的地址。
& b2 e: A1 y5 p* `  4.CreateRemoteThread运行LoadLibraryA,注入dll,dll载入时会为游戏进程打上补丁。1 w3 L' e% S6 Q
  6.WaitForSingleObject等候dll载入完成。  ]0 f. D* B* S( U* {
  7.VirtualFreeEx清理掉之前申请的内存。
2 `2 `% ]6 L2 i  8.ResumeThread让打过补丁的游戏进程运行起来。" W  j3 L* l  X4 X
  
1 M5 Z% E7 @% q1 _* h. N: d' a  内存补丁主要是让游戏在关键的地方跳转到我们的dll,执行一段代码后再跳回去,或者直接用dll里的函数代替之。
) e; W/ o2 h/ ~1 J& Q3 j) Z# k' w5 C, U  0 E+ t8 F1 o! L! \$ O: S- A8 R9 Z
  8 W# X$ r0 I$ z( Q+ E# R. |- \0 e
  【结尾】
3 w2 N0 }. Z9 n+ Y  此游戏的汉化正在http://code.google.com/p/gsbzhcn/ 进行,文本不多,奈何翻译人手也不多,希望有兴趣的同学能够参与。
- u6 }/ i0 _. C+ b( o9 L5 W' h% F  2 ^9 l% t" i  t4 _% [
--------------------------------------------------------------------------------
2 J6 H3 p3 n  d【版权声明】: 本文原创于看雪技术论坛, 转载请注明作者并保持文章的完整, 谢谢!0 t* i/ i. m7 H8 v$ C

4 f$ \7 O# }( I                                                       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日,是全球华人共同的冒险解谜类游戏家园。我们致力于提供各类冒险游戏资讯供大家学习交流。本站所有资源均不用于商业用途。

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