From a623dd23831b4d9be78d3070c40be4b3eec1b2a5 Mon Sep 17 00:00:00 2001 From: Benjamin Jackson <38561765+heyitsbench@users.noreply.github.com> Date: Sat, 13 Jun 2026 15:29:45 -0400 Subject: [PATCH] refactor(Core/Packets): Rewrite various quest packets to modern class. (#22835) Co-authored-by: sudlud Co-authored-by: Claude Opus 4.8 (1M context) --- src/server/game/Entities/Player/Player.h | 4 +- .../game/Entities/Player/PlayerQuest.cpp | 141 ++++++------ src/server/game/Handlers/QuestHandler.cpp | 66 ++---- src/server/game/Server/Packets/AllPackets.h | 1 + .../game/Server/Packets/QuestPackets.cpp | 126 +++++++++++ src/server/game/Server/Packets/QuestPackets.h | 214 ++++++++++++++++++ src/server/game/Server/WorldSession.h | 22 +- src/server/scripts/World/player_scripts.cpp | 13 +- 8 files changed, 458 insertions(+), 129 deletions(-) create mode 100644 src/server/game/Server/Packets/QuestPackets.cpp create mode 100644 src/server/game/Server/Packets/QuestPackets.h diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index 43482d4ed2..a8e744a1ba 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -1559,9 +1559,9 @@ public: void SendQuestReward(Quest const* quest, uint32 XP); void SendQuestFailed(uint32 questId, InventoryResult reason = EQUIP_ERR_OK); void SendQuestTimerFailed(uint32 quest_id); - void SendCanTakeQuestResponse(uint32 msg) const; + void SendCanTakeQuestResponse(QuestFailedReason msg) const; void SendQuestConfirmAccept(Quest const* quest, Player* pReceiver); - void SendPushToPartyResponse(Player const* player, uint8 msg) const; + void SendPushToPartyResponse(Player const* player, QuestShareMessages msg) const; void SendQuestUpdateAddItem(Quest const* quest, uint32 item_idx, uint16 count); void SendQuestUpdateAddCreatureOrGo(Quest const* quest, ObjectGuid guid, uint32 creatureOrGO_idx, uint16 old_count, uint16 add_count); void SendQuestUpdateAddPlayer(Quest const* quest, uint16 old_count, uint16 add_count); diff --git a/src/server/game/Entities/Player/PlayerQuest.cpp b/src/server/game/Entities/Player/PlayerQuest.cpp index 94ac419b46..57735685e4 100644 --- a/src/server/game/Entities/Player/PlayerQuest.cpp +++ b/src/server/game/Entities/Player/PlayerQuest.cpp @@ -26,6 +26,7 @@ #include "MapMgr.h" #include "Player.h" #include "PoolMgr.h" +#include "QuestPackets.h" #include "ReputationMgr.h" #include "ScriptMgr.h" #include "SpellAuraEffects.h" @@ -991,8 +992,7 @@ bool Player::SatisfyQuestLog(bool msg) if (msg) { - WorldPacket data(SMSG_QUESTLOG_FULL, 0); - SendDirectMessage(&data); + SendDirectMessage(WorldPackets::Quest::QuestLogFull().Write()); LOG_DEBUG("network", "WORLD: Sent SMSG_QUESTLOG_FULL"); } return false; @@ -2381,13 +2381,13 @@ bool Player::HasQuestForItem(uint32 itemid, uint32 excludeQuestId /* 0 */, bool void Player::SendQuestComplete(uint32 quest_id) { - if (quest_id) - { - WorldPacket data(SMSG_QUESTUPDATE_COMPLETE, 4); - data << uint32(quest_id); - SendDirectMessage(&data); - LOG_DEBUG("network", "WORLD: Sent SMSG_QUESTUPDATE_COMPLETE quest = {}", quest_id); - } + if (!quest_id) + return; + + WorldPackets::Quest::QuestUpdateComplete questUpdateComplete; + questUpdateComplete.QuestId = quest_id; + SendDirectMessage(questUpdateComplete.Write()); + LOG_DEBUG("network", "WORLD: Sent SMSG_QUESTUPDATE_COMPLETE quest = {}", quest_id); } void Player::SendQuestReward(Quest const* quest, uint32 XP) @@ -2395,54 +2395,50 @@ void Player::SendQuestReward(Quest const* quest, uint32 XP) uint32 questid = quest->GetQuestId(); LOG_DEBUG("network", "WORLD: Sent SMSG_QUESTGIVER_QUEST_COMPLETE quest = {}", questid); sGameEventMgr->HandleQuestComplete(questid); - WorldPacket data(SMSG_QUESTGIVER_QUEST_COMPLETE, (4 + 4 + 4 + 4 + 4)); - data << uint32(questid); + WorldPackets::Quest::QuestGiverQuestComplete questGiverQuestComplete; + questGiverQuestComplete.QuestId = questid; + uint32 rewardMoney = quest->GetRewOrReqMoney(GetLevel()); if (!IsMaxLevel()) - { - data << uint32(XP); - data << uint32(quest->GetRewOrReqMoney(GetLevel())); - } + questGiverQuestComplete.Experience = XP; else - { - data << uint32(0); - data << uint32(quest->GetRewOrReqMoney(GetLevel()) + quest->GetRewMoneyMaxLevel()); - } + rewardMoney += quest->GetRewMoneyMaxLevel(); - data << uint32(10 * quest->CalculateHonorGain(GetQuestLevel(quest))); - data << uint32(quest->GetBonusTalents()); // bonus talents - data << uint32(quest->GetRewArenaPoints()); - SendDirectMessage(&data); + questGiverQuestComplete.RewardMoney = rewardMoney; + questGiverQuestComplete.RewardHonor = 10 * quest->CalculateHonorGain(GetQuestLevel(quest)); + questGiverQuestComplete.RewardTalents = quest->GetBonusTalents(); + questGiverQuestComplete.RewardArena = quest->GetRewArenaPoints(); + SendDirectMessage(questGiverQuestComplete.Write()); } void Player::SendQuestFailed(uint32 questId, InventoryResult reason) { - if (questId) - { - WorldPacket data(SMSG_QUESTGIVER_QUEST_FAILED, 4 + 4); - data << uint32(questId); - data << uint32(reason); // failed reason (valid reasons: 4, 16, 50, 17, 74, other values show default message) - SendDirectMessage(&data); - LOG_DEBUG("network", "WORLD: Sent SMSG_QUESTGIVER_QUEST_FAILED"); - } + if (!questId) + return; + + WorldPackets::Quest::QuestGiverQuestFailed questGiverQuestFailed; + questGiverQuestFailed.QuestId = questId; + questGiverQuestFailed.FailureReason = reason; // failed reason (valid reasons: 4, 16, 50, 17, 74, other values show default message) + SendDirectMessage(questGiverQuestFailed.Write()); + LOG_DEBUG("network", "WORLD: Sent SMSG_QUESTGIVER_QUEST_FAILED"); } void Player::SendQuestTimerFailed(uint32 quest_id) { - if (quest_id) - { - WorldPacket data(SMSG_QUESTUPDATE_FAILEDTIMER, 4); - data << uint32(quest_id); - SendDirectMessage(&data); - LOG_DEBUG("network", "WORLD: Sent SMSG_QUESTUPDATE_FAILEDTIMER"); - } + if (!quest_id) + return; + + WorldPackets::Quest::QuestUpdateFailedTimer questUpdateFailedTimer; + questUpdateFailedTimer.QuestId = quest_id; + SendDirectMessage(questUpdateFailedTimer.Write()); + LOG_DEBUG("network", "WORLD: Sent SMSG_QUESTUPDATE_FAILEDTIMER"); } -void Player::SendCanTakeQuestResponse(uint32 msg) const +void Player::SendCanTakeQuestResponse(QuestFailedReason msg) const { - WorldPacket data(SMSG_QUESTGIVER_QUEST_INVALID, 4); - data << uint32(msg); - SendDirectMessage(&data); + WorldPackets::Quest::QuestGiverQuestInvalid questGiverQuestInvalid; + questGiverQuestInvalid.FailureReason = msg; + SendDirectMessage(questGiverQuestInvalid.Write()); LOG_DEBUG("network", "WORLD: Sent SMSG_QUESTGIVER_QUEST_INVALID"); } @@ -2458,35 +2454,36 @@ void Player::SendQuestConfirmAccept(const Quest* quest, Player* pReceiver) if (const QuestLocale* pLocale = sObjectMgr->GetQuestLocale(quest->GetQuestId())) ObjectMgr::GetLocaleString(pLocale->Title, loc_idx, strTitle); - WorldPacket data(SMSG_QUEST_CONFIRM_ACCEPT, (4 + quest->GetTitle().size() + 8)); - data << uint32(quest->GetQuestId()); - data << quest->GetTitle(); - data << GetGUID(); - pReceiver->SendDirectMessage(&data); + WorldPackets::Quest::QuestConfirmAccept questConfirmAccept; + questConfirmAccept.QuestId = quest->GetQuestId(); + questConfirmAccept.QuestTitle = quest->GetTitle(); + questConfirmAccept.PlayerGuid = GetGUID(); + pReceiver->SendDirectMessage(questConfirmAccept.Write()); LOG_DEBUG("network", "WORLD: Sent SMSG_QUEST_CONFIRM_ACCEPT"); } } -void Player::SendPushToPartyResponse(Player const* player, uint8 msg) const +void Player::SendPushToPartyResponse(Player const* player, QuestShareMessages msg) const { - if (player) - { - WorldPacket data(MSG_QUEST_PUSH_RESULT, (8 + 1)); - data << player->GetGUID(); - data << uint8(msg); // valid values: 0-8 - SendDirectMessage(&data); - LOG_DEBUG("network", "WORLD: Sent MSG_QUEST_PUSH_RESULT"); - } + if (!player) + return; + + WorldPackets::Quest::QuestPushResult questPushResult; + questPushResult.PlayerGuid = player->GetGUID(); + questPushResult.QuestShareMessage = msg; + SendDirectMessage(questPushResult.Write()); + LOG_DEBUG("network", "WORLD: Sent MSG_QUEST_PUSH_RESULT"); } void Player::SendQuestUpdateAddItem(Quest const* /*quest*/, uint32 /*item_idx*/, uint16 /*count*/) { - WorldPacket data(SMSG_QUESTUPDATE_ADD_ITEM, 0); + // Packet is intentionally sent empty; the optional payload (item id and + // count) is not required by the 3.3.5 client: + //questUpdateAddItem.ItemId = quest->RequiredItemId[item_idx]; + //questUpdateAddItem.Count = count; + SendDirectMessage(WorldPackets::Quest::QuestUpdateAddItem().Write()); LOG_DEBUG("network", "WORLD: Sent SMSG_QUESTUPDATE_ADD_ITEM"); - //data << quest->RequiredItemId[item_idx]; - //data << count; - SendDirectMessage(&data); } void Player::SendQuestUpdateAddCreatureOrGo(Quest const* quest, ObjectGuid guid, uint32 creatureOrGO_idx, uint16 old_count, uint16 add_count) @@ -2498,14 +2495,14 @@ void Player::SendQuestUpdateAddCreatureOrGo(Quest const* quest, ObjectGuid guid, // client expected gameobject template id in form (id|0x80000000) entry = (-entry) | 0x80000000; - WorldPacket data(SMSG_QUESTUPDATE_ADD_KILL, (4 * 4 + 8)); + WorldPackets::Quest::QuestUpdateAddKill questUpdateAddKill; + questUpdateAddKill.QuestId = quest->GetQuestId(); + questUpdateAddKill.CreatureEntry = entry; + questUpdateAddKill.CurrentCount = old_count + add_count; + questUpdateAddKill.RequiredCount = quest->RequiredNpcOrGoCount[creatureOrGO_idx]; + questUpdateAddKill.ObjectiveGuid = guid; + SendDirectMessage(questUpdateAddKill.Write()); LOG_DEBUG("network", "WORLD: Sent SMSG_QUESTUPDATE_ADD_KILL"); - data << uint32(quest->GetQuestId()); - data << uint32(entry); - data << uint32(old_count + add_count); - data << uint32(quest->RequiredNpcOrGoCount[ creatureOrGO_idx ]); - data << guid; - SendDirectMessage(&data); uint16 log_slot = FindQuestSlot(quest->GetQuestId()); if (log_slot < MAX_QUEST_LOG_SIZE) @@ -2516,12 +2513,12 @@ void Player::SendQuestUpdateAddPlayer(Quest const* quest, uint16 old_count, uint { ASSERT(old_count + add_count < 65536 && "player count store in 16 bits"); - WorldPacket data(SMSG_QUESTUPDATE_ADD_PVP_KILL, (3 * 4)); + WorldPackets::Quest::QuestUpdateAddPvPKill questUpdateAddPvPKill; + questUpdateAddPvPKill.QuestId = quest->GetQuestId(); + questUpdateAddPvPKill.CurrentCount = old_count + add_count; + questUpdateAddPvPKill.RequiredCount = quest->GetPlayersSlain(); + SendDirectMessage(questUpdateAddPvPKill.Write()); LOG_DEBUG("network", "WORLD: Sent SMSG_QUESTUPDATE_ADD_PVP_KILL"); - data << uint32(quest->GetQuestId()); - data << uint32(old_count + add_count); - data << uint32(quest->GetPlayersSlain()); - SendDirectMessage(&data); uint16 log_slot = FindQuestSlot(quest->GetQuestId()); if (log_slot < MAX_QUEST_LOG_SIZE) diff --git a/src/server/game/Handlers/QuestHandler.cpp b/src/server/game/Handlers/QuestHandler.cpp index a2c7753280..89a0a84af7 100644 --- a/src/server/game/Handlers/QuestHandler.cpp +++ b/src/server/game/Handlers/QuestHandler.cpp @@ -27,6 +27,7 @@ #include "Opcodes.h" #include "Player.h" #include "QuestDef.h" +#include "QuestPackets.h" #include "ScriptMgr.h" #include "World.h" #include "WorldPacket.h" @@ -382,29 +383,23 @@ void WorldSession::HandleQuestgiverCancel(WorldPacket& /*recvData*/) _player->PlayerTalkClass->SendCloseGossip(); } -void WorldSession::HandleQuestLogSwapQuest(WorldPacket& recvData) +void WorldSession::HandleQuestLogSwapQuest(WorldPackets::Quest::QuestLogSwapQuest& packet) { - uint8 slot1, slot2; - recvData >> slot1 >> slot2; - - if (slot1 == slot2 || slot1 >= MAX_QUEST_LOG_SIZE || slot2 >= MAX_QUEST_LOG_SIZE) + if (packet.Slot1 == packet.Slot2 || packet.Slot1 >= MAX_QUEST_LOG_SIZE || packet.Slot2 >= MAX_QUEST_LOG_SIZE) return; - LOG_DEBUG("network", "WORLD: Received CMSG_QUESTLOG_SWAP_QUEST slot 1 = {}, slot 2 = {}", slot1, slot2); + LOG_DEBUG("network", "WORLD: Received CMSG_QUESTLOG_SWAP_QUEST slot 1 = {}, slot 2 = {}", packet.Slot1, packet.Slot2); - GetPlayer()->SwapQuestSlot(slot1, slot2); + GetPlayer()->SwapQuestSlot(packet.Slot1, packet.Slot2); } -void WorldSession::HandleQuestLogRemoveQuest(WorldPacket& recvData) +void WorldSession::HandleQuestLogRemoveQuest(WorldPackets::Quest::QuestLogRemoveQuest& packet) { - uint8 slot; - recvData >> slot; + LOG_DEBUG("network", "WORLD: Received CMSG_QUESTLOG_REMOVE_QUEST slot = {}", packet.Slot); - LOG_DEBUG("network", "WORLD: Received CMSG_QUESTLOG_REMOVE_QUEST slot = {}", slot); - - if (slot < MAX_QUEST_LOG_SIZE) + if (packet.Slot < MAX_QUEST_LOG_SIZE) { - if (uint32 questId = _player->GetQuestSlotQuestId(slot)) + if (uint32 questId = _player->GetQuestSlotQuestId(packet.Slot)) { if (!_player->TakeQuestSourceItem(questId, true)) return; // can't un-equip some items, reject quest cancel @@ -442,20 +437,17 @@ void WorldSession::HandleQuestLogRemoveQuest(WorldPacket& recvData) } } - _player->SetQuestSlot(slot, 0); + _player->SetQuestSlot(packet.Slot, 0); _player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_QUEST_ABANDONED, 1); } } -void WorldSession::HandleQuestConfirmAccept(WorldPacket& recvData) +void WorldSession::HandleQuestConfirmAccept(WorldPackets::Quest::QuestConfirmAcceptClient& packet) { - uint32 questId; - recvData >> questId; + LOG_DEBUG("network", "WORLD: Received CMSG_QUEST_CONFIRM_ACCEPT quest = {}", packet.QuestId); - LOG_DEBUG("network", "WORLD: Received CMSG_QUEST_CONFIRM_ACCEPT quest = {}", questId); - - if (Quest const* quest = sObjectMgr->GetQuestTemplate(questId)) + if (Quest const* quest = sObjectMgr->GetQuestTemplate(packet.QuestId)) { if (!quest->HasFlag(QUEST_FLAGS_PARTY_ACCEPT)) return; @@ -530,21 +522,18 @@ void WorldSession::HandleQuestgiverCompleteQuest(WorldPacket& recvData) } } -void WorldSession::HandleQuestgiverQuestAutoLaunch(WorldPacket& /*recvPacket*/) +void WorldSession::HandleQuestgiverQuestAutoLaunch(WorldPackets::Quest::QuestGiverQuestAutoLaunch& /*packet*/) { } -void WorldSession::HandlePushQuestToParty(WorldPacket& recvPacket) +void WorldSession::HandlePushQuestToParty(WorldPackets::Quest::PushQuestToParty& packet) { - uint32 questId; - recvPacket >> questId; - - if (!_player->CanShareQuest(questId)) + if (!_player->CanShareQuest(packet.QuestId)) return; - LOG_DEBUG("network", "WORLD: Received CMSG_PUSHQUESTTOPARTY quest = {}", questId); + LOG_DEBUG("network", "WORLD: Received CMSG_PUSHQUESTTOPARTY quest = {}", packet.QuestId); - if (Quest const* quest = sObjectMgr->GetQuestTemplate(questId)) + if (Quest const* quest = sObjectMgr->GetQuestTemplate(packet.QuestId)) { if (Group* group = _player->GetGroup()) { @@ -561,7 +550,7 @@ void WorldSession::HandlePushQuestToParty(WorldPacket& recvPacket) continue; } - if (player->GetQuestStatus(questId) == QUEST_STATUS_COMPLETE) + if (player->GetQuestStatus(packet.QuestId) == QUEST_STATUS_COMPLETE) { _player->SendPushToPartyResponse(player, QUEST_PARTY_MSG_FINISH_QUEST); continue; @@ -613,21 +602,16 @@ void WorldSession::HandlePushQuestToParty(WorldPacket& recvPacket) } } -void WorldSession::HandleQuestPushResult(WorldPacket& recvPacket) +void WorldSession::HandleQuestPushResult(WorldPackets::Quest::QuestPushResultClient& packet) { - ObjectGuid guid; - uint32 questId; - uint8 msg; - recvPacket >> guid >> questId >> msg; - - if (_player->GetDivider() && _player->GetDivider() == guid) + if (_player->GetDivider() && _player->GetDivider() == packet.PlayerGuid) { if (Player* player = ObjectAccessor::GetPlayer(*_player, _player->GetDivider())) { - WorldPacket data(MSG_QUEST_PUSH_RESULT, 8 + 4 + 1); - data << _player->GetGUID(); - data << uint8(msg); // valid values: 0-8 - player->SendDirectMessage(&data); + WorldPackets::Quest::QuestPushResult questPushResult; + questPushResult.PlayerGuid = _player->GetGUID(); + questPushResult.QuestShareMessage = packet.QuestShareMessage; + player->SendDirectMessage(questPushResult.Write()); _player->SetDivider(); } } diff --git a/src/server/game/Server/Packets/AllPackets.h b/src/server/game/Server/Packets/AllPackets.h index 8cdbc7cda6..85d247e7ea 100644 --- a/src/server/game/Server/Packets/AllPackets.h +++ b/src/server/game/Server/Packets/AllPackets.h @@ -32,6 +32,7 @@ #include "NPCPackets.h" #include "PetPackets.h" #include "QueryPackets.h" +#include "QuestPackets.h" #include "TotemPackets.h" #include "WorldStatePackets.h" diff --git a/src/server/game/Server/Packets/QuestPackets.cpp b/src/server/game/Server/Packets/QuestPackets.cpp new file mode 100644 index 0000000000..e840602f37 --- /dev/null +++ b/src/server/game/Server/Packets/QuestPackets.cpp @@ -0,0 +1,126 @@ +/* + * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#include "QuestPackets.h" + +WorldPacket const* WorldPackets::Quest::QuestUpdateComplete::Write() +{ + _worldPacket << QuestId; + + return &_worldPacket; +} + +WorldPacket const* WorldPackets::Quest::QuestGiverQuestComplete::Write() +{ + _worldPacket << QuestId; + _worldPacket << Experience; + _worldPacket << RewardMoney; + _worldPacket << RewardHonor; + _worldPacket << RewardTalents; + _worldPacket << RewardArena; + + return &_worldPacket; +} + +WorldPacket const* WorldPackets::Quest::QuestGiverQuestFailed::Write() +{ + _worldPacket << QuestId; + _worldPacket << FailureReason; + + return &_worldPacket; +} + +WorldPacket const* WorldPackets::Quest::QuestUpdateFailedTimer::Write() +{ + _worldPacket << QuestId; + + return &_worldPacket; +} + +WorldPacket const* WorldPackets::Quest::QuestGiverQuestInvalid::Write() +{ + _worldPacket << FailureReason; + + return &_worldPacket; +} + +WorldPacket const* WorldPackets::Quest::QuestConfirmAccept::Write() +{ + _worldPacket << QuestId; + _worldPacket << QuestTitle; + _worldPacket << PlayerGuid; + + return &_worldPacket; +} + +WorldPacket const* WorldPackets::Quest::QuestPushResult::Write() +{ + _worldPacket << PlayerGuid; + _worldPacket << QuestShareMessage; + + return &_worldPacket; +} + +WorldPacket const* WorldPackets::Quest::QuestUpdateAddKill::Write() +{ + _worldPacket << QuestId; + _worldPacket << CreatureEntry; + _worldPacket << CurrentCount; + _worldPacket << RequiredCount; + _worldPacket << ObjectiveGuid; + + return &_worldPacket; +} + +WorldPacket const* WorldPackets::Quest::QuestUpdateAddPvPKill::Write() +{ + _worldPacket << QuestId; + _worldPacket << CurrentCount; + _worldPacket << RequiredCount; + + return &_worldPacket; +} + +void WorldPackets::Quest::QuestPushResultClient::Read() +{ + _worldPacket >> PlayerGuid; + _worldPacket >> QuestId; + uint8 Message; + _worldPacket >> Message; + QuestShareMessage = static_cast(Message); +} + +void WorldPackets::Quest::QuestLogSwapQuest::Read() +{ + _worldPacket >> Slot1; + _worldPacket >> Slot2; +} + +void WorldPackets::Quest::QuestLogRemoveQuest::Read() +{ + _worldPacket >> Slot; +} + +void WorldPackets::Quest::QuestConfirmAcceptClient::Read() +{ + _worldPacket >> QuestId; +} + +void WorldPackets::Quest::PushQuestToParty::Read() +{ + _worldPacket >> QuestId; +} diff --git a/src/server/game/Server/Packets/QuestPackets.h b/src/server/game/Server/Packets/QuestPackets.h new file mode 100644 index 0000000000..40079d437e --- /dev/null +++ b/src/server/game/Server/Packets/QuestPackets.h @@ -0,0 +1,214 @@ +/* + * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#ifndef QuestPackets_h__ +#define QuestPackets_h__ + +#include "ObjectGuid.h" +#include "Packet.h" +#include "QuestDef.h" + +namespace WorldPackets +{ + namespace Quest + { + class QuestLogFull final : public ServerPacket + { + public: + QuestLogFull() : ServerPacket(SMSG_QUESTLOG_FULL, 0) {} + + WorldPacket const* Write() override { return &_worldPacket; } + }; + + class QuestUpdateComplete final : public ServerPacket + { + public: + QuestUpdateComplete() : ServerPacket(SMSG_QUESTUPDATE_COMPLETE, 4) {} + + WorldPacket const* Write() override; + + uint32 QuestId = 0; + }; + + class QuestGiverQuestComplete final : public ServerPacket + { + public: + QuestGiverQuestComplete() : ServerPacket(SMSG_QUESTGIVER_QUEST_COMPLETE, 4 + 4 + 4 + 4 + 4 + 4) {} + + WorldPacket const* Write() override; + + uint32 QuestId = 0; + uint32 Experience = 0; + uint32 RewardMoney = 0; + uint32 RewardHonor = 0; + uint32 RewardTalents = 0; + uint32 RewardArena = 0; + }; + + class QuestGiverQuestFailed final : public ServerPacket + { + public: + QuestGiverQuestFailed() : ServerPacket(SMSG_QUESTGIVER_QUEST_FAILED, 4 + 4) {} + + WorldPacket const* Write() override; + + uint32 QuestId = 0; + uint32 FailureReason = 0; + }; + + class QuestUpdateFailedTimer final : public ServerPacket + { + public: + QuestUpdateFailedTimer() : ServerPacket(SMSG_QUESTUPDATE_FAILEDTIMER, 4) {} + + WorldPacket const* Write() override; + + uint32 QuestId = 0; + }; + + class QuestGiverQuestInvalid final : public ServerPacket + { + public: + QuestGiverQuestInvalid() : ServerPacket(SMSG_QUESTGIVER_QUEST_INVALID, 4) {} + + WorldPacket const* Write() override; + + QuestFailedReason FailureReason = INVALIDREASON_DONT_HAVE_REQ; + }; + + class QuestConfirmAccept final : public ServerPacket + { + public: + // 4 (QuestId) + title (variable, 16 reserved estimate) + 8 (GUID) + QuestConfirmAccept() : ServerPacket(SMSG_QUEST_CONFIRM_ACCEPT, 4 + 16 + 8) {} + + WorldPacket const* Write() override; + + uint32 QuestId = 0; + std::string_view QuestTitle = ""; + ObjectGuid PlayerGuid; + }; + + class QuestPushResult final : public ServerPacket + { + public: + QuestPushResult() : ServerPacket(MSG_QUEST_PUSH_RESULT, 8 + 1) {} + + WorldPacket const* Write() override; + + ObjectGuid PlayerGuid; + QuestShareMessages QuestShareMessage = QUEST_PARTY_MSG_SHARING_QUEST; // valid values: 0-10 + }; + + class QuestUpdateAddItem final : public ServerPacket + { + public: + QuestUpdateAddItem() : ServerPacket(SMSG_QUESTUPDATE_ADD_ITEM, 0) {} + + WorldPacket const* Write() override { return &_worldPacket; } + }; + + class QuestUpdateAddKill final : public ServerPacket + { + public: + QuestUpdateAddKill() : ServerPacket(SMSG_QUESTUPDATE_ADD_KILL, 4 * 4 + 8) {} + + WorldPacket const* Write() override; + + uint32 QuestId = 0; + uint32 CreatureEntry = 0; + uint32 CurrentCount = 0; + uint32 RequiredCount = 0; + ObjectGuid ObjectiveGuid; + }; + + class QuestUpdateAddPvPKill final : public ServerPacket + { + public: + QuestUpdateAddPvPKill() : ServerPacket(SMSG_QUESTUPDATE_ADD_PVP_KILL, 3 * 4) {} + + WorldPacket const* Write() override; + + uint32 QuestId = 0; + uint32 CurrentCount = 0; + uint32 RequiredCount = 0; + }; + + class QuestPushResultClient final : public ClientPacket + { + public: + QuestPushResultClient(WorldPacket&& packet) : ClientPacket(MSG_QUEST_PUSH_RESULT, std::move(packet)) {} + + void Read() override; + + ObjectGuid PlayerGuid; + uint32 QuestId = 0; + QuestShareMessages QuestShareMessage = QUEST_PARTY_MSG_SHARING_QUEST; + }; + + class QuestGiverQuestAutoLaunch final : public ClientPacket + { + public: + QuestGiverQuestAutoLaunch(WorldPacket&& packet) : ClientPacket(CMSG_QUESTGIVER_QUEST_AUTOLAUNCH, std::move(packet)) {} + + void Read() override {} + }; + + class QuestLogSwapQuest final : public ClientPacket + { + public: + QuestLogSwapQuest(WorldPacket&& packet) : ClientPacket(CMSG_QUESTLOG_SWAP_QUEST, std::move(packet)) {} + + void Read() override; + + uint8 Slot1 = 0; + uint8 Slot2 = 0; + }; + + class QuestLogRemoveQuest final : public ClientPacket + { + public: + QuestLogRemoveQuest(WorldPacket&& packet) : ClientPacket(CMSG_QUESTLOG_REMOVE_QUEST, std::move(packet)) {} + + void Read() override; + + uint8 Slot = 0; + }; + + class QuestConfirmAcceptClient final : public ClientPacket + { + public: + QuestConfirmAcceptClient(WorldPacket&& packet) : ClientPacket(CMSG_QUEST_CONFIRM_ACCEPT, std::move(packet)) {} + + void Read() override; + + uint32 QuestId = 0; + }; + + class PushQuestToParty final : public ClientPacket + { + public: + PushQuestToParty(WorldPacket&& packet) : ClientPacket(CMSG_PUSHQUESTTOPARTY, std::move(packet)) {} + + void Read() override; + + uint32 QuestId = 0; + }; + } +} + +#endif // QuestPackets_h__ diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h index 0904312c9b..b588ad8f1b 100644 --- a/src/server/game/Server/WorldSession.h +++ b/src/server/game/Server/WorldSession.h @@ -192,6 +192,16 @@ namespace WorldPackets class ItemRefund; } + namespace Quest + { + class QuestPushResultClient; + class QuestGiverQuestAutoLaunch; + class QuestLogSwapQuest; + class QuestLogRemoveQuest; + class QuestConfirmAcceptClient; + class PushQuestToParty; + } + namespace Calendar { class GetEvent; @@ -915,13 +925,13 @@ public: // opcodes handlers void HandleQuestgiverRequestRewardOpcode(WorldPacket& recvPacket); void HandleQuestQueryOpcode(WorldPacket& recvPacket); void HandleQuestgiverCancel(WorldPacket& recvData); - void HandleQuestLogSwapQuest(WorldPacket& recvData); - void HandleQuestLogRemoveQuest(WorldPacket& recvData); - void HandleQuestConfirmAccept(WorldPacket& recvData); + void HandleQuestLogSwapQuest(WorldPackets::Quest::QuestLogSwapQuest& packet); + void HandleQuestLogRemoveQuest(WorldPackets::Quest::QuestLogRemoveQuest& packet); + void HandleQuestConfirmAccept(WorldPackets::Quest::QuestConfirmAcceptClient& packet); void HandleQuestgiverCompleteQuest(WorldPacket& recvData); - void HandleQuestgiverQuestAutoLaunch(WorldPacket& recvPacket); - void HandlePushQuestToParty(WorldPacket& recvPacket); - void HandleQuestPushResult(WorldPacket& recvPacket); + void HandleQuestgiverQuestAutoLaunch(WorldPackets::Quest::QuestGiverQuestAutoLaunch& packet); + void HandlePushQuestToParty(WorldPackets::Quest::PushQuestToParty& packet); + void HandleQuestPushResult(WorldPackets::Quest::QuestPushResultClient& packet); void HandleMessagechatOpcode(WorldPacket& recvPacket); void SendPlayerNotFoundNotice(std::string const& name); diff --git a/src/server/scripts/World/player_scripts.cpp b/src/server/scripts/World/player_scripts.cpp index 22e0bd85a6..3cdfaa2d22 100644 --- a/src/server/scripts/World/player_scripts.cpp +++ b/src/server/scripts/World/player_scripts.cpp @@ -17,6 +17,7 @@ #include "Player.h" #include "PlayerScript.h" +#include "QuestPackets.h" enum ApprenticeAnglerQuestEnum { @@ -54,14 +55,10 @@ public: player->SaveToDB(false, false); // Send packet with money - WorldPacket data(SMSG_QUESTGIVER_QUEST_COMPLETE, (4 + 4 + 4 + 4 + 4)); - data << uint32(quest->GetQuestId()); - data << uint32(0); - data << uint32(moneyRew); - data << uint32(0); - data << uint32(0); - data << uint32(0); - player->SendDirectMessage(&data); + WorldPackets::Quest::QuestGiverQuestComplete questGiverQuestComplete; + questGiverQuestComplete.QuestId = quest->GetQuestId(); + questGiverQuestComplete.RewardMoney = moneyRew; + player->SendDirectMessage(questGiverQuestComplete.Write()); } } };