Core/Gossip: Use std::variant to store InteractionData

This commit is contained in:
Shauren
2025-06-21 13:25:30 +02:00
parent a562f4fafa
commit 7c32af9a27
4 changed files with 40 additions and 17 deletions

View File

@@ -21,6 +21,7 @@
#include "Common.h"
#include "ObjectGuid.h"
#include "Optional.h"
#include <variant>
class Object;
class Quest;
@@ -233,19 +234,41 @@ class TC_GAME_API QuestMenu
class InteractionData
{
public:
void Reset()
{
SourceGuid.Clear();
TrainerId = 0;
PlayerChoiceId = 0;
IsLaunchedByQuest = false;
}
template <typename>
struct TaggedId
{
TaggedId() = default;
explicit TaggedId(uint32 id) : Id(id) { }
ObjectGuid SourceGuid;
uint32 TrainerId = 0;
uint32 PlayerChoiceId = 0;
bool IsLaunchedByQuest = false;
uint32 Id = 0;
};
struct TrainerTag;
using TrainerData = TaggedId<TrainerTag>;
struct PlayerChoiceTag;
using PlayerChoiceData = TaggedId<PlayerChoiceTag>;
public:
void Reset()
{
SourceGuid.Clear();
IsLaunchedByQuest = false;
_data.emplace<std::monostate>();
}
ObjectGuid SourceGuid;
Optional<uint32> GetTrainerId() const { return std::holds_alternative<TrainerData>(_data) ? std::get<TrainerData>(_data).Id : Optional<uint32>(); }
void SetTrainerId(uint32 trainerId) { _data.emplace<TrainerData>(trainerId); }
Optional<uint32> GetPlayerChoiceId() const { return std::holds_alternative<TrainerData>(_data) ? std::get<PlayerChoiceData>(_data).Id : Optional<uint32>(); }
void SetPlayerChoice(uint32 choiceId) { _data.emplace<PlayerChoiceData>(choiceId); }
bool IsLaunchedByQuest = false;
private:
std::variant<std::monostate, TrainerData, PlayerChoiceData> _data;
};
class TC_GAME_API PlayerMenu

View File

@@ -29786,7 +29786,7 @@ void Player::SendPlayerChoice(ObjectGuid sender, int32 choiceId)
PlayerTalkClass->GetInteractionData().Reset();
PlayerTalkClass->GetInteractionData().SourceGuid = sender;
PlayerTalkClass->GetInteractionData().PlayerChoiceId = uint32(choiceId);
PlayerTalkClass->GetInteractionData().SetPlayerChoice(choiceId);
WorldPackets::Quest::DisplayPlayerChoice displayPlayerChoice;
displayPlayerChoice.SenderGUID = sender;

View File

@@ -124,7 +124,7 @@ void WorldSession::SendTrainerList(Creature* npc, uint32 trainerId)
_player->PlayerTalkClass->GetInteractionData().Reset();
_player->PlayerTalkClass->GetInteractionData().SourceGuid = npc->GetGUID();
_player->PlayerTalkClass->GetInteractionData().TrainerId = trainerId;
_player->PlayerTalkClass->GetInteractionData().SetTrainerId(trainerId);
trainer->SendSpells(npc, _player, GetSessionDbLocaleIndex());
}
@@ -146,7 +146,7 @@ void WorldSession::HandleTrainerBuySpellOpcode(WorldPackets::NPC::TrainerBuySpel
if (_player->PlayerTalkClass->GetInteractionData().SourceGuid != packet.TrainerGUID)
return;
if (_player->PlayerTalkClass->GetInteractionData().TrainerId != uint32(packet.TrainerID))
if (_player->PlayerTalkClass->GetInteractionData().GetTrainerId() != uint32(packet.TrainerID))
return;
Trainer::Trainer const* trainer = sObjectMgr->GetTrainer(packet.TrainerID);

View File

@@ -770,10 +770,10 @@ void WorldSession::HandleRequestWorldQuestUpdate(WorldPackets::Quest::RequestWor
void WorldSession::HandlePlayerChoiceResponse(WorldPackets::Quest::ChoiceResponse& choiceResponse)
{
if (_player->PlayerTalkClass->GetInteractionData().PlayerChoiceId != uint32(choiceResponse.ChoiceID))
if (_player->PlayerTalkClass->GetInteractionData().GetPlayerChoiceId() != uint32(choiceResponse.ChoiceID))
{
TC_LOG_ERROR("entities.player.cheat", "Error in CMSG_CHOICE_RESPONSE: {} tried to respond to invalid player choice {} (allowed {}) (possible packet-hacking detected)",
GetPlayerInfo(), choiceResponse.ChoiceID, _player->PlayerTalkClass->GetInteractionData().PlayerChoiceId);
GetPlayerInfo(), choiceResponse.ChoiceID, _player->PlayerTalkClass->GetInteractionData().GetPlayerChoiceId());
return;
}