地图项每次 node.js 都会被替换
Map items gets replaced every time node.js
我正在尝试为我的 Discord 机器人中的命令处理程序实施冷却,但我被卡住了。
冷却时间本身有效,但是当我尝试使用与我之前执行的命令不同的命令时,该冷却时间会被最后一个替换。这是代码:
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});
}
}
因此,例如,当我使用命令 /hello
时,冷却时间为 30 秒,这是第一次执行,如果我尝试再次执行它,机器人会以冷却时间响应说我在冷却时间到期之前不能使用该命令,这是正确的,但是如果我使用另一个命令,例如 /world
和 0 冷却时间,该命令会正确执行,但是 /hello
命令的冷却时间被取消,它可以再次使用。
我假设 interaction.user.id
和 "command"
项目被替换为新项目,但我找不到创建新项目的方法。
已更新
根据您的要求,我创建了如下数据结构
{
"userA": {
"/hello": startTime
"/world": startTime
},
"userB": {
"/hello": startTime
"/world": startTime
}
}
userA
是用户id
/hello
和/world
是命令
startTime
是每个命令的冷却时间
您可以通过一些评论来检查此实现
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
});
}
旧答案
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)}`});
}
我认为这部分导致了问题cooldowns.get("command") == command.data.name
。如果您的新命令与之前的命令匹配,则检查冷却时间。
但是只要你的新命令与前一个命令不匹配,你就绕过了系统不会检查剩余时间的条件。
可能的解决方法应该是
if (cooldown) {
const remaining = ms(cooldown - Date.now(), {till: "second"});
return interaction.reply({ content: `Please wait until cooldown expires! Remaining: ${codeLine(remaining)}`});
}
只需要从用户id上查看cooldown,不需要查看command匹配
我正在尝试为我的 Discord 机器人中的命令处理程序实施冷却,但我被卡住了。
冷却时间本身有效,但是当我尝试使用与我之前执行的命令不同的命令时,该冷却时间会被最后一个替换。这是代码:
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});
}
}
因此,例如,当我使用命令 /hello
时,冷却时间为 30 秒,这是第一次执行,如果我尝试再次执行它,机器人会以冷却时间响应说我在冷却时间到期之前不能使用该命令,这是正确的,但是如果我使用另一个命令,例如 /world
和 0 冷却时间,该命令会正确执行,但是 /hello
命令的冷却时间被取消,它可以再次使用。
我假设 interaction.user.id
和 "command"
项目被替换为新项目,但我找不到创建新项目的方法。
已更新
根据您的要求,我创建了如下数据结构
{
"userA": {
"/hello": startTime
"/world": startTime
},
"userB": {
"/hello": startTime
"/world": startTime
}
}
userA
是用户id
/hello
和/world
是命令
startTime
是每个命令的冷却时间
您可以通过一些评论来检查此实现
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
});
}
旧答案
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)}`});
}
我认为这部分导致了问题cooldowns.get("command") == command.data.name
。如果您的新命令与之前的命令匹配,则检查冷却时间。
但是只要你的新命令与前一个命令不匹配,你就绕过了系统不会检查剩余时间的条件。
可能的解决方法应该是
if (cooldown) {
const remaining = ms(cooldown - Date.now(), {till: "second"});
return interaction.reply({ content: `Please wait until cooldown expires! Remaining: ${codeLine(remaining)}`});
}
只需要从用户id上查看cooldown,不需要查看command匹配