43 // |
43 // |
44 RCONSession::RCONSession() : |
44 RCONSession::RCONSession() : |
45 m_state(RCON_DISCONNECTED), |
45 m_state(RCON_DISCONNECTED), |
46 m_lastPing(0), |
46 m_lastPing(0), |
47 m_adminCount(0), |
47 m_adminCount(0), |
48 m_lastMissingPacketRequest(0), |
|
49 m_interface(nullptr) |
48 m_interface(nullptr) |
50 { |
49 { |
51 if (not m_socket.set_blocking(false)) |
50 if (not m_socket.set_blocking(false)) |
52 { |
51 { |
53 fprintf(stderr, "unable to set socket as non-blocking: %s\n", |
52 fprintf(stderr, "unable to set socket as non-blocking: %s\n", |
121 // Check for new packets in our socket |
120 // Check for new packets in our socket |
122 for (Datagram datagram; m_socket.read(datagram);) |
121 for (Datagram datagram; m_socket.read(datagram);) |
123 { |
122 { |
124 // Only process packets that originate from the game server. |
123 // Only process packets that originate from the game server. |
125 if (datagram.address == m_address) |
124 if (datagram.address == m_address) |
126 { |
125 handlePacket(datagram.message); |
127 // Parse and cut off the header. |
|
128 PacketHeader header; |
|
129 { |
|
130 // Read the header, and find the sequence number |
|
131 Bytestream stream(datagram.message); |
|
132 header.header = stream.readLong(); |
|
133 header.sequenceNumber = (header.header != 0) ? stream.readLong() : -1; |
|
134 datagram.message = datagram.message.splice(stream.position(), datagram.message.size()); |
|
135 } |
|
136 |
|
137 // Try to store this packet into the queue. However, do not try to store packets without a sequence number. |
|
138 bool stored = false; |
|
139 |
|
140 if (header.sequenceNumber != -1) |
|
141 stored = m_packetQueue.addPacket(header.sequenceNumber, datagram.message); |
|
142 |
|
143 // If the packet was not stored, we are to just process it right away. |
|
144 if (stored == false) |
|
145 handlePacket(datagram.message); |
|
146 } |
|
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 } |
126 } |
179 } |
127 } |
180 |
128 |
181 // ------------------------------------------------------------------------------------------------- |
129 // ------------------------------------------------------------------------------------------------- |
182 // |
130 // |