def __init__(self, bot: UtilsBot): self.bot = bot self.current_presence = 0 self.update_status.start() self.data = DataHelper() self.colour_guilds = self.bot.mongo.client.misc.colour_guilds self.colour_roles = self.bot.mongo.client.misc.colour_roles
async def members(self, ctx): data = DataHelper() enabled = not data.get("members", False) data["members"] = enabled state = ("Disabled", "Enabled")[enabled] await ctx.reply(embed=self.bot.create_completed_embed("Member Count {}!".format(state), f"Member count logging successfully {state.lower()}"))
def __init__(self, bot: UtilsBot): self.bot = bot self.bot.database_handler = self self.session = aiohttp.ClientSession() self.restarting = False self.data = DataHelper() self.last_update = self.bot.create_processing_embed( "Working...", "Starting processing!") self.last_ping = datetime.datetime.now() self.active_channel_ids = [] self.running = False self.channel_lock = asyncio.Lock() self.update_motw.start() self.bot.loop.create_task(self.startup_check())
async def on_member_join(self, member): if member.guild.id == config.apollo_guild_id and (member.bot and not member.id == self.bot.user.id): await member.ban() return data = DataHelper() await self.on_member_change(member) og_cog: OGCog = self.bot.get_cog("OGCog") try: is_og = await og_cog.is_og(member) print("checking og for {}".format(member.name)) if is_og: print("IS OG!") if data.get("og_roles", {}).get(str(member.guild.id), None) is not None: og_role = member.guild.get_role(data.get("og_roles", {}).get(str(member.guild.id), None)) print("Gotten OG role!") if og_role is not None: await member.add_roles(og_role) print("Added role!") else: print("failed to get og role...") else: print("not og") except AssertionError: pass
def __init__(self): # Initialises the actual commands.Bot class intents = discord.Intents.all() intents.members = True super().__init__(command_prefix=self.determine_prefix, description=config.description, loop=asyncio.get_event_loop(), intents=intents, case_insensitive=True, help_command=PrettyHelp(color=discord.Colour.blue())) self.guild = None self.error_channel = None self.data = DataHelper() self.database_handler = None self.latest_joins = {} self.restart_event: Union[asyncio.Event, None] = None self.mongo: Union[MongoDB, None] = None self.restart_waiter_lock = asyncio.Lock() self.restart_waiters = 0
def __init__(self, bot: UtilsBot): self.bot: UtilsBot = bot self.data = DataHelper()
class Blacklist(commands.Cog): def __init__(self, bot: UtilsBot): self.bot: UtilsBot = bot self.data = DataHelper() @staticmethod def remove_obfuscation(input_string: str): return unidecode(input_string.replace(" ", "")).lower() @commands.command() @is_staff() async def blacklist(self, ctx, *, words: str): words = self.remove_obfuscation(words) all_guilds = self.data.get("blacklist", {}) this_guild_words = all_guilds.get(str(ctx.guild.id), []) if words not in this_guild_words: this_guild_words.append(words) await ctx.reply(embed=self.bot.create_completed_embed("Added!", "Added that word to blacklist.")) else: this_guild_words.remove(words) await ctx.reply(embed=self.bot.create_completed_embed("Removed!", "Removed that word from blacklist.")) all_guilds[str(ctx.guild.id)] = this_guild_words self.data["blacklist"] = all_guilds async def blacklist_check(self, message): def check(m): return m.author.id == config.lexibot_id and m.channel.id == message.channel.id try: await self.bot.wait_for("message", check=check, timeout=0.6) return except asyncio.TimeoutError: pass content = message.content content = self.remove_obfuscation(content) all_guilds = self.data.get("blacklist", {}) this_guild_words = all_guilds.get(str(message.guild.id), []) for word in this_guild_words: if word in content: await message.delete() # sent = await message.channel.send("~warn {} Bad word usage.".format(message.author.mention)) # try: # await self.bot.wait_for("message", check=check, timeout=10) # except asyncio.TimeoutError: # pass # await sent.delete() return @commands.Cog.listener() async def on_message(self, message): if message.guild is None or message.author.bot or is_staff_backend(message.author): return await self.blacklist_check(message) # if message.author.bot: # return # print("running blacklist check...") # if (config.staff_role_id in [role.id for role in message.author.roles] or # message.author.guild_permissions.administrator): # return # contents: str = message.content # print(''.join(filter(str.isalpha, contents))) # if "cantswim" in ''.join(filter(str.isalpha, contents)): # print("it's in...") # await message.delete() @commands.Cog.listener() async def on_message_edit(self, before, after): message = after if message.guild is None or message.author.bot or is_staff_backend(message.author): return await self.blacklist_check(message)
def __init__(self, bot: UtilsBot): self.bot: UtilsBot = bot self.data = DataHelper() self.transport, self.engine = None, None
class Games(commands.Cog): def __init__(self, bot: UtilsBot): self.bot: UtilsBot = bot self.data = DataHelper() self.transport, self.engine = None, None async def connect4_send_to_player(self, player, board: np.array, their_turn): board_embed = discord.Embed(title="Connect Four!", colour=discord.Colour.light_grey()) for array in board: for character in array: board_embed.description += [ config.c4_none, config.c4_red, config.c4_yellow ][character] board_embed.description += "\n" board_embed.add_field(name="Turn", value="It is " + ("NOT ", "")[their_turn] + "your turn!") @commands.command(description="Play connect four!", aliases=["connectfour", "connect_four", "c4"], enabled=False) async def connect4(self, ctx, player2: discord.Member): connect_four_games = self.data.get("ongoing_games", {}).get("connect_four", {}) player1 = ctx.author sorted_ids = sorted([player1.id, player2.id]) combined_id = "{}-{}".format(*sorted_ids) if combined_id in connect_four_games: await ctx.reply(embed=self.bot.create_error_embed( "You already have a connect four game with that person!")) return game_board = np.array([[None] * 6] * 7) @staticmethod def get_kernels(): horizontal_kernel = np.array([[1, 1, 1, 1]]) vertical_kernel = np.transpose(horizontal_kernel) diag1_kernel = np.eye(4, dtype=np.uint8) diag2_kernel = np.fliplr(diag1_kernel) return [horizontal_kernel, vertical_kernel, diag1_kernel, diag2_kernel] async def connect4_check_win(self, board, player_id): detection_kernels = self.get_kernels() for kernel in detection_kernels: if (convolve2d(board == player_id, kernel, mode="valid") == 4).any(): return True return False @commands.command() async def chess_ai(self, ctx, difficulty: str = "easy"): if self.engine is None: print("starting engine...") self.transport, self.engine = await chess.engine.popen_uci( "/usr/games/stockfish") all_games = self.data.get("ongoing_games", {}) chess_games = all_games.get("chess_games", {}) difficulty = difficulty.lower() player = ctx.author if difficulty not in config.chess_difficulties: await ctx.reply(embed=self.bot.create_error_embed( "That difficulty is not available. " "Please choose from the following: " + ", ".join(config.chess_difficulties.keys()))) return for difficulty_level in config.chess_difficulties: if ("{}-{}".format(ctx.author.id, difficulty_level) in chess_games or "{}-{}".format(difficulty_level, ctx.author.id) in chess_games): await ctx.reply(embed=self.bot.create_error_embed( "You already have an AI chess game!")) return new_game = chess.Board() both_ids = [player.id, difficulty] random.shuffle(both_ids) white, black = both_ids game_id = "{}-{}".format(white, black) chess_games[game_id] = new_game.fen() all_games["chess_games"] = chess_games self.data["ongoing_games"] = all_games await self.send_current_board_state(game_id) @commands.command() async def chess(self, ctx, player2: discord.Member): all_games = self.data.get("ongoing_games", {}) chess_games = all_games.get("chess_games", {}) player1 = ctx.author if player2 == player1: await ctx.reply(embed=self.bot.create_error_embed( "You can't play a game against yourself you loner! " "Was \"!chess_ai\" what you meant?")) return possible_id_1 = "{}-{}".format(player1.id, player2.id) possible_id_2 = "{}-{}".format(player2.id, player1.id) if possible_id_1 in chess_games or possible_id_2 in chess_games: await ctx.reply(embed=self.bot.create_error_embed( "You already have a chess game with that person!")) return new_game = chess.Board() both_ids = [player1.id, player2.id] random.shuffle(both_ids) white, black = both_ids game_id = "{}-{}".format(white, black) chess_games[game_id] = new_game.fen() all_games["chess_games"] = chess_games self.data["ongoing_games"] = all_games await self.send_current_board_state(game_id) @staticmethod def get_board_images(board): try: last_move = board.peek() except IndexError: last_move = None player1_oriented_svg = chess.svg.board(board=board, orientation=chess.WHITE, lastmove=last_move) player2_oriented_svg = chess.svg.board(board=board, orientation=chess.BLACK, lastmove=last_move) player1_png = BytesIO() player2_png = BytesIO() svg2png(bytestring=player1_oriented_svg, write_to=player1_png) svg2png(bytestring=player2_oriented_svg, write_to=player2_png) player1_png.seek(0) player2_png.seek(0) player1_file = discord.File(fp=player1_png, filename="image.png") player2_file = discord.File(fp=player2_png, filename="image.png") return player1_file, player2_file async def handle_ai_board_state(self, game_id, board): print("handling board state...") try: player_id = int(game_id.split("-")[0]) difficulty_level = game_id.split("-")[1] ai_colour = chess.BLACK player_file, _ = self.get_board_images(board) except ValueError: player_id = int(game_id.split("-")[1]) difficulty_level = game_id.split("-")[0] _, player_file = self.get_board_images(board) ai_colour = chess.WHITE player = self.bot.get_user(player_id) thinking_message = None if ai_colour == chess.WHITE: embed = discord.Embed( title="Chess Game between {} AI (WHITE) and {} (BLACK)!". format(difficulty_level, player.name)) else: embed = discord.Embed( title="Chess Game between {} (WHITE) and {} AI (BLACK)!". format(player.name, difficulty_level)) embed.colour = discord.Colour.orange() if board.turn == ai_colour: embed.set_footer(text="It's the AI's turn!") embed.set_image(url="attachment://image.png") await player.send(file=player_file, embed=embed) if board.turn == ai_colour: thinking_message = await player.send( embed=self.bot.create_processing_embed( "Thinking...", "The bot is thinking. " "Please wait.")) if self.engine is None: print("starting engine...") self.transport, self.engine = await chess.engine.popen_uci( "/usr/games/stockfish") limit = chess.engine.Limit( time=config.chess_difficulties[difficulty_level]) result = await self.engine.play(board, limit) board.push(result.move) all_games = self.data.get("ongoing_games", {}) chess_games = all_games.get("chess_games", {}) chess_games[game_id] = board.fen() all_games["chess_games"] = chess_games self.data["ongoing_games"] = all_games if await self.check_game_over(game_id): return if ai_colour == chess.BLACK: player_file, _ = self.get_board_images(board) else: _, player_file = self.get_board_images(board) player_embed = discord.Embed( title="Chess Game between {} and {} bot!".format( player.name, difficulty_level), colour=discord.Colour.orange()) player_embed.set_image(url="attachment://image.png") player_embed.set_author(name=game_id) player_embed.set_footer(text="It's your turn to move!") await player.send(file=player_file, embed=player_embed) if thinking_message is not None: await thinking_message.delete() async def send_current_board_state(self, game_id, board=None): chess_games = self.data.get("ongoing_games", {}).get("chess_games", {}) if game_id not in chess_games: return False board_fen = chess_games.get(game_id) if board is None: board = chess.Board(fen=board_fen) try: player1_id, player2_id = [int(x) for x in game_id.split("-")] except ValueError: await self.handle_ai_board_state(game_id, board) return player1 = self.bot.get_user(player1_id) player2 = self.bot.get_user(player2_id) player1_embed = discord.Embed( title="Chess Game between {} and {}!".format( player1.name, player2.name), colour=discord.Colour.orange()) player2_embed = discord.Embed( title="Chess Game between {} and {}!".format( player1.name, player2.name), colour=discord.Colour.orange()) player1_embed.set_author(name=game_id) player2_embed.set_author(name=game_id) player1_embed.set_image(url="attachment://image.png") player2_embed.set_image(url="attachment://image.png") if board.turn == chess.WHITE: player1_embed.set_footer(text="It's your turn to move!") player2_embed.set_footer( text="It's {}'s turn to move!".format(player1.name)) else: player1_embed.set_footer( text="It's {}'s turn to move!".format(player2.name)) player2_embed.set_footer(text="It's your turn to move!") player1_file, player2_file = self.get_board_images(board) await player1.send(file=player1_file, embed=player1_embed) await player2.send(file=player2_file, embed=player2_embed) def mark_win_loss_draw(self, player_id, has_won): all_players = self.data.get("chess_scores", {}) current_player = all_players.get(str(player_id), {}) if has_won is None: draw_score = current_player.get("draws", 0) current_player["draws"] = draw_score + 1 elif has_won == 0: loss_score = current_player.get("losses", 0) current_player["losses"] = loss_score + 1 elif has_won == 1: win_score = current_player.get("wins", 0) current_player["wins"] = win_score + 1 all_players[str(player_id)] = current_player self.data["chess_scores"] = all_players async def ai_game_over(self, game_id, board): try: player_file, _ = self.get_board_images(board) player_id = int(game_id.split("-")[0]) difficulty_level = game_id.split("-")[1] ai_colour = chess.BLACK except ValueError: _, player_file = self.get_board_images(board) player_id = int(game_id.split("-")[1]) difficulty_level = game_id.split("-")[0] ai_colour = chess.WHITE result = board.result() white_points, black_points = result.split("-") player_embed = discord.Embed() player = self.bot.get_user(player_id) if white_points == "1" and ai_colour == chess.BLACK or black_points == "1" and ai_colour == chess.WHITE: player_embed.title = messages.chess_win.format( "{} AI".format(difficulty_level)) player_embed.colour = discord.Colour.green() elif black_points == "1" and ai_colour == chess.BLACK or white_points == "1" and ai_colour == chess.WHITE: player_embed.title = messages.chess_loss.format( "{} AI".format(difficulty_level)) player_embed.colour = discord.Colour.red() else: player_embed.title = messages.chess_draw.format( "{} AI".format(difficulty_level)) player_embed.colour = discord.Colour.blue() player_embed.set_image(url="attachment://image.png") await player.send(file=player_file, embed=player_embed) all_games = self.data.get("ongoing_games", {}) chess_games = all_games.get("chess_games", {}) del chess_games[game_id] all_games["chess_games"] = chess_games self.data["ongoing_games"] = all_games return True async def check_game_over(self, game_id, claiming_draw=False): all_games = self.data.get("ongoing_games", {}) chess_games = all_games.get("chess_games", {}) board = chess.Board(fen=chess_games[game_id]) if not board.is_game_over(claim_draw=claiming_draw): return False try: player1_id, player2_id = [int(x) for x in game_id.split("-")] except ValueError: return await self.ai_game_over(game_id, board) player1 = self.bot.get_user(player1_id) player2 = self.bot.get_user(player2_id) result = board.result() white_points, black_points = result.split("-") player1_embed = discord.Embed() player2_embed = discord.Embed() if white_points == "1": player1_embed.title = messages.chess_win.format(player2.name) player1_embed.colour = discord.Colour.green() player2_embed.title = messages.chess_loss.format(player1.name) player2_embed.colour = discord.Colour.red() self.mark_win_loss_draw(player1_id, 1) self.mark_win_loss_draw(player2_id, 0) elif black_points == "1": player2_embed.title = messages.chess_win.format(player1.name) player2_embed.colour = discord.Colour.green() player1_embed.title = messages.chess_loss.format(player2.name) player1_embed.colour = discord.Colour.red() self.mark_win_loss_draw(player1_id, 0) self.mark_win_loss_draw(player2_id, 1) else: player1_embed.title = messages.chess_draw.format(player2.name) player1_embed.colour = discord.Colour.blue() player2_embed.title = messages.chess_draw.format(player1.name) player2_embed.colour = discord.Colour.blue() self.mark_win_loss_draw(player1_id, None) self.mark_win_loss_draw(player2_id, None) player1_file, player2_file = self.get_board_images(board) player1_embed.set_image(url="attachment://image.png") player2_embed.set_image(url="attachment://image.png") await player1.send(file=player1_file, embed=player1_embed) await player2.send(file=player2_file, embed=player2_embed) del chess_games[game_id] all_games["chess_games"] = chess_games self.data["ongoing_games"] = all_games return True async def handle_move(self, game_id, turn_message, board, move_info): split_into_spaces = move_info.split(" ") try: white_id, black_id = [int(x) for x in game_id.split("-")] player_colour = (chess.WHITE, chess.BLACK)[black_id == turn_message.author.id] except ValueError: try: int(game_id.split("-")[0]) player_colour = chess.WHITE except ValueError: player_colour = chess.BLACK if len(split_into_spaces) == 1: try: square = chess.parse_square(move_info) except ValueError: await turn_message.reply(embed=self.bot.create_error_embed( messages.invalid_chess_square)) return piece = board.piece_at(square) if piece is None or piece.color != player_colour: await turn_message.reply(embed=self.bot.create_error_embed( "That square doesn't contain one of your " "pieces!")) return legal_squares = chess.SquareSet([ move.to_square for move in board.legal_moves if move.from_square == square ]) board_svg = chess.svg.board(board=board, orientation=player_colour, squares=legal_squares) board_png = BytesIO() svg2png(bytestring=board_svg, write_to=board_png) board_png.seek(0) embed = discord.Embed(title="Possible moves for {} at {}".format( chess.piece_name(piece.piece_type), chess.square_name(square))) file = discord.File(fp=board_png, filename="image.png") embed.set_image(url="attachment://image.png") await turn_message.reply(file=file, embed=embed) return else: move_uci = "".join(split_into_spaces) try: move = chess.Move.from_uci(move_uci) except ValueError: await turn_message.reply(embed=self.bot.create_error_embed( "I couldn't interpret that " "as a valid move!")) return if move not in board.legal_moves: if board.is_check(): await turn_message.reply(embed=self.bot.create_error_embed( "That's not a legal move - " "you're in check.")) else: await turn_message.reply(embed=self.bot.create_error_embed( "That move is NOT legal. Make sure " "that's your piece, and a valid move " "for that piece.")) return board.push(move) all_games = self.data.get("ongoing_games", {}) chess_games = all_games.get("chess_games", {}) chess_games[game_id] = board.fen() all_games["chess_games"] = chess_games self.data["ongoing_games"] = all_games if not await self.check_game_over(game_id): await self.send_current_board_state(game_id, board) async def handle_draw(self, game_id, turn_message, board): if not board.can_claim_draw(): await turn_message.reply(embed=self.bot.create_error_embed( "You can't claim a draw at this stage.")) return await self.check_game_over(game_id, claiming_draw=True) async def ai_resign(self, game_id, author, board): try: player_file, _ = self.get_board_images(board) difficulty_level = game_id.split("-")[1] except ValueError: _, player_file = self.get_board_images(board) difficulty_level = game_id.split("-")[0] embed = discord.Embed( title="{} has resigned from the {} vs {} AI chess game.".format( author.name, author.name, difficulty_level), colour=discord.Colour.red()) embed.set_image(url="attachment://image.png") await author.send(file=player_file, embed=embed) async def handle_resign(self, game_id, author, board): all_games = self.data.get("ongoing_games", {}) chess_games = all_games.get("chess_games", {}) del chess_games[game_id] all_games["chess_games"] = chess_games self.data["ongoing_games"] = all_games try: player1_id, player2_id = [int(x) for x in game_id.split("-")] except ValueError: await self.ai_resign(game_id, author, board) return player1 = self.bot.get_user(player1_id) player2 = self.bot.get_user(player2_id) player1_file, player2_file = self.get_board_images(board) embed = discord.Embed( title="{} has resigned from the {} vs {} chess game.".format( author.name, player1.name, player2.name), colour=discord.Colour.red()) embed.set_image(url="attachment://image.png") await player1.send(file=player1_file, embed=embed) await player2.send(file=player2_file, embed=embed) if author.id == player1_id: self.mark_win_loss_draw(player1_id, 0) self.mark_win_loss_draw(player2_id, 1) elif author.id == player2.id: self.mark_win_loss_draw(player1_id, 1) self.mark_win_loss_draw(player2_id, 0) async def give_hint(self, board, turn_message): if self.engine is None: print("starting engine...") self.transport, self.engine = await chess.engine.popen_uci( "/usr/games/stockfish") result = await self.engine.play(board, limit=chess.engine.Limit(time=15)) await turn_message.reply( content="from {} to {} is advised. " "Info: {}".format(chess.square_name(result.move.from_square), chess.square_name(result.move.to_square), result.info)) return async def parse_message(self, game_id, turn_message): chess_games = self.data.get("ongoing_games", {}).get("chess_games", {}) if game_id not in chess_games: return False board_fen = chess_games.get(game_id) board = chess.Board(fen=board_fen) turn_message.content = turn_message.content.lower() turn_command = turn_message.content.partition(" ")[0] turn_command = turn_command try: white_id, black_id = [int(x) for x in game_id.split("-")] if ((turn_message.author.id == white_id and board.turn == chess.BLACK) or (turn_message.author.id == black_id and board.turn == chess.WHITE)): await turn_message.reply( embed=self.bot.create_error_embed("It is not your turn!")) return True except ValueError: pass if turn_command == "move": await self.handle_move(game_id, turn_message, board, turn_message.content.partition("move ")[2]) elif turn_command == "resign": await self.handle_resign(game_id, turn_message.author, board) elif turn_command == "draw": await self.handle_draw(game_id, turn_message, board) elif turn_command == "thomasgo123": await self.give_hint(board, turn_message) else: await turn_message.reply(embed=self.bot.create_error_embed( messages.invalid_chess_command)) return True return True @commands.command() async def chess_stats(self, ctx, member: discord.Member): all_players = self.data.get("chess_scores", {}) current_player = all_players.get(str(member.id), {}) draw_score = current_player.get("draws", 0) loss_score = current_player.get("losses", 0) win_score = current_player.get("wins", 0) embed = discord.Embed( title="Stats for {}!".format(member.name), description="This player has played {} games!".format( sum((draw_score, loss_score, win_score))), colour=discord.Colour.green()) embed.add_field(name="Games Won", value=str(win_score), inline=True) embed.add_field(name="Games Lost", value=str(loss_score), inline=True) embed.add_field(name="Games Drawn", value=str(draw_score), inline=True) embed.set_author(name=member.name, icon_url=member.avatar_url) await ctx.send(embed=embed) async def show_ai_board(self, ctx, player): chess_games = self.data.get("ongoing_games", {}).get("chess_games", {}) game_id = None for difficulty_level in config.chess_difficulties: if "{}-{}".format(player.id, difficulty_level) in chess_games: game_id = "{}-{}".format(player.id, difficulty_level) break if "{}-{}".format(difficulty_level, player.id) in chess_games: game_id = "{}-{}".format(difficulty_level, player.id) break if game_id is None: await ctx.reply( embed=self.bot.create_error_embed("You don't have an AI game!") ) return board = chess.Board(fen=chess_games[game_id]) try: player_file, _ = self.get_board_images(board) difficulty_level = game_id.split("-")[1] ai_colour = chess.BLACK except ValueError: _, player_file = self.get_board_images(board) difficulty_level = game_id.split("-")[0] ai_colour = chess.WHITE if ai_colour == chess.WHITE: embed = discord.Embed( title="Chess Game between {} AI (WHITE) and {} (BLACK)!". format(difficulty_level, player.name)) else: embed = discord.Embed( title="Chess Game between {} (WHITE) and {} AI (BLACK)!". format(player.name, difficulty_level)) embed.colour = discord.Colour.orange() if board.turn == ai_colour: embed.set_footer(text="It's the AI's turn!") else: embed.set_footer(text="It's {}'s turn!".format(player.name)) embed.set_image(url="attachment://image.png") await ctx.send(file=player_file, embed=embed) @commands.command() async def show_board(self, ctx, player1: Optional[discord.User], player2: Optional[discord.User]): if player2 is None: player2 = player1 player1 = ctx.author if player2 is None: await self.show_ai_board(ctx, ctx.author) return if player1 == player2 and player1 is not None: await self.show_ai_board(ctx, player1) return chess_games = self.data.get("ongoing_games", {}).get("chess_games", {}) possible_id_1 = "{}-{}".format(player1.id, player2.id) possible_id_2 = "{}-{}".format(player2.id, player1.id) if possible_id_1 in chess_games: board_fen = chess_games[possible_id_1] game_id = possible_id_1 elif possible_id_2 in chess_games: board_fen = chess_games[possible_id_2] game_id = possible_id_2 else: await ctx.reply(embed=self.bot.create_error_embed( "There is no game between those two members!")) return player1_id, player2_id = [int(x) for x in game_id.split("-")] if player2.id == player1_id: player1, player2 = player2, player1 board = chess.Board(fen=board_fen) rendered_board, _ = self.get_board_images(board) embed = discord.Embed( title="Chess Game between {} (WHITE) and {} (BLACK)!".format( player1.name, player2.name), colour=discord.Colour.orange()) if board.turn == chess.WHITE: embed.set_footer(text="It's {}'s turn!".format( self.bot.get_user(int(game_id.split("-")[0])).name)) else: embed.set_footer(text="It's {}'s turn!".format( self.bot.get_user(int(game_id.split("-")[1])).name)) embed.set_image(url="attachment://image.png") await ctx.send(file=rendered_board, embed=embed) @commands.Cog.listener() async def on_message(self, message): if message.guild is not None or message.author == self.bot.user or message.content.startswith("!") \ or message.content.startswith("u!"): return else: chess_games = self.data.get("ongoing_games", {}).get("chess_games", {}) game_ids = chess_games.keys() players_games = [ x for x in game_ids if str(message.author.id) in x ] if len(players_games) > 1 and message.reference is None: await message.reply(embed=self.bot.create_error_embed( "You have multiple games! Please **reply** to " "the game you're making a move in.")) return elif len(players_games) > 1: referenced_message = await message.channel.fetch_message( message.reference.message_id) if not referenced_message.author == self.bot.user: await message.reply(embed=self.bot.create_error_embed( "That is not a message that I sent!")) return if len(referenced_message.embeds) == 0: await message.reply(embed=self.bot.create_error_embed( "That message has no embeds!")) return embed = referenced_message.embeds[0] if embed.author == discord.Embed.Empty: await message.reply(embed=self.bot.create_error_embed( "That's not a chess message.")) return game_id = embed.author.name elif len(players_games) == 0: await message.reply(embed=self.bot.create_error_embed( "You currently don't have a chess game!")) return else: game_id = players_games[0] if not await self.parse_message(game_id, message): await message.reply(embed=self.bot.create_error_embed( "That game appears to be invalid."))
class Misc(commands.Cog): def __init__(self, bot: UtilsBot): self.bot = bot self.current_presence = 0 self.update_status.start() self.data = DataHelper() self.colour_guilds = self.bot.mongo.client.misc.colour_guilds self.colour_roles = self.bot.mongo.client.misc.colour_roles @commands.command(aliases=["enable_color_change", "enablecolorchange", "enablecolourchange"]) @is_staff() async def enable_colour_change(self, ctx, minimum_role: Optional[discord.Role]): if minimum_role is None: await self.bot.mongo.force_insert(self.colour_guilds, {"_id": ctx.guild.id}) else: await self.bot.mongo.force_insert(self.colour_guilds, {"_id": ctx.guild.id, "minimum_role_id": minimum_role.id}) await ctx.reply(embed=self.bot.create_completed_embed("Set Up Guild", f"{ctx.guild.name} now has self-colour change enabled! " f"Do !colour <colour> (eg !colour red or !colour #ff0000)" f" to change your colour!")) @commands.command(aliases=["color"]) async def colour(self, ctx, new_colour: convert_colour): guild_doc = await self.colour_guilds.find_one({"_id": ctx.guild.id}) if guild_doc is None: await ctx.reply(embed=self.bot.create_error_embed("This guild does not have colour roles enabled! " "Get a staff member to do !enable_colour_change " "to enable it!")) return minimum_role_id = guild_doc.get("minimum_role_id", None) if minimum_role_id is not None: minimum_role = ctx.guild.get_role(minimum_role_id) if minimum_role is None: await ctx.reply(embed=self.bot.create_error_embed("This guild's minimum_role appears to have been " "deleted. Get a staff member to run " "!enable_colour_change")) return if ctx.author.top_role < minimum_role: raise commands.MissingRole(minimum_role) user_doc = await self.colour_roles.find_one({"_id": {"user_id": ctx.author.id, "guild_id": ctx.guild.id}}) changing_role = None if user_doc is not None: changing_role = ctx.guild.get_role(user_doc.get("role_id")) else: user_doc = {"_id": {"user_id": ctx.author.id, "guild_id": ctx.guild.id}} done = False if changing_role is None: for role in ctx.guild.roles: if role.name == str(ctx.author.id): changing_role = role if changing_role is None: ideal_position = 0 for role in ctx.author.roles: if role.colour != discord.Colour.default(): ideal_position = role.position + 1 if ideal_position >= ctx.guild.me.top_role.position: await ctx.reply("My role isn't high enough to make this role your top coloured role, " "so it may not instantly re-colour your name!") changing_role = await ctx.guild.create_role(name=ctx.author.id, colour=new_colour, reason=f"Custom colour role for {ctx.author.name}") done = True if not done: try: await changing_role.edit(colour=new_colour) except discord.errors.Forbidden: await ctx.reply(embed=self.bot.create_error_embed("My role isn't high enough to edit your " "colour role.")) return await ctx.author.add_roles(changing_role, reason="Added custom colour role.") user_doc["role_id"] = changing_role.id await self.bot.mongo.force_insert(self.colour_roles, user_doc) await ctx.reply(embed=self.bot.create_completed_embed("Added role!", "Added your colour role!")) @commands.command(aliases=["disable_color_change", "disablecolorchange", "disablecolourchange"]) @is_staff() async def disable_colour_change(self, ctx): await self.colour_guilds.delete_one({"_id": ctx.guild.id}) await ctx.reply(embed=self.bot.create_completed_embed("Disabled Guild", f"{ctx.guild.name} now has self-colour change disabled.\n" f"Any already created roles will remain.")) @commands.command(pass_context=True) @is_staff() async def embed(self, ctx, colour: Optional[convert_colour] = discord.Colour.default(), title: str = '\u200b', description: str = '\u200b', *fields): embed = discord.Embed(colour=colour, title=title, description=description, timestamp=datetime.datetime.utcnow()) embed.set_author(name=ctx.message.author.name, icon_url=ctx.message.author.avatar_url) if len(fields) % 2 != 0: await ctx.reply(embed=self.bot.create_error_embed("Fields were not even.")) return for i in range(0, len(fields), 2): embed.add_field(name=fields[i], value=fields[i + 1], inline=False) await ctx.reply(embed=embed) await ctx.message.delete(delay=5) @commands.command(name="error_channel", description="Sets the bot error message channel for this guild.") @is_owner() async def error_channel(self, ctx, error_channel: discord.TextChannel): data = DataHelper() error_channels = data.get("guild_error_channels", {}) error_channels[str(ctx.guild.id)] = error_channel.id data["guild_error_channels"] = error_channels @commands.command() @is_high_staff() async def oldest(self, ctx): if self.bot.latest_joins == {}: await self.bot.get_latest_joins() members = self.bot.latest_joins[ctx.guild.id] leader_board = "" for index, member in enumerate(members): string_to_add = "{}: {} - {}\n".format(index + 1, member.name, member.joined_at.strftime("%Y-%m-%d %H:%M")) if len(leader_board + string_to_add) > 2048: break leader_board = leader_board + string_to_add embed = discord.Embed(title="First Join Leaderboard", colour=discord.Colour.green(), description=leader_board) await ctx.reply(embed=embed) @commands.command(pass_context=True) @is_high_staff() async def members(self, ctx): data = DataHelper() enabled = not data.get("members", False) data["members"] = enabled state = ("Disabled", "Enabled")[enabled] await ctx.reply(embed=self.bot.create_completed_embed("Member Count {}!".format(state), f"Member count logging successfully {state.lower()}")) @commands.command() @is_owner() async def split_up(self, ctx): message: discord.Message = ctx.message if len(message.attachments) != 1: await ctx.reply(embed=self.bot.create_error_embed("There wasn't 1 file in that message.")) return attachment = message.attachments[0] if attachment.filename[-4:].lower() != ".txt": await ctx.reply(embed=self.bot.create_error_embed("I can only do text files.")) return text_file = BytesIO() await attachment.save(text_file) text_file.seek(0) full_text = text_file.read().decode() while len(full_text) > 2000: newline_indices = [m.end() for m in re.finditer("\n", full_text[:2000])] if len(newline_indices) == 0: to_send = full_text[:2000] full_text = full_text[2000:] else: to_send = full_text[:newline_indices[-1]] full_text = full_text[newline_indices[-1]:] await ctx.send(to_send) if len(full_text) > 0: await ctx.send(content=full_text) async def update_members_vc(self): users_vc: discord.VoiceChannel = self.bot.get_channel(727202196600651858) data = DataHelper() if data["members"]: guild_members = users_vc.guild.member_count await users_vc.edit(name="Total Users: {}".format(guild_members)) async def on_member_change(self, member): print("processing member change") guild = member.guild if guild.id == config.monkey_guild_id: await self.update_members_vc() self.bot.latest_joins[guild.id] = await self.bot.get_sorted_members(guild) @commands.Cog.listener() async def on_member_join(self, member): if member.guild.id == config.apollo_guild_id and (member.bot and not member.id == self.bot.user.id): await member.ban() return data = DataHelper() await self.on_member_change(member) og_cog: OGCog = self.bot.get_cog("OGCog") try: is_og = await og_cog.is_og(member) print("checking og for {}".format(member.name)) if is_og: print("IS OG!") if data.get("og_roles", {}).get(str(member.guild.id), None) is not None: og_role = member.guild.get_role(data.get("og_roles", {}).get(str(member.guild.id), None)) print("Gotten OG role!") if og_role is not None: await member.add_roles(og_role) print("Added role!") else: print("failed to get og role...") else: print("not og") except AssertionError: pass @commands.Cog.listener() async def on_member_remove(self, member): await self.on_member_change(member) @tasks.loop(seconds=30, count=None) async def update_status(self): memory = psutil.virtual_memory() free = memory.available // (1024 ** 2) total = memory.total // (1024 ** 2) used = total - free possible_presences = ["Current CPU load: {}%!".format(psutil.cpu_percent(None)), "Current RAM usage: {}MB/{}MB.".format(used, total), "Total guild count: {}!".format(len(self.bot.guilds)), "Owner: ThomasW#1707"] activity = discord.Game(name=possible_presences[self.current_presence]) self.current_presence += 1 if self.current_presence > len(possible_presences) - 1: self.current_presence = 0 await self.bot.change_presence(status=discord.Status.online, activity=activity) @commands.command() @is_staff() async def poll(self, ctx, *, poll_info): polls = self.data.get("polls", {}) if str(ctx.channel.id) in polls: await ctx.reply(embed=self.bot.create_error_embed(f"There's already a poll in this channel! \n" f"Do {config.bot_prefix}endpoll to end it!")) return embed = self.bot.create_completed_embed("Poll", poll_info) embed.set_author(name=ctx.author.name, icon_url=ctx.author.avatar_url) embed.timestamp = datetime.datetime.now() sent: discord.Message = await ctx.reply(embed=embed) await sent.add_reaction(emoji="✅") await sent.add_reaction(emoji="❌") polls[str(ctx.channel.id)] = sent.id self.data["polls"] = polls @commands.command() @is_staff() async def endpoll(self, ctx): polls = self.data.get("polls", {}) if str(ctx.channel.id) not in polls: await ctx.reply(embed=self.bot.create_error_embed(f"There's not already a poll in this channel! \n" f"Do {config.bot_prefix}poll to start one!")) return message_id = polls.pop(str(ctx.channel.id)) self.data["polls"] = polls try: message: discord.Message = await ctx.channel.fetch_message(message_id) assert message is not None except (discord.HTTPException, AssertionError): await ctx.reply(embed=self.bot.create_error_embed(f"The previous poll in this channel was deleted.")) return plus_reactions = [reaction for reaction in message.reactions if reaction.emoji == "✅"][0].count - 1 negative_reactions = [reaction for reaction in message.reactions if reaction.emoji == "❌"][0].count - 1 colour = (discord.Colour.red(), discord.Colour.green())[plus_reactions >= negative_reactions] if plus_reactions == negative_reactions: colour = discord.Colour.orange() if plus_reactions + negative_reactions != 0: positive_amount = round((plus_reactions / (plus_reactions + negative_reactions)) * 100, 1) else: positive_amount = "N/A" embed = discord.Embed( colour=colour, title="Poll Results", description=f"Poll: \"{message.embeds[0].description}\" " f"has finished!\n" f"It was {positive_amount}% positive!") embed.add_field(name="✅", value=plus_reactions, inline=True) embed.add_field(name="❌", value=negative_reactions, inline=True) await message.reply(embed=embed) embed = message.embeds[0] embed.title = "This poll has closed." embed.colour = discord.Colour.red() await message.edit(embed=embed) @commands.command() async def choose(self, ctx, *choices): await ctx.reply(embed=self.bot.create_completed_embed("Random Choice", f"I choose {random.choice(choices)}")) @commands.command(aliases=["exec"]) @is_owner() async def execute(self, ctx, *, code): author = ctx.message.author tmp_dic = {} executing_string = format_execute(ctx.message.content) print(executing_string) exec(executing_string, {**globals(), **locals()}, tmp_dic) print(tmp_dic) print(tmp_dic['temp_func']) function = tmp_dic['temp_func'] await function()
async def update_members_vc(self): users_vc: discord.VoiceChannel = self.bot.get_channel(727202196600651858) data = DataHelper() if data["members"]: guild_members = users_vc.guild.member_count await users_vc.edit(name="Total Users: {}".format(guild_members))
async def error_channel(self, ctx, error_channel: discord.TextChannel): data = DataHelper() error_channels = data.get("guild_error_channels", {}) error_channels[str(ctx.guild.id)] = error_channel.id data["guild_error_channels"] = error_channels