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"
|
"`/warn <user> [reason]` - Warn a user\n"
|
||||||
"`/mute <user> <duration> [reason]` - Mute a user temporarily\n"
|
"`/mute <user> <duration> [reason]` - Mute a user temporarily\n"
|
||||||
"`/unmute <user>` - Manually unmute a user\n"
|
"`/unmute <user>` - Manually unmute a user\n"
|
||||||
|
"`/modinfo [user]` - View comprehensive user information\n"
|
||||||
"`/modstats [user]` - View moderation statistics\n"
|
"`/modstats [user]` - View moderation statistics\n"
|
||||||
"`/processes <action> [type]` - Manage active processes\n"
|
"`/processes <action> [type]` - Manage active processes\n"
|
||||||
"`/startgiveaway` - Create server giveaways\n"
|
"`/startgiveaway` - Create server giveaways\n"
|
||||||
@@ -2703,6 +2704,44 @@ def create_warnings_table():
|
|||||||
if connection:
|
if connection:
|
||||||
close_database_connection(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):
|
async def save_user_roles(user_id, guild_id, roles):
|
||||||
"""Saves a user's roles before a mute"""
|
"""Saves a user's roles before a mute"""
|
||||||
connection = None
|
connection = None
|
||||||
@@ -3053,6 +3092,201 @@ async def mywarns(ctx):
|
|||||||
logger.error(f"Error in mywarns command: {e}")
|
logger.error(f"Error in mywarns command: {e}")
|
||||||
await ctx.send("❌ An error occurred while retrieving your warning information.")
|
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()
|
@client.hybrid_command()
|
||||||
async def mute(ctx, user: discord.User, duration: str, *, reason: str = "No reason provided"):
|
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)
|
"""Mutes a user for a specified duration (Requires Permission Level 5 or higher)
|
||||||
|
|||||||
Reference in New Issue
Block a user