From b06b0cdb66cadfc9bc18207992aa08493b6d3ffe Mon Sep 17 00:00:00 2001 From: neoarz Date: Thu, 9 Oct 2025 22:56:43 -0400 Subject: [PATCH] refactor(serverinfo): new info Enhanced the server info embed with more detailed statistics and improved formatting. Updated help command to send responses in the channel when possible, with fallback to DMs if sending fails, and added error handling for users with DMs disabled. Made botinfo embed non-ephemeral and added a custom emoji to the description. --- cogs/botinfo.py | 6 +- cogs/general/serverinfo.py | 125 +++++++++++++++++++++++++++++++------ cogs/help.py | 32 ++++++++-- 3 files changed, 136 insertions(+), 27 deletions(-) diff --git a/cogs/botinfo.py b/cogs/botinfo.py index 12863f1..dac5dea 100644 --- a/cogs/botinfo.py +++ b/cogs/botinfo.py @@ -92,7 +92,7 @@ class BotInfo(commands.Cog, name="botinfo"): current_time = datetime.now().strftime("%m/%d/%y, %I:%M %p") description_text = ( - "Heyooo! Im Syntrel, a bot made to help with [SideStore](https://discord.gg/3DwCwpBHfv), [MeloNX](https://discord.gg/Q4VkbkYfmk), and [idevice](https://discord.gg/ZnNcrRT3M8). I even have some cool extras! If you encounter any issues, please file a bug report. If you have any feedback or suggestions, simply select \"Feedback\"!\n\n" + "Heyooo! Im Syntrel, a bot made to help with [SideStore](https://discord.gg/3DwCwpBHfv), [MeloNX](https://discord.gg/Q4VkbkYfmk), and [idevice](https://discord.gg/ZnNcrRT3M8). I even have some cool extras! If you encounter any issues, please file a bug report. If you have any feedback or suggestions, simply select \"Feedback\"! <:HeardPanda:1417619745896660992>\n\n" f"**Owner:** [neoarz](https://discordapp.com/users/1015372540937502851)\n" f"**Python Version:** {platform.python_version()}\n" f"**Prefix:** / (Slash Commands) or {self.bot.bot_prefix} for normal commands" @@ -123,7 +123,7 @@ class BotInfo(commands.Cog, name="botinfo"): current_time = datetime.now().strftime("%m/%d/%y, %I:%M %p") description_text = ( - "Heyooo! Im Syntrel, a bot made to help with [SideStore](https://discord.gg/3DwCwpBHfv), [MeloNX](https://discord.gg/Q4VkbkYfmk), and [idevice](https://discord.gg/ZnNcrRT3M8). I even have some cool extras! If you encounter any issues, please file a bug report. If have any feedback or suggestions, simply select “Feedback”!\n\n" + "Heyooo! Im Syntrel, a bot made to help with [SideStore](https://discord.gg/3DwCwpBHfv), [MeloNX](https://discord.gg/Q4VkbkYfmk), and [idevice](https://discord.gg/ZnNcrRT3M8). I even have some cool extras! If you encounter any issues, please file a bug report. If you have any feedback or suggestions, simply select \"Feedback\"! <:HeardPanda:1417619745896660992>\n\n" f"**Owner:** [neoarz](https://discordapp.com/users/1015372540937502851)\n" f"**Python Version:** {platform.python_version()}\n" f"**Prefix:** / (Slash Commands) or {self.bot.bot_prefix} for normal commands" @@ -141,7 +141,7 @@ class BotInfo(commands.Cog, name="botinfo"): view = BotInfoView(self.bot) if context.interaction: - await context.interaction.response.send_message(embed=embed, view=view, ephemeral=True) + await context.interaction.response.send_message(embed=embed, view=view, ephemeral=False) else: await context.send(embed=embed, view=view) diff --git a/cogs/general/serverinfo.py b/cogs/general/serverinfo.py index 691b830..f8cb4cf 100644 --- a/cogs/general/serverinfo.py +++ b/cogs/general/serverinfo.py @@ -11,37 +11,122 @@ def serverinfo_command(): if context.guild is None: await context.send("This command can only be used in a server, not in DMs!") return - - roles = [role.name for role in context.guild.roles] - num_roles = len(roles) - if num_roles > 50: - roles = roles[:50] - roles.append(f">>>> Displaying [50/{num_roles}] Roles") - roles = ", ".join(roles) + + guild = context.guild + + text_channels = len([c for c in guild.channels if isinstance(c, discord.TextChannel)]) + voice_channels = len([c for c in guild.channels if isinstance(c, discord.VoiceChannel)]) + category_channels = len([c for c in guild.channels if isinstance(c, discord.CategoryChannel)]) + forum_channels = len([c for c in guild.channels if isinstance(c, discord.ForumChannel)]) + stage_channels = len([c for c in guild.channels if isinstance(c, discord.StageChannel)]) + + age_restricted = len([c for c in guild.channels if hasattr(c, 'nsfw') and c.nsfw]) + hidden_channels = len([c for c in guild.channels if c.permissions_for(guild.default_role).view_channel == False]) + + managed_roles = len([r for r in guild.roles if r.managed]) + + animated_emojis = len([e for e in guild.emojis if e.animated]) + managed_emojis = len([e for e in guild.emojis if e.managed]) + unavailable_emojis = len([e for e in guild.emojis if not e.available]) + + png_stickers = len([s for s in guild.stickers if s.format == discord.StickerFormatType.png]) + apng_stickers = len([s for s in guild.stickers if s.format == discord.StickerFormatType.apng]) + gif_stickers = len([s for s in guild.stickers if s.format == discord.StickerFormatType.lottie]) + lottie_stickers = len([s for s in guild.stickers if s.format == discord.StickerFormatType.lottie]) + + online_members = len([m for m in guild.members if m.status == discord.Status.online]) + idle_members = len([m for m in guild.members if m.status == discord.Status.idle]) + dnd_members = len([m for m in guild.members if m.status == discord.Status.dnd]) + offline_members = len([m for m in guild.members if m.status == discord.Status.offline]) + + bot_count = len([m for m in guild.members if m.bot]) + human_count = guild.member_count - bot_count + + created_delta = discord.utils.utcnow() - guild.created_at + years_ago = created_delta.days // 365 embed = discord.Embed( - title="**Server Name:**", - description=f"{context.guild}", + title=f"**Server Name:** {guild.name}", color=0x7289DA ).set_author(name="Server Information", icon_url="https://yes.nighty.works/raw/gSxqzV.png") - if context.guild.icon is not None: - embed.set_thumbnail(url=context.guild.icon.url) - - embed.add_field(name="Server ID", value=context.guild.id) - embed.add_field(name="Member Count", value=context.guild.member_count) + if guild.icon is not None: + embed.set_thumbnail(url=guild.icon.url) + + owner_value = guild.owner.mention if guild.owner else (f"<@{guild.owner_id}>" if guild.owner_id else "Unknown") embed.add_field( - name="Text/Voice Channels", - value=f"{len(context.guild.channels)}" + name="Owner", + value=owner_value, + inline=True ) + embed.add_field( - name=f"Roles ({len(context.guild.roles)})", - value=roles + name="Created", + value=f"{years_ago} year{'s' if years_ago != 1 else ''} ago", + inline=True ) - embed.set_footer(text=f"Created at: {context.guild.created_at.strftime('%m/%d/%Y')}") + + embed.add_field( + name="Max Members", + value=f"{guild.max_members:,}" if guild.max_members else "Unknown", + inline=True + ) + + boost_level = guild.premium_tier + boost_count = guild.premium_subscription_count or 0 + embed.add_field( + name="Boost Status", + value=f"Level {boost_level}, {boost_count} Boost{'s' if boost_count != 1 else ''}", + inline=False + ) + + channels_info = f"{text_channels} text, {voice_channels} voice, {category_channels} category" + if forum_channels > 0: + channels_info += f", {forum_channels} forum" + if stage_channels > 0: + channels_info += f", {stage_channels} stage" + channels_info += f"\n{age_restricted} age restricted, {hidden_channels} hidden" + + embed.add_field( + name=f"Channels ({len(guild.channels)})", + value=channels_info, + inline=True + ) + + roles_info = f"{len(guild.roles)} total\n{managed_roles} managed" + embed.add_field( + name=f"Roles ({len(guild.roles)})", + value=roles_info, + inline=True + ) + + emotes_info = f"{len(guild.emojis)} total\n{animated_emojis} animated, {managed_emojis} managed" + if unavailable_emojis > 0: + emotes_info += f"\n{unavailable_emojis} unavailable" + embed.add_field( + name=f"Emotes ({len(guild.emojis)})", + value=emotes_info, + inline=True + ) + + if len(guild.stickers) > 0: + stickers_info = f"{len(guild.stickers)} total\n{png_stickers} PNG, {apng_stickers} APNG, {gif_stickers} GIF, {lottie_stickers} Lottie" + embed.add_field( + name=f"Stickers ({len(guild.stickers)})", + value=stickers_info, + inline=True + ) + + embed.add_field( + name="Member Count", + value=f"{guild.member_count}", + inline=False + ) + + embed.set_footer(text=f"Server ID: {guild.id} • Created: {guild.created_at.strftime('%m/%d/%Y')}") if getattr(context, "interaction", None): - await context.interaction.response.send_message(embed=embed, ephemeral=True) + await context.interaction.response.send_message(embed=embed, ephemeral=False) else: await context.send(embed=embed) diff --git a/cogs/help.py b/cogs/help.py index 672ac72..bc0bdd6 100644 --- a/cogs/help.py +++ b/cogs/help.py @@ -112,7 +112,13 @@ class Help(commands.Cog, name="help"): if context.interaction: await context.interaction.response.send_message(embed=embed, ephemeral=True) else: - await context.author.send(embed=embed) + try: + await context.send(embed=embed) + except (discord.Forbidden, discord.HTTPException): + try: + await context.author.send(embed=embed) + except discord.Forbidden: + pass # User has DMs disabled return category = category.lower() @@ -125,7 +131,13 @@ class Help(commands.Cog, name="help"): if context.interaction: await context.interaction.response.send_message(embed=embed, ephemeral=True) else: - await context.author.send(embed=embed) + try: + await context.send(embed=embed) + except (discord.Forbidden, discord.HTTPException): + try: + await context.author.send(embed=embed) + except discord.Forbidden: + pass return @@ -179,7 +191,13 @@ class Help(commands.Cog, name="help"): if context.interaction: await context.interaction.response.send_message(embed=embed, ephemeral=True) else: - await context.author.send(embed=embed) + try: + await context.send(embed=embed) + except (discord.Forbidden, discord.HTTPException): + try: + await context.author.send(embed=embed) + except discord.Forbidden: + pass return embed = discord.Embed( @@ -199,7 +217,13 @@ class Help(commands.Cog, name="help"): if context.interaction: await context.interaction.response.send_message(embed=embed, ephemeral=True) else: - await context.author.send(embed=embed) + try: + await context.send(embed=embed) + except (discord.Forbidden, discord.HTTPException): + try: + await context.author.send(embed=embed) + except discord.Forbidden: + pass async def setup(bot) -> None: