def info_server(ctx): """Mostra informações do servidor.""" permissions = ctx.message.channel.permissions_for(get_member(bot, bot.user.id, ctx.message.server)) if not permissions.embed_links: yield from bot.say("Sorry, I need `Embed Links` permission for this command.") return embed = discord.Embed() _server = ctx.message.server # type: discord.Server embed.set_thumbnail(url=_server.icon_url) embed.description = _server.name # Check if owner has a nickname if _server.owner.name == _server.owner.display_name: owner = "{0.name}#{0.discriminator}".format(_server.owner) else: owner = "{0.display_name}\n({0.name}#{0.discriminator})".format(_server.owner) embed.add_field(name="Dono", value=owner) embed.add_field(name="Criado", value=_server.created_at.strftime("%d/%m/%y")) embed.add_field(name="Região do Servidor", value=get_region_string(_server.region)) # Channels text_channels = 0 for channel in _server.channels: if channel.type == discord.ChannelType.text: text_channels += 1 voice_channels = len(_server.channels) - text_channels embed.add_field(name="Canais de texto", value=text_channels) embed.add_field(name="Canais de voz", value=voice_channels) embed.add_field(name="Membros", value=_server.member_count) embed.add_field(name="Cargos", value=len(_server.roles)) embed.add_field(name="Emojis", value=len(_server.emojis)) embed.add_field(name="Bot entrou", value=_server.me.joined_at.strftime("%d/%m/%y")) yield from bot.say(embed=embed)
def refresh_names(self, ctx): """Checks and updates user names on the database.""" if not ctx.message.channel.is_private: return True c = userDatabase.cursor() try: c.execute("SELECT id FROM users") result = c.fetchall() if len(result) <= 0: yield from self.bot.say("There are no registered users.") return update_users = list() for user in result: update_users.append( ("unknown" if get_member(self.bot, user[0]) is None else get_member(self.bot, user[0]).display_name, user["id"])) c.executemany("UPDATE users SET name = ? WHERE id LIKE ?", update_users) yield from self.bot.say("Usernames updated successfully.") finally: c.close() userDatabase.commit()
def about(ctx): """Mostra informações do bot""" permissions = ctx.message.channel.permissions_for(get_member(bot, bot.user.id, ctx.message.server)) if not permissions.embed_links: yield from bot.say("Foi mal, eu preciso de permissões de `Embed Links` para executar este comando.") return embed = discord.Embed(description="*SCRIPTS SCRIPTS SCRIPTS*. Eu vou cobrar todo mundo!") embed.set_author(name="Monkey Slave", url="https://github.com/rodrigokiller/MonkeyBot", icon_url="https://assets-cdn.github.com/favicon.ico") embed.add_field(name="Autor", value="@Killer#9093") embed.add_field(name="Plataforma", value="Python " + EMOJI[":snake:"]) embed.add_field(name="Criado", value="July 01th 2017") embed.add_field(name="Servidores", value="{0:,}".format(len(bot.servers))) embed.add_field(name="Membros", value="{0:,}".format(len(set(bot.get_all_members())))) embed.add_field(name="Tempo", value=get_uptime()) memory_usage = psutil.Process().memory_full_info().uss / 1024 ** 2 embed.add_field(name='Uso de Memória', value='{:.2f} MiB'.format(memory_usage)) yield from bot.say(embed=embed)
def remove_char(self, ctx, *, name): """Removes a registered character. The syntax is: /stalk removechar name""" if not ctx.message.channel.is_private: return True # This could be used to remove deleted chars so we don't need to check anything # Except if the char exists in the database... yield from self.bot.send_typing(ctx.message.channel) c = userDatabase.cursor() try: c.execute( "SELECT name, user_id, world, ABS(last_level) as level, vocation " "FROM chars WHERE name LIKE ?", (name, )) result = c.fetchone() if result is None: yield from self.bot.say( "There's no character with that name registered.") return user = get_member(self.bot, result["user_id"]) username = "******" if user is None else user.display_name c.execute("DELETE FROM chars WHERE name LIKE ?", (name, )) yield from self.bot.say( "**{0}** was removed successfully from **@{1}**.".format( result["name"], username)) if user is not None: for server in get_user_servers(self.bot, user.id): world = tracked_worlds.get(server.id, None) if world != result["world"]: continue log_msg = "{0.mention} removed **{1}** ({2} {3}) from {4.mention}.".\ format(ctx.message.author, result["name"], result["level"], result["vocation"], user) yield from send_log_message(self.bot, server, log_msg) return finally: c.close() userDatabase.commit()
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 purge(self, ctx): """Performs a database cleanup Removes characters that have been deleted and users with no characters or no longer in server.""" if not ctx.message.channel.is_private: return True c = userDatabase.cursor() try: c.execute("SELECT id FROM users") result = c.fetchall() if result is None: yield from self.bot.say("There are no users registered.") return delete_users = list() yield from self.bot.say("Initiating purge...") # Deleting users no longer in server for row in result: user = get_member(self.bot, row["id"]) if user is None: delete_users.append((row["id"], )) if len(delete_users) > 0: c.executemany("DELETE FROM users WHERE id = ?", delete_users) yield from self.bot.say( "{0} user(s) no longer in the server were removed.".format( c.rowcount)) # Deleting chars with non-existent user c.execute( "SELECT name FROM chars WHERE user_id NOT IN (SELECT id FROM users)" ) result = c.fetchall() if len(result) >= 1: chars = ["**" + i["name"] + "**" for i in result] reply = "{0} char(s) were assigned to a non-existent user and were deleted:\n\t".format( len(result)) reply += "\n\t".join(chars) yield from self.bot.say(reply) c.execute( "DELETE FROM chars WHERE user_id NOT IN (SELECT id FROM users)" ) # Removing deleted chars c.execute("SELECT name,last_level,vocation FROM chars") result = c.fetchall() if result is None: return delete_chars = list() rename_chars = list() # revoc_chars = list() for row in result: char = yield from get_character(row["name"]) if char == ERROR_NETWORK: yield from self.bot.say( "Couldn't fetch **{0}**, skipping...".format( row["name"])) continue # Char was deleted if char == ERROR_DOESNTEXIST: delete_chars.append((row["name"], )) yield from self.bot.say( "**{0}** doesn't exists, deleting...".format( row["name"])) continue # Char was renamed if char['name'] != row["name"]: rename_chars.append(( char['name'], row["name"], )) yield from self.bot.say( "**{0}** was renamed to **{1}**, updating...".format( row["name"], char['name'])) # No need to check if user exists cause those were removed already if len(delete_chars) > 0: c.executemany("DELETE FROM chars WHERE name LIKE ?", delete_chars) yield from self.bot.say("{0} char(s) were removed.".format( c.rowcount)) if len(rename_chars) > 0: c.executemany("UPDATE chars SET name = ? WHERE name LIKE ?", rename_chars) yield from self.bot.say("{0} char(s) were renamed.".format( c.rowcount)) # Remove users with no chars c.execute( "SELECT id FROM users WHERE id NOT IN (SELECT user_id FROM chars)" ) result = c.fetchall() if len(result) >= 1: c.execute( "DELETE FROM users WHERE id NOT IN (SELECT user_id FROM chars)" ) yield from self.bot.say( "{0} user(s) with no characters were removed.".format( c.rowcount)) # Remove level ups of removed characters c.execute( "DELETE FROM char_levelups WHERE char_id NOT IN (SELECT id FROM chars)" ) if c.rowcount > 0: yield from self.bot.say( "{0} level up registries from removed characters were deleted." .format(c.rowcount)) c.execute( "DELETE FROM char_deaths WHERE char_id NOT IN (SELECT id FROM chars)" ) # Remove deaths of removed characters if c.rowcount > 0: yield from self.bot.say( "{0} death registries from removed characters were deleted." .format(c.rowcount)) yield from self.bot.say("Purge done.") return finally: userDatabase.commit() c.close()
def remove_user(self, ctx, *, name): """Removes a discord user from the database The syntax is: /stalk remove name""" if not ctx.message.channel.is_private: return True c = userDatabase.cursor() yield from self.bot.send_typing(ctx.message.channel) # Searching users in server user = get_member_by_name(self.bot, name) # Searching users in database try: c.execute("SELECT id, name from users WHERE name LIKE ?", (name, )) result = c.fetchone() # Users in database and not in servers if result is not None and get_member(self.bot, result['id']) is None: yield from self.bot.say( "**@{0}** was no longer in server and was removed successfully." .format(result["name"])) delete_id = result["id"] # User in servers and in database elif user is not None and result is not None: yield from self.bot.say( "**{0}** was removed successfully.".format( user.display_name)) delete_id = user.id # User in server but not in database elif user is not None and result is None: yield from self.bot.say("**{0}** is not registered.".format( user.display_name)) return # User not in server or database else: yield from self.bot.say( "I don't see any user named **{0}**.".format(name)) return c.execute("DELETE FROM users WHERE id = ?", (delete_id, )) c.execute("SELECT name FROM chars WHERE user_id = ?", (delete_id, )) result = c.fetchall() if len(result) >= 1: chars = ["**" + i["name"] + "**" for i in result] reply = "The following characters were registered to the user:\n\t" reply += "\n\t".join(chars) reply += "\nDo you want to delete them? ``(yes/no)``" yield from self.bot.say(reply) 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( "I will take your silence as a no...") elif answer.content.lower() in ["yes", "y"]: c.execute("DELETE FROM chars WHERE user_id = ?", (delete_id, )) yield from self.bot.say("Characters deleted successfully.") else: yield from self.bot.say("Ok, we are done then.") return finally: c.close() userDatabase.commit()
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 add_account(self, ctx, *, params): """Register a character and all other visible characters to a discord user. If a character is hidden, only that character will be added. Characters in other worlds are skipped. The syntax is the following: /stalk addacc user,char""" if not ctx.message.channel.is_private: return True params = params.split(",") if len(params) != 2: yield from self.bot.say( "The correct syntax is: ``/stalk addacc username,character``") return author = ctx.message.author if author.id in mod_ids + owner_ids: author_servers = get_user_servers(self.bot, author.id) else: author_servers = get_user_admin_servers(self.bot, author.id) author_worlds = get_user_worlds(self.bot, author.id) user = get_member_by_name(self.bot, params[0], server_list=author_servers) user_servers = get_user_servers(self.bot, user.id) user_worlds = get_user_worlds(self.bot, user.id) common_worlds = list(set(author_worlds) & set(user_worlds)) yield from self.bot.send_typing(ctx.message.channel) character = yield from get_character(params[1]) if user is None: yield from self.bot.say( "I don't see any user named **{0}** in the servers you manage." .format(params[0])) return if type(character) is not dict: if character == ERROR_NETWORK: yield from self.bot.say( "I couldn't fetch the character, please try again.") elif character == ERROR_DOESNTEXIST: yield from self.bot.say("That character doesn't exists.") return c = userDatabase.cursor() try: chars = character['chars'] # If the char is hidden,we still add the searched character if len(chars) == 0: yield from self.bot.say("Character is hidden.") chars = [character] skipped = list() added = list() added_tuples = list() reassigned_tuples = list() existent = list() error = list() for char in chars: # Character not in followed server(s), skip. if char['world'] not in common_worlds: skipped.append([char["name"], char["world"]]) continue name = char["name"] # If char is the same we already looked up, no need to look him up again if character["name"] == char["name"]: char = character else: char = yield from get_character(char["name"]) if type(char) is not dict: error.append(name) continue # Skip characters scheduled for deletion if char.get("deleted", False): skipped.append([char["name"], char["world"]]) continue c.execute( "SELECT id, name,user_id FROM chars WHERE name LIKE ?", (char['name'], )) result = c.fetchone() # Char is already in database if result is not None: # Registered to different user if str(result["user_id"]) != user.id: current_user = get_member(self.bot, result["user_id"]) # Char is registered to user no longer in server if current_user is None: added.append(char) reassigned_tuples.append(( user.id, result["id"], )) continue else: yield from self.bot.say( "{0} is already assigned to {1}. We can't add any other of these " "characters.".format( char["name"], current_user.display_name)) return # Registered to current user existent.append(char) continue added.append(char) added_tuples.append(( char["name"], char["level"] * -1, char["vocation"], user.id, char["world"], )) c.execute("SELECT id from users WHERE id = ?", (user.id, )) result = c.fetchone() if result is None: c.execute("INSERT INTO users(id,name) VALUES (?,?)", ( user.id, user.display_name, )) c.executemany( "INSERT INTO chars(name,last_level,vocation,user_id, world) VALUES (?,?,?,?,?)", added_tuples) c.executemany("UPDATE chars SET user_id = ? WHERE id = ?", reassigned_tuples) reply = "" log_reply = dict().fromkeys([server.id for server in user_servers], "") if added: reply += "\nThe following characters were registered or reassigned successfully:" for char in added: char["guild"] = char.get("guild", "No guild") reply += "\n\t**{name}** ({level} {vocation}) - **{guild}**".format( **char) # Announce on server log of each server for server in user_servers: # Only announce on worlds where the character's world is tracked if tracked_worlds.get(server.id, None) == char["world"]: log_reply[ server. id] += "\n\t{name} - {level} {vocation} - **{guild}**".format( **char) if existent: reply += "\nThe following characters were already registered to this user:"******"guild"] = char.get("guild", "No guild") reply += "\n\t**{name}** ({level} {vocation}) - **{guild}**".format( **char) if skipped: reply += "\nThe following characters were skipped (not in tracked worlds or scheduled deletion):" for char, world in skipped: reply += "\n\t{0} ({1})".format(char, world) if error: reply += "\nThe following characters couldn't be fetched: " reply += ", ".join(error) yield from self.bot.say(reply) for server_id, message in log_reply.items(): if message: message = "{0.mention} registered the following characters to {1.mention}: {2}".format( author, user, message) yield from send_log_message(self.bot, self.bot.get_server(server_id), message) return finally: c.close() userDatabase.commit()
def add_char(self, ctx, *, params): """Registers a tibia character to a discord user. The syntax is: /stalk addchar user,character""" if not ctx.message.channel.is_private: return True params = params.split(",") if len(params) != 2: yield from self.bot.say( "The correct syntax is: ``/stalk addchar username,character``") return author = ctx.message.author if author.id in mod_ids + owner_ids: author_servers = get_user_servers(self.bot, author.id) else: author_servers = get_user_admin_servers(self.bot, author.id) author_worlds = get_user_worlds(self.bot, author.id) # Only search in the servers the command author is user = get_member_by_name(self.bot, params[0], server_list=author_servers) user_servers = get_user_servers(self.bot, user.id) user_worlds = get_user_worlds(self.bot, author.id) common_worlds = list(set(author_worlds) & set(user_worlds)) yield from self.bot.send_typing(ctx.message.channel) char = yield from get_character(params[1]) if user is None: yield from self.bot.say( "I don't see any user named **{0}** in the servers you manage." .format(params[0])) return if type(char) is not dict: if char == ERROR_NETWORK: yield from self.bot.say( "I couldn't fetch the character, please try again.") elif char == ERROR_DOESNTEXIST: yield from self.bot.say("That character doesn't exists.") return if char["world"] not in common_worlds: yield from self.bot.say( "**{name}** ({world}) is not in a world you can manage.". format(**char)) return if char.get("deleted", False): yield from self.bot.say( "**{name}** ({world}) is scheduled for deletion and can't be added." .format(**char)) return c = userDatabase.cursor() try: c.execute("SELECT id, name, user_id FROM chars WHERE name LIKE ?", (char['name'], )) result = c.fetchone() # Char is already in database if result is not None: # Update name if it was changed if char['name'] != params[1]: c.execute("UPDATE chars SET name = ? WHERE id = ?", ( char['name'], result["id"], )) yield from self.bot.say( "This character's name was changed from **{0}** to **{1}**" .format(params[1], char['name'])) # Registered to a different user if result["user_id"] != user.id: current_user = get_member(self.bot, result["user_id"]) # User no longer in server if current_user is None: c.execute("UPDATE chars SET user_id = ? WHERE id = ?", ( user.id, result["id"], )) yield from self.bot.say( "This character was registered to a user no longer in server. " "It was assigned to this user successfully.") # Log on relevant servers for server in user_servers: world = tracked_worlds.get(server.id, None) if world == char["world"]: log_msg = "{0.mention} registered **{1}** ({2} {3}) to {4.mention}." yield from send_log_message( self.bot, server, log_msg.format(author, char["name"], char["level"], char["vocation"], user)) else: yield from self.bot.say( "This character is already registered to **@{0}**". format(current_user.display_name)) return # Registered to current user yield from self.bot.say( "This character is already registered to this user.") return c.execute( "INSERT INTO chars (name,last_level,vocation,user_id, world) VALUES (?,?,?,?,?)", (char["name"], char["level"] * -1, char["vocation"], user.id, char["world"])) # Check if user is already registered c.execute("SELECT id from users WHERE id = ?", (user.id, )) result = c.fetchone() if result is None: c.execute("INSERT INTO users(id,name) VALUES (?,?)", ( user.id, user.display_name, )) yield from self.bot.say( "**{0}** was registered successfully to this user.".format( char['name'])) # Log on relevant servers for server in user_servers: world = tracked_worlds.get(server.id, None) if world == char["world"]: char["guild"] = char.get("guild", "No guild") log_msg = "{0.mention} registered **{1}** ({2} {3}, {4}) to {5.mention}." yield from send_log_message( self.bot, server, log_msg.format(author, char["name"], char["level"], char["vocation"], char["guild"], user)) return finally: c.close() userDatabase.commit()
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 ban(self, ctx: commands.Context, *, message: str = None): """Bane um usuário Deve ser passado um (ou mais) @usuario(s) como parâmetro.""" # 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 banir usuários neste servidor.") return server = ctx.message.server split = ctx.message.clean_content.split(" ", 1) split.pop(0) motivo = '' for i in split: motivo += i + ' ' for member in ctx.message.mentions: # Busca maior role do membro member_pos = 0 for role in member.roles: if role.position > member_pos: member_pos = role.position # Busca mamior role do bot bot_pos = 0 for role in server.get_member(self.bot.user.id).roles: if role.position > bot_pos: bot_pos = role.position # Verifica se a role do usuário é menor que a role do bot if member_pos > bot_pos: yield from self.bot.say( "Não tenho permissão para banir o usuário {0} deste servidor." .format(member.name)) # Verifica se o usuário faz parate dos admins ou mods elif member.id in owner_ids or member.id in mod_ids: yield from self.bot.say( "Não tenho permissão para banir o usuário {0} deste servidor." .format(member.name)) elif member.id == self.bot.user.id: yield from self.bot.say( "Desculpe, mas não irei obedecer. Se você quiser me banir, faça você mesmo." .format(member.name)) else: motivo = motivo.replace('@{0}'.format(member.name), '').replace(' ', '') formatted_message = '{0} banido.'.format(member.name) #if len(motivo)> 0: #formatted_message += ' Motivo: {0}'.format(motivo) yield from self.bot.send_message(member, formatted_message) yield from self.bot.send_message(server.owner, formatted_message) yield from self.bot.send_message(ctx.message.channel, formatted_message) yield from self.bot.ban(member, 0) 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