【问题标题】:Adding a cooldown to awarding points on SQLite xp system在 SQLite xp 系统上为奖励积分添加冷却时间
【发布时间】:2020-12-31 23:16:09
【问题描述】:

我希望通过每 60 秒只获得一次经验来改进我的积分系统。我尝试了一些东西,但没有一个真正接近。当前积分奖励代码为

client.on('ready', () => {
 // Check if the table "points" exists.
 const table = sql
  .prepare(
   "SELECT count(*) FROM sqlite_master WHERE type='table' AND name = 'scores';"
  )
  .get();
 if (!table['count(*)']) {
  // create and setup the database correctly.
  sql
   .prepare(
    'CREATE TABLE scores (id TEXT PRIMARY KEY, user TEXT, guild TEXT, points INTEGER, level INTEGER);'
   )
   .run();
  // "id" row is always unique and indexed.
  sql.prepare('CREATE UNIQUE INDEX idx_scores_id ON scores (id);').run();
  sql.pragma('synchronous = 1');
  sql.pragma('journal_mode = wal');
 }

 // get and set the score data.
 client.getScore = sql.prepare(
  'SELECT * FROM scores WHERE user = ? AND guild = ?'
 );
 client.setScore = sql.prepare(
  'INSERT OR REPLACE INTO scores (id, user, guild, points, level) VALUES (@id, @user, @guild, @points, @level);'
 );
});
client.on('message', (message) => {
 if (message.author.bot) return;
 let score;
 if (message.guild) {
  score = client.getScore.get(message.author.id, message.guild.id);
  if (!score) {
   score = {
    id: `${message.guild.id}-${message.author.id}`,
    user: message.author.id,
    guild: message.guild.id,
    points: 0,
    level: 1,
   };
  }
  score.points++;
  const curLevel = Math.floor(0.2 * Math.sqrt(score.points));
  if (score.level < curLevel) {
   score.level++;
   client.channels.cache
    .get('738662532700700719')
    .send(`${message.author} has leveled up to level **${curLevel}**!`);
  }
  client.setScore.run(score);
 }

 if (message.content.indexOf(config.prefix) !== 0) return;

 const args = message.content
  .slice(config.prefix.length)
  .trim()
  .split(/ +/g);
 const command = args.shift().toLowerCase();
});

【问题讨论】:

    标签: javascript node.js sqlite discord.js


    【解决方案1】:

    我想到的是存储您上次给用户积分的时间戳。然后,每次您想为新消息奖励用户更多积分时,请检查当前时间是否比您上次为用户分配积分的时间晚了 60 秒以上。

    看看下面的示例代码并试一试。它可能需要调整,因为我对 SQLite 没有真正的经验,但我会在下面链接我使用的资源。

    client.on('ready', () => {
     // Check if the table "points" exists.
     const table = sql
      .prepare(
       "SELECT count(*) FROM sqlite_master WHERE type='table' AND name = 'scores';"
      )
      .get();
     if (!table['count(*)']) {
      // create and setup the database correctly.
      // Includes the new column 'lastAwardedDate'.
      sql
       .prepare(
        'CREATE TABLE scores (id TEXT PRIMARY KEY, user TEXT, guild TEXT, points INTEGER, level INTEGER, lastAwardedDate TEXT);'
       )
       .run();
      // "id" row is always unique and indexed.
      sql.prepare('CREATE UNIQUE INDEX idx_scores_id ON scores (id);').run();
      sql.pragma('synchronous = 1');
      sql.pragma('journal_mode = wal');
     }
    
     // get and set the score data.
     client.getScore = sql.prepare(
      'SELECT * FROM scores WHERE user = ? AND guild = ?'
     );
     client.setScore = sql.prepare(
      'INSERT OR REPLACE INTO scores (id, user, guild, points, level, lastAwardedDate) VALUES (@id, @user, @guild, @points, @level, @lastAwardedDate);'
     );
    });
    
    // Define a constant value for the delay (in ms).
    const pointDelay = 60 * 1000;
    
    client.on('message', (message) => {
     if (message.author.bot) return;
     let score;
     if (message.guild) {
      score = client.getScore.get(message.author.id, message.guild.id);
      if (!score) {
       score = {
        id: `${message.guild.id}-${message.author.id}`,
        user: message.author.id,
        guild: message.guild.id,
        points: 0,
        level: 1,
       };
      } else {
       // Check if the current time minus the last awarded time is less than the delay.
       if (new Date() - Date.parse(score.lastAwardedDate) < pointDelay) {
        return;
       }
      }
      score.points++;
      score.lastAwardedDate = new Date().toString();
      const curLevel = Math.floor(0.2 * Math.sqrt(score.points));
      if (score.level < curLevel) {
       score.level++;
       client.channels.cache
        .get('738662532700700719')
        .send(`${message.author} has leveled up to level **${curLevel}**!`);
      }
      client.setScore.run(score);
     }
    
     if (message.content.indexOf(config.prefix) !== 0) return;
    
     const args = message.content
      .slice(config.prefix.length)
      .trim()
      .split(/ +/g);
     const command = args.shift().toLowerCase();
    });
    

    我使用的来源:

    【讨论】:

    • 您好,谢谢您的回复 - 它非常有用!我现在遇到了 client.setScore.run(score); 的问题。我收到“TypeError:SQLite3 只能绑定数字、字符串、bigint、缓冲区和空值”的持续错误。你能解释一下为什么会这样吗?
    • 就像我说的,我对 SQLite 没有太多经验,但如果我猜测的话,我认为 score.lastAwardedDate = new Date(); 行可能会导致问题。我猜 SQL 正在尝试将其保存为 Date 对象,而不是先将其解析为字符串。尝试将该行更改为score.lastAwardedDate = new Date().toString();,看看它是否有效
    猜你喜欢
    • 1970-01-01
    • 2021-04-21
    • 1970-01-01
    • 1970-01-01
    • 2020-11-14
    • 1970-01-01
    • 2012-07-29
    • 2016-02-19
    • 1970-01-01
    相关资源
    最近更新 更多