mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-21 17:54:48 +01:00
Core/Packets: convert CMSG_ENUM_CHARACTERS and SMSG_ENUM_CHARACTERS_R… (#24)
* Core/Packets: convert CMSG_ENUM_CHARACTERS and SMSG_ENUM_CHARACTERS_RESULT to packet class * Cleanup some excessive large spaces * These entire spaces must be purged * Order members by type size and alphabetical * Change TaggedPosition into Position
This commit is contained in:
@@ -105,51 +105,6 @@
|
||||
|
||||
#define ZONE_UPDATE_INTERVAL (1*IN_MILLISECONDS)
|
||||
|
||||
enum CharacterFlags
|
||||
{
|
||||
CHARACTER_FLAG_NONE = 0x00000000,
|
||||
CHARACTER_FLAG_UNK1 = 0x00000001,
|
||||
CHARACTER_FLAG_UNK2 = 0x00000002,
|
||||
CHARACTER_LOCKED_FOR_TRANSFER = 0x00000004,
|
||||
CHARACTER_FLAG_UNK4 = 0x00000008,
|
||||
CHARACTER_FLAG_UNK5 = 0x00000010,
|
||||
CHARACTER_FLAG_UNK6 = 0x00000020,
|
||||
CHARACTER_FLAG_UNK7 = 0x00000040,
|
||||
CHARACTER_FLAG_UNK8 = 0x00000080,
|
||||
CHARACTER_FLAG_UNK9 = 0x00000100,
|
||||
CHARACTER_FLAG_UNK10 = 0x00000200,
|
||||
CHARACTER_FLAG_HIDE_HELM = 0x00000400,
|
||||
CHARACTER_FLAG_HIDE_CLOAK = 0x00000800,
|
||||
CHARACTER_FLAG_UNK13 = 0x00001000,
|
||||
CHARACTER_FLAG_GHOST = 0x00002000,
|
||||
CHARACTER_FLAG_RENAME = 0x00004000,
|
||||
CHARACTER_FLAG_UNK16 = 0x00008000,
|
||||
CHARACTER_FLAG_UNK17 = 0x00010000,
|
||||
CHARACTER_FLAG_UNK18 = 0x00020000,
|
||||
CHARACTER_FLAG_UNK19 = 0x00040000,
|
||||
CHARACTER_FLAG_UNK20 = 0x00080000,
|
||||
CHARACTER_FLAG_UNK21 = 0x00100000,
|
||||
CHARACTER_FLAG_UNK22 = 0x00200000,
|
||||
CHARACTER_FLAG_UNK23 = 0x00400000,
|
||||
CHARACTER_FLAG_UNK24 = 0x00800000,
|
||||
CHARACTER_FLAG_LOCKED_BY_BILLING = 0x01000000,
|
||||
CHARACTER_FLAG_DECLINED = 0x02000000,
|
||||
CHARACTER_FLAG_UNK27 = 0x04000000,
|
||||
CHARACTER_FLAG_UNK28 = 0x08000000,
|
||||
CHARACTER_FLAG_UNK29 = 0x10000000,
|
||||
CHARACTER_FLAG_UNK30 = 0x20000000,
|
||||
CHARACTER_FLAG_UNK31 = 0x40000000,
|
||||
CHARACTER_FLAG_UNK32 = 0x80000000
|
||||
};
|
||||
|
||||
enum CharacterCustomizeFlags
|
||||
{
|
||||
CHAR_CUSTOMIZE_FLAG_NONE = 0x00000000,
|
||||
CHAR_CUSTOMIZE_FLAG_CUSTOMIZE = 0x00000001, // name, gender, etc...
|
||||
CHAR_CUSTOMIZE_FLAG_FACTION = 0x00010000, // name, gender, faction, etc...
|
||||
CHAR_CUSTOMIZE_FLAG_RACE = 0x00100000 // name, gender, race, etc...
|
||||
};
|
||||
|
||||
// corpse reclaim times
|
||||
#define DEATH_EXPIRE_STEP (5*MINUTE)
|
||||
#define MAX_DEATH_COUNT 3
|
||||
@@ -1452,200 +1407,6 @@ void Player::setDeathState(DeathState s)
|
||||
SetUInt32Value(PLAYER_SELF_RES_SPELL, 0);
|
||||
}
|
||||
|
||||
bool Player::BuildEnumData(PreparedQueryResult result, ByteBuffer* dataBuffer, ByteBuffer* bitBuffer)
|
||||
{
|
||||
// 0 1 2 3 4 5 6 7
|
||||
// SELECT characters.guid, characters.name, characters.race, characters.class, characters.gender, characters.skin, characters.face, characters.hairStyle,
|
||||
// 8 9 10 11 12 13 14 15
|
||||
// characters.hairColor, characters.facialStyle, characters.level, characters.zone, characters.map, characters.position_x, characters.position_y, characters.position_z,
|
||||
// 16 17 18 19 20 21 22
|
||||
// guild_member.guildid, characters.playerFlags, characters.at_login, character_pet.entry, character_pet.modelid, character_pet.level, characters.data,
|
||||
// 23 24 25
|
||||
// character_banned.guid, characters.slot, character_declinedname.genitive
|
||||
|
||||
Field* fields = result->Fetch();
|
||||
|
||||
ObjectGuid guid(HighGuid::Player, fields[0].GetUInt32());
|
||||
std::string name = fields[1].GetString();
|
||||
uint8 plrRace = fields[2].GetUInt8();
|
||||
uint8 plrClass = fields[3].GetUInt8();
|
||||
uint8 gender = fields[4].GetUInt8();
|
||||
uint8 skin = fields[5].GetUInt8();
|
||||
uint8 face = fields[6].GetUInt8();
|
||||
uint8 hairStyle = fields[7].GetUInt8();
|
||||
uint8 hairColor = fields[8].GetUInt8();
|
||||
uint8 facialStyle = fields[9].GetUInt8();
|
||||
uint8 level = fields[10].GetUInt8();
|
||||
uint32 zone = fields[11].GetUInt16();
|
||||
uint32 mapId = uint32(fields[12].GetUInt16());
|
||||
float x = fields[13].GetFloat();
|
||||
float y = fields[14].GetFloat();
|
||||
float z = fields[15].GetFloat();
|
||||
uint32 guildId = fields[16].GetUInt32();
|
||||
ObjectGuid guildGuid;
|
||||
if (guildId)
|
||||
guildGuid = ObjectGuid(HighGuid::Guild, guildId);
|
||||
uint32 playerFlags = fields[17].GetUInt32();
|
||||
uint32 atLoginFlags = fields[18].GetUInt16();
|
||||
Tokenizer equipment(fields[22].GetString(), ' ');
|
||||
uint8 slot = fields[24].GetUInt8();
|
||||
|
||||
if (!ValidateAppearance(uint8(plrRace), uint8(plrClass), gender, hairStyle, hairColor, face, facialStyle, skin))
|
||||
{
|
||||
TC_LOG_ERROR("entities.player.loading", "Player %s has wrong Appearance values (Hair/Skin/Color), forcing recustomize", guid.ToString().c_str());
|
||||
|
||||
// Make sure customization always works properly - send all zeroes instead
|
||||
skin = 0, face = 0, hairStyle = 0, hairColor = 0, facialStyle = 0;
|
||||
|
||||
if (!(atLoginFlags & AT_LOGIN_CUSTOMIZE))
|
||||
{
|
||||
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_ADD_AT_LOGIN_FLAG);
|
||||
stmt->setUInt16(0, uint16(AT_LOGIN_CUSTOMIZE));
|
||||
stmt->setUInt32(1, guid);
|
||||
CharacterDatabase.Execute(stmt);
|
||||
atLoginFlags |= AT_LOGIN_CUSTOMIZE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
uint32 charFlags = 0;
|
||||
if (atLoginFlags & AT_LOGIN_RESURRECT)
|
||||
playerFlags &= ~PLAYER_FLAGS_GHOST;
|
||||
if (playerFlags & PLAYER_FLAGS_HIDE_HELM)
|
||||
charFlags |= CHARACTER_FLAG_HIDE_HELM;
|
||||
|
||||
if (playerFlags & PLAYER_FLAGS_HIDE_CLOAK)
|
||||
charFlags |= CHARACTER_FLAG_HIDE_CLOAK;
|
||||
|
||||
if (playerFlags & PLAYER_FLAGS_GHOST)
|
||||
charFlags |= CHARACTER_FLAG_GHOST;
|
||||
|
||||
if (atLoginFlags & AT_LOGIN_RENAME)
|
||||
charFlags |= CHARACTER_FLAG_RENAME;
|
||||
|
||||
if (fields[23].GetUInt32())
|
||||
charFlags |= CHARACTER_FLAG_LOCKED_BY_BILLING;
|
||||
|
||||
if (sWorld->getBoolConfig(CONFIG_DECLINED_NAMES_USED) && !fields[22].GetString().empty())
|
||||
charFlags |= CHARACTER_FLAG_DECLINED;
|
||||
|
||||
uint32 customizationFlag = 0;
|
||||
if (atLoginFlags & AT_LOGIN_CUSTOMIZE)
|
||||
customizationFlag = CHAR_CUSTOMIZE_FLAG_CUSTOMIZE;
|
||||
else if (atLoginFlags & AT_LOGIN_CHANGE_FACTION)
|
||||
customizationFlag = CHAR_CUSTOMIZE_FLAG_FACTION;
|
||||
else if (atLoginFlags & AT_LOGIN_CHANGE_RACE)
|
||||
customizationFlag = CHAR_CUSTOMIZE_FLAG_RACE;
|
||||
|
||||
uint32 petDisplayId = 0;
|
||||
uint32 petLevel = 0;
|
||||
CreatureFamily petFamily = CREATURE_FAMILY_NONE;
|
||||
// show pet at selection character in character list only for non-ghost character
|
||||
if (result && !(playerFlags & PLAYER_FLAGS_GHOST) && (plrClass == CLASS_WARLOCK || plrClass == CLASS_HUNTER || plrClass == CLASS_DEATH_KNIGHT))
|
||||
{
|
||||
uint32 entry = fields[19].GetUInt32();
|
||||
CreatureTemplate const* creatureInfo = sObjectMgr->GetCreatureTemplate(entry);
|
||||
if (creatureInfo)
|
||||
{
|
||||
petDisplayId = fields[20].GetUInt32();
|
||||
petLevel = fields[21].GetUInt16();
|
||||
petFamily = creatureInfo->family;
|
||||
}
|
||||
}
|
||||
|
||||
// Packet content flags
|
||||
bitBuffer->WriteBit(guid[3]);
|
||||
bitBuffer->WriteBit(guildGuid[1]);
|
||||
bitBuffer->WriteBit(guildGuid[7]);
|
||||
bitBuffer->WriteBit(guildGuid[2]);
|
||||
bitBuffer->WriteBits(uint32(name.length()), 7);
|
||||
bitBuffer->WriteBit(guid[4]);
|
||||
bitBuffer->WriteBit(guid[7]);
|
||||
bitBuffer->WriteBit(guildGuid[3]);
|
||||
bitBuffer->WriteBit(guid[5]);
|
||||
bitBuffer->WriteBit(guildGuid[6]);
|
||||
bitBuffer->WriteBit(guid[1]);
|
||||
bitBuffer->WriteBit(guildGuid[5]);
|
||||
bitBuffer->WriteBit(guildGuid[4]);
|
||||
bitBuffer->WriteBit(atLoginFlags & AT_LOGIN_FIRST);
|
||||
bitBuffer->WriteBit(guid[0]);
|
||||
bitBuffer->WriteBit(guid[2]);
|
||||
bitBuffer->WriteBit(guid[6]);
|
||||
bitBuffer->WriteBit(guildGuid[0]);
|
||||
|
||||
// Character data
|
||||
*dataBuffer << uint8(plrClass); // Class
|
||||
for (uint8 slot = 0; slot < INVENTORY_SLOT_BAG_END; ++slot)
|
||||
{
|
||||
uint32 visualbase = slot * 2;
|
||||
uint32 itemId = GetUInt32ValueFromArray(equipment, visualbase);
|
||||
ItemTemplate const* proto = sObjectMgr->GetItemTemplate(itemId);
|
||||
if (!proto)
|
||||
{
|
||||
*dataBuffer << uint8(0);
|
||||
*dataBuffer << uint32(0);
|
||||
*dataBuffer << uint32(0);
|
||||
continue;
|
||||
}
|
||||
|
||||
SpellItemEnchantmentEntry const* enchant = nullptr;
|
||||
uint32 enchants = GetUInt32ValueFromArray(equipment, visualbase + 1);
|
||||
for (uint8 enchantSlot = PERM_ENCHANTMENT_SLOT; enchantSlot <= TEMP_ENCHANTMENT_SLOT; ++enchantSlot)
|
||||
{
|
||||
// values stored in 2 uint16
|
||||
uint32 enchantId = 0x0000FFFF & (enchants >> enchantSlot * 16);
|
||||
if (!enchantId)
|
||||
continue;
|
||||
|
||||
enchant = sSpellItemEnchantmentStore.LookupEntry(enchantId);
|
||||
if (enchant)
|
||||
break;
|
||||
}
|
||||
|
||||
*dataBuffer << uint8(proto->InventoryType);
|
||||
*dataBuffer << uint32(proto->DisplayInfoID);
|
||||
*dataBuffer << uint32(enchant ? enchant->aura_id : 0);
|
||||
}
|
||||
|
||||
*dataBuffer << uint32(petFamily); // Pet family
|
||||
dataBuffer->WriteByteSeq(guildGuid[2]);
|
||||
*dataBuffer << uint8(slot); // List order
|
||||
*dataBuffer << uint8(hairStyle); // Hair style
|
||||
dataBuffer->WriteByteSeq(guildGuid[3]);
|
||||
*dataBuffer << uint32(petDisplayId); // Pet DisplayID
|
||||
*dataBuffer << uint32(charFlags); // Character flags
|
||||
*dataBuffer << uint8(hairColor); // Hair color
|
||||
dataBuffer->WriteByteSeq(guid[4]);
|
||||
*dataBuffer << uint32(mapId); // Map Id
|
||||
dataBuffer->WriteByteSeq(guildGuid[5]);
|
||||
*dataBuffer << float(z); // Z
|
||||
dataBuffer->WriteByteSeq(guildGuid[6]);
|
||||
*dataBuffer << uint32(petLevel); // Pet level
|
||||
dataBuffer->WriteByteSeq(guid[3]);
|
||||
*dataBuffer << float(y); // Y
|
||||
*dataBuffer << uint32(customizationFlag); // Character customization flags
|
||||
*dataBuffer << uint8(facialStyle); // Facial hair
|
||||
dataBuffer->WriteByteSeq(guid[7]);
|
||||
*dataBuffer << uint8(gender); // Gender
|
||||
dataBuffer->append(name.c_str(), name.length()); // Name
|
||||
*dataBuffer << uint8(face); // Face
|
||||
dataBuffer->WriteByteSeq(guid[0]);
|
||||
dataBuffer->WriteByteSeq(guid[2]);
|
||||
dataBuffer->WriteByteSeq(guildGuid[1]);
|
||||
dataBuffer->WriteByteSeq(guildGuid[7]);
|
||||
*dataBuffer << float(x); // X
|
||||
*dataBuffer << uint8(skin); // Skin
|
||||
*dataBuffer << uint8(plrRace); // Race
|
||||
*dataBuffer << uint8(level); // Level
|
||||
dataBuffer->WriteByteSeq(guid[6]);
|
||||
dataBuffer->WriteByteSeq(guildGuid[4]);
|
||||
dataBuffer->WriteByteSeq(guildGuid[0]);
|
||||
dataBuffer->WriteByteSeq(guid[5]);
|
||||
dataBuffer->WriteByteSeq(guid[1]);
|
||||
*dataBuffer << uint32(zone); // Zone id
|
||||
return true;
|
||||
}
|
||||
|
||||
void Player::ToggleAFK()
|
||||
{
|
||||
ToggleFlag(PLAYER_FLAGS, PLAYER_FLAGS_AFK);
|
||||
|
||||
@@ -1047,8 +1047,6 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>
|
||||
|
||||
void Update(uint32 time) override;
|
||||
|
||||
static bool BuildEnumData(PreparedQueryResult result, ByteBuffer* dataBuffer, ByteBuffer* bitBuffer);
|
||||
|
||||
bool IsImmunedToSpellEffect(SpellInfo const* spellInfo, uint32 index, Unit* caster) const override;
|
||||
|
||||
void SetInWater(bool apply);
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include "BattlenetServerManager.h"
|
||||
#include "CalendarMgr.h"
|
||||
#include "CharacterCache.h"
|
||||
#include "CharacterPackets.h"
|
||||
#include "Chat.h"
|
||||
#include "DatabaseEnv.h"
|
||||
#include "DBCStores.h"
|
||||
@@ -242,53 +243,56 @@ bool LoginQueryHolder::Initialize()
|
||||
|
||||
void WorldSession::HandleCharEnum(PreparedQueryResult result)
|
||||
{
|
||||
uint32 charCount = 0;
|
||||
ByteBuffer bitBuffer;
|
||||
ByteBuffer dataBuffer;
|
||||
WorldPackets::Character::EnumCharactersResult charEnum;
|
||||
charEnum.Success = true;
|
||||
|
||||
_legitCharacters.clear();
|
||||
|
||||
bitBuffer.WriteBits(0, 23);
|
||||
bitBuffer.WriteBit(1);
|
||||
if (result)
|
||||
{
|
||||
_legitCharacters.clear();
|
||||
|
||||
charCount = uint32(result->GetRowCount());
|
||||
bitBuffer.reserve(24 * charCount / 8);
|
||||
dataBuffer.reserve(charCount * 381);
|
||||
|
||||
bitBuffer.WriteBits(charCount, 17);
|
||||
|
||||
do
|
||||
{
|
||||
ObjectGuid guid(HighGuid::Player, (*result)[0].GetUInt32());
|
||||
charEnum.Characters.emplace_back(result->Fetch());
|
||||
|
||||
TC_LOG_INFO("network", "Loading char guid %s from account %u.", guid.ToString().c_str(), GetAccountId());
|
||||
WorldPackets::Character::EnumCharactersResult::CharacterInfo& charInfo = charEnum.Characters.back();
|
||||
|
||||
Player::BuildEnumData(result, &dataBuffer, &bitBuffer);
|
||||
TC_LOG_INFO("network", "Loading char guid %s from account %u.", charInfo.Guid.ToString().c_str(), GetAccountId());
|
||||
|
||||
// Do not allow banned characters to log in
|
||||
if (!(*result)[23].GetUInt32())
|
||||
_legitCharacters.insert(guid);
|
||||
if (!Player::ValidateAppearance(charInfo.RaceID, charInfo.ClassID, charInfo.SexID, charInfo.HairStyle, charInfo.HairColor, charInfo.FaceID, charInfo.FacialHair, charInfo.SkinID))
|
||||
{
|
||||
TC_LOG_ERROR("entities.player.loading", "Player %s has wrong Appearance values (Hair/Skin/Color), forcing recustomize", charInfo.Guid.ToString().c_str());
|
||||
|
||||
if (!sCharacterCache->HasCharacterCacheEntry(guid)) // This can happen if characters are inserted into the database manually. Core hasn't loaded name data yet.
|
||||
sCharacterCache->AddCharacterCacheEntry(guid, GetAccountId(), (*result)[1].GetString(), (*result)[4].GetUInt8(), (*result)[2].GetUInt8(), (*result)[3].GetUInt8(), (*result)[10].GetUInt8());
|
||||
// Make sure customization always works properly - send all zeroes instead
|
||||
charInfo.SkinID = 0;
|
||||
charInfo.FaceID = 0;
|
||||
charInfo.HairStyle = 0;
|
||||
charInfo.HairColor = 0;
|
||||
charInfo.FacialHair = 0;
|
||||
|
||||
} while (result->NextRow());
|
||||
if (!(charInfo.Flags2 == CHAR_CUSTOMIZE_FLAG_CUSTOMIZE))
|
||||
{
|
||||
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_ADD_AT_LOGIN_FLAG);
|
||||
stmt->setUInt16(0, uint16(AT_LOGIN_CUSTOMIZE));
|
||||
stmt->setUInt32(1, charInfo.Guid.GetCounter());
|
||||
CharacterDatabase.Execute(stmt);
|
||||
charInfo.Flags2 = CHAR_CUSTOMIZE_FLAG_CUSTOMIZE;
|
||||
}
|
||||
}
|
||||
|
||||
// Do not allow locked characters to login
|
||||
if (!(charInfo.Flags & (CHARACTER_FLAG_LOCKED_FOR_TRANSFER | CHARACTER_FLAG_LOCKED_BY_BILLING)))
|
||||
_legitCharacters.insert(charInfo.Guid);
|
||||
|
||||
if (!sCharacterCache->HasCharacterCacheEntry(charInfo.Guid)) // This can happen if characters are inserted into the database manually. Core hasn't loaded name data yet.
|
||||
sCharacterCache->AddCharacterCacheEntry(charInfo.Guid, GetAccountId(), charInfo.Name, charInfo.SexID, charInfo.RaceID, charInfo.ClassID, charInfo.ExperienceLevel);
|
||||
}
|
||||
while (result->NextRow());
|
||||
}
|
||||
else
|
||||
bitBuffer.WriteBits(0, 17);
|
||||
|
||||
bitBuffer.FlushBits();
|
||||
|
||||
WorldPacket data(SMSG_CHAR_ENUM, 7 + bitBuffer.size() + dataBuffer.size());
|
||||
data.append(bitBuffer);
|
||||
if (charCount)
|
||||
data.append(dataBuffer);
|
||||
|
||||
SendPacket(&data);
|
||||
SendPacket(charEnum.Write());
|
||||
}
|
||||
|
||||
void WorldSession::HandleCharEnumOpcode(WorldPacket& /*recvData*/)
|
||||
void WorldSession::HandleCharEnumOpcode(WorldPackets::Character::EnumCharacters& /*enumCharacters*/)
|
||||
{
|
||||
// remove expired bans
|
||||
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_EXPIRED_BANS);
|
||||
|
||||
@@ -780,6 +780,51 @@ enum SheathTypes
|
||||
|
||||
#define MAX_SHEATHETYPE 8
|
||||
|
||||
enum CharacterFlags
|
||||
{
|
||||
CHARACTER_FLAG_NONE = 0x00000000,
|
||||
CHARACTER_FLAG_UNK1 = 0x00000001,
|
||||
CHARACTER_FLAG_UNK2 = 0x00000002,
|
||||
CHARACTER_FLAG_LOCKED_FOR_TRANSFER = 0x00000004,
|
||||
CHARACTER_FLAG_UNK4 = 0x00000008,
|
||||
CHARACTER_FLAG_UNK5 = 0x00000010,
|
||||
CHARACTER_FLAG_UNK6 = 0x00000020,
|
||||
CHARACTER_FLAG_UNK7 = 0x00000040,
|
||||
CHARACTER_FLAG_UNK8 = 0x00000080,
|
||||
CHARACTER_FLAG_UNK9 = 0x00000100,
|
||||
CHARACTER_FLAG_UNK10 = 0x00000200,
|
||||
CHARACTER_FLAG_HIDE_HELM = 0x00000400,
|
||||
CHARACTER_FLAG_HIDE_CLOAK = 0x00000800,
|
||||
CHARACTER_FLAG_UNK13 = 0x00001000,
|
||||
CHARACTER_FLAG_GHOST = 0x00002000,
|
||||
CHARACTER_FLAG_RENAME = 0x00004000,
|
||||
CHARACTER_FLAG_UNK16 = 0x00008000,
|
||||
CHARACTER_FLAG_UNK17 = 0x00010000,
|
||||
CHARACTER_FLAG_UNK18 = 0x00020000,
|
||||
CHARACTER_FLAG_UNK19 = 0x00040000,
|
||||
CHARACTER_FLAG_UNK20 = 0x00080000,
|
||||
CHARACTER_FLAG_UNK21 = 0x00100000,
|
||||
CHARACTER_FLAG_UNK22 = 0x00200000,
|
||||
CHARACTER_FLAG_UNK23 = 0x00400000,
|
||||
CHARACTER_FLAG_UNK24 = 0x00800000,
|
||||
CHARACTER_FLAG_LOCKED_BY_BILLING = 0x01000000,
|
||||
CHARACTER_FLAG_DECLINED = 0x02000000,
|
||||
CHARACTER_FLAG_UNK27 = 0x04000000,
|
||||
CHARACTER_FLAG_UNK28 = 0x08000000,
|
||||
CHARACTER_FLAG_UNK29 = 0x10000000,
|
||||
CHARACTER_FLAG_UNK30 = 0x20000000,
|
||||
CHARACTER_FLAG_UNK31 = 0x40000000,
|
||||
CHARACTER_FLAG_UNK32 = 0x80000000
|
||||
};
|
||||
|
||||
enum CharacterCustomizeFlags
|
||||
{
|
||||
CHAR_CUSTOMIZE_FLAG_NONE = 0x00000000,
|
||||
CHAR_CUSTOMIZE_FLAG_CUSTOMIZE = 0x00000001, // name, gender, etc...
|
||||
CHAR_CUSTOMIZE_FLAG_FACTION = 0x00010000, // name, gender, faction, etc...
|
||||
CHAR_CUSTOMIZE_FLAG_RACE = 0x00100000 // name, gender, race, etc...
|
||||
};
|
||||
|
||||
enum CharacterSlot
|
||||
{
|
||||
SLOT_HEAD = 0,
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#define AllPackets_h__
|
||||
|
||||
#include "AuthenticationPackets.h"
|
||||
#include "CharacterPackets.h"
|
||||
#include "GuildPackets.h"
|
||||
#include "LFGPackets.h"
|
||||
#include "NPCPackets.h"
|
||||
|
||||
211
src/server/game/Server/Packets/CharacterPackets.cpp
Normal file
211
src/server/game/Server/Packets/CharacterPackets.cpp
Normal file
@@ -0,0 +1,211 @@
|
||||
/*
|
||||
* This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "CharacterPackets.h"
|
||||
#include "DBCStores.h"
|
||||
#include "Field.h"
|
||||
#include "ObjectMgr.h"
|
||||
#include "Player.h"
|
||||
#include "World.h"
|
||||
|
||||
WorldPackets::Character::EnumCharactersResult::CharacterInfo::CharacterInfo(Field* fields)
|
||||
{
|
||||
// 0 1 2 3 4 5 6 7
|
||||
// SELECT characters.guid, characters.name, characters.race, characters.class, characters.gender, characters.skin, characters.face, characters.hairStyle,
|
||||
// 8 9 10 11 12 13 14 15
|
||||
// characters.hairColor, characters.facialStyle, characters.level, characters.zone, characters.map, characters.position_x, characters.position_y, characters.position_z,
|
||||
// 16 17 18 19 20 21 22
|
||||
// guild_member.guildid, characters.playerFlags, characters.at_login, character_pet.entry, character_pet.modelid, character_pet.level, characters.data,
|
||||
// 23 24 25
|
||||
// character_banned.guid, characters.slot, character_declinedname.genitive
|
||||
|
||||
Guid = ObjectGuid::Create<HighGuid::Player>(fields[0].GetUInt32());
|
||||
Name = fields[1].GetString();
|
||||
RaceID = fields[2].GetUInt8();
|
||||
ClassID = fields[3].GetUInt8();
|
||||
SexID = fields[4].GetUInt8();
|
||||
SkinID = fields[5].GetUInt8();
|
||||
FaceID = fields[6].GetUInt8();
|
||||
HairStyle = fields[7].GetUInt8();
|
||||
HairColor = fields[8].GetUInt8();
|
||||
FacialHair = fields[9].GetUInt8();
|
||||
ExperienceLevel = fields[10].GetUInt8();
|
||||
ZoneID = int32(fields[11].GetUInt16());
|
||||
MapID = int32(fields[12].GetUInt16());
|
||||
PreloadPos = Position(fields[13].GetFloat(), fields[14].GetFloat(), fields[15].GetFloat());
|
||||
|
||||
if (ObjectGuid::LowType guildId = fields[16].GetUInt32())
|
||||
GuildGUID = ObjectGuid::Create<HighGuid::Guild>(guildId);
|
||||
|
||||
uint32 playerFlags = fields[17].GetUInt32();
|
||||
uint32 atLoginFlags = fields[18].GetUInt16();
|
||||
|
||||
if (atLoginFlags & AT_LOGIN_RESURRECT)
|
||||
playerFlags &= ~PLAYER_FLAGS_GHOST;
|
||||
|
||||
if (playerFlags & PLAYER_FLAGS_GHOST)
|
||||
Flags |= CHARACTER_FLAG_GHOST;
|
||||
|
||||
if (atLoginFlags & AT_LOGIN_RENAME)
|
||||
Flags |= CHARACTER_FLAG_RENAME;
|
||||
|
||||
if (fields[23].GetUInt32())
|
||||
Flags |= CHARACTER_FLAG_LOCKED_BY_BILLING;
|
||||
|
||||
if (sWorld->getBoolConfig(CONFIG_DECLINED_NAMES_USED) && !fields[22].GetString().empty())
|
||||
Flags |= CHARACTER_FLAG_DECLINED;
|
||||
|
||||
if (atLoginFlags & AT_LOGIN_CUSTOMIZE)
|
||||
Flags2 = CHAR_CUSTOMIZE_FLAG_CUSTOMIZE;
|
||||
else if (atLoginFlags & AT_LOGIN_CHANGE_FACTION)
|
||||
Flags2 = CHAR_CUSTOMIZE_FLAG_FACTION;
|
||||
else if (atLoginFlags & AT_LOGIN_CHANGE_RACE)
|
||||
Flags2 = CHAR_CUSTOMIZE_FLAG_RACE;
|
||||
|
||||
FirstLogin = (atLoginFlags & AT_LOGIN_FIRST) != 0;
|
||||
|
||||
// show pet at selection character in character list only for non-ghost character
|
||||
if (!(playerFlags & PLAYER_FLAGS_GHOST) && (ClassID == CLASS_WARLOCK || ClassID == CLASS_HUNTER || ClassID == CLASS_DEATH_KNIGHT))
|
||||
{
|
||||
if (CreatureTemplate const* creatureInfo = sObjectMgr->GetCreatureTemplate(fields[19].GetUInt32()))
|
||||
{
|
||||
PetCreatureDisplayID = fields[20].GetUInt32();
|
||||
PetExperienceLevel = fields[21].GetUInt16();
|
||||
PetCreatureFamilyID = creatureInfo->family;
|
||||
}
|
||||
}
|
||||
|
||||
Tokenizer equipment(fields[22].GetString(), ' ');
|
||||
ListPosition = fields[24].GetUInt8();
|
||||
|
||||
for (uint8 slot = 0; slot < INVENTORY_SLOT_BAG_END; ++slot)
|
||||
{
|
||||
uint32 visualBase = slot * 2;
|
||||
uint32 itemId = Player::GetUInt32ValueFromArray(equipment, visualBase);
|
||||
ItemTemplate const* proto = sObjectMgr->GetItemTemplate(itemId);
|
||||
if (!proto)
|
||||
continue;
|
||||
|
||||
SpellItemEnchantmentEntry const* enchant = nullptr;
|
||||
uint32 enchants = Player::GetUInt32ValueFromArray(equipment, visualBase + 1);
|
||||
for (uint8 enchantSlot = PERM_ENCHANTMENT_SLOT; enchantSlot <= TEMP_ENCHANTMENT_SLOT; ++enchantSlot)
|
||||
{
|
||||
// values stored in 2 uint16
|
||||
uint32 enchantId = 0x0000FFFF & (enchants >> enchantSlot * 16);
|
||||
if (!enchantId)
|
||||
continue;
|
||||
|
||||
enchant = sSpellItemEnchantmentStore.LookupEntry(enchantId);
|
||||
if (enchant)
|
||||
break;
|
||||
}
|
||||
|
||||
VisualItems[slot].InvType = proto->InventoryType;
|
||||
VisualItems[slot].DisplayID = proto->DisplayInfoID;
|
||||
VisualItems[slot].DisplayEnchantID = enchant ? enchant->aura_id : 0;
|
||||
}
|
||||
}
|
||||
|
||||
WorldPacket const* WorldPackets::Character::EnumCharactersResult::Write()
|
||||
{
|
||||
_worldPacket.reserve(6 + Characters.size() * sizeof(CharacterInfo) + FactionChangeRestrictions.size() * sizeof(RestrictedFactionChangeRuleInfo));
|
||||
|
||||
_worldPacket.WriteBits(FactionChangeRestrictions.size(), 23);
|
||||
_worldPacket.WriteBit(Success);
|
||||
_worldPacket.WriteBits(Characters.size(), 17);
|
||||
|
||||
for (CharacterInfo const& charInfo : Characters)
|
||||
{
|
||||
_worldPacket.WriteBit(charInfo.Guid[3]);
|
||||
_worldPacket.WriteBit(charInfo.GuildGUID[1]);
|
||||
_worldPacket.WriteBit(charInfo.GuildGUID[7]);
|
||||
_worldPacket.WriteBit(charInfo.GuildGUID[2]);
|
||||
_worldPacket.WriteBits(charInfo.Name.length(), 7);
|
||||
_worldPacket.WriteBit(charInfo.Guid[4]);
|
||||
_worldPacket.WriteBit(charInfo.Guid[7]);
|
||||
_worldPacket.WriteBit(charInfo.GuildGUID[3]);
|
||||
_worldPacket.WriteBit(charInfo.Guid[5]);
|
||||
_worldPacket.WriteBit(charInfo.GuildGUID[6]);
|
||||
_worldPacket.WriteBit(charInfo.Guid[1]);
|
||||
_worldPacket.WriteBit(charInfo.GuildGUID[5]);
|
||||
_worldPacket.WriteBit(charInfo.GuildGUID[4]);
|
||||
_worldPacket.WriteBit(charInfo.FirstLogin);
|
||||
_worldPacket.WriteBit(charInfo.Guid[0]);
|
||||
_worldPacket.WriteBit(charInfo.Guid[2]);
|
||||
_worldPacket.WriteBit(charInfo.Guid[6]);
|
||||
_worldPacket.WriteBit(charInfo.GuildGUID[0]);
|
||||
}
|
||||
|
||||
_worldPacket.FlushBits();
|
||||
|
||||
for (CharacterInfo const& charInfo : Characters)
|
||||
{
|
||||
_worldPacket << uint8(charInfo.ClassID);
|
||||
|
||||
for (WorldPackets::Character::EnumCharactersResult::CharacterInfo::VisualItemInfo const& visualItem : charInfo.VisualItems)
|
||||
{
|
||||
_worldPacket << uint8(visualItem.InvType);
|
||||
_worldPacket << uint32(visualItem.DisplayID);
|
||||
_worldPacket << uint32(visualItem.DisplayEnchantID);
|
||||
}
|
||||
|
||||
_worldPacket << uint32(charInfo.PetCreatureFamilyID);
|
||||
_worldPacket.WriteByteSeq(charInfo.GuildGUID[2]);
|
||||
_worldPacket << uint8(charInfo.ListPosition);
|
||||
_worldPacket << uint8(charInfo.HairStyle);
|
||||
_worldPacket.WriteByteSeq(charInfo.GuildGUID[3]);
|
||||
_worldPacket << uint32(charInfo.PetCreatureDisplayID);
|
||||
_worldPacket << uint32(charInfo.Flags);
|
||||
_worldPacket << uint8(charInfo.HairColor);
|
||||
_worldPacket.WriteByteSeq(charInfo.Guid[4]);
|
||||
_worldPacket << int32(charInfo.MapID);
|
||||
_worldPacket.WriteByteSeq(charInfo.GuildGUID[5]);
|
||||
_worldPacket << float(charInfo.PreloadPos.GetPositionZ());
|
||||
_worldPacket.WriteByteSeq(charInfo.GuildGUID[6]);
|
||||
_worldPacket << uint32(charInfo.PetExperienceLevel);
|
||||
_worldPacket.WriteByteSeq(charInfo.Guid[3]);
|
||||
_worldPacket << float(charInfo.PreloadPos.GetPositionY());
|
||||
_worldPacket << uint32(charInfo.Flags2);
|
||||
_worldPacket << uint8(charInfo.FacialHair);
|
||||
_worldPacket.WriteByteSeq(charInfo.Guid[7]);
|
||||
_worldPacket << uint8(charInfo.SexID);
|
||||
_worldPacket.WriteString(charInfo.Name);
|
||||
_worldPacket << uint8(charInfo.FaceID);
|
||||
_worldPacket.WriteByteSeq(charInfo.Guid[0]);
|
||||
_worldPacket.WriteByteSeq(charInfo.Guid[2]);
|
||||
_worldPacket.WriteByteSeq(charInfo.GuildGUID[1]);
|
||||
_worldPacket.WriteByteSeq(charInfo.GuildGUID[7]);
|
||||
_worldPacket << float(charInfo.PreloadPos.GetPositionX());
|
||||
_worldPacket << uint8(charInfo.SkinID);
|
||||
_worldPacket << uint8(charInfo.RaceID);
|
||||
_worldPacket << uint8(charInfo.ExperienceLevel);
|
||||
_worldPacket.WriteByteSeq(charInfo.Guid[6]);
|
||||
_worldPacket.WriteByteSeq(charInfo.GuildGUID[4]);
|
||||
_worldPacket.WriteByteSeq(charInfo.GuildGUID[0]);
|
||||
_worldPacket.WriteByteSeq(charInfo.Guid[5]);
|
||||
_worldPacket.WriteByteSeq(charInfo.Guid[1]);
|
||||
_worldPacket << int32(charInfo.ZoneID);
|
||||
}
|
||||
|
||||
for (RestrictedFactionChangeRuleInfo const& rule : FactionChangeRestrictions)
|
||||
{
|
||||
_worldPacket << int32(rule.Mask);
|
||||
_worldPacket << uint8(rule.Race);
|
||||
}
|
||||
|
||||
return &_worldPacket;
|
||||
}
|
||||
107
src/server/game/Server/Packets/CharacterPackets.h
Normal file
107
src/server/game/Server/Packets/CharacterPackets.h
Normal file
@@ -0,0 +1,107 @@
|
||||
/*
|
||||
* This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef MiscPackets_h__
|
||||
#define MiscPackets_h__
|
||||
|
||||
#include "Packet.h"
|
||||
#include "ObjectGuid.h"
|
||||
#include "Position.h"
|
||||
#include <array>
|
||||
|
||||
class Field;
|
||||
|
||||
namespace WorldPackets
|
||||
{
|
||||
namespace Character
|
||||
{
|
||||
class EnumCharacters final : public ClientPacket
|
||||
{
|
||||
public:
|
||||
EnumCharacters(WorldPacket&& packet) : ClientPacket(CMSG_ENUM_CHARACTERS, std::move(packet)) { }
|
||||
|
||||
void Read() override { }
|
||||
};
|
||||
|
||||
class EnumCharactersResult final : public ServerPacket
|
||||
{
|
||||
public:
|
||||
struct CharacterInfo
|
||||
{
|
||||
/**
|
||||
* @fn void WorldPackets::Character::EnumCharactersResult::CharacterInfo::CharacterInfo(Field* fields);
|
||||
*
|
||||
* @brief Initialize the struct with values from QueryResult
|
||||
*
|
||||
* @param fields Field set of CharacterDatabaseStatements::CHAR_SEL_ENUM
|
||||
*/
|
||||
CharacterInfo(Field* fields);
|
||||
|
||||
struct VisualItemInfo
|
||||
{
|
||||
uint32 DisplayID = 0;
|
||||
uint32 DisplayEnchantID = 0;
|
||||
uint8 InvType = 0;
|
||||
};
|
||||
|
||||
Position PreloadPos;
|
||||
ObjectGuid Guid;
|
||||
ObjectGuid GuildGUID;
|
||||
uint32 Flags = 0; ///< Character flag @see enum CharacterFlags
|
||||
uint32 Flags2 = 0; ///< Character customization flags @see enum CharacterCustomizeFlags
|
||||
int32 MapID = 0;
|
||||
uint32 PetCreatureDisplayID = 0;
|
||||
uint32 PetCreatureFamilyID = 0;
|
||||
uint32 PetExperienceLevel = 0;
|
||||
int32 ZoneID = 0;
|
||||
uint8 ClassID = 0;
|
||||
uint8 ExperienceLevel = 0;
|
||||
uint8 FaceID = 0;
|
||||
uint8 FacialHair = 0;
|
||||
uint8 HairColor = 0;
|
||||
uint8 HairStyle = 0;
|
||||
uint8 ListPosition = 0; ///< Order of the characters in list
|
||||
uint8 RaceID = 0;
|
||||
uint8 SexID = 0;
|
||||
uint8 SkinID = 0;
|
||||
bool FirstLogin = false;
|
||||
std::string Name;
|
||||
std::array<VisualItemInfo, 23> VisualItems = { };
|
||||
};
|
||||
|
||||
struct RestrictedFactionChangeRuleInfo
|
||||
{
|
||||
RestrictedFactionChangeRuleInfo(int32 mask, uint8 race)
|
||||
: Mask(mask), Race(race) { }
|
||||
|
||||
int32 Mask = 0;
|
||||
uint8 Race = 0;
|
||||
};
|
||||
|
||||
EnumCharactersResult() : ServerPacket(SMSG_ENUM_CHARACTERS_RESULT) { }
|
||||
|
||||
WorldPacket const* Write() override;
|
||||
|
||||
bool Success = false; ///<
|
||||
|
||||
std::vector<CharacterInfo> Characters; ///< all characters on the list
|
||||
std::vector<RestrictedFactionChangeRuleInfo> FactionChangeRestrictions; ///< @todo: research
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif // CharacterPackets_h__
|
||||
@@ -256,7 +256,6 @@ void OpcodeTable::Initialize()
|
||||
DEFINE_HANDLER(CMSG_CHAR_CREATE, STATUS_AUTHED, PROCESS_THREADUNSAFE, &WorldSession::HandleCharCreateOpcode );
|
||||
DEFINE_HANDLER(CMSG_CHAR_CUSTOMIZE, STATUS_AUTHED, PROCESS_THREADUNSAFE, &WorldSession::HandleCharCustomize );
|
||||
DEFINE_HANDLER(CMSG_CHAR_DELETE, STATUS_AUTHED, PROCESS_THREADUNSAFE, &WorldSession::HandleCharDeleteOpcode );
|
||||
DEFINE_HANDLER(CMSG_CHAR_ENUM, STATUS_AUTHED, PROCESS_THREADUNSAFE, &WorldSession::HandleCharEnumOpcode );
|
||||
DEFINE_HANDLER(CMSG_CHAR_FACTION_CHANGE, STATUS_AUTHED, PROCESS_THREADUNSAFE, &WorldSession::HandleCharFactionOrRaceChange );
|
||||
DEFINE_HANDLER(CMSG_CHAR_RACE_CHANGE, STATUS_AUTHED, PROCESS_THREADUNSAFE, &WorldSession::HandleCharFactionOrRaceChange );
|
||||
DEFINE_HANDLER(CMSG_CHAR_RENAME, STATUS_AUTHED, PROCESS_THREADUNSAFE, &WorldSession::HandleCharRenameOpcode );
|
||||
@@ -294,6 +293,7 @@ void OpcodeTable::Initialize()
|
||||
DEFINE_HANDLER(CMSG_EMOTE, STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleEmoteOpcode );
|
||||
DEFINE_HANDLER(CMSG_ENABLETAXI, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleTaxiQueryAvailableNodes );
|
||||
DEFINE_HANDLER(CMSG_ENABLE_NAGLE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_EarlyProccess );
|
||||
DEFINE_HANDLER(CMSG_ENUM_CHARACTERS, STATUS_AUTHED, PROCESS_THREADUNSAFE, &WorldSession::HandleCharEnumOpcode );
|
||||
DEFINE_HANDLER(CMSG_EQUIPMENT_SET_DELETE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleEquipmentSetDelete );
|
||||
DEFINE_HANDLER(CMSG_EQUIPMENT_SET_SAVE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleEquipmentSetSave );
|
||||
DEFINE_HANDLER(CMSG_EQUIPMENT_SET_USE, STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleEquipmentSetUse );
|
||||
@@ -757,7 +757,6 @@ void OpcodeTable::Initialize()
|
||||
DEFINE_SERVER_OPCODE_HANDLER(SMSG_CHAR_CREATE, STATUS_NEVER, CONNECTION_TYPE_REALM);
|
||||
DEFINE_SERVER_OPCODE_HANDLER(SMSG_CHAR_CUSTOMIZE, STATUS_NEVER, CONNECTION_TYPE_REALM);
|
||||
DEFINE_SERVER_OPCODE_HANDLER(SMSG_CHAR_DELETE, STATUS_NEVER, CONNECTION_TYPE_REALM);
|
||||
DEFINE_SERVER_OPCODE_HANDLER(SMSG_CHAR_ENUM, STATUS_NEVER, CONNECTION_TYPE_REALM);
|
||||
DEFINE_SERVER_OPCODE_HANDLER(SMSG_CHAR_FACTION_CHANGE, STATUS_NEVER, CONNECTION_TYPE_REALM);
|
||||
DEFINE_SERVER_OPCODE_HANDLER(SMSG_CHAR_RENAME, STATUS_NEVER, CONNECTION_TYPE_REALM);
|
||||
DEFINE_SERVER_OPCODE_HANDLER(SMSG_CHAT_IGNORED_ACCOUNT_MUTED, STATUS_NEVER, CONNECTION_TYPE_REALM);
|
||||
@@ -829,6 +828,7 @@ void OpcodeTable::Initialize()
|
||||
DEFINE_SERVER_OPCODE_HANDLER(SMSG_EMOTE, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
|
||||
DEFINE_SERVER_OPCODE_HANDLER(SMSG_ENABLE_BARBER_SHOP, STATUS_NEVER, CONNECTION_TYPE_REALM);
|
||||
DEFINE_SERVER_OPCODE_HANDLER(SMSG_ENCHANTMENTLOG, STATUS_NEVER, CONNECTION_TYPE_REALM);
|
||||
DEFINE_SERVER_OPCODE_HANDLER(SMSG_ENUM_CHARACTERS_RESULT, STATUS_NEVER, CONNECTION_TYPE_REALM);
|
||||
DEFINE_SERVER_OPCODE_HANDLER(SMSG_ENVIRONMENTALDAMAGELOG, STATUS_NEVER, CONNECTION_TYPE_REALM);
|
||||
DEFINE_SERVER_OPCODE_HANDLER(SMSG_EQUIPMENT_SET_LIST, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
|
||||
DEFINE_SERVER_OPCODE_HANDLER(SMSG_EQUIPMENT_SET_SAVED, STATUS_NEVER, CONNECTION_TYPE_REALM);
|
||||
|
||||
@@ -149,7 +149,6 @@ enum OpcodeClient : uint16
|
||||
CMSG_CHAR_CREATE = 0x4A36,
|
||||
CMSG_CHAR_CUSTOMIZE = 0x2C34,
|
||||
CMSG_CHAR_DELETE = 0x6425,
|
||||
CMSG_CHAR_ENUM = 0x0502,
|
||||
CMSG_CHAR_FACTION_CHANGE = 0x2735,
|
||||
CMSG_CHAR_RACE_CHANGE = 0x0D24,
|
||||
CMSG_CHAR_RENAME = 0x2327,
|
||||
@@ -188,6 +187,7 @@ enum OpcodeClient : uint16
|
||||
CMSG_EMOTE = 0x4C26,
|
||||
CMSG_ENABLETAXI = 0x0C16,
|
||||
CMSG_ENABLE_NAGLE = 0x4449,
|
||||
CMSG_ENUM_CHARACTERS = 0x0502,
|
||||
CMSG_EQUIPMENT_SET_DELETE = 0x4D07,
|
||||
CMSG_EQUIPMENT_SET_SAVE = 0x4F27,
|
||||
CMSG_EQUIPMENT_SET_USE = 0x0417,
|
||||
@@ -691,7 +691,6 @@ enum OpcodeServer
|
||||
SMSG_CHAR_CREATE = 0x2D05,
|
||||
SMSG_CHAR_CUSTOMIZE = 0x4F16,
|
||||
SMSG_CHAR_DELETE = 0x0304,
|
||||
SMSG_CHAR_ENUM = 0x10B0,
|
||||
SMSG_CHAR_FACTION_CHANGE = 0x4C06,
|
||||
SMSG_CHAR_RENAME = 0x2024,
|
||||
SMSG_CHAT_IGNORED_ACCOUNT_MUTED = 0x15A4,
|
||||
@@ -768,6 +767,7 @@ enum OpcodeServer
|
||||
SMSG_EMOTE = 0x0A34,
|
||||
SMSG_ENABLE_BARBER_SHOP = 0x2D16,
|
||||
SMSG_ENCHANTMENTLOG = 0x6035,
|
||||
SMSG_ENUM_CHARACTERS_RESULT = 0x10B0,
|
||||
SMSG_ENVIRONMENTALDAMAGELOG = 0x6C05,
|
||||
SMSG_EQUIPMENT_SET_LIST = 0x2E04,
|
||||
SMSG_EQUIPMENT_SET_SAVED = 0x2216,
|
||||
@@ -1431,9 +1431,6 @@ enum OpcodeMisc : uint16
|
||||
COMPRESSED_OPCODE_MASK = 0x8000
|
||||
};
|
||||
|
||||
typedef OpcodeClient OpcodeClient;
|
||||
typedef OpcodeServer OpcodeServer;
|
||||
|
||||
/// Player state
|
||||
enum SessionStatus
|
||||
{
|
||||
@@ -1452,7 +1449,7 @@ enum PacketProcessing
|
||||
PROCESS_THREADSAFE //packet is thread-safe - process it in Map::Update()
|
||||
};
|
||||
|
||||
class WorldSession;
|
||||
class WorldPacket;
|
||||
class WorldSession;
|
||||
|
||||
class OpcodeHandler
|
||||
|
||||
@@ -411,8 +411,8 @@ bool WorldSession::Update(uint32 diff, PacketFilter& updater)
|
||||
}
|
||||
|
||||
// some auth opcodes can be recieved before STATUS_LOGGEDIN_OR_RECENTLY_LOGGOUT opcodes
|
||||
// however when we recieve CMSG_CHAR_ENUM we are surely no longer during the logout process.
|
||||
if (packet->GetOpcode() == CMSG_CHAR_ENUM)
|
||||
// however when we recieve CMSG_ENUM_CHARACTERS we are surely no longer during the logout process.
|
||||
if (packet->GetOpcode() == CMSG_ENUM_CHARACTERS)
|
||||
m_playerRecentlyLogout = false;
|
||||
|
||||
if (AntiDOS.EvaluateOpcode(*packet, currentTime))
|
||||
@@ -1521,7 +1521,7 @@ uint32 WorldSession::DosProtection::GetMaxPacketCounterAllowed(uint16 opcode) co
|
||||
}
|
||||
|
||||
case CMSG_CHAR_CREATE: // 7 5 3 async db queries
|
||||
case CMSG_CHAR_ENUM: // 22 3 2 async db queries
|
||||
case CMSG_ENUM_CHARACTERS: // 22 3 2 async db queries
|
||||
case CMSG_GMTICKET_CREATE: // 1 25 1 async db query
|
||||
case CMSG_GMTICKET_UPDATETEXT: // 0 15 1 async db query
|
||||
case CMSG_GMTICKET_DELETETICKET: // 1 25 1 async db query
|
||||
|
||||
@@ -80,6 +80,11 @@ namespace WorldPackets
|
||||
enum class ConnectToSerial : uint32;
|
||||
}
|
||||
|
||||
namespace Character
|
||||
{
|
||||
class EnumCharacters;
|
||||
}
|
||||
|
||||
namespace LFG
|
||||
{
|
||||
class LFGJoin;
|
||||
@@ -550,13 +555,13 @@ class TC_GAME_API WorldSession
|
||||
void Handle_ServerSide(WorldPacket& recvPacket); // sever side only, can't be accepted from client
|
||||
void Handle_Deprecated(WorldPacket& recvPacket); // never used anymore by client
|
||||
|
||||
void HandleCharEnumOpcode(WorldPacket& recvPacket);
|
||||
void HandleCharEnum(PreparedQueryResult result);
|
||||
void HandleCharEnumOpcode(WorldPackets::Character::EnumCharacters& /*enumCharacters*/);
|
||||
void HandleCharDeleteOpcode(WorldPacket& recvPacket);
|
||||
void HandleCharCreateOpcode(WorldPacket& recvPacket);
|
||||
void HandlePlayerLoginOpcode(WorldPacket& recvPacket);
|
||||
void HandleContinuePlayerLogin();
|
||||
void HandleLoadScreenOpcode(WorldPacket& recvPacket);
|
||||
void HandleCharEnum(PreparedQueryResult result);
|
||||
void HandlePlayerLogin(LoginQueryHolder* holder);
|
||||
void HandleCharFactionOrRaceChange(WorldPacket& recvData);
|
||||
void HandleCharFactionOrRaceChangeCallback(std::shared_ptr<CharacterFactionChangeInfo> factionChangeInfo, PreparedQueryResult result);
|
||||
|
||||
Reference in New Issue
Block a user