You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Discord.js偷糖果命令逻辑错误:余额不足仍执行扣款

问题排查与修复:Discord.js /steal命令逻辑错误

问题描述

编写的Discord.js /steal命令用于偷取用户糖果,但存在逻辑问题:当目标用户的Candies数值小于偷取数量stealAmt时,命令仍会扣除其糖果;仅当把判断条件改为Candies > stealAmt时逻辑才看似正常,但这不符合实际需求。

问题根源

代码存在核心逻辑错误:

  • 用const { Candies } = profileData;获取的是命令执行者的糖果数,而非目标用户的糖果数
  • 后续判断if (Candies < stealAmt)是在检查执行者自己的糖果够不够,完全和目标用户无关,导致判断失效,错误执行扣除操作

修复步骤

  1. 获取目标用户的Profile数据:在判断前先查询目标用户的profileModel数据
  2. 修正判断条件:检查目标用户的糖果数是否大于等于偷取数量(targetUserCandies >= stealAmt)
  3. 调整代码顺序:先检查目标用户是否存在数据,再判断糖果数量,避免无效的数据库更新操作

修复后的完整代码

const { SlashCommandBuilder } = require("discord.js");
const profileModel = require("../models/profileSchema");
const parseMilliseconds = require("parse-ms-2");

module.exports = {
  cooldown: 10,
  data: new SlashCommandBuilder()
    .setName("steal")
    .setDescription("steals candies from a user")
    .addUserOption((option) =>
      option
        .setName("user")
        .setDescription("The user you want to steal from")
        .setRequired(true)
    )
    .addIntegerOption((option) =>
      option
        .setName("amount")
        .setDescription("The amount you want to steal")
        .setRequired(true)
        .setMinValue(1)
        .setMaxValue(2)
    ),
  async execute(interaction, profileData) {
    const targetUser = interaction.options.getUser("user");
    const stealAmt = interaction.options.getInteger("amount");

    try {
      await interaction.deferReply();

      const commandName = `Steal`;
      const userId = interaction.user.id;

      let cooldown = await Cooldown.findOne({ userId, commandName });

      if (cooldown && Date.now() < cooldown.endsAt) {
        const { default: prettyMs } = await import(`pretty-ms`);
        await interaction.editReply(
          `You are on cooldown, come back after ${prettyMs(
            cooldown.endsAt - Date.now()
          )}`
        );
        return;
      }

      if (!cooldown) {
        cooldown = new Cooldown({ userId, commandName });
      }

      // 查询目标用户的Profile数据
      const targetUserData = await profileModel.findOne({ userId: targetUser.id });
      
      // 检查目标用户是否存在数据
      if (!targetUserData) {
        return await interaction.editReply(`<@${targetUser.id}> doesn't have a bag!`);
      }

      // 检查目标用户的糖果数是否足够被偷取
      if (targetUserData.Candies < stealAmt) {
        return await interaction.editReply(
          `<@${targetUser.id}> does not have ${stealAmt} candies in their bag!`
        );
      }

      // 执行偷取操作:扣除目标用户糖果,增加执行者糖果
      await profileModel.findOneAndUpdate(
        { userId: targetUser.id },
        { $inc: { Candies: -stealAmt } }
      );

      await profileModel.findOneAndUpdate(
        { userId: interaction.user.id },
        { $inc: { Candies: +stealAmt } }
      );

      // 正确设置冷却时间(原代码无实际冷却,此处修正为10秒)
      cooldown.endsAt = Date.now() + this.cooldown * 1000;

      await Promise.all([cooldown.save(), profileData.save()]);

      interaction.editReply(
        `You have stolen ${stealAmt} candies from <@${targetUser.id}>`
      );
    } catch (error) {
      console.log(`Error handling /steal: ${error}`);
    }
  },
};

额外优化提示

  • 原代码中cooldown.endsAt = Date.now() + 0等于没有设置冷却,已修正为Date.now() + this.cooldown * 1000,应用定义的10秒冷却
  • 修正变量名拼写:原recieveUser改为targetUser,更符合语义

内容的提问来源于stack exchange,提问作者Magicstar135

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 16:34:56