def perm_bar_command(self, event): # Check if they supplied an argument for the perm level if len(event.msg.mentions): # Mentioned a user for k, v in event.msg.mentions.items(): user = v break elif len(event.args): #Supplied an ID/name if event.guild: user = event.guild.get_member(event.args[0]) else: return event.msg.reply(Invalid.argument.format(event.args[0])) else: # Didn't supply an argument, use the author if event.msg.guild: user = event.msg.member else: user = event.msg.author # Acknowledge if isinstance(user, GuildMember): return event.msg.reply( Util.level.format( user.name, Perms.permission_bar( user ) ) ) elif isinstance(user, User): return event.msg.reply( Util.level.format( user.username, Perms.permission_bar( user ) ) ) else: return event.msg.reply( Util.error )
def tag_edit(self, event): # argument checking if not len(event.args): return event.msg.reply(Tags.nea) tag_data = tag_data_parser(event.msg.content, require_mandatory=False, defaults=False) # Ensure name is given so we know what tag to modify if "name" not in tag_data.keys(): return event.msg.reply(Tags.arg_needed.format("name")) # Assign name argument to command else: command = tag_data.pop("name") # Check if we are modifying a global tag or not if "global" not in tag_data.keys(): global_cmd = False else: global_cmd = tag_data["global"] # Guild tag if not global_cmd: tags = GuildConfig.load(event.msg.guild.id, force_guild=False, no_guild_default=False) # Global tag else: # Ensure proper permissions for global tags if Perms.integer(event.msg.member) < tag_data["global_admin"]: return event.msg.reply(Tags.invalid_perms) tags = GuildConfig.load("default") # Ensure tag already exists if command not in tags["tags"]["list"]: return event.msg.reply(Tags.not_exist.format(command)) # Cycle through arguments given in command for argument in tag_data.keys(): # Overwrite previous data tags["tags"]["list"][command][argument] = tag_data[argument] # ensure global if global_cmd: GuildConfig.write("default", tags) else: GuildConfig.write(event.msg.guild.id, tags) event.msg.reply(Tags.tag_updated.format(command))
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 tag_list(self, event): tags = GuildConfig.load(event.msg.guild.id)["tags"] tag_list = [] # Ensure there are no tags if len(tags["list"].keys()) > 0: user_perm_level = Perms.integer(event.msg.member) # Cycle through the tags for tag in tags["list"].keys(): # Ensure user has proper permissions to run command if user_perm_level >= tags["list"][tag]["level"]: tag_list.append(tag) else: tag_list.append("*" + tag) # ensure guild has global enabled if tags["options"]["allow_global"]: tags = GuildConfig.load("default")["tags"] user_perm_level = Perms.integer(event.msg.member) # Cycle through the tags for tag in tags["list"].keys(): # Ensure user has proper permissions to run command if user_perm_level >= tags["list"][tag]["level"]: tag_list.append(tag) else: tag_list.append("*" + tag) response = Tags.tag_list.format(", ".join(tag_list)) # Ensure that the response isn't too long if len(response) <= 2000: return event.msg.reply(response) else: return event.msg.reply(Tags.too_long)
def respond_to_tag(event, tag_data): msg = event.message cmd_args = event.message.content.split()[1:] args = [""] # Increase each argument's index by one. for arg in cmd_args: args.append(arg) # Check permission level if Perms.integer(msg.member) < tag_data["level"]: return msg.reply(Tags.invalid_perms) # Set variables variables = { "name": msg.author.username, "count": tag_data["count"], "arg": args } # Check if embedding it if tag_data["embed"]: # Get embed: try: embed = TagEmbed(tag_data, variables) # Try to embed the message return msg.reply(tag_data["content"], embed=embed) # Error if user didn't supply enough arguments except IndexError: return msg.reply(Tags.nea) # Error if part of the tag embed is missing except KeyError: msg.reply(Tags.key_missing) return msg.reply(tag_data["response"]) except: # Return an embed error return msg.reply(Tags.embed_error) else: try: return msg.reply(tag_data["response"].format(**variables)) # Error if user didn't supply enough variables. except IndexError: msg.reply(Tags.nea)
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 tag_delete(self, event): # argument checking if len(event.args) >= 2: tag = event.args[0] # global == true if event.args[1].lower() in bool_true: is_global = True # global == False elif event.args[1].lower() in bool_false: is_global = False # invalid argument else: return event.msg.reply(Tags.invalid_arg.format(event.args[1])) # Only tag name given elif len(event.args) == 1: tag = event.args[0] is_global = False else: return event.msg.reply(Tags.nea) # Check if global if is_global: tags = GuildConfig.load("default") # Ensure tag exists as global if tag not in tags["tags"]["list"].keys(): return event.msg.reply(Tags.not_exist.format(tag)) else: # Ensure user has global permissions if Perms.integer(event.msg.member) < tag_data["global_admin"]: return event.msg.reply(Tags.invalid_perms) # Remove tag and acknowledge tag_data = tags["tags"]["list"].pop(tag) GuildConfig.write("default", tags) return event.msg.reply(Tags.tag_removed.format(tag, tag_data)) else: tags = GuildConfig.load(event.msg.guild.id) tag_list = tags["tags"]["list"] if "tags" not in tags.keys(): return event.msg.reply(Tags.guild_not_setup) # Ensure tag exists as global if tag not in tags["tags"]["list"].keys(): return event.msg.reply(Tags.not_exist.format(tag)) # Ensure tag is not at global admin+ level if tag_list[tag]["level"] < perm_ints["global_admin"]: # Ensure the user has >= the tag permission level if Perms.integer(event.msg.member) < tag_list[tag]["level"]: return event.msg.reply( Tags.invalid_perms + " You can't remove a tag you can't run.") # Remove tag and acknowledge tag_data = tags["tags"]["list"].pop(tag) GuildConfig.write(event.msg.guild.id, tags) return event.msg.reply(Tags.tag_removed.format(tag, tag_data))
def tag_add(self, event): tag_data = tag_data_parser(event.msg.content) if type(tag_data) == type(""): tag_data = tag_data.split("--") # Return a value error to the user's face if tag_data[0] == "ValueError": return event.msg.reply(Tags.invalid_arg.format(tag_data[2])) # Mandatory argument missing elif tag_data[0] == "MandatoryMissing": return event.msg.reply(Tags.arg_needed.format(tag_data[1])) # Invalid argument elif tag_data[0] == "InvalidArg": return event.msg.reply(Tags.invalid_arg.format(tag_data[1])) else: return event.msg.reply(Tags.error) # Ensure name doesn't contain any illegal characters for char in illegal_name_characters: if char in tag_data["name"]: return event.msg.reply(Tags.illegal_char.format("name", char)) # Ensure level not greater than highest allowed if tag_data["level"] > max_permission_int: return event.msg.reply(Tags.invalid_perm_int.format(max_perm_int)) tag_data["name"] = tag_data["name"].replace(" ", "-") # Ensure tag not global if not tag_data["global"]: data = GuildConfig.load(event.guild.id, True) # Ensure guild has been setup for tags if "tags" not in data.keys(): return event.msg.reply(Tags.guild_not_setup) # Ensure tag doesn't already exist if tag_data["name"] in data["tags"]["list"].keys(): return event.msg.reply( Tags.already_exists.format(tag_data["name"])) # Create tag structure data["tags"]["list"][tag_data["name"]] = { "response": tag_data["response"], "embed": tag_data["embed"], "colour": tag_data["colour"], "content": tag_data["content"], "footer": tag_data["footer"], "url": tag_data["url"], "level": tag_data["level"], "title": tag_data["title"], "count": 0 } # update guild config GuildConfig.write(event.guild.id, data) else: if Perms.integer(event.msg.member) >= perm_ints["global_admin"]: data = GuildConfig.load("default") # Ensure tag doesn't already exist if tag_data["name"] in data["tags"]["list"].keys(): return event.msg.reply( Tags.already_exists.format(tag_data["name"])) # Create tag structure data["tags"]["list"][tag_data["name"]] = { "response": tag_data["response"], "embed": tag_data["embed"], "colour": tag_data["colour"], "content": tag_data["content"], "footer": tag_data["footer"], "url": tag_data["url"], "level": tag_data["level"], "count": 0 } # update guild config GuildConfig.write("default", data) # invalid permission else: return event.msg.reply(Tags.invalid_perms) event.msg.reply(Tags.tag_created.format(tag_data["name"]))
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)