def makesay(self, ctx: discord.ext.commands.Context, *, message: str): """Makes the bot say a message If it's used directly on a text channel, the bot will delete the command's message and repeat it itself If it's used on a private message, the bot will ask on which channel he should say the message.""" if ctx.message.channel.is_private: description_list = [] channel_list = [] prev_server = None num = 1 for server in self.bot.servers: author = get_member(self.bot, ctx.message.author.id, server) bot_member = get_member(self.bot, self.bot.user.id, server) # Skip servers where the command user is not in if author is None: continue # Check for every channel for channel in server.channels: # Skip voice channels if channel.type != discord.ChannelType.text: continue author_permissions = author.permissions_in( channel) # type: discord.Permissions bot_permissions = bot_member.permissions_in( channel) # type: discord.Permissions # Check if both the author and the bot have permissions to send messages and add channel to list if (author_permissions.send_messages and bot_permissions.send_messages) and \ (ctx.message.author.id in owner_ids or author_permissions.administrator): separator = "" if prev_server is not server: separator = "---------------\n\t" description_list.append( "{2}{3}: **#{0}** in **{1}**".format( channel.name, server.name, separator, num)) channel_list.append(channel) prev_server = server num += 1 if len(description_list) < 1: yield from self.bot.say( "We don't have channels in common with permissions.") return yield from self.bot.say( "Choose a channel for me to send your message (number only):" + "\n\t0: *Cancel*\n\t" + "\n\t".join(["{0}".format(i) for i in description_list])) answer = yield from self.bot.wait_for_message( author=ctx.message.author, channel=ctx.message.channel, timeout=30.0) if answer is None: yield from self.bot.say("... are you there? Fine, nevermind!") elif is_numeric(answer.content): answer = int(answer.content) if answer == 0: yield from self.bot.say( "Changed your mind? Typical human.") return try: yield from self.bot.send_message(channel_list[answer - 1], message) yield from self.bot.say("Message sent on {0} ({1})".format( channel_list[answer - 1].mention, channel_list[answer - 1].server)) except IndexError: yield from self.bot.say( "That wasn't in the choices, you ruined it. Start from the beginning." ) else: yield from self.bot.say("That's not a valid answer!") else: yield from self.bot.delete_message(ctx.message) yield from self.bot.send_message(ctx.message.channel, message)
def tutorial(self, ctx, *, name: str=None): """Pesquisa tutoriais no PO.B.R.E.""" ask_channel = get_channel_by_name(self.bot, ask_channel_name, ctx.message.server) destination = ctx.message.channel if ctx.message.channel.name == ask_channel_name else ctx.message.author permissions = ctx.message.channel.permissions_for(get_member(self.bot, self.bot.user.id, ctx.message.server)) if not permissions.embed_links: yield from self.bot.say("Foi mal, eu preciso de permissões de `Embed Links` para executar este comando.") return if name is None: yield from self.bot.say("Diga-me o nome do tutorial que desejas pesquisar.") return tutorial = yield from get_search(parse.quote(name.replace(' ', '+').encode('iso-8859-1'), safe='+'), "19", '0') if tutorial is None or len(tutorial) == 0: yield from self.bot.say("Não encontrei nenhum tutorial.") return long = ctx.message.channel.is_private or ctx.message.channel.name == ask_channel_name embed = self.get_tutorial_embed(ctx, tutorial, long) if len(tutorial) > 1: start = 0 answer = '+' bot_message = yield from self.bot.say("Escolha uma das opções abaixo (0: Cancelar):", embed=embed) while answer == '+' or answer == '-': answer = yield from self.bot.wait_for_message(author=ctx.message.author, channel=ctx.message.channel,timeout=30.0) if answer is None: yield from self.bot.say("... opa, esqueceu de mim? Beleza, então!") return elif is_numeric(answer.content): answer = int(answer.content) if answer == 0: yield from self.bot.say("Mudou de ideia? Típico.") return try: choice = tutorial[answer-1] tutorial = [] details = yield from get_details(choice["link"], "19", '0') tutorial.append({'name' : choice["name"], 'link' : choice["link"], 'details': details}) embed = self.get_tutorial_embed(ctx, tutorial, long) except IndexError: yield from self.bot.say("Nossa, pra que fazer isso, você nem escolheu algo válido. Agora comece de novo.") elif isinstance(answer.content, str) and (answer.content == '-' or answer.content == '+'): if not ctx.message.channel.is_private and ctx.message.channel != ask_channel: yield from self.bot.delete_message(answer) answer = str(answer.content) if answer == '-' and start - 10 >= 0: start -= 10 embed = self.get_tutorial_embed(ctx, tutorial, long, start) elif answer == '+' and start + 10 < len(tutorial): start += 10 embed = self.get_tutorial_embed(ctx, tutorial, long, start) yield from self.bot.edit_message(bot_message, "Escolha uma das opções abaixo (0: Cancelar):", embed=embed) else: yield from self.bot.say("Essa não é uma resposta válida!") if len(tutorial) == 1: if destination != ask_channel: yield from self.bot.say("Estou te enviando as informações solicitadas via mensagem privada.") yield from self.bot.send_message(destination, embed=embed) # Attach item's image only if the bot has permissions permissions = ctx.message.channel.permissions_for(get_member(self.bot, self.bot.user.id, ctx.message.server)) trad = tutorial[0] item = dict() if "details" in trad: if "imagens" in trad["details"]: for image in trad["details"]["imagens"]: if permissions.attach_files and image != 0: filename = 'temp.png' while os.path.isfile(filename): filename = "_" + filename with open(filename, "w+b") as f: f.write(image) f.close() with open(filename, "r+b") as f: yield from self.bot.send_file(destination, f) f.close() os.remove(filename)
def unban(self, ctx: commands.Context, *, message: str = None): """Desbane um usuário Deve ser verificado os usuários banidos com /getban e depois utilizar /unban [nome] ao invés de @user.""" # Verifica se está em conversa privada ou em um canal no servidor # if ctx.message.channel.is_private: yield from self.bot.say( "Você não pode executar este comando aqui.") return # Verifica se tem permissão pra remover usuário # permissions = ctx.message.channel.permissions_for( get_member(self.bot, self.bot.user.id, ctx.message.server)) if not permissions.ban_members: yield from self.bot.say( "Não tenho permissão para desbanir usuários neste servidor.") return server = ctx.message.server split = ctx.message.clean_content.split(" ", 1) split.pop(0) ban_users = yield from self.bot.get_bans(server) if len(ban_users) == 0: yield from self.bot.say("Nenhum usuário banido neste servidor.") return usernames = [user.name for user in ban_users] matching_list = [s for s in split if s in usernames] formatted_message = '' matching_id = [] if len(matching_list) == 1: for user in ban_users: matching = [s for s in split if s in user.name] if len(matching) == 1: formatted_message = '{0} desbanido do servidor {1}'.format( user.name, server.name) yield from self.bot.send_message(server.owner, formatted_message) yield from self.bot.unban(server, user) return if len(matching_list) > 1: for i, user in ban_users: formatted_message += '0. Sair\n' matching = [s for s in split if s in user.name] if len(matching) == 1: matching_id.append(i) formatted_message += '{0}. {0.name}\n'.format(i + 1, user) embed = discord.Embed(title='Usuários banidos encontrados', description=formatted_message) yield from self.bot.say(embed) yield from self.bot.say( 'Digite o número do usuário que você quer desbanir.') answer = yield from self.bot.wait_for_message( timeout=60.0, author=ctx.message.author, channel=ctx.message.channel) if answer is None: yield from self.bot.say("Pelo visto você mudou de ideia.") return elif is_numeric(answer.content): answer = int(answer.content) if answer not in matching_id: yield from self.bot.say( "Este número não estava nas possíveis escolhas. Tente novamente." ) return if answer == 0: yield from self.bot.say("Mudou de ideia? Típico.") return try: user = ban_users[answer - 1] except IndexError: yield from self.bot.say( "Este número não estava nas possíveis escolhas. Tente novamente." ) return else: yield from self.bot.say("Resposta inválida.") return yield from self.bot.unban(server, user) return if len(matching_list) == 0: yield from self.bot.say( "Não encontrei usuários banidos com este critério.") return
def set_announce_channel(self, ctx: commands.Context, *, name: str = None): """Changes the channel used for the bot's announcements If no channel is set, the bot will use the server's default channel.""" admin_servers = get_user_admin_servers(self.bot, ctx.message.author.id) if not ctx.message.channel.is_private: if ctx.message.server not in admin_servers: yield from self.bot.say( "You don't have permissions to diagnose this server.") return server = ctx.message.server else: if len(admin_servers) == 1: server = admin_servers[0] else: server_list = [ str(i + 1) + ": " + admin_servers[i].name for i in range(len(admin_servers)) ] yield from self.bot.say( "For which server do you want to change the announce channel?\n\t0: *Cancel*\n\t" + "\n\t".join(server_list)) answer = yield from self.bot.wait_for_message( timeout=60.0, author=ctx.message.author, channel=ctx.message.channel) if answer is None: yield from self.bot.say("I guess you changed your mind.") return elif is_numeric(answer.content): answer = int(answer.content) if answer == 0: yield from self.bot.say( "Changed your mind? Typical human.") return try: server = admin_servers[answer - 1] except IndexError: yield from self.bot.say( "That wasn't in the choices, you ruined it. " "Start from the beginning.") return else: yield from self.bot.say("That's not a valid answer.") return server_id = server.id if name is None: current_channel = announce_channels.get(server_id, None) if current_channel is None: yield from self.bot.say( "This server has no custom channel set, {0} is used.". format(server.default_channel.mention)) else: channel = get_channel_by_name(self.bot, current_channel, server) if channel is not None: permissions = channel.permissions_for( get_member(self.bot, self.bot.user.id, server)) if not permissions.read_messages or not permissions.send_messages: yield from self.bot.say( "This server's announce channel is set to #**{0}** but I don't have " "permissions to use it. {1.mention} will be used instead." .format(current_channel, channel)) return yield from self.bot.say( "This server's announce channel is {0.mention}".format( channel)) else: yield from self.bot.say( "This server's announce channel is set to #**{0}** but it doesn't exist. " "{1.mention} will be used instead.".format( current_channel, server.default_channel)) return if name.lower() in ["clear", "none", "delete", "remove"]: yield from self.bot.say( "Are you sure you want to delete this server's announce channel? `yes/no`\n" "The server's default channel ({0.mention}) will still be used." .format(server.default_channel)) reply = yield from self.bot.wait_for_message( author=ctx.message.author, channel=ctx.message.channel, timeout=50.0) if reply is None: yield from self.bot.say("I guess you changed your mind...") return elif reply.content.lower() not in ["yes", "y"]: yield from self.bot.say("No changes were made then.") return c = userDatabase.cursor() try: c.execute( "DELETE FROM server_properties WHERE server_id = ? AND name = 'announce_channel'", (server_id, )) finally: c.close() userDatabase.commit() yield from self.bot.say( "This server's announce channel was removed.") reload_welcome_messages() return channel = get_channel_by_name(self.bot, name, server) if channel is None: yield from self.bot.say("There is no channel with that name.") return permissions = channel.permissions_for( get_member(self.bot, self.bot.user.id, server)) if not permissions.read_messages or not permissions.send_messages: yield from self.bot.say( "I don't have permission to use {0.mention}.".format(channel)) return yield from self.bot.say( "Are you sure you want {0.mention} as the announcement channel? `yes/no`" .format(channel)) reply = yield from self.bot.wait_for_message( author=ctx.message.author, channel=ctx.message.channel, timeout=120.0) if reply is None: yield from self.bot.say("I guess you changed your mind...") return elif reply.content.lower() not in ["yes", "y"]: yield from self.bot.say("No changes were made then.") return c = userDatabase.cursor() try: # Safer to just delete old entry and add new one c.execute( "DELETE FROM server_properties WHERE server_id = ? AND name = 'announce_channel'", (server_id, )) c.execute( "INSERT INTO server_properties(server_id, name, value) VALUES (?, 'announce_channel', ?)", ( server_id, channel.name, )) yield from self.bot.say( "This server's announcement channel was changed successfully.\nRemember that if " "the channel is renamed, you must set it again using this command.\nIf the channel " "becomes unavailable for me in any way, {0.mention} will be used." .format(server.default_channel)) finally: c.close() userDatabase.commit() reload_announce_channels()
def diagnose(self, ctx: discord.ext.commands.Context, *, server_name=None): """Diagnose the bots permissions and channels""" # This will always have at least one server, otherwise this command wouldn't pass the is_admin check. admin_servers = get_user_admin_servers(self.bot, ctx.message.author.id) if server_name is None: if not ctx.message.channel.is_private: if ctx.message.server not in admin_servers: yield from self.bot.say( "You don't have permissions to diagnose this server.") return server = ctx.message.server else: if len(admin_servers) == 1: server = admin_servers[0] else: server_list = [ str(i + 1) + ": " + admin_servers[i].name for i in range(len(admin_servers)) ] yield from self.bot.say( "Which server do you want to check?\n\t0: *Cancel*\n\t" + "\n\t".join(server_list)) answer = yield from self.bot.wait_for_message( timeout=60.0, author=ctx.message.author, channel=ctx.message.channel) if answer is None: yield from self.bot.say( "I guess you changed your mind.") return elif is_numeric(answer.content): answer = int(answer.content) if answer == 0: yield from self.bot.say( "Changed your mind? Typical human.") return try: server = admin_servers[answer - 1] except IndexError: yield from self.bot.say( "That wasn't in the choices, you ruined it. " "Start from the beginning.") return else: yield from self.bot.say("That's not a valid answer.") return else: server = get_server_by_name(self.bot, server_name) if server is None: yield from self.bot.say( "I couldn't find a server with that name.") return if server not in admin_servers: yield from self.bot.say( "You don't have permissions to diagnose **{0}**.".format( server.name)) return if server is None: return member = get_member(self.bot, self.bot.user.id, server) server_perms = member.server_permissions channels = server.channels not_read_messages = [] not_send_messages = [] not_manage_messages = [] not_embed_links = [] not_attach_files = [] not_mention_everyone = [] not_add_reactions = [] not_read_history = [] count = 0 for channel in channels: if channel.type == discord.ChannelType.voice: continue count += 1 channel_permissions = channel.permissions_for(member) if not channel_permissions.read_messages: not_read_messages.append(channel) if not channel_permissions.send_messages: not_send_messages.append(channel) if not channel_permissions.manage_messages: not_manage_messages.append(channel) if not channel_permissions.embed_links: not_embed_links.append(channel) if not channel_permissions.attach_files: not_attach_files.append(channel) if not channel_permissions.mention_everyone: not_mention_everyone.append(channel) if not channel_permissions.add_reactions: not_add_reactions.append(channel) if not channel_permissions.read_message_history: not_read_history.append(channel) channel_lists_list = [ not_read_messages, not_send_messages, not_manage_messages, not_embed_links, not_attach_files, not_mention_everyone, not_add_reactions, not_read_history ] permission_names_list = [ "Read Messages", "Send Messages", "Manage Messages", "Embed Links", "Attach Files", "Mention Everyone", "Add reactions", "Read Message History" ] server_wide_list = [ server_perms.read_messages, server_perms.send_messages, server_perms.manage_messages, server_perms.embed_links, server_perms.attach_files, server_perms.mention_everyone, server_perms.add_reactions, server_perms.read_message_history ] answer = "Permissions for {0.name}:\n".format(server) i = 0 while i < len(channel_lists_list): answer += "**{0}**\n\t{1} Server wide".format( permission_names_list[i], get_check_emoji(server_wide_list[i])) if len(channel_lists_list[i]) == 0: answer += "\n\t{0} All channels\n".format( get_check_emoji(True)) elif len(channel_lists_list[i]) == count: answer += "\n\t All channels\n".format(get_check_emoji(False)) else: channel_list = ["#" + x.name for x in channel_lists_list[i]] answer += "\n\t{0} Not in: {1}\n".format( get_check_emoji(False), ",".join(channel_list)) i += 1 ask_channel = get_channel_by_name(self.bot, ask_channel_name, server) answer += "\nAsk channel:\n\t" if ask_channel is not None: answer += "{0} Enabled: {1.mention}".format( get_check_emoji(True), ask_channel) else: answer += "{0} Not enabled".format(get_check_emoji(False)) log_channel = get_channel_by_name(self.bot, log_channel_name, server) answer += "\nLog channel:\n\t" if log_channel is not None: answer += "{0} Enabled: {1.mention}".format( get_check_emoji(True), log_channel) else: answer += "{0} Not enabled".format(get_check_emoji(False)) yield from self.bot.say(answer) return
def set_welcome(self, ctx: commands.Context, *, message: str = None): """Changes the messages members get pmed when joining A part of the message is already fixed and cannot be changed, but the message can be extended Say "clear" to clear the current message. The following can be used to get dynamically replaced: {0.name} - The joining user's name {0.server.name} - The name of the server the user joined {0.server.owner.name} - The name of the owner of the server the member joined {0.server.owner.mention} - A mention to the owner of the server {1.user.name} - The name of the bot""" admin_servers = get_user_admin_servers(self.bot, ctx.message.author.id) if not ctx.message.channel.is_private: if ctx.message.server not in admin_servers: yield from self.bot.say( "You don't have permissions to diagnose this server.") return server = ctx.message.server else: if len(admin_servers) == 1: server = admin_servers[0] else: server_list = [ str(i + 1) + ": " + admin_servers[i].name for i in range(len(admin_servers)) ] yield from self.bot.say( "For which server do you want to change the welcome message?\n\t0: *Cancel*\n\t" + "\n\t".join(server_list)) answer = yield from self.bot.wait_for_message( timeout=60.0, author=ctx.message.author, channel=ctx.message.channel) if answer is None: yield from self.bot.say("I guess you changed your mind.") return elif is_numeric(answer.content): answer = int(answer.content) if answer == 0: yield from self.bot.say( "Changed your mind? Typical human.") return try: server = admin_servers[answer - 1] except IndexError: yield from self.bot.say( "That wasn't in the choices, you ruined it. " "Start from the beginning.") return else: yield from self.bot.say("That's not a valid answer.") return server_id = server if message is None: current_message = welcome_messages.get(server_id, None) if current_message is None: current_message = welcome_pm.format(ctx.message.author, self.bot) yield from self.bot.say( "This server has no custom message, joining members get the default message:\n" "----------\n{0}".format(current_message)) else: current_message = (welcome_pm + "\n" + current_message).format( ctx.message.author, self.bot) yield from self.bot.say( "This server has the following welcome message:\n" "----------\n``The first two lines can't be changed``\n{0}" .format(current_message)) return if message.lower() in ["clear", "none", "delete", "remove"]: yield from self.bot.say( "Are you sure you want to delete this server's welcome message? `yes/no`\n" "The default welcome message will still be shown.") reply = yield from self.bot.wait_for_message( author=ctx.message.author, channel=ctx.message.channel, timeout=50.0) if reply is None: yield from self.bot.say("I guess you changed your mind...") return elif reply.content.lower() not in ["yes", "y"]: yield from self.bot.say("No changes were made then.") return c = userDatabase.cursor() try: c.execute( "DELETE FROM server_properties WHERE server_id = ? AND name = 'welcome'", (server_id, )) finally: c.close() userDatabase.commit() yield from self.bot.say( "This server's welcome message was removed.") reload_welcome_messages() return if len(message) > 1200: yield from self.bot.say( "This message exceeds the character limit! ({0}/{1}".format( len(message), 1200)) return try: complete_message = (welcome_pm + "\n" + message).format( ctx.message.author, self.bot) except Exception as e: yield from self.bot.say( "There is something wrong with your message.\n```{0}```". format(e)) return yield from self.bot.say( "Are you sure you want this as your private welcome message?\n" "----------\n``The first two lines can't be changed``\n{0}".format( complete_message)) reply = yield from self.bot.wait_for_message( author=ctx.message.author, channel=ctx.message.channel, timeout=120.0) if reply is None: yield from self.bot.say("I guess you changed your mind...") return elif reply.content.lower() not in ["yes", "y"]: yield from self.bot.say("No changes were made then.") return c = userDatabase.cursor() try: # Safer to just delete old entry and add new one c.execute( "DELETE FROM server_properties WHERE server_id = ? AND name = 'welcome'", (server_id, )) c.execute( "INSERT INTO server_properties(server_id, name, value) VALUES (?, 'welcome', ?)", ( server_id, message, )) yield from self.bot.say( "This server's welcome message has been changed successfully.") finally: c.close() userDatabase.commit() reload_welcome_messages()
def set_world(self, ctx: commands.Context, *, world: str = None): """Sets this server's Tibia world. If no world is passed, it shows this server's current assigned world.""" admin_servers = get_user_admin_servers(self.bot, ctx.message.author.id) if not ctx.message.channel.is_private: if ctx.message.server not in admin_servers: yield from self.bot.say( "You don't have permissions to diagnose this server.") return server = ctx.message.server else: if len(admin_servers) == 1: server = admin_servers[0] else: server_list = [ str(i + 1) + ": " + admin_servers[i].name for i in range(len(admin_servers)) ] yield from self.bot.say( "For which server do you want to change the world?\n\t0: *Cancel*\n\t" + "\n\t".join(server_list)) answer = yield from self.bot.wait_for_message( timeout=60.0, author=ctx.message.author, channel=ctx.message.channel) if answer is None: yield from self.bot.say("I guess you changed your mind.") return elif is_numeric(answer.content): answer = int(answer.content) if answer == 0: yield from self.bot.say( "Changed your mind? Typical human.") return try: server = admin_servers[answer - 1] except IndexError: yield from self.bot.say( "That wasn't in the choices, you ruined it. " "Start from the beginning.") return else: yield from self.bot.say("That's not a valid answer.") return server_id = server.id if world is None: current_world = tracked_worlds.get(server_id, None) if current_world is None: yield from self.bot.say( "This server has no tibia world assigned.") else: yield from self.bot.say( "This server has **{0}** assigned.".format(current_world)) return if world.lower() in ["clear", "none", "delete", "remove"]: yield from self.bot.say( "Are you sure you want to delete this server's tracked world? `yes/no`" ) reply = yield from self.bot.wait_for_message( author=ctx.message.author, channel=ctx.message.channel, timeout=50.0) if reply is None: yield from self.bot.say("I guess you changed your mind...") return elif reply.content.lower() not in ["yes", "y"]: yield from self.bot.say("No changes were made then.") return c = userDatabase.cursor() try: c.execute( "DELETE FROM server_properties WHERE server_id = ? AND name = 'world'", (server_id, )) finally: c.close() userDatabase.commit() yield from self.bot.say( "This server's tracked world has been removed.") reload_worlds() return world = world.strip().capitalize() if world not in tibia_worlds: yield from self.bot.say("There's no world with that name.") return yield from self.bot.say( "Are you sure you want to assign **{0}** to this server? " "Previous worlds will be replaced.".format(world)) reply = yield from self.bot.wait_for_message( author=ctx.message.author, channel=ctx.message.channel, timeout=50.0) if reply is None: yield from self.bot.say("I guess you changed your mind...") return elif reply.content.lower() not in ["yes", "y"]: yield from self.bot.say("No changes were made then.") return c = userDatabase.cursor() try: # Safer to just delete old entry and add new one c.execute( "DELETE FROM server_properties WHERE server_id = ? AND name = 'world'", (server_id, )) c.execute( "INSERT INTO server_properties(server_id, name, value) VALUES (?, 'world', ?)", ( server_id, world, )) yield from self.bot.say( "This server's world has been changed successfully.") finally: c.close() userDatabase.commit() reload_worlds()