update
This commit is contained in:
@@ -49,57 +49,137 @@ class GuardDenHelpCommand(commands.HelpCommand):
|
||||
"""Get description for a cog."""
|
||||
return self.CATEGORY_DESCRIPTIONS.get(cog_name, "Commands")
|
||||
|
||||
def _get_permission_info(self, command: commands.Command) -> tuple[str, discord.Color]:
|
||||
"""Get permission requirement text and color for a command."""
|
||||
# Check cog-level restrictions
|
||||
if command.cog:
|
||||
cog_name = command.cog.qualified_name
|
||||
if cog_name == "Admin":
|
||||
return "🔒 Admin Only", discord.Color.red()
|
||||
elif cog_name == "Moderation":
|
||||
return "🛡️ Moderator/Owner", discord.Color.orange()
|
||||
elif cog_name == "WordlistSync":
|
||||
return "🔒 Admin Only", discord.Color.red()
|
||||
|
||||
# Check command-level checks
|
||||
if hasattr(command.callback, "__commands_checks__"):
|
||||
checks = command.callback.__commands_checks__
|
||||
for check in checks:
|
||||
check_name = getattr(check, "__name__", "")
|
||||
if "is_owner" in check_name:
|
||||
return "👑 Bot Owner Only", discord.Color.dark_red()
|
||||
elif "has_permissions" in check_name or "administrator" in check_name:
|
||||
return "🔒 Admin Only", discord.Color.red()
|
||||
|
||||
return "👥 Everyone", discord.Color.green()
|
||||
|
||||
async def send_bot_help(self, mapping: dict) -> None:
|
||||
"""Send the main help menu showing all categories."""
|
||||
embed = discord.Embed(
|
||||
title="GuardDen Help Menu",
|
||||
description="A comprehensive Discord moderation bot",
|
||||
"""Send the main help menu showing all commands with detailed information."""
|
||||
embeds = []
|
||||
prefix = self.context.clean_prefix
|
||||
|
||||
# Create overview embed
|
||||
overview = discord.Embed(
|
||||
title="📚 GuardDen Help - All Commands",
|
||||
description=f"A comprehensive Discord moderation bot\n\n"
|
||||
f"**Legend:**\n"
|
||||
f"👥 Everyone can use | 🛡️ Moderators/Owners | 🔒 Admins | 👑 Bot Owner",
|
||||
color=discord.Color.blue(),
|
||||
)
|
||||
overview.set_footer(text=f"Prefix: {prefix} (customizable per server)")
|
||||
embeds.append(overview)
|
||||
|
||||
# Filter and display categories
|
||||
# Collect all commands organized by category
|
||||
for cog, cog_commands in mapping.items():
|
||||
if cog is None:
|
||||
continue
|
||||
|
||||
# Filter commands the user can actually run
|
||||
filtered = await self.filter_commands(cog_commands, sort=True)
|
||||
if not filtered:
|
||||
# Get all commands (don't filter by permissions for full overview)
|
||||
all_commands = sorted(cog_commands, key=lambda c: c.qualified_name)
|
||||
if not all_commands:
|
||||
continue
|
||||
|
||||
cog_name = cog.qualified_name
|
||||
display_name = self.get_cog_display_name(cog_name)
|
||||
description = self.get_cog_description(cog_name)
|
||||
|
||||
# Create embed for this category
|
||||
embed = discord.Embed(
|
||||
title=display_name,
|
||||
description=self.get_cog_description(cog_name),
|
||||
color=discord.Color.gold() if "Admin" in display_name else discord.Color.blue(),
|
||||
)
|
||||
|
||||
# Add each command with full details
|
||||
for command in all_commands:
|
||||
perm_text, _ = self._get_permission_info(command)
|
||||
|
||||
# Build command signature with all parameters
|
||||
signature_parts = [command.name]
|
||||
if command.signature:
|
||||
signature_parts.append(command.signature)
|
||||
|
||||
full_signature = f"{prefix}{' '.join(signature_parts)}"
|
||||
|
||||
# Build description
|
||||
desc_parts = []
|
||||
|
||||
# Add help text
|
||||
if command.help:
|
||||
desc_parts.append(command.help.split("\n")[0])
|
||||
else:
|
||||
desc_parts.append("No description available")
|
||||
|
||||
# Add aliases if present
|
||||
if command.aliases:
|
||||
desc_parts.append(f"*Aliases: {', '.join(command.aliases)}*")
|
||||
|
||||
# Add permission requirement
|
||||
desc_parts.append(f"**Permission:** {perm_text}")
|
||||
|
||||
# Add parameter details if present
|
||||
if command.clean_params:
|
||||
param_details = []
|
||||
for param_name, param in command.clean_params.items():
|
||||
if param.default is param.empty:
|
||||
param_details.append(f"`{param_name}` (required)")
|
||||
else:
|
||||
default_val = param.default if param.default is not None else "None"
|
||||
param_details.append(f"`{param_name}` (default: {default_val})")
|
||||
|
||||
if param_details:
|
||||
desc_parts.append(f"**Options:** {', '.join(param_details)}")
|
||||
|
||||
# Handle subcommands for groups
|
||||
if isinstance(command, commands.Group):
|
||||
subcommands = list(command.commands)
|
||||
if subcommands:
|
||||
subcommand_names = ", ".join(
|
||||
f"`{cmd.name}`" for cmd in sorted(subcommands, key=lambda c: c.name)
|
||||
)
|
||||
desc_parts.append(f"**Subcommands:** {subcommand_names}")
|
||||
|
||||
description = "\n".join(desc_parts)
|
||||
|
||||
embed.add_field(
|
||||
name=display_name,
|
||||
name=f"`{full_signature}`",
|
||||
value=description,
|
||||
inline=False,
|
||||
)
|
||||
|
||||
# Add usage instructions
|
||||
prefix = self.context.clean_prefix
|
||||
embed.add_field(
|
||||
name="Usage",
|
||||
value=f"Use `{prefix}help <category>` for category commands\n"
|
||||
f"Use `{prefix}help <command>` for detailed help",
|
||||
inline=False,
|
||||
)
|
||||
|
||||
embed.set_footer(text=f"Prefix: {prefix} (customizable per server)")
|
||||
embeds.append(embed)
|
||||
|
||||
# Send all embeds
|
||||
channel = self.get_destination()
|
||||
for embed in embeds:
|
||||
await channel.send(embed=embed)
|
||||
|
||||
async def send_cog_help(self, cog: commands.Cog) -> None:
|
||||
"""Send help for a specific category/cog."""
|
||||
# Filter commands the user can run
|
||||
filtered = await self.filter_commands(cog.get_commands(), sort=True)
|
||||
# Get all commands (show all, not just what user can run)
|
||||
all_commands = sorted(cog.get_commands(), key=lambda c: c.qualified_name)
|
||||
|
||||
if not filtered:
|
||||
await self.get_destination().send(
|
||||
f"No commands available in this category or you lack permissions to use them."
|
||||
)
|
||||
if not all_commands:
|
||||
await self.get_destination().send(f"No commands available in this category.")
|
||||
return
|
||||
|
||||
cog_name = cog.qualified_name
|
||||
@@ -107,12 +187,16 @@ class GuardDenHelpCommand(commands.HelpCommand):
|
||||
|
||||
embed = discord.Embed(
|
||||
title=f"{display_name} Commands",
|
||||
description=cog.description or "Commands in this category",
|
||||
description=f"{cog.description or 'Commands in this category'}\n\n"
|
||||
f"**Legend:** 👥 Everyone | 🛡️ Moderators/Owners | 🔒 Admins | 👑 Bot Owner",
|
||||
color=discord.Color.gold() if "Admin" in display_name else discord.Color.blue(),
|
||||
)
|
||||
|
||||
# Group commands by type (regular vs groups)
|
||||
for command in filtered:
|
||||
# Show each command with full details
|
||||
for command in all_commands:
|
||||
# Get permission info
|
||||
perm_text, _ = self._get_permission_info(command)
|
||||
|
||||
# Get command signature
|
||||
signature = self.get_command_signature(command)
|
||||
|
||||
@@ -120,30 +204,34 @@ class GuardDenHelpCommand(commands.HelpCommand):
|
||||
desc_parts = []
|
||||
if command.help:
|
||||
desc_parts.append(command.help.split("\n")[0]) # First line only
|
||||
else:
|
||||
desc_parts.append("No description available")
|
||||
|
||||
if command.aliases:
|
||||
desc_parts.append(f"*Aliases: {', '.join(command.aliases)}*")
|
||||
|
||||
description = "\n".join(desc_parts) if desc_parts else "No description available"
|
||||
# Add permission info
|
||||
desc_parts.append(f"**Permission:** {perm_text}")
|
||||
|
||||
# Add parameter info
|
||||
if command.clean_params:
|
||||
param_count = len(command.clean_params)
|
||||
required_count = sum(
|
||||
1 for p in command.clean_params.values() if p.default is p.empty
|
||||
)
|
||||
desc_parts.append(
|
||||
f"**Parameters:** {required_count} required, {param_count - required_count} optional"
|
||||
)
|
||||
|
||||
description = "\n".join(desc_parts)
|
||||
|
||||
embed.add_field(
|
||||
name=signature,
|
||||
name=f"`{signature}`",
|
||||
value=description,
|
||||
inline=False,
|
||||
)
|
||||
|
||||
# Add permission requirements if applicable
|
||||
if hasattr(cog, "cog_check"):
|
||||
# Try to determine permissions
|
||||
footer_parts = []
|
||||
|
||||
# Check common permission patterns
|
||||
if "Admin" in display_name or "Config" in display_name:
|
||||
footer_parts.append("Requires: Administrator permission")
|
||||
elif "Moderation" in display_name:
|
||||
footer_parts.append("Requires: Kick Members or Ban Members permission")
|
||||
|
||||
if footer_parts:
|
||||
embed.set_footer(text=" | ".join(footer_parts))
|
||||
embed.set_footer(text=f"Use {self.context.clean_prefix}help <command> for detailed info")
|
||||
|
||||
channel = self.get_destination()
|
||||
await channel.send(embed=embed)
|
||||
@@ -199,10 +287,12 @@ class GuardDenHelpCommand(commands.HelpCommand):
|
||||
|
||||
async def send_command_help(self, command: commands.Command) -> None:
|
||||
"""Send help for a specific command."""
|
||||
perm_text, perm_color = self._get_permission_info(command)
|
||||
|
||||
embed = discord.Embed(
|
||||
title=f"Command: {command.qualified_name}",
|
||||
description=command.help or "No description available",
|
||||
color=discord.Color.green(),
|
||||
color=perm_color,
|
||||
)
|
||||
|
||||
# Add usage
|
||||
@@ -213,6 +303,13 @@ class GuardDenHelpCommand(commands.HelpCommand):
|
||||
inline=False,
|
||||
)
|
||||
|
||||
# Add permission requirement prominently
|
||||
embed.add_field(
|
||||
name="Permission Required",
|
||||
value=perm_text,
|
||||
inline=False,
|
||||
)
|
||||
|
||||
# Add aliases
|
||||
if command.aliases:
|
||||
embed.add_field(
|
||||
@@ -225,12 +322,20 @@ class GuardDenHelpCommand(commands.HelpCommand):
|
||||
if command.clean_params:
|
||||
params_text = []
|
||||
for param_name, param in command.clean_params.items():
|
||||
# Get parameter annotation for type hint
|
||||
param_type = ""
|
||||
if param.annotation is not param.empty:
|
||||
type_name = getattr(param.annotation, "__name__", str(param.annotation))
|
||||
param_type = f" ({type_name})"
|
||||
|
||||
# Determine if required or optional
|
||||
if param.default is param.empty:
|
||||
params_text.append(f"`{param_name}` - Required parameter")
|
||||
params_text.append(f"`{param_name}`{param_type} - **Required**")
|
||||
else:
|
||||
default_val = param.default if param.default is not None else "None"
|
||||
params_text.append(f"`{param_name}` - Optional (default: {default_val})")
|
||||
params_text.append(
|
||||
f"`{param_name}`{param_type} - Optional (default: `{default_val}`)"
|
||||
)
|
||||
|
||||
if params_text:
|
||||
embed.add_field(
|
||||
@@ -239,26 +344,10 @@ class GuardDenHelpCommand(commands.HelpCommand):
|
||||
inline=False,
|
||||
)
|
||||
|
||||
# Add permission requirements
|
||||
footer_parts = []
|
||||
if hasattr(command.callback, "__commands_checks__"):
|
||||
# Try to extract permission requirements
|
||||
checks = command.callback.__commands_checks__
|
||||
for check in checks:
|
||||
check_name = getattr(check, "__name__", "")
|
||||
if "has_permissions" in check_name:
|
||||
footer_parts.append("Requires specific permissions")
|
||||
elif "is_owner" in check_name:
|
||||
footer_parts.append("Requires bot owner")
|
||||
elif "guild_only" in check_name:
|
||||
footer_parts.append("Guild only (no DMs)")
|
||||
|
||||
# Add category info
|
||||
if command.cog:
|
||||
cog_name = command.cog.qualified_name
|
||||
footer_parts.append(f"Category: {self.get_cog_display_name(cog_name)}")
|
||||
|
||||
if footer_parts:
|
||||
embed.set_footer(text=" | ".join(footer_parts))
|
||||
embed.set_footer(text=f"Category: {self.get_cog_display_name(cog_name)}")
|
||||
|
||||
channel = self.get_destination()
|
||||
await channel.send(embed=embed)
|
||||
|
||||
Reference in New Issue
Block a user