import datetime import time import os import discord from discord.ext import commands async def reload_all(client, ctx): """ Reloads all cogs (modules) in the 'cogs' folder and syncs the command tree. Args: client (discord.Client): The bot's main client object. ctx (commands.Context): The context in which the command was invoked. """ cogs_folder = os.path.abspath(os.path.dirname(__file__)) # Get the cogs folder path for filename in os.listdir(cogs_folder): if filename.endswith(".py"): try: await client.reload_extension(f"implementing.{filename[:-3]}") except Exception as e: print(f"Error reloading {filename}: {e}") await client.load_extension(f"implementing.{filename[:-3]}") await client.tree.sync() # Synchronize command tree await ctx.reply("Reloaded all cogs.") class Admin(commands.Cog): """Cog that provides administrative commands for bot control and information.""" def __init__(self, client): self.client = client @commands.command( name="ping", brief="Bot Latency", description="Displays the bot's latency in milliseconds.", ) async def _ping(self, ctx): """ Responds with the bot's latency (ping time). Args: ctx (commands.Context): The context in which the command was invoked. """ latency = round(self.client.latency * 1000, 2) # Convert to ms await ctx.reply(f"Pong! 🏓\nLatency: {latency}ms") @commands.command( name="info", brief="Bot Info", description="Provides information about the bot's owner and team (if applicable).", ) async def _info(self, ctx): """ Displays information about the bot's owner or team members. Args: ctx (commands.Context): The context in which the command was invoked. """ app_info = await self.client.application_info() if app_info.team: team_members = "\n".join( f"{member.name}#{member.discriminator} ({'Owner' if member.id == app_info.team.owner_id else 'Member'})" for member in app_info.team.members ) await ctx.reply( f"Bot is part of the team: {app_info.team.name}\nMembers:\n{team_members}" ) else: await ctx.reply( f"Bot is owned by {app_info.owner} and is not part of a team." ) @commands.command( name="uptime", brief="Bot Runtime", description="Displays how long the bot has been running since its last restart.", ) async def _uptime(self, ctx): """ Calculates and sends the bot's uptime based on a start timestamp. Args: ctx (commands.Context): The context in which the command was invoked. """ with open("time.txt", "r") as file: start_time = float(file.read()) uptime = str( datetime.timedelta(seconds=int(time.time() - start_time)) ) # Calculate uptime await ctx.send(f"Uptime: {uptime}") @commands.hybrid_command( name="reload", brief="Reload Cog", description="Reloads a specific cog or all cogs.", aliases=["rl"], ) @commands.is_owner() async def _reload(self, ctx, extension: str): """ Reloads a specified cog/module or all modules if 'all' is passed. Args: ctx (commands.Context): The context in which the command was invoked. extension (str): Name of the cog to reload, or 'all' to reload all cogs. """ if extension.lower() == "all": await reload_all(self.client, ctx) return try: await self.client.unload_extension(f"implementing.{extension}") await self.client.load_extension(f"implementing.{extension}") await ctx.send(f"Successfully reloaded {extension}.") except commands.ExtensionNotLoaded: await ctx.send(f"Extension {extension} was not loaded, loading it now.") try: await self.client.load_extension(f"implementing.{extension}") await ctx.send(f"Successfully loaded {extension}.") except Exception as e: await ctx.send(f"Failed to load {extension}: {e}") except commands.ExtensionNotFound: await ctx.send(f"Extension {extension} was not found.") except Exception as e: await ctx.send(f"Failed to reload {extension}: {e}") @commands.hybrid_command( name="purge", brief="Delete messages", description="Deletes a specified number of messages from the current channel (default: 100).", ) @commands.has_permissions(manage_channels=True) @commands.cooldown(1, 10, commands.BucketType.user) async def _purge(self, ctx, n: int = 100): """ Deletes a specified number of messages from the current channel. Args: ctx (commands.Context): The context in which the command was invoked. n (int, optional): The number of messages to delete. Defaults to 100. """ n += 1 if n <= 0: return if n < 100: await ctx.channel.purge(limit=n) await ctx.channel.send( f"Successfully purged last {n-1} messages", delete_after=2 ) elif n == 100: await ctx.channel.purge() await ctx.channel.send( "Successfully purged last 100 messages", delete_after=2 ) else: # n > 100 for i in range(n // 100): await ctx.channel.purge() await ctx.channel.purge(limit=n % 100) await ctx.channel.send( f"Successfully purged last {n-1} messages", delete_after=2 ) @commands.hybrid_command( name="nuke", brief="Clear channel", description="Deletes all messages by duplicating and deleting the channel.", ) @commands.has_permissions(manage_channels=True) @commands.cooldown(1, 30, commands.BucketType.user) async def _nuke(self, ctx, channel_name: str = "Current"): """ Duplicates and deletes a specified channel (or the current channel) to clear messages. Args: ctx (commands.Context): The context in which the command was invoked. channel_name (str, optional): Name of the channel to nuke. Defaults to 'Current' (the invoking channel). """ # Determine the channel ID based on the channel_name parameter if channel_name.lower() == "current": channel_id = ctx.channel.id else: channel_id = discord.utils.get(ctx.guild.channels, name=channel_name) if channel_id is None: return await ctx.send(f"Channel **{channel_name}** was not found.") existing_channel = self.client.get_channel(channel_id) if existing_channel: await existing_channel.clone(reason="Channel has been nuked") await existing_channel.delete() await self._send_embed( ctx, f"Channel **{existing_channel.name}** has been nuked.", discord.Color.red(), ) else: await ctx.send(f"No channel with ID {channel_id} was found.") @commands.command( name="guildids", brief="List all guild IDs", description="Lists all guild IDs the bot is currently in. Owner only.", ) @commands.is_owner() async def _guildids(self, ctx): """ Sends a list of all guild IDs the bot is in to the owner. Args: ctx (commands.Context): The context in which the command was invoked. """ guild_ids = [str(guild.id) for guild in self.client.guilds] guilds_str = "\n".join(guild_ids) await ctx.author.send(f"Guild IDs:\n{guilds_str}") await ctx.reply("Sent you a DM with all guild IDs.") async def _send_embed(self, ctx, description, color=discord.Color.blurple()): embed = discord.Embed(description=description, color=color) await ctx.send(embed=embed) async def setup(client): """Sets up the Admin cog for the bot.""" await client.add_cog(Admin(client))