aboutsummaryrefslogtreecommitdiff
path: root/src/server/game/Handlers/QuestHandler.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/server/game/Handlers/QuestHandler.cpp')
-rw-r--r--src/server/game/Handlers/QuestHandler.cpp173
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();