async def handle_packet(stream: Stream): packet_length = 0 # Basically an implementation of Buffer.unpack_varint() # except designed to read directly from a a StreamReader # and also to handle legacy server list ping packets for i in range(5): try: read = await asyncio.wait_for(stream.read(1), 5) except asyncio.TimeoutError: logger.debug("Closing due to timeout on read...") return False, stream if read == b"": logger.debug("Closing due to invalid read....") return False, stream if i == 0 and read == b"\xFE": logger.warn("Legacy ping attempted, legacy ping is not supported.") return False, stream b = struct.unpack("B", read)[0] packet_length |= (b & 0x7F) << 7 * i if not b & 0x80: break if packet_length & (1 << 31): packet_length -= 1 << 32 buf = Buffer(await stream.read(packet_length)) state = STATES.encode(states.get(stream.remote, 0)) packet = buf.unpack_packet(state, PACKET_MAP) logger.debug( f"IN : state:{state:<11} | id:0x{packet.id:02X} | packet:{type(packet).__name__}" ) for handler in pymine_api.packet.PACKET_HANDLERS[state][packet.id]: resp_value = await handler(stream, packet) try: continue_, stream = resp_value except ( ValueError, TypeError, ): logger.warn( f"Invalid return from packet handler: {handler.__module__}.{handler.__qualname__}" ) continue if not continue_: return False, stream return continue_, stream
async def handle_packet( self, stream: Stream ): # Handle / respond to packets, this is called in a loop packet_length = 0 # Basically an implementation of Buffer.unpack_varint() # except designed to read directly from a a StreamReader # and also to handle legacy server list ping packets for i in range(3): try: read = await asyncio.wait_for(stream.read(1), 30) except asyncio.TimeoutError: self.console.debug("Closing due to timeout on read...") raise StopHandling if read == b"": self.console.debug("Closing due to invalid read....") raise StopHandling if i == 0 and read == b"\xFE": self.console.warn("Legacy ping attempted, legacy ping is not supported.") raise StopHandling b = struct.unpack(">B", read)[0] packet_length |= (b & 0x7F) << 7 * i if not b & 0x80: break if packet_length & (1 << 31): packet_length -= 1 << 32 buf = Buffer(await stream.read(packet_length)) state = self.cache.states.get(stream.remote, 0) try: packet = buf.unpack_packet(state, PACKET_MAP) except InvalidPacketID: self.console.warn("Invalid packet ID received.") return stream self.console.debug( f"IN : state: {state} | id:0x{packet.id:02X} | packet:{type(packet).__name__}" ) if self.api.register._on_packet[state].get(packet.id) is None: self.console.warn( f"No packet handler found for packet: 0x{packet.id:02X} {type(packet).__name__}" ) return stream for handler in self.api.register._on_packet[state][packet.id].values(): try: res = await handler(stream, packet) if isinstance(res, Stream): stream = res except StopHandling: raise except BaseException as e: self.console.error( f"Error occurred in {handler.__module__}.{handler.__qualname__}: {self.console.f_traceback(e)}" ) return stream