Exemplo n.º 1
0
def combat_event(game_: "game.Game", data: bytes):
    """
    'Now only used to display the game over screen (with enter combat
    and end combat completely ignored by the Notchain client)'
    """
    event, data = converters.extract_varint(data)

    if event == 2:  # Entity dead
        player_id, data = converters.extract_varint(data)
        entity_id, data = converters.extract_int(data)
        message = converters.extract_json_from_chat(data)

        # 'Entity ID of the player that died
        # (should match the client's entity ID).'
        if entity_id == game_.player.data.entity_id:

            message = f"Player has been killed by: {entity_id}, " \
                      f"death message: '{message}' "

            game_.on_death()
        else:
            message = f"Entity: {player_id} has been " \
                      f"killed by: {entity_id}, death message: '{message}' "

        logger.info(message)
        gui.add_to_hotbar(message)
Exemplo n.º 2
0
def set_compression(game_: "game.Game", data: bytes) -> None:
    threshold = converters.extract_varint(data)[0]

    gui.set_labels(("compression threshold", threshold))

    if threshold < 0:
        logger.info("Compression is disabled")
    else:
        logger.info("Compression set to %i bytes", threshold)

    return threshold
Exemplo n.º 3
0
    def start(self) -> Union[str, None]:
        """
        Start game.

        :return: error message, otherwise None
        """
        if not self._connect_to_server():
            return self.stop("Cannot connect to the server.")
        logger.info("Successfully connected to the server.")

        if not self._conn.start_listener(self.received_packets):
            return self.stop("Cannot start listener")
        logger.debug("Successfully started listening thread")

        if not self._conn.start_sender(self.to_send_packets):
            return self.stop("Cannot start sender")
        logger.debug("Successfully started sending thread")

        if not self._log_in():
            return self.stop("Cannot log in.")
        logger.info("Successfully logged in to server.")

        self._switch_action_packets("play")

        if not self.move_manager.start():
            return self.stop("Can't start move manager.")

        # TODO: Add reaction_list, user_action_list, or other shit.
        while True:
            try:
                data = self.received_packets.get(timeout=20)
            except TimeoutError:
                return self.stop("Server timeout error.")

            if not data:
                return self.stop("Received 0 bytes")

            if not self._conn.compression_threshold < 0:
                try:
                    data = self._decompress_packet(data)
                except InvalidUncompressedPacketError:
                    return self.stop(
                        "Received packet with invalid compression.")

            # Decompression needs to be done before this!
            packet_id, packet = converters.extract_varint(data)

            if self._interpret_packet(packet_id, packet) == 5555:
                break

        return None
Exemplo n.º 4
0
    def _login_non_premium(self) -> bool:
        """
        #TODO: when login_premium done, write what da fuk is dat.
        #TODO: improve and simplify

        :return success
        :rtype bool
        """
        logger.info("Trying to log in in offline mode (non-premium).")

        self.to_send_packets.put(
            self.login_packet_creator.handshake(self.host.get_host_data()))

        self.to_send_packets.put(
            self.login_packet_creator.login_start(self.player.data.username))

        # Try to log in for 50 sec (10 sec x 5 packets)
        for _ in range(5):
            data = self.received_packets.get(timeout=10)
            if not data:
                logger.error("Received 0 bytes")
                return False

            try:
                packet = self._decompress_packet(data)
            except InvalidUncompressedPacketError:
                return False

            packet_id, data = converters.extract_varint(packet)
            # print(packet_id, data)
            try:
                result = self._interpret_packet(packet_id, data)
            except DisconnectedError:
                self.to_send_packets.put(b'')
                return False
            except Exception as err:
                logger.critical("<bot#1>Uncaught exception [%s] occurred: %s ",
                                err.__class__.__name__, err)
                # print("FOUND UNEXPECTED EXCEPTION\n" * 20)
                self.to_send_packets.put(b'')
                return False

            if result is True:
                return True
            if isinstance(result, int):
                self.game_data.compression_threshold = result
                self._conn.compression_threshold = result

        return False
Exemplo n.º 5
0
 def test_convert_extract_varint(self):
     times = []
     n_of_numbers = 100000
     for i in range(n_of_numbers):
         rand = randint(MIN_INT, MAX_INT)
         with self.subTest(i=i):
             start = time.perf_counter_ns()
             v1 = convert_to_varint(rand)
             v2, _ = extract_varint(v1)
             self.assertEqual(rand, v2)
             times.append(time.perf_counter_ns() - start)
     total_time = sum(times)
     print(f"Total time: {total_time}ns, "
           f"average per test: {total_time // n_of_numbers}ns,"
           f"best: {min(times)}ns")
Exemplo n.º 6
0
def update_health(game_: "game.Game", data: bytes):
    """Auto-respawn player."""
    player = game_.player.data

    player.health, data = converters.extract_float(data)
    player.food, data = converters.extract_varint(data)
    player.food_saturation = converters.extract_float(data)[0]

    logger.info("Updated player. Health: %f, Food: %i, Food_saturation: %f",
                player.health, player.food, player.food_saturation)

    gui.set_labels(("health", player.health), ("food", player.food),
                   ("food_saturation", player.food_saturation))

    if not player.health > 0:
        game_.on_death()
Exemplo n.º 7
0
    def _decompress_packet(self, packet: bytes) -> bytes:
        """Decompress packet, and return it."""
        threshold = self.game_data.compression_threshold

        # If compression is enabled.
        if threshold < 0:
            return packet

        data_length, packet = converters.extract_varint(packet)

        if data_length == 0:  # Packet is not compressed.
            return packet

        packet = zlib.decompress(packet)

        if len(packet) < threshold:
            logger.critical("Received invalid packet.")
            # TODO: to improve performance:
            #   change try except to if
            #   move extraction into _interpret_packet
            raise InvalidUncompressedPacketError("Received invalid packet.")

        return packet