using System.Buffers.Binary; using System.Text; using Wonderking.Packets.Outgoing.Data; namespace Wonderking.Packets.Outgoing; [PacketId(OperationCode.ChannelSelectionResponse)] public class ChannelSelectionResponsePacket : IPacket { public required byte ChannelIsFullFlag { get; set; } public required string Endpoint { get; set; } public required ushort Port { get; set; } public required CharacterData[] Characters { get; set; } public void Deserialize(byte[] data) { throw new NotSupportedException(); } public byte[] Serialize() { Span data = stackalloc byte[1 + 16 + 2 + 1 + 132 * Characters.Length]; data.Clear(); data[0] = ChannelIsFullFlag; Encoding.ASCII.GetBytes(Endpoint, data.Slice(1, 16)); BinaryPrimitives.WriteUInt16LittleEndian(data.Slice(17, 2), Port); data[19] = (byte)Characters.Length; // Character Data for (var i = 0; i < Characters.Length; i++) { var offset = 20 + i * 132; var character = Characters[i]; // Character Data BinaryPrimitives.WriteInt32LittleEndian(data.Slice(offset, 4), i); Encoding.ASCII.GetBytes(character.Name, data.Slice(offset + 4, 20)); // Job Data data[offset + 24] = character.Job.FirstJob; data[offset + 25] = character.Job.SecondJob; data[offset + 26] = character.Job.ThirdJob; data[offset + 27] = character.Job.FourthJob; data[offset + 28] = (byte)character.Gender; BinaryPrimitives.WriteUInt16LittleEndian(data.Slice(offset + 29, 2), character.Level); data[offset + 31] = (byte)character.Experience; // Stats BinaryPrimitives.WriteInt16LittleEndian(data.Slice(offset + 32, 2), character.Stats.Strength); BinaryPrimitives.WriteInt16LittleEndian(data.Slice(offset + 34, 2), character.Stats.Dexterity); BinaryPrimitives.WriteInt16LittleEndian(data.Slice(offset + 36, 2), character.Stats.Intelligence); BinaryPrimitives.WriteInt16LittleEndian(data.Slice(offset + 38, 2), character.Stats.Vitality); BinaryPrimitives.WriteInt16LittleEndian(data.Slice(offset + 40, 2), character.Stats.Luck); BinaryPrimitives.WriteInt16LittleEndian(data.Slice(offset + 42, 2), character.Stats.Wisdom); BinaryPrimitives.WriteInt32LittleEndian(data.Slice(offset + 44, 4), character.Health); BinaryPrimitives.WriteInt32LittleEndian(data.Slice(offset + 48, 4), character.Mana); for (var j = 0; j < 20; j++) { // Equipped Items BinaryPrimitives.WriteUInt16LittleEndian(data.Slice(offset + 52 + j * 2, 2), character.EquippedItems.Length > j ? character.EquippedItems[j] : (ushort)0); // Equipped Cash Items BinaryPrimitives.WriteUInt16LittleEndian(data.Slice(offset + 92 + j * 2, 2), character.EquippedCashItems.Length > j ? character.EquippedCashItems[j] : (ushort)0); } } return data.ToArray(); } }