魔兽私服Trinitycore架构设计分析之一

本文分析了魔兽私服Trinitycore的架构设计,重点讲述了网络层的启动过程,包括线程创建、服务监听、网络包处理流程。在Session管理方面,详细描述了如何生成和维护玩家Session,以及WorldSocket与WorldSession之间的交互。通过WorldRunnable的run方法,可以看到世界心跳更新的逻辑,包括定时任务、天气更新、日常任务重置等功能的执行。整个流程展示了网络游戏服务器中关键的网络服务和会话管理机制。
摘要由CSDN通过智能技术生成

这几天有些空闲时间,把改编自MangOS的魔兽私服Trinitycore代码梳理一下,也给有这方面兴趣
的童鞋一个交流空间,可能会连载15篇左右,大家慢慢看
首先把整体架构网络层说一下


打开整个工程,找到Trinitycore项目,game这个库引用了framework,shared等库,以后有时间再一一介绍

Trinitycore_build_8128_for_client_333a/src/trinitycore/Main.cpp

这个主函数其实就是提取配置文件名称和在Windows环境下以WIN32 服务方式使用的三种情况,这种编程手法
在我们很多项目中都很常见,就不多说了

 


最主要的就是这句

 return sMaster.Run();

这里最重要的一个步骤就是
void World::SetInitialWorldSettings()
其实我们做过网游开发的人都应该知道,这就是加载服务器的各种资源文件,初始化场景,初始化脚本引擎,
序列化文件读取之类的步骤,每款游戏各有不同,但都是启动前最耗时间的一段程序

然后就是启动4个线程
 ACE_Based::Thread world_thread(new WorldRunnable);
   
 world_thread.setPriority(ACE_Based::Highest);

 ACE_Based::Thread* cliThread = NULL;

 cliThread = new ACE_Based::Thread(new CliRunnable);

 ACE_Based::Thread rar_thread(new RARunnable);
 FreezeDetectorRunnable *fdr = new FreezeDetectorRunnable();

接着取得IP,和端口开始网络服务
int
WorldSocketMgr::StartNetwork (ACE_UINT16 port, const char* address)
这个函数很明显,大家都可以找到,也可以很轻松找到下一个函数


int 
WorldSocketMgr::StartReactiveIO (ACE_UINT16 port, const char* address)

在分析这个函数时不得不去仔细阅读一下另一个类的声明,只看一部分就够了
typedef ACE_Svc_Handler<ACE_SOCK_STREAM, ACE_NULL_SYNCH> WorldHandler;
class WorldSocket : protected WorldHandler
{
    public:
        /// Declare some friends
        friend class ACE_Acceptor< WorldSocket, ACE_SOCK_ACCEPTOR >;
        friend class WorldSocketMgr;
        friend class ReactorRunnable;

        /// Declare the acceptor for this class
        typedef ACE_Acceptor< WorldSocket, ACE_SOCK_ACCEPTOR > Acceptor;----------这个模板定义很重要


WorldSocket 的 open 方法由接受器工厂在连接建立之后调用的时候调用

 

这样思路就完全清晰了

int WorldSocket::open (void *a)

函数中通过
   if (sWorldSocketMgr->OnSocketOpen (this) == -1)
 ----这个方法,把这个SOCKET对象放入了一个合适的线程中      
  return -1;

 

最后就是网络包对应逻辑处理的流程

WorldSocket::handle_input (ACE_HANDLE)
---WorldSocket::handle_input_missing_data
---WorldSocket::handle_input_payload
---WorldSocket::ProcessIncoming (WorldPacket* new_pct)
---最后进入
int WorldSocket::HandleAuthSession (WorldPacket& recvPacket)
此函数最重要的部分,列出如下

//这句话生成了玩家的session,并保存
    ACE_NEW_RETURN (m_Session, WorldSession (id, this, AccountTypes(security), expansion, mutetime, locale), -1);

    m_Crypt.Init(&K);

    m_Session->LoadGlobalAccountData();
    m_Session->LoadTutorialsData();
    m_Session->ReadAddonsInfo(recvPacket);

    // In case needed sometime the second arg is in microseconds 1 000 000 = 1 sec
    ACE_OS::sleep (ACE_Time_Value (0, 10000));

    sWorld.AddSession (m_Session);

 


网络这一块真是难以用很漂亮的语言描述清楚,中间再加一个小插曲

WorldSocketMgr.cpp中定义了一个主动对象类,这个就是sWorldSocketMgr->OnSocketOpen函数中
分担各个WorldSocket的那个线程类


        virtual int svc ()
        {
            DEBUG_LOG ("Network Thread Starting");

            WorldDatabase.ThreadStart();

            ACE_ASSERT (m_Reactor);

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值