void WorldSession::HandleGameobjectReportUse(WorldPackets::GameObject::GameObjReportUse& packet) { // ignore for remote control state if (_player->m_mover != _player) return; GameObject* go = GetPlayer()->GetMap()->GetGameObject(packet.Guid); if (!go) return; if (!go->IsWithinDistInMap(_player, INTERACTION_DISTANCE)) return; if (go->AI()->GossipHello(_player)) return; _player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_USE_GAMEOBJECT, go->GetEntry()); }
void WorldSession::HandleQuestgiverChooseRewardOpcode(WorldPackets::Quest::QuestGiverChooseReward& packet) { TC_LOG_DEBUG("network", "WORLD: Received CMSG_QUESTGIVER_CHOOSE_REWARD npc = %s, quest = %u, reward = %u", packet.QuestGiverGUID.ToString().c_str(), packet.QuestID, packet.ItemChoiceID); Quest const* quest = sObjectMgr->GetQuestTemplate(packet.QuestID); if (!quest) return; // This is Real Item Entry, not slot id as pre 5.x if (packet.ItemChoiceID) { ItemTemplate const* rewardProto = sObjectMgr->GetItemTemplate(packet.ItemChoiceID); if (!rewardProto) { TC_LOG_ERROR("network", "Error in CMSG_QUESTGIVER_CHOOSE_REWARD: player %s (%s) tried to get invalid reward item (Item Entry: %u) for quest %u (possible packet-hacking detected)", _player->GetName().c_str(), _player->GetGUID().ToString().c_str(), packet.ItemChoiceID, packet.QuestID); return; } bool itemValid = false; for (uint32 i = 0; i < quest->GetRewChoiceItemsCount(); ++i) { if (quest->RewardChoiceItemId[i] && quest->RewardChoiceItemId[i] == uint32(packet.ItemChoiceID)) { itemValid = true; break; } } if (!itemValid && quest->GetQuestPackageID()) { if (std::vector<QuestPackageItemEntry const*> const* questPackageItems = sDB2Manager.GetQuestPackageItems(quest->GetQuestPackageID())) { for (QuestPackageItemEntry const* questPackageItem : *questPackageItems) { if (questPackageItem->ItemID != uint32(packet.ItemChoiceID)) continue; rewardProto = sObjectMgr->GetItemTemplate(questPackageItem->ItemID); if (rewardProto) { if (rewardProto->CanWinForPlayer(_player)) { itemValid = true; break; } } } } } if (!itemValid) { TC_LOG_ERROR("network", "Error in CMSG_QUESTGIVER_CHOOSE_REWARD: player %s (%s) tried to get reward item (Item Entry: %u) wich is not a reward for quest %u (possible packet-hacking detected)", _player->GetName().c_str(), _player->GetGUID().ToString().c_str(), packet.ItemChoiceID, packet.QuestID); return; } } Object* object = _player; if (!quest->HasFlag(QUEST_FLAGS_AUTOCOMPLETE)) { object = ObjectAccessor::GetObjectByTypeMask(*_player, packet.QuestGiverGUID, TYPEMASK_UNIT|TYPEMASK_GAMEOBJECT); if (!object || !object->hasInvolvedQuest(packet.QuestID)) return; // some kind of WPE protection if (!_player->CanInteractWithQuestGiver(object)) return; } if ((!_player->CanSeeStartQuest(quest) && _player->GetQuestStatus(packet.QuestID) == QUEST_STATUS_NONE) || (_player->GetQuestStatus(packet.QuestID) != QUEST_STATUS_COMPLETE && !quest->IsAutoComplete())) { TC_LOG_ERROR("network", "Error in QUEST_STATUS_COMPLETE: player %s (%s) tried to complete quest %u, but is not allowed to do so (possible packet-hacking or high latency)", _player->GetName().c_str(), _player->GetGUID().ToString().c_str(), packet.QuestID); return; } if (_player->CanRewardQuest(quest, packet.ItemChoiceID, true)) { _player->RewardQuest(quest, packet.ItemChoiceID, object); switch (object->GetTypeId()) { case TYPEID_UNIT: case TYPEID_PLAYER: { //For AutoSubmition was added plr case there as it almost same exclute AI script cases. Creature* creatureQGiver = object->ToCreature(); if (!creatureQGiver || !sScriptMgr->OnQuestReward(_player, creatureQGiver, quest, packet.ItemChoiceID)) { // Send next quest if (Quest const* nextQuest = _player->GetNextQuest(packet.QuestGiverGUID, quest)) { // Only send the quest to the player if the conditions are met if (_player->CanTakeQuest(nextQuest, false)) { if (nextQuest->IsAutoAccept() && _player->CanAddQuest(nextQuest, true)) _player->AddQuestAndCheckCompletion(nextQuest, object); _player->PlayerTalkClass->SendQuestGiverQuestDetails(nextQuest, packet.QuestGiverGUID, true); } } if (creatureQGiver) creatureQGiver->AI()->sQuestReward(_player, quest, packet.ItemChoiceID); } break; } case TYPEID_GAMEOBJECT: { GameObject* questGiver = object->ToGameObject(); if (!sScriptMgr->OnQuestReward(_player, questGiver, quest, packet.ItemChoiceID)) { // Send next quest if (Quest const* nextQuest = _player->GetNextQuest(packet.QuestGiverGUID, quest)) { // Only send the quest to the player if the conditions are met if (_player->CanTakeQuest(nextQuest, false)) { if (nextQuest->IsAutoAccept() && _player->CanAddQuest(nextQuest, true)) _player->AddQuestAndCheckCompletion(nextQuest, object); _player->PlayerTalkClass->SendQuestGiverQuestDetails(nextQuest, packet.QuestGiverGUID, true); } } questGiver->AI()->QuestReward(_player, quest, packet.ItemChoiceID); } break; } default: break; } } else _player->PlayerTalkClass->SendQuestGiverOfferReward(quest, packet.QuestGiverGUID, true); }
void WorldSession::HandleQuestgiverChooseRewardOpcode(WorldPacket& recvData) { uint32 questId, reward; uint64 guid; recvData >> guid >> questId >> reward; if (reward >= QUEST_REWARD_CHOICES_COUNT) { TC_LOG_ERROR("network", "Error in CMSG_QUESTGIVER_CHOOSE_REWARD: player %s (guid %d) tried to get invalid reward (%u) (possible packet-hacking detected)", _player->GetName().c_str(), _player->GetGUIDLow(), reward); return; } TC_LOG_DEBUG("network", "WORLD: Received CMSG_QUESTGIVER_CHOOSE_REWARD npc = %u, quest = %u, reward = %u", uint32(GUID_LOPART(guid)), questId, reward); Object* object = ObjectAccessor::GetObjectByTypeMask(*_player, guid, TYPEMASK_UNIT | TYPEMASK_GAMEOBJECT); if (!object || !object->hasInvolvedQuest(questId)) return; // some kind of WPE protection if (!_player->CanInteractWithQuestGiver(object)) return; if (Quest const* quest = sObjectMgr->GetQuestTemplate(questId)) { if ((!_player->CanSeeStartQuest(quest) && _player->GetQuestStatus(questId) == QUEST_STATUS_NONE) || (_player->GetQuestStatus(questId) != QUEST_STATUS_COMPLETE && !quest->IsAutoComplete())) { TC_LOG_ERROR("network", "Error in QUEST_STATUS_COMPLETE: player %s (guid %u) tried to complete quest %u, but is not allowed to do so (possible packet-hacking or high latency)", _player->GetName().c_str(), _player->GetGUIDLow(), questId); return; } if (_player->CanRewardQuest(quest, reward, true)) { _player->RewardQuest(quest, reward, object); switch (object->GetTypeId()) { case TYPEID_UNIT: { Creature* questgiver = object->ToCreature(); if (!sScriptMgr->OnQuestReward(_player, questgiver, quest, reward)) { // Send next quest if (Quest const* nextQuest = _player->GetNextQuest(guid, quest)) { // Only send the quest to the player if the conditions are met if (_player->CanTakeQuest(nextQuest, true)) { if (nextQuest->IsAutoAccept() && _player->CanAddQuest(nextQuest, true)) _player->AddQuestAndCheckCompletion(nextQuest, object); _player->PlayerTalkClass->SendQuestGiverQuestDetails(nextQuest, guid, true); } } questgiver->AI()->sQuestReward(_player, quest, reward); } break; } case TYPEID_GAMEOBJECT: { GameObject* questGiver = object->ToGameObject(); if (!sScriptMgr->OnQuestReward(_player, questGiver, quest, reward)) { // Send next quest if (Quest const* nextQuest = _player->GetNextQuest(guid, quest)) { // Only send the quest to the player if the conditions are met if (_player->CanTakeQuest(nextQuest, true)) { if (nextQuest->IsAutoAccept() && _player->CanAddQuest(nextQuest, true)) _player->AddQuestAndCheckCompletion(nextQuest, object); _player->PlayerTalkClass->SendQuestGiverQuestDetails(nextQuest, guid, true); } } questGiver->AI()->QuestReward(_player, quest, reward); } break; } default: break; } } else _player->PlayerTalkClass->SendQuestGiverOfferReward(quest, guid, true); } }
void WorldSession::HandleGossipSelectOptionOpcode(WorldPackets::NPC::GossipSelectOption& packet) { if (!_player->PlayerTalkClass->GetGossipMenu().GetItem(packet.GossipIndex)) return; // Prevent cheating on C++ scripted menus if (_player->PlayerTalkClass->GetGossipMenu().GetSenderGUID() != packet.GossipUnit) return; Creature* unit = nullptr; GameObject* go = nullptr; if (packet.GossipUnit.IsCreatureOrVehicle()) { unit = GetPlayer()->GetNPCIfCanInteractWith(packet.GossipUnit, UNIT_NPC_FLAG_NONE); if (!unit) { TC_LOG_DEBUG("network", "WORLD: HandleGossipSelectOptionOpcode - %s not found or you can't interact with him.", packet.GossipUnit.ToString().c_str()); return; } } else if (packet.GossipUnit.IsGameObject()) { go = _player->GetMap()->GetGameObject(packet.GossipUnit); if (!go) { TC_LOG_DEBUG("network", "WORLD: HandleGossipSelectOptionOpcode - %s not found.", packet.GossipUnit.ToString().c_str()); return; } } else { TC_LOG_DEBUG("network", "WORLD: HandleGossipSelectOptionOpcode - unsupported %s.", packet.GossipUnit.ToString().c_str()); return; } // remove fake death if (GetPlayer()->HasUnitState(UNIT_STATE_DIED)) GetPlayer()->RemoveAurasByType(SPELL_AURA_FEIGN_DEATH); if ((unit && unit->GetCreatureTemplate()->ScriptID != unit->LastUsedScriptID) || (go && go->GetGOInfo()->ScriptId != go->LastUsedScriptID)) { TC_LOG_DEBUG("network", "WORLD: HandleGossipSelectOptionOpcode - Script reloaded while in use, ignoring and set new scipt id"); if (unit) unit->LastUsedScriptID = unit->GetCreatureTemplate()->ScriptID; if (go) go->LastUsedScriptID = go->GetGOInfo()->ScriptId; _player->PlayerTalkClass->SendCloseGossip(); return; } if (!packet.PromotionCode.empty()) { if (unit) { unit->AI()->sGossipSelectCode(_player, packet.GossipID, packet.GossipIndex, packet.PromotionCode.c_str()); if (!sScriptMgr->OnGossipSelectCode(_player, unit, _player->PlayerTalkClass->GetGossipOptionSender(packet.GossipIndex), _player->PlayerTalkClass->GetGossipOptionAction(packet.GossipIndex), packet.PromotionCode.c_str())) _player->OnGossipSelect(unit, packet.GossipIndex, packet.GossipID); } else { go->AI()->GossipSelectCode(_player, packet.GossipID, packet.GossipIndex, packet.PromotionCode.c_str()); if (!sScriptMgr->OnGossipSelectCode(_player, go, _player->PlayerTalkClass->GetGossipOptionSender(packet.GossipIndex), _player->PlayerTalkClass->GetGossipOptionAction(packet.GossipIndex), packet.PromotionCode.c_str())) _player->OnGossipSelect(go, packet.GossipIndex, packet.GossipID); } } else { if (unit) { unit->AI()->sGossipSelect(_player, packet.GossipID, packet.GossipIndex); if (!sScriptMgr->OnGossipSelect(_player, unit, _player->PlayerTalkClass->GetGossipOptionSender(packet.GossipIndex), _player->PlayerTalkClass->GetGossipOptionAction(packet.GossipIndex))) _player->OnGossipSelect(unit, packet.GossipIndex, packet.GossipID); } else { go->AI()->GossipSelect(_player, packet.GossipID, packet.GossipIndex); if (!sScriptMgr->OnGossipSelect(_player, go, _player->PlayerTalkClass->GetGossipOptionSender(packet.GossipIndex), _player->PlayerTalkClass->GetGossipOptionAction(packet.GossipIndex))) _player->OnGossipSelect(go, packet.GossipIndex, packet.GossipID); } } }
void WorldSession::HandleQuestgiverChooseRewardOpcode(WorldPackets::Quest::QuestGiverChooseReward& packet) { if (packet.ItemChoiceID >= QUEST_REWARD_CHOICES_COUNT) { TC_LOG_ERROR("network", "Error in CMSG_QUESTGIVER_CHOOSE_REWARD: player %s (%s) tried to get invalid reward (%u) (possible packet-hacking detected)", _player->GetName().c_str(), _player->GetGUID().ToString().c_str(), packet.ItemChoiceID); return; } TC_LOG_DEBUG("network", "WORLD: Received CMSG_QUESTGIVER_CHOOSE_REWARD npc = %s, quest = %u, reward = %u", packet.QuestGiverGUID.ToString().c_str(), packet.QuestID, packet.ItemChoiceID); Quest const* quest = sObjectMgr->GetQuestTemplate(packet.QuestID); if (!quest) return; Object* object = _player; if (!quest->HasFlag(QUEST_FLAGS_AUTOCOMPLETE)) { object = ObjectAccessor::GetObjectByTypeMask(*_player, packet.QuestGiverGUID, TYPEMASK_UNIT|TYPEMASK_GAMEOBJECT); if (!object || !object->hasInvolvedQuest(packet.QuestID)) return; // some kind of WPE protection if (!_player->CanInteractWithQuestGiver(object)) return; } if ((!_player->CanSeeStartQuest(quest) && _player->GetQuestStatus(packet.QuestID) == QUEST_STATUS_NONE) || (_player->GetQuestStatus(packet.QuestID) != QUEST_STATUS_COMPLETE && !quest->IsAutoComplete())) { TC_LOG_ERROR("network", "Error in QUEST_STATUS_COMPLETE: player %s (%s) tried to complete quest %u, but is not allowed to do so (possible packet-hacking or high latency)", _player->GetName().c_str(), _player->GetGUID().ToString().c_str(), packet.QuestID); return; } if (_player->CanRewardQuest(quest, packet.ItemChoiceID, true)) { _player->RewardQuest(quest, packet.ItemChoiceID, object); switch (object->GetTypeId()) { case TYPEID_UNIT: case TYPEID_PLAYER: { //For AutoSubmition was added plr case there as it almost same exclute AI script cases. Creature* creatureQGiver = object->ToCreature(); if (!creatureQGiver || !sScriptMgr->OnQuestReward(_player, creatureQGiver, quest, packet.ItemChoiceID)) { // Send next quest if (Quest const* nextQuest = _player->GetNextQuest(packet.QuestGiverGUID, quest)) { // Only send the quest to the player if the conditions are met if (_player->CanTakeQuest(nextQuest, false)) { if (nextQuest->IsAutoAccept() && _player->CanAddQuest(nextQuest, true)) _player->AddQuestAndCheckCompletion(nextQuest, object); _player->PlayerTalkClass->SendQuestGiverQuestDetails(nextQuest, packet.QuestGiverGUID, true); } } if (creatureQGiver) creatureQGiver->AI()->sQuestReward(_player, quest, packet.ItemChoiceID); } break; } case TYPEID_GAMEOBJECT: { GameObject* questGiver = object->ToGameObject(); if (!sScriptMgr->OnQuestReward(_player, questGiver, quest, packet.ItemChoiceID)) { // Send next quest if (Quest const* nextQuest = _player->GetNextQuest(packet.QuestGiverGUID, quest)) { // Only send the quest to the player if the conditions are met if (_player->CanTakeQuest(nextQuest, false)) { if (nextQuest->IsAutoAccept() && _player->CanAddQuest(nextQuest, true)) _player->AddQuestAndCheckCompletion(nextQuest, object); _player->PlayerTalkClass->SendQuestGiverQuestDetails(nextQuest, packet.QuestGiverGUID, true); } } questGiver->AI()->QuestReward(_player, quest, packet.ItemChoiceID); } break; } default: break; } } else _player->PlayerTalkClass->SendQuestGiverOfferReward(quest, packet.QuestGiverGUID, true); }