Compare commits
2 Commits
f15c869993
...
6b0091f7d5
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6b0091f7d5 | ||
|
|
fc77f0a3c2 |
@@ -19,6 +19,11 @@ LAVALINK_PORT=13592
|
||||
EMOJI_SYNC=false
|
||||
JISHAKU_ENABLED=false
|
||||
|
||||
# Slash (/) command sync — guild sync makes commands appear immediately
|
||||
SLASH_SYNC_GLOBAL=true
|
||||
SLASH_SYNC_ALL_GUILDS=true
|
||||
# SLASH_GUILD_IDS=
|
||||
|
||||
# Traefik (optional override — default in compose: letsencrypt)
|
||||
# TRAEFIK_CERT_RESOLVER=letsencrypt
|
||||
|
||||
|
||||
@@ -27,8 +27,11 @@ LAVALINK_PASSWORD="youshallnotpass"
|
||||
LAVALINK_SECURE="false"
|
||||
LAVALINK_PORT="13592"
|
||||
|
||||
# ── Emoji Sync ────────────────────────────────────────────────────────────────
|
||||
EMOJI_SYNC="false"
|
||||
SLASH_SYNC_GLOBAL=true
|
||||
# Instant / commands in every connected server (set false if you have many guilds and hit rate limits)
|
||||
SLASH_SYNC_ALL_GUILDS=true
|
||||
# Or limit instant sync to specific guild IDs (comma-separated). Overrides ALL_GUILDS when set.
|
||||
# SLASH_GUILD_IDS=
|
||||
|
||||
# ── API / Dashboard Backend ───────────────────────────────────────────────────
|
||||
API_ENABLED="false"
|
||||
|
||||
32
bot/Axiom.py
32
bot/Axiom.py
@@ -33,6 +33,7 @@ from utils.Tools import *
|
||||
from utils.config import *
|
||||
from utils.emoji import SUCCESS, ERROR, TICK, CROSS, REACTION_TEST_EMOJIS
|
||||
from utils.sync_emojis import run_sync
|
||||
from utils.slash_sync import sync_slash_commands
|
||||
|
||||
import cogs
|
||||
|
||||
@@ -99,21 +100,28 @@ async def on_ready():
|
||||
# Sync application emojis on startup
|
||||
await run_sync(TOKEN)
|
||||
|
||||
async def sync_commands():
|
||||
# Register / slash commands (guild sync = instant; global can take up to ~1h)
|
||||
if not getattr(client, "_slash_synced", False):
|
||||
client._slash_synced = True
|
||||
try:
|
||||
synced = await client.tree.sync()
|
||||
all_commands = list(client.commands)
|
||||
print(f"Synced Total {len(all_commands)} Client Commands and {len(synced)} Slash Commands")
|
||||
await sync_slash_commands(client)
|
||||
except Exception as e:
|
||||
print(f"Error syncing command tree: {e}")
|
||||
print(f"\033[31mError syncing command tree: {e}\033[0m")
|
||||
|
||||
client.loop.create_task(sync_commands())
|
||||
if SERVER_COUNT_CHANNEL_ID or USER_COUNT_CHANNEL_ID:
|
||||
client.loop.create_task(update_stats())
|
||||
|
||||
|
||||
@client.event
|
||||
async def on_guild_join(guild: discord.Guild):
|
||||
# Instant slash commands in the new server
|
||||
try:
|
||||
from utils.slash_sync import sync_guild
|
||||
synced = await sync_guild(client, guild, copy_global=True)
|
||||
print(f"◈ Slash sync for new guild {guild.id}: {len(synced)} command(s)")
|
||||
except Exception as e:
|
||||
print(f"Slash sync on guild join failed: {e}")
|
||||
|
||||
if not LOG_CHANNEL_ID:
|
||||
return
|
||||
log_channel = client.get_channel(LOG_CHANNEL_ID)
|
||||
@@ -155,7 +163,7 @@ async def on_command_completion(context: commands.Context) -> None:
|
||||
|
||||
|
||||
# --- Utility Commands ---
|
||||
@client.command(name='spotify')
|
||||
@client.hybrid_command(name='spotify')
|
||||
async def spotify(ctx: Context, user: discord.Member = None):
|
||||
"""Shows what a user is listening to on Spotify."""
|
||||
user = user or ctx.author
|
||||
@@ -176,7 +184,7 @@ async def spotify(ctx: Context, user: discord.Member = None):
|
||||
await ctx.send(embed=embed)
|
||||
|
||||
|
||||
@client.command(name='makeinvite', aliases=['createinvite', 'makeinv'])
|
||||
@client.hybrid_command(name='makeinvite', aliases=['createinvite', 'makeinv'])
|
||||
@commands.is_owner()
|
||||
async def make_invite(ctx: Context, guild_id: int = None):
|
||||
"""Creates an invite for a specified server (owner only)."""
|
||||
@@ -206,7 +214,7 @@ async def make_invite(ctx: Context, guild_id: int = None):
|
||||
|
||||
|
||||
# --- Webhook Management Commands ---
|
||||
@client.command(name='create_hook', aliases=['makehook'])
|
||||
@client.hybrid_command(name='create_hook', aliases=['makehook'])
|
||||
@commands.has_permissions(administrator=True)
|
||||
async def create_hook(ctx: Context, *, name: str = None):
|
||||
"""Creates a webhook in the current channel."""
|
||||
@@ -228,7 +236,7 @@ async def create_hook(ctx: Context, *, name: str = None):
|
||||
await ctx.send(f"Webhook created: **{webhook.name}**\n||{webhook.url}||\n(I could not DM you the URL.)")
|
||||
|
||||
|
||||
@client.command(name='delete_hook', aliases=['delhook'])
|
||||
@client.hybrid_command(name='delete_hook', aliases=['delhook'])
|
||||
@commands.has_permissions(administrator=True)
|
||||
async def delete_hook(ctx: Context, webhook_url: str = None):
|
||||
"""Deletes a webhook using its URL."""
|
||||
@@ -244,7 +252,7 @@ async def delete_hook(ctx: Context, webhook_url: str = None):
|
||||
await ctx.send(f"{ERROR} Webhook not found or URL is invalid.")
|
||||
|
||||
|
||||
@client.command(name='list_hooks', aliases=['hooks'])
|
||||
@client.hybrid_command(name='list_hooks', aliases=['hooks'])
|
||||
@commands.has_permissions(administrator=True)
|
||||
async def list_hooks(ctx: Context):
|
||||
"""Lists all webhooks in the current channel."""
|
||||
@@ -262,7 +270,7 @@ async def list_hooks(ctx: Context):
|
||||
|
||||
|
||||
# --- Game Command ---
|
||||
@client.command()
|
||||
@client.hybrid_command()
|
||||
async def reaction(ctx: Context):
|
||||
"""See how fast you can react to the correct emoji."""
|
||||
emojis = ["🍪", "🎉", "🧋", "🍒", "🍑", "💸", "🌙", "💕"]
|
||||
|
||||
@@ -50,7 +50,7 @@ class Birthdays(commands.Cog):
|
||||
self.client = client
|
||||
self.check_birthdays.start()
|
||||
|
||||
@commands.command(
|
||||
@commands.hybrid_command(
|
||||
name="birthdaysetup",
|
||||
help="Set up the birthday log channel and role.")
|
||||
@commands.has_permissions(administrator=True)
|
||||
@@ -69,7 +69,7 @@ class Birthdays(commands.Cog):
|
||||
|
||||
await ctx.send(view=CV2("Birthday Setup", f"Birthday log channel set to {channel.mention} and birthday role set to {role.mention}."))
|
||||
|
||||
@commands.command(
|
||||
@commands.hybrid_command(
|
||||
name="setbirthday",
|
||||
help="Set your birthday.")
|
||||
@commands.guild_only()
|
||||
@@ -112,7 +112,7 @@ class Birthdays(commands.Cog):
|
||||
except asyncio.TimeoutError:
|
||||
await ctx.send(view=CV2("Error", "You took too long to respond. Please try again."))
|
||||
|
||||
@commands.command(
|
||||
@commands.hybrid_command(
|
||||
name="removebirthday",
|
||||
help="Remove your birthday.")
|
||||
@commands.guild_only()
|
||||
@@ -126,7 +126,7 @@ class Birthdays(commands.Cog):
|
||||
else:
|
||||
await ctx.send(view=CV2("Error", "You have no birthday set."))
|
||||
|
||||
@commands.command(
|
||||
@commands.hybrid_command(
|
||||
name="listbirthdays",
|
||||
help="List all members who have their birthday today.")
|
||||
@commands.guild_only()
|
||||
@@ -143,7 +143,7 @@ class Birthdays(commands.Cog):
|
||||
else:
|
||||
await ctx.send(view=CV2("Birthdays", "No birthdays today."))
|
||||
|
||||
@commands.command(
|
||||
@commands.hybrid_command(
|
||||
name="birthday",
|
||||
help="Check your birthday.")
|
||||
@commands.guild_only()
|
||||
|
||||
@@ -144,7 +144,7 @@ class Games(Cog):
|
||||
game = btn.BetaBattleShip(player1=ctx.author, player2=player)
|
||||
await game.start(ctx)
|
||||
|
||||
@commands.group(name="country-guesser",
|
||||
@commands.hybrid_group(name="country-guesser",
|
||||
help="Guess name of the country by flag.",
|
||||
aliases=["guess", "guesser", "countryguesser"],
|
||||
usage="country-guesser")
|
||||
|
||||
@@ -36,7 +36,7 @@ class Invcrole(commands.Cog):
|
||||
''')
|
||||
await db.commit()
|
||||
|
||||
@commands.group(name='vcrole', help="Vcrole Setup commands", invoke_without_command=True)
|
||||
@commands.hybrid_group(name='vcrole', help="Vcrole Setup commands", invoke_without_command=True)
|
||||
@blacklist_check()
|
||||
@ignore_check()
|
||||
@commands.has_permissions(administrator=True)
|
||||
|
||||
@@ -52,7 +52,7 @@ class AutoReaction(commands.Cog):
|
||||
cursor = await db.execute("SELECT 1 FROM autoreact WHERE guild_id = ? AND trigger = ?", (guild_id, trigger))
|
||||
return await cursor.fetchone()
|
||||
|
||||
@commands.group(name="react", aliases=["autoreact"], help="Lists all subcommands of autoreact group.", invoke_without_command=True)
|
||||
@commands.hybrid_group(name="react", aliases=["autoreact"], help="Lists all subcommands of autoreact group.", invoke_without_command=True)
|
||||
@blacklist_check()
|
||||
@ignore_check()
|
||||
@commands.cooldown(1, 4, commands.BucketType.user)
|
||||
|
||||
@@ -46,7 +46,7 @@ class AutoResponder(commands.Cog):
|
||||
''')
|
||||
await db.commit()
|
||||
|
||||
@commands.group(name="autoresponder", invoke_without_command=True, aliases=['ar'], help="Manage autoresponders in the server.")
|
||||
@commands.hybrid_group(name="autoresponder", invoke_without_command=True, aliases=['ar'], help="Manage autoresponders in the server.")
|
||||
@blacklist_check()
|
||||
@ignore_check()
|
||||
@commands.cooldown(1, 5, commands.BucketType.user)
|
||||
|
||||
@@ -92,7 +92,7 @@ class AutoRole(commands.Cog):
|
||||
|
||||
|
||||
|
||||
@commands.group(name="autorole", invoke_without_command=True)
|
||||
@commands.hybrid_group(name="autorole", invoke_without_command=True)
|
||||
@commands.cooldown(1, 5, commands.BucketType.user)
|
||||
@commands.max_concurrency(1, per=commands.BucketType.default, wait=False)
|
||||
@commands.guild_only()
|
||||
|
||||
@@ -123,7 +123,7 @@ class Blackjack(commands.Cog):
|
||||
total_sum += 1
|
||||
return total_sum
|
||||
|
||||
@commands.command(aliases=['bj', 'blackjacks'], help="Play a simple game of blackjack.", usage="blackjack")
|
||||
@commands.hybrid_command(aliases=['bj', 'blackjacks'], help="Play a simple game of blackjack.", usage="blackjack")
|
||||
@blacklist_check()
|
||||
@ignore_check()
|
||||
@commands.cooldown(1, 3, commands.BucketType.user)
|
||||
|
||||
@@ -207,7 +207,7 @@ class Blacklist(commands.Cog):
|
||||
await warning_message.delete(delay=3)
|
||||
break
|
||||
|
||||
@commands.group(name="blacklistword", aliases=["blword"], invoke_without_command=True)
|
||||
@commands.hybrid_group(name="blacklistword", aliases=["blword"], invoke_without_command=True)
|
||||
@blacklist_check()
|
||||
@ignore_check()
|
||||
@commands.cooldown(1, 3, commands.BucketType.user)
|
||||
|
||||
@@ -54,7 +54,7 @@ class Block(commands.Cog):
|
||||
|
||||
|
||||
|
||||
@commands.group(name="blacklist", aliases=["bl"], invoke_without_command=True)
|
||||
@commands.hybrid_group(name="blacklist", aliases=["bl"], invoke_without_command=True)
|
||||
@commands.is_owner()
|
||||
async def blacklist(self, ctx):
|
||||
if ctx.subcommand_passed is None:
|
||||
|
||||
@@ -122,7 +122,7 @@ class calculator(commands.Cog):
|
||||
def __init__(self, bot):
|
||||
self.bot = bot
|
||||
|
||||
@commands.command(name='calculator', help='Starts a calculator session', aliases=['calc', 'calculate', 'math'])
|
||||
@commands.hybrid_command(name='calculator', help='Starts a calculator session', aliases=['calc', 'calculate', 'math'])
|
||||
async def calculator(self, ctx):
|
||||
"""Starts a new calculator session."""
|
||||
# Ensure we pass the author to the view so it knows who triggered it
|
||||
|
||||
@@ -74,7 +74,7 @@ class Counting(commands.Cog):
|
||||
"**counting stats** — View current counting stats"
|
||||
))
|
||||
|
||||
@commands.group(name="counting", invoke_without_command=True)
|
||||
@commands.hybrid_group(name="counting", invoke_without_command=True)
|
||||
async def counting(self, ctx):
|
||||
if not self.is_enabled(ctx.guild.id):
|
||||
await self.not_enabled_embed(ctx)
|
||||
|
||||
@@ -81,7 +81,7 @@ class StaffDMCog(commands.Cog):
|
||||
def __init__(self, bot):
|
||||
self.bot = bot
|
||||
|
||||
@commands.command(name="dmstaff")
|
||||
@commands.hybrid_command(name="dmstaff")
|
||||
async def dm_staff(self, ctx, member: discord.Member, *, message: str):
|
||||
if ctx.author.id not in STAFF_IDS:
|
||||
view = PermissionErrorView()
|
||||
|
||||
@@ -406,7 +406,7 @@ class Emergency(commands.Cog):
|
||||
) as cursor:
|
||||
return await cursor.fetchone() is not None
|
||||
|
||||
@commands.group(name="emergency", aliases=["emg"], invoke_without_command=True)
|
||||
@commands.hybrid_group(name="emergency", aliases=["emg"], invoke_without_command=True)
|
||||
@blacklist_check()
|
||||
@ignore_check()
|
||||
@commands.cooldown(1, 4, commands.BucketType.user)
|
||||
@@ -614,7 +614,7 @@ class Emergency(commands.Cog):
|
||||
roles = await cursor.fetchall()
|
||||
await ctx.reply(view=RoleListView(roles, is_auth))
|
||||
|
||||
@commands.command(name="emergencysituation", aliases=["emgs"])
|
||||
@commands.hybrid_command(name="emergencysituation", aliases=["emgs"])
|
||||
@blacklist_check()
|
||||
@ignore_check()
|
||||
@commands.cooldown(1, 40, commands.BucketType.user)
|
||||
@@ -736,7 +736,7 @@ class Emergency(commands.Cog):
|
||||
await anti.commit()
|
||||
await proc_msg.delete()
|
||||
|
||||
@commands.command(name="emergencyrestore", aliases=["emgrestore"])
|
||||
@commands.hybrid_command(name="emergencyrestore", aliases=["emgrestore"])
|
||||
@blacklist_check()
|
||||
@ignore_check()
|
||||
@commands.cooldown(1, 30, commands.BucketType.user)
|
||||
|
||||
@@ -88,12 +88,12 @@ class encryption(commands.Cog):
|
||||
def __init__(self, bot):
|
||||
self.bot = bot
|
||||
|
||||
@commands.group(invoke_without_command=True)
|
||||
@commands.hybrid_group(invoke_without_command=True)
|
||||
async def encode(self, ctx):
|
||||
"""All encode methods"""
|
||||
await ctx.send_help(ctx.command)
|
||||
|
||||
@commands.group(invoke_without_command=True)
|
||||
@commands.hybrid_group(invoke_without_command=True)
|
||||
async def decode(self, ctx):
|
||||
"""All decode methods"""
|
||||
await ctx.send_help(ctx.command)
|
||||
@@ -204,7 +204,7 @@ class encryption(commands.Cog):
|
||||
except Exception:
|
||||
await ctx.send(view=DecodeErrorView("ASCII85"))
|
||||
|
||||
@commands.command(name="password")
|
||||
@commands.hybrid_command(name="password")
|
||||
async def password(self, ctx):
|
||||
"""Generates a random secure password for you"""
|
||||
if hasattr(ctx, "guild") and ctx.guild is not None:
|
||||
|
||||
@@ -197,7 +197,7 @@ class Extra(commands.Cog):
|
||||
|
||||
|
||||
|
||||
@commands.command(name="uptime", description="Shows the Bot's Uptime.")
|
||||
@commands.hybrid_command(name="uptime", description="Shows the Bot's Uptime.")
|
||||
@blacklist_check()
|
||||
@ignore_check()
|
||||
@commands.cooldown(1, 3, commands.BucketType.user)
|
||||
@@ -447,7 +447,7 @@ class Extra(commands.Cog):
|
||||
|
||||
|
||||
|
||||
@commands.command(name="boostcount",
|
||||
@commands.hybrid_command(name="boostcount",
|
||||
help="Shows boosts count",
|
||||
usage="boosts",
|
||||
aliases=["bco"],
|
||||
@@ -788,7 +788,7 @@ class Extra(commands.Cog):
|
||||
|
||||
|
||||
|
||||
@commands.command(name="joined-at",
|
||||
@commands.hybrid_command(name="joined-at",
|
||||
help="Shows when a user joined",
|
||||
usage="joined-at [user]",
|
||||
with_app_command=True)
|
||||
@@ -799,7 +799,7 @@ class Extra(commands.Cog):
|
||||
joined = ctx.author.joined_at.strftime("%a, %d %b %Y %I:%M %p")
|
||||
await ctx.send(view=CV2("joined-at", f"**`{joined}`**"))
|
||||
|
||||
@commands.command(name="github", usage="github [search]")
|
||||
@commands.hybrid_command(name="github", usage="github [search]")
|
||||
@blacklist_check()
|
||||
@ignore_check()
|
||||
@commands.cooldown(1, 3, commands.BucketType.user)
|
||||
@@ -906,7 +906,7 @@ class Extra(commands.Cog):
|
||||
|
||||
|
||||
|
||||
@commands.command(name="permissions", aliases= ["perms"],
|
||||
@commands.hybrid_command(name="permissions", aliases= ["perms"],
|
||||
help="Check and list the key permissions of a specific user",
|
||||
usage="perms <user>",
|
||||
with_app_command=True)
|
||||
|
||||
@@ -35,7 +35,7 @@ class FastGreet(commands.Cog):
|
||||
)
|
||||
""")
|
||||
|
||||
@commands.command(name="fastgreet_add")
|
||||
@commands.hybrid_command(name="fastgreet_add")
|
||||
@commands.has_permissions(administrator=True)
|
||||
async def add_greet_channel(self, ctx, channel: discord.TextChannel):
|
||||
with sqlite3.connect(DB_PATH) as conn:
|
||||
@@ -45,7 +45,7 @@ class FastGreet(commands.Cog):
|
||||
""", (ctx.guild.id, channel.id))
|
||||
await ctx.send(f"✅ {channel.mention} added as a greet channel.")
|
||||
|
||||
@commands.command(name="fastgreet_remove")
|
||||
@commands.hybrid_command(name="fastgreet_remove")
|
||||
@commands.has_permissions(administrator=True)
|
||||
async def remove_greet_channel(self, ctx, channel: discord.TextChannel):
|
||||
with sqlite3.connect(DB_PATH) as conn:
|
||||
@@ -54,7 +54,7 @@ class FastGreet(commands.Cog):
|
||||
""", (ctx.guild.id, channel.id))
|
||||
await ctx.send(f"❌ {channel.mention} removed from greet channels.")
|
||||
|
||||
@commands.command(name="fastgreet_list")
|
||||
@commands.hybrid_command(name="fastgreet_list")
|
||||
async def list_greet_channels(self, ctx):
|
||||
with sqlite3.connect(DB_PATH) as conn:
|
||||
cursor = conn.execute("""
|
||||
|
||||
@@ -56,58 +56,58 @@ class Fun(commands.Cog):
|
||||
async def meter_command(self, ctx, title, user, text):
|
||||
await ctx.send(view=CV2(title, text))
|
||||
|
||||
@commands.command(name="shipp")
|
||||
@commands.hybrid_command(name="shipp")
|
||||
@blacklist_check()
|
||||
@ignore_check()
|
||||
async def shipp(self, ctx, user1: discord.Member, user2: discord.Member):
|
||||
percentage = random.randint(0, 100)
|
||||
await ctx.send(view=CV2(f"{self.random_emoji()} Ship Result", f"**{user1.mention} x {user2.mention} = {percentage}% Love**"))
|
||||
|
||||
@commands.command()
|
||||
@commands.hybrid_command()
|
||||
@blacklist_check()
|
||||
@ignore_check()
|
||||
async def hug(self, ctx, user: discord.Member):
|
||||
await self.action_command(ctx, user, "hug")
|
||||
|
||||
@commands.command()
|
||||
@commands.hybrid_command()
|
||||
@blacklist_check()
|
||||
@ignore_check()
|
||||
async def kiss(self, ctx, user: discord.Member):
|
||||
await self.action_command(ctx, user, "kiss")
|
||||
|
||||
@commands.command()
|
||||
@commands.hybrid_command()
|
||||
@blacklist_check()
|
||||
@ignore_check()
|
||||
async def pat(self, ctx, user: discord.Member):
|
||||
await self.action_command(ctx, user, "pat")
|
||||
|
||||
@commands.command()
|
||||
@commands.hybrid_command()
|
||||
@blacklist_check()
|
||||
@ignore_check()
|
||||
async def slap(self, ctx, user: discord.Member):
|
||||
await self.action_command(ctx, user, "slap")
|
||||
|
||||
@commands.command()
|
||||
@commands.hybrid_command()
|
||||
@blacklist_check()
|
||||
@ignore_check()
|
||||
async def tickle(self, ctx, user: discord.Member):
|
||||
await self.action_command(ctx, user, "tickle")
|
||||
|
||||
@commands.command()
|
||||
@commands.hybrid_command()
|
||||
@blacklist_check()
|
||||
@ignore_check()
|
||||
async def coinflip(self, ctx):
|
||||
result = random.choice(["Heads", "Tails"])
|
||||
await ctx.send(view=CV2("🪙 Coin Flip", f"**Result: {result}**"))
|
||||
|
||||
@commands.command()
|
||||
@commands.hybrid_command()
|
||||
@blacklist_check()
|
||||
@ignore_check()
|
||||
async def dice(self, ctx):
|
||||
result = random.randint(1, 6)
|
||||
await ctx.send(view=CV2("🎲 Dice Roll", f"**You rolled a {result}!**"))
|
||||
|
||||
@commands.command(name="8ball")
|
||||
@commands.hybrid_command(name="8ball")
|
||||
@blacklist_check()
|
||||
@ignore_check()
|
||||
async def eight_ball(self, ctx, *, question: str):
|
||||
@@ -116,7 +116,7 @@ class Fun(commands.Cog):
|
||||
"Don't count on it.", "My sources say no.", "Very doubtful."]
|
||||
await ctx.send(view=CV2("🎱 Magic 8Ball", f"**Q:** {question}\n**A:** {random.choice(responses)}"))
|
||||
|
||||
@commands.command()
|
||||
@commands.hybrid_command()
|
||||
@blacklist_check()
|
||||
@ignore_check()
|
||||
async def roast(self, ctx, user: discord.Member):
|
||||
@@ -127,56 +127,56 @@ class Fun(commands.Cog):
|
||||
]
|
||||
await ctx.send(view=CV2("🔥 Roast Time", random.choice(roasts)))
|
||||
|
||||
@commands.command()
|
||||
@commands.hybrid_command()
|
||||
@blacklist_check()
|
||||
@ignore_check()
|
||||
async def iq(self, ctx, user: discord.Member = None):
|
||||
user = user or ctx.author
|
||||
await ctx.send(view=CV2("🧠 IQ Test", f"**{user.mention} has an IQ of {random.randint(50, 200)}!**"))
|
||||
|
||||
@commands.command()
|
||||
@commands.hybrid_command()
|
||||
@blacklist_check()
|
||||
@ignore_check()
|
||||
async def dumb(self, ctx, user: discord.Member = None):
|
||||
user = user or ctx.author
|
||||
await ctx.send(view=CV2("🤪 Dumbness Test", f"**{user.mention} is {random.randint(0, 100)}% dumb!**"))
|
||||
|
||||
@commands.command()
|
||||
@commands.hybrid_command()
|
||||
@blacklist_check()
|
||||
@ignore_check()
|
||||
async def simprate(self, ctx, user: discord.Member = None):
|
||||
user = user or ctx.author
|
||||
await ctx.send(view=CV2("😳 Simp Rate", f"**{user.mention} is {random.randint(0, 100)}% simp!**"))
|
||||
|
||||
@commands.command()
|
||||
@commands.hybrid_command()
|
||||
@blacklist_check()
|
||||
@ignore_check()
|
||||
async def toxic(self, ctx, user: discord.Member = None):
|
||||
user = user or ctx.author
|
||||
await ctx.send(view=CV2("☠️ Toxic Meter", f"**{user.mention} is {random.randint(0, 100)}% toxic!**"))
|
||||
|
||||
@commands.command()
|
||||
@commands.hybrid_command()
|
||||
@blacklist_check()
|
||||
@ignore_check()
|
||||
async def intelligence(self, ctx, user: discord.Member = None):
|
||||
user = user or ctx.author
|
||||
await ctx.send(view=CV2("🧠 Intelligence Meter", f"**{user.mention} has {random.randint(0, 200)} IQ Points!**"))
|
||||
|
||||
@commands.command()
|
||||
@commands.hybrid_command()
|
||||
@blacklist_check()
|
||||
@ignore_check()
|
||||
async def genius(self, ctx, user: discord.Member = None):
|
||||
user = user or ctx.author
|
||||
await ctx.send(view=CV2("🤓 Genius Rate", f"**{user.mention} is {random.randint(0, 100)}% genius!**"))
|
||||
|
||||
@commands.command()
|
||||
@commands.hybrid_command()
|
||||
@blacklist_check()
|
||||
@ignore_check()
|
||||
async def brainrate(self, ctx, user: discord.Member = None):
|
||||
user = user or ctx.author
|
||||
await ctx.send(view=CV2("🧠 Brain Power", f"**{user.mention} is using {random.randint(0, 100)}% of their brain!**"))
|
||||
|
||||
@commands.command()
|
||||
@commands.hybrid_command()
|
||||
@blacklist_check()
|
||||
@ignore_check()
|
||||
async def howhot(self, ctx, user: discord.Member = None):
|
||||
|
||||
@@ -86,7 +86,7 @@ class AvatarView(View):
|
||||
await interaction.response.edit_message(embed=embed)
|
||||
|
||||
|
||||
from utils.config import BotName
|
||||
from utils.config import BotName, DISCORD_CLIENT_ID
|
||||
|
||||
class General(commands.Cog):
|
||||
|
||||
@@ -208,7 +208,7 @@ class General(commands.Cog):
|
||||
await msg.add_reaction(CROSS)
|
||||
|
||||
|
||||
@commands.command(name="users", help=f"checks total users of {BotName}.")
|
||||
@commands.hybrid_command(name="users", help=f"checks total users of {BotName}.")
|
||||
@blacklist_check()
|
||||
@ignore_check()
|
||||
@commands.cooldown(1, 3, commands.BucketType.user)
|
||||
@@ -251,7 +251,7 @@ class General(commands.Cog):
|
||||
except:
|
||||
pass
|
||||
|
||||
@commands.command(name="rickroll",
|
||||
@commands.hybrid_command(name="rickroll",
|
||||
help="Detects if provided url is a rick-roll",
|
||||
usage="Rickroll <url>")
|
||||
@blacklist_check()
|
||||
@@ -271,7 +271,7 @@ class General(commands.Cog):
|
||||
title = "Rick Roll {} in webpage".format("was found" if rickRoll else "was not found")
|
||||
await ctx.reply(view=CV2(title, "🎵 Never gonna give you up..." if rickRoll else "✅ Safe to click!"), mention_author=True)
|
||||
|
||||
@commands.command(name="hash",
|
||||
@commands.hybrid_command(name="hash",
|
||||
help="Hashes provided text with provided algorithm")
|
||||
@blacklist_check()
|
||||
@ignore_check()
|
||||
@@ -297,7 +297,7 @@ class General(commands.Cog):
|
||||
hash_lines = f"**{algorithm}:** `{algos[algorithm.lower()]}`"
|
||||
await ctx.reply(view=CV2(f"Hashed \"{message}\"", hash_lines), mention_author=True)
|
||||
|
||||
@commands.command(
|
||||
@commands.hybrid_command(
|
||||
name="invite",
|
||||
aliases=['invite-bot'],
|
||||
description="Get Support & Bot invite link!"
|
||||
@@ -309,7 +309,7 @@ class General(commands.Cog):
|
||||
invite_text = (
|
||||
"```Empower your server with blazing-fast features and 24/7 support!```\n"
|
||||
f"{AXIOM_LINKS} **Quick Actions**\n"
|
||||
f">>> **[Invite {BotName}](https://discord.com/oauth2/authorize?client_id=1396114795102470196&permissions=8&integration_type=0&scope=bot+applications.commands)**\n"
|
||||
f">>> **[Invite {BotName}](https://discord.com/oauth2/authorize?client_id={DISCORD_CLIENT_ID or (ctx.bot.user.id if ctx.bot.user else '')}&permissions=8&integration_type=0&scope=bot%20applications.commands)**\n"
|
||||
"**[Support Server](https://discord.gg/hexahost)**"
|
||||
)
|
||||
await ctx.send(view=CV2(f"{AXIOM_CONNECTION} {BotName} Integration Hub!", invite_text))
|
||||
@@ -118,7 +118,7 @@ class Ignore(commands.Cog):
|
||||
)
|
||||
await db.commit()
|
||||
|
||||
@commands.group(
|
||||
@commands.hybrid_group(
|
||||
name="ignore",
|
||||
help="Manage ignored commands, channels, users, and bypassed users.",
|
||||
invoke_without_command=True,
|
||||
|
||||
@@ -53,22 +53,22 @@ class ImageCommands(commands.Cog):
|
||||
else:
|
||||
await ctx.send(view=CV2("❌ Error", f"No image found for {title.lower()}."))
|
||||
|
||||
@commands.command(name="boy")
|
||||
@commands.hybrid_command(name="boy")
|
||||
async def boy_image(self, ctx):
|
||||
url = await self.fetch_pexels_image("handsome boy")
|
||||
await self.send_image_view(ctx, "👦 Boy Pic", url)
|
||||
|
||||
# @commands.command(name="girl")
|
||||
# @commands.hybrid_command(name="girl")
|
||||
# async def girl_image(self, ctx):
|
||||
# url = await self.fetch_pexels_image("beautiful girl")
|
||||
# await self.send_image_view(ctx, "👧 Girl Pic", url)
|
||||
|
||||
@commands.command(name="couple")
|
||||
@commands.hybrid_command(name="couple")
|
||||
async def couple_image(self, ctx):
|
||||
url = await self.fetch_pexels_image("romantic couple")
|
||||
await self.send_image_view(ctx, "💑 Couple Pic", url)
|
||||
|
||||
@commands.command(name="anime")
|
||||
@commands.hybrid_command(name="anime")
|
||||
async def anime_image(self, ctx):
|
||||
url = await self.fetch_waifu_image("waifu")
|
||||
await self.send_image_view(ctx, "🧚 Anime Waifu", url)
|
||||
|
||||
@@ -190,7 +190,7 @@ class JoinToCreate(commands.Cog):
|
||||
print(f"Error in J2C on_ready: {e}")
|
||||
continue
|
||||
|
||||
@commands.command(name='j2csetup')
|
||||
@commands.hybrid_command(name='j2csetup')
|
||||
@commands.has_permissions(administrator=True)
|
||||
async def setup_private_channels(self, ctx):
|
||||
if ctx.guild.id in self.setup_data:
|
||||
@@ -225,7 +225,7 @@ class JoinToCreate(commands.Cog):
|
||||
|
||||
await ctx.send(view=CV2("✅ Success", f"J2C system setup complete! Join {join_channel.mention} to create a private VC."))
|
||||
|
||||
@commands.command(name='j2creset')
|
||||
@commands.hybrid_command(name='j2creset')
|
||||
@commands.has_permissions(administrator=True)
|
||||
async def reset_private_channels(self, ctx):
|
||||
if ctx.guild.id not in self.setup_data:
|
||||
|
||||
@@ -129,7 +129,7 @@ class Jail(commands.Cog):
|
||||
)
|
||||
await log_channel.send(view=CV2("🔓 Member Unjailed", desc))
|
||||
|
||||
@commands.command(name="jail")
|
||||
@commands.hybrid_command(name="jail")
|
||||
@commands.has_permissions(manage_roles=True)
|
||||
async def jail(self, ctx, member: discord.Member, duration: str = None, *, reason="No reason provided"):
|
||||
jail_role_id = self.get_setting(ctx.guild.id, "jail_role")
|
||||
@@ -182,13 +182,13 @@ class Jail(commands.Cog):
|
||||
)
|
||||
await log_channel.send(view=CV2("🔒 Member Jailed", desc))
|
||||
|
||||
@commands.command(name="unjail")
|
||||
@commands.hybrid_command(name="unjail")
|
||||
@commands.has_permissions(manage_roles=True)
|
||||
async def unjail(self, ctx, member: discord.Member):
|
||||
await self.unjail_member(ctx.guild, member)
|
||||
await ctx.send(view=CV2("✅ Success", f"{member.mention} has been unjailed."))
|
||||
|
||||
@commands.command(name="jailhistory")
|
||||
@commands.hybrid_command(name="jailhistory")
|
||||
async def jailhistory(self, ctx, member: discord.Member):
|
||||
cursor = self.conn.execute("""
|
||||
SELECT reason, jailed_at, duration, mod_id FROM jailed
|
||||
|
||||
@@ -37,7 +37,7 @@ class joindm(commands.Cog):
|
||||
with open(jsondb_path('joindm_messages.json'), 'w') as f:
|
||||
json.dump(self.joindm_messages, f)
|
||||
|
||||
@commands.group(invoke_without_command=True)
|
||||
@commands.hybrid_group(invoke_without_command=True)
|
||||
@commands.has_permissions(administrator=True)
|
||||
async def joindm(self, ctx):
|
||||
# Display the current join DM message
|
||||
|
||||
@@ -293,7 +293,7 @@ class Leveling (commands .Cog ):
|
||||
self .last_level_cache ={}
|
||||
self .db_path =db_path("leveling.db")
|
||||
|
||||
@commands.group (name ="level",invoke_without_command =True ,description ="Leveling system")
|
||||
@commands.hybrid_group (name ="level",invoke_without_command =True ,description ="Leveling system")
|
||||
async def level (self ,ctx ):
|
||||
"""Main leveling command"""
|
||||
if ctx .invoked_subcommand is None :
|
||||
|
||||
@@ -81,7 +81,7 @@ class Messages(commands.Cog):
|
||||
conn.commit()
|
||||
conn.close()
|
||||
|
||||
@commands.command(name="messages", aliases=["msg"])
|
||||
@commands.hybrid_command(name="messages", aliases=["msg"])
|
||||
async def messages(self, ctx, member: discord.Member = None):
|
||||
member = member or ctx.author
|
||||
today = datetime.utcnow().strftime("%Y-%m-%d")
|
||||
|
||||
@@ -21,7 +21,7 @@ class Messagespack(commands.Cog):
|
||||
def __init__(self, bot):
|
||||
self.bot = bot
|
||||
|
||||
@commands.command(name="addmessages", aliases=["addmsg"])
|
||||
@commands.hybrid_command(name="addmessages", aliases=["addmsg"])
|
||||
@commands.has_permissions(manage_messages=True)
|
||||
async def addmessages(self, ctx, member: discord.Member, amount: int):
|
||||
if amount <= 0:
|
||||
@@ -46,7 +46,7 @@ class Messagespack(commands.Cog):
|
||||
conn.close()
|
||||
await ctx.send(f"Added {amount} messages to {member.mention} for today.")
|
||||
|
||||
@commands.command(name="removemessages", aliases=["removemsg"])
|
||||
@commands.hybrid_command(name="removemessages", aliases=["removemsg"])
|
||||
@commands.has_permissions(manage_messages=True)
|
||||
async def removemessages(self, ctx, member: discord.Member, amount: int):
|
||||
if amount <= 0:
|
||||
@@ -70,7 +70,7 @@ class Messagespack(commands.Cog):
|
||||
await ctx.send(f"{member.mention} has no messages recorded for today.")
|
||||
conn.close()
|
||||
|
||||
@commands.command(name="clearmessage", aliases=["clearmsg"])
|
||||
@commands.hybrid_command(name="clearmessage", aliases=["clearmsg"])
|
||||
@commands.has_permissions(manage_messages=True)
|
||||
async def clearmessage(self, ctx, member: discord.Member):
|
||||
conn = sqlite3.connect(db_path("messages.db"))
|
||||
|
||||
@@ -585,7 +585,7 @@ class Music(commands.Cog):
|
||||
bar = '█' * filled_length + '░' * (length - filled_length)
|
||||
return bar
|
||||
|
||||
@commands.command(name="play", aliases=['p'], usage="play <query>", help="Plays a song or playlist.")
|
||||
@commands.hybrid_command(name="play", aliases=['p'], usage="play <query>", help="Plays a song or playlist.")
|
||||
@blacklist_check()
|
||||
@ignore_check()
|
||||
@commands.cooldown(1, 3, commands.BucketType.user)
|
||||
@@ -594,7 +594,7 @@ class Music(commands.Cog):
|
||||
await self.play_source(ctx, query)
|
||||
|
||||
|
||||
@commands.command(name="search", usage="search <query>", help="Searches music from multiple platforms.")
|
||||
@commands.hybrid_command(name="search", usage="search <query>", help="Searches music from multiple platforms.")
|
||||
@blacklist_check()
|
||||
@ignore_check()
|
||||
@commands.cooldown(1, 3, commands.BucketType.user)
|
||||
@@ -606,7 +606,7 @@ class Music(commands.Cog):
|
||||
await ctx.send(view=PlatformSelectView(ctx, query))
|
||||
|
||||
|
||||
@commands.command(name="nowplaying", aliases=["nop"], usage="nowplaying", help="Shows the info about current playing song.")
|
||||
@commands.hybrid_command(name="nowplaying", aliases=["nop"], usage="nowplaying", help="Shows the info about current playing song.")
|
||||
@blacklist_check()
|
||||
@ignore_check()
|
||||
@commands.cooldown(1, 3, commands.BucketType.user)
|
||||
@@ -659,7 +659,7 @@ class Music(commands.Cog):
|
||||
|
||||
await ctx.send(view=view)
|
||||
|
||||
@commands.command(name="autoplay", usage="autoplay", help="Toggles autoplay mode.")
|
||||
@commands.hybrid_command(name="autoplay", usage="autoplay", help="Toggles autoplay mode.")
|
||||
@blacklist_check()
|
||||
@ignore_check()
|
||||
@commands.cooldown(1, 3, commands.BucketType.user)
|
||||
@@ -679,7 +679,7 @@ class Music(commands.Cog):
|
||||
)
|
||||
await ctx.send(view=CV2(f"{TICK} Autoplay {'enabled' if vc.autoplay == wavelink.AutoPlayMode.enabled else 'disabled'} by {ctx.author.mention}."))
|
||||
|
||||
@commands.command(name="loop", usage="loop", help="Toggles loop mode.")
|
||||
@commands.hybrid_command(name="loop", usage="loop", help="Toggles loop mode.")
|
||||
@blacklist_check()
|
||||
@ignore_check()
|
||||
@commands.cooldown(1, 3, commands.BucketType.user)
|
||||
@@ -700,7 +700,7 @@ class Music(commands.Cog):
|
||||
await ctx.send(view=CV2("I'm not connected to a voice channel."))
|
||||
|
||||
|
||||
@commands.command(name="pause", usage="pause", help="Pauses the current song.")
|
||||
@commands.hybrid_command(name="pause", usage="pause", help="Pauses the current song.")
|
||||
@blacklist_check()
|
||||
@ignore_check()
|
||||
@commands.cooldown(1, 3, commands.BucketType.user)
|
||||
@@ -721,7 +721,7 @@ class Music(commands.Cog):
|
||||
else:
|
||||
await ctx.send(view=CV2(f"{WARNING} Nothing is playing or already paused."))
|
||||
|
||||
@commands.command(name="resume", usage="resume", help="Resumes the paused song.")
|
||||
@commands.hybrid_command(name="resume", usage="resume", help="Resumes the paused song.")
|
||||
@blacklist_check()
|
||||
@ignore_check()
|
||||
@commands.cooldown(1, 3, commands.BucketType.user)
|
||||
@@ -742,7 +742,7 @@ class Music(commands.Cog):
|
||||
else:
|
||||
await ctx.send(view=CV2("Player is not paused."))
|
||||
|
||||
@commands.command(name="skip", usage="skip", help="Skips the current song.")
|
||||
@commands.hybrid_command(name="skip", usage="skip", help="Skips the current song.")
|
||||
@blacklist_check()
|
||||
@ignore_check()
|
||||
@commands.cooldown(1, 3, commands.BucketType.user)
|
||||
@@ -767,7 +767,7 @@ class Music(commands.Cog):
|
||||
else:
|
||||
await ctx.send(view=CV2(f"{WARNING} No song is playing or in the queue to skip."))
|
||||
|
||||
@commands.command(name="shuffle", usage="shuffle", help="Shuffles the queue.")
|
||||
@commands.hybrid_command(name="shuffle", usage="shuffle", help="Shuffles the queue.")
|
||||
@blacklist_check()
|
||||
@ignore_check()
|
||||
@commands.cooldown(1, 3, commands.BucketType.user)
|
||||
@@ -787,7 +787,7 @@ class Music(commands.Cog):
|
||||
else:
|
||||
await ctx.send(view=CV2("Queue is empty."))
|
||||
|
||||
@commands.command(name="stop", usage="stop", help="Stops the current song and clears the queue.")
|
||||
@commands.hybrid_command(name="stop", usage="stop", help="Stops the current song and clears the queue.")
|
||||
@blacklist_check()
|
||||
@ignore_check()
|
||||
@commands.cooldown(1, 3, commands.BucketType.user)
|
||||
@@ -810,7 +810,7 @@ class Music(commands.Cog):
|
||||
else:
|
||||
await ctx.send(view=CV2("Nothing is playing to stop."))
|
||||
|
||||
@commands.command(name="volume", aliases=["vol"], usage="volume <level>", help="Sets the volume of the player.")
|
||||
@commands.hybrid_command(name="volume", aliases=["vol"], usage="volume <level>", help="Sets the volume of the player.")
|
||||
@blacklist_check()
|
||||
@ignore_check()
|
||||
@commands.cooldown(1, 3, commands.BucketType.user)
|
||||
@@ -834,7 +834,7 @@ class Music(commands.Cog):
|
||||
else:
|
||||
await ctx.send(view=CV2("Bot is not connected to a voice channel."))
|
||||
|
||||
@commands.command(name="queue", usage="queue", help="Shows the current queue.")
|
||||
@commands.hybrid_command(name="queue", usage="queue", help="Shows the current queue.")
|
||||
@blacklist_check()
|
||||
@ignore_check()
|
||||
@commands.cooldown(1, 3, commands.BucketType.user)
|
||||
@@ -860,7 +860,7 @@ class Music(commands.Cog):
|
||||
ctx=ctx)
|
||||
await paginator.paginate()
|
||||
|
||||
@commands.command(name="clearqueue", usage="clearqueue", help="Clears the queue.")
|
||||
@commands.hybrid_command(name="clearqueue", usage="clearqueue", help="Clears the queue.")
|
||||
@blacklist_check()
|
||||
@ignore_check()
|
||||
@commands.cooldown(1, 3, commands.BucketType.user)
|
||||
@@ -881,7 +881,7 @@ class Music(commands.Cog):
|
||||
else:
|
||||
await ctx.send(view=CV2("No queue to clear."))
|
||||
|
||||
@commands.command(name="replay", usage="replay", help="Replays the current song.")
|
||||
@commands.hybrid_command(name="replay", usage="replay", help="Replays the current song.")
|
||||
@blacklist_check()
|
||||
@ignore_check()
|
||||
@commands.cooldown(1, 3, commands.BucketType.user)
|
||||
@@ -902,7 +902,7 @@ class Music(commands.Cog):
|
||||
else:
|
||||
await ctx.send(view=CV2("No track is currently playing."))
|
||||
|
||||
@commands.command(name="join", aliases=["connect"], usage="join", help="Joins the voice channel.")
|
||||
@commands.hybrid_command(name="join", aliases=["connect"], usage="join", help="Joins the voice channel.")
|
||||
@blacklist_check()
|
||||
@ignore_check()
|
||||
@commands.cooldown(1, 3, commands.BucketType.user)
|
||||
@@ -933,7 +933,7 @@ class Music(commands.Cog):
|
||||
else:
|
||||
await ctx.send(view=CV2("Bot is not connected to any voice channel."))
|
||||
|
||||
@commands.command(name="seek", usage="seek <percentage>", help="Seeks to a specific percentage of the song.")
|
||||
@commands.hybrid_command(name="seek", usage="seek <percentage>", help="Seeks to a specific percentage of the song.")
|
||||
@blacklist_check()
|
||||
@ignore_check()
|
||||
@commands.cooldown(1, 3, commands.BucketType.user)
|
||||
|
||||
@@ -28,7 +28,7 @@ class Nitro(commands.Cog):
|
||||
ctx = await self.bot.get_context(message)
|
||||
await self.bot.invoke(ctx)
|
||||
|
||||
@commands.command(name="nitro")
|
||||
@commands.hybrid_command(name="nitro")
|
||||
async def nitro(self, ctx):
|
||||
embed = discord.Embed(color=0x2B2D31)
|
||||
embed.add_field(
|
||||
|
||||
@@ -34,7 +34,7 @@ class NotifCommands(commands.Cog):
|
||||
channel_id INTEGER NOT NULL)""")
|
||||
await db.commit()
|
||||
|
||||
@commands.group(invoke_without_command=True)
|
||||
@commands.hybrid_group(invoke_without_command=True)
|
||||
async def setnotif(self, ctx):
|
||||
view = CV2(
|
||||
"Notification Commands",
|
||||
|
||||
@@ -465,7 +465,7 @@ class NoPrefix(commands.Cog):
|
||||
|
||||
await ctx.reply(view=embed)
|
||||
|
||||
@commands.group(name="autonp", help="Manage auto no-prefix for partner guilds.")
|
||||
@commands.hybrid_group(name="autonp", help="Manage auto no-prefix for partner guilds.")
|
||||
@commands.is_owner()
|
||||
async def autonp(self, ctx):
|
||||
if ctx.invoked_subcommand is None:
|
||||
|
||||
@@ -160,7 +160,7 @@ class Owner(commands.Cog):
|
||||
async with db.execute('SELECT id FROM staff') as cursor:
|
||||
self.staff = {row[0] for row in await cursor.fetchall()}
|
||||
|
||||
@commands.command(name="staff_add", aliases=["staffadd", "addstaff"], help="Adds a user to the staff list.")
|
||||
@commands.hybrid_command(name="staff_add", aliases=["staffadd", "addstaff"], help="Adds a user to the staff list.")
|
||||
@commands.is_owner()
|
||||
async def staff_add(self, ctx, user: discord.User):
|
||||
if user.id in self.staff:
|
||||
@@ -174,7 +174,7 @@ class Owner(commands.Cog):
|
||||
sonu2 = discord.Embed(title=f"{TICK} Success", description=f"Added {user} to the staff list.", color=0xFF0000)
|
||||
await ctx.reply(embed=sonu2, mention_author=False)
|
||||
|
||||
@commands.command(name="staff_remove", aliases=["staffremove", "removestaff"], help="Removes a user from the staff list.")
|
||||
@commands.hybrid_command(name="staff_remove", aliases=["staffremove", "removestaff"], help="Removes a user from the staff list.")
|
||||
@commands.is_owner()
|
||||
async def staff_remove(self, ctx, user: discord.User):
|
||||
if user.id not in self.staff:
|
||||
@@ -188,7 +188,7 @@ class Owner(commands.Cog):
|
||||
sonu2 = discord.Embed(title=f"{TICK} Success", description=f"Removed {user} from the staff list.", color=0xFF0000)
|
||||
await ctx.reply(embed=sonu2, mention_author=False)
|
||||
|
||||
@commands.command(name="staff_list", aliases=["stafflist", "liststaff", "staffs"], help="Lists all staff members.")
|
||||
@commands.hybrid_command(name="staff_list", aliases=["stafflist", "liststaff", "staffs"], help="Lists all staff members.")
|
||||
@commands.is_owner()
|
||||
async def staff_list(self, ctx):
|
||||
if not self.staff:
|
||||
@@ -202,7 +202,7 @@ class Owner(commands.Cog):
|
||||
sonu = discord.Embed(title=f"{TICK} {BotName} Staffs", description=f"\n{staff_display}", color=0xFF0000)
|
||||
await ctx.send(embed=sonu)
|
||||
|
||||
@commands.command(name="slist")
|
||||
@commands.hybrid_command(name="slist")
|
||||
@commands.check(is_owner_or_staff)
|
||||
async def _slist(self, ctx):
|
||||
servers = sorted(self.client.guilds, key=lambda g: g.member_count, reverse=True)
|
||||
@@ -220,7 +220,7 @@ class Owner(commands.Cog):
|
||||
await paginator.paginate()
|
||||
|
||||
|
||||
@commands.command(name="mutuals", aliases=["mutual"])
|
||||
@commands.hybrid_command(name="mutuals", aliases=["mutual"])
|
||||
@commands.is_owner()
|
||||
async def mutuals(self, ctx, user: discord.User):
|
||||
guilds = [guild for guild in self.client.guilds if user in guild.members]
|
||||
@@ -237,7 +237,7 @@ class Owner(commands.Cog):
|
||||
ctx=ctx)
|
||||
await paginator.paginate()
|
||||
|
||||
@commands.command(name="getinvite", aliases=["gi", "guildinvite"])
|
||||
@commands.hybrid_command(name="getinvite", aliases=["gi", "guildinvite"])
|
||||
@commands.is_owner()
|
||||
async def getinvite(self, ctx: Context, guild= discord.Guild):
|
||||
if not guild:
|
||||
@@ -272,13 +272,13 @@ class Owner(commands.Cog):
|
||||
await ctx.send("Forbidden.")
|
||||
|
||||
|
||||
@commands.command(name="reload", help="Restarts the client.")
|
||||
@commands.hybrid_command(name="reload", help="Restarts the client.")
|
||||
@commands.is_owner()
|
||||
async def _restart(self, ctx: Context):
|
||||
await ctx.reply(f"{TICK} | **Successfully Restarting {BotName} It Takes 10 seconds**")
|
||||
restart_program()
|
||||
|
||||
@commands.command(name="sync", help="Syncs all database.")
|
||||
@commands.hybrid_command(name="sync", help="Syncs all database.")
|
||||
@commands.is_owner()
|
||||
async def _sync(self, ctx):
|
||||
await ctx.reply("Syncing...", mention_author=False)
|
||||
@@ -300,8 +300,35 @@ class Owner(commands.Cog):
|
||||
with open('config.json', 'w') as f:
|
||||
json.dump(data, f, indent=4)
|
||||
|
||||
@commands.hybrid_command(name="syncslash", help="Re-register all slash (/) commands with Discord.")
|
||||
@commands.is_owner()
|
||||
async def syncslash(self, ctx, scope: str = "all"):
|
||||
"""Force-sync slash commands. scope: all | global | guild"""
|
||||
if ctx.interaction:
|
||||
await ctx.defer(ephemeral=True)
|
||||
from utils.slash_sync import sync_slash_commands
|
||||
|
||||
@commands.command(name="owners")
|
||||
scope = (scope or "all").lower().strip()
|
||||
if scope == "global":
|
||||
result = await sync_slash_commands(self.client, guilds=[], global_sync=True)
|
||||
elif scope == "guild":
|
||||
if not ctx.guild:
|
||||
return await ctx.send("Use this in a server, or pass scope `all` / `global`.")
|
||||
result = await sync_slash_commands(
|
||||
self.client, guilds=[ctx.guild], global_sync=False
|
||||
)
|
||||
else:
|
||||
result = await sync_slash_commands(self.client)
|
||||
|
||||
guild_n = len(result.get("guilds") or {})
|
||||
err_n = len(result.get("errors") or [])
|
||||
await ctx.send(
|
||||
f"{TICK} Slash sync done — tree `{result.get('local_tree')}`, "
|
||||
f"global `{result.get('global')}`, guilds `{guild_n}`, errors `{err_n}`."
|
||||
)
|
||||
|
||||
|
||||
@commands.hybrid_command(name="owners")
|
||||
@commands.is_owner()
|
||||
async def own_list(self, ctx):
|
||||
nplist = OWNER_IDS
|
||||
@@ -324,7 +351,7 @@ class Owner(commands.Cog):
|
||||
|
||||
|
||||
|
||||
@commands.command()
|
||||
@commands.hybrid_command()
|
||||
@commands.is_owner()
|
||||
async def dm(self, ctx, user: discord.User, *, message: str):
|
||||
""" DM the user of your choice """
|
||||
@@ -336,7 +363,7 @@ class Owner(commands.Cog):
|
||||
|
||||
|
||||
|
||||
@commands.group()
|
||||
@commands.hybrid_group()
|
||||
@commands.is_owner()
|
||||
async def change(self, ctx):
|
||||
if ctx.invoked_subcommand is None:
|
||||
@@ -357,7 +384,7 @@ class Owner(commands.Cog):
|
||||
await ctx.send(err)
|
||||
|
||||
|
||||
@commands.command(name="ownerban", aliases=["forceban", "dna"])
|
||||
@commands.hybrid_command(name="ownerban", aliases=["forceban", "dna"])
|
||||
@commands.is_owner()
|
||||
async def _ownerban(self, ctx: Context, user_id: int, *, reason: str = "No reason provided"):
|
||||
|
||||
@@ -391,7 +418,7 @@ class Owner(commands.Cog):
|
||||
await ctx.reply("User not found in this guild.", mention_author=False, delete_after=3)
|
||||
await ctx.message.delete()
|
||||
|
||||
@commands.command(name="ownerunban", aliases=["forceunban"])
|
||||
@commands.hybrid_command(name="ownerunban", aliases=["forceunban"])
|
||||
@commands.is_owner()
|
||||
async def _ownerunban(self, ctx: Context, user_id: int, *, reason: str = "No reason provided"):
|
||||
user = self.client.get_user(user_id)
|
||||
@@ -423,7 +450,7 @@ class Owner(commands.Cog):
|
||||
|
||||
|
||||
|
||||
@commands.command(name="globalunban")
|
||||
@commands.hybrid_command(name="globalunban")
|
||||
@commands.is_owner()
|
||||
async def globalunban(self, ctx: Context, user: discord.User):
|
||||
success_guilds = []
|
||||
@@ -447,7 +474,7 @@ class Owner(commands.Cog):
|
||||
|
||||
await ctx.reply(f"{success_message}\n{error_message}", mention_author=False)
|
||||
|
||||
@commands.command(name="guildban")
|
||||
@commands.hybrid_command(name="guildban")
|
||||
@commands.is_owner()
|
||||
async def guildban(self, ctx: Context, guild_id: int, user_id: int, *, reason: str = "No reason provided"):
|
||||
guild = self.client.get_guild(guild_id)
|
||||
@@ -467,7 +494,7 @@ class Owner(commands.Cog):
|
||||
else:
|
||||
await ctx.reply(f"User not found in the specified guild {guild.name}.", mention_author=False)
|
||||
|
||||
@commands.command(name="guildunban")
|
||||
@commands.hybrid_command(name="guildunban")
|
||||
@commands.is_owner()
|
||||
async def guildunban(self, ctx: Context, guild_id: int, user_id: int, *, reason: str = "No reason provided"):
|
||||
guild = self.client.get_guild(guild_id)
|
||||
@@ -492,7 +519,7 @@ class Owner(commands.Cog):
|
||||
await ctx.reply(f"An error occurred while unbanning user ID {user_id} in {guild.name}: {str(e)}", mention_author=False)
|
||||
|
||||
|
||||
@commands.command(name="leaveguild", aliases=["leavesv"])
|
||||
@commands.hybrid_command(name="leaveguild", aliases=["leavesv"])
|
||||
@commands.is_owner()
|
||||
async def leave_guild(self, ctx, guild_id: int):
|
||||
guild = self.client.get_guild(guild_id)
|
||||
@@ -503,7 +530,7 @@ class Owner(commands.Cog):
|
||||
await guild.leave()
|
||||
await ctx.send(f"Left the guild: {guild.name} ({guild.id})")
|
||||
|
||||
@commands.command(name="guildinfo")
|
||||
@commands.hybrid_command(name="guildinfo")
|
||||
@commands.check(is_owner_or_staff)
|
||||
async def guild_info(self, ctx, guild_id: int):
|
||||
guild = self.client.get_guild(guild_id)
|
||||
@@ -527,7 +554,7 @@ class Owner(commands.Cog):
|
||||
|
||||
await ctx.send(embed=embed)
|
||||
|
||||
@commands.command()
|
||||
@commands.hybrid_command()
|
||||
@commands.is_owner()
|
||||
async def servertour(self, ctx, time_in_seconds: int, member: discord.Member):
|
||||
guild = ctx.guild
|
||||
@@ -594,7 +621,7 @@ class Owner(commands.Cog):
|
||||
|
||||
|
||||
|
||||
@commands.group()
|
||||
@commands.hybrid_group()
|
||||
@commands.check(is_owner_or_staff)
|
||||
@blacklist_check()
|
||||
@ignore_check()
|
||||
@@ -657,7 +684,7 @@ class Owner(commands.Cog):
|
||||
await ctx.send(embed=embed)
|
||||
|
||||
|
||||
@commands.command(name="forcepurgebots",
|
||||
@commands.hybrid_command(name="forcepurgebots",
|
||||
aliases=["fpb"],
|
||||
help="Clear recently bot messages in channel (Bot owner only)")
|
||||
@commands.cooldown(1, 3, commands.BucketType.user)
|
||||
@@ -673,7 +700,7 @@ class Owner(commands.Cog):
|
||||
await do_removal(ctx, search, predicate)
|
||||
|
||||
|
||||
@commands.command(name="forcepurgeuser",
|
||||
@commands.hybrid_command(name="forcepurgeuser",
|
||||
aliases=["fpu"],
|
||||
help="Clear recent messages of a user in channel (Bot owner only)")
|
||||
@commands.cooldown(1, 3, commands.BucketType.user)
|
||||
|
||||
@@ -25,14 +25,14 @@ class Global(commands.Cog):
|
||||
self.local_frozen_nicks = {}
|
||||
self.client.frozen_nicknames = {}
|
||||
|
||||
@commands.group(name="global", invoke_without_command=True)
|
||||
@commands.hybrid_group(name="global", invoke_without_command=True)
|
||||
@commands.is_owner()
|
||||
async def global_command(self, ctx: commands.Context):
|
||||
if ctx.subcommand_passed is None:
|
||||
await ctx.send_help(ctx.command)
|
||||
ctx.command.reset_cooldown(ctx)
|
||||
|
||||
@commands.command(name="GB",help="Bans the user from all mutual guilds.")
|
||||
@commands.hybrid_command(name="GB",help="Bans the user from all mutual guilds.")
|
||||
@commands.is_owner()
|
||||
async def global_ban(self, ctx: commands.Context, user: discord.User, reason: str = "Severe violations of Discord's terms of service."):
|
||||
mutual_guilds = [guild for guild in self.client.guilds if guild.get_member(user.id)]
|
||||
@@ -563,7 +563,7 @@ class Global(commands.Cog):
|
||||
await ctx.send(f"✅ | Nickname freezing stopped for {user.name}.")
|
||||
|
||||
|
||||
@commands.command(name="freezenick", help="Freezes a member's nickname in the current server.")
|
||||
@commands.hybrid_command(name="freezenick", help="Freezes a member's nickname in the current server.")
|
||||
@commands.has_permissions(manage_nicknames=True)
|
||||
async def freeze_nickname(self, ctx: commands.Context, member: Member, *, nickname: str):
|
||||
guild_id = ctx.guild.id
|
||||
@@ -597,7 +597,7 @@ class Global(commands.Cog):
|
||||
|
||||
self.client.loop.create_task(monitor_nickname())
|
||||
|
||||
@commands.command(name="unfreezenick", help="Unfreezes a member's nickname in the current server.")
|
||||
@commands.hybrid_command(name="unfreezenick", help="Unfreezes a member's nickname in the current server.")
|
||||
@commands.has_permissions(manage_nicknames=True)
|
||||
async def unfreeze_nickname(self, ctx: commands.Context, member: Member):
|
||||
guild_id = ctx.guild.id
|
||||
|
||||
@@ -19,7 +19,7 @@ class QR(commands.Cog):
|
||||
def __init__(self, bot):
|
||||
self.bot = bot
|
||||
|
||||
@commands.command(
|
||||
@commands.hybrid_command(
|
||||
name="qr",
|
||||
aliases=["qrcode"],
|
||||
help="Sends a QR code image.",
|
||||
|
||||
@@ -25,7 +25,7 @@ class Slots(commands.Cog):
|
||||
def __init__(self, bot):
|
||||
self.bot = bot
|
||||
|
||||
@commands.command(aliases=['slot'])
|
||||
@commands.hybrid_command(aliases=['slot'])
|
||||
@blacklist_check()
|
||||
@ignore_check()
|
||||
@commands.cooldown(1, 3, commands.BucketType.user)
|
||||
|
||||
@@ -23,7 +23,7 @@ class Status(commands.Cog):
|
||||
def __init__(self, bot):
|
||||
self.bot = bot
|
||||
|
||||
@commands.command(name="status", help="Shows the status of the user in detail.")
|
||||
@commands.hybrid_command(name="status", help="Shows the status of the user in detail.")
|
||||
@blacklist_check()
|
||||
@ignore_check()
|
||||
@commands.cooldown(1, 3, commands.BucketType.user)
|
||||
|
||||
@@ -130,7 +130,7 @@ class StickyMessage(commands.Cog):
|
||||
)
|
||||
await db.commit()
|
||||
|
||||
@commands.group(aliases=['sticky', 'sm'], invoke_without_command=True)
|
||||
@commands.hybrid_group(aliases=['sticky', 'sm'], invoke_without_command=True)
|
||||
@commands.has_permissions(manage_messages=True)
|
||||
async def stickymessage(self, ctx: commands.Context):
|
||||
if ctx.invoked_subcommand is None:
|
||||
|
||||
@@ -136,7 +136,7 @@ class Tracking(commands.Cog):
|
||||
row = await cursor.fetchone()
|
||||
return row[0] if row else 0
|
||||
|
||||
@commands.command(aliases=["inv"])
|
||||
@commands.hybrid_command(aliases=["inv"])
|
||||
async def invites(self, ctx, member: discord.Member = None):
|
||||
member = member or ctx.author
|
||||
await self.ensure_tables(ctx.guild.id)
|
||||
@@ -161,7 +161,7 @@ class Tracking(commands.Cog):
|
||||
)
|
||||
await ctx.send(view=CV2(f"Invite Log - {member.name}", desc))
|
||||
|
||||
@commands.command(aliases=["addinvs"])
|
||||
@commands.hybrid_command(aliases=["addinvs"])
|
||||
@commands.has_permissions(administrator=True)
|
||||
async def addinvites(self, ctx, member: discord.Member, amount: int):
|
||||
await self.ensure_tables(ctx.guild.id)
|
||||
@@ -171,7 +171,7 @@ class Tracking(commands.Cog):
|
||||
await db.commit()
|
||||
await ctx.send(view=CV2("✅ Success", f"Added **{amount}** invites to {member.mention}."))
|
||||
|
||||
@commands.command(aliases=["setinvs"])
|
||||
@commands.hybrid_command(aliases=["setinvs"])
|
||||
@commands.has_permissions(administrator=True)
|
||||
async def setinvites(self, ctx, member: discord.Member, amount: int):
|
||||
await self.ensure_tables(ctx.guild.id)
|
||||
@@ -180,7 +180,7 @@ class Tracking(commands.Cog):
|
||||
await db.commit()
|
||||
await ctx.send(view=CV2("✅ Success", f"Set invites of {member.mention} to **{amount}**."))
|
||||
|
||||
@commands.command(aliases=["resetinvs"])
|
||||
@commands.hybrid_command(aliases=["resetinvs"])
|
||||
@commands.has_permissions(administrator=True)
|
||||
async def resetinvites(self, ctx, member: discord.Member):
|
||||
await self.ensure_tables(ctx.guild.id)
|
||||
@@ -189,7 +189,7 @@ class Tracking(commands.Cog):
|
||||
await db.commit()
|
||||
await ctx.send(view=CV2("✅ Success", f"Reset invites of {member.mention}."))
|
||||
|
||||
@commands.command(aliases=["invlb"])
|
||||
@commands.hybrid_command(aliases=["invlb"])
|
||||
async def invitesleaderboard(self, ctx):
|
||||
await self.ensure_tables(ctx.guild.id)
|
||||
async with aiosqlite.connect(INVITE_DB) as db:
|
||||
@@ -208,7 +208,7 @@ class Tracking(commands.Cog):
|
||||
|
||||
await ctx.send(view=CV2("📊 Invite Leaderboard", leaderboard))
|
||||
|
||||
@commands.command(aliases=["invlog"])
|
||||
@commands.hybrid_command(aliases=["invlog"])
|
||||
@commands.has_permissions(administrator=True)
|
||||
async def invitelogging(self, ctx, channel: discord.TextChannel):
|
||||
await self.ensure_tables(ctx.guild.id)
|
||||
|
||||
@@ -49,7 +49,7 @@ class VanityRoles(commands.Cog):
|
||||
await db.execute("ALTER TABLE vanity_roles ADD COLUMN current_status TEXT")
|
||||
await db.commit()
|
||||
|
||||
@commands.group(name="vanityroles", invoke_without_command=True)
|
||||
@commands.hybrid_group(name="vanityroles", invoke_without_command=True)
|
||||
@blacklist_check()
|
||||
@ignore_check()
|
||||
async def vanityroles(self, ctx):
|
||||
|
||||
@@ -29,7 +29,7 @@ class Voice(commands.Cog):
|
||||
self.bot = bot
|
||||
self.color = 0xFF0000
|
||||
|
||||
@commands.group(name="voice", invoke_without_command=True, aliases=['vc'])
|
||||
@commands.hybrid_group(name="voice", invoke_without_command=True, aliases=['vc'])
|
||||
@blacklist_check()
|
||||
@ignore_check()
|
||||
async def vc(self, ctx: commands.Context):
|
||||
|
||||
@@ -22,7 +22,7 @@ class Youtube(commands.Cog):
|
||||
self.bot = bot
|
||||
|
||||
|
||||
@commands.command(name='yt', aliases=['youtube'])
|
||||
@commands.hybrid_command(name='yt', aliases=['youtube'])
|
||||
async def search_youtube(self, ctx, *, search_query):
|
||||
query_string = urllib.parse.urlencode({'search_query': search_query})
|
||||
html_content = urllib.request.urlopen('http://www.youtube.com/results?' + query_string)
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
from utils.db_paths import db_path
|
||||
|
||||
from utils import getConfig
|
||||
from utils.config import BotName
|
||||
from utils.config import BotName, DISCORD_CLIENT_ID
|
||||
import discord
|
||||
from utils.emoji import ARROWRED, CODEBASE, HEART3, INDEX, AXIOM_LINKS
|
||||
from discord.ui import LayoutView, TextDisplay, Separator, Container, ActionRow, Select
|
||||
@@ -87,7 +87,7 @@ class MentionSelectView(LayoutView):
|
||||
)
|
||||
elif selected == "Links":
|
||||
content = (
|
||||
f"**[Invite {BotName}](https://discord.com/oauth2/authorize?client_id=1396114795102470196)**\n"
|
||||
f"**[Invite {BotName}](https://discord.com/oauth2/authorize?client_id={DISCORD_CLIENT_ID or (self.bot.user.id if self.bot.user else '')}&permissions=8&scope=bot%20applications.commands)**\n"
|
||||
"**[Join Support Server](https://discord.gg/hexahost)**"
|
||||
)
|
||||
|
||||
|
||||
@@ -89,7 +89,7 @@ class Message(commands.Cog):
|
||||
self.color = 0xFF0000
|
||||
|
||||
|
||||
@commands.group(invoke_without_command=True, aliases=["purge"], help="Clears the messages")
|
||||
@commands.hybrid_group(invoke_without_command=True, aliases=["purge"], help="Clears the messages")
|
||||
@blacklist_check()
|
||||
@ignore_check()
|
||||
@commands.cooldown(1, 3, commands.BucketType.user)
|
||||
@@ -232,7 +232,7 @@ class Message(commands.Cog):
|
||||
|
||||
|
||||
|
||||
@commands.command(name="purgebots",
|
||||
@commands.hybrid_command(name="purgebots",
|
||||
aliases=["cleanup", "pb", "clearbot", "clearbots"],
|
||||
help="Clear recently bot messages in channel")
|
||||
@blacklist_check()
|
||||
@@ -250,7 +250,7 @@ class Message(commands.Cog):
|
||||
await do_removal(ctx, search, predicate)
|
||||
|
||||
|
||||
@commands.command(name="purgeuser",
|
||||
@commands.hybrid_command(name="purgeuser",
|
||||
aliases=["pu", "cu", "clearuser"],
|
||||
help="Clear recent messages of a user in channel")
|
||||
@blacklist_check()
|
||||
|
||||
@@ -115,7 +115,7 @@ class Moderation(commands.Cog):
|
||||
|
||||
|
||||
|
||||
@commands.command()
|
||||
@commands.hybrid_command()
|
||||
@blacklist_check()
|
||||
@ignore_check()
|
||||
@commands.cooldown(1, 3, commands.BucketType.user)
|
||||
@@ -793,7 +793,7 @@ class Moderation(commands.Cog):
|
||||
|
||||
|
||||
|
||||
@commands.command(aliases=["deletesticker", "removesticker"], description="Delete the sticker from the server")
|
||||
@commands.hybrid_command(aliases=["deletesticker", "removesticker"], description="Delete the sticker from the server")
|
||||
@blacklist_check()
|
||||
@ignore_check()
|
||||
@commands.cooldown(1, 3, commands.BucketType.user)
|
||||
@@ -815,7 +815,7 @@ class Moderation(commands.Cog):
|
||||
await ctx.reply("Failed to delete the sticker")
|
||||
|
||||
|
||||
@commands.command(aliases=["deleteemoji", "removeemoji"], description="Deletes the emoji from the server")
|
||||
@commands.hybrid_command(aliases=["deleteemoji", "removeemoji"], description="Deletes the emoji from the server")
|
||||
@blacklist_check()
|
||||
@ignore_check()
|
||||
@commands.cooldown(1, 3, commands.BucketType.user)
|
||||
@@ -864,7 +864,7 @@ class Moderation(commands.Cog):
|
||||
|
||||
|
||||
|
||||
@commands.command(description="Changes the icon for the role.")
|
||||
@commands.hybrid_command(description="Changes the icon for the role.")
|
||||
@blacklist_check()
|
||||
@ignore_check()
|
||||
@commands.cooldown(1, 3, commands.BucketType.user)
|
||||
|
||||
@@ -56,7 +56,7 @@ class Role(commands.Cog):
|
||||
self.color = 0xFF0000
|
||||
|
||||
|
||||
@commands.group(name="role",invoke_without_command=True)
|
||||
@commands.hybrid_group(name="role",invoke_without_command=True)
|
||||
@blacklist_check()
|
||||
@ignore_check()
|
||||
@commands.cooldown(1, 5, commands.BucketType.user)
|
||||
@@ -598,7 +598,7 @@ class Role(commands.Cog):
|
||||
|
||||
|
||||
|
||||
@commands.group(name="removerole",invoke_without_command=True,
|
||||
@commands.hybrid_group(name="removerole",invoke_without_command=True,
|
||||
aliases=['rrole'],
|
||||
help="remove a role from all members .")
|
||||
@blacklist_check()
|
||||
|
||||
@@ -36,7 +36,7 @@ class Snipe(commands.Cog):
|
||||
'deleted_at': datetime.utcnow()
|
||||
}
|
||||
|
||||
@commands.command(name='snipe', help="Shows the most recently deleted message in the channel.")
|
||||
@commands.hybrid_command(name='snipe', help="Shows the most recently deleted message in the channel.")
|
||||
@commands.has_permissions(manage_messages=True)
|
||||
async def snipe(self, ctx):
|
||||
# Check if there is a sniped message for the current channel
|
||||
|
||||
@@ -53,7 +53,7 @@ class TopCheck(commands.Cog):
|
||||
await db.execute("UPDATE topcheck SET enabled = 0 WHERE guild_id = ?", (guild_id,))
|
||||
await db.commit()
|
||||
|
||||
@commands.group(
|
||||
@commands.hybrid_group(
|
||||
name="topcheck",
|
||||
help="Manage topcheck settings for the server.",
|
||||
invoke_without_command=True)
|
||||
|
||||
@@ -48,11 +48,10 @@ class Axiom(commands.AutoShardedBot):
|
||||
owner_ids=OWNER_IDS,
|
||||
allowed_mentions=discord.AllowedMentions(
|
||||
everyone=False, replied_user=False, roles=False),
|
||||
sync_commands_debug=True,
|
||||
sync_commands=True,
|
||||
shard_count=1)
|
||||
self.status_index = 0
|
||||
self.status_list = []
|
||||
self._slash_synced = False
|
||||
|
||||
async def setup_hook(self):
|
||||
await setup_db()
|
||||
|
||||
@@ -77,6 +77,9 @@ def _parse_ids(env_key: str) -> list[int]:
|
||||
OWNER_IDS: list[int] = _parse_ids("OWNER_IDS")
|
||||
OWNER_IDS_STR: list[str] = [str(i) for i in OWNER_IDS]
|
||||
|
||||
# Discord application / OAuth client id (same as dashboard DISCORD_CLIENT_ID)
|
||||
DISCORD_CLIENT_ID = os.getenv("DISCORD_CLIENT_ID", "").strip()
|
||||
|
||||
# Aliases kept for backwards compatibility with files that import these names
|
||||
BOT_OWNER_IDS = OWNER_IDS
|
||||
BOT_OWNER_IDS_STR = OWNER_IDS_STR
|
||||
|
||||
184
bot/utils/slash_sync.py
Normal file
184
bot/utils/slash_sync.py
Normal file
@@ -0,0 +1,184 @@
|
||||
# ╔══════════════════════════════════════════════════════════════════╗
|
||||
# ║ ║
|
||||
# ║ +-+-+-+-+-+-+-+-+ ║
|
||||
# ║ |H|e|x|a|H|o|s|t| ║
|
||||
# ║ +-+-+-+-+-+-+-+-+ ║
|
||||
# ║ ║
|
||||
# ║ © 2026 HexaHost — All Rights Reserved ║
|
||||
# ║ ║
|
||||
# ║ discord ── https://discord.gg/hexahost ║
|
||||
# ║ github ── https://github.com/theoneandonlymace ║
|
||||
# ║ ║
|
||||
# ╚══════════════════════════════════════════════════════════════════╝
|
||||
"""Register slash (/) commands with Discord.
|
||||
|
||||
Global sync alone can take up to ~1 hour to appear in clients.
|
||||
Guild sync makes them available immediately in every server the bot is in.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import asyncio
|
||||
import logging
|
||||
import os
|
||||
from typing import TYPE_CHECKING, Iterable, Optional
|
||||
|
||||
import discord
|
||||
from discord import app_commands
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from discord.ext import commands
|
||||
|
||||
logger = logging.getLogger("axiom.slash_sync")
|
||||
|
||||
# Discord hard limit for top-level application commands (global or per-guild)
|
||||
MAX_TOP_LEVEL = 100
|
||||
|
||||
|
||||
def _parse_guild_ids(raw: str | None) -> list[int]:
|
||||
if not raw:
|
||||
return []
|
||||
out: list[int] = []
|
||||
for part in raw.split(","):
|
||||
part = part.strip()
|
||||
if part.isdigit():
|
||||
out.append(int(part))
|
||||
return out
|
||||
|
||||
|
||||
def _tree_command_count(bot: "commands.Bot") -> int:
|
||||
return len(bot.tree.get_commands())
|
||||
|
||||
|
||||
def _prune_tree_to_limit(bot: "commands.Bot", limit: int = MAX_TOP_LEVEL) -> list[str]:
|
||||
"""Drop excess top-level app commands so Discord accepts the sync."""
|
||||
commands_list = list(bot.tree.get_commands())
|
||||
if len(commands_list) <= limit:
|
||||
return []
|
||||
|
||||
# Prefer keeping groups (more coverage) over single commands; drop from the end
|
||||
singles = [c for c in commands_list if not isinstance(c, app_commands.Group)]
|
||||
groups = [c for c in commands_list if isinstance(c, app_commands.Group)]
|
||||
ordered = groups + singles
|
||||
removed: list[str] = []
|
||||
while len(ordered) > limit:
|
||||
cmd = ordered.pop()
|
||||
bot.tree.remove_command(cmd.name)
|
||||
removed.append(cmd.name)
|
||||
return removed
|
||||
|
||||
|
||||
async def sync_guild(
|
||||
bot: "commands.Bot",
|
||||
guild: discord.abc.Snowflake,
|
||||
*,
|
||||
copy_global: bool = True,
|
||||
) -> list[app_commands.AppCommand]:
|
||||
if copy_global:
|
||||
bot.tree.copy_global_to(guild=guild)
|
||||
return await bot.tree.sync(guild=guild)
|
||||
|
||||
|
||||
async def sync_slash_commands(
|
||||
bot: "commands.Bot",
|
||||
*,
|
||||
guilds: Optional[Iterable[discord.abc.Snowflake]] = None,
|
||||
global_sync: bool = True,
|
||||
) -> dict:
|
||||
"""
|
||||
Sync application commands.
|
||||
|
||||
Env:
|
||||
SLASH_SYNC_GLOBAL=true|false (default true)
|
||||
SLASH_GUILD_IDS=id,id (optional; if set, only these guilds get instant sync)
|
||||
SLASH_SYNC_ALL_GUILDS=true (default true — sync every connected guild for instant /)
|
||||
"""
|
||||
env_global = os.getenv("SLASH_SYNC_GLOBAL", "true").strip().lower() in ("1", "true", "yes", "on")
|
||||
do_global = global_sync and env_global
|
||||
sync_all = os.getenv("SLASH_SYNC_ALL_GUILDS", "true").strip().lower() in ("1", "true", "yes", "on")
|
||||
env_guild_ids = _parse_guild_ids(os.getenv("SLASH_GUILD_IDS"))
|
||||
|
||||
removed = _prune_tree_to_limit(bot)
|
||||
if removed:
|
||||
logger.warning(
|
||||
"Pruned %s top-level slash command(s) to stay under Discord's %s limit: %s",
|
||||
len(removed),
|
||||
MAX_TOP_LEVEL,
|
||||
", ".join(removed[:20]) + ("…" if len(removed) > 20 else ""),
|
||||
)
|
||||
print(
|
||||
f"\033[33m◈ Slash tree pruned by {len(removed)} (Discord max {MAX_TOP_LEVEL} top-level)\033[0m"
|
||||
)
|
||||
|
||||
local_count = _tree_command_count(bot)
|
||||
result: dict = {
|
||||
"local_tree": local_count,
|
||||
"global": None,
|
||||
"guilds": {},
|
||||
"errors": [],
|
||||
"pruned": removed,
|
||||
}
|
||||
|
||||
async def _try_sync(label: str, factory):
|
||||
try:
|
||||
synced = await factory()
|
||||
return synced, None
|
||||
except Exception as e:
|
||||
detail = str(e)
|
||||
logger.error("%s failed: %s", label, detail)
|
||||
dropped = []
|
||||
for cmd in list(bot.tree.get_commands()):
|
||||
if cmd.name in detail or getattr(cmd, "qualified_name", "") in detail:
|
||||
bot.tree.remove_command(cmd.name)
|
||||
dropped.append(cmd.name)
|
||||
if dropped:
|
||||
print(f"\033[33m◈ Removed invalid slash cmd(s) after error: {', '.join(dropped)}\033[0m")
|
||||
try:
|
||||
synced = await factory()
|
||||
return synced, None
|
||||
except Exception as e2:
|
||||
return None, f"{label}: {e2}"
|
||||
return None, f"{label}: {e}"
|
||||
|
||||
if do_global:
|
||||
synced, err = await _try_sync("Global slash sync", lambda: bot.tree.sync())
|
||||
if err:
|
||||
result["errors"].append(err)
|
||||
print(f"\033[31m◈ {err}\033[0m")
|
||||
else:
|
||||
result["global"] = len(synced or [])
|
||||
print(f"◈ Slash sync (global): {result['global']} command(s)")
|
||||
|
||||
target_guilds: list[discord.abc.Snowflake] = []
|
||||
if guilds is not None:
|
||||
target_guilds = list(guilds)
|
||||
elif env_guild_ids:
|
||||
target_guilds = [discord.Object(id=gid) for gid in env_guild_ids]
|
||||
elif sync_all:
|
||||
target_guilds = list(bot.guilds)
|
||||
|
||||
for guild in target_guilds:
|
||||
gid = getattr(guild, "id", guild)
|
||||
|
||||
def _make_factory(g=guild):
|
||||
async def _factory():
|
||||
bot.tree.copy_global_to(guild=g)
|
||||
return await bot.tree.sync(guild=g)
|
||||
return _factory
|
||||
|
||||
synced, err = await _try_sync(f"Guild {gid} slash sync", _make_factory())
|
||||
if err:
|
||||
result["errors"].append(err)
|
||||
print(f"\033[31m◈ {err}\033[0m")
|
||||
else:
|
||||
result["guilds"][str(gid)] = len(synced or [])
|
||||
print(f"◈ Slash sync (guild {gid}): {result['guilds'][str(gid)]} command(s) — instant")
|
||||
await asyncio.sleep(0.35)
|
||||
|
||||
prefix_count = len(list(bot.commands))
|
||||
print(
|
||||
f"Synced Total {prefix_count} Client Commands and "
|
||||
f"{result.get('global') or local_count} Slash Commands"
|
||||
+ (f" (guild-synced: {len(result['guilds'])})" if result["guilds"] else "")
|
||||
)
|
||||
return result
|
||||
Reference in New Issue
Block a user