【问题标题】:How to post leaderboard in embed [discord.js]如何在嵌入 [discord.js] 中发布排行榜
【发布时间】:2021-03-23 11:21:42
【问题描述】:

我有一个 discord.js 调平系统,它将人们的关卡存储在一个 json 文件 database.json 中,如下所示:{"626916199783071750":{"xp":54,"level":14}我正在使用此代码对每个人的关卡进行排序:

members.sort(function(a, b) {
  const keyA = a[Object.keys(a)[0]].level,
        keyB = b[Object.keys(a)[0]].level;
  // Compare
  // (swap -1 and 1 to change sort order)
  if(keyA < keyB) return -1;
  if(keyA > keyB) return 1;
  return 0;
});
console.log(members);

(成员被定义为const members = [require("./database.json")];) 我能够很好地记录它并且它的顺序正确,但我想知道如何将它发送到嵌入中,因为此代码不起作用:

      let embed = new Discord.RichEmbed()
      .setColor(0x4286f4)
      .addField('Level:', members)
      member.channel.send(embed);

这给了我一个带有未定义字段的嵌入。 作为参考,我正在使用 discord.js v12+

【问题讨论】:

  • 应该是new Discord.MessageEmbed(),因为你使用的是 Discord.js 的 v12
  • 现在我得到TypeError: Cannot read property 'client' of undefined
  • 我认为它是由其他地方引起的,请检查引起错误的行号。
  • 我不相信 discord.js 允许您直接将嵌入字段或消息内容设置为数组/对象。在将数组添加到嵌入字段之前,您需要将其转换为字符串。至于Cannot read property 'client' of undefined,该错误与此问题无关,完全在您代码中的其他位置。
  • 它说它发生在let embed = new Discord.RichEmbed()的代码行上

标签: javascript node.js discord.js


【解决方案1】:

在多次编辑并在下面与您交谈后,我允许自己对您的机器人的运行方式进行一些更改。

数据存储

首先,您存储数据的方式有点糟糕。 JSON 是一个糟糕的选择,用作数据库非常烦人,但它仍然是一种选择。您应该查看Quick.db,它非常适合初学者!另一方面,您总是总是希望将文档存储在数组中。数组就是为此而生的。这是一些将当前数据切换到新模型的代码。不要忘记更新机器人中存储数据的其他部分,使其与新形状相匹配。我不想做太多更改,但我想补充一点,存储level 是个坏主意,因为它取决于xp。您应该编写一个将xp 转换为level 的函数并使用它,而不是存储level。

// const fs = require("fs")
// const oldDb = JSON.parse(fs.readFileSync("database.json"))
const oldDb = {
  "626916199783071750": {
    "xp": 69,
    "level": 14
  },
  "579776588732956674": {
    "xp": 2,
    "level": 13
  },
  "784566696244674621": {
    "xp": 99,
    "level": 1
  },
  "495304082769051660": {
    "xp": 6,
    "level": 1
  },
  "752987763573391411": {
    "xp": 1,
    "level": 0
  }
}

let newDb = Object.keys(oldDb).map((id) =>
  ({
    id,
    xp: oldDb[id].xp,
    level: oldDb[id].level
  })
)

console.log(newDb)
// fs.writeFile("database.json", JSON.stringify(newDb), 'utf8')

按级别排序

从那时起,您将能够以更高效的方式工作。由于我们更改了 bot 的数据模型,我将帮助您将排序方法转换为一种实际有效的方法。

// const users = require("./database.json"), with the new data model this time
const users = [{
  id: "626916199783071750",
  level: 14,
  xp: 69
}, {
  id: "579776588732956674",
  level: 13,
  xp: 2
}, {
  id: "784566696244674621",
  level: 1,
  xp: 99
}, {
  id: "495304082769051660",
  level: 1,
  xp: 6
}, {
  id: "752987763573391411",
  level: 0,
  xp: 1
}]

const sortedUsers = users.sort((a, b) => (a.level > b.level) ? 1 : -1) // ternary operation, it's basically just a 'if'
console.log(sortedUsers)

发布排行榜

啊,你做到了!现在,这是我的原始答案……如何发送所有数据。 您需要为每个成员添加一个字段。 MessageEmbed#addFields() 在这里很完美。以下代码未经测试。

const maxNumberOfUsersToDisplay = 10;

const embed = new Discord.MessageEmbed().setColor(0x4286f4).addFields(
  sortedUsers.flatMap((userDoc, i) => {
    // flatMap will map and delete all the [] of the array
    if (!(i < maxNumberOfUsersToDisplay && i < 25)) return [];

    return {
      name: user.id, // Feel free to mess with the code and replace this with a mention/tag
      value: `Level ${user.level}`,
      inline: false, // default value, just to show you you can adjust this param to change the embed layout
    };
  })
);

message.channel.send(embed);

Array#flatMap() 的作用类似于.map() 和.flat(),这是一种应更频繁使用的晦涩方法:它也可以用作.map() 和.filter(),如上所示。

【讨论】:

  • 这里是我的数据库的链接,您发送的内容应该仍然有效吗? sourceb.in/x4hsyLxeaf
  • 那你为什么用sort呢?这是一个对象...你能告诉我console.log(members) 的输出吗?
  • 日志让我Link to Image
  • 好的。你为什么使用[require('database-file')]? [] 的目的是什么?其中只有 1 个元素,因此 sort 方法什么也不做。
  • 如果我不这样做,它会给我TypeError: members.sort is not a function
猜你喜欢
  • 2021-05-14
  • 2021-09-03
  • 2020-11-22
  • 2020-06-21
  • 2019-07-26
  • 2020-07-29
  • 1970-01-01
  • 1970-01-01
  • 2020-08-19
相关资源
最近更新 更多