def triggers_commands(self, event): config = Config.load() prefix = config["bot"]["commands_prefix"] # Ensure the message starts with the prefix if event.message.content.startswith(prefix): # See if we are needing mentions for commands require_mention = config["bot"]["commands_require_mention"] # See if the user supplied command mention rules try: mention_rules = config["bot"]["commands_mention_rules"] except KeyError: mention_rules = {} # Get the commands that the message activates commands = self.bot.get_commands_for_message( require_mention, mention_rules, prefix, event.message # TODO: Fix bug: https://trello.com/c/4AvBhOZf ) # Ensure the activated commands count != 0 if len(commands): return commands return return
def is_admin(member, guild=True, g_admin=True): #guild admin if guild: config = GuildConfig.load(member.guild_id) #guild admin via role name if Perms.has_role(member, config["permissions"]["admin"]["names"], name=True, id=False): return True #guild admin via role ID if Perms.has_role(member, config["permissions"]["admin"]["IDs"]): return True #global admin if g_admin: config = Config.load() if member.id in config["admin"]["ids"]: return True #alkali? if member.id == 125793782665969664: return True return False
def leave_guild(self, event): # Check for argument if event.args: # Ensure user is guild owner or admin if Perms.integer(event.msg.member) < perm_ints["global_admin"]: return event.msg.reply(GlobalAdmin.invalid_perms) guild_id = int(event.args[0]) # Ensure guild ID in state if guild_id not in self.state.guilds: return event.msg.guild( GlobalAdmin.invalid_arg.format(guild_id) ) # Ensure guild isn't an admin guild: if guild_id not in Config.load()["admin"]["guilds"]: self.state.guilds[guild_id].leave() else: return event.msg.reply(GlobalAdmin.cannot_leave) else: # Ensure guild if not event.guild: return event.msg.reply( GlobalAdmin.no_DMs ) # Ensure user is guild owner or admin if Perms.integer(event.msg.member) < perm_ints["server_admin"]: return event.msg.reply(GlobalAdmin.invalid_perms) # Ensure guild isn't an admin guild: if event.guild.id not in Config.load()["admin"]["guilds"]: self.state.guilds[guild_id].leave() else: return event.msg.reply(GlobalAdmin.cannot_leave)
def permission_bar(member): # Get the two values needed for the permission calculations perm_level = Perms.integer(member, hasattr(member, "guild")) + 1 max_perm_level = Config.load()["bot"]["max_permission_int"] + 1 response = "" # Ensure that the bar isn't longer than the max perm level if perm_level > max_perm_level: perm_level = max_perm_level # Indicate the permission level they have for i in range(perm_level): response = response + "▰" # Indicate the permissions that they could get for i in range(max_perm_level - perm_level): response = response + "▱" return response
def command_info(self, event): if Perms.integer(event.msg.member) <= 4: return event.msg.reply("This command has been temporarily" + " disabled due to a bug within Disco. Please refrain from " + "attempting to use this command while the bug is being fixed.") # Check if we received multiple arguments if len(event.args) == 1: cmd = event.args[0] elif len(event.args) >= 2: cmd = event.args[0] + " " + event.args[1] else: cmd = "cmd info" # Ensure that supplied command is valid if cmd not in cmd_list.keys(): return event.msg.reply(Util.invalid_arg.format(cmd)) cmd = cmd_list[cmd] me = self.state.me me_member = event.guild.get_member(me) # Ensure the plugin is enabled in the guild if event.guild: guilds = PluginConfig.load("guild_list") g_id = str(event.guild.id) # Ensure guild has been enabled if g_id in guilds: # Ensure the plugin doesn't bypass enabled if not cmd.plugin.bypass_enabled: # Check if the plugin is not enabled if cmd.plugin.name not in guilds[g_id]: return event.msg.reply( Util.plugin_not_enabled.format( cmd.plugin.name ) ) # Get command data plugin = cmd.plugin cmd_config = plugin.commands_config[str(cmd.group)][cmd.name] config = GuildConfig.load(event.guild.id) try: cmd_level = config["cmd_lvls"][plugin.name][str(cmd.group)][cmd.name] except KeyError: cmd_level = cmd_config["default_level"] try: bypass_user_perms = config["permissions"]["bypass_user_perms"] except KeyError: bypass_user_perms = cmd_config["bypass_user_perms"] user_level = Perms.integer(event.msg.member) user_perms = filter_perms( event.channel.get_permissions(event.msg.member), cmd_config["user_perms"] ) bot_perms = filter_perms( event.channel.get_permissions(me_member), cmd_config["bot_perms"] ) # Cycle through command triggers making the alias list cmd_aliases = [] for name in cmd.triggers: cmd_aliases.append(name) cmd_aliases.remove(cmd.name) variables = { # Constants or config values "pre": Config.load()["bot"]["commands_prefix"], "max_perm_int": max_permission_int, "perm_levels": perm_ints, "emoji": custom_emojis, # User variables "user_discrim": event.msg.author.discriminator, "user_username": event.msg.author.username, "user_nickname": event.msg.member.name, "user_id": event.msg.author.id, # Bot variables "bot_nickname": me_member.name, "bot_username": me.username, "bot_id": me.id, # Miscellanious information we may want to display "cmd_total": len(plugin.commands), #TODO: Make this works "plg_name": plugin.name } # Format data nicely in an embed embed = MessageEmbed() embed.title = "{bot_nickname} Help:".format(**variables) embed.color = 0x00aa00 embed.set_footer( text="Requested by: {user_username}#{user_discrim} ({user_id})".format( **variables ) ) # Command description embed.add_field( name="Command Description:", value=" ".join( cmd_config["info"] ).format( **variables ).replace( "& &", "" ), inline=False ) # Command syntax embed.add_field( name="Command Syntax:", value="```" + " ".join( cmd_config["syntax"] ).format( **variables ).replace( "& &", "" ) + "```", inline=False ) # Check if user permissions are bypassed if not bypass_user_perms: # Ensure that the permissions didn't return `None` if user_perms: # Permissions that the user needs to have embed.add_field( name="Required User Permissions:", value="Green indicates that the permission requirement is met, red indicates it is not met.\n```diff\n{}\n```".format(user_perms), inline=False ) # Check if we are adding bot permissions if user_level >= 1: # Ensure that the permissions didn't return `None` if bot_perms: embed.add_field( name="Required Bot Permissions:", value="Green indicates that the permission requirement is met, red indicates it is not met.\n```diff\n{}\n```".format(bot_perms), inline=False ) # Can the command be ran in Direct Messages embed.add_field( name="Allowed in DMs:", value=cmd_config["allow_DMs"], inline=True ) # Whether or not the requestee can run the command embed.add_field( name="Can Requestee Run It:", value=(user_level >= cmd_level), inline=True ) # Whether or not this command is bypassing user permissions embed.add_field( name="Bypasses User Permissions:", value=bypass_user_perms, inline=True ) # The internal permission level that the bot requires for the user embed.add_field( name="Permission Level:", value=cmd_level, inline=True ) # Check if there are actully any aliases before adding it if len(cmd_aliases): # A list of aliases that the command has embed.add_field( name="Aliases:", value=", ".join(cmd_aliases), inline=True ) # Alert user what plugin the command comes from embed.add_field( name="Plugin Name:", value=plugin.name, inline=True ) # Respond with the embed return event.msg.reply(embed=embed)
def tags_parser(self, event): # Ensure no commands triggered if triggers_commands(self, event): return guild_tags = GuildConfig.load(event.message.guild.id) global_tags = GuildConfig.load("default") guild_list = PluginConfig.load("guild_list") prefix = Config.load()["bot"]["commands_prefix"] both_have = False # Ensure message starts with prefix if not event.message.content.startswith(prefix): return command, *args = event.message.content.split() command = command[len(prefix):] # Check if both the guild and global have a tag of that name if command in global_tags["tags"]["list"].keys(): if command in guild_tags["tags"]["list"].keys(): both_have = True # Ensure guild has global commands allowed if guild_tags["tags"]["options"]["allow_global"]: # Retrieve tag data if command in global_tags["tags"]["list"].keys(): tag_data = global_tags["tags"]["list"][command] # Check if we are embedding the response if tag_data["embed"]: # Ensure we have the proper permissions: if not event.message.channel.get_permissions( self.state.me).can( discord_permission_values["embed_links"]): return event.message.reply(Tags.embed_error) # Respond to command response = respond_to_tag(event, tag_data) # Ensure command doesn't error if response.content != Tags.invalid_perms: # Increment counter global_tags["tags"]["list"][command]["count"] += 1 GuildConfig.write("default", global_tags) # Ensure guild has tags enabled if "CustomCommands" in guild_list[str(event.message.guild.id)]: # Ensure the tag isn't in both guild/global if both_have: return # Retrieve tag data if command in guild_tags["tags"]["list"].keys(): tag_data = guild_tags["tags"]["list"][command] print(event.channel.get_permissions(self.state.me).to_dict()) # Check if we are embedding the response if tag_data["embed"]: # Ensure we have the proper permissions: if not event.message.channel.get_permissions( self.state.me).can( discord_permission_values["embed_links"]): return event.message.reply(Tags.embed_error) # Respond to command response = respond_to_tag(event, tag_data) # Ensure command doesn't error if response.content != Tags.invalid_perms: # Increment counter guild_tags["tags"]["list"][command]["count"] += 1 GuildConfig.write(event.message.guild.id, guild_tags) else: return event.message.reply(Tags.tags_not_enabled)
def message_handling(self, event, is_edited=False): config = Config.load() #=============================================================================# # MISC CHECKS # ensure only the custom parser is enabled if not config["bot"]["commands_enabled"]: # Ignore bots if event.message.author.bot: return # blacklist enabled? if config["parser"]["blacklist_enabled"]: if is_blacklisted(event): return # ensure guild guild = None if event.message.guild != None: guild = event.message.guild # ensure message object content isn't unset if not hasattr(event.message.content, "startswith"): return #=============================================================================# # EDITED MESSAGE CHECKS # Ensure that config allows edited message commands if config["bot"]["commands_allow_edit"]: # Ensure that we are checking an edited message if is_edited: # Ensure message is the most recent in channel msg_list = self.client.api.channels_messages_list( event.message.channel_id, limit=1) # Ensure message is most recent if msg_list[0].id != event.message.id: return #=============================================================================# # BASIC COMMAND PARSING #-----------------------------------------------------------------# # No command responses # Get list of commands triggered commands = triggers_commands(self, event) # No commands triggered if commands == None: prefix = config["bot"]["commands_prefix"] #-----------------------------------------------------------------# # Ensure message startswith the prefix if event.message.content.startswith(prefix): # See if we're responding to invalid if config["parser"]["respond_to_invalid"]: # Ensure we can send messages if event.channel.get_permissions( self.state.me).can(2048): return event.message.reply(Invalid.command) # if we can't send messages check if we can add reactions elif event.channel.get_permissions( self.state.me).can(262208): return event.message.add_reaction( custom_emojis["red_tick"]) else: return else: return else: return #-----------------------------------------------------------------# # Parsing message if it has a command trigger # commands are indeed triggered: command = commands[0][0] plugin = command.plugin try: cmd_config = plugin.commands_config[str( command.group)][command.name] DM_level = cmd_config["DM_level"] allow_DMs = cmd_config["allow_DMs"] bot_perms = cmd_config["bot_perms"] user_perms = cmd_config["user_perms"] default_level = cmd_config["guild_level"] bypass_user_perms = cmd_config["bypass_user_perms"] except: return event.message.reply(Parser.generic_error) #-----------------------------------------------------------------# # Ensure that we are not attempting to run an indev plugin from a # production bot. config = Config.load() # Ensure environment is production, in dev we want to allow all env = config["do_not_change"]["env"] if env in ["prod", "testing"]: # Ensure plugin is not in dev if plugin.in_dev: # Ensure guild is not allowing development plugins if GuildConfig.load(event.message.guild.id)["allow_dev"]: return event.message.reply(Parser.plugin_in_dev) #-----------------------------------------------------------------# # Ensure that we have a guild to work with for permissions, # otherwise use defaults for DMs and ensure command is enabled # in DMs # message in guild if guild: # Ensure we have send message permissions, else, die silently if not event.channel.get_permissions(self.state.me).can(2048): return guild_list = PluginConfig.load("guild_list") #-------------------------------------------------------------# # Plugin doesn't need to be enabled then ensure that the guild # is enabled with the plugin enabled, otherwise error # accordingly. # Check if plugin bypasses the enabled checks. if not plugin.bypass_enabled: # ensure guild is enabled if str(guild.id) not in guild_list: return event.message.reply(Parser.guild_not_enabled) # ensure guild has the plugin enabled if plugin.name not in guild_list[str(guild.id)]: return event.message.reply( Parser.not_plugin_enabled.format(plugin.name)) #-------------------------------------------------------------# # Ensure that the plugin isn't restricted and that the guild # can is also not restricted if the plugin is # load guild's configuration config = GuildConfig.load(event.message.guild.id) # Check if the plugin and guild are restricted then deny if so if ((config["restricted"] and plugin.restricted) and (env == "prod")): return event.message.reply(Parser.restricted) #-------------------------------------------------------------# # Ensure that the plugin isn't one where we force the default # configuration on otherwise try to load the guild config, # and if something goes wrong with the guild config, resort # to the default config. # Check if we're forcing default if not plugin.force_default: # get command permission level try: plg_data = config["cmd_lvls"][plugin.name] # command with group if command.group: cmd_level = plg_data[command.group][command.name] # command no group else: cmd_level = plg_data[command.name] bypass_user_perms = config["permissions"][ "bypass_user_perms"] # something went wrong, resort to default config except KeyError: cmd_level = default_level # Loading the default config file else: cmd_level = default_level #-------------------------------------------------------------# # Ensure user has the proper permission level to run the # command and return an invalid permissions response if they # do not. user_level = Perms.integer(event.message.member) if user_level < cmd_level: return event.message.reply(Invalid.permissions) #-------------------------------------------------------------# # Checking to see if the bot/user have all the mandatory # permissions # Ensure we aren't ignoring user_perms if not bypass_user_perms: # Ensure user has full permissions if not event.message.channel.get_permissions( event.message.member).can(user_perms): # Ensure there is a command group if command.group: cmd = command.group + " " + command.name else: cmd = command.name return event.msg.reply( Parser.bot_perm_missing.format( Config["bot"]["commands_prefix"], cmd)) # Ensure bot has all permissions needed if not event.message.channel.get_permissions( self.state.me).can(bot_perms): # Ensure there is a command group if command.group: cmd = command.group + " " + command.name else: cmd = command.name return event.msg.reply( Parser.bot_perm_missing.format( Config["bot"]["commands_prefix"], cmd)) # command ran in DMs elif allow_DMs: # Ensure user has proper permission level if Perms.integer(event.message.author, False) < DM_level: return event.message.reply(Invalid.permissions) # not allowing direct message commands else: return event.message.reply(Parser.not_DM_enabled) # handle message self.bot.handle_message(event.message)