示例#1
0
    def handle_message(self, msg):
        """
        Attempts to handle a newly created or edited message in the context of
        command parsing/triggering. Calls all relevant commands the message triggers.

        Parameters
        ---------
        msg : :class:`disco.types.message.Message`
            The newly created or updated message object to parse/handle.

        Returns
        -------
        bool
            whether any commands where successfully triggered by the message
        """
        commands = list(
            self.get_commands_for_message(
                self.config.commands_require_mention,
                self.config.commands_mention_rules,
                self.config.commands_prefix,
                msg,
            ))

        if not len(commands):
            return False

        for command, match in commands:
            if not self.check_command_permissions(command, msg):
                continue

            if command.plugin.execute(CommandEvent(command, msg, match)):
                return True
        return False
示例#2
0
    def run_command(self, event, prefix, group=False):
        msgContent = event.message.content[len(prefix):].lstrip()
        firstWord = msgContent.partition(" ")[0]
        restOfPartition = msgContent.partition(" ")[2]
        secondWord = restOfPartition.partition(" ")[0]

        firstWord = firstWord.lower()
        secondWord = secondWord.lower()

        for command in self.get_all_commands():
            for trigger in self.get_command_triggers(command):
                if (not group) and (firstWord == trigger.lower()):
                    command.execute(
                        CommandEvent(
                            command, event.message,
                            re.search(command.compiled_regex, msgContent)))
                elif (group) and (secondWord == trigger.lower()):
                    command.execute(
                        CommandEvent(
                            command, event.message,
                            re.search(command.compiled_regex, msgContent)))
示例#3
0
  def message_parser(self, event):
    with open(DATA_DIR.format(event.message.guild.id), 'r') as file:
      data = json.load(file)
    if event.message.author.bot:
      return

    if event.message.content.startswith(data['prefix']):
      commands = self.bot.get_commands_for_message(
          False,
          {},
          data['prefix'],
          event.message
      )

      if len(commands):
          print("[LOG] [CMD] [{}] {}#{} ({}) ran command {}".format(event.message.timestamp, event.message.author.username, event.message.author.discriminator, event.message.author.id, commands[0][0].name))
          commands[0][0].plugin.execute(CommandEvent(commands[0][0], event.message, commands[0][1]))
示例#4
0
    def on_message_create(self, event):
        if event.author.id == self.bot.client.state.me.id:
            return

        guild_state = self.bot.guild_state.get(event.guild.id)
        if not guild_state:
            return

        content = event.content

        # TODO: pull from config
        prefix = '!'
        if prefix and not content.startswith(prefix):
            return []
        else:
            content = content[len(prefix):]

        if not self.command_matches_re.match(content):
            return []

        options = []
        for command in self.commands:
            match = command.compiled_regex(self.group_abbrev).match(content)
            if match:
                options.append((command, match))
        options = sorted(options, key=lambda obj: obj[0].group is None)
        if not options:
            return

        user = None
        for command, match in options:
            # If this is an admin command, check if the user is an admin
            if command.level == -1:
                if not user:
                    user = User.with_id(event.author.id)

                if not user or not user.admin:
                    log.warning(
                        'User attempted to execute admin-only command %s (%s)',
                        command.name, event.author.id)
                    continue

            # TODO: permissions
            (command_event, kwargs) = command.execute(
                CommandEvent(command, event.message, match))
            gevent.spawn(command.func, guild_state, command_event, **kwargs)
示例#5
0
    def handle_message(self, msg, custom_prefix=None) -> bool:
        commands = list(self.get_commands_for_message(
            self.config.commands_require_mention,
            self.config.commands_mention_rules,
            self.config.commands_prefix if not custom_prefix else custom_prefix,
            msg,
        ))

        if not len(commands):
            return False

        for command, match in commands:
            if not self.check_command_permissions(command, msg):
                continue

            if command.plugin.execute(CommandEvent(command, msg, match)):
                return True
        return False
示例#6
0
    def on_message_create(self, event):
        if event.message.author.bot:
            return

        commands = list(self.bot.get_commands_for_message(
            self.bot.config.commands_require_mention,
            self.bot.config.commands_mention_rules,
            self.bot.config.commands_prefix,
            event.message
        ))

        if not len(commands):
            return

        global_admin = check_global_admin(event.author.id)

        user_level = get_user_level(event.guild.members[event.author.id])

        for command, match in commands:
            if command.level == -1 and not global_admin:
                continue

            if not global_admin and command.level > user_level:
                continue

            try:
                command_event = CommandEvent(command, event.message, match)
                command.plugin.execute(command_event)
            except:
                self.log.exception('Command error:')

                with self.send_control_message() as embed:
                    embed.title = u'Command Error: {}'.format(command.name)
                    embed.color = 0xf3733a
                    embed.add_field(
                        name='Author', value='({}) `{}`'.format(event.author, event.author.id), inline=True)
                    embed.add_field(name='Channel', value='({}) `{}` in {}'.format(
                        event.channel.name if event.guild else event.channel.recipients.itervalues().next(),
                        event.channel.id,
                        event.guild.name if event.guild else 'a DM'
                    ), inline=True)
                    embed.description = '```{}```'.format(u'\n'.join(traceback.format_exc().split('\n')[-8:]))

                return event.reply('Something went wrong, perhaps try again another time!')
示例#7
0
文件: core.py 项目: Eros/speedboat
    def on_message_create(self, event):
        """
        This monstrosity of a function handles the parsing and dispatching of
        commands.
        """
        # Ignore messages sent by bots
        if event.message.author.bot:
            return

        # If this is message for a guild, grab the guild object
        if hasattr(event, 'guild') and event.guild:
            guild_id = event.guild.id
        elif hasattr(event, 'guild_id') and event.guild_id:
            guild_id = event.guild_id
        else:
            guild_id = None

        guild = self.guilds.get(event.guild.id) if guild_id else None
        config = guild and guild.get_config()

        # If the guild has configuration, use that (otherwise use defaults)
        if config and config.commands:
            commands = list(
                self.bot.get_commands_for_message(config.commands.mention, {},
                                                  config.commands.prefix,
                                                  event.message))
        elif guild_id:
            # Otherwise, default to requiring mentions
            commands = list(
                self.bot.get_commands_for_message(True, {}, '', event.message))
        else:
            if ENV != 'prod':
                if not event.message.content.startswith(ENV + '!'):
                    return
                event.message.content = event.message.content[len(ENV) + 1:]

            # DM's just use the commands (no prefix/mention)
            commands = list(
                self.bot.get_commands_for_message(False, {}, '',
                                                  event.message))

        # If we didn't find any matching commands, return
        if not len(commands):
            return

        event.user_level = self.get_level(event.guild,
                                          event.author) if event.guild else 0

        # Grab whether this user is a global admin
        # TODO: cache this
        global_admin = rdb.sismember('global_admins', event.author.id)

        # Iterate over commands and find a match
        for command, match in commands:
            if command.level == -1 and not global_admin:
                continue

            level = command.level

            if guild and not config and command.triggers[0] != 'setup':
                continue
            elif config and config.commands and command.plugin != self:
                overrides = {}
                for obj in config.commands.get_command_override(command):
                    overrides.update(obj)

                if overrides.get('disabled'):
                    continue

                level = overrides.get('level', level)

            if not global_admin and event.user_level < level:
                continue

            with timed('rowboat.command.duration',
                       tags={
                           'plugin': command.plugin.name,
                           'command': command.name
                       }):
                try:
                    command_event = CommandEvent(command, event.message, match)
                    command_event.user_level = event.user_level
                    command.plugin.execute(command_event)
                except CommandResponse as e:
                    event.reply(e.response)
                except:
                    tracked = Command.track(event, command, exception=True)
                    self.log.exception('Command error:')

                    with self.send_control_message() as embed:
                        embed.title = u'Command Error: {}'.format(command.name)
                        embed.color = 0xff6961
                        embed.add_field(name='Author',
                                        value='({}) `{}`'.format(
                                            event.author, event.author.id),
                                        inline=True)
                        embed.add_field(name='Channel',
                                        value='({}) `{}`'.format(
                                            event.channel.name,
                                            event.channel.id),
                                        inline=True)
                        embed.description = '```{}```'.format(u'\n'.join(
                            tracked.traceback.split('\n')[-8:]))

                    return event.reply(
                        '<:{}> something went wrong, perhaps try again later'.
                        format(RED_TICK_EMOJI))

            Command.track(event, command)

            # Dispatch the command used modlog event
            if config:
                modlog_config = getattr(config.plugins, 'modlog', None)
                if not modlog_config:
                    return

                self._attach_local_event_data(event, 'modlog', event.guild.id)

                plugin = self.bot.plugins.get('ModLogPlugin')
                if plugin:
                    plugin.log_action(Actions.COMMAND_USED, event)

            return
示例#8
0
    def on_message_create(self, event):

        if event.message.channel.type == ChannelType.DM:
            return

        if event.message.author.bot:
            return

        user_obj, created = Users.get_or_create(id=event.message.author.id)

        perms = event.message.channel.get_permissions(self.state.me)

        if not perms.can(Permissions.SEND_MESSAGES):
            return

        event.bot_admin = event.message.author.id in TEMP_BOT_ADMINS
        event.user_level = 0

        has_admin = False

        new_setup = False
        guild = None

        if event.message.guild:
            try:
                guild = Guild.using_id(event.guild.id)
            except Guild.DoesNotExist:
                guild = self.fresh_start(event, event.guild.id)
                new_setup = True
            if len(event.message.member.roles) > 0:
                for x in event.message.member.roles:
                    role = event.message.guild.roles.get(x)
                    if role.permissions.can(Permissions.ADMINISTRATOR):
                        event.user_level = 100
                        has_admin = True
            if guild.referee_role:
                if not has_admin and guild.referee_role in event.message.member.roles:
                    event.user_level = 50

        if event.message.author.bot:
            return

        if not event.message.content.startswith(
                guild.prefix
        ) and event.message.mentions and self.state.me.id in event.message.mentions:
            content = event.message.without_mentions
            content = content.replace(' ', '', -1)
            if 'prefix' in content.lower():
                return event.channel.send_message('Prefix: `{}`'.format(
                    guild.prefix))
            else:
                pass

        # Grab the list of commands
        commands = list(
            self.bot.get_commands_for_message(False, {}, guild.prefix,
                                              event.message))

        # Used for cmd cooldowns
        user_ignores_cooldowns = self.cooldown_check(event.message.author.id)

        # Sorry, nothing to see here :C
        if not len(commands):
            return

        for command, match in commands:

            if command.name == 'settings' and len(commands) > 1:
                continue

            needed_level = 0
            if command.level:
                needed_level = command.level

            cooldown = 0

            if hasattr(command.plugin, 'game'):
                if not guild.check_if_listed(game_checker(command.plugin.game),
                                             'enabled'):
                    return

            if command.level == -1 and not event.bot_admin:
                return

            if not event.bot_admin and event.user_level < needed_level:
                continue

            try:
                command_event = CommandEvent(command, event.message, match)
                command_event.bot_admin = event.bot_admin
                command_event.user_level = event.user_level
                command_event.db_user = user_obj
                command_event.db_guild = guild
                if command.args:
                    if len(command_event.args) < command.args.required_length:
                        self.dis_cmd_help(command, command_event, event, guild)
                        return
                command.plugin.execute(command_event)
            except:
                self.log.exception('Command error:')
                return event.reply('It seems that an error has occured! :(')
        if new_setup:
            event.message.reply(
                'Hey! I\'ve noticed that I\'m new to the server and have no config, please check out `{}settings` to edit and setup the bot.'
                .format(guild.prefix))
        return
示例#9
0
    def on_message_create(self, event):
        """
        This monstrosity of a function handles the parsing and dispatching of
        commands.
        """
        # Ignore messages sent by bots
        if event.message.author.bot:
            return

        if rdb.sismember('ignored_channels', event.message.channel_id):
            return

        # If this is message for a guild, grab the guild object
        if hasattr(event, 'guild') and event.guild:
            guild_id = event.guild.id
        elif hasattr(event, 'guild_id') and event.guild_id:
            guild_id = event.guild_id
        else:
            guild_id = None

        guild = self.guilds.get(event.guild.id) if guild_id else None
        config = guild and guild.get_config()

        # If the guild has configuration, use that (otherwise use defaults)
        if config and config.commands:
            commands = list(
                self.bot.get_commands_for_message(config.commands.mention, {},
                                                  config.commands.prefix,
                                                  event.message))
        elif guild_id:
            # Otherwise, default to requiring mentions
            commands = list(
                self.bot.get_commands_for_message(True, {}, '', event.message))
        else:
            if ENV != 'prod':
                if not event.message.content.startswith(ENV + '!'):
                    return
                event.message.content = event.message.content[len(ENV) + 1:]

            # DM's just use the commands (no prefix/mention)
            commands = list(
                self.bot.get_commands_for_message(False, {}, '',
                                                  event.message))

        # If we didn't find any matching commands, return
        if not len(commands):
            return

        event.user_level = self.get_level(event.guild,
                                          event.author) if event.guild else 0

        # Grab whether this user is a global admin
        # TODO: cache this
        global_admin = rdb.sismember('global_admins', event.author.id)

        # Iterate over commands and find a match
        for command, match in commands:
            if command.level == -1 and not global_admin:
                continue

            level = command.level

            if guild and not config and command.triggers[0] != 'setup':
                continue
            elif config and config.commands and command.plugin != self:
                overrides = {}
                for obj in config.commands.get_command_override(command):
                    overrides.update(obj)

                if overrides.get('disabled'):
                    continue

                level = overrides.get('level', level)

            if not global_admin and event.user_level < level:
                continue

            with timed('rowboat.command.duration',
                       tags={
                           'plugin': command.plugin.name,
                           'command': command.name
                       }):
                try:
                    command.plugin.execute(
                        CommandEvent(command, event.message, match))
                except CommandResponse as e:
                    return event.reply(e.response)
                except:
                    event.reply(
                        '<:{}> something went wrong, perhaps try again later'.
                        format(RED_TICK_EMOJI))
                    self.log.exception('Command error:')

            Message.update(command=command.plugin.name + ':' +
                           command.name).where(
                               (Message.id == event.message.id)).execute()

            # Dispatch the command used modlog event
            if config:
                event.config.set(getattr(config.plugins, 'modlog', None))
                if not event.config:
                    return

                plugin = self.bot.plugins.get('ModLogPlugin')
                if plugin:
                    plugin.log_action(Actions.COMMAND_USED, event)

            return
示例#10
0
    def on_message_create(self, event, is_tag=False):
        """
        This monstrosity of a function handles the parsing and dispatching of
        commands.
        """
        # Ignore messages sent by bots
        if event.message.author.bot or rdb.sismember('ignored_channels',
                                                     event.message.channel_id):
            return

        # If this is message for a guild, grab the guild object
        if hasattr(event, 'guild') and event.guild:
            guild_id = event.guild.id
        elif hasattr(event, 'guild_id') and event.guild_id:
            guild_id = event.guild_id
        else:
            guild_id = None

        guild = self.guilds.get(event.guild.id) if guild_id else None
        config = guild and guild.get_config()
        cc = config.commands if config else None

        # If the guild has configuration, use that (otherwise use defaults)
        if config and config.commands:
            commands = list(
                self.bot.get_commands_for_message(config.commands.mention, {},
                                                  config.commands.prefix,
                                                  event.message))
        elif guild_id:
            # Otherwise, default to requiring mentions
            commands = list(
                self.bot.get_commands_for_message(True, {}, '', event.message))
        else:
            # if ENV != 'prod':
            if ENV not in 'prod':
                if not event.message.content.startswith(ENV + '!'):
                    return
                event.message.content = event.message.content[len(ENV) + 1:]

            # DM's just use the commands (no prefix/mention)
            commands = list(
                self.bot.get_commands_for_message(False, {}, '',
                                                  event.message))

        # if no command, attempt to run as a tag
        if not commands:
            if is_tag:
                return

            if not event.guild or not self.bot.plugins.get('TagsPlugin'):
                return

            if not config or not config.plugins or not config.plugins.tags:
                return

            prefixes = []
            if cc.prefix:
                prefixes.append(cc.prefix)
            if cc.mention:
                prefixes.append('{} '.format(self.bot.client.state.me.mention))
            if not prefixes:
                return

            tag_re = re.compile('^({})(.+)'.format(
                re.escape('|'.join(prefixes))))
            m = tag_re.match(event.message.content)
            if not m:
                return

            sqlplugin = self.bot.plugins.get('SQLPlugin')
            if sqlplugin:
                sqlplugin.tag_messages.append(event.message.id)
            event.message.content = '{}tags show {}'.format(
                m.group(1), m.group(2))
            return self.on_message_create(event, True)

        event.user_level = self.get_level(event.guild,
                                          event.author) if event.guild else 0

        # Grab whether this user is a global admin
        # TODO: cache this
        ## this is technically already cached and runs fastest this way
        global_admin = rdb.sismember('global_admins', event.author.id)

        # Iterate over commands and find a match
        for command, match in commands:
            if command.level == -1 and not global_admin:
                continue

            level = command.level

            if guild and not config and command.triggers[0] != 'setup':
                continue
            elif config and config.commands and command.plugin != self:
                overrides = {}
                for obj in config.commands.get_command_override(command):
                    overrides.update(obj)

                if overrides.get('disabled'):
                    continue

                level = overrides.get('level', level)

            if not global_admin and event.user_level < level:
                continue

            try:
                command_event = CommandEvent(command, event.message, match)
                command_event.user_level = event.user_level
                command.plugin.execute(command_event)
            except CommandResponse as e:
                if is_tag:
                    return
                event.reply(e.response)
            except:
                tracked = Command.track(event, command, exception=True)
                self.log.exception('Command error:')

                with self.send_control_message() as embed:
                    embed.title = 'Command Error: {}'.format(command.name)
                    embed.color = 0xff6961
                    embed.add_field(name='Author',
                                    value='({}) `{}`'.format(
                                        event.author, event.author.id),
                                    inline=True)
                    embed.add_field(name='Channel',
                                    value='({}) `{}`'.format(
                                        event.channel.name, event.channel.id),
                                    inline=True)
                    embed.description = '```{}```'.format('\n'.join(
                        tracked.traceback.split('\n')[-8:]))

                return event.reply(
                    '<:{}> something went wrong, perhaps try again later'.
                    format(RED_TICK_EMOJI))

            Command.track(event, command)

            # Dispatch the command used modlog event
            if config:
                modlog_config = getattr(config.plugins, 'modlog', None)
                if not modlog_config:
                    return

                if is_tag:  # Yes, I know, this is ugly but I don't have better
                    event.content = event.content.replace('tags show ', '', 1)

                self._attach_local_event_data(event, 'modlog', event.guild.id)

                plugin = self.bot.plugins.get('ModLogPlugin')
                if plugin:
                    plugin.log_action(Actions.COMMAND_USED, event)

            return