mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-20 09:17:36 +01:00
Core/DBLayer: Fixed memory leaks with existing SQLQueryHolder uses and eliminated the possibilty of adding more in future (replaced manual memory management with smart pointers)
This commit is contained in:
@@ -75,8 +75,8 @@ using LoginDatabaseTransaction = SQLTransaction<LoginDatabaseConnection>;
|
||||
using WorldDatabaseTransaction = SQLTransaction<WorldDatabaseConnection>;
|
||||
|
||||
class SQLQueryHolderBase;
|
||||
using QueryResultHolderFuture = std::future<SQLQueryHolderBase*>;
|
||||
using QueryResultHolderPromise = std::promise<SQLQueryHolderBase*>;
|
||||
using QueryResultHolderFuture = std::future<void>;
|
||||
using QueryResultHolderPromise = std::promise<void>;
|
||||
|
||||
template<typename T>
|
||||
class SQLQueryHolder;
|
||||
|
||||
@@ -223,13 +223,13 @@ QueryCallback DatabaseWorkerPool<T>::AsyncQuery(PreparedStatement<T>* stmt)
|
||||
}
|
||||
|
||||
template <class T>
|
||||
SQLQueryHolderCallback DatabaseWorkerPool<T>::DelayQueryHolder(SQLQueryHolder<T>* holder)
|
||||
SQLQueryHolderCallback DatabaseWorkerPool<T>::DelayQueryHolder(std::shared_ptr<SQLQueryHolder<T>> 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 <class T>
|
||||
|
||||
@@ -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<T>* holder);
|
||||
SQLQueryHolderCallback DelayQueryHolder(std::shared_ptr<SQLQueryHolder<T>> holder);
|
||||
|
||||
/**
|
||||
Transaction context methods.
|
||||
|
||||
@@ -15,10 +15,11 @@
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#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;
|
||||
}
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#define _QUERYHOLDER_H
|
||||
|
||||
#include "SQLOperation.h"
|
||||
#include <vector>
|
||||
|
||||
class TC_DATABASE_API SQLQueryHolderBase
|
||||
{
|
||||
@@ -27,10 +28,10 @@ class TC_DATABASE_API SQLQueryHolderBase
|
||||
std::vector<std::pair<PreparedStatementBase*, PreparedQueryResult>> 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<SQLQueryHolderBase> m_holder;
|
||||
QueryResultHolderPromise m_result;
|
||||
bool m_executed;
|
||||
|
||||
public:
|
||||
SQLQueryHolderTask(SQLQueryHolderBase* holder)
|
||||
: m_holder(holder), m_executed(false) { }
|
||||
explicit SQLQueryHolderTask(std::shared_ptr<SQLQueryHolderBase> 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<SQLQueryHolderBase>&& holder, QueryResultHolderFuture&& future)
|
||||
: m_holder(std::move(holder)), m_future(std::move(future)) { }
|
||||
|
||||
SQLQueryHolderCallback(SQLQueryHolderCallback&&) = default;
|
||||
|
||||
SQLQueryHolderCallback& operator=(SQLQueryHolderCallback&&) = default;
|
||||
|
||||
void AfterComplete(std::function<void(SQLQueryHolderBase*)> callback) &
|
||||
void AfterComplete(std::function<void(SQLQueryHolderBase const&)> callback)&
|
||||
{
|
||||
m_callback = std::move(callback);
|
||||
}
|
||||
|
||||
bool InvokeIfReady();
|
||||
|
||||
std::shared_ptr<SQLQueryHolderBase> m_holder;
|
||||
QueryResultHolderFuture m_future;
|
||||
std::function<void(SQLQueryHolderBase*)> m_callback;
|
||||
std::function<void(SQLQueryHolderBase const&)> m_callback;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -42,13 +42,6 @@ struct SQLElementData
|
||||
SQLElementDataType type;
|
||||
};
|
||||
|
||||
//- For ambigious resultsets
|
||||
union SQLResultSetUnion
|
||||
{
|
||||
PreparedResultSet* presult;
|
||||
ResultSet* qresult;
|
||||
};
|
||||
|
||||
class MySQLConnection;
|
||||
|
||||
class TC_DATABASE_API SQLOperation
|
||||
|
||||
@@ -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 = "<unknown>";
|
||||
@@ -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<Player>(holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_SPELL_COOLDOWNS));
|
||||
GetSpellHistory()->LoadFromDB<Player>(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;
|
||||
}
|
||||
|
||||
@@ -1485,7 +1485,7 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>
|
||||
/*** LOAD SYSTEM ***/
|
||||
/*********************************************************/
|
||||
|
||||
bool LoadFromDB(ObjectGuid guid, CharacterDatabaseQueryHolder* holder);
|
||||
bool LoadFromDB(ObjectGuid guid, CharacterDatabaseQueryHolder const& holder);
|
||||
bool IsLoading() const override;
|
||||
|
||||
void Initialize(ObjectGuid::LowType guid);
|
||||
|
||||
@@ -764,19 +764,18 @@ void WorldSession::HandleContinuePlayerLogin()
|
||||
return;
|
||||
}
|
||||
|
||||
LoginQueryHolder* holder = new LoginQueryHolder(GetAccountId(), m_playerLoading);
|
||||
std::shared_ptr<LoginQueryHolder> holder = std::make_shared<LoginQueryHolder>(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<LoginQueryHolder*>(holder));
|
||||
HandlePlayerLogin(static_cast<LoginQueryHolder const&>(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)
|
||||
|
||||
@@ -1205,24 +1205,23 @@ public:
|
||||
|
||||
void WorldSession::InitializeSession()
|
||||
{
|
||||
AccountInfoQueryHolderPerRealm* realmHolder = new AccountInfoQueryHolderPerRealm();
|
||||
std::shared_ptr<AccountInfoQueryHolderPerRealm> realmHolder = std::make_shared<AccountInfoQueryHolderPerRealm>();
|
||||
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<AccountInfoQueryHolderPerRealm*>(holder));
|
||||
InitializeSessionCallback(static_cast<AccountInfoQueryHolderPerRealm const&>(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()
|
||||
|
||||
@@ -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<CharacterFactionChangeInfo> factionChangeInfo, PreparedQueryResult result);
|
||||
void HandleCharRenameOpcode(WorldPacket& recvData);
|
||||
|
||||
Reference in New Issue
Block a user