Skip to content

Commit a2aef78

Browse files
committed
Ensure only the latest packet is processed
1 parent 82ce6a5 commit a2aef78

File tree

4 files changed

+74
-38
lines changed

4 files changed

+74
-38
lines changed

rlbot/interface.py

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -250,43 +250,46 @@ def run(self, *, background_thread: bool = False):
250250
else:
251251
self._running = True
252252
while self._running and self.is_connected:
253-
self._running = self.handle_incoming_messages(blocking=True)
253+
self._running, _ = self.handle_incoming_messages(blocking=True)
254254
self._running = False
255255

256-
def handle_incoming_messages(self, blocking: bool = False) -> bool:
256+
def handle_incoming_messages(self, blocking: bool = False) -> tuple[bool, bool]:
257257
"""
258258
Empties queue of incoming messages (should be called regularly, see `run`).
259259
Optionally blocking, ensuring that at least one message will be handled.
260-
Returns true message handling should continue running, and
260+
261+
First boolean returns true message handling should continue running, and
261262
false if RLBotServer has asked us to shut down or an error happened.
263+
264+
Second boolean returns true if there might be more messages to handle without a delay.
262265
"""
263266
assert self.is_connected, "Connection has not been established"
264267
try:
265268
self.socket.setblocking(blocking)
266269
incoming_message = self.read_message()
267270
try:
268-
return self.handle_incoming_message(incoming_message)
271+
return self.handle_incoming_message(incoming_message), True
269272
except flat.InvalidFlatbuffer as e:
270273
self.logger.error(
271274
"Error while unpacking message of type %s (%s bytes): %s",
272275
incoming_message.type.name,
273276
len(incoming_message.data),
274277
e,
275278
)
276-
return False
279+
return False, False
277280
except Exception as e:
278281
self.logger.error(
279282
"Unexpected error while handling message of type %s: %s",
280283
incoming_message.type.name,
281284
e,
282285
)
283-
return False
286+
return False, False
284287
except BlockingIOError:
285288
# No incoming messages and blocking==False
286-
return True
289+
return True, False
287290
except:
288291
self.logger.error("SocketRelay disconnected unexpectedly!")
289-
return False
292+
return False, False
290293

291294
def handle_incoming_message(self, incoming_message: SocketMessage):
292295
"""

rlbot/managers/bot.py

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,26 @@ def _packet_processor(self, packet: flat.GamePacket):
151151
player_input = flat.PlayerInput(self.index, controller)
152152
self._game_interface.send_player_input(player_input)
153153

154+
def _run(self):
155+
running = True
156+
has_more_messages = True
157+
158+
while running:
159+
# If there might be more messages,
160+
# check for another one with blocking=False
161+
# if there are no more messages, this immediately returns with has_more_messages=False
162+
# after there are no more messages and we've processed the latest packet,
163+
# wait for the next one with blocking=True
164+
running, has_more_messages = self._game_interface.handle_incoming_messages(
165+
blocking=not has_more_messages
166+
)
167+
168+
# if there might be more messages, handle them first
169+
# this ensures that only the latest packet is processed
170+
if self._latest_packet is not None and running and not has_more_messages:
171+
self._packet_processor(self._latest_packet)
172+
self._latest_packet = None
173+
154174
def run(
155175
self,
156176
*,
@@ -172,16 +192,7 @@ def run(
172192
rlbot_server_port=rlbot_server_port,
173193
)
174194

175-
running = True
176-
while running:
177-
# Whenever we receive one or more game packets,
178-
# we want to process the latest one.
179-
running = self._game_interface.handle_incoming_messages(
180-
blocking=self._latest_packet is None
181-
)
182-
if self._latest_packet is not None and running:
183-
self._packet_processor(self._latest_packet)
184-
self._latest_packet = None
195+
self._run()
185196
except Exception as e:
186197
self.logger.error("Unexpected error: %s", e)
187198
finally:

rlbot/managers/hivemind.py

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,26 @@ def _packet_processor(self, packet: flat.GamePacket):
163163
player_input = flat.PlayerInput(index, controller)
164164
self._game_interface.send_player_input(player_input)
165165

166+
def _run(self):
167+
running = True
168+
has_more_messages = True
169+
170+
while running:
171+
# If there might be more messages,
172+
# check for another one with blocking=False
173+
# if there are no more messages, this immediately returns with has_more_messages=False
174+
# after there are no more messages and we've processed the latest packet,
175+
# wait for the next one with blocking=True
176+
running, has_more_messages = self._game_interface.handle_incoming_messages(
177+
blocking=not has_more_messages
178+
)
179+
180+
# if there might be more messages, handle them first
181+
# this ensures that only the latest packet is processed
182+
if self._latest_packet is not None and running and not has_more_messages:
183+
self._packet_processor(self._latest_packet)
184+
self._latest_packet = None
185+
166186
def run(
167187
self,
168188
*,
@@ -184,16 +204,7 @@ def run(
184204
rlbot_server_port=rlbot_server_port,
185205
)
186206

187-
running = True
188-
while running:
189-
# Whenever we receive one or more game packets,
190-
# we want to process the latest one.
191-
running = self._game_interface.handle_incoming_messages(
192-
blocking=self._latest_packet is None
193-
)
194-
if self._latest_packet is not None and running:
195-
self._packet_processor(self._latest_packet)
196-
self._latest_packet = None
207+
self._run()
197208
finally:
198209
self.retire()
199210
del self._game_interface

rlbot/managers/script.py

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,26 @@ def _packet_processor(self, packet: flat.GamePacket):
120120
)
121121
print_exc()
122122

123+
def _run(self):
124+
running = True
125+
has_more_messages = True
126+
127+
while running:
128+
# If there might be more messages,
129+
# check for another one with blocking=False
130+
# if there are no more messages, this immediately returns with has_more_messages=False
131+
# after there are no more messages and we've processed the latest packet,
132+
# wait for the next one with blocking=True
133+
running, has_more_messages = self._game_interface.handle_incoming_messages(
134+
blocking=not has_more_messages
135+
)
136+
137+
# if there might be more messages, handle them first
138+
# this ensures that only the latest packet is processed
139+
if self._latest_packet is not None and running and not has_more_messages:
140+
self._packet_processor(self._latest_packet)
141+
self._latest_packet = None
142+
123143
def run(
124144
self,
125145
*,
@@ -141,16 +161,7 @@ def run(
141161
rlbot_server_port=rlbot_server_port,
142162
)
143163

144-
running = True
145-
while running:
146-
# Whenever we receive one or more game packets,
147-
# we want to process the latest one.
148-
running = self._game_interface.handle_incoming_messages(
149-
blocking=self._latest_packet is None
150-
)
151-
if self._latest_packet is not None and running:
152-
self._packet_processor(self._latest_packet)
153-
self._latest_packet = None
164+
self._run()
154165
finally:
155166
self.retire()
156167
del self._game_interface

0 commit comments

Comments
 (0)