예제 #1
0
        private bool TryReadPacket(MinecraftStream stream, out int lastPacketId)
        {
            Packets.Packet packet = null;
            int            packetId;

            byte[] packetData;

            if (!CompressionEnabled)
            {
                int length = stream.ReadVarInt();

                int packetIdLength;
                packetId     = stream.ReadVarInt(out packetIdLength);
                lastPacketId = packetId;

                if (length - packetIdLength > 0)
                {
                    packetData = stream.Read(length - packetIdLength);
                }
                else
                {
                    packetData = new byte[0];
                }
            }
            else
            {
                int packetLength = stream.ReadVarInt();

                int br;
                int dataLength = stream.ReadVarInt(out br);

                int readMore;

                if (dataLength == 0)
                {
                    packetId     = stream.ReadVarInt(out readMore);
                    lastPacketId = packetId;
                    packetData   = stream.Read(packetLength - (br + readMore));
                }
                else
                {
                    var data = stream.ReadToSpan(packetLength - br);

                    using (MinecraftStream a = new MinecraftStream())
                    {
                        using (ZlibStream outZStream = new ZlibStream(
                                   a, CompressionMode.Decompress, CompressionLevel.Default, true))
                        {
                            outZStream.Write(data);
                            //  outZStream.Write(data, 0, data.Length);
                        }

                        a.Seek(0, SeekOrigin.Begin);

                        int l;
                        packetId     = a.ReadVarInt(out l);
                        lastPacketId = packetId;
                        packetData   = a.Read(dataLength - l);
                    }
                }
            }

            packet = MCPacketFactory.GetPacket(PacketDirection, ConnectionState, packetId);

            Interlocked.Increment(ref PacketsIn);
            Interlocked.Add(ref PacketSizeIn, packetData.Length);

            if (packet == null)
            {
                if (UnhandledPacketsFilter[ConnectionState].TryAdd(packetId, 1))
                {
                    Log.Debug(
                        $"Unhandled packet in {ConnectionState}! 0x{packetId.ToString("x2")} = {(ConnectionState == ConnectionState.Play ? MCPacketFactory.GetPlayPacketName(packetId) : "Unknown")}");
                }
                else
                {
                    UnhandledPacketsFilter[ConnectionState][packetId] =
                        UnhandledPacketsFilter[ConnectionState][packetId] + 1;
                }

                return(false);
            }

            //    Log.Info($"Received: {packet}");

            if (ConnectionState == ConnectionState.Play)
            {
                if (ShouldAddToProcessing(packet))
                {
                    // Interlocked.Increment(ref _queued);

                    // ThreadPool.QueueUserWorkItem(
                    //	    () =>
                    //	    {
                    ProcessPacket(packet, packetData);
                    //   Interlocked.Decrement(ref _queued);
                    //	    });

                    return(true);
                }
            }
            else
            {
                ProcessPacket(packet, packetData);

                return(true);
            }

            return(false);
        }