Esempio n. 1
0
    def from_data(cls, data: ExtDict, user_2: Union[ExtDict, AbstractUser],
                  client: Client) -> FriendRequest:
        user_1 = AbstractUser(
            name=data.get(Index.REQUEST_SENDER_NAME, "unknown"),
            id=data.getcast(Index.REQUEST_SENDER_ID, 0, int),
            account_id=data.getcast(Index.REQUEST_SENDER_ACCOUNT_ID, 0, int),
            client=client,
        )
        if isinstance(user_2, ExtDict):
            user_2 = AbstractUser(**user_2, client=client)

        indicator = data.getcast(Index.REQUEST_INDICATOR, 0, int)
        is_normal = indicator ^ 1

        return cls(
            id=data.getcast(Index.REQUEST_ID, 0, int),
            timestamp=str(data.get(Index.REQUEST_TIMESTAMP, "unknown")),
            body=Coder.do_base64(data.get(Index.REQUEST_BODY, ""),
                                 encode=False,
                                 errors="replace"),
            is_read=(not data.get(Index.REQUEST_STATUS)),
            author=(user_1 if is_normal else user_2),
            recipient=(user_2 if is_normal else user_1),
            type=MessageOrRequestType.from_value(indicator, 0),
            client=client,
        )
Esempio n. 2
0
    def from_data(cls, data: ExtDict, author: Union[ExtDict, AbstractUser],
                  client: Client) -> Comment:
        if isinstance(author, ExtDict):
            if any(key.isdigit() for key in author.keys()):
                author = AbstractUser.from_data(author, client=client)
            else:
                author = AbstractUser(**author, client=client)

        color_string = data.get(Index.COMMENT_COLOR, "255,255,255")
        color = Color.from_rgb(*map(int, color_string.split(",")))

        return cls(
            body=Coder.do_base64(data.get(Index.COMMENT_BODY, ""),
                                 encode=False,
                                 errors="replace"),
            rating=data.getcast(Index.COMMENT_RATING, 0, int),
            timestamp=data.get(Index.COMMENT_TIMESTAMP, "unknown"),
            id=data.getcast(Index.COMMENT_ID, 0, int),
            is_spam=bool(data.getcast(Index.COMMENT_IS_SPAM, 0, int)),
            type=CommentType.from_value(
                data.getcast(Index.COMMENT_TYPE, 0, int), 0),
            color=color,
            level_id=data.getcast(Index.COMMENT_LEVEL_ID, 0, int),
            level_percentage=data.getcast(Index.COMMENT_LEVEL_PERCENTAGE, -1,
                                          int),
            author=author,
            client=client,
        )
Esempio n. 3
0
    def from_data(cls, data: ExtDict, user_2: Union[ExtDict, AbstractUser],
                  client: Client) -> Message:
        user_1 = AbstractUser(
            name=data.get(Index.MESSAGE_SENDER_NAME, "unknown"),
            id=data.getcast(Index.MESSAGE_SENDER_ID, 0, int),
            account_id=data.getcast(Index.MESSAGE_SENDER_ACCOUNT_ID, 0, int),
            client=client,
        )
        if isinstance(user_2, ExtDict):
            user_2 = AbstractUser(**user_2, client=client)

        indicator = data.getcast(Index.MESSAGE_INDICATOR, 0, int)
        is_normal = indicator ^ 1

        subject = Coder.do_base64(data.get(Index.MESSAGE_SUBJECT, ""),
                                  encode=False,
                                  errors="replace")

        return Message(
            id=data.getcast(Index.MESSAGE_ID, 0, int),
            timestamp=data.get(Index.MESSAGE_TIMESTAMP, "unknown"),
            subject=subject,
            is_read=bool(data.getcast(Index.MESSAGE_IS_READ, 0, int)),
            author=(user_1 if is_normal else user_2),
            recipient=(user_2 if is_normal else user_1),
            type=MessageOrRequestType.from_value(indicator, 0),
            client=client,
        )
Esempio n. 4
0
    def into_level(
        self,
        client: Optional[Client] = None,
        get_data: bool = True,
        server_style: bool = False,
    ) -> Level:
        if self.is_demon():
            difficulty = DemonDifficulty.from_name(self.difficulty)
        else:
            difficulty = LevelDifficulty.from_name(self.difficulty)

        if get_data:
            data = official_levels_data.get(self.name, "")

            if data:
                data = Coder.unzip(data)

        else:
            data = ""

        return Level(
            id=self.level_id,
            name=self.name,
            description=f"Official Level: {self.name}",
            version=1,
            creator=AbstractUser(name="RobTop",
                                 id=16,
                                 account_id=71,
                                 client=client),
            song=Song.official(self.get_song_id(server_style),
                               client=client,
                               server_style=server_style),
            data=data,
            password=None,
            copyable=False,
            is_demon=self.is_demon(),
            is_auto=self.is_auto(),
            difficulty=difficulty,
            stars=self.stars,
            coins=self.coins,
            verified_coins=True,
            is_epic=False,
            original=True,
            low_detail_mode=False,
            downloads=0,
            rating=0,
            score=1,
            uploaded_timestamp="unknown",
            last_updated_timestamp="unknown",
            length=LevelLength.from_name(self.length),
            stars_requested=self.stars,
            object_count=0,
            type=TimelyType.from_value(0),
            time_n=-1,
            cooldown=-1,
            client=client,
        )
Esempio n. 5
0
 def creator(self) -> AbstractUser:
     """:class:`.AbstractUser`: Creator of the level."""
     return self.options.get("creator", AbstractUser(client=self.options.get("client")))
Esempio n. 6
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,
        )
Esempio n. 7
0
 def recipient(self) -> AbstractUser:
     """:class:`.AbstractUser`: A recipient of the friend request."""
     return self.options.get("recipient", AbstractUser(client=self.client))
Esempio n. 8
0
 def author(self) -> AbstractUser:
     """:class:`.AbstractUser`: An author of the friend request."""
     return self.options.get("author", AbstractUser(client=self.client))
Esempio n. 9
0
    def official(cls, level_id: int, client: Optional[Client] = None) -> None:
        mapping = {
            # ID: (name, stars, difficulty, coins, length)
            1: ("Stereo Madness", 1, "easy", 3, 3),
            2: ("Back On Track", 2, "easy", 3, 3),
            3: ("Polargeist", 3, "normal", 3, 3),
            4: ("Dry Out", 4, "normal", 3, 3),
            5: ("Base After Base", 5, "hard", 3, 3),
            6: ("Cant Let Go", 6, "hard", 3, 3),
            7: ("Jumper", 7, "harder", 3, 3),
            8: ("Time Machine", 8, "harder", 3, 3),
            9: ("Cycles", 9, "harder", 3, 3),
            10: ("xStep", 10, "insane", 3, 3),
            11: ("Clutterfunk", 11, "insane", 3, 3),
            12: ("Theory of Everything", 12, "insane", 3, 3),
            13: ("Electroman Adventures", 10, "insane", 3, 3),
            14: ("Clubstep", 14, "easy_demon", 3, 3),
            15: ("Electrodynamix", 12, "insane", 3, 3),
            16: ("Hexagon Force", 12, "insane", 3, 3),
            17: ("Blast Processing", 10, "harder", 3, 3),
            18: ("Theory of Everything 2", 14, "easy_demon", 3, 3),
            19: ("Geometrical Dominator", 10, "harder", 3, 3),
            20: ("Deadlocked", 15, "easy_demon", 3, 3),
            21: ("Fingerdash", 12, "insane", 3, 3),
            1001: ("The Seven Seas", 1, "easy", 3, 3),
            1002: ("Viking Arena", 2, "normal", 3, 3),
            1003: ("Airborne Robots", 3, "hard", 3, 3),
            2001: ("Payload", 2, "easy", 0, 1),
            2002: ("Beast Mode", 3, "normal", 0, 2),
            2003: ("Machina", 3, "normal", 0, 2),
            2004: ("Years", 3, "normal", 0, 2),
            2005: ("Frontlines", 3, "normal", 0, 2),
            2006: ("Space Pirates", 3, "normal", 0, 2),
            2007: ("Striker", 3, "normal", 0, 2),
            2008: ("Embers", 3, "normal", 0, 1),
            2009: ("Round 1", 3, "normal", 0, 2),
            2010: ("Monster Dance Off", 3, "normal", 0, 2),
            3001: ("The Challenge", 3, "hard", 0, 1),  # well...
            4001: ("Press Start", 4, "normal", 3, 3),
            4002: ("Nock Em", 6, "hard", 3, 3),
            4003: ("Power Trip", 8, "harder", 3, 3),
        }
        translate = {
            1001: 22,
            1002: 23,
            1003: 24,
            3001: 25,
            2001: 26,
            2002: 27,
            2003: 28,
            2004: 29,
            2005: 30,
            2006: 31,
            2007: 32,
            2008: 33,
            2009: 34,
            2010: 35,
            4001: 36,
            4002: 37,
            4003: 38,
        }

        if level_id not in mapping:
            raise ValueError(
                f"Level ID [{level_id}] is not known to be official.")

        song_id, (name, stars, str_diff, coins, length) = (
            translate.get(level_id, level_id),
            mapping[level_id],
        )

        creator, song = (
            AbstractUser(client=client),
            Song.official(song_id, server_style=False, client=client),
        )
        is_demon = "demon" in str_diff

        if is_demon:
            difficulty = DemonDifficulty.from_value(str_diff)
        else:
            difficulty = LevelDifficulty.from_value(str_diff)

        return cls(
            id=level_id,
            name=name,
            description=f"Official Level: {name}",
            version=1,
            creator=creator,
            song=song,
            data=
            "",  # XXX: maybe we can dump all official levels and load their data
            password=None,
            copyable=False,
            is_demon=is_demon,
            is_auto=(str_diff == "auto"),
            difficulty=difficulty,
            stars=stars,
            coins=coins,
            verified_coins=True,
            is_epic=False,  # XXX: are Rob's levels epic? ~ nekit
            original=True,  # would be fun if this was false haha
            low_detail_mode=False,
            downloads=0,
            rating=0,
            score=1,
            uploaded_timestamp="unknown",
            last_updated_timestamp="unknown",
            length=length,
            game_version=21,
            stars_requested=0,
            object_count=0,
            type=0,
            time_n=-1,
            cooldown=-1,
            client=client,
        )