diff --git a/src/server/database/Database/DatabaseEnvFwd.h b/src/server/database/Database/DatabaseEnvFwd.h index c72df398cd0..4521409902b 100644 --- a/src/server/database/Database/DatabaseEnvFwd.h +++ b/src/server/database/Database/DatabaseEnvFwd.h @@ -75,8 +75,8 @@ using LoginDatabaseTransaction = SQLTransaction; using WorldDatabaseTransaction = SQLTransaction; class SQLQueryHolderBase; -using QueryResultHolderFuture = std::future; -using QueryResultHolderPromise = std::promise; +using QueryResultHolderFuture = std::future; +using QueryResultHolderPromise = std::promise; template class SQLQueryHolder; diff --git a/src/server/database/Database/DatabaseWorkerPool.cpp b/src/server/database/Database/DatabaseWorkerPool.cpp index 07a661d5041..fb92cd28e9d 100644 --- a/src/server/database/Database/DatabaseWorkerPool.cpp +++ b/src/server/database/Database/DatabaseWorkerPool.cpp @@ -223,13 +223,13 @@ QueryCallback DatabaseWorkerPool::AsyncQuery(PreparedStatement* stmt) } template -SQLQueryHolderCallback DatabaseWorkerPool::DelayQueryHolder(SQLQueryHolder* holder) +SQLQueryHolderCallback DatabaseWorkerPool::DelayQueryHolder(std::shared_ptr> holder) { SQLQueryHolderTask* task = new SQLQueryHolderTask(holder); // Store future result before enqueueing - task might get already processed and deleted before returning from this method QueryResultHolderFuture result = task->GetFuture(); Enqueue(task); - return result; + return { std::move(holder), std::move(result) }; } template diff --git a/src/server/database/Database/DatabaseWorkerPool.h b/src/server/database/Database/DatabaseWorkerPool.h index d17c45d6cd8..995743ba548 100644 --- a/src/server/database/Database/DatabaseWorkerPool.h +++ b/src/server/database/Database/DatabaseWorkerPool.h @@ -160,7 +160,7 @@ class DatabaseWorkerPool //! return object as soon as the query is executed. //! The return value is then processed in ProcessQueryCallback methods. //! Any prepared statements added to this holder need to be prepared with the CONNECTION_ASYNC flag. - SQLQueryHolderCallback DelayQueryHolder(SQLQueryHolder* holder); + SQLQueryHolderCallback DelayQueryHolder(std::shared_ptr> holder); /** Transaction context methods. diff --git a/src/server/database/Database/QueryHolder.cpp b/src/server/database/Database/QueryHolder.cpp index 719914c8d5c..7b7c83a53b4 100644 --- a/src/server/database/Database/QueryHolder.cpp +++ b/src/server/database/Database/QueryHolder.cpp @@ -15,10 +15,11 @@ * with this program. If not, see . */ -#include "MySQLConnection.h" #include "QueryHolder.h" -#include "PreparedStatement.h" +#include "Errors.h" #include "Log.h" +#include "MySQLConnection.h" +#include "PreparedStatement.h" #include "QueryResult.h" bool SQLQueryHolderBase::SetPreparedQueryImpl(size_t index, PreparedStatementBase* stmt) @@ -33,13 +34,13 @@ bool SQLQueryHolderBase::SetPreparedQueryImpl(size_t index, PreparedStatementBas return true; } -PreparedQueryResult SQLQueryHolderBase::GetPreparedResult(size_t index) +PreparedQueryResult SQLQueryHolderBase::GetPreparedResult(size_t index) const { // Don't call to this function if the index is of a prepared statement - if (index < m_queries.size()) - return m_queries[index].second; - else - return PreparedQueryResult(nullptr); + ASSERT(index < m_queries.size(), "Query holder result index out of range, tried to access index " SZFMTD " but there are only " SZFMTD " results", + index, m_queries.size()); + + return m_queries[index].second; } void SQLQueryHolderBase::SetPreparedResult(size_t index, PreparedResultSet* result) @@ -71,25 +72,16 @@ void SQLQueryHolderBase::SetSize(size_t size) m_queries.resize(size); } -SQLQueryHolderTask::~SQLQueryHolderTask() -{ - if (!m_executed) - delete m_holder; -} +SQLQueryHolderTask::~SQLQueryHolderTask() = default; bool SQLQueryHolderTask::Execute() { - m_executed = true; - - if (!m_holder) - return false; - /// execute all queries in the holder and pass the results for (size_t i = 0; i < m_holder->m_queries.size(); ++i) if (PreparedStatementBase* stmt = m_holder->m_queries[i].first) m_holder->SetPreparedResult(i, m_conn->Query(stmt)); - m_result.set_value(m_holder); + m_result.set_value(); return true; } @@ -97,7 +89,7 @@ bool SQLQueryHolderCallback::InvokeIfReady() { if (m_future.valid() && m_future.wait_for(std::chrono::seconds(0)) == std::future_status::ready) { - m_callback(m_future.get()); + m_callback(*m_holder); return true; } diff --git a/src/server/database/Database/QueryHolder.h b/src/server/database/Database/QueryHolder.h index 83b80b79b15..f6a52cb2dd3 100644 --- a/src/server/database/Database/QueryHolder.h +++ b/src/server/database/Database/QueryHolder.h @@ -19,6 +19,7 @@ #define _QUERYHOLDER_H #include "SQLOperation.h" +#include class TC_DATABASE_API SQLQueryHolderBase { @@ -27,10 +28,10 @@ class TC_DATABASE_API SQLQueryHolderBase std::vector> m_queries; public: - SQLQueryHolderBase() { } + SQLQueryHolderBase() = default; virtual ~SQLQueryHolderBase(); void SetSize(size_t size); - PreparedQueryResult GetPreparedResult(size_t index); + PreparedQueryResult GetPreparedResult(size_t index) const; void SetPreparedResult(size_t index, PreparedResultSet* result); protected: @@ -50,13 +51,12 @@ public: class TC_DATABASE_API SQLQueryHolderTask : public SQLOperation { private: - SQLQueryHolderBase* m_holder; + std::shared_ptr m_holder; QueryResultHolderPromise m_result; - bool m_executed; public: - SQLQueryHolderTask(SQLQueryHolderBase* holder) - : m_holder(holder), m_executed(false) { } + explicit SQLQueryHolderTask(std::shared_ptr holder) + : m_holder(std::move(holder)) { } ~SQLQueryHolderTask(); @@ -67,20 +67,23 @@ class TC_DATABASE_API SQLQueryHolderTask : public SQLOperation class TC_DATABASE_API SQLQueryHolderCallback { public: - SQLQueryHolderCallback(QueryResultHolderFuture&& future) : m_future(std::move(future)) { } + SQLQueryHolderCallback(std::shared_ptr&& holder, QueryResultHolderFuture&& future) + : m_holder(std::move(holder)), m_future(std::move(future)) { } + SQLQueryHolderCallback(SQLQueryHolderCallback&&) = default; SQLQueryHolderCallback& operator=(SQLQueryHolderCallback&&) = default; - void AfterComplete(std::function callback) & + void AfterComplete(std::function callback)& { m_callback = std::move(callback); } bool InvokeIfReady(); + std::shared_ptr m_holder; QueryResultHolderFuture m_future; - std::function m_callback; + std::function m_callback; }; #endif diff --git a/src/server/database/Database/SQLOperation.h b/src/server/database/Database/SQLOperation.h index 97f1b396cea..2e85f72c17c 100644 --- a/src/server/database/Database/SQLOperation.h +++ b/src/server/database/Database/SQLOperation.h @@ -42,13 +42,6 @@ struct SQLElementData SQLElementDataType type; }; -//- For ambigious resultsets -union SQLResultSetUnion -{ - PreparedResultSet* presult; - ResultSet* qresult; -}; - class MySQLConnection; class TC_DATABASE_API SQLOperation diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index db265cc03bb..f92cdd31a4d 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -16845,7 +16845,7 @@ bool Player::IsLoading() const return GetSession()->PlayerLoading(); } -bool Player::LoadFromDB(ObjectGuid guid, CharacterDatabaseQueryHolder* holder) +bool Player::LoadFromDB(ObjectGuid guid, CharacterDatabaseQueryHolder const& holder) { //// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 //QueryResult* result = CharacterDatabase.PQuery("SELECT guid, account, name, race, class, gender, level, xp, money, skin, face, hairStyle, hairColor, facialStyle, bankSlots, restState, playerFlags, " @@ -16860,7 +16860,7 @@ bool Player::LoadFromDB(ObjectGuid guid, CharacterDatabaseQueryHolder* holder) // 62 63 64 65 66 //"knownTitles, actionBars, grantableLevels, fishing_steps, trans_spawn_id FROM characters WHERE guid = '%u'", guid); - PreparedQueryResult result = holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_FROM); + PreparedQueryResult result = holder.GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_FROM); if (!result) { std::string name = ""; @@ -16881,7 +16881,7 @@ bool Player::LoadFromDB(ObjectGuid guid, CharacterDatabaseQueryHolder* holder) return false; } - if (holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_BANNED)) + if (holder.GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_BANNED)) { TC_LOG_ERROR("entities.player", "Player::LoadFromDB: Player (%s) is banned, can't load.", guid.ToString().c_str()); return false; @@ -16934,7 +16934,7 @@ bool Player::LoadFromDB(ObjectGuid guid, CharacterDatabaseQueryHolder* holder) SetFloatValue(UNIT_FIELD_HOVERHEIGHT, 1.0f); // 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)); uint64 money = fields[8].GetUInt64(); if (money > MAX_MONEY_AMOUNT) @@ -16993,7 +16993,7 @@ bool Player::LoadFromDB(ObjectGuid guid, CharacterDatabaseQueryHolder* holder) SetFactionForRace(getRace()); // load home bind and check in same time class/race pair, it used later for restore broken positions - if (!_LoadHomeBind(holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_HOME_BIND))) + if (!_LoadHomeBind(holder.GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_HOME_BIND))) return false; InitializeSkillFields(); @@ -17021,9 +17021,9 @@ bool Player::LoadFromDB(ObjectGuid guid, CharacterDatabaseQueryHolder* holder) #define RelocateToHomebind(){ mapId = m_homebindMapId; instanceId = 0; Relocate(m_homebindX, m_homebindY, m_homebindZ); } - _LoadGroup(holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_GROUP)); + _LoadGroup(holder.GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_GROUP)); - _LoadArenaTeamInfo(holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_ARENA_INFO)); + _LoadArenaTeamInfo(holder.GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_ARENA_INFO)); // check arena teams integrity for (uint32 arena_slot = 0; arena_slot < MAX_ARENA_SLOT; ++arena_slot) @@ -17041,14 +17041,14 @@ bool Player::LoadFromDB(ObjectGuid guid, CharacterDatabaseQueryHolder* holder) SetArenaTeamInfoField(arena_slot, ArenaTeamInfoType(j), 0); } - _LoadCurrency(holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_CURRENCY)); + _LoadCurrency(holder.GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_CURRENCY)); SetUInt32Value(PLAYER_FIELD_LIFETIME_HONORABLE_KILLS, fields[45].GetUInt32()); SetUInt16Value(PLAYER_FIELD_KILLS, 0, fields[46].GetUInt16()); SetUInt16Value(PLAYER_FIELD_KILLS, 1, fields[47].GetUInt16()); - _LoadBoundInstances(holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_BOUND_INSTANCES)); - _LoadInstanceTimeRestrictions(holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_INSTANCE_LOCK_TIMES)); - _LoadBGData(holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_BG_DATA)); + _LoadBoundInstances(holder.GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_BOUND_INSTANCES)); + _LoadInstanceTimeRestrictions(holder.GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_INSTANCE_LOCK_TIMES)); + _LoadBGData(holder.GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_BG_DATA)); GetSession()->SetPlayer(this); MapEntry const* mapEntry = sMapStore.LookupEntry(mapId); @@ -17514,7 +17514,7 @@ bool Player::LoadFromDB(ObjectGuid guid, CharacterDatabaseQueryHolder* holder) } // load skills after InitStatsForLevel because it triggering aura apply also - _LoadSkills(holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_SKILLS)); + _LoadSkills(holder.GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_SKILLS)); UpdateSkillsForLevel(); //update skills after load, to make sure they are correctly update at player load // apply original stats mods before spell loading or item equipment that call before equip _RemoveStatsMods() @@ -17523,25 +17523,25 @@ bool Player::LoadFromDB(ObjectGuid guid, CharacterDatabaseQueryHolder* holder) //_LoadMail(); UpdateDisplayPower(); - _LoadTalents(holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_TALENTS)); - _LoadSpells(holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_SPELLS)); + _LoadTalents(holder.GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_TALENTS)); + _LoadSpells(holder.GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_SPELLS)); - _LoadGlyphs(holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_GLYPHS)); - _LoadAuras(holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_AURAS), time_diff); + _LoadGlyphs(holder.GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_GLYPHS)); + _LoadAuras(holder.GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_AURAS), time_diff); _LoadGlyphAuras(); // add ghost flag (must be after aura load: PLAYER_FLAGS_GHOST set in aura) if (HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_GHOST)) m_deathState = DEAD; // after spell load, learn rewarded spell if need also - _LoadQuestStatus(holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_QUEST_STATUS)); - _LoadQuestStatusRewarded(holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_QUEST_STATUS_REW)); - _LoadDailyQuestStatus(holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_DAILY_QUEST_STATUS)); - _LoadWeeklyQuestStatus(holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_WEEKLY_QUEST_STATUS)); - _LoadSeasonalQuestStatus(holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_SEASONAL_QUEST_STATUS)); - _LoadMonthlyQuestStatus(holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_MONTHLY_QUEST_STATUS)); - _LoadLFGRewardStatus(holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_LFG_REWARD_STATUS)); - _LoadRandomBGStatus(holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_RANDOM_BG)); + _LoadQuestStatus(holder.GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_QUEST_STATUS)); + _LoadQuestStatusRewarded(holder.GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_QUEST_STATUS_REW)); + _LoadDailyQuestStatus(holder.GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_DAILY_QUEST_STATUS)); + _LoadWeeklyQuestStatus(holder.GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_WEEKLY_QUEST_STATUS)); + _LoadSeasonalQuestStatus(holder.GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_SEASONAL_QUEST_STATUS)); + _LoadMonthlyQuestStatus(holder.GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_MONTHLY_QUEST_STATUS)); + _LoadLFGRewardStatus(holder.GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_LFG_REWARD_STATUS)); + _LoadRandomBGStatus(holder.GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_RANDOM_BG)); // after spell and quest load InitTalentForLevel(); @@ -17549,22 +17549,22 @@ bool Player::LoadFromDB(ObjectGuid guid, CharacterDatabaseQueryHolder* holder) LearnCustomSpells(); // must be before inventory (some items required reputation check) - m_reputationMgr->LoadFromDB(holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_REPUTATION)); + m_reputationMgr->LoadFromDB(holder.GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_REPUTATION)); - _LoadInventory(holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_INVENTORY), time_diff); + _LoadInventory(holder.GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_INVENTORY), time_diff); if (IsVoidStorageUnlocked()) - _LoadVoidStorage(holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_VOID_STORAGE)); + _LoadVoidStorage(holder.GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_VOID_STORAGE)); // update items with duration and realtime UpdateItemDuration(time_diff, true); - _LoadActions(holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_ACTIONS)); + _LoadActions(holder.GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_ACTIONS)); // unread mails and next delivery time, actual mails not loaded - _LoadMail(holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_MAILS), holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_MAIL_ITEMS)); + _LoadMail(holder.GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_MAILS), holder.GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_MAIL_ITEMS)); - m_social = sSocialMgr->LoadFromDB(holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_SOCIAL_LIST), GetGUID()); + m_social = sSocialMgr->LoadFromDB(holder.GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_SOCIAL_LIST), GetGUID()); // check PLAYER_CHOSEN_TITLE compatibility with PLAYER__FIELD_KNOWN_TITLES // note: PLAYER__FIELD_KNOWN_TITLES updated at quest status loaded @@ -17577,7 +17577,7 @@ bool Player::LoadFromDB(ObjectGuid guid, CharacterDatabaseQueryHolder* holder) // has to be called after last Relocate() in Player::LoadFromDB SetFallInformation(0, GetPositionZ()); - GetSpellHistory()->LoadFromDB(holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_SPELL_COOLDOWNS)); + GetSpellHistory()->LoadFromDB(holder.GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_SPELL_COOLDOWNS)); uint32 savedHealth = fields[51].GetUInt32(); if (!savedHealth) @@ -17687,13 +17687,13 @@ bool Player::LoadFromDB(ObjectGuid guid, CharacterDatabaseQueryHolder* holder) if (m_grantableLevels > 0) SetByteValue(PLAYER_FIELD_BYTES, PLAYER_FIELD_BYTES_OFFSET_RAF_GRANTABLE_LEVEL, 0x01); - _LoadDeclinedNames(holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_DECLINED_NAMES)); + _LoadDeclinedNames(holder.GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_DECLINED_NAMES)); m_achievementMgr->CheckAllAchievementCriteria(this); - _LoadEquipmentSets(holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_EQUIPMENT_SETS)); + _LoadEquipmentSets(holder.GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_EQUIPMENT_SETS)); - _LoadCUFProfiles(holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_CUF_PROFILES)); + _LoadCUFProfiles(holder.GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_CUF_PROFILES)); return true; } diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index 7c0651409a8..41e603c5593 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -1485,7 +1485,7 @@ class TC_GAME_API Player : public Unit, public GridObject /*** LOAD SYSTEM ***/ /*********************************************************/ - bool LoadFromDB(ObjectGuid guid, CharacterDatabaseQueryHolder* holder); + bool LoadFromDB(ObjectGuid guid, CharacterDatabaseQueryHolder const& holder); bool IsLoading() const override; void Initialize(ObjectGuid::LowType guid); diff --git a/src/server/game/Handlers/CharacterHandler.cpp b/src/server/game/Handlers/CharacterHandler.cpp index 27007128b5d..8f9ca9a90e1 100644 --- a/src/server/game/Handlers/CharacterHandler.cpp +++ b/src/server/game/Handlers/CharacterHandler.cpp @@ -764,19 +764,18 @@ void WorldSession::HandleContinuePlayerLogin() return; } - LoginQueryHolder* holder = new LoginQueryHolder(GetAccountId(), m_playerLoading); + std::shared_ptr holder = std::make_shared(GetAccountId(), m_playerLoading); if (!holder->Initialize()) { - delete holder; // delete all unprocessed queries m_playerLoading.Clear(); return; } SendPacket(WorldPackets::Auth::ResumeComms(CONNECTION_TYPE_INSTANCE).Write()); - AddQueryHolderCallback(CharacterDatabase.DelayQueryHolder(holder)).AfterComplete([this](SQLQueryHolderBase* holder) + AddQueryHolderCallback(CharacterDatabase.DelayQueryHolder(holder)).AfterComplete([this](SQLQueryHolderBase const& holder) { - HandlePlayerLogin(static_cast(holder)); + HandlePlayerLogin(static_cast(holder)); }); } @@ -803,9 +802,9 @@ void WorldSession::HandleLoadScreenOpcode(WorldPacket& recvPacket) // TODO: Do something with this packet } -void WorldSession::HandlePlayerLogin(LoginQueryHolder* holder) +void WorldSession::HandlePlayerLogin(LoginQueryHolder const& holder) { - ObjectGuid playerGuid = holder->GetGuid(); + ObjectGuid playerGuid = holder.GetGuid(); Player* pCurrChar = new Player(this); // for send server info and strings (config) @@ -817,7 +816,6 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder* holder) SetPlayer(nullptr); KickPlayer(); // disconnect client, player no set to session and it will not deleted or saved at kick delete pCurrChar; // delete it manually - delete holder; // delete all unprocessed queries m_playerLoading.Clear(); return; } @@ -831,7 +829,7 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder* holder) SendPacket(loginVerifyWorld.Write()); // load player specific part before send times - LoadAccountData(holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_ACCOUNT_DATA), PER_CHARACTER_CACHE_MASK); + LoadAccountData(holder.GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_ACCOUNT_DATA), PER_CHARACTER_CACHE_MASK); SendAccountDataTimes(PER_CHARACTER_CACHE_MASK); WorldPackets::System::FeatureSystemStatus features; @@ -865,7 +863,7 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder* holder) chH.PSendSysMessage(GitRevision::GetFullVersion()); //QueryResult* result = CharacterDatabase.PQuery("SELECT guildid, rank FROM guild_member WHERE guid = '%u'", pCurrChar->GetGUID().GetCounter()); - if (PreparedQueryResult resultGuild = holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_GUILD)) + if (PreparedQueryResult resultGuild = holder.GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_GUILD)) { Field* fields = resultGuild->Fetch(); pCurrChar->SetInGuild(fields[0].GetUInt32()); @@ -986,7 +984,7 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder* holder) sSocialMgr->SendFriendStatus(pCurrChar, FRIEND_ONLINE, pCurrChar->GetGUID(), true); // Place character in world (and load zone) before some object loading - pCurrChar->LoadCorpse(holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_CORPSE_LOCATION)); + pCurrChar->LoadCorpse(holder.GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_CORPSE_LOCATION)); // setting Ghost+speed if dead if (pCurrChar->m_deathState == DEAD) @@ -998,7 +996,7 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder* holder) if (pCurrChar->HasAtLoginFlag(AT_LOGIN_RESET_PET_TALENTS)) Pet::resetTalentsForAllPetsOf(pCurrChar); - pCurrChar->LoadPetsFromDB(holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_ALL_PETS)); + pCurrChar->LoadPetsFromDB(holder.GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_ALL_PETS)); // Load pet if any (if player not alive and in taxi flight or another then pet will remember as temporary unsummoned) pCurrChar->LoadPet(); @@ -1149,8 +1147,6 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder* holder) TC_METRIC_EVENT("player_events", "Login", pCurrChar->GetName()); sBattlenetServer.SendChangeToonOnlineState(GetBattlenetAccountId(), GetAccountId(), _player->GetGUID(), _player->GetName(), true); - - delete holder; } void WorldSession::HandleSetFactionAtWar(WorldPacket& recvData) diff --git a/src/server/game/Server/WorldSession.cpp b/src/server/game/Server/WorldSession.cpp index 7efdcd80848..aaf50df84b0 100644 --- a/src/server/game/Server/WorldSession.cpp +++ b/src/server/game/Server/WorldSession.cpp @@ -1205,24 +1205,23 @@ public: void WorldSession::InitializeSession() { - AccountInfoQueryHolderPerRealm* realmHolder = new AccountInfoQueryHolderPerRealm(); + std::shared_ptr realmHolder = std::make_shared(); if (!realmHolder->Initialize(GetAccountId(), GetBattlenetAccountId())) { - delete realmHolder; SendAuthResponse(AUTH_SYSTEM_ERROR, false); return; } - AddQueryHolderCallback(CharacterDatabase.DelayQueryHolder(realmHolder)).AfterComplete([this](SQLQueryHolderBase* holder) + AddQueryHolderCallback(CharacterDatabase.DelayQueryHolder(realmHolder)).AfterComplete([this](SQLQueryHolderBase const& holder) { - InitializeSessionCallback(static_cast(holder)); + InitializeSessionCallback(static_cast(holder)); }); } -void WorldSession::InitializeSessionCallback(CharacterDatabaseQueryHolder* realmHolder) +void WorldSession::InitializeSessionCallback(CharacterDatabaseQueryHolder const& realmHolder) { - LoadAccountData(realmHolder->GetPreparedResult(AccountInfoQueryHolderPerRealm::GLOBAL_ACCOUNT_DATA), GLOBAL_CACHE_MASK); - LoadTutorialsData(realmHolder->GetPreparedResult(AccountInfoQueryHolderPerRealm::TUTORIALS)); + LoadAccountData(realmHolder.GetPreparedResult(AccountInfoQueryHolderPerRealm::GLOBAL_ACCOUNT_DATA), GLOBAL_CACHE_MASK); + LoadTutorialsData(realmHolder.GetPreparedResult(AccountInfoQueryHolderPerRealm::TUTORIALS)); if (!m_inQueue) SendAuthResponse(AUTH_OK, false); @@ -1235,8 +1234,6 @@ void WorldSession::InitializeSessionCallback(CharacterDatabaseQueryHolder* realm SendAddonsInfo(); SendClientCacheVersion(sWorld->getIntConfig(CONFIG_CLIENTCACHE_VERSION)); SendTutorialsData(); - - delete realmHolder; } rbac::RBACData* WorldSession::GetRBACData() diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h index 9ba42f4868d..83bd96eb42f 100644 --- a/src/server/game/Server/WorldSession.h +++ b/src/server/game/Server/WorldSession.h @@ -422,7 +422,7 @@ class TC_GAME_API WorldSession void SendClientCacheVersion(uint32 version); void InitializeSession(); - void InitializeSessionCallback(CharacterDatabaseQueryHolder* realmHolder); + void InitializeSessionCallback(CharacterDatabaseQueryHolder const& realmHolder); rbac::RBACData* GetRBACData(); bool HasPermission(uint32 permissionId); @@ -603,7 +603,7 @@ class TC_GAME_API WorldSession void HandleContinuePlayerLogin(); void AbortLogin(WorldPackets::Character::LoginFailureReason reason); void HandleLoadScreenOpcode(WorldPacket& recvPacket); - void HandlePlayerLogin(LoginQueryHolder* holder); + void HandlePlayerLogin(LoginQueryHolder const& holder); void HandleCharFactionOrRaceChange(WorldPacket& recvData); void HandleCharFactionOrRaceChangeCallback(std::shared_ptr factionChangeInfo, PreparedQueryResult result); void HandleCharRenameOpcode(WorldPacket& recvData);