aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRochet2 <rochet2@post.com>2017-08-14 00:42:02 +0300
committerShauren <shauren.trinity@gmail.com>2017-08-13 23:42:02 +0200
commite5b9c207f8889010c88f66ea39160659137402d3 (patch)
tree9554e728e3f7a39f79b55a17d2f1c7e894fafcca /src
parentf17cb00ee36f834a103268742246c13b09458d2f (diff)
Core/Creatures: Implement a general way to store selection data for gossip and fix trainer exploit (#20085)
* Implement mail check * Implement CloseInteraction packet
Diffstat (limited to 'src')
-rw-r--r--src/server/game/Entities/Creature/GossipDef.cpp6
-rw-r--r--src/server/game/Entities/Creature/GossipDef.h20
-rw-r--r--src/server/game/Entities/Player/Player.h4
-rw-r--r--src/server/game/Handlers/MailHandler.cpp8
-rw-r--r--src/server/game/Handlers/MiscHandler.cpp5
-rw-r--r--src/server/game/Handlers/NPCHandler.cpp11
-rw-r--r--src/server/game/Server/Packets/MiscPackets.cpp5
-rw-r--r--src/server/game/Server/Packets/MiscPackets.h10
-rw-r--r--src/server/game/Server/Protocol/Opcodes.cpp2
-rw-r--r--src/server/game/Server/WorldSession.h2
10 files changed, 56 insertions, 17 deletions
diff --git a/src/server/game/Entities/Creature/GossipDef.cpp b/src/server/game/Entities/Creature/GossipDef.cpp
index aaa273573f3..fabe6333503 100644
--- a/src/server/game/Entities/Creature/GossipDef.cpp
+++ b/src/server/game/Entities/Creature/GossipDef.cpp
@@ -33,7 +33,6 @@ GossipMenu::GossipMenu()
{
_menuId = 0;
_locale = DEFAULT_LOCALE;
- _senderGUID.Clear();
}
GossipMenu::~GossipMenu()
@@ -207,7 +206,8 @@ void PlayerMenu::ClearMenus()
void PlayerMenu::SendGossipMenu(uint32 titleTextId, ObjectGuid objectGUID)
{
- _gossipMenu.SetSenderGUID(objectGUID);
+ _interactionData.Reset();
+ _interactionData.SourceGuid = objectGUID;
WorldPackets::NPC::GossipMessage packet;
packet.GossipGUID = objectGUID;
@@ -269,7 +269,7 @@ void PlayerMenu::SendGossipMenu(uint32 titleTextId, ObjectGuid objectGUID)
void PlayerMenu::SendCloseGossip()
{
- _gossipMenu.SetSenderGUID(ObjectGuid::Empty);
+ _interactionData.Reset();
WorldPackets::NPC::GossipComplete packet;
_session->SendPacket(packet.Write());
diff --git a/src/server/game/Entities/Creature/GossipDef.h b/src/server/game/Entities/Creature/GossipDef.h
index 5b1db6e8227..472cf19b36d 100644
--- a/src/server/game/Entities/Creature/GossipDef.h
+++ b/src/server/game/Entities/Creature/GossipDef.h
@@ -172,8 +172,6 @@ class TC_GAME_API GossipMenu
void SetMenuId(uint32 menu_id) { _menuId = menu_id; }
uint32 GetMenuId() const { return _menuId; }
- void SetSenderGUID(ObjectGuid guid) { _senderGUID = guid; }
- ObjectGuid GetSenderGUID() const { return _senderGUID; }
void SetLocale(LocaleConstant locale) { _locale = locale; }
LocaleConstant GetLocale() const { return _locale; }
@@ -216,7 +214,6 @@ class TC_GAME_API GossipMenu
GossipMenuItemContainer _menuItems;
GossipMenuItemDataContainer _menuItemData;
uint32 _menuId;
- ObjectGuid _senderGUID;
LocaleConstant _locale;
};
@@ -237,6 +234,21 @@ class TC_GAME_API QuestMenu
QuestMenuItemList _questMenuItems;
};
+class InteractionData
+{
+ public:
+ InteractionData() { Reset(); }
+
+ void Reset()
+ {
+ SourceGuid.Clear();
+ TrainerId = 0;
+ }
+
+ ObjectGuid SourceGuid;
+ uint32 TrainerId;
+};
+
class TC_GAME_API PlayerMenu
{
public:
@@ -245,6 +257,7 @@ class TC_GAME_API PlayerMenu
GossipMenu& GetGossipMenu() { return _gossipMenu; }
QuestMenu& GetQuestMenu() { return _questMenu; }
+ InteractionData& GetInteractionData() { return _interactionData; }
bool Empty() const { return _gossipMenu.Empty() && _questMenu.Empty(); }
@@ -276,5 +289,6 @@ class TC_GAME_API PlayerMenu
GossipMenu _gossipMenu;
QuestMenu _questMenu;
WorldSession* _session;
+ InteractionData _interactionData;
};
#endif
diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h
index c94b5804e45..414515b5e36 100644
--- a/src/server/game/Entities/Player/Player.h
+++ b/src/server/game/Entities/Player/Player.h
@@ -2338,8 +2338,6 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>
SceneMgr& GetSceneMgr() { return m_sceneMgr; }
RestMgr& GetRestMgr() const { return *_restMgr; }
- uint32 GetCurrentTrainerId() const { return _currentTrainerId; }
- void SetCurrentTrainerId(uint32 trainerId) { _currentTrainerId = trainerId; }
protected:
// Gamemaster whisper whitelist
GuidList WhisperList;
@@ -2691,8 +2689,6 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>
void _InitHonorLevelOnLoadFromDB(uint32 /*honor*/, uint32 /*honorLevel*/, uint32 /*prestigeLevel*/);
std::unique_ptr<RestMgr> _restMgr;
-
- uint32 _currentTrainerId;
};
TC_GAME_API void AddItemsSetItem(Player* player, Item* item);
diff --git a/src/server/game/Handlers/MailHandler.cpp b/src/server/game/Handlers/MailHandler.cpp
index 2baa149f123..73423256893 100644
--- a/src/server/game/Handlers/MailHandler.cpp
+++ b/src/server/game/Handlers/MailHandler.cpp
@@ -20,6 +20,7 @@
#include "BattlenetAccountMgr.h"
#include "DatabaseEnv.h"
#include "DB2Stores.h"
+#include "GossipDef.h"
#include "Guild.h"
#include "GuildMgr.h"
#include "Item.h"
@@ -382,9 +383,8 @@ void WorldSession::HandleMailDelete(WorldPackets::Mail::MailDelete& packet)
void WorldSession::HandleMailReturnToSender(WorldPackets::Mail::MailReturnToSender& packet)
{
- //TODO: find a proper way to replace this check. Idea: Save Guid form MailGetList until CMSG_CLOSE_INTERACTION is sent
- /*if (!CanOpenMailBox(mailbox))
- return;*/
+ if (!CanOpenMailBox(_player->PlayerTalkClass->GetInteractionData().SourceGuid))
+ return;
Player* player = _player;
Mail* m = player->GetMail(packet.MailID);
@@ -592,6 +592,8 @@ void WorldSession::HandleGetMailList(WorldPackets::Mail::MailGetList& packet)
++response.TotalNumRecords;
}
+ player->PlayerTalkClass->GetInteractionData().Reset();
+ player->PlayerTalkClass->GetInteractionData().SourceGuid = packet.Mailbox;
SendPacket(response.Write());
// recalculate m_nextMailDelivereTime and unReadMails
diff --git a/src/server/game/Handlers/MiscHandler.cpp b/src/server/game/Handlers/MiscHandler.cpp
index 3337c8dacb6..950acf967d9 100644
--- a/src/server/game/Handlers/MiscHandler.cpp
+++ b/src/server/game/Handlers/MiscHandler.cpp
@@ -1168,3 +1168,8 @@ void WorldSession::HandlePvpPrestigeRankUp(WorldPackets::Misc::PvpPrestigeRankUp
if (_player->CanPrestige())
_player->Prestige();
}
+
+void WorldSession::HandleCloseInteraction(WorldPackets::Misc::CloseInteraction& /*packet*/)
+{
+ _player->PlayerTalkClass->GetInteractionData().Reset();
+}
diff --git a/src/server/game/Handlers/NPCHandler.cpp b/src/server/game/Handlers/NPCHandler.cpp
index d4e9f23482e..6d16a63d81a 100644
--- a/src/server/game/Handlers/NPCHandler.cpp
+++ b/src/server/game/Handlers/NPCHandler.cpp
@@ -113,7 +113,9 @@ void WorldSession::SendTrainerList(ObjectGuid guid, uint32 trainerId)
return;
}
- _player->SetCurrentTrainerId(trainerId);
+ _player->PlayerTalkClass->GetInteractionData().Reset();
+ _player->PlayerTalkClass->GetInteractionData().SourceGuid = guid;
+ _player->PlayerTalkClass->GetInteractionData().TrainerId = trainerId;
trainer->SendSpells(unit, _player, GetSessionDbLocaleIndex());
}
@@ -132,7 +134,10 @@ void WorldSession::HandleTrainerBuySpellOpcode(WorldPackets::NPC::TrainerBuySpel
if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
GetPlayer()->RemoveAurasByType(SPELL_AURA_FEIGN_DEATH);
- if (_player->GetCurrentTrainerId() != uint32(packet.TrainerID))
+ if (_player->PlayerTalkClass->GetInteractionData().SourceGuid != packet.TrainerGUID)
+ return;
+
+ if (_player->PlayerTalkClass->GetInteractionData().TrainerId != uint32(packet.TrainerID))
return;
Trainer::Trainer const* trainer = sObjectMgr->GetTrainer(packet.TrainerID);
@@ -190,7 +195,7 @@ void WorldSession::HandleGossipSelectOptionOpcode(WorldPackets::NPC::GossipSelec
return;
// Prevent cheating on C++ scripted menus
- if (_player->PlayerTalkClass->GetGossipMenu().GetSenderGUID() != packet.GossipUnit)
+ if (_player->PlayerTalkClass->GetInteractionData().SourceGuid != packet.GossipUnit)
return;
Creature* unit = nullptr;
diff --git a/src/server/game/Server/Packets/MiscPackets.cpp b/src/server/game/Server/Packets/MiscPackets.cpp
index ed880a0d7f6..68d5496cdb6 100644
--- a/src/server/game/Server/Packets/MiscPackets.cpp
+++ b/src/server/game/Server/Packets/MiscPackets.cpp
@@ -662,3 +662,8 @@ void WorldPackets::Misc::MountSetFavorite::Read()
_worldPacket >> MountSpellID;
IsFavorite = _worldPacket.ReadBit();
}
+
+void WorldPackets::Misc::CloseInteraction::Read()
+{
+ _worldPacket >> SourceGuid;
+}
diff --git a/src/server/game/Server/Packets/MiscPackets.h b/src/server/game/Server/Packets/MiscPackets.h
index c277d3dce26..a7e74d571b2 100644
--- a/src/server/game/Server/Packets/MiscPackets.h
+++ b/src/server/game/Server/Packets/MiscPackets.h
@@ -874,6 +874,16 @@ namespace WorldPackets
void Read() override { }
};
+
+ class CloseInteraction final : public ClientPacket
+ {
+ public:
+ CloseInteraction(WorldPacket&& packet) : ClientPacket(CMSG_CLOSE_INTERACTION, std::move(packet)) { }
+
+ void Read() override;
+
+ ObjectGuid SourceGuid;
+ };
}
}
diff --git a/src/server/game/Server/Protocol/Opcodes.cpp b/src/server/game/Server/Protocol/Opcodes.cpp
index 1001dd1aeec..22241fc3f25 100644
--- a/src/server/game/Server/Protocol/Opcodes.cpp
+++ b/src/server/game/Server/Protocol/Opcodes.cpp
@@ -323,7 +323,7 @@ void OpcodeTable::Initialize()
DEFINE_HANDLER(CMSG_CLEAR_RAID_MARKER, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleClearRaidMarker);
DEFINE_HANDLER(CMSG_CLEAR_TRADE_ITEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleClearTradeItemOpcode);
DEFINE_HANDLER(CMSG_CLIENT_PORT_GRAVEYARD, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandlePortGraveyard);
- DEFINE_HANDLER(CMSG_CLOSE_INTERACTION, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL);
+ DEFINE_HANDLER(CMSG_CLOSE_INTERACTION, STATUS_UNHANDLED, PROCESS_THREADSAFE, &WorldSession::HandleCloseInteraction);
DEFINE_HANDLER(CMSG_COLLECTION_ITEM_SET_FAVORITE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleCollectionItemSetFavorite);
DEFINE_HANDLER(CMSG_COMMENTATOR_ENABLE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL);
DEFINE_HANDLER(CMSG_COMMENTATOR_ENTER_INSTANCE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL);
diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h
index 6899bf97b95..2addad0b5c2 100644
--- a/src/server/game/Server/WorldSession.h
+++ b/src/server/game/Server/WorldSession.h
@@ -466,6 +466,7 @@ namespace WorldPackets
class SetTaxiBenchmarkMode;
class MountSetFavorite;
class PvpPrestigeRankUp;
+ class CloseInteraction;
}
namespace Movement
@@ -1644,6 +1645,7 @@ class TC_GAME_API WorldSession
void HandleObjectUpdateFailedOpcode(WorldPackets::Misc::ObjectUpdateFailed& objectUpdateFailed);
void HandleObjectUpdateRescuedOpcode(WorldPackets::Misc::ObjectUpdateRescued& objectUpdateRescued);
void HandleRequestCategoryCooldowns(WorldPackets::Spells::RequestCategoryCooldowns& requestCategoryCooldowns);
+ void HandleCloseInteraction(WorldPackets::Misc::CloseInteraction& packet);
// Toys
void HandleAddToy(WorldPackets::Toy::AddToy& packet);