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
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)))
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]))
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)
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
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!')
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
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
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
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