diff options
| author | Shauren <shauren.trinity@gmail.com> | 2017-01-13 21:38:03 +0100 |
|---|---|---|
| committer | Shauren <shauren.trinity@gmail.com> | 2017-01-13 21:38:03 +0100 |
| commit | 8e2634b2b49eb814b8cc425a060b2f160dbb49b7 (patch) | |
| tree | 9fc926ba9f77539c3eb847e37f3f9d7061f9d47a /src/server/game | |
| parent | 0f432edc4b48a8692e41fc30aef7751d295a7176 (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.cpp | 3 | ||||
| -rw-r--r-- | src/server/game/Accounts/RBAC.h | 2 | ||||
| -rw-r--r-- | src/server/game/Handlers/CharacterHandler.cpp | 440 | ||||
| -rw-r--r-- | src/server/game/Handlers/NPCHandler.cpp | 18 | ||||
| -rw-r--r-- | src/server/game/Handlers/SocialHandler.cpp | 9 | ||||
| -rw-r--r-- | src/server/game/Server/WorldSession.cpp | 127 | ||||
| -rw-r--r-- | src/server/game/Server/WorldSession.h | 36 | ||||
| -rw-r--r-- | src/server/game/Server/WorldSocket.cpp | 20 | ||||
| -rw-r--r-- | src/server/game/Server/WorldSocket.h | 4 | ||||
| -rw-r--r-- | src/server/game/World/World.cpp | 20 | ||||
| -rw-r--r-- | src/server/game/World/World.h | 4 |
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; |
