mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-05-02 15:53:51 +00:00
game: fix Classic/TBC SMSG_QUESTGIVER_QUEST_LIST quest title and questCount parsing
Classic 1.12 and TBC 2.4.3 don't include questFlags(u32) + isRepeatable(u8) before each quest title in SMSG_QUESTGIVER_QUEST_LIST. WotLK 3.3.5a added those 5 bytes. The previous code read them speculatively for all expansions and only rewound on empty title, which failed for any non-empty title. Also fix questCount always reading as uint8 (all WoW versions use u8 here). The old u32/u8 heuristic could misread 4 bytes instead of 1, misaligning all subsequent quest item reads.
This commit is contained in:
parent
7270a4e690
commit
967cedba0e
1 changed files with 11 additions and 25 deletions
|
|
@ -14887,21 +14887,16 @@ void GameHandler::handleQuestgiverQuestList(network::Packet& packet) {
|
||||||
}
|
}
|
||||||
(void)header;
|
(void)header;
|
||||||
|
|
||||||
auto readQuestCount = [&](network::Packet& pkt) -> uint32_t {
|
// questCount is uint8 in all WoW versions for SMSG_QUESTGIVER_QUEST_LIST.
|
||||||
size_t rem = pkt.getSize() - pkt.getReadPos();
|
uint32_t questCount = 0;
|
||||||
if (rem >= 4) {
|
if (packet.getSize() - packet.getReadPos() >= 1) {
|
||||||
size_t p = pkt.getReadPos();
|
questCount = packet.readUInt8();
|
||||||
uint32_t c = pkt.readUInt32();
|
}
|
||||||
if (c <= 64) return c;
|
|
||||||
pkt.setReadPos(p);
|
// Classic 1.12 and TBC 2.4.3 don't include questFlags(u32) + isRepeatable(u8)
|
||||||
}
|
// before the quest title. WotLK 3.3.5a added those 5 bytes.
|
||||||
if (rem >= 1) {
|
const bool hasQuestFlagsField = !isClassicLikeExpansion() && !isActiveExpansion("tbc");
|
||||||
return static_cast<uint32_t>(pkt.readUInt8());
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
uint32_t questCount = readQuestCount(packet);
|
|
||||||
data.quests.reserve(questCount);
|
data.quests.reserve(questCount);
|
||||||
for (uint32_t i = 0; i < questCount; ++i) {
|
for (uint32_t i = 0; i < questCount; ++i) {
|
||||||
if (packet.getSize() - packet.getReadPos() < 12) break;
|
if (packet.getSize() - packet.getReadPos() < 12) break;
|
||||||
|
|
@ -14910,23 +14905,14 @@ void GameHandler::handleQuestgiverQuestList(network::Packet& packet) {
|
||||||
q.questIcon = packet.readUInt32();
|
q.questIcon = packet.readUInt32();
|
||||||
q.questLevel = static_cast<int32_t>(packet.readUInt32());
|
q.questLevel = static_cast<int32_t>(packet.readUInt32());
|
||||||
|
|
||||||
// WotLK includes questFlags + isRepeatable; Classic variants may omit.
|
if (hasQuestFlagsField && packet.getSize() - packet.getReadPos() >= 5) {
|
||||||
size_t titlePos = packet.getReadPos();
|
|
||||||
if (packet.getSize() - packet.getReadPos() >= 5) {
|
|
||||||
q.questFlags = packet.readUInt32();
|
q.questFlags = packet.readUInt32();
|
||||||
q.isRepeatable = packet.readUInt8();
|
q.isRepeatable = packet.readUInt8();
|
||||||
q.title = normalizeWowTextTokens(packet.readString());
|
|
||||||
if (q.title.empty()) {
|
|
||||||
packet.setReadPos(titlePos);
|
|
||||||
q.questFlags = 0;
|
|
||||||
q.isRepeatable = 0;
|
|
||||||
q.title = normalizeWowTextTokens(packet.readString());
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
q.questFlags = 0;
|
q.questFlags = 0;
|
||||||
q.isRepeatable = 0;
|
q.isRepeatable = 0;
|
||||||
q.title = normalizeWowTextTokens(packet.readString());
|
|
||||||
}
|
}
|
||||||
|
q.title = normalizeWowTextTokens(packet.readString());
|
||||||
if (q.questId != 0) {
|
if (q.questId != 0) {
|
||||||
data.quests.push_back(std::move(q));
|
data.quests.push_back(std::move(q));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue