Allow tempban by ID and ban downgrade (#5978)

Co-authored-by: Jakub Kuczys <me@jacken.men>
This commit is contained in:
Raiden
2026-05-28 23:43:26 +08:00
committed by GitHub
parent d128335f1d
commit 60199c8231
+53 -15
View File
@@ -16,6 +16,7 @@ from redbot.core.utils.chat_formatting import (
format_perms_list, format_perms_list,
) )
from redbot.core.utils.mod import get_audit_reason from redbot.core.utils.mod import get_audit_reason
from redbot.core.utils.views import ConfirmView
from .abc import MixinMeta from .abc import MixinMeta
from .utils import is_allowed_by_hierarchy from .utils import is_allowed_by_hierarchy
@@ -607,7 +608,7 @@ class KickBanMixin(MixinMeta):
async def tempban( async def tempban(
self, self,
ctx: commands.Context, ctx: commands.Context,
member: discord.Member, member: Union[discord.Member, RawUserIdConverter],
duration: Optional[commands.TimedeltaConverter] = None, duration: Optional[commands.TimedeltaConverter] = None,
days: Optional[int] = None, days: Optional[int] = None,
*, *,
@@ -628,6 +629,11 @@ class KickBanMixin(MixinMeta):
""" """
guild = ctx.guild guild = ctx.guild
author = ctx.author author = ctx.author
in_server = True
if isinstance(member, int):
in_server = False
member = self.bot.get_user(member) or discord.Object(id=member)
if reason is None and await self.config.guild(guild).require_reason(): if reason is None and await self.config.guild(guild).require_reason():
await ctx.send(_("You must provide a reason for the temporary ban.")) await ctx.send(_("You must provide a reason for the temporary ban."))
@@ -638,18 +644,19 @@ class KickBanMixin(MixinMeta):
_("I cannot let you do that. Self-harm is bad {}").format("\N{PENSIVE FACE}") _("I cannot let you do that. Self-harm is bad {}").format("\N{PENSIVE FACE}")
) )
return return
elif not await is_allowed_by_hierarchy(self.bot, self.config, guild, author, member): elif in_server:
await ctx.send( if not await is_allowed_by_hierarchy(self.bot, self.config, guild, author, member):
_( await ctx.send(
"I cannot let you do that. You are " _(
"not higher than the user in the role " "I cannot let you do that. You are "
"hierarchy." "not higher than the user in the role "
"hierarchy."
)
) )
) return
return elif guild.me.top_role <= member.top_role or member == guild.owner:
elif guild.me.top_role <= member.top_role or member == guild.owner: await ctx.send(_("I cannot do that due to Discord hierarchy rules."))
await ctx.send(_("I cannot do that due to Discord hierarchy rules.")) return
return
guild_data = await self.config.guild(guild).all() guild_data = await self.config.guild(guild).all()
@@ -665,9 +672,39 @@ class KickBanMixin(MixinMeta):
return return
invite = await self.get_invite_for_reinvite(ctx, int(duration.total_seconds() + 86400)) invite = await self.get_invite_for_reinvite(ctx, int(duration.total_seconds() + 86400))
await self.config.member(member).banned_until.set(unban_time.timestamp()) try:
await guild.fetch_ban(member)
except discord.NotFound:
pass
else:
current_tempbans = await self.config.guild(guild).current_tempbans()
banned_until = False
if member.id in current_tempbans:
banned_until = await self.config.member_from_ids(
guild.id, member.id
).banned_until()
if not ctx.assume_yes:
content = (
_(
"User is already tempbanned (ban expires {relative_time}),"
" do you want to proceed?"
).format(relative_time=f"<t:{int(banned_until)}:R>")
if banned_until
else _("This will downgrade the ban to a tempban, do you want to proceed?")
)
view = ConfirmView(ctx.author)
view.message = await ctx.send(content, view=view)
await view.wait()
if not view.result:
await ctx.send(_("Okay, I will not be doing that then."))
return
await self.config.member_from_ids(guild.id, member.id).banned_until.set(
unban_time.timestamp()
)
async with self.config.guild(guild).current_tempbans() as current_tempbans: async with self.config.guild(guild).current_tempbans() as current_tempbans:
current_tempbans.append(member.id) if member.id not in current_tempbans:
current_tempbans.append(member.id)
with contextlib.suppress(discord.HTTPException): with contextlib.suppress(discord.HTTPException):
# We don't want blocked DMs preventing us from banning # We don't want blocked DMs preventing us from banning
@@ -702,7 +739,8 @@ class KickBanMixin(MixinMeta):
value=extra_embed_contents, value=extra_embed_contents,
inline=False, inline=False,
) )
await member.send(embed=em) if in_server:
await member.send(embed=em)
audit_reason = get_audit_reason(author, reason, shorten=True) audit_reason = get_audit_reason(author, reason, shorten=True)