第一条命令始终使用开关 discord.js 执行
First command always executing with switch discord.js
我在使用 JavaScript 和 discord.js 的 switch 语句时遇到问题。我希望机器人执行带前缀和不带前缀的两个命令。当我尝试执行不带前缀的命令时,它会起作用,但是当我尝试执行前缀命令时,机器人会同时响应我询问的命令和我的非前缀命令中的第一种情况。这是代码:
const Discord = require('discord.js')
const fs = require('fs')
const token = "xxx"
const client = new Discord.Client({
intents: [
Discord.Intents.FLAGS.GUILDS,
Discord.Intents.FLAGS.GUILD_MESSAGES
]
})
client.commands = new Discord.Collection()
const commandFiles = fs.readdirSync(`./commands/`).filter(file => file.endsWith('.js'))
for (const file of commandFiles){
const command = require(`./commands/${file}`)
client.commands.set(command.name, command)
}
//ready event
client.on('ready', () => {
console.log('online')
})
const prefix = 'ao'
//message event
client.on('messageCreate', (message) => {
const args = message.content.slice(prefix.length).trim().split(/ +/);
var command = args.shift().toLowerCase()
if(message.author.bot) return;
//non-prefix commands
switch(!message.content.startsWith(prefix)){
case message.content.includes('ping'):
message.reply('pong')
break;
case message.content.includes('hello'):
message.reply('hello')
break;
}
//prefix commands
switch(command){
case command = 'ciao':
message.reply('ciao')
break;
}
})
client.login(token)
例如,如果我只输入“hello”或“ping”,机器人会回复正确的命令,但当我尝试使用“prefix + ciao”时,机器人会回复“pong”和“ciao”。
您的代码存在的问题是,您在代码中尝试执行的操作根本不是 switch
语句的工作方式。让我们首先看看 switch
语句实际上应该如何工作。
switch
语句如何工作
假设您有一个像 message.content
这样的值,您想要重复检查它的值。例如,你想知道是否 message.content == "ping"
,你想知道是否 message.content == "hello"
,等等。一种写法是这样的,使用经典的 if
语句:
if (message.content == "ping") {
// Do stuff for ping
}
else if (message.content == "hello") {
// Do stuff for hello
}
//... and so on
else {
// Do stuff if none of the above cases equals value of message.content
}
如您所见,如果您有数十个值要与同一个 message.content
变量进行比较,这将变得非常冗长且重复。 switch
语句是一种快捷方式,其工作方式与上面的 if
语句完全相同,但语法更简洁且重复性更少。这是上面的 if
语句重写为 switch
语句的样子:
switch (message.content) {
case "ping":
// Do stuff for ping
break;
case "hello":
// Do stuff for hello
break;
//... and so on
default:
// Do stuff if none of the above cases equals value of message.content
break;
}
如您所见,switch
语句更清晰且重复更少,因此在 discord bot command-handling.
等情况下更受欢迎
问题
现在我们已经了解了 switch
语句应该如何工作,让我们看看您实际上是如何使用它们的。首先,你的 non-prefix 一个:
switch(!message.content.startsWith(prefix)){
case message.content.includes('ping'):
message.reply('pong')
break;
case message.content.includes('hello'):
message.reply('hello')
break;
}
现在,让我们使用不适合您的测试用例来查看此代码:当消息内容为 prefix + "ciao"
时。由于此消息中存在前缀,因此 !message.content.startsWith(prefix)
的计算结果为 false
。现在,让我们将上述 switch
语句中的所有其他值转换为它们的计算结果:
switch(false){
case false: //message doesn't include 'ping'
message.reply('pong')
break;
case false: //message doesn't include 'hello'
message.reply('hello')
break;
}
你明白为什么你现在遇到问题了吗?你的第一个 switch
语句基本上等同于做一堆 if (false == false)
语句,所以每当你做 prefix + "ciao"
时,第一个 switch
中的第一个 case
将总是被执行。
这是你第一个 switch
的问题,但你的第二个也有问题:
switch(command){
case command = 'ciao':
message.reply('ciao')
break;
}
case
中发生的是技术上无效的语法。 command = 'ciao'
将变量 command
的值设置为 'ciao'
,它并没有真正检查 command
等于 'ciao'
的情况。然而,像 x = y
这样的赋值语句做 return y
,这就是为什么这第二个 switch
最终为你工作。但是,我们可以通过删除不必要的 x =
.
来简化操作
解决方案
要解决这些问题,您需要做两件事。首先,修复 switch
语句中的语法和逻辑问题。其次,重新排序和重组您的代码以正确分离前缀和 non-prefix 命令的逻辑。
这是我所做的修复。我添加了解释某些更改的评论:
var args = message.content.trim().split(/ +/); //Args with no prefix
var command = args.shift().toLowerCase(); //Command with no prefix
if(message.author.bot) return;
//non-prefix commands
if (!message.content.startsWith(prefix)) { //Check if no prefix with 'if'
switch(command){
case 'ping': //Use proper 'switch' and 'case' syntax like so
message.reply('pong')
break;
case 'hello':
message.reply('hello')
break;
}
}
//prefix commands
else {
//Args and command accounting for prefix
args = message.content.slice(prefix.length).trim().split(/ +/);
command = args.shift().toLowerCase();
switch(command){
case 'ciao': //Removed incorrect "command = 'ciao'" syntax
message.reply('ciao')
break;
}
}
这应该可以解决您遇到的问题并解决您的 switch
语句中的问题。而且,由于实际的 switch
语法比您尝试使用的语法简单得多,因此您添加命令也应该容易得多。
我在使用 JavaScript 和 discord.js 的 switch 语句时遇到问题。我希望机器人执行带前缀和不带前缀的两个命令。当我尝试执行不带前缀的命令时,它会起作用,但是当我尝试执行前缀命令时,机器人会同时响应我询问的命令和我的非前缀命令中的第一种情况。这是代码:
const Discord = require('discord.js')
const fs = require('fs')
const token = "xxx"
const client = new Discord.Client({
intents: [
Discord.Intents.FLAGS.GUILDS,
Discord.Intents.FLAGS.GUILD_MESSAGES
]
})
client.commands = new Discord.Collection()
const commandFiles = fs.readdirSync(`./commands/`).filter(file => file.endsWith('.js'))
for (const file of commandFiles){
const command = require(`./commands/${file}`)
client.commands.set(command.name, command)
}
//ready event
client.on('ready', () => {
console.log('online')
})
const prefix = 'ao'
//message event
client.on('messageCreate', (message) => {
const args = message.content.slice(prefix.length).trim().split(/ +/);
var command = args.shift().toLowerCase()
if(message.author.bot) return;
//non-prefix commands
switch(!message.content.startsWith(prefix)){
case message.content.includes('ping'):
message.reply('pong')
break;
case message.content.includes('hello'):
message.reply('hello')
break;
}
//prefix commands
switch(command){
case command = 'ciao':
message.reply('ciao')
break;
}
})
client.login(token)
例如,如果我只输入“hello”或“ping”,机器人会回复正确的命令,但当我尝试使用“prefix + ciao”时,机器人会回复“pong”和“ciao”。
您的代码存在的问题是,您在代码中尝试执行的操作根本不是 switch
语句的工作方式。让我们首先看看 switch
语句实际上应该如何工作。
switch
语句如何工作
假设您有一个像 message.content
这样的值,您想要重复检查它的值。例如,你想知道是否 message.content == "ping"
,你想知道是否 message.content == "hello"
,等等。一种写法是这样的,使用经典的 if
语句:
if (message.content == "ping") {
// Do stuff for ping
}
else if (message.content == "hello") {
// Do stuff for hello
}
//... and so on
else {
// Do stuff if none of the above cases equals value of message.content
}
如您所见,如果您有数十个值要与同一个 message.content
变量进行比较,这将变得非常冗长且重复。 switch
语句是一种快捷方式,其工作方式与上面的 if
语句完全相同,但语法更简洁且重复性更少。这是上面的 if
语句重写为 switch
语句的样子:
switch (message.content) {
case "ping":
// Do stuff for ping
break;
case "hello":
// Do stuff for hello
break;
//... and so on
default:
// Do stuff if none of the above cases equals value of message.content
break;
}
如您所见,switch
语句更清晰且重复更少,因此在 discord bot command-handling.
问题
现在我们已经了解了 switch
语句应该如何工作,让我们看看您实际上是如何使用它们的。首先,你的 non-prefix 一个:
switch(!message.content.startsWith(prefix)){
case message.content.includes('ping'):
message.reply('pong')
break;
case message.content.includes('hello'):
message.reply('hello')
break;
}
现在,让我们使用不适合您的测试用例来查看此代码:当消息内容为 prefix + "ciao"
时。由于此消息中存在前缀,因此 !message.content.startsWith(prefix)
的计算结果为 false
。现在,让我们将上述 switch
语句中的所有其他值转换为它们的计算结果:
switch(false){
case false: //message doesn't include 'ping'
message.reply('pong')
break;
case false: //message doesn't include 'hello'
message.reply('hello')
break;
}
你明白为什么你现在遇到问题了吗?你的第一个 switch
语句基本上等同于做一堆 if (false == false)
语句,所以每当你做 prefix + "ciao"
时,第一个 switch
中的第一个 case
将总是被执行。
这是你第一个 switch
的问题,但你的第二个也有问题:
switch(command){
case command = 'ciao':
message.reply('ciao')
break;
}
case
中发生的是技术上无效的语法。 command = 'ciao'
将变量 command
的值设置为 'ciao'
,它并没有真正检查 command
等于 'ciao'
的情况。然而,像 x = y
这样的赋值语句做 return y
,这就是为什么这第二个 switch
最终为你工作。但是,我们可以通过删除不必要的 x =
.
解决方案
要解决这些问题,您需要做两件事。首先,修复 switch
语句中的语法和逻辑问题。其次,重新排序和重组您的代码以正确分离前缀和 non-prefix 命令的逻辑。
这是我所做的修复。我添加了解释某些更改的评论:
var args = message.content.trim().split(/ +/); //Args with no prefix
var command = args.shift().toLowerCase(); //Command with no prefix
if(message.author.bot) return;
//non-prefix commands
if (!message.content.startsWith(prefix)) { //Check if no prefix with 'if'
switch(command){
case 'ping': //Use proper 'switch' and 'case' syntax like so
message.reply('pong')
break;
case 'hello':
message.reply('hello')
break;
}
}
//prefix commands
else {
//Args and command accounting for prefix
args = message.content.slice(prefix.length).trim().split(/ +/);
command = args.shift().toLowerCase();
switch(command){
case 'ciao': //Removed incorrect "command = 'ciao'" syntax
message.reply('ciao')
break;
}
}
这应该可以解决您遇到的问题并解决您的 switch
语句中的问题。而且,由于实际的 switch
语法比您尝试使用的语法简单得多,因此您添加命令也应该容易得多。