A端(Hearthstone) Logon服务器综合分析(零散笔记)

来源:互联网 发布:特征选择算法 编辑:程序博客网 时间:2024/06/05 03:14

 

                            原创作品 勿擅自转帖

 

////////////////////////////////////////////////////////////////////

 

 

Logon的作用是处理分区服务器,并将辅助世界服务器和客户端建立起连接,具体分析见后。

 

分为两部分:与客户端通讯和与分区服务器通讯

 

配置文件中:
"RealmListPort" 3724

"ServerPort" 8093

"Host" "0.0.0.0"

"ISHost" "0.0.0.0"

 

通讯中RemotePassword 经过hash后传递。

 

HOSTRealmListPort接收的是来自客户端的连接,以ListenSocket<AuthSocket>的形式存在。

ISHOSTServerPort作为服务器监听并处理来自World或者Realm的通讯,以ListenSocket<LogonCommServerSocket>的形式存在。

 

template<class T>

class SERVER_DECL ListenSocket : public ThreadContext

 

ListenSocket继承自 ThreadContext 传递给线程池由线程池执行,CThreadPool::ExecuteTask(ThreadContext * ExecutionTarget)

 

认证过程见AuthSocket

 

分区信息的处理见AccountCache中的 InformationCore,放在这里可能不太合适!

 

解释RealmWS)与Logon的连接验证方式:

1Logon作为服务器,监听,默认端口8093,在Main()

ListenSocket<LogonCommServerSocket> * sl = new ListenSocket<LogonCommServerSocket>(shost.c_str(), sport);

2)当Logon接收到连接,首先是需要验证,由void HandleAuthChallenge(WorldPacket & recvData);处理验证,验证需要密码,密码分别在RealmLogon的配置文件有设定RemotePasswordLogon启动时将密码经过加密后,与Realm发来的加密过的密码相比较判断是否合法,此外Logon严格限制连接的IP,由 AllowedIPsAllowedModIPs设定。

3)最后由Logon返回验证信息。如果通过则建立起连接通讯。

 

解释客户端的验证和连接,

1)首先客户端登录,连接到Logon3724端口。并由Logon信息返回是否登陆成功。

其中由void AuthSocket::HandleChallenge()判断账号是否禁用、账户冻结、客户端补丁是否最新等。

void AuthSocket::HandleProof()处理账户的是否登录成功,验证过程是找不到明文的密码,如果不加密(见注)那么

hash.UpdateData((Username + ":" + Password));

hash.Finalize();

memcpy(acct->SrpHash, hash.GetDigest(), 20);

也就是说UsernamePassword组合hash后保存在 Account结构的SrpHash成员 uint8 SrpHash[20];

2)如果HandleProof()验证通过则会为该账户分配SessionKey

const char* m_sessionkey_hex = m_sessionkey.AsHexStr();

并将账户标记为已验证:

m_authenticated = true;

 

3)接下来客户端会请求得到Realm——分区表,#define REALM_LIST 16

4)当Logon收到该消息后交给 AuthSocket::HandleRealmlist 处理,该函数调用InformationCoreSendRealm()方法:

sInfoCore.SendRealms(this); //#define sInfoCore InformationCore::getSingleton()

5)Logon会将注册的分区表发送给客户端,其中包含Realm的服务器名,地址,端口信息等

但是地址和端口是一个整体,就像在Realm配置文件中看到的那样:

data << itr->second->Address;

string Address;

realm->Address = Config.RealmConfig.GetStringVA("Address", "127.0.0.1:8129", "Realm%u", i);

6)到此客户端将尝试连接至Realm服务器!

7Realm收到请求后向Logon Server发送消息

Logon Server将消息由

void LogonCommServerSocket::HandleSessionRequest(WorldPacket & recvData)

函数处理,通过

request_id;

account_name;

验证账户的合法性,如果通过则返回SessionKey

 

登录连接的过程至此就结束了。

 

注:配置文件中的UseEncryptedPasswords不是指RemotePassword是否加密而是指Account表中的账户密码是否加密,搜索m_encryptedPasswords可证。

 

控制台分析

 

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

控制台中 class LogonConsoleThread : public ThreadContext发送到线程池执行,处理控制台的输入,并将命令转发到 class LogonConsole : public Singleton < LogonConsole >进行处理,包括关闭,帮助,Rehash

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////