sources/network/rconsession.cpp

branch
protocol5
changeset 167
0150f86e68f0
parent 166
af5fa8c43ca8
child 169
febc3ed5435c
equal deleted inserted replaced
166:af5fa8c43ca8 167:0150f86e68f0
31 #include <time.h> 31 #include <time.h>
32 #include "rconsession.h" 32 #include "rconsession.h"
33 #include "../interface.h" 33 #include "../interface.h"
34 BEGIN_ZFC_NAMESPACE 34 BEGIN_ZFC_NAMESPACE
35 35
36 struct PacketHeader
37 {
38 int32_t header;
39 int sequenceNumber;
40 };
41
36 // ------------------------------------------------------------------------------------------------- 42 // -------------------------------------------------------------------------------------------------
37 // 43 //
38 RCONSession::RCONSession() : 44 RCONSession::RCONSession() :
39 m_state(RCON_DISCONNECTED), 45 m_state(RCON_DISCONNECTED),
40 m_lastPing(0), 46 m_lastPing(0),
41 m_adminCount(0), 47 m_adminCount(0),
48 m_lastMissingPacketRequest(0),
42 m_interface(nullptr) 49 m_interface(nullptr)
43 { 50 {
44 if (not m_socket.set_blocking(false)) 51 if (not m_socket.set_blocking(false))
45 { 52 {
46 fprintf(stderr, "unable to set socket as non-blocking: %s\n", 53 fprintf(stderr, "unable to set socket as non-blocking: %s\n",
109 send({CLRC_PONG}); 116 send({CLRC_PONG});
110 bumpLastPing(); 117 bumpLastPing();
111 } 118 }
112 } 119 }
113 120
121 // Check for new packets in our socket
114 for (Datagram datagram; m_socket.read(datagram);) 122 for (Datagram datagram; m_socket.read(datagram);)
115 handlePacket(datagram); 123 {
116 } 124 // Packet came from the wrong address, ignore
117 125 if (datagram.address != m_address)
118 // ------------------------------------------------------------------------------------------------- 126 continue;
119 // 127
120 void RCONSession::handlePacket(Datagram& datagram) 128 // Parse and cut off the header.
121 { 129 PacketHeader header;
122 if (datagram.address != m_address) 130 {
123 return; 131 // Read the header, and find the sequence number
124 132 Bytestream stream(datagram.message);
125 Bytestream stream(datagram.message); 133 header.header = stream.readLong();
134 header.sequenceNumber = (header.header != 0) ? stream.readLong() : -1;
135 datagram.message = datagram.message.splice(stream.position(), datagram.message.size());
136 }
137
138 // Try to store this packet into the queue. However, do not try to store packets without a sequence number.
139 bool stored = false;
140
141 if (header.sequenceNumber != -1)
142 stored = m_packetQueue.addPacket(header.sequenceNumber, datagram.message);
143
144 // If the packet was not stored, we are to just process it right away.
145 if (stored == false)
146 handlePacket(datagram.message);
147 }
148
149 // Check if we can now also process some packets from the queue.
150 if (m_packetQueue.hasPacketsToPop())
151 {
152 ByteArray message;
153 while (m_packetQueue.popNextPacket(message))
154 handlePacket(message);
155 }
156
157 // Check whether there are packets stuck in the queue. If this is the case, we have lost some packets and need to
158 // ask the game server to re-send them.
159 if (m_packetQueue.isStuck() and m_lastMissingPacketRequest + 1 < time(NULL))
160 {
161 m_interface->printWarning("Missing packets detected. Packets currently in queue:\n");
162
163 for (int packetNumber : m_packetQueue.getWaitingPackets())
164 m_interface->printWarning("- %d:\n", packetNumber);
165
166 m_lastMissingPacketRequest = time(NULL);
167 ByteArray message;
168 Bytestream stream(message);
169 stream.writeByte(CLRC_MISSINGPACKET);
170
171 for (int packetNumber : m_packetQueue.getLostPackets())
172 {
173 m_interface->printWarning("Requesting lost packet %d\n", packetNumber);
174 stream.writeLong(packetNumber);
175 }
176
177 send(message);
178 }
179 }
180
181 // -------------------------------------------------------------------------------------------------
182 //
183 void RCONSession::handlePacket(ByteArray& message)
184 {
185 Bytestream stream(message);
126 186
127 try 187 try
128 { 188 {
129 int32_t header = stream.readLong();
130 int32_t sequenceNumber = (header != 0) ? stream.readLong() : 0;
131 m_interface->print("Recieved packet with header 0x%x and sequence number #%d\n", header, sequenceNumber);
132
133 while (stream.bytesLeft() > 0) 189 while (stream.bytesLeft() > 0)
134 { 190 {
135 int header = stream.readByte(); 191 int header = stream.readByte();
136 192
137 switch (ServerResponse(header)) 193 switch (ServerResponse(header))

mercurial