Esempio n. 1
0
    async def on_command_error(self, ctx, error):
        """The event triggered when an error is raised while invoking a command."""
        async def send_del(*args, **kwargs):
            await ctx.reply(*args,
                            delete_after=60,
                            mention_author=False,
                            **kwargs)
            if ctx.me.permissions_in(ctx.channel).manage_messages:
                with contextlib.suppress(discord.NotFound):
                    await ctx.message.delete(delay=60)

        if hasattr(ctx.command, 'on_error'):
            return

        cog = ctx.cog
        if cog:
            if cog._get_overridden_method(cog.cog_command_error) is not None:
                return

        ignored = (commands.CommandNotFound, )
        default_error = (commands.NotOwner, commands.TooManyArguments,
                         flags.ArgumentParsingError, NotInDpy)

        error = getattr(error, 'original', error)

        if isinstance(error, ignored):
            return

        if isinstance(error, commands.DisabledCommand):
            await send_del(f'{ctx.command} has been disabled.')

        elif isinstance(error, commands.CommandOnCooldown):
            if ctx.author == self.bot.stella:
                return await ctx.reinvoke()
            await send_del(embed=BaseEmbed.to_error(
                title="Cooldown Error",
                description=
                f"You're on cooldown. Retry after `{error.retry_after:.2f}` seconds"
            ))
        elif isinstance(error, default_error):
            await send_del(embed=BaseEmbed.to_error(description=f"{error}"))
        else:
            if template := await self.generate_signature_error(ctx, error):
                await send_del(embed=template)
            else:
Esempio n. 2
0
    async def generate_signature_error(self, ctx, error):
        command = ctx.command
        help_com = self.bot.help_command
        help_com.context = ctx
        real_signature = help_com.get_command_signature(command, ctx)
        if ctx.current_parameter is None:
            return

        parameter = [*ctx.command.params.values()
                     ][ctx.command.cog is not None:]
        pos = parameter.index(ctx.current_parameter)
        list_sig = real_signature.split()
        pos += list_sig.index(ctx.invoked_with)

        target = list_sig[pos]
        print(target, "here")
        target_list = list(target)
        alpha_index = [
            i for i, a in enumerate(target) if a.isalnum() or a in ("|", '"')
        ]
        minimum, maximum = min(alpha_index), max(alpha_index)
        target_list[minimum] = target_list[minimum].capitalize()
        list_sig[pos] = "".join(target_list)
        space = " " * sum([len(x) + 1 for x in list_sig[:pos]])
        offset = " " * int((minimum + 1 + (maximum - minimum)) / 2)
        embed = BaseEmbed.to_error(description=f"```{error}```\n")
        embed.description += f"**Errored at**\n" \
                             f"```prolog\n" \
                             f"{' '.join(list_sig)}\n" \
                             f"{space}{offset}^\n" \
                             f"```\n"
        if (demo := help_com.get_demo(command)) and isinstance(
                error, commands.MissingRequiredArgument):
            cooldown = self.error_cooldown
            bucket = cooldown.get_bucket(ctx.message)
            if not bucket.update_rate_limit():
                embed.description += "**Command Example**"
                embed.set_image(url=demo)
Esempio n. 3
0
        elif isinstance(error, commands.CommandOnCooldown):
            if ctx.author == self.bot.stella:
                return await ctx.reinvoke()
            await send_del(embed=BaseEmbed.to_error(
                title="Cooldown Error",
                description=
                f"You're on cooldown. Retry after `{error.retry_after:.2f}` seconds"
            ))
        elif isinstance(error, default_error):
            await send_del(embed=BaseEmbed.to_error(description=f"{error}"))
        else:
            if template := await self.generate_signature_error(ctx, error):
                await send_del(embed=template)
            else:
                await send_del(embed=BaseEmbed.to_error(description=f"{error}")
                               )
                traceback_error = print_exception(
                    f'Ignoring exception in command {ctx.command}:', error)
                if not self.bot.tester:
                    error_message = f"**Command:** {ctx.message.content}\n" \
                                    f"**Message ID:** `{ctx.message.id}`\n" \
                                    f"**Author:** `{ctx.author}`\n" \
                                    f"**Guild:** `{ctx.guild}`\n" \
                                    f"**Channel:** `{ctx.channel}`\n" \
                                    f"**Jump:** [`jump`]({ctx.message.jump_url})```py\n" \
                                    f"{traceback_error}\n" \
                                    f"```"
                    await self.bot.error_channel.send(
                        embed=BaseEmbed.default(ctx, description=error_message)
                    )
Esempio n. 4
0
    async def connect4(self, ctx, player2: Player):
        GAME = "Connect 4"
        message = BaseEmbed.invite(ctx,
                                   GAME,
                                   status=None,
                                   invitation=self.INVITATION.format(
                                       player2, ctx, GAME))
        message["content"] = player2.mention
        responses_text = tuple(
            BaseEmbed.invite(ctx, GAME, status=not x, invited=player2)
            for x in range(2))  # first is approve, second disapprove
        responses = {
            ctx.bot.INVITE_REACT[1 - x]: y
            for x, y in zip(range(2), responses_text)
        }
        game = self.bot.global_player.add(ctx, [player2.id],
                                          game_classes.Connect4)
        error = f"Looks like {{}} seconds is up! Sorry **{ctx.author}**, You will have to request for another one"
        respond = await prompt(ctx,
                               message=message,
                               event_type="reaction_add",
                               responses=responses,
                               error=error,
                               target_id={player2.id})
        if not respond:
            self.bot.global_player.remove(game)
            return
        game.status = True

        def check_turn(game):
            def predicate(m):
                checking = (m.author in (game.current_player, self.bot.stella),
                            m.content.isdigit()
                            and 1 <= int(m.content) <= game.cols)
                return all(checking)

            return predicate

        async def connect4_prompt(game, message=None):
            if not message:
                display = await game.render_board()
                player = game.current_player
                description = f"`{player}`, It's your turn. Please choose a column between `1` to `7`."
                message = BaseEmbed.board(player.mention,
                                          game.color,
                                          display,
                                          "connect_4",
                                          title="Connect 4",
                                          description=description)
            error = f"`{{}}` seconds is up. Looks like `{game.last_player}` wins"
            return await prompt(ctx,
                                message=message,
                                predicate=check_turn(game),
                                error=error,
                                delete_after=True,
                                ret=True,
                                delete_timeout=True)

        message_sent = None
        while response := await connect4_prompt(game, message_sent):
            if isinstance(response, discord.Message):
                message_sent = None
                if game_result := await atry_catch(game.insert,
                                                   int(response.content) - 1,
                                                   ret=True):
                    if not isinstance(game_result, Connect4ColumnFull):
                        await ctx.send(**game_result)
                        break
                    else:
                        message_sent = {
                            "embed":
                            BaseEmbed.to_error(title="Connect 4",
                                               description=str(game_result))
                        }