Fix quest system for Classic/Turtle: correct packet formats and log stride

- CMSG_QUESTGIVER_QUERY_QUEST: Classic override omits trailing unk1 byte
  (WotLK sends 13 bytes, Classic servers expect 12 — extra byte caused
  server to silently drop the packet, preventing quest details dialog)
- SMSG_QUESTGIVER_QUEST_DETAILS: Classic override skips informUnit GUID
  (WotLK prepends 8-byte informUnit before questId; Vanilla does not)
- Quest log UPDATE_OBJECT stride: use packetParsers_->questLogStride()
  (WotLK=5 fields/slot, Classic=3 fields/slot)
- handleQuestDetails: route through packetParsers_->parseQuestDetails()
- selectGossipQuest: route through packetParsers_->buildQueryQuestPacket()
This commit is contained in:
Kelsi 2026-02-18 04:56:23 -08:00
parent 2dffba63d8
commit dd3149e3c1
3 changed files with 92 additions and 4 deletions

View file

@ -3858,7 +3858,8 @@ void GameHandler::handleUpdateObject(network::Packet& packet) {
const uint16_t ufPlayerLevel = fieldIndex(UF::UNIT_FIELD_LEVEL);
const uint16_t ufCoinage = fieldIndex(UF::PLAYER_FIELD_COINAGE);
const uint16_t ufQuestStart = fieldIndex(UF::PLAYER_QUEST_LOG_START);
const uint16_t ufQuestEnd = ufQuestStart + 25 * 5; // 25 quest slots, stride 5
const uint8_t qStride = packetParsers_ ? packetParsers_->questLogStride() : 5;
const uint16_t ufQuestEnd = ufQuestStart + 25 * qStride; // 25 quest slots
for (const auto& [key, val] : block.fields) {
if (key == ufPlayerXp) { playerXp_ = val; }
else if (key == ufPlayerNextXp) { playerNextLevelXp_ = val; }
@ -3872,8 +3873,8 @@ void GameHandler::handleUpdateObject(network::Packet& packet) {
playerMoneyCopper_ = val;
LOG_INFO("Money set from update fields: ", val, " copper");
}
// Parse quest log fields (stride 5, 25 slots)
else if (key >= ufQuestStart && key < ufQuestEnd && (key - ufQuestStart) % 5 == 0) {
// Parse quest log fields (stride varies by expansion: 5=WotLK, 3=Classic)
else if (key >= ufQuestStart && key < ufQuestEnd && (key - ufQuestStart) % qStride == 0) {
uint32_t questId = val;
if (questId != 0) {
// Check if quest is already in log
@ -8306,7 +8307,9 @@ void GameHandler::selectGossipQuest(uint32_t questId) {
void GameHandler::handleQuestDetails(network::Packet& packet) {
QuestDetailsData data;
if (!QuestDetailsParser::parse(packet, data)) {
bool ok = packetParsers_ ? packetParsers_->parseQuestDetails(packet, data)
: QuestDetailsParser::parse(packet, data);
if (!ok) {
LOG_WARNING("Failed to parse SMSG_QUESTGIVER_QUEST_DETAILS");
return;
}