From 03d2e1b815d1a0cb8c5ba8e54ce09f2a23caf509 Mon Sep 17 00:00:00 2001 From: AlterEgo Date: Sun, 29 Oct 2023 12:30:57 -0500 Subject: [PATCH] Update SMSG_QUEST_NPC_QUERY_RESPONSE and CMSG_QUEST_NPC_QUERY Signed-off-by: AlterEgo --- src/server/game/Globals/ObjectMgr.h | 16 +++++++- src/server/game/Handlers/QueryHandler.cpp | 42 +++++++++++++++++++++ src/server/game/Server/Protocol/Opcodes.cpp | 4 +- src/server/game/Server/Protocol/Opcodes.h | 4 +- src/server/game/Server/WorldSession.h | 1 + 5 files changed, 62 insertions(+), 5 deletions(-) diff --git a/src/server/game/Globals/ObjectMgr.h b/src/server/game/Globals/ObjectMgr.h index 9af418564ca..806e11ab236 100644 --- a/src/server/game/Globals/ObjectMgr.h +++ b/src/server/game/Globals/ObjectMgr.h @@ -438,8 +438,10 @@ typedef UNORDERED_MAP GossipMenuItemsLocaleContai typedef UNORDERED_MAP PointOfInterestLocaleContainer; typedef UNORDERED_MAP QuestObjectiveLocaleContainer; -typedef std::multimap QuestRelations; +typedef std::multimap QuestRelations; // unit/go -> quest +typedef std::multimap QuestRelationsReverse; // quest -> unit/go typedef std::pair QuestRelationBounds; +typedef std::pair QuestRelationReverseBounds; struct PetLevelInfo { @@ -919,6 +921,11 @@ class ObjectMgr return _goQuestInvolvedRelations.equal_range(go_entry); } + QuestRelationReverseBounds GetGOQuestInvolvedRelationReverseBounds(uint32 questId) + { + return _goQuestInvolvedRelationsReverse.equal_range(questId); + } + QuestRelations* GetCreatureQuestRelationMap() { return &_creatureQuestRelations; @@ -934,6 +941,11 @@ class ObjectMgr return _creatureQuestInvolvedRelations.equal_range(creature_entry); } + QuestRelationReverseBounds GetCreatureQuestInvolvedRelationReverseBounds(uint32 questId) + { + return _creatureQuestInvolvedRelationsReverse.equal_range(questId); + } + void LoadEventScripts(); void LoadSpellScripts(); void LoadWaypointScripts(); @@ -1465,8 +1477,10 @@ class ObjectMgr QuestRelations _goQuestRelations; QuestRelations _goQuestInvolvedRelations; + QuestRelationsReverse _goQuestInvolvedRelationsReverse; QuestRelations _creatureQuestRelations; QuestRelations _creatureQuestInvolvedRelations; + QuestRelationsReverse _creatureQuestInvolvedRelationsReverse; //character reserved names typedef std::set ReservedNamesContainer; diff --git a/src/server/game/Handlers/QueryHandler.cpp b/src/server/game/Handlers/QueryHandler.cpp index b7df0d635fe..419ef9d28e9 100644 --- a/src/server/game/Handlers/QueryHandler.cpp +++ b/src/server/game/Handlers/QueryHandler.cpp @@ -577,6 +577,48 @@ void WorldSession::HandleCorpseMapPositionQuery(WorldPacket& recvData) SendPacket(&data); } +void WorldSession::HandleQuestNPCQuery(WorldPacket& recvData) +{ + std::map> quests; + for (int i = 0; i < 50; ++i) + { + uint32 questId; + recvData >> questId; + + /// @todo verify if we should only send completed quests questgivers + if (sObjectMgr->GetQuestTemplate(questId) && _player->GetQuestStatus(questId) == QUEST_STATUS_COMPLETE) + { + auto creatures = sObjectMgr->GetCreatureQuestInvolvedRelationReverseBounds(questId); + for (auto it = creatures.first; it != creatures.second; ++it) + quests[questId].push_back(it->second); + + auto gos = sObjectMgr->GetGOQuestInvolvedRelationReverseBounds(questId); + for (auto it = gos.first; it != gos.second; ++it) + quests[questId].push_back(it->second | 0x80000000); // GO mask + } + } + + uint32 count; + recvData >> count; + + WorldPacket data(SMSG_QUEST_NPC_QUERY_RESPONSE, 3 + count * 14); + data.WriteBits(quests.size(), 21); + + for (auto it = quests.begin(); it != quests.end(); ++it) + data.WriteBits(it->second.size(), 22); + + data.FlushBits(); + + for (auto it = quests.begin(); it != quests.end(); ++it) + { + data << uint32(it->first); + for (const auto& entry : it->second) + data << uint32(entry); + } + + SendPacket(&data); +} + void WorldSession::HandleQuestPOIQuery(WorldPacket& recvData) { uint32 count = recvData.ReadBits(22); diff --git a/src/server/game/Server/Protocol/Opcodes.cpp b/src/server/game/Server/Protocol/Opcodes.cpp index 4ffa6f1d33e..b2eb8ad9256 100644 --- a/src/server/game/Server/Protocol/Opcodes.cpp +++ b/src/server/game/Server/Protocol/Opcodes.cpp @@ -332,6 +332,7 @@ void OpcodeTable::InitializeClientTable() DEFINE_OPCODE_HANDLER(CMSG_QUEST_GIVER_STATUS_QUERY, 0x036A, STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleQuestgiverStatusQueryOpcode ); // 5.4.8 18414 DEFINE_OPCODE_HANDLER(CMSG_QUESTLOG_REMOVE_QUEST, 0x0779, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleQuestLogRemoveQuest ); // 5.4.8 18414 DEFINE_OPCODE_HANDLER(CMSG_QUEST_CONFIRM_ACCEPT, 0x124B, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleQuestConfirmAccept ); // 5.4.8 18414 + DEFINE_OPCODE_HANDLER(CMSG_QUEST_NPC_QUERY, 0x1DAE, STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleQuestNPCQuery ); // 5.4.8 18414 DEFINE_OPCODE_HANDLER(CMSG_QUEST_POI_QUERY, 0x10C2, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleQuestPOIQuery ); // 5.4.8 18414 DEFINE_OPCODE_HANDLER(CMSG_QUEST_QUERY, 0x02D5, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleQuestQueryOpcode ); // 5.4.8 18414 DEFINE_OPCODE_HANDLER(CMSG_RAID_READY_CHECK, 0x0817, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleRaidReadyCheckOpcode ); // 5.4.8 18414 @@ -583,7 +584,6 @@ void OpcodeTable::InitializeClientTable() DEFINE_OPCODE_HANDLER(CMSG_QUERY_GUILD_MEMBERS_FOR_RECIPE, 0x0000, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL); DEFINE_OPCODE_HANDLER(CMSG_QUERY_GUILD_MEMBER_RECIPES, 0x0000, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL); DEFINE_OPCODE_HANDLER(CMSG_QUERY_GUILD_RECIPES, 0x0000, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL); - DEFINE_OPCODE_HANDLER(CMSG_QUEST_NPC_QUERY, 0x1DAE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL); DEFINE_OPCODE_HANDLER(CMSG_REDIRECTION_AUTH_PROOF, 0x0000, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL); DEFINE_OPCODE_HANDLER(CMSG_REQUEST_INSPECT_RATED_BG_STATS, 0x0882, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL); DEFINE_OPCODE_HANDLER(CMSG_REQUEST_RESEARCH_HISTORY, 0x15E2, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL); @@ -962,6 +962,7 @@ void OpcodeTable::InitializeServerTable() DEFINE_OPCODE_HANDLER(SMSG_QUEST_POI_QUERY_RESPONSE, 0x067F, STATUS_NEVER ); // 5.4.8 18414 DEFINE_OPCODE_HANDLER(SMSG_QUEST_PUSH_RESULT, 0x074D, STATUS_NEVER ); // 5.4.8 18414 DEFINE_OPCODE_HANDLER(SMSG_QUEST_QUERY_RESPONSE, 0x0276, STATUS_NEVER ); // 5.4.8 18414 + DEFINE_OPCODE_HANDLER(SMSG_QUEST_NPC_QUERY_RESPONSE, 0x036D, STATUS_NEVER ); // 5.4.8 18414 DEFINE_OPCODE_HANDLER(SMSG_RAID_INSTANCE_INFO, 0x16BF, STATUS_NEVER ); // 5.4.8 18414 DEFINE_OPCODE_HANDLER(SMSG_RAID_READY_CHECK, 0x1C8E, STATUS_NEVER ); // 5.4.8 18414 DEFINE_OPCODE_HANDLER(SMSG_RAID_READY_CHECK_COMPLETED, 0x15C2, STATUS_NEVER ); // 5.4.8 18414 @@ -1312,7 +1313,6 @@ void OpcodeTable::InitializeServerTable() DEFINE_OPCODE_HANDLER(SMSG_PLAY_TIME_WARNING, 0x062A, STATUS_UNHANDLED); // NYI DEFINE_OPCODE_HANDLER(SMSG_QUESTUPDATE_FAILED, 0x07DD, STATUS_UNHANDLED); // NYI DEFINE_OPCODE_HANDLER(SMSG_QUEST_FORCE_REMOVE, 0x07C5, STATUS_UNHANDLED); // NYI - DEFINE_OPCODE_HANDLER(SMSG_QUEST_NPC_QUERY_RESPONSE, 0x036D, STATUS_UNHANDLED); // NYI DEFINE_OPCODE_HANDLER(SMSG_RAID_MARKERS_CHANGED, 0x008A, STATUS_UNHANDLED); // NYI DEFINE_OPCODE_HANDLER(SMSG_RAID_READY_CHECK_THROTTLED_ERROR, 0x0000, STATUS_UNHANDLED); // NYI DEFINE_OPCODE_HANDLER(SMSG_RAID_SUMMON_FAILED, 0x108A, STATUS_UNHANDLED); // NYI diff --git a/src/server/game/Server/Protocol/Opcodes.h b/src/server/game/Server/Protocol/Opcodes.h index 51d190a5c96..8dfd27c7c96 100644 --- a/src/server/game/Server/Protocol/Opcodes.h +++ b/src/server/game/Server/Protocol/Opcodes.h @@ -408,6 +408,7 @@ enum Opcodes CMSG_QUESTLOG_REMOVE_QUEST, CMSG_QUESTLOG_SWAP_QUEST, CMSG_QUEST_CONFIRM_ACCEPT, + CMSG_QUEST_NPC_QUERY, CMSG_QUEST_POI_QUERY, CMSG_QUEST_PUSH_RESULT, CMSG_QUEST_QUERY, @@ -992,6 +993,7 @@ enum Opcodes SMSG_QUEST_POI_QUERY_RESPONSE, SMSG_QUEST_PUSH_RESULT, SMSG_QUEST_QUERY_RESPONSE, + SMSG_QUEST_NPC_QUERY_RESPONSE, SMSG_RAID_GROUP_ONLY, SMSG_RAID_INSTANCE_INFO, SMSG_RAID_INSTANCE_MESSAGE, @@ -1193,7 +1195,6 @@ enum Opcodes CMSG_QUERY_GUILD_MEMBERS_FOR_RECIPE, CMSG_QUERY_GUILD_MEMBER_RECIPES, CMSG_QUERY_GUILD_RECIPES, - CMSG_QUEST_NPC_QUERY, CMSG_REDIRECTION_AUTH_PROOF, CMSG_REQUEST_INSPECT_RATED_BG_STATS, CMSG_REQUEST_RESEARCH_HISTORY, @@ -1374,7 +1375,6 @@ enum Opcodes SMSG_PLAY_TIME_WARNING, SMSG_QUESTUPDATE_FAILED, SMSG_QUEST_FORCE_REMOVE, - SMSG_QUEST_NPC_QUERY_RESPONSE, SMSG_RAID_MARKERS_CHANGED, SMSG_RAID_READY_CHECK_THROTTLED_ERROR, SMSG_RAID_SUMMON_FAILED, diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h index 7fb239a7aed..c223b6c1696 100644 --- a/src/server/game/Server/WorldSession.h +++ b/src/server/game/Server/WorldSession.h @@ -1040,6 +1040,7 @@ class WorldSession void HandleEquipmentSetUse(WorldPacket& recvData); void HandleWorldStateUITimerUpdate(WorldPacket& recvData); void HandleReadyForAccountDataTimes(WorldPacket& recvData); + void HandleQuestNPCQuery(WorldPacket& recvData); void HandleQueryQuestsCompleted(WorldPacket& recvData); void HandleQuestPOIQuery(WorldPacket& recvData); void HandleEjectPassenger(WorldPacket& data);