Пример #1
0
        public bool read(IBaseClient client, SuperPacket <PQ> superpacket, IMarshal marshal)
        {
            timestampBlockId = ExpectedTickId;
            timestamp        = DateTimeExtensions.now();

            if (!client.hasPendingSuperPackets())
            {
                if (++sinceLastRecv >= Constants.MaxBlocksUntilDisconnection)
                {
                    client.disconnect();
                    return(false);
                }

                marshal.Update(client, ExpectedTickId);
                ExpectedTickId = Overflow.inc(ExpectedTickId);
                return(false);
            }

            sinceLastRecv = 0;
            ushort expectedId = ExpectedTickId;

            if (!Constants.UseKumoQueues)
            {
                ExpectedTickId = Overflow.sub(ExpectedTickId, bufferSize);
            }

            while (client.hasPendingSuperPackets() &&
                   !Overflow.ge(client.firstSuperPacketTickId(), expectedId))
            {
                read_impl(client, superpacket, marshal);
            }

            marshal.Update(client, ExpectedTickId);
            ExpectedTickId = Overflow.inc(ExpectedTickId);
            return(true);
        }
Пример #2
0
        public bool finish(ushort tickId, bool isFirst)
        {
            _buffer.reset();

            //  First two bytes are tick id, next two id, finally 1 byte for flags
            _buffer.write(tickId);
            _buffer.write(_id);
            _buffer.write(_flags);

            // Reset if there is something we must ack
            bool hasAcks = _mustAck;

            _mustAck = false;

            // Write acks and move for next id
            // Moving acks bitset only happens if no doing handshake (ie. if incrementing id)
            _buffer.write(_ackBase);
            _buffer.write(_pendingAcks);

            //  -1 is to account for the number of blocks
            ushort remaining = (ushort)(MAX_SIZE - _buffer.getPosition() - 1 - 1);

            // During handshake/resync do not include any packets
            bool hasData = false;

            _last_left_data = false;
            if (!HasFlag(SuperPacketFlags.Handshake))
            {
                // Organize packets that must be resent until ack'ed
                SortedDictionary <uint, List <Packet> > by_block = new SortedDictionary <uint, List <Packet> >();

                _queues.process(tickId, _id, ref remaining, ref _last_left_data, by_block);

                // Write number of blocks
                _buffer.write((byte)by_block.Count);

                // Has there been any overflow? That can be detected by, for example
                //  checking max-min>thr
                hasData = by_block.Count != 0;
                if (hasData)
                {
                    uint   max       = by_block.Keys.ToList()[by_block.Count - 1]; // TODO(gpascualg): Linq .Last()?
                    ushort threshold = ushort.MaxValue / 2;

                    foreach (var key in by_block.Keys.ToList())
                    {
                        if (max - key < threshold)
                        {
                            break;
                        }

                        // Overflows are masked higher, so that they get pushed to the end
                        //  of the map
                        uint masked = (Convert.ToUInt32(1) << 16) | key;
                        by_block.Add(masked, by_block[key]);
                        by_block.Remove(key);
                    }

                    // Write in packets
                    foreach (var entry in by_block)
                    {
                        _buffer.write((ushort)Convert.ToUInt16(entry.Key & 0xffff));
                        _buffer.write((byte)entry.Value.Count);

                        UnityEngine.Assertions.Assert.AreNotEqual(entry.Value.Count, 0);
                        foreach (var packet in entry.Value)
                        {
                            if (entry.Key == _id)
                            {
                                packet.finish(_counter++);
                            }

                            _buffer.write(packet);
                        }
                    }
                }
            }

            // Increment _id for next iter and acks
            _id = Overflow.inc(_id);
            return(hasAcks || hasData || (isFirst && _flags != 0));
        }