aboutsummaryrefslogtreecommitdiff
path: root/src/server/game
diff options
context:
space:
mode:
authorShauren <shauren.trinity@gmail.com>2017-01-13 21:38:03 +0100
committerShauren <shauren.trinity@gmail.com>2017-01-13 21:38:03 +0100
commit8e2634b2b49eb814b8cc425a060b2f160dbb49b7 (patch)
tree9fc926ba9f77539c3eb847e37f3f9d7061f9d47a /src/server/game
parent0f432edc4b48a8692e41fc30aef7751d295a7176 (diff)
Core/DBLayer: Convert async queries to new query callbacks and remove old callback handling
Diffstat (limited to 'src/server/game')
-rw-r--r--src/server/game/Accounts/RBAC.cpp3
-rw-r--r--src/server/game/Accounts/RBAC.h2
-rw-r--r--src/server/game/Handlers/CharacterHandler.cpp440
-rw-r--r--src/server/game/Handlers/NPCHandler.cpp18
-rw-r--r--src/server/game/Handlers/SocialHandler.cpp9
-rw-r--r--src/server/game/Server/WorldSession.cpp127
-rw-r--r--src/server/game/Server/WorldSession.h36
-rw-r--r--src/server/game/Server/WorldSocket.cpp20
-rw-r--r--src/server/game/Server/WorldSocket.h4
-rw-r--r--src/server/game/World/World.cpp20
-rw-r--r--src/server/game/World/World.h4
11 files changed, 215 insertions, 468 deletions
diff --git a/src/server/game/Accounts/RBAC.cpp b/src/server/game/Accounts/RBAC.cpp
index 378a66aa989..951223a9257 100644
--- a/src/server/game/Accounts/RBAC.cpp
+++ b/src/server/game/Accounts/RBAC.cpp
@@ -18,6 +18,7 @@
#include "RBAC.h"
#include "AccountMgr.h"
#include "Log.h"
+#include "QueryCallback.h"
namespace rbac
{
@@ -182,7 +183,7 @@ void RBACData::LoadFromDB()
LoadFromDBCallback(LoginDatabase.Query(stmt));
}
-PreparedQueryResultFuture RBACData::LoadFromDBAsync()
+QueryCallback RBACData::LoadFromDBAsync()
{
ClearData();
diff --git a/src/server/game/Accounts/RBAC.h b/src/server/game/Accounts/RBAC.h
index 597f2a9fd24..a053a9e86bf 100644
--- a/src/server/game/Accounts/RBAC.h
+++ b/src/server/game/Accounts/RBAC.h
@@ -923,7 +923,7 @@ class TC_GAME_API RBACData
/// Loads all permissions assigned to current account
void LoadFromDB();
- PreparedQueryResultFuture LoadFromDBAsync();
+ QueryCallback LoadFromDBAsync();
void LoadFromDBCallback(PreparedQueryResult result);
/// Sets security level
diff --git a/src/server/game/Handlers/CharacterHandler.cpp b/src/server/game/Handlers/CharacterHandler.cpp
index 644365b9177..04477528a04 100644
--- a/src/server/game/Handlers/CharacterHandler.cpp
+++ b/src/server/game/Handlers/CharacterHandler.cpp
@@ -42,6 +42,7 @@
#include "Pet.h"
#include "PlayerDump.h"
#include "Player.h"
+#include "QueryCallback.h"
#include "QueryPackets.h"
#include "ReputationMgr.h"
#include "GitRevision.h"
@@ -350,8 +351,7 @@ void WorldSession::HandleCharEnumOpcode(WorldPackets::Character::EnumCharacters&
stmt->setUInt8(0, PET_SAVE_AS_CURRENT);
stmt->setUInt32(1, GetAccountId());
- _charEnumCallback.SetParam(false);
- _charEnumCallback.SetFutureResult(CharacterDatabase.AsyncQuery(stmt));
+ _queryProcessor.AddQuery(CharacterDatabase.AsyncQuery(stmt).WithPreparedCallback(std::bind(&WorldSession::HandleCharEnum, this, std::placeholders::_1)));
}
void WorldSession::HandleCharUndeleteEnum(PreparedQueryResult result)
@@ -393,8 +393,7 @@ void WorldSession::HandleCharUndeleteEnumOpcode(WorldPackets::Character::EnumCha
stmt->setUInt8(0, PET_SAVE_AS_CURRENT);
stmt->setUInt32(1, GetAccountId());
- _charEnumCallback.SetParam(true);
- _charEnumCallback.SetFutureResult(CharacterDatabase.AsyncQuery(stmt));
+ _queryProcessor.AddQuery(CharacterDatabase.AsyncQuery(stmt).WithPreparedCallback(std::bind(&WorldSession::HandleCharUndeleteEnum, this, std::placeholders::_1)));
}
void WorldSession::HandleCharCreateOpcode(WorldPackets::Character::CreateCharacter& charCreate)
@@ -519,101 +518,60 @@ void WorldSession::HandleCharCreateOpcode(WorldPackets::Character::CreateCharact
}
}
+ std::shared_ptr<WorldPackets::Character::CharacterCreateInfo> createInfo = charCreate.CreateInfo;
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHECK_NAME);
stmt->setString(0, charCreate.CreateInfo->Name);
- _charCreateCallback.SetParam(charCreate.CreateInfo);
- _charCreateCallback.SetFutureResult(CharacterDatabase.AsyncQuery(stmt));
-}
-
-void WorldSession::HandleCharCreateCallback(PreparedQueryResult result, WorldPackets::Character::CharacterCreateInfo* createInfo)
-{
- /** This is a series of callbacks executed consecutively as a result from the database becomes available.
- This is much more efficient than synchronous requests on packet handler, and much less DoS prone.
- It also prevents data synchronisation errors.
- */
- switch (_charCreateCallback.GetStage())
+ _queryProcessor.AddQuery(CharacterDatabase.AsyncQuery(stmt)
+ .WithChainingPreparedCallback([this](QueryCallback& queryCallback, PreparedQueryResult result)
{
- case 0:
+ if (result)
{
- if (result)
- {
- SendCharCreate(CHAR_CREATE_NAME_IN_USE);
- _charCreateCallback.Reset();
- return;
- }
-
- ASSERT(_charCreateCallback.GetParam().get() == createInfo);
+ SendCharCreate(CHAR_CREATE_NAME_IN_USE);
+ return;
+ }
- PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_SUM_REALM_CHARACTERS);
- stmt->setUInt32(0, GetAccountId());
+ PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_SUM_REALM_CHARACTERS);
+ stmt->setUInt32(0, GetAccountId());
+ queryCallback.SetNextQuery(LoginDatabase.AsyncQuery(stmt));
+ })
+ .WithChainingPreparedCallback([this](QueryCallback& queryCallback, PreparedQueryResult result)
+ {
+ uint64 acctCharCount = 0;
+ if (result)
+ {
+ Field* fields = result->Fetch();
+ acctCharCount = uint64(fields[0].GetDouble());
+ }
- _charCreateCallback.FreeResult();
- _charCreateCallback.SetFutureResult(LoginDatabase.AsyncQuery(stmt));
- _charCreateCallback.NextStage();
- break;
+ if (acctCharCount >= sWorld->getIntConfig(CONFIG_CHARACTERS_PER_ACCOUNT))
+ {
+ SendCharCreate(CHAR_CREATE_ACCOUNT_LIMIT);
+ return;
}
- case 1:
+
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_SUM_CHARS);
+ stmt->setUInt32(0, GetAccountId());
+ queryCallback.SetNextQuery(LoginDatabase.AsyncQuery(stmt));
+ })
+ .WithChainingPreparedCallback([this, createInfo](QueryCallback& queryCallback, PreparedQueryResult result)
+ {
+ if (result)
{
- uint64 acctCharCount = 0;
- if (result)
- {
- Field* fields = result->Fetch();
- acctCharCount = uint64(fields[0].GetDouble());
- }
+ Field* fields = result->Fetch();
+ createInfo->CharCount = uint8(fields[0].GetUInt64()); // SQL's COUNT() returns uint64 but it will always be less than uint8.Max
- if (acctCharCount >= sWorld->getIntConfig(CONFIG_CHARACTERS_PER_ACCOUNT))
+ if (createInfo->CharCount >= sWorld->getIntConfig(CONFIG_CHARACTERS_PER_REALM))
{
- SendCharCreate(CHAR_CREATE_ACCOUNT_LIMIT);
- _charCreateCallback.Reset();
+ SendCharCreate(CHAR_CREATE_SERVER_LIMIT);
return;
}
-
- ASSERT(_charCreateCallback.GetParam().get() == createInfo);
-
- PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_SUM_CHARS);
- stmt->setUInt32(0, GetAccountId());
-
- _charCreateCallback.FreeResult();
- _charCreateCallback.SetFutureResult(CharacterDatabase.AsyncQuery(stmt));
- _charCreateCallback.NextStage();
- break;
}
- case 2:
- {
- if (result)
- {
- Field* fields = result->Fetch();
- createInfo->CharCount = uint8(fields[0].GetUInt64()); // SQL's COUNT() returns uint64 but it will always be less than uint8.Max
- if (createInfo->CharCount >= sWorld->getIntConfig(CONFIG_CHARACTERS_PER_REALM))
- {
- SendCharCreate(CHAR_CREATE_SERVER_LIMIT);
- _charCreateCallback.Reset();
- return;
- }
- }
-
- bool allowTwoSideAccounts = !sWorld->IsPvPRealm() || HasPermission(rbac::RBAC_PERM_TWO_SIDE_CHARACTER_CREATION);
- uint32 skipCinematics = sWorld->getIntConfig(CONFIG_SKIP_CINEMATICS);
-
- _charCreateCallback.FreeResult();
-
- if (!allowTwoSideAccounts || skipCinematics == 1 || createInfo->Class == CLASS_DEATH_KNIGHT || createInfo->Class == CLASS_DEMON_HUNTER)
- {
- PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_CREATE_INFO);
- stmt->setUInt32(0, GetAccountId());
- stmt->setUInt32(1, (skipCinematics == 1 || createInfo->Class == CLASS_DEATH_KNIGHT || createInfo->Class == CLASS_DEMON_HUNTER) ? 12 : 1);
- _charCreateCallback.SetFutureResult(CharacterDatabase.AsyncQuery(stmt));
- _charCreateCallback.NextStage();
- return;
- }
+ bool allowTwoSideAccounts = !sWorld->IsPvPRealm() || HasPermission(rbac::RBAC_PERM_TWO_SIDE_CHARACTER_CREATION);
+ uint32 skipCinematics = sWorld->getIntConfig(CONFIG_SKIP_CINEMATICS);
- _charCreateCallback.NextStage();
- HandleCharCreateCallback(PreparedQueryResult(NULL), createInfo); // Will jump to case 3
- break;
- }
- case 3:
+ std::function<void(PreparedQueryResult)> finalizeCharacterCreation = [this, createInfo](PreparedQueryResult result)
{
bool haveSameRace = false;
uint32 heroicReqLevel = sWorld->getIntConfig(CONFIG_CHARACTER_CREATING_MIN_LEVEL_FOR_HEROIC_CHARACTER);
@@ -632,7 +590,7 @@ void WorldSession::HandleCharCreateCallback(PreparedQueryResult result, WorldPac
uint32 freeDemonHunterSlots = sWorld->getIntConfig(CONFIG_DEMON_HUNTERS_PER_REALM);
Field* field = result->Fetch();
- uint8 accRace = field[1].GetUInt8();
+ uint8 accRace = field[1].GetUInt8();
if (checkHeroicReqs)
{
@@ -645,7 +603,6 @@ void WorldSession::HandleCharCreateCallback(PreparedQueryResult result, WorldPac
if (freeHeroicSlots == 0)
{
SendCharCreate(CHAR_CREATE_UNIQUE_CLASS_LIMIT);
- _charCreateCallback.Reset();
return;
}
}
@@ -669,7 +626,6 @@ void WorldSession::HandleCharCreateCallback(PreparedQueryResult result, WorldPac
if (freeDemonHunterSlots == 0)
{
SendCharCreate(CHAR_CREATE_FAILED);
- _charCreateCallback.Reset();
return;
}
}
@@ -693,7 +649,6 @@ void WorldSession::HandleCharCreateCallback(PreparedQueryResult result, WorldPac
if (accTeam != team)
{
SendCharCreate(CHAR_CREATE_PVP_TEAMS_VIOLATION);
- _charCreateCallback.Reset();
return;
}
}
@@ -722,7 +677,6 @@ void WorldSession::HandleCharCreateCallback(PreparedQueryResult result, WorldPac
if (freeHeroicSlots == 0)
{
SendCharCreate(CHAR_CREATE_UNIQUE_CLASS_LIMIT);
- _charCreateCallback.Reset();
return;
}
}
@@ -746,7 +700,6 @@ void WorldSession::HandleCharCreateCallback(PreparedQueryResult result, WorldPac
if (freeDemonHunterSlots == 0)
{
SendCharCreate(CHAR_CREATE_FAILED);
- _charCreateCallback.Reset();
return;
}
}
@@ -764,26 +717,23 @@ void WorldSession::HandleCharCreateCallback(PreparedQueryResult result, WorldPac
if (checkHeroicReqs && !hasHeroicReqLevel)
{
SendCharCreate(CHAR_CREATE_LEVEL_REQUIREMENT);
- _charCreateCallback.Reset();
return;
}
if (checkDemonHunterReqs && !hasDemonHunterReqLevel)
{
SendCharCreate(CHAR_CREATE_LEVEL_REQUIREMENT);
- _charCreateCallback.Reset();
return;
}
Player newChar(this);
newChar.GetMotionMaster()->Initialize();
- if (!newChar.Create(sObjectMgr->GetGenerator<HighGuid::Player>().Generate(), createInfo))
+ if (!newChar.Create(sObjectMgr->GetGenerator<HighGuid::Player>().Generate(), createInfo.get()))
{
// Player not create (race/class/etc problem?)
newChar.CleanupsBeforeDelete();
SendCharCreate(CHAR_CREATE_ERROR);
- _charCreateCallback.Reset();
return;
}
@@ -792,7 +742,7 @@ void WorldSession::HandleCharCreateCallback(PreparedQueryResult result, WorldPac
newChar.SetAtLoginFlag(AT_LOGIN_FIRST); // First login
- // Player created, save it now
+ // Player created, save it now
newChar.SaveToDB(true);
createInfo->CharCount += 1;
@@ -837,10 +787,19 @@ void WorldSession::HandleCharCreateCallback(PreparedQueryResult result, WorldPac
sWorld->AddCharacterInfo(newChar.GetGUID(), GetAccountId(), newChar.GetName(), newChar.GetByteValue(PLAYER_BYTES_3, PLAYER_BYTES_3_OFFSET_GENDER), newChar.getRace(), newChar.getClass(), newChar.getLevel(), false);
newChar.CleanupsBeforeDelete();
- _charCreateCallback.Reset();
- break;
+ };
+
+ if (allowTwoSideAccounts && !skipCinematics && createInfo->Class != CLASS_DEATH_KNIGHT && createInfo->Class != CLASS_DEMON_HUNTER)
+ {
+ finalizeCharacterCreation(PreparedQueryResult(nullptr));
+ return;
}
- }
+
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_CREATE_INFO);
+ stmt->setUInt32(0, GetAccountId());
+ stmt->setUInt32(1, (skipCinematics == 1 || createInfo->Class == CLASS_DEATH_KNIGHT || createInfo->Class == CLASS_DEMON_HUNTER) ? 12 : 1);
+ queryCallback.WithPreparedCallback(std::move(finalizeCharacterCreation)).SetNextQuery(CharacterDatabase.AsyncQuery(stmt));
+ }));
}
void WorldSession::HandleCharDeleteOpcode(WorldPackets::Character::CharDelete& charDelete)
@@ -1371,17 +1330,15 @@ void WorldSession::HandleCharRenameOpcode(WorldPackets::Character::CharacterRena
stmt->setUInt64(0, request.RenameInfo->Guid.GetCounter());
stmt->setString(1, request.RenameInfo->NewName);
- _charRenameCallback.SetParam(request.RenameInfo);
- _charRenameCallback.SetFutureResult(CharacterDatabase.AsyncQuery(stmt));
+ _queryProcessor.AddQuery(CharacterDatabase.AsyncQuery(stmt)
+ .WithPreparedCallback(std::bind(&WorldSession::HandleCharRenameCallBack, this, request.RenameInfo, std::placeholders::_1)));
}
-void WorldSession::HandleCharRenameCallBack(PreparedQueryResult result, WorldPackets::Character::CharacterRenameInfo* renameInfo)
+void WorldSession::HandleCharRenameCallBack(std::shared_ptr<WorldPackets::Character::CharacterRenameInfo> renameInfo, PreparedQueryResult result)
{
- ASSERT(_charRenameCallback.GetParam().get() == renameInfo);
-
if (!result)
{
- SendCharRename(CHAR_CREATE_ERROR, renameInfo);
+ SendCharRename(CHAR_CREATE_ERROR, renameInfo.get());
return;
}
@@ -1392,7 +1349,7 @@ void WorldSession::HandleCharRenameCallBack(PreparedQueryResult result, WorldPac
if (!(atLoginFlags & AT_LOGIN_RENAME))
{
- SendCharRename(CHAR_CREATE_ERROR, renameInfo);
+ SendCharRename(CHAR_CREATE_ERROR, renameInfo.get());
return;
}
@@ -1420,7 +1377,7 @@ void WorldSession::HandleCharRenameCallBack(PreparedQueryResult result, WorldPac
TC_LOG_INFO("entities.player.character", "Account: %u (IP: %s) Character:[%s] (%s) Changed name to: %s",
GetAccountId(), GetRemoteAddress().c_str(), oldName.c_str(), renameInfo->Guid.ToString().c_str(), renameInfo->NewName.c_str());
- SendCharRename(RESPONSE_SUCCESS, renameInfo);
+ SendCharRename(RESPONSE_SUCCESS, renameInfo.get());
sWorld->UpdateCharacterInfo(renameInfo->Guid, renameInfo->NewName);
}
@@ -1582,17 +1539,15 @@ void WorldSession::HandleCharCustomizeOpcode(WorldPackets::Character::CharCustom
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_CUSTOMIZE_INFO);
stmt->setUInt64(0, packet.CustomizeInfo->CharGUID.GetCounter());
- _charCustomizeCallback.SetParam(packet.CustomizeInfo);
- _charCustomizeCallback.SetFutureResult(CharacterDatabase.AsyncQuery(stmt));
+ _queryProcessor.AddQuery(CharacterDatabase.AsyncQuery(stmt)
+ .WithPreparedCallback(std::bind(&WorldSession::HandleCharCustomizeCallback, this, packet.CustomizeInfo, std::placeholders::_1)));
}
-void WorldSession::HandleCharCustomizeCallback(PreparedQueryResult result, WorldPackets::Character::CharCustomizeInfo* customizeInfo)
+void WorldSession::HandleCharCustomizeCallback(std::shared_ptr<WorldPackets::Character::CharCustomizeInfo> customizeInfo, PreparedQueryResult result)
{
- ASSERT(_charCustomizeCallback.GetParam().get() == customizeInfo);
-
if (!result)
{
- SendCharCustomize(CHAR_CREATE_ERROR, customizeInfo);
+ SendCharCustomize(CHAR_CREATE_ERROR, customizeInfo.get());
return;
}
@@ -1607,13 +1562,13 @@ void WorldSession::HandleCharCustomizeCallback(PreparedQueryResult result, World
if (!Player::ValidateAppearance(plrRace, plrClass, plrGender, customizeInfo->HairStyleID, customizeInfo->HairColorID, customizeInfo->FaceID,
customizeInfo->FacialHairStyleID, customizeInfo->SkinID, customizeInfo->CustomDisplay))
{
- SendCharCustomize(CHAR_CREATE_ERROR, customizeInfo);
+ SendCharCustomize(CHAR_CREATE_ERROR, customizeInfo.get());
return;
}
if (!(atLoginFlags & AT_LOGIN_CUSTOMIZE))
{
- SendCharCustomize(CHAR_CREATE_ERROR, customizeInfo);
+ SendCharCustomize(CHAR_CREATE_ERROR, customizeInfo.get());
return;
}
@@ -1622,21 +1577,21 @@ void WorldSession::HandleCharCustomizeCallback(PreparedQueryResult result, World
// prevent character rename to invalid name
if (!normalizePlayerName(customizeInfo->CharName))
{
- SendCharCustomize(CHAR_NAME_NO_NAME, customizeInfo);
+ SendCharCustomize(CHAR_NAME_NO_NAME, customizeInfo.get());
return;
}
ResponseCodes res = ObjectMgr::CheckPlayerName(customizeInfo->CharName, GetSessionDbcLocale(), true);
if (res != CHAR_NAME_SUCCESS)
{
- SendCharCustomize(res, customizeInfo);
+ SendCharCustomize(res, customizeInfo.get());
return;
}
// check name limitations
if (!HasPermission(rbac::RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_RESERVEDNAME) && sObjectMgr->IsReservedName(customizeInfo->CharName))
{
- SendCharCustomize(CHAR_NAME_RESERVED, customizeInfo);
+ SendCharCustomize(CHAR_NAME_RESERVED, customizeInfo.get());
return;
}
@@ -1647,7 +1602,7 @@ void WorldSession::HandleCharCustomizeCallback(PreparedQueryResult result, World
{
if (newGuid != customizeInfo->CharGUID)
{
- SendCharCustomize(CHAR_CREATE_NAME_IN_USE, customizeInfo);
+ SendCharCustomize(CHAR_CREATE_NAME_IN_USE, customizeInfo.get());
return;
}
}
@@ -1694,7 +1649,7 @@ void WorldSession::HandleCharCustomizeCallback(PreparedQueryResult result, World
sWorld->UpdateCharacterInfo(customizeInfo->CharGUID, customizeInfo->CharName, customizeInfo->SexID);
- SendCharCustomize(RESPONSE_SUCCESS, customizeInfo);
+ SendCharCustomize(RESPONSE_SUCCESS, customizeInfo.get());
TC_LOG_INFO("entities.player.character", "Account: %u (IP: %s), Character[%s] (%s) Customized to: %s",
GetAccountId(), GetRemoteAddress().c_str(), oldName.c_str(), customizeInfo->CharGUID.ToString().c_str(), customizeInfo->CharName.c_str());
@@ -1855,17 +1810,15 @@ void WorldSession::HandleCharRaceOrFactionChangeOpcode(WorldPackets::Character::
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_RACE_OR_FACTION_CHANGE_INFOS);
stmt->setUInt64(0, packet.RaceOrFactionChangeInfo->Guid.GetCounter());
- _charFactionChangeCallback.SetParam(packet.RaceOrFactionChangeInfo);
- _charFactionChangeCallback.SetFutureResult(CharacterDatabase.AsyncQuery(stmt));
+ _queryProcessor.AddQuery(CharacterDatabase.AsyncQuery(stmt)
+ .WithPreparedCallback(std::bind(&WorldSession::HandleCharRaceOrFactionChangeCallback, this, packet.RaceOrFactionChangeInfo, std::placeholders::_1)));
}
-void WorldSession::HandleCharRaceOrFactionChangeCallback(PreparedQueryResult result, WorldPackets::Character::CharRaceOrFactionChangeInfo* factionChangeInfo)
+void WorldSession::HandleCharRaceOrFactionChangeCallback(std::shared_ptr<WorldPackets::Character::CharRaceOrFactionChangeInfo> factionChangeInfo, PreparedQueryResult result)
{
- ASSERT(_charFactionChangeCallback.GetParam().get() == factionChangeInfo);
-
if (!result)
{
- SendCharFactionChange(CHAR_CREATE_ERROR, factionChangeInfo);
+ SendCharFactionChange(CHAR_CREATE_ERROR, factionChangeInfo.get());
return;
}
@@ -1873,7 +1826,7 @@ void WorldSession::HandleCharRaceOrFactionChangeCallback(PreparedQueryResult res
CharacterInfo const* characterInfo = sWorld->GetCharacterInfo(factionChangeInfo->Guid);
if (!characterInfo)
{
- SendCharFactionChange(CHAR_CREATE_ERROR, factionChangeInfo);
+ SendCharFactionChange(CHAR_CREATE_ERROR, factionChangeInfo.get());
return;
}
@@ -1883,7 +1836,7 @@ void WorldSession::HandleCharRaceOrFactionChangeCallback(PreparedQueryResult res
if (!sObjectMgr->GetPlayerInfo(factionChangeInfo->RaceID, playerClass))
{
- SendCharFactionChange(CHAR_CREATE_ERROR, factionChangeInfo);
+ SendCharFactionChange(CHAR_CREATE_ERROR, factionChangeInfo.get());
return;
}
@@ -1894,20 +1847,20 @@ void WorldSession::HandleCharRaceOrFactionChangeCallback(PreparedQueryResult res
uint16 usedLoginFlag = (factionChangeInfo->FactionChange ? AT_LOGIN_CHANGE_FACTION : AT_LOGIN_CHANGE_RACE);
if (!(atLoginFlags & usedLoginFlag))
{
- SendCharFactionChange(CHAR_CREATE_ERROR, factionChangeInfo);
+ SendCharFactionChange(CHAR_CREATE_ERROR, factionChangeInfo.get());
return;
}
TeamId newTeamId = Player::TeamIdForRace(factionChangeInfo->RaceID);
if (newTeamId == TEAM_NEUTRAL)
{
- SendCharFactionChange(CHAR_CREATE_RESTRICTED_RACECLASS, factionChangeInfo);
+ SendCharFactionChange(CHAR_CREATE_RESTRICTED_RACECLASS, factionChangeInfo.get());
return;
}
if (factionChangeInfo->FactionChange == (Player::TeamIdForRace(oldRace) == newTeamId))
{
- SendCharFactionChange(factionChangeInfo->FactionChange ? CHAR_CREATE_CHARACTER_SWAP_FACTION : CHAR_CREATE_CHARACTER_RACE_ONLY, factionChangeInfo);
+ SendCharFactionChange(factionChangeInfo->FactionChange ? CHAR_CREATE_CHARACTER_SWAP_FACTION : CHAR_CREATE_CHARACTER_RACE_ONLY, factionChangeInfo.get());
return;
}
@@ -1916,7 +1869,7 @@ void WorldSession::HandleCharRaceOrFactionChangeCallback(PreparedQueryResult res
uint32 raceMaskDisabled = sWorld->getIntConfig(CONFIG_CHARACTER_CREATING_DISABLED_RACEMASK);
if ((1 << (factionChangeInfo->RaceID - 1)) & raceMaskDisabled)
{
- SendCharFactionChange(CHAR_CREATE_ERROR, factionChangeInfo);
+ SendCharFactionChange(CHAR_CREATE_ERROR, factionChangeInfo.get());
return;
}
}
@@ -1924,21 +1877,21 @@ void WorldSession::HandleCharRaceOrFactionChangeCallback(PreparedQueryResult res
// prevent character rename to invalid name
if (!normalizePlayerName(factionChangeInfo->Name))
{
- SendCharFactionChange(CHAR_NAME_NO_NAME, factionChangeInfo);
+ SendCharFactionChange(CHAR_NAME_NO_NAME, factionChangeInfo.get());
return;
}
ResponseCodes res = ObjectMgr::CheckPlayerName(factionChangeInfo->Name, GetSessionDbcLocale(), true);
if (res != CHAR_NAME_SUCCESS)
{
- SendCharFactionChange(res, factionChangeInfo);
+ SendCharFactionChange(res, factionChangeInfo.get());
return;
}
// check name limitations
if (!HasPermission(rbac::RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_RESERVEDNAME) && sObjectMgr->IsReservedName(factionChangeInfo->Name))
{
- SendCharFactionChange(CHAR_NAME_RESERVED, factionChangeInfo);
+ SendCharFactionChange(CHAR_NAME_RESERVED, factionChangeInfo.get());
return;
}
@@ -1948,14 +1901,14 @@ void WorldSession::HandleCharRaceOrFactionChangeCallback(PreparedQueryResult res
{
if (newGuid != factionChangeInfo->Guid)
{
- SendCharFactionChange(CHAR_CREATE_NAME_IN_USE, factionChangeInfo);
+ SendCharFactionChange(CHAR_CREATE_NAME_IN_USE, factionChangeInfo.get());
return;
}
}
if (sArenaTeamMgr->GetArenaTeamByCaptain(factionChangeInfo->Guid))
{
- SendCharFactionChange(CHAR_CREATE_CHARACTER_ARENA_LEADER, factionChangeInfo);
+ SendCharFactionChange(CHAR_CREATE_CHARACTER_ARENA_LEADER, factionChangeInfo.get());
return;
}
@@ -2306,7 +2259,7 @@ void WorldSession::HandleCharRaceOrFactionChangeCallback(PreparedQueryResult res
if (tokens.size() != ktcount)
{
- SendCharFactionChange(CHAR_CREATE_ERROR, factionChangeInfo);
+ SendCharFactionChange(CHAR_CREATE_ERROR, factionChangeInfo.get());
return;
}
@@ -2370,7 +2323,7 @@ void WorldSession::HandleCharRaceOrFactionChangeCallback(PreparedQueryResult res
TC_LOG_DEBUG("entities.player", "%s (IP: %s) changed race from %u to %u", GetPlayerInfo().c_str(), GetRemoteAddress().c_str(), oldRace, factionChangeInfo->RaceID);
- SendCharFactionChange(RESPONSE_SUCCESS, factionChangeInfo);
+ SendCharFactionChange(RESPONSE_SUCCESS, factionChangeInfo.get());
}
void WorldSession::HandleRandomizeCharNameOpcode(WorldPackets::Character::GenerateRandomCharacterName& packet)
@@ -2427,176 +2380,123 @@ void WorldSession::HandleOpeningCinematic(WorldPackets::Misc::OpeningCinematic&
void WorldSession::HandleGetUndeleteCooldownStatus(WorldPackets::Character::GetUndeleteCharacterCooldownStatus& /*getCooldown*/)
{
- /// empty result to force wait
- PreparedQueryResultPromise result;
- result.set_value(PreparedQueryResult(nullptr));
- _undeleteCooldownStatusCallback.SetFutureResult(result.get_future());
+ PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_LAST_CHAR_UNDELETE);
+ stmt->setUInt32(0, GetBattlenetAccountId());
+
+ _queryProcessor.AddQuery(LoginDatabase.AsyncQuery(stmt).WithPreparedCallback(std::bind(&WorldSession::HandleUndeleteCooldownStatusCallback, this, std::placeholders::_1)));
}
void WorldSession::HandleUndeleteCooldownStatusCallback(PreparedQueryResult result)
{
- switch (_undeleteCooldownStatusCallback.GetStage())
+ uint32 cooldown = 0;
+ uint32 maxCooldown = sWorld->getIntConfig(CONFIG_FEATURE_SYSTEM_CHARACTER_UNDELETE_COOLDOWN);
+ if (result)
{
- case 0:
- {
- PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_LAST_CHAR_UNDELETE);
- stmt->setUInt32(0, GetBattlenetAccountId());
-
- _undeleteCooldownStatusCallback.FreeResult();
- _undeleteCooldownStatusCallback.SetFutureResult(LoginDatabase.AsyncQuery(stmt));
- _undeleteCooldownStatusCallback.NextStage();
- break;
- }
- case 1:
- {
- uint32 cooldown = 0;
- uint32 maxCooldown = sWorld->getIntConfig(CONFIG_FEATURE_SYSTEM_CHARACTER_UNDELETE_COOLDOWN);
- if (result)
- {
- uint32 lastUndelete = result->Fetch()[0].GetUInt32();
- uint32 now = uint32(time(nullptr));
- if (lastUndelete + maxCooldown > now)
- cooldown = std::max<uint32>(0, lastUndelete + maxCooldown - now);
- }
-
- SendUndeleteCooldownStatusResponse(cooldown, maxCooldown);
- _undeleteCooldownStatusCallback.Reset();
- break;
- }
+ uint32 lastUndelete = result->Fetch()[0].GetUInt32();
+ uint32 now = uint32(time(nullptr));
+ if (lastUndelete + maxCooldown > now)
+ cooldown = std::max<uint32>(0, lastUndelete + maxCooldown - now);
}
+ SendUndeleteCooldownStatusResponse(cooldown, maxCooldown);
}
-void WorldSession::HandleCharUndeleteOpcode(WorldPackets::Character::UndeleteCharacter& undeleteInfo)
+void WorldSession::HandleCharUndeleteOpcode(WorldPackets::Character::UndeleteCharacter& undeleteCharacter)
{
if (!sWorld->getBoolConfig(CONFIG_FEATURE_SYSTEM_CHARACTER_UNDELETE_ENABLED))
{
- SendUndeleteCharacterResponse(CHARACTER_UNDELETE_RESULT_ERROR_DISABLED, undeleteInfo.UndeleteInfo.get());
+ SendUndeleteCharacterResponse(CHARACTER_UNDELETE_RESULT_ERROR_DISABLED, undeleteCharacter.UndeleteInfo.get());
return;
}
PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_LAST_CHAR_UNDELETE);
stmt->setUInt32(0, GetBattlenetAccountId());
- _charUndeleteCallback.SetParam(undeleteInfo.UndeleteInfo);
- _charUndeleteCallback.SetFutureResult(LoginDatabase.AsyncQuery(stmt));
- _charUndeleteCallback.NextStage();
-}
-
-void WorldSession::HandleCharUndeleteCallback(PreparedQueryResult result, WorldPackets::Character::CharacterUndeleteInfo* undeleteInfo)
-{
- /** This is a series of callbacks executed consecutively as a result from the database becomes available.
- * This is much more efficient than synchronous requests on packet handler.
- * It also prevents data synchronisation errors.
- */
-
- ASSERT(_charUndeleteCallback.GetParam().get() == undeleteInfo);
-
- switch (_charUndeleteCallback.GetStage())
+ std::shared_ptr<WorldPackets::Character::CharacterUndeleteInfo> undeleteInfo = undeleteCharacter.UndeleteInfo;
+ _queryProcessor.AddQuery(LoginDatabase.AsyncQuery(stmt)
+ .WithChainingPreparedCallback([this, undeleteInfo](QueryCallback& queryCallback, PreparedQueryResult result)
{
- case 1:
- {
- if (result)
- {
- uint32 lastUndelete = result->Fetch()[0].GetUInt32();
- uint32 maxCooldown = sWorld->getIntConfig(CONFIG_FEATURE_SYSTEM_CHARACTER_UNDELETE_COOLDOWN);
- if (lastUndelete && (lastUndelete + maxCooldown > time(nullptr)))
- {
- SendUndeleteCharacterResponse(CHARACTER_UNDELETE_RESULT_ERROR_COOLDOWN, undeleteInfo);
- _charUndeleteCallback.Reset();
- return;
- }
- }
-
- PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_DEL_INFO_BY_GUID);
- stmt->setUInt64(0, undeleteInfo->CharacterGuid.GetCounter());
-
- _charUndeleteCallback.FreeResult();
- _charUndeleteCallback.SetFutureResult(CharacterDatabase.AsyncQuery(stmt));
- _charUndeleteCallback.NextStage();
- break;
- }
- case 2:
+ if (result)
{
- if (!result)
+ uint32 lastUndelete = result->Fetch()[0].GetUInt32();
+ uint32 maxCooldown = sWorld->getIntConfig(CONFIG_FEATURE_SYSTEM_CHARACTER_UNDELETE_COOLDOWN);
+ if (lastUndelete && (lastUndelete + maxCooldown > time(nullptr)))
{
- SendUndeleteCharacterResponse(CHARACTER_UNDELETE_RESULT_ERROR_CHAR_CREATE, undeleteInfo);
- _charUndeleteCallback.Reset();
+ SendUndeleteCharacterResponse(CHARACTER_UNDELETE_RESULT_ERROR_COOLDOWN, undeleteInfo.get());
return;
}
+ }
- Field* fields = result->Fetch();
- undeleteInfo->Name = fields[1].GetString();
- uint32 account = fields[2].GetUInt32();
-
- if (account != GetAccountId())
- {
- SendUndeleteCharacterResponse(CHARACTER_UNDELETE_RESULT_ERROR_UNKNOWN, undeleteInfo);
- _charUndeleteCallback.Reset();
- return;
- }
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_DEL_INFO_BY_GUID);
+ stmt->setUInt64(0, undeleteInfo->CharacterGuid.GetCounter());
+ queryCallback.SetNextQuery(CharacterDatabase.AsyncQuery(stmt));
+ })
+ .WithChainingPreparedCallback([this, undeleteInfo](QueryCallback& queryCallback, PreparedQueryResult result)
+ {
+ if (!result)
+ {
+ SendUndeleteCharacterResponse(CHARACTER_UNDELETE_RESULT_ERROR_CHAR_CREATE, undeleteInfo.get());
+ return;
+ }
- PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHECK_NAME);
- stmt->setString(0, undeleteInfo->Name);
+ Field* fields = result->Fetch();
+ undeleteInfo->Name = fields[1].GetString();
+ uint32 account = fields[2].GetUInt32();
- _charUndeleteCallback.FreeResult();
- _charUndeleteCallback.SetFutureResult(CharacterDatabase.AsyncQuery(stmt));
- _charUndeleteCallback.NextStage();
- break;
- }
- case 3:
+ if (account != GetAccountId())
{
- if (result)
- {
- SendUndeleteCharacterResponse(CHARACTER_UNDELETE_RESULT_ERROR_NAME_TAKEN_BY_THIS_ACCOUNT, undeleteInfo);
- _charUndeleteCallback.Reset();
- return;
- }
+ SendUndeleteCharacterResponse(CHARACTER_UNDELETE_RESULT_ERROR_UNKNOWN, undeleteInfo.get());
+ return;
+ }
- /// @todo: add more safety checks
- /// * max char count per account
- /// * max heroic char count
- /// * team violation
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHECK_NAME);
+ stmt->setString(0, undeleteInfo->Name);
+ queryCallback.SetNextQuery(CharacterDatabase.AsyncQuery(stmt));
+ })
+ .WithChainingPreparedCallback([this, undeleteInfo](QueryCallback& queryCallback, PreparedQueryResult result)
+ {
+ if (result)
+ {
+ SendUndeleteCharacterResponse(CHARACTER_UNDELETE_RESULT_ERROR_NAME_TAKEN_BY_THIS_ACCOUNT, undeleteInfo.get());
+ return;
+ }
- PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_SUM_CHARS);
- stmt->setUInt32(0, GetAccountId());
+ /// @todo: add more safety checks
+ /// * max char count per account
+ /// * max heroic char count
+ /// * team violation
- _charUndeleteCallback.FreeResult();
- _charUndeleteCallback.SetFutureResult(CharacterDatabase.AsyncQuery(stmt));
- _charUndeleteCallback.NextStage();
- break;
- }
- case 4:
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_SUM_CHARS);
+ stmt->setUInt32(0, GetAccountId());
+ queryCallback.SetNextQuery(CharacterDatabase.AsyncQuery(stmt));
+ })
+ .WithPreparedCallback([this, undeleteInfo](PreparedQueryResult result)
+ {
+ if (result)
{
- if (result)
- {
- Field* fields = result->Fetch();
+ Field* fields = result->Fetch();
- if (fields[0].GetUInt64() >= sWorld->getIntConfig(CONFIG_CHARACTERS_PER_REALM)) // SQL's COUNT() returns uint64 but it will always be less than uint8.Max
- {
- SendUndeleteCharacterResponse(CHARACTER_UNDELETE_RESULT_ERROR_CHAR_CREATE, undeleteInfo);
- _charUndeleteCallback.Reset();
- return;
- }
+ if (fields[0].GetUInt64() >= sWorld->getIntConfig(CONFIG_CHARACTERS_PER_REALM)) // SQL's COUNT() returns uint64 but it will always be less than uint8.Max
+ {
+ SendUndeleteCharacterResponse(CHARACTER_UNDELETE_RESULT_ERROR_CHAR_CREATE, undeleteInfo.get());
+ return;
}
+ }
- PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_RESTORE_DELETE_INFO);
- stmt->setString(0, undeleteInfo->Name);
- stmt->setUInt32(1, GetAccountId());
- stmt->setUInt64(2, undeleteInfo->CharacterGuid.GetCounter());
- CharacterDatabase.Execute(stmt);
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_RESTORE_DELETE_INFO);
+ stmt->setString(0, undeleteInfo->Name);
+ stmt->setUInt32(1, GetAccountId());
+ stmt->setUInt64(2, undeleteInfo->CharacterGuid.GetCounter());
+ CharacterDatabase.Execute(stmt);
- stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_LAST_CHAR_UNDELETE);
- stmt->setUInt32(0, GetBattlenetAccountId());
- LoginDatabase.Execute(stmt);
+ stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_LAST_CHAR_UNDELETE);
+ stmt->setUInt32(0, GetBattlenetAccountId());
+ LoginDatabase.Execute(stmt);
- sWorld->UpdateCharacterInfoDeleted(undeleteInfo->CharacterGuid, false, &undeleteInfo->Name);
+ sWorld->UpdateCharacterInfoDeleted(undeleteInfo->CharacterGuid, false, &undeleteInfo->Name);
- SendUndeleteCharacterResponse(CHARACTER_UNDELETE_RESULT_OK, undeleteInfo);
- _charUndeleteCallback.Reset();
- break;
- }
- }
+ SendUndeleteCharacterResponse(CHARACTER_UNDELETE_RESULT_OK, undeleteInfo.get());
+ }));
}
void WorldSession::SendCharCreate(ResponseCodes result)
diff --git a/src/server/game/Handlers/NPCHandler.cpp b/src/server/game/Handlers/NPCHandler.cpp
index 0283bb826f2..69e31d9f59f 100644
--- a/src/server/game/Handlers/NPCHandler.cpp
+++ b/src/server/game/Handlers/NPCHandler.cpp
@@ -19,6 +19,7 @@
#include "Common.h"
#include "Language.h"
#include "DatabaseEnv.h"
+#include "QueryCallback.h"
#include "WorldPacket.h"
#include "WorldSession.h"
#include "Opcodes.h"
@@ -485,11 +486,10 @@ void WorldSession::SendStablePet(ObjectGuid guid)
stmt->setUInt8(1, PET_SAVE_FIRST_STABLE_SLOT);
stmt->setUInt8(2, PET_SAVE_LAST_STABLE_SLOT);
- _sendStabledPetCallback.SetParam(guid);
- _sendStabledPetCallback.SetFutureResult(CharacterDatabase.AsyncQuery(stmt));
+ _queryProcessor.AddQuery(CharacterDatabase.AsyncQuery(stmt).WithPreparedCallback(std::bind(&WorldSession::SendStablePetCallback, this, guid, std::placeholders::_1)));
}
-void WorldSession::SendStablePetCallback(PreparedQueryResult result, ObjectGuid guid)
+void WorldSession::SendStablePetCallback(ObjectGuid guid, PreparedQueryResult result)
{
if (!GetPlayer())
return;
@@ -585,7 +585,7 @@ void WorldSession::HandleStablePet(WorldPacket& recvData)
stmt->setUInt8(1, PET_SAVE_FIRST_STABLE_SLOT);
stmt->setUInt8(2, PET_SAVE_LAST_STABLE_SLOT);
- _stablePetCallback = CharacterDatabase.AsyncQuery(stmt);
+ _queryProcessor.AddQuery(CharacterDatabase.AsyncQuery(stmt).WithPreparedCallback(std::bind(&WorldSession::HandleStablePetCallback, this, std::placeholders::_1)));
}
void WorldSession::HandleStablePetCallback(PreparedQueryResult result)
@@ -645,11 +645,10 @@ void WorldSession::HandleUnstablePet(WorldPacket& recvData)
stmt->setUInt8(2, PET_SAVE_FIRST_STABLE_SLOT);
stmt->setUInt8(3, PET_SAVE_LAST_STABLE_SLOT);
- _unstablePetCallback.SetParam(petnumber);
- _unstablePetCallback.SetFutureResult(CharacterDatabase.AsyncQuery(stmt));
+ _queryProcessor.AddQuery(CharacterDatabase.AsyncQuery(stmt).WithPreparedCallback(std::bind(&WorldSession::HandleUnstablePetCallback, this, petnumber, std::placeholders::_1)));
}
-void WorldSession::HandleUnstablePetCallback(PreparedQueryResult result, uint32 petId)
+void WorldSession::HandleUnstablePetCallback(uint32 petId, PreparedQueryResult result)
{
if (!GetPlayer())
return;
@@ -770,11 +769,10 @@ void WorldSession::HandleStableSwapPet(WorldPacket& recvData)
stmt->setUInt64(0, _player->GetGUID().GetCounter());
stmt->setUInt32(1, petId);
- _stableSwapCallback.SetParam(petId);
- _stableSwapCallback.SetFutureResult(CharacterDatabase.AsyncQuery(stmt));
+ _queryProcessor.AddQuery(CharacterDatabase.AsyncQuery(stmt).WithPreparedCallback(std::bind(&WorldSession::HandleStableSwapPetCallback, this, petId, std::placeholders::_1)));
}
-void WorldSession::HandleStableSwapPetCallback(PreparedQueryResult result, uint32 petId)
+void WorldSession::HandleStableSwapPetCallback(uint32 petId, PreparedQueryResult result)
{
if (!GetPlayer())
return;
diff --git a/src/server/game/Handlers/SocialHandler.cpp b/src/server/game/Handlers/SocialHandler.cpp
index 0c87093bb90..3989e76e56a 100644
--- a/src/server/game/Handlers/SocialHandler.cpp
+++ b/src/server/game/Handlers/SocialHandler.cpp
@@ -18,6 +18,7 @@
#include "WorldSession.h"
#include "Player.h"
+#include "QueryCallback.h"
#include "SocialMgr.h"
#include "SocialPackets.h"
#include "ObjectMgr.h"
@@ -39,11 +40,11 @@ void WorldSession::HandleAddFriendOpcode(WorldPackets::Social::AddFriend& packet
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_GUID_RACE_ACC_BY_NAME);
stmt->setString(0, packet.Name);
- _addFriendCallback.SetParam(std::move(packet.Notes));
- _addFriendCallback.SetFutureResult(CharacterDatabase.AsyncQuery(stmt));
+ _queryProcessor.AddQuery(CharacterDatabase.AsyncQuery(stmt)
+ .WithPreparedCallback(std::bind(&WorldSession::HandleAddFriendOpcodeCallBack, this, std::move(packet.Notes), std::placeholders::_1)));
}
-void WorldSession::HandleAddFriendOpcodeCallBack(PreparedQueryResult result, std::string const& friendNote)
+void WorldSession::HandleAddFriendOpcodeCallBack(std::string const& friendNote, PreparedQueryResult result)
{
if (!GetPlayer())
return;
@@ -110,7 +111,7 @@ void WorldSession::HandleAddIgnoreOpcode(WorldPackets::Social::AddIgnore& packet
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_GUID_BY_NAME);
stmt->setString(0, packet.Name);
- _addIgnoreCallback = CharacterDatabase.AsyncQuery(stmt);
+ _queryProcessor.AddQuery(CharacterDatabase.AsyncQuery(stmt).WithPreparedCallback(std::bind(&WorldSession::HandleAddIgnoreOpcodeCallBack, this, std::placeholders::_1)));
}
void WorldSession::HandleAddIgnoreOpcodeCallBack(PreparedQueryResult result)
diff --git a/src/server/game/Server/WorldSession.cpp b/src/server/game/Server/WorldSession.cpp
index 070f75f3392..c9daf2a274f 100644
--- a/src/server/game/Server/WorldSession.cpp
+++ b/src/server/game/Server/WorldSession.cpp
@@ -24,6 +24,7 @@
#include "Config.h"
#include "Common.h"
#include "DatabaseEnv.h"
+#include "QueryCallback.h"
#include "AccountMgr.h"
#include "Log.h"
#include "Opcodes.h"
@@ -151,8 +152,6 @@ WorldSession::WorldSession(uint32 id, std::string&& name, uint32 battlenetAccoun
m_Socket[CONNECTION_TYPE_REALM] = sock;
_instanceConnectKey.Raw = UI64LIT(0);
-
- InitializeQueryCallbackParameters();
}
/// WorldSession destructor
@@ -863,135 +862,17 @@ void WorldSession::SetPlayer(Player* player)
m_GUIDLow = _player->GetGUID().GetCounter();
}
-void WorldSession::InitializeQueryCallbackParameters()
-{
- // Callback parameters that have pointers in them should be properly
- // initialized to nullptr here.
-}
-
void WorldSession::ProcessQueryCallbacks()
{
- PreparedQueryResult result;
+ _queryProcessor.ProcessReadyQueries();
if (_realmAccountLoginCallback.valid() && _realmAccountLoginCallback.wait_for(std::chrono::seconds(0)) == std::future_status::ready &&
_accountLoginCallback.valid() && _accountLoginCallback.wait_for(std::chrono::seconds(0)) == std::future_status::ready)
InitializeSessionCallback(_realmAccountLoginCallback.get(), _accountLoginCallback.get());
- //! HandleCharEnumOpcode and HandleCharUndeleteEnumOpcode
- if (_charEnumCallback.IsReady())
- {
- _charEnumCallback.GetResult(result);
-
- if (_charEnumCallback.GetParam())
- HandleCharUndeleteEnum(result);
- else
- HandleCharEnum(result);
-
- _charEnumCallback.FreeResult();
- }
-
- //! HandleCharCreateOpcode
- if (_charCreateCallback.IsReady())
- {
- _charCreateCallback.GetResult(result);
- HandleCharCreateCallback(result, _charCreateCallback.GetParam().get());
- }
-
- //! HandleCharCustomizeOpcode
- if (_charCustomizeCallback.IsReady())
- {
- _charCustomizeCallback.GetResult(result);
- HandleCharCustomizeCallback(result, _charCustomizeCallback.GetParam().get());
- _charCustomizeCallback.Reset();
- }
-
- //! HandleCharRaceOrFactionChangeOpcode
- if (_charFactionChangeCallback.IsReady())
- {
- _charFactionChangeCallback.GetResult(result);
- HandleCharRaceOrFactionChangeCallback(result, _charFactionChangeCallback.GetParam().get());
- _charFactionChangeCallback.Reset();
- }
-
//! HandlePlayerLoginOpcode
if (_charLoginCallback.valid() && _charLoginCallback.wait_for(std::chrono::seconds(0)) == std::future_status::ready)
- {
- SQLQueryHolder* param = _charLoginCallback.get();
- HandlePlayerLogin((LoginQueryHolder*)param);
- }
-
- //! HandleAddFriendOpcode
- if (_addFriendCallback.IsReady())
- {
- std::string param = _addFriendCallback.GetParam();
- _addFriendCallback.GetResult(result);
- HandleAddFriendOpcodeCallBack(result, param);
- _addFriendCallback.FreeResult();
- }
-
- //- HandleCharRenameOpcode
- if (_charRenameCallback.IsReady())
- {
- _charRenameCallback.GetResult(result);
- HandleCharRenameCallBack(result, _charRenameCallback.GetParam().get());
- _charRenameCallback.Reset();
- }
-
- /// HandleUndeleteCooldownStatusOpcode
- /// wait until no char undelete is in progress
- if (!_charUndeleteCallback.GetStage() && _undeleteCooldownStatusCallback.IsReady())
- {
- _undeleteCooldownStatusCallback.GetResult(result);
- HandleUndeleteCooldownStatusCallback(result);
- }
-
- /// HandleCharUndeleteOpcode
- if (_charUndeleteCallback.IsReady())
- {
- _charUndeleteCallback.GetResult(result);
- HandleCharUndeleteCallback(result, _charUndeleteCallback.GetParam().get());
- }
-
- //- HandleCharAddIgnoreOpcode
- if (_addIgnoreCallback.valid() && _addIgnoreCallback.wait_for(std::chrono::seconds(0)) == std::future_status::ready)
- {
- result = _addIgnoreCallback.get();
- HandleAddIgnoreOpcodeCallBack(result);
- }
-
- //- SendStabledPet
- if (_sendStabledPetCallback.IsReady())
- {
- ObjectGuid param = _sendStabledPetCallback.GetParam();
- _sendStabledPetCallback.GetResult(result);
- SendStablePetCallback(result, param);
- _sendStabledPetCallback.FreeResult();
- }
-
- //- HandleStablePet
- if (_stablePetCallback.valid() && _stablePetCallback.wait_for(std::chrono::seconds(0)) == std::future_status::ready)
- {
- result = _stablePetCallback.get();
- HandleStablePetCallback(result);
- }
-
- //- HandleUnstablePet
- if (_unstablePetCallback.IsReady())
- {
- uint32 param = _unstablePetCallback.GetParam();
- _unstablePetCallback.GetResult(result);
- HandleUnstablePetCallback(result, param);
- _unstablePetCallback.FreeResult();
- }
-
- //- HandleStableSwapPet
- if (_stableSwapCallback.IsReady())
- {
- uint32 param = _stableSwapCallback.GetParam();
- _stableSwapCallback.GetResult(result);
- HandleStableSwapPetCallback(result, param);
- _stableSwapCallback.FreeResult();
- }
+ HandlePlayerLogin(reinterpret_cast<LoginQueryHolder*>(_charLoginCallback.get()));
}
void WorldSession::InitWarden(BigNumber* k)
@@ -1023,7 +904,7 @@ void WorldSession::LoadPermissions()
_RBACData->LoadFromDB();
}
-PreparedQueryResultFuture WorldSession::LoadPermissionsAsync()
+QueryCallback WorldSession::LoadPermissionsAsync()
{
uint32 id = GetAccountId();
uint8 secLevel = GetSecurity();
diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h
index bdd0e44bcf7..dd5c32133c3 100644
--- a/src/server/game/Server/WorldSession.h
+++ b/src/server/game/Server/WorldSession.h
@@ -938,7 +938,7 @@ class TC_GAME_API WorldSession
rbac::RBACData* GetRBACData();
bool HasPermission(uint32 permissionId);
void LoadPermissions();
- PreparedQueryResultFuture LoadPermissionsAsync();
+ QueryCallback LoadPermissionsAsync();
void InvalidateRBACData(); // Used to force LoadPermissions at next HasPermission check
AccountTypes GetSecurity() const { return _security; }
@@ -1013,7 +1013,7 @@ class TC_GAME_API WorldSession
// Pet
void SendQueryPetNameResponse(ObjectGuid guid);
void SendStablePet(ObjectGuid guid);
- void SendStablePetCallback(PreparedQueryResult result, ObjectGuid guid);
+ void SendStablePetCallback(ObjectGuid guid, PreparedQueryResult result);
void SendPetStableResult(uint8 guid);
bool CheckStableMaster(ObjectGuid guid);
@@ -1129,29 +1129,27 @@ class TC_GAME_API WorldSession
void HandleCharUndeleteEnumOpcode(WorldPackets::Character::EnumCharacters& /*enumCharacters*/);
void HandleCharDeleteOpcode(WorldPackets::Character::CharDelete& charDelete);
void HandleCharCreateOpcode(WorldPackets::Character::CreateCharacter& charCreate);
- void HandleCharCreateCallback(PreparedQueryResult result, WorldPackets::Character::CharacterCreateInfo* createInfo);
void HandlePlayerLoginOpcode(WorldPackets::Character::PlayerLogin& playerLogin);
void SendConnectToInstance(WorldPackets::Auth::ConnectToSerial serial);
void HandleContinuePlayerLogin();
void AbortLogin(WorldPackets::Character::LoginFailureReason reason);
void HandleLoadScreenOpcode(WorldPackets::Character::LoadingScreenNotify& loadingScreenNotify);
- void HandlePlayerLogin(LoginQueryHolder * holder);
+ void HandlePlayerLogin(LoginQueryHolder* holder);
void HandleCharRenameOpcode(WorldPackets::Character::CharacterRenameRequest& request);
- void HandleCharRenameCallBack(PreparedQueryResult result, WorldPackets::Character::CharacterRenameInfo* renameInfo);
+ void HandleCharRenameCallBack(std::shared_ptr<WorldPackets::Character::CharacterRenameInfo> renameInfo, PreparedQueryResult result);
void HandleSetPlayerDeclinedNames(WorldPackets::Character::SetPlayerDeclinedNames& packet);
void HandleAlterAppearance(WorldPackets::Character::AlterApperance& packet);
void HandleCharCustomizeOpcode(WorldPackets::Character::CharCustomize& packet);
- void HandleCharCustomizeCallback(PreparedQueryResult result, WorldPackets::Character::CharCustomizeInfo* customizeInfo);
+ void HandleCharCustomizeCallback(std::shared_ptr<WorldPackets::Character::CharCustomizeInfo> customizeInfo, PreparedQueryResult result);
void HandleCharRaceOrFactionChangeOpcode(WorldPackets::Character::CharRaceOrFactionChange& packet);
- void HandleCharRaceOrFactionChangeCallback(PreparedQueryResult result, WorldPackets::Character::CharRaceOrFactionChangeInfo* factionChangeInfo);
+ void HandleCharRaceOrFactionChangeCallback(std::shared_ptr<WorldPackets::Character::CharRaceOrFactionChangeInfo> factionChangeInfo, PreparedQueryResult result);
void HandleRandomizeCharNameOpcode(WorldPackets::Character::GenerateRandomCharacterName& packet);
void HandleReorderCharacters(WorldPackets::Character::ReorderCharacters& reorderChars);
void HandleOpeningCinematic(WorldPackets::Misc::OpeningCinematic& packet);
void HandleGetUndeleteCooldownStatus(WorldPackets::Character::GetUndeleteCharacterCooldownStatus& /*getCooldown*/);
void HandleUndeleteCooldownStatusCallback(PreparedQueryResult result);
void HandleCharUndeleteOpcode(WorldPackets::Character::UndeleteCharacter& undeleteInfo);
- void HandleCharUndeleteCallback(PreparedQueryResult result, WorldPackets::Character::CharacterUndeleteInfo* undeleteInfo);
void SendCharCreate(ResponseCodes result);
void SendCharDelete(ResponseCodes result);
@@ -1223,7 +1221,7 @@ class TC_GAME_API WorldSession
// Social
void HandleContactListOpcode(WorldPackets::Social::SendContactList& packet);
void HandleAddFriendOpcode(WorldPackets::Social::AddFriend& packet);
- void HandleAddFriendOpcodeCallBack(PreparedQueryResult result, std::string const& friendNote);
+ void HandleAddFriendOpcodeCallBack(std::string const& friendNote, PreparedQueryResult result);
void HandleDelFriendOpcode(WorldPackets::Social::DelFriend& packet);
void HandleAddIgnoreOpcode(WorldPackets::Social::AddIgnore& packet);
void HandleAddIgnoreOpcodeCallBack(PreparedQueryResult result);
@@ -1369,11 +1367,11 @@ class TC_GAME_API WorldSession
void HandleStablePet(WorldPacket& recvPacket);
void HandleStablePetCallback(PreparedQueryResult result);
void HandleUnstablePet(WorldPacket& recvPacket);
- void HandleUnstablePetCallback(PreparedQueryResult result, uint32 petId);
+ void HandleUnstablePetCallback(uint32 petId, PreparedQueryResult result);
void HandleBuyStableSlot(WorldPacket& recvPacket);
void HandleStableRevivePet(WorldPacket& recvPacket);
void HandleStableSwapPet(WorldPacket& recvPacket);
- void HandleStableSwapPetCallback(PreparedQueryResult result, uint32 petId);
+ void HandleStableSwapPetCallback(uint32 petId, PreparedQueryResult result);
void SendTrainerBuyFailed(ObjectGuid trainerGUID, uint32 spellID, int32 trainerFailedReason);
void HandleCanDuel(WorldPackets::Duel::CanDuel& packet);
@@ -1763,26 +1761,14 @@ class TC_GAME_API WorldSession
uint64 GetConnectToInstanceKey() const { return _instanceConnectKey.Raw; }
private:
- void InitializeQueryCallbackParameters();
void ProcessQueryCallbacks();
QueryResultHolderFuture _realmAccountLoginCallback;
QueryResultHolderFuture _accountLoginCallback;
- PreparedQueryResultFuture _addIgnoreCallback;
- PreparedQueryResultFuture _stablePetCallback;
- QueryCallback<PreparedQueryResult, bool> _charEnumCallback;
- QueryCallback<PreparedQueryResult, std::string> _addFriendCallback;
- QueryCallback<PreparedQueryResult, uint32> _unstablePetCallback;
- QueryCallback<PreparedQueryResult, uint32> _stableSwapCallback;
- QueryCallback<PreparedQueryResult, ObjectGuid> _sendStabledPetCallback;
- QueryCallback<PreparedQueryResult, std::shared_ptr<WorldPackets::Character::CharacterCreateInfo>, true> _charCreateCallback;
- QueryCallback<PreparedQueryResult, std::shared_ptr<WorldPackets::Character::CharacterRenameInfo>> _charRenameCallback;
- QueryCallback<PreparedQueryResult, std::shared_ptr<WorldPackets::Character::CharCustomizeInfo>> _charCustomizeCallback;
- QueryCallback<PreparedQueryResult, std::shared_ptr<WorldPackets::Character::CharRaceOrFactionChangeInfo>> _charFactionChangeCallback;
- QueryCallback<PreparedQueryResult, bool, true> _undeleteCooldownStatusCallback;
- QueryCallback<PreparedQueryResult, std::shared_ptr<WorldPackets::Character::CharacterUndeleteInfo>, true> _charUndeleteCallback;
QueryResultHolderFuture _charLoginCallback;
+ QueryCallbackProcessor _queryProcessor;
+
friend class World;
protected:
class DosProtection
diff --git a/src/server/game/Server/WorldSocket.cpp b/src/server/game/Server/WorldSocket.cpp
index 0230ab6d59b..bd5b84f24e3 100644
--- a/src/server/game/Server/WorldSocket.cpp
+++ b/src/server/game/Server/WorldSocket.cpp
@@ -24,6 +24,7 @@
#include "HmacHash.h"
#include "Opcodes.h"
#include "PacketLog.h"
+#include "QueryCallback.h"
#include "ScriptMgr.h"
#include "SessionKeyGeneration.h"
#include "SHA256.h"
@@ -91,8 +92,7 @@ void WorldSocket::Start()
stmt->setString(0, ip_address);
stmt->setUInt32(1, inet_addr(ip_address.c_str()));
- _queryCallback = std::bind(&WorldSocket::CheckIpCallback, this, std::placeholders::_1);
- _queryFuture = LoginDatabase.AsyncQuery(stmt);
+ _queryProcessor.AddQuery(LoginDatabase.AsyncQuery(stmt).WithPreparedCallback(std::bind(&WorldSocket::CheckIpCallback, this, std::placeholders::_1)));
}
void WorldSocket::CheckIpCallback(PreparedQueryResult result)
@@ -233,12 +233,7 @@ bool WorldSocket::Update()
if (!BaseSocket::Update())
return false;
- if (_queryFuture.valid() && _queryFuture.wait_for(std::chrono::seconds(0)) == std::future_status::ready)
- {
- auto callback = _queryCallback;
- _queryCallback = nullptr;
- callback(_queryFuture.get());
- }
+ _queryProcessor.ProcessReadyQueries();
return true;
}
@@ -652,8 +647,7 @@ void WorldSocket::HandleAuthSession(std::shared_ptr<WorldPackets::Auth::AuthSess
stmt->setInt32(0, int32(realm.Id.Realm));
stmt->setString(1, authSession->RealmJoinTicket);
- _queryCallback = std::bind(&WorldSocket::HandleAuthSessionCallback, this, authSession, std::placeholders::_1);
- _queryFuture = LoginDatabase.AsyncQuery(stmt);
+ _queryProcessor.AddQuery(LoginDatabase.AsyncQuery(stmt).WithPreparedCallback(std::bind(&WorldSocket::HandleAuthSessionCallback, this, authSession, std::placeholders::_1)));
}
void WorldSocket::HandleAuthSessionCallback(std::shared_ptr<WorldPackets::Auth::AuthSession> authSession, PreparedQueryResult result)
@@ -818,8 +812,7 @@ void WorldSocket::HandleAuthSessionCallback(std::shared_ptr<WorldPackets::Auth::
if (wardenActive)
_worldSession->InitWarden(&_sessionKey);
- _queryCallback = std::bind(&WorldSocket::LoadSessionPermissionsCallback, this, std::placeholders::_1);
- _queryFuture = _worldSession->LoadPermissionsAsync();
+ _queryProcessor.AddQuery(_worldSession->LoadPermissionsAsync().WithPreparedCallback(std::bind(&WorldSocket::LoadSessionPermissionsCallback, this, std::placeholders::_1)));
AsyncRead();
}
@@ -848,8 +841,7 @@ void WorldSocket::HandleAuthContinuedSession(std::shared_ptr<WorldPackets::Auth:
PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_ACCOUNT_INFO_CONTINUED_SESSION);
stmt->setUInt32(0, accountId);
- _queryCallback = std::bind(&WorldSocket::HandleAuthContinuedSessionCallback, this, authSession, std::placeholders::_1);
- _queryFuture = LoginDatabase.AsyncQuery(stmt);
+ _queryProcessor.AddQuery(LoginDatabase.AsyncQuery(stmt).WithPreparedCallback(std::bind(&WorldSocket::HandleAuthContinuedSessionCallback, this, authSession, std::placeholders::_1)));
}
void WorldSocket::HandleAuthContinuedSessionCallback(std::shared_ptr<WorldPackets::Auth::AuthContinuedSession> authSession, PreparedQueryResult result)
diff --git a/src/server/game/Server/WorldSocket.h b/src/server/game/Server/WorldSocket.h
index f257848fac1..1a3e4e71b25 100644
--- a/src/server/game/Server/WorldSocket.h
+++ b/src/server/game/Server/WorldSocket.h
@@ -20,6 +20,7 @@
#define __WORLDSOCKET_H__
#include "Common.h"
+#include "QueryCallbackProcessor.h"
#include "WorldPacketCrypt.h"
#include "Socket.h"
#include "Util.h"
@@ -144,8 +145,7 @@ private:
z_stream_s* _compressionStream;
- PreparedQueryResultFuture _queryFuture;
- std::function<void(PreparedQueryResult&&)> _queryCallback;
+ QueryCallbackProcessor _queryProcessor;
std::string _ipCountry;
};
diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp
index 85fb1db40ac..c2da938cfa8 100644
--- a/src/server/game/World/World.cpp
+++ b/src/server/game/World/World.cpp
@@ -43,6 +43,7 @@
#include "GameEventMgr.h"
#include "GameTables.h"
#include "GarrisonMgr.h"
+#include "GitRevision.h"
#include "GridNotifiersImpl.h"
#include "GroupMgr.h"
#include "GuildFinderMgr.h"
@@ -58,7 +59,7 @@
#include "OutdoorPvPMgr.h"
#include "Player.h"
#include "PoolMgr.h"
-#include "GitRevision.h"
+#include "QueryCallback.h"
#include "ScenarioMgr.h"
#include "ScriptMgr.h"
#include "ScriptReloadMgr.h"
@@ -3055,7 +3056,7 @@ void World::UpdateRealmCharCount(uint32 accountId)
{
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHARACTER_COUNT);
stmt->setUInt32(0, accountId);
- m_realmCharCallbacks.push_back(CharacterDatabase.AsyncQuery(stmt));
+ _queryProcessor.AddQuery(CharacterDatabase.AsyncQuery(stmt).WithPreparedCallback(std::bind(&World::_UpdateRealmCharCount, this, std::placeholders::_1)));
}
void World::_UpdateRealmCharCount(PreparedQueryResult resultCharCount)
@@ -3459,20 +3460,7 @@ uint32 World::getWorldState(uint32 index) const
void World::ProcessQueryCallbacks()
{
- PreparedQueryResult result;
-
- for (std::deque<PreparedQueryResultFuture>::iterator itr = m_realmCharCallbacks.begin(); itr != m_realmCharCallbacks.end(); )
- {
- if ((*itr).wait_for(std::chrono::seconds(0)) != std::future_status::ready)
- {
- ++itr;
- continue;
- }
-
- result = (*itr).get();
- _UpdateRealmCharCount(result);
- itr = m_realmCharCallbacks.erase(itr);
- }
+ _queryProcessor.ProcessReadyQueries();
}
/**
diff --git a/src/server/game/World/World.h b/src/server/game/World/World.h
index fa780b81b54..53378f5ff93 100644
--- a/src/server/game/World/World.h
+++ b/src/server/game/World/World.h
@@ -29,7 +29,7 @@
#include "Timer.h"
#include "SharedDefines.h"
#include "QueryResult.h"
-#include "QueryCallback.h"
+#include "QueryCallbackProcessor.h"
#include "Realm/Realm.h"
#include <atomic>
@@ -913,7 +913,7 @@ class TC_GAME_API World
void LoadCharacterInfoStore();
void ProcessQueryCallbacks();
- std::deque<PreparedQueryResultFuture> m_realmCharCallbacks;
+ QueryCallbackProcessor _queryProcessor;
};
TC_GAME_API extern Realm realm;