diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/server/game/Entities/Player/Player.cpp | 101 | ||||
-rw-r--r-- | src/server/game/Server/Packets/QuestPackets.cpp | 7 | ||||
-rw-r--r-- | src/server/game/Server/Packets/QuestPackets.h | 10 | ||||
-rw-r--r-- | src/server/game/Server/Protocol/Opcodes.cpp | 2 | ||||
-rw-r--r-- | src/server/game/World/World.cpp | 26 |
5 files changed, 77 insertions, 69 deletions
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index d0181dcf88e..6d52f3112bc 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -19232,6 +19232,9 @@ void Player::_LoadQuestStatus(PreparedQueryResult result) //// 0 1 2 3 4 //QueryResult* result = CharacterDatabase.PQuery("SELECT quest, status, explored, acceptTime, endTime WHERE guid = '{}' AND status <> 0", GetGUIDLow()); + time_t lastDailyReset = sWorld->GetNextDailyQuestsResetTime() - DAY; + time_t lastWeeklyReset = sWorld->GetNextWeeklyQuestsResetTime() - WEEK; + if (result) { do @@ -19241,63 +19244,73 @@ void Player::_LoadQuestStatus(PreparedQueryResult result) uint32 quest_id = fields[0].GetUInt32(); // used to be new, no delete? Quest const* quest = sObjectMgr->GetQuestTemplate(quest_id); - if (quest) + if (!quest) + continue; + + // find or create + QuestStatusData questStatusData; + + uint8 qstatus = fields[1].GetUInt8(); + if (qstatus < MAX_QUEST_STATUS) + questStatusData.Status = QuestStatus(qstatus); + else { - // find or create - auto questStatusItr = m_QuestStatus.emplace(quest_id, QuestStatusData{}).first; - QuestStatusData& questStatusData = questStatusItr->second; + questStatusData.Status = QUEST_STATUS_INCOMPLETE; + TC_LOG_ERROR("entities.player", "Player::_LoadQuestStatus: Player '{}' ({}) has invalid quest {} status ({}), replaced by QUEST_STATUS_INCOMPLETE(3).", + GetName(), GetGUID().ToString(), quest_id, qstatus); + } - uint8 qstatus = fields[1].GetUInt8(); - if (qstatus < MAX_QUEST_STATUS) - questStatusData.Status = QuestStatus(qstatus); - else + questStatusData.Explored = (fields[2].GetUInt8() > 0); + + questStatusData.AcceptTime = time_t(fields[3].GetInt64()); + if (quest->HasFlagEx(QUEST_FLAGS_EX_REMOVE_ON_PERIODIC_RESET)) + { + if ((quest->IsDaily() && questStatusData.AcceptTime < lastDailyReset) + || (quest->IsWeekly() && questStatusData.AcceptTime < lastWeeklyReset)) { - questStatusData.Status = QUEST_STATUS_INCOMPLETE; - TC_LOG_ERROR("entities.player", "Player::_LoadQuestStatus: Player '{}' ({}) has invalid quest {} status ({}), replaced by QUEST_STATUS_INCOMPLETE(3).", - GetName(), GetGUID().ToString(), quest_id, qstatus); + questStatusData.Status = QUEST_STATUS_NONE; + m_QuestStatusSave[quest_id] = QUEST_DELETE_SAVE_TYPE; + SendDirectMessage(WorldPackets::Quest::QuestForceRemoved(quest_id).Write()); } + } - questStatusData.Explored = (fields[2].GetUInt8() > 0); - - time_t acceptTime = time_t(fields[3].GetInt64()); - time_t endTime = time_t(fields[4].GetInt64()); + time_t endTime = time_t(fields[4].GetInt64()); - if (quest->GetLimitTime() && !GetQuestRewardStatus(quest_id)) - { - AddTimedQuest(quest_id); + if (quest->GetLimitTime() && !GetQuestRewardStatus(quest_id)) + { + AddTimedQuest(quest_id); - if (endTime <= GameTime::GetGameTime()) - questStatusData.Timer = 1; - else - questStatusData.Timer = uint32((endTime - GameTime::GetGameTime()) * IN_MILLISECONDS); - } + if (endTime <= GameTime::GetGameTime()) + questStatusData.Timer = 1; else - endTime = 0; + questStatusData.Timer = uint32((endTime - GameTime::GetGameTime()) * IN_MILLISECONDS); + } + else + endTime = 0; - // add to quest log - if (slot < MAX_QUEST_LOG_SIZE && questStatusData.Status != QUEST_STATUS_NONE) - { - questStatusData.Slot = slot; + TC_LOG_DEBUG("entities.player.loading", "Player::_LoadQuestStatus: Quest status is {{{}}} for quest {{{}}} for player ({})", questStatusData.Status, quest_id, GetGUID().ToString()); - for (QuestObjective const& obj : quest->GetObjectives()) - m_questObjectiveStatus.emplace(std::make_pair(QuestObjectiveType(obj.Type), obj.ObjectID), QuestObjectiveStatusData{ questStatusItr, obj.ID }); + // add to quest log + if (slot < MAX_QUEST_LOG_SIZE && questStatusData.Status != QUEST_STATUS_NONE) + { + questStatusData.Slot = slot; - SetQuestSlot(slot, quest_id); - SetQuestSlotEndTime(slot, endTime); - questStatusData.AcceptTime = acceptTime; + auto questStatusItr = m_QuestStatus.emplace(quest_id, std::move(questStatusData)).first; + for (QuestObjective const& obj : quest->GetObjectives()) + m_questObjectiveStatus.emplace(std::make_pair(QuestObjectiveType(obj.Type), obj.ObjectID), QuestObjectiveStatusData{ questStatusItr, obj.ID }); - if (questStatusData.Status == QUEST_STATUS_COMPLETE) - SetQuestSlotState(slot, QUEST_STATE_COMPLETE); - else if (questStatusData.Status == QUEST_STATUS_FAILED) - SetQuestSlotState(slot, QUEST_STATE_FAIL); + SetQuestSlot(slot, quest_id); + SetQuestSlotEndTime(slot, endTime); - if (quest->HasFlagEx(QUEST_FLAGS_EX_RECAST_ACCEPT_SPELL_ON_LOGIN) && quest->HasFlag(QUEST_FLAGS_PLAYER_CAST_ACCEPT) && quest->GetSrcSpell() > 0) - CastSpell(this, quest->GetSrcSpell(), TRIGGERED_FULL_MASK); + if (questStatusItr->second.Status == QUEST_STATUS_COMPLETE) + SetQuestSlotState(slot, QUEST_STATE_COMPLETE); + else if (questStatusItr->second.Status == QUEST_STATUS_FAILED) + SetQuestSlotState(slot, QUEST_STATE_FAIL); - ++slot; - } + if (quest->HasFlagEx(QUEST_FLAGS_EX_RECAST_ACCEPT_SPELL_ON_LOGIN) && quest->HasFlag(QUEST_FLAGS_PLAYER_CAST_ACCEPT) && quest->GetSrcSpell() > 0) + CastSpell(this, quest->GetSrcSpell(), TRIGGERED_FULL_MASK); - TC_LOG_DEBUG("entities.player.loading", "Player::_LoadQuestStatus: Quest status is {{{}}} for quest {{{}}} for player ({})", questStatusData.Status, quest_id, GetGUID().ToString()); + ++slot; } } while (result->NextRow()); @@ -24762,6 +24775,8 @@ void Player::DailyReset() if (quest->GetLimitTime()) RemoveTimedQuest(questId); + + SendDirectMessage(WorldPackets::Quest::QuestForceRemoved(questId).Write()); } // DB data deleted in caller @@ -24799,6 +24814,8 @@ void Player::ResetWeeklyQuestStatus() if (quest->GetLimitTime()) RemoveTimedQuest(questId); + + SendDirectMessage(WorldPackets::Quest::QuestForceRemoved(questId).Write()); } m_weeklyquests.clear(); diff --git a/src/server/game/Server/Packets/QuestPackets.cpp b/src/server/game/Server/Packets/QuestPackets.cpp index f270a1efd44..cefc2959e07 100644 --- a/src/server/game/Server/Packets/QuestPackets.cpp +++ b/src/server/game/Server/Packets/QuestPackets.cpp @@ -682,6 +682,13 @@ WorldPacket const* DailyQuestsReset::Write() return &_worldPacket; } +WorldPacket const* QuestForceRemoved::Write() +{ + _worldPacket << int32(QuestID); + + return &_worldPacket; +} + WorldPacket const* WorldQuestUpdateResponse::Write() { _worldPacket << uint32(WorldQuestUpdates.size()); diff --git a/src/server/game/Server/Packets/QuestPackets.h b/src/server/game/Server/Packets/QuestPackets.h index 1c30e309ecc..582144adcb2 100644 --- a/src/server/game/Server/Packets/QuestPackets.h +++ b/src/server/game/Server/Packets/QuestPackets.h @@ -648,6 +648,16 @@ namespace WorldPackets int32 Count = 0; }; + class QuestForceRemoved final : public ServerPacket + { + public: + explicit QuestForceRemoved(int32 questId) : ServerPacket(SMSG_QUEST_FORCE_REMOVED, 4), QuestID(questId) { } + + WorldPacket const* Write() override; + + int32 QuestID = 0; + }; + class RequestWorldQuestUpdate final : public ClientPacket { public: diff --git a/src/server/game/Server/Protocol/Opcodes.cpp b/src/server/game/Server/Protocol/Opcodes.cpp index 0494fe453f9..9a40d087df3 100644 --- a/src/server/game/Server/Protocol/Opcodes.cpp +++ b/src/server/game/Server/Protocol/Opcodes.cpp @@ -1885,7 +1885,7 @@ void OpcodeTable::Initialize() DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUERY_TIME_RESPONSE, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUEST_COMPLETION_NPC_RESPONSE, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUEST_CONFIRM_ACCEPT, STATUS_NEVER, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUEST_FORCE_REMOVED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUEST_FORCE_REMOVED, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUEST_GIVER_INVALID_QUEST, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUEST_GIVER_OFFER_REWARD_MESSAGE, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUEST_GIVER_QUEST_COMPLETE, STATUS_NEVER, CONNECTION_TYPE_REALM); diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index 71da70e292c..77f7801446b 100644 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -3531,19 +3531,6 @@ void World::DailyReset() if (Player* player = itr->second->GetPlayer()) player->DailyReset(); - { - std::ostringstream questIds; - questIds << "DELETE cq, cqo FROM character_queststatus cq LEFT JOIN character_queststatus_objectives cqo ON cq.quest = cqo.quest WHERE cq.quest IN ("; - for (auto const& [questId, quest] : sObjectMgr->GetQuestTemplates()) - { - if (quest.IsDaily() && quest.HasFlagEx(QUEST_FLAGS_EX_REMOVE_ON_PERIODIC_RESET)) - questIds << questId << ','; - } - questIds << "0)"; - - CharacterDatabase.Execute(questIds.str().c_str()); - } - // reselect pools sQuestPoolMgr->ChangeDailyQuests(); @@ -3580,19 +3567,6 @@ void World::ResetWeeklyQuests() if (Player* player = itr->second->GetPlayer()) player->ResetWeeklyQuestStatus(); - { - std::ostringstream questIds; - questIds << "DELETE cq, cqo FROM character_queststatus cq LEFT JOIN character_queststatus_objectives cqo ON cq.quest = cqo.quest WHERE cq.quest IN ("; - for (auto const& [questId, quest] : sObjectMgr->GetQuestTemplates()) - { - if (quest.IsWeekly() && quest.HasFlagEx(QUEST_FLAGS_EX_REMOVE_ON_PERIODIC_RESET)) - questIds << questId << ','; - } - questIds << "0)"; - - CharacterDatabase.Execute(questIds.str().c_str()); - } - // reselect pools sQuestPoolMgr->ChangeWeeklyQuests(); |