posts - 311, comments - 0, trackbacks - 0, articles - 0
  C++博客 :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

(搬运工)Mangos代码阅读(一)

Posted on 2012-07-13 13:49 点点滴滴 阅读(1186) 评论(0)  编辑 收藏 引用 所属分类: 10 服务器

Mangos有13个工程。

使用了4个外部工具库,分别是:

  1. 跨平台的网络通讯框架The ADAPTIVE Communication Environment (ACE)
  2. 压缩库zlib
  3. Socket通信库 C++ Sockets Library (使用在realmd工程中,和使用在Mangosd工程中的RASocket,负责处理Remote Administration。其他地方没有使用到这个C++ Sockets Library )。发现在C++ Sockets Library的TcpSocket::Open中存在一个问题,在n = connect(s, ad, ad);语句执行后,如果n=-1,C++ Sockets Library会检测是否ERR为WSAEWOULDBLOCK,否则表示成功,但在动态库中使用TcpSocket的时候,我发现n = connect(s, ad, ad);语句执行后,n=-1,ERR会为0,这个时候连接也是成功了,但TcpSocket::Open会当做不成功处理。我发现这个问题,但没有时间去探究原因,也许并不是一个问题。
  4. C++的并行编程模板库Threading Building Blocks (tbb 和 tbbmalloc)

Mangos的实现分为:登录服务器(realmd)和世界服务器(mangosd+game)。realmd和mangos共用了Mangos公共库(shared)。

工程shared

提供了通用功能,包括了数据库的封装类,实现了对MySql的访问,同样,我们可以编写派生类来支持其他的数据库。

工程script

提供了脚本接口,并实现了简单的几个脚本,封装为DLL,提供给game使用,具体可参考:MaNGOS脚本接口

通过使用不同的脚本DLL来替换Mangos中的AI实现,可以让game具有更强的AI。ScriptDev2 就是一个这样的库。ScriptDev2 is a replacement for the Script Library that comes with MaNGOS( http://www.getmangos.com ) written in C++ and is compatible with Windows and Linux. It provides scripts for NPCs, Boss events, and Items currently. Once ScriptDev2 is compiled it is automatically run by MaNGOS on server startup.

image

工程mangosd

mangos是世界服务器的管理器,负责初始化工作和启动世界服务器各层的线程,这些工作主要是由类Master来实现。具体是:

  1. 使用三个数据库对象WorldDatabase和CharacterDatabase和loginDatabase,初始化三大数据库:World Database和Character Database和login Database,并为每个数据库的访问都启动一个DB delay threads。具体的数据库操作功能都是由Mangos公共库shared来提供。
  2. 调用sWorld.SetInitialWorldSettings,对World进行初始化,包括加载所有的游戏数据和初始化各种更新定时器和邮件定时器,还有些其他的初始化工作。类World的成员函数SetInitialWorldSettings调用成员函数LoadConfigSettings解析mangosd.conf,解析后内容放入uint32 m_configs[CONFIG_VALUE_COUNT]中。
    1. 加载的游戏数据有:
      1. DBC数据
      2. Objects数据
      3. Spells数据
      4. Pooling数据
      5. Game Event数据
      6. loot数据
      7. 技能数据
      8. 所有其他的游戏数据,包括Waypoints和Trainers等等等。
      9. 脚本数据
    2. 初始化的更新定时器有:
      1. WUPDATE_OBJECTS
      2. WUPDATE_SESSIONS
      3. WUPDATE_AUCTIONS
      4. WUPDATE_WEATHERS
      5. WUPDATE_UPTIME
      6. WUPDATE_CORPSES
      7. WUPDATE_EVENTS
    3. 其他的初始化工作有:
      1. 初始化MapManager,启动Map System
      2. 初始化Battlegrounds,启动BattleGround System
      3. 初始化DailyQuestResetTime
      4. 初始化sGameEventMgr,Starting Game Event system
  3. 类Master还实现了mangos server的退出管理
  4. 类Master启动WorldRunnable,开始游戏逻辑。Heartbeat for the World,由Master创建,并设置线程为最高优先级。
  5. 类Master启动CliRunnable:Command Line Interface handling thread,由Master创建。CliRunnable运行时候会生成一个WorldDatabase线程,在接收到输入后会调用sWorld.QueueCliCommand把Cmd放入到World::cliCmdQueue中。
  6. 类Master启动RARunnable:Remote Administration,由Master创建
  7. 如果配置要求,类Master还会启动一个freeze catcher thread
  8. 类Master启动2个网络线程ReactorRunnable(可配置数目)

mangosd的线程总共有(1+3+1+1+1+2 +1 =10)10个线程。

  1. 主线程Master
  2. 2个网络线程ReactorRunnable(可配置数目)(网络层)
  3. 一个World线程(逻辑层)
  4. 三个DB线程(数据层)
  5. 一个CLI线程(输入层),运行时候会生成一个WorldDatabase线程
  6. 一个RA线程(管理层)
  7. 一个freeze catcher 线程(可选)

工程g3dlite:游戏逻辑层的底层库

工程framework:系统框架

工程realm

负责登陆和选择游戏服务器,进行负载均衡。用到了C++ Sockets Library进行登录处理,采用select I/O模型。实现了Wow, Mangos登录时的SRP6认证。客户端作为它的client连接到realm server认证和选择了mangos server就断开。 而mangos server和realm server则不进行连接,只是通过数据库交互数据:mangos server把自己的状态和拥有的角色数放入库中。realm server会读取数据库中的这些信息来获知mangos server的状态。

  1. 数据库realm的realmlist表保存了realm的列表
  2. realm通过如下事件处理函数来负责登陆和选择游戏服务器。

    const AuthHandler table[] =
    {
        { AUTH_LOGON_CHALLENGE,     STATUS_CONNECTED, &AuthSocket::_HandleLogonChallenge    },
        { AUTH_LOGON_PROOF,         STATUS_CONNECTED, &AuthSocket::_HandleLogonProof        },
        { AUTH_RECONNECT_CHALLENGE, STATUS_CONNECTED, &AuthSocket::_HandleReconnectChallenge},
        { AUTH_RECONNECT_PROOF,     STATUS_CONNECTED, &AuthSocket::_HandleReconnectProof    },
        { REALM_LIST,               STATUS_AUTHED,    &AuthSocket::_HandleRealmList         },
        { XFER_ACCEPT,              STATUS_CONNECTED, &AuthSocket::_HandleXferAccept        },
        { XFER_RESUME,              STATUS_CONNECTED, &AuthSocket::_HandleXferResume        },
        { XFER_CANCEL,              STATUS_CONNECTED, &AuthSocket::_HandleXferCancel        }
    };

登录处理:

user登录到realm server进行身份认证,并选择登录上哪个mangos server。user登录到mangos server后,将不再和realm server交互。

参考: Wow 服务器解析