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

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

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

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

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

【转】DirectX 9 游戏汉化详解

本帖最后由 shane007 于 2011-1-30 14:13 编辑 ( J' T% P4 R3 i9 J

8 H/ h" F5 `) k* n1 g/ M作 者: noword_forever7 H- F% j  p/ u- A0 ?9 Z
时 间: 2010-05-25,14:52:51& `( f! _, M- b0 l' [
链 接: http://bbs.pediy.com/showthread.php?t=113739
% U% @& L4 T. d7 J9 X
- t( q, s0 x8 z. R- }6 _5 F【文章标题】: DirectX 9 游戏汉化详解, i$ k; @; ?8 J, T
【文章作者】: noword& }0 H, x! ]: k* T( F
【软件名称】: 无厘头太空战役
3 ?: j! g, r! D3 U  J+ B【下载地址】: http://www.verycd.com/topics/2819995/
! L& z1 a8 p( h' c: o. S, C--------------------------------------------------------------------------------: t+ p2 {& o/ {, a$ X
  【前言】
$ _8 X7 W6 ^8 o! x  先copy一段此游戏介绍:4 m. h( J* f5 n2 U- U5 W4 K) E
  7 y: u  `/ z. S
  这是一个独特的战略游戏,具有即时战略与塔防的混合风格,玩家将扮演庞大太空舰队的最高指挥官,你可以自定飞船的构造,摆放飞船的位置,下达命令,然后观看绚丽的射击与爆炸。移动和爆炸时会有动态模糊效果。支持自定义地图。
" U$ s: I: \$ ^+ S" S  + T! L% D/ m% e" j1 G
  想玩中文版,两个游戏论坛,3DM和YX上,都有人说要汉化,等了几个月,没有下文,说是技术原因。于是决定自己来试试看。: p" S: [4 o; }9 k8 q
  
, H' Q% t3 [2 e- i2 T  ' T; O& x$ w7 n3 {& |
  【困难何在】
& I  k- X0 f2 p1 P+ T, y  此游戏的文本都在data目录下,都是明文的文本文件。修改data\strings.ini,将; f7 P8 o% }& G! g2 c% S& ?" U
  4 i( v* A! N" p2 Y1 M3 p
代码:2 x, p+ \" S! X9 e5 W0 ^6 `
  MAINMENU_QUIT        = "Exit"4 I& {8 @- _+ F3 E- g; `! f( x
  ! r$ G8 H# t3 S+ e2 e: J
  改成
) c& j+ x7 y4 J/ @  . |5 K9 h5 L! H8 w( {: ?( e6 k
代码:
, I; T  F/ p7 ]5 F1 p  MAINMENU_QUIT        = "退出"5 b; S$ _9 k: L) T4 u* E
  2 T! H/ c; Y' e! x0 z9 h
  
: K: N6 T1 p0 ^8 O  进入游戏后,不出所料,无法显示此中文。
3 Z8 G: I( `9 o; C9 h  - a/ P: s( c7 Z; ~: ?; K4 \- ]  t9 P6 j: ?
  茫茫多的游戏爱好者,在尝试汉化某款自己心仪的游戏时,都是死在了这一步——找了半天文本资源,然后翻成中文,满心欢喜和期待的进入游戏,面对的却是一堆乱码或一片空白。满腔热情,化为乌有,无可奈何,黯然神伤。4 r" y! T; ?& N) x1 G/ D
  & }' @' `# a" H
  本文的目的,就是希望能够帮助这些有志于游戏汉化的同学,主要介绍了如何让一个英文的游戏,能够正确的显示出中文。
9 O! b- `1 O) c, `5 W6 W! u  
5 ]5 E$ T' H2 P" k% T  
/ T4 i3 b: b/ L3 Q  【调试分析】
2 [" N3 h, G6 @3 }$ V0 n7 h  DirectX 9游戏的启动流程是这样的,先执行Direct3DCreate9,返回值是一个IDirect3D9句柄,然后执行IDirect3D9->CreateDevice,得到IDirect3DDevice9句柄。
% P% H$ t' B8 p" Q0 L3 I  有了IDirect3DDevice9就能使用DirectX 9的一切绘图手段,而我们最关心的就是能够使用D3DXCreateFont来创建ID3DXFont,继而能够非常方便快捷的在游戏中显示文字。. {1 `" a1 @. G/ d
  
) m* ^5 Z3 j- A7 i+ E2 t; X9 ^  用ODBG载入游戏的exe文件,“查找所有模块间的调用”,找“d3d9.Direct3DCreate9”:' I( S3 [4 T0 `' t+ @0 W
  4 _/ H6 M$ w+ V) ?' X+ }! h7 g
代码:
" }% x9 t( {$ Z: _" e  00501974   .  BB 500A5400        mov     ebx, 00540A50                   ;  ASCII "Initialising 3D Engine"
% R$ |" L" a' b3 B5 [7 h7 L) [  00501979   .  E8 22130000        call    00502CA0
9 o$ ^# `9 n# n6 D6 ]: s* G; o  0050197E   .  6A 20              push    20
4 n$ v: @4 S- n- T. Q. O9 C  00501980   .  8977 18            mov     dword ptr [edi+18], esi
: a5 ?. N( W* `  ?! A. g' L  00501983   .  E8 2E8B0100        call    <jmp.&d3d9.Direct3DCreate9>: X  k, C/ U% [+ ~* S* S
  00501988   .  85C0               test    eax, eax8 e% a) K: h# @7 C% e/ F8 {% }
  0050198A   .  8947 10            mov     dword ptr [edi+10], eax         ;  edi+10 = 58d550
* o; P  Q! O- I2 T  _; c2 k1 N  
+ x& r+ T) O. s. H9 O9 _9 u, q  往下找,就能找到IDirect3D9->CreateDevice:
; ]6 e( n6 I. w8 u  
, Y3 P2 [3 D/ W* U9 C( x8 W1 G代码:2 H6 ~& J2 B! O
  00501B4C   .  8D77 14            lea     esi, dword ptr [edi+14]
4 v! ]" A) H: G, E  00501B4F   .  56                 push    esi                              ;  58d554  => IDirect3DDevice9
# d6 F% L2 y; c. _! n4 E  00501B50   .  8D4F 40            lea     ecx, dword ptr [edi+40]. h) L" O' `8 @6 F% D
  00501B53   .  51                 push    ecx
9 @/ }9 s& u2 Z+ t) C  00501B54   .  6A 40              push    40! D8 Y' J9 z) p* n0 w
  00501B56   .  EB 14              jmp     short 00501B6C1 R. k$ A0 ^: _; s
  ...6 \' b' \4 a- \; q* w% K6 \
  00501B6C   >  8B4F 18            mov     ecx, dword ptr [edi+18]
: l0 v- ?' _) j  Q! v, h( h( v9 q) D  00501B6F   .  8B47 10            mov     eax, dword ptr [edi+10]) W5 ^% H% s. m! H% T8 y
  00501B72   .  8B10               mov     edx, dword ptr [eax]; [9 p& r. l' W% T
  00501B74   .  8B52 40            mov     edx, dword ptr [edx+40]
# b% d, O  X: Q& \  00501B77   .  51                 push    ecx
3 m) n5 U# s% V  00501B78   .  8B4C24 24          mov     ecx, dword ptr [esp+24]
  G$ S9 h9 I5 ?$ v- @( N' o  00501B7C   .  51                 push    ecx
3 U' E: Z1 r6 y3 o0 R  00501B7D   .  55                 push    ebp
/ U$ \+ |3 j' `1 i9 y( u7 G* n  00501B7E   .  50                 push    eax# K, C! p1 c4 n  ~# Q8 g
  00501B7F   .  FFD2               call    edx                             ;  IDirect3D9::CreateDevice
1 i) T1 M' b! a5 F) ]( m  
% t- H; n% ^: l# f  , b; L: t$ U' c2 K/ |
  由于是所谓的COM接口,没有十分明显的标志,不是很好找。% R5 P* k7 i0 E% r' u
  ' e) \% F5 l  m' `
  在微软的DirectX SDK d3d9.h文件中,IDirect3D9的接口是这样的:
* K& C0 I) n; _% m  
5 `- y- ~2 m! J5 D; H  
/ H! c9 V$ c. R: y& ^代码:
4 C6 p0 W: t# N# ]* I  DECLARE_INTERFACE_(IDirect3D9, IUnknown)
" G; ^( h( e/ c) D; [$ Q6 r  {
& ?! b& d* D4 a. _% F      /*** IUnknown methods ***/
" w  @; ]9 c+ C6 ?* h  A      STDMETHOD(QueryInterface)(THIS_ REFIID riid, void** ppvObj) PURE;
: g9 K, F+ G7 s      STDMETHOD_(ULONG,AddRef)(THIS) PURE;" k4 e8 ]6 \/ S) L6 m
      STDMETHOD_(ULONG,Release)(THIS) PURE;
# d! i3 c) [6 {0 z; r) i. H1 N( K  + @, L2 q; a( `; F$ |
      /*** IDirect3D9 methods ***/
  r; v! J. [- m+ p% k      STDMETHOD(RegisterSoftwareDevice)(THIS_ void* pInitializeFunction) PURE;
* j3 ~  J4 a' v& [% {      STDMETHOD_(UINT, GetAdapterCount)(THIS) PURE;2 y) m; p6 V" i' l; V5 [; ?
      STDMETHOD(GetAdapterIdentifier)(THIS_ UINT Adapter,DWORD Flags,D3DADAPTER_IDENTIFIER9* pIdentifier) PURE;# p0 m) m! {# G3 U! }# x
      STDMETHOD_(UINT, GetAdapterModeCount)(THIS_ UINT Adapter,D3DFORMAT Format) PURE;
  f' j! d! C/ _      STDMETHOD(EnumAdapterModes)(THIS_ UINT Adapter,D3DFORMAT Format,UINT Mode,D3DDISPLAYMODE* pMode) PURE;
- W& i% q! y+ U  v( x      STDMETHOD(GetAdapterDisplayMode)(THIS_ UINT Adapter,D3DDISPLAYMODE* pMode) PURE;9 f2 d! s: w: L2 h- [$ {6 }, N
      STDMETHOD(CheckDeviceType)(THIS_ UINT Adapter,D3DDEVTYPE DevType,D3DFORMAT AdapterFormat,D3DFORMAT BackBufferFormat,BOOL bWindowed) PURE;
% l3 F8 p( f% e6 ?      STDMETHOD(CheckDeviceFormat)(THIS_ UINT Adapter,D3DDEVTYPE DeviceType,D3DFORMAT AdapterFormat,DWORD Usage,D3DRESOURCETYPE RType,D3DFORMAT CheckFormat) PURE;+ g4 V4 w$ \! N% G8 ~' ^& m
      STDMETHOD(CheckDeviceMultiSampleType)(THIS_ UINT Adapter,D3DDEVTYPE DeviceType,D3DFORMAT SurfaceFormat,BOOL Windowed,D3DMULTISAMPLE_TYPE MultiSampleType,DWORD* pQualityLevels) PURE;
) F; x/ g, q, X& a) s# [% h  x      STDMETHOD(CheckDepthStencilMatch)(THIS_ UINT Adapter,D3DDEVTYPE DeviceType,D3DFORMAT AdapterFormat,D3DFORMAT RenderTargetFormat,D3DFORMAT DepthStencilFormat) PURE;$ g; x  w, T! p* ^% o& o5 t% H
      STDMETHOD(CheckDeviceFormatConversion)(THIS_ UINT Adapter,D3DDEVTYPE DeviceType,D3DFORMAT SourceFormat,D3DFORMAT TargetFormat) PURE;% ]$ ?! Y* i& R1 `
      STDMETHOD(GetDeviceCaps)(THIS_ UINT Adapter,D3DDEVTYPE DeviceType,D3DCAPS9* pCaps) PURE;
6 c% t( }9 O1 u+ D4 P) g      STDMETHOD_(HMONITOR, GetAdapterMonitor)(THIS_ UINT Adapter) PURE;% u; ~* ~: @4 n7 _; V
      STDMETHOD(CreateDevice)(THIS_ UINT Adapter,D3DDEVTYPE DeviceType,HWND hFocusWindow,DWORD BehaviorFlags,D3DPRESENT_PARAMETERS* pPresentationParameters,IDirect3DDevice9** ppReturnedDeviceInterface) PURE;- c8 B$ |. C; M+ g- u
      
+ d) Q7 F% _# ~7 N4 T+ w/ K      #ifdef D3D_DEBUG_INFO
5 h9 E, u; j0 U1 U$ v      LPCWSTR Version;3 ]8 t( G# \5 y- Z
      #endif. H- J8 h& ]$ C+ v2 m! X8 c
  };8 B& i2 r6 @9 W3 p
  9 t& D5 {% f  D( o
  ; }( X2 ^- r9 k0 K( J
  CreateDevice是第17个函数,所以它的地址是(17-1)*4 = 0x40,
3 k: ~* A9 v. s  g  00501B74   .  8B52 40            mov     edx, dword ptr [edx+40]7 C; A$ x8 \8 e: T3 a+ B* D
  这里的edx+40就是这么来的。
; T# P0 z  i/ X5 b  6 B5 s2 P' Z! }9 G) m& J, b
  如果觉得算起来很麻烦的话,还有一个简单的方法,可以自己编译一个d3d9的程序,然后反汇编看看。8 x" A& Q5 v6 b
  
+ s% B, ~3 t& L/ v6 b4 Q$ i  如果还觉得麻烦,还有个更简单的方法,直接往下找,通常会有一些调试文本能够帮助定位,例如:2 }# W" S. F* L. r3 [( l* J
  00501B86   .  BB 600B5400        mov     ebx, 00540B60                   ;  ASCII "CreateDevice"
7 w0 W8 Z7 p- y& f+ k% z5 [" N  ...
$ c9 T# K; |. a8 K  00501BBB   .  BB 700B5400        mov     ebx, 00540B70                   ;  ASCII "CreateDevice failed again". V2 o$ ~3 ^1 i+ _" [- Y" P! _9 G
  当然,这个办法并不通用,有效与否完全要看游戏作者的脸色。
+ w& W, }7 O! B+ ~  - s" u7 ]6 x. E. ?
  知道了IDirect3DDevice9的地址,就能植入我们自己的初始化ID3DXFont的代码。6 V( r' i2 r# {% P0 l
  
% _1 [6 o, P: p' J" [4 _  有了ID3DXFont,下面就是要找到用于显示文字的函数,并用我们自己的代码来替换实现。! j; i" M7 A2 X% R! i; M4 a- m
  / ]9 ~# }3 w4 b. W7 ?. O# G6 M$ v
  随便找一段游戏中出现的文字,比如开始菜单上出现的“Full 1.37”,ALT-M,进入内存窗口,在所有搜到的该字符串上下“内存访问”断点,最终会找到地址在4FFF50的一个函数。5 y( p) e, _( u# J
  6 E# N4 m% w3 g0 F8 O4 S6 Z/ B  {' u+ n
  该函数返回时,用的是“retn 14”,在4FFF50处用“retn 14”改写,切回到游戏后没有任何字符出现,说明这个函数正是用来显示字符的。
3 V$ D2 H7 Z6 i) _- R2 O  5 j& {6 S( j: K' I. g5 m2 e
  原谅我在这里对于怎么找到4FFF50的过程含糊其辞,一笔带过了。确实没有什么取巧的方法,完全取决于破解的功力,良好的耐力,以及一点点好运气。而这也正是游戏汉化的难点所在。, d4 }9 o+ \& ~8 ]/ `6 P
  # _; o+ z5 o) D3 Z
  找到字符串显示的函数后,还要弄清楚该函数的接口。4 M2 a/ g* i; [
  ) O  z  C# [8 |5 x# f8 e( O
  在屏幕上显示一个字符串,通常需要知道这些要素:字符串、显示的位置(X,Y坐标)、颜色、字符的大小,以及一些flag用于表示左对齐,右对齐,居中,加粗,倾斜等。
, N  |+ D* }7 D' o) W( h  
0 s: J; L& ?! C# I7 c  前面说过,返回用的是“retn 14”,说明栈里有20(10进制的14h)/4=5个参数,当进入该函数时,栈上的数据是这样的:
% a4 a% s9 f0 \, `, H  
# E7 C& P( D4 M' P3 B% X代码:3 P" T; U5 o) D$ r' ~
  0012FE84   00453C48  返回到 GSB_1_37.00453C48 来自 GSB_1_37.004FFF50
, _: D# x6 H, f9 j4 l  0012FE88   0012FEB8  ASCII "Full 1.37"- S! ]2 K$ D- q7 Y1 }
  0012FE8C   000000006 H; m* D3 b5 s$ W5 \0 F9 v% a
  0012FE90   404000001 c6 ]" R* H, x+ @& [2 G1 m9 _
  0012FE94   FFFFFFFF; J3 E. t8 p- C5 @0 O- {
  0012FE98   447D8000
5 z9 U+ S9 ^/ z- Z( {+ m  
/ ~2 J2 A. ?$ }( o: U0 C1 w1 R) k  第一个,很明显就是要显示的字符串,后面几个是什么玩意儿呢?
# x3 S; z5 @! r& z- I8 y" @  
* ~" p5 Q+ Y0 [/ p& q$ F  回到调用004FFF50的地方,在00453C1D下断点:
  \5 E$ Z! r) \( S1 O  8 k7 C' B# o1 ]& i$ ^
代码:
' G% d, b- A" S# P  00453C1D  |> \D94424 14          fld     dword ptr [esp+14]
  J$ p& I% c. U! w/ _, z  00453C21  |.  51                 push    ecx
, h4 d! ?/ W5 R& v  j2 D2 s7 T  00453C22  |.  D91C24             fstp    dword ptr [esp]                  ;  参数5  1024.05 V$ V1 r4 m. l9 }, G3 `+ h
  00453C25  |.  6A FF              push    -1                               ;  参数42 ~% h! x% t  Q. R  a4 s0 r8 |$ O
  00453C27  |.  D905 F4125400      fld     dword ptr [5412F4]  V* v. k; i* s
  00453C2D  |.  83EC 08            sub     esp, 8+ k) O1 n6 r/ u: A% j2 b; r( g1 @
  00453C30  |.  D95C24 04          fstp    dword ptr [esp+4]                ;  参数3  3.0
( T) a+ b6 o- P. H, s  00453C34  |.  8BD0               mov     edx, eax
9 z) t/ c" u, D0 h  00453C36  |.  D9EE               fldz
* q0 L6 N+ k0 L1 @  00453C38  |.  D91C24             fstp    dword ptr [esp]                  ;  参数2  0.0/ ]! g7 @( y% U% t0 Q/ e1 Z5 B% l
  00453C3B  |.  56                 push    esi                              ;  参数19 x9 R* d" j" T! Q2 U  [; R8 O
  00453C3C  |.  BE 01000000        mov     esi, 1/ w  [  [7 l: x% Y9 O+ F4 r# T
  00453C41  |.  8BCE               mov     ecx, esi/ v/ ^8 z8 J5 a
  00453C43  |.  E8 08C30A00        call    004FFF500 ^8 o* w) ?$ z" N! ]- Z" K
  
+ h& Q8 K9 J, R, A% E: O  
; [4 L/ a4 G$ n% }7 R5 {+ g% n  可以看到,参数4是一个固定值,第二、三、五参数都是浮点数。
: }* p& E" h7 d+ [  
9 \+ @4 U% g, }  这里有一个技巧,在函数开始的地方修改参数的值,看看会发生什么变化,很快就能知道参数的作用。  h9 G: |# C# ~  J5 h# t  `; P
  
& v6 [/ b; j. d7 z  参数4是颜色值,Alpha和RGB值都是FF,就是白色,与在游戏中看到的字符颜色相同。/ [% e  `! g% Z" _( ^% R
  参数2是X坐标,参数3是Y坐标,参数5用于调整。
5 X- _6 H; O/ u! J  需要注意的是,还有两个参数是通过寄存器ECX和EDX传递的,ECX用于表示左对齐(0),右对齐(1)和居中(2),EDX是固定值58D6D0,一个全局的结构或类。( a: Y0 v0 O5 h7 Z; Y
  
, L: t' j' p! U2 J- |3 S0 k  此游戏有两种字体,因此用于显示字符的几大要素,现在还缺一个,就是不知道如何判断字符的大小。
" y! M, @- ]2 k8 ^" O7 `  
9 r: U' [. q. q( P, V3 |  在用于显示文字的004FFF50的上下断点,多跟几次,就会发现,每次调用以前,都会调用一个call:
$ \- n$ O: l) m: _; y$ E* Y  
( P  N1 o8 x) }& b代码:. q6 w1 P* S8 x: ]+ @; r* T" @: m
  00453BD5  |.  BE 44035300        mov     esi, 00530344                    ;  ASCII "zekton16.dds"( [+ j1 w- U: Z5 m; V
  00453BDA  |.  E8 91B50A00        call    004FF1703 r( Y5 f& Y6 q% A( f! L8 b
  * @5 T. ]! B1 L) X( M7 e
  004479E7  |.  BE 54035300        mov     esi, 00530354                    ;  ASCII "cwfont20.dds"& G# \5 j1 f2 N& h, |
  004479EC  |.  E8 7F770B00        call    004FF170; Z" i( M1 |: @$ S) ^% U3 s
    b4 r& W1 Q, V/ p
  在游戏目录data\font下面有两个文件zekton16.dds.dat和cwfont20.dds.dat,由此判断004FF170应该是用于选择字体的函数。
. d4 D4 l6 M0 O  & J/ O# B; {  L9 W, z
  总结一下:1 B$ |  X% N1 |3 J* v+ E" Y
  第一步,找到IDirect3DDevice9句柄,用于初始化ID3DXFont。
+ T& b0 u, ]" J  第二步,找到显示文字的函数,用自己的代码实现之。7 y* |1 N' `* c4 Q) @$ z
  第三步,逐步找到其他需要修改的地方,比如用于得到字符串宽度、高度,指定宽度的字符串换行显示等函数。0 b% K* f/ A' R) i
  
* F9 o: Z1 G- H5 {  . |$ ?- R& m4 s( r
  【具体实现】
2 J- O* _# e/ M9 k  我用的是注入dll,然后打内存补丁的方式。这样的好处是便于更新,可以任意修改实现过程,以后游戏出了新版本,也只要修改几个地址变量,重新编译一下就可以了。
0 p/ N& I, P, Z4 a  另外一个好处是,不以文件补丁的形式发布,没有版权问题。(有人关心这个吗?): ?2 Q" K0 a* o1 l
  5 u: K: k/ D8 E( V
  源码在这里:7 j1 |5 C2 H# ~' s1 G' S
  http://gsbzhcn.googlecode.com/svn/trunk/src2 K! y& H+ x& g, i( {
  ; G9 z, _# v* @
  简单的介绍一下流程:4 z) G, ~5 H$ b
  1.CreateProcess启动游戏的exe,并使之处于挂起状态。- c5 d/ w5 G5 B) c9 I: u$ R2 i6 k  f
  2.VirtualAllocEx在游戏进程上申请一块内存,WriteProcessMemory往里写入要注入的dll名称。
5 Q  {3 h8 |0 O" V  3.GetProcAddress得到LoadLibraryA的地址。/ b6 E1 v0 }" B3 P. b8 O( f
  4.CreateRemoteThread运行LoadLibraryA,注入dll,dll载入时会为游戏进程打上补丁。  ?' v- Q& L; Q) A5 l2 w8 ~7 Q& V: a
  6.WaitForSingleObject等候dll载入完成。9 P- b! a( ~7 `. M! ?# N
  7.VirtualFreeEx清理掉之前申请的内存。
6 H5 J/ b4 z9 P+ K  8.ResumeThread让打过补丁的游戏进程运行起来。* @  q9 I* j. a
  6 K" B  H4 Y9 `$ c; R% m/ h$ O$ N' b
  内存补丁主要是让游戏在关键的地方跳转到我们的dll,执行一段代码后再跳回去,或者直接用dll里的函数代替之。1 C5 Y7 H! i# Z9 a! {: T0 D4 w
  . O$ b3 e3 j& i' Z
  3 O, M; m9 ?) K. w6 l2 Y+ b
  【结尾】
! T- e0 r* {) |  此游戏的汉化正在http://code.google.com/p/gsbzhcn/ 进行,文本不多,奈何翻译人手也不多,希望有兴趣的同学能够参与。! N. y; g+ G) {3 R
  # B2 q' j, q+ n. ^; W
--------------------------------------------------------------------------------
. F* N5 t$ o$ u; o, ^7 R! R2 c5 ^8 {【版权声明】: 本文原创于看雪技术论坛, 转载请注明作者并保持文章的完整, 谢谢!
% i& r' {. i8 \; g- |
- i* l/ A7 J8 Q4 ?6 a+ p. t3 }                                                       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日,是全球华人共同的冒险解谜类游戏家园。我们致力于提供各类冒险游戏资讯供大家学习交流。本站所有资源均不用于商业用途。

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