diff options
author | Anton Popovichenko <anton.popovichenko@mendix.com> | 2024-09-03 18:05:23 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-09-03 13:05:23 -0300 |
commit | 9999a80c9644027ebc7c46563711b2d713c32c0d (patch) | |
tree | 88198a60d90b45cbf06bb69fb871fe7955a37ac5 /src | |
parent | 221dbd3fdbca4348061a5f6da7eb217118866f8c (diff) |
feat(Core/Achievements): Add possibility to complete achievements and update achievement criteria for offline players. (#19851)
Diffstat (limited to 'src')
-rw-r--r-- | src/common/Common.h | 3 | ||||
-rw-r--r-- | src/server/database/Database/Implementation/CharacterDatabase.cpp | 3 | ||||
-rw-r--r-- | src/server/database/Database/Implementation/CharacterDatabase.h | 3 | ||||
-rw-r--r-- | src/server/game/Achievements/AchievementMgr.cpp | 113 | ||||
-rw-r--r-- | src/server/game/Achievements/AchievementMgr.h | 33 | ||||
-rw-r--r-- | src/server/game/AuctionHouse/AuctionHouseMgr.cpp | 11 | ||||
-rw-r--r-- | src/server/game/Entities/Player/Player.h | 67 | ||||
-rw-r--r-- | src/server/game/Entities/Player/PlayerStorage.cpp | 2 | ||||
-rw-r--r-- | src/server/game/Entities/Player/PlayerUpdates.cpp | 2 | ||||
-rw-r--r-- | src/server/game/Handlers/CharacterHandler.cpp | 4 |
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; } |