SQLite数据库在Discord.js机器人的主键下未保存多个值

时间:2019-07-06 18:25:52

标签: sql discord.js

首先,这是我的主要bot.js代码(很抱歉,如果它看起来像意大利面条代码。我对javascript并不是最好的选择):

const fs = require('fs');
const Discord = require('discord.js');
const client = new Discord.Client();
const auth = require('./auth.json');
const pack = require('./package.json');
const SQLite = require('better-sqlite3');
const sql = new SQLite('./scores.sqlite');
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);
}

client.on('ready', () => {
    console.log(`    Bot: ${client.user.tag}
    Version: ${pack.version}
    Logged in and clear for takeoff.`);
});

client.on("ready", () => {
  const battle_leaderboard = sql.prepare("SELECT count(*) FROM sqlite_master WHERE type='table' AND name = 'scores';").get();
  if (!battle_leaderboard['count(*)']) {
      sql.prepare("CREATE TABLE scores (id TEXT PRIMARY KEY, user TEXT, guild TEXT, points INTEGER;").run();
      sql.prepare("CREATE UNIQUE INDEX idx_scores_id ON scores (id);").run();
      sql.pragma("synchronous = 1");
      sql.pragma("journal_mode = wal");
    }

      client.getScore = sql.prepare("SELECT * FROM scores WHERE user = ? AND guild = ?");
      client.setScore = sql.prepare("INSERT OR REPLACE INTO scores (id, user, guild, points) VALUES (@id, @user, @guild, @points);");
            client.removeScore = sql.prepare("DELETE FROM scores WHERE user=?");
});

client.on('message', message => {
    if (!message.content.startsWith(auth.prefix) || message.author.bot) return;

    const args = message.content.slice(auth.prefix.length).split(/ +/);
    const command = args.shift().toLowerCase();

        switch (command) {
    case 'ping':
            client.commands.get('ping').execute(message, args);
        break;
    case 'mimic':
        client.commands.get('mimic').execute(message, args);
        break;
    case 'add_role':
        client.commands.get('add_role').execute(message, args);
        break;
    case 'remove_role':
        client.commands.get('remove_role').execute(message, args);
        break;
    case 'bl_add_point':
        if (message.member.roles.some(r=>["Fight Officiator"])) {
            let score;
            let member = message.mentions.members.first() || client.members.get(args[0]);
      score = client.getScore.get(member.id, member.guild.id);
      if (!score) {
      score = { id: `${member.guild.id}-${member.id}`, user: member.username, guild: member.guild.id, points: 0}
      }
      score.points ++;
      client.setScore.run(score);
      message.channel.send(`Looks like ${member} got a win! Good one.`);
        } else {
            message.channel.send(`Sorry, this is only usable by GFOs.`);
        };
        break;
    case '!bl_delete':
        if (message.member.roles.some(r=>["Fight Officiator"])) {
          let member = message.mentions.users.first();
          client.removeScore.run(`${member.guild.id}-${member.id}`)
      message.channel.send(`${member} has been set to zero on the leaderboard!`);
        } else {
            message.channel.send(`Sorry, this is only usable by GFOs.`);
        };
        break;
        case 'bl':
            const top5 = sql.prepare("SELECT * FROM scores WHERE guild = ? ORDER BY points DESC LIMIT 5;").all(message.guild.id);
            const battleleaderboard = new Discord.RichEmbed()
                .setColor('#FFD700')
                .setTitle('The Battle Leaderboard - Current Rankings')
                .setAuthor(`RankBot`)
                .setDescription('The top fighters are displayed here.')
                .setTimestamp()
                .setFooter(`DM a Gang Fight Officiator to set up a spar with another member and possibly get your name registered onto RankBot's leaderboard!`);

            for (const data of top5) {
                 battleleaderboard.addField(client.users.get(data.user), `${data.points} Win(s)`);
                }
            message.channel.send(battleleaderboard);
            break;
};
});

client.login(auth.token);

我正在创建一个非常简单的机器人: 该机器人是RankBot(至少是我所称的),它应使用特殊角色来跟踪战斗中的获胜数量(因为这是关于格斗游戏的不和),该角色可以通过手动添加这些获胜次数命令,然后能够拉出一个排行榜,向人们展示获胜最多的人。我正在与朋友进行测试的方式不一致,正在测试中,并且直到我们命令漫游器打开排行榜之前,它似乎一直有效。什么也没显示。我们认为这很奇怪,因为它在数据库中只有一个用户时才起作用,所以我去了PowerShell命令行查看是否有错误消息,然后显示出来。

C:\Users\USER\Documents\OF_RankBot\bot.js:89
                                 battleleaderboard.addField(client.users.get(data.user).tag || client.members.get(data.user).tag, `${data.points} Win(s)`);
                                                                                       ^

TypeError: Cannot read property 'tag' of undefined

我们对发生的事情感到困惑,因此我删除了命令的tag部分,然后再次使用它。这次出现了嵌入,但看起来像this.
我认为出了问题的原因是,由于他们都列出了相同的获胜次数,因此对用户进行排序的bl命令部分感到困惑。然后我去对我使用bl_add_point并再次尝试。显示了几乎完全相同的嵌入。

我对出什么问题的猜测是,在设置bl_add_point命令时,我有时会搞砸,但是我不确定如何解决此问题。

这不是主要问题的一部分,但是我似乎也无法使bl_delete工作。使用时没有显示错误。实际上,似乎什么也没发生。我不确定这些问题是否相关,但是我真的只需要解决主要问题。 预先感谢。

edit:我部分地发现了bl_delete问题的发生,这是我将前缀放在已经定义了前缀的情况下。现在,当我输入命令时,PowerShell将响应:

C:\Users\USER\Documents\OF_RankBot\bot.js:72
                  client.removeScore.run(`${member.guild.id}-${member.id}`)
                                                         ^

TypeError: Cannot read property 'id' of undefined

0 个答案:

没有答案