public override async Task Initialize(TcpClient client) { await base.Initialize(client); Log("-- connected"); Crypt = new AuthCrypt(); // TODO DI?? await Send(new SMSG_AUTH_CHALLENGE().Get()); await HandleConnection(); }
public static IEnumerable <WorldPacket> FromBuffer(byte[] buffer, WorldPacketFlags flags = WorldPacketFlags.None, AuthCrypt crypt = null) { using (var ms = new MemoryStream(buffer)) using (var br = new BinaryReader(ms)) using (var bw = new BinaryWriter(ms)) { while (ms.Position < buffer.Length) { var pkt = new WorldPacket(); if (flags.HasFlag(WorldPacketFlags.GUIDPrefix)) { pkt.GUID = br.ReadUInt64(); pkt.TotalLength += 8; } pkt.Header = new WorldPacketHeader(); var headerSize = flags.HasFlag(WorldPacketFlags.Outbound) ? 4 : 6; var headerBytes = br.ReadBytes(headerSize); pkt.TotalLength += headerSize; if (flags.HasFlag(WorldPacketFlags.EncryptedHeader) && crypt != null) { // We do a null check, because the first received world packet is NOT encrypted //Console.WriteLine($"Encrypted: {string.Join(" ", headerBytes.Select(b => b.ToString("X2")))}"); crypt.Decrypt(headerBytes); bw.Seek(-6, SeekOrigin.Current); bw.Write(headerBytes); //Console.WriteLine($"Decrypted: {string.Join(" ", headerBytes.Select(b => b.ToString("X2")))}"); } pkt.Header.Length = BitConverter.ToUInt16(headerBytes, 0); if (flags.HasFlag(WorldPacketFlags.BigEndianLength)) // Client sends 6 byte header (4-byte opcode, 2-byte length) { pkt.Header.Length = pkt.Header.Length.SwitchEndian(); // TODO: eew? } //Console.WriteLine($"Length: {pkt.Header.Length}"); // This means we have received a partial packet, can't pass that on if (((ms.Position - headerSize + 2) + pkt.Header.Length) > buffer.Length) { break; } pkt.Header.Opcode = flags.HasFlag(WorldPacketFlags.Outbound) ? (WorldOpcodes)BitConverter.ToUInt16(headerBytes, 2) : (WorldOpcodes)BitConverter.ToUInt32(headerBytes, 2); //Console.WriteLine($"Opcode: {pkt.Header.Opcode}"); var payloadLength = pkt.Header.Length - (flags.HasFlag(WorldPacketFlags.Outbound) ? 2 : 4); pkt.TotalLength += payloadLength; pkt.Payload = new ArraySegment <byte>(buffer, (int)ms.Position, payloadLength); yield return(pkt); ms.Seek(payloadLength, SeekOrigin.Current); } } }