diff options
author | ariel- <ariel-@users.noreply.github.com> | 2016-07-19 12:37:16 -0300 |
---|---|---|
committer | ariel- <ariel-@users.noreply.github.com> | 2016-07-19 12:37:16 -0300 |
commit | f87f7619aa8f8662b79fdb5e190a84c646ad0cb2 (patch) | |
tree | 340d293ad81f558637ca7fe8e5fb37b4c9b2c381 | |
parent | 5fb93b3fb8b2600d4e59d2ddbccfcbdfc27c7526 (diff) |
Core/Handlers: actually check allowed trainer classes and races to avoid spoofing
Closes #14586
-rw-r--r-- | src/server/game/Entities/Player/Player.cpp | 5 | ||||
-rw-r--r-- | src/server/game/Handlers/NPCHandler.cpp | 24 |
2 files changed, 22 insertions, 7 deletions
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index d06484615ed..30a1e3d0ff0 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -14010,8 +14010,11 @@ void Player::PrepareGossipMenu(WorldObject* source, uint32 menuId /*= 0*/, bool break; case GOSSIP_OPTION_TRAINER: if (getClass() != creature->GetCreatureTemplate()->trainer_class && creature->GetCreatureTemplate()->trainer_type == TRAINER_TYPE_CLASS) + { TC_LOG_ERROR("sql.sql", "GOSSIP_OPTION_TRAINER:: Player %s (GUID: %u) requested wrong gossip menu: %u with wrong class: %u at Creature: %s (Entry: %u, Trainer Class: %u)", - GetName().c_str(), GetGUID().GetCounter(), menu->GetGossipMenu().GetMenuId(), getClass(), creature->GetName().c_str(), creature->GetEntry(), creature->GetCreatureTemplate()->trainer_class); + GetName().c_str(), GetGUID().GetCounter(), menu->GetGossipMenu().GetMenuId(), getClass(), creature->GetName().c_str(), creature->GetEntry(), creature->GetCreatureTemplate()->trainer_class); + canTalk = false; + } // no break; case GOSSIP_OPTION_GOSSIP: case GOSSIP_OPTION_SPIRITGUIDE: diff --git a/src/server/game/Handlers/NPCHandler.cpp b/src/server/game/Handlers/NPCHandler.cpp index 1e00c25a0c3..d02611971cc 100644 --- a/src/server/game/Handlers/NPCHandler.cpp +++ b/src/server/game/Handlers/NPCHandler.cpp @@ -236,8 +236,8 @@ void WorldSession::HandleTrainerBuySpellOpcode(WorldPacket& recvData) recvData >> guid >> spellId; TC_LOG_DEBUG("network", "WORLD: Received CMSG_TRAINER_BUY_SPELL %s, learn spell id is: %u", guid.ToString().c_str(), spellId); - Creature* unit = GetPlayer()->GetNPCIfCanInteractWith(guid, UNIT_NPC_FLAG_TRAINER); - if (!unit) + Creature* trainer = GetPlayer()->GetNPCIfCanInteractWith(guid, UNIT_NPC_FLAG_TRAINER); + if (!trainer) { TC_LOG_DEBUG("network", "WORLD: HandleTrainerBuySpellOpcode - %s not found or you can not interact with him.", guid.ToString().c_str()); return; @@ -247,8 +247,20 @@ void WorldSession::HandleTrainerBuySpellOpcode(WorldPacket& recvData) if (GetPlayer()->HasUnitState(UNIT_STATE_DIED)) GetPlayer()->RemoveAurasByType(SPELL_AURA_FEIGN_DEATH); + // check race for mount trainers + if (trainer->GetCreatureTemplate()->trainer_type == TRAINER_TYPE_MOUNTS) + { + if (uint32 trainerRace = trainer->GetCreatureTemplate()->trainer_race) + if (_player->getRace() != trainerRace) + return; + } + + // check class for class trainers + if (_player->getClass() != trainer->GetCreatureTemplate()->trainer_class && trainer->GetCreatureTemplate()->trainer_type == TRAINER_TYPE_CLASS) + return; + // check present spell in trainer spell list - TrainerSpellData const* trainer_spells = unit->GetTrainerSpells(); + TrainerSpellData const* trainer_spells = trainer->GetTrainerSpells(); if (!trainer_spells) return; @@ -262,7 +274,7 @@ void WorldSession::HandleTrainerBuySpellOpcode(WorldPacket& recvData) return; // apply reputation discount - uint32 nSpellCost = uint32(floor(trainer_spell->spellCost * _player->GetReputationPriceDiscount(unit))); + uint32 nSpellCost = uint32(floor(trainer_spell->spellCost * _player->GetReputationPriceDiscount(trainer))); // check money requirement if (!_player->HasEnoughMoney(nSpellCost)) @@ -270,8 +282,8 @@ void WorldSession::HandleTrainerBuySpellOpcode(WorldPacket& recvData) _player->ModifyMoney(-int32(nSpellCost)); - unit->SendPlaySpellVisual(179); // 53 SpellCastDirected - unit->SendPlaySpellImpact(_player->GetGUID(), 362); // 113 EmoteSalute + trainer->SendPlaySpellVisual(179); // 53 SpellCastDirected + trainer->SendPlaySpellImpact(_player->GetGUID(), 362); // 113 EmoteSalute // learn explicitly or cast explicitly if (trainer_spell->IsCastable()) |