mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-03-22 23:30:14 +00:00
Fix quest details parser, ImGui ID conflict, and gossip reopen guard
Quest details parser now reads all 6 choice + 4 reward item slots (matching AzerothCore's fixed-size arrays) with bounds checking at every step. Use loop index for quest ImGui IDs instead of questId to avoid conflicts. Don't reopen gossip window while quest details are showing.
This commit is contained in:
parent
67a3da3bae
commit
a4a39c7f0f
3 changed files with 33 additions and 18 deletions
|
|
@ -3623,6 +3623,7 @@ void GameHandler::handleLootRemoved(network::Packet& packet) {
|
|||
|
||||
void GameHandler::handleGossipMessage(network::Packet& packet) {
|
||||
if (!GossipMessageParser::parse(packet, currentGossip)) return;
|
||||
if (questDetailsOpen) return; // Don't reopen gossip while viewing quest
|
||||
gossipWindowOpen = true;
|
||||
vendorWindowOpen = false; // Close vendor if gossip opens
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1836,38 +1836,51 @@ network::Packet QuestgiverAcceptQuestPacket::build(uint64_t npcGuid, uint32_t qu
|
|||
}
|
||||
|
||||
bool QuestDetailsParser::parse(network::Packet& packet, QuestDetailsData& data) {
|
||||
if (packet.getSize() < 20) return false;
|
||||
if (packet.getSize() < 28) return false;
|
||||
data.npcGuid = packet.readUInt64();
|
||||
/*informUnit*/ packet.readUInt64();
|
||||
data.questId = packet.readUInt32();
|
||||
data.title = packet.readString();
|
||||
data.details = packet.readString();
|
||||
data.objectives = packet.readString();
|
||||
|
||||
if (packet.getReadPos() + 10 > packet.getSize()) {
|
||||
LOG_INFO("Quest details (short): id=", data.questId, " title='", data.title, "'");
|
||||
return true;
|
||||
}
|
||||
|
||||
/*activateAccept*/ packet.readUInt8();
|
||||
/*flags*/ packet.readUInt32();
|
||||
data.suggestedPlayers = packet.readUInt32();
|
||||
/*isFinished*/ packet.readUInt8();
|
||||
|
||||
// Reward choice items
|
||||
uint32_t choiceCount = packet.readUInt32();
|
||||
for (uint32_t i = 0; i < choiceCount && i < 6; i++) {
|
||||
packet.readUInt32(); // itemId
|
||||
packet.readUInt32(); // count
|
||||
packet.readUInt32(); // displayInfo
|
||||
// Reward choice items: server always writes 6 entries (QUEST_REWARD_CHOICES_COUNT)
|
||||
if (packet.getReadPos() + 4 <= packet.getSize()) {
|
||||
/*choiceCount*/ packet.readUInt32();
|
||||
for (int i = 0; i < 6; i++) {
|
||||
if (packet.getReadPos() + 12 > packet.getSize()) break;
|
||||
packet.readUInt32(); // itemId
|
||||
packet.readUInt32(); // count
|
||||
packet.readUInt32(); // displayInfo
|
||||
}
|
||||
}
|
||||
|
||||
// Reward items
|
||||
uint32_t rewardCount = packet.readUInt32();
|
||||
for (uint32_t i = 0; i < rewardCount && i < 4; i++) {
|
||||
packet.readUInt32(); // itemId
|
||||
packet.readUInt32(); // count
|
||||
packet.readUInt32(); // displayInfo
|
||||
// Reward items: server always writes 4 entries (QUEST_REWARDS_COUNT)
|
||||
if (packet.getReadPos() + 4 <= packet.getSize()) {
|
||||
/*rewardCount*/ packet.readUInt32();
|
||||
for (int i = 0; i < 4; i++) {
|
||||
if (packet.getReadPos() + 12 > packet.getSize()) break;
|
||||
packet.readUInt32(); // itemId
|
||||
packet.readUInt32(); // count
|
||||
packet.readUInt32(); // displayInfo
|
||||
}
|
||||
}
|
||||
|
||||
data.rewardMoney = packet.readUInt32();
|
||||
if (packet.getReadPos() < packet.getSize()) {
|
||||
// Money and XP rewards
|
||||
if (packet.getReadPos() + 4 <= packet.getSize())
|
||||
data.rewardMoney = packet.readUInt32();
|
||||
if (packet.getReadPos() + 4 <= packet.getSize())
|
||||
data.rewardXp = packet.readUInt32();
|
||||
}
|
||||
|
||||
LOG_INFO("Quest details: id=", data.questId, " title='", data.title, "'");
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -1610,8 +1610,9 @@ void GameScreen::renderGossipWindow(game::GameHandler& gameHandler) {
|
|||
ImGui::Spacing();
|
||||
ImGui::Separator();
|
||||
ImGui::TextColored(ImVec4(1.0f, 1.0f, 0.3f, 1.0f), "Quests:");
|
||||
for (const auto& quest : gossip.quests) {
|
||||
ImGui::PushID(static_cast<int>(quest.questId));
|
||||
for (size_t qi = 0; qi < gossip.quests.size(); qi++) {
|
||||
const auto& quest = gossip.quests[qi];
|
||||
ImGui::PushID(static_cast<int>(qi));
|
||||
char qlabel[256];
|
||||
snprintf(qlabel, sizeof(qlabel), "[%d] %s", quest.questLevel, quest.title.c_str());
|
||||
ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(1.0f, 1.0f, 0.3f, 1.0f));
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue