【问题标题】:Discord.py don't require space for tempmute commandDiscord.py 不需要空间用于 tempmute 命令
【发布时间】:2021-03-28 15:13:46
【问题描述】:

我的 discord.py 机器人有这个代码,用于我的 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: Converting to "int" failed for parameter "time"。”发生,可能是因为它无法识别末尾带有字母的数字。谢谢

【问题讨论】:

    标签: discord.py


    【解决方案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

    【讨论】:

      【解决方案2】:

      我自己一直在处理 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 创建静音计时器。


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

      谢谢!

      【讨论】:

        猜你喜欢
        • 2020-10-19
        • 2021-02-09
        • 1970-01-01
        • 2021-07-10
        • 2020-11-21
        • 1970-01-01
        • 2020-05-20
        • 2021-06-23
        • 1970-01-01
        相关资源
        最近更新 更多