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

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

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

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

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

【转】DirectX 9 游戏汉化详解

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

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