游戏服务器,登陆认证

    写这些东西,纯属是在学习的时候的一些笔记,或者是自己的认识,或者是在资料上看到的好的论点,发现有的时候如果不把这些东西记下来,后来再忘记掉,真的是很划不来的一件事,本来是打算记在笔记本上,但是最终觉得记在这里会更好,也许对别人会有所帮助.真的是第一次写帖子,大家多包涵~~~



这一篇的主题是介绍一个网络游戏的登陆认证过程


 1. 概述

     网络游戏 通常都需要进行账号登陆管理,验证账号及密码,进行上线下线记录以及计费等等,那么这个过程是怎么实现的呢,其实原理上是很简单的,就是当客户端向游戏服务器连接之前,先和账号登录服务器连接[当然,也有一种情况是客户端直接和游戏服务器相连,然后游戏服务器作为客户端的代理向 账号 登录服务器进行验证],然后通过验证后,获取游戏服务器的列表,由玩家自行选择进入那个游戏服务器。

     从上面的描述中,可以看出来一个 账号 登录服务器的职责:

     1. 管理账号

     2. 验证账号

 

     1. 管理账号,就是账号的产生,管理,删除。这里并不是讨论的主题,但是为了便于大家理解和后面的说明,在这里做一个简要的说明,账号一般都是用数据库来管理的[什么,你说用txt来记录?:(],通常去网站上注册一个什么账号啊,通信证啊,一卡通啊,差不多都是同一件事,就是向账号数据库中的账号表里面插一条记录,账号表的结构也是大同小异,比如

         create table 'account'

         ( 'id', bigint(20) unsigned NOT NULL auto_increment,

           'accountname' varchar(32) NOT NULL,

           'password' varchar(32) NOT NULL,

           'email' varchar(32) NOT NULL,

           PRIMARY KEY('id')) ENGINE=MyISAM;

          如果你看出来我会点MySQL,你就是对的~~~呵呵,那么,你按照注册网站千篇一律的流程痛苦的填完N多资料以后,比如


          账号名称: 我就是我

          密码      : ooxx

          E-mail   : 我还是我@猪猪.com


          点击确定,那么实质上只是执行了一条SQL语句

          insert into account( 'accountname', 'password', 'email' ) values( 我就是我, ooxx , 我还是我@猪猪.com ),就是这么回事,你就算有一个账号了,好了,再说的话我真要离题了

 

      2. 验证账号,你通过上面的注册,已经拥有了一个账号了,那么现在想进入游戏,只要输入相应的账号和密码即可,但是,一般来说这里还有很多的细节要处理,大部分服务器使用状态机变迁来描述登陆这一过程,实际上 状态机处处存在

          光是描述原理,显得过于简单,大家会觉得一听都懂,甚至是太简单,抱着学习的态度,我就用 常见的WOW 开源项目 Mangosd的realmd server来讲解,因为这个代码大家都能得到,看完文章可以去看看代码,这样就明白了, 登陆状态逻辑图如下

   

    事实上,它分为三个过程,你在自己的机器上启动wow客户端,它就和RealmServer建立起一个连接,然后向 RealmServer发送一个 AUTH_LOGON_CHALLENGE_C数据包, RealmServer进行账号合法性验证,然后向客户端发送验证结果,如果通过验证,客户端再向RealmServer发送 AUTH_LOGON_PROOF_C数据包,进行密码验证,并向客户端 发送验证结果,如果通过验证,客户端会发送 AUTH_LOGON_REAlMLIST_C来请求可用的服务器列表,收到 RealmServer 发来的游戏服务器列表后,玩家就可以选择一个合适的游戏服务器登入游戏了。

 

    在RealmServer使用的MySQL数据库,其中的realmd数据库是 用来管理账号的,他包含有几张表,在附录中有简单的描述。

    下面是更详细的描述,如果要结合代码来看的话只要关注 /trunk/src/realmd/AuthSocket.cpp就行了,OnRead函数中有状态的分派,是用函数指针数组实现的,这是一种惯用法,或者直接copy下面的网址到IE浏览器中 https://mangos.svn.sourceforge.net/svnroot/mangos/trunk/src/realmd/AuthSocket.cpp,记住,如果是初学者,一定不要一口吃个大胖子,减少自己在一个时间段的关注量有利于知识的理解和学习,同一时刻关注太多的东西会打击人的信心,而且分散注意力


    状态一: AUTH_LOGON_CHALLENGE
        1. 上行包结构
        struct AUTH_LOGON_CHALLENGE_C
        {
            uint8   cmd;         // 协议
            uint8   error;
            uint16  size;
            uint8   gamename[4];
            uint8   version1;
            uint8   version2;
            uint8   version3;
            uint16  build;
            uint8   platform[4];
            uint8   os[4];
            uint8   country[4];
            uint32  timezone_bias;
            uint32  ip;
            uint8   I_len;
            uint8   I[1];      //这里是账号名
        };
        这个结构体很简单,成员基本上看名字就知道什么意思了,重要的是cmd成员[它的值为AUTH_LOGON_CHALLENGE],它标示出该上行包应该由AuthSocket::_HandleLogonChallenge()协议处理函数来处理
        2. 协议处理函数流程
           1. 检查IP是否处于冻结状态
           2. 检查账号是否处于冻结状态
           3. 向Client发送验证结果

    状态二: AUTH_LOGON_PROOF
        1. 上行包结构
            struct AUTH_LOGON_PROOF_C
            {
                uint8   cmd;
                uint8   A[32];
                uint8   M1[20];
                uint8   crc_hash[20];
                uint8   number_of_keys;
                uint8   unk;
            };
            这个上行包的作用是密码的验证,cmd成员[它的值为AUTH_LOGON_PROOF],由AuthSocket::_HandleLogonProof()来处理。

        2. 协议处理函数流程

            1. 进行密码验证

            2. 如果验证成功,会更新account表中的last_ip, last_login等字段,并通知客户端。

    状态三: REALM_LIST
         1. 上行包结构
              这个包的结构不重要,但是可以肯定的是其结构如下
             struct AUTH_LOGON_REAlMLIST_C
             {
                uint8   cmd;
                ····
             };
             这个上行包的作用是请求realmlist,也就是ServerList,以获取服务器列表,cmd成员[它的值为REALM_LIST],Server会返回一个游戏服务器的列表其中包含各个游戏服务器的装态,本账号在该服务器的角色数量等信息,其实这个并不能算做是一个认证状态,真正的认证状态在AUTH_LOGON_CHALLENGE和AUTH_LOGON_PROOF就已经已经确定了下来,这个上行包只是用来请求ServerList而已。

 

 

     至于客户端是怎么连接上RealmServer的,RealmServer怎么管理多个并发的客户端的链接和通信的,在这里就不细说了,只能是简单的在这里提一下,我看的Mangosd的版本里面,使用的是select模型~~这个简单易懂,但是大家都知道它的缺点,虽然说是并发的获取了IO事件,但是事件的处理过程却是依次同步的,连接越多,IO事件越多,它就越慢~~~而且还有一个进程里面监听句柄数量的限制,不过新的Mangosd里面已经使用了ACE,但是我觉得初学还是看select版本的比较好,比较ACE又会给你的学习带来不小的负担,网络这部分以后也会慢慢的讲解~~呵呵,希望大家支持

 

附录:RealmServer使用的表

1.  account  账号表

关键字段介绍:id  全局唯一的标示

  username        账号名

  sha_pass_hash   账号密码密文

  gmlevel         GM账号等级 [0~3( 最高级别 )]

  joindate       账号创建时间

  online         在线标志位 [ 玩家在线时为 1]

  mutetime       禁言时间

 

2.   account_banned 冻结账号表

关键字段介绍:id account      表中对应的 id

  bandate         冻结开始时间[ 以秒记 ]

  unbandate      解冻时间

  bannedby        冻结方式

  banreason      冻结原因

  active         解冻标志 [0 为解冻,默认为 1]

   Ps : 玩家在冻结时间过后登陆时会把 active 置为 0

 

3.   ip_banned 冻结 IP

   关键字段介绍:ip ip地址

 bandate          冻结开始时间[ 以秒记 ]

 unbandate       解冻时间

 bannedby         冻结方式

 banreason       冻结原因

 

4.   realmcharacters 玩家角色数量统计表

   关键字段介绍: realmid          GameSeverId[对应于 relmlist GaveServer id]

  acctid         账号Id[ 对应于 account 中的 id]

  numchars        角色数量

   Ps : realmid是在 mangos.conf 中配置的

 

5.   realmlist GameServer列表

   关键字段介绍: id              GamesServer的唯一标示

  name            GameServerName

  address        GamServerIP

  port           GameServerPort

  icon            据说是GameServer Type PVPorPVE

  color           据说等于2 的时候标示 GS 不在线,黑色选不中

  timezone       GS类型,分国家

  allowedSecurityLevel 安全等级,和登陆的玩家的权限有关

  population      GS人数百分比



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值