예제 #1
0
        public PacketHandler(Ts3Crypt ts3Crypt)
        {
            packetAckManager = new Dictionary <ushort, C2SPacket>();
            receiveQueue     = new RingQueue <S2CPacket>(ReceivePacketWindowSize, ushort.MaxValue + 1);
            receiveQueueLow  = new RingQueue <S2CPacket>(ReceivePacketWindowSize, ushort.MaxValue + 1);
            NetworkStats     = new NetworkStats();

            packetCounter     = new ushort[9];
            generationCounter = new uint[9];
            this.ts3Crypt     = ts3Crypt;
            resendThreadId    = -1;
        }
예제 #2
0
        public PacketHandler(Ts3Crypt ts3Crypt)
        {
            packetAckManager  = new Dictionary <ushort, OutgoingPacket>();
            packetPingManager = new Dictionary <ushort, OutgoingPacket>();
            receiveQueue      = new RingQueue <IncomingPacket>(PacketBufferSize);
            receiveQueueLow   = new RingQueue <IncomingPacket>(PacketBufferSize);
            NetworkStats      = new NetworkStats();

            packetCounter  = new ushort[9];
            this.ts3Crypt  = ts3Crypt;
            resendThreadId = -1;
        }
예제 #3
0
        public PacketHandler(Ts3Crypt ts3Crypt, Id id)
        {
            receiveQueueCommand       = new RingQueue <Packet <TIn> >(ReceivePacketWindowSize, ushort.MaxValue + 1);
            receiveQueueCommandLow    = new RingQueue <Packet <TIn> >(ReceivePacketWindowSize, ushort.MaxValue + 1);
            receiveWindowVoice        = new GenerationWindow(ushort.MaxValue + 1);
            receiveWindowVoiceWhisper = new GenerationWindow(ushort.MaxValue + 1);

            NetworkStats = new NetworkStats();

            packetCounter     = new ushort[Ts3Crypt.PacketTypeKinds];
            generationCounter = new uint[Ts3Crypt.PacketTypeKinds];
            this.ts3Crypt     = ts3Crypt;
            this.id           = id;
        }
예제 #4
0
        public PacketHandler(Ts3Crypt ts3Crypt)
        {
            Util.Init(out packetAckManager);
            receiveQueueCommand       = new RingQueue <Packet <TIn> >(ReceivePacketWindowSize, ushort.MaxValue + 1);
            receiveQueueCommandLow    = new RingQueue <Packet <TIn> >(ReceivePacketWindowSize, ushort.MaxValue + 1);
            receiveWindowVoice        = new GenerationWindow(ushort.MaxValue + 1);
            receiveWindowVoiceWhisper = new GenerationWindow(ushort.MaxValue + 1);

            NetworkStats = new NetworkStats();

            packetCounter     = new ushort[Ts3Crypt.PacketTypeKinds];
            generationCounter = new uint[Ts3Crypt.PacketTypeKinds];
            this.ts3Crypt     = ts3Crypt;
            resendThreadId    = -1;
        }
예제 #5
0
        private S2CPacket ReceiveCommand(S2CPacket packet, RingQueue <S2CPacket> packetQueue, PacketType ackType)
        {
            var setStatus = packetQueue.IsSet(packet.PacketId);

            // Check if we cannot accept this packet since it doesn't fit into the receive window
            if (setStatus == ItemSetStatus.OutOfWindowNotSet)
            {
                return(null);
            }

            packet.GenerationId = packetQueue.GetGeneration(packet.PacketId);
            SendAck(packet.PacketId, ackType);

            // Check if we already have this packet and only need to ack it.
            if (setStatus == ItemSetStatus.InWindowSet || setStatus == ItemSetStatus.OutOfWindowSet)
            {
                return(null);
            }

            packetQueue.Set(packet.PacketId, packet);
            return(TryFetchPacket(packetQueue, out var retPacket) ? retPacket : null);
        }
예제 #6
0
        private static bool TryFetchPacket(RingQueue <IncomingPacket> packetQueue, out IncomingPacket packet)
        {
            if (packetQueue.Count <= 0)
            {
                packet = null; return(false);
            }

            int  take     = 0;
            int  takeLen  = 0;
            bool hasStart = false;
            bool hasEnd   = false;

            for (int i = 0; i < packetQueue.Count; i++)
            {
                IncomingPacket peekPacket;
                if (packetQueue.TryPeekStart(i, out peekPacket))
                {
                    take++;
                    takeLen += peekPacket.Size;
                    if (peekPacket.FragmentedFlag)
                    {
                        if (!hasStart)
                        {
                            hasStart = true;
                        }
                        else if (!hasEnd)
                        {
                            hasEnd = true; break;
                        }
                    }
                    else
                    {
                        if (!hasStart)
                        {
                            hasStart = true; hasEnd = true; break;
                        }
                    }
                }
                else
                {
                    break;
                }
            }

            if (!hasStart || !hasEnd)
            {
                packet = null; return(false);
            }

            // GET
            if (!packetQueue.TryDequeue(out packet))
            {
                throw new InvalidOperationException("Packet in queue got missing (?)");
            }

            if (take > 1)             // MERGE
            {
                var preFinalArray = new byte[takeLen];

                // for loop at 0th element
                int curCopyPos = packet.Size;
                Array.Copy(packet.Data, 0, preFinalArray, 0, packet.Size);

                for (int i = 1; i < take; i++)
                {
                    IncomingPacket nextPacket = null;
                    if (!packetQueue.TryDequeue(out nextPacket))
                    {
                        throw new InvalidOperationException("Packet in queue got missing (?)");
                    }

                    Array.Copy(nextPacket.Data, 0, preFinalArray, curCopyPos, nextPacket.Size);
                    curCopyPos += nextPacket.Size;
                }
                packet.Data = preFinalArray;
            }

            // DECOMPRESS
            if (packet.CompressedFlag)
            {
                if (QuickLZ.SizeDecompressed(packet.Data) > MaxDecompressedSize)
                {
                    throw new InvalidOperationException("Compressed packet is too large");
                }
                packet.Data = QuickLZ.Decompress(packet.Data);
            }
            return(true);
        }
예제 #7
0
        private static bool TryFetchPacket(RingQueue <S2CPacket> packetQueue, out S2CPacket packet)
        {
            if (packetQueue.Count <= 0)
            {
                packet = null; return(false);
            }

            int  take     = 0;
            int  takeLen  = 0;
            bool hasStart = false;
            bool hasEnd   = false;

            for (int i = 0; i < packetQueue.Count; i++)
            {
                if (packetQueue.TryPeekStart(i, out var peekPacket))
                {
                    take++;
                    takeLen += peekPacket.Size;
                    if (peekPacket.FragmentedFlag)
                    {
                        if (!hasStart)
                        {
                            hasStart = true;
                        }
                        else
                        {
                            hasEnd = true; break;
                        }
                    }
                    else
                    {
                        if (!hasStart)
                        {
                            hasStart = true; hasEnd = true; break;
                        }
                    }
                }
                else
                {
                    break;
                }
            }

            if (!hasStart || !hasEnd)
            {
                packet = null; return(false);
            }

            // GET
            if (!packetQueue.TryDequeue(out packet))
            {
                throw new InvalidOperationException("Packet in queue got missing (?)");
            }

            // MERGE
            if (take > 1)
            {
                var preFinalArray = new byte[takeLen];

                // for loop at 0th element
                int curCopyPos = packet.Size;
                Array.Copy(packet.Data, 0, preFinalArray, 0, packet.Size);

                for (int i = 1; i < take; i++)
                {
                    if (!packetQueue.TryDequeue(out S2CPacket nextPacket))
                    {
                        throw new InvalidOperationException("Packet in queue got missing (?)");
                    }

                    Array.Copy(nextPacket.Data, 0, preFinalArray, curCopyPos, nextPacket.Size);
                    curCopyPos += nextPacket.Size;
                }
                packet.Data = preFinalArray;
            }

            // DECOMPRESS
            if (packet.CompressedFlag)
            {
                try
                {
                    packet.Data = QuickerLz.Decompress(packet.Data, MaxDecompressedSize);
                }
                catch (Exception)
                {
                    Debug.WriteLine("Got invalid compressed data.");
                    return(false);
                }
            }
            return(true);
        }