艾泽拉斯核心的更新差异如何运作?

How does the update diff work in AzerothCore?

worldserver 源代码充满了 Update 方法,这些方法将 diff 整数值作为输入:

它是如何工作的?

这如何链接到 .server info 命令中的“更新时间差异”?

要完全了解其工作原理,有必要查看主要世界 运行 进程。

WorldRunnable::运行()

文件:src/server/worldserver/WorldThread/WorldRunnable.cpp

方法 void WorldRunnable::run() 是“世界的主要心跳”。这个方法运行是整个世界的进程。

里面有一个 while 循环 运行 只要世界应该保持 运行ning:

void WorldRunnable::run()
{
    uint32 realCurrTime = 0;
    uint32 realPrevTime = getMSTime();

    ///- While we have not World::m_stopEvent, update the world
    while (!World::IsStopped())
    {
        ++World::m_worldLoopCounter;
        realCurrTime = getMSTime();

        uint32 diff = getMSTimeDiff(realPrevTime, realCurrTime);

        sWorld->Update( diff );
        realPrevTime = realCurrTime;

        uint32 executionTimeDiff = getMSTimeDiff(realCurrTime, getMSTime());
        devDiffTracker.Update(executionTimeDiff);
        avgDiffTracker.Update(executionTimeDiff > WORLD_SLEEP_CONST ? executionTimeDiff : WORLD_SLEEP_CONST);

        // ... some more code here
    }
    // at this point the world process is terminating

    // ... some more code here

这个循环真正做的基本上是:

1) 计算自上次迭代以来经过的时间(毫秒),这将是diff

2) 调用 sWorld->Update( diff ); 函数,它包含所有世界进程逻辑(见下文)并将 diff 传递给它

3) 计算 运行 sWorld->Update( diff ); 花费的时间并更新 devDiffTracker 及其平均值 avgDiffTracker。这些值将由 .server info 命令显示。

世界::更新(uint32 差异)

文件:src/server/game/World/World.cpp

World::Update(uint32 diff) 函数不断地被主世界服务器循环进程调用,并且每次它接收自上次调用以来经过的时间 diff 的输入。

这个函数负责不断更新世界,这是所有魔法发生的地方。

计时器

有一组计时器(在 World.h 中定义,正在 World::Update 函数中更新:

/// Timers for different object refresh rates
enum WorldTimers
{
    WUPDATE_AUCTIONS,
    WUPDATE_WEATHERS,
    WUPDATE_UPTIME,
    WUPDATE_CORPSES,
    WUPDATE_EVENTS,
    WUPDATE_CLEANDB,
    WUPDATE_AUTOBROADCAST,
    WUPDATE_MAILBOXQUEUE,
    WUPDATE_PINGDB,
    WUPDATE_5_SECS,
    WUPDATE_COUNT
};

例如WUPDATE_AUTOBROADCAST负责acore_auth.autobroadcasttable中定义的周期全局消息。

任务

World::Update函数还处理很多定时任务,例如:

/// Handle daily quests reset time
if (m_gameTime > m_NextDailyQuestReset)
    ResetDailyQuests();

调用 Managers 的 Update(diff) 函数

在 AzerothCore 中有单例 类 称为管理器 (Mgr),负责处理游戏的特定部分。例如 BattlegroundMgr 处理战场 (BG)。

那些 类 有自己的 Update(uint32 diff) 函数,它们由 World::Update 调用,将 diff 传递给它们,例如:

sBattlegroundMgr->Update(diff);
sOutdoorPvPMgr->Update(diff);
sBattlefieldMgr->Update(diff);
/// ... there are more!

OnWorldUpdate 挂钩

最后但同样重要的是,它调用 sScriptMgr->OnWorldUpdate(diff);

这是 AzerothCore Module System 的一部分,定义了一个挂钩,第三方模块可以使用该挂钩将自定义逻辑附加到 World::Update 函数。