/// <summary> /// Constructs and sends the <see cref="PacketOut.Login"/> packet to Wolfteam. /// </summary> /// <returns></returns> public async Task LoginAsync() { using (var packet = new PacketComposer(PacketOut.Login)) { // Add username (16 bytes). packet.Writer.Write(Encoding.ASCII.GetBytes(_account.Username)); // Username. packet.Writer.Write(new byte[16 - _account.Username.Length]); // Username padding (to 16 bytes). // Add unknown (16 bytes). packet.Writer.Write(_account.AuthRandom); // Auth uk (4 bytes). packet.Writer.Write(HexUtil.HexToBytes("60F41900")); // Unknown (4 bytes). packet.Writer.Write(HexUtil.HexToBytes("41F3DADA")); // Unknown (4 bytes) (Changes in between requests through real client). packet.Writer.Write(HexUtil.HexToBytes("60F41900")); // Unknown (4 bytes). // Add second payload (32 bytes) using (var subPacketStream = new MemoryStream(32)) using (var subPacket = new BinaryWriter(subPacketStream)) { subPacket.Write(Encoding.ASCII.GetBytes(_account.Password)); // Password. subPacket.Write(new byte[20 - _account.Password.Length]); // Password padding (to 20 bytes). subPacket.Write(WolfteamConfig.ClientVersion); // Client version (4 bytes). // Add checksums. const int subPacketId = 4114; var subPacketBuffer = subPacketStream.ToArray(); if (subPacketBuffer.Length % 12 != 0) { throw new Exception("Buffer length must be a multiple of 12."); } // Write checksums. subPacket.Seek(0, SeekOrigin.Begin); for (var index = 0; index < subPacketBuffer.Length / 12; index++) { subPacket.Write(WolfteamConfig.MagicChecksum + subPacketId); subPacket.Write(subPacketBuffer, index * 12, 12); } // Append to main packet. packet.AppendPayload(await _crypto.EncryptAsync(subPacketStream.ToArray())); } await SendPacketAsync(packet); } }