discord.js搭配quick.db实现手动等级系统XP发放与升级异常排查
问题定位
1. 首次发放XP不生效/数值异常原因
代码执行顺序存在逻辑错误:
- 先从数据库读取
xp、level、totalxp三个字段的值存入本地变量,后续即使对数据库中这三个字段做了新用户初始化(设为0),也没有同步更新本地变量,本地变量仍为初始的null或旧值 - 调用
db.add更新数据库中totalxp的数值后,没有重新读取最新值到本地变量,后续所有逻辑判断用的都是加XP之前的旧值,导致计算完全错位
2. 0级用户满100XP不自动升级原因
升级判断逻辑用的是加XP之前的旧totalxp值:
- 比如给0级、当前
totalxp为0的用户加100XP,数据库中totalxp已经更新为100,但本地变量里的totalxp还是0,判断0 >= 100不满足,不会触发升级 - 下次再给用户加任意数值XP时,读取到的
totalxp是之前的100,判断100 >= 100满足,才会触发升级,正好对应你遇到的“需要再发一次XP才升级”的现象
修复方案
修改givexp.js里的核心逻辑,调整变量赋值和执行顺序即可,同时新增了连续跨级升级支持(比如一次性加300XP可直接升多级,避免漏升级),修复后代码如下:
const Discord = require("discord.js"); const db = require("quick.db") const adm = " "; //ids here module.exports = { name: "givexp" } module.exports.ex = async(message, args) => { let { guild } = message; const user = message.mentions.users.first(); if (message.author.id === adm) { if (!user) { message.channel.send(new Discord.MessageEmbed().setColor("D9B3FF").setTitle("Invalid Syntax").setDescription(`The format for [givexp] is \`>givexp @user#1234 [amount]\``)); } else { // xp requirements for each level const levels = { 0: 100, 1: 125, 2: 150, 3: 175, 4: 200, 5: 225 }; // total xp requirements const xpreqs = { 0: 100, 1: 225, 2: 350, 3: 475, 4: 600, 5: 725 } const giveAmount = args.slice(1).join(" "); let xp = db.get(`xp_${message.guild.id}_${user.id}`); let level = db.get(`level_${message.guild.id}_${user.id}`); let totalxp = db.get(`totalxp_${message.guild.id}_${user.id}`); // 初始化后同步更新本地变量 if (xp === null) { db.set(`xp_${message.guild.id}_${user.id}`, 0); xp = 0; } if (totalxp === null) { db.set(`totalxp_${message.guild.id}_${user.id}`, 0); totalxp = 0; } if (level === null) { db.set(`level_${message.guild.id}_${user.id}`, 0); level = 0; } if (giveAmount) { const addNum = parseInt(giveAmount); await db.add(`totalxp_${message.guild.id}_${user.id}`, addNum); // 加完后重新读取最新的totalxp再做判断 totalxp = db.get(`totalxp_${message.guild.id}_${user.id}`); user.send(new Discord.MessageEmbed().setColor("D9B3FF").setDescription(`You were awarded **${giveAmount}XP** by ${message.author.tag}`)); await message.channel.send(new Discord.MessageEmbed().setColor("D9B3FF").setDescription(`${user.tag} has been awarded **${giveAmount}XP** by ${message.author.tag}`)); console.log(`${message.author.tag} awarded ${user.tag} ${giveAmount}XP.`); // 循环判断支持连续升级 while(totalxp >= xpreqs[level] && level < Object.keys(xpreqs).length - 1) { await db.add(`level_${message.guild.id}_${user.id}`, 1); level = db.get(`level_${message.guild.id}_${user.id}`); await db.set(`xp_${message.guild.id}_${user.id}`, totalxp - xpreqs[level - 1]); await message.channel.send(new Discord.MessageEmbed().setColor("D9B3FF").setTitle("Level Up!").setDescription(`<@${user.id}> has reached Level ${level}!`)) } // 不需要升级时才累加当前等级XP if(totalxp < xpreqs[level]) { await db.add(`xp_${message.guild.id}_${user.id}`, addNum); } } else { message.channel.send(new Discord.MessageEmbed().setColor("D9B3FF").setTitle("Invalid Syntax").setDescription(`The format for [givexp] is \`>givexp @user#1234 [amount]\``)); } } } else { message.channel.send(new Discord.MessageEmbed().setColor("D9B3FF").setDescription(`<@${message.author.id}>, you do not have permission to give users XP.`)); } };
内容的提问来源于stack exchange,提问作者aerviix
相关产品推荐
相关产品推荐

