Пример #1
0
    def __check(self, ctx):
        msg = ctx.message
        if checks.is_owner_check(ctx):
            return True

        try:
            entry = self.bot.db.not_json_get("permissions", {})[msg.server.id]
        except (KeyError, AttributeError):
            return True
        else:
            name = ctx.command.qualified_name.split(' ')[0]
            return name not in entry
Пример #2
0
    async def _send(self, ctx: commands.Context,
                    messageable: typing.Union[discord.Member, discord.User,
                                              discord.TextChannel], *,
                    message: str):
        """
        send a message to a messageable
        """

        if (not checks.is_owner_check(ctx)):
            message = "{0}\n{1}".format(ctx.author, message)

        await messageable.send(message)
        await ctx.send("done.")
Пример #3
0
    async def process_message(self, message):
        content = message.content
        loops = 0

        while True:
            pos = content.find('!!')
            if pos == -1:
                return

            content = content[pos + 1:]
            end_pos = content.find('!!')
            command_content = content if end_pos == -1 else content[:end_pos]

            command = bot.SubcommandMessage(message=message)
            command.content = command_content.strip()

            await self.bot.process_commands(command)

            loops += 1
            if not checks.is_owner_check(message) and loops >= 3:
                break
Пример #4
0
    async def andre(self, ctx, *, command: str = None):

        all_commands = {
            '#Profile': {
                'user setup': {
                    'args': '',
                    'usage': 'Starts the q/a to fill your profile.'
                },
                'user update': {
                    'args': '',
                    'usage': 'Lets you update part of your profile.'
                },
                'user extras setup': {
                    'args': '',
                    'usage': 'Starts the q/a to fill your extras profile.'
                },
                'user extras update': {
                    'args': '',
                    'usage': 'Lets you update part of your extras profile.'
                },
            },

            'User stats': {
                'users': {
                    'args': '[extras]',
                    'usage': 'Prints the list of users who have filled their profile. If extras is specified, also prints tho who have filled their extras profile.'
                },
                'profile': {
                    'args': '[[+]extras] [user]',
                    'usage': 'Shows a user\'s profile (or yours if *user* is unspecified). If extras is specified, print the extras profile questions instead. If +extras is specified, print both'
                },
                'tz': {
                    'args': '[user]',
                    'usage': 'Prints the timezone of the specified user (if no *user* is specified, prints all known users grouped by local time).'
                },
                'stats': {
                    'args': '[field]',
                    'usage': 'Prints a list of members grouped by the specified field. If no *field* is specified, prints the available fields.'
                },
                'projects': {
                    'args': '[name]',
                    'usage': 'Prints details about the specified project. If no *name* is specified, lists all projects.'
                },
                'badges': {
                    'args': '[user]',
                    'usage': 'Shows a user\'s badges (or yours if *user* is unspecified).'
                },
            },

            '#MAL': {
                'search': {
                    'args': '[anime|manga] [search]',
                    'usage': 'Searches for an anime/manga (if unspecified, anime is the default) and prints a short list of the 10 first results.'
                },
                'anime': {
                    'args': '[search|ID]',
                    'usage': 'Searches for an anime and prints basic info about it, plus a list of all members\'s who have the anime in their lists.'
                },
                'manga': {
                    'args': '[search|ID]',
                    'usage': 'Searches for a manga and prints basic info about it, plus a list of all members\'s who have the manga in their lists.'
                },
                'airing': {
                    'args': '[watching] [anime|member]',
                    'usage':
                        """Prints the airing shows in the memebers' lists.
                        If *watching* is specified, only watching anime are considered.
                        If a *anime* filter argument is provided, only print the anime matching the filter.
                        If a *member* filter is provided instead, print the anime in that member's list."""
                },
                'animelist': {
                    'args': '[status] [user]',
                    'usage': 'Prints the user\'s list in the specified status (or you if *user* is unspecified).'
                },
                'mangalist': {
                    'args': '[status] [user]',
                    'usage': 'Prints the user\'s list in the specified status (or you if *user* is unspecified).'
                },
                'nextmal': {
                    'args': '[user]',
                    'usage': 'Prints a random entry from the user\'s PTW list (or you if *user* is unspecified).'
                },
                'shared': {
                    'args': '[anime|manga] [arguments]',
                    'usage':
                        """Prints stats about common anime or manga.
                        *arguments* can be any arrangement of the following, in the format *key=value*:
                        
                        **style**: How to display results. Values: *short*, *details*, *full*. Defaults to details.
                        **results**: Limit how many results to display. 0 means no limit. Defaults to 5.
                        **reverse**: Reverse the sort. Can be true of false. Defaults to false.
                        **sort**: Type of sort to apply. Values: *members* (number of members who shared this anime/manga), *completed* (same but only completed), *score* (average member score). Defaults to members.
                        **min_members**: Can be used with sort=score to only show anime/manga scored by at least that amount of members. Defaults to 0.
                
                        Example: `!shared anime sort=score min_members=10 results=10`"""
                },
                'sao': {
                    'args': '[user]',
                    'usage': 'Prints the SAO scores for the given user (or you if *user* is unspecified).'
                },
                'compare': {
                    'args': '[user1] [user2] [arguments]',
                    'usage':
                        """Compares the lists of the two specified users.
                        *arguments* can be any arrangement of the following, in the format *key=value*:
                        
                        **entity**: *anime* or *manga*. Defaults to anime.
                        **results**: Limit how many results to display. 0 means no limit. Defaults to 20.
                        **min_score**: The minimum score the user must have given for the entity to be included. Defaults to 1.
                        **max_score**: The maximum score the user must have given for the entity to be included. Defaults to 10.
                        **diff_score**: The difference in score between the two users. -1 means no limit. Defaults to -1.
                        **sort**: Type of sort to apply. Values: *similar* (lower difference first) or *different* (higher difference first). Defaults to similar.
                        **group**: Whether to group the results by score difference. Defaults to true.
                
                        Example: `!compare usera userb group=false results=10 diff_score=3`"""
                },
                'affinity': {
                    'args': '[user1] [user2] [anime|manga]',
                    'usage': 'Prints the affinity scores between the two users. If user1 is not specified, use your username instad. If user2 is not specified, compare with all other members.'
                },
                'unique': {
                    'args': '[anime|manga] [user_comparing] user_to_compare',
                    'usage': 'Finds unique anime/manga from *user_comparing*\'s list that *user_to_compare* has not watched/read yet, and sort them by score. *user_comparing* will be set to you if not specified.'
                },
                'when': {
                    'args': '[anime|manga] [title]',
                    'usage': 'Prints the start/end dates of an anime/manga (if unspecified, anime is the default).'
                },
                'scoredistribution': {
                    'args': '[arguments]',
                    'usage':
                        """Prints the score distribution of users in the server.
                        *arguments* can be any arrangement of the following, in the format *key=value*:

                        **entity**: *anime* or *manga*. Defaults to anime.
                        **score**: Show the distribution for a specific score [1-10]. Defaults to None.
                        **sort**: Type of sort to apply. Values: 
                            *percent* (sort by percent of the specific score in the list)
                            *amount* (sort by most of a specific score in the list)
                            *balanced* (sort by percent * amount)
                        Defaults to percent.

                        Example: `!scoredistribution entity=manga score=8`"""
                },
                'meanscores': {
                    'args': '[anime|manga]',
                    'usage': 'Prints the mean score of all the users.'
                }
            },

            'VNDB': {
                'vndb': {
                    'args': '',
                    'usage': 'Prints detailed help about the vndb commands.'
                },
                'vndbalias': {
                    'args': '',
                    'usage': 'Prints usage for adding or removing vndb aliases.'
                },
                'vn': {
                    'args': '[options] [id|name]',
                    'usage': 'Displays the specified VN. See `!vndb` for more details on the available options.'
                },
                'vns': {
                    'args': '[name]',
                    'usage': 'Searches for VNs with the specified name.'
                },
                'vnt': {
                    'args': '[options] [id|name]',
                    'usage': 'Displays the tags of the specified VN. See `!vndb` for more details on the available options.'
                },
                'vnc': {
                    'args': '[options] [id|name]',
                    'usage': 'Displays the specified VN character. See `!vndb` for more details on the available options.'
                },
                'vncs': {
                    'args': '[name]',
                    'usage': 'Searches for VN characters with the specified name.'
                },
                'vnct': {
                    'args': '[options] [id|name]',
                    'usage': 'Displays the traits of the specified VN character. See `!vndb` for more details on the available options.'
                },
                'vndbapi': {
                    'args': '[id]',
                    'usage': 'Returns a json string containing the requested character. The json output is always wrapped around triple backquotes.'
                },
            },

            'User lists': {
                'mal': {
                    'args': '[user]',
                    'usage': 'Prints basic MAL info for the specified user (or you if *user* is unspecified).'
                },
                'scores': {
                    'args': '[anime|manga] [user] [filter]',
                    'usage':
                        """Prints the score distribution for the specified user (or you if *user* is unspecified).
                        If *anime* or *manga* is not specified, anime will be used as the default.
                        If a *filter* argument is provided, it will instead print all anime/manga matching the score filter.
                        *filter* can be one of the following: `n`, `=n`, `<n`, `<=n`, `>n` or `>=n` where n is in [0, 10]
                        
                        Scores are considered shamful if given to PTW anime or dropped anime (unless you have watched 80% or more than 50 eps)"""
                },
            },

            '#Languages': {
                'moonrunes': {
                    'args': '[runes]',
                    'usage': 'Translates the given Japanese text. If no argument is provided, translate the last 10 messages'
                },
                'tr': {
                    'args': '[[from]=>to] text',
                    'usage': 'Translates the given text. If no language is specified, it will translate to english.'
                },
            },

            'Random': {
                'about': {
                    'args': '',
                    'usage': 'Prints info about André'
                },
                'updatelist': {
                    'args': '[user]',
                    'usage': 'Updates your (or *user*\'s) lists cache.'
                },
                'bots': {
                    'args': '',
                    'usage': 'Prints a short description of this server\'s bots.'
                },
                'school': {
                    'args': '[year]',
                    'usage': 'Translates a school year (grade). If *year* is not specified, prints the entire conversion table.'
                },
                'ping': {
                    'args': '',
                    'usage': 'It\'s a ping command. It pings the bot. What pings commands are supposed to do.'
                },
                'quote': {
                    'args': '',
                    'usage': 'Get a random inspirational quote.'
                },
                'exec': {
                    'args': '[command] [;; command]*',
                    'usage': 'Evaluates the commands separated by ;; in order.'
                },
                'bc': {
                    'args': '[expr]',
                    'usage': 'Evaluates the expression using the ExprTk math library. You may wrap your expression around backquotes.'
                },
            },

            'Special': {
                'eva': {
                    'args': '',
                    'usage': 'It does nothing.'
                },
                'noop': {
                    'args': '',
                    'usage': 'It does nothing.'
                },
                'meesterp': {
                    'args': '',
                    'usage': 'An alias for `!exec !updatelist ;; !airing @me`.'
                },
            },

            'Database': {
                'db users': {
                    'args': '[fmt]',
                    'usage': 'Dumps the saved users\' discord_id/mal_name. Default fmt is `{0}:{1}`'
                },
            },

            ##### Admin

            '!Admin': {
                'whois': {
                    'args': '[user]',
                    'usage': 'Displays the different names for the specified user.'
                },
                'newgame': {
                    'args': '[game]',
                    'usage': 'Updates André\'s current game. If *game* in unspecified, takes a random game. Enables the random game rotation'
                },
                'setgame': {
                    'args': '[type] [game]',
                    'usage': 'Updates André\'s current game. Disables the random game rotation.'
                },
                'clearcache': {
                    'args': '',
                    'usage': 'Clears all lists cache.'
                },
                'admin': {
                    'args': '',
                    'usage': 'Starts André\'s interactive mode.'
                },
                'moonrunes auto': {
                    'args': '[enable/disable]',
                    'usage': 'Enables/Disables automatic moonrune translation for the current channel.'
                },
                'update': {
                    'args': '[force]',
                    'usage': 'Runs `git pull` and restarts the bot.'
                },
                'restart': {
                    'args': '[force]',
                    'usage': 'Restarts the bot.'
                },
                'shutdown': {
                    'args': '',
                    'usage': 'This kills the bot.'
                },
                'say': {
                    'args': '[message]',
                    'usage': 'Prints the message.'
                },
                'for': {
                    'args': '[n] [command]',
                    'usage': 'Executes the command *n* times.'
                },
                'avatar': {
                    'args': '',
                    'usage': 'Runs the script that changes my avatar.'
                },
                'birthday': {
                    'args': '',
                    'usage': 'Checks members\' birthdays.'
                },
                'birthdaytime': {
                    'args': '',
                    'usage': 'Prints time remaining before next birthday check.'
                },
                'extrasdb': {
                    'args': '[subcommand]',
                    'usage': 'Manage the extras db. If no subcommand is passed, prints an help message.'
                },
                'backupdb': {
                    'args': '',
                    'usage': 'Makes a backup of the database.'
                },
                'purgedb': {
                    'args': '[mal_name or discord_id] [field_name]',
                    'usage':
                        """Removes the db field for the selected user.
                        Will always make a backup of the database beforehand.
                        If `*` is provided, remove the user completely.
                        Accepted fields are: 'mal_name', 'gender', 'birthdate', 'bio', 'timezone', 'languages', 'prog_languages', 'projects', 'extras'"""
                },
                'ignorenickname': {
                    'args': '[user] [true|false]',
                    'usage': 'If true, the nickname of this user will not be considered when displaying names.'
                },
                'botstate': {
                    'args': '',
                    'usage': 'Prints the running user commands.'
                },
                'clearbotstate': {
                    'args': '',
                    'usage': 'Clears the running user commands state.'
                },
                'badgesdb': {
                    'args': '[subcommand]',
                    'usage': 'Manage the badges db. If no subcommand is passed, prints an help message.'
                },
                'setmalembed': {
                    'args': 'link_template',
                    'usage': 'Sets the MALembed link template. use `<username>` as a placeholder for the username.'
                },
                'ban': {
                    'args': '[member]',
                    'usage': 'Bans the member from using commands'
                },
                'bans': {
                    'args': '',
                    'usage': 'List the current bans'
                },
                'unban': {
                    'args': '[member]',
                    'usage': 'Unban the member'
                },
            }
        }

        message = ''
        if command:
            command = command.lower()
            for category, command_lists in all_commands.items():
                for name, info in command_lists.items():
                    if command == name:
                        if category.startswith('!') and not checks.is_owner_check(ctx.message):
                            await ctx.bot.say('This is top secret, sorry.')
                        else:
                            args = f' {info["args"]}' if info["args"] else ''
                            usage = inspect.cleandoc(info['usage'])
                            await ctx.bot.say(f'`!{command}{args}`\n\n{usage}')
                        return
            message += f'Unknown command `{command}`\n\n'

        message += '```Available commands```'
        for category, items in all_commands.items():
            if category.startswith('!') and not checks.is_owner_check(ctx.message):
                pass
            else:
                if category.startswith('#') or category.startswith('!'):
                    message += f'\n**{category[1:]}** - '
                else:
                    message += f'**{category}** - '
                message += ', '.join(map(lambda name: f'*{name}*', items.keys()))
                message += '\n'

        message += '\n\nType `!help [command]` to get more info for a specific command.'
        await utils.safe_say(ctx, message)
Пример #5
0
    async def _flags(self, ctx: commands.Context, member: typing.Optional[discord.Member]):
        """
        display a user's flags

        defaults to your own

        examples:
            `>flags`
            `>flags 310418322384748544`
        """

        author = ctx.author

        if (member):
            ctx = copy.copy(ctx)
            ctx.author = member

        flags = list()

        if (checks.is_owner_check(ctx)):
            flags.append("owner")

        if (checks.is_supervisor_check(ctx)):
            flags.append("supervisor")

        if (checks.is_support_check(ctx)):
            flags.append("support team")

        if (checks.is_alpha_check(ctx)):
            flags.append("alpha tester")

        if (checks.is_beta_check(ctx)):
            flags.append("beta tester")

        if (checks.is_dj_check(ctx)):
            flags.append("dj")

        if (ctx.author.id in ctx.bot._settings.whitelist):
            flags.append("whitelisted")

        if (ctx.author.id in ctx.bot._settings.blacklist):
            flags.append("blacklisted")

        if (not flags):
            await ctx.send("no results")
            return

        message = ", ".join(flags)

        color = ctx.me.color if ctx.guild else discord.Color.blurple()
        e = discord.Embed(color=color)
        e.add_field(name="Flags for {0}".format(ctx.author), value=message)
        e.set_footer(
            text = "{0} | {1}".format(
                author.name,
                format.humanize_datetime()
            ),
            icon_url=author.avatar_url
        )

        await ctx.send(embed=e)
Пример #6
0
    async def loot(self, ctx: NabCtx):
        """Scans an image of a container looking for Tibia items and shows an approximate loot value.

        An image must be attached with the message. The prices used are NPC prices only.

        The image requires the following:

        - Must be a screenshot of inventory windows (backpacks, depots, etc).
        - Have the original size, the image can't be scaled up or down, however it can be cropped.
        - The image must show the complete slot.
        - JPG images are usually not recognized.
        - PNG images with low compression settings take longer to be scanned or aren't detected at all.

        The bot shows the total loot value and a list of the items detected, separated into the NPC that buy them.
        """
        if ctx.author.id in self.processing_users and not checks.is_owner_check(
                ctx):
            await ctx.send(
                "I'm already scanning an image for you! Wait for me to finish that one."
            )
            return

        if len(ctx.message.attachments) == 0:
            await ctx.send(
                "You need to upload a picture of your loot and type the command in the comment."
            )
            return

        attachment: discord.Attachment = ctx.message.attachments[0]
        if attachment.height is None:
            await ctx.send("That's not an image!")
            return
        if attachment.size > 2097152:
            await ctx.send(
                "That image was too big! Try splitting it into smaller images, or cropping out anything "
                "irrelevant.")
            return
        if attachment.height < MIN_HEIGHT or attachment.width < MIN_WIDTH:
            await ctx.send("That image is too small to be a loot image.")
            return

        try:
            async with aiohttp.ClientSession() as session:
                async with session.get(attachment.url) as resp:
                    loot_image = await resp.read()
        except aiohttp.ClientError:
            log.exception("loot: Couldn't parse image")
            await ctx.send("I failed to load your image. Please try again.")
            return

        await ctx.send(
            f"I've begun parsing your image, **@{ctx.author.display_name}**. "
            "Please be patient, this may take a few moments.")
        status_msg = await ctx.send("Status: Reading")
        try:
            # Owners are not affected by the limit.
            self.processing_users.append(ctx.author.id)
            start_time = time.time()
            loot_list, loot_image_overlay = await loot_scan(
                ctx, loot_image, status_msg)
            scan_time = time.time() - start_time
        except LootScanException as e:
            await ctx.send(e)
            return
        finally:
            self.processing_users.remove(ctx.author.id)
        embed = discord.Embed(color=discord.Color.blurple())
        embed.set_footer(text=f"Loot scanned in {scan_time:,.2f} seconds.")
        long_message = f"These are the results for your image: [{attachment.filename}]({attachment.url})"

        if len(loot_list) == 0:
            await ctx.send(
                f"Sorry {ctx.author.mention}, I couldn't find any loot in that image. Loot parsing will "
                f"only work on high quality images, so make sure your image wasn't compressed."
            )
            return

        total_value = 0

        unknown = False
        for item in loot_list:
            if loot_list[item]['group'] == "Unknown":
                unknown = loot_list[item]
                break

        groups = []
        for item in loot_list:
            if not loot_list[item]['group'] in groups and loot_list[item][
                    'group'] != "Unknown":
                groups.append(loot_list[item]['group'])
        has_marketable = False
        for group in groups:
            value = ""
            group_value = 0
            for item in loot_list:
                if loot_list[item]['group'] == group and loot_list[item][
                        'group'] != "Unknown":
                    if group == "No Value":
                        value += f"x{loot_list[item]['count']} {item}\n"
                    else:
                        with closing(tibiaDatabase.cursor()) as c:
                            c.execute(
                                "SELECT name FROM items, items_attributes "
                                "WHERE name LIKE ? AND id = item_id AND attribute = 'imbuement'"
                                " LIMIT 1", (item, ))
                            result = c.fetchone()
                        if result:
                            has_marketable = True
                            emoji = "💎"
                        else:
                            emoji = ""
                        value += "x{1} {0}{3} \u2192 {2:,}gp total\n".format(
                            item, loot_list[item]['count'],
                            loot_list[item]['count'] *
                            loot_list[item]['value_sell'], emoji)

                    total_value += loot_list[item]['count'] * loot_list[item][
                        'value_sell']
                    group_value += loot_list[item]['count'] * loot_list[item][
                        'value_sell']
            if group == "No Value":
                name = group
            else:
                name = f"{group} - {group_value:,} gold"
            # Split into multiple fields if they exceed field max length
            split_group = split_message(value, FIELD_VALUE_LIMIT)
            for subgroup in split_group:
                if subgroup != split_group[0]:
                    name = "\u200F"
                embed.add_field(name=name, value=subgroup, inline=False)

        if unknown:
            long_message += f"\n**There were {unknown['count']} unknown items.**\n"

        long_message += f"\nThe total loot value is: **{total_value:,}** gold coins."
        if has_marketable:
            long_message += f"\n💎 Items marked with this are used in imbuements and might be worth " \
                            f"more in the market."
        embed.description = long_message
        embed.set_image(url="attachment://results.png")

        # Short message
        short_message = f"I've finished parsing your image {ctx.author.mention}." \
                        f"\nThe total value is {total_value:,} gold coins."
        if not ctx.long:
            short_message += "\nI've also sent you a PM with detailed information."

        # Send on ask_channel or PM
        if ctx.long:
            await ctx.send(short_message,
                           embed=embed,
                           file=discord.File(loot_image_overlay,
                                             "results.png"))
        else:
            try:
                await ctx.author.send(file=discord.File(
                    loot_image_overlay, "results.png"),
                                      embed=embed)
            except discord.Forbidden:
                await ctx.send(
                    f"{ctx.tick(False)} {ctx.author.mention}, I tried pming you to send you the results, "
                    f"but you don't allow private messages from this server.\n"
                    f"Enable the option and try again, or try the command channel"
                )
            else:
                await ctx.send(short_message)
Пример #7
0
async def on_message(message):
    ctx = await bot.get_context(message)
    serverdata = r.table("blacklist").get(str(
        message.guild.id)).run(connection)
    if not ctx.command:
        return
    elif checks.is_owner_check(ctx):
        return await bot.process_commands(message)
    elif isinstance(message.channel, discord.abc.PrivateChannel):
        return await message.channel.send(
            "You can't use commands in private messages :no_entry:")
    elif message.author.bot:
        return
    elif str(message.author.id) in r.table("blacklist").get(
            "owner")["users"].run(connection):
        return await ctx.send(
            "You are blacklisted from using the bot, to appeal make sure to join the bots support server which can be found in `{}support`"
            .format(ctx.prefix))
    elif serverdata:
        if not checks.has_permissions(
                "administrator").__closure__[0].cell_contents(ctx):
            commands = list(map(lambda x: x["id"], serverdata["commands"]))
            if ctx.command.module[5:] in commands:
                whitelisted = list(
                    filter(lambda x: x["id"] == ctx.command.module[5:],
                           serverdata["commands"]))[0]["whitelisted"]
                if whitelisted != []:
                    if str(message.channel.id) in map(
                            lambda x: x["id"],
                            filter(lambda x: x["type"] == "channel",
                                   whitelisted)):
                        return await bot.process_commands(message)
                    if str(message.author.id) in map(
                            lambda x: x["id"],
                            filter(lambda x: x["type"] == "user",
                                   whitelisted)):
                        return await bot.process_commands(message)
                    for x in message.author.roles:
                        if str(x.id) in map(
                                lambda x: x["id"],
                                filter(lambda x: x["type"] == "role",
                                       whitelisted)):
                            return await bot.process_commands(message)
            if str(ctx.command) in commands:
                whitelisted = list(
                    filter(lambda x: x["id"] == str(ctx.command),
                           serverdata["commands"]))[0]["whitelisted"]
                if whitelisted != []:
                    if str(message.channel.id) in map(
                            lambda x: x["id"],
                            filter(lambda x: x["type"] == "channel",
                                   whitelisted)):
                        return await bot.process_commands(message)
                    if str(message.author.id) in map(
                            lambda x: x["id"],
                            filter(lambda x: x["type"] == "user",
                                   whitelisted)):
                        return await bot.process_commands(message)
                    for x in message.author.roles:
                        if str(x.id) in map(
                                lambda x: x["id"],
                                filter(lambda x: x["type"] == "role",
                                       whitelisted)):
                            return await bot.process_commands(message)
            if ctx.command.module[5:] in commands:
                blacklisted = list(
                    filter(lambda x: x["id"] == ctx.command.module[5:],
                           serverdata["commands"]))[0]["blacklisted"]
                if blacklisted != []:
                    if str(message.channel.id) in map(
                            lambda x: x["id"],
                            filter(lambda x: x["type"] == "channel",
                                   blacklisted)):
                        return await ctx.send(
                            "You cannot use any commands in the module {} in this channel :no_entry:"
                            .format(ctx.command.module[5:]))
                    if str(message.author.id) in map(
                            lambda x: x["id"],
                            filter(lambda x: x["type"] == "user",
                                   blacklisted)):
                        return await ctx.send(
                            "You are blacklisted from using any commands in the module {} in this server :no_entry:"
                            .format(ctx.command.module[5:]))
                    for x in message.author.roles:
                        if str(x.id) in map(
                                lambda x: x["id"],
                                filter(lambda x: x["type"] == "role",
                                       blacklisted)):
                            return await ctx.send(
                                "You are in the role `{}` which means you are blacklisted from using any commands in the module {} in this server :no_entry:"
                                .format(x.name, ctx.command.module[5:]))
            if str(ctx.command) in commands:
                blacklisted = list(
                    filter(lambda x: x["id"] == str(ctx.command),
                           serverdata["commands"]))[0]["blacklisted"]
                if blacklisted != []:
                    if str(message.channel.id) in map(
                            lambda x: x["id"],
                            filter(lambda x: x["type"] == "channel",
                                   blacklisted)):
                        return await ctx.send(
                            "You cannot use that command in this channel :no_entry:"
                        )
                    if str(message.author.id) in map(
                            lambda x: x["id"],
                            filter(lambda x: x["type"] == "user",
                                   blacklisted)):
                        return await ctx.send(
                            "You are blacklisted from using that command in this server :no_entry:"
                        )
                    for x in message.author.roles:
                        if str(x.id) in map(
                                lambda x: x["id"],
                                filter(lambda x: x["type"] == "role",
                                       blacklisted)):
                            return await ctx.send(
                                "You are in the role `{}` which means you are blacklisted from using that command in this server :no_entry:"
                                .format(x.name))
            if str(ctx.command) in serverdata["disabled"]:
                return await ctx.send(
                    "That command is disabled across the server :no_entry:")
    await bot.process_commands(message)
Пример #8
0
async def on_command_error(ctx, error, *args, **kwargs):
    channel = ctx.channel
    author = ctx.author
    if isinstance(error, commands.CheckFailure):
        perms = ctx.command.checks[0]
        if ctx.command.checks[0].__name__ == "is_owner_check":
            try:
                ctx.command.reset_cooldown(ctx)
            except:
                pass
            return await channel.send(
                "You do not have permission to use this command, Required permissions: Bot Owner :no_entry:"
            )
        elif str(perms).split(" ")[1].split(".")[0] == "is_main_owner":
            try:
                ctx.command.reset_cooldown(ctx)
            except:
                pass
            return await channel.send(
                "You do not have permission to use this command, Required permissions: Bot Owner :no_entry:"
            )
        else:
            try:
                ctx.command.reset_cooldown(ctx)
            except:
                pass
            return await channel.send(
                "You do not have permission to use this command, Required permissions: {} :no_entry:"
                .format(", ".join(
                    inspect.getclosurevars(
                        ctx.command.checks[0]).nonlocals["perms"])))
    elif isinstance(error, commands.NoPrivateMessage):
        try:
            ctx.command.reset_cooldown(ctx)
        except:
            pass
        return await channel.send("This command cannot be used in DMs!")
    elif isinstance(error, commands.DisabledCommand):
        try:
            ctx.command.reset_cooldown(ctx)
        except:
            pass
        if not checks.is_owner_check(ctx):
            return await channel.send(
                "The command `{}` has been disabled :no_entry:".format(
                    ctx.command))
    elif isinstance(error, commands.CommandOnCooldown):
        m, s = divmod(error.retry_after, 60)
        h, m = divmod(m, 60)
        if h == 0:
            time = "%d minutes %d seconds" % (m, s)
        elif h == 0 and m == 0:
            time = "%d seconds" % (s)
        else:
            time = "%d hours %d minutes %d seconds" % (h, m, s)
        return await channel.send(
            "This command is on cooldown! Try again in {}".format(time))
    elif isinstance(error, commands.MissingRequiredArgument):
        try:
            perms = ctx.command.checks[0]
        except:
            perms = None
        msg = ""
        if not ctx.command.usage:
            for x in ctx.command.params:
                if x != "ctx":
                    if x != "self":
                        if "=" in str(ctx.command.params[x]):
                            msg += "[{}] ".format(x)
                        else:
                            msg += "<{}> ".format(x)
        else:
            msg += ctx.command.usage
        if not ctx.command.aliases:
            aliases = "None"
        else:
            aliases = ", ".join([x for x in ctx.command.aliases])
        if not perms:
            msg = "Usage: {}{} {}\nCommand aliases: {}\nRequired permissions: None\nCommand description: {}".format(
                ctx.prefix, ctx.command, msg, aliases, ctx.command.help)
        else:
            msg = "Usage: {}{} {}\nCommand aliases: {}\nRequired permissions: {}\nCommand description: {}".format(
                ctx.prefix, ctx.command, msg, aliases,
                ", ".join(inspect.getclosurevars(perms).nonlocals["perms"])
                if perms.__name__ != "is_owner_check"
                and str(perms).split(" ")[1].split(".")[0] != "is_main_owner"
                else "Bot Owner", ctx.command.help)
        try:
            msg += "\n\nSub commands: {}".format(", ".join([
                x for x in ctx.command.all_commands
                if x not in ctx.command.all_commands[x].aliases
            ]))
        except:
            pass
        s = discord.Embed(description=msg)
        s.set_author(name=ctx.command, icon_url=bot.user.avatar_url)
        await channel.send(embed=s)
        try:
            ctx.command.reset_cooldown(ctx)
        except:
            pass
        return
    elif isinstance(error, commands.CommandNotFound):
        pass
    elif isinstance(error, commands.BadArgument):
        try:
            perms = ctx.command.checks[0]
        except:
            perms = None
        msg = ""
        for x in ctx.command.params:
            if x != "ctx":
                if x != "self":
                    if "=" in str(ctx.command.params[x]):
                        msg += "[{}] ".format(x)
                    else:
                        msg += "<{}> ".format(x)
        if not ctx.command.aliases:
            aliases = "None"
        else:
            aliases = ", ".join([x for x in ctx.command.aliases])
        if not perms:
            msg = "Usage: {}{} {}\nCommand aliases: {}\nRequired permissions: None\nCommand description: {}".format(
                ctx.prefix, ctx.command, msg, aliases, ctx.command.help)
        else:
            msg = "Usage: {}{} {}\nCommand aliases: {}\nRequired permissions: {}\nCommand description: {}".format(
                ctx.prefix, ctx.command, msg, aliases,
                ", ".join(inspect.getclosurevars(perms).nonlocals["perms"])
                if perms.__name__ != "is_owner_check"
                and str(perms).split(" ")[1].split(".")[0] != "is_main_owner"
                else "Bot Owner", ctx.command.help)
        try:
            msg += "\n\nSub commands: {}".format(", ".join([
                x for x in ctx.command.all_commands
                if x not in ctx.command.all_commands[x].aliases
            ]))
        except:
            pass
        s = discord.Embed(description=msg)
        s.set_author(name=ctx.command, icon_url=bot.user.avatar_url)
        await channel.send(embed=s)
        try:
            ctx.command.reset_cooldown(ctx)
        except:
            pass
        return
    else:
        s = discord.Embed(
            title="Error",
            description=
            "You have came across an error! [Support Server](https://discord.gg/PqJNcfB)\n{}"
            .format(str(error)).replace("Command raised an exception: ", ""))
        await channel.send(embed=s)
        print("".join(
            traceback.format_exception(type(error), error,
                                       error.__traceback__)))
        await bot.get_channel(439745234285625355).send(
            "```py\nServer: {}\nTime: {}\nCommand: {}\nAuthor: {}\n\n{}```".
            format(
                ctx.message.guild,
                datetime.datetime.utcnow().strftime("%d/%m/%Y %H:%M:%S"),
                ctx.command, ctx.message.author, "".join(
                    traceback.format_exception(type(error), error,
                                               error.__traceback__, 1000))))
Пример #9
0
 def __global_check(self, ctx):
     return is_private(ctx.channel) or \
            ctx.channel.id not in self.ignored.get(ctx.guild.id, []) or checks.is_owner_check(ctx) \
            or checks.check_guild_permissions(ctx, {'manage_channels': True})