Files
2025-09-16 15:00:16 +02:00

225 lines
8.4 KiB
Python
Executable File

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"cogs.{filename[:-3]}")
except Exception as e:
print(f"Error reloading {filename}: {e}")
await client.load_extension(f"cogs.{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"cogs.{extension}")
await self.client.load_extension(f"cogs.{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"cogs.{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))