1010from rlbot import flat
1111from rlbot .utils .logging import get_logger
1212
13- # We can connect to RLBotServer on this port.
13+ MAX_SIZE_2_BYTES = 2 ** 16 - 1
14+ # The default port we can expect RLBotServer to be listening on.
1415RLBOT_SERVER_PORT = 23234
1516
1617
@@ -38,30 +39,12 @@ class SocketDataType(IntEnum):
3839 CONTROLLABLE_TEAM_INFO = 15
3940
4041
41- MAX_SIZE_2_BYTES = 2 ** 16 - 1
42-
43-
44- def int_to_bytes (val : int ) -> bytes :
45- return val .to_bytes (2 , byteorder = "big" )
46-
47-
48- def int_from_bytes (bytes : bytes ) -> int :
49- return int .from_bytes (bytes , "big" )
50-
51-
5242class SocketMessage :
5343 def __init__ (self , type : int , data : bytes ):
5444 self .type = SocketDataType (type )
5545 self .data = data
5646
5747
58- def read_message_from_socket (s : socket ) -> SocketMessage :
59- type_int = int_from_bytes (s .recv (2 ))
60- size = int_from_bytes (s .recv (2 ))
61- data = s .recv (size )
62- return SocketMessage (type_int , data )
63-
64-
6548class SocketRelay :
6649 """
6750 The SocketRelay provides an abstraction over the direct communication with
@@ -97,11 +80,36 @@ def __init__(
9780 self .logger = get_logger ("interface" ) if logger is None else logger
9881
9982 self .socket = socket ()
83+
84+ # Allow sending packets before getting a response from core
10085 self .socket .setsockopt (IPPROTO_TCP , TCP_NODELAY , 1 )
10186
10287 def __del__ (self ):
10388 self .socket .close ()
10489
90+ @staticmethod
91+ def _int_to_bytes (val : int ) -> bytes :
92+ return val .to_bytes (2 , byteorder = "big" )
93+
94+ def _read_int (self ) -> int :
95+ return int .from_bytes (self ._read_exact (2 ), "big" )
96+
97+ def _read_exact (self , n : int ) -> bytes :
98+ buff = bytearray (n )
99+ pos = 0
100+ while pos < n :
101+ cr = self .socket .recv_into (memoryview (buff )[pos :])
102+ if cr == 0 :
103+ raise EOFError
104+ pos += cr
105+ return bytes (buff )
106+
107+ def read_message (self ) -> SocketMessage :
108+ type_int = self ._read_int ()
109+ size = self ._read_int ()
110+ data = self ._read_exact (size )
111+ return SocketMessage (type_int , data )
112+
105113 def send_bytes (self , data : bytes , data_type : SocketDataType ):
106114 assert self .is_connected , "Connection has not been established"
107115
@@ -112,7 +120,7 @@ def send_bytes(self, data: bytes, data_type: SocketDataType):
112120 )
113121 return
114122
115- message = int_to_bytes (data_type ) + int_to_bytes (size ) + data
123+ message = self . _int_to_bytes (data_type ) + self . _int_to_bytes (size ) + data
116124 self .socket .sendall (message )
117125
118126 def send_init_complete (self ):
@@ -255,7 +263,7 @@ def handle_incoming_messages(self, blocking: bool = False) -> bool:
255263 assert self .is_connected , "Connection has not been established"
256264 try :
257265 self .socket .setblocking (blocking )
258- incoming_message = read_message_from_socket ( self .socket )
266+ incoming_message = self .read_message ( )
259267 try :
260268 return self .handle_incoming_message (incoming_message )
261269 except flat .InvalidFlatbuffer as e :
0 commit comments