update
This commit is contained in:
@@ -49,57 +49,137 @@ class GuardDenHelpCommand(commands.HelpCommand):
|
|||||||
"""Get description for a cog."""
|
"""Get description for a cog."""
|
||||||
return self.CATEGORY_DESCRIPTIONS.get(cog_name, "Commands")
|
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:
|
async def send_bot_help(self, mapping: dict) -> None:
|
||||||
"""Send the main help menu showing all categories."""
|
"""Send the main help menu showing all commands with detailed information."""
|
||||||
embed = discord.Embed(
|
embeds = []
|
||||||
title="GuardDen Help Menu",
|
prefix = self.context.clean_prefix
|
||||||
description="A comprehensive Discord moderation bot",
|
|
||||||
|
# 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(),
|
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():
|
for cog, cog_commands in mapping.items():
|
||||||
if cog is None:
|
if cog is None:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# Filter commands the user can actually run
|
# Get all commands (don't filter by permissions for full overview)
|
||||||
filtered = await self.filter_commands(cog_commands, sort=True)
|
all_commands = sorted(cog_commands, key=lambda c: c.qualified_name)
|
||||||
if not filtered:
|
if not all_commands:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
cog_name = cog.qualified_name
|
cog_name = cog.qualified_name
|
||||||
display_name = self.get_cog_display_name(cog_name)
|
display_name = self.get_cog_display_name(cog_name)
|
||||||
description = self.get_cog_description(cog_name)
|
|
||||||
|
|
||||||
embed.add_field(
|
# Create embed for this category
|
||||||
name=display_name,
|
embed = discord.Embed(
|
||||||
value=description,
|
title=display_name,
|
||||||
inline=False,
|
description=self.get_cog_description(cog_name),
|
||||||
|
color=discord.Color.gold() if "Admin" in display_name else discord.Color.blue(),
|
||||||
)
|
)
|
||||||
|
|
||||||
# Add usage instructions
|
# Add each command with full details
|
||||||
prefix = self.context.clean_prefix
|
for command in all_commands:
|
||||||
embed.add_field(
|
perm_text, _ = self._get_permission_info(command)
|
||||||
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)")
|
# 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=f"`{full_signature}`",
|
||||||
|
value=description,
|
||||||
|
inline=False,
|
||||||
|
)
|
||||||
|
|
||||||
|
embeds.append(embed)
|
||||||
|
|
||||||
|
# Send all embeds
|
||||||
channel = self.get_destination()
|
channel = self.get_destination()
|
||||||
await channel.send(embed=embed)
|
for embed in embeds:
|
||||||
|
await channel.send(embed=embed)
|
||||||
|
|
||||||
async def send_cog_help(self, cog: commands.Cog) -> None:
|
async def send_cog_help(self, cog: commands.Cog) -> None:
|
||||||
"""Send help for a specific category/cog."""
|
"""Send help for a specific category/cog."""
|
||||||
# Filter commands the user can run
|
# Get all commands (show all, not just what user can run)
|
||||||
filtered = await self.filter_commands(cog.get_commands(), sort=True)
|
all_commands = sorted(cog.get_commands(), key=lambda c: c.qualified_name)
|
||||||
|
|
||||||
if not filtered:
|
if not all_commands:
|
||||||
await self.get_destination().send(
|
await self.get_destination().send(f"No commands available in this category.")
|
||||||
f"No commands available in this category or you lack permissions to use them."
|
|
||||||
)
|
|
||||||
return
|
return
|
||||||
|
|
||||||
cog_name = cog.qualified_name
|
cog_name = cog.qualified_name
|
||||||
@@ -107,12 +187,16 @@ class GuardDenHelpCommand(commands.HelpCommand):
|
|||||||
|
|
||||||
embed = discord.Embed(
|
embed = discord.Embed(
|
||||||
title=f"{display_name} Commands",
|
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(),
|
color=discord.Color.gold() if "Admin" in display_name else discord.Color.blue(),
|
||||||
)
|
)
|
||||||
|
|
||||||
# Group commands by type (regular vs groups)
|
# Show each command with full details
|
||||||
for command in filtered:
|
for command in all_commands:
|
||||||
|
# Get permission info
|
||||||
|
perm_text, _ = self._get_permission_info(command)
|
||||||
|
|
||||||
# Get command signature
|
# Get command signature
|
||||||
signature = self.get_command_signature(command)
|
signature = self.get_command_signature(command)
|
||||||
|
|
||||||
@@ -120,30 +204,34 @@ class GuardDenHelpCommand(commands.HelpCommand):
|
|||||||
desc_parts = []
|
desc_parts = []
|
||||||
if command.help:
|
if command.help:
|
||||||
desc_parts.append(command.help.split("\n")[0]) # First line only
|
desc_parts.append(command.help.split("\n")[0]) # First line only
|
||||||
|
else:
|
||||||
|
desc_parts.append("No description available")
|
||||||
|
|
||||||
if command.aliases:
|
if command.aliases:
|
||||||
desc_parts.append(f"*Aliases: {', '.join(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(
|
embed.add_field(
|
||||||
name=signature,
|
name=f"`{signature}`",
|
||||||
value=description,
|
value=description,
|
||||||
inline=False,
|
inline=False,
|
||||||
)
|
)
|
||||||
|
|
||||||
# Add permission requirements if applicable
|
embed.set_footer(text=f"Use {self.context.clean_prefix}help <command> for detailed info")
|
||||||
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))
|
|
||||||
|
|
||||||
channel = self.get_destination()
|
channel = self.get_destination()
|
||||||
await channel.send(embed=embed)
|
await channel.send(embed=embed)
|
||||||
@@ -199,10 +287,12 @@ class GuardDenHelpCommand(commands.HelpCommand):
|
|||||||
|
|
||||||
async def send_command_help(self, command: commands.Command) -> None:
|
async def send_command_help(self, command: commands.Command) -> None:
|
||||||
"""Send help for a specific command."""
|
"""Send help for a specific command."""
|
||||||
|
perm_text, perm_color = self._get_permission_info(command)
|
||||||
|
|
||||||
embed = discord.Embed(
|
embed = discord.Embed(
|
||||||
title=f"Command: {command.qualified_name}",
|
title=f"Command: {command.qualified_name}",
|
||||||
description=command.help or "No description available",
|
description=command.help or "No description available",
|
||||||
color=discord.Color.green(),
|
color=perm_color,
|
||||||
)
|
)
|
||||||
|
|
||||||
# Add usage
|
# Add usage
|
||||||
@@ -213,6 +303,13 @@ class GuardDenHelpCommand(commands.HelpCommand):
|
|||||||
inline=False,
|
inline=False,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Add permission requirement prominently
|
||||||
|
embed.add_field(
|
||||||
|
name="Permission Required",
|
||||||
|
value=perm_text,
|
||||||
|
inline=False,
|
||||||
|
)
|
||||||
|
|
||||||
# Add aliases
|
# Add aliases
|
||||||
if command.aliases:
|
if command.aliases:
|
||||||
embed.add_field(
|
embed.add_field(
|
||||||
@@ -225,12 +322,20 @@ class GuardDenHelpCommand(commands.HelpCommand):
|
|||||||
if command.clean_params:
|
if command.clean_params:
|
||||||
params_text = []
|
params_text = []
|
||||||
for param_name, param in command.clean_params.items():
|
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
|
# Determine if required or optional
|
||||||
if param.default is param.empty:
|
if param.default is param.empty:
|
||||||
params_text.append(f"`{param_name}` - Required parameter")
|
params_text.append(f"`{param_name}`{param_type} - **Required**")
|
||||||
else:
|
else:
|
||||||
default_val = param.default if param.default is not None else "None"
|
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:
|
if params_text:
|
||||||
embed.add_field(
|
embed.add_field(
|
||||||
@@ -239,26 +344,10 @@ class GuardDenHelpCommand(commands.HelpCommand):
|
|||||||
inline=False,
|
inline=False,
|
||||||
)
|
)
|
||||||
|
|
||||||
# Add permission requirements
|
# Add category info
|
||||||
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)")
|
|
||||||
|
|
||||||
if command.cog:
|
if command.cog:
|
||||||
cog_name = command.cog.qualified_name
|
cog_name = command.cog.qualified_name
|
||||||
footer_parts.append(f"Category: {self.get_cog_display_name(cog_name)}")
|
embed.set_footer(text=f"Category: {self.get_cog_display_name(cog_name)}")
|
||||||
|
|
||||||
if footer_parts:
|
|
||||||
embed.set_footer(text=" | ".join(footer_parts))
|
|
||||||
|
|
||||||
channel = self.get_destination()
|
channel = self.get_destination()
|
||||||
await channel.send(embed=embed)
|
await channel.send(embed=embed)
|
||||||
|
|||||||
Reference in New Issue
Block a user