async def change_color(self, ctx, hex_code, *, input_tree_name): """Replaces the background color with a new color.""" user = find_or_insert_user(ctx.author.id) tree_index = find_tree_index(user, input_tree_name) if tree_index == None: await ctx.send(embed=error_embed( ctx.author, f"You do not have a tree with the name {input_tree_name}.")) return # convert to rgb try: h = hex_code.lstrip("#") user["trees"][tree_index]["background_color"] = tuple( int(h[i:i + 2], 16) for i in (0, 2, 4)) except: await ctx.send( embed=error_embed(ctx.author, f"{hex_code} is not valid.")) return user_col.update_one({"user_id": ctx.author.id}, {"$set": user}) tree_to_display = find_tree(user, input_tree_name) im_tree = create_tree_image(user, tree_to_display) embed = tree_embed(user, ctx.author, tree_to_display) await ctx.send(file=im_tree, embed=embed)
async def change_prefix(self, ctx, *, input_prefixes): """Change bot's prefixes in a specific guild.""" prefixes = input_prefixes.split() # checks if len(prefixes) > 3: await ctx.send(embed=error_embed( ctx.author, "Only 3 prefixes can be entered.")) return for prefix in prefixes: if len(prefix) > 10: await ctx.send(embed=error_embed( ctx.author, f"`{prefix}` is over the 10 character limit.")) return guild = guild_col.find_one({"guild_id": ctx.guild.id}) if guild == None: guild = {"guild_id": ctx.guild.id, "prefixes": "b!"} guild_col.insert_one(guild.copy()) guild["prefixes"] = prefixes guild_col.update_one({"guild_id": ctx.guild.id}, {"$set": guild}) embed = discord.Embed(title=f"{ctx.guild} Prefixes", color=3138682) for i, prefix in enumerate(prefixes): embed = embed.add_field(name=f"Prefix {i+1}", value=prefix) await ctx.send(embed=embed)
async def buy_part_with_username(self, ctx, part_name, member: discord.User = None): """Buy a part from a player's shop with their username.""" user = find_or_insert_user(ctx.author.id) if len(user["inventory"]) >= 100: await ctx.send(embed=error_embed( ctx.author, "You have reached the limit of 100 parts in your inventory.")) return if member == None: member = ctx.author seller = user_col.find_one({"user_id": member.id}) if seller == None: await ctx.send( embed=error_embed(ctx.author, f"{member} has no parts listed.") ) return # get correct spelling of list in seller all_parts = seller["parts"] part_to_buy = None for part in all_parts: if part["name"].lower() == part_name.lower(): part_to_buy = part if part_to_buy == None: await ctx.send(embed=error_embed( ctx.author, f"{member} does not have a part named {part_name}.")) return if part_to_buy["price"] > user["balance"]: await ctx.send(embed=error_embed( ctx.author, f"You only have ${user['balance']}, but {part_to_buy['name']} costs ${part_to_buy['price']}." )) return # give part and remove money from user part_to_buy["creator"] = str(member) user["inventory"].append(part_to_buy) user["balance"] -= part_to_buy["price"] user_col.update_one({"user_id": ctx.author.id}, {"$set": user}) # give money to seller seller_tree_account = user_col.find_one({"user_id": member.id}) seller_tree_account["balance"] += part_to_buy["price"] user_col.update_one({"user_id": member.id}, {"$set": seller_tree_account}) await ctx.send(embed=info_embed( ctx.author, f"You bought {member}'s {part_to_buy['name']}."))
async def rename_tree(self, ctx, input_tree_name, *, new_name): """Rename tree of input_tree_name.""" if len(new_name) > 50: await ctx.send(embed=error_embed( ctx.author, "Tree Name cannot be over 50 characters long.")) return user = find_or_insert_user(ctx.author.id) tree_index = find_tree_index(user, input_tree_name) if tree_index == None: await ctx.send(embed=error_embed( ctx.author, f"You do not have a tree with the name {input_tree_name}.")) return user["trees"][tree_index]["name"] = new_name user_col.update_one({"user_id": ctx.author.id}, {"$set": user}) tree_to_display = find_tree(user, new_name) im_tree = create_tree_image(user, tree_to_display) embed = tree_embed(user, ctx.author, tree_to_display) await ctx.send(file=im_tree, embed=embed)
async def delete_inventory_part(self, ctx, input_inventory_num: int): """Delete a part from the inventory.""" user = find_or_insert_user(ctx.author.id) inventory_num = input_inventory_num - 1 # check for proper inventory number if input_inventory_num <= 0: await ctx.send(embed=error_embed( ctx.author, "Inventory numbers must be over 0.")) return elif len(user["inventory"]) - 1 < inventory_num: await ctx.send(embed=error_embed( ctx.author, f"Your inventory only goes up to {len(user['inventory'])}, but #{input_inventory_num} was entered." )) return user["inventory"].pop(inventory_num) user_col.update_one({"user_id": ctx.author.id}, {"$set": user}) await ctx.send(embed=info_embed( ctx.author, f"Part at #{input_inventory_num} has been removed."))
async def replace_part(self, ctx, input_inventory_num: int, *, input_tree_name): """Replaces a part of the tree of input_tree_name with the new input_inventory_num.""" user = find_or_insert_user(ctx.author.id) inventory_num = input_inventory_num - 1 if input_inventory_num <= 0: await ctx.send(embed=error_embed( ctx.author, "Inventory numbers must be over 0.")) return elif len(user["inventory"]) - 1 < inventory_num: await ctx.send(embed=error_embed( ctx.author, f"Your inventory only goes up to {len(user['inventory'])}, but #{input_inventory_num} was entered." )) return tree_index = find_tree_index(user, input_tree_name) if tree_index == None: await ctx.send(embed=error_embed( ctx.author, f"You do not have a tree with the name {input_tree_name}.")) return # get new part from user part = user["inventory"].pop(inventory_num) # set tree part to new part part_type = part.pop("type") # add old part to inventory part_for_inventory = user["trees"][tree_index][part_type] part_for_inventory["type"] = part_type user["inventory"].append(part_for_inventory) # add new part to tree user["trees"][tree_index][part_type] = part user_col.update_one({"user_id": ctx.author.id}, {"$set": user}) tree_to_display = find_tree(user, input_tree_name) im_tree = create_tree_image(user, tree_to_display) embed = tree_embed(user, ctx.author, tree_to_display) await ctx.send(file=im_tree, embed=embed)
async def help(self, ctx, *, category_or_command=None): """Shows the help message for the bot.""" if category_or_command: cog = self.bot.get_cog(category_or_command.lower()) command = self.bot.get_command(category_or_command) if cog: await self.send_cog_help(cog, ctx) elif command: await self.send_command_help(command, ctx) else: embed = error_embed( ctx, error_name='No Command or Category', error_msg= f'Sorry, There\'s no command or category by the name: `{category_or_command}`\nYou should try out just ``{ctx.prefix}help``.' ) await ctx.send(embed=embed) else: all_cogs = list(self.bot.cogs.values()) new_cogs = [] for cog in all_cogs: if cog.qualified_name not in self.ignored_cogs: new_cogs.append(cog) menu = MenuPages(source=HelpMainMenu(ctx, new_cogs), clear_reactions_after=True, timeout=60.0) await menu.start(ctx)
async def reset_tree(self, ctx, *, input_tree_name): """Resets the tree of input_tree_name.""" user = find_or_insert_user(ctx.author.id) tree_index = find_tree_index(user, input_tree_name) if tree_index == None: await ctx.send(embed=error_embed( ctx.author, f"You do not have a tree with the name {input_tree_name}.")) return # Reset tree and update in db tree_for_name = find_tree(user, input_tree_name) user["trees"][tree_index] = default_tree.copy() user["trees"][tree_index]["name"] = tree_for_name["name"] user_col.update_one({"user_id": ctx.author.id}, {"$set": user}) tree_to_display = find_tree(user, input_tree_name) im_tree = create_tree_image(user, tree_to_display) embed = tree_embed(user, ctx.author, tree_to_display) await ctx.send(file=im_tree, embed=embed)
async def delete_tree(self, ctx, *, input_tree_name): """Delete tree of input_tree_name.""" user = find_or_insert_user(ctx.author.id) tree_index = find_tree_index(user, input_tree_name) if tree_index == None: await ctx.send(embed=error_embed( ctx.author, f"You do not have a tree with the name {input_tree_name}.")) return # get parts and move to inventory tree_name_output = user["trees"][tree_index]["name"] # iterate over tree to return parts to inventory inventory_parts = [] for key, value in user["trees"][tree_index].items(): if key == "name" or key == "background_color": continue part_for_inventory = value part_for_inventory["type"] = key inventory_parts.append(part_for_inventory) # add old part to inventory user["inventory"].extend(inventory_parts) # delete tree user["trees"].pop(tree_index) user_col.update_one({"user_id": ctx.author.id}, {"$set": user}) await ctx.send( embed=info_embed(ctx.author, f"Deleted tree {tree_name_output}."))
async def subcommand_not_found(self, command, string): embed = error_embed( self.context, error_name='No SubCommand', error_msg= f'Sorry, There\'s no subcommand by the name: `{string}` under `{command.name}` command.\nYou should check out just ``{self.context.prefix}{command.name}``.' ) return embed
async def command_not_found(self, string): embed = error_embed( self.context, error_name='No Command or Category', error_msg= f'Sorry, There\'s no command or category by the name: `{string}`\nYou should check out just ``{self.context.prefix}help``.' ) return embed
async def create_tree(self, ctx, *, input_tree_name): """Creates a new tree.""" user = find_or_insert_user(ctx.author.id) if len(input_tree_name) > 50: await ctx.send(embed=error_embed( ctx.author, "Tree Name cannot be over 50 characters long.")) return if len(user["trees"]) >= 3: await ctx.send(embed=error_embed( ctx.author, "You are already at the max number of trees! To reset a tree, use the reset [Tree Name] command. To delete a tree, use the delete [Tree Name] command." )) return if find_tree(user, input_tree_name) != None: await ctx.send(embed=error_embed( ctx.author, f"A tree with the name {input_tree_name} already exists.")) return new_tree = default_tree.copy() new_tree["name"] = input_tree_name user["trees"].append(new_tree) user_col.update_one({"user_id": ctx.author.id}, {"$set": user}) tree_to_display = find_tree(user, input_tree_name) if tree_to_display == None: await ctx.send(embed=error_embed( ctx.author, f"You do not have a tree with the name {input_tree_name}.")) return im_tree = create_tree_image(user, tree_to_display) embed = tree_embed(user, ctx.author, tree_to_display) await ctx.send(file=im_tree, embed=embed)
async def check_attachment(ctx, width, height): """Check for attachment on message.""" if len(ctx.message.attachments) == 0: await ctx.send(embed=error_embed(ctx.author, "Attach an image ending with jpg, jpeg, or png.")) return False # check for correct extension on attachment pic_ext = [".jpg", ".jpeg", ".png"] match = False for ext in pic_ext: if ctx.message.attachments[0].filename.endswith(ext): match = True if match == False: await ctx.send(embed=error_embed(ctx.author, "Attach an image ending with jpg, jpeg, or png.")) return False # check for correct size if ctx.message.attachments[0].width != width or ctx.message.attachments[0].height != height: await ctx.send(embed=error_embed(ctx.author, f"Wrong size: ({ctx.message.attachments[0].width} x {ctx.message.attachments[0].height})! The image must be {width} x {height}.")) return False
async def check_balance(self, ctx, member : discord.User = None): """Check a player's balance.""" if member == None: member = ctx.author user = find_user(member.id) if user == None: await ctx.send(embed=error_embed(ctx.author, f"{member} does not have a balance yet.")) return await ctx.send(embed=info_embed(ctx.author, f"{member} has ${user['balance']}."))
async def on_command_error(self, ctx, e): # send error if command fails on argument if isinstance(e, commands.BadArgument) or isinstance( e, commands.MissingRequiredArgument): await ctx.send(embed=error_embed(ctx.author, e)) # check if command is on cooldown and send time remaining if it is. elif isinstance(e, commands.CommandOnCooldown): # send time left in seconds if cooldown is under a minute if e.retry_after <= 60: await ctx.send(embed=error_embed( ctx.author, f"This command is on cooldown, try again in{e.retry_after: .1f} seconds." )) # send time left in hours else: await ctx.send(embed=error_embed( ctx.author, f"This command is on cooldown, try again in{e.retry_after / 3600: .1f} hours." )) else: print(e)
async def view_other_tree(self, ctx, member: discord.User, *, input_tree_name): """Displays the tree of input_tree_name of a certain member.""" user = find_user(member.id) if user == None: await ctx.send(embed=error_embed( ctx.author, f"{member} does not have any trees.")) return tree_to_display = find_tree(user, input_tree_name) if tree_to_display == None: await ctx.send(embed=error_embed( ctx.author, f"{member} does not have a tree with the name {input_tree_name}." )) return im_tree = create_tree_image(user, tree_to_display) embed = tree_embed(user, member, tree_to_display) await ctx.send(file=im_tree, embed=embed)
async def display_tree(self, ctx, *, input_tree_name): """Displays the tree of input_tree_name.""" user = find_or_insert_user(ctx.author.id) tree_to_display = find_tree(user, input_tree_name) if tree_to_display == None: await ctx.send(embed=error_embed( ctx.author, f"You do not have a tree with the name {input_tree_name}.")) return im_tree = create_tree_image(user, tree_to_display) embed = tree_embed(user, ctx.author, tree_to_display) await ctx.send(file=im_tree, embed=embed)
async def send_cog_help(self, cog): all_cog_commands = cog.get_commands() filtered_commands = await self.filter_commands(all_cog_commands) if not filtered_commands: embed = error_embed( self.context, error_name='No Commands', error_msg= f'Sorry, There are no commands in this category yet.\nMaybe check out other categories by using just `{self.context.prefix}help`.' ) await self.context.send(embed=embed) return menu = MenuPages(source=HelpCogMenu(self.context, filtered_commands, self.format_command_usage), clear_reactions_after=True, timeout=60.0) await menu.start(self.context)
async def delete_part_listing(self, ctx, part_name): """Delete a listing from the player's shop.""" user = find_or_insert_user(ctx.author.id) part_for_removal = None for i, part in enumerate(user["parts"]): if part["name"].lower() == part_name.lower(): part_for_removal = part["name"] break if part_for_removal == None: await ctx.send(embed=error_embed( ctx.author, f"Part {part_name} was not found.")) return user["parts"].pop(i) user_col.update_one({"user_id": ctx.author.id}, {"$set": user}) await ctx.send( embed=info_embed(ctx.author, f"Unlisted part {part_for_removal}."))
async def list_trees(self, ctx, member: discord.User = None): """List all the trees of member.""" if member == None: member = ctx.author user = find_user(member.id) if user == None: await ctx.send( embed=error_embed(ctx.author, f"{member} has no trees.")) return embed = discord.Embed(title=f"{member}'s Trees", color=0o05300) for tree in user["trees"]: embed = embed.add_field( name=tree['name'], value= f"""Base: {tree["base"]["creator"]}'s {tree["base"]["name"]}\n Trunk: {tree["trunk"]["creator"]}'s {tree["trunk"]["name"]}\n Leaves: {tree["leaves"]["creator"]}'s {tree["leaves"]["name"]}\n""" ) await ctx.send(embed=embed)
async def send_cog_help(self, cog, ctx): """Send help about a cog or category""" commands = cog.get_commands() commands_runnable = [] for command in commands: is_runnable = await command.can_run(ctx) if is_runnable: commands_runnable.append(command) if not commands_runnable: embed = error_embed( ctx, error_name='No Commands', error_msg= f'Sorry, There are no commands in this category yet.\nMaybe check out other categories by using just `{ctx.prefix}help`.' ) await ctx.send(embed=embed) return menu = MenuPages(source=HelpCogMenu(ctx, commands_runnable, self.format_command_usage), clear_reactions_after=True, timeout=60.0) await menu.start(ctx)
async def _disable_guild_feature(self, ctx, config_type, success_msg): is_config_entry_exists = await is_config_value_set( self.config_collection, ctx.guild.id, config_type ) if is_config_entry_exists: is_feature_enabled = await get_config_value( self.config_collection, ctx.guild.id, config_type ) if is_feature_enabled: await delete_config_value( self.config_collection, ctx.guild.id, config_type ) embed = normal_embed( ctx, title='Disabled feature', description=success_msg ) await ctx.send(embed=embed) else: embed = error_embed( ctx, error_name='Already Disabled', error_msg='Sorry, This Feature is already disabled.\nIf you want to enable it then use the `enable` command.' ) await ctx.send(embed=embed) return
async def create_part_listing(self, ctx, part_type, part_name, list_price: int): """List a part on the player's shop.""" part_type = part_type.lower() if part_type not in valid_parts: await ctx.send( embed=error_embed(ctx.author, "Enter base, trunk, or leaves.")) return if len(part_name) > 50: await ctx.send(embed=error_embed( ctx.author, "Part Name cannot be over 50 characters long.")) return if list_price < 0 or list_price > 10000: await ctx.send(embed=error_embed( ctx.author, "List Price cannot be less than $0 or over $10,000.")) return if part_type == "base" and await check_attachment(ctx, 15, 3) == False: return elif part_type in ["trunk", "leaves"] and await check_attachment( ctx, 15, 12) == False: return user = find_or_insert_user(ctx.author.id) parts = user["parts"] if len(parts) >= 15: await ctx.send(embed=error_embed( ctx.author, "You have exceeded the limit of 15 parts.")) return for part in parts: if part["name"].lower() == part_name.lower(): await ctx.send(embed=error_embed( ctx.author, f"You have already listed a part with the name {part['name']}." )) return # get image file with aiohttp attachment_bytes = await ctx.message.attachments[0].read() parts.append({ "image": attachment_bytes, "name": part_name, "type": part_type, "price": list_price }) user_col.update_one({"user_id": ctx.author.id}, {"$set": user}) im_part = bytes_to_file(attachment_bytes) embed = discord.Embed(title=f"New {part_type} Listing", color=255)\ .set_author(name= str(ctx.author))\ .add_field(name="Name", value=part_name)\ .add_field(name="List Price", value=list_price)\ .set_image(url="attachment://image.png") await ctx.send(file=im_part, embed=embed)
async def shop_parts_with_id(self, ctx, part_type, member_id): """View all the parts in a player's shop with their id.""" part_type = part_type.lower() if part_type not in valid_parts: await ctx.send( embed=error_embed(ctx.author, "Enter base, trunk, or leaves.")) return member = None try: member = await self.bot.fetch_user(member_id) except: await ctx.send(embed=error_embed( ctx.author, f"Member with ID {member_id} not found.")) return seller = user_col.find_one({"user_id": member.id}) if seller == None: await ctx.send( embed=error_embed(ctx.author, f"{member} has no parts listed.") ) return all_parts = seller["parts"] parts = [] for part in all_parts: if part["type"] == part_type: parts.append(part) if len(parts) == 0: await ctx.send(embed=error_embed( ctx.author, f"{member} has no parts of that type listed.")) return part_picture = bytes_to_file(parts[0]["image"]) total_parts = len(parts) embed = shop_part_embed(member, parts, 1, total_parts) shop_message = await ctx.send(file=part_picture, embed=embed) if len(parts) == 1: return await shop_message.add_reaction("⬅️") await shop_message.add_reaction("➡️") def check(reaction, user): return reaction.message.id == shop_message.id and user.id == ctx.author.id and str( reaction.emoji) in ["⬅️", "➡️"] current_part = 1 while True: try: reaction, user = await self.bot.wait_for("reaction_add", check=check, timeout=60) # check for arrow reactions if str(reaction.emoji) == "⬅️" and current_part > 1: current_part -= 1 part_picture = bytes_to_file(parts[current_part - 1]["image"]) embed = shop_part_embed(member, parts, current_part, total_parts) await shop_message.delete() shop_message = await ctx.send(file=part_picture, embed=embed) await shop_message.add_reaction("⬅️") await shop_message.add_reaction("➡️") elif str( reaction.emoji) == "➡️" and current_part < total_parts: current_part += 1 part_picture = bytes_to_file(parts[current_part - 1]["image"]) embed = shop_part_embed(member, parts, current_part, total_parts) await shop_message.delete() shop_message = await ctx.send(file=part_picture, embed=embed) await shop_message.add_reaction("⬅️") await shop_message.add_reaction("➡️") except TimeoutError: await shop_message.clear_reaction("⬅️") await shop_message.clear_reaction("➡️") break
async def list_inventory(self, ctx, input_inventory_num: int = None): """Lists the entire inventory 25 items at a time.""" user = find_or_insert_user(ctx.author.id) # information on specific part if input_inventory_num != None: inventory_num = input_inventory_num - 1 # check for proper inventory number if input_inventory_num <= 0: await ctx.send(embed=error_embed( ctx.author, "Inventory numbers must be over 0.")) return elif len(user["inventory"]) - 1 < inventory_num: await ctx.send(embed=error_embed( ctx.author, f"Your inventory only goes up to {len(user['inventory'])}, but #{input_inventory_num} was entered." )) return inventory_part = user["inventory"][inventory_num] part_picture = bytes_to_file(inventory_part["image"]) embed = inventory_part_embed(inventory_part, inventory_part["creator"]) await ctx.send(file=part_picture, embed=embed) return embed = discord.Embed(title=f"{ctx.author}'s Inventory", color=255) total_part_lists = ceil(len(user["inventory"]) / 25) i = 1 for part in user["inventory"][:26]: embed = embed.add_field(name=part["type"], value=f"{i} : {part['creator']}'s {part['name']}", inline=False)\ .set_footer(text=f"Page 1 / {total_part_lists}") i += 1 inventory_message = await ctx.send(embed=embed) # only one page needs to be displayed if len(user["inventory"]) <= 25: return await inventory_message.add_reaction("⬅️") await inventory_message.add_reaction("➡️") def check(reaction, user): return reaction.message.id == inventory_message.id and user.id == ctx.author.id and str( reaction.emoji) in ["⬅️", "➡️"] current_part_list = 1 while True: try: reaction, reaction_user = await self.bot.wait_for( "reaction_add", check=check, timeout=60) # check for arrow reactions if str(reaction.emoji) == "⬅️" and current_part_list > 1: current_part_list -= 1 inventory_index_first = (current_part_list - 1) * 25 inventory_index_last = (current_part_list * 25) + 1 embed = discord.Embed(title=f"{ctx.author}'s Inventory", color=255)\ .set_footer(text=f"Page {current_part_list} / {total_part_lists}") j = inventory_index_first for part in user["inventory"][ inventory_index_first:inventory_index_last]: embed = embed.add_field( name=part["type"], value=f"{j+1} : {part['creator']}'s {part['name']}", inline=False) j += 1 await inventory_message.edit(embed=embed) await inventory_message.remove_reaction( reaction, reaction_user) elif str(reaction.emoji ) == "➡️" and current_part_list < total_part_lists: current_part_list += 1 inventory_index_first = (current_part_list - 1) * 25 inventory_index_last = (current_part_list * 25) + 1 embed = discord.Embed(title=f"{ctx.author}'s Inventory", color=255)\ .set_footer(text=f"Page {current_part_list} / {total_part_lists}") j = inventory_index_first for part in user["inventory"][ inventory_index_first:inventory_index_last]: embed = embed.add_field( name=part["type"], value=f"{j+1} : {part['creator']}'s {part['name']}", inline=False) j += 1 await inventory_message.edit(embed=embed) await inventory_message.remove_reaction( reaction, reaction_user) except asyncio.TimeoutError: await inventory_message.clear_reaction("⬅️") await inventory_message.clear_reaction("➡️") break
async def on_command_error(self, ctx, error): """Using on_command_error as an error handler.""" error = getattr(error, 'original', error) if isinstance(error, self.ignored): return if isinstance(error, exceptions.AdminPermsRequiredError): embed = error_embed( ctx, error_name='Admin Perms Required', error_msg='Sorry, This command requires admin perms to execute.' ) await ctx.send(embed=embed) return if isinstance(error, exceptions.UserBlacklistedError): if error.global_: embed = error_embed( ctx, error_name='Blacklisted', error_msg= 'Sorry, You\'ve been blacklisted from using any of my commands globally.\nPlease stop trying to use them.' ) await ctx.send(embed=embed) else: embed = error_embed( ctx, error_name='Blacklisted', error_msg= 'Sorry, You\'ve been blacklisted from using any of my commands in this server.\nPlease stop trying to use them.' ) await ctx.send(embed=embed) return if isinstance(error, exceptions.ApiFetchError): embed = error_embed( ctx, error_name='API Fetch Error', error_msg= 'Sorry, Failed to fetch data from an external API.\nMaybe try again later.' ) await ctx.send(embed=embed) if isinstance(error, commands.DisabledCommand): embed = error_embed( ctx, error_name='Disabled Command', error_msg= 'Sorry, This command has been disabled by the owner of bot.\nPlease stop trying to use it.' ) await ctx.send(embed=embed) return # Im a little confused about this error if isinstance(error, commands.ConversionError): embed = error_embed( ctx, error_name='Conversion Error', error_msg= 'Sorry, I failed to convert your input.\nMaybe the command expects a number and you provided a text instead?' ) await ctx.send(embed=embed) return if isinstance(error, commands.CheckFailure): if isinstance(error, commands.NoPrivateMessage): embed = error_embed( ctx, error_name='No Private Message', error_msg= 'Sorry, This command can\'t be used in private messages.') await ctx.send(embed=embed) return if isinstance(error, commands.PrivateMessageOnly): embed = error_embed( ctx, error_name='Private Message Only', error_msg= 'Sorry, This command can only be used in private messages.' ) await ctx.send(embed=embed) return if isinstance(error, commands.NotOwner): embed = error_embed( ctx, error_name='Not Owner', error_msg= 'Sorry, This command can only be used by the owner of bot.' ) await ctx.send(embed=embed) return if isinstance(error, commands.MissingPermissions): required_perms = '' for perm in error.missing_perms: required_perms += f'- {perm}' required_perms += '\n' embed = error_embed( ctx, error_name='Missing Permmisions', error_msg= f'Sorry, You need to have these permissions to run this command:\n``{required_perms}``' ) await ctx.send(embed=embed) return if isinstance(error, commands.BotMissingPermissions): required_perms = '' for perm in error.missing_perms: required_perms += f'- {perm}' required_perms += '\n' embed = error_embed( ctx, error_name='Bot Missing Permmisions', error_msg= f'Sorry, I need to have these permissions to run this command:\n``{required_perms}``' ) await ctx.send(embed=embed) return if isinstance(error, commands.MissingRole): missing_role = ctx.guild.get_role(error.missing_role) embed = error_embed( ctx, error_name='Missing Role', error_msg= f'Sorry, You need to have this role to run this command: ``{missing_role.name}``' ) await ctx.send(embed=embed) return if isinstance(error, commands.BotMissingRole): missing_role = ctx.guild.get_role(error.missing_role) embed = error_embed( ctx, error_name='Bot Missing Role', error_msg= f'Sorry, I need to have this role to run this command: ``{missing_role.name}``' ) await ctx.send(embed=embed) return if isinstance(error, commands.MissingAnyRole): missing_roles_list = [] for role in error.missing_roles: missing_roles_list.append(ctx.guild.get_role(role)) missing_roles = ', '.join( [role.name for role in missing_roles_list]) embed = error_embed( ctx, error_name='Missing Any Role', error_msg= f'Sorry, You need to have atleast one of these roles to run this command: ``{missing_roles}``' ) await ctx.send(embed=embed) return if isinstance(error, commands.BotMissingAnyRole): missing_roles_list = [] for role in error.missing_roles: missing_roles_list.append(ctx.guild.get_role(role)) missing_roles = ', '.join( [role.name for role in missing_roles_list]) embed = error_embed( ctx, error_name='Bot Missing Any Role', error_msg= f'Sorry, I need to have atleast one of these roles to run this command: ``{missing_roles}``' ) await ctx.send(embed=embed) return if isinstance(error, commands.NSFWChannelRequired): embed = error_embed( ctx, error_name='NSFW Channel Required', error_msg= 'Sorry, This channel needs to be a nsfw channel in order to run this command.' ) await ctx.send(embed=embed) return if isinstance(error, commands.UserInputError): if isinstance(error, commands.MissingRequiredArgument): embed = error_embed( ctx, error_name='Missing Required Argument', error_msg= f'Sorry, You\'re missing a required argument: ``{error.param.name}``\nMaybe check out the help command?' ) await ctx.send(embed=embed) return if isinstance(error, commands.ArgumentParsingError): if isinstance(error, commands.UnexpectedQuoteError): embed = error_embed( ctx, error_name='Unexpected Quote Error', error_msg= 'Sorry, An unexpected quote(") in your input has been detected.\nMaybe check out the help command?' ) await ctx.send(embed=embed) return if isinstance(error, commands.InvalidEndOfQuotedStringError): embed = error_embed( ctx, error_name='Invalid End Of Quoted String Error', error_msg= 'Sorry, An empty space was expected after your closing quoted(""<-this) string.\nMaybe check out the help command?' ) await ctx.send(embed=embed) return if isinstance(error, commands.ExpectedClosingQuoteError): embed = error_embed( ctx, error_name='Expected Closing Quote Error', error_msg= 'Sorry, You started a quoted("") string, But you never closed it.\nMaybe check out the help command?' ) await ctx.send(embed=embed) return if isinstance(error, commands.BadArgument): embed = error_embed( ctx, error_name='Bad Argument', error_msg= 'Sorry, I failed to convert your input.\nMaybe the command expects a number and you provided a text instead?' ) await ctx.send(embed=embed) return if isinstance(error, commands.BadUnionArgument): # TODO: do this later pass if isinstance(error, commands.TooManyArguments): embed = error_embed( ctx, error_name='Too Many Arguments', error_msg= 'Sorry, You provided too many arguments to this command.\nMaybe check out the help command?' ) await ctx.send(embed=embed) return if isinstance(error, commands.CommandOnCooldown): embed = error_embed( ctx, error_name='Command On Cooldown', error_msg= f'Sorry, This command is on a cooldown.\nPlease wait `{round(error.retry_after, 1)}` more seconds before retrying.' ) await ctx.send(embed=embed) return if isinstance(error, commands.MaxConcurrencyReached): # Don't need this for now pass if isinstance(error, commands.ExtensionError): if isinstance(error, commands.ExtensionAlreadyLoaded): embed = error_embed( ctx, error_name='Extension Already Loaded', error_msg='Sorry, This Extension is already loaded.') await ctx.send(embed=embed) return if isinstance(error, commands.ExtensionNotLoaded): embed = error_embed( ctx, error_name='Extension Not Loaded', error_msg='Sorry, This Extension is not loaded.') await ctx.send(embed=embed) return if isinstance(error, commands.NoEntryPointError): embed = error_embed( ctx, error_name='No Entry Point Error', error_msg= 'Sorry, This Extension does not contain a setup funtion.') await ctx.send(embed=embed) return if isinstance(error, commands.ExtensionFailed): embed = error_embed( ctx, error_name='Extension Failed', error_msg='Sorry, This Extension Failed to load.') await ctx.send(embed=embed) if isinstance(error, commands.ExtensionNotFound): embed = error_embed( ctx, error_name='Extension Not Found', error_msg='Sorry, This Extension was not found.') await ctx.send(embed=embed) return if self.bot.is_env_dev(): await ctx.send( f'```py\n{error.__class__.__name__}: {str(error)}\n```') raise error return embed = error_embed( ctx, error_name='Unexpected Error', error_msg= 'Sorry, An unexpected error occured.\nThis gotta be a very serious error, Notifying the owner of bot...' ) await ctx.send(embed=embed) app_info = await self.bot.application_info() ctx_dict = f'```py\n{ctx.__dict__}\n```' await app_info.owner.send( f'An error occured in {ctx.guild.id} while invoking command: {ctx.command.name}\n{error.__class__.__name__}: {str(error)}\n{ctx_dict}' ) raise error