private void SendDatagram(Packet packet) { lastAckSent = receivedTotal; packet.Stream.Position = PACKET_RELIABLE_STATE_OFFSET * 8; packet.Stream.WriteByte(reliableStateIn); packet.Stream.Position = PACKET_RELIABLE_STATE_OFFSET * 8; ushort crc = CrcUtils.Compute16(packet.Stream); packet.Stream.Position = 0; packet.Stream.WriteUInt32(packet.Seq); packet.Stream.WriteUInt32(packet.Ack); packet.Stream.WriteByte(packet.Flags); packet.Stream.WriteUInt16(crc); byte[] bytes = new byte[packet.Stream.Length]; packet.Stream.Position = 0; packet.Stream.Read(bytes, 0, bytes.Length); socket.Send(bytes); }
private void ProcessPacket(byte[] bytes, int length) { using (var stream = Bitstream.CreateWith(bytes, length)) { var seq = stream.ReadUInt32(); var ack = stream.ReadUInt32(); var flags = stream.ReadByte(); var checksum = stream.ReadUInt16(); var at = stream.Position; var computed = CrcUtils.Compute16(stream); stream.Position = at; if (checksum != computed) { return; } var reliableState = stream.ReadByte(); if (seq < sequenceIn) { // We no longer care. return; } for (byte i = 0; i < subchannels.Length; ++i) { var channel = subchannels[i]; var mask = 1 << i; if ((reliableStateOut & mask) == (reliableState & mask)) { if (channel.Blocked) { channel.Clear(); } } else { if (channel.Blocked && channel.SentIn < ack) { reliableStateOut = Flip(reliableStateOut, i); channel.Requeue(); } } } if ((flags & (uint)PacketFlags.IsReliable) != 0) { var bit = stream.ReadBits(3); reliableStateIn = Flip(reliableStateIn, bit); for (var i = 0; i < streams.Length; ++i) { var message = streams[i].Receive(stream); if (message.HasValue) { ProcessMessage(message.Value); } } } while (stream.HasByte()) { HandleMessage(stream); } if (!stream.Eof) { var remain = (byte)stream.Remain; var expect = (1 << remain) - 1; var expectedTru = stream.ReadBits(remain) == expect; // if false then probably something wrong } lastAckRecv = ack; sequenceIn = seq; } }
private void ProcessPacket(byte[] bytes, int length) { using (var stream = Bitstream.CreateWith(bytes, length)) { uint seq = stream.ReadUInt32(); uint ack = stream.ReadUInt32(); byte flags = stream.ReadByte(); ushort checksum = stream.ReadUInt16(); long at = stream.Position; ushort computed = CrcUtils.Compute16(stream); stream.Position = at; if (checksum != computed) { log.WarnFormat( "failed checksum:" + "recv seq {0} ack {1} flags {2:x} checksum {3:x} computed {4:x}", seq, ack, flags, checksum, computed); return; } byte reliableState = stream.ReadByte(); if ((flags & 0x10) == 0x10) { log.WarnFormat( "choke {0}: recv seq {1} ack {2} flags {3:x}", stream.ReadByte(), seq, ack, flags); } if (seq < sequenceIn) { // We no longer care. log.WarnFormat("dropped: recv seq {0} ack {1}", seq, ack); return; } for (byte i = 0; i < subchannels.Length; ++i) { Subchannel channel = subchannels[i]; int mask = 1 << i; if ((reliableStateOut & mask) == (reliableState & mask)) { if (channel.Blocked) { Preconditions.CheckArgument(ack >= channel.SentIn); channel.Clear(); } } else { if (channel.Blocked && channel.SentIn < ack) { reliableStateOut = Flip(reliableStateOut, i); channel.Requeue(); } } } if ((flags & (uint)PacketFlags.IsReliable) != 0) { uint bit = stream.ReadBits(3); //Debug.WriteLine(" reliable, flip {0}. {1} => {2}", bit, reliableStateIn, Flip(reliableStateIn, bit)); reliableStateIn = Flip(reliableStateIn, bit); for (int i = 0; i < streams.Length; ++i) { Nullable <Stream.Message> message = streams[i].Receive(stream); if (message.HasValue) { ProcessMessage(message.Value); } } } while (stream.HasByte()) { HandleMessage(stream); } if (!stream.Eof) { byte remain = (byte)stream.Remain; int expect = (1 << remain) - 1; Preconditions.CheckArgument(stream.ReadBits(remain) == expect); } lastAckRecv = ack; sequenceIn = seq; } }
private static void ProcessPacket(byte[] bytes) { var length = bytes.Length; uint seq, ack; byte flags; using (var stream = BitStreamUtil.Create(bytes)) { seq = stream.ReadInt(32); ack = stream.ReadInt(32); flags = stream.ReadByte(); ushort checksum = (ushort)stream.ReadInt(16); stream.BeginChunk((length - 11) * 8); ushort computed = CrcUtils.Compute16(stream); stream.EndChunk(); if (checksum != computed) { //Console.WriteLine( // "failed checksum:" // + "recv seq {0} ack {1} flags {2:x} checksum {3:x} computed {4:x}", // seq, ack, flags, checksum, computed); return; } } var remaining = new byte[length - 11]; Array.Copy(bytes, 11, remaining, 0, length - 11); using (var stream = BitStreamUtil.Create(remaining)) { byte reliableState = stream.ReadByte(); if ((flags & 0x10) == 0x10) { //Console.WriteLine( // "choke {0}: recv seq {1} ack {2} flags {3:x}", // stream.ReadByte(), seq, ack, flags); return; } if (seq < sequenceIn) { // We no longer care. //Console.WriteLine("dropped: recv seq {0} ack {1}", seq, ack); return; } if ((flags & (uint)PacketFlags.IsReliable) != 0) { return; } //filter2++; //Console.WriteLine($"filter2: {filter2}"); try { stream.BeginChunk((remaining.Length - 1) * 8); DemoPacketParser.ParsePacket(stream, demoParser); stream.EndChunk(); demoParser.ForceTick(true); } catch { } lastAckRecv = ack; sequenceIn = seq; } }