modified: bot.py
This commit is contained in:
234
bot.py
234
bot.py
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user