使用命令处理程序剩余时间的Discord.js冷却时间

时间:2020-06-10 15:57:51

标签: javascript discord discord.js

我希望使用discord.js为不和谐的bot命令制作一个冷却系统。我正在寻找它,以显示用户尝试执行命令时冷却时间剩余的时间。目前,我拥有它,因此它可以使用命令处理程序进行冷却,因此我只需要添加“超时:'10000'”,尽管我似乎无法找到一种方法来显示使用此系统剩余的时间。 / p>

这是我当前在message.js文件中拥有的代码,可以与命令处理程序一起使用,这样我就不必在每个命令文件上编写超时代码。下面的代码是整个message.js文件。

const Timeout = new Set();
const { MessageEmbed } = require('discord.js')
const {prefix} = require('../../config.json')
const ms = require('ms')
module.exports=async(bot, message)=>{

    if(message.author.bot) return;
    if(!message.content.toLowerCase().startsWith(prefix)) return;
    if(!message.member) message.member = await message.guild.fetchMember(messsage);
    if(!message.guild) return;
    const args = message.content.slice(prefix.length).trim().split(/ +/g);
    const cmd = args.shift().toLowerCase();

    if(cmd.length === 0) return;

    let command = bot.commands.get(cmd);
    if(!command) command = bot.commands.get(bot.aliases.get(cmd));

    if(command){
        if(command.timeout){
            if(Timeout.has(`${message.author.id}${command.name}`)){
                return message.reply(`**Slow down, you can only use this command every ${ms(command.timeout)}!**`)
            } else {

                command.run(bot, message, args);
                Timeout.add(`${message.author.id}${command.name}`)
                setTimeout(() => {
                    Timeout.delete(`${message.author.id}${command.name}`)
                }, command.timeout);
            }
        } else {
            command.run(bot, message, args)
        }
    }
}

当前回复在上方以粗体显示。

作为参考,在我的index.js文件中的以下代码中引用了message.js文件。

bot.on('message', async message =>{
    require('./events/guild/message')(bot, message)
})

以下是我必须在每个命令文件的开头放置的内容,并显示了一个简单的命令示例供参考。

const Discord = require('discord.js');
module.exports={
    name: 'test',
    category: 'info',
    timeout: '15000', //This would result in a 15 second cooldown as time is in ms.
    run: async(bot, message, args) =>{
        message.channel.send(`test`)
    }
}

最后,我希望保留我的系统,但与其说“慢下来,您只能每15000使用此命令!(例如,上面的例子),我希望它在”慢”行中说些什么下来,您可以在10秒钟内再次使用此命令。 默认的冷却时间是15秒。

1 个答案:

答案 0 :(得分:4)

如果我没记错的话,您想将every 15000转换为every 15s吗?

您已经拥有ms模块,因此您似乎对如何使用它感到困惑:

如果接收到字符串,则将其转换为ms;如果接收到数字,则将其转换为可读格式,例如1d 2h 3m

在模块中。导出时,它有一个字符串,因此将其设为数字​​,并且所有内容都已固定。

该字符串也可能会被setTimeout(func, time)

拦截

如果由于某种原因您不想将module.exports.timeout更改为字符串,则在调用ms之前,您必须做parseInt(command.timeout)

代码:

let command = bot.commands.get(cmd) || bot.commands.get(bot.aliases.get(cmd));

if (!command) return;
if (!command.timeout) return command.run(bot, message, args);

//if you changed it to a number in module.exports you don't have to parseInt it
const timeout = parseInt(command.timeout);
if (Timeout.has(`${message.author.id}${command.name}`)) {
    return message.reply(`**Slow down, you can only use this command every ${ms(timeout)}!**`)
} else {
    command.run(bot, message, args);
    Timeout.add(`${message.author.id}${command.name}`)
    setTimeout(() => {
        Timeout.delete(`${message.author.id}${command.name}`)
    }, timeout);
}

第二部分:

您需要跟踪设置超时的时间,使用Set类的问题是 不是基于键值的,因此有两个选择:

Set.add({ key: key, time: Date.now()})或使用Discord.Collection / Map

首先:仍然使用Set,而是设置对象:

const timeout = command.timeout;
const key = message.author.id + command.name;
let found;

for(const e of Timeout) {
  if(e.key === key) {
    found = e;
    //possibly bad practice, arguable
    break;
  }
}

if(found) {
  const timePassed = Date.now() - found.time;
  const timeLeft = timeout - timePassed;
  //the part at this command has a default cooldown of, did you want to hard code 15s? or have it be the commands.config.timeout?
  return message.reply(`**Slow down, you can use this command again in ${ms(timeLeft)} This command has a default cooldown of ${timeout}!**`)
} else {
  command.run(bot, message, args);
  Timeout.add({ key, time: Date.now() });

  setTimeout(() => {
     Timeout.delete(key);
  }, timeout);
}

第二个:Discord.CollectionMap也是有效的,因为它只是该类的扩展类。

如果您使用Collection,我将使用Map

const { MessageEmbed, Collection } = require("discord.js");
const Timeout = new Collection();

地图代码:

const Timeout = new Map();

代码后:

const timeout = command.timeout;
const key = message.author.id + command.name;
const found = Timeout.get(key);
if(found) {
  const timePassed = Date.now() - found;
  const timeLeft = timeout - timePassed;
  //the part at this command has a default cooldown of, did you want to hard code 15s? or have it be the commands.config.timeout?
  return message.reply(`**Slow down, you can use this command again in ${ms(timeLeft)} This command has a default cooldown of ${timeout}!**`);
} else {
  command.run(bot, message, args);
  Timeout.set(key, Date.now());

  setTimeout(() => {
     Timeout.delete(key);
  }, timeout);
}