Files
felwell-core/src/server/game/Handlers/HotfixHandler.cpp
T
SylvaniaCore deploy d10873b2b2 Ecran de chargement fige : le serveur ne repondait pas aux tables DB2 inconnues
Preuve dans Server.log, exactement une fois par tentative de connexion
bloquee :
  CMSG_DB_QUERY_BULK: [Daemon] requested unsupported unknown hotfix type:
  3386291891

HandleDBQueryBulk se contentait de journaliser puis de RETURN sans envoyer
la moindre reponse. Le client, qui attend une reponse par enregistrement
demande, restait bloque indefiniment a lecran de chargement.

Corrige en emettant une reponse negative (Allow a false) pour chaque
enregistrement demande, comme le fait deja la branche enregistrement
introuvable juste en dessous.

Portee generale : nimporte quel client reclamant une table que ce core ne
connait pas restait bloque, quelle que soit la carte. La table en cause ici
etait 0xC9D6B6B3, absente des metadonnees du core.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-21 22:56:32 +02:00

104 lines
4.0 KiB
C++

/*
* This file is part of the DestinyCore Project. See AUTHORS file for Copyright information
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "WorldSession.h"
#include "Containers.h"
#include "DB2Stores.h"
#include "HotfixPackets.h"
#include "Log.h"
#include "ObjectDefines.h"
#include "World.h"
void WorldSession::HandleDBQueryBulk(WorldPackets::Hotfix::DBQueryBulk& dbQuery)
{
DB2StorageBase const* store = sDB2Manager.GetStorage(dbQuery.TableHash);
if (!store)
{
TC_LOG_ERROR("network", "CMSG_DB_QUERY_BULK: %s requested unsupported unknown hotfix type: %u", GetPlayerInfo().c_str(), dbQuery.TableHash);
// Repondre malgre tout, une reponse negative par enregistrement demande.
// Sans cela le serveur ne renvoyait RIEN et le client attendait
// indefiniment : ecran de chargement fige, joueur incapable dentrer
// dans le monde. Constate le 21/08/2026 sur la carte 1468 (Caveau des
// Gardiennes) : le client reclamait la table 0xC9D6B6B3, que ce core ne
// connait pas, et lerreur apparaissait exactement une fois par
// tentative de connexion bloquee.
for (WorldPackets::Hotfix::DBQueryBulk::DBQueryRecord const& record : dbQuery.Queries)
{
WorldPackets::Hotfix::DBReply dbReply;
dbReply.TableHash = dbQuery.TableHash;
dbReply.RecordID = record.RecordID;
dbReply.Timestamp = time(NULL);
SendPacket(dbReply.Write());
}
return;
}
for (WorldPackets::Hotfix::DBQueryBulk::DBQueryRecord const& record : dbQuery.Queries)
{
WorldPackets::Hotfix::DBReply dbReply;
dbReply.TableHash = dbQuery.TableHash;
dbReply.RecordID = record.RecordID;
if (store->HasRecord(record.RecordID))
{
dbReply.Allow = true;
dbReply.Timestamp = sWorld->GetGameTime();
store->WriteRecord(record.RecordID, GetSessionDbcLocale(), dbReply.Data);
}
else
{
TC_LOG_TRACE("network", "CMSG_DB_QUERY_BULK: %s requested non-existing entry %u in datastore: %u", GetPlayerInfo().c_str(), record.RecordID, dbQuery.TableHash);
dbReply.Timestamp = time(NULL);
}
SendPacket(dbReply.Write());
}
}
void WorldSession::SendAvailableHotfixes(int32 version)
{
SendPacket(WorldPackets::Hotfix::AvailableHotfixes(version, sDB2Manager.GetHotfixData()).Write());
}
void WorldSession::HandleHotfixRequest(WorldPackets::Hotfix::HotfixRequest& hotfixQuery)
{
std::map<uint64, int32> const& hotfixes = sDB2Manager.GetHotfixData();
WorldPackets::Hotfix::HotfixResponse hotfixQueryResponse;
hotfixQueryResponse.Hotfixes.reserve(hotfixQuery.Hotfixes.size());
for (uint64 hotfixId : hotfixQuery.Hotfixes)
{
if (int32 const* hotfix = Trinity::Containers::MapGetValuePtr(hotfixes, hotfixId))
{
DB2StorageBase const* storage = sDB2Manager.GetStorage(PAIR64_HIPART(hotfixId));
WorldPackets::Hotfix::HotfixResponse::HotfixData hotfixData;
hotfixData.ID = hotfixId;
hotfixData.RecordID = *hotfix;
if (storage->HasRecord(hotfixData.RecordID))
{
hotfixData.Data.emplace();
storage->WriteRecord(hotfixData.RecordID, GetSessionDbcLocale(), *hotfixData.Data);
}
hotfixQueryResponse.Hotfixes.emplace_back(std::move(hotfixData));
}
}
SendPacket(hotfixQueryResponse.Write());
}