diff --git a/reginaldCog/blacklist.py b/reginaldCog/blacklist.py new file mode 100644 index 0000000..10fd834 --- /dev/null +++ b/reginaldCog/blacklist.py @@ -0,0 +1,44 @@ +from redbot.core import commands +import discord + +class BlacklistMixin: + """Handles user blacklisting for Reginald.""" + + async def is_blacklisted(self, user: discord.Member) -> bool: + """Checks if a user is blacklisted from interacting with Reginald.""" + blacklisted_users = await self.config.guild(user.guild).blacklisted_users() + return str(user.id) in blacklisted_users + + @commands.command(name="reginald_blacklist", help="List users who are explicitly denied access to Reginald.") + @commands.has_permissions(administrator=True) + async def list_blacklisted_users(self, ctx): + """Lists all users currently blacklisted from interacting with Reginald.""" + blacklisted_users = await self.config.guild(ctx.guild).blacklisted_users() + if not blacklisted_users: + await ctx.send("✅ No users are currently blacklisted from interacting with Reginald.") + return + + user_mentions = [f"<@{user_id}>" for user_id in blacklisted_users] + await ctx.send(f"🚫 **Blacklisted Users:**\n{', '.join(user_mentions)}") + + @commands.command(name="reginald_blacklist_add", help="Blacklist a user from interacting with Reginald.") + @commands.has_permissions(administrator=True) + async def add_to_blacklist(self, ctx, user: discord.User): + """Adds a user to Reginald's blacklist.""" + async with self.config.guild(ctx.guild).blacklisted_users() as blacklisted_users: + if str(user.id) not in blacklisted_users: + blacklisted_users.append(str(user.id)) + await ctx.send(f"🚫 {user.display_name} has been **blacklisted** from interacting with Reginald.") + else: + await ctx.send(f"⚠️ {user.display_name} is already blacklisted.") + + @commands.command(name="reginald_blacklist_remove", help="Remove a user from Reginald's blacklist.") + @commands.has_permissions(administrator=True) + async def remove_from_blacklist(self, ctx, user: discord.User): + """Removes a user from Reginald's blacklist.""" + async with self.config.guild(ctx.guild).blacklisted_users() as blacklisted_users: + if str(user.id) in blacklisted_users: + blacklisted_users.remove(str(user.id)) + await ctx.send(f"✅ {user.display_name} has been removed from the blacklist.") + else: + await ctx.send(f"⚠️ {user.display_name} was not on the blacklist.") diff --git a/reginaldCog/chess_addon.py b/reginaldCog/chess_addon.py deleted file mode 100644 index ccfdd68..0000000 --- a/reginaldCog/chess_addon.py +++ /dev/null @@ -1,98 +0,0 @@ -import chess -import chess.svg -import io -from cairosvg import svg2png -import discord - -class ChessHandler: - def __init__(self): - self.active_games = {} # {user_id: FEN string} - - async def set_board(self, user_id: str, fen: str): - """Sets a board to a given FEN string for a user and saves it in long-term memory.""" - try: - board = chess.Board(fen) # Validate FEN - self.active_games[user_id] = fen - - async with self.config.guild(ctx.guild).long_term_profiles() as long_memory: - long_memory[user_id] = {"fen": fen} # Store in long-term memory - - return f"Board state updated successfully:\n```{fen}```" - except ValueError: - return "⚠️ Invalid FEN format. Please provide a valid board state." - - def reset_board(self, user_id: str): - """Resets a user's board to the standard starting position.""" - self.active_games[user_id] = chess.STARTING_FEN - return "The board has been reset to the standard starting position." - - def get_board(self, user_id: str): - """Returns a chess.Board() instance based on stored FEN.""" - fen = self.active_games.get(user_id, chess.STARTING_FEN) - return chess.Board(fen) - - async def get_fen(self, user_id: str): - """Returns the current FEN of the user's board, using long-term memory.""" - async with self.config.guild(ctx.guild).long_term_profiles() as long_memory: - return long_memory.get(user_id, {}).get("fen", chess.STARTING_FEN) - - def make_move(self, user_id: str, move: str): - """Attempts to execute a move and checks if the game is over.""" - board = self.get_board(user_id) - - try: - board.push_san(move) # Execute move in standard algebraic notation - self.active_games[user_id] = board.fen() # Store FEN string instead of raw board object - - if board.is_checkmate(): - self.active_games.pop(user_id) - return f"Move executed: `{move}`. **Checkmate!** 🎉" - elif board.is_stalemate(): - self.active_games.pop(user_id) - return f"Move executed: `{move}`. **Stalemate!** 🤝" - elif board.is_insufficient_material(): - self.active_games.pop(user_id) - return f"Move executed: `{move}`. **Draw due to insufficient material.**" - elif board.can_claim_threefold_repetition(): - self.active_games.pop(user_id) - return f"Move executed: `{move}`. **Draw by threefold repetition.**" - elif board.can_claim_fifty_moves(): - self.active_games.pop(user_id) - return f"Move executed: `{move}`. **Draw by 50-move rule.**" - - return f"Move executed: `{move}`.\nCurrent FEN:\n```{board.fen()}```" - except ValueError: - return "⚠️ Invalid move. Please enter a legal chess move." - - def resign(self, user_id: str): - """Handles player resignation.""" - if user_id in self.active_games: - del self.active_games[user_id] - return "**You have resigned. Well played!** 🏳️" - return "No active game to resign from." - - def get_board_state_text(self, user_id: str): - """Returns the current FEN as a message.""" - fen = self.active_games.get(user_id, chess.STARTING_FEN) - return f"Current board state (FEN):\n```{fen}```" - - def get_board_state_image(self, user_id: str): - """Generates a chessboard image from the current FEN and returns it as a file.""" - fen = self.active_games.get(user_id, chess.STARTING_FEN) - board = chess.Board(fen) - - try: - # Generate SVG representation of the board - svg_data = chess.svg.board(board) - - # Convert SVG to PNG using cairosvg - png_data = svg2png(bytestring=svg_data) - - # Store PNG in memory - image_file = io.BytesIO(png_data) - image_file.seek(0) # Ensure file pointer is reset before returning - - return discord.File(image_file, filename="chessboard.png") - - except Exception as e: - return f"⚠️ Error generating board image: {str(e)}" diff --git a/reginaldCog/reginald.py b/reginaldCog/reginald.py index 77049af..40b9683 100644 --- a/reginaldCog/reginald.py +++ b/reginaldCog/reginald.py @@ -9,8 +9,9 @@ from collections import Counter from redbot.core import Config, commands from openai import OpenAIError from .permissions import PermissionsMixin +from .blacklist import BlacklistMixin -class ReginaldCog(commands.Cog, PermissionsMixin): +class ReginaldCog(commands.Cog, PermissionsMixin, BlacklistMixin): def __init__(self, bot): self.bot = bot self.config = Config.get_conf(self, identifier=71717171171717) @@ -45,42 +46,6 @@ class ReginaldCog(commands.Cog, PermissionsMixin): allowed_roles = await self.config.guild(user.guild).allowed_roles() or [] # Ensure it's always a list return any(role.id in allowed_roles for role in user.roles) - async def is_blacklisted(self, user: discord.Member) -> bool: - blacklisted_users = await self.config.guild(user.guild).blacklisted_users() - return str(user.id) in blacklisted_users - - @commands.command(name="reginald_blacklist", help="List users who are explicitly denied access to Reginald.") - @commands.has_permissions(administrator=True) - async def list_blacklisted_users(self, ctx): - blacklisted_users = await self.config.guild(ctx.guild).blacklisted_users() - if not blacklisted_users: - await ctx.send("✅ No users are currently blacklisted from interacting with Reginald.") - return - - user_mentions = [f"<@{user_id}>" for user_id in blacklisted_users] - await ctx.send(f"🚫 **Blacklisted Users:**\n{', '.join(user_mentions)}") - - @commands.command(name="reginald_blacklist_add", help="Blacklist a user from interacting with Reginald.") - @commands.has_permissions(administrator=True) - async def add_to_blacklist(self, ctx, user: discord.User): - async with self.config.guild(ctx.guild).blacklisted_users() as blacklisted_users: - if str(user.id) not in blacklisted_users: - blacklisted_users.append(str(user.id)) - await ctx.send(f"🚫 {user.display_name} has been **blacklisted** from interacting with Reginald.") - else: - await ctx.send(f"⚠️ {user.display_name} is already blacklisted.") - - - @commands.command(name="reginald_blacklist_remove", help="Remove a user from Reginald's blacklist.") - @commands.has_permissions(administrator=True) - async def remove_from_blacklist(self, ctx, user: discord.User): - async with self.config.guild(ctx.guild).blacklisted_users() as blacklisted_users: - if str(user.id) in blacklisted_users: - blacklisted_users.remove(str(user.id)) - await ctx.send(f"✅ {user.display_name} has been removed from the blacklist.") - else: - await ctx.send(f"⚠️ {user.display_name} was not on the blacklist.") - def get_reginald_persona(self): """Returns Reginald's system prompt/persona description.""" return (