modified: bot.py

This commit is contained in:
SimolZimol
2025-08-19 22:07:26 +02:00
parent 6109a8beb8
commit 2097b2da11

234
bot.py
View File

@@ -1994,6 +1994,7 @@ async def modhelp(ctx):
"`/warn <user> [reason]` - Warn a user\n"
"`/mute <user> <duration> [reason]` - Mute a user temporarily\n"
"`/unmute <user>` - Manually unmute a user\n"
"`/modinfo [user]` - View comprehensive user information\n"
"`/modstats [user]` - View moderation statistics\n"
"`/processes <action> [type]` - Manage active processes\n"
"`/startgiveaway` - Create server giveaways\n"
@@ -2703,6 +2704,44 @@ def create_warnings_table():
if connection:
close_database_connection(connection)
async def get_user_warnings(user_id, guild_id):
"""Retrieves all warning records for a user"""
connection = None
cursor = None
try:
connection = connect_to_database()
cursor = connection.cursor()
select_query = """
SELECT id, moderator_id, reason, created_at
FROM user_warnings
WHERE user_id = %s AND guild_id = %s
ORDER BY created_at DESC
"""
cursor.execute(select_query, (user_id, guild_id))
results = cursor.fetchall()
warnings = []
for row in results:
warnings.append({
"id": row[0],
"moderator_id": row[1],
"reason": row[2],
"created_at": row[3]
})
return warnings
except Exception as e:
logger.error(f"Error retrieving user warnings: {e}")
return []
finally:
if cursor:
cursor.close()
if connection:
close_database_connection(connection)
async def save_user_roles(user_id, guild_id, roles):
"""Saves a user's roles before a mute"""
connection = None
@@ -3053,6 +3092,201 @@ async def mywarns(ctx):
logger.error(f"Error in mywarns command: {e}")
await ctx.send("❌ An error occurred while retrieving your warning information.")
@client.hybrid_command()
async def modinfo(ctx, user: discord.User = None):
"""Shows comprehensive moderation information about a user (Requires Permission Level 5 or higher)"""
try:
# Load moderator data
mod_data = await load_user_data(ctx.author.id, ctx.guild.id)
# Check moderation rights
if not check_moderation_permission(mod_data["permission"]):
embed = discord.Embed(
title="❌ Insufficient Permissions",
description="You need moderation permissions (Level 5 or higher) to use this command.",
color=0xff0000
)
await ctx.send(embed=embed, ephemeral=True)
return
# Default to command author if no user specified
if user is None:
user = ctx.author
# Get member object for additional Discord info
member = ctx.guild.get_member(user.id)
# Load user data
user_data = await load_user_data(user.id, ctx.guild.id)
# Get guild settings
guild_settings = get_guild_settings(ctx.guild.id)
warn_threshold = guild_settings.get("max_warn_threshold", 3)
# Get detailed warning records
warning_records = await get_user_warnings(user.id, ctx.guild.id)
# Create main embed
embed = discord.Embed(
title="🛡️ Moderation Information",
description=f"Comprehensive data for {user.mention}",
color=0x3498db,
timestamp=datetime.now()
)
# Basic user information
user_info = f"**Username:** {user.name}\n"
user_info += f"**Display Name:** {user.display_name}\n"
user_info += f"**User ID:** `{user.id}`\n"
if member:
user_info += f"**Joined Server:** <t:{int(member.joined_at.timestamp())}:F>\n"
user_info += f"**Joined Discord:** <t:{int(user.created_at.timestamp())}:F>\n"
# Account age
account_age = datetime.now(user.created_at.tzinfo) - user.created_at
server_age = datetime.now(member.joined_at.tzinfo) - member.joined_at
user_info += f"**Account Age:** {account_age.days} days\n"
user_info += f"**Server Membership:** {server_age.days} days"
else:
user_info += f"**Created:** <t:{int(user.created_at.timestamp())}:F>\n"
user_info += "**Status:** Not in server"
embed.add_field(name="👤 User Information", value=user_info, inline=True)
# Permission and role information
perm_info = f"**Permission Level:** {user_data['permission']}\n"
if member:
# Get roles (excluding @everyone)
roles = [role for role in member.roles if not role.is_default()]
if roles:
role_list = ", ".join([role.mention for role in roles[:10]]) # Limit to 10 roles
if len(roles) > 10:
role_list += f" +{len(roles) - 10} more"
perm_info += f"**Roles ({len(roles)}):** {role_list}\n"
else:
perm_info += "**Roles:** None\n"
# Highest role
highest_role = member.top_role
perm_info += f"**Highest Role:** {highest_role.mention}"
else:
perm_info += "**Roles:** User not in server"
embed.add_field(name="🎭 Permissions & Roles", value=perm_info, inline=True)
# Moderation statistics
mod_stats = f"**Warnings:** {user_data['warns']}/{warn_threshold}\n"
mod_stats += f"**Mutes:** {user_data['mutes']}\n"
mod_stats += f"**AI Violations:** {user_data['ai_ban']}\n"
# Calculate total infractions
total_infractions = user_data["warns"] + user_data["mutes"] + user_data["ai_ban"]
mod_stats += f"**Total Infractions:** {total_infractions}"
# Risk assessment
if total_infractions == 0:
risk_level = "🟢 Low Risk"
embed.color = 0x00ff00
elif total_infractions <= 2:
risk_level = "🟡 Medium Risk"
embed.color = 0xffa500
elif total_infractions <= 5:
risk_level = "🟠 High Risk"
embed.color = 0xff6600
else:
risk_level = "🔴 Critical Risk"
embed.color = 0xff0000
mod_stats += f"\n**Risk Level:** {risk_level}"
embed.add_field(name="📊 Moderation Statistics", value=mod_stats, inline=False)
# Recent warning history (last 3 warnings)
if warning_records:
warning_history = ""
display_count = min(3, len(warning_records))
for i in range(display_count):
record = warning_records[i]
moderator = ctx.guild.get_member(record["moderator_id"])
mod_name = moderator.display_name if moderator else f"ID: {record['moderator_id']}"
# Format date
warning_date = record["created_at"].strftime("%d.%m.%Y %H:%M")
# Truncate reason if too long
reason = record["reason"]
if len(reason) > 60:
reason = reason[:57] + "..."
warning_history += f"`{warning_date}` **{mod_name}**: {reason}\n"
if len(warning_records) > 3:
warning_history += f"*... and {len(warning_records) - 3} more warning(s)*"
embed.add_field(name="📋 Recent Warnings", value=warning_history, inline=False)
# Server activity (if member)
if member:
activity_info = ""
# Current status
if member.status != discord.Status.offline:
activity_info += f"**Status:** {str(member.status).title()}\n"
else:
activity_info += "**Status:** Offline\n"
# Current activity
if member.activity:
activity_type = str(member.activity.type).replace('ActivityType.', '').title()
activity_info += f"**Activity:** {activity_type} - {member.activity.name}\n"
# Voice channel
if member.voice:
activity_info += f"**Voice Channel:** {member.voice.channel.mention}\n"
# Mobile/Desktop
if member.is_on_mobile():
activity_info += "**Platform:** Mobile 📱"
else:
activity_info += "**Platform:** Desktop 🖥️"
if activity_info:
embed.add_field(name="🎮 Current Activity", value=activity_info, inline=True)
# Server settings relevant to this user
settings_info = f"**Warning Threshold:** {warn_threshold}\n"
auto_mute_enabled = guild_settings.get("auto_mute_on_warns", False)
if auto_mute_enabled:
auto_mute_duration = guild_settings.get("auto_mute_duration", "1 hour")
settings_info += f"**Auto-Mute:** Enabled ({auto_mute_duration})\n"
else:
settings_info += "**Auto-Mute:** Disabled\n"
settings_info += f"**Moderation Logs:** {'Enabled' if guild_settings.get('mod_log_enabled', False) else 'Disabled'}"
embed.add_field(name="⚙️ Server Settings", value=settings_info, inline=True)
# Set thumbnail and footer
embed.set_thumbnail(url=user.display_avatar.url)
embed.set_footer(text=f"Requested by {ctx.author.display_name} • Use /warn, /mute for actions")
await ctx.send(embed=embed)
# Log the modinfo request
logger.info(f"Modinfo requested for user {user.id} by {ctx.author.id} in guild {ctx.guild.id}")
except Exception as e:
logger.error(f"Error in modinfo command: {e}")
embed = discord.Embed(
title="❌ Error",
description="An error occurred while retrieving user information. Please try again.",
color=0xff0000
)
await ctx.send(embed=embed)
@client.hybrid_command()
async def mute(ctx, user: discord.User, duration: str, *, reason: str = "No reason provided"):
"""Mutes a user for a specified duration (Requires Permission Level 5 or higher)