示例#1
0
    async def can_run(self, ctx: commands.Context):
        original = ctx.command
        ctx.command = self

        try:
            if not (await ctx.bot.can_run(ctx)):
                raise commands.CheckFailure(
                    f'The global check functions for {self.qualified_name} failed.'
                )

            cog = self.instance
            if cog is not None:
                try:
                    local_check = getattr(
                        cog, f'_{cog.__class__.__name__}__local_check')
                except AttributeError:
                    pass
                else:
                    ret = await discord.utils.maybe_coroutine(local_check, ctx)
                    if not ret:
                        return False

            if ctx.author.id in ctx.bot.owners:
                return True

            predicates = self.checks
            if not predicates:
                return True

            return await discord.utils.async_all(
                predicate(ctx) for predicate in predicates)
        finally:
            ctx.command = original
示例#2
0
文件: core.py 项目: avimetry/avimetry
    async def can_run(self, ctx: commands.Context) -> bool:
        if not self.enabled:
            raise DisabledCommand(f"{self.name} command is disabled")

        original = ctx.command
        ctx.command = self

        try:
            if not await ctx.bot.can_run(ctx):
                raise CheckFailure(f"The global check functions for command {self.qualified_name} failed.")

            cog = self.cog
            if cog is not None:
                local_check = Cog._get_overridden_method(cog.cog_check)
                if local_check is not None:
                    ret = await discord.utils.maybe_coroutine(local_check, ctx)
                    if not ret:
                        return False

            predicates = self.checks
            if not predicates:
                # since we have no checks, then we just return True.
                return True

            return await discord.utils.async_all(predicate(ctx) for predicate in predicates)  # type: ignore
        finally:
            ctx.command = original
示例#3
0
    async def reinvoke(self, ctx: commands.Context, *, call_hooks=False):
        early_invoke = not self.invoke_without_command
        if early_invoke:
            ctx.command = self
            await self._parse_arguments(ctx)

            if call_hooks:
                await self.call_before_hooks(ctx)

        view = ctx.view
        previous = view.index
        view.skip_ws()
        trigger = view.get_word()

        if trigger:
            ctx.subcommand_passed = trigger
            ctx.invoked_subcommand = self.all_commands.get(trigger)

        if early_invoke:
            try:
                await self.callback(*ctx.args, **ctx.kwargs)
            except Exception:
                ctx.command_failed = True
                raise
            finally:
                if call_hooks:
                    await self.call_after_hooks(ctx)

        if trigger and ctx.invoked_subcommand:
            ctx.invoked_with = trigger
            await ctx.invoked_subcommand.reinvoke(ctx, call_hooks=call_hooks)
        elif not early_invoke:
            view.index = previous
            view.previous = previous
            await super().reinvoke(ctx, call_hooks=call_hooks)
示例#4
0
 async def can_run(self, ctx: commands.Context, cmd: Union[RainCommand, RainGroup]) -> bool:
     ctx.command = cmd
     can_run = True
     if cmd.checks:
         try:
             can_run = (await discord.utils.async_all(predicate(ctx) for predicate in cmd.checks))
         except commands.CheckFailure:
             can_run = False
     return can_run
示例#5
0
 async def on_command_error(self, ctx: commands.Context, error):
     """only for CommandNotFound"""
     error = getattr(error, "original", error)
     if isinstance(error, commands.CommandNotFound
                   ) and ctx.message.content.startswith(f"{ctx.prefix}!"):
         ctx.timer = time()
         ctx.iscallback = True
         ctx.command = self.bot.get_command("!")
         await ctx.command.callback(self, ctx)
示例#6
0
 async def warn(self, ctx: commands.Context, member: Union[MemberOrID, str]=None, *, reason: str=None) -> None:
     """Manage warns"""
     if isinstance(member, (discord.User, discord.Member)):
         if reason:
             ctx.command = self.add_
             await ctx.invoke(self.add_, member=member, reason=reason)
         else:
             await ctx.invoke(self.bot.get_command('help'), command_or_cog='warn add')
     else:
         await ctx.invoke(self.bot.get_command('help'), command_or_cog='warn')
示例#7
0
    async def do_test_command(self, ctx: commands.Context,
                              cmd: commands.Command, *args, **kwargs) -> None:
        if isinstance(cmd, str):
            cmd = self.bot.get_command(cmd)

        ctx.command = cmd

        if not cmd:
            raise TypeError(
                "Command must be name of command or discord.ext.commands.Command object!"
            )

        return await self._do_test(cmd, *args, **kwargs, ctx=ctx)
示例#8
0
    async def get_context(client: Client, msg: Message) -> Context:
        view = StringView(msg.content)
        ctx = Context(prefix=None, view=view, bot=client, message=msg)

        if client._skip_check(msg.author.id, client.user.id):
            return ctx

        prefix = await client._get_prefix(msg)
        invoked_prefix = prefix

        if isinstance(prefix, str):
            if not view.skip_string(prefix):
                return ctx
        else:
            invoked_prefix = discord.utils.find(view.skip_string, prefix)
            if invoked_prefix is None:
                return ctx

        invoker = view.get_word()
        ctx.invoked_with = invoker
        ctx.prefix = invoked_prefix
        ctx.command = client.all_commands.get(invoker)
        return ctx
示例#9
0
async def on_command_error(ctx: Context, error: Exception):
    "Suppress command check failures and invalid commands."

    if isinstance(error, CheckFailure):
        return

    if isinstance(error, CommandNotFound):
        if isinstance(ctx.channel, DMChannel):
            return

        cog = ctx.bot.get_cog('alias')

        if cog is None:
            return

        guild = str(ctx.guild.id)
        aliases = cog.aliases[guild] if guild in cog.aliases else None

        if aliases is None:
            return

        name = ctx.message.content \
            .replace(ctx.prefix, '').split(' ')[0].strip()

        if name not in aliases:
            return

        cmd = ctx.bot.get_command(aliases[name])

        if cmd is None:
            return

        ctx.command = cmd

        return await ctx.bot.invoke(ctx)

    raise error
示例#10
0
    async def add_(self, ctx: commands.Context, member: MemberOrID, *,
                   reason: str) -> None:
        """Warn a user

        Can also be used as `warn <member> [reason]`"""
        if get_perm_level(member, await self.bot.db.get_guild_config(
                ctx.guild.id))[0] >= get_perm_level(
                    ctx.author, await self.bot.db.get_guild_config(ctx.guild.id
                                                                   ))[0]:
            await ctx.send('User has insufficient permissions')
        else:
            guild_config = await self.bot.db.get_guild_config(ctx.guild.id)
            guild_warns = guild_config.warns
            warn_punishments = guild_config.warn_punishments
            warn_punishment_limits = [i.warn_number for i in warn_punishments]
            warns = list(
                filter(lambda w: w['member_id'] == str(member.id),
                       guild_warns))

            cmd = None
            punish = False

            num_warns = len(warns) + 1
            fmt = f'You have been warned in **{ctx.guild.name}**, reason: {reason}. This is warning #{num_warns}.'

            if warn_punishments:
                punishments = list(
                    filter(lambda x: int(x) == num_warns,
                           warn_punishment_limits))
                if not punishments:
                    punish = False
                    above = list(
                        filter(lambda x: int(x) > num_warns,
                               warn_punishment_limits))
                    if above:
                        closest = min(map(int, above))
                        cmd = warn_punishments.get_kv('warn_number',
                                                      closest).punishment
                        if cmd == 'ban':
                            cmd = 'bann'
                        fmt += f' You will be {cmd}ed on warning {closest}.'
                else:
                    punish = True
                    cmd = warn_punishments.get_kv(
                        'warn_number', max(map(int, punishments))).punishment
                    if cmd == 'ban':
                        cmd = 'bann'
                    fmt += f' You have been {cmd}ed from the server.'

            try:
                await member.send(fmt)
            except discord.Forbidden:
                if ctx.author != ctx.guild.me:
                    await ctx.send(
                        'The user has PMs disabled or blocked the bot.')
            finally:
                guild_config = await self.bot.db.get_guild_config(ctx.guild.id)
                current_date = (ctx.message.created_at + timedelta(
                    hours=guild_config.time_offset)).strftime('%Y-%m-%d')
                if len(guild_warns) == 0:
                    case_number = 1
                else:
                    case_number = guild_warns[-1]['case_number'] + 1
                push = {
                    'case_number': case_number,
                    'date': current_date,
                    'member_id': str(member.id),
                    'moderator_id': str(ctx.author.id),
                    'reason': reason
                }
                await self.bot.db.update_guild_config(
                    ctx.guild.id, {'$push': {
                        'warns': push
                    }})
                if ctx.author != ctx.guild.me:
                    await ctx.send(self.bot.accept)
                await self.send_log(ctx, member, reason, case_number)

                # apply punishment
                if punish:
                    if cmd == 'bann':
                        cmd = 'ban'
                    ctx.command = self.bot.get_command(cmd)
                    ctx.author = ctx.guild.me
                    await ctx.invoke(ctx.command,
                                     member,
                                     reason=f'Hit warn limit {num_warns}')