我有这个代码用于我的 discord.py bot,用于我的 tempmute 命令:
@bot.command()
async def tempmute(ctx, member: discord.Member, time: int, d, *, reason=None):
guild = ctx.guild
mutedRole = discord.utils.get(guild.roles, name="Muted")
if not mutedRole:
mutedRole = await guild.create_role(name="Muted")
for channel in guild.channels:
await channel.set_permissions(mutedRole, speak=False, send_messages=False)
for role in guild.roles:
if role.name == "Muted":
await member.add_roles(role)
embed = discord.Embed(title="TempMuted!", description=f"{member.mention} has been tempmuted.", colour=discord.Colour.red())
embed.add_field(name="Reason:", value=reason, inline=False)
embed.add_field(name="Time for the mute:", value=f"{time}{d}", inline=False)
await ctx.send(embed=embed)
if d == "s":
await asyncio.sleep(time)
if d == "m":
await asyncio.sleep(time*60)
if d == "h":
await asyncio.sleep(time*60*60)
if d == "d":
await asyncio.sleep(time*60*60*24)
await member.remove_roles(role)
embed = discord.Embed(title="Unmute (temp mute expired) ", description=f"Unmuted -{member.mention} ", colour=discord.Colour.light_gray())
await ctx.send(embed=embed)
return
但是,在使用该命令时,如果我想要 10 分钟静音,则必须像这样输入:“!tempmute @user 10 m”。注意它是“10 m”。我将如何使它如此“10m”起作用(没有空格)。所以“!tempmute @user 10m”?如果用户此时在没有空格的情况下写入它,则会出现错误“discord.ext.commands.errors.BadArgument:参数“time”的转换为“int”失败。发生,可能是因为它没有识别末尾带有字母的数字。谢谢
答案 0 :(得分:1)
解决此问题的最佳方法是创建您自己的 Converter 并在参数中键入提示该类。如记录here
因此,与其在命令函数中转换时间,不如在转换器中进行,使语法更简洁。
转换器示例
time_regex = re.compile(r"(\d{1,5}(?:[.,]?\d{1,5})?)([smhd])")
time_dict = {"h":3600, "s":1, "m":60, "d":86400}
class TimeConverter(commands.Converter):
async def convert(self, ctx, argument):
matches = time_regex.findall(argument.lower())
time = 0
for v, k in matches:
try:
time += time_dict[k]*float(v)
except KeyError:
raise commands.BadArgument(f"{k} is an invalid time-key! h/m/s/d are valid!")
except ValueError:
raise commands.BadArgument(f"{v} is not a number!")
return time
这是时间转换器的示例,它将使用正则表达式并在几秒钟内将其转换为 int。其中接受 <number><smhd>
,例如 2d
。
库在命令调用期间调用 TimeConverter().convert,因此我们创建了一个名为 convert 的方法,该方法接受 Context 对象和参数作为 str。你所要做的就是返回一些东西,或者如果有错误就抛出一个错误。
为了使用它,你可以这样做
@bot.command()
async def tempmute(ctx, member: discord.Member, time: TimeConverter, *, reason=None):
...
await member.add_roles(role)
await asyncio.sleep(time)
await member.remove_roles(role)
...
命令调用是
!tempmute @user 2d here's the reason
答案 1 :(得分:0)
我自己一直在研究 tempmute 命令。我会说这个命令可以用一个简单的字典正常工作。如果你想转换时间单位,一个简单的字典就可以做到,而且你不需要大量的代码。
首先我会添加代码,然后给出一个简短的解释。
@MyBot.command()
@commands.has_permissions(manage_roles=True)
async def tempmute(ctx, member: discord.Member, time, *, reason=None):
await ctx.message.delete()
if member.guild_permissions.administrator:
ifadmin_embed = discord.Embed(title='Member is Administrator!', description=f'The user, {member.mention} can\'t be muted as he/she is an administrator.', color=0xff0000)
ifadmin_embed.set_author(name='NucleoBot')
ifadmin_embed.set_footer(text=ctx.author)
await ctx.channel.send(embed=ifadmin_embed, delete_after=10.0)
else:
if discord.utils.get(ctx.guild.roles, name='Muted'):
muted_role = discord.utils.get(ctx.guild.roles, name='Muted')
else:
perms = discord.Permissions(send_messages=False, add_reactions=False, connect=False, speak=False)
await ctx.guild.create_role(name='Muted', permissions=perms)
muted_role = discord.utils.get(ctx.guild.roles, name='Muted')
time_convert = {'s' : 1 , 'm' : 60 , 'h' : 3600 , 'd' : 86400, 'y' : 31536000}
mute_time = int(time[0]) * time_convert[time[-1]]
await ctx.message.delete()
role_if_muted = discord.utils.find(lambda r: r.name == 'Muted', ctx.guild.roles)
if role_if_muted in member.roles:
alreadymuted_embed = discord.Embed(title='Already Muted!', description=f'The user, {member.mention} is already muted for {mute_time} seconds.', color=0xff0000)
alreadymuted_embed.set_footer(text=ctx.author)
alreadymuted_embed.set_author(name='NucleoBot')
await ctx.channel.send(embed=alreadymuted_embed, delete_after=10.0)
else:
if reason == None:
await member.add_roles(muted_role)
tempmuted_embed = discord.Embed(title='Temporary Mute Successfull!', description=f'{member.mention} has been muted for {mute_time} seconds successfully! \n \n Reason: No reason given.', color=0x4fff4d)
tempmuted_embed.set_author(name='NucleoBot')
tempmuted_embed.set_footer(text=ctx.author)
else:
await member.add_roles(muted_role)
tempmuted_embed = discord.Embed(title='Temporary Mute Successfull!', description=f'{member.mention} has been muted for {mute_time} seconds successfully! \n \n Reason: {reason}', color=0x4fff4d)
tempmuted_embed.set_author(name='NucleoBot')
tempmuted_embed.set_footer(text=ctx.author)
await ctx.channel.send(embed=tempmuted_embed, delete_after=10.0)
await asyncio.sleep(mute_time)
await member.remove_roles(muted_role)
我的代码几乎包含了静音命令所需的一切。只有具有 manage_role
权限的角色的成员才能执行此命令。此外,如果有人试图将服务器管理员成员静音,则会弹出一个嵌入内容,说 Member is an admin
。
代码还有一个方面,如果没有给出原因,它不会显示任何错误,而是发布为 No Reason
命令制作的嵌入,即,如果没有提到原因。它还检查服务器是否没有名为 Muted
的角色。如果角色存在,它将简单地使用它,否则首先它会创建一个名为 Muted
的角色并拒绝重要权限并将其用于静音。
现在是时间转换。用于此的行:
time_convert = {'s' : 1 , 'm' : 60 , 'h' : 3600 , 'd' : 86400, 'y' : 31536000}
此命令将 second
作为转换的基本值,然后以秒为单位转换每隔一个单位。这里 s
等于 1
,m
等于 60
,因为 I 分钟等于 60 秒。与其他单位类似,我们将所有内容推导出到秒。这本词典将所有内容都转换为秒,我们使用 asyncio
创建了一个静音计时器。
希望对您有所帮助,如果您还有任何疑问,请随时问我。
谢谢!