示例#1
0
        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);
        }