diff options
Diffstat (limited to 'src/server/game/Handlers/QuestHandler.cpp')
-rw-r--r-- | src/server/game/Handlers/QuestHandler.cpp | 173 |
1 files changed, 98 insertions, 75 deletions
diff --git a/src/server/game/Handlers/QuestHandler.cpp b/src/server/game/Handlers/QuestHandler.cpp index 97e13d52913..3efb127bc4f 100644 --- a/src/server/game/Handlers/QuestHandler.cpp +++ b/src/server/game/Handlers/QuestHandler.cpp @@ -37,8 +37,8 @@ void WorldSession::HandleQuestgiverStatusQueryOpcode(WorldPacket& recvData) { uint64 guid; recvData >> guid; - uint8 questStatus = DIALOG_STATUS_NONE; - uint8 defstatus = DIALOG_STATUS_NONE; + uint32 questStatus = DIALOG_STATUS_NONE; + uint32 defstatus = DIALOG_STATUS_NONE; Object* questgiver = ObjectAccessor::GetObjectByTypeMask(*_player, guid, TYPEMASK_UNIT|TYPEMASK_GAMEOBJECT); if (!questgiver) @@ -295,74 +295,87 @@ void WorldSession::HandleQuestgiverChooseRewardOpcode(WorldPacket& recvData) sLog->outDebug(LOG_FILTER_NETWORKIO, "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)) + Quest const* quest = sObjectMgr->GetQuestTemplate(questId); + if (!quest) return; - // some kind of WPE protection - if (!_player->CanInteractWithQuestGiver(object)) - return; + Object* object = _player; - if (Quest const* quest = sObjectMgr->GetQuestTemplate(questId)) + if (!quest->HasFlag(QUEST_FLAGS_AUTO_SUBMIT)) { - if ((!_player->CanSeeStartQuest(quest) && _player->GetQuestStatus(questId) == QUEST_STATUS_NONE) || - (_player->GetQuestStatus(questId) != QUEST_STATUS_COMPLETE && !quest->IsAutoComplete())) - { - sLog->outError(LOG_FILTER_NETWORKIO, "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); + object = ObjectAccessor::GetObjectByTypeMask(*_player, guid, TYPEMASK_UNIT|TYPEMASK_GAMEOBJECT); + if (!object || !object->hasInvolvedQuest(questId)) return; - } - if (_player->CanRewardQuest(quest, reward, true)) - { - _player->RewardQuest(quest, reward, object); - switch (object->GetTypeId()) + // some kind of WPE protection + if (!_player->CanInteractWithQuestGiver(object)) + return; + } + + if ((!_player->CanSeeStartQuest(quest) && _player->GetQuestStatus(questId) == QUEST_STATUS_NONE) || + (_player->GetQuestStatus(questId) != QUEST_STATUS_COMPLETE && !quest->IsAutoComplete())) + { + sLog->outError(LOG_FILTER_NETWORKIO, "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: + case TYPEID_PLAYER: { - case TYPEID_UNIT: - if (!(sScriptMgr->OnQuestReward(_player, (object->ToCreature()), quest, reward))) + //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, reward))) + { + // Send next quest + if (Quest const* nextQuest = _player->GetNextQuest(guid, quest)) { - // Send next quest - if (Quest const* nextQuest = _player->GetNextQuest(guid, quest)) + if (nextQuest->IsAutoAccept() && _player->CanAddQuest(nextQuest, true) && _player->CanTakeQuest(nextQuest, true)) { - if (nextQuest->IsAutoAccept() && _player->CanAddQuest(nextQuest, true) && _player->CanTakeQuest(nextQuest, true)) - { - _player->AddQuest(nextQuest, object); - if (_player->CanCompleteQuest(nextQuest->GetQuestId())) - _player->CompleteQuest(nextQuest->GetQuestId()); - } - - _player->PlayerTalkClass->SendQuestGiverQuestDetails(nextQuest, guid, true); + _player->AddQuest(nextQuest, object); + if (_player->CanCompleteQuest(nextQuest->GetQuestId())) + _player->CompleteQuest(nextQuest->GetQuestId()); } - (object->ToCreature())->AI()->sQuestReward(_player, quest, reward); + _player->PlayerTalkClass->SendQuestGiverQuestDetails(nextQuest, guid, true); } - break; - case TYPEID_GAMEOBJECT: - if (!sScriptMgr->OnQuestReward(_player, ((GameObject*)object), quest, reward)) + + if (creatureQGiver) + creatureQGiver->AI()->sQuestReward(_player, quest, reward); + } + break; + } + case TYPEID_GAMEOBJECT: + if (!sScriptMgr->OnQuestReward(_player, ((GameObject*)object), quest, reward)) + { + // Send next quest + if (Quest const* nextQuest = _player->GetNextQuest(guid, quest)) { - // Send next quest - if (Quest const* nextQuest = _player->GetNextQuest(guid, quest)) + if (nextQuest->IsAutoAccept() && _player->CanAddQuest(nextQuest, true) && _player->CanTakeQuest(nextQuest, true)) { - if (nextQuest->IsAutoAccept() && _player->CanAddQuest(nextQuest, true) && _player->CanTakeQuest(nextQuest, true)) - { - _player->AddQuest(nextQuest, object); - if (_player->CanCompleteQuest(nextQuest->GetQuestId())) - _player->CompleteQuest(nextQuest->GetQuestId()); - } - - _player->PlayerTalkClass->SendQuestGiverQuestDetails(nextQuest, guid, true); + _player->AddQuest(nextQuest, object); + if (_player->CanCompleteQuest(nextQuest->GetQuestId())) + _player->CompleteQuest(nextQuest->GetQuestId()); } - object->ToGameObject()->AI()->QuestReward(_player, quest, reward); + _player->PlayerTalkClass->SendQuestGiverQuestDetails(nextQuest, guid, true); } - break; - default: - break; - } + + object->ToGameObject()->AI()->QuestReward(_player, quest, reward); + } + break; + default: + break; } - else - _player->PlayerTalkClass->SendQuestGiverOfferReward(quest, guid, true); } + else + _player->PlayerTalkClass->SendQuestGiverOfferReward(quest, guid, true); } void WorldSession::HandleQuestgiverRequestRewardOpcode(WorldPacket& recvData) @@ -427,7 +440,7 @@ void WorldSession::HandleQuestLogRemoveQuest(WorldPacket& recvData) if (Quest const* quest = sObjectMgr->GetQuestTemplate(questId)) { - if (quest->HasFlag(QUEST_TRINITY_FLAGS_TIMED)) + if (quest->HasSpecialFlag(QUEST_SPECIAL_FLAGS_TIMED)) _player->RemoveTimedQuest(questId); if (quest->HasFlag(QUEST_FLAGS_FLAGS_PVP)) @@ -455,7 +468,7 @@ void WorldSession::HandleQuestConfirmAccept(WorldPacket& recvData) uint32 questId; recvData >> questId; - sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_QUEST_CONFIRM_ACCEPT quest = %u", questId); + sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_QUEST_CONFIRM_ACCEPT questId = %u", questId); if (const Quest* quest = sObjectMgr->GetQuestTemplate(questId)) { @@ -480,25 +493,35 @@ void WorldSession::HandleQuestConfirmAccept(WorldPacket& recvData) void WorldSession::HandleQuestgiverCompleteQuest(WorldPacket& recvData) { uint32 questId; - uint64 guid; + uint64 playerGuid; + bool autoCompleteMode; // 0 - standart complete quest mode with npc, 1 - auto-complete mode + recvData >> playerGuid >> questId >> autoCompleteMode; - recvData >> guid >> questId; + sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_QUESTGIVER_COMPLETE_QUEST npc = %u, questId = %u", uint32(GUID_LOPART(playerGuid)), questId); - sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_QUESTGIVER_COMPLETE_QUEST npc = %u, quest = %u", uint32(GUID_LOPART(guid)), questId); - - Object* object = ObjectAccessor::GetObjectByTypeMask(*_player, guid, TYPEMASK_UNIT|TYPEMASK_GAMEOBJECT); - if (!object || !object->hasInvolvedQuest(questId)) - return; + if (autoCompleteMode == 0) + { + Object* object = ObjectAccessor::GetObjectByTypeMask(*_player, playerGuid, TYPEMASK_UNIT|TYPEMASK_GAMEOBJECT); + if (!object || !object->hasInvolvedQuest(questId)) + return; - // some kind of WPE protection - if (!_player->CanInteractWithQuestGiver(object)) - return; + // some kind of WPE protection + if (!_player->CanInteractWithQuestGiver(object)) + return; + } if (Quest const* quest = sObjectMgr->GetQuestTemplate(questId)) { + if (autoCompleteMode && !quest->HasFlag(QUEST_FLAGS_AUTO_SUBMIT)) + { + sLog->outError(LOG_FILTER_NETWORKIO, "Possible hacking attempt: Player %s [playerGuid: %u] tried to complete questId [entry: %u] by auto-submit flag for quest witch not suport it.", + _player->GetName().c_str(), _player->GetGUIDLow(), questId); + return; + } + if (!_player->CanSeeStartQuest(quest) && _player->GetQuestStatus(questId) == QUEST_STATUS_NONE) { - sLog->outError(LOG_FILTER_NETWORKIO, "Possible hacking attempt: Player %s [guid: %u] tried to complete quest [entry: %u] without being in possession of the quest!", + sLog->outError(LOG_FILTER_NETWORKIO, "Possible hacking attempt: Player %s [playerGuid: %u] tried to complete questId [entry: %u] without being in possession of the questId!", _player->GetName().c_str(), _player->GetGUIDLow(), questId); return; } @@ -511,16 +534,16 @@ void WorldSession::HandleQuestgiverCompleteQuest(WorldPacket& recvData) if (_player->GetQuestStatus(questId) != QUEST_STATUS_COMPLETE) { if (quest->IsRepeatable()) - _player->PlayerTalkClass->SendQuestGiverRequestItems(quest, guid, _player->CanCompleteRepeatableQuest(quest), false); + _player->PlayerTalkClass->SendQuestGiverRequestItems(quest, playerGuid, _player->CanCompleteRepeatableQuest(quest), false); else - _player->PlayerTalkClass->SendQuestGiverRequestItems(quest, guid, _player->CanRewardQuest(quest, false), false); + _player->PlayerTalkClass->SendQuestGiverRequestItems(quest, playerGuid, _player->CanRewardQuest(quest, false), false); } else { if (quest->GetReqItemsCount()) // some items required - _player->PlayerTalkClass->SendQuestGiverRequestItems(quest, guid, _player->CanRewardQuest(quest, false), false); + _player->PlayerTalkClass->SendQuestGiverRequestItems(quest, playerGuid, _player->CanRewardQuest(quest, false), false); else // no items required - _player->PlayerTalkClass->SendQuestGiverOfferReward(quest, guid, true); + _player->PlayerTalkClass->SendQuestGiverOfferReward(quest, playerGuid, !autoCompleteMode); } } } @@ -535,7 +558,7 @@ void WorldSession::HandlePushQuestToParty(WorldPacket& recvPacket) uint32 questId; recvPacket >> questId; - sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_PUSHQUESTTOPARTY quest = %u", questId); + sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_PUSHQUESTTOPARTY questId = %u", questId); if (Quest const* quest = sObjectMgr->GetQuestTemplate(questId)) { @@ -713,13 +736,13 @@ void WorldSession::HandleQuestgiverStatusMultipleQuery(WorldPacket& /*recvPacket uint32 count = 0; - WorldPacket data(SMSG_QUESTGIVER_STATUS_MULTIPLE, 4); + WorldPacket data(SMSG_QUESTGIVER_STATUS_MULTIPLE, 4 + 8 + 4); data << uint32(count); // placeholder for (Player::ClientGUIDs::const_iterator itr = _player->m_clientGUIDs.begin(); itr != _player->m_clientGUIDs.end(); ++itr) { - uint8 questStatus = DIALOG_STATUS_NONE; - uint8 defstatus = DIALOG_STATUS_NONE; + uint32 questStatus = DIALOG_STATUS_NONE; + uint32 defstatus = DIALOG_STATUS_NONE; if (IS_CRE_OR_VEH_OR_PET_GUID(*itr)) { @@ -734,7 +757,7 @@ void WorldSession::HandleQuestgiverStatusMultipleQuery(WorldPacket& /*recvPacket questStatus = getDialogStatus(_player, questgiver, defstatus); data << uint64(questgiver->GetGUID()); - data << uint8(questStatus); + data << uint32(questStatus); ++count; } else if (IS_GAMEOBJECT_GUID(*itr)) @@ -749,7 +772,7 @@ void WorldSession::HandleQuestgiverStatusMultipleQuery(WorldPacket& /*recvPacket questStatus = getDialogStatus(_player, questgiver, defstatus); data << uint64(questgiver->GetGUID()); - data << uint8(questStatus); + data << uint32(questStatus); ++count; } } @@ -758,7 +781,7 @@ void WorldSession::HandleQuestgiverStatusMultipleQuery(WorldPacket& /*recvPacket SendPacket(&data); } -void WorldSession::HandleQueryQuestsCompleted(WorldPacket & /*recvData*/) +void WorldSession::HandleQueryQuestsCompleted(WorldPacket& /*recvData*/) { size_t rew_count = _player->GetRewardedQuestCount(); |