Discord.py 不需要 tempmute 命令的空间

时间:2021-03-27 00:42:02

标签: discord.py

我有这个代码用于我的 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”失败。发生,可能是因为它没有识别末尾带有字母的数字。谢谢

2 个答案:

答案 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 等于 1m 等于 60,因为 I 分钟等于 60 秒。与其他单位类似,我们将所有内容推导出到秒。这本词典将所有内容都转换为秒,我们使用 asyncio 创建了一个静音计时器。


希望对您有所帮助,如果您还有任何疑问,请随时问我。

谢谢!