public static MinecraftPacket CreateClientPacket(MinecraftClient client, MemoryStream stream, ProtocolState state) { int id = -1; if (client.EncryptionEnabled) { byte[] decrypted = client.Decryptor.ProcessBytes(stream.ToArray(), 0, (int)stream.Length); stream.Position = 0; stream.SetLength(0); stream.Write(decrypted); stream.Position = 0; } if (!client.CompressionEnabled) { VarInt varInt = new(); varInt.Read(stream); varInt.Read(stream); id = varInt.Value; stream.Position = 0; } else { int packetLength = new VarInt(stream).Value; long _pos = stream.Position; int length = new VarInt(stream).Value; if (length == 0) // packet is uncompressed { id = new VarInt(stream).Value; byte[] data = new byte[packetLength - 1]; stream.Read(data, 0, data.Length); stream.Position = 0; stream.SetLength(0); new VarInt(id).Write(stream); stream.Write(data); stream.Position = 0; } else { byte[] compressedData = new byte[packetLength - _pos]; stream.Read(compressedData, 0, compressedData.Length); CompressionUtils.ZLibDecompress(compressedData, out byte[] data); using (MemoryStream output = RMSManager.Get().GetStream(data)) { _pos = output.Position; id = new VarInt(output).Value; } stream.Position = 0; stream.SetLength(0); stream.Write(data); stream.Position = 0; } } Func <MinecraftClient, Stream, MinecraftPacket> ctor; switch (state) { case ProtocolState.Handshaking: ctor = clientPacketConstructors[0][id]; return(ctor?.Invoke(client, stream)); case ProtocolState.Status: ctor = clientPacketConstructors[1][id]; return(ctor?.Invoke(client, stream)); case ProtocolState.Login: ctor = clientPacketConstructors[2][id]; return(ctor?.Invoke(client, stream)); case ProtocolState.Play: ctor = clientPacketConstructors[3][id]; return(ctor?.Invoke(client, stream)); } return(null); }