TrinityCore3.3.5.57服務器離線無法登錄bug探究

上文,我按照官網教程摸索着啓動了遊戲之後,發現能夠看到TrinityCore這個服務器,但是顯示爲離線狀態,無法進入,確認自己沒有漏掉操作之後,在網上搜了下,沒有結果,所以只能從代碼入手看了。

既然是server顯示爲離線狀態,我第一感覺是authserver沒問題,worldserver(遊戲服務器)或許有問題,所以直接看worldserver的main函數。很幸運,看到了下面這樣

main函數摘選:

    // Set server offline (not connectable)
    LoginDatabase.DirectPExecute("UPDATE realmlist SET flag = (flag & ~%u) | %u WHERE id = '%d'", REALM_FLAG_OFFLINE, REALM_FLAG_INVALID, realmID);

   // 加載各種配置,不妨礙分析,已屏蔽

    // Set server online (allow connecting now)
    LoginDatabase.DirectPExecute("UPDATE realmlist SET flag = flag & ~%u, population = 0 WHERE id = '%u'", REALM_FLAG_INVALID, realmID);

worldserver啓動時設置自己離線,啓動成功後設置在線,按理說沒問題啊,我猜測是不是flag的值有問題呢?

enum RealmFlags
{
    REALM_FLAG_NONE = 0x00,
    REALM_FLAG_INVALID = 0x01,
    REALM_FLAG_OFFLINE = 0x02,
    REALM_FLAG_SPECIFYBUILD = 0x04,
    REALM_FLAG_UNK1 = 0x08,
    REALM_FLAG_UNK2 = 0x10,
    REALM_FLAG_RECOMMENDED = 0x20,
    REALM_FLAG_NEW = 0x40,
    REALM_FLAG_FULL = 0x80
};

起初數據庫中flag爲0,所以設置offline的操作,相當於設置flag=REALM_FLAG_INVALID(0x01), 設置online的操作相當於設置flag=REALM_FLAG_NONE(0x00),我不是很清楚是否REALM_FLAG_NONE導致了server無法登錄,所以,我修改代碼如下:

    // Set server offline (not connectable)
    LoginDatabase.DirectPExecute("UPDATE realmlist SET flag = %u WHERE id = '%d'", REALM_FLAG_OFFLINE, realmID);

   // 加載各種配置,不妨礙分析,已屏蔽

    // Set server online (allow connecting now)
    LoginDatabase.DirectPExecute("UPDATE realmlist SET flag = %u, population = 0 WHERE id = '%u'",REALM_FLAG_RECOMMENDED, realmID);
注意設置的flag的值,重新編譯啓動服務器後,發現還是不行,沒辦法了,看看是不是authserver的問題。


猜測下流程,客戶端請求進入服務器,authserver推送服務器列表,所以打算找到authserver的接受客戶端鏈接的socket,很幸運,在main中看到下面

 // Start the listening port (acceptor) for auth connections
    int32 port = sConfigMgr->GetIntDefault("RealmServerPort", 3724);
    if (port < 0 || port > 0xFFFF)
    {
        TC_LOG_ERROR("server.authserver", "Specified port out of allowed range (1-65535)");
        StopDB();
        return 1;
    }

    std::string bindIp = sConfigMgr->GetStringDefault("BindIP", "0.0.0.0");

    sAuthSocketMgr.StartNetwork(_ioService, bindIp, port);
由sAuthSocketMgr進而追蹤到AuthSession(代表每一個client與authserver的會話),然後看到了AuthServer::HandleRealmList(),進入看一眼

size_t RealmListSize = 0;
    for (RealmList::RealmMap::const_iterator i = sRealmList->begin(); i != sRealmList->end(); ++i)
    {
        const Realm &realm = i->second;
        // don't work with realms which not compatible with the client
        bool okBuild = ((_expversion & POST_BC_EXP_FLAG) && realm.gamebuild == _build) || ((_expversion & PRE_BC_EXP_FLAG) && !AuthHelper::IsPreBCAcceptedClientBuild(realm.gamebuild));

        // No SQL injection. id of realm is controlled by the database.
        uint32 flag = realm.flag;
        RealmBuildInfo const* buildInfo = AuthHelper::GetBuildInfo(realm.gamebuild);
        if (!okBuild)
        {
            if (!buildInfo)
                continue;

            flag |= REALM_FLAG_OFFLINE | REALM_FLAG_SPECIFYBUILD;   // tell the client what build the realm is for
        }
 //忽略不相關的
}
authserver遍歷每一個worldserver服務器,看看版本是否接受,是的,問題就出在這了,我們的worldserver(realmlist)的gamebuild是12340,客戶端的版本號_build是13930,所以設置了worldserver的離線狀態,現在明白了,修改auth數據庫realmlist表中gamebuild字段爲13930即可。


ok。



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章