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。



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