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); }
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)); }