问题
I am trying to move all of my currency/shop commands/ Sequelize database into the command handler from index.js (works perfectly in index.js file) but I am running into issues transferring data from the index.js file into the individual command files. Any help on how to properly integrate the index.js commands into the command handler would be greatly appreciated. I realize this is a lot to go through but it would really mean a lot to me if anyone was able to help me out
index.js:
Reflect.defineProperty(currency, 'add', {
value: async function add(id, amount) {
const user = currency.get(id);
if (user) {
user.balance += Number(amount);
return user.save();
}
const newUser = await Users.create({ user_id: id, balance: amount });
currency.set(id, newUser);
return newUser;
},
});
Reflect.defineProperty(currency, 'getBalance', {
value: function getBalance(id) {
const user = currency.get(id);
return user ? user.balance : 0;
},
});
client.once('ready', async () => {
const storedBalances = await Users.findAll();
storedBalances.forEach(b => currency.set(b.user_id, b));
console.log(`Logged in as ${client.user.tag}!`);
});
client.on('message', async message => {
if (message.author.bot) return;
currency.add(message.author.id, 1);
if (!message.content.startsWith(prefix)) return;
const input = message.content.slice(prefix.length).trim();
if (!input.length) return;
const [, command, commandArgs] = input.match(/(\w+)\s*([\s\S]*)/);
if (command === 'balance') {
const target = message.mentions.users.first() || message.author;
return message.channel.send(`${target.tag} has ${currency.getBalance(target.id)}💰`);
} else if (command === 'buy') {
const item = await CurrencyShop.findOne({ where: { name: { [Op.like]: commandArgs } } });
if (!item) return message.channel.send('That item doesn\'t exist.');
if (item.cost > currency.getBalance(message.author.id)) {
return message.channel.send(`You don't have enough currency, ${message.author}`);
}
const user = await Users.findOne({ where: { user_id: message.author.id } });
currency.add(message.author.id, -item.cost);
await user.addItem(item);
message.channel.send(`You've bought a ${item.name}`);
} else if (command === 'shop') {
const items = await CurrencyShop.findAll();
return message.channel.send(items.map(i => `${i.name}: ${i.cost}💰`).join('\n'), { code: true });
} else if (command === 'leaderboard') {
return message.channel.send(
currency.sort((a, b) => b.balance - a.balance)
.filter(user => client.users.cache.has(user.user_id))
.first(10)
.map((user, position) => `(${position + 1}) ${(client.users.cache.get(user.user_id).tag)}: ${user.balance}💰`)
.join('\n'),
{ code: true }
);
}
});
converting balance command to balance.js
balance.js:
const { currency, getBalance, id, tag } = require('../index.js');
module.exports = {
name: "balance",
description: "checks balance",
execute(message) {
const target = message.mentions.users.first() || message.author;
message.channel.send(`${target.tag} has ${currency.getBalance(target.id)}💰`);
},
};
error:
TypeError: Cannot read property 'getBalance' of undefined
Command Handler
client.on('message', message => {
if (!message.content.startsWith(prefix) || message.author.bot) return;
const args = message.content.slice(prefix.length).split(/ +/);
const commandName = args.shift().toLowerCase();
const command = client.commands.get(commandName)
|| client.commands.find(cmd => cmd.aliases && cmd.aliases.includes(commandName));
if (!command) return;
if (command.guildOnly && message.channel.type !== 'text') {
return message.reply('I can\'t execute that command inside DMs!');
}
if (command.args && !args.length) {
let reply = `You didn't provide any arguments, ${message.author}!`;
if (command.usage) {
reply += `\nThe proper usage would be: \`${prefix}${command.name} ${command.usage}\``;
}
return message.channel.send(reply);
}
if (!cooldowns.has(command.name)) {
cooldowns.set(command.name, new Discord.Collection());
}
const now = Date.now();
const timestamps = cooldowns.get(command.name);
const cooldownAmount = (command.cooldown || 3) * 1000;
if (timestamps.has(message.author.id)) {
const expirationTime = timestamps.get(message.author.id) + cooldownAmount;
if (now < expirationTime) {
const timeLeft = (expirationTime - now) / 1000;
return message.reply(`please wait ${timeLeft.toFixed(1)} more second(s) before reusing the \`${command.name}\` command.`);
}
}
timestamps.set(message.author.id, now);
setTimeout(() => timestamps.delete(message.author.id), cooldownAmount);
try {
command.execute(message, args);
} catch (error) {
console.error(error);
message.reply('there was an error trying to execute that command!');
}
});
the bot sends an error from the command handler as seen above
EDIT: Cherryblossom's post seems to work. i have 1 more issue with immigrating the buy command though I dont know how to make the async work as async doesnt work in command handler. here is what i tried
const { currency, CurrencyShop} = require('../index.js');
const item = await CurrencyShop.findOne({ where: { name: { [Op.like]: commandArgs } } });
if (!item) return message.channel.send('That item doesn\'t exist.');
if (item.cost > currency.getBalance(message.author.id)) {
return message.channel.send(`You don't have enough currency, ${message.author}`);
}
const user = await Users.findOne({ where: { user_id: message.author.id } });
currency.add(message.author.id, -item.cost);
await user.addItem(item);
message.channel.send(`You've bought a ${item.name}`);```
回答1:
What's happening is that in balance.js, currency
is undefined. You need to export currency
from index.js:
module.exports = { currency }
Also, in balance.js, you don't need to (and actually can't) import/require properties of other objects (getBalance
, tag
, id
). Sorry if that doesn't make sense but basically you only need to require currency
:
const { currency } = require('../index.js')
Edit
await
can only be used in an async function. Edit the execute
function so it is like this:
async execute(message) {
// your code here
}
When calling execute
, use await
. You'll need to make the message handler async as well:
client.on('message', async message => {
// code...
try {
await command.execute(message, args);
} catch (error) {
console.error(error);
message.reply('there was an error trying to execute that command!');
}
}
来源:https://stackoverflow.com/questions/60537931/discord-js-currency-to-command-handler