From 8aa25d9721817fbf543d0091df17249036097bfa Mon Sep 17 00:00:00 2001 From: Ovahlord Date: Sun, 5 Jan 2020 13:59:56 +0100 Subject: [PATCH] Core/Quests: convert SMSG_QUEST_GIVER_QUEST_LIST_MESSAGE to packet class * fixed build * fixed an issue that was preventing players from turning in quests that have collect objectives but are not in quest logs --- .../game/Entities/Creature/GossipDef.cpp | 36 +++++++------------ .../game/Server/Packets/QuestPackets.cpp | 22 ++++++++++++ src/server/game/Server/Packets/QuestPackets.h | 27 ++++++++++++++ src/server/game/Server/Protocol/Opcodes.cpp | 2 +- src/server/game/Server/Protocol/Opcodes.h | 2 +- src/server/game/Server/WorldSession.cpp | 4 +-- 6 files changed, 66 insertions(+), 27 deletions(-) diff --git a/src/server/game/Entities/Creature/GossipDef.cpp b/src/server/game/Entities/Creature/GossipDef.cpp index ddd230d2c58..09e4c237901 100644 --- a/src/server/game/Entities/Creature/GossipDef.cpp +++ b/src/server/game/Entities/Creature/GossipDef.cpp @@ -323,8 +323,8 @@ void QuestMenu::ClearMenu() void PlayerMenu::SendQuestGiverQuestList(QEmote const& eEmote, const std::string& Title, ObjectGuid guid) { - WorldPacket data(SMSG_QUESTGIVER_QUEST_LIST, 100); // guess size - data << uint64(guid); + WorldPackets::Quest::QuestGiverQuestListMessage questList; + questList.QuestGiverGUID = guid; if (QuestGreeting const* questGreeting = sObjectMgr->GetQuestGreeting(guid)) { @@ -335,21 +335,17 @@ void PlayerMenu::SendQuestGiverQuestList(QEmote const& eEmote, const std::string if (QuestGreetingLocale const* questGreetingLocale = sObjectMgr->GetQuestGreetingLocale(MAKE_PAIR32(guid.GetEntry(), guid.GetTypeId()))) ObjectMgr::GetLocaleString(questGreetingLocale->greeting, localeConstant, strGreeting); - data << strGreeting; - data << uint32(questGreeting->greetEmoteDelay); - data << uint32(questGreeting->greetEmoteType); + questList.GreetEmoteDelay = questGreeting->greetEmoteDelay; + questList.GreetEmoteType = questGreeting->greetEmoteType; + questList.Greeting = strGreeting; } else { - data << Title; - data << uint32(eEmote._Delay); // player emote - data << uint32(eEmote._Emote); // NPC emote + questList.GreetEmoteDelay = eEmote._Delay; + questList.GreetEmoteType = eEmote._Emote; + questList.Greeting = Title; } - size_t count_pos = data.wpos(); - data << uint8(0); - uint32 count = 0; - // Store this instead of checking the Singleton every loop iteration bool questLevelInTitle = sWorld->getBoolConfig(CONFIG_UI_QUESTLEVELS_IN_DIALOGS); @@ -361,7 +357,6 @@ void PlayerMenu::SendQuestGiverQuestList(QEmote const& eEmote, const std::string if (Quest const* quest = sObjectMgr->GetQuestTemplate(questID)) { - ++count; std::string title = quest->GetTitle(); LocaleConstant localeConstant = _session->GetSessionDbLocaleIndex(); @@ -372,18 +367,13 @@ void PlayerMenu::SendQuestGiverQuestList(QEmote const& eEmote, const std::string if (questLevelInTitle) AddQuestLevelToTitle(title, quest->GetQuestLevel()); - data << uint32(questID); - data << uint32(questMenuItem.QuestIcon); - data << int32(quest->GetQuestLevel()); - data << uint32(quest->GetFlags()); // 3.3.3 quest flags - data << uint8(quest->IsAutoComplete() && quest->IsRepeatable() && !quest->IsDailyOrWeekly() && !quest->IsMonthly()); // 3.3.3 icon changes - 0: yellow exclapamtion mark, 1: blue question mark - data << title; + bool repeatable = quest->IsAutoComplete() && quest->IsRepeatable() && !quest->IsDailyOrWeekly() && !quest->IsMonthly(); + questList.QuestDataText.emplace_back(questID, questMenuItem.QuestIcon, quest->GetQuestLevel(), quest->GetFlags(), repeatable, title); } } - data.put(count_pos, count); - _session->SendPacket(&data); - TC_LOG_DEBUG("network", "WORLD: Sent SMSG_QUESTGIVER_QUEST_LIST (QuestGiver: %s)", guid.ToString().c_str()); + _session->SendPacket(questList.Write()); + TC_LOG_DEBUG("network", "WORLD: Sent SMSG_QUEST_GIVER_QUEST_LIST_MESSAGE (QuestGiverGUID: %s)", guid.ToString().c_str()); } void PlayerMenu::SendQuestGiverStatus(uint32 questStatus, ObjectGuid npcGUID) const @@ -753,7 +743,7 @@ void PlayerMenu::SendQuestGiverRequestItems(Quest const* quest, ObjectGuid npcGU if (ItemTemplate const* itemTemplate = sObjectMgr->GetItemTemplate(quest->RequiredItemId[i])) displayId = itemTemplate->DisplayInfoID; - if (data.ItemCount[i] != quest->RequiredItemCount[i]) + if (data.ItemCount[i] < quest->RequiredItemCount[i] && !_session->GetPlayer()->HasItemCount(quest->RequiredItemId[i], quest->RequiredItemCount[i])) collectObjectiveComplete = false; packet.Collect.emplace_back(quest->RequiredItemId[i], quest->RequiredItemCount[i], displayId); diff --git a/src/server/game/Server/Packets/QuestPackets.cpp b/src/server/game/Server/Packets/QuestPackets.cpp index d8f7204f501..a25d35c80a2 100644 --- a/src/server/game/Server/Packets/QuestPackets.cpp +++ b/src/server/game/Server/Packets/QuestPackets.cpp @@ -110,3 +110,25 @@ void WorldPackets::Quest::QueryQuestInfo::Read() { _worldPacket >> QuestID; } + +WorldPacket const* WorldPackets::Quest::QuestGiverQuestListMessage::Write() +{ + _worldPacket << QuestGiverGUID; + _worldPacket << Greeting; + _worldPacket << uint32(GreetEmoteDelay); + _worldPacket << uint32(GreetEmoteType); + + _worldPacket << uint8(QuestDataText.size()); + for (GossipText const& gossip : QuestDataText) + { + _worldPacket << uint32(gossip.QuestID); + _worldPacket << uint32(gossip.QuestType); + _worldPacket << int32(gossip.QuestLevel); + _worldPacket << uint32(gossip.QuestFlags); + _worldPacket << uint8(gossip.Repeatable); + _worldPacket << gossip.QuestTitle; + } + + return &_worldPacket; +} + diff --git a/src/server/game/Server/Packets/QuestPackets.h b/src/server/game/Server/Packets/QuestPackets.h index fde59762989..b36085f00e4 100644 --- a/src/server/game/Server/Packets/QuestPackets.h +++ b/src/server/game/Server/Packets/QuestPackets.h @@ -180,6 +180,33 @@ namespace WorldPackets int32 QuestID = 0; }; + + struct GossipText + { + GossipText(uint32 questID, uint32 questType, int32 questLevel, uint32 questFlags, bool repeatable, std::string questTitle) : + QuestID(questID), QuestType(questType), QuestLevel(questLevel), QuestFlags(questFlags), Repeatable(repeatable), + QuestTitle(std::move(questTitle)) { } + uint32 QuestID; + uint32 QuestType; + int32 QuestLevel; + uint32 QuestFlags; + bool Repeatable; + std::string QuestTitle; + }; + + class QuestGiverQuestListMessage final : public ServerPacket + { + public: + QuestGiverQuestListMessage() : ServerPacket(SMSG_QUEST_GIVER_QUEST_LIST_MESSAGE, 100) { } + + WorldPacket const* Write() override; + + ObjectGuid QuestGiverGUID; + uint32 GreetEmoteDelay = 0; + uint32 GreetEmoteType = 0; + std::vector QuestDataText; + std::string Greeting; + }; } } diff --git a/src/server/game/Server/Protocol/Opcodes.cpp b/src/server/game/Server/Protocol/Opcodes.cpp index ae3614bf869..0f1a7759927 100644 --- a/src/server/game/Server/Protocol/Opcodes.cpp +++ b/src/server/game/Server/Protocol/Opcodes.cpp @@ -1138,7 +1138,7 @@ void OpcodeTable::Initialize() DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUESTGIVER_QUEST_DETAILS, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUESTGIVER_QUEST_FAILED, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUESTGIVER_QUEST_INVALID, STATUS_NEVER, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUESTGIVER_QUEST_LIST, STATUS_NEVER, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUEST_GIVER_QUEST_LIST_MESSAGE, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUEST_GIVER_REQUEST_ITEMS, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUESTGIVER_STATUS, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUESTGIVER_STATUS_MULTIPLE, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); diff --git a/src/server/game/Server/Protocol/Opcodes.h b/src/server/game/Server/Protocol/Opcodes.h index ab36e9b5d5f..032171cb90a 100644 --- a/src/server/game/Server/Protocol/Opcodes.h +++ b/src/server/game/Server/Protocol/Opcodes.h @@ -1097,7 +1097,7 @@ enum OpcodeServer SMSG_QUESTGIVER_QUEST_DETAILS = 0x2425, SMSG_QUESTGIVER_QUEST_FAILED = 0x4236, SMSG_QUESTGIVER_QUEST_INVALID = 0x4016, - SMSG_QUESTGIVER_QUEST_LIST = 0x0134, + SMSG_QUEST_GIVER_QUEST_LIST_MESSAGE = 0x0134, SMSG_QUEST_GIVER_REQUEST_ITEMS = 0x6236, SMSG_QUESTGIVER_STATUS = 0x2115, SMSG_QUESTGIVER_STATUS_MULTIPLE = 0x4F25, diff --git a/src/server/game/Server/WorldSession.cpp b/src/server/game/Server/WorldSession.cpp index b7390d32d4c..97f054f6d51 100644 --- a/src/server/game/Server/WorldSession.cpp +++ b/src/server/game/Server/WorldSession.cpp @@ -1364,7 +1364,7 @@ uint32 WorldSession::DosProtection::GetMaxPacketCounterAllowed(uint16 opcode) co case CMSG_DUEL_ACCEPTED: // 0 1 case CMSG_DUEL_CANCELLED: // 0 1 case CMSG_CALENDAR_COMPLAIN: // 0 1 - case CMSG_QUEST_QUERY: // 0 1.5 + case CMSG_QUERY_QUEST_INFO: // 0 1.5 case CMSG_GAMEOBJECT_QUERY: // 0 1.5 case CMSG_CREATURE_QUERY: // 0 1.5 case CMSG_QUEST_GIVER_STATUS_QUERY: // 0 1.5 @@ -1441,7 +1441,7 @@ uint32 WorldSession::DosProtection::GetMaxPacketCounterAllowed(uint16 opcode) co } case CMSG_QUEST_GIVER_ACCEPT_QUEST: // 0 4 - case CMSG_QUESTLOG_REMOVE_QUEST: // 0 4 + case CMSG_QUEST_LOG_REMOVE_QUEST: // 0 4 case CMSG_QUEST_GIVER_CHOOSE_REWARD: // 0 4 case CMSG_CONTACT_LIST: // 0 5 case CMSG_LEARN_PREVIEW_TALENTS: // 0 6