mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-05-03 08:03:50 +00:00
Fix quest required item display and add NPC spawn diagnostics
- Fix SMSG_QUESTGIVER_REQUEST_ITEMS: read emoteDelay(u32)+emoteId(u32)+autoFinish(u8) instead of 5 uint32s — the 11-byte over-read corrupted requiredMoney, itemCount, and all item data (itemId/count/displayInfoId) - Fix garbled CSV fallback in asset_manager: return nullptr instead of silently returning garbled DBC data when binary fallback is unavailable - Add NPC spawn diagnostics: log when UNIT blocks have displayId=0 (wrong field index) and when spawn callback fires with displayId + position - Improve getModelPathForDisplayId failure logging: distinguish displayDataMap_ miss vs modelIdToPath_ miss, and include map sizes for context
This commit is contained in:
parent
30efc59fff
commit
eebc0007a6
4 changed files with 26 additions and 26 deletions
|
|
@ -2950,11 +2950,18 @@ std::string Application::getModelPathForDisplayId(uint32_t displayId) const {
|
||||||
}
|
}
|
||||||
if (displayId == 30412) return "Creature\\Gryphon\\Gryphon.m2";
|
if (displayId == 30412) return "Creature\\Gryphon\\Gryphon.m2";
|
||||||
if (displayId == 30413) return "Creature\\Wyvern\\Wyvern.m2";
|
if (displayId == 30413) return "Creature\\Wyvern\\Wyvern.m2";
|
||||||
|
LOG_WARNING("No display data for displayId ", displayId,
|
||||||
|
" (displayDataMap_ has ", displayDataMap_.size(), " entries)");
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
auto itPath = modelIdToPath_.find(itData->second.modelId);
|
auto itPath = modelIdToPath_.find(itData->second.modelId);
|
||||||
if (itPath == modelIdToPath_.end()) return "";
|
if (itPath == modelIdToPath_.end()) {
|
||||||
|
LOG_WARNING("No model path for modelId ", itData->second.modelId,
|
||||||
|
" from displayId ", displayId,
|
||||||
|
" (modelIdToPath_ has ", modelIdToPath_.size(), " entries)");
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
return itPath->second;
|
return itPath->second;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3436,6 +3436,10 @@ void GameHandler::handleUpdateObject(network::Packet& packet) {
|
||||||
unit->setHostile(isHostileFaction(unit->getFactionTemplate()));
|
unit->setHostile(isHostileFaction(unit->getFactionTemplate()));
|
||||||
}
|
}
|
||||||
// Trigger creature spawn callback for units/players with displayId
|
// Trigger creature spawn callback for units/players with displayId
|
||||||
|
if (block.objectType == ObjectType::UNIT && unit->getDisplayId() == 0) {
|
||||||
|
LOG_INFO("[Spawn] UNIT guid=0x", std::hex, block.guid, std::dec,
|
||||||
|
" has displayId=0 — no spawn (entry=", unit->getEntry(), ")");
|
||||||
|
}
|
||||||
if ((block.objectType == ObjectType::UNIT || block.objectType == ObjectType::PLAYER) && unit->getDisplayId() != 0) {
|
if ((block.objectType == ObjectType::UNIT || block.objectType == ObjectType::PLAYER) && unit->getDisplayId() != 0) {
|
||||||
if (block.objectType == ObjectType::PLAYER && block.guid == playerGuid) {
|
if (block.objectType == ObjectType::PLAYER && block.guid == playerGuid) {
|
||||||
// Skip local player — spawned separately via spawnPlayerCharacter()
|
// Skip local player — spawned separately via spawnPlayerCharacter()
|
||||||
|
|
@ -3451,6 +3455,9 @@ void GameHandler::handleUpdateObject(network::Packet& packet) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (creatureSpawnCallback_) {
|
} else if (creatureSpawnCallback_) {
|
||||||
|
LOG_INFO("[Spawn] UNIT guid=0x", std::hex, block.guid, std::dec,
|
||||||
|
" displayId=", unit->getDisplayId(), " at (",
|
||||||
|
unit->getX(), ",", unit->getY(), ",", unit->getZ(), ")");
|
||||||
creatureSpawnCallback_(block.guid, unit->getDisplayId(),
|
creatureSpawnCallback_(block.guid, unit->getDisplayId(),
|
||||||
unit->getX(), unit->getY(), unit->getZ(), unit->getOrientation());
|
unit->getX(), unit->getY(), unit->getZ(), unit->getOrientation());
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2931,50 +2931,35 @@ bool QuestRequestItemsParser::parse(network::Packet& packet, QuestRequestItemsDa
|
||||||
data.title = packet.readString();
|
data.title = packet.readString();
|
||||||
data.completionText = packet.readString();
|
data.completionText = packet.readString();
|
||||||
|
|
||||||
LOG_INFO("QRI raw: packetSize=", packet.getSize(),
|
if (packet.getReadPos() + 9 > packet.getSize()) {
|
||||||
" posAfterStrings=", packet.getReadPos(),
|
|
||||||
" remaining=", packet.getSize() - packet.getReadPos());
|
|
||||||
|
|
||||||
if (packet.getReadPos() + 20 > packet.getSize()) {
|
|
||||||
LOG_INFO("Quest request items (short): id=", data.questId, " title='", data.title, "'");
|
LOG_INFO("Quest request items (short): id=", data.questId, " title='", data.title, "'");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Log each skipped field so we can verify the offset count
|
// emoteDelay (uint32) + emoteId (uint32) + autoFinish (uint8) = 9 bytes
|
||||||
uint32_t f1 = packet.readUInt32();
|
// (same format in vanilla 1.12 and WotLK 3.3.5a)
|
||||||
uint32_t f2 = packet.readUInt32();
|
/*uint32_t emoteDelay =*/ packet.readUInt32();
|
||||||
uint32_t f3 = packet.readUInt32();
|
/*uint32_t emoteId =*/ packet.readUInt32();
|
||||||
uint32_t f4 = packet.readUInt32();
|
/*uint8_t autoFinish =*/ packet.readUInt8();
|
||||||
uint32_t f5 = packet.readUInt32();
|
|
||||||
LOG_INFO("QRI fields: f1=", f1, " f2=", f2, " f3=", f3, " f4=", f4, " f5=", f5,
|
|
||||||
" (emoteDelay/emote/autoClose/flags/suggestedPlayers)");
|
|
||||||
|
|
||||||
if (packet.getReadPos() + 4 > packet.getSize()) return true;
|
if (packet.getReadPos() + 4 > packet.getSize()) return true;
|
||||||
data.requiredMoney = packet.readUInt32();
|
data.requiredMoney = packet.readUInt32();
|
||||||
LOG_INFO("QRI requiredMoney=", data.requiredMoney);
|
|
||||||
|
|
||||||
if (packet.getReadPos() + 4 > packet.getSize()) return true;
|
if (packet.getReadPos() + 4 > packet.getSize()) return true;
|
||||||
uint32_t requiredItemCount = packet.readUInt32();
|
uint32_t requiredItemCount = packet.readUInt32();
|
||||||
LOG_INFO("QRI requiredItemCount=", requiredItemCount,
|
|
||||||
" posBeforeItems=", packet.getReadPos());
|
|
||||||
|
|
||||||
for (uint32_t i = 0; i < requiredItemCount && requiredItemCount < 20; ++i) {
|
for (uint32_t i = 0; i < requiredItemCount && requiredItemCount < 20; ++i) {
|
||||||
if (packet.getReadPos() + 12 > packet.getSize()) break;
|
if (packet.getReadPos() + 12 > packet.getSize()) break;
|
||||||
uint32_t raw0 = packet.readUInt32();
|
|
||||||
uint32_t raw1 = packet.readUInt32();
|
|
||||||
uint32_t raw2 = packet.readUInt32();
|
|
||||||
LOG_INFO("QRI item[", i, "]: raw0=", raw0, " raw1=", raw1, " raw2=", raw2);
|
|
||||||
QuestRewardItem item;
|
QuestRewardItem item;
|
||||||
item.itemId = raw0;
|
item.itemId = packet.readUInt32();
|
||||||
item.count = raw1;
|
item.count = packet.readUInt32();
|
||||||
item.displayInfoId = raw2;
|
item.displayInfoId = packet.readUInt32();
|
||||||
if (item.itemId > 0)
|
if (item.itemId > 0)
|
||||||
data.requiredItems.push_back(item);
|
data.requiredItems.push_back(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (packet.getReadPos() + 4 > packet.getSize()) return true;
|
if (packet.getReadPos() + 4 > packet.getSize()) return true;
|
||||||
data.completableFlags = packet.readUInt32();
|
data.completableFlags = packet.readUInt32();
|
||||||
LOG_INFO("QRI completableFlags=", data.completableFlags);
|
|
||||||
|
|
||||||
LOG_INFO("Quest request items: id=", data.questId, " title='", data.title,
|
LOG_INFO("Quest request items: id=", data.questId, " title='", data.title,
|
||||||
"' items=", data.requiredItems.size(), " completable=", data.isCompletable());
|
"' items=", data.requiredItems.size(), " completable=", data.isCompletable());
|
||||||
|
|
|
||||||
|
|
@ -300,7 +300,8 @@ std::shared_ptr<DBCFile> AssetManager::loadDBC(const std::string& name) {
|
||||||
}
|
}
|
||||||
LOG_INFO("Binary DBC fallback succeeded: ", name);
|
LOG_INFO("Binary DBC fallback succeeded: ", name);
|
||||||
} else {
|
} else {
|
||||||
LOG_WARNING("No binary DBC fallback available for: ", name);
|
LOG_ERROR("No binary DBC fallback available for: ", name, " — discarding garbled CSV");
|
||||||
|
return nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue