Estoy tratando de implementar el tiempo de reutilización de mi controlador de comandos en mi bot Discord, pero estoy atascado.
El enfriamiento en sí funciona, pero cuando trato de usar un comando que es diferente al que ejecuté antes, ese enfriamiento se reemplaza por el último. Aquí está el código:
const cooldowns = new Map(); try { const cooldown = cooldowns.get(interaction.user.id); if (cooldown && cooldowns.get("command") == command.data.name) { const remaining = ms(cooldown - Date.now(), {till: "second"}); return interaction.reply({ content: `Please wait until cooldown expires! Remaining: ${codeLine(remaining)}`}); } await command.execute(client, interaction, Discord, profileData); let startTime = Date.now() + command.cooldown; cooldowns.set(interaction.user.id, startTime); cooldowns.set("command", command.data.name); setTimeout(async () => cooldowns.delete(interaction.user.id, "command"), command.cooldown); } catch (error) { console.log(`The interaction error is ${error}`); await interaction.reply({ content: "There was an error trying to execute this command. 🍐", ephemeral: true}); } } Entonces, por ejemplo, cuando uso el comando /hello , con un enfriamiento de 30 segundos, la primera vez que se ejecuta, y si trato de ejecutarlo nuevamente, el bot responde con el enfriamiento diciendo que no puedo usar el comando hasta que el el tiempo de reutilización expira, lo cual es correcto, pero si uso otro comando, por ejemplo /world con 0 tiempo de reutilización, el comando se ejecuta correctamente, pero el tiempo de reutilización para el comando /hello se cancela y se puede usar nuevamente.
Supongo que la interaction.user.id y los elementos de "command" se reemplazan por otros nuevos, y no puedo encontrar un método para crear otros nuevos.
ACTUALIZADO
De acuerdo con su requerimiento, creé una estructura de datos como la siguiente
{ "userA": { "/hello": startTime "/world": startTime }, "userB": { "/hello": startTime "/world": startTime } } userA es para la identificación del usuario
/hello y /world son comandos
startTime es el tiempo de reutilización para cada comando
Puedes comprobar esta implementación con algunos comentarios.
const cooldowns = {}; //similar to Map but simpler try { //cannot find any user in cooldowns map if (!cooldowns[interaction.user.id]) { cooldowns[interaction.user.id] = {} //create map to keep commands } //check if the cooldown exists in the commands const cooldown = cooldowns[interaction.user.id][command.data.name]; if (cooldown) { const remaining = ms(cooldown - Date.now(), { till: "second" }); if (remaining > 0) { return interaction.reply({ content: `Please wait until cooldown expires! Remaining: ${codeLine(remaining)}` }); } } await command.execute(client, interaction, Discord, profileData); let startTime = Date.now() + command.cooldown; cooldowns[interaction.user.id][command.data.name] = startTime setTimeout(async () => delete cooldowns[interaction.user.id][command.data.name], command.cooldown); } catch (error) { console.log(`The interaction error is ${error}`); await interaction.reply({ content: "There was an error trying to execute this command. 🍐", ephemeral: true }); }RESPUESTA ANTIGUA
if (cooldown && cooldowns.get("command") == command.data.name) { const remaining = ms(cooldown - Date.now(), {till: "second"}); return interaction.reply({ content: `Please wait until cooldown expires! Remaining: ${codeLine(remaining)}`}); } Creo que esta parte está causando el problema cooldowns.get("command") == command.data.name . Si su nuevo comando coincide con el comando anterior, verifica el tiempo de reutilización.
PERO siempre que su nuevo comando no coincida con el anterior, omita esa condición, que es que el sistema no verificará el tiempo restante.
La posible solución debería ser
if (cooldown) { const remaining = ms(cooldown - Date.now(), {till: "second"}); return interaction.reply({ content: `Please wait until cooldown expires! Remaining: ${codeLine(remaining)}`}); }Solo necesita verificar el tiempo de reutilización de la identificación del usuario y no necesita verificar la coincidencia de comandos.