aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/server/game/Entities/Player/Player.cpp44
-rw-r--r--src/server/game/Entities/Player/Player.h6
-rw-r--r--src/server/game/Handlers/CharacterHandler.cpp492
-rw-r--r--src/server/game/Server/Packets/CharacterPackets.cpp92
-rw-r--r--src/server/game/Server/Packets/CharacterPackets.h127
-rw-r--r--src/server/game/Server/Packets/WorldStatePackets.cpp2
-rw-r--r--src/server/game/Server/Protocol/Opcodes.cpp53
-rw-r--r--src/server/game/Server/Protocol/Opcodes.h118
-rw-r--r--src/server/game/Server/WorldSession.cpp21
-rw-r--r--src/server/game/Server/WorldSession.h27
-rw-r--r--src/server/scripts/Commands/cs_character.cpp2
-rw-r--r--src/server/shared/Database/Implementation/CharacterDatabase.cpp13
-rw-r--r--src/server/shared/Database/Implementation/CharacterDatabase.h9
-rw-r--r--src/server/shared/Utilities/Util.h12
14 files changed, 661 insertions, 357 deletions
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index 01d68b3871b..dcd69e65264 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -3348,7 +3348,7 @@ bool Player::AddTalent(uint32 spellId, uint8 spec, bool learning)
TC_LOG_ERROR("spells", "Player::addTalent: Learning non-talent spell %u not allowed.", spellId);
return false;
}
-
+
TalentSpecInfo* talentSpecInfo = GetTalentSpecInfo(spec);
// Check if player already has this talent
@@ -4120,7 +4120,7 @@ bool Player::ResetTalents(bool no_cost)
}
RemovePet(NULL, PET_SAVE_NOT_IN_SLOT, true);
-
+
uint8 spec = GetActiveSpec();
for (uint32 talentId = 0; talentId < sTalentStore.GetNumRows(); ++talentId)
@@ -4142,7 +4142,7 @@ bool Player::ResetTalents(bool no_cost)
continue;
RemoveSpell(talentInfo->SpellID, true);
-
+
// search for spells that the talent teaches and unlearn them
for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
if (_spellEntry->Effects[i].TriggerSpell > 0 && _spellEntry->Effects[i].Effect == SPELL_EFFECT_LEARN_SPELL)
@@ -4172,7 +4172,7 @@ bool Player::ResetTalents(bool no_cost)
for (uint32 i = 0; i < MAX_MASTERY_SPELLS; ++i)
if (uint32 mastery = chrSpec->MasterySpellID[i])
RemoveAurasDueToSpell(mastery);
-
+
SetTalentSpec(spec, 0);
SQLTransaction trans = CharacterDatabase.BeginTransaction();
@@ -6538,6 +6538,15 @@ uint32 Player::TeamForRace(uint8 race)
return ALLIANCE;
}
+TeamId Player::TeamIdForRace(uint8 race)
+{
+ if (ChrRacesEntry const* rEntry = sChrRacesStore.LookupEntry(race))
+ return TeamId(rEntry->TeamID);
+
+ TC_LOG_ERROR("entities.player", "Race (%u) not found in DBC: wrong DBC files?", race);
+ return TEAM_NEUTRAL;
+}
+
void Player::setFactionForRace(uint8 race)
{
m_team = TeamForRace(race);
@@ -20135,31 +20144,6 @@ void Player::SetUInt32ValueInArray(Tokenizer& Tokenizer, uint16 index, uint32 va
Tokenizer[index] = buf;
}
-void Player::Customize(WorldPackets::Character::CharacterCustomizeInfo const* customizeInfo, SQLTransaction& trans)
-{
- PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_PLAYERBYTES2);
- stmt->setUInt64(0, customizeInfo->Guid.GetCounter());
- PreparedQueryResult result = CharacterDatabase.Query(stmt);
-
- if (!result)
- return;
-
- Field* fields = result->Fetch();
-
- uint32 playerBytes2 = fields[0].GetUInt32();
- playerBytes2 &= ~0xFF;
- playerBytes2 |= customizeInfo->FacialHair;
-
- stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_GENDER_PLAYERBYTES);
-
- stmt->setUInt8(0, customizeInfo->Gender);
- stmt->setUInt32(1, customizeInfo->Skin | (customizeInfo->Face << 8) | (customizeInfo->HairStyle << 16) | (customizeInfo->HairColor << 24));
- stmt->setUInt32(2, playerBytes2);
- stmt->setUInt64(3, customizeInfo->Guid.GetCounter());
-
- CharacterDatabase.ExecuteOrAppend(trans, stmt);
-}
-
void Player::SendAttackSwingDeadTarget()
{
WorldPacket data(SMSG_ATTACKSWING_DEADTARGET, 0);
@@ -26163,7 +26147,7 @@ void Player::_SaveTalents(SQLTransaction& trans)
if (talent->State == PLAYERSPELL_REMOVED)
talent->SpellID = 0;
-
+
talent->State = PLAYERSPELL_UNCHANGED;
}
}
diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h
index 19105f49add..54d542011a1 100644
--- a/src/server/game/Entities/Player/Player.h
+++ b/src/server/game/Entities/Player/Player.h
@@ -1222,7 +1222,7 @@ struct TalentSpecInfo
PlayerTalent Talents[MAX_TALENT_TIERS];
uint32 Glyphs[MAX_GLYPH_SLOT_INDEX];
uint32 TalentSpec;
-
+
bool HasTalent(uint32 spellId)
{
for (uint32 i = 0; i < MAX_TALENT_TIERS; ++i)
@@ -1230,7 +1230,7 @@ struct TalentSpecInfo
return true;
return false;
}
-
+
void Reset()
{
for (uint32 i = 0; i < MAX_TALENT_TIERS; ++i) {
@@ -1712,7 +1712,6 @@ class Player : public Unit, public GridObject<Player>
static void SetUInt32ValueInArray(Tokenizer& data, uint16 index, uint32 value);
static void SetFloatValueInArray(Tokenizer& data, uint16 index, float value);
- static void Customize(WorldPackets::Character::CharacterCustomizeInfo const* customizeInfo, SQLTransaction& trans);
static void SavePositionInDB(WorldLocation const& loc, uint16 zoneId, ObjectGuid guid, SQLTransaction& trans);
static void DeleteFromDB(ObjectGuid playerguid, uint32 accountId, bool updateRealmChars = true, bool deleteFinally = false);
@@ -2146,6 +2145,7 @@ class Player : public Unit, public GridObject<Player>
void CheckAreaExploreAndOutdoor(void);
static uint32 TeamForRace(uint8 race);
+ static TeamId TeamIdForRace(uint8 race);
uint32 GetTeam() const { return m_team; }
TeamId GetTeamId() const { return m_team == ALLIANCE ? TEAM_ALLIANCE : TEAM_HORDE; }
void setFactionForRace(uint8 race);
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)
diff --git a/src/server/game/Server/Packets/CharacterPackets.cpp b/src/server/game/Server/Packets/CharacterPackets.cpp
index 7f6fefbf058..9a187ac7ead 100644
--- a/src/server/game/Server/Packets/CharacterPackets.cpp
+++ b/src/server/game/Server/Packets/CharacterPackets.cpp
@@ -220,6 +220,98 @@ WorldPacket const* WorldPackets::Character::CharacterDeleteResponse::Write()
return &_worldPacket;
}
+void WorldPackets::Character::CharacterRenameRequest::Read()
+{
+ RenameInfo.reset(new CharacterRenameInfo());
+ _worldPacket >> RenameInfo->Guid;
+ RenameInfo->NewName = _worldPacket.ReadString(_worldPacket.ReadBits(6));
+}
+
+WorldPacket const* WorldPackets::Character::CharacterRenameResult::Write()
+{
+ _worldPacket << uint8(Result);
+ _worldPacket.WriteBit(Guid.HasValue);
+ _worldPacket.WriteBits(Name.length(), 6);
+
+ if (Guid.HasValue)
+ _worldPacket << Guid.value;
+
+ _worldPacket.WriteString(Name);
+ return &_worldPacket;
+}
+
+void WorldPackets::Character::CharCustomize::Read()
+{
+ CustomizeInfo.reset(new CharCustomizeInfo());
+ _worldPacket >> CustomizeInfo->CharGUID;
+ _worldPacket >> CustomizeInfo->SexID;
+ _worldPacket >> CustomizeInfo->SkinID;
+ _worldPacket >> CustomizeInfo->HairColorID;
+ _worldPacket >> CustomizeInfo->HairStyleID;
+ _worldPacket >> CustomizeInfo->FacialHairStyleID;
+ _worldPacket >> CustomizeInfo->FaceID;
+ CustomizeInfo->CharName = _worldPacket.ReadString(_worldPacket.ReadBits(6));
+}
+
+void WorldPackets::Character::CharRaceOrFactionChange::Read()
+{
+ RaceOrFactionChangeInfo.reset(new CharRaceOrFactionChangeInfo());
+
+ RaceOrFactionChangeInfo->FactionChange = _worldPacket.ReadBit();
+
+ uint32 nameLength = _worldPacket.ReadBits(6);
+
+ RaceOrFactionChangeInfo->SkinID.HasValue = _worldPacket.ReadBit();
+ RaceOrFactionChangeInfo->HairColorID.HasValue = _worldPacket.ReadBit();
+ RaceOrFactionChangeInfo->HairStyleID.HasValue = _worldPacket.ReadBit();
+ RaceOrFactionChangeInfo->FacialHairStyleID.HasValue = _worldPacket.ReadBit();
+ RaceOrFactionChangeInfo->FaceID.HasValue = _worldPacket.ReadBit();
+
+ _worldPacket >> RaceOrFactionChangeInfo->Guid;
+ _worldPacket >> RaceOrFactionChangeInfo->SexID;
+ _worldPacket >> RaceOrFactionChangeInfo->RaceID;
+
+ RaceOrFactionChangeInfo->Name = _worldPacket.ReadString(nameLength);
+
+ if (RaceOrFactionChangeInfo->SkinID.HasValue)
+ _worldPacket >> RaceOrFactionChangeInfo->SkinID.value;
+
+ if (RaceOrFactionChangeInfo->HairColorID.HasValue)
+ _worldPacket >> RaceOrFactionChangeInfo->HairColorID.value;
+
+ if (RaceOrFactionChangeInfo->HairStyleID.HasValue)
+ _worldPacket >> RaceOrFactionChangeInfo->HairStyleID.value;
+
+ if (RaceOrFactionChangeInfo->FacialHairStyleID.HasValue)
+ _worldPacket >> RaceOrFactionChangeInfo->FacialHairStyleID.value;
+
+ if (RaceOrFactionChangeInfo->FaceID.HasValue)
+ _worldPacket >> RaceOrFactionChangeInfo->FaceID.value;
+}
+
+WorldPacket const* WorldPackets::Character::CharFactionChangeResult::Write()
+{
+ _worldPacket << uint8(Result);
+ _worldPacket << Guid;
+ _worldPacket.WriteBit(Display.HasValue);
+ _worldPacket.FlushBits();
+
+ if (Display.HasValue)
+ {
+ _worldPacket.WriteBits(Display.value.Name.length(), 6);
+ _worldPacket << uint8(Display.value.SexID);
+ _worldPacket << uint8(Display.value.SkinID);
+ _worldPacket << uint8(Display.value.HairColorID);
+ _worldPacket << uint8(Display.value.HairStyleID);
+ _worldPacket << uint8(Display.value.FacialHairStyleID);
+ _worldPacket << uint8(Display.value.FaceID);
+ _worldPacket << uint8(Display.value.RaceID);
+ _worldPacket.WriteString(Display.value.Name);
+ }
+
+ return &_worldPacket;
+}
+
void WorldPackets::Character::GenerateRandomCharacterName::Read()
{
_worldPacket >> Race;
diff --git a/src/server/game/Server/Packets/CharacterPackets.h b/src/server/game/Server/Packets/CharacterPackets.h
index f2bec8e2510..017f2d6b122 100644
--- a/src/server/game/Server/Packets/CharacterPackets.h
+++ b/src/server/game/Server/Packets/CharacterPackets.h
@@ -46,23 +46,34 @@ namespace WorldPackets
struct CharacterRenameInfo
{
+ std::string NewName;
ObjectGuid Guid;
- std::string Name;
};
- struct CharacterCustomizeInfo : public CharacterRenameInfo
+ struct CharCustomizeInfo
{
- uint8 Gender = GENDER_NONE;
- uint8 Skin = 0;
- uint8 Face = 0;
- uint8 HairStyle = 0;
- uint8 HairColor = 0;
- uint8 FacialHair = 0;
+ uint8 HairStyleID = 0;
+ uint8 FaceID = 0;
+ ObjectGuid CharGUID;
+ uint8 SexID = GENDER_NONE;
+ std::string CharName;
+ uint8 HairColorID = 0;
+ uint8 FacialHairStyleID = 0;
+ uint8 SkinID = 0;
};
- struct CharacterFactionChangeInfo : public CharacterCustomizeInfo
+ struct CharRaceOrFactionChangeInfo
{
- uint8 Race = RACE_NONE;
+ Optional<uint8> HairColorID;
+ uint8 RaceID = RACE_NONE;
+ uint8 SexID = GENDER_NONE;
+ Optional<uint8> SkinID;
+ Optional<uint8> FacialHairStyleID;
+ ObjectGuid Guid;
+ bool FactionChange = false;
+ std::string Name;
+ Optional<uint8> FaceID;
+ Optional<uint8> HairStyleID;
};
struct CharacterUndeleteInfo
@@ -203,6 +214,100 @@ namespace WorldPackets
uint8 Code = 0; ///< Result code @see enum ResponseCodes
};
+ class CharacterRenameRequest final : public ClientPacket
+ {
+ public:
+ CharacterRenameRequest(WorldPacket&& packet) : ClientPacket(CMSG_CHAR_RENAME, std::move(packet)) { }
+
+ void Read() override;
+
+ /**
+ * @var std::string NewName
+ * @var ObjectGuid Guid
+ */
+ std::shared_ptr<CharacterRenameInfo> RenameInfo;
+ };
+
+ class CharacterRenameResult final : public ServerPacket
+ {
+ public:
+ CharacterRenameResult() : ServerPacket(SMSG_CHAR_RENAME, 20) { }
+
+ WorldPacket const* Write() override;
+
+ std::string Name;
+ uint8 Result = 0;
+ Optional<ObjectGuid> Guid;
+ };
+
+ class CharCustomize final : public ClientPacket
+ {
+ public:
+ CharCustomize(WorldPacket&& packet) : ClientPacket(CMSG_CHAR_CUSTOMIZE, std::move(packet)) { }
+
+ void Read() override;
+
+ /**
+ * @var uint8 HairStyleID
+ * @var uint8 FaceID
+ * @var ObjectGuid CharGUID
+ * @var uint8 SexID
+ * @var std::string CharName
+ * @var uint8 HairColorID
+ * @var uint8 FacialHairStyleID
+ * @var uint8 SkinID
+ */
+ std::shared_ptr<CharCustomizeInfo> CustomizeInfo;
+ };
+
+ /// @todo: CharCustomizeResult
+
+ class CharRaceOrFactionChange final : public ClientPacket
+ {
+ public:
+ CharRaceOrFactionChange(WorldPacket&& packet) : ClientPacket(CMSG_CHAR_RACE_OR_FACTION_CHANGE, std::move(packet)) { }
+
+ void Read() override;
+
+ /**
+ * @var Optional<uint8> HairColorID
+ * @var uint8 RaceID
+ * @var uint8 SexID
+ * @var Optional<uint8> SkinID
+ * @var Optional<uint8> FacialHairStyleID
+ * @var ObjectGuid Guid
+ * @var bool FactionChange
+ * @var std::string Name
+ * @var Optional<uint8> FaceID
+ * @var Optional<uint8> HairStyleID
+ */
+ std::shared_ptr<CharRaceOrFactionChangeInfo> RaceOrFactionChangeInfo;
+ };
+
+ class CharFactionChangeResult final : public ServerPacket
+ {
+ public:
+ struct CharFactionChangeDisplayInfo
+ {
+ std::string Name;
+ uint8 SexID = 0;
+ uint8 SkinID = 0;
+ uint8 HairColorID = 0;
+ uint8 HairStyleID = 0;
+ uint8 FacialHairStyleID = 0;
+ uint8 FaceID = 0;
+ uint8 RaceID = RACE_NONE;
+ };
+
+ CharFactionChangeResult() : ServerPacket(SMSG_CHAR_FACTION_CHANGE, 20 + sizeof(CharFactionChangeDisplayInfo)) { }
+
+ WorldPacket const* Write() override;
+
+ uint8 Result = 0; ///< @see enum ResponseCodes
+ ObjectGuid Guid;
+ Optional<CharFactionChangeDisplayInfo> Display;
+ };
+
class GenerateRandomCharacterName final : public ClientPacket
{
public:
@@ -217,7 +322,7 @@ namespace WorldPackets
class GenerateRandomCharacterNameResult final : public ServerPacket
{
public:
- GenerateRandomCharacterNameResult(): ServerPacket(SMSG_RANDOMIZE_CHAR_NAME, 20) { }
+ GenerateRandomCharacterNameResult() : ServerPacket(SMSG_RANDOMIZE_CHAR_NAME, 20) { }
WorldPacket const* Write() override;
diff --git a/src/server/game/Server/Packets/WorldStatePackets.cpp b/src/server/game/Server/Packets/WorldStatePackets.cpp
index 7d062841003..919ad11e738 100644
--- a/src/server/game/Server/Packets/WorldStatePackets.cpp
+++ b/src/server/game/Server/Packets/WorldStatePackets.cpp
@@ -32,7 +32,7 @@ WorldPacket const* WorldPackets::WorldState::InitWorldStates::Write()
for (WorldStateInfo const& wsi : Worldstates)
{
_worldPacket << uint32(wsi.VariableID);
- _worldPacket << uint32(wsi.Value);
+ _worldPacket << int32(wsi.Value);
}
return &_worldPacket;
diff --git a/src/server/game/Server/Protocol/Opcodes.cpp b/src/server/game/Server/Protocol/Opcodes.cpp
index b9611e361e8..9f9f11e8fa2 100644
--- a/src/server/game/Server/Protocol/Opcodes.cpp
+++ b/src/server/game/Server/Protocol/Opcodes.cpp
@@ -224,12 +224,11 @@ void OpcodeTable::Initialize()
DEFINE_OPCODE_HANDLER_OLD(CMSG_CHANNEL_VOICE_OFF, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleChannelVoiceOnOpcode );
DEFINE_OPCODE_HANDLER_OLD(CMSG_CHANNEL_VOICE_ON, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleChannelVoiceOnOpcode );
DEFINE_HANDLER(CMSG_CHAR_CREATE, STATUS_AUTHED, PROCESS_THREADUNSAFE, WorldPackets::Character::CharacterCreate, &WorldSession::HandleCharCreateOpcode);
- DEFINE_OPCODE_HANDLER_OLD(CMSG_CHAR_CUSTOMIZE, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleCharCustomize );
+ DEFINE_HANDLER(CMSG_CHAR_CUSTOMIZE, STATUS_AUTHED, PROCESS_THREADUNSAFE, WorldPackets::Character::CharCustomize, &WorldSession::HandleCharCustomizeOpcode);
DEFINE_HANDLER(CMSG_CHAR_DELETE, STATUS_AUTHED, PROCESS_THREADUNSAFE, WorldPackets::Character::CharacterDelete, &WorldSession::HandleCharDeleteOpcode);
DEFINE_OPCODE_HANDLER_OLD(CMSG_CHAR_ENUM, STATUS_AUTHED, PROCESS_THREADUNSAFE, &WorldSession::HandleCharEnumOpcode );
- DEFINE_OPCODE_HANDLER_OLD(CMSG_CHAR_FACTION_CHANGE, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleCharFactionOrRaceChange );
- DEFINE_OPCODE_HANDLER_OLD(CMSG_CHAR_RACE_CHANGE, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleCharFactionOrRaceChange );
- DEFINE_OPCODE_HANDLER_OLD(CMSG_CHAR_RENAME, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleCharRenameOpcode );
+ DEFINE_HANDLER(CMSG_CHAR_RACE_OR_FACTION_CHANGE, STATUS_AUTHED, PROCESS_THREADUNSAFE, WorldPackets::Character::CharRaceOrFactionChange, &WorldSession::HandleCharRaceOrFactionChangeOpcode);
+ DEFINE_HANDLER(CMSG_CHAR_RENAME, STATUS_AUTHED, PROCESS_THREADUNSAFE, WorldPackets::Character::CharacterRenameRequest, &WorldSession::HandleCharRenameOpcode);
DEFINE_OPCODE_HANDLER_OLD(CMSG_CHAR_UNDELETE_ENUM, STATUS_AUTHED, PROCESS_THREADUNSAFE, &WorldSession::HandleCharUndeleteEnumOpcode );
DEFINE_OPCODE_HANDLER_OLD(CMSG_CHAT_FILTERED, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
DEFINE_OPCODE_HANDLER_OLD(CMSG_CHAT_IGNORED, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleChatIgnoredOpcode );
@@ -441,12 +440,31 @@ void OpcodeTable::Initialize()
DEFINE_OPCODE_HANDLER_OLD(CMSG_MOVE_SET_CAN_FLY_ACK, STATUS_UNHANDLED, PROCESS_THREADSAFE, &WorldSession::HandleMoveSetCanFlyAckOpcode );
DEFINE_OPCODE_HANDLER_OLD(CMSG_MOVE_SET_CAN_TRANSITION_BETWEEN_SWIM_AND_FLY_ACK, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
DEFINE_OPCODE_HANDLER_OLD(CMSG_MOVE_SET_COLLISION_HEIGHT_ACK, STATUS_UNHANDLED, PROCESS_THREADSAFE, &WorldSession::HandleSetCollisionHeightAck );
+ DEFINE_OPCODE_HANDLER_OLD(CMSG_MOVE_SET_FACING, STATUS_UNHANDLED, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes );
+ DEFINE_OPCODE_HANDLER_OLD(CMSG_MOVE_SET_PITCH, STATUS_UNHANDLED, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes );
+ DEFINE_OPCODE_HANDLER_OLD(CMSG_MOVE_SET_RUN_MODE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ DEFINE_OPCODE_HANDLER_OLD(CMSG_MOVE_SET_WALK_MODE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
DEFINE_OPCODE_HANDLER_OLD(CMSG_MOVE_SPLINE_DONE, STATUS_UNHANDLED, PROCESS_THREADSAFE, &WorldSession::HandleMoveSplineDoneOpcode );
+ DEFINE_OPCODE_HANDLER_OLD(CMSG_MOVE_START_ASCEND, STATUS_UNHANDLED, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes );
DEFINE_OPCODE_HANDLER_OLD(CMSG_MOVE_START_BACKWARD, STATUS_UNHANDLED, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes );
+ DEFINE_OPCODE_HANDLER_OLD(CMSG_MOVE_START_DESCEND, STATUS_UNHANDLED, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes );
DEFINE_OPCODE_HANDLER_OLD(CMSG_MOVE_START_FORWARD, STATUS_UNHANDLED, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes );
+ DEFINE_OPCODE_HANDLER_OLD(CMSG_MOVE_START_PITCH_DOWN, STATUS_UNHANDLED, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes );
+ DEFINE_OPCODE_HANDLER_OLD(CMSG_MOVE_START_PITCH_UP, STATUS_UNHANDLED, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes );
+ DEFINE_OPCODE_HANDLER_OLD(CMSG_MOVE_START_STRAFE_LEFT, STATUS_UNHANDLED, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes );
+ DEFINE_OPCODE_HANDLER_OLD(CMSG_MOVE_START_STRAFE_RIGHT, STATUS_UNHANDLED, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes );
+ DEFINE_OPCODE_HANDLER_OLD(CMSG_MOVE_START_SWIM, STATUS_UNHANDLED, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes );
+ DEFINE_OPCODE_HANDLER_OLD(CMSG_MOVE_START_TURN_LEFT, STATUS_UNHANDLED, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes );
+ DEFINE_OPCODE_HANDLER_OLD(CMSG_MOVE_START_TURN_RIGHT, STATUS_UNHANDLED, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes );
DEFINE_OPCODE_HANDLER_OLD(CMSG_MOVE_STOP, STATUS_UNHANDLED, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes );
+ DEFINE_OPCODE_HANDLER_OLD(CMSG_MOVE_STOP_ASCEND, STATUS_UNHANDLED, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes );
+ DEFINE_OPCODE_HANDLER_OLD(CMSG_MOVE_STOP_PITCH, STATUS_UNHANDLED, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes );
+ DEFINE_OPCODE_HANDLER_OLD(CMSG_MOVE_STOP_STRAFE, STATUS_UNHANDLED, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes );
+ DEFINE_OPCODE_HANDLER_OLD(CMSG_MOVE_STOP_SWIM, STATUS_UNHANDLED, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes );
+ DEFINE_OPCODE_HANDLER_OLD(CMSG_MOVE_STOP_TURN, STATUS_UNHANDLED, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes );
DEFINE_OPCODE_HANDLER_OLD(CMSG_MOVE_TIME_SKIPPED, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::HandleMoveTimeSkippedOpcode );
DEFINE_OPCODE_HANDLER_OLD(CMSG_MOVE_WATER_WALK_ACK, STATUS_UNHANDLED, PROCESS_THREADSAFE, &WorldSession::HandleMoveWaterWalkAck );
+ DEFINE_OPCODE_HANDLER_OLD(CMSG_MOVE_WORLDPORT_ACK, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleMoveWorldportAckOpcode );
DEFINE_HANDLER(CMSG_NAME_QUERY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Character::QueryPlayerName, &WorldSession::HandleNameQueryOpcode);
DEFINE_OPCODE_HANDLER_OLD(CMSG_NEXT_CINEMATIC_CAMERA, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleNextCinematicCamera );
DEFINE_OPCODE_HANDLER_OLD(CMSG_NPC_TEXT_QUERY, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleNpcTextQueryOpcode );
@@ -504,6 +522,7 @@ void OpcodeTable::Initialize()
DEFINE_OPCODE_HANDLER_OLD(CMSG_QUEST_POI_QUERY, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleQuestPOIQuery );
DEFINE_OPCODE_HANDLER_OLD(CMSG_QUEST_QUERY, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleQuestQueryOpcode );
DEFINE_OPCODE_HANDLER_OLD(CMSG_QUEUED_MESSAGES_END, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ DEFINE_OPCODE_HANDLER_OLD(CMSG_RANDOM_ROLL, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleRandomRollOpcode );
DEFINE_HANDLER(CMSG_RANDOMIZE_CHAR_NAME, STATUS_AUTHED, PROCESS_THREADUNSAFE, WorldPackets::Character::GenerateRandomCharacterName, &WorldSession::HandleRandomizeCharNameOpcode);
DEFINE_OPCODE_HANDLER_OLD(CMSG_READ_ITEM, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleReadItem );
DEFINE_OPCODE_HANDLER_OLD(CMSG_REALM_SPLIT, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleRealmSplitOpcode );
@@ -635,30 +654,11 @@ void OpcodeTable::Initialize()
DEFINE_OPCODE_HANDLER_OLD(MSG_LIST_STABLED_PETS, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleListStabledPetsOpcode );
DEFINE_OPCODE_HANDLER_OLD(MSG_MINIMAP_PING, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleMinimapPingOpcode );
DEFINE_OPCODE_HANDLER_OLD(MSG_MOVE_CHARM_TELEPORT_CHEAT, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
- DEFINE_OPCODE_HANDLER_OLD(MSG_MOVE_SET_FACING, STATUS_UNHANDLED, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes );
- DEFINE_OPCODE_HANDLER_OLD(MSG_MOVE_SET_PITCH, STATUS_UNHANDLED, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes );
- DEFINE_OPCODE_HANDLER_OLD(MSG_MOVE_SET_RUN_MODE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
- DEFINE_OPCODE_HANDLER_OLD(MSG_MOVE_SET_WALK_MODE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
- DEFINE_OPCODE_HANDLER_OLD(MSG_MOVE_START_ASCEND, STATUS_UNHANDLED, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes );
- DEFINE_OPCODE_HANDLER_OLD(MSG_MOVE_START_DESCEND, STATUS_UNHANDLED, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes );
- DEFINE_OPCODE_HANDLER_OLD(MSG_MOVE_START_PITCH_DOWN, STATUS_UNHANDLED, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes );
- DEFINE_OPCODE_HANDLER_OLD(MSG_MOVE_START_PITCH_UP, STATUS_UNHANDLED, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes );
- DEFINE_OPCODE_HANDLER_OLD(MSG_MOVE_START_STRAFE_LEFT, STATUS_UNHANDLED, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes );
- DEFINE_OPCODE_HANDLER_OLD(MSG_MOVE_START_STRAFE_RIGHT, STATUS_UNHANDLED, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes );
- DEFINE_OPCODE_HANDLER_OLD(MSG_MOVE_START_SWIM, STATUS_UNHANDLED, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes );
- DEFINE_OPCODE_HANDLER_OLD(MSG_MOVE_START_TURN_LEFT, STATUS_UNHANDLED, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes );
- DEFINE_OPCODE_HANDLER_OLD(MSG_MOVE_START_TURN_RIGHT, STATUS_UNHANDLED, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes );
- DEFINE_OPCODE_HANDLER_OLD(MSG_MOVE_STOP_ASCEND, STATUS_UNHANDLED, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes );
- DEFINE_OPCODE_HANDLER_OLD(MSG_MOVE_STOP_PITCH, STATUS_UNHANDLED, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes );
- DEFINE_OPCODE_HANDLER_OLD(MSG_MOVE_STOP_STRAFE, STATUS_UNHANDLED, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes );
- DEFINE_OPCODE_HANDLER_OLD(MSG_MOVE_STOP_SWIM, STATUS_UNHANDLED, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes );
- DEFINE_OPCODE_HANDLER_OLD(MSG_MOVE_STOP_TURN, STATUS_UNHANDLED, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes );
DEFINE_OPCODE_HANDLER_OLD(MSG_MOVE_TELEPORT, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
DEFINE_OPCODE_HANDLER_OLD(MSG_MOVE_TELEPORT_ACK, STATUS_UNHANDLED, PROCESS_THREADSAFE, &WorldSession::HandleMoveTeleportAck );
DEFINE_OPCODE_HANDLER_OLD(MSG_MOVE_TELEPORT_CHEAT, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
DEFINE_OPCODE_HANDLER_OLD(MSG_MOVE_TIME_SKIPPED, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
DEFINE_OPCODE_HANDLER_OLD(MSG_MOVE_TOGGLE_COLLISION_CHEAT, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
- DEFINE_OPCODE_HANDLER_OLD(MSG_MOVE_WORLDPORT_ACK, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleMoveWorldportAckOpcode );
DEFINE_OPCODE_HANDLER_OLD(MSG_NOTIFY_PARTY_SQUELCH, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
DEFINE_OPCODE_HANDLER_OLD(MSG_PARTY_ASSIGNMENT, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandlePartyAssignmentOpcode );
DEFINE_OPCODE_HANDLER_OLD(MSG_PETITION_DECLINE, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandlePetitionDeclineOpcode );
@@ -797,10 +797,11 @@ void OpcodeTable::Initialize()
DEFINE_SERVER_OPCODE_HANDLER(SMSG_CHARACTER_LOGIN_FAILED, STATUS_UNHANDLED);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_CHAR_CREATE, STATUS_NEVER);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_CHAR_CUSTOMIZE, STATUS_UNHANDLED);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_CHAR_CUSTOMIZE_RESULT, STATUS_UNHANDLED);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_CHAR_DELETE, STATUS_NEVER);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_CHAR_ENUM, STATUS_NEVER);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_CHAR_FACTION_CHANGE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_CHAR_RENAME, STATUS_UNHANDLED);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_CHAR_FACTION_CHANGE, STATUS_NEVER);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_CHAR_RENAME, STATUS_NEVER);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_CHAT_IGNORED_ACCOUNT_MUTED, STATUS_UNHANDLED);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_CHAT_NOT_IN_PARTY, STATUS_UNHANDLED);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_CHAT_PLAYER_AMBIGUOUS, STATUS_UNHANDLED);
@@ -1073,6 +1074,8 @@ void OpcodeTable::Initialize()
DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_COLLISION_DISABLE, STATUS_UNHANDLED);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_COLLISION_ENABLE, STATUS_UNHANDLED);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_FEATHER_FALL, STATUS_UNHANDLED);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_FORCE_RUN_SPEED_CHANGE, STATUS_UNHANDLED);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_FORCE_SWIM_SPEED_CHANGE, STATUS_UNHANDLED);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_GRAVITY_DISABLE, STATUS_UNHANDLED);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_GRAVITY_ENABLE, STATUS_UNHANDLED);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_KNOCK_BACK, STATUS_UNHANDLED);
diff --git a/src/server/game/Server/Protocol/Opcodes.h b/src/server/game/Server/Protocol/Opcodes.h
index a77793ce6dd..c5e92afa690 100644
--- a/src/server/game/Server/Protocol/Opcodes.h
+++ b/src/server/game/Server/Protocol/Opcodes.h
@@ -45,8 +45,8 @@ enum OpcodeClient : uint32
{
CMSG_ACCEPT_LEVEL_GRANT = 0xBADD,
CMSG_ACCEPT_TRADE = 0xBADD,
- CMSG_ACTIVATETAXI = 0xBADD,
- CMSG_ACTIVATETAXIEXPRESS = 0xBADD,
+ CMSG_ACTIVATETAXI = 0x0311,
+ CMSG_ACTIVATETAXIEXPRESS = 0x1B52,
CMSG_ADDON_REGISTERED_PREFIXES = 0x03F4,
CMSG_ADD_FRIEND = 0x0DB9,
CMSG_ADD_IGNORE = 0x1321,
@@ -66,8 +66,8 @@ enum OpcodeClient : uint32
CMSG_ARENA_TEAM_QUERY = 0xBADD,
CMSG_ARENA_TEAM_REMOVE = 0xBADD,
CMSG_ARENA_TEAM_ROSTER = 0xBADD,
- CMSG_ATTACKSTOP = 0xBADD,
- CMSG_ATTACKSWING = 0xBADD,
+ CMSG_ATTACKSTOP = 0x065B,
+ CMSG_ATTACKSWING = 0x1E9B,
CMSG_AUCTION_HELLO = 0x13EA,
CMSG_AUCTION_LIST_BIDDER_ITEMS = 0xBADD,
CMSG_AUCTION_LIST_ITEMS = 0xBADD,
@@ -108,12 +108,12 @@ enum OpcodeClient : uint32
CMSG_BATTLE_PAY_GET_PURCHASE_LIST_QUERY = 0x120C,
CMSG_BATTLE_PET_NAME_QUERY = 0x041C,
CMSG_BEGIN_TRADE = 0xBADD,
- CMSG_BINDER_ACTIVATE = 0xBADD,
+ CMSG_BINDER_ACTIVATE = 0x02F3,
CMSG_BOT_DETECTED2 = 0xBADD,
CMSG_BUG = 0xBADD,
CMSG_BUSY_TRADE = 0xBADD,
- CMSG_BUYBACK_ITEM = 0xBADD,
- CMSG_BUY_BANK_SLOT = 0xBADD,
+ CMSG_BUYBACK_ITEM = 0x02D3,
+ CMSG_BUY_BANK_SLOT = 0x0A25,
CMSG_BUY_ITEM = 0xBADD,
CMSG_CALENDAR_ADD_EVENT = 0xBADD,
CMSG_CALENDAR_ARENA_TEAM = 0xBADD,
@@ -167,12 +167,11 @@ enum OpcodeClient : uint32
CMSG_CHANNEL_VOICE_OFF = 0xBADD,
CMSG_CHANNEL_VOICE_ON = 0xBADD,
CMSG_CHAR_CREATE = 0x070D,
- CMSG_CHAR_CUSTOMIZE = 0xBADD,
+ CMSG_CHAR_CUSTOMIZE = 0x072A,
CMSG_CHAR_DELETE = 0x030E,
CMSG_CHAR_ENUM = 0x0918,
- CMSG_CHAR_FACTION_CHANGE = 0xBADD,
- CMSG_CHAR_RACE_CHANGE = 0xBADD,
- CMSG_CHAR_RENAME = 0xBADD,
+ CMSG_CHAR_RACE_OR_FACTION_CHANGE = 0x1209,
+ CMSG_CHAR_RENAME = 0x038B,
CMSG_CHAR_UNDELETE_ENUM = 0x0F2D,
CMSG_CHAT_FILTERED = 0xBADD,
CMSG_CHAT_IGNORED = 0xBADD,
@@ -202,14 +201,14 @@ enum OpcodeClient : uint32
CMSG_DEL_IGNORE = 0x033D,
CMSG_DEL_MUTE = 0x0128,
CMSG_DEL_VOICE_IGNORE = 0xBADD,
- CMSG_DESTROY_ITEM = 0xBADD,
+ CMSG_DESTROY_ITEM = 0x01EE,
CMSG_DISMISS_CONTROLLED_VEHICLE = 0xBADD,
CMSG_DISMISS_CRITTER = 0xBADD,
CMSG_DUEL_ACCEPTED = 0xBADD,
CMSG_DUEL_CANCELLED = 0xBADD,
CMSG_EJECT_PASSENGER = 0xBADD,
CMSG_EMOTE = 0xBADD,
- CMSG_ENABLETAXI = 0xBADD,
+ CMSG_ENABLETAXI = 0x00D2,
CMSG_ENABLE_NAGLE = 0x0460,
CMSG_EQUIPMENT_SET_DELETE = 0xBADD,
CMSG_EQUIPMENT_SET_SAVE = 0x1B54,
@@ -219,8 +218,8 @@ enum OpcodeClient : uint32
CMSG_FORCE_MOVE_ROOT_ACK = 0x0B73,
CMSG_FORCE_MOVE_UNROOT_ACK = 0xBADD,
CMSG_GAMEOBJECT_QUERY = 0x03AE,
- CMSG_GAMEOBJ_REPORT_USE = 0x082E,
- CMSG_GAMEOBJ_USE = 0xBADD,
+ CMSG_GAMEOBJ_REPORT_USE = 0x0B19,
+ CMSG_GAMEOBJ_USE = 0x082E,
CMSG_GAMESPEED_SET = 0xBADD,
CMSG_GAMETIME_SET = 0xBADD,
CMSG_GETDEATHBINDZONE = 0xBADD,
@@ -287,13 +286,13 @@ enum OpcodeClient : uint32
CMSG_GUILD_PROMOTE = 0xBADD,
CMSG_GUILD_QUERY = 0x0930,
CMSG_GUILD_QUERY_NEWS = 0xBADD,
- CMSG_GUILD_QUERY_RANKS = 0xBADD,
+ CMSG_GUILD_QUERY_RANKS = 0x0C37,
CMSG_GUILD_REMOVE = 0xBADD,
CMSG_GUILD_REPLACE_GUILD_MASTER = 0xBADD,
CMSG_GUILD_REQUEST_CHALLENGE_UPDATE = 0xBADD,
CMSG_GUILD_REQUEST_MAX_DAILY_XP = 0xBADD,
CMSG_GUILD_REQUEST_PARTY_STATE = 0x0A8E,
- CMSG_GUILD_ROSTER = 0xBADD,
+ CMSG_GUILD_ROSTER = 0x0638,
CMSG_GUILD_SET_ACHIEVEMENT_TRACKING = 0xBADD,
CMSG_GUILD_SET_GUILD_MASTER = 0xBADD,
CMSG_GUILD_SET_NOTE = 0xBADD,
@@ -338,7 +337,7 @@ enum OpcodeClient : uint32
CMSG_LOGOUT_CANCEL = 0x03C2,
CMSG_LOGOUT_REQUEST = 0x1911,
CMSG_LOG_DISCONNECT = 0x04D5,
- CMSG_LOOT = 0xBADD,
+ CMSG_LOOT = 0x01B1,
CMSG_LOOT_CURRENCY = 0xBADD,
CMSG_LOOT_MASTER_GIVE = 0xBADD,
CMSG_LOOT_METHOD = 0xBADD,
@@ -369,7 +368,7 @@ enum OpcodeClient : uint32
CMSG_MESSAGECHAT_RAID = 0xBADD,
CMSG_MESSAGECHAT_RAID_WARNING = 0xBADD,
CMSG_MESSAGECHAT_SAY = 0x1884,
- CMSG_MESSAGECHAT_WHISPER = 0xBADD,
+ CMSG_MESSAGECHAT_WHISPER = 0x1829,
CMSG_MESSAGECHAT_YELL = 0x1161,
CMSG_MINIGAME_MOVE = 0xBADD,
CMSG_MOUNTSPECIAL_ANIM = 0xBADD,
@@ -382,9 +381,9 @@ enum OpcodeClient : uint32
CMSG_MOVE_FORCE_FLIGHT_SPEED_CHANGE_ACK = 0xBADD,
CMSG_MOVE_FORCE_PITCH_RATE_CHANGE_ACK = 0xBADD,
CMSG_MOVE_FORCE_RUN_BACK_SPEED_CHANGE_ACK = 0xBADD,
- CMSG_MOVE_FORCE_RUN_SPEED_CHANGE_ACK = 0xBADD,
+ CMSG_MOVE_FORCE_RUN_SPEED_CHANGE_ACK = 0x0B7C,
CMSG_MOVE_FORCE_SWIM_BACK_SPEED_CHANGE_ACK = 0xBADD,
- CMSG_MOVE_FORCE_SWIM_SPEED_CHANGE_ACK = 0xBADD,
+ CMSG_MOVE_FORCE_SWIM_SPEED_CHANGE_ACK = 0x008A,
CMSG_MOVE_FORCE_TURN_RATE_CHANGE_ACK = 0xBADD,
CMSG_MOVE_FORCE_WALK_SPEED_CHANGE_ACK = 0xBADD,
CMSG_MOVE_GRAVITY_DISABLE_ACK = 0x0553,
@@ -399,15 +398,34 @@ enum OpcodeClient : uint32
CMSG_MOVE_SET_CAN_FLY_ACK = 0xBADD,
CMSG_MOVE_SET_CAN_TRANSITION_BETWEEN_SWIM_AND_FLY_ACK = 0xBADD,
CMSG_MOVE_SET_COLLISION_HEIGHT_ACK = 0x0141,
+ CMSG_MOVE_SET_FACING = 0x19D2,
+ CMSG_MOVE_SET_PITCH = 0x0D92,
CMSG_MOVE_SET_RELATIVE_POSITION = 0xBADD,
+ CMSG_MOVE_SET_RUN_MODE = 0x0D51,
CMSG_MOVE_SET_VEHICLE_REC_ID_ACK = 0xBADD,
+ CMSG_MOVE_SET_WALK_MODE = 0x0544,
CMSG_MOVE_SPLINE_DONE = 0xBADD,
+ CMSG_MOVE_START_ASCEND = 0x0D41,
CMSG_MOVE_START_BACKWARD = 0x0583,
+ CMSG_MOVE_START_DESCEND = 0x0B79,
CMSG_MOVE_START_FORWARD = 0x0521,
+ CMSG_MOVE_START_PITCH_DOWN = 0x1974,
+ CMSG_MOVE_START_PITCH_UP = 0x0151,
+ CMSG_MOVE_START_STRAFE_LEFT = 0x0082,
+ CMSG_MOVE_START_STRAFE_RIGHT = 0x1151,
+ CMSG_MOVE_START_SWIM = 0x0B7A,
+ CMSG_MOVE_START_TURN_LEFT = 0x000B,
+ CMSG_MOVE_START_TURN_RIGHT = 0x0D14,
CMSG_MOVE_STOP = 0x0513,
+ CMSG_MOVE_STOP_ASCEND = 0x197C,
+ CMSG_MOVE_STOP_PITCH = 0x0503,
+ CMSG_MOVE_STOP_STRAFE = 0x01D1,
+ CMSG_MOVE_STOP_SWIM = 0x097C,
+ CMSG_MOVE_STOP_TURN = 0x0964,
CMSG_MOVE_TIME_SKIPPED = 0x19C2,
CMSG_MOVE_TOGGLE_COLLISION_ACK = 0xBADD,
CMSG_MOVE_WATER_WALK_ACK = 0xBADD,
+ CMSG_MOVE_WORLDPORT_ACK = 0x0938,
CMSG_NAME_QUERY = 0x0B15,
CMSG_NEW_SPELL_SLOT = 0xBADD,
CMSG_NEXT_CINEMATIC_CAMERA = 0xBADD,
@@ -429,7 +447,7 @@ enum OpcodeClient : uint32
CMSG_PET_ABANDON = 0xBADD,
CMSG_PET_ACTION = 0x133A,
CMSG_PET_CANCEL_AURA = 0xBADD,
- CMSG_PET_CAST_SPELL = 0xBADD,
+ CMSG_PET_CAST_SPELL = 0x0286,
CMSG_PET_LEARN_TALENT = 0xBADD,
CMSG_PET_NAME_CACHE = 0xBADD,
CMSG_PET_NAME_QUERY = 0x1433,
@@ -472,13 +490,14 @@ enum OpcodeClient : uint32
CMSG_QUEST_POI_QUERY = 0x0BD9,
CMSG_QUEST_QUERY = 0x09A6,
CMSG_QUEUED_MESSAGES_END = 0x04DF,
+ CMSG_RANDOM_ROLL = 0x12AA,
CMSG_RANDOMIZE_CHAR_NAME = 0x1981,
CMSG_READ_ITEM = 0xBADD,
CMSG_REALM_SPLIT = 0xBADD,
CMSG_RECLAIM_CORPSE = 0xBADD,
CMSG_REFORGE_ITEM = 0xBADD,
CMSG_REORDER_CHARACTERS = 0x0DAA,
- CMSG_REPAIR_ITEM = 0xBADD,
+ CMSG_REPAIR_ITEM = 0x0B54,
CMSG_REPLACE_ACCOUNT_DATA = 0xBADD,
CMSG_REPOP_REQUEST = 0xBADD,
CMSG_REPORT_PVP_AFK = 0xBADD,
@@ -502,14 +521,14 @@ enum OpcodeClient : uint32
CMSG_RESET_FACTION_CHEAT = 0xBADD,
CMSG_RESET_INSTANCES = 0xBADD,
CMSG_RESURRECT_RESPONSE = 0xBADD,
- CMSG_RETURN_TO_GRAVEYARD = 0xBADD,
+ CMSG_RETURN_TO_GRAVEYARD = 0x12EA,
CMSG_ROLE_POLL_BEGIN = 0xBADD,
CMSG_SAVE_CUF_PROFILES = 0x0053,
CMSG_SAVE_PLAYER = 0xBADD,
CMSG_SEARCH_LFG_JOIN = 0xBADD,
CMSG_SEARCH_LFG_LEAVE = 0xBADD,
CMSG_SELF_RES = 0xBADD,
- CMSG_SELL_ITEM = 0xBADD,
+ CMSG_SELL_ITEM = 0x0351,
CMSG_SEND_MAIL = 0x0910,
CMSG_SEND_SOR_REQUEST_VIA_ADDRESS = 0xBADD,
CMSG_SEND_SOR_REQUEST_VIA_BNET_ACCOUNT_ID = 0xBADD,
@@ -517,7 +536,7 @@ enum OpcodeClient : uint32
CMSG_SETDEATHBINDPOINT = 0xBADD,
CMSG_SETSHEATHED = 0xBADD,
CMSG_SET_ACTIONBAR_TOGGLES = 0xBADD,
- CMSG_SET_ACTION_BUTTON = 0xBADD,
+ CMSG_SET_ACTION_BUTTON = 0x0599,
CMSG_SET_ACTIVE_MOVER = 0xBADD,
CMSG_SET_ACTIVE_VOICE_CHANNEL = 0xBADD,
CMSG_SET_ALLOW_LOW_LEVEL_RAID1 = 0xBADD,
@@ -579,8 +598,8 @@ enum OpcodeClient : uint32
CMSG_TIME_SYNC_RESP_FAILED = 0xBADD,
CMSG_TOGGLE_PVP = 0xBADD,
CMSG_TOTEM_DESTROYED = 0xBADD,
- CMSG_TRAINER_BUY_SPELL = 0xBADD,
- CMSG_TRAINER_LIST = 0xBADD,
+ CMSG_TRAINER_BUY_SPELL = 0x0A28,
+ CMSG_TRAINER_LIST = 0x0A2E,
CMSG_TRANSMOGRIFY_ITEMS = 0x0A85,
CMSG_TRIGGER_CINEMATIC_CHEAT = 0xBADD,
CMSG_TURN_IN_PETITION = 0xBADD,
@@ -590,19 +609,19 @@ enum OpcodeClient : uint32
CMSG_UNACCEPT_TRADE = 0xBADD,
CMSG_UNDELETE_CHARACTER = 0x0D99,
CMSG_UNDELETE_COOLDOWN_STATUS_QUERY = 0x19A9,
- CMSG_UNLEARN_SKILL = 0xBADD,
+ CMSG_UNLEARN_SKILL = 0x0A26,
CMSG_UNLEARN_SPECIALIZATION = 0xBADD,
CMSG_UNREGISTER_ALL_ADDON_PREFIXES = 0xBADD,
CMSG_UPDATE_ACCOUNT_DATA = 0x12A1,
CMSG_UPDATE_MISSILE_TRAJECTORY = 0xBADD,
CMSG_UPDATE_PROJECTILE_POSITION = 0xBADD,
CMSG_USED_FOLLOW = 0xBADD,
- CMSG_USE_ITEM = 0xBADD,
+ CMSG_USE_ITEM = 0x08B6,
CMSG_VIOLENCE_LEVEL = 0x098D,
CMSG_VOICE_SESSION_ENABLE = 0xBADD,
CMSG_VOID_STORAGE_QUERY = 0x019E,
CMSG_VOID_STORAGE_TRANSFER = 0x0463,
- CMSG_VOID_STORAGE_UNLOCK = 0xBADD,
+ CMSG_VOID_STORAGE_UNLOCK = 0x13BB,
CMSG_VOID_SWAP_ITEM = 0x0619,
CMSG_WARDEN_DATA = 0x0BA1,
CMSG_WARGAME_ACCEPT = 0xBADD,
@@ -622,33 +641,14 @@ enum OpcodeClient : uint32
MSG_MINIMAP_PING = 0xBADD,
MSG_MOVE_CHARM_TELEPORT_CHEAT = 0xBADD,
MSG_MOVE_SET_ALL_SPEED_CHEAT = 0xBADD,
- MSG_MOVE_SET_COLLISION_HEIGHT = 0xBADD,
- MSG_MOVE_SET_FACING = 0xBADD,
MSG_MOVE_SET_FLIGHT_SPEED_CHEAT = 0xBADD,
- MSG_MOVE_SET_PITCH = 0xBADD,
MSG_MOVE_SET_RAW_POSITION_ACK = 0xBADD,
MSG_MOVE_SET_RUN_BACK_SPEED_CHEAT = 0xBADD,
- MSG_MOVE_SET_RUN_MODE = 0xBADD,
MSG_MOVE_SET_RUN_SPEED_CHEAT = 0xBADD,
MSG_MOVE_SET_SWIM_BACK_SPEED_CHEAT = 0xBADD,
MSG_MOVE_SET_SWIM_SPEED_CHEAT = 0xBADD,
MSG_MOVE_SET_TURN_RATE_CHEAT = 0xBADD,
- MSG_MOVE_SET_WALK_MODE = 0xBADD,
MSG_MOVE_SET_WALK_SPEED_CHEAT = 0xBADD,
- MSG_MOVE_START_ASCEND = 0xBADD,
- MSG_MOVE_START_DESCEND = 0xBADD,
- MSG_MOVE_START_PITCH_DOWN = 0xBADD,
- MSG_MOVE_START_PITCH_UP = 0xBADD,
- MSG_MOVE_START_STRAFE_LEFT = 0xBADD,
- MSG_MOVE_START_STRAFE_RIGHT = 0xBADD,
- MSG_MOVE_START_SWIM = 0xBADD,
- MSG_MOVE_START_TURN_LEFT = 0xBADD,
- MSG_MOVE_START_TURN_RIGHT = 0xBADD,
- MSG_MOVE_STOP_ASCEND = 0xBADD,
- MSG_MOVE_STOP_PITCH = 0xBADD,
- MSG_MOVE_STOP_STRAFE = 0xBADD,
- MSG_MOVE_STOP_SWIM = 0xBADD,
- MSG_MOVE_STOP_TURN = 0xBADD,
MSG_MOVE_TELEPORT = 0xBADD,
MSG_MOVE_TELEPORT_ACK = 0xBADD,
MSG_MOVE_TELEPORT_CHEAT = 0xBADD,
@@ -657,7 +657,6 @@ enum OpcodeClient : uint32
MSG_MOVE_TOGGLE_FALL_LOGGING = 0xBADD,
MSG_MOVE_TOGGLE_LOGGING = 0xBADD,
MSG_MOVE_UPDATE_MOUSE = 0xBADD,
- MSG_MOVE_WORLDPORT_ACK = 0xBADD,
MSG_NOTIFY_PARTY_SQUELCH = 0xBADD,
MSG_PARTY_ASSIGNMENT = 0xBADD,
MSG_PETITION_DECLINE = 0xBADD,
@@ -800,11 +799,12 @@ enum OpcodeServer : uint32
SMSG_CHANNEL_UPDATE = 0x19DB,
SMSG_CHARACTER_LOGIN_FAILED = 0xBADD,
SMSG_CHAR_CREATE = 0x0107,
- SMSG_CHAR_CUSTOMIZE = 0xBADD,
+ SMSG_CHAR_CUSTOMIZE = 0x1932,
+ SMSG_CHAR_CUSTOMIZE_RESULT = 0x0BAA,
SMSG_CHAR_DELETE = 0x0BC4,
SMSG_CHAR_ENUM = 0x05AF,
- SMSG_CHAR_FACTION_CHANGE = 0xBADD,
- SMSG_CHAR_RENAME = 0xBADD,
+ SMSG_CHAR_FACTION_CHANGE = 0x0810,
+ SMSG_CHAR_RENAME = 0x0D89,
SMSG_CHAT_IGNORED_ACCOUNT_MUTED = 0xBADD,
SMSG_CHAT_NOT_IN_PARTY = 0xBADD,
SMSG_CHAT_PLAYER_AMBIGUOUS = 0xBADD,
@@ -1100,6 +1100,8 @@ enum OpcodeServer : uint32
SMSG_MOVE_COLLISION_DISABLE = 0xBADD,
SMSG_MOVE_COLLISION_ENABLE = 0xBADD,
SMSG_MOVE_FEATHER_FALL = 0xBADD,
+ SMSG_MOVE_FORCE_RUN_SPEED_CHANGE = 0x08F5,
+ SMSG_MOVE_FORCE_SWIM_SPEED_CHANGE = 0x061A,
SMSG_MOVE_GRAVITY_DISABLE = 0x02C6,
SMSG_MOVE_GRAVITY_ENABLE = 0xBADD,
SMSG_MOVE_KNOCK_BACK = 0xBADD,
@@ -1200,7 +1202,7 @@ enum OpcodeServer : uint32
SMSG_PLAY_ONE_SHOT_ANIM_KIT = 0xBADD,
SMSG_PLAY_SOUND = 0x02D2,
SMSG_PLAY_SPELL_VISUAL = 0xBADD,
- SMSG_PLAY_SPELL_VISUAL_KIT = 0xBADD,
+ SMSG_PLAY_SPELL_VISUAL_KIT = 0x0171,
SMSG_PLAY_TIME_WARNING = 0xBADD,
SMSG_PONG = 0x17CA,
SMSG_POWER_UPDATE = 0x0B27,
@@ -1258,7 +1260,7 @@ enum OpcodeServer : uint32
SMSG_REQUEST_CEMETERY_LIST_RESPONSE = 0xBADD,
SMSG_REQUEST_PVP_REWARDS_RESPONSE = 0xBADD,
SMSG_RESEARCH_COMPLETE = 0xBADD,
- SMSG_RESEARCH_SETUP_HISTORY = 0xBADD,
+ SMSG_RESEARCH_SETUP_HISTORY = 0x0A25,
SMSG_RESET_COMPRESSION_CONTEXT = 0xBADD,
SMSG_RESET_FAILED_NOTIFY = 0xBADD,
SMSG_RESISTLOG = 0xBADD,
@@ -1302,7 +1304,7 @@ enum OpcodeServer : uint32
SMSG_SOCKET_GEMS_RESULT = 0xBADD,
SMSG_SOR_START_EXPERIENCE_INCOMPLETE = 0xBADD,
SMSG_SPELLBREAKLOG = 0xBADD,
- SMSG_SPELLDAMAGESHIELD = 0xBADD,
+ SMSG_SPELLDAMAGESHIELD = 0x188A,
SMSG_SPELLDISPELLOG = 0xBADD,
SMSG_SPELLENERGIZELOG = 0x137C,
SMSG_SPELLHEALLOG = 0x0114,
@@ -1372,7 +1374,7 @@ enum OpcodeServer : uint32
SMSG_TEXT_EMOTE = 0x0383,
SMSG_THREAT_CLEAR = 0xBADD,
SMSG_THREAT_REMOVE = 0xBADD,
- SMSG_THREAT_UPDATE = 0xBADD,
+ SMSG_THREAT_UPDATE = 0x03A9,
SMSG_TIME_ADJUSTMENT = 0xBADD,
SMSG_TIME_SYNC_REQ = 0x03B1,
SMSG_TITLE_EARNED = 0xBADD,
diff --git a/src/server/game/Server/WorldSession.cpp b/src/server/game/Server/WorldSession.cpp
index c0f97733d33..4dcd2430642 100644
--- a/src/server/game/Server/WorldSession.cpp
+++ b/src/server/game/Server/WorldSession.cpp
@@ -939,7 +939,6 @@ void WorldSession::InitializeQueryCallbackParameters()
{
// Callback parameters that have pointers in them should be properly
// initialized to nullptr here.
- _charRenameCallback.SetParam(nullptr);
}
void WorldSession::ProcessQueryCallbacks()
@@ -966,6 +965,22 @@ void WorldSession::ProcessQueryCallbacks()
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)
{
@@ -986,9 +1001,7 @@ void WorldSession::ProcessQueryCallbacks()
if (_charRenameCallback.IsReady())
{
_charRenameCallback.GetResult(result);
- WorldPackets::Character::CharacterRenameInfo* renameInfo = _charRenameCallback.GetParam();
- HandleCharRenameCallBack(result, renameInfo);
- delete renameInfo;
+ HandleCharRenameCallBack(result, _charRenameCallback.GetParam().get());
_charRenameCallback.Reset();
}
diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h
index ec791a52ca6..7be4efbc46b 100644
--- a/src/server/game/Server/WorldSession.h
+++ b/src/server/game/Server/WorldSession.h
@@ -77,12 +77,15 @@ namespace WorldPackets
{
struct CharacterCreateInfo;
struct CharacterRenameInfo;
- struct CharacterCustomizeInfo;
- struct CharacterFactionChangeInfo;
+ struct CharCustomizeInfo;
+ struct CharRaceOrFactionChangeInfo;
struct CharacterUndeleteInfo;
class CharacterCreate;
class CharacterDelete;
+ class CharacterRenameRequest;
+ class CharCustomize;
+ class CharRaceOrFactionChange;
class GenerateRandomCharacterName;
class ReorderCharacters;
class UndeleteCharacter;
@@ -455,11 +458,14 @@ class WorldSession
void HandleContinuePlayerLogin();
void HandleLoadScreenOpcode(WorldPackets::Character::LoadingScreenNotify& loadingScreenNotify);
void HandlePlayerLogin(LoginQueryHolder * holder);
- void HandleCharRenameOpcode(WorldPacket& recvData);
- void HandleCharRenameCallBack(PreparedQueryResult result, WorldPackets::Character::CharacterRenameInfo const* renameInfo);
+ void HandleCharRenameOpcode(WorldPackets::Character::CharacterRenameRequest& request);
+ void HandleCharRenameCallBack(PreparedQueryResult result, WorldPackets::Character::CharacterRenameInfo* renameInfo);
void HandleSetPlayerDeclinedNames(WorldPacket& recvData);
void HandleAlterAppearance(WorldPacket& recvData);
- void HandleCharFactionOrRaceChange(WorldPacket& recvData);
+ void HandleCharCustomizeOpcode(WorldPackets::Character::CharCustomize& packet);
+ void HandleCharCustomizeCallback(PreparedQueryResult result, WorldPackets::Character::CharCustomizeInfo* customizeInfo);
+ void HandleCharRaceOrFactionChangeOpcode(WorldPackets::Character::CharRaceOrFactionChange& packet);
+ void HandleCharRaceOrFactionChangeCallback(PreparedQueryResult result, WorldPackets::Character::CharRaceOrFactionChangeInfo* factionChangeInfo);
void HandleRandomizeCharNameOpcode(WorldPackets::Character::GenerateRandomCharacterName& packet);
void HandleReorderCharacters(WorldPackets::Character::ReorderCharacters& reorderChars);
void HandleOpeningCinematic(WorldPacket& recvData);
@@ -470,9 +476,9 @@ class WorldSession
void SendCharCreate(ResponseCodes result);
void SendCharDelete(ResponseCodes result);
- void SendCharRename(ResponseCodes result, WorldPackets::Character::CharacterRenameInfo const& renameInfo);
- void SendCharCustomize(ResponseCodes result, WorldPackets::Character::CharacterCustomizeInfo const& customizeInfo);
- void SendCharFactionChange(ResponseCodes result, WorldPackets::Character::CharacterFactionChangeInfo const& factionChangeInfo);
+ void SendCharRename(ResponseCodes result, WorldPackets::Character::CharacterRenameInfo const* renameInfo);
+ void SendCharCustomize(ResponseCodes result, WorldPackets::Character::CharCustomizeInfo const* customizeInfo);
+ void SendCharFactionChange(ResponseCodes result, WorldPackets::Character::CharRaceOrFactionChangeInfo const* factionChangeInfo);
void SendSetPlayerDeclinedNamesResult(DeclinedNameResult result, ObjectGuid guid);
void SendBarberShopResult(BarberShopResult result);
void SendUndeleteCooldownStatusResponse(uint32 currentCooldown, uint32 maxCooldown);
@@ -1009,7 +1015,6 @@ class WorldSession
void HandleSpellClick(WorldPacket& recvData);
void HandleMirrorImageDataRequest(WorldPacket& recvData);
void HandleRemoveGlyph(WorldPacket& recvData);
- void HandleCharCustomize(WorldPacket& recvData);
void HandleQueryInspectAchievements(WorldPacket& recvData);
void HandleGuildAchievementProgressQuery(WorldPacket& recvData);
void HandleEquipmentSetSave(WorldPacket& recvData);
@@ -1045,7 +1050,9 @@ class WorldSession
QueryCallback<PreparedQueryResult, uint32> _stableSwapCallback;
QueryCallback<PreparedQueryResult, ObjectGuid> _sendStabledPetCallback;
QueryCallback<PreparedQueryResult, std::shared_ptr<WorldPackets::Character::CharacterCreateInfo>, true> _charCreateCallback;
- QueryCallback<PreparedQueryResult, WorldPackets::Character::CharacterRenameInfo*> _charRenameCallback;
+ 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;
diff --git a/src/server/scripts/Commands/cs_character.cpp b/src/server/scripts/Commands/cs_character.cpp
index ec435e0bb2f..7bd2775e6c6 100644
--- a/src/server/scripts/Commands/cs_character.cpp
+++ b/src/server/scripts/Commands/cs_character.cpp
@@ -367,7 +367,7 @@ public:
}
// Remove declined name from db
- stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_DECLINED_NAME);
+ stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_DECLINED_NAME);
stmt->setUInt64(0, targetGuid.GetCounter());
CharacterDatabase.Execute(stmt);
diff --git a/src/server/shared/Database/Implementation/CharacterDatabase.cpp b/src/server/shared/Database/Implementation/CharacterDatabase.cpp
index 90b662cea5c..572230a6071 100644
--- a/src/server/shared/Database/Implementation/CharacterDatabase.cpp
+++ b/src/server/shared/Database/Implementation/CharacterDatabase.cpp
@@ -60,7 +60,7 @@ void CharacterDatabaseConnection::DoPrepareStatements()
"cb.guid, c.slot, cd.genitive FROM characters AS c LEFT JOIN character_pet AS cp ON c.guid = cp.owner AND cp.slot = ? "
"LEFT JOIN character_declinedname AS cd ON c.guid = cd.guid LEFT JOIN guild_member AS gm ON c.guid = gm.guid "
"LEFT JOIN character_banned AS cb ON c.guid = cb.guid AND cb.active = 1 WHERE c.deleteInfos_Account = ? AND c.deleteInfos_Name IS NOT NULL", CONNECTION_ASYNC);
- PrepareStatement(CHAR_SEL_FREE_NAME, "SELECT name FROM characters WHERE guid = ? AND account = ? AND (at_login & ?) = ? AND NOT EXISTS (SELECT NULL FROM characters WHERE name = ?)", CONNECTION_ASYNC);
+ PrepareStatement(CHAR_SEL_FREE_NAME, "SELECT name, at_login FROM characters WHERE guid = ? AND NOT EXISTS (SELECT NULL FROM characters WHERE name = ?)", CONNECTION_ASYNC);
PrepareStatement(CHAR_SEL_GUID_RACE_ACC_BY_NAME, "SELECT guid, race, account FROM characters WHERE name = ?", CONNECTION_BOTH);
PrepareStatement(CHAR_SEL_CHAR_RACE, "SELECT race FROM characters WHERE guid = ?", CONNECTION_SYNCH);
PrepareStatement(CHAR_SEL_CHAR_LEVEL, "SELECT level FROM characters WHERE guid = ?", CONNECTION_SYNCH);
@@ -173,9 +173,7 @@ void CharacterDatabaseConnection::DoPrepareStatements()
PrepareStatement(CHAR_SEL_CHARACTER_NAME, "SELECT name FROM characters WHERE guid = ?", CONNECTION_SYNCH);
PrepareStatement(CHAR_SEL_MATCH_MAKER_RATING, "SELECT matchMakerRating FROM character_arena_stats WHERE guid = ? AND slot = ?", CONNECTION_SYNCH);
PrepareStatement(CHAR_SEL_CHARACTER_COUNT, "SELECT account, COUNT(guid) FROM characters WHERE account = ? GROUP BY account", CONNECTION_ASYNC);
- PrepareStatement(CHAR_UPD_NAME, "UPDATE characters set name = ?, at_login = at_login & ~ ? WHERE guid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_UPD_NAME_BY_GUID, "UPDATE characters SET name = ? WHERE guid = ?", CONNECTION_ASYNC);
- PrepareStatement(CHAR_DEL_DECLINED_NAME, "DELETE FROM character_declinedname WHERE guid = ?", CONNECTION_ASYNC);
// Guild handling
// 0: uint32, 1: string, 2: uint32, 3: string, 4: string, 5: uint64, 6-10: uint32, 11: uint64
@@ -425,7 +423,7 @@ void CharacterDatabaseConnection::DoPrepareStatements()
PrepareStatement(CHAR_UPD_INSTANCE_RESETTIME, "UPDATE instance SET resettime = ? WHERE id = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_UPD_GLOBAL_INSTANCE_RESETTIME, "UPDATE instance_reset SET resettime = ? WHERE mapid = ? AND difficulty = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_UPD_CHAR_ONLINE, "UPDATE characters SET online = 1 WHERE guid = ?", CONNECTION_ASYNC);
- PrepareStatement(CHAR_UPD_CHAR_NAME_AT_LOGIN, "UPDATE characters set name = ?, at_login = at_login & ~ ? WHERE guid = ?", CONNECTION_ASYNC);
+ PrepareStatement(CHAR_UPD_CHAR_NAME_AT_LOGIN, "UPDATE characters SET name = ?, at_login = ? WHERE guid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_UPD_WORLDSTATE, "UPDATE worldstates SET value = ? WHERE entry = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_INS_WORLDSTATE, "INSERT INTO worldstates (entry, value) VALUES (?, ?)", CONNECTION_ASYNC);
PrepareStatement(CHAR_DEL_CHAR_INSTANCE_BY_INSTANCE_GUID, "DELETE FROM character_instance WHERE guid = ? AND instance = ?", CONNECTION_ASYNC);
@@ -454,15 +452,14 @@ void CharacterDatabaseConnection::DoPrepareStatements()
PrepareStatement(CHAR_SEL_CHAR_HOMEBIND, "SELECT mapId, zoneId, posX, posY, posZ FROM character_homebind WHERE guid = ?", CONNECTION_SYNCH);
PrepareStatement(CHAR_SEL_CHAR_GUID_NAME_BY_ACC, "SELECT guid, name FROM characters WHERE account = ?", CONNECTION_SYNCH);
PrepareStatement(CHAR_SEL_POOL_QUEST_SAVE, "SELECT quest_id FROM pool_quest_save WHERE pool_id = ?", CONNECTION_SYNCH);
- PrepareStatement(CHAR_SEL_CHARACTER_AT_LOGIN, "SELECT at_login FROM characters WHERE guid = ?", CONNECTION_SYNCH);
- PrepareStatement(CHAR_SEL_CHAR_AT_LOGIN_TITLES, "SELECT at_login, knownTitles FROM characters WHERE guid = ?", CONNECTION_SYNCH);
+ PrepareStatement(CHAR_SEL_CHAR_CUSTOMIZE_INFO, "SELECT name, at_login, playerBytes2 FROM characters WHERE guid = ?", CONNECTION_ASYNC);
+ PrepareStatement(CHAR_SEL_CHAR_RACE_OR_FACTION_CHANGE_INFOS, "SELECT at_login, knownTitles, playerBytes, playerBytes2 FROM characters WHERE guid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_SEL_INSTANCE, "SELECT data, completedEncounters FROM instance WHERE map = ? AND id = ?", CONNECTION_SYNCH);
PrepareStatement(CHAR_SEL_CHAR_COD_ITEM_MAIL, "SELECT id, messageType, mailTemplateId, sender, subject, body, money, has_items FROM mail WHERE receiver = ? AND has_items <> 0 AND cod <> 0", CONNECTION_SYNCH);
PrepareStatement(CHAR_SEL_CHAR_SOCIAL, "SELECT DISTINCT guid FROM character_social WHERE friend = ?", CONNECTION_SYNCH);
PrepareStatement(CHAR_SEL_CHAR_OLD_CHARS, "SELECT guid, deleteInfos_Account FROM characters WHERE deleteDate IS NOT NULL AND deleteDate < ?", CONNECTION_SYNCH);
PrepareStatement(CHAR_SEL_ARENA_TEAM_ID_BY_PLAYER_GUID, "SELECT arena_team_member.arenateamid FROM arena_team_member JOIN arena_team ON arena_team_member.arenateamid = arena_team.arenateamid WHERE guid = ? AND type = ? LIMIT 1", CONNECTION_SYNCH);
PrepareStatement(CHAR_SEL_MAIL, "SELECT id, messageType, sender, receiver, subject, body, has_items, expire_time, deliver_time, money, cod, checked, stationery, mailTemplateId FROM mail WHERE receiver = ? ORDER BY id DESC", CONNECTION_SYNCH);
- PrepareStatement(CHAR_SEL_CHAR_PLAYERBYTES2, "SELECT playerBytes2 FROM characters WHERE guid = ?", CONNECTION_SYNCH);
PrepareStatement(CHAR_DEL_CHAR_AURA_FROZEN, "DELETE FROM character_aura WHERE spell = 9454 AND guid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_SEL_CHAR_INVENTORY_COUNT_ITEM, "SELECT COUNT(itemEntry) FROM character_inventory ci INNER JOIN item_instance ii ON ii.guid = ci.item WHERE itemEntry = ?", CONNECTION_SYNCH);
PrepareStatement(CHAR_SEL_MAIL_COUNT_ITEM, "SELECT COUNT(itemEntry) FROM mail_items mi INNER JOIN item_instance ii ON ii.guid = mi.item_guid WHERE itemEntry = ?", CONNECTION_SYNCH);
@@ -500,7 +497,7 @@ void CharacterDatabaseConnection::DoPrepareStatements()
PrepareStatement(CHAR_DEL_PETITION_SIGNATURE_BY_GUID, "DELETE FROM petition_sign WHERE petitionguid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_DEL_CHAR_DECLINED_NAME, "DELETE FROM character_declinedname WHERE guid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_INS_CHAR_DECLINED_NAME, "INSERT INTO character_declinedname (guid, genitive, dative, accusative, instrumental, prepositional) VALUES (?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC);
- PrepareStatement(CHAR_UPD_FACTION_OR_RACE, "UPDATE characters SET name = ?, race = ?, at_login = at_login & ~ ? WHERE guid = ?", CONNECTION_ASYNC);
+ PrepareStatement(CHAR_UPD_CHAR_RACE, "UPDATE characters SET race = ? WHERE guid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_DEL_CHAR_SKILL_LANGUAGES, "DELETE FROM character_skills WHERE skill IN (98, 113, 759, 111, 313, 109, 115, 315, 673, 137) AND guid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_INS_CHAR_SKILL_LANGUAGE, "INSERT INTO `character_skills` (guid, skill, value, max) VALUES (?, ?, 300, 300)", CONNECTION_ASYNC);
PrepareStatement(CHAR_UPD_CHAR_TAXI_PATH, "UPDATE characters SET taxi_path = '' WHERE guid = ?", CONNECTION_ASYNC);
diff --git a/src/server/shared/Database/Implementation/CharacterDatabase.h b/src/server/shared/Database/Implementation/CharacterDatabase.h
index 6cb239ed85b..72d103aa4f8 100644
--- a/src/server/shared/Database/Implementation/CharacterDatabase.h
+++ b/src/server/shared/Database/Implementation/CharacterDatabase.h
@@ -164,9 +164,7 @@ enum CharacterDatabaseStatements
CHAR_SEL_CHARACTER_NAME,
CHAR_SEL_MATCH_MAKER_RATING,
CHAR_SEL_CHARACTER_COUNT,
- CHAR_UPD_NAME,
CHAR_UPD_NAME_BY_GUID,
- CHAR_DEL_DECLINED_NAME,
CHAR_SEL_CHARACTER_DATA_BY_GUID,
CHAR_INS_GUILD,
@@ -389,15 +387,14 @@ enum CharacterDatabaseStatements
CHAR_SEL_CHAR_HOMEBIND,
CHAR_SEL_CHAR_GUID_NAME_BY_ACC,
CHAR_SEL_POOL_QUEST_SAVE,
- CHAR_SEL_CHARACTER_AT_LOGIN,
- CHAR_SEL_CHAR_AT_LOGIN_TITLES,
+ CHAR_SEL_CHAR_CUSTOMIZE_INFO,
+ CHAR_SEL_CHAR_RACE_OR_FACTION_CHANGE_INFOS,
CHAR_SEL_INSTANCE,
CHAR_SEL_CHAR_COD_ITEM_MAIL,
CHAR_SEL_CHAR_SOCIAL,
CHAR_SEL_CHAR_OLD_CHARS,
CHAR_SEL_ARENA_TEAM_ID_BY_PLAYER_GUID,
CHAR_SEL_MAIL,
- CHAR_SEL_CHAR_PLAYERBYTES2,
CHAR_DEL_CHAR_AURA_FROZEN,
CHAR_SEL_CHAR_INVENTORY_COUNT_ITEM,
CHAR_SEL_MAIL_COUNT_ITEM,
@@ -430,7 +427,7 @@ enum CharacterDatabaseStatements
CHAR_DEL_PETITION_SIGNATURE_BY_GUID,
CHAR_DEL_CHAR_DECLINED_NAME,
CHAR_INS_CHAR_DECLINED_NAME,
- CHAR_UPD_FACTION_OR_RACE,
+ CHAR_UPD_CHAR_RACE,
CHAR_DEL_CHAR_SKILL_LANGUAGES,
CHAR_INS_CHAR_SKILL_LANGUAGE,
CHAR_UPD_CHAR_TAXI_PATH,
diff --git a/src/server/shared/Utilities/Util.h b/src/server/shared/Utilities/Util.h
index 8b70c8de41e..8a4f7325add 100644
--- a/src/server/shared/Utilities/Util.h
+++ b/src/server/shared/Utilities/Util.h
@@ -37,6 +37,18 @@ struct Optional
T value;
bool HasValue;
+
+ inline void Set(T const& v)
+ {
+ HasValue = true;
+ value = v;
+ }
+
+ inline void Clear()
+ {
+ HasValue = false;
+ value = T();
+ }
};
// Searcher for map of structs