在嵌入中显示排行榜
Displaying leaderboard in embed
我正在尝试为我的 Discord 机器人创建排行榜命令,但在显示数据时遇到了一些问题,我当前的代码仅显示排名靠前的用户,您可以在图像中看到有 4 行,这是因为数据库中有 4 个条目,因此它获取信息但不显示所有数据。有人可以指出我在做什么 wrong/what 我需要更改才能解决此问题。 (照片中被遮挡的部分是我的用户名)
代码:
const top10 = db
.prepare(
'SELECT * FROM scores WHERE guild = ? ORDER BY points DESC LIMIT 10;',
)
.all(message.guild.id);
if (!top10) {
return;
}
for (const data of top10) {
let userNames = '';
for (let i = 0; i < top10.length; i++) {
const user = bot.users.cache.get(data.user).tag;
userNames += `\`${i + 1}\` ${user}\n`;
}
const level = `\`${data.level}\`\n`;
const xp = `\`${data.points.toLocaleString('en')}\`\n`;
const embed = new MessageEmbed()
.setAuthor(`Leaderboard for ${message.guild.name}`, message.guild.iconURL({ dynamic: true }))
.setColor(0x51267)
.addFields({ name: 'Top 10', value: userNames, inline: true },
{ name: 'Level', value: level, inline: true },
{ name: 'XP', value: xp, inline: true });
message.channel.send(embed);
return;
}
当前输出:
期望的输出:
通过阅读您的代码,我相信您在代码结构方面犯了错误。从表面上看,您的代码获取 top10
中的第一项,然后将其添加到字符串中的次数与 top10 数组的长度一样多。然后它获取第一个用户的级别和 xp,将其添加到一个字符串中,然后将其构建到一个嵌入中。
这是经过修改的代码,因此它应该可以按您的预期工作:
let userNames = '';
let levels = '';
let xp = '';
for (let i = 0; i < top10.length; i++) {
const data = top10[i];
const user = (await bot.users.fetch(data.user)).tag;
userNames += `\`${i + 1}\` ${user}\n`;
levels += `\`${data.level}\`\n`;
xp += `\`${data.points.toLocaleString('en')}\`\n`;
}
const embed = new MessageEmbed()
.setAuthor(`Leaderboard for ${message.guild.name}`, message.guild.iconURL({ dynamic: true }))
.setColor(0x51267)
.addFields({ name: 'Top 10', value: userNames, inline: true },
{ name: 'Level', value: levels, inline: true },
{ name: 'XP', value: xp, inline: true });
message.channel.send(embed);
return;
你的问题是,你只是将 \n
添加到 js 对象,所以它不起作用。
作为 varian,您可以使用数据创建 3 个 arr,然后将 db 结果推送信息映射到数据。
最好使用 message.guild.members.chache.get
来检查用户是否在服务器上,因为如果用户不在已处理的机器人中发送任何消息,bot.users.cache.get(data.user).tag
将在机器人重启后 return 失效频道。
const top10 = db.prepare('SELECT * FROM scores WHERE guild = ? ORDER BY points DESC LIMIT 10;').all(message.guild.id);
if (!top10) {
return;
}
let usersArr = [];
let levelArr = [];
let xpArr = [];
top10.forEach(dataUser, index => {
let findUser = message.guild.members.cache.get(dataUser.user);
if (findUser) {
usersArr.push(`\`${index + 1}\` ${user.tag}`);
levelArr.push(dataUser.level);
xpArr.push(dataUser.points.toLocaleString('en'));
}
});
const embed = new MessageEmbed()
.setAuthor(`Leaderboard for ${message.guild.name}`, message.guild.iconURL({ dynamic: true }))
.setColor(0x51267)
.addFields({ name: 'Top 10', value: usersArr.join('\n'), inline: true }, { name: 'Level', value: levelArr.join('\n'), inline: true }, { name: 'XP', value: xpArr.join('\n'), inline: true });
message.channel.send(embed);
我正在尝试为我的 Discord 机器人创建排行榜命令,但在显示数据时遇到了一些问题,我当前的代码仅显示排名靠前的用户,您可以在图像中看到有 4 行,这是因为数据库中有 4 个条目,因此它获取信息但不显示所有数据。有人可以指出我在做什么 wrong/what 我需要更改才能解决此问题。 (照片中被遮挡的部分是我的用户名) 代码:
const top10 = db
.prepare(
'SELECT * FROM scores WHERE guild = ? ORDER BY points DESC LIMIT 10;',
)
.all(message.guild.id);
if (!top10) {
return;
}
for (const data of top10) {
let userNames = '';
for (let i = 0; i < top10.length; i++) {
const user = bot.users.cache.get(data.user).tag;
userNames += `\`${i + 1}\` ${user}\n`;
}
const level = `\`${data.level}\`\n`;
const xp = `\`${data.points.toLocaleString('en')}\`\n`;
const embed = new MessageEmbed()
.setAuthor(`Leaderboard for ${message.guild.name}`, message.guild.iconURL({ dynamic: true }))
.setColor(0x51267)
.addFields({ name: 'Top 10', value: userNames, inline: true },
{ name: 'Level', value: level, inline: true },
{ name: 'XP', value: xp, inline: true });
message.channel.send(embed);
return;
}
当前输出:
通过阅读您的代码,我相信您在代码结构方面犯了错误。从表面上看,您的代码获取 top10
中的第一项,然后将其添加到字符串中的次数与 top10 数组的长度一样多。然后它获取第一个用户的级别和 xp,将其添加到一个字符串中,然后将其构建到一个嵌入中。
这是经过修改的代码,因此它应该可以按您的预期工作:
let userNames = '';
let levels = '';
let xp = '';
for (let i = 0; i < top10.length; i++) {
const data = top10[i];
const user = (await bot.users.fetch(data.user)).tag;
userNames += `\`${i + 1}\` ${user}\n`;
levels += `\`${data.level}\`\n`;
xp += `\`${data.points.toLocaleString('en')}\`\n`;
}
const embed = new MessageEmbed()
.setAuthor(`Leaderboard for ${message.guild.name}`, message.guild.iconURL({ dynamic: true }))
.setColor(0x51267)
.addFields({ name: 'Top 10', value: userNames, inline: true },
{ name: 'Level', value: levels, inline: true },
{ name: 'XP', value: xp, inline: true });
message.channel.send(embed);
return;
你的问题是,你只是将 \n
添加到 js 对象,所以它不起作用。
作为 varian,您可以使用数据创建 3 个 arr,然后将 db 结果推送信息映射到数据。
最好使用 message.guild.members.chache.get
来检查用户是否在服务器上,因为如果用户不在已处理的机器人中发送任何消息,bot.users.cache.get(data.user).tag
将在机器人重启后 return 失效频道。
const top10 = db.prepare('SELECT * FROM scores WHERE guild = ? ORDER BY points DESC LIMIT 10;').all(message.guild.id);
if (!top10) {
return;
}
let usersArr = [];
let levelArr = [];
let xpArr = [];
top10.forEach(dataUser, index => {
let findUser = message.guild.members.cache.get(dataUser.user);
if (findUser) {
usersArr.push(`\`${index + 1}\` ${user.tag}`);
levelArr.push(dataUser.level);
xpArr.push(dataUser.points.toLocaleString('en'));
}
});
const embed = new MessageEmbed()
.setAuthor(`Leaderboard for ${message.guild.name}`, message.guild.iconURL({ dynamic: true }))
.setColor(0x51267)
.addFields({ name: 'Top 10', value: usersArr.join('\n'), inline: true }, { name: 'Level', value: levelArr.join('\n'), inline: true }, { name: 'XP', value: xpArr.join('\n'), inline: true });
message.channel.send(embed);