aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/server/game/Entities/Player/Player.cpp101
-rw-r--r--src/server/game/Server/Packets/QuestPackets.cpp7
-rw-r--r--src/server/game/Server/Packets/QuestPackets.h10
-rw-r--r--src/server/game/Server/Protocol/Opcodes.cpp2
-rw-r--r--src/server/game/World/World.cpp26
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();