Core/Players: Fix possible (exploitable) data desynchronisation that would lead to repeating the same quest while already having received the rewards.
This commit is contained in:
@@ -14960,17 +14960,24 @@ void Player::RewardQuest(Quest const *pQuest, uint32 reward, Object* questGiver,
|
||||
GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_DAILY_QUEST, quest_id);
|
||||
GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_DAILY_QUEST_DAILY, quest_id);
|
||||
}
|
||||
} else if (pQuest->IsWeekly())
|
||||
}
|
||||
else if (pQuest->IsWeekly())
|
||||
SetWeeklyQuestStatus(quest_id);
|
||||
|
||||
RemoveActiveQuest(quest_id);
|
||||
m_RewardedQuests.insert(quest_id);
|
||||
m_RewardedQuestsSave[quest_id] = true;
|
||||
|
||||
// StoreNewItem, mail reward, etc. save data directly to the database
|
||||
// to prevent exploitable data desynchronisation we save the quest status to the database too
|
||||
// (to prevent rewarding this quest another time while rewards were already given out)
|
||||
SQLTransaction trans = SQLTransaction(NULL);
|
||||
_SaveQuestStatus(trans);
|
||||
|
||||
if (announce)
|
||||
SendQuestReward(pQuest, XP, questGiver);
|
||||
|
||||
// cast spells after mark quest complete (some spells have quest completed state reqyurements in spell_area data)
|
||||
// cast spells after mark quest complete (some spells have quest completed state requirements in spell_area data)
|
||||
if (pQuest->GetRewSpellCast() > 0)
|
||||
CastSpell(this, pQuest->GetRewSpellCast(), true);
|
||||
else if (pQuest->GetRewSpell() > 0)
|
||||
@@ -18629,6 +18636,10 @@ void Player::_SaveMail(SQLTransaction& trans)
|
||||
|
||||
void Player::_SaveQuestStatus(SQLTransaction& trans)
|
||||
{
|
||||
bool isTransaction = !trans.null();
|
||||
if (!isTransaction)
|
||||
trans = CharacterDatabase.BeginTransaction();
|
||||
|
||||
QuestStatusSaveMap::iterator saveItr;
|
||||
QuestStatusMap::iterator statusItr;
|
||||
|
||||
@@ -18661,6 +18672,9 @@ void Player::_SaveQuestStatus(SQLTransaction& trans)
|
||||
}
|
||||
|
||||
m_RewardedQuestsSave.clear();
|
||||
|
||||
if (!isTransaction)
|
||||
CharacterDatabase.CommitTransaction(trans);
|
||||
}
|
||||
|
||||
void Player::_SaveDailyQuestStatus(SQLTransaction& trans)
|
||||
|
||||
Reference in New Issue
Block a user