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

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

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

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

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

【转】DirectX 9 游戏汉化详解

本帖最后由 shane007 于 2011-1-30 14:13 编辑 7 l: e8 d: u) Q$ n7 d6 F% o4 ?. C

) w. @6 _: U. ]作 者: noword_forever
8 ]1 Q0 b9 Z( x: K9 l  b% u# Y时 间: 2010-05-25,14:52:514 P; w; C: _0 x2 v& X' Y
链 接: http://bbs.pediy.com/showthread.php?t=113739
: l0 d$ K# C) s: c3 [8 q8 {8 [8 d  j% L4 B
【文章标题】: DirectX 9 游戏汉化详解
0 @. D0 ?# F$ F6 r0 k; @5 ~0 ~0 }8 Y【文章作者】: noword
7 U/ m! {( w9 n$ g【软件名称】: 无厘头太空战役& |: S% {  N; n/ V2 l* ?) l
【下载地址】: http://www.verycd.com/topics/2819995/# X* u7 i! o, J
--------------------------------------------------------------------------------
( [8 n# w4 M& z: M, p: a1 H  【前言】2 B0 _& y1 R/ V. f; ^
  先copy一段此游戏介绍:% E4 D, r1 m, w! H3 ?5 l9 y0 R2 w+ r, a
  & d( |0 u9 W/ M
  这是一个独特的战略游戏,具有即时战略与塔防的混合风格,玩家将扮演庞大太空舰队的最高指挥官,你可以自定飞船的构造,摆放飞船的位置,下达命令,然后观看绚丽的射击与爆炸。移动和爆炸时会有动态模糊效果。支持自定义地图。, D" R/ h, c" s  X9 \+ V  m7 q
  
% O$ E: @: {# l  ^# [. j4 D1 _  想玩中文版,两个游戏论坛,3DM和YX上,都有人说要汉化,等了几个月,没有下文,说是技术原因。于是决定自己来试试看。
+ |1 y2 Y' J5 n' N$ `' l8 g  
  _& m' ?9 j( O  % L9 \' Y* [2 V" V
  【困难何在】
8 E) Q* x) Y& |8 w9 q! Y2 e  此游戏的文本都在data目录下,都是明文的文本文件。修改data\strings.ini,将
/ T; B' H( w4 Y7 Y+ S" w$ W  
/ Q+ P9 z2 k- ]0 V( ?代码:
9 [5 o/ k3 m! T8 t4 Q  MAINMENU_QUIT        = "Exit": V# h. V& T' S2 c8 G4 P# r
  6 G9 r0 v( }4 E4 B, t3 D( j) Y
  改成$ X& I) D/ K0 ~
  # }# p# e2 {# O  U. x
代码:
) \: v- L! u% ~! Z+ p  r% ^  MAINMENU_QUIT        = "退出"
5 H# v6 _; {; O  
8 m) y  ]2 }+ n$ H, Y$ S  5 ?2 |: d1 ^7 L" ^3 F- H
  进入游戏后,不出所料,无法显示此中文。
! ?* m) V5 [* [, G4 d# }; V    F: J  l& w$ t) X! x! y
  茫茫多的游戏爱好者,在尝试汉化某款自己心仪的游戏时,都是死在了这一步——找了半天文本资源,然后翻成中文,满心欢喜和期待的进入游戏,面对的却是一堆乱码或一片空白。满腔热情,化为乌有,无可奈何,黯然神伤。
) v! _( b- G$ F  4 B3 B/ [8 i  k' L" n
  本文的目的,就是希望能够帮助这些有志于游戏汉化的同学,主要介绍了如何让一个英文的游戏,能够正确的显示出中文。( `1 q6 y) p# Y: I
  ( x, e* r  s, m7 d
  
$ A! f0 @5 L! o2 z% E) @  【调试分析】* f6 e) z9 @$ ~- L! g9 E9 j
  DirectX 9游戏的启动流程是这样的,先执行Direct3DCreate9,返回值是一个IDirect3D9句柄,然后执行IDirect3D9->CreateDevice,得到IDirect3DDevice9句柄。9 @  t- r; k/ J
  有了IDirect3DDevice9就能使用DirectX 9的一切绘图手段,而我们最关心的就是能够使用D3DXCreateFont来创建ID3DXFont,继而能够非常方便快捷的在游戏中显示文字。0 V8 Q1 W1 W0 @2 ~/ m. T
  
2 Y; J2 ^0 ]8 T2 x  用ODBG载入游戏的exe文件,“查找所有模块间的调用”,找“d3d9.Direct3DCreate9”:
; O4 i. x* d& V* R" n0 ?  % b& b8 Z! Z8 R
代码:
- J# g; @8 Q( N' f1 T  00501974   .  BB 500A5400        mov     ebx, 00540A50                   ;  ASCII "Initialising 3D Engine"
; y% h8 Y0 G) }( ~0 e% U1 C  00501979   .  E8 22130000        call    00502CA0
% t6 I: L/ E% N- r  0050197E   .  6A 20              push    20* M, l% l3 I( m: C8 I4 _
  00501980   .  8977 18            mov     dword ptr [edi+18], esi' M$ D2 X  H! N& V* J, `
  00501983   .  E8 2E8B0100        call    <jmp.&d3d9.Direct3DCreate9>: M3 |- o# M3 i' O" ~" C
  00501988   .  85C0               test    eax, eax
; M+ B& J, \0 h# R6 S+ o4 W& C' \  0050198A   .  8947 10            mov     dword ptr [edi+10], eax         ;  edi+10 = 58d550
+ t( [6 n9 ~- S) \0 }, s  4 r% I! L9 N& j! c. J
  往下找,就能找到IDirect3D9->CreateDevice:
: |& z/ K$ J" @# T) ^/ O& f, D  
- `. d5 L, Q2 y  \7 I) }代码:
& C1 M  q% `% j, v  00501B4C   .  8D77 14            lea     esi, dword ptr [edi+14]
; H1 _* w9 R. p  00501B4F   .  56                 push    esi                              ;  58d554  => IDirect3DDevice9; B0 [8 e% @: M: @# M- e% {" C. M
  00501B50   .  8D4F 40            lea     ecx, dword ptr [edi+40]
9 S. T& |, r4 m7 }" T7 W# U  00501B53   .  51                 push    ecx& _5 r5 |' s7 s" Y; s7 Y7 {" L
  00501B54   .  6A 40              push    40
$ g/ ]1 S7 `& o  00501B56   .  EB 14              jmp     short 00501B6C7 C' T0 S4 |. L" q& W* T1 Z
  .../ a3 V8 W( A) V% z2 s$ t* Q4 J
  00501B6C   >  8B4F 18            mov     ecx, dword ptr [edi+18]; B7 z+ _3 n$ }# i& I6 v- l8 V9 ?
  00501B6F   .  8B47 10            mov     eax, dword ptr [edi+10]1 v9 M* i) O" i! ?* r
  00501B72   .  8B10               mov     edx, dword ptr [eax]
" h/ N, N" Y$ |6 V7 C& a  00501B74   .  8B52 40            mov     edx, dword ptr [edx+40]
3 ^2 u! \+ J3 u  00501B77   .  51                 push    ecx
& J% T7 f8 F% b! W9 ?4 r' U8 J: w' m  00501B78   .  8B4C24 24          mov     ecx, dword ptr [esp+24]; c* h7 \/ d& B$ ?: J( t) M
  00501B7C   .  51                 push    ecx
2 o5 i( t; o& b9 q9 S4 d  00501B7D   .  55                 push    ebp
% I3 S" T5 z7 e5 l& `9 {/ ~  g% ?  00501B7E   .  50                 push    eax9 j9 }; V1 Y; {: P$ P
  00501B7F   .  FFD2               call    edx                             ;  IDirect3D9::CreateDevice2 R1 s4 A( t3 L% t2 I
  
( ?+ P8 K- D* K  / w+ i" U# |2 x4 E6 P/ D( [
  由于是所谓的COM接口,没有十分明显的标志,不是很好找。7 M5 `, m# }+ S5 ~
  
9 Z4 v! A0 l4 ]9 F& S% ?  在微软的DirectX SDK d3d9.h文件中,IDirect3D9的接口是这样的:
5 L2 ~8 B  z& U# S1 m  , H& [# S) o/ q; i, W) m
  . g9 G8 f6 `2 w3 ]
代码:
( p/ [# t1 g. e. M* @* L' C  DECLARE_INTERFACE_(IDirect3D9, IUnknown)
0 ]4 c1 Y8 ]( Z7 S' r) a+ P9 C) T* p  {- K2 u8 k  m9 ~! z
      /*** IUnknown methods ***/0 n. q% W' B+ e( |* {+ P
      STDMETHOD(QueryInterface)(THIS_ REFIID riid, void** ppvObj) PURE;3 E# n2 W* U  m% Q- d$ u. G
      STDMETHOD_(ULONG,AddRef)(THIS) PURE;- V/ N- m# ~4 J
      STDMETHOD_(ULONG,Release)(THIS) PURE;7 U* k( w4 O/ E8 c
  
' w: \0 a' R9 J- I! k      /*** IDirect3D9 methods ***/
% F( M* ?$ r! s# _      STDMETHOD(RegisterSoftwareDevice)(THIS_ void* pInitializeFunction) PURE;& K( M, x1 o7 x% \9 Z" I( e+ j% p
      STDMETHOD_(UINT, GetAdapterCount)(THIS) PURE;
5 t0 g  T' p* ?( Y- Z4 R6 @6 y. x      STDMETHOD(GetAdapterIdentifier)(THIS_ UINT Adapter,DWORD Flags,D3DADAPTER_IDENTIFIER9* pIdentifier) PURE;
) S! L% A( y& S" o/ ?' w! Y2 w+ Y      STDMETHOD_(UINT, GetAdapterModeCount)(THIS_ UINT Adapter,D3DFORMAT Format) PURE;
$ K1 D! D" A+ C      STDMETHOD(EnumAdapterModes)(THIS_ UINT Adapter,D3DFORMAT Format,UINT Mode,D3DDISPLAYMODE* pMode) PURE;' O/ F  ]8 d) b. l% l. `
      STDMETHOD(GetAdapterDisplayMode)(THIS_ UINT Adapter,D3DDISPLAYMODE* pMode) PURE;+ r! n: S* l* l
      STDMETHOD(CheckDeviceType)(THIS_ UINT Adapter,D3DDEVTYPE DevType,D3DFORMAT AdapterFormat,D3DFORMAT BackBufferFormat,BOOL bWindowed) PURE;
, V; D! _, h% u, ~      STDMETHOD(CheckDeviceFormat)(THIS_ UINT Adapter,D3DDEVTYPE DeviceType,D3DFORMAT AdapterFormat,DWORD Usage,D3DRESOURCETYPE RType,D3DFORMAT CheckFormat) PURE;5 j1 t5 m" c+ B. f0 b2 [% ?8 _
      STDMETHOD(CheckDeviceMultiSampleType)(THIS_ UINT Adapter,D3DDEVTYPE DeviceType,D3DFORMAT SurfaceFormat,BOOL Windowed,D3DMULTISAMPLE_TYPE MultiSampleType,DWORD* pQualityLevels) PURE;* U: W$ y, e' P0 P* Z  E  Z' \# W
      STDMETHOD(CheckDepthStencilMatch)(THIS_ UINT Adapter,D3DDEVTYPE DeviceType,D3DFORMAT AdapterFormat,D3DFORMAT RenderTargetFormat,D3DFORMAT DepthStencilFormat) PURE;+ F* M8 S7 D8 J( k& V
      STDMETHOD(CheckDeviceFormatConversion)(THIS_ UINT Adapter,D3DDEVTYPE DeviceType,D3DFORMAT SourceFormat,D3DFORMAT TargetFormat) PURE;
& y: A) y' d) [/ f$ q      STDMETHOD(GetDeviceCaps)(THIS_ UINT Adapter,D3DDEVTYPE DeviceType,D3DCAPS9* pCaps) PURE;5 d% E" ^5 ]4 m1 V' l1 b+ u. p
      STDMETHOD_(HMONITOR, GetAdapterMonitor)(THIS_ UINT Adapter) PURE;
' A) P/ c5 x& d' u3 j) Q2 x      STDMETHOD(CreateDevice)(THIS_ UINT Adapter,D3DDEVTYPE DeviceType,HWND hFocusWindow,DWORD BehaviorFlags,D3DPRESENT_PARAMETERS* pPresentationParameters,IDirect3DDevice9** ppReturnedDeviceInterface) PURE;
/ U9 ?# L& [; o9 U% r" S2 [      ) Q: ^0 h3 q# V
      #ifdef D3D_DEBUG_INFO' p4 S+ v" |& {' p3 m
      LPCWSTR Version;, G, L4 O0 ?4 B6 P
      #endif7 t, q& e: v( c: e/ n, A9 W# J
  };7 l% P4 I  {; ]- h) k
  
& u0 G, Q' N9 X  
  m) n* H" T2 _+ O8 o. C9 R  CreateDevice是第17个函数,所以它的地址是(17-1)*4 = 0x40,
2 ~  {1 J! p$ Y( v  00501B74   .  8B52 40            mov     edx, dword ptr [edx+40]- L  |- B# t+ J8 g' E. U/ j6 I* r3 Q
  这里的edx+40就是这么来的。
( g8 k8 a6 E) n  # ]; }# H# Z' c' |$ G7 W! n
  如果觉得算起来很麻烦的话,还有一个简单的方法,可以自己编译一个d3d9的程序,然后反汇编看看。
2 s# f0 t0 V" A0 o! i  
2 m3 M4 `- y; l( B1 q  如果还觉得麻烦,还有个更简单的方法,直接往下找,通常会有一些调试文本能够帮助定位,例如:
! v8 F* m* r( c. C  00501B86   .  BB 600B5400        mov     ebx, 00540B60                   ;  ASCII "CreateDevice"" b/ f% ^4 c# P) _) S8 p" E! c
  ...
; R' e* i3 `/ q. i! U& ^4 ~+ ^  00501BBB   .  BB 700B5400        mov     ebx, 00540B70                   ;  ASCII "CreateDevice failed again"" `; d( o) ^/ f* f2 w1 x: x' o
  当然,这个办法并不通用,有效与否完全要看游戏作者的脸色。
  @/ V; W0 R# i& D6 e# y" {  
  b7 N' V  X& W# h2 W' v  知道了IDirect3DDevice9的地址,就能植入我们自己的初始化ID3DXFont的代码。3 `0 c  L, A2 ^& y* V: R( w3 c
  
, d3 n. d: @' s3 w) s  有了ID3DXFont,下面就是要找到用于显示文字的函数,并用我们自己的代码来替换实现。% u9 g  t# q! d: d+ V
  
9 w$ Y% j* _& @0 i0 o  随便找一段游戏中出现的文字,比如开始菜单上出现的“Full 1.37”,ALT-M,进入内存窗口,在所有搜到的该字符串上下“内存访问”断点,最终会找到地址在4FFF50的一个函数。
" V3 X3 o- ?- g7 l% U1 }  & M! _' y" ?# h+ |6 c
  该函数返回时,用的是“retn 14”,在4FFF50处用“retn 14”改写,切回到游戏后没有任何字符出现,说明这个函数正是用来显示字符的。
# A' \$ q* N4 g) V  
) f, u" c7 I$ _8 M  原谅我在这里对于怎么找到4FFF50的过程含糊其辞,一笔带过了。确实没有什么取巧的方法,完全取决于破解的功力,良好的耐力,以及一点点好运气。而这也正是游戏汉化的难点所在。
+ ?; W* i9 ?3 U  |+ N; b  
4 v4 C6 I4 M$ n+ |3 M  找到字符串显示的函数后,还要弄清楚该函数的接口。
( A+ M. @# ?) x- z1 Q  
  Q' g/ E2 e- V; G  在屏幕上显示一个字符串,通常需要知道这些要素:字符串、显示的位置(X,Y坐标)、颜色、字符的大小,以及一些flag用于表示左对齐,右对齐,居中,加粗,倾斜等。
2 y9 T" \( @1 `6 X3 K) i' C  
7 S& e' ?: Z7 ~9 l0 t8 `5 k2 g  前面说过,返回用的是“retn 14”,说明栈里有20(10进制的14h)/4=5个参数,当进入该函数时,栈上的数据是这样的:
$ g0 {; A* i2 I+ B& ]  ' S: j1 u( \' E- L- @0 s0 Q
代码:
4 I  ~* l8 G) g8 }& ]* {  0012FE84   00453C48  返回到 GSB_1_37.00453C48 来自 GSB_1_37.004FFF50; K$ o; e2 J1 o2 j! K. @
  0012FE88   0012FEB8  ASCII "Full 1.37"
, ]8 G7 C0 t2 P) D  0012FE8C   00000000( I" B+ w1 f9 m+ p. j- ]  a
  0012FE90   40400000& s+ i5 b; o% }/ q. M) K9 x; h0 s
  0012FE94   FFFFFFFF( a( h; S; _6 A9 v  B
  0012FE98   447D8000
7 S. L7 k# ?/ j5 f9 I0 A4 m8 X, K  2 a3 v1 v2 t) @: P
  第一个,很明显就是要显示的字符串,后面几个是什么玩意儿呢?/ W: y7 b$ f' g$ N2 U5 y  ~
  
! @5 R. N& N9 Y  回到调用004FFF50的地方,在00453C1D下断点:
3 c- L( @: q$ Q( Q% f0 l( R% p  
% G. c, Z7 u* f代码:" _# t! v0 b4 x; D4 J" q6 F0 j
  00453C1D  |> \D94424 14          fld     dword ptr [esp+14]
! u# p9 M) F, o5 }' r9 h  00453C21  |.  51                 push    ecx
# N0 A9 |! D0 m! h( M5 L  00453C22  |.  D91C24             fstp    dword ptr [esp]                  ;  参数5  1024.0
, u& X# _) _$ R  00453C25  |.  6A FF              push    -1                               ;  参数4
9 U" Q7 @! H. a  00453C27  |.  D905 F4125400      fld     dword ptr [5412F4]
) `, G) V$ A! F+ K' ?  B9 ~  00453C2D  |.  83EC 08            sub     esp, 8
# w* _+ t( H% q  `' {  00453C30  |.  D95C24 04          fstp    dword ptr [esp+4]                ;  参数3  3.0
6 S' ^# X+ G! _" q4 G( n  00453C34  |.  8BD0               mov     edx, eax
# E8 i5 m8 `* u  v7 i. R2 v& i  00453C36  |.  D9EE               fldz
% B- Y& N7 I* T% `+ b  00453C38  |.  D91C24             fstp    dword ptr [esp]                  ;  参数2  0.04 A# W+ U# G5 R! T8 Z, j1 W$ m
  00453C3B  |.  56                 push    esi                              ;  参数1
5 N9 x0 M& ?: I8 `; e  00453C3C  |.  BE 01000000        mov     esi, 1
" [+ l) Z7 G( y  00453C41  |.  8BCE               mov     ecx, esi$ }: ?( v  F0 h1 ^; A& J% K
  00453C43  |.  E8 08C30A00        call    004FFF50) c, X. v( U3 Z* d3 k$ W+ @: {
  
1 H1 Y2 t1 T# Z- I3 A7 @# F  ) _- w' e: }/ d! x1 {7 |5 I4 k
  可以看到,参数4是一个固定值,第二、三、五参数都是浮点数。
! k0 D2 s* W1 F  A# m' A  
0 T8 X8 K' p/ l- S3 A" ^. z  这里有一个技巧,在函数开始的地方修改参数的值,看看会发生什么变化,很快就能知道参数的作用。# Y" {" n2 Y: p7 ^4 J. Z
  
. e8 I2 S/ e* s3 `! j  参数4是颜色值,Alpha和RGB值都是FF,就是白色,与在游戏中看到的字符颜色相同。5 R4 K  r% d/ b: E, S6 F7 H
  参数2是X坐标,参数3是Y坐标,参数5用于调整。! i/ @- e( I% P6 {' n! N# \
  需要注意的是,还有两个参数是通过寄存器ECX和EDX传递的,ECX用于表示左对齐(0),右对齐(1)和居中(2),EDX是固定值58D6D0,一个全局的结构或类。; S6 s2 ?' u% W4 O
  
' R  g. T$ N( T" F: h+ [; M  此游戏有两种字体,因此用于显示字符的几大要素,现在还缺一个,就是不知道如何判断字符的大小。% _) I8 O( R7 E' l  \& g
  
4 p& D+ [9 ]+ E1 X2 Z4 |* \& \% N. W  在用于显示文字的004FFF50的上下断点,多跟几次,就会发现,每次调用以前,都会调用一个call:
" c) O2 J5 i4 D8 G$ i  1 a5 i9 C  Z: x  w  r0 U
代码:6 G3 ~: M( y/ m0 Y2 D3 C) X+ y
  00453BD5  |.  BE 44035300        mov     esi, 00530344                    ;  ASCII "zekton16.dds"/ v1 ]; D2 g; t' @6 _- v
  00453BDA  |.  E8 91B50A00        call    004FF170
5 a! u5 J3 T$ D1 w5 S2 P) E  
: h) ]+ h- \" v  004479E7  |.  BE 54035300        mov     esi, 00530354                    ;  ASCII "cwfont20.dds"  P# v4 c$ l+ x4 y4 b- D# }7 O* Y
  004479EC  |.  E8 7F770B00        call    004FF170( t' e& I/ _1 u2 d$ S* Y" c; K
  0 q8 m4 k, j4 G( J. z
  在游戏目录data\font下面有两个文件zekton16.dds.dat和cwfont20.dds.dat,由此判断004FF170应该是用于选择字体的函数。
) u, r5 e+ B; J% k2 f  
- X! Q9 F& B, u/ l3 u  总结一下:1 }  M6 a0 ?9 A. v
  第一步,找到IDirect3DDevice9句柄,用于初始化ID3DXFont。
0 V  N% L& K: B  第二步,找到显示文字的函数,用自己的代码实现之。
2 I- B6 |) h. m6 }' t8 q) q  第三步,逐步找到其他需要修改的地方,比如用于得到字符串宽度、高度,指定宽度的字符串换行显示等函数。
$ P5 v  R. }+ x2 w9 p: \  
) N5 D0 |& `. b6 |; ^7 _( Q  
. g1 X+ z6 ?/ m3 _( s' p  【具体实现】
. ^) k2 E" p  T! G! |& z8 f  我用的是注入dll,然后打内存补丁的方式。这样的好处是便于更新,可以任意修改实现过程,以后游戏出了新版本,也只要修改几个地址变量,重新编译一下就可以了。" J  }4 r$ I/ y
  另外一个好处是,不以文件补丁的形式发布,没有版权问题。(有人关心这个吗?)
# j" R  Q6 X. y  8 ?- w$ h" I$ B7 e0 F* x7 [
  源码在这里:
+ ]3 j8 p2 h  v9 G  http://gsbzhcn.googlecode.com/svn/trunk/src+ B4 c" K8 \7 k. i  n
  
/ G" n. Z6 D5 x  简单的介绍一下流程:
! ]; S  Y( b; ^6 H7 E  1.CreateProcess启动游戏的exe,并使之处于挂起状态。* c# s$ E* A8 a7 v
  2.VirtualAllocEx在游戏进程上申请一块内存,WriteProcessMemory往里写入要注入的dll名称。0 ^7 M$ F; S5 E2 z- K! G
  3.GetProcAddress得到LoadLibraryA的地址。
3 m! R- [4 s6 T) O  4.CreateRemoteThread运行LoadLibraryA,注入dll,dll载入时会为游戏进程打上补丁。1 O: @) K- k# J2 \7 F9 w& }
  6.WaitForSingleObject等候dll载入完成。5 K5 n6 Q, c+ A% S6 ?
  7.VirtualFreeEx清理掉之前申请的内存。
' v5 n; c, v2 F  v1 z  8.ResumeThread让打过补丁的游戏进程运行起来。
% {& E4 Z. y8 n2 L  
2 M; E+ W3 P" t$ Y4 z  B3 H% m& ^: u  内存补丁主要是让游戏在关键的地方跳转到我们的dll,执行一段代码后再跳回去,或者直接用dll里的函数代替之。
6 h$ H' U/ W+ W) u9 e  $ X, B# [; u4 E! i7 e$ [5 p
  9 h% Z( ?2 [9 @- m- t9 l" `
  【结尾】
7 m7 [- o1 C' a  此游戏的汉化正在http://code.google.com/p/gsbzhcn/ 进行,文本不多,奈何翻译人手也不多,希望有兴趣的同学能够参与。& W0 p# z1 N/ a. E3 A& r$ T
  
2 ]" A; j& Q/ a0 i0 M--------------------------------------------------------------------------------% b* Z7 n/ y/ g
【版权声明】: 本文原创于看雪技术论坛, 转载请注明作者并保持文章的完整, 谢谢!
$ j$ C: y* u. v. i0 q; W0 w3 Z2 l1 J2 w) K+ S
                                                       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日,是全球华人共同的冒险解谜类游戏家园。我们致力于提供各类冒险游戏资讯供大家学习交流。本站所有资源均不用于商业用途。

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