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

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

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

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

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

【转】DirectX 9 游戏汉化详解

本帖最后由 shane007 于 2011-1-30 14:13 编辑
0 \+ V, j$ @% ]* ^" d5 i
) \% k$ q  Z# `作 者: noword_forever0 [4 c" l8 Z, N+ y6 y. G/ l0 |- K
时 间: 2010-05-25,14:52:513 f6 O: q( L. F  M, L
链 接: http://bbs.pediy.com/showthread.php?t=113739
" \; }( y8 D/ g2 [7 l$ c4 v# G2 y( E+ ]" X9 n0 w9 Q
【文章标题】: DirectX 9 游戏汉化详解
3 ]% t/ o* v& P# L. g【文章作者】: noword
' Z' e& ~8 n  W- |! `# B【软件名称】: 无厘头太空战役
. U3 q6 p; L& k9 ?3 F0 n& Z【下载地址】: http://www.verycd.com/topics/2819995/2 l5 s% C4 m6 |# b2 v, v: R" k
--------------------------------------------------------------------------------
; L! [  {3 s1 t: o/ F4 e  【前言】
" e+ k# l' t; ^1 F; o4 d  先copy一段此游戏介绍:) y- j2 I, Z4 e% P: D- ^
  $ ]& O: S. |& K/ p: J. m8 Y
  这是一个独特的战略游戏,具有即时战略与塔防的混合风格,玩家将扮演庞大太空舰队的最高指挥官,你可以自定飞船的构造,摆放飞船的位置,下达命令,然后观看绚丽的射击与爆炸。移动和爆炸时会有动态模糊效果。支持自定义地图。6 x8 Y, i8 J- r
  
9 I( z3 q7 H; k. u+ w  想玩中文版,两个游戏论坛,3DM和YX上,都有人说要汉化,等了几个月,没有下文,说是技术原因。于是决定自己来试试看。0 B" V8 f- O) O* l
  ( Y& T# ]8 E  T( `- `
  
" e, a  I; x" l+ i6 a" O  【困难何在】
* t* [0 Q0 n9 r. }& m$ i7 S. w9 H  此游戏的文本都在data目录下,都是明文的文本文件。修改data\strings.ini,将
$ Q$ E, o4 @5 U2 K. e3 W  
; H! a/ Z2 N- ?6 T. ~! g7 B代码:# i# k1 G7 {9 j) C
  MAINMENU_QUIT        = "Exit"4 F+ c! X6 P% P1 F, r
  6 T8 S- e; M. g6 e- W
  改成
7 Z6 @5 N4 O4 t3 J' c  
* w  |: Q% Q  g0 \7 H; Y1 [代码:  J( g* a' o$ ~7 x
  MAINMENU_QUIT        = "退出"  s, d; n) Y( U3 _
  5 D% _: q2 t, X' K
  8 x( j: ~* V  P4 {
  进入游戏后,不出所料,无法显示此中文。; }) Z5 T, A& Q3 \% E$ H# K
  2 Y3 K( Z' z/ H# Q: \1 E/ l
  茫茫多的游戏爱好者,在尝试汉化某款自己心仪的游戏时,都是死在了这一步——找了半天文本资源,然后翻成中文,满心欢喜和期待的进入游戏,面对的却是一堆乱码或一片空白。满腔热情,化为乌有,无可奈何,黯然神伤。
& J: Y. _) _: r5 c7 j* C" L  
6 M( {2 h& }1 g$ g$ _  本文的目的,就是希望能够帮助这些有志于游戏汉化的同学,主要介绍了如何让一个英文的游戏,能够正确的显示出中文。
  }# o3 ]- {' c) |: N4 z  , w& E8 C! h0 v  g9 d7 J, S; l2 _
  
6 H8 a. X% p6 h7 q  【调试分析】
% u7 {& H6 Z. J3 {% W5 B% ?, o  DirectX 9游戏的启动流程是这样的,先执行Direct3DCreate9,返回值是一个IDirect3D9句柄,然后执行IDirect3D9->CreateDevice,得到IDirect3DDevice9句柄。
; F/ ~2 l/ a/ @+ E' ]  有了IDirect3DDevice9就能使用DirectX 9的一切绘图手段,而我们最关心的就是能够使用D3DXCreateFont来创建ID3DXFont,继而能够非常方便快捷的在游戏中显示文字。) P& n! a2 s9 }9 V; T, j" g6 z
  . W* J" W& ]+ k2 P
  用ODBG载入游戏的exe文件,“查找所有模块间的调用”,找“d3d9.Direct3DCreate9”:
- T% [9 J5 ^) l. u' `( `  ; }2 `; S' W, ?# B9 p: b
代码:& Z/ u& ~- `& n+ y% l6 G
  00501974   .  BB 500A5400        mov     ebx, 00540A50                   ;  ASCII "Initialising 3D Engine"9 i( m; p' Z8 j$ \6 g: m
  00501979   .  E8 22130000        call    00502CA0
1 U1 f* {9 m+ _9 e. X9 n  0050197E   .  6A 20              push    20& y) R' U! d0 p) r3 m  V! {1 w* O, y
  00501980   .  8977 18            mov     dword ptr [edi+18], esi) \, c/ H0 B' ]
  00501983   .  E8 2E8B0100        call    <jmp.&d3d9.Direct3DCreate9>; R3 f* H# {1 C( Q- n9 S+ C4 A
  00501988   .  85C0               test    eax, eax- v0 s( q3 @0 J& `' s
  0050198A   .  8947 10            mov     dword ptr [edi+10], eax         ;  edi+10 = 58d550
, N* V8 K. n" W6 I2 x9 j  
& ]8 L% I4 p0 h. b  往下找,就能找到IDirect3D9->CreateDevice:
6 n9 T8 `: W2 Y( g# D  w- o  & B: ?* G3 V5 Y" V+ ?; T# Q; Q! W
代码:
$ c6 e/ r/ u# I7 t  00501B4C   .  8D77 14            lea     esi, dword ptr [edi+14]
, x% e3 B# N) ~  @  00501B4F   .  56                 push    esi                              ;  58d554  => IDirect3DDevice9
& m: ?7 E) b8 {  00501B50   .  8D4F 40            lea     ecx, dword ptr [edi+40]
3 ?' b/ y& [6 ~9 S) G2 F  00501B53   .  51                 push    ecx
' U$ m7 ~7 I3 F+ v0 r7 I3 M: B7 R; H  00501B54   .  6A 40              push    408 g0 m2 N; t" g
  00501B56   .  EB 14              jmp     short 00501B6C1 y* I( @6 w  j9 ^1 Z; l
  ...
( P. ~) j* R8 @, E5 O  00501B6C   >  8B4F 18            mov     ecx, dword ptr [edi+18]7 d" b0 I! n* s8 C
  00501B6F   .  8B47 10            mov     eax, dword ptr [edi+10]
# ~: {& P- R/ {  O  00501B72   .  8B10               mov     edx, dword ptr [eax]5 R. i3 I: C" c5 L2 q. L
  00501B74   .  8B52 40            mov     edx, dword ptr [edx+40]
. f/ {% z3 n" g# z  T, W$ f  00501B77   .  51                 push    ecx
" n* p" T' b6 P  00501B78   .  8B4C24 24          mov     ecx, dword ptr [esp+24]
  z, _8 }7 X. Z% g- A. u$ L: V  00501B7C   .  51                 push    ecx
# H2 A' [6 n3 U5 |  00501B7D   .  55                 push    ebp
5 F; P( l' U6 m; T  00501B7E   .  50                 push    eax
- A( o0 {# U1 B* `- p0 u  00501B7F   .  FFD2               call    edx                             ;  IDirect3D9::CreateDevice; A! @& S) @0 i8 N' Z; `
  3 T1 @; d  S) _" B+ P
  ) n) T  e/ x" P, H
  由于是所谓的COM接口,没有十分明显的标志,不是很好找。7 [# }( g( d3 x$ f. k+ l2 |% [+ O
  
. s& K9 y7 A8 W1 b1 \' |  在微软的DirectX SDK d3d9.h文件中,IDirect3D9的接口是这样的:7 c8 D) h# F. F# p# k
  
" j/ R$ c: \1 F, k* l/ u  
+ F: ]6 [+ ?. u. x代码:
  {& i. }* `  p7 w0 u9 _  DECLARE_INTERFACE_(IDirect3D9, IUnknown)
. t3 G% F1 U3 h  {& s0 i) u3 |8 |6 s! L$ J( g0 J1 D
      /*** IUnknown methods ***/
  m/ w; X/ Q5 e+ |( K) n( p+ N      STDMETHOD(QueryInterface)(THIS_ REFIID riid, void** ppvObj) PURE;8 U" O$ ?: `6 w. V+ u
      STDMETHOD_(ULONG,AddRef)(THIS) PURE;
/ m, J: _2 a; T0 v  o      STDMETHOD_(ULONG,Release)(THIS) PURE;
# O* Y) \. s% I/ |: ?+ p  : X" v2 F( W& n3 {6 Y6 L5 z  Q
      /*** IDirect3D9 methods ***/& K6 q; D2 W( B# p5 ]5 I: V
      STDMETHOD(RegisterSoftwareDevice)(THIS_ void* pInitializeFunction) PURE;
. Y4 i  L2 m' `# ^' F+ V& r' X5 c, i      STDMETHOD_(UINT, GetAdapterCount)(THIS) PURE;
& Y7 y  r$ w8 ]% F  g      STDMETHOD(GetAdapterIdentifier)(THIS_ UINT Adapter,DWORD Flags,D3DADAPTER_IDENTIFIER9* pIdentifier) PURE;
) D, v2 i, D+ ?  ?# d- Q* _0 [6 ?0 c      STDMETHOD_(UINT, GetAdapterModeCount)(THIS_ UINT Adapter,D3DFORMAT Format) PURE;& Y8 @' C: j& @8 j( D
      STDMETHOD(EnumAdapterModes)(THIS_ UINT Adapter,D3DFORMAT Format,UINT Mode,D3DDISPLAYMODE* pMode) PURE;
( I1 J, }. @/ a9 R2 j      STDMETHOD(GetAdapterDisplayMode)(THIS_ UINT Adapter,D3DDISPLAYMODE* pMode) PURE;) e$ |+ K, u4 Z. Y4 W0 ~
      STDMETHOD(CheckDeviceType)(THIS_ UINT Adapter,D3DDEVTYPE DevType,D3DFORMAT AdapterFormat,D3DFORMAT BackBufferFormat,BOOL bWindowed) PURE;+ e9 @% i# A: t2 }; j: s2 b# A; c
      STDMETHOD(CheckDeviceFormat)(THIS_ UINT Adapter,D3DDEVTYPE DeviceType,D3DFORMAT AdapterFormat,DWORD Usage,D3DRESOURCETYPE RType,D3DFORMAT CheckFormat) PURE;7 _  @* J  A4 B& N: L* E1 i
      STDMETHOD(CheckDeviceMultiSampleType)(THIS_ UINT Adapter,D3DDEVTYPE DeviceType,D3DFORMAT SurfaceFormat,BOOL Windowed,D3DMULTISAMPLE_TYPE MultiSampleType,DWORD* pQualityLevels) PURE;# }0 }, g% x8 X! }. w4 {
      STDMETHOD(CheckDepthStencilMatch)(THIS_ UINT Adapter,D3DDEVTYPE DeviceType,D3DFORMAT AdapterFormat,D3DFORMAT RenderTargetFormat,D3DFORMAT DepthStencilFormat) PURE;
+ @0 W. E: I' V) G1 N, u      STDMETHOD(CheckDeviceFormatConversion)(THIS_ UINT Adapter,D3DDEVTYPE DeviceType,D3DFORMAT SourceFormat,D3DFORMAT TargetFormat) PURE;
  K8 k5 x& B; P' r      STDMETHOD(GetDeviceCaps)(THIS_ UINT Adapter,D3DDEVTYPE DeviceType,D3DCAPS9* pCaps) PURE;
8 ~6 i1 m* E3 q6 ^3 D9 k- i      STDMETHOD_(HMONITOR, GetAdapterMonitor)(THIS_ UINT Adapter) PURE;8 L0 h% p6 r& `  q2 u; L. E- h* k
      STDMETHOD(CreateDevice)(THIS_ UINT Adapter,D3DDEVTYPE DeviceType,HWND hFocusWindow,DWORD BehaviorFlags,D3DPRESENT_PARAMETERS* pPresentationParameters,IDirect3DDevice9** ppReturnedDeviceInterface) PURE;
6 g$ `6 J/ o+ k0 R! D      
5 d2 v" n( N' y# R( y, R- R* ?- |* q      #ifdef D3D_DEBUG_INFO
, Z' q$ \# l/ ~" A/ [      LPCWSTR Version;
3 Z  P" U' ?2 ?      #endif
$ G5 T8 L  p; [  };
0 r. k8 |& Z8 X8 `% o; P  
- S4 a: w0 _' k  6 C& j& q1 @6 W/ J6 w$ a
  CreateDevice是第17个函数,所以它的地址是(17-1)*4 = 0x40,  M1 R2 m; V1 e$ ~0 O
  00501B74   .  8B52 40            mov     edx, dword ptr [edx+40]
( a) R1 z7 g8 y  这里的edx+40就是这么来的。; [8 t  A: O3 R# q) t8 p6 z, e
  
% D1 c+ o* u$ p# o+ o  如果觉得算起来很麻烦的话,还有一个简单的方法,可以自己编译一个d3d9的程序,然后反汇编看看。0 t% ~. w3 s* `! N7 F) j6 Z' W) {
  
/ D! R5 x1 v, g- Z: d4 @% r  如果还觉得麻烦,还有个更简单的方法,直接往下找,通常会有一些调试文本能够帮助定位,例如:' `# I- U& \& V% K! |! ?8 o0 l
  00501B86   .  BB 600B5400        mov     ebx, 00540B60                   ;  ASCII "CreateDevice"
: u% v1 N0 ^% |/ F, n- q! e  ...
% u2 t1 G1 W" M/ l  ?+ G  00501BBB   .  BB 700B5400        mov     ebx, 00540B70                   ;  ASCII "CreateDevice failed again"4 X; B& a- r! R! E! i; k6 j1 o
  当然,这个办法并不通用,有效与否完全要看游戏作者的脸色。
( T/ u0 E7 ]& x- F2 X  
8 X% X: q$ h$ x4 ~  知道了IDirect3DDevice9的地址,就能植入我们自己的初始化ID3DXFont的代码。
6 j" A, ^/ A( j0 t# ]% I( Q7 `  
: O6 G# J" `: K+ R0 c. w  有了ID3DXFont,下面就是要找到用于显示文字的函数,并用我们自己的代码来替换实现。# w) `2 L; {+ T8 N; s/ d
  : B4 \4 F) D4 h
  随便找一段游戏中出现的文字,比如开始菜单上出现的“Full 1.37”,ALT-M,进入内存窗口,在所有搜到的该字符串上下“内存访问”断点,最终会找到地址在4FFF50的一个函数。
( @8 Q, V  C8 C2 r! r4 q: c  / R& F; h- ]/ s6 [& k
  该函数返回时,用的是“retn 14”,在4FFF50处用“retn 14”改写,切回到游戏后没有任何字符出现,说明这个函数正是用来显示字符的。
0 t& f( i6 k  a5 S0 ?  5 l: q. @) ]- N) I
  原谅我在这里对于怎么找到4FFF50的过程含糊其辞,一笔带过了。确实没有什么取巧的方法,完全取决于破解的功力,良好的耐力,以及一点点好运气。而这也正是游戏汉化的难点所在。
2 s) G* p: f1 N  ]  . f. O4 p. _6 N# @5 ^
  找到字符串显示的函数后,还要弄清楚该函数的接口。
7 t7 U  z- {6 x. B# l$ \) _& }  
9 i7 J+ c: z7 I- G' j. g1 t  在屏幕上显示一个字符串,通常需要知道这些要素:字符串、显示的位置(X,Y坐标)、颜色、字符的大小,以及一些flag用于表示左对齐,右对齐,居中,加粗,倾斜等。+ [2 X$ R9 W: J' q
  
& Q$ U2 k! i8 [" I( s5 |3 i* A  前面说过,返回用的是“retn 14”,说明栈里有20(10进制的14h)/4=5个参数,当进入该函数时,栈上的数据是这样的:1 t( J& ^& b/ X- N& G5 F6 s
  . ?1 n; U3 o! w) }+ E8 C
代码:
6 e" n/ `& B: c+ I+ A5 h  0012FE84   00453C48  返回到 GSB_1_37.00453C48 来自 GSB_1_37.004FFF50
* w  L" D2 X$ Y% A/ j8 }+ z+ |; @  0012FE88   0012FEB8  ASCII "Full 1.37"
: w# K5 L9 ~" f8 `' A  0012FE8C   00000000
+ g. K4 c8 H" y) z1 c  0012FE90   40400000
) G. j8 }( }8 b  0012FE94   FFFFFFFF' d: v* l8 q5 X  I7 Y% h4 a& L4 ~/ g" I
  0012FE98   447D8000
! K9 i/ y/ ~4 J/ v+ U- B5 i  
  T5 ?4 r1 a( w+ j) q. Y  第一个,很明显就是要显示的字符串,后面几个是什么玩意儿呢?' B/ F# `! g2 I: X( h" s9 L& y' L
  
$ q$ @4 G& j7 M0 ?) u  回到调用004FFF50的地方,在00453C1D下断点:
0 f  m; j9 p9 z0 D  . m. ]$ W% y5 @: y" S( t- H. _
代码:7 f4 L1 q1 A; |; o0 A
  00453C1D  |> \D94424 14          fld     dword ptr [esp+14]
* H6 C7 R2 t& v0 i$ D+ z" A  00453C21  |.  51                 push    ecx
# T' D- h* q8 Z) _  00453C22  |.  D91C24             fstp    dword ptr [esp]                  ;  参数5  1024.00 P. |# P6 Q* ?6 {8 H5 J4 K. t. N
  00453C25  |.  6A FF              push    -1                               ;  参数48 J3 R$ u' }: R" V+ w! C
  00453C27  |.  D905 F4125400      fld     dword ptr [5412F4]7 ?, {3 o$ Z* d. l( x( B/ ~( v
  00453C2D  |.  83EC 08            sub     esp, 8: e( e. N6 c9 }- H( r/ g
  00453C30  |.  D95C24 04          fstp    dword ptr [esp+4]                ;  参数3  3.02 f7 p# R6 ~2 ~( O9 \
  00453C34  |.  8BD0               mov     edx, eax
  ]! Y7 n9 u; W1 D# q1 ^  00453C36  |.  D9EE               fldz6 }% `3 [7 P1 H. u) e' V
  00453C38  |.  D91C24             fstp    dword ptr [esp]                  ;  参数2  0.0) _% j/ O. C8 K, a" |0 l  v
  00453C3B  |.  56                 push    esi                              ;  参数1
2 }, _6 b9 ~; _7 s  00453C3C  |.  BE 01000000        mov     esi, 1
& T5 U+ z. v: X  00453C41  |.  8BCE               mov     ecx, esi
3 b3 ]2 p/ [+ T( m0 r# g5 D  00453C43  |.  E8 08C30A00        call    004FFF50
1 u! v6 G" G2 [$ |  * G: }2 `* k& S$ t" m8 N2 F
  . S7 P: _7 Y, Z8 b# K; e" i
  可以看到,参数4是一个固定值,第二、三、五参数都是浮点数。$ F, L( z+ K) x8 c' B! {  J
  & Z& W$ w3 }; R+ |
  这里有一个技巧,在函数开始的地方修改参数的值,看看会发生什么变化,很快就能知道参数的作用。: m: e  d& x+ ^2 c! M
  
9 i. ]/ _  x$ Z' i3 W  参数4是颜色值,Alpha和RGB值都是FF,就是白色,与在游戏中看到的字符颜色相同。
: M  B, E& z" o7 c  参数2是X坐标,参数3是Y坐标,参数5用于调整。
4 G6 }+ l: S# v  需要注意的是,还有两个参数是通过寄存器ECX和EDX传递的,ECX用于表示左对齐(0),右对齐(1)和居中(2),EDX是固定值58D6D0,一个全局的结构或类。
! k6 b; v4 n$ o* F" n* M) \  
6 C: |+ l4 m+ a: u6 Q. @# M* E  此游戏有两种字体,因此用于显示字符的几大要素,现在还缺一个,就是不知道如何判断字符的大小。
$ S0 S! N$ S( r7 T* I& P  
* |. s1 e* }- h! W  在用于显示文字的004FFF50的上下断点,多跟几次,就会发现,每次调用以前,都会调用一个call:
! u! [- B, ]& F. s  - _4 Q0 k& G; i% `3 o. S9 U: I$ C& ~) F
代码:% }' B6 e9 A& `: _- U
  00453BD5  |.  BE 44035300        mov     esi, 00530344                    ;  ASCII "zekton16.dds"" S% A0 S# \% A7 }( m8 U
  00453BDA  |.  E8 91B50A00        call    004FF170
8 M# J7 V+ S+ N' h4 O  
' D2 Q1 l" H. b# H* A  004479E7  |.  BE 54035300        mov     esi, 00530354                    ;  ASCII "cwfont20.dds"
' a6 K/ U( V& y/ u9 N) w; E  004479EC  |.  E8 7F770B00        call    004FF170' d2 l7 W0 J( z# T$ b1 T) k5 g; j/ m
  
  ^7 e5 {! Z3 J% y4 t5 R5 P, g0 X  在游戏目录data\font下面有两个文件zekton16.dds.dat和cwfont20.dds.dat,由此判断004FF170应该是用于选择字体的函数。1 i3 N2 O% j/ V) w% ~
  
6 ~+ ], _* q# T) H; {  总结一下:1 [* V0 I3 v/ W' W* H( u
  第一步,找到IDirect3DDevice9句柄,用于初始化ID3DXFont。
8 S! L+ S) L% r7 F- }$ v5 G! m  第二步,找到显示文字的函数,用自己的代码实现之。# Y5 O5 a9 E0 |; U! j8 m5 z  \
  第三步,逐步找到其他需要修改的地方,比如用于得到字符串宽度、高度,指定宽度的字符串换行显示等函数。
# l% @6 \/ x8 f$ X) q; X* `% v" i  & y1 `0 F9 M4 L6 o
  
, w7 V9 Z+ k) ^* n  【具体实现】
6 P, s0 I1 U6 Q1 R  我用的是注入dll,然后打内存补丁的方式。这样的好处是便于更新,可以任意修改实现过程,以后游戏出了新版本,也只要修改几个地址变量,重新编译一下就可以了。
: x* m4 {- C7 X: X9 J$ s  另外一个好处是,不以文件补丁的形式发布,没有版权问题。(有人关心这个吗?)# m/ P; F5 P1 h6 [
  : G- E: o- ?3 Q+ M8 B& |9 i
  源码在这里:
+ |) j0 l: d5 x1 Z  http://gsbzhcn.googlecode.com/svn/trunk/src# O) J) q" A& U4 G9 k6 d2 {6 }
  ) z& B0 ^4 ^1 n5 o8 l" k
  简单的介绍一下流程:
. t# a0 I, G+ K2 V# |  1.CreateProcess启动游戏的exe,并使之处于挂起状态。
3 W- O: ^# Q+ ?; B/ v# W0 `  2.VirtualAllocEx在游戏进程上申请一块内存,WriteProcessMemory往里写入要注入的dll名称。
5 Y% n$ q: b9 ?: @, E  v  3.GetProcAddress得到LoadLibraryA的地址。
4 I2 S3 h: E7 F: {% T3 I  4.CreateRemoteThread运行LoadLibraryA,注入dll,dll载入时会为游戏进程打上补丁。" Z4 w- r* r3 g3 e1 c
  6.WaitForSingleObject等候dll载入完成。* Q$ S# g# O' o
  7.VirtualFreeEx清理掉之前申请的内存。
5 v  `( {. z5 k; m/ w4 u  8.ResumeThread让打过补丁的游戏进程运行起来。
: r' G  p5 L4 J" F* F! E0 h; o  
. i2 P- a& S  {' K  内存补丁主要是让游戏在关键的地方跳转到我们的dll,执行一段代码后再跳回去,或者直接用dll里的函数代替之。# g% x  P( G% f  O
  ' O4 U) q: y/ o
  
# ~  y3 K2 f" z3 L  【结尾】
& L* W# H( Q4 I# o6 ]  此游戏的汉化正在http://code.google.com/p/gsbzhcn/ 进行,文本不多,奈何翻译人手也不多,希望有兴趣的同学能够参与。" \$ Y1 L5 r+ D, b
  
9 @5 u6 S' ]( j( U) Z, @6 z) h/ j2 c$ s. K--------------------------------------------------------------------------------3 r2 q2 K. t3 b3 y, a
【版权声明】: 本文原创于看雪技术论坛, 转载请注明作者并保持文章的完整, 谢谢!
. ~" x. \8 `7 y4 ^9 N5 @
. F+ `2 J$ c. o, G. e  m+ x' E1 a                                                       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日,是全球华人共同的冒险解谜类游戏家园。我们致力于提供各类冒险游戏资讯供大家学习交流。本站所有资源均不用于商业用途。

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