Discord-Bot-Python/cogs/moderation.py

266 lines
11 KiB
Python

import discord
from discord import app_commands
from discord.ext import commands
from discord.ext.commands import Context
from helpers import checks, db_manager
class Moderation(commands.Cog, name="moderation"):
def __init__(self, bot):
self.bot = bot
@commands.hybrid_command(
name="kick",
description="Kick a user out of the server.",
)
@commands.has_permissions(kick_members=True)
@commands.bot_has_permissions(kick_members=True)
@checks.not_blacklisted()
@app_commands.describe(user="The user that should be kicked.", reason="The reason why the user should be kicked.")
async def kick(self, context: Context, user: discord.User, *, reason: str = "Not specified") -> None:
member = context.guild.get_member(user.id) or await context.guild.fetch_member(user.id)
if member.guild_permissions.administrator:
embed = discord.Embed(
title="Error!",
description="User has Admin permissions.",
color=0xE02B2B
)
await context.send(embed=embed)
else:
try:
embed = discord.Embed(
title="User Kicked!",
description=f"**{member}** was kicked by **{context.author}**!",
color=0x9C84EF
)
embed.add_field(
name="Reason:",
value=reason
)
await context.send(embed=embed)
try:
await member.send(
f"You were kicked by **{context.author}**!\nReason: {reason}"
)
except:
# Couldn't send a message in the private messages of the user
pass
await member.kick(reason=reason)
except:
embed = discord.Embed(
title="Error!",
description="An error occurred while trying to kick the user. Make sure my role is above the role of the user you want to kick.",
color=0xE02B2B
)
await context.send(embed=embed)
@commands.hybrid_command(
name="nick",
description="Change the nickname of a user on a server.",
)
@commands.has_permissions(manage_nicknames=True)
@commands.bot_has_permissions(manage_nicknames=True)
@checks.not_blacklisted()
@app_commands.describe(user="The user that should have a new nickname.", nickname="The new nickname that should be set.")
async def nick(self, context: Context, user: discord.User, *, nickname: str = None) -> None:
member = context.guild.get_member(user.id) or await context.guild.fetch_member(user.id)
try:
await member.edit(nick=nickname)
embed = discord.Embed(
title="Changed Nickname!",
description=f"**{member}'s** new nickname is **{nickname}**!",
color=0x9C84EF
)
await context.send(embed=embed)
except:
embed = discord.Embed(
title="Error!",
description="An error occurred while trying to change the nickname of the user. Make sure my role is above the role of the user you want to change the nickname.",
color=0xE02B2B
)
await context.send(embed=embed)
@commands.hybrid_command(
name="ban",
description="Bans a user from the server.",
)
@commands.has_permissions(ban_members=True)
@commands.bot_has_permissions(ban_members=True)
@checks.not_blacklisted()
@app_commands.describe(user="The user that should be banned.", reason="The reason why the user should be banned.")
async def ban(self, context: Context, user: discord.User, *, reason: str = "Not specified") -> None:
member = context.guild.get_member(user.id) or await context.guild.fetch_member(user.id)
try:
if member.guild_permissions.administrator:
embed = discord.Embed(
title="Error!",
description="User has Admin permissions.",
color=0xE02B2B
)
await context.send(embed=embed)
else:
embed = discord.Embed(
title="User Banned!",
description=f"**{member}** was banned by **{context.author}**!",
color=0x9C84EF
)
embed.add_field(
name="Reason:",
value=reason
)
await context.send(embed=embed)
try:
await member.send(f"You were banned by **{context.author}**!\nReason: {reason}")
except:
# Couldn't send a message in the private messages of the user
pass
await member.ban(reason=reason)
except:
embed = discord.Embed(
title="Error!",
description="An error occurred while trying to ban the user. Make sure my role is above the role of the user you want to ban.",
color=0xE02B2B
)
await context.send(embed=embed)
@commands.hybrid_group(
name="warning",
description="Manage warnings of a user on a server.",
)
@commands.has_permissions(manage_messages=True)
@checks.not_blacklisted()
async def warning(self, context: Context) -> None:
if context.invoked_subcommand is None:
embed = discord.Embed(
title="Error!",
description="Please specify a subcommand.\n\n**Subcommands:**\n`add` - Add a warning to a user.\n`remove` - Remove a warning from a user.\n`list` - List all warnings of a user.",
color=0xE02B2B
)
await context.send(embed=embed)
@warning.command(
name="add",
description="Adds a warning to a user in the server.",
)
@checks.not_blacklisted()
@commands.has_permissions(manage_messages=True)
@app_commands.describe(user="The user that should be warned.", reason="The reason why the user should be warned.")
async def warning_add(self, context: Context, user: discord.User, *, reason: str = "Not specified") -> None:
member = context.guild.get_member(user.id) or await context.guild.fetch_member(user.id)
total = await db_manager.add_warn(
user.id, context.guild.id, context.author.id, reason)
embed = discord.Embed(
title="User Warned!",
description=f"**{member}** was warned by **{context.author}**!\nTotal warns for this user: {total}",
color=0x9C84EF
)
embed.add_field(
name="Reason:",
value=reason
)
await context.send(embed=embed)
try:
await member.send(f"You were warned by **{context.author}**!\nReason: {reason}")
except:
# Couldn't send a message in the private messages of the user
await context.send(f"{member.mention}, you were warned by **{context.author}**!\nReason: {reason}")
@warning.command(
name="remove",
description="Removes a warning from a user in the server.",
)
@checks.not_blacklisted()
@commands.has_permissions(manage_messages=True)
@app_commands.describe(user="The user that should get their warning removed.", warn_id="The ID of the warning that should be removed.")
async def warning_remove(self, context: Context, user: discord.User, warn_id: int) -> None:
member = context.guild.get_member(user.id) or await context.guild.fetch_member(user.id)
total = await db_manager.remove_warn(warn_id, user.id, context.guild.id)
embed = discord.Embed(
title="User Warn Removed!",
description=f"I've removed the warning **#{warn_id}** from **{member}**!\nTotal warns for this user: {total}",
color=0x9C84EF
)
await context.send(embed=embed)
@warning.command(
name="list",
description="Shows the warnings of a user in the server.",
)
@commands.has_guild_permissions(manage_messages=True)
@checks.not_blacklisted()
@app_commands.describe(user="The user you want to get the warnings of.")
async def warning_list(self, context: Context, user: discord.User):
warnings_list = await db_manager.get_warnings(user.id, context.guild.id)
embed = discord.Embed(
title=f"Warnings of {user}",
color=0x9C84EF
)
description = ""
if len(warnings_list) == 0:
description = "This user has no warnings."
else:
for warning in warnings_list:
description += f"• Warned by <@{warning[2]}>: **{warning[3]}** (<t:{warning[4]}>) - Warn ID #{warning[5]}\n"
embed.description = description
await context.send(embed=embed)
@commands.hybrid_command(
name="purge",
description="Delete a number of messages.",
)
@commands.has_guild_permissions(manage_messages=True)
@commands.bot_has_permissions(manage_messages=True)
@checks.not_blacklisted()
@app_commands.describe(amount="The amount of messages that should be deleted.")
async def purge(self, context: Context, amount: int) -> None:
await context.send("Deleting messages...") # Bit of a hacky way to make sure the bot responds to the interaction and doens't get a "Unknown Interaction" response
purged_messages = await context.channel.purge(limit=amount+1)
embed = discord.Embed(
title="Chat Cleared!",
description=f"**{context.author}** cleared **{len(purged_messages)-1}** messages!",
color=0x9C84EF
)
await context.channel.send(embed=embed)
@commands.hybrid_command(
name="hackban",
description="Bans a user without the user having to be in the server.",
)
@commands.has_permissions(ban_members=True)
@commands.bot_has_permissions(ban_members=True)
@checks.not_blacklisted()
@app_commands.describe(user_id="The user ID that should be banned.", reason="The reason why the user should be banned.")
async def hackban(self, context: Context, user_id: str, *, reason: str = "Not specified") -> None:
try:
await self.bot.http.ban(user_id, context.guild.id, reason=reason)
user = self.bot.get_user(int(user_id)) or await self.bot.fetch_user(int(user_id))
embed = discord.Embed(
title="User Banned!",
description=f"**{user} (ID: {user_id}) ** was banned by **{context.author}**!",
color=0x9C84EF
)
embed.add_field(
name="Reason:",
value=reason
)
await context.send(embed=embed)
except Exception as e:
embed = discord.Embed(
title="Error!",
description="An error occurred while trying to ban the user. Make sure ID is an existing ID that belongs to a user.",
color=0xE02B2B
)
await context.send(embed=embed)
async def setup(bot):
await bot.add_cog(Moderation(bot))