async def servInfo(self, ctx, server: int):
        out = ''
        page = None
        if server < 9999:
            page = server

        if page:  # grab all server info
            all_servers = self.bot.guilds
            members = sum(len(g.members) for g in all_servers)
            out += f"I am in {len(all_servers)} servers, with {members} members."
            for s in sorted(all_servers,
                            key=lambda k: len(k.members),
                            reverse=True):
                out += "\n{} ({}, {} members, {} bot)".format(
                    s.name, s.id, len(s.members),
                    sum(1 for m in s.members if m.bot))
        else:  # grab one server info
            guild = self.bot.get_guild(server)
            user = None
            if not guild:
                channel = self.bot.get_channel(server)
                if not channel:
                    user = self.bot.get_user(server)
                else:
                    guild = channel.guild

            if (not guild) and (not user):
                return await ctx.send("Not found.")

            if user:
                return await ctx.send("{} - {}".format(str(user), user.id))
            else:
                try:
                    invite = (await next(c for c in guild.channels
                                         if isinstance(c, discord.TextChannel)
                                         ).create_invite()).url
                except:
                    invite = None

                if invite:
                    out += "\n\n**{} ({}, {})**".format(
                        guild.name, guild.id, invite)
                else:
                    out += "\n\n**{} ({})**".format(guild.name, guild.id)
                out += "\n{} members, {} bot".format(
                    len(guild.members), sum(1 for m in guild.members if m.bot))
                for c in guild.channels:
                    out += '\n|- {} ({})'.format(c.name, c.id)
        out = discord_trim(out)
        if page is None:
            for m in out:
                await ctx.send(m)
        else:
            await ctx.send(out[page - 1])
Exemple #2
0
async def on_command_error(error, ctx):
    if isinstance(error, commands.CommandNotFound):
        return
    print("Error caused by message: `{}`".format(ctx.message.content))
    traceback.print_exception(type(error),
                              error,
                              error.__traceback__,
                              file=sys.stderr)
    tb = ''.join(
        traceback.format_exception(type(error), error, error.__traceback__))
    if isinstance(error, commands.CheckFailure):
        await bot.send_message(
            ctx.message.channel,
            "Error: Either you do not have the permissions to run this command or the command is disabled."
        )
        return
    elif isinstance(error, (commands.MissingRequiredArgument,
                            commands.BadArgument, commands.NoPrivateMessage)):
        await bot.send_message(
            ctx.message.channel, "Error: " + str(error) + "\nUse `.help " +
            ctx.command.qualified_name + "` for help.")
    elif bot.mask & coreCog.debug_mask:
        await bot.send_message(
            ctx.message.channel, "Error: " + str(error) +
            "\nThis incident has been reported to the developer.")
        try:
            await bot.send_message(
                bot.owner,
                "Error in channel {} ({}), server {} ({}): {}\nCaused by message: `{}`"
                .format(ctx.message.channel, ctx.message.channel.id,
                        ctx.message.server, ctx.message.server.id, repr(error),
                        ctx.message.content))
        except AttributeError:
            await bot.send_message(
                bot.owner,
                "Error in PM with {} ({}): {}\nCaused by message: `{}`".format(
                    ctx.message.author.mention, str(ctx.message.author),
                    repr(error), ctx.message.content))
        for o in discord_trim(tb):
            await bot.send_message(bot.owner, o)
    else:
        await bot.send_message(ctx.message.channel, "Error: " + str(error))
Exemple #3
0
    async def debug_roll(self, ctx, *, rollStr: str):
        adv = 0
        self.bot.db.incr('dice_rolled_life')
        if re.search('(^|\s+)(adv|dis)(\s+|$)', rollStr) is not None:
            adv = 1 if re.search('(^|\s+)adv(\s+|$)',
                                 rollStr) is not None else -1
            rollStr = re.sub('(adv|dis)(\s+|$)', '', rollStr)
        res = roll(rollStr, adv=adv, debug=True)
        out = res.result
        try:
            await self.bot.delete_message(ctx.message)
        except:
            pass
        outStr = ctx.message.author.mention + '  :game_die:\n' + out
        if len(outStr) > 1999:
            await self.bot.say(
                ctx.message.author.mention +
                '  :game_die:\n[Output truncated due to length]\n**Result:** '
                + str(res.plain))
        else:
            await self.bot.say(outStr)

        debug = ""
        for p in res.raw_dice.parts:
            if isinstance(p, SingleDiceGroup):
                debug += "SingleDiceGroup:\nnum_dice={0.num_dice}, max_value={0.max_value}, annotation={0.annotation}, operators={0.operators}".format(
                    p) + \
                         "\nrolled={}\n\n".format(', '.join(repr(r) for r in p.rolled))
            elif isinstance(p, Constant):
                debug += "Constant:\nvalue={0.value}, annotation={0.annotation}\n\n".format(
                    p)
            elif isinstance(p, Operator):
                debug += "Operator:\nop={0.op}, annotation={0.annotation}\n\n".format(
                    p)
            else:
                debug += "Comment:\ncomment={0.comment}\n\n".format(p)
        for t in discord_trim(debug):
            await self.bot.say(t)
Exemple #4
0
async def on_command_error(ctx, error):
    if isinstance(error, commands.CommandNotFound):
        return
    log.debug("Error caused by message: `{}`".format(ctx.message.content))
    log.debug('\n'.join(
        traceback.format_exception(type(error), error, error.__traceback__)))
    if isinstance(error, AvraeException):
        return await ctx.send(str(error))
    tb = ''.join(
        traceback.format_exception(type(error), error, error.__traceback__))
    if isinstance(error,
                  (commands.MissingRequiredArgument, commands.BadArgument,
                   commands.NoPrivateMessage, ValueError)):
        return await ctx.send("Error: " + str(error) +
                              f"\nUse `{ctx.prefix}help " +
                              ctx.command.qualified_name + "` for help.")
    elif isinstance(error, commands.CheckFailure):
        return await ctx.send("Error: You are not allowed to run this command."
                              )
    elif isinstance(error, commands.CommandOnCooldown):
        return await ctx.send(
            "This command is on cooldown for {:.1f} seconds.".format(
                error.retry_after))
    elif isinstance(error, CommandInvokeError):
        original = error.original
        if isinstance(original,
                      EvaluationError):  # PM an alias author tiny traceback
            e = original.original
            if not isinstance(e, AvraeException):
                tb = f"```py\nError when parsing expression {original.expression}:\n" \
                    f"{''.join(traceback.format_exception(type(e), e, e.__traceback__, limit=0, chain=False))}\n```"
                try:
                    await ctx.author.send(tb)
                except Exception as e:
                    log.info(f"Error sending traceback: {e}")
        if isinstance(original, AvraeException):
            return await ctx.send(str(original))
        if isinstance(original, Forbidden):
            try:
                return await ctx.author.send(
                    f"Error: I am missing permissions to run this command. "
                    f"Please make sure I have permission to send messages to <#{ctx.channel.id}>."
                )
            except:
                try:
                    return await ctx.send(
                        f"Error: I cannot send messages to this user.")
                except:
                    return
        if isinstance(original, NotFound):
            return await ctx.send(
                "Error: I tried to edit or delete a message that no longer exists."
            )
        if isinstance(original, ValueError) and str(original) in (
                "No closing quotation", "No escaped character"):
            return await ctx.send("Error: No closing quotation.")
        if isinstance(original, (ClientResponseError, InvalidArgument,
                                 asyncio.TimeoutError, ClientOSError)):
            return await ctx.send("Error in Discord API. Please try again.")
        if isinstance(original, HTTPException):
            if original.response.status == 400:
                return await ctx.send(
                    "Error: Message is too long, malformed, or empty.")
            if original.response.status == 500:
                return await ctx.send(
                    "Error: Internal server error on Discord's end. Please try again."
                )
        if isinstance(original, OverflowError):
            return await ctx.send(
                f"Error: A number is too large for me to store.")

    error_msg = gen_error_message()

    await ctx.send(
        f"Error: {str(error)}\nUh oh, that wasn't supposed to happen! "
        f"Please join <http://support.avrae.io> and tell the developer that {error_msg}!"
    )
    try:
        await bot.owner.send(
            f"**{error_msg}**\n" \
            + "Error in channel {} ({}), server {} ({}): {}\nCaused by message: `{}`".format(
                ctx.channel, ctx.channel.id, ctx.guild,
                ctx.guild.id, repr(error),
                ctx.message.content))
    except AttributeError:
        await bot.owner.send(f"**{error_msg}**\n" \
                             + "Error in PM with {} ({}), shard 0: {}\nCaused by message: `{}`".format(
            ctx.author.mention, str(ctx.author), repr(error), ctx.message.content))
    for o in discord_trim(tb):
        await bot.owner.send(o)
    log.error("Error caused by message: `{}`".format(ctx.message.content))
    traceback.print_exception(type(error),
                              error,
                              error.__traceback__,
                              file=sys.stderr)
Exemple #5
0
async def on_command_error(ctx, error):
    if isinstance(error, commands.CommandNotFound):
        return
    log.debug("Error caused by message: `{}`".format(ctx.message.content))
    log.debug('\n'.join(traceback.format_exception(type(error), error, error.__traceback__)))
    if isinstance(error, AvraeException):
        return await ctx.send(str(error))
    tb = ''.join(traceback.format_exception(type(error), error, error.__traceback__))
    if isinstance(error,
                  (commands.MissingRequiredArgument, commands.BadArgument, commands.NoPrivateMessage, ValueError)):
        return await ctx.send("Error: " + str(
            error) + f"\nUse `{ctx.prefix}help " + ctx.command.qualified_name + "` for help.")
    elif isinstance(error, commands.CheckFailure):
        return await ctx.send("Error: You are not allowed to run this command.")
    elif isinstance(error, commands.CommandOnCooldown):
        return await ctx.send("This command is on cooldown for {:.1f} seconds.".format(error.retry_after))
    elif isinstance(error, CommandInvokeError):
        original = error.original
        if isinstance(original, EvaluationError):  # PM an alias author tiny traceback
            e = original.original
            if not isinstance(e, AvraeException):
                tb = f"```py\n{''.join(traceback.format_exception(type(e), e, e.__traceback__, limit=0, chain=False))}\n```"
                try:
                    await ctx.author.send(tb)
                except Exception as e:
                    log.info(f"Error sending traceback: {e}")
        if isinstance(original, AvraeException):
            return await ctx.send(str(original))
        if isinstance(original, Forbidden):
            try:
                return await ctx.author.send(
                    f"Error: I am missing permissions to run this command. "
                    f"Please make sure I have permission to send messages to <#{ctx.channel.id}>."
                )
            except:
                try:
                    return await ctx.send(f"Error: I cannot send messages to this user.")
                except:
                    return
        if isinstance(original, NotFound):
            return await ctx.send("Error: I tried to edit or delete a message that no longer exists.")
        if isinstance(original, ValueError) and str(original) in ("No closing quotation", "No escaped character"):
            return await ctx.send("Error: No closing quotation.")
        if isinstance(original, AttributeError) and str(original) in ("'NoneType' object has no attribute 'name'",):
            return await ctx.send("Error in Discord API. Please try again.")
        if isinstance(original, (ClientResponseError, InvalidArgument, asyncio.TimeoutError)):
            return await ctx.send("Error in Discord API. Please try again.")
        if isinstance(original, HTTPException):
            if original.response.status == 400:
                return await ctx.send("Error: Message is too long, malformed, or empty.")
            if original.response.status == 500:
                return await ctx.send("Error: Internal server error on Discord's end. Please try again.")
        if isinstance(original, redis.ResponseError):
            await ctx.send(
                "Error: I am having an issue writing to my database. Please report this to the dev!")
            return await bot.owner.send(f"Database error!\n{repr(original)}")
        if isinstance(original, OverflowError):
            return await ctx.send(
                f"Error: A number is too large for me to store. "
                f"This generally means you've done something terribly wrong.")

    error_msg = gen_error_message()

    await ctx.send(
        f"Error: {str(error)}\nUh oh, that wasn't supposed to happen! "
        f"Please ignore this and tell the developer that {error_msg}!")
    try:
        await bot.owner.send(
            f"**{error_msg}**\n" \
            + "Error in channel {} ({}), server {} ({}): {}\nCaused by message: `{}`".format(
                ctx.channel, ctx.channel.id, ctx.guild,
                ctx.guild.id, repr(error),
                ctx.message.content))
        await ctx.send("Try again. The goblins should have been murdered. If they haven't harrass the developers. They'll love that")
        process = ["sudo", "systemctl", "restart", "mongodb"]
        subprocess.run(process)
    except AttributeError:
        await bot.owner.send(f"**{error_msg}**\n" \
                             + "Error in PM with {} ({}), shard 0: {}\nCaused by message: `{}`".format(
            ctx.author.mention, str(ctx.author), repr(error), ctx.message.content))
    for o in discord_trim(tb):
        await bot.owner.send(o)
    log.error("Error caused by message: `{}`".format(ctx.message.content))
    traceback.print_exception(type(error), error, error.__traceback__, file=sys.stderr)
    async def servInfo(self, server: str = None):
        out = ''
        page = None
        num_shards = int(getattr(self.bot, 'shard_count', 1))
        if len(server) < 3:
            page = int(server)
            server = None

        req = self.request_server_info(server)
        for _ in range(300):  # timeout after 30 sec
            if len(self.requests[req]) >= num_shards:
                break
            else:
                await asyncio.sleep(0.1)

        data = self.requests[req]
        del self.requests[req]
        for shard in range(num_shards):
            if str(shard) not in data:
                out += '\nMissing data from shard {}'.format(shard)

        if server is None:  # grab all server info
            all_servers = []
            for _shard, _data in data.items():
                for s in _data:
                    s['shard'] = _shard
                all_servers += _data
            out += f"I am in {len(all_servers)} servers, with {sum(s['members'] for s in all_servers)} members."
            for s in sorted(all_servers,
                            key=lambda k: k['members'],
                            reverse=True):
                out += "\n{} ({}, {} members, {} bot, shard {})".format(
                    s['name'], s['id'], s['members'], s['bots'], s['shard'])
        else:  # grab one server info
            try:
                _data = next(
                    (s, d) for s, d in data.items() if d
                    is not None)  # here we assume only one shard will reply
                shard = _data[0]
                data = _data[1]
            except StopIteration:
                return await self.bot.say("Not found.")

            if data.get('private_message'):
                return await self.bot.say("{} - {} - Shard 0".format(
                    data['name'], data['user']))
            else:
                if data.get('invite'):
                    out += "\n\n**{} ({}, {}, shard {})**".format(
                        data['name'], data['id'], data['invite'], shard)
                else:
                    out += "\n\n**{} ({}, shard {})**".format(
                        data['name'], data['id'], shard)
                out += "\n{} members, {} bot".format(data['members'],
                                                     data['bots'])
                for c in data['channels']:
                    out += '\n|- {} ({})'.format(c['name'], c['id'])
        out = discord_trim(out)
        if page is None:
            for m in out:
                await self.bot.say(m)
        else:
            await self.bot.say(out[page - 1])
async def on_command_error(error, ctx):
    if isinstance(error, commands.CommandNotFound):
        return
    log.debug("Error caused by message: `{}`".format(ctx.message.content))
    log.debug('\n'.join(
        traceback.format_exception(type(error), error, error.__traceback__)))
    if isinstance(error, AvraeException):
        return await bot.send_message(ctx.message.channel, str(error))
    tb = ''.join(
        traceback.format_exception(type(error), error, error.__traceback__))
    if isinstance(error, commands.CheckFailure):
        await bot.send_message(
            ctx.message.channel,
            "Error: Either you do not have the permissions to run this command, the command is disabled, or something went wrong internally."
        )
        return
    elif isinstance(error,
                    (commands.MissingRequiredArgument, commands.BadArgument,
                     commands.NoPrivateMessage, ValueError)):
        return await bot.send_message(
            ctx.message.channel, "Error: " + str(error) + "\nUse `!help " +
            ctx.command.qualified_name + "` for help.")
    elif isinstance(error, commands.CommandOnCooldown):
        return await bot.send_message(
            ctx.message.channel,
            "This command is on cooldown for {:.1f} seconds.".format(
                error.retry_after))
    elif isinstance(error, CommandInvokeError):
        original = error.original
        if isinstance(original,
                      EvaluationError):  # PM an alias author tiny traceback
            e = original.original
            if not isinstance(e, AvraeException):
                tb = f"```py\n{''.join(traceback.format_exception(type(e), e, e.__traceback__, limit=0, chain=False))}\n```"
                try:
                    await bot.send_message(ctx.message.author, tb)
                except Exception as e:
                    log.info(f"Error sending traceback: {e}")
        if isinstance(original, AvraeException):
            return await bot.send_message(ctx.message.channel, str(original))
        if isinstance(original, Forbidden):
            try:
                return await bot.send_message(
                    ctx.message.author,
                    "Error: I am missing permissions to run this command. Please make sure I have permission to send messages to <#{}>."
                    .format(ctx.message.channel.id))
            except:
                try:
                    return await bot.send_message(
                        ctx.message.channel,
                        f"Error: I cannot send messages to this user.")
                except:
                    return
        if isinstance(original, NotFound):
            return await bot.send_message(
                ctx.message.channel,
                "Error: I tried to edit or delete a message that no longer exists."
            )
        if isinstance(original, ValueError) and str(original) in (
                "No closing quotation", "No escaped character"):
            return await bot.send_message(ctx.message.channel,
                                          "Error: No closing quotation.")
        if isinstance(original, AttributeError) and str(original) in (
                "'NoneType' object has no attribute 'name'", ):
            return await bot.send_message(
                ctx.message.channel, "Error in Discord API. Please try again.")
        if isinstance(original, (ClientResponseError, InvalidArgument)):
            return await bot.send_message(
                ctx.message.channel, "Error in Discord API. Please try again.")
        if isinstance(original, HTTPException):
            if original.response.status == 400:
                return await bot.send_message(
                    ctx.message.channel,
                    "Error: Message is too long, malformed, or empty.")
            if original.response.status == 500:
                return await bot.send_message(
                    ctx.message.channel,
                    "Error: Internal server error on Discord's end. Please try again."
                )
        if isinstance(original, redis.ResponseError):
            await bot.send_message(
                ctx.message.channel,
                "Error: I am having an issue writing to my database. Please report this to the dev!"
            )
            return await bot.send_message(
                bot.owner, f"Database error!\n{repr(original)}")

    error_msg = gen_error_message()

    await bot.send_message(
        ctx.message.channel,
        f"Error: {str(error)}\nUh oh, that wasn't supposed to happen! "
        f"Please join <https://support.avrae.io> and tell the developer that {error_msg}!"
    )
    try:
        await bot.send_message(bot.owner,
                               f"**{error_msg}**\n" \
                               + "Error in channel {} ({}), server {} ({}), shard {}: {}\nCaused by message: `{}`".format(
                                   ctx.message.channel, ctx.message.channel.id, ctx.message.server,
                                   ctx.message.server.id, getattr(bot, 'shard_id', 0), repr(error),
                                   ctx.message.content))
    except AttributeError:
        await bot.send_message(bot.owner, f"**{error_msg}**\n" \
                               + "Error in PM with {} ({}), shard 0: {}\nCaused by message: `{}`".format(
            ctx.message.author.mention, str(ctx.message.author), repr(error), ctx.message.content))
    for o in discord_trim(tb):
        await bot.send_message(bot.owner, o)
    log.error("Error caused by message: `{}`".format(ctx.message.content))
    traceback.print_exception(type(error),
                              error,
                              error.__traceback__,
                              file=sys.stderr)
    async def on_command_error(self, ctx, error):
        owner = self.bot.get_user(GG.OWNER)
        if isinstance(error, commands.CommandNotFound):
            return
        log.debug("Error caused by message: `{}`".format(ctx.message.content))
        log.debug('\n'.join(
            traceback.format_exception(type(error), error,
                                       error.__traceback__)))
        if isinstance(error, FeCrawlerException):
            return await ctx.send(str(error))
        tb = ''.join(
            traceback.format_exception(type(error), error,
                                       error.__traceback__))
        if isinstance(error,
                      (commands.MissingRequiredArgument, commands.BadArgument,
                       commands.NoPrivateMessage, ValueError)):
            return await ctx.send("Error: " + str(error) +
                                  f"\nUse `{ctx.prefix}oldhelp " +
                                  ctx.command.qualified_name + "` for help.")
        elif isinstance(error, commands.CheckFailure):
            return await ctx.send(
                "Error: You are not allowed to run this command.")
        elif isinstance(error, commands.CommandOnCooldown):
            return await ctx.send(
                "This command is on cooldown for {:.1f} seconds.".format(
                    error.retry_after))
        elif isinstance(error, UnexpectedQuoteError):
            return await ctx.send(
                f"Error: You either gave me a command that requires quotes, and you forgot one.\n"
                f"Or you have used the characters that are used to define what's optional and required (<> and [])\n"
                f"Please check the ``!help`` command for proper usage of my commands."
            )
        elif isinstance(error, ExpectedClosingQuoteError):
            return await ctx.send(
                f"Error: You gave me a command that requires quotes, and you forgot one at the end."
            )
        elif isinstance(error, CommandInvokeError):
            original = error.original
            if isinstance(
                    original,
                    EvaluationError):  # PM an alias author tiny traceback
                e = original.original
                if not isinstance(e, FeCrawlerException):
                    tb = f"```py\nError when parsing expression {original.expression}:\n" \
                         f"{''.join(traceback.format_exception(type(e), e, e.__traceback__, limit=0, chain=False))}\n```"
                    try:
                        await ctx.author.send(tb)
                    except Exception as e:
                        log.info(f"Error sending traceback: {e}")
            if isinstance(original, FeCrawlerException):
                return await ctx.send(str(original))
            if isinstance(original, Forbidden):
                try:
                    return await ctx.author.send(
                        f"Error: I am missing permissions to run this command. "
                        f"Please make sure I have permission to send messages to <#{ctx.channel.id}>."
                    )
                except:
                    try:
                        return await ctx.send(
                            f"Error: I cannot send messages to this user.")
                    except:
                        return
            if isinstance(original, NotFound):
                return await ctx.send(
                    "Error: I tried to edit or delete a message that no longer exists."
                )
            if isinstance(original, ValueError) and str(original) in (
                    "No closing quotation", "No escaped character"):
                return await ctx.send("Error: No closing quotation.")
            if isinstance(original, (ClientResponseError, InvalidArgument,
                                     asyncio.TimeoutError, ClientOSError)):
                return await ctx.send("Error in Discord API. Please try again."
                                      )
            if isinstance(original, HTTPException):
                if original.response.status == 400:
                    return await ctx.send(
                        "Error: Message is too long, malformed, or empty.")
                if original.response.status == 500:
                    return await ctx.send(
                        "Error: Internal server error on Discord's end. Please try again."
                    )
                if original.response.status == 503:
                    return await ctx.send(
                        "Error: Connecting failure on Discord's end. (Service unavailable). Please check https://status.discordapp.com for the status of the Discord Service, and try again later."
                    )
            if isinstance(original, OverflowError):
                return await ctx.send(
                    f"Error: A number is too large for me to store.")
            if isinstance(original, SearchException):
                return await ctx.send(
                    f"Search Timed out, please try the command again.")
            if isinstance(original, KeyError):
                if str(original) == "'content-type'":
                    return await ctx.send(
                        f"The command errored on Discord's side. I can't do anything about this, Sorry.\nPlease check https://status.discordapp.com for the status on the Discord API, and try again later."
                    )

        error_msg = gen_error_message()

        await ctx.send(
            f"Error: {str(error)}\nUh oh, that wasn't supposed to happen! "
            f"Please join the 5eCrawler Support Discord (!support) and tell the developer that: **{error_msg}!**"
        )
        if not self.bot.testing:
            try:
                await owner.send(
                    f"**{error_msg}**\n" \
                    + "Error in channel {} ({}), server {} ({}): {}\nCaused by message: `{}`".format(
                        ctx.channel, ctx.channel.id, ctx.guild,
                        ctx.guild.id, repr(error),
                        ctx.message.content))
            except AttributeError:
                await owner.send(f"**{error_msg}**\n" \
                                 + "Error in PM with {} ({}), shard 0: {}\nCaused by message: `{}`".format(
                    ctx.author.mention, str(ctx.author), repr(error), ctx.message.content))
            for o in discord_trim(tb):
                await owner.send(o)
        log.error("Error caused by message: `{}`".format(ctx.message.content))