所以我有我的eval命令,但是当我运行eval来设置状态或类似的东西时,它会返回[object Object]
或[object Map]
。我已经修复了[object Promise]
之前的错误,但是Object和Map仍然会出现。我的代码如下,如果有人知道如何解决这个问题,那将是惊人的。
if (message.content.startsWith(prefix + "eval")) {
if (message.content === (prefix + 'eval client.token')) {
const noToken = new Discord.MessageEmbed()
.setColor('RANDOM')
.setDescription('OI WHO GAVE YOU PERMISSION TO TOUCH MY TOKEN!!!nn*back off...*')
return message.channel.send(noToken)
}
var result = message.content.split(" ").slice(1).join(" ")
let evaled = await eval(result);
const evalEmbed = new Discord.MessageEmbed()
.setColor('RANDOM')
.addFields(
{ name: '**Input:**', value: ````jsn${args}````, inline: false },
{ name: '**Output:**', value: ````jsn${evaled}````, inline: false }
)
message.channel.send(evalEmbed)
}
好吧,你明白为什么要得到[object Object]
和[object Map]
吗?让我们以设置机器人的状态为例。查看文档以了解setStatus()
返回的内容。根据文档,它返回Promise<Presence>
。
问题
你提到你";已解决";它返回一个Promise
,我假设您的意思是使用async/await
来获得Promise
的结果,而不是获得Promise
本身。因此,基本上,在状态示例中,因为您使用的是await
,所以您不再获得Promise
,而是获得Presence
对象,这是Promise
的成功结果(正如文档中所提到的,当它说setStatus()
返回Promise<Presence>
时(。
好的,这意味着evaled
变量现在表示Presence
对象。所以evaled
是Object
,而不是String
;这不是一行文本,你可以发送在一条消息或嵌入。当您尝试像对待文本(String
(一样对待Object
时,您的代码将尝试将Object
转换为String
,这将导致您得到的文本:[object Object]
。当然,Map
也是如此,因为它也不是String
。
当您使用eval
命令时,结果可能是任何数据类型。例如,如果执行/eval 33
,则会返回一个Number
。如果执行/eval message.channel.name
,则会返回String
,因为频道名称将为文本。但如果你做/eval client.user.setStatus()
,你就不会得到一个简单的数字或一段文本。你会得到Object
,这就是你问题的原因。
由于eval
命令可以返回任何数据类型的结果,因此我们需要考虑无法转换为一段文本的数据类型,或者将转换为我们没有预料到的一段文本(如Object(的数据类型。
此外,我在您的代码中注意到,eval
命令的唯一限制是用户不能访问或修改机器人的令牌根本不允许用户访问eval命令通过eval
命令可能会比简单地访问您的令牌做得更糟。用户可以做任何事情,从故意导致错误使你的机器人崩溃,到创建一个新的消息处理程序,自动删除在你的机器人所在的所有公会中发送的每一条消息。此外,正如你现在的代码一样,用户仍然可以执行eval client.token
并破坏你的令牌,只需在该行末尾添加一个分号。这个关于eval命令限制的问题并不是造成问题的原因,但你需要解决它,否则就有可能为用户提供一种简单的方式来伤害你的机器人、你的机器人所在的公会和/或这些公会的成员。如果此机器人程序在您的计算机上本地托管,不将此命令仅限于您自己,甚至可以授予用户访问您计算机上文件的权限。
解决方案
以下是我建议您更改eval命令的方式,这样它既可以部分解决您的问题,又可以防止用户进行任何恶意操作。
if (message.content.startsWith(prefix + "eval")) {
if (message.author.id != "add YOUR discord id here") {
//Only allow bot developer(s) to use the eval command, not all users
const noToken = new Discord.MessageEmbed()
.setColor('RANDOM')
.setDescription('OI WHO GAVE YOU PERMISSION TO USE EVAL!!!nn*back off...*')
return message.channel.send(noToken)
}
var result = message.content.split(" ").slice(1).join(" ")
let evaled = await eval(result);
//Convert evaled into a JSON String if it is an Object
if (typeof evaled === "object") evaled = JSON.stringify(evaled);
//Do this if evaled is anything else other than a number, text, or true/false
if (typeof evaled !== "number" && typeof evaled !== "string" && typeof evaled !== "boolean") evaled = `Output could not be converted to text (output was of type: ${typeof evaled}).`;
const evalEmbed = new Discord.MessageEmbed()
.setColor('RANDOM')
.addFields(
{
name: '**Input:**',
value: ````jsn${args}````,
inline: false
},
{
name: '**Output:**',
value: ````jsn${evaled}````,
inline: false
}
);
message.channel.send(evalEmbed)
}
这肯定会解决您的[object Object]
问题(现在它将改为JSON字符串,如{"key": "value"}
(。不过,我不确定它是否能够将Map
转换为JSON。任何其他无法轻松转换为文本的内容(除了数字、布尔值、文本、对象和数组(都将被转换为一条消息,以这种格式表示:"Output could not be converted to text (output was of type: <insert datatype here>)."
您可以随意更改此代码,但您希望使其外观和工作效果最佳。输出应该如何查找您的特定输入完全取决于您。重要的是,你得到了这个答案的概念:使用typeof
来检查将被转换为类似[object Object]
的特定数据类型,并将这些数据转换为更好、更可读的数据。
我想重复一下,将此命令的使用限制为仅限您或直接使用此机器人程序的任何其他人。eval命令的目的是让机器人程序开发人员更容易解决代码中的问题,允许他们测试某些变量和属性的值,而不必重新启动您的机器人程序和console.log
这些值。然而,让所有用户都可以访问该命令,将为用户打开数百种不同的方式来恶意对待公会、会员、你的机器人,甚至你。