首页 > 解决方案 > discord.js 的冷却系统问题

问题描述

我是编码新手,我正在制作一个不和谐的机器人,我想发出一个命令,所有成员都需要等待一段时间才能再次使用它,但其中一些不需要等待时间。

例如:角色 X 的成员等待 20 秒,角色 Y 的成员等待 10 秒。

问题是我无法使其与调用的 npm 包一起工作humanize-duration以腾出时间。嵌入说明未显示正确的时间戳。也许这是我犯的一个错误。

我试图解决我的问题是什么?

我尝试阅读 discord.js 文档、humanize-duration 文档和这篇文章,但无法修复。另外,我没有收到任何错误。顺便说一句,我使用命令处理程序。

这是我用作示例的代码(ping 命令):

const Discord = require("discord.js");
const humanizeDuration = require("humanize-duration");

let cooldown = new Set();

module.exports = {
  name: "ping",
  description: "It shows the bot latency.",
  
  execute(client, message, args) {
      
    let guild = client.guilds.cache.get("828376495969402901");

    let member = guild.members.cache.get(message.author.id);
      
    if(cooldown.has(message.author.id) && !member.roles.cache.has("830503345251680298")) {
        const remaining = humanizeDuration(cooldown.has(message.author.id) && !member.roles.cache.has("830503345251680298") - Date.now(), { units: ["s"], round: true, language: "en" });
        const cooldownEmbed = new Discord.MessageEmbed()
        .setTitle(`Slow down, bud`)
        .setDescription(`You can run \`ping\` again in **${remaining}**.\nThe default cooldown is \`20s\`, but boosters can only wait \`10s\`!`)
        .setColor(`RANDOM`);
        
       return message.channel.send(cooldownEmbed)
    }else if (cooldown.has(message.author.id) && member.roles.cache.has("830503345251680298")) {
        const remaining = humanizeDuration(cooldown.has(message.author.id) && member.roles.cache.has("830503345251680298") - Date.now(), { units: ["s"], round: true, language: "en" });
        const cooldownEmbed = new Discord.MessageEmbed()
        .setTitle(`Too fast`)
        .setDescription(`You can run this command again in **${remaining}**. (booster perk)`)
        .setColor(`RANDOM`);
        
        return message.channel.send(cooldownEmbed)
    }
    
    if(cooldown.add(message.author.id) && !member.roles.cache.has("830503345251680298")) {
    setTimeout(() => {
        cooldown.delete(message.author.id) && !member.roles.cache.has("830503345251680298")
    }, 10000)
}else if(cooldown.add(message.author.id) && member.roles.cache.has("830503345251680298")) {
    setTimeout(() => {
        cooldown.delete(message.author.id) && member.roles.cache.has("830503345251680298")
    }, 2000)
}

    message.channel.send('Pinging...').then(message => {

      const embed = new Discord.MessageEmbed()
        .setDescription(`Pong! :ping_pong: \`${Date.now() - message.createdTimestamp} ms\``)
        .setColor(`RANDOM`);

      message.edit(" ", embed);
    })
  }
}

在此处输入图像描述

非常感谢您提前提供的帮助。

亲切的问候。

标签: javascriptdiscord.jsbots

解决方案


有几个错误。首先,cooldown.has(message.author.id)并且member.roles.cache.has("830503345251680298")都返回一个布尔值。你不能用它来测量剩余时间。

您的图像上显示的错误来自您尝试Date.now()从布尔值 ( !member.roles.cache.has("830503345251680298")) 中减去日期 ( ) 的事实,因此它返回自纪元时间以来的毫秒数。检查下面的片段:

console.log(true - Date.now())
console.log(false - Date.now())

要解决此问题,您需要将到期日期存储在某处。我建议您将这些冷却到期时间与成员 ID 的密钥一起存储在 discordcollection中。然后,检查两件事;如果该成员具有助推器角色 ( memberHasBooster) 并且该成员必须等待冷却时间到期 ( memberHasCooldown)。

如果,您可以通过从到期日期 ( )memberHasCooldown中减去当前日期 ( ) 来计算剩余时间。它以毫秒为单位返回剩余时间。请注意,我使用了,而不是. 返回存储的实际值,仅返回布尔值。new Date()cooldowns.get(message.author.id)cooldowns.getcooldowns.hasCollection#getCollection#has

然后,您可以格式化剩余时间,并将其发送到嵌入中。

如果成员没有冷却时间,您可以使用 来添加一个新的Collection#set。键是成员 ID,值是到期日期。timeout您可以通过将 10000/20000 毫秒 ( ) 添加到当前时间来计算到期日期。您还需要添加一个setTimeout相同的timeout并从集合中删除冷却时间。

添加冷却时间后,您可以发送实际消息。我在这里使用了异步/等待。不要忘记为实际发送的消息使用不同的名称(sentMessage而不是message)。

查看下面的完整代码:

let Discord = require('discord.js');
let humanizeDuration = require('humanize-duration');

let cooldowns = new Discord.Collection();

module.exports = {
  name: 'ping',
  description: 'It shows the bot latency.',
  async execute(client, message, args) {
      let guild = client.guilds.cache.get('828376495969402901');
      let member = guild.members.cache.get(message.author.id);
      let memberHasBooster = member.roles.cache.has('830503345251680298');
      let memberHasCooldown = cooldowns.has(message.author.id);

      if (memberHasCooldown) {
        let remaining = cooldowns.get(message.author.id) - new Date.now();
        let remainingFormatted = humanizeDuration(remaining, {
          language: 'en',
          round: true,
          units: ['s'],
        });
        let embed = new Discord.MessageEmbed()
          .setColor(`RANDOM`)
          .setTitle(`Slow down, bud`)
          .setDescription(
            `You can run \`ping\` again in **${remainingFormatted}**. ${
              memberHasBooster
                ? '(booster perk)'
                : '\nThe default cooldown is `20s`, but boosters can only wait `10s`!'
            }`,
          );

        return message.channel.send(embed);
      }

      // add cooldown
      const timeout = memberHasBooster ? 10 * 1000 : 20 * 1000;
      cooldowns.set(message.author.id, new Date() + timeout);

      setTimeout(() => cooldowns.delete(message.author.id), timeout);

      const sentMessage = await message.channel.send('Pinging...');

      const embed = new Discord.MessageEmbed()
        .setDescription(
          `Pong! :ping_pong: \`${
            Date.now() - sentMessage.createdTimestamp
          } ms\``,
        )
        .setColor(`RANDOM`);

      sentMessage.edit(' ', embed);
  },
};

推荐阅读