Exemplo n.º 1
0
    def get_level_difficulty(self) -> Union[LevelDifficulty, DemonDifficulty]:
        """Compute actual level difficulty and return the enum."""
        address = self.read_type(self.ptr_type, 0x3222D0, 0x164, 0x22C, 0x114)

        is_demon, is_auto, difficulty, demon_difficulty = (
            self.read(Bool, address + 0x29C),
            self.read(Bool, address + 0x2B0),
            self.read(UInt32, address + 0x1E4),
            self.read(UInt32, address + 0x2A0),
        )

        return Converter.convert_level_difficulty(difficulty, demon_difficulty,
                                                  is_demon, is_auto)
Exemplo n.º 2
0
    def get_level_difficulty(self) -> Union[LevelDifficulty, DemonDifficulty]:
        address = self.read_bytes(self.PTR_LEN, 0x3222D0, 0x164, 0x22C, 0x114).as_int()

        is_demon, is_auto, diff, demon_diff = (
            self.read_at(1, address + 0x29C).as_bool(),
            self.read_at(1, address + 0x2B0).as_bool(),
            self.read_at(4, address + 0x1E4).as_int(),
            self.read_at(4, address + 0x2A0).as_int(),
        )

        return Converter.convert_level_difficulty(
            diff=diff, demon_diff=demon_diff, is_demon=is_demon, is_auto=is_auto
        )
Exemplo n.º 3
0
    def from_data(
        cls,
        data: ExtDict,
        creator: Union[ExtDict, AbstractUser],
        song: Union[ExtDict, Song],
        client: Client,
    ) -> Level:
        if isinstance(creator, ExtDict):
            creator = AbstractUser(**creator, client=client)

        if isinstance(song, ExtDict):
            if any(key.isdigit() for key in song.keys()):
                song = Song.from_data(song, client=client)
            else:
                song = Song(**song, client=client)

        string = data.get(Index.LEVEL_PASS)

        if string is None:
            copyable, password = False, None
        else:
            if string == ZERO_STR:
                copyable, password = False, None
            else:
                try:
                    # decode password
                    password = Coder.decode(type="levelpass", string=string)
                except Exception:
                    # failed to get password
                    copyable, password = False, None
                else:
                    copyable = True

                    if not password:
                        password = None

                    else:
                        # password is in format 1XXXXXX
                        password = password[1:]
                        password = int(password) if password.isdigit() else None

        desc = Coder.do_base64(
            data.get(Index.LEVEL_DESCRIPTION, ""), encode=False, errors="replace"
        )

        level_data = data.get(Index.LEVEL_DATA, "")
        try:
            level_data = Coder.unzip(level_data)
        except Exception:  # conversion failed
            pass

        diff = data.getcast(Index.LEVEL_DIFFICULTY, 0, int)
        demon_diff = data.getcast(Index.LEVEL_DEMON_DIFFICULTY, 0, int)
        is_demon = bool(data.getcast(Index.LEVEL_IS_DEMON, 0, int))
        is_auto = bool(data.getcast(Index.LEVEL_IS_AUTO, 0, int))
        difficulty = Converter.convert_level_difficulty(
            diff=diff, demon_diff=demon_diff, is_demon=is_demon, is_auto=is_auto
        )

        return cls(
            id=data.getcast(Index.LEVEL_ID, 0, int),
            name=data.get(Index.LEVEL_NAME, "unknown"),
            description=desc,
            version=data.getcast(Index.LEVEL_VERSION, 0, int),
            creator=creator,
            song=song,
            data=level_data,
            password=password,
            copyable=copyable,
            is_demon=is_demon,
            is_auto=is_auto,
            low_detail_mode=bool(data.get(Index.LEVEL_HAS_LDM)),
            difficulty=difficulty,
            stars=data.getcast(Index.LEVEL_STARS, 0, int),
            coins=data.getcast(Index.LEVEL_COIN_COUNT, 0, int),
            verified_coins=bool(data.getcast(Index.LEVEL_COIN_VERIFIED, 0, int)),
            is_epic=bool(data.getcast(Index.LEVEL_IS_EPIC, 0, int)),
            original=data.getcast(Index.LEVEL_ORIGINAL, 0, int),
            downloads=data.getcast(Index.LEVEL_DOWNLOADS, 0, int),
            rating=data.getcast(Index.LEVEL_LIKES, 0, int),
            score=data.getcast(Index.LEVEL_FEATURED_SCORE, 0, int),
            uploaded_timestamp=data.get(Index.LEVEL_UPLOADED_TIMESTAMP, "unknown"),
            last_updated_timestamp=data.get(Index.LEVEL_LAST_UPDATED_TIMESTAMP, "unknown"),
            length=LevelLength.from_value(data.getcast(Index.LEVEL_LENGTH, 0, int), "XL"),
            game_version=data.getcast(Index.LEVEL_GAME_VERSION, 0, int),
            stars_requested=data.getcast(Index.LEVEL_REQUESTED_STARS, 0, int),
            object_count=data.getcast(Index.LEVEL_OBJECT_COUNT, 0, int),
            type=TimelyType.from_value(data.getcast(Index.LEVEL_TIMELY_TYPE, 0, int), 0),
            time_n=data.getcast(Index.LEVEL_TIMELY_INDEX, -1, int),
            cooldown=data.getcast(Index.LEVEL_TIMELY_COOLDOWN, -1, int),
            client=client,
        )