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 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, 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