summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/common/Common.h3
-rw-r--r--src/server/database/Database/Implementation/CharacterDatabase.cpp3
-rw-r--r--src/server/database/Database/Implementation/CharacterDatabase.h3
-rw-r--r--src/server/game/Achievements/AchievementMgr.cpp113
-rw-r--r--src/server/game/Achievements/AchievementMgr.h33
-rw-r--r--src/server/game/AuctionHouse/AuctionHouseMgr.cpp11
-rw-r--r--src/server/game/Entities/Player/Player.h67
-rw-r--r--src/server/game/Entities/Player/PlayerStorage.cpp2
-rw-r--r--src/server/game/Entities/Player/PlayerUpdates.cpp2
-rw-r--r--src/server/game/Handlers/CharacterHandler.cpp4
10 files changed, 198 insertions, 43 deletions
diff --git a/src/common/Common.h b/src/common/Common.h
index cd50104c88..9baec924e5 100644
--- a/src/common/Common.h
+++ b/src/common/Common.h
@@ -43,7 +43,8 @@
#define MAX_NETCLIENT_PACKET_SIZE (32767 - 1) // Client hardcap: int16 with trailing zero space otherwise crash on memory free
// TimeConstants
-constexpr auto MINUTE = 60;
+constexpr auto SECOND = 1;
+constexpr auto MINUTE = SECOND * 60;
constexpr auto HOUR = MINUTE * 60;
constexpr auto DAY = HOUR * 24;
constexpr auto WEEK = DAY * 7;
diff --git a/src/server/database/Database/Implementation/CharacterDatabase.cpp b/src/server/database/Database/Implementation/CharacterDatabase.cpp
index f21af3aa9e..6e777a2782 100644
--- a/src/server/database/Database/Implementation/CharacterDatabase.cpp
+++ b/src/server/database/Database/Implementation/CharacterDatabase.cpp
@@ -441,6 +441,9 @@ void CharacterDatabaseConnection::DoPrepareStatements()
PrepareStatement(CHAR_INS_CHAR_ACHIEVEMENT, "INSERT INTO character_achievement (guid, achievement, date) VALUES (?, ?, ?)", CONNECTION_ASYNC);
PrepareStatement(CHAR_DEL_CHAR_ACHIEVEMENT_PROGRESS_BY_CRITERIA, "DELETE FROM character_achievement_progress WHERE guid = ? AND criteria = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_INS_CHAR_ACHIEVEMENT_PROGRESS, "INSERT INTO character_achievement_progress (guid, criteria, counter, date) VALUES (?, ?, ?, ?)", CONNECTION_ASYNC);
+ PrepareStatement(CHAR_INS_CHAR_ACHIEVEMENT_OFFLINE_UPDATES, "INSERT INTO character_achievement_offline_updates (guid, update_type, arg1, arg2, arg3) VALUES (?, ?, ?, ?, ?)", CONNECTION_ASYNC);
+ PrepareStatement(CHAR_SEL_CHAR_ACHIEVEMENT_OFFLINE_UPDATES, "SELECT update_type, arg1, arg2, arg3 FROM character_achievement_offline_updates WHERE guid = ?", CONNECTION_ASYNC);
+ PrepareStatement(CHAR_DEL_CHAR_ACHIEVEMENT_OFFLINE_UPDATES, "DELETE FROM character_achievement_offline_updates WHERE guid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_DEL_CHAR_REPUTATION_BY_FACTION, "DELETE FROM character_reputation WHERE guid = ? AND faction = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_INS_CHAR_REPUTATION_BY_FACTION, "INSERT INTO character_reputation (guid, faction, standing, flags) VALUES (?, ?, ? , ?)", CONNECTION_ASYNC);
PrepareStatement(CHAR_UPD_CHAR_ARENA_POINTS, "UPDATE characters SET arenaPoints = (arenaPoints + ?) WHERE guid = ?", CONNECTION_ASYNC);
diff --git a/src/server/database/Database/Implementation/CharacterDatabase.h b/src/server/database/Database/Implementation/CharacterDatabase.h
index ede962b498..c2c906936e 100644
--- a/src/server/database/Database/Implementation/CharacterDatabase.h
+++ b/src/server/database/Database/Implementation/CharacterDatabase.h
@@ -365,6 +365,9 @@ enum CharacterDatabaseStatements : uint32
CHAR_INS_CHAR_ACHIEVEMENT,
CHAR_DEL_CHAR_ACHIEVEMENT_PROGRESS_BY_CRITERIA,
CHAR_INS_CHAR_ACHIEVEMENT_PROGRESS,
+ CHAR_INS_CHAR_ACHIEVEMENT_OFFLINE_UPDATES,
+ CHAR_SEL_CHAR_ACHIEVEMENT_OFFLINE_UPDATES,
+ CHAR_DEL_CHAR_ACHIEVEMENT_OFFLINE_UPDATES,
CHAR_DEL_CHAR_REPUTATION_BY_FACTION,
CHAR_INS_CHAR_REPUTATION_BY_FACTION,
CHAR_UPD_CHAR_ARENA_POINTS,
diff --git a/src/server/game/Achievements/AchievementMgr.cpp b/src/server/game/Achievements/AchievementMgr.cpp
index 6748e01906..52c2ae11f3 100644
--- a/src/server/game/Achievements/AchievementMgr.cpp
+++ b/src/server/game/Achievements/AchievementMgr.cpp
@@ -481,6 +481,7 @@ bool AchievementCriteriaDataSet::Meets(Player const* source, Unit const* target,
AchievementMgr::AchievementMgr(Player* player)
{
_player = player;
+ _offlineUpdatesDelayTimer = 0;
}
AchievementMgr::~AchievementMgr()
@@ -550,6 +551,10 @@ void AchievementMgr::DeleteFromDB(ObjectGuid::LowType lowguid)
stmt->SetData(0, lowguid);
trans->Append(stmt);
+ stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_ACHIEVEMENT_OFFLINE_UPDATES);
+ stmt->SetData(0, lowguid);
+ trans->Append(stmt);
+
CharacterDatabase.CommitTransaction(trans);
}
@@ -609,7 +614,7 @@ void AchievementMgr::SaveToDB(CharacterDatabaseTransaction trans)
}
}
-void AchievementMgr::LoadFromDB(PreparedQueryResult achievementResult, PreparedQueryResult criteriaResult)
+void AchievementMgr::LoadFromDB(PreparedQueryResult achievementResult, PreparedQueryResult criteriaResult, PreparedQueryResult offlineUpdatesResult)
{
if (achievementResult)
{
@@ -669,6 +674,28 @@ void AchievementMgr::LoadFromDB(PreparedQueryResult achievementResult, PreparedQ
progress.changed = false;
} while (criteriaResult->NextRow());
}
+
+ if (offlineUpdatesResult)
+ {
+ uint32 count = 0;
+ do
+ {
+ Field* fields = offlineUpdatesResult->Fetch();
+
+ AchievementOfflinePlayerUpdate update;
+ update.updateType = static_cast<AchievementOfflinePlayerUpdateType>(fields[0].Get<uint8>());
+ update.arg1 = fields[1].Get<uint32>();
+ update.arg2 = fields[2].Get<uint32>();
+ update.arg3 = fields[3].Get<uint32>();
+
+ _offlineUpdatesQueue.push_back(update);
+
+ ++count;
+ } while (offlineUpdatesResult->NextRow());
+
+ if (count > 0)
+ _offlineUpdatesDelayTimer = 5 * SECOND * IN_MILLISECONDS;
+ }
}
void AchievementMgr::SendAchievementEarned(AchievementEntry const* achievement) const
@@ -884,7 +911,7 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
case ACHIEVEMENT_CRITERIA_TYPE_NUMBER_OF_TALENT_RESETS:
case ACHIEVEMENT_CRITERIA_TYPE_LOSE_DUEL:
case ACHIEVEMENT_CRITERIA_TYPE_CREATE_AUCTION:
- case ACHIEVEMENT_CRITERIA_TYPE_WON_AUCTIONS: /* FIXME: for online player only currently */
+ case ACHIEVEMENT_CRITERIA_TYPE_WON_AUCTIONS:
case ACHIEVEMENT_CRITERIA_TYPE_ROLL_NEED:
case ACHIEVEMENT_CRITERIA_TYPE_ROLL_GREED:
case ACHIEVEMENT_CRITERIA_TYPE_ROLL_DISENCHANT:
@@ -904,7 +931,7 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
case ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_AT_BARBER:
case ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_FOR_MAIL:
case ACHIEVEMENT_CRITERIA_TYPE_LOOT_MONEY:
- case ACHIEVEMENT_CRITERIA_TYPE_GOLD_EARNED_BY_AUCTIONS:/* FIXME: for online player only currently */
+ case ACHIEVEMENT_CRITERIA_TYPE_GOLD_EARNED_BY_AUCTIONS:
case ACHIEVEMENT_CRITERIA_TYPE_TOTAL_DAMAGE_RECEIVED:
case ACHIEVEMENT_CRITERIA_TYPE_TOTAL_HEALING_RECEIVED:
case ACHIEVEMENT_CRITERIA_TYPE_USE_LFD_TO_GROUP_WITH_PLAYERS:
@@ -915,7 +942,7 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
break;
// std case: high value at miscvalue1
case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_AUCTION_BID:
- case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_AUCTION_SOLD: /* FIXME: for online player only currently */
+ case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_AUCTION_SOLD:
case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_HIT_DEALT:
case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_HIT_RECEIVED:
case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_HEAL_CASTED:
@@ -2158,6 +2185,22 @@ void AchievementMgr::RemoveCriteriaProgress(const AchievementCriteriaEntry* entr
_criteriaProgress.erase(criteriaProgress);
}
+void AchievementMgr::Update(uint32 timeDiff)
+{
+ if (_offlineUpdatesDelayTimer > 0)
+ {
+ if (timeDiff >= _offlineUpdatesDelayTimer)
+ {
+ _offlineUpdatesDelayTimer = 0;
+ ProcessOfflineUpdatesQueue();
+ }
+ else
+ _offlineUpdatesDelayTimer -= timeDiff;
+ }
+
+ UpdateTimedAchievements(timeDiff);
+}
+
void AchievementMgr::UpdateTimedAchievements(uint32 timeDiff)
{
if (!_timedAchievements.empty())
@@ -2437,6 +2480,46 @@ CompletedAchievementMap const& AchievementMgr::GetCompletedAchievements()
return _completedAchievements;
}
+void AchievementMgr::ProcessOfflineUpdatesQueue()
+{
+ if (_offlineUpdatesQueue.empty())
+ return;
+
+ for (auto const& update : _offlineUpdatesQueue)
+ ProcessOfflineUpdate(update);
+
+ _offlineUpdatesQueue.clear();
+
+ CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_ACHIEVEMENT_OFFLINE_UPDATES);
+ stmt->SetData(0, GetPlayer()->GetGUID().GetCounter());
+ CharacterDatabase.Execute(stmt);
+}
+
+void AchievementMgr::ProcessOfflineUpdate(AchievementOfflinePlayerUpdate const& update)
+{
+ switch (update.updateType)
+ {
+ case ACHIEVEMENT_OFFLINE_PLAYER_UPDATE_TYPE_COMPLETE_ACHIEVEMENT:
+ {
+ AchievementEntry const* achievement = sAchievementStore.LookupEntry(update.arg1);
+
+ ASSERT(achievement != NULL, "Not found achievement to complete for offline achievements update. Wrong arg1 ({}) value?", update.arg1);
+
+ CompletedAchievement(achievement);
+ break;
+ }
+ case ACHIEVEMENT_OFFLINE_PLAYER_UPDATE_TYPE_UPDATE_CRITERIA:
+ {
+ AchievementCriteriaTypes criteriaType = static_cast<AchievementCriteriaTypes>(update.arg1);
+ UpdateAchievementCriteria(criteriaType, update.arg2, update.arg3);
+ break;
+ }
+ default:
+ ASSERT(false, "Unknown offline achievement update type ({}) for player - {}", update.updateType, GetPlayer()->GetGUID().GetCounter());
+ break;
+ }
+}
+
AchievementGlobalMgr* AchievementGlobalMgr::instance()
{
static AchievementGlobalMgr instance;
@@ -3054,3 +3137,25 @@ AchievementEntry const* AchievementGlobalMgr::GetAchievement(uint32 achievementI
{
return sAchievementStore.LookupEntry(achievementId);
}
+
+void AchievementGlobalMgr::CompletedAchievementForOfflinePlayer(ObjectGuid::LowType playerLowGuid, AchievementEntry const* entry)
+{
+ CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_CHAR_ACHIEVEMENT_OFFLINE_UPDATES);
+ stmt->SetData(0, playerLowGuid);
+ stmt->SetData(1, uint32(ACHIEVEMENT_OFFLINE_PLAYER_UPDATE_TYPE_COMPLETE_ACHIEVEMENT));
+ stmt->SetData(2, entry->ID);
+ stmt->SetData(3, 0);
+ stmt->SetData(4, 0);
+ CharacterDatabase.Execute(stmt);
+}
+
+void AchievementGlobalMgr::UpdateAchievementCriteriaForOfflinePlayer(ObjectGuid::LowType playerLowGuid, AchievementCriteriaTypes type, uint32 miscValue1, uint32 miscValue2)
+{
+ CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_CHAR_ACHIEVEMENT_OFFLINE_UPDATES);
+ stmt->SetData(0, playerLowGuid);
+ stmt->SetData(1, uint32(ACHIEVEMENT_OFFLINE_PLAYER_UPDATE_TYPE_UPDATE_CRITERIA));
+ stmt->SetData(2, type);
+ stmt->SetData(3, miscValue1);
+ stmt->SetData(4, miscValue2);
+ CharacterDatabase.Execute(stmt);
+}
diff --git a/src/server/game/Achievements/AchievementMgr.h b/src/server/game/Achievements/AchievementMgr.h
index e05ef8e312..34e79ac4c2 100644
--- a/src/server/game/Achievements/AchievementMgr.h
+++ b/src/server/game/Achievements/AchievementMgr.h
@@ -33,6 +33,20 @@ typedef std::list<AchievementEntry const*> AchievementEntryList;
typedef std::unordered_map<uint32, AchievementCriteriaEntryList> AchievementCriteriaListByAchievement;
typedef std::map<uint32, AchievementEntryList> AchievementListByReferencedId;
+enum AchievementOfflinePlayerUpdateType
+{
+ ACHIEVEMENT_OFFLINE_PLAYER_UPDATE_TYPE_COMPLETE_ACHIEVEMENT = 1,
+ ACHIEVEMENT_OFFLINE_PLAYER_UPDATE_TYPE_UPDATE_CRITERIA = 2
+};
+
+struct AchievementOfflinePlayerUpdate
+{
+ AchievementOfflinePlayerUpdateType updateType;
+ uint32 arg1;
+ uint32 arg2;
+ uint32 arg3;
+};
+
struct CriteriaProgress
{
uint32 counter;
@@ -284,7 +298,7 @@ public:
void Reset();
static void DeleteFromDB(ObjectGuid::LowType lowguid);
- void LoadFromDB(PreparedQueryResult achievementResult, PreparedQueryResult criteriaResult);
+ void LoadFromDB(PreparedQueryResult achievementResult, PreparedQueryResult criteriaResult, PreparedQueryResult offlineUpdatesResult);
void SaveToDB(CharacterDatabaseTransaction trans);
void ResetAchievementCriteria(AchievementCriteriaCondition condition, uint32 value, bool evenIfCriteriaComplete = false);
void UpdateAchievementCriteria(AchievementCriteriaTypes type, uint32 miscValue1 = 0, uint32 miscValue2 = 0, Unit* unit = nullptr);
@@ -294,7 +308,8 @@ public:
void SendRespondInspectAchievements(Player* player) const;
[[nodiscard]] bool HasAchieved(uint32 achievementId) const;
[[nodiscard]] Player* GetPlayer() const { return _player; }
- void UpdateTimedAchievements(uint32 timeDiff);
+
+ void Update(uint32 timeDiff);
void StartTimedAchievement(AchievementCriteriaTimedTypes type, uint32 entry, uint32 timeLost = 0);
void RemoveTimedAchievement(AchievementCriteriaTimedTypes type, uint32 entry); // used for quest and scripted timed achievements
@@ -313,11 +328,23 @@ private:
bool CanUpdateCriteria(AchievementCriteriaEntry const* criteria, AchievementEntry const* achievement);
void BuildAllDataPacket(WorldPacket* data) const;
+ void UpdateTimedAchievements(uint32 timeDiff);
+
+ // Handles updates when character was offline.
+ void ProcessOfflineUpdate(AchievementOfflinePlayerUpdate const& update);
+ void ProcessOfflineUpdatesQueue();
+
Player* _player;
CriteriaProgressMap _criteriaProgress;
CompletedAchievementMap _completedAchievements;
typedef std::map<uint32, uint32> TimedAchievementMap;
TimedAchievementMap _timedAchievements; // Criteria id/time left in MS
+
+ // Offline updates cannot be processed while players are loading,
+ // as the player will not be notified of the changes.
+ // To ensure proper notification, introduce a delay before processing.
+ uint32 _offlineUpdatesDelayTimer;
+ std::vector<AchievementOfflinePlayerUpdate> _offlineUpdatesQueue;
};
class AchievementGlobalMgr
@@ -398,6 +425,8 @@ public:
[[nodiscard]] AchievementEntry const* GetAchievement(uint32 achievementId) const;
+ void CompletedAchievementForOfflinePlayer(ObjectGuid::LowType playerLowGuid, AchievementEntry const* entry);
+ void UpdateAchievementCriteriaForOfflinePlayer(ObjectGuid::LowType playerLowGuid, AchievementCriteriaTypes type, uint32 miscValue1 = 0, uint32 miscValue2 = 0);
private:
AchievementCriteriaDataMap _criteriaDataMap;
diff --git a/src/server/game/AuctionHouse/AuctionHouseMgr.cpp b/src/server/game/AuctionHouse/AuctionHouseMgr.cpp
index bdda9b37e9..e7cf7ab95e 100644
--- a/src/server/game/AuctionHouse/AuctionHouseMgr.cpp
+++ b/src/server/game/AuctionHouse/AuctionHouseMgr.cpp
@@ -318,10 +318,14 @@ void AuctionHouseMgr::SendAuctionWonMail(AuctionEntry* auction, CharacterDatabas
{
if (sendNotification) // can be changed in the hook
bidder->GetSession()->SendAuctionBidderNotification(auction->GetHouseId(), auction->Id, auction->bidder, 0, 0, auction->item_template);
- // FIXME: for offline player need also
+
if (updateAchievementCriteria) // can be changed in the hook
bidder->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_WON_AUCTIONS, 1);
}
+ else if (updateAchievementCriteria)
+ {
+ sAchievementMgr->UpdateAchievementCriteriaForOfflinePlayer(auction->bidder.GetCounter(), ACHIEVEMENT_CRITERIA_TYPE_WON_AUCTIONS, 1);
+ }
if (sendMail) // can be changed in the hook
MailDraft(auction->BuildAuctionMailSubject(AUCTION_WON), AuctionEntry::BuildAuctionMailBody(auction->owner, auction->bid, auction->buyout))
@@ -375,6 +379,11 @@ void AuctionHouseMgr::SendAuctionSuccessfulMail(AuctionEntry* auction, Character
if (sendNotification) // can be changed in the hook
owner->GetSession()->SendAuctionOwnerNotification(auction);
}
+ else if (updateAchievementCriteria)
+ {
+ sAchievementMgr->UpdateAchievementCriteriaForOfflinePlayer(auction->owner.GetCounter(), ACHIEVEMENT_CRITERIA_TYPE_GOLD_EARNED_BY_AUCTIONS, profit);
+ sAchievementMgr->UpdateAchievementCriteriaForOfflinePlayer(auction->owner.GetCounter(), ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_AUCTION_SOLD, auction->bid);
+ }
if (sendMail) // can be changed in the hook
MailDraft(auction->BuildAuctionMailSubject(AUCTION_SUCCESSFUL), AuctionEntry::BuildAuctionMailBody(auction->bidder, auction->bid, auction->buyout, auction->deposit, auction->GetAuctionCut()))
diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h
index 3633ebf3f3..2ebf6c8dbc 100644
--- a/src/server/game/Entities/Player/Player.h
+++ b/src/server/game/Entities/Player/Player.h
@@ -861,39 +861,40 @@ enum PlayedTimeIndex
// used at player loading query list preparing, and later result selection
enum PlayerLoginQueryIndex
{
- PLAYER_LOGIN_QUERY_LOAD_FROM = 0,
- PLAYER_LOGIN_QUERY_LOAD_AURAS = 3,
- PLAYER_LOGIN_QUERY_LOAD_SPELLS = 4,
- PLAYER_LOGIN_QUERY_LOAD_QUEST_STATUS = 5,
- PLAYER_LOGIN_QUERY_LOAD_DAILY_QUEST_STATUS = 6,
- PLAYER_LOGIN_QUERY_LOAD_REPUTATION = 7,
- PLAYER_LOGIN_QUERY_LOAD_INVENTORY = 8,
- PLAYER_LOGIN_QUERY_LOAD_ACTIONS = 9,
- PLAYER_LOGIN_QUERY_LOAD_MAILS = 10,
- PLAYER_LOGIN_QUERY_LOAD_MAIL_ITEMS = 11,
- PLAYER_LOGIN_QUERY_LOAD_SOCIAL_LIST = 13,
- PLAYER_LOGIN_QUERY_LOAD_HOME_BIND = 14,
- PLAYER_LOGIN_QUERY_LOAD_SPELL_COOLDOWNS = 15,
- PLAYER_LOGIN_QUERY_LOAD_DECLINED_NAMES = 16,
- PLAYER_LOGIN_QUERY_LOAD_ACHIEVEMENTS = 18,
- PLAYER_LOGIN_QUERY_LOAD_CRITERIA_PROGRESS = 19,
- PLAYER_LOGIN_QUERY_LOAD_EQUIPMENT_SETS = 20,
- PLAYER_LOGIN_QUERY_LOAD_ENTRY_POINT = 21,
- PLAYER_LOGIN_QUERY_LOAD_GLYPHS = 22,
- PLAYER_LOGIN_QUERY_LOAD_TALENTS = 23,
- PLAYER_LOGIN_QUERY_LOAD_ACCOUNT_DATA = 24,
- PLAYER_LOGIN_QUERY_LOAD_SKILLS = 25,
- PLAYER_LOGIN_QUERY_LOAD_WEEKLY_QUEST_STATUS = 26,
- PLAYER_LOGIN_QUERY_LOAD_RANDOM_BG = 27,
- PLAYER_LOGIN_QUERY_LOAD_BANNED = 28,
- PLAYER_LOGIN_QUERY_LOAD_QUEST_STATUS_REW = 29,
- PLAYER_LOGIN_QUERY_LOAD_INSTANCE_LOCK_TIMES = 30,
- PLAYER_LOGIN_QUERY_LOAD_SEASONAL_QUEST_STATUS = 31,
- PLAYER_LOGIN_QUERY_LOAD_MONTHLY_QUEST_STATUS = 32,
- PLAYER_LOGIN_QUERY_LOAD_BREW_OF_THE_MONTH = 34,
- PLAYER_LOGIN_QUERY_LOAD_CORPSE_LOCATION = 35,
- PLAYER_LOGIN_QUERY_LOAD_CHARACTER_SETTINGS = 36,
- PLAYER_LOGIN_QUERY_LOAD_PET_SLOTS = 37,
+ PLAYER_LOGIN_QUERY_LOAD_FROM = 0,
+ PLAYER_LOGIN_QUERY_LOAD_AURAS = 3,
+ PLAYER_LOGIN_QUERY_LOAD_SPELLS = 4,
+ PLAYER_LOGIN_QUERY_LOAD_QUEST_STATUS = 5,
+ PLAYER_LOGIN_QUERY_LOAD_DAILY_QUEST_STATUS = 6,
+ PLAYER_LOGIN_QUERY_LOAD_REPUTATION = 7,
+ PLAYER_LOGIN_QUERY_LOAD_INVENTORY = 8,
+ PLAYER_LOGIN_QUERY_LOAD_ACTIONS = 9,
+ PLAYER_LOGIN_QUERY_LOAD_MAILS = 10,
+ PLAYER_LOGIN_QUERY_LOAD_MAIL_ITEMS = 11,
+ PLAYER_LOGIN_QUERY_LOAD_SOCIAL_LIST = 13,
+ PLAYER_LOGIN_QUERY_LOAD_HOME_BIND = 14,
+ PLAYER_LOGIN_QUERY_LOAD_SPELL_COOLDOWNS = 15,
+ PLAYER_LOGIN_QUERY_LOAD_DECLINED_NAMES = 16,
+ PLAYER_LOGIN_QUERY_LOAD_ACHIEVEMENTS = 18,
+ PLAYER_LOGIN_QUERY_LOAD_CRITERIA_PROGRESS = 19,
+ PLAYER_LOGIN_QUERY_LOAD_EQUIPMENT_SETS = 20,
+ PLAYER_LOGIN_QUERY_LOAD_ENTRY_POINT = 21,
+ PLAYER_LOGIN_QUERY_LOAD_GLYPHS = 22,
+ PLAYER_LOGIN_QUERY_LOAD_TALENTS = 23,
+ PLAYER_LOGIN_QUERY_LOAD_ACCOUNT_DATA = 24,
+ PLAYER_LOGIN_QUERY_LOAD_SKILLS = 25,
+ PLAYER_LOGIN_QUERY_LOAD_WEEKLY_QUEST_STATUS = 26,
+ PLAYER_LOGIN_QUERY_LOAD_RANDOM_BG = 27,
+ PLAYER_LOGIN_QUERY_LOAD_BANNED = 28,
+ PLAYER_LOGIN_QUERY_LOAD_QUEST_STATUS_REW = 29,
+ PLAYER_LOGIN_QUERY_LOAD_INSTANCE_LOCK_TIMES = 30,
+ PLAYER_LOGIN_QUERY_LOAD_SEASONAL_QUEST_STATUS = 31,
+ PLAYER_LOGIN_QUERY_LOAD_MONTHLY_QUEST_STATUS = 32,
+ PLAYER_LOGIN_QUERY_LOAD_BREW_OF_THE_MONTH = 34,
+ PLAYER_LOGIN_QUERY_LOAD_CORPSE_LOCATION = 35,
+ PLAYER_LOGIN_QUERY_LOAD_CHARACTER_SETTINGS = 36,
+ PLAYER_LOGIN_QUERY_LOAD_PET_SLOTS = 37,
+ PLAYER_LOGIN_QUERY_LOAD_OFFLINE_ACHIEVEMENTS_UPDATES = 38,
MAX_PLAYER_LOGIN_QUERY
};
diff --git a/src/server/game/Entities/Player/PlayerStorage.cpp b/src/server/game/Entities/Player/PlayerStorage.cpp
index c4d0a7f689..0211a57779 100644
--- a/src/server/game/Entities/Player/PlayerStorage.cpp
+++ b/src/server/game/Entities/Player/PlayerStorage.cpp
@@ -5023,7 +5023,7 @@ bool Player::LoadFromDB(ObjectGuid playerGuid, CharacterDatabaseQueryHolder cons
SetCreationTime(fields[74].Get<Seconds>());
// load achievements before anything else to prevent multiple gains for the same achievement/criteria on every loading (as loading does call UpdateAchievementCriteria)
- m_achievementMgr->LoadFromDB(holder.GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_ACHIEVEMENTS), holder.GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_CRITERIA_PROGRESS));
+ m_achievementMgr->LoadFromDB(holder.GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_ACHIEVEMENTS), holder.GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_CRITERIA_PROGRESS), holder.GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_OFFLINE_ACHIEVEMENTS_UPDATES));
uint32 money = fields[8].Get<uint32>();
if (money > MAX_MONEY_AMOUNT)
diff --git a/src/server/game/Entities/Player/PlayerUpdates.cpp b/src/server/game/Entities/Player/PlayerUpdates.cpp
index c97d6b2e97..59079f311a 100644
--- a/src/server/game/Entities/Player/PlayerUpdates.cpp
+++ b/src/server/game/Entities/Player/PlayerUpdates.cpp
@@ -159,7 +159,7 @@ void Player::Update(uint32 p_time)
}
}
- m_achievementMgr->UpdateTimedAchievements(p_time);
+ m_achievementMgr->Update(p_time);
if (HasUnitState(UNIT_STATE_MELEE_ATTACKING) && !HasUnitState(UNIT_STATE_CASTING) && !HasUnitState(UNIT_STATE_CHARGING))
{
diff --git a/src/server/game/Handlers/CharacterHandler.cpp b/src/server/game/Handlers/CharacterHandler.cpp
index 762d39e229..4021d541f7 100644
--- a/src/server/game/Handlers/CharacterHandler.cpp
+++ b/src/server/game/Handlers/CharacterHandler.cpp
@@ -216,6 +216,10 @@ bool LoginQueryHolder::Initialize()
stmt->SetData(0, lowGuid);
res &= SetPreparedQuery(PLAYER_LOGIN_QUERY_LOAD_PET_SLOTS, stmt);
+ stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_ACHIEVEMENT_OFFLINE_UPDATES);
+ stmt->SetData(0, lowGuid);
+ res &= SetPreparedQuery(PLAYER_LOGIN_QUERY_LOAD_OFFLINE_ACHIEVEMENTS_UPDATES, stmt);
+
return res;
}