sources/network/rconsession.cpp

branch
protocol5
changeset 172
0b0bc8045d28
parent 171
d0fba0d7ad03
child 177
131518f86af6
--- a/sources/network/rconsession.cpp	Wed Jan 27 12:34:26 2021 +0200
+++ b/sources/network/rconsession.cpp	Wed Jan 27 12:34:56 2021 +0200
@@ -45,6 +45,7 @@
 	m_state(RCON_DISCONNECTED),
 	m_lastPing(0),
 	m_adminCount(0),
+    m_lastMissingPacketRequest(0),
 	m_interface(nullptr)
 {
 	if (not m_socket.set_blocking(false))
@@ -122,7 +123,58 @@
 	{
 		// Only process packets that originate from the game server.
 		if (datagram.address == m_address)
-			handlePacket(datagram.message);
+		{
+			// Parse and cut off the header.
+			PacketHeader header;
+			{
+				// Read the header, and find the sequence number
+				Bytestream stream(datagram.message);
+				header.header = stream.readLong();
+				header.sequenceNumber = (header.header != 0) ? stream.readLong() : -1;
+				datagram.message = datagram.message.splice(stream.position(), datagram.message.size());
+			}
+
+			// Try to store this packet into the queue. However, do not try to store packets without a sequence number.
+			bool stored = false;
+
+			if (header.sequenceNumber != -1)
+				stored = m_packetQueue.addPacket(header.sequenceNumber, datagram.message);
+
+			// If the packet was not stored, we are to just process it right away.
+			if (stored == false)
+				handlePacket(datagram.message);
+		}
+	}
+
+	// Check if we can now also process some packets from the queue.
+	if (m_packetQueue.hasPacketsToPop())
+	{
+		ByteArray message;
+		while (m_packetQueue.popNextPacket(message))
+			handlePacket(message);
+	}
+
+	// Check whether there are packets stuck in the queue. If this is the case, we have lost some packets and need to
+	// ask the game server to re-send them.
+	if (m_packetQueue.isStuck()  and  m_lastMissingPacketRequest + 1 < time(NULL))
+	{
+		m_interface->printWarning("Missing packets detected. Packets currently in queue:\n");
+
+		for (int packetNumber : m_packetQueue.getWaitingPackets())
+			m_interface->printWarning("- %d:\n", packetNumber);
+
+		m_lastMissingPacketRequest = time(NULL);
+		ByteArray message;
+		Bytestream stream(message);
+		stream.writeByte(CLRC_MISSINGPACKET);
+
+		for (int packetNumber : m_packetQueue.getLostPackets())
+		{
+			m_interface->printWarning("Requesting lost packet %d\n", packetNumber);
+			stream.writeLong(packetNumber);
+		}
+
+		send(message);
 	}
 }
 

mercurial