Core/Quests: Removed slow queries from daily and weekly resets

Closes #29146
This commit is contained in:
Shauren
2023-12-31 00:42:19 +01:00
parent 3dbd171399
commit ee7b0e82fa
5 changed files with 82 additions and 74 deletions

View File

@@ -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);
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_NONE;
m_QuestStatusSave[quest_id] = QUEST_DELETE_SAVE_TYPE;
SendDirectMessage(WorldPackets::Quest::QuestForceRemoved(quest_id).Write());
}
}
time_t endTime = time_t(fields[4].GetInt64());
if (quest->GetLimitTime() && !GetQuestRewardStatus(quest_id))
{
AddTimedQuest(quest_id);
if (endTime <= GameTime::GetGameTime())
questStatusData.Timer = 1;
else
{
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.Timer = uint32((endTime - GameTime::GetGameTime()) * IN_MILLISECONDS);
}
else
endTime = 0;
questStatusData.Explored = (fields[2].GetUInt8() > 0);
TC_LOG_DEBUG("entities.player.loading", "Player::_LoadQuestStatus: Quest status is {{{}}} for quest {{{}}} for player ({})", questStatusData.Status, quest_id, GetGUID().ToString());
time_t acceptTime = time_t(fields[3].GetInt64());
time_t endTime = time_t(fields[4].GetInt64());
// add to quest log
if (slot < MAX_QUEST_LOG_SIZE && questStatusData.Status != QUEST_STATUS_NONE)
{
questStatusData.Slot = slot;
if (quest->GetLimitTime() && !GetQuestRewardStatus(quest_id))
{
AddTimedQuest(quest_id);
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 (endTime <= GameTime::GetGameTime())
questStatusData.Timer = 1;
else
questStatusData.Timer = uint32((endTime - GameTime::GetGameTime()) * IN_MILLISECONDS);
}
else
endTime = 0;
SetQuestSlot(slot, quest_id);
SetQuestSlotEndTime(slot, endTime);
// add to quest log
if (slot < MAX_QUEST_LOG_SIZE && questStatusData.Status != QUEST_STATUS_NONE)
{
questStatusData.Slot = slot;
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);
for (QuestObjective const& obj : quest->GetObjectives())
m_questObjectiveStatus.emplace(std::make_pair(QuestObjectiveType(obj.Type), obj.ObjectID), QuestObjectiveStatusData{ questStatusItr, obj.ID });
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);
SetQuestSlot(slot, quest_id);
SetQuestSlotEndTime(slot, endTime);
questStatusData.AcceptTime = acceptTime;
if (questStatusData.Status == QUEST_STATUS_COMPLETE)
SetQuestSlotState(slot, QUEST_STATE_COMPLETE);
else if (questStatusData.Status == QUEST_STATUS_FAILED)
SetQuestSlotState(slot, QUEST_STATE_FAIL);
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);
++slot;
}
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();

View File

@@ -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());

View File

@@ -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:

View File

@@ -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);

View File

@@ -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();