From c3d8340e6b6451650fc0a2a971b470e082015389 Mon Sep 17 00:00:00 2001 From: UltraNix <80540499+UltraNix@users.noreply.github.com> Date: Wed, 6 Jul 2022 14:05:45 +0200 Subject: [PATCH] fix(Core/Gossips): Properly send packet with questgiver query handler. (#12290) Fixes #12215 --- src/server/game/Entities/Creature/GossipDef.cpp | 9 +++++++-- src/server/game/Entities/Creature/GossipDef.h | 8 ++++++-- src/server/game/Handlers/MiscHandler.cpp | 16 ++++++++++++++++ src/server/game/Handlers/QuestHandler.cpp | 6 ++++-- 4 files changed, 33 insertions(+), 6 deletions(-) diff --git a/src/server/game/Entities/Creature/GossipDef.cpp b/src/server/game/Entities/Creature/GossipDef.cpp index 15598c833..842bb9506 100644 --- a/src/server/game/Entities/Creature/GossipDef.cpp +++ b/src/server/game/Entities/Creature/GossipDef.cpp @@ -29,6 +29,7 @@ GossipMenu::GossipMenu() { _menuId = 0; _locale = DEFAULT_LOCALE; + _senderGUID.Clear(); } GossipMenu::~GossipMenu() @@ -188,8 +189,10 @@ void PlayerMenu::ClearMenus() _questMenu.ClearMenu(); } -void PlayerMenu::SendGossipMenu(uint32 titleTextId, ObjectGuid objectGUID) const +void PlayerMenu::SendGossipMenu(uint32 titleTextId, ObjectGuid objectGUID) { + _gossipMenu.SetSenderGUID(objectGUID); + WorldPacket data(SMSG_GOSSIP_MESSAGE, 24 + _gossipMenu.GetMenuItemCount() * 100 + _questMenu.GetMenuItemCount() * 75); // guess size data << objectGUID; data << uint32(_gossipMenu.GetMenuId()); // new 2.4.0 @@ -234,8 +237,10 @@ void PlayerMenu::SendGossipMenu(uint32 titleTextId, ObjectGuid objectGUID) const _session->SendPacket(&data); } -void PlayerMenu::SendCloseGossip() const +void PlayerMenu::SendCloseGossip() { + _gossipMenu.SetSenderGUID(ObjectGuid::Empty); + WorldPacket data(SMSG_GOSSIP_COMPLETE, 0); _session->SendPacket(&data); } diff --git a/src/server/game/Entities/Creature/GossipDef.h b/src/server/game/Entities/Creature/GossipDef.h index 0b8eedfc8..c8f98d684 100644 --- a/src/server/game/Entities/Creature/GossipDef.h +++ b/src/server/game/Entities/Creature/GossipDef.h @@ -213,11 +213,15 @@ public: return _menuItems; } + void SetSenderGUID(ObjectGuid guid) { _senderGUID = guid; } + [[nodiscard]] ObjectGuid GetSenderGUID() const { return _senderGUID; } + private: GossipMenuItemContainer _menuItems; GossipMenuItemDataContainer _menuItemData; uint32 _menuId; LocaleConstant _locale; + ObjectGuid _senderGUID; }; class QuestMenu @@ -266,8 +270,8 @@ public: [[nodiscard]] uint32 GetGossipOptionAction(uint32 selection) const { return _gossipMenu.GetMenuItemAction(selection); } [[nodiscard]] bool IsGossipOptionCoded(uint32 selection) const { return _gossipMenu.IsMenuItemCoded(selection); } - void SendGossipMenu(uint32 titleTextId, ObjectGuid objectGUID) const; - void SendCloseGossip() const; + void SendGossipMenu(uint32 titleTextId, ObjectGuid objectGUID); + void SendCloseGossip(); void SendPointOfInterest(uint32 poiId) const; /*********************************************************/ diff --git a/src/server/game/Handlers/MiscHandler.cpp b/src/server/game/Handlers/MiscHandler.cpp index dc5b48e68..e3d8912ea 100644 --- a/src/server/game/Handlers/MiscHandler.cpp +++ b/src/server/game/Handlers/MiscHandler.cpp @@ -98,6 +98,12 @@ void WorldSession::HandleGossipSelectOptionOpcode(WorldPacket& recv_data) if (_player->PlayerTalkClass->IsGossipOptionCoded(gossipListId)) recv_data >> code; + // Prevent cheating on C++ scripted menus + if (_player->PlayerTalkClass->GetGossipMenu().GetSenderGUID() != guid) + { + return; + } + Creature* unit = nullptr; GameObject* go = nullptr; Item* item = nullptr; @@ -528,6 +534,16 @@ void WorldSession::HandleSetSelectionOpcode(WorldPacket& recv_data) ObjectGuid guid; recv_data >> guid; + if (!guid) + { + // Clear any active gossip related to current selection if not present at player's client + GossipMenu& gossipMenu = _player->PlayerTalkClass->GetGossipMenu(); + if (gossipMenu.GetSenderGUID() == _player->GetTarget()) + { + _player->PlayerTalkClass->SendCloseGossip(); + } + } + _player->SetSelection(guid); // Change target of current autoshoot spell diff --git a/src/server/game/Handlers/QuestHandler.cpp b/src/server/game/Handlers/QuestHandler.cpp index 25366f52a..49e951549 100644 --- a/src/server/game/Handlers/QuestHandler.cpp +++ b/src/server/game/Handlers/QuestHandler.cpp @@ -38,9 +38,11 @@ void WorldSession::HandleQuestgiverStatusQueryOpcode(WorldPacket& recvData) uint32 questStatus = DIALOG_STATUS_NONE; GossipMenu& gossipMenu = _player->PlayerTalkClass->GetGossipMenu(); - // Did we already get get a gossip menu? if so no need to status query - if (!gossipMenu.Empty()) + // Did we already get a gossip menu with that NPC? if so no need to status query + if (gossipMenu.GetSenderGUID() == guid) + { return; + } Object* questGiver = ObjectAccessor::GetObjectByTypeMask(*_player, guid, TYPEMASK_UNIT | TYPEMASK_GAMEOBJECT); if (!questGiver)