javascript - 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);
})
}
}
非常感谢您提前提供的帮助。
亲切的问候。
解决方案
有几个错误。首先,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.get
cooldowns.has
Collection#get
Collection#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);
},
};