aboutsummaryrefslogtreecommitdiff
path: root/src/server/game/Handlers/CharacterHandler.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/server/game/Handlers/CharacterHandler.cpp')
-rw-r--r--src/server/game/Handlers/CharacterHandler.cpp684
1 files changed, 321 insertions, 363 deletions
diff --git a/src/server/game/Handlers/CharacterHandler.cpp b/src/server/game/Handlers/CharacterHandler.cpp
index cab80d23cba..0d6d750c73f 100644
--- a/src/server/game/Handlers/CharacterHandler.cpp
+++ b/src/server/game/Handlers/CharacterHandler.cpp
@@ -35,6 +35,7 @@
#include "Pet.h"
#include "PlayerDump.h"
#include "Player.h"
+#include "QueryCallback.h"
#include "ReputationMgr.h"
#include "GitRevision.h"
#include "ScriptMgr.h"
@@ -261,23 +262,23 @@ void WorldSession::HandleCharEnumOpcode(WorldPacket& /*recvData*/)
stmt->setUInt8(0, PET_SAVE_AS_CURRENT);
stmt->setUInt32(1, GetAccountId());
- _charEnumCallback = CharacterDatabase.AsyncQuery(stmt);
+ _queryProcessor.AddQuery(CharacterDatabase.AsyncQuery(stmt).WithPreparedCallback(std::bind(&WorldSession::HandleCharEnum, this, std::placeholders::_1)));
}
void WorldSession::HandleCharCreateOpcode(WorldPacket& recvData)
{
- CharacterCreateInfo createInfo;
-
- recvData >> createInfo.Name
- >> createInfo.Race
- >> createInfo.Class
- >> createInfo.Gender
- >> createInfo.Skin
- >> createInfo.Face
- >> createInfo.HairStyle
- >> createInfo.HairColor
- >> createInfo.FacialHair
- >> createInfo.OutfitId;
+ std::shared_ptr<CharacterCreateInfo> createInfo = std::make_shared<CharacterCreateInfo>();
+
+ recvData >> createInfo->Name
+ >> createInfo->Race
+ >> createInfo->Class
+ >> createInfo->Gender
+ >> createInfo->Skin
+ >> createInfo->Face
+ >> createInfo->HairStyle
+ >> createInfo->HairColor
+ >> createInfo->FacialHair
+ >> createInfo->OutfitId;
if (!HasPermission(rbac::RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_TEAMMASK))
{
@@ -285,7 +286,7 @@ void WorldSession::HandleCharCreateOpcode(WorldPacket& recvData)
{
bool disabled = false;
- switch (Player::TeamForRace(createInfo.Race))
+ switch (Player::TeamForRace(createInfo->Race))
{
case ALLIANCE:
disabled = (mask & (1 << 0)) != 0;
@@ -303,18 +304,18 @@ void WorldSession::HandleCharCreateOpcode(WorldPacket& recvData)
}
}
- ChrClassesEntry const* classEntry = sChrClassesStore.LookupEntry(createInfo.Class);
+ ChrClassesEntry const* classEntry = sChrClassesStore.LookupEntry(createInfo->Class);
if (!classEntry)
{
- TC_LOG_ERROR("network", "Class (%u) not found in DBC while creating new char for account (ID: %u): wrong DBC files or cheater?", createInfo.Class, GetAccountId());
+ TC_LOG_ERROR("network", "Class (%u) not found in DBC while creating new char for account (ID: %u): wrong DBC files or cheater?", createInfo->Class, GetAccountId());
SendCharCreate(CHAR_CREATE_FAILED);
return;
}
- ChrRacesEntry const* raceEntry = sChrRacesStore.LookupEntry(createInfo.Race);
+ ChrRacesEntry const* raceEntry = sChrRacesStore.LookupEntry(createInfo->Race);
if (!raceEntry)
{
- TC_LOG_ERROR("network", "Race (%u) not found in DBC while creating new char for account (ID: %u): wrong DBC files or cheater?", createInfo.Race, GetAccountId());
+ TC_LOG_ERROR("network", "Race (%u) not found in DBC while creating new char for account (ID: %u): wrong DBC files or cheater?", createInfo->Race, GetAccountId());
SendCharCreate(CHAR_CREATE_FAILED);
return;
}
@@ -322,7 +323,7 @@ void WorldSession::HandleCharCreateOpcode(WorldPacket& recvData)
// prevent character creating Expansion race without Expansion account
if (raceEntry->expansion > Expansion())
{
- TC_LOG_ERROR("entities.player.cheat", "Expansion %u account:[%d] tried to Create character with expansion %u race (%u)", Expansion(), GetAccountId(), raceEntry->expansion, createInfo.Race);
+ TC_LOG_ERROR("entities.player.cheat", "Expansion %u account:[%d] tried to Create character with expansion %u race (%u)", Expansion(), GetAccountId(), raceEntry->expansion, createInfo->Race);
SendCharCreate(CHAR_CREATE_EXPANSION);
return;
}
@@ -330,7 +331,7 @@ void WorldSession::HandleCharCreateOpcode(WorldPacket& recvData)
// prevent character creating Expansion class without Expansion account
if (classEntry->expansion > Expansion())
{
- TC_LOG_ERROR("entities.player.cheat", "Expansion %u account:[%d] tried to Create character with expansion %u class (%u)", Expansion(), GetAccountId(), classEntry->expansion, createInfo.Class);
+ TC_LOG_ERROR("entities.player.cheat", "Expansion %u account:[%d] tried to Create character with expansion %u class (%u)", Expansion(), GetAccountId(), classEntry->expansion, createInfo->Class);
SendCharCreate(CHAR_CREATE_EXPANSION_CLASS);
return;
}
@@ -338,7 +339,7 @@ void WorldSession::HandleCharCreateOpcode(WorldPacket& recvData)
if (!HasPermission(rbac::RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_RACEMASK))
{
uint32 raceMaskDisabled = sWorld->getIntConfig(CONFIG_CHARACTER_CREATING_DISABLED_RACEMASK);
- if ((1 << (createInfo.Race - 1)) & raceMaskDisabled)
+ if ((1 << (createInfo->Race - 1)) & raceMaskDisabled)
{
SendCharCreate(CHAR_CREATE_DISABLED);
return;
@@ -348,7 +349,7 @@ void WorldSession::HandleCharCreateOpcode(WorldPacket& recvData)
if (!HasPermission(rbac::RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_CLASSMASK))
{
uint32 classMaskDisabled = sWorld->getIntConfig(CONFIG_CHARACTER_CREATING_DISABLED_CLASSMASK);
- if ((1 << (createInfo.Class - 1)) & classMaskDisabled)
+ if ((1 << (createInfo->Class - 1)) & classMaskDisabled)
{
SendCharCreate(CHAR_CREATE_DISABLED);
return;
@@ -356,7 +357,7 @@ void WorldSession::HandleCharCreateOpcode(WorldPacket& recvData)
}
// prevent character creating with invalid name
- if (!normalizePlayerName(createInfo.Name))
+ if (!normalizePlayerName(createInfo->Name))
{
TC_LOG_ERROR("entities.player.cheat", "Account:[%d] but tried to Create character with empty [name] ", GetAccountId());
SendCharCreate(CHAR_NAME_NO_NAME);
@@ -364,20 +365,20 @@ void WorldSession::HandleCharCreateOpcode(WorldPacket& recvData)
}
// check name limitations
- ResponseCodes res = ObjectMgr::CheckPlayerName(createInfo.Name, GetSessionDbcLocale(), true);
+ ResponseCodes res = ObjectMgr::CheckPlayerName(createInfo->Name, GetSessionDbcLocale(), true);
if (res != CHAR_NAME_SUCCESS)
{
SendCharCreate(res);
return;
}
- if (!HasPermission(rbac::RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_RESERVEDNAME) && sObjectMgr->IsReservedName(createInfo.Name))
+ if (!HasPermission(rbac::RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_RESERVEDNAME) && sObjectMgr->IsReservedName(createInfo->Name))
{
SendCharCreate(CHAR_NAME_RESERVED);
return;
}
- if (createInfo.Class == CLASS_DEATH_KNIGHT && !HasPermission(rbac::RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_HEROIC_CHARACTER))
+ if (createInfo->Class == CLASS_DEATH_KNIGHT && !HasPermission(rbac::RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_HEROIC_CHARACTER))
{
// speedup check for heroic class disabled case
uint32 heroic_free_slots = sWorld->getIntConfig(CONFIG_HEROIC_CHARACTERS_PER_REALM);
@@ -397,104 +398,58 @@ void WorldSession::HandleCharCreateOpcode(WorldPacket& recvData)
}
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHECK_NAME);
- stmt->setString(0, createInfo.Name);
+ stmt->setString(0, createInfo->Name);
- delete _charCreateCallback.GetParam(); // Delete existing if any, to make the callback chain reset to stage 0
- _charCreateCallback.SetParam(new CharacterCreateInfo(std::move(createInfo)));
- _charCreateCallback.SetFutureResult(CharacterDatabase.AsyncQuery(stmt));
-}
-
-void WorldSession::HandleCharCreateCallback(PreparedQueryResult result, 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 syncrhonisation 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);
- delete createInfo;
- _charCreateCallback.Reset();
- return;
- }
-
- ASSERT(_charCreateCallback.GetParam() == 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);
- delete createInfo;
- _charCreateCallback.Reset();
+ SendCharCreate(CHAR_CREATE_SERVER_LIMIT);
return;
}
-
- ASSERT(_charCreateCallback.GetParam() == 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);
- delete createInfo;
- _charCreateCallback.Reset();
- return;
- }
- }
-
- bool allowTwoSideAccounts = !sWorld->IsPvPRealm() || HasPermission(rbac::RBAC_PERM_TWO_SIDE_CHARACTER_CREATION);
- uint32 skipCinematics = sWorld->getIntConfig(CONFIG_SKIP_CINEMATICS);
-
- _charCreateCallback.FreeResult();
+ bool allowTwoSideAccounts = !sWorld->IsPvPRealm() || HasPermission(rbac::RBAC_PERM_TWO_SIDE_CHARACTER_CREATION);
+ uint32 skipCinematics = sWorld->getIntConfig(CONFIG_SKIP_CINEMATICS);
- if (!allowTwoSideAccounts || skipCinematics == 1 || createInfo->Class == CLASS_DEATH_KNIGHT)
- {
- PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_CREATE_INFO);
- stmt->setUInt32(0, GetAccountId());
- stmt->setUInt32(1, (skipCinematics == 1 || createInfo->Class == CLASS_DEATH_KNIGHT) ? 10 : 1);
- _charCreateCallback.SetFutureResult(CharacterDatabase.AsyncQuery(stmt));
- _charCreateCallback.NextStage();
- return;
- }
-
- _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);
@@ -509,7 +464,7 @@ void WorldSession::HandleCharCreateCallback(PreparedQueryResult result, Characte
uint32 freeHeroicSlots = sWorld->getIntConfig(CONFIG_HEROIC_CHARACTERS_PER_REALM);
Field* field = result->Fetch();
- uint8 accRace = field[1].GetUInt8();
+ uint8 accRace = field[1].GetUInt8();
if (checkHeroicReqs)
{
@@ -522,8 +477,6 @@ void WorldSession::HandleCharCreateCallback(PreparedQueryResult result, Characte
if (freeHeroicSlots == 0)
{
SendCharCreate(CHAR_CREATE_UNIQUE_CLASS_LIMIT);
- delete createInfo;
- _charCreateCallback.Reset();
return;
}
}
@@ -547,8 +500,6 @@ void WorldSession::HandleCharCreateCallback(PreparedQueryResult result, Characte
if (accTeam != team)
{
SendCharCreate(CHAR_CREATE_PVP_TEAMS_VIOLATION);
- delete createInfo;
- _charCreateCallback.Reset();
return;
}
}
@@ -577,8 +528,6 @@ void WorldSession::HandleCharCreateCallback(PreparedQueryResult result, Characte
if (freeHeroicSlots == 0)
{
SendCharCreate(CHAR_CREATE_UNIQUE_CLASS_LIMIT);
- delete createInfo;
- _charCreateCallback.Reset();
return;
}
}
@@ -596,22 +545,18 @@ void WorldSession::HandleCharCreateCallback(PreparedQueryResult result, Characte
if (checkHeroicReqs && !hasHeroicReqLevel)
{
SendCharCreate(CHAR_CREATE_LEVEL_REQUIREMENT);
- delete createInfo;
- _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);
- delete createInfo;
- _charCreateCallback.Reset();
return;
}
@@ -620,7 +565,7 @@ void WorldSession::HandleCharCreateCallback(PreparedQueryResult result, Characte
newChar.SetAtLoginFlag(AT_LOGIN_FIRST); // First login
- // Player created, save it now
+ // Player created, save it now
newChar.SaveToDB(true);
createInfo->CharCount += 1;
@@ -646,11 +591,19 @@ void WorldSession::HandleCharCreateCallback(PreparedQueryResult result, Characte
sWorld->AddCharacterInfo(newChar.GetGUID(), GetAccountId(), newChar.GetName(), newChar.GetByteValue(PLAYER_BYTES_3, PLAYER_BYTES_3_OFFSET_GENDER), newChar.getRace(), newChar.getClass(), newChar.getLevel());
newChar.CleanupsBeforeDelete();
- delete createInfo;
- _charCreateCallback.Reset();
- break;
+ };
+
+ if (allowTwoSideAccounts && !skipCinematics && createInfo->Class != CLASS_DEATH_KNIGHT)
+ {
+ 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) ? 10 : 1);
+ queryCallback.WithPreparedCallback(std::move(finalizeCharacterCreation)).SetNextQuery(CharacterDatabase.AsyncQuery(stmt));
+ }));
}
void WorldSession::HandleCharDeleteOpcode(WorldPacket& recvData)
@@ -1084,29 +1037,29 @@ void WorldSession::HandleShowingCloakOpcode(WorldPacket& recvData)
void WorldSession::HandleCharRenameOpcode(WorldPacket& recvData)
{
- CharacterRenameInfo renameInfo;
+ std::shared_ptr<CharacterRenameInfo> renameInfo = std::make_shared<CharacterRenameInfo>();
- recvData >> renameInfo.Guid
- >> renameInfo.Name;
+ recvData >> renameInfo->Guid
+ >> renameInfo->Name;
// prevent character rename to invalid name
- if (!normalizePlayerName(renameInfo.Name))
+ if (!normalizePlayerName(renameInfo->Name))
{
- SendCharRename(CHAR_NAME_NO_NAME, renameInfo);
+ SendCharRename(CHAR_NAME_NO_NAME, renameInfo.get());
return;
}
- ResponseCodes res = ObjectMgr::CheckPlayerName(renameInfo.Name, GetSessionDbcLocale(), true);
+ ResponseCodes res = ObjectMgr::CheckPlayerName(renameInfo->Name, GetSessionDbcLocale(), true);
if (res != CHAR_NAME_SUCCESS)
{
- SendCharRename(res, renameInfo);
+ SendCharRename(res, renameInfo.get());
return;
}
// check name limitations
- if (!HasPermission(rbac::RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_RESERVEDNAME) && sObjectMgr->IsReservedName(renameInfo.Name))
+ if (!HasPermission(rbac::RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_RESERVEDNAME) && sObjectMgr->IsReservedName(renameInfo->Name))
{
- SendCharRename(CHAR_NAME_RESERVED, renameInfo);
+ SendCharRename(CHAR_NAME_RESERVED, renameInfo.get());
return;
}
@@ -1114,35 +1067,43 @@ void WorldSession::HandleCharRenameOpcode(WorldPacket& recvData)
// and that there is no character with the desired new name
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_FREE_NAME);
- stmt->setUInt32(0, renameInfo.Guid.GetCounter());
+ stmt->setUInt32(0, renameInfo->Guid.GetCounter());
stmt->setUInt32(1, GetAccountId());
- stmt->setUInt16(2, AT_LOGIN_RENAME);
- stmt->setUInt16(3, AT_LOGIN_RENAME);
- stmt->setString(4, renameInfo.Name);
+ stmt->setString(2, renameInfo->Name);
- delete _charRenameCallback.GetParam();
- _charRenameCallback.SetParam(new CharacterRenameInfo(std::move(renameInfo)));
- _charRenameCallback.SetFutureResult(CharacterDatabase.AsyncQuery(stmt));
+ _queryProcessor.AddQuery(CharacterDatabase.AsyncQuery(stmt)
+ .WithPreparedCallback(std::bind(&WorldSession::HandleCharRenameCallback, this, renameInfo, std::placeholders::_1)));
}
-void WorldSession::HandleChangePlayerNameOpcodeCallBack(PreparedQueryResult result, CharacterRenameInfo const* renameInfo)
+void WorldSession::HandleCharRenameCallback(std::shared_ptr<CharacterRenameInfo> renameInfo, PreparedQueryResult result)
{
if (!result)
{
- SendCharRename(CHAR_CREATE_ERROR, *renameInfo);
+ SendCharRename(CHAR_CREATE_ERROR, renameInfo.get());
return;
}
Field* fields = result->Fetch();
- ObjectGuid::LowType guidLow = fields[0].GetUInt32();
+ ObjectGuid::LowType guidLow = fields[0].GetUInt32();
std::string oldName = fields[1].GetString();
+ uint16 atLoginFlags = fields[2].GetUInt16();
+
+ if (!(atLoginFlags & AT_LOGIN_RENAME))
+ {
+ SendCharRename(CHAR_CREATE_ERROR, renameInfo.get());
+ return;
+ }
+
+ atLoginFlags &= ~AT_LOGIN_RENAME;
+
+ SQLTransaction trans = CharacterDatabase.BeginTransaction();
// Update name and at_login flag in the db
- PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_NAME);
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHAR_NAME_AT_LOGIN);
stmt->setString(0, renameInfo->Name);
- stmt->setUInt16(1, AT_LOGIN_RENAME);
+ stmt->setUInt16(1, atLoginFlags);
stmt->setUInt32(2, guidLow);
CharacterDatabase.Execute(stmt);
@@ -1156,7 +1117,7 @@ void WorldSession::HandleChangePlayerNameOpcodeCallBack(PreparedQueryResult resu
TC_LOG_INFO("entities.player.character", "Account: %d (IP: %s) Character:[%s] (%s) Changed name to: %s", GetAccountId(), GetRemoteAddress().c_str(), oldName.c_str(), renameInfo->Guid.ToString().c_str(), renameInfo->Name.c_str());
- SendCharRename(RESPONSE_SUCCESS, *renameInfo);
+ SendCharRename(RESPONSE_SUCCESS, renameInfo.get());
sWorld->UpdateCharacterInfo(renameInfo->Guid, renameInfo->Name);
}
@@ -1331,131 +1292,131 @@ void WorldSession::HandleRemoveGlyph(WorldPacket& recvData)
void WorldSession::HandleCharCustomize(WorldPacket& recvData)
{
- CharacterCustomizeInfo customizeInfo;
+ std::shared_ptr<CharacterCustomizeInfo> customizeInfo = std::make_shared<CharacterCustomizeInfo>();
- recvData >> customizeInfo.Guid;
- if (!IsLegitCharacterForAccount(customizeInfo.Guid))
+ recvData >> customizeInfo->Guid;
+ if (!IsLegitCharacterForAccount(customizeInfo->Guid))
{
TC_LOG_ERROR("entities.player.cheat", "Account %u, IP: %s tried to customise %s, but it does not belong to their account!",
- GetAccountId(), GetRemoteAddress().c_str(), customizeInfo.Guid.ToString().c_str());
+ GetAccountId(), GetRemoteAddress().c_str(), customizeInfo->Guid.ToString().c_str());
recvData.rfinish();
KickPlayer();
return;
}
- recvData >> customizeInfo.Name
- >> customizeInfo.Gender
- >> customizeInfo.Skin
- >> customizeInfo.HairColor
- >> customizeInfo.HairStyle
- >> customizeInfo.FacialHair
- >> customizeInfo.Face;
+ recvData >> customizeInfo->Name
+ >> customizeInfo->Gender
+ >> customizeInfo->Skin
+ >> customizeInfo->HairColor
+ >> customizeInfo->HairStyle
+ >> customizeInfo->FacialHair
+ >> customizeInfo->Face;
+
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_CUSTOMIZE_INFO);
+ stmt->setUInt32(0, customizeInfo->Guid.GetCounter());
- PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHARACTER_NAME_DATA);
- stmt->setUInt32(0, customizeInfo.Guid.GetCounter());
- PreparedQueryResult result = CharacterDatabase.Query(stmt);
+ _queryProcessor.AddQuery(CharacterDatabase.AsyncQuery(stmt)
+ .WithPreparedCallback(std::bind(&WorldSession::HandleCharCustomizeCallback, this, customizeInfo, std::placeholders::_1)));
+}
+void WorldSession::HandleCharCustomizeCallback(std::shared_ptr<CharacterCustomizeInfo> customizeInfo, PreparedQueryResult result)
+{
if (!result)
{
- SendCharCustomize(CHAR_CREATE_ERROR, customizeInfo);
+ SendCharCustomize(CHAR_CREATE_ERROR, customizeInfo.get());
return;
}
Field* fields = result->Fetch();
- uint8 plrRace = fields[0].GetUInt8();
- uint8 plrClass = fields[1].GetUInt8();
- uint8 plrGender = fields[2].GetUInt8();
- std::string oldName = fields[4].GetString();
+ std::string oldName = fields[0].GetString();
+ uint8 plrRace = fields[1].GetUInt8();
+ uint8 plrClass = fields[2].GetUInt8();
+ uint8 plrGender = fields[3].GetUInt8();
+ uint16 atLoginFlags = fields[4].GetUInt16();
- if (!Player::ValidateAppearance(plrRace, plrClass, plrGender, customizeInfo.HairStyle, customizeInfo.HairColor, customizeInfo.Face, customizeInfo.FacialHair, customizeInfo.Skin, true))
+ if (!Player::ValidateAppearance(plrRace, plrClass, plrGender, customizeInfo->HairStyle, customizeInfo->HairColor, customizeInfo->Face, customizeInfo->FacialHair, customizeInfo->Skin, true))
{
- SendCharCustomize(CHAR_CREATE_ERROR, customizeInfo);
+ SendCharCustomize(CHAR_CREATE_ERROR, customizeInfo.get());
return;
}
- stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHARACTER_AT_LOGIN);
-
- stmt->setUInt32(0, customizeInfo.Guid.GetCounter());
- // TODO: Make async with callback
- result = CharacterDatabase.Query(stmt);
-
- if (!result)
+ if (!(atLoginFlags & AT_LOGIN_CUSTOMIZE))
{
- SendCharCustomize(CHAR_CREATE_ERROR, customizeInfo);
+ SendCharCustomize(CHAR_CREATE_ERROR, customizeInfo.get());
return;
}
- fields = result->Fetch();
- uint32 at_loginFlags = fields[0].GetUInt16();
-
- if (!(at_loginFlags & AT_LOGIN_CUSTOMIZE))
- {
- SendCharCustomize(CHAR_CREATE_ERROR, customizeInfo);
- return;
- }
+ atLoginFlags &= ~AT_LOGIN_CUSTOMIZE;
// prevent character rename
- if (sWorld->getBoolConfig(CONFIG_PREVENT_RENAME_CUSTOMIZATION) && (customizeInfo.Name != oldName))
+ if (sWorld->getBoolConfig(CONFIG_PREVENT_RENAME_CUSTOMIZATION) && (customizeInfo->Name != oldName))
{
- SendCharCustomize(CHAR_NAME_FAILURE, customizeInfo);
+ SendCharCustomize(CHAR_NAME_FAILURE, customizeInfo.get());
return;
}
// prevent character rename to invalid name
- if (!normalizePlayerName(customizeInfo.Name))
+ if (!normalizePlayerName(customizeInfo->Name))
{
- SendCharCustomize(CHAR_NAME_NO_NAME, customizeInfo);
+ SendCharCustomize(CHAR_NAME_NO_NAME, customizeInfo.get());
return;
}
- ResponseCodes res = ObjectMgr::CheckPlayerName(customizeInfo.Name, GetSessionDbcLocale(), true);
+ ResponseCodes res = ObjectMgr::CheckPlayerName(customizeInfo->Name, 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.Name))
+ if (!HasPermission(rbac::RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_RESERVEDNAME) && sObjectMgr->IsReservedName(customizeInfo->Name))
{
- SendCharCustomize(CHAR_NAME_RESERVED, customizeInfo);
+ SendCharCustomize(CHAR_NAME_RESERVED, customizeInfo.get());
return;
}
// character with this name already exist
- if (ObjectGuid newGuid = sObjectMgr->GetPlayerGUIDByName(customizeInfo.Name))
+ if (ObjectGuid newGuid = sObjectMgr->GetPlayerGUIDByName(customizeInfo->Name))
{
- if (newGuid != customizeInfo.Guid)
+ if (newGuid != customizeInfo->Guid)
{
- SendCharCustomize(CHAR_CREATE_NAME_IN_USE, customizeInfo);
+ SendCharCustomize(CHAR_CREATE_NAME_IN_USE, customizeInfo.get());
return;
}
}
+ PreparedStatement* stmt = nullptr;
SQLTransaction trans = CharacterDatabase.BeginTransaction();
- Player::Customize(&customizeInfo, trans);
+ ObjectGuid::LowType lowGuid = customizeInfo->Guid.GetCounter();
- stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHAR_NAME_AT_LOGIN);
- stmt->setString(0, customizeInfo.Name);
- stmt->setUInt16(1, uint16(AT_LOGIN_CUSTOMIZE));
- stmt->setUInt32(2, customizeInfo.Guid.GetCounter());
+ /// Customize
+ Player::Customize(customizeInfo.get(), trans);
- trans->Append(stmt);
+ /// Name Change and update atLogin flags
+ {
+ stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHAR_NAME_AT_LOGIN);
+ stmt->setString(0, customizeInfo->Name);
+ stmt->setUInt16(1, atLoginFlags);
+ stmt->setUInt32(2, lowGuid);
- stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_DECLINED_NAME);
- stmt->setUInt32(0, customizeInfo.Guid.GetCounter());
+ trans->Append(stmt);
- trans->Append(stmt);
+ stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_DECLINED_NAME);
+ stmt->setUInt32(0, lowGuid);
+
+ trans->Append(stmt);
+ }
CharacterDatabase.CommitTransaction(trans);
- sWorld->UpdateCharacterInfo(customizeInfo.Guid, customizeInfo.Name, customizeInfo.Gender);
+ sWorld->UpdateCharacterInfo(customizeInfo->Guid, customizeInfo->Name, customizeInfo->Gender);
- SendCharCustomize(RESPONSE_SUCCESS, customizeInfo);
+ SendCharCustomize(RESPONSE_SUCCESS, customizeInfo.get());
TC_LOG_INFO("entities.player.character", "Account: %d (IP: %s), Character[%s] (%s) Customized to: %s",
- GetAccountId(), GetRemoteAddress().c_str(), oldName.c_str(), customizeInfo.Guid.ToString().c_str(), customizeInfo.Name.c_str());
+ GetAccountId(), GetRemoteAddress().c_str(), oldName.c_str(), customizeInfo->Guid.ToString().c_str(), customizeInfo->Name.c_str());
}
void WorldSession::HandleEquipmentSetSave(WorldPacket& recvData)
@@ -1585,157 +1546,174 @@ void WorldSession::HandleEquipmentSetUse(WorldPacket& recvData)
void WorldSession::HandleCharFactionOrRaceChange(WorldPacket& recvData)
{
- CharacterFactionChangeInfo factionChangeInfo;
- recvData >> factionChangeInfo.Guid;
+ std::shared_ptr<CharacterFactionChangeInfo> factionChangeInfo = std::make_shared<CharacterFactionChangeInfo>();
+ recvData >> factionChangeInfo->Guid;
- if (!IsLegitCharacterForAccount(factionChangeInfo.Guid))
+ if (!IsLegitCharacterForAccount(factionChangeInfo->Guid))
{
TC_LOG_ERROR("entities.player.cheat", "Account %u, IP: %s tried to factionchange character %s, but it does not belong to their account!",
- GetAccountId(), GetRemoteAddress().c_str(), factionChangeInfo.Guid.ToString().c_str());
+ GetAccountId(), GetRemoteAddress().c_str(), factionChangeInfo->Guid.ToString().c_str());
recvData.rfinish();
KickPlayer();
return;
}
- recvData >> factionChangeInfo.Name
- >> factionChangeInfo.Gender
- >> factionChangeInfo.Skin
- >> factionChangeInfo.HairColor
- >> factionChangeInfo.HairStyle
- >> factionChangeInfo.FacialHair
- >> factionChangeInfo.Face
- >> factionChangeInfo.Race;
+ recvData >> factionChangeInfo->Name
+ >> factionChangeInfo->Gender
+ >> factionChangeInfo->Skin
+ >> factionChangeInfo->HairColor
+ >> factionChangeInfo->HairStyle
+ >> factionChangeInfo->FacialHair
+ >> factionChangeInfo->Face
+ >> factionChangeInfo->Race;
- ObjectGuid::LowType lowGuid = factionChangeInfo.Guid.GetCounter();
+ factionChangeInfo->FactionChange = (recvData.GetOpcode() == CMSG_CHAR_FACTION_CHANGE);
- // get the players old (at this moment current) race
- CharacterInfo const* nameData = sWorld->GetCharacterInfo(factionChangeInfo.Guid);
- if (!nameData)
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_RACE_OR_FACTION_CHANGE_INFOS);
+ stmt->setUInt32(0, factionChangeInfo->Guid.GetCounter());
+
+ _queryProcessor.AddQuery(CharacterDatabase.AsyncQuery(stmt)
+ .WithPreparedCallback(std::bind(&WorldSession::HandleCharFactionOrRaceChangeCallback, this, factionChangeInfo, std::placeholders::_1)));
+}
+
+void WorldSession::HandleCharFactionOrRaceChangeCallback(std::shared_ptr<CharacterFactionChangeInfo> factionChangeInfo, PreparedQueryResult result)
+{
+ if (!result)
{
- SendCharFactionChange(CHAR_CREATE_ERROR, factionChangeInfo);
+ SendCharFactionChange(CHAR_CREATE_ERROR, factionChangeInfo.get());
return;
}
- std::string oldName = nameData->Name;
- uint8 oldRace = nameData->Race;
- uint8 playerClass = nameData->Class;
- uint8 level = nameData->Level;
+ // get the players old (at this moment current) race
+ CharacterInfo const* characterInfo = sWorld->GetCharacterInfo(factionChangeInfo->Guid);
+ if (!characterInfo)
+ {
+ SendCharFactionChange(CHAR_CREATE_ERROR, factionChangeInfo.get());
+ return;
+ }
- // TO Do: Make async
- PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_AT_LOGIN_TITLES);
- stmt->setUInt32(0, lowGuid);
- PreparedQueryResult result = CharacterDatabase.Query(stmt);
+ uint8 oldRace = characterInfo->Race;
+ uint8 playerClass = characterInfo->Class;
+ uint8 level = characterInfo->Level;
- if (!result)
+ if (!sObjectMgr->GetPlayerInfo(factionChangeInfo->Race, playerClass))
{
- SendCharFactionChange(CHAR_CREATE_ERROR, factionChangeInfo);
+ SendCharFactionChange(CHAR_CREATE_ERROR, factionChangeInfo.get());
return;
}
- Field* fields = result->Fetch();
- uint32 at_loginFlags = fields[0].GetUInt16();
+ Field* fields = result->Fetch();
+ uint32 atLoginFlags = fields[0].GetUInt16();
std::string knownTitlesStr = fields[1].GetString();
- uint32 used_loginFlag = ((recvData.GetOpcode() == CMSG_CHAR_RACE_CHANGE) ? AT_LOGIN_CHANGE_RACE : AT_LOGIN_CHANGE_FACTION);
- if (!sObjectMgr->GetPlayerInfo(factionChangeInfo.Race, playerClass))
+ uint32 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;
}
- if (!(at_loginFlags & used_loginFlag))
+ uint32 newTeam = Player::TeamForRace(factionChangeInfo->Race);
+ if (factionChangeInfo->FactionChange == (Player::TeamForRace(oldRace) == newTeam))
{
- SendCharFactionChange(CHAR_CREATE_ERROR, factionChangeInfo);
+ SendCharFactionChange(factionChangeInfo->FactionChange ? CHAR_CREATE_CHARACTER_SWAP_FACTION : CHAR_CREATE_CHARACTER_RACE_ONLY, factionChangeInfo.get());
return;
}
if (!HasPermission(rbac::RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_RACEMASK))
{
uint32 raceMaskDisabled = sWorld->getIntConfig(CONFIG_CHARACTER_CREATING_DISABLED_RACEMASK);
- if ((1 << (factionChangeInfo.Race - 1)) & raceMaskDisabled)
+ if ((1 << (factionChangeInfo->Race - 1)) & raceMaskDisabled)
{
- SendCharFactionChange(CHAR_CREATE_ERROR, factionChangeInfo);
+ SendCharFactionChange(CHAR_CREATE_ERROR, factionChangeInfo.get());
return;
}
}
// prevent character rename
- if (sWorld->getBoolConfig(CONFIG_PREVENT_RENAME_CUSTOMIZATION) && (factionChangeInfo.Name != oldName))
+ if (sWorld->getBoolConfig(CONFIG_PREVENT_RENAME_CUSTOMIZATION) && (factionChangeInfo->Name != characterInfo->Name))
{
- SendCharFactionChange(CHAR_NAME_FAILURE, factionChangeInfo);
+ SendCharFactionChange(CHAR_NAME_FAILURE, factionChangeInfo.get());
return;
}
// prevent character rename to invalid name
- if (!normalizePlayerName(factionChangeInfo.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);
+ 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))
+ 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;
}
// character with this name already exist
- if (ObjectGuid newGuid = sObjectMgr->GetPlayerGUIDByName(factionChangeInfo.Name))
+ ObjectGuid newGuid = sObjectMgr->GetPlayerGUIDByName(factionChangeInfo->Name);
+ if (!newGuid.IsEmpty())
{
- if (newGuid != factionChangeInfo.Guid)
+ 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.get());
+ return;
+ }
+
+ // All checks are fine, deal with race change now
+ ObjectGuid::LowType lowGuid = factionChangeInfo->Guid.GetCounter();
+
+ PreparedStatement* stmt = nullptr;
SQLTransaction trans = CharacterDatabase.BeginTransaction();
// resurrect the character in case he's dead
- Player::OfflineResurrect(factionChangeInfo.Guid, trans);
+ Player::OfflineResurrect(factionChangeInfo->Guid, trans);
- CharacterDatabase.EscapeString(factionChangeInfo.Name);
- Player::Customize(&factionChangeInfo, trans);
+ // Name Change and update atLogin flags
+ {
+ CharacterDatabase.EscapeString(factionChangeInfo->Name);
- stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_FACTION_OR_RACE);
- stmt->setString(0, factionChangeInfo.Name);
- stmt->setUInt8(1, factionChangeInfo.Race);
- stmt->setUInt16(2, used_loginFlag);
- stmt->setUInt32(3, lowGuid);
- trans->Append(stmt);
+ stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHAR_NAME_AT_LOGIN);
+ stmt->setString(0, factionChangeInfo->Name);
+ stmt->setUInt16(1, uint16((atLoginFlags | AT_LOGIN_RESURRECT) & ~usedLoginFlag));
+ stmt->setUInt32(2, lowGuid);
+ trans->Append(stmt);
- stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_DECLINED_NAME);
- stmt->setUInt32(0, lowGuid);
- trans->Append(stmt);
+ stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_DECLINED_NAME);
+ stmt->setUInt32(0, lowGuid);
+ trans->Append(stmt);
+ }
- sWorld->UpdateCharacterInfo(factionChangeInfo.Guid, factionChangeInfo.Name, factionChangeInfo.Gender, factionChangeInfo.Race);
+ // Customize
+ Player::Customize(factionChangeInfo.get(), trans);
- if (oldRace != factionChangeInfo.Race)
+ // Race Change
{
- TeamId team = TEAM_ALLIANCE;
+ stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHAR_RACE);
+ stmt->setUInt8(0, factionChangeInfo->Race);
+ stmt->setUInt32(1, lowGuid);
+ trans->Append(stmt);
+ }
- // Search each faction is targeted
- switch (factionChangeInfo.Race)
- {
- case RACE_ORC:
- case RACE_TAUREN:
- case RACE_UNDEAD_PLAYER:
- case RACE_TROLL:
- case RACE_BLOODELF:
- team = TEAM_HORDE;
- break;
- default:
- break;
- }
+ sWorld->UpdateCharacterInfo(factionChangeInfo->Guid, factionChangeInfo->Name, factionChangeInfo->Gender, factionChangeInfo->Race);
+ if (oldRace != factionChangeInfo->Race)
+ {
// Switch Languages
// delete all languages first
stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_SKILL_LANGUAGES);
@@ -1747,7 +1725,7 @@ void WorldSession::HandleCharFactionOrRaceChange(WorldPacket& recvData)
stmt->setUInt32(0, lowGuid);
// Faction specific languages
- if (team == TEAM_HORDE)
+ if (newTeam == HORDE)
stmt->setUInt16(1, 109);
else
stmt->setUInt16(1, 98);
@@ -1755,12 +1733,12 @@ void WorldSession::HandleCharFactionOrRaceChange(WorldPacket& recvData)
trans->Append(stmt);
// Race specific languages
- if (factionChangeInfo.Race != RACE_ORC && factionChangeInfo.Race != RACE_HUMAN)
+ if (factionChangeInfo->Race != RACE_ORC && factionChangeInfo->Race != RACE_HUMAN)
{
stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_CHAR_SKILL_LANGUAGE);
stmt->setUInt32(0, lowGuid);
- switch (factionChangeInfo.Race)
+ switch (factionChangeInfo->Race)
{
case RACE_DWARF:
stmt->setUInt16(1, 111);
@@ -1791,7 +1769,7 @@ void WorldSession::HandleCharFactionOrRaceChange(WorldPacket& recvData)
trans->Append(stmt);
}
- if (recvData.GetOpcode() == CMSG_CHAR_FACTION_CHANGE)
+ if (factionChangeInfo->FactionChange)
{
// Delete all Flypaths
stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHAR_TAXI_PATH);
@@ -1806,41 +1784,21 @@ void WorldSession::HandleCharFactionOrRaceChange(WorldPacket& recvData)
uint32 numFullTaximasks = level / 7;
if (numFullTaximasks > 11)
numFullTaximasks = 11;
- if (team == TEAM_ALLIANCE)
- {
- if (playerClass != CLASS_DEATH_KNIGHT)
- {
- for (uint8 i = 0; i < numFullTaximasks; ++i)
- taximaskstream << uint32(sAllianceTaxiNodesMask[i]) << ' ';
- }
- else
- {
- for (uint8 i = 0; i < numFullTaximasks; ++i)
- taximaskstream << uint32(sAllianceTaxiNodesMask[i] | sDeathKnightTaxiNodesMask[i]) << ' ';
- }
- }
- else
+
+ TaxiMask const& factionMask = newTeam == HORDE ? sHordeTaxiNodesMask : sAllianceTaxiNodesMask;
+ for (uint8 i = 0; i < numFullTaximasks; ++i)
{
- if (playerClass != CLASS_DEATH_KNIGHT)
- {
- for (uint8 i = 0; i < numFullTaximasks; ++i)
- taximaskstream << uint32(sHordeTaxiNodesMask[i]) << ' ';
- }
- else
- {
- for (uint8 i = 0; i < numFullTaximasks; ++i)
- taximaskstream << uint32(sHordeTaxiNodesMask[i] | sDeathKnightTaxiNodesMask[i]) << ' ';
- }
+ uint8 deathKnightExtraNode = (playerClass == CLASS_DEATH_KNIGHT) ? sDeathKnightTaxiNodesMask[i] : 0;
+ taximaskstream << uint32(factionMask[i] | deathKnightExtraNode) << ' ';
}
uint32 numEmptyTaximasks = 11 - numFullTaximasks;
for (uint8 i = 0; i < numEmptyTaximasks; ++i)
taximaskstream << "0 ";
taximaskstream << '0';
- std::string taximask = taximaskstream.str();
stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHAR_TAXIMASK);
- stmt->setString(0, taximask);
+ stmt->setString(0, taximaskstream.str());
stmt->setUInt32(1, lowGuid);
trans->Append(stmt);
}
@@ -1853,9 +1811,9 @@ void WorldSession::HandleCharFactionOrRaceChange(WorldPacket& recvData)
stmt->setUInt32(0, lowGuid);
if (PreparedQueryResult result = CharacterDatabase.Query(stmt))
if (Guild* guild = sGuildMgr->GetGuildById((result->Fetch()[0]).GetUInt32()))
- guild->DeleteMember(trans, factionChangeInfo.Guid, false, false, true);
+ guild->DeleteMember(trans, factionChangeInfo->Guid, false, false, true);
- Player::LeaveAllArenaTeams(factionChangeInfo.Guid);
+ Player::LeaveAllArenaTeams(factionChangeInfo->Guid);
}
if (!HasPermission(rbac::RBAC_PERM_TWO_SIDE_ADD_FRIEND))
@@ -1880,7 +1838,7 @@ void WorldSession::HandleCharFactionOrRaceChange(WorldPacket& recvData)
WorldLocation loc;
uint16 zoneId = 0;
- if (team == TEAM_ALLIANCE)
+ if (newTeam == ALLIANCE)
{
loc.WorldRelocate(0, -8867.68f, 673.373f, 97.9034f, 0.0f);
zoneId = 1519;
@@ -1898,7 +1856,7 @@ void WorldSession::HandleCharFactionOrRaceChange(WorldPacket& recvData)
stmt->setFloat(5, loc.GetPositionZ());
trans->Append(stmt);
- Player::SavePositionInDB(loc, zoneId, factionChangeInfo.Guid, trans);
+ Player::SavePositionInDB(loc, zoneId, factionChangeInfo->Guid, trans);
// Achievement conversion
for (std::map<uint32, uint32>::const_iterator it = sObjectMgr->FactionChangeAchievements.begin(); it != sObjectMgr->FactionChangeAchievements.end(); ++it)
@@ -1907,13 +1865,13 @@ void WorldSession::HandleCharFactionOrRaceChange(WorldPacket& recvData)
uint32 achiev_horde = it->second;
stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_ACHIEVEMENT_BY_ACHIEVEMENT);
- stmt->setUInt16(0, uint16(team == TEAM_ALLIANCE ? achiev_alliance : achiev_horde));
+ stmt->setUInt16(0, uint16(newTeam == ALLIANCE ? achiev_alliance : achiev_horde));
stmt->setUInt32(1, lowGuid);
trans->Append(stmt);
stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHAR_ACHIEVEMENT);
- stmt->setUInt16(0, uint16(team == TEAM_ALLIANCE ? achiev_alliance : achiev_horde));
- stmt->setUInt16(1, uint16(team == TEAM_ALLIANCE ? achiev_horde : achiev_alliance));
+ stmt->setUInt16(0, uint16(newTeam == ALLIANCE ? achiev_alliance : achiev_horde));
+ stmt->setUInt16(1, uint16(newTeam == ALLIANCE ? achiev_horde : achiev_alliance));
stmt->setUInt32(2, lowGuid);
trans->Append(stmt);
}
@@ -1925,8 +1883,8 @@ void WorldSession::HandleCharFactionOrRaceChange(WorldPacket& recvData)
uint32 item_horde = it->second;
stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHAR_INVENTORY_FACTION_CHANGE);
- stmt->setUInt32(0, (team == TEAM_ALLIANCE ? item_alliance : item_horde));
- stmt->setUInt32(1, (team == TEAM_ALLIANCE ? item_horde : item_alliance));
+ stmt->setUInt32(0, (newTeam == ALLIANCE ? item_alliance : item_horde));
+ stmt->setUInt32(1, (newTeam == ALLIANCE ? item_horde : item_alliance));
stmt->setUInt32(2, lowGuid);
trans->Append(stmt);
}
@@ -1944,12 +1902,12 @@ void WorldSession::HandleCharFactionOrRaceChange(WorldPacket& recvData)
stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_QUESTSTATUS_REWARDED_BY_QUEST);
stmt->setUInt32(0, lowGuid);
- stmt->setUInt32(1, (team == TEAM_ALLIANCE ? quest_alliance : quest_horde));
+ stmt->setUInt32(1, (newTeam == ALLIANCE ? quest_alliance : quest_horde));
trans->Append(stmt);
stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHAR_QUESTSTATUS_REWARDED_FACTION_CHANGE);
- stmt->setUInt32(0, (team == TEAM_ALLIANCE ? quest_alliance : quest_horde));
- stmt->setUInt32(1, (team == TEAM_ALLIANCE ? quest_horde : quest_alliance));
+ stmt->setUInt32(0, (newTeam == ALLIANCE ? quest_alliance : quest_horde));
+ stmt->setUInt32(1, (newTeam == ALLIANCE ? quest_horde : quest_alliance));
stmt->setUInt32(2, lowGuid);
trans->Append(stmt);
}
@@ -1965,7 +1923,7 @@ void WorldSession::HandleCharFactionOrRaceChange(WorldPacket& recvData)
for (ObjectMgr::QuestMap::const_iterator iter = questTemplates.begin(); iter != questTemplates.end(); ++iter)
{
Quest const* quest = iter->second;
- uint32 newRaceMask = (team == TEAM_ALLIANCE) ? RACEMASK_ALLIANCE : RACEMASK_HORDE;
+ uint32 newRaceMask = (newTeam == ALLIANCE) ? RACEMASK_ALLIANCE : RACEMASK_HORDE;
if (!(quest->GetAllowableRaces() & newRaceMask))
{
stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHAR_QUESTSTATUS_REWARDED_ACTIVE_BY_QUEST);
@@ -1983,13 +1941,13 @@ void WorldSession::HandleCharFactionOrRaceChange(WorldPacket& recvData)
uint32 spell_horde = it->second;
stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_SPELL_BY_SPELL);
- stmt->setUInt32(0, (team == TEAM_ALLIANCE ? spell_alliance : spell_horde));
+ stmt->setUInt32(0, (newTeam == ALLIANCE ? spell_alliance : spell_horde));
stmt->setUInt32(1, lowGuid);
trans->Append(stmt);
stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHAR_SPELL_FACTION_CHANGE);
- stmt->setUInt32(0, (team == TEAM_ALLIANCE ? spell_alliance : spell_horde));
- stmt->setUInt32(1, (team == TEAM_ALLIANCE ? spell_horde : spell_alliance));
+ stmt->setUInt32(0, (newTeam == ALLIANCE ? spell_alliance : spell_horde));
+ stmt->setUInt32(1, (newTeam == ALLIANCE ? spell_horde : spell_alliance));
stmt->setUInt32(2, lowGuid);
trans->Append(stmt);
}
@@ -1999,8 +1957,8 @@ void WorldSession::HandleCharFactionOrRaceChange(WorldPacket& recvData)
{
uint32 reputation_alliance = it->first;
uint32 reputation_horde = it->second;
- uint32 newReputation = (team == TEAM_ALLIANCE) ? reputation_alliance : reputation_horde;
- uint32 oldReputation = (team == TEAM_ALLIANCE) ? reputation_horde : reputation_alliance;
+ uint32 newReputation = (newTeam == ALLIANCE) ? reputation_alliance : reputation_horde;
+ uint32 oldReputation = (newTeam == ALLIANCE) ? reputation_horde : reputation_alliance;
// select old standing set in db
stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_REP_BY_FACTION);
@@ -2017,7 +1975,7 @@ void WorldSession::HandleCharFactionOrRaceChange(WorldPacket& recvData)
int32 oldBaseRep = sObjectMgr->GetBaseReputationOf(factionEntry, oldRace, playerClass);
// new base reputation
- int32 newBaseRep = sObjectMgr->GetBaseReputationOf(sFactionStore.LookupEntry(newReputation), factionChangeInfo.Race, playerClass);
+ int32 newBaseRep = sObjectMgr->GetBaseReputationOf(sFactionStore.LookupEntry(newReputation), factionChangeInfo->Race, playerClass);
// final reputation shouldnt change
int32 FinalRep = oldDBRep + oldBaseRep;
@@ -2040,13 +1998,13 @@ void WorldSession::HandleCharFactionOrRaceChange(WorldPacket& recvData)
// Title conversion
if (!knownTitlesStr.empty())
{
- const uint32 ktcount = KNOWN_TITLES_SIZE * 2;
+ uint32 const ktcount = KNOWN_TITLES_SIZE * 2;
uint32 knownTitles[ktcount];
Tokenizer tokens(knownTitlesStr, ' ', ktcount);
if (tokens.size() != ktcount)
{
- SendCharFactionChange(CHAR_CREATE_ERROR, factionChangeInfo);
+ SendCharFactionChange(CHAR_CREATE_ERROR, factionChangeInfo.get());
return;
}
@@ -2061,7 +2019,7 @@ void WorldSession::HandleCharFactionOrRaceChange(WorldPacket& recvData)
CharTitlesEntry const* atitleInfo = sCharTitlesStore.LookupEntry(title_alliance);
CharTitlesEntry const* htitleInfo = sCharTitlesStore.LookupEntry(title_horde);
// new team
- if (team == TEAM_ALLIANCE)
+ if (newTeam == ALLIANCE)
{
uint32 bitIndex = htitleInfo->bit_index;
uint32 index = bitIndex / 32;
@@ -2108,9 +2066,9 @@ void WorldSession::HandleCharFactionOrRaceChange(WorldPacket& recvData)
CharacterDatabase.CommitTransaction(trans);
- TC_LOG_DEBUG("entities.player", "%s (IP: %s) changed race from %u to %u", GetPlayerInfo().c_str(), GetRemoteAddress().c_str(), oldRace, factionChangeInfo.Race);
+ TC_LOG_DEBUG("entities.player", "%s (IP: %s) changed race from %u to %u", GetPlayerInfo().c_str(), GetRemoteAddress().c_str(), oldRace, factionChangeInfo->Race);
- SendCharFactionChange(RESPONSE_SUCCESS, factionChangeInfo);
+ SendCharFactionChange(RESPONSE_SUCCESS, factionChangeInfo.get());
}
void WorldSession::SendCharCreate(ResponseCodes result)
@@ -2127,51 +2085,51 @@ void WorldSession::SendCharDelete(ResponseCodes result)
SendPacket(&data);
}
-void WorldSession::SendCharRename(ResponseCodes result, CharacterRenameInfo const& renameInfo)
+void WorldSession::SendCharRename(ResponseCodes result, CharacterRenameInfo const* renameInfo)
{
- WorldPacket data(SMSG_CHAR_RENAME, 1 + 8 + renameInfo.Name.size() + 1);
+ WorldPacket data(SMSG_CHAR_RENAME, 1 + 8 + renameInfo->Name.size() + 1);
data << uint8(result);
if (result == RESPONSE_SUCCESS)
{
- data << renameInfo.Guid;
- data << renameInfo.Name;
+ data << renameInfo->Guid;
+ data << renameInfo->Name;
}
SendPacket(&data);
}
-void WorldSession::SendCharCustomize(ResponseCodes result, CharacterCustomizeInfo const& customizeInfo)
+void WorldSession::SendCharCustomize(ResponseCodes result, CharacterCustomizeInfo const* customizeInfo)
{
- WorldPacket data(SMSG_CHAR_CUSTOMIZE, 1 + 8 + customizeInfo.Name.size() + 1 + 6);
+ WorldPacket data(SMSG_CHAR_CUSTOMIZE, 1 + 8 + customizeInfo->Name.size() + 1 + 6);
data << uint8(result);
if (result == RESPONSE_SUCCESS)
{
- data << customizeInfo.Guid;
- data << customizeInfo.Name;
- data << uint8(customizeInfo.Gender);
- data << uint8(customizeInfo.Skin);
- data << uint8(customizeInfo.Face);
- data << uint8(customizeInfo.HairStyle);
- data << uint8(customizeInfo.HairColor);
- data << uint8(customizeInfo.FacialHair);
+ data << customizeInfo->Guid;
+ data << customizeInfo->Name;
+ data << uint8(customizeInfo->Gender);
+ data << uint8(customizeInfo->Skin);
+ data << uint8(customizeInfo->Face);
+ data << uint8(customizeInfo->HairStyle);
+ data << uint8(customizeInfo->HairColor);
+ data << uint8(customizeInfo->FacialHair);
}
SendPacket(&data);
}
-void WorldSession::SendCharFactionChange(ResponseCodes result, CharacterFactionChangeInfo const& factionChangeInfo)
+void WorldSession::SendCharFactionChange(ResponseCodes result, CharacterFactionChangeInfo const* factionChangeInfo)
{
- WorldPacket data(SMSG_CHAR_FACTION_CHANGE, 1 + 8 + factionChangeInfo.Name.size() + 1 + 7);
+ WorldPacket data(SMSG_CHAR_FACTION_CHANGE, 1 + 8 + factionChangeInfo->Name.size() + 1 + 7);
data << uint8(result);
if (result == RESPONSE_SUCCESS)
{
- data << factionChangeInfo.Guid;
- data << factionChangeInfo.Name;
- data << uint8(factionChangeInfo.Gender);
- data << uint8(factionChangeInfo.Skin);
- data << uint8(factionChangeInfo.Face);
- data << uint8(factionChangeInfo.HairStyle);
- data << uint8(factionChangeInfo.HairColor);
- data << uint8(factionChangeInfo.FacialHair);
- data << uint8(factionChangeInfo.Race);
+ data << factionChangeInfo->Guid;
+ data << factionChangeInfo->Name;
+ data << uint8(factionChangeInfo->Gender);
+ data << uint8(factionChangeInfo->Skin);
+ data << uint8(factionChangeInfo->Face);
+ data << uint8(factionChangeInfo->HairStyle);
+ data << uint8(factionChangeInfo->HairColor);
+ data << uint8(factionChangeInfo->FacialHair);
+ data << uint8(factionChangeInfo->Race);
}
SendPacket(&data);
}