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.cpp492
1 files changed, 292 insertions, 200 deletions
diff --git a/src/server/game/Handlers/CharacterHandler.cpp b/src/server/game/Handlers/CharacterHandler.cpp
index f605e138ce3..9be421e2f83 100644
--- a/src/server/game/Handlers/CharacterHandler.cpp
+++ b/src/server/game/Handlers/CharacterHandler.cpp
@@ -1174,82 +1174,94 @@ void WorldSession::HandleShowingCloakOpcode(WorldPacket& recvData)
_player->ToggleFlag(PLAYER_FLAGS, PLAYER_FLAGS_HIDE_CLOAK);
}
-void WorldSession::HandleCharRenameOpcode(WorldPacket& recvData)
+void WorldSession::HandleCharRenameOpcode(WorldPackets::Character::CharacterRenameRequest& request)
{
- WorldPackets::Character::CharacterRenameInfo renameInfo;
-
- recvData >> renameInfo.Guid
- >> renameInfo.Name;
+ if (!IsLegitCharacterForAccount(request.RenameInfo->Guid))
+ {
+ TC_LOG_ERROR("network", "Account %u, IP: %s tried to rename character %s, but it does not belong to their account!",
+ GetAccountId(), GetRemoteAddress().c_str(), request.RenameInfo->Guid.ToString().c_str());
+ KickPlayer();
+ return;
+ }
// prevent character rename to invalid name
- if (!normalizePlayerName(renameInfo.Name))
+ if (!normalizePlayerName(request.RenameInfo->NewName))
{
- SendCharRename(CHAR_NAME_NO_NAME, renameInfo);
+ SendCharRename(CHAR_NAME_NO_NAME, request.RenameInfo.get());
return;
}
- ResponseCodes res = ObjectMgr::CheckPlayerName(renameInfo.Name, true);
+ ResponseCodes res = ObjectMgr::CheckPlayerName(request.RenameInfo->NewName, true);
if (res != CHAR_NAME_SUCCESS)
{
- SendCharRename(res, renameInfo);
+ SendCharRename(res, request.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(request.RenameInfo->NewName))
{
- SendCharRename(CHAR_NAME_RESERVED, renameInfo);
+ SendCharRename(CHAR_NAME_RESERVED, request.RenameInfo.get());
return;
}
- // Ensure that the character belongs to the current account, that rename at login is enabled
- // and that there is no character with the desired new name
+ // Ensure that there is no character with the desired new name
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_FREE_NAME);
+ stmt->setUInt64(0, request.RenameInfo->Guid.GetCounter());
+ stmt->setString(1, request.RenameInfo->NewName);
- stmt->setUInt64(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);
-
- delete _charRenameCallback.GetParam();
- _charRenameCallback.SetParam(new WorldPackets::Character::CharacterRenameInfo(std::move(renameInfo)));
+ _charRenameCallback.SetParam(request.RenameInfo);
_charRenameCallback.SetFutureResult(CharacterDatabase.AsyncQuery(stmt));
}
-void WorldSession::HandleCharRenameCallBack(PreparedQueryResult result, WorldPackets::Character::CharacterRenameInfo const* renameInfo)
+void WorldSession::HandleCharRenameCallBack(PreparedQueryResult result, WorldPackets::Character::CharacterRenameInfo* renameInfo)
{
+ ASSERT(_charRenameCallback.GetParam().get() == renameInfo);
+
if (!result)
{
- SendCharRename(CHAR_CREATE_ERROR, *renameInfo);
+ SendCharRename(CHAR_CREATE_ERROR, renameInfo);
return;
}
Field* fields = result->Fetch();
std::string oldName = fields[0].GetString();
+ uint16 atLoginFlags = fields[1].GetUInt16();
- // Update name and at_login flag in the db
- PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_NAME);
+ if (!(atLoginFlags & AT_LOGIN_RENAME))
+ {
+ SendCharRename(CHAR_CREATE_ERROR, renameInfo);
+ return;
+ }
- stmt->setString(0, renameInfo->Name);
- stmt->setUInt16(1, AT_LOGIN_RENAME);
- stmt->setUInt64(2, renameInfo->Guid.GetCounter());
+ atLoginFlags &= ~AT_LOGIN_RENAME;
- CharacterDatabase.Execute(stmt);
+ SQLTransaction trans = CharacterDatabase.BeginTransaction();
+ ObjectGuid::LowType lowGuid = renameInfo->Guid.GetCounter();
+
+ // Update name and at_login flag in the db
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHAR_NAME_AT_LOGIN);
+ stmt->setString(0, renameInfo->NewName);
+ stmt->setUInt16(1, atLoginFlags);
+ stmt->setUInt64(2, lowGuid);
+
+ trans->Append(stmt);
// Removed declined name from db
- stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_DECLINED_NAME);
+ stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_DECLINED_NAME);
+ stmt->setUInt64(0, lowGuid);
- stmt->setUInt64(0, renameInfo->Guid.GetCounter());
+ trans->Append(stmt);
- CharacterDatabase.Execute(stmt);
+ CharacterDatabase.CommitTransaction(trans);
- 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->Name.c_str());
+ 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);
- sWorld->UpdateCharacterNameData(renameInfo->Guid, renameInfo->Name);
+ sWorld->UpdateCharacterNameData(renameInfo->Guid, renameInfo->NewName);
}
void WorldSession::HandleSetPlayerDeclinedNames(WorldPacket& recvData)
@@ -1412,32 +1424,26 @@ void WorldSession::HandleRemoveGlyph(WorldPacket& recvData)
}
}
-void WorldSession::HandleCharCustomize(WorldPacket& recvData)
+void WorldSession::HandleCharCustomizeOpcode(WorldPackets::Character::CharCustomize& packet)
{
- WorldPackets::Character::CharacterCustomizeInfo customizeInfo;
-
- recvData >> customizeInfo.Guid;
- if (!IsLegitCharacterForAccount(customizeInfo.Guid))
+ if (!IsLegitCharacterForAccount(packet.CustomizeInfo->CharGUID))
{
TC_LOG_ERROR("network", "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());
- recvData.rfinish();
+ GetAccountId(), GetRemoteAddress().c_str(), packet.CustomizeInfo->CharGUID.ToString().c_str());
KickPlayer();
return;
}
- 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->setUInt64(0, packet.CustomizeInfo->CharGUID.GetCounter());
- PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHARACTER_AT_LOGIN);
- stmt->setUInt64(0, customizeInfo.Guid.GetCounter());
- // TODO: Make async with callback
- PreparedQueryResult result = CharacterDatabase.Query(stmt);
+ _charCustomizeCallback.SetParam(packet.CustomizeInfo);
+ _charCustomizeCallback.SetFutureResult(CharacterDatabase.AsyncQuery(stmt));
+}
+
+void WorldSession::HandleCharCustomizeCallback(PreparedQueryResult result, WorldPackets::Character::CharCustomizeInfo* customizeInfo)
+{
+ ASSERT(_charCustomizeCallback.GetParam().get() == customizeInfo);
if (!result)
{
@@ -1446,22 +1452,27 @@ void WorldSession::HandleCharCustomize(WorldPacket& recvData)
}
Field* fields = result->Fetch();
- uint32 at_loginFlags = fields[0].GetUInt16();
- if (!(at_loginFlags & AT_LOGIN_CUSTOMIZE))
+ std::string oldName = fields[0].GetString();
+ uint16 atLoginFlags = fields[1].GetUInt16();
+ uint32 playerBytes2 = fields[2].GetUInt32();
+
+ if (!(atLoginFlags & AT_LOGIN_CUSTOMIZE))
{
SendCharCustomize(CHAR_CREATE_ERROR, customizeInfo);
return;
}
+ atLoginFlags &= ~AT_LOGIN_CUSTOMIZE;
+
// prevent character rename to invalid name
- if (!normalizePlayerName(customizeInfo.Name))
+ if (!normalizePlayerName(customizeInfo->CharName))
{
SendCharCustomize(CHAR_NAME_NO_NAME, customizeInfo);
return;
}
- ResponseCodes res = ObjectMgr::CheckPlayerName(customizeInfo.Name, true);
+ ResponseCodes res = ObjectMgr::CheckPlayerName(customizeInfo->CharName, true);
if (res != CHAR_NAME_SUCCESS)
{
SendCharCustomize(res, customizeInfo);
@@ -1469,55 +1480,67 @@ void WorldSession::HandleCharCustomize(WorldPacket& recvData)
}
// 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->CharName))
{
SendCharCustomize(CHAR_NAME_RESERVED, customizeInfo);
return;
}
// character with this name already exist
- ObjectGuid newGuid = sObjectMgr->GetPlayerGUIDByName(customizeInfo.Name);
+ /// @todo: make async
+ ObjectGuid newGuid = sObjectMgr->GetPlayerGUIDByName(customizeInfo->CharName);
if (!newGuid.IsEmpty())
{
- if (newGuid != customizeInfo.Guid)
+ if (newGuid != customizeInfo->CharGUID)
{
SendCharCustomize(CHAR_CREATE_NAME_IN_USE, customizeInfo);
return;
}
}
- stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHARACTER_NAME);
- stmt->setUInt64(0, customizeInfo.Guid.GetCounter());
- result = CharacterDatabase.Query(stmt);
+ PreparedStatement* stmt = nullptr;
+ SQLTransaction trans = CharacterDatabase.BeginTransaction();
+
+ ObjectGuid::LowType lowGuid = customizeInfo->CharGUID.GetCounter();
- if (result)
+ /// Customize
{
- std::string oldname = result->Fetch()[0].GetString();
- TC_LOG_INFO("entities.player.character", "Account: %u (IP: %s), Character[%s] (%s) Customized to: %s",
- GetAccountId(), GetRemoteAddress().c_str(), oldname.c_str(), customizeInfo.Guid.ToString().c_str(), customizeInfo.Name.c_str());
- }
+ playerBytes2 &= ~0xFF;
+ playerBytes2 |= customizeInfo->FacialHairStyleID;
- SQLTransaction trans = CharacterDatabase.BeginTransaction();
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_GENDER_PLAYERBYTES);
- Player::Customize(&customizeInfo, trans);
+ stmt->setUInt8(0, customizeInfo->SexID);
+ stmt->setUInt32(1, customizeInfo->SkinID | (uint32(customizeInfo->FaceID) << 8) | (uint32(customizeInfo->HairStyleID) << 16) | (uint32(customizeInfo->HairColorID) << 24));
+ stmt->setUInt32(2, playerBytes2);
+ stmt->setUInt64(3, lowGuid);
- stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHAR_NAME_AT_LOGIN);
- stmt->setString(0, customizeInfo.Name);
- stmt->setUInt16(1, uint16(AT_LOGIN_CUSTOMIZE));
- stmt->setUInt64(2, customizeInfo.Guid.GetCounter());
+ trans->Append(stmt);
+ }
- trans->Append(stmt);
+ /// Name Change and update atLogin flags
+ {
+ stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHAR_NAME_AT_LOGIN);
+ stmt->setString(0, customizeInfo->CharName);
+ stmt->setUInt16(1, atLoginFlags);
+ stmt->setUInt64(2, lowGuid);
- stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_DECLINED_NAME);
- stmt->setUInt64(0, customizeInfo.Guid.GetCounter());
+ trans->Append(stmt);
- trans->Append(stmt);
+ stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_DECLINED_NAME);
+ stmt->setUInt64(0, lowGuid);
+
+ trans->Append(stmt);
+ }
CharacterDatabase.CommitTransaction(trans);
- sWorld->UpdateCharacterNameData(customizeInfo.Guid, customizeInfo.Name, customizeInfo.Gender);
+ sWorld->UpdateCharacterNameData(customizeInfo->CharGUID, customizeInfo->CharName, customizeInfo->SexID);
SendCharCustomize(RESPONSE_SUCCESS, customizeInfo);
+
+ 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());
}
void WorldSession::HandleEquipmentSetSave(WorldPacket& recvData)
@@ -1643,33 +1666,35 @@ void WorldSession::HandleEquipmentSetUse(WorldPacket& recvData)
SendPacket(&data);
}
-void WorldSession::HandleCharFactionOrRaceChange(WorldPacket& recvData)
+void WorldSession::HandleCharRaceOrFactionChangeOpcode(WorldPackets::Character::CharRaceOrFactionChange& packet)
{
- WorldPackets::Character::CharacterFactionChangeInfo factionChangeInfo;
- recvData >> factionChangeInfo.Guid;
-
- if (!IsLegitCharacterForAccount(factionChangeInfo.Guid))
+ if (!IsLegitCharacterForAccount(packet.RaceOrFactionChangeInfo->Guid))
{
TC_LOG_ERROR("network", "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());
- recvData.rfinish();
+ GetAccountId(), GetRemoteAddress().c_str(), packet.RaceOrFactionChangeInfo->Guid.ToString().c_str());
KickPlayer();
return;
}
- recvData >> factionChangeInfo.Name
- >> factionChangeInfo.Gender
- >> factionChangeInfo.Skin
- >> factionChangeInfo.HairColor
- >> factionChangeInfo.HairStyle
- >> factionChangeInfo.FacialHair
- >> factionChangeInfo.Face
- >> factionChangeInfo.Race;
+ 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));
+}
- ObjectGuid::LowType lowGuid = factionChangeInfo.Guid.GetCounter();
+void WorldSession::HandleCharRaceOrFactionChangeCallback(PreparedQueryResult result, WorldPackets::Character::CharRaceOrFactionChangeInfo* factionChangeInfo)
+{
+ ASSERT(_charFactionChangeCallback.GetParam().get() == factionChangeInfo);
+
+ if (!result)
+ {
+ SendCharFactionChange(CHAR_CREATE_ERROR, factionChangeInfo);
+ return;
+ }
// get the players old (at this moment current) race
- CharacterNameData const* nameData = sWorld->GetCharacterNameData(factionChangeInfo.Guid);
+ CharacterNameData const* nameData = sWorld->GetCharacterNameData(factionChangeInfo->Guid);
if (!nameData)
{
SendCharFactionChange(CHAR_CREATE_ERROR, factionChangeInfo);
@@ -1680,38 +1705,42 @@ void WorldSession::HandleCharFactionOrRaceChange(WorldPacket& recvData)
uint8 playerClass = nameData->m_class;
uint8 level = nameData->m_level;
- // TO Do: Make async
- PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_AT_LOGIN_TITLES);
- stmt->setUInt64(0, lowGuid);
- PreparedQueryResult result = CharacterDatabase.Query(stmt);
-
- if (!result)
+ if (!sObjectMgr->GetPlayerInfo(factionChangeInfo->RaceID, playerClass))
{
SendCharFactionChange(CHAR_CREATE_ERROR, factionChangeInfo);
return;
}
- Field* fields = result->Fetch();
- uint32 at_loginFlags = fields[0].GetUInt16();
+ Field* fields = result->Fetch();
+ uint16 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);
+ uint32 playerBytes = fields[2].GetUInt32();
+ uint32 playerBytes2 = fields[3].GetUInt32();
- if (!sObjectMgr->GetPlayerInfo(factionChangeInfo.Race, playerClass))
+ uint16 usedLoginFlag = (factionChangeInfo->FactionChange ? AT_LOGIN_CHANGE_FACTION : AT_LOGIN_CHANGE_RACE);
+ if (!(atLoginFlags & usedLoginFlag))
{
SendCharFactionChange(CHAR_CREATE_ERROR, factionChangeInfo);
return;
}
- if (!(at_loginFlags & used_loginFlag))
+ TeamId newTeamId = Player::TeamIdForRace(factionChangeInfo->RaceID);
+ if (newTeamId == TEAM_NEUTRAL)
{
- SendCharFactionChange(CHAR_CREATE_ERROR, factionChangeInfo);
+ SendCharFactionChange(CHAR_CREATE_RESTRICTED_RACECLASS, factionChangeInfo);
+ return;
+ }
+
+ if (factionChangeInfo->FactionChange == (Player::TeamIdForRace(oldRace) != newTeamId))
+ {
+ SendCharFactionChange(factionChangeInfo->FactionChange ? CHAR_CREATE_CHARACTER_SWAP_FACTION : CHAR_CREATE_CHARACTER_RACE_ONLY, factionChangeInfo);
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->RaceID - 1)) & raceMaskDisabled)
{
SendCharFactionChange(CHAR_CREATE_ERROR, factionChangeInfo);
return;
@@ -1719,13 +1748,13 @@ void WorldSession::HandleCharFactionOrRaceChange(WorldPacket& recvData)
}
// prevent character rename to invalid name
- if (!normalizePlayerName(factionChangeInfo.Name))
+ if (!normalizePlayerName(factionChangeInfo->Name))
{
SendCharFactionChange(CHAR_NAME_NO_NAME, factionChangeInfo);
return;
}
- ResponseCodes res = ObjectMgr::CheckPlayerName(factionChangeInfo.Name, true);
+ ResponseCodes res = ObjectMgr::CheckPlayerName(factionChangeInfo->Name, true);
if (res != CHAR_NAME_SUCCESS)
{
SendCharFactionChange(res, factionChangeInfo);
@@ -1733,63 +1762,120 @@ void WorldSession::HandleCharFactionOrRaceChange(WorldPacket& recvData)
}
// 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);
return;
}
// character with this name already exist
- 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);
return;
}
}
+ if (sArenaTeamMgr->GetArenaTeamByCaptain(factionChangeInfo->Guid))
+ {
+ SendCharFactionChange(CHAR_CREATE_CHARACTER_ARENA_LEADER, factionChangeInfo);
+ return;
+ }
+
+ /// All checks are fine, deal with race change now
+
+ ObjectGuid::LowType lowGuid = factionChangeInfo->Guid.GetCounter();
+
// resurrect the character in case he's dead
- sObjectAccessor->ConvertCorpseForPlayer(factionChangeInfo.Guid);
+ sObjectAccessor->ConvertCorpseForPlayer(factionChangeInfo->Guid);
+ PreparedStatement* stmt = nullptr;
SQLTransaction trans = CharacterDatabase.BeginTransaction();
- 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->setUInt64(3, lowGuid);
- trans->Append(stmt);
+ stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHAR_NAME_AT_LOGIN);
+ stmt->setString(0, factionChangeInfo->Name);
+ stmt->setUInt16(1, uint16(atLoginFlags & ~usedLoginFlag));
+ stmt->setUInt64(2, lowGuid);
- stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_DECLINED_NAME);
- stmt->setUInt64(0, lowGuid);
- trans->Append(stmt);
+ trans->Append(stmt);
+
+ stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_DECLINED_NAME);
+ stmt->setUInt64(0, lowGuid);
- sWorld->UpdateCharacterNameData(factionChangeInfo.Guid, factionChangeInfo.Name, factionChangeInfo.Gender, factionChangeInfo.Race);
+ trans->Append(stmt);
+ }
- if (oldRace != factionChangeInfo.Race)
+ /// Customize
{
- TeamId team = TEAM_ALLIANCE;
+ if (factionChangeInfo->SkinID.HasValue)
+ {
+ playerBytes &= ~uint32(0xFF);
+ playerBytes |= factionChangeInfo->SkinID.value;
+ }
+ else
+ factionChangeInfo->SkinID.Set(uint8(playerBytes & 0xFF));
- // Search each faction is targeted
- switch (factionChangeInfo.Race)
+ if (factionChangeInfo->FaceID.HasValue)
{
- case RACE_ORC:
- case RACE_TAUREN:
- case RACE_UNDEAD_PLAYER:
- case RACE_TROLL:
- case RACE_BLOODELF:
- case RACE_GOBLIN:
- team = TEAM_HORDE;
- break;
- default:
- break;
+ playerBytes &= ~(uint32(0xFF) << 8);
+ playerBytes |= uint32(factionChangeInfo->FaceID.value) << 8;
}
+ else
+ factionChangeInfo->FaceID.Set(uint8((playerBytes2 >> 8) & 0xFF));
+ if (factionChangeInfo->HairStyleID.HasValue)
+ {
+ playerBytes &= ~(uint32(0xFF) << 16);
+ playerBytes |= uint32(factionChangeInfo->HairStyleID.value) << 16;
+ }
+ else
+ factionChangeInfo->HairStyleID.Set(uint8((playerBytes2 >> 16) & 0xFF));
+
+ if (factionChangeInfo->HairColorID.HasValue)
+ {
+ playerBytes &= ~(uint32(0xFF) << 24);
+ playerBytes |= uint32(factionChangeInfo->HairColorID.value) << 24;
+ }
+ else
+ factionChangeInfo->HairColorID.Set(uint8((playerBytes2 >> 24) & 0xFF));
+
+ if (factionChangeInfo->FacialHairStyleID.HasValue)
+ {
+ playerBytes2 &= ~0xFF;
+ playerBytes2 |= factionChangeInfo->FacialHairStyleID.value;
+ }
+ else
+ factionChangeInfo->FacialHairStyleID.Set(uint8(playerBytes2 & 0xFF));
+
+ stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_GENDER_PLAYERBYTES);
+ stmt->setUInt8(0, factionChangeInfo->SexID);
+ stmt->setUInt32(1, playerBytes);
+ stmt->setUInt32(2, playerBytes2);
+ stmt->setUInt64(3, lowGuid);
+
+ trans->Append(stmt);
+ }
+
+ /// Race Change
+ {
+ stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHAR_RACE);
+ stmt->setUInt8(0, factionChangeInfo->RaceID);
+ stmt->setUInt64(1, lowGuid);
+
+ trans->Append(stmt);
+ }
+
+ sWorld->UpdateCharacterNameData(factionChangeInfo->Guid, factionChangeInfo->Name, factionChangeInfo->SexID, factionChangeInfo->RaceID);
+
+ if (oldRace != factionChangeInfo->RaceID)
+ {
// Switch Languages
// delete all languages first
stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_SKILL_LANGUAGES);
@@ -1801,7 +1887,7 @@ void WorldSession::HandleCharFactionOrRaceChange(WorldPacket& recvData)
stmt->setUInt64(0, lowGuid);
// Faction specific languages
- if (team == TEAM_HORDE)
+ if (newTeamId == TEAM_HORDE)
stmt->setUInt16(1, 109);
else
stmt->setUInt16(1, 98);
@@ -1809,12 +1895,12 @@ void WorldSession::HandleCharFactionOrRaceChange(WorldPacket& recvData)
trans->Append(stmt);
// Race specific languages
- if (factionChangeInfo.Race != RACE_ORC && factionChangeInfo.Race != RACE_HUMAN)
+ if (factionChangeInfo->RaceID != RACE_ORC && factionChangeInfo->RaceID != RACE_HUMAN)
{
stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_CHAR_SKILL_LANGUAGE);
stmt->setUInt64(0, lowGuid);
- switch (factionChangeInfo.Race)
+ switch (factionChangeInfo->RaceID)
{
case RACE_DWARF:
stmt->setUInt16(1, 111);
@@ -1851,7 +1937,8 @@ void WorldSession::HandleCharFactionOrRaceChange(WorldPacket& recvData)
trans->Append(stmt);
}
- if (recvData.GetOpcode() == CMSG_CHAR_FACTION_CHANGE)
+ /// Team Conversation
+ if (factionChangeInfo->FactionChange)
{
// Delete all Flypaths
stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHAR_TAXI_PATH);
@@ -1866,7 +1953,8 @@ void WorldSession::HandleCharFactionOrRaceChange(WorldPacket& recvData)
uint32 numFullTaximasks = level / 7;
if (numFullTaximasks > 11)
numFullTaximasks = 11;
- if (team == TEAM_ALLIANCE)
+
+ if (newTeamId == TEAM_ALLIANCE)
{
if (playerClass != CLASS_DEATH_KNIGHT)
{
@@ -1897,27 +1985,25 @@ void WorldSession::HandleCharFactionOrRaceChange(WorldPacket& recvData)
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->setUInt64(1, lowGuid);
trans->Append(stmt);
}
+ /// @todo: make this part asynch
if (!sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD))
{
// Reset guild
stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_GUILD_MEMBER);
-
stmt->setUInt64(0, lowGuid);
- PreparedQueryResult result = CharacterDatabase.Query(stmt);
- if (result)
- if (Guild* guild = sGuildMgr->GetGuildById((result->Fetch()[0]).GetUInt64()))
- guild->DeleteMember(factionChangeInfo.Guid, false, false, true);
+ if (PreparedQueryResult result = CharacterDatabase.Query(stmt))
+ if (Guild* guild = sGuildMgr->GetGuildById(result->Fetch()[0].GetUInt64()))
+ guild->DeleteMember(factionChangeInfo->Guid, false, false, true);
- Player::LeaveAllArenaTeams(factionChangeInfo.Guid);
+ Player::LeaveAllArenaTeams(factionChangeInfo->Guid);
}
if (!HasPermission(rbac::RBAC_PERM_TWO_SIDE_ADD_FRIEND))
@@ -1942,7 +2028,7 @@ void WorldSession::HandleCharFactionOrRaceChange(WorldPacket& recvData)
WorldLocation loc;
uint16 zoneId = 0;
- if (team == TEAM_ALLIANCE)
+ if (newTeamId == TEAM_ALLIANCE)
{
loc.WorldRelocate(0, -8867.68f, 673.373f, 97.9034f, 0.0f);
zoneId = 1519;
@@ -1960,7 +2046,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)
@@ -1969,13 +2055,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(newTeamId == TEAM_ALLIANCE ? achiev_alliance : achiev_horde));
stmt->setUInt64(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(newTeamId == TEAM_ALLIANCE ? achiev_alliance : achiev_horde));
+ stmt->setUInt16(1, uint16(newTeamId == TEAM_ALLIANCE ? achiev_horde : achiev_alliance));
stmt->setUInt64(2, lowGuid);
trans->Append(stmt);
}
@@ -1987,8 +2073,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, (newTeamId == TEAM_ALLIANCE ? item_alliance : item_horde));
+ stmt->setUInt32(1, (newTeamId == TEAM_ALLIANCE ? item_horde : item_alliance));
stmt->setUInt64(2, lowGuid);
trans->Append(stmt);
}
@@ -2006,12 +2092,12 @@ void WorldSession::HandleCharFactionOrRaceChange(WorldPacket& recvData)
stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_QUESTSTATUS_REWARDED_BY_QUEST);
stmt->setUInt64(0, lowGuid);
- stmt->setUInt32(1, (team == TEAM_ALLIANCE ? quest_alliance : quest_horde));
+ stmt->setUInt32(1, (newTeamId == TEAM_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, (newTeamId == TEAM_ALLIANCE ? quest_alliance : quest_horde));
+ stmt->setUInt32(1, (newTeamId == TEAM_ALLIANCE ? quest_horde : quest_alliance));
stmt->setUInt64(2, lowGuid);
trans->Append(stmt);
}
@@ -2027,8 +2113,8 @@ 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;
- if (!(quest->GetRequiredRaces() & newRaceMask))
+ uint32 newRaceMask = (newTeamId == TEAM_ALLIANCE) ? RACEMASK_ALLIANCE : RACEMASK_HORDE;
+ if (quest->GetRequiredRaces() && !(quest->GetRequiredRaces() & newRaceMask))
{
stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHAR_QUESTSTATUS_REWARDED_ACTIVE_BY_QUEST);
stmt->setUInt64(0, lowGuid);
@@ -2045,13 +2131,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, (newTeamId == TEAM_ALLIANCE ? spell_alliance : spell_horde));
stmt->setUInt64(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, (newTeamId == TEAM_ALLIANCE ? spell_alliance : spell_horde));
+ stmt->setUInt32(1, (newTeamId == TEAM_ALLIANCE ? spell_horde : spell_alliance));
stmt->setUInt64(2, lowGuid);
trans->Append(stmt);
}
@@ -2061,8 +2147,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 = (newTeamId == TEAM_ALLIANCE) ? reputation_alliance : reputation_horde;
+ uint32 oldReputation = (newTeamId == TEAM_ALLIANCE) ? reputation_horde : reputation_alliance;
// select old standing set in db
stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_REP_BY_FACTION);
@@ -2079,7 +2165,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->RaceID, playerClass);
// final reputation shouldnt change
int32 FinalRep = oldDBRep + oldBaseRep;
@@ -2102,7 +2188,7 @@ 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);
@@ -2123,7 +2209,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 (newTeamId == TEAM_ALLIANCE)
{
uint32 maskID = htitleInfo->MaskID;
uint32 index = maskID / 32;
@@ -2155,7 +2241,7 @@ void WorldSession::HandleCharFactionOrRaceChange(WorldPacket& recvData)
ss << knownTitles[index] << ' ';
stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHAR_TITLES_FACTION_CHANGE);
- stmt->setString(0, ss.str().c_str());
+ stmt->setString(0, ss.str());
stmt->setUInt64(1, lowGuid);
trans->Append(stmt);
@@ -2170,7 +2256,7 @@ 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->RaceID);
SendCharFactionChange(RESPONSE_SUCCESS, factionChangeInfo);
}
@@ -2434,26 +2520,28 @@ void WorldSession::SendCharDelete(ResponseCodes result)
SendPacket(response.Write());
}
-void WorldSession::SendCharRename(ResponseCodes result, WorldPackets::Character::CharacterRenameInfo const& renameInfo)
+void WorldSession::SendCharRename(ResponseCodes result, WorldPackets::Character::CharacterRenameInfo const* renameInfo)
{
- WorldPacket data(SMSG_CHAR_RENAME, 1 + 8 + renameInfo.Name.size() + 1);
- data << uint8(result);
+ WorldPackets::Character::CharacterRenameResult packet;
+ packet.Result = result;
+ packet.Name = renameInfo->NewName;
if (result == RESPONSE_SUCCESS)
- {
- data << renameInfo.Guid;
- data << renameInfo.Name;
- }
- SendPacket(&data);
+ packet.Guid.Set(renameInfo->Guid);
+
+ SendPacket(packet.Write());
}
-void WorldSession::SendCharCustomize(ResponseCodes result, WorldPackets::Character::CharacterCustomizeInfo const& customizeInfo)
+void WorldSession::SendCharCustomize(ResponseCodes result, WorldPackets::Character::CharCustomizeInfo const* customizeInfo)
{
- WorldPacket data(SMSG_CHAR_CUSTOMIZE, 1 + 8 + customizeInfo.Name.size() + 1 + 6);
+ /// @todo: fix 6.x implementation
+ (void)customizeInfo;
+ /*
+ WorldPacket data(SMSG_CHAR_CUSTOMIZE, 1 + 8 + customizeInfo.NewName.size() + 1 + 6);
data << uint8(result);
if (result == RESPONSE_SUCCESS)
{
data << customizeInfo.Guid;
- data << customizeInfo.Name;
+ data << customizeInfo.NewName;
data << uint8(customizeInfo.Gender);
data << uint8(customizeInfo.Skin);
data << uint8(customizeInfo.Face);
@@ -2462,25 +2550,29 @@ void WorldSession::SendCharCustomize(ResponseCodes result, WorldPackets::Charact
data << uint8(customizeInfo.FacialHair);
}
SendPacket(&data);
+ */
}
-void WorldSession::SendCharFactionChange(ResponseCodes result, WorldPackets::Character::CharacterFactionChangeInfo const& factionChangeInfo)
+void WorldSession::SendCharFactionChange(ResponseCodes result, WorldPackets::Character::CharRaceOrFactionChangeInfo const* factionChangeInfo)
{
- WorldPacket data(SMSG_CHAR_FACTION_CHANGE, 1 + 8 + factionChangeInfo.Name.size() + 1 + 7);
- data << uint8(result);
+ WorldPackets::Character::CharFactionChangeResult packet;
+ packet.Result = result;
+ packet.Guid = factionChangeInfo->Guid;
+
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);
+ packet.Display.HasValue = true;
+ packet.Display.value.Name = factionChangeInfo->Name;
+ packet.Display.value.SexID = factionChangeInfo->SexID;
+ packet.Display.value.SkinID = factionChangeInfo->SkinID.value;
+ packet.Display.value.HairColorID = factionChangeInfo->HairColorID.value;
+ packet.Display.value.HairStyleID = factionChangeInfo->HairStyleID.value;
+ packet.Display.value.FacialHairStyleID = factionChangeInfo->FacialHairStyleID.value;
+ packet.Display.value.FaceID = factionChangeInfo->FaceID.value;
+ packet.Display.value.RaceID = factionChangeInfo->RaceID;
}
- SendPacket(&data);
+
+ SendPacket(packet.Write());
}
void WorldSession::SendSetPlayerDeclinedNamesResult(DeclinedNameResult result, ObjectGuid guid)