Example #1
0
    async def userinfo(
        self,
        ctx: HarleyContext,
        user: Optional[Union[discord.Member, discord.User]] = None,
        *,
        flags: WhoIsFlags,
    ):
        """
        Returns user info, input can be a user not in the guild.
        If the user's name has a space, use quotes around their name.
        """
        user = user or ctx.author

        embed = Embed(
            title=f"Information About {user}",
            description=(
                f"Created At: {user.created_at.strftime(TIME_TEMPLATE)}\n"
                f"Bot: {YES_NO[user.bot]} \n"
                f"ID: {user.id}"),
        )

        if flags.avatar is not False:
            embed.set_thumbnail(url=user.avatar)

        if isinstance(user, discord.Member):

            embed.add_field(
                name="Guild Related Info:",
                value=(f"Joined At: {user.joined_at.strftime(TIME_TEMPLATE)}\n"
                       f"Nickname: {user.nick or 'None'}\n"
                       f"Top Role: {user.top_role.mention}"),
            )

        await ctx.reply(embed=embed)
Example #2
0
    def _get_main_menu(self, ctx: SlashContext, guild_data: GuildData, content: dict) -> Embed:
        embed = Embed(
            title="Help | Asteroid Bot",
            timestamp=datetime.datetime.utcnow(),
            color=DiscordColors.EMBED_COLOR,
        )
        embed.add_field(
            name=content["INFORMATION_TEXT"],
            value=content["INFORMATION_CONTENT_TEXT"],
            inline=False,
        )
        embed.set_thumbnail(url=ctx.bot.user.avatar_url)
        embed.set_footer(
            text=content["REQUIRED_BY_TEXT"].format(user=ctx.author),
            icon_url=ctx.author.avatar_url,
        )

        cog_translations = content["PLUGINS"]
        cogs = "".join(
            f"**ยป {cog_translations[cog_name.upper()]}**\n"
            for cog_name, cog in self.bot.cogs.items()
            if not self._cog_check(guild_data, cog)
        )

        embed.add_field(name=content["PLUGINS_TEXT"], value=cogs)
        return embed
Example #3
0
    async def stats(self, ctx):
        """
        Displays stats about the bot including number of servers and users.
        """
        server_rankings = sorted(self.bot.guilds,
                                 key=lambda guild: len(guild.members),
                                 reverse=True)[:10]
        server_rankings = f'{"Top Servers".ljust(28)} | Users\n' + '\n'.join([
            f'{guild.name[:28].ljust(28)} | {len(guild.members):,}'
            for guild in server_rankings
        ])

        embed = Embed(
            ctx=ctx,
            title='Discord Stats',
            description=
            f'This command was run on shard {(ctx.guild.shard_id if ctx.guild else 0) + 1} / {self.bot.shard_count}.\n```{server_rankings}```'
        ).add_field(
            name='Servers',
            value=
            f'{self.bot.user.name} is running in {len(self.bot.guilds):,} servers with {sum(len(guild.text_channels) for guild in self.bot.guilds):,} channels.',
            inline=False
        ).add_field(
            name='Users',
            value=
            f'There are currently {sum(len(guild.members) for guild in self.bot.guilds):,} users with access to the bot.',
            inline=False)
        shards = []
        for x in range(self.bot.shard_count):
            shards.append([0, 0, 0])
        for x in self.bot.guilds:
            shards[x.shard_id][0] += 1
            shards[x.shard_id][1] += len(x.text_channels)
            shards[x.shard_id][2] += len(x.members)

        for x in range(self.bot.shard_count):
            embed.add_field(
                name=f'Shard {x + 1}',
                value=
                f'{shards[x][0]:,} servers\n{shards[x][1]:,} channels\n{shards[x][2]:,} members',
                inline=True)

        memory_usage = self.process.memory_full_info().uss / 1024**2
        cpu_usage = self.process.cpu_percent() / psutil.cpu_count()
        embed.add_field(name='Process',
                        value=f'{memory_usage:.2f} MiB\n{cpu_usage:.2f}% CPU',
                        inline=False)

        embed.add_footer(
            text=
            f'This message was delivered in {self.bot.latency * 1000:.0f} milliseconds.'
        )

        await embed.send()
Example #4
0
    async def rep(self, ctx, player: discord.Member):
        """
        Command to check user's reviewed reputation in this discord server.
        """
        positive_reviewed_reps = []
        positive_unreviewed_reps = []
        negative_reviewed_reps = []
        negative_unreviewed_reps = []

        async for rep in self.reps_db.find({
                'guild_id': ctx.guild.id,
                'reported_discord_id': player.id
        }):
            if rep['type'] is None and rep['positive']:
                positive_unreviewed_reps.append(rep)
            elif rep['type'] is None and not rep['positive']:
                negative_unreviewed_reps.append(rep)
            elif rep['type'] is not None and rep['positive']:
                positive_reviewed_reps.append(rep)
            elif rep['type'] is not None and not rep['positive']:
                negative_reviewed_reps.append(rep)

        embed = Embed(
            ctx=ctx,
            title=f'{player.name} Reputations',
        ).add_field(name='All Positive Reps',
                    value=f'{len(positive_reviewed_reps)}').add_field(
                        name='All Negative Reps',
                        value=f'{len(negative_reviewed_reps)}')

        async for category in self.rep_categories_db.find(
            {'guild_id': ctx.guild.id}):
            category_reps = [
                rep for rep in positive_reviewed_reps + negative_reviewed_reps
                if rep['type'] == category['name']
            ]
            embed.add_field(name=f'{category["name"]}',
                            value=f'{len(category_reps)}')

        await embed.add_field(
            name=f'Unreviewed',
            value=
            f'{len(negative_unreviewed_reps) + len(positive_unreviewed_reps)}'
        ).send()
Example #5
0
    async def status(self, ctx):
        """
        Check all the skyblock event schedules status.
        """
        embed = Embed(
            ctx=ctx,
            title='Current event schedules status',
            description=
            f'There are currently {len(self.event_schedules)} event schedules. (EST time)'
        )

        for event in self.event_schedules.values():
            estimate = datetime.fromtimestamp(
                event["estimate"] / 1000.0).astimezone(EST).strftime(
                    datetime_fmt).lstrip('0').replace(' 0', ' ')
            embed.add_field(
                name=f'{SKYBLOCK_EVENTS[event["name"]]["name"]} Status',
                value=f'Current estimate > {estimate}\n'
                f'Next schedule > {event["time"].astimezone(EST).strftime(datetime_fmt).lstrip("0").replace(" 0", " ")}\n'
                f'Next schedule type > {event["type"]}',
                inline=False)

        await embed.send()
Example #6
0
 async def confirm_options(ctx, perfect_crit_chance, attack_speed_limit,
                           only_blacksmith, ignored_reforges, selected_pots,
                           selected_buffs, dungeon_item_used,
                           include_dungeon):
     potions_list = [
         f'{name.capitalize()}: {level}' for name, level in selected_pots
         if level != 0
     ]
     embed = Embed(ctx=ctx, title='Are these options correct?').add_field(
         name='Goal',
         value=
         f'```{"Perfect crit chance" if perfect_crit_chance else "Maximum damage"}```'
     ).add_field(
         name='Attack speed limit', value=f'```{attack_speed_limit}%```'
     ).add_field(
         name='Reforges',
         value=
         f'```{"Only blacksmith reforges" if only_blacksmith else "All reforges"}```'
         + '{s}'.format(
             s=f'\n```Ignored reforges: {", ".join(ignored_reforges)}```'
             if ignored_reforges else ""),
         inline=False
     ).add_field(
         name='Potions',
         value=f"```{', '.join(potions_list) if potions_list else 'None'}```"
     ).add_field(
         name='Support items',
         value=
         f"```{', '.join([f'{item.capitalize()}' for item in selected_buffs]) if selected_buffs else 'None'}```"
     )
     if dungeon_item_used:
         embed.add_field(
             name='Dungeon items',
             value=
             f'```{"Dungeon stats" if include_dungeon else "Regular stats"}```',
             inline=False)
     return await ctx.prompt(embed=embed)
Example #7
0
    async def serverinfo(self, ctx: HarleyContext, *, flags: GuildInfoFlags):
        """
        Returns info about the server.
        """
        guild = ctx.guild

        embed = Embed(
            title=guild.name,
            description=(f"Owner: {guild.owner} \n"
                         f"Member Count: {guild.member_count} \n"
                         f"Region: {title_format(str(guild.region))} \n"),
        ).set_thumbnail(url=guild.icon)

        if flags.banner is True:
            embed.set_thumbnail(url=guild.banner)

        if flags.features is True:
            embed.add_field(
                name="Features",
                value="\n".join(
                    [title_format(feature) for feature in guild.features]),
            )

        await ctx.reply(embed=embed)
Example #8
0
    async def player(self, ctx, player: str = '', profile: str = ''):
        """
        Displays a player\'s guild, skills, and slayer levels.
        """
        player = await ask_for_skyblock_profiles(ctx, player, profile, session=self.bot.http_session,
                                                 hypixel_api_client=self.bot.hypixel_api_client, auto_set=True,
                                                 get_guild=True)
        profile = player.profile
        guild = player.guild

        api_header = ' '.join(
            f'{key.capitalize()} {"โœ…" if value else "โŒ"}' for key, value in profile.enabled_api.items())

        total_xp = 0
        for skill in SKILL_NAMES:
            if skill in COSMETIC_SKILL_NAMES:
                continue
            total_xp += profile.skills_xp.get(skill, 0)

        embed = Embed(
            ctx=ctx,
            title=f'{player.uname} | {profile.name}',
            description=f'```{api_header}```\n'
                        f'```Deaths > {profile.deaths:,}\n'
                        f'Guild > {guild.name if guild else None}\n'
                        f'Money > {profile.bank_balance + profile.purse:,.2f}\n'
                        f'Pet > {format_pet(profile.pet)}```'
        ).add_field(
            name=f'๐Ÿ”ฐ \tSkills',
            value=f'```Average > {profile.skill_average:.2f}\n'
                  f'Total XP > {total_xp:,.0f}\n'
                  f'{(profile.skill_average / 50 * 100):.2f}% Maxed```',
            inline=False
        ).add_field(
            name=f'๐Ÿ› ๏ธ \tMinions',
            value=f'```Slots > {profile.minion_slots}\n'
                  f'Uniques > {profile.unique_minions}```',
            inline=False
        ).set_thumbnail(
            url=player.get_avatar_url()
        )

        for skill, level in profile.skills.items():
            percent_to_max = 100 * min(1, profile.skills_xp.get(skill, 0) / (
                RUNECRAFTING_LEVEL_REQUIREMENT[-1] if skill == 'runecrafting' else SKILL_LEVEL_REQUIREMENT[-1]))
            embed.add_field(
                name=f'{SKILL_EMOJIS[skill]}\t{skill.capitalize()}',
                value=f'```Level > {level}\n'
                      f'XP > {profile.skills_xp.get(skill, 0):,.0f}\n'
                      f'{percent_to_max:.2f}% Maxed```'
            )
        # So every skill embed field is same size
        left_over_field = 3 - (len(profile.skills) % 3)
        if left_over_field < 3:
            for i in range(0, left_over_field):
                embed.add_field()

        for slayer, level in profile.slayers.items():
            percent_to_max = 100 * min(1, profile.slayers_xp.get(slayer, 0) / SLAYER_LEVEL_REQUIREMENT[slayer][-1])
            embed.add_field(
                name=f'{SKILL_EMOJIS[slayer]}\t{slayer.capitalize()}',
                value=f'```Level > {level}\n'
                      f'XP > {profile.slayers_xp.get(slayer, 0):,.0f}\n'
                      f'{percent_to_max:.2f}% Maxed```'
            )
            
        embed.add_field(
            name=f'{SKILL_EMOJIS["dungeons"]}\tDungeon Stats',
            value=f'```Selected Class > **{profile.dungeons.selected_dungeon_class.capitalize()}**\n'
                  f'Experience > **{Math.round(profile.dungeons.dungeon_types.catacombs.experience)}**```\n'
            inline=False
        )
            
        for d_class, experience in profile.dungeons.player_classes.items():
            percent_to_max = 100 * min(1, profile.dungeons.player_classes.get(d_class, 0) / DUNGEON_SKILL_LEVEL_REQUIREMENT[d_class][-1])
            embed.add_field(
                name=f'{DUNGEON_EMOJIS[d_class]}\t{d_class.capitalize()}',
                value=f'```Level > ?\n'
                      f'Experience > {experience:,.0f} XP\n'
                      f'{percent_to_max:.2f}% Maxed```'
            ).set_footer(
            text=f'Player is currently {"online" if player.online else "offline"} in game.'
        )

        await embed.send()
Example #9
0
    async def send_optimizer_result(ctx, profile, best_route, include_dungeon):
        weapon = profile.weapon
        best_stats = best_route[0] or {}
        best_equip = best_route[1] or {}
        is_optimized = best_route[0]['is optimized']

        if not best_equip:
            return await ctx.send(
                f'{ctx.author.mention}, Optimization is not possible with the options you chose!\n'
                f'Collect more talismans or raise your combat level before trying again.'
            )

        embed = Embed(
            ctx=ctx,
            title='{s}'.format(
                s='Successful!' if is_optimized else 'Unsuccessful!')
        ).add_footer(
            text='Player\'s stats include pots.\n'
            '{s}'.format(s='Armor/Weapon includes dungeon stats.\n'
                         if include_dungeon else '') +
            'Please make sure your "before" stats are correct before reforging.'
        )

        for equipment in best_equip:
            for rarity in best_equip[equipment]:
                text = colorize(
                    ' + '.join([
                        f'{best_equip[equipment][rarity][reforge]} {reforge.title()}'
                        for reforge in best_equip[equipment][rarity]
                    ]), RARITY_COLORS[rarity])
                embed.add_field(
                    name=f'**{rarity.title()} {equipment.title()}**',
                    value=text,
                    inline=False)

        base_mod = profile.stats.combat_bonus + (profile.stats.archery_bonus if
                                                 weapon.type == 'bow' else 0)

        if include_dungeon:
            normal_mod = emod('base', weapon) + base_mod

            normal_damage_before = damage(
                profile.weapon.stats.get_stat('damage',
                                              dungeon=include_dungeon),
                profile.stats.get_stat('strength', dungeon=include_dungeon),
                profile.stats.get_stat('crit damage', dungeon=include_dungeon),
                normal_mod)

            normal_damage_after = damage(best_stats['damage'],
                                         best_stats['strength'],
                                         best_stats['crit damage'], normal_mod)

            before_damage = f'```Base > {normal_damage_before:,.0f}```'
            after_damage = f'```Base > {normal_damage_after:,.0f}```'
        else:
            zealot_mod = emod('zealots', weapon) + base_mod
            slayer_mod = emod('slayer bosses', weapon) + base_mod

            slayer_mult = 1
            if weapon.internal_name == 'REAPER_SWORD':
                slayer_mult = 3
            elif weapon.internal_name == 'SCORPION_FOIL':
                slayer_mult = 2.5

            zealot_damage_before = damage(
                profile.weapon.stats.get_stat('damage',
                                              dungeon=include_dungeon),
                profile.stats.get_stat('strength', dungeon=include_dungeon),
                profile.stats.get_stat('crit damage', dungeon=include_dungeon),
                zealot_mod)
            slayer_damage_before = damage(
                profile.weapon.stats.get_stat('damage',
                                              dungeon=include_dungeon),
                profile.stats.get_stat('strength', dungeon=include_dungeon),
                profile.stats.get_stat('crit damage', dungeon=include_dungeon),
                slayer_mod)
            slayer_damage_before *= slayer_mult

            zealot_damage_after = damage(best_stats['damage'],
                                         best_stats['strength'],
                                         best_stats['crit damage'], zealot_mod)
            slayer_damage_after = damage(best_stats['damage'],
                                         best_stats['strength'],
                                         best_stats['crit damage'], slayer_mod)
            slayer_damage_after *= slayer_mult

            before_damage = f'```Zealots > {zealot_damage_before:,.0f}\nSlayers > {slayer_damage_before:,.0f}```'
            after_damage = f'```Zealots > {zealot_damage_after:,.0f}\nSlayers > {slayer_damage_after:,.0f}```'

        weapon_damage_before = ''
        weapon_damage_after = ''
        if weapon.internal_name == 'MIDAS_SWORD':
            weapon_damage_before = f'Weapon damage > {profile.weapon.stats.get_stat("damage", dungeon=include_dungeon):.0f}'
            weapon_damage_after = f'Weapon damage > {best_stats["damage"]:.0f}'

        embed.add_field(
            name='**Before**',
            value=
            f'```Strength > {profile.stats.get_stat("strength", dungeon=include_dungeon):.0f}\n'
            f'Crit damage > {profile.stats.get_stat("crit damage", dungeon=include_dungeon):.0f}%\n'
            f'Crit chance > {profile.stats.get_stat("crit chance", dungeon=include_dungeon):.0f}%\n'
            f'Attack speed > {profile.stats.get_stat("attack speed", dungeon=include_dungeon):.0f}%\n'
            f'{weapon_damage_before}```{before_damage}')
        embed.add_field(
            name='**After**',
            value=
            f'```Strength > {best_stats["strength"]:.0f}\nCrit damage > {best_stats["crit damage"]:.0f}%\n'
            f'Crit chance > {best_stats["crit chance"]:.0f}%\nAttack speed > {best_stats["attack speed"]:.0f}%\n'
            f'{weapon_damage_after}```{after_damage}')

        if not is_optimized:
            embed.add_field(
                name='**Warning**',
                value=
                'The bot took too long to optimize your gear so it gave up.\n'
                'This result is the best it could do in the allotted time.',
                inline=False)

        await embed.send()
Example #10
0
    async def stats(self, ctx):
        """
        Displays stats about the bot including number of servers and users.
        """
        server_rankings = sorted(self.bot.guilds, key=lambda guild: guild.member_count, reverse=True)[:10]
        #server_rankings2 = f'{"Top Servers".ljust(28)} | Users\n' + '\n'.join(
        #    [f'{guild.name[:28].ljust(28)} | {guild.member_count}' for guild in server_rankings])

        embed = Embed(
            ctx=ctx,
            title='SkyBlock Simplified Bot Stats',
            description=f'This discord server in on shard {(ctx.guild.shard_id if ctx.guild else 0) + 1} / {self.bot.shard_count}.'
        ).add_field(
            name='Top Servers',
            value='\n'.join([f'{guild.name}' for guild in server_rankings]),
            inline=True,
        ).add_field(
            name='Users',
            value='\n'.join([f'{guild.member_count}' for guild in server_rankings]),
            inline=True,
        ).add_field(
            name='\u200b',
            value='\u200b',
            inline=True,
        ).add_field(
            name='Servers',
            value=f'{self.bot.user.name} is running in {len(self.bot.guilds):,} servers with {sum(len(guild.text_channels) for guild in self.bot.guilds):,} channels.',
            inline=False
        ).add_field(
            name='Users',
            value=f'There are currently {sum(guild.member_count for guild in self.bot.guilds):,} users with access to the bot.',
            inline=False
        )

        shards = []
        for x in range(self.bot.shard_count):
            shards.append([0, 0, 0])
        for x in self.bot.guilds:
            shards[x.shard_id][0] += 1
            shards[x.shard_id][1] += len(x.text_channels)
            shards[x.shard_id][2] += x.member_count

        for x in range(self.bot.shard_count):
            embed.add_field(
                name=f'Shard {x + 1}',
                value=f'{shards[x][0]:,} servers\n{shards[x][1]:,} channels\n{shards[x][2]:,} members',
                inline=True
            )

        shard_count = len(shards)
        total_fields = 3 * round((shard_count + 3) / 3)
        remaining_fields = total_fields - shard_count

        # column adjustment
        for x in range(remaining_fields):
            embed.add_field(
                name='\u200b',
                value='\u200b',
                inline=True
            )

        memory_usage = self.process.memory_full_info().uss / 1024 ** 2
        cpu_usage = self.process.cpu_percent() / psutil.cpu_count()
        embed.add_field(
            name='Process',
            value=f'{memory_usage:.2f} MiB\n{cpu_usage:.2f}% CPU',
            inline=True
        ).add_field(
            name='Latency',
            value=f'{self.bot.latency * 1000:.0f} ms',
            inline=True
        ).add_field(
            name='\u200b',
            value='\u200b',
            inline=True
        )

        await embed.send()
Example #11
0
    async def enable(self, ctx):
        """
        Use this to enable a command!
        """
        disabled_commands = []
        for command in self.bot.walk_commands():
            if not command.enabled and command.qualified_name not in [
                    'disable', 'enable'
            ]:
                disabled_commands.append(command)

        if not disabled_commands:
            return await ctx.send(
                f'{ctx.author.mention}\nThere is no disabled commands to enable!'
            )

        embed = Embed(ctx=ctx,
                      title='Enter a command from the list below to enable!')
        _num = (len(disabled_commands) // 3)
        _left_over = len(disabled_commands) % 3
        _field1 = '\n'.join([
            command.qualified_name
            for command in disabled_commands[:_num + _left_over]
        ]) + '\u200b'
        if _field1:
            embed.add_field(value=f'{_field1}')
        else:
            embed.add_field()
        _field2 = '\n'.join([
            command.qualified_name
            for command in disabled_commands[_num + _left_over:(_num * 2) +
                                             _left_over]
        ]) + '\u200b'
        embed.add_field(value=f'{_field2}')
        _field3 = '\n'.join([
            command.qualified_name
            for command in disabled_commands[(_num * 2) + _left_over:]
        ]) + '\u200b'
        embed.add_field(value=f'{_field3}')
        await embed.send()

        def check(m):
            if m.author.id == ctx.author.id and m.channel.id == ctx.channel.id:
                if m.clean_content.lower() == 'exit':
                    raise SessionTimeout
                if not m.clean_content.isdigit():
                    return True
            return False

        _run = True
        while _run:
            msg = await self.bot.wait_for('message', timeout=60.0, check=check)
            for command in disabled_commands:
                if msg.clean_content.lower() == command.qualified_name:
                    command.enabled = True
                    await ctx.send(
                        f'{ctx.author.mention}\nSuccessfully enable command `{command.qualified_name}`!'
                    )
                    _run = False
                    break
            if _run:
                await ctx.send(
                    f'{ctx.author.mention}\nDid you make a typo? Choose a command from the list.'
                )