现在的位置: 首页 > 综合 > 正文

Wow 服务器解析(一)

2013年10月09日 ⁄ 综合 ⁄ 共 2296字 ⁄ 字号 评论关闭

http://www.cppblog.com/Jedimaster/archive/2006/10/14/13674.aspx

 

Wow
服务器解析(一)


      

最近抽空研究了一下
WOW
的服务器结构,也顺便从那些项目中又复习了一下
ManGOs

template
方式下
SingleTon
的使用方法。不过有些不明白的,如果这样,
SingleTon<Master>
这样的使用,如果传入的类型不同,难道传出的
static
是一样的?不可能吧,如果打印出
this
指针看看呢?抽空我再试试。
SingleTon
在游戏设计中是相当重要的设计模式,大家一定要好好学习。

认证过程

Wow
的服务器有两部分组成:
Logon Server
(以下简称
LS
)和
Realm Server
(以下简称
RS
)。
LS
接受来自
Wow
客户端的连接,主要有以下几步完成:

检查客户端版本区域等信息,检察账号密码

开始
/
继续传送
Patch
(如果有)

与客户端进行
SRP6
的加密会话,把生成的密匙写入数据库

根据客户端请求发送
Realms
列表

当客户端选择好
Realms
后,客户端就从
LS
断开,连接到
RS
上:

认证,使用刚才生成的客户端密匙

如通过,进行游戏循环的交互

RS

LS
使用相同的数据库,
SRP6
密匙被
LS
生成并写入
DB
后还要由
RS
读取出来进行下一步的认证。

 

Logon Server
详解

基本的连接过程如下:

客户端准备连接,发送
CMD_AUTH_LOGON_CHALLENGE
数据包,包含了所有登陆所需要的数据比如用户名密码等

服务端返回
CMD_AUTH_LOGON_CHALLENGE
数据包,填充字段包括有效验证,以及计算好的服务端
SRP6
数据

如果有效,客户端发送
CMD_AUTH_LOGON_PROOF
数据包,并把自己计算的
SRP6
数据填充进去

服务端进行验证,发送回
CMD_AUTH_LOGON_PROOF
,包含了
SRP6
验证的结果

如果一切正常,客户端发送
CMD_REALM_LIST
数据包,请求发送有效的
Realm

服务器回复
CMD_REALM_LIST
数据报,并填充过客户端需要的
Realm
数据

客户端的
Realm
列表每隔
3-4
秒就会从服务器端刷新一次。


 

这个
SPR6
是一种什么样的加密手段呢?以前我也没有用过,看得最多的是
MD5SHA

hash
算法
SPR
算法吸取了
EKE
类型算法的优点进行了改进,非常适合于网络的认证服务,如果我没有记错,
J2EE
包含了这个算法的实现。下面简单介绍一下
SRP6a
运作机制,原文见这里。

N    
N = 2q + 1


q
是一个素数,下面所有的取模运算都和这个
N
有关



g    

一个
N
的模数,应该是
2
个巨大的素数乘得来

k    
k = H(N,G)


SRP6

k = 3

s     
User’s Salt

I     

用户名

p    

明文密码

H() 

单向
hash
函数

^     

求幂运算

u    

随机数

a,b  

保密的临时数字

A,B 

公开的临时数字

x    

私有密匙(从
p

s
计算得来)

v    

密码验证数字

其中
x 
= 
H(s,p)


v = g ^ x

s
是随机选择的,
v
用来将来验证密码。

主机将
{ I,s,v }
存入数据库。认证的过程如下:


 

客户向主机发送
I

A = g ^ a

a
是一个随机数)

主机向客户发送
s

B = kv + g^b
(发送
salt

b
是一个随机数字)

双方同时计算
u = H(A,B)

客户计算机算
x = H(s,p)
(开始
hash
密码),
S = ((B - kg^x) ^ (a + ux) )

K = H(S)
,(开始计算会话
Key

主机计算
S = (Av^u)^b

K = H(S)
,也生成会话
Key


 

为了完成认证,双方交换
Key
,各自进行如下的计算:

客户接收到来自主机的
key
后,计算
H(A,M,K)

同理,主机计算
M = H(H(N) xor H(g), H(I), s, A, B, K)
,验证是否合自己储存的数值匹配。至此完成验证过程。


 


三、

Realm Server
详解


LS
断开后,开始和
RS
认证:

连接到
RS
,向服务器发送
SMSG_AUTH_CHALLENGE
数据包,包含上次所用的随机种子

服务器发送回
SMSG_AUTH_CHALLENG
。客户端从服务器端发送回来的种子和
SRP6
数据中产生随机种子,生成
SHA1
字符串,用这些数据生成
CMSG_AUITH_SESSION
数据包,发送给服务端。

需要注意的是,这个过程是没有经过加密的。当服务端收到认证回复后,通过客户端产生的种子也生成一个
SHA1
串和来自客户端的进行对比,如果相同,一切
OK


 

下面看一下对账号创建的角色等操作进行分析。一个账号最多可以建
50
个角色吧,我还没有玩过,只是看了一下
Manual

 客户端发送一个
CMSG_CHAR_ENUM
数据包请求接受角色

服务端发送回包含所有角色信息的
CMSG_CHAR_ENUM
数据包

这里客户端可以对这些角色进行操作了,
CMSG_CHAR_CREATE

CMSG_CHAR_DELETE

CMSG_CHAR_PLAYER_LOGIN

角色登陆完成后,服务器发送回
SMSG_CHAR_DATA
数据包



在游戏循环中是如何操作的呢?

如果玩家立刻退出游戏,那么客户端发送
CMSG_PLAYER_LOGOUT
,服务器回复
SMSG_LOGOUT_COMPLETE

如果玩家选择稍后退出游戏,发送
CMSG_LOGOUT_REQUEST
。服务端回复
SMSG_LOGOUT_RESPONSE
。如果玩家在倒计时阶段退出,发送
CMSG_PLAYER_LOGOUT
,那么玩家的角色依旧等倒计时完成后再退出。

如果玩家中断了退出继续游戏,发送
CMSG_LOGOUT_CANCEL
,服务器回复
SMSG_LOGOUT_CANCEL_ACK

抱歉!评论已关闭.