ryuko-ng/cogs/mod.py

292 lines
12 KiB
Python
Raw Normal View History

2018-12-23 15:07:59 +00:00
import discord
from discord.ext import commands
import config
2018-12-23 15:44:16 +00:00
class ModCog:
2018-12-23 15:07:59 +00:00
def __init__(self, bot):
self.bot = bot
def check_if_staff(ctx):
return any(r.id in config.staff_role_ids for r in ctx.author.roles)
def check_if_target_is_staff(self, target):
return any(r.id in config.staff_role_ids for r in target.roles)
2018-12-23 20:50:05 +00:00
@commands.guild_only()
@commands.bot_has_permissions(kick_members=True)
@commands.check(check_if_staff)
@commands.command()
async def mute(self, ctx, target: discord.Member, *, reason: str = ""):
"""Mutes a user, staff only."""
# TODO: keep a restriction list
# so that muted people can't just leave and rejoin
if self.check_if_target_is_staff(target):
return await ctx.send("I can't mute this user as "
"they're a member of staff.")
safe_name = self.bot.escape_message(str(target))
dm_message = f"You were muted!"
if reason:
dm_message += f" The given reason is: \"{reason}\"."
try:
await target.send(dm_message)
except discord.errors.Forbidden:
# Prevents kick issues in cases where user blocked bot
# or has DMs disabled
pass
mute_role = ctx.guild.get_role(config.mute_role)
await target.add_roles(mute_role, reason=str(ctx.author))
chan_message = f"🔇 **Muted**: {ctx.author.mention} muted "\
f"{target.mention} | {safe_name}\n"\
f"🏷 __User ID__: {target.id}\n"
if reason:
chan_message += f"✏️ __Reason__: \"{reason}\""
else:
chan_message += "Please add an explanation below. In the future, "\
"it is recommended to use `.mute <user> [reason]`"\
" as the reason is automatically sent to the user."
log_channel = self.bot.get_channel(config.log_channel)
await log_channel.send(chan_message)
await ctx.send(f"{target.mention} can no longer speak.")
@commands.guild_only()
@commands.bot_has_permissions(kick_members=True)
@commands.check(check_if_staff)
@commands.command()
async def unmute(self, ctx, target: discord.Member):
"""Unmutes a user, staff only."""
if self.check_if_target_is_staff(target):
return await ctx.send("I can't unmute this user as "
"they're a member of staff.")
safe_name = self.bot.escape_message(str(target))
mute_role = ctx.guild.get_role(config.mute_role)
await target.remove_roles(mute_role, reason=str(ctx.author))
chan_message = f"🔈 **Unmuted**: {ctx.author.mention} unmuted "\
f"{target.mention} | {safe_name}\n"\
f"🏷 __User ID__: {target.id}\n"
log_channel = self.bot.get_channel(config.log_channel)
await log_channel.send(chan_message)
await ctx.send(f"{target.mention} can now speak again.")
@commands.guild_only()
@commands.bot_has_permissions(kick_members=True)
@commands.check(check_if_staff)
@commands.command()
async def kick(self, ctx, target: discord.Member, *, reason: str = ""):
"""Kicks a user, staff only."""
if self.check_if_target_is_staff(target):
return await ctx.send("I can't kick this user as "
"they're a member of staff.")
safe_name = self.bot.escape_message(str(target))
dm_message = f"You were kicked from {ctx.guild.name}."
if reason:
dm_message += f" The given reason is: \"{reason}\"."
dm_message += "\n\nYou are able to rejoin the server,"\
" but please be sure to behave when participating again."
try:
await target.send(dm_message)
except discord.errors.Forbidden:
# Prevents kick issues in cases where user blocked bot
# or has DMs disabled
pass
await target.kick(reason=f"{ctx.author}, reason: {reason}")
chan_message = f"👢 **Kick**: {ctx.author.mention} kicked "\
f"{target.mention} | {safe_name}\n"\
f"🏷 __User ID__: {target.id}\n"
if reason:
chan_message += f"✏️ __Reason__: \"{reason}\""
else:
chan_message += "Please add an explanation below. In the future"\
", it is recommended to use `.ban <user> [reason]`"\
" as the reason is automatically sent to the user."
2018-12-23 19:03:40 +00:00
log_channel = self.bot.get_channel(config.log_channel)
await log_channel.send(chan_message)
@commands.guild_only()
@commands.bot_has_permissions(ban_members=True)
@commands.check(check_if_staff)
@commands.command()
async def ban(self, ctx, target: discord.Member, *, reason: str = ""):
"""Bans a user, staff only."""
if self.check_if_target_is_staff(target):
return await ctx.send("I can't ban this user as "
"they're a member of staff.")
safe_name = self.bot.escape_message(str(target))
dm_message = f"You were banned from {ctx.guild.name}."
if reason:
dm_message += f" The given reason is: \"{reason}\"."
dm_message += "\n\nThis ban does not expire."
try:
await target.send(dm_message)
except discord.errors.Forbidden:
# Prevents kick issues in cases where user blocked bot
# or has DMs disabled
pass
await target.ban(reason=f"{ctx.author}, reason: {reason}",
delete_message_days=0)
2018-12-23 15:44:16 +00:00
chan_message = f"⛔ **Ban**: {ctx.author.mention} banned "\
f"{target.mention} | {safe_name}\n"\
f"🏷 __User ID__: {target.id}\n"
if reason:
chan_message += f"✏️ __Reason__: \"{reason}\""
else:
chan_message += "Please add an explanation below. In the future"\
", it is recommended to use `.ban <user> [reason]`"\
" as the reason is automatically sent to the user."
2018-12-23 19:03:40 +00:00
log_channel = self.bot.get_channel(config.log_channel)
await log_channel.send(chan_message)
await ctx.send(f"{safe_name} is now b&. 👍")
@commands.guild_only()
2018-12-23 15:44:16 +00:00
@commands.bot_has_permissions(ban_members=True)
@commands.check(check_if_staff)
@commands.command()
async def silentban(self, ctx, target: discord.Member, *, reason: str = ""):
"""Bans a user, staff only."""
if self.check_if_target_is_staff(target):
return await ctx.send("I can't ban this user as "
"they're a member of staff.")
safe_name = self.bot.escape_message(str(target))
await target.ban(reason=f"{ctx.author}, reason: {reason}",
delete_message_days=0)
chan_message = f"⛔ **Silent ban**: {ctx.author.mention} banned "\
f"{target.mention} | {safe_name}\n"\
f"🏷 __User ID__: {target.id}\n"
if reason:
chan_message += f"✏️ __Reason__: \"{reason}\""
else:
chan_message += "Please add an explanation below. In the future"\
", it is recommended to use `.ban <user> [reason]`"\
" as the reason is automatically sent to the user."
2018-12-23 19:03:40 +00:00
log_channel = self.bot.get_channel(config.log_channel)
await log_channel.send(chan_message)
2018-12-23 15:44:16 +00:00
@commands.guild_only()
2018-12-23 15:07:59 +00:00
@commands.check(check_if_staff)
@commands.command()
async def userinfo(self, ctx, *, user: discord.Member):
"""Gets user info, staff only."""
role = user.top_role.name
if role == "@everyone":
role = "@ everyone"
await ctx.send(f"user = {user}\n"
f"id = {user.id}\n"
f"avatar = {user.avatar_url}\n"
f"bot = {user.bot}\n"
f"created_at = {user.created_at}\n"
f"display_name = {user.display_name}\n"
f"joined_at = {user.joined_at}\n"
f"activities = `{user.activities}`\n"
f"color = {user.colour}\n"
f"top_role = {role}\n")
2018-12-23 19:32:48 +00:00
@commands.guild_only()
@commands.check(check_if_staff)
@commands.command()
async def approve(self, ctx, target: discord.Member,
role: str = "community"):
if role not in config.named_roles:
return await ctx.send("No such role! Available roles: " +
','.join(config.named_roles))
2018-12-23 19:32:48 +00:00
log_channel = self.bot.get_channel(config.log_channel)
target_role = ctx.guild.get_role(config.named_roles[role])
if target_role in target.roles:
return await ctx.send("Target already has this role.")
await target.add_roles(target_role, reason=str(ctx.author))
2018-12-23 20:01:43 +00:00
await ctx.send(f"Approved {target.mention} to `{role}` role.")
2018-12-23 19:32:48 +00:00
await log_channel.send(f"✅ Approved: {ctx.author.mention} added"
f" {role} to {target.mention}")
2018-12-23 19:32:48 +00:00
@commands.guild_only()
@commands.check(check_if_staff)
@commands.command(aliases=["unapprove"])
async def revoke(self, ctx, target: discord.Member,
role: str = "community"):
if role not in config.named_roles:
return await ctx.send("No such role! Available roles: " +
','.join(config.named_roles))
2018-12-23 19:32:48 +00:00
log_channel = self.bot.get_channel(config.log_channel)
target_role = ctx.guild.get_role(config.named_roles[role])
if target_role not in target.roles:
return await ctx.send("Target doesn't have this role.")
await target.remove_roles(target_role, reason=str(ctx.author))
2018-12-23 20:01:43 +00:00
await ctx.send(f"Un-approved {target.mention} from `{role}` role.")
2018-12-23 19:32:48 +00:00
await log_channel.send(f"❌ Un-approved: {ctx.author.mention} removed"
f" {role} from {target.mention}")
2018-12-23 19:32:48 +00:00
@commands.guild_only()
@commands.check(check_if_staff)
@commands.command(aliases=["setplaying", "setgame"])
async def playing(self, ctx, *, game: str = ""):
2018-12-23 17:56:27 +00:00
"""Sets the bot's currently played game name, staff only.
Just send .playing to wipe the playing state."""
if game:
await self.bot.change_presence(activity=discord.Game(name=game))
else:
await self.bot.change_presence(activity=None)
2018-12-23 17:56:27 +00:00
@commands.guild_only()
@commands.check(check_if_staff)
@commands.command(aliases=["setbotnick", "botnick", "robotnick"])
async def botnickname(self, ctx, *, nick: str = ""):
"""Sets the bot's nickname, staff only.
Just send .botnickname to wipe the nickname."""
if nick:
await ctx.guild.me.edit(nick=nick, reason=str(ctx.author))
else:
await ctx.guild.me.edit(nick=None, reason=str(ctx.author))
@commands.guild_only()
@commands.check(check_if_staff)
@commands.command(aliases=["setnick", "nick"])
async def nickname(self, ctx, target: discord.Member, *, nick: str = ""):
"""Sets a user's nickname, staff only.
Just send .nickname <user> to wipe the nickname."""
if nick:
await target.edit(nick=nick, reason=str(ctx.author))
else:
await target.edit(nick=None, reason=str(ctx.author))
2018-12-23 15:07:59 +00:00
def setup(bot):
2018-12-23 15:44:16 +00:00
bot.add_cog(ModCog(bot))