예제 #1
0
    def bot_permissions(self) -> Permissions:
        """:class:`.Permissions`: Returns the resolved permissions for the bot in this channel.
        Shorthand for :meth:`.abc.GuildChannel.permissions_for` or :attr:`.Interaction.app_permissions`.

        For interaction-based commands, this will reflect the effective permissions
        for :class:`Context` calls, which may differ from calls through
        other :class:`.abc.Messageable` endpoints, like :attr:`channel`.

        Notably, sending messages, embedding links, and attaching files are always
        permitted, while reading messages might not be.

        .. versionadded:: 2.0
        """
        channel = self.channel
        if channel.type == ChannelType.private:
            return Permissions._dm_permissions()
        if not self.interaction:
            # channel and me will always match relevant types here
            return channel.permissions_for(self.me)  # type: ignore
        guild = channel.guild
        base = self.interaction.app_permissions
        if self.channel.type in (ChannelType.voice, ChannelType.stage_voice):
            if not base.connect:
                # voice channels cannot be edited by people who can't connect to them
                # It also implicitly denies all other voice perms
                denied = Permissions.voice()
                denied.update(manage_channels=True, manage_roles=True)
                base.value &= ~denied.value
        else:
            # text channels do not have voice related permissions
            denied = Permissions.voice()
            base.value &= ~denied.value
        base.update(
            embed_links=True,
            attach_files=True,
            send_tts_messages=False,
        )
        if isinstance(channel, Thread):
            base.send_messages_in_threads = True
        else:
            base.send_messages = True
        return base
예제 #2
0
    def permissions(self) -> Permissions:
        """:class:`.Permissions`: Returns the resolved permissions for the invoking user in this channel.
        Shorthand for :meth:`.abc.GuildChannel.permissions_for` or :attr:`.Interaction.permissions`.

        .. versionadded:: 2.0
        """
        if self.channel.type is ChannelType.private:
            return Permissions._dm_permissions()
        if not self.interaction:
            # channel and author will always match relevant types here
            return self.channel.permissions_for(self.author)  # type: ignore
        base = self.interaction.permissions
        if self.channel.type in (ChannelType.voice, ChannelType.stage_voice):
            if not base.connect:
                # voice channels cannot be edited by people who can't connect to them
                # It also implicitly denies all other voice perms
                denied = Permissions.voice()
                denied.update(manage_channels=True, manage_roles=True)
                base.value &= ~denied.value
        else:
            # text channels do not have voice related permissions
            denied = Permissions.voice()
            base.value &= ~denied.value
        return base
예제 #3
0
    async def on_call(self, ctx, args, **flags):
        value = flags.pop('value', None)

        if value:
            if flags:
                return '{error} value flag conflict with all other flags'

            if not value.isdigit():
                return '{error} value is not integer'

            permissions = Permissions(permissions=int(value))
        else:
            permissions = None

        channel_flag = flags.pop('channel', None)
        if channel_flag is None:
            channel = ctx.channel
        else:
            channel = await find_channel(channel_flag, ctx.guild)
            if channel is None:
                return '{warning} Channel not found'

        only_true  = flags.pop('t', False)
        only_false = flags.pop('f', False)
        use_global = flags.pop('global', False)

        if only_true and only_false:
            return '{error} t and f flags conflict'

        if permissions is not None:
            target = value
        elif len(args) == 1:
            if use_global:
                permissions = ctx.author.guild_permissions
            else:
                permissions = channel.permissions_for(ctx.author)
            target = str(ctx.author)
        else:
            role = await find_role(args[1:], ctx.guild)
            if role is not None:
                permissions = role.permissions
                target = str(role)

                if use_global:
                    if permissions.administrator:
                        permissions = Permissions.all()
                elif permissions.administrator:
                    if isinstance(channel, VoiceChannel):
                        permissions = Permissions(
                            Permissions.all().value & ~Permissions.text().value)
                    elif isinstance(channel, TextChannel):
                        permissions = Permissions(
                            Permissions.all().value & ~Permissions.voice().value)
                    else:
                        permissions = Permissions(
                            Permissions.all().value
                            & ~Permissions.text().value
                            & ~Permissions.voice().value
                        )
                else:
                    for k, v in channel.overwrites_for(role):
                        if v is not None:
                            setattr(permissions, k, v)
            else:
                member = await find_user(args[1:], ctx.message, strict_guild=True)
                if member is None:
                    return '{warning} Role or member not found'

                if use_global:
                    permissions = member.guild_permissions
                else:
                    permissions = channel.permissions_for(member)
                target = str(member)

        if only_true:
            p = [(k, v) for k, v in permissions if v]
        elif only_false:
            p = [(k, v) for k, v in permissions if not v]
        else:
            p = permissions

        return f'Permissions of **{target}** in **{channel.mention if not use_global else ctx.guild}**```\n' + '\n'.join(f'{PERM_THERE if v else PERM_MISSING} | {k}' for k, v in p) + '```'