введите здесь описание изображения. Я много отлаживал и рефакторил это, но до сих пор не нашел исправления.
Цель этой команды — отключить определенную команду в гильдии, но не глобально, чтобы пользователи могли отключить некоторые команды, которые они считают нужными.
Мне интересно, есть ли конкретная строка, которая обходит это?
Мой код:
import discord
from discord.ext import commands
from hanni.core.database import db
async def is_disabled(guild_id: int, command_name: str) -> bool:
doc = await db.disabled_commands.find_one({
"guild_id": guild_id,
"command": command_name,
})
return doc is not None
class CommandToggle(commands.Cog, name="Command Toggle"):
"""Per-guild command enable / disable management."""
def __init__(self, bot: commands.Bot):
self.bot = bot
# Patch bot.invoke so we intercept BEFORE argument parsing and checks
self._original_invoke = bot.invoke
bot.invoke = self._patched_invoke
def cog_unload(self):
# Restore original invoke on unload
self.bot.invoke = self._original_invoke
async def _patched_invoke(self, ctx: commands.Context) -> None:
"""
Intercepts every command invocation at the earliest possible point —
before argument parsing, before checks, before anything.
This is the only reliable way to block disabled commands regardless
of what error would have fired (MissingRequiredArgument, etc.).
"""
if (
ctx.command is not None
and ctx.guild is not None
and not await self.bot.is_owner(ctx.author)
and not ctx.command.qualified_name.startswith("command")
):
if await is_disabled(ctx.guild.id, ctx.command.qualified_name):
await ctx.warn(f"`{ctx.command.qualified_name}` is disabled on this server.")
return # Dead stop — nothing else runs
await self._original_invoke(ctx)
def _resolve_command(self, name: str) -> commands.Command | None:
return self.bot.get_command(name)
@commands.group(name="command", invoke_without_command=True)
@commands.guild_only()
@commands.has_permissions(manage_guild=True)
async def _command(self, ctx: commands.Context):
"""Manage per-guild command toggles."""
await ctx.send_help(ctx.command)
@_command.command(name="disable")
@commands.guild_only()
@commands.has_permissions(manage_guild=True)
async def cmd_disable(self, ctx: commands.Context, *, command_name: str):
"""Disable a command on this server."""
cmd = self._resolve_command(command_name)
if cmd is None:
return await ctx.warn(f"No command named `{command_name}` exists.")
if cmd.qualified_name.startswith("command"):
return await ctx.warn("You cannot disable command management commands.")
if await is_disabled(ctx.guild.id, cmd.qualified_name):
return await ctx.warn(f"`{cmd.qualified_name}` is already disabled on this server.")
await db.disabled_commands.insert_one({
"guild_id": ctx.guild.id,
"command": cmd.qualified_name,
"disabled_by": ctx.author.id,
})
await ctx.approve(f"`{cmd.qualified_name}` has been disabled on this server.")
@_command.command(name="enable")
@commands.guild_only()
@commands.has_permissions(manage_guild=True)
async def cmd_enable(self, ctx: commands.Context, *, command_name: str):
"""Re-enable a previously disabled command on this server."""
cmd = self._resolve_command(command_name)
qualified = cmd.qualified_name if cmd else command_name
result = await db.disabled_commands.delete_one({
"guild_id": ctx.guild.id,
"command": qualified,
})
if result.deleted_count == 0:
return await ctx.warn(f"`{qualified}` is not currently disabled on this server.")
await ctx.approve(f"`{qualified}` has been re-enabled on this server.")
@_command.command(name="list")
@commands.guild_only()
@commands.has_permissions(manage_guild=True)
async def cmd_list(self, ctx: commands.Context):
"""List all commands currently disabled on this server."""
docs = await db.disabled_commands.find(
{"guild_id": ctx.guild.id}
).to_list(length=None)
if not docs:
return await ctx.warn("No commands are disabled on this server.")
lines = []
for doc in docs:
disabler = f"" if "disabled_by" in doc else "unknown"
lines.append(f"`{doc['command']}` — disabled by {disabler}")
embed = discord.Embed(
title="Disabled Commands",
description="\n".join(lines),
color=discord.Color.blurple(),
)
embed.set_footer(text=f"{ctx.guild.name} • {len(docs)} command(s) disabled")
await ctx.send(embed=embed)
async def setup(bot: commands.Bot):
await bot.add_cog(CommandToggle(bot))