Ejemplo n.º 1
0
    async def add_perms(self, target, member, guild):
        """Add a target role / channel to a member."""
        roles, channels = self.get_target(target, guild)
        for role in roles:
            if role is not None and role not in member.roles:
                await member.add_roles(role)
        for channel in channels:
            if channel is not None:
                perms: disnake.PermissionOverwrite = channel.overwrites_for(member)

                if not perms.is_empty():
                    deny_exp_perm = disnake.Permissions()
                    deny_exp_perm.view_channel = True

                    perm_pair = perms.pair()
                    if deny_exp_perm.value == perm_pair[1].value and perm_pair[0].value == 0:
                        # User have only expected permission (Allow: None, Deny: view_channel).
                        # This configuration will remove overwrite before checks and set.
                        # This will prevent from removing higher permissions from channels (or bans).
                        await channel.set_permissions(member, overwrite=None)

                perms_for: disnake.Permissions = channel.permissions_for(member)
                if perms_for.administrator or perms_for.view_channel:  # Is mod, or now have access. Ignore
                    continue

                current_perms = channel.permissions_for(member)
                if not current_perms.read_messages:
                    if not perms.is_empty():
                        perms.read_messages = True
                        await channel.set_permissions(member, overwrite=perms)
                    else:
                        await channel.set_permissions(member, read_messages=True)
Ejemplo n.º 2
0
    async def jsk_invite(self, ctx: commands.Context, *perms: str):
        """
        Retrieve the invite URL for this bot.

        If the names of permissions are provided, they are requested as part of the invite.
        """

        scopes = ('bot', 'applications.commands')
        permissions = disnake.Permissions()

        for perm in perms:
            if perm not in dict(permissions):
                raise commands.BadArgument(f"Invalid permission: {perm}")

            setattr(permissions, perm, True)

        application_info = await self.bot.application_info()

        query = {
            "client_id": application_info.id,
            "scope": "+".join(scopes),
            "permissions": permissions.value
        }

        return await ctx.send(
            f"Link to invite this bot:\n<https://discordapp.com/oauth2/authorize?{urlencode(query, safe='+')}>"
        )
Ejemplo n.º 3
0
    def apply_overwrites(permissions: dict, allow: int, deny: int, name: str):
        """
        Applies overwrites to the permissions dictionary (see permtrace),
        based on an allow and deny mask.
        """

        allow: disnake.Permissions = disnake.Permissions(allow)
        deny: disnake.Permissions = disnake.Permissions(deny)

        # Denies first..
        for key, value in dict(deny).items():
            # Check that this is denied and it is not already denied
            # (we want to show the lowest-level reason for the denial)
            if value and permissions[key][0]:
                permissions[key] = (False,
                                    f"it is the channel's {name} overwrite")

        # Then allows
        for key, value in dict(allow).items():
            # Check that this is allowed and it is not already allowed
            # (we want to show the lowest-level reason for the allowance)
            if value and not permissions[key][0]:
                permissions[key] = (True,
                                    f"it is the channel's {name} overwrite")
Ejemplo n.º 4
0
    async def guildinfo(self,
                        inter: disnake.ApplicationCommandInteraction,
                        *,
                        guild_id: int = None):
        """Shows info about the current server."""

        if guild_id is not None and await self.bot.is_owner(inter.author):
            guild = self.bot.get_guild(guild_id)
            if guild is None:
                return await inter.send(f'Invalid Guild ID given.')
        else:
            guild = inter.guild

        roles = [role.name.replace('@', '@\u200b') for role in guild.roles]

        if not guild.chunked:
            async with inter.typing():
                await guild.chunk(cache=True)

        # figure out what channels are 'secret'
        everyone = guild.default_role
        everyone_perms = everyone.permissions.value
        secret = Counter()
        totals = Counter()
        for channel in guild.channels:
            allow, deny = channel.overwrites_for(everyone).pair()
            perms = disnake.Permissions((everyone_perms & ~deny.value)
                                        | allow.value)
            channel_type = type(channel)
            totals[channel_type] += 1
            if not perms.read_messages:
                secret[channel_type] += 1
            elif isinstance(channel,
                            disnake.VoiceChannel) and (not perms.connect
                                                       or not perms.speak):
                secret[channel_type] += 1

        e = disnake.Embed(color=inter.me.color)
        e.title = guild.name
        e.description = f'**ID**: {guild.id}\n**Owner**: {guild.owner}'
        if guild.icon:
            e.set_thumbnail(url=guild.icon)

        channel_info = []
        key_to_emoji = {
            disnake.TextChannel: 'Text Channels: ',
            disnake.VoiceChannel: 'Voice Channels: ',
        }
        for key, total in totals.items():
            secrets = secret[key]
            try:
                emoji = key_to_emoji[key]
            except KeyError:
                continue

            if secrets:
                channel_info.append(f'{emoji} {total} ({secrets} locked)')
            else:
                channel_info.append(f'{emoji} {total}')

        info = []
        features = set(guild.features)
        all_features = {
            'PARTNERED': 'Partnered',
            'VERIFIED': 'Verified',
            'DISCOVERABLE': 'Server Discovery',
            'COMMUNITY': 'Community Server',
            'FEATURABLE': 'Featured',
            'WELCOME_SCREEN_ENABLED': 'Welcome Screen',
            'INVITE_SPLASH': 'Invite Splash',
            'VIP_REGIONS': 'VIP Voice Servers',
            'VANITY_URL': 'Vanity Invite',
            'COMMERCE': 'Commerce',
            'LURKABLE': 'Lurkable',
            'NEWS': 'News Channels',
            'ANIMATED_ICON': 'Animated Icon',
            'BANNER': 'Banner'
        }

        for feature, label in all_features.items():
            if feature in features:
                info.append(f'\N{WHITE HEAVY CHECK MARK} {label}')

        if info:
            e.add_field(name='Features', value='\n'.join(info))

        e.add_field(name='Channels', value='\n'.join(channel_info))

        if guild.premium_tier != 0:
            boosts = f'Level {guild.premium_tier}\n{guild.premium_subscription_count} boosts'
            last_boost = max(guild.members,
                             key=lambda m: m.premium_since or guild.created_at)
            if last_boost.premium_since is not None:
                boosts = f'{boosts}\nLast Boost: {last_boost} ({time.human_timedelta(last_boost.premium_since, accuracy=2)})'
            e.add_field(name='Boosts', value=boosts, inline=False)

        bots = sum(m.bot for m in guild.members)
        fmt = f'Total: {guild.member_count} ({formats.plural(bots):bot})'

        e.add_field(name='Members', value=fmt, inline=False)
        e.add_field(name='Roles',
                    value=', '.join(roles)
                    if len(roles) < 10 else f'{len(roles)} roles')

        emoji_stats = Counter()
        for emoji in guild.emojis:
            if emoji.animated:
                emoji_stats['animated'] += 1
                emoji_stats['animated_disabled'] += not emoji.available
            else:
                emoji_stats['regular'] += 1
                emoji_stats['disabled'] += not emoji.available

        fmt = f'Regular: {emoji_stats["regular"]}/{guild.emoji_limit}\n' \
              f'Animated: {emoji_stats["animated"]}/{guild.emoji_limit}\n' \

        if emoji_stats['disabled'] or emoji_stats['animated_disabled']:
            fmt = f'{fmt}Disabled: {emoji_stats["disabled"]} regular, {emoji_stats["animated_disabled"]} animated\n'

        fmt = f'{fmt}Total Emoji: {len(guild.emojis)}/{guild.emoji_limit*2}'
        e.add_field(name='Emoji', value=fmt, inline=False)
        e.set_footer(text='Created').timestamp = guild.created_at
        await inter.send(embed=e)
Ejemplo n.º 5
0
 def __init__(
     self,
     default_value,
     permissions=disnake.Permissions(manage_guild=True)) -> None:
     self._default_value = default_value
     self.permissions = permissions