在 SQLite xp 系统上为奖励积分添加冷却时间
Posted
技术标签:
【中文标题】在 SQLite xp 系统上为奖励积分添加冷却时间【英文标题】:Adding a cooldown to awarding points on SQLite xp system 【发布时间】: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();
);
【问题讨论】:
【参考方案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();
);
我使用的来源:
SQLite Date & Time Date.toISOString【讨论】:
您好,谢谢您的回复 - 它非常有用!我现在遇到了 client.setScore.run(score); 的问题。我收到“TypeError:SQLite3 只能绑定数字、字符串、bigint、缓冲区和空值”的持续错误。你能解释一下为什么会这样吗? 就像我说的,我对 SQLite 没有太多经验,但如果我猜测的话,我认为score.lastAwardedDate = new Date();
行可能会导致问题。我猜 SQL 正在尝试将其保存为 Date 对象,而不是先将其解析为字符串。尝试将该行更改为score.lastAwardedDate = new Date().toString();
,看看它是否有效以上是关于在 SQLite xp 系统上为奖励积分添加冷却时间的主要内容,如果未能解决你的问题,请参考以下文章
在branch.io中的redeemRewards函数调用时每次显示错误消息