/* * Copyright (C) 2012-2017 CypherCore * * 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 3 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 . */ using Framework.Constants; using Framework.Database; using Framework.Dynamic; using Framework.GameMath; using Framework.IO; using Game.Entities; using System; using System.Collections.Generic; using System.Diagnostics.Contracts; namespace Game.Network.Packets { public class EnumCharacters : ClientPacket { public EnumCharacters(WorldPacket packet) : base(packet) { } public override void Read() { } } public class EnumCharactersResult : ServerPacket { public EnumCharactersResult() : base(ServerOpcodes.EnumCharactersResult) { } public override void Write() { _worldPacket.WriteBit(Success); _worldPacket.WriteBit(IsDeletedCharacters); _worldPacket.WriteBit(IsDemonHunterCreationAllowed); _worldPacket.WriteBit(HasDemonHunterOnRealm); _worldPacket.WriteBit(HasLevel70OnRealm); _worldPacket.WriteBit(Unknown7x); _worldPacket.WriteBit(DisabledClassesMask.HasValue); _worldPacket.WriteUInt32(Characters.Count); _worldPacket.WriteUInt32(FactionChangeRestrictions.Count); if (DisabledClassesMask.HasValue) _worldPacket.WriteUInt32(DisabledClassesMask.Value); foreach (RestrictedFactionChangeRuleInfo rule in FactionChangeRestrictions) { _worldPacket.WriteUInt32(rule.Mask); _worldPacket.WriteUInt8(rule.Race); } foreach (CharacterInfo charInfo in Characters) { _worldPacket.WritePackedGuid(charInfo.Guid); _worldPacket.WriteUInt8(charInfo.ListPosition); _worldPacket.WriteUInt8(charInfo.RaceId); _worldPacket.WriteUInt8(charInfo.ClassId); _worldPacket.WriteUInt8(charInfo.Sex); _worldPacket.WriteUInt8(charInfo.Skin); _worldPacket.WriteUInt8(charInfo.Face); _worldPacket.WriteUInt8(charInfo.HairStyle); _worldPacket.WriteUInt8(charInfo.HairColor); _worldPacket.WriteUInt8(charInfo.FacialHair); charInfo.CustomDisplay.ForEach(id => _worldPacket.WriteUInt8(id)); _worldPacket.WriteUInt8(charInfo.Level); _worldPacket.WriteUInt32(charInfo.ZoneId); _worldPacket.WriteUInt32(charInfo.MapId); _worldPacket.WriteVector3(charInfo.PreLoadPosition); _worldPacket.WritePackedGuid(charInfo.GuildGuid); _worldPacket.WriteUInt32(charInfo.Flags); _worldPacket.WriteUInt32(charInfo.CustomizationFlag); _worldPacket.WriteUInt32(charInfo.Flags3); _worldPacket.WriteUInt32(charInfo.Pet.CreatureDisplayId); _worldPacket.WriteUInt32(charInfo.Pet.Level); _worldPacket.WriteUInt32(charInfo.Pet.CreatureFamily); _worldPacket.WriteUInt32(charInfo.ProfessionIds[0]); _worldPacket.WriteUInt32(charInfo.ProfessionIds[1]); foreach (var visualItem in charInfo.VisualItems) { _worldPacket.WriteUInt32(visualItem.DisplayId); _worldPacket.WriteUInt32(visualItem.DisplayEnchantId); _worldPacket.WriteUInt8(visualItem.InventoryType); } _worldPacket.WriteUInt32(charInfo.LastPlayedTime); _worldPacket.WriteUInt16(charInfo.SpecID); _worldPacket.WriteUInt32(charInfo.Unknown703); _worldPacket.WriteUInt32(charInfo.Flags4); _worldPacket.WriteBits(charInfo.Name.Length, 6); _worldPacket.WriteBit(charInfo.FirstLogin); _worldPacket.WriteBit(charInfo.BoostInProgress); _worldPacket.WriteBits(charInfo.unkWod61x, 5); _worldPacket.WriteString(charInfo.Name); } } public bool Success { get; set; } public bool IsDeletedCharacters; // used for character undelete list public bool IsDemonHunterCreationAllowed { get; set; } = false; ///< used for demon hunter early access public bool HasDemonHunterOnRealm { get; set; } = false; public bool HasLevel70OnRealm { get; set; } = false; public bool Unknown7x { get; set; } = false; public Optional DisabledClassesMask { get; set; } = new Optional(); public List Characters { get; set; } = new List(); // all characters on the list public List FactionChangeRestrictions { get; set; } = new List(); // @todo: research public class CharacterInfo { public CharacterInfo(SQLFields 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 // "characters.hairColor, characters.facialStyle, characters.customDisplay1, characters.customDisplay2, characters.customDisplay3, characters.level, " // 14 15 16 17 18 // "characters.zone, characters.map, characters.position_x, characters.position_y, characters.position_z, " // 19 20 21 22 23 24 25 // "guild_member.guildid, characters.playerFlags, characters.at_login, character_pet.entry, character_pet.modelid, character_pet.level, characters.equipmentCache, " // 26 27 28 29 30 // "character_banned.guid, characters.slot, characters.logout_time, characters.activeTalentGroup, character_declinedname.genitive" Guid = ObjectGuid.Create(HighGuid.Player, fields.Read(0)); Name = fields.Read(1); RaceId = fields.Read(2); ClassId = (Class)fields.Read(3); Sex = fields.Read(4); Skin = fields.Read(5); Face = fields.Read(6); HairStyle = fields.Read(7); HairColor = fields.Read(8); FacialHair = fields.Read(9); CustomDisplay[0] = fields.Read(10); CustomDisplay[1] = fields.Read(11); CustomDisplay[2] = fields.Read(12); Level = fields.Read(13); ZoneId = fields.Read(14); MapId = fields.Read(15); PreLoadPosition = new Vector3(fields.Read(16), fields.Read(17), fields.Read(18)); ulong guildId = fields.Read(19); if (guildId != 0) GuildGuid = ObjectGuid.Create(HighGuid.Guild, guildId); PlayerFlags playerFlags = (PlayerFlags)fields.Read(20); AtLoginFlags atLoginFlags = (AtLoginFlags)fields.Read(21); if (atLoginFlags.HasAnyFlag(AtLoginFlags.Resurrect)) playerFlags &= ~PlayerFlags.Ghost; if (playerFlags.HasAnyFlag(PlayerFlags.HideHelm)) Flags |= CharacterFlags.HideHelm; if (playerFlags.HasAnyFlag(PlayerFlags.HideCloak)) Flags |= CharacterFlags.HideCloak; if (playerFlags.HasAnyFlag(PlayerFlags.Ghost)) Flags |= CharacterFlags.Ghost; if (atLoginFlags.HasAnyFlag(AtLoginFlags.Rename)) Flags |= CharacterFlags.Rename; if (fields.Read(26) != 0) Flags |= CharacterFlags.LockedByBilling; if (WorldConfig.GetBoolValue(WorldCfg.DeclinedNamesUsed) && !string.IsNullOrEmpty(fields.Read(30))) Flags |= CharacterFlags.Declined; if (atLoginFlags.HasAnyFlag(AtLoginFlags.Customize)) CustomizationFlag = CharacterCustomizeFlags.Customize; else if (atLoginFlags.HasAnyFlag(AtLoginFlags.ChangeFaction)) CustomizationFlag = CharacterCustomizeFlags.Faction; else if (atLoginFlags.HasAnyFlag(AtLoginFlags.ChangeRace)) CustomizationFlag = CharacterCustomizeFlags.Race; Flags3 = 0; Flags4 = 0; FirstLogin = atLoginFlags.HasAnyFlag(AtLoginFlags.FirstLogin); // show pet at selection character in character list only for non-ghost character if (!playerFlags.HasAnyFlag(PlayerFlags.Ghost) && (ClassId == Class.Warlock || ClassId == Class.Hunter || ClassId == Class.Deathknight)) { CreatureTemplate creatureInfo = Global.ObjectMgr.GetCreatureTemplate(fields.Read(22)); if (creatureInfo != null) { Pet.CreatureDisplayId = fields.Read(23); Pet.Level = fields.Read(24); Pet.CreatureFamily = (uint)creatureInfo.Family; } } BoostInProgress = false; ProfessionIds[0] = 0; ProfessionIds[1] = 0; StringArguments equipment = new StringArguments(fields.Read(25)); ListPosition = fields.Read(27); LastPlayedTime = fields.Read(28); var spec = Global.DB2Mgr.GetChrSpecializationByIndex(ClassId, fields.Read(29)); if (spec != null) SpecID = (ushort)spec.Id; for (byte slot = 0; slot < InventorySlots.BagEnd; ++slot) { VisualItems[slot].InventoryType = (byte)equipment.NextUInt32(); VisualItems[slot].DisplayId = equipment.NextUInt32(); VisualItems[slot].DisplayEnchantId = equipment.NextUInt32(); } } public ObjectGuid Guid { get; set; } public string Name { get; set; } public byte ListPosition; // Order of the characters in list public byte RaceId { get; set; } public Class ClassId { get; set; } public byte Sex { get; set; } public byte Skin { get; set; } public byte Face { get; set; } public byte HairStyle { get; set; } public byte HairColor { get; set; } public byte FacialHair { get; set; } public Array CustomDisplay { get; set; } = new Array(PlayerConst.CustomDisplaySize); public byte Level { get; set; } public uint ZoneId { get; set; } public uint MapId { get; set; } public Vector3 PreLoadPosition { get; set; } public ObjectGuid GuildGuid { get; set; } public CharacterFlags Flags; // Character flag @see enum CharacterFlags public CharacterCustomizeFlags CustomizationFlag; // Character customization flags @see enum CharacterCustomizeFlags public uint Flags3; // Character flags 3 @todo research public uint Flags4 { get; set; } public bool FirstLogin { get; set; } public byte unkWod61x { get; set; } public uint LastPlayedTime { get; set; } public ushort SpecID { get; set; } public uint Unknown703 { get; set; } public PetInfo Pet = new PetInfo(); public bool BoostInProgress; // @todo public uint[] ProfessionIds { get; set; } = new uint[2]; // @todo public VisualItemInfo[] VisualItems { get; set; } = new VisualItemInfo[InventorySlots.BagEnd]; public struct VisualItemInfo { public uint DisplayId { get; set; } public uint DisplayEnchantId { get; set; } public byte InventoryType { get; set; } } public struct PetInfo { public uint CreatureDisplayId; // PetCreatureDisplayId public uint Level; // PetExperienceLevel public uint CreatureFamily; // PetCreatureFamilyId } } public struct RestrictedFactionChangeRuleInfo { public RestrictedFactionChangeRuleInfo(uint mask, byte race) { Mask = mask; Race = race; } public uint Mask { get; set; } public byte Race { get; set; } } } public class CreateCharacter : ClientPacket { public CreateCharacter(WorldPacket packet) : base(packet) { } public override void Read() { CreateInfo = new CharacterCreateInfo(); uint nameLength = _worldPacket.ReadBits(6); CreateInfo.TemplateSet.HasValue = _worldPacket.HasBit(); CreateInfo.RaceId = (Race)_worldPacket.ReadUInt8(); CreateInfo.ClassId = (Class)_worldPacket.ReadUInt8(); CreateInfo.Sex = (Gender)_worldPacket.ReadUInt8(); CreateInfo.Skin = _worldPacket.ReadUInt8(); CreateInfo.Face = _worldPacket.ReadUInt8(); CreateInfo.HairStyle = _worldPacket.ReadUInt8(); CreateInfo.HairColor = _worldPacket.ReadUInt8(); CreateInfo.FacialHairStyle = _worldPacket.ReadUInt8(); CreateInfo.OutfitId = _worldPacket.ReadUInt8(); for (var i = 0; i < CreateInfo.CustomDisplay.GetLimit(); ++i) CreateInfo.CustomDisplay.Add(_worldPacket.ReadUInt8()); CreateInfo.Name = _worldPacket.ReadString(nameLength); if (CreateInfo.TemplateSet.HasValue) CreateInfo.TemplateSet.Value = _worldPacket.ReadUInt32(); } public CharacterCreateInfo CreateInfo; } public class CreateChar : ServerPacket { public CreateChar() : base(ServerOpcodes.CreateChar) { } public override void Write() { _worldPacket.WriteUInt8(Code); } public ResponseCodes Code { get; set; } } public class CharDelete : ClientPacket { public CharDelete(WorldPacket packet) : base(packet) { } public override void Read() { Guid = _worldPacket.ReadPackedGuid(); } public ObjectGuid Guid; // Guid of the character to delete } public class DeleteChar : ServerPacket { public DeleteChar() : base(ServerOpcodes.DeleteChar) { } public override void Write() { _worldPacket.WriteUInt8(Code); } public ResponseCodes Code { get; set; } } public class CharacterRenameRequest : ClientPacket { public CharacterRenameRequest(WorldPacket packet) : base(packet) { } public override void Read() { RenameInfo = new CharacterRenameInfo(); RenameInfo.Guid = _worldPacket.ReadPackedGuid(); RenameInfo.NewName = _worldPacket.ReadString(_worldPacket.ReadBits(6)); } public CharacterRenameInfo RenameInfo { get; set; } } public class CharacterRenameResult : ServerPacket { public CharacterRenameResult() : base(ServerOpcodes.CharacterRenameResult) { Guid = new Optional(); } public override void Write() { _worldPacket.WriteUInt8(Result); _worldPacket.WriteBit(Guid.HasValue); _worldPacket.WriteBits(Name.Length, 6); _worldPacket.FlushBits(); if (Guid.HasValue) _worldPacket.WritePackedGuid(Guid.Value); _worldPacket.WriteString(Name); } public string Name { get; set; } public ResponseCodes Result { get; set; } = 0; public Optional Guid { get; set; } } public class CharCustomize : ClientPacket { public CharCustomize(WorldPacket packet) : base(packet) { } public override void Read() { CustomizeInfo = new CharCustomizeInfo(); CustomizeInfo.CharGUID = _worldPacket.ReadPackedGuid(); CustomizeInfo.SexID = (Gender)_worldPacket.ReadUInt8(); CustomizeInfo.SkinID = _worldPacket.ReadUInt8(); CustomizeInfo.HairColorID = _worldPacket.ReadUInt8(); CustomizeInfo.HairStyleID = _worldPacket.ReadUInt8(); CustomizeInfo.FacialHairStyleID = _worldPacket.ReadUInt8(); CustomizeInfo.FaceID = _worldPacket.ReadUInt8(); for (var i = 0; i < CustomizeInfo.CustomDisplay.GetLimit(); ++i) CustomizeInfo.CustomDisplay.Add(_worldPacket.ReadUInt8()); CustomizeInfo.CharName = _worldPacket.ReadString(_worldPacket.ReadBits(6)); } public CharCustomizeInfo CustomizeInfo { get; set; } } // @todo: CharCustomizeResult public class CharRaceOrFactionChange : ClientPacket { public CharRaceOrFactionChange(WorldPacket packet) : base(packet) { } public override void Read() { RaceOrFactionChangeInfo = new CharRaceOrFactionChangeInfo(); RaceOrFactionChangeInfo.FactionChange = _worldPacket.HasBit(); uint nameLength = _worldPacket.ReadBits(6); RaceOrFactionChangeInfo.Guid = _worldPacket.ReadPackedGuid(); RaceOrFactionChangeInfo.SexID = (Gender)_worldPacket.ReadUInt8(); RaceOrFactionChangeInfo.RaceID = (Race)_worldPacket.ReadUInt8(); RaceOrFactionChangeInfo.SkinID = _worldPacket.ReadUInt8(); RaceOrFactionChangeInfo.HairColorID = _worldPacket.ReadUInt8(); RaceOrFactionChangeInfo.HairStyleID = _worldPacket.ReadUInt8(); RaceOrFactionChangeInfo.FacialHairStyleID = _worldPacket.ReadUInt8(); RaceOrFactionChangeInfo.FaceID = _worldPacket.ReadUInt8(); for (var i = 0; i < RaceOrFactionChangeInfo.CustomDisplay.GetLimit(); ++i) RaceOrFactionChangeInfo.CustomDisplay.Add(_worldPacket.ReadUInt8()); RaceOrFactionChangeInfo.Name = _worldPacket.ReadString(nameLength); } public CharRaceOrFactionChangeInfo RaceOrFactionChangeInfo { get; set; } } public class CharFactionChangeResult : ServerPacket { public CharFactionChangeResult() : base(ServerOpcodes.CharFactionChangeResult) { Display = new Optional(); } public override void Write() { _worldPacket.WriteUInt8(Result); _worldPacket.WritePackedGuid(Guid); _worldPacket.WriteBit(Display.HasValue); _worldPacket.FlushBits(); if (Display.HasValue) { _worldPacket.WriteBits(Display.Value.Name.Length, 6); _worldPacket.WriteUInt8(Display.Value.SexID); _worldPacket.WriteUInt8(Display.Value.SkinID); _worldPacket.WriteUInt8(Display.Value.HairColorID); _worldPacket.WriteUInt8(Display.Value.HairStyleID); _worldPacket.WriteUInt8(Display.Value.FacialHairStyleID); _worldPacket.WriteUInt8(Display.Value.FaceID); _worldPacket.WriteUInt8(Display.Value.RaceID); Display.Value.CustomDisplay.ForEach(id => _worldPacket.WriteUInt8(id)); _worldPacket.WriteString(Display.Value.Name); } } public ResponseCodes Result { get; set; } = 0; public ObjectGuid Guid { get; set; } public Optional Display; public class CharFactionChangeDisplayInfo { public string Name { get; set; } public byte SexID { get; set; } public byte SkinID { get; set; } public byte HairColorID { get; set; } public byte HairStyleID { get; set; } public byte FacialHairStyleID { get; set; } public byte FaceID { get; set; } public byte RaceID { get; set; } public Array CustomDisplay { get; set; } = new Array(PlayerConst.CustomDisplaySize); } } public class GenerateRandomCharacterName : ClientPacket { public GenerateRandomCharacterName(WorldPacket packet) : base(packet) { } public override void Read() { Race = _worldPacket.ReadUInt8(); Sex = _worldPacket.ReadUInt8(); } public byte Sex { get; set; } public byte Race { get; set; } } public class GenerateRandomCharacterNameResult : ServerPacket { public GenerateRandomCharacterNameResult() : base(ServerOpcodes.GenerateRandomCharacterNameResult) { } public override void Write() { _worldPacket.WriteBit(Success); _worldPacket.WriteBits(Name.Length, 6); _worldPacket.WriteString(Name); } public string Name { get; set; } public bool Success { get; set; } } public class ReorderCharacters : ClientPacket { public ReorderCharacters(WorldPacket packet) : base(packet) { } public override void Read() { uint count = _worldPacket.ReadBits(9); for (var i = 0; i < count && i < WorldConfig.GetIntValue(WorldCfg.CharactersPerRealm); ++i) { ReorderInfo reorderInfo = new ReorderInfo(); reorderInfo.PlayerGUID = _worldPacket.ReadPackedGuid(); reorderInfo.NewPosition = _worldPacket.ReadUInt8(); Entries[i] = reorderInfo; } } public ReorderInfo[] Entries { get; set; } = new ReorderInfo[WorldConfig.GetIntValue(WorldCfg.CharactersPerRealm)]; public struct ReorderInfo { public ObjectGuid PlayerGUID { get; set; } public byte NewPosition { get; set; } } } public class UndeleteCharacter : ClientPacket { public UndeleteCharacter(WorldPacket packet) : base(packet) { } public override void Read() { UndeleteInfo = new CharacterUndeleteInfo(); _worldPacket.WriteUInt32(UndeleteInfo.ClientToken); _worldPacket.WritePackedGuid(UndeleteInfo.CharacterGuid); } public CharacterUndeleteInfo UndeleteInfo { get; set; } } public class UndeleteCharacterResponse : ServerPacket { public UndeleteCharacterResponse() : base(ServerOpcodes.UndeleteCharacterResponse) { } public override void Write() { Contract.Assert(UndeleteInfo != null); _worldPacket.WriteInt32(UndeleteInfo.ClientToken); _worldPacket.WriteUInt32(Result); _worldPacket.WritePackedGuid(UndeleteInfo.CharacterGuid); } public CharacterUndeleteInfo UndeleteInfo { get; set; } public CharacterUndeleteResult Result { get; set; } } public class GetUndeleteCharacterCooldownStatus : ClientPacket { public GetUndeleteCharacterCooldownStatus(WorldPacket packet) : base(packet) { } public override void Read() { } } public class UndeleteCooldownStatusResponse : ServerPacket { public UndeleteCooldownStatusResponse() : base(ServerOpcodes.UndeleteCooldownStatusResponse) { } public override void Write() { _worldPacket.WriteBit(OnCooldown); _worldPacket.WriteUInt32(MaxCooldown); _worldPacket.WriteUInt32(CurrentCooldown); } public bool OnCooldown { get; set; } public uint MaxCooldown { get; set; } // Max. cooldown until next free character restoration. Displayed in undelete confirm message. (in sec) public uint CurrentCooldown { get; set; } // Current cooldown until next free character restoration. (in sec) } public class PlayerLogin : ClientPacket { public PlayerLogin(WorldPacket packet) : base(packet) { } public override void Read() { Guid = _worldPacket.ReadPackedGuid(); FarClip = _worldPacket.ReadFloat(); } public ObjectGuid Guid; // Guid of the player that is logging in float FarClip = 0.0f; // Visibility distance (for terrain) } public class LoginVerifyWorld : ServerPacket { public LoginVerifyWorld() : base(ServerOpcodes.LoginVerifyWorld, ConnectionType.Instance) { } public override void Write() { _worldPacket.WriteInt32(MapID); _worldPacket.WriteFloat(Pos.GetPositionX()); _worldPacket.WriteFloat(Pos.GetPositionY()); _worldPacket.WriteFloat(Pos.GetPositionZ()); _worldPacket.WriteFloat(Pos.GetOrientation()); _worldPacket.WriteUInt32(Reason); } public int MapID { get; set; } = -1; public Position Pos { get; set; } public uint Reason { get; set; } = 0; } public class CharacterLoginFailed : ServerPacket { public CharacterLoginFailed(LoginFailureReason code) : base(ServerOpcodes.CharacterLoginFailed) { Code = code; } public override void Write() { _worldPacket.WriteUInt8(Code); } LoginFailureReason Code; } public class LogoutRequest : ClientPacket { public LogoutRequest(WorldPacket packet) : base(packet) { } public override void Read() { IdleLogout = _worldPacket.HasBit(); } bool IdleLogout; } public class LogoutResponse : ServerPacket { public LogoutResponse() : base(ServerOpcodes.LogoutResponse, ConnectionType.Instance) { } public override void Write() { _worldPacket.WriteInt32(LogoutResult); _worldPacket.WriteBit(Instant); _worldPacket.FlushBits(); } public int LogoutResult { get; set; } public bool Instant { get; set; } = false; } public class LogoutComplete : ServerPacket { public LogoutComplete() : base(ServerOpcodes.LogoutComplete) { } public override void Write() { } } public class LogoutCancel : ClientPacket { public LogoutCancel(WorldPacket packet) : base(packet) { } public override void Read() { } } public class LogoutCancelAck : ServerPacket { public LogoutCancelAck() : base(ServerOpcodes.LogoutCancelAck, ConnectionType.Instance) { } public override void Write() { } } public class LoadingScreenNotify : ClientPacket { public LoadingScreenNotify(WorldPacket packet) : base(packet) { } public override void Read() { MapID = _worldPacket.ReadInt32(); Showing = _worldPacket.HasBit(); } int MapID = -1; bool Showing; } public class InitialSetup : ServerPacket { public InitialSetup() : base(ServerOpcodes.InitialSetup, ConnectionType.Instance) { } public override void Write() { _worldPacket.WriteUInt8(ServerExpansionLevel); _worldPacket.WriteUInt8(ServerExpansionTier); } public byte ServerExpansionTier { get; set; } public byte ServerExpansionLevel { get; set; } } public class SetActionBarToggles : ClientPacket { public SetActionBarToggles(WorldPacket packet) : base(packet) { } public override void Read() { Mask = _worldPacket.ReadUInt8(); } public byte Mask { get; set; } } public class RequestPlayedTime : ClientPacket { public RequestPlayedTime(WorldPacket packet) : base(packet) { } public override void Read() { TriggerScriptEvent = _worldPacket.HasBit(); } public bool TriggerScriptEvent { get; set; } } public class PlayedTime : ServerPacket { public PlayedTime() : base(ServerOpcodes.PlayedTime, ConnectionType.Instance) { } public override void Write() { _worldPacket.WriteUInt32(TotalTime); _worldPacket.WriteUInt32(LevelTime); _worldPacket.WriteBit(TriggerEvent); _worldPacket.FlushBits(); } public uint TotalTime { get; set; } public uint LevelTime { get; set; } public bool TriggerEvent { get; set; } } public class SetTitle : ClientPacket { public int TitleID { get; set; } public SetTitle(WorldPacket packet) : base(packet) { } public override void Read() { TitleID = _worldPacket.ReadInt32(); } } public class AlterApperance : ClientPacket { public AlterApperance(WorldPacket packet) : base(packet) { } public override void Read() { NewHairStyle = _worldPacket.ReadUInt32(); NewHairColor = _worldPacket.ReadUInt32(); NewFacialHair = _worldPacket.ReadUInt32(); NewSkinColor = _worldPacket.ReadUInt32(); NewFace = _worldPacket.ReadUInt32(); for (var i = 0; i < NewCustomDisplay.GetLimit(); ++i) NewCustomDisplay.Add(_worldPacket.ReadUInt32()); } public uint NewHairStyle { get; set; } public uint NewHairColor { get; set; } public uint NewFacialHair { get; set; } public uint NewSkinColor { get; set; } public uint NewFace { get; set; } public Array NewCustomDisplay { get; set; } = new Array(PlayerConst.CustomDisplaySize); } public class BarberShopResult : ServerPacket { public BarberShopResult(ResultEnum result) : base(ServerOpcodes.BarberShopResult) { Result = result; } public override void Write() { _worldPacket.WriteInt32(Result); } public ResultEnum Result { get; set; } public enum ResultEnum { Success = 0, NoMoney = 1, NotOnChair = 2, NoMoney2 = 3 } } class LogXPGain : ServerPacket { public LogXPGain() : base(ServerOpcodes.LogXpGain) { } public override void Write() { _worldPacket.WritePackedGuid(Victim); _worldPacket.WriteInt32(Original); _worldPacket.WriteUInt8(Reason); _worldPacket.WriteInt32(Amount); _worldPacket.WriteFloat(GroupBonus); _worldPacket.WriteBit(ReferAFriend); _worldPacket.FlushBits(); } public ObjectGuid Victim { get; set; } public int Original { get; set; } public PlayerLogXPReason Reason { get; set; } public int Amount { get; set; } public float GroupBonus { get; set; } public bool ReferAFriend { get; set; } } class TitleEarned : ServerPacket { public TitleEarned(ServerOpcodes opcode) : base(opcode) { } public override void Write() { _worldPacket.WriteUInt32(Index); } public uint Index { get; set; } } class SetFactionAtWar : ClientPacket { public SetFactionAtWar(WorldPacket packet) : base(packet) { } public override void Read() { FactionIndex = _worldPacket.ReadUInt8(); } public byte FactionIndex { get; set; } } class SetFactionNotAtWar : ClientPacket { public SetFactionNotAtWar(WorldPacket packet) : base(packet) { } public override void Read() { FactionIndex = _worldPacket.ReadUInt8(); } public byte FactionIndex { get; set; } } class SetFactionInactive : ClientPacket { public SetFactionInactive(WorldPacket packet) : base(packet) { } public override void Read() { Index = _worldPacket.ReadUInt32(); State = _worldPacket.HasBit(); } public uint Index { get; set; } public bool State { get; set; } } class SetWatchedFaction : ClientPacket { public SetWatchedFaction(WorldPacket packet) : base(packet) { } public override void Read() { FactionIndex = _worldPacket.ReadUInt32(); } public uint FactionIndex { get; set; } } class SetFactionVisible : ServerPacket { public SetFactionVisible(bool visible) : base(visible ? ServerOpcodes.SetFactionVisible : ServerOpcodes.SetFactionNotVisible, ConnectionType.Instance) { } public override void Write() { _worldPacket.WriteUInt32(FactionIndex); } public uint FactionIndex { get; set; } } class CharCustomizeResponse : ServerPacket { public CharCustomizeResponse(CharCustomizeInfo customizeInfo) : base(ServerOpcodes.CharCustomize) { CharGUID = customizeInfo.CharGUID; SexID = (byte)customizeInfo.SexID; SkinID = customizeInfo.SkinID; HairColorID = customizeInfo.HairColorID; HairStyleID = customizeInfo.HairStyleID; FacialHairStyleID = customizeInfo.FacialHairStyleID; FaceID = customizeInfo.FaceID; CharName = customizeInfo.CharName; CustomDisplay = customizeInfo.CustomDisplay; } public override void Write() { _worldPacket.WritePackedGuid(CharGUID); _worldPacket.WriteUInt8(SexID); _worldPacket.WriteUInt8(SkinID); _worldPacket.WriteUInt8(HairColorID); _worldPacket.WriteUInt8(HairStyleID); _worldPacket.WriteUInt8(FacialHairStyleID); _worldPacket.WriteUInt8(FaceID); CustomDisplay.ForEach(id => _worldPacket.WriteUInt8(id)); _worldPacket.WriteBits(CharName.Length, 6); _worldPacket.FlushBits(); _worldPacket.WriteString(CharName); } ObjectGuid CharGUID; string CharName = ""; byte SexID; byte SkinID; byte HairColorID; byte HairStyleID; byte FacialHairStyleID; byte FaceID; public Array CustomDisplay { get; set; } = new Array(PlayerConst.CustomDisplaySize); } class CharCustomizeFailed : ServerPacket { public CharCustomizeFailed() : base(ServerOpcodes.CharCustomizeFailed) { } public override void Write() { _worldPacket.WriteUInt8(Result); _worldPacket.WritePackedGuid(CharGUID); } public byte Result { get; set; } public ObjectGuid CharGUID { get; set; } } class SetPlayerDeclinedNames : ClientPacket { public SetPlayerDeclinedNames(WorldPacket packet) : base(packet) { DeclinedNames = new DeclinedName(); } public override void Read() { Player = _worldPacket.ReadPackedGuid(); ; byte[] stringLengths = new byte[SharedConst.MaxDeclinedNameCases]; for (byte i = 0; i < SharedConst.MaxDeclinedNameCases; ++i) stringLengths[i] = _worldPacket.ReadBits(7); for (byte i = 0; i < SharedConst.MaxDeclinedNameCases; ++i) DeclinedNames.name[i] = _worldPacket.ReadString(stringLengths[i]); } public ObjectGuid Player { get; set; } public DeclinedName DeclinedNames { get; set; } } class SetPlayerDeclinedNamesResult : ServerPacket { public SetPlayerDeclinedNamesResult() : base(ServerOpcodes.SetPlayerDeclinedNamesResult) { } public override void Write() { _worldPacket.WriteInt32(ResultCode); _worldPacket.WritePackedGuid(Player); } public ObjectGuid Player { get; set; } public DeclinedNameResult ResultCode { get; set; } } //Structs public class CharacterCreateInfo { // User specified variables public Race RaceId { get; set; } = Race.None; public Class ClassId { get; set; } = Class.None; public Gender Sex { get; set; } = Gender.None; public byte Skin { get; set; } = 0; public byte Face { get; set; } = 0; public byte HairStyle { get; set; } = 0; public byte HairColor { get; set; } = 0; public byte FacialHairStyle { get; set; } = 0; public Array CustomDisplay { get; set; } = new Array(PlayerConst.CustomDisplaySize); public byte OutfitId { get; set; } = 0; public Optional TemplateSet = new Optional(); public string Name; // Server side data public byte CharCount { get; set; } = 0; } public class CharacterRenameInfo { public string NewName; public ObjectGuid Guid { get; set; } } public class CharCustomizeInfo { public byte HairStyleID { get; set; } = 0; public byte FaceID { get; set; } = 0; public ObjectGuid CharGUID { get; set; } public Gender SexID { get; set; } = Gender.None; public string CharName; public byte HairColorID { get; set; } = 0; public byte FacialHairStyleID { get; set; } = 0; public byte SkinID { get; set; } = 0; public Array CustomDisplay { get; set; } = new Array(PlayerConst.CustomDisplaySize); } public class CharRaceOrFactionChangeInfo { public byte HairColorID { get; set; } public Race RaceID { get; set; } = Race.None; public Gender SexID { get; set; } = Gender.None; public byte SkinID { get; set; } public byte FacialHairStyleID { get; set; } public ObjectGuid Guid { get; set; } public bool FactionChange { get; set; } = false; public string Name; public byte FaceID { get; set; } public byte HairStyleID { get; set; } public Array CustomDisplay { get; set; } = new Array(PlayerConst.CustomDisplaySize); } public class CharacterUndeleteInfo { // User specified variables public ObjectGuid CharacterGuid; // Guid of the character to restore public int ClientToken { get; set; } = 0; // @todo: research // Server side data public string Name { get; set; } } }