Пример #1
0
    async def read_match(data: bytes) -> TypedReadMatch:
        buffer = KurisoBuffer(None)
        await buffer.write_to_buffer(data)

        await buffer.read_int_16(
        )  # skip 3 bytes for id and inProgress because default is False
        await buffer.read_byte()

        match_type = MatchTypes(await buffer.read_byte())
        mods = Mods(await buffer.read_int_32())

        name = await buffer.read_osu_string()
        password = await buffer.read_osu_string()

        beatmap_name = await buffer.read_osu_string()
        beatmap_id = await buffer.read_int_32()
        beatmap_md5 = await buffer.read_osu_string()

        slots = [Slot() for _ in range(0, 16)]  # make slots
        for slot in slots:
            slot.status = SlotStatus(await buffer.read_byte())

        for slot in slots:
            slot.team = SlotTeams(await buffer.read_byte())

        for slot in slots:
            if slot.status.value & SlotStatus.HasPlayer:
                await buffer.read_int_32()

        host_id = await buffer.read_int_32()
        play_mode = GameModes(await buffer.read_byte())
        scoring_type = MatchScoringTypes(await buffer.read_byte())
        team_type = MatchTeamTypes(await buffer.read_byte())
        is_freemod = await buffer.read_bool()
        match_freemod = MultiSpecialModes(int(is_freemod))

        if is_freemod:
            for slot in slots:
                slot.mods = Mods(await buffer.read_int_32())

        seed = await buffer.read_int_32()

        t_dict = {
            'match_type': match_type,
            'mods': mods,
            'name': name,
            'password': password,
            'beatmap_name': beatmap_name,
            'beatmap_id': beatmap_id,
            'beatmap_md5': beatmap_md5,
            'slots': slots,
            'host_id': host_id,
            'play_mode': play_mode,
            'scoring_type': scoring_type,
            'team_type': team_type,
            'match_freemod': match_freemod,
            'seed': seed
        }

        return t_dict
Пример #2
0
async def tillerino_last(_, token: 'Player', message: 'Message'):
    if message.to.startswith("#") and (
            token.privileges
            & KurikkuPrivileges.Donor) != KurikkuPrivileges.Donor:
        return False  # don't allow run np commands in public channels!

    data = await Context.mysql.fetch(
        """SELECT beatmaps.song_name as sn, scores.*,
        beatmaps.beatmap_id as bid, beatmaps.difficulty_std, beatmaps.difficulty_taiko, beatmaps.difficulty_ctb,
        beatmaps.difficulty_mania, beatmaps.max_combo as fc
    FROM scores
    LEFT JOIN beatmaps ON beatmaps.beatmap_md5=scores.beatmap_md5
    WHERE scores.userid = %s
    ORDER BY scores.time DESC
    LIMIT 1""", [token.id])

    diffString = f"difficulty_{GameModes.resolve_to_str(GameModes(data['play_mode']))}"
    rank = legacy_utils.getRank(data["play_mode"], data["mods"],
                                data["accuracy"], data["300_count"],
                                data["100_count"], data["50_count"],
                                data["misses_count"])

    ifPlayer = f"{token.name if message.to != CrystalBot.bot_name else ''} | "
    ifFc = " (FC)" if data["max_combo"] == data[
        "fc"] else f" {data['max_combo']}x/{data['fc']}x"
    beatmapLink = f"[http://osu.ppy.sh/b/{data['bid']} {data['sn']}]"

    hasPP = data["play_mode"] != GameModes.CTB.value

    msg = ifPlayer
    msg += beatmapLink
    if data["play_mode"] != GameModes.STD.value:
        msg += f" <{GameModes.resolve_to_str(GameModes(data['play_mode']))}>"

    if data["mods"]:
        msg += ' +' + new_utils.readable_mods(Mods(data["mods"]))

    if not hasPP:
        msg += " | {0:,}".format(data["score"])
        msg += ifFc
        msg += f" | {round(data['accuracy'], 2)}%, {rank.upper()}"
        msg += f" {{ {data['300_count']} / {data['100_count']} / {data['50_count']} / {data['misses_count']} }}"
        msg += f" | {round(data[diffString], 2)} stars"
        return msg

    msg += f" | {round(data['accuracy'], 2)}%, {rank.upper()}"
    msg += ifFc
    msg += f" | {round(data['pp'], 2)}pp"

    stars = data[diffString]
    if data["mods"]:
        token.tillerino[0] = data["bid"]
        token.tillerino[1] = Mods(data["mods"])
        peace_data = await get_pp_message(token, just_data=True)
        if "stars" in peace_data:
            stars = peace_data['stars']

    msg += " | {0:.2f} stars".format(stars)
    return msg
Пример #3
0
 def update(self, **kwargs):
     self.action = Action(kwargs.get('action', 0))
     self.action_text = kwargs.get('action_text', '')
     self.map_md5 = kwargs.get('map_md5', '')
     self.mode = GameModes(kwargs.get('mode', 0))
     self.mods = Mods(kwargs.get('mods', 0))
     self.map_id = kwargs.get('map_id', 0)
Пример #4
0
async def tilleino_like(args: List[str], token: 'Player', message: 'Message'):
    if (token.privileges & KurikkuPrivileges.Donor) != KurikkuPrivileges.Donor:
        return False  # don't allow run np commands in public channels!

    play_or_watch = "playing" in message.body or "watching" in message.body
    # Get URL from message
    beatmap_url = args[0][1:]
    modsEnum = Mods(0)
    if play_or_watch:
        mapping = {
            "-Easy": Mods.Easy,
            "-NoFail": Mods.NoFail,
            "+Hidden": Mods.Hidden,
            "+HardRock": Mods.HardRock,
            "+Nightcore": Mods.Nightcore,
            "+DoubleTime": Mods.DoubleTime,
            "-HalfTime": Mods.HalfTime,
            "+Flashlight": Mods.Flashlight,
            "-SpunOut": Mods.SpunOut
        }
        for part in args:
            part = part.replace("\x01", "")
            if part in mapping.keys():
                modsEnum |= mapping[part]
    try:
        beatmap_id = NP_REGEX.search(beatmap_url).groups(0)[1]
    except Exception as e:
        traceback.print_exc()
        capture_exception(e)
        return "Can't find beatmap"

    token.tillerino = [int(beatmap_id), modsEnum]

    return await get_pp_message(token)
Пример #5
0
async def update_match_mods(packet_data: bytes, token: 'Player'):
    if not token.match:
        return False

    match = token.match
    newMods = Mods(await PacketResolver.read_mods(packet_data))
    await match.change_mods(newMods, token)

    await match.update_match()
    return True
Пример #6
0
    def __init__(self,
                 user_id: Union[int],
                 user_name: Union[str],
                 privileges: Union[int],
                 utc_offset: Optional[int] = 0,
                 pm_private: bool = False,
                 silence_end: int = 0,
                 is_tourneymode: bool = False,
                 is_bot: bool = False,
                 ip: str = ''):
        self.token: str = self.generate_token()
        self.id: int = user_id
        self.name: str = user_name
        self.ip: str = ip
        self.privileges: int = privileges
        self.selected_game_mode: GameModes = GameModes.STD

        self.stats: Dict[GameModes, StatsMode] = {
            mode: StatsMode()
            for mode in GameModes
        }  # setup dictionary with stats
        self.pr_status: Status = Status()

        self.spectators: List[Player] = []
        self.spectating: Optional[Player] = None

        self.country: Tuple[int, str] = (0, 'XX')
        self.location: Tuple[float, float] = (0.0, 0.0)
        self.timezone: int = 24 + utc_offset
        self.timezone_offset: int = utc_offset

        self.pm_private: bool = pm_private  # Как я понял, это типо только друзья могут писать
        self.friends: Union[List[int]] = []
        self.away_msg: Optional[str] = None
        self.silence_end: int = silence_end

        self.presence_filter: PresenceFilter = PresenceFilter(1)
        self.bot_np: Optional[dict] = None  # TODO: Beatmap

        self._match: Optional['Match'] = None
        self.friends: Union[List[int]] = []  # bot by default xd

        self.queue: bytearray = bytearray()  # main thing
        self.login_time: int = int(time.time())
        self.last_packet_unix: int = int(time.time())

        self.is_tourneymode: bool = is_tourneymode
        self.id_tourney: int = -1
        self.is_in_lobby: bool = False

        self.is_bot: bool = is_bot
        self.tillerino: List[Union[int, Mods]] = [
            0, Mods(0), -1.0
        ]  # 1 - map id, 2 - current_mods, 3 - acc <- legacy code
        self.user_chat_log: List['Message'] = []
Пример #7
0
async def mp_mods(args: List[str], player: 'Player', message: 'Message'):
    if not player.match:
        return 'You are not in any match'

    if not can_take_match(player, player.match, check_tourney_host=True):
        return 'You cant do anything with that match'

    if len(args) < 2:
        return "Wrong syntax: !mp mods <mod1> [<mod2>] ..."

    new_mods = Mods(0)
    freeMod = False
    for _mod in args[1:]:
        if _mod.lower().strip() == "hd":
            new_mods |= Mods.Hidden
        elif _mod.lower().strip() == "hr":
            new_mods |= Mods.HardRock
        elif _mod.lower().strip() == "dt":
            new_mods |= Mods.DoubleTime
        elif _mod.lower().strip() == "fl":
            new_mods |= Mods.Flashlight
        elif _mod.lower().strip() == "fi":
            new_mods |= Mods.FadeIn
        elif _mod.lower().strip() == "nf":
            new_mods |= Mods.NoFail
        elif _mod.lower().strip() == "ez":
            new_mods |= Mods.Easy
        if _mod.lower().strip() == "none" or _mod.lower().strip() == "nomod":
            new_mods = Mods(0)

        if _mod.lower().strip() == "freemod":
            freeMod = True

    await player.match.change_special_mods(MultiSpecialModes.Freemod if freeMod else MultiSpecialModes.Empty)
    await player.match.change_mods(new_mods, player)
    await player.match.unready_everyone()
    await player.match.update_match()
    return "Match mods have been updated!"
Пример #8
0
async def tillerino_mods(args: List[str], token: 'Player', _):
    if not args:
        return 'Enter mods as first argument'

    if (token.privileges & KurikkuPrivileges.Donor) != KurikkuPrivileges.Donor:
        return False  # don't allow run np commands in public channels!

    if token.tillerino[0] == 0:
        return 'Please give me beatmap first with /np command'

    mods_list = [a.upper() for a in args]
    mods_enum = Mods(0)
    for mod in mods_list:
        if mod not in ALLOWED_MODS:
            return f"Invalid mods. Allowed mods: {', '.join(ALLOWED_MODS)} do not use spaces for multiple mods."

        mods_enum |= ALLOWED_MODS_MAPPING.get(mod, 0)

    token.tillerino[1] = mods_enum

    return await get_pp_message(token)