mirror of
https://github.com/aydenjahola/discord-multipurpose-bot.git
synced 2024-11-24 17:55:56 +00:00
add economy system
This commit is contained in:
parent
9453225b23
commit
fc46176044
12 changed files with 655 additions and 0 deletions
35
commands/economy/balance.js
Normal file
35
commands/economy/balance.js
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
const { SlashCommandBuilder, EmbedBuilder } = require("discord.js");
|
||||||
|
const UserEconomy = require("../../models/UserEconomy");
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
data: new SlashCommandBuilder()
|
||||||
|
.setName("balance")
|
||||||
|
.setDescription("Check your balance"),
|
||||||
|
|
||||||
|
async execute(interaction) {
|
||||||
|
const { user, guild } = interaction;
|
||||||
|
|
||||||
|
let userEconomy = await UserEconomy.findOne({
|
||||||
|
userId: user.id,
|
||||||
|
guildId: guild.id,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!userEconomy) {
|
||||||
|
userEconomy = await UserEconomy.create({
|
||||||
|
userId: user.id,
|
||||||
|
guildId: guild.id,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const embed = new EmbedBuilder()
|
||||||
|
.setColor("#0099ff")
|
||||||
|
.setTitle(`${user.username}'s Balance`)
|
||||||
|
.setDescription(`You have **${userEconomy.balance}** coins.`)
|
||||||
|
.setTimestamp()
|
||||||
|
.setFooter({
|
||||||
|
text: `Requested by ${user.username}`,
|
||||||
|
iconURL: user.displayAvatarURL(),
|
||||||
|
});
|
||||||
|
await interaction.reply({ embeds: [embed] });
|
||||||
|
},
|
||||||
|
};
|
72
commands/economy/daily.js
Normal file
72
commands/economy/daily.js
Normal file
|
@ -0,0 +1,72 @@
|
||||||
|
const { SlashCommandBuilder, EmbedBuilder } = require("discord.js");
|
||||||
|
const UserEconomy = require("../../models/UserEconomy");
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
data: new SlashCommandBuilder()
|
||||||
|
.setName("daily")
|
||||||
|
.setDescription("Claim your daily reward"),
|
||||||
|
|
||||||
|
async execute(interaction) {
|
||||||
|
const { user, guild } = interaction;
|
||||||
|
const dailyReward = 100;
|
||||||
|
const oneDay = 24 * 60 * 60 * 1000;
|
||||||
|
|
||||||
|
let userEconomy = await UserEconomy.findOne({
|
||||||
|
userId: user.id,
|
||||||
|
guildId: guild.id,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!userEconomy) {
|
||||||
|
userEconomy = await UserEconomy.create({
|
||||||
|
userId: user.id,
|
||||||
|
guildId: guild.id,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const now = new Date();
|
||||||
|
if (userEconomy.lastDaily && now - userEconomy.lastDaily < oneDay) {
|
||||||
|
const remainingTime =
|
||||||
|
new Date(userEconomy.lastDaily.getTime() + oneDay) - now;
|
||||||
|
const hours = Math.floor((remainingTime / (1000 * 60 * 60)) % 24);
|
||||||
|
const minutes = Math.floor((remainingTime / (1000 * 60)) % 60);
|
||||||
|
const seconds = Math.floor((remainingTime / 1000) % 60);
|
||||||
|
|
||||||
|
const errorEmbed = new EmbedBuilder()
|
||||||
|
.setColor("#ff0000")
|
||||||
|
.setTitle("Daily Reward Claim")
|
||||||
|
.setDescription(
|
||||||
|
`You have already claimed your daily reward today. Come back in **${hours}h ${minutes}m ${seconds}s**!`
|
||||||
|
)
|
||||||
|
.setFooter({
|
||||||
|
text: `Requested in ${guild.name}`,
|
||||||
|
iconURL: guild.iconURL() || null,
|
||||||
|
});
|
||||||
|
|
||||||
|
await interaction.reply({ embeds: [errorEmbed] });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
userEconomy.balance += dailyReward;
|
||||||
|
userEconomy.lastDaily = now;
|
||||||
|
await userEconomy.save();
|
||||||
|
|
||||||
|
const successEmbed = new EmbedBuilder()
|
||||||
|
.setColor("#00ff00")
|
||||||
|
.setTitle("Daily Reward Claimed!")
|
||||||
|
.setDescription(
|
||||||
|
`You claimed your daily reward of **${dailyReward}** coins!`
|
||||||
|
)
|
||||||
|
.addFields({
|
||||||
|
name: "Total Balance",
|
||||||
|
value: `You now have **${userEconomy.balance}** coins.`,
|
||||||
|
inline: true,
|
||||||
|
})
|
||||||
|
.setTimestamp()
|
||||||
|
.setFooter({
|
||||||
|
text: `Requested by ${user.username}`,
|
||||||
|
iconURL: user.displayAvatarURL(),
|
||||||
|
});
|
||||||
|
|
||||||
|
await interaction.reply({ embeds: [successEmbed] });
|
||||||
|
},
|
||||||
|
};
|
70
commands/economy/inventory.js
Normal file
70
commands/economy/inventory.js
Normal file
|
@ -0,0 +1,70 @@
|
||||||
|
const { SlashCommandBuilder, EmbedBuilder } = require("discord.js");
|
||||||
|
const UserInventory = require("../../models/UserInventory");
|
||||||
|
const ShopItem = require("../../models/ShopItem");
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
data: new SlashCommandBuilder()
|
||||||
|
.setName("inventory")
|
||||||
|
.setDescription("View your inventory"),
|
||||||
|
|
||||||
|
async execute(interaction) {
|
||||||
|
const { user, guild } = interaction;
|
||||||
|
|
||||||
|
const inventory = await UserInventory.find({
|
||||||
|
userId: user.id,
|
||||||
|
guildId: guild.id,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (inventory.length === 0) {
|
||||||
|
const emptyEmbed = new EmbedBuilder()
|
||||||
|
.setColor("#ff0000")
|
||||||
|
.setTitle("Inventory")
|
||||||
|
.setDescription("Your inventory is empty.")
|
||||||
|
.setFooter({
|
||||||
|
text: `Requested in ${guild.name}`,
|
||||||
|
iconURL: guild.iconURL() || null,
|
||||||
|
});
|
||||||
|
|
||||||
|
await interaction.reply({ embeds: [emptyEmbed] });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const itemDetails = await Promise.all(
|
||||||
|
inventory.map(async (item) => {
|
||||||
|
const shopItem = await ShopItem.findOne({ itemId: item.itemId });
|
||||||
|
if (item.quantity > 0) {
|
||||||
|
return `${shopItem.name} (x${item.quantity})`;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
const filteredItemDetails = itemDetails.filter((detail) => detail !== null);
|
||||||
|
|
||||||
|
if (filteredItemDetails.length === 0) {
|
||||||
|
const noItemsEmbed = new EmbedBuilder()
|
||||||
|
.setColor("#ff0000")
|
||||||
|
.setTitle("Inventory")
|
||||||
|
.setDescription("Your inventory is empty.")
|
||||||
|
.setFooter({
|
||||||
|
text: `Requested in ${guild.name}`,
|
||||||
|
iconURL: guild.iconURL() || null,
|
||||||
|
});
|
||||||
|
|
||||||
|
await interaction.reply({ embeds: [noItemsEmbed] });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const inventoryEmbed = new EmbedBuilder()
|
||||||
|
.setColor("#00ff00")
|
||||||
|
.setTitle(`${user.username}'s Inventory`)
|
||||||
|
.setDescription(filteredItemDetails.join("\n"))
|
||||||
|
.setTimestamp()
|
||||||
|
.setFooter({
|
||||||
|
text: `Requested by ${user.username}`,
|
||||||
|
iconURL: user.displayAvatarURL(),
|
||||||
|
});
|
||||||
|
|
||||||
|
await interaction.reply({ embeds: [inventoryEmbed] });
|
||||||
|
},
|
||||||
|
};
|
108
commands/economy/shop.js
Normal file
108
commands/economy/shop.js
Normal file
|
@ -0,0 +1,108 @@
|
||||||
|
const { SlashCommandBuilder, EmbedBuilder } = require("discord.js");
|
||||||
|
const ShopItem = require("../../models/ShopItem");
|
||||||
|
const UserEconomy = require("../../models/UserEconomy");
|
||||||
|
const UserInventory = require("../../models/UserInventory");
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
data: new SlashCommandBuilder()
|
||||||
|
.setName("shop")
|
||||||
|
.setDescription("View the shop and buy items")
|
||||||
|
.addStringOption((option) =>
|
||||||
|
option.setName("item").setDescription("The ID of the item to buy")
|
||||||
|
),
|
||||||
|
|
||||||
|
async execute(interaction) {
|
||||||
|
const { user, guild } = interaction;
|
||||||
|
const itemId = interaction.options.getString("item");
|
||||||
|
|
||||||
|
if (!itemId) {
|
||||||
|
const items = await ShopItem.find();
|
||||||
|
const itemDescriptions = items.map(
|
||||||
|
(item) => `**${item.itemId}**: ${item.name} - **${item.price}** coins`
|
||||||
|
);
|
||||||
|
|
||||||
|
const shopEmbed = new EmbedBuilder()
|
||||||
|
.setColor("#00bfff")
|
||||||
|
.setTitle("🛒 Shop Items")
|
||||||
|
.setDescription(
|
||||||
|
itemDescriptions.length > 0
|
||||||
|
? itemDescriptions.join("\n")
|
||||||
|
: "No items available at the moment."
|
||||||
|
)
|
||||||
|
.setFooter({
|
||||||
|
text: `Requested in ${guild.name}`,
|
||||||
|
iconURL: guild.iconURL() || null,
|
||||||
|
});
|
||||||
|
|
||||||
|
await interaction.reply({ embeds: [shopEmbed] });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const shopItem = await ShopItem.findOne({ itemId });
|
||||||
|
if (!shopItem) {
|
||||||
|
const notFoundEmbed = new EmbedBuilder()
|
||||||
|
.setColor("#ff0000")
|
||||||
|
.setTitle("❌ Item Not Found")
|
||||||
|
.setDescription("The specified item could not be found in the shop.")
|
||||||
|
.setFooter({
|
||||||
|
text: `Requested in ${guild.name}`,
|
||||||
|
iconURL: guild.iconURL() || null,
|
||||||
|
});
|
||||||
|
|
||||||
|
await interaction.reply({ embeds: [notFoundEmbed] });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const userEconomy = await UserEconomy.findOne({
|
||||||
|
userId: user.id,
|
||||||
|
guildId: guild.id,
|
||||||
|
});
|
||||||
|
if (!userEconomy || userEconomy.balance < shopItem.price) {
|
||||||
|
const insufficientFundsEmbed = new EmbedBuilder()
|
||||||
|
.setColor("#ff0000")
|
||||||
|
.setTitle("💸 Insufficient Funds")
|
||||||
|
.setDescription("You don't have enough coins to purchase this item.")
|
||||||
|
.setFooter({
|
||||||
|
text: `Requested in ${guild.name}`,
|
||||||
|
iconURL: guild.iconURL() || null,
|
||||||
|
});
|
||||||
|
|
||||||
|
await interaction.reply({ embeds: [insufficientFundsEmbed] });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
userEconomy.balance -= shopItem.price;
|
||||||
|
await userEconomy.save();
|
||||||
|
|
||||||
|
let userInventory = await UserInventory.findOne({
|
||||||
|
userId: user.id,
|
||||||
|
guildId: guild.id,
|
||||||
|
itemId,
|
||||||
|
});
|
||||||
|
if (userInventory) {
|
||||||
|
userInventory.quantity += 1;
|
||||||
|
} else {
|
||||||
|
userInventory = new UserInventory({
|
||||||
|
userId: user.id,
|
||||||
|
guildId: guild.id,
|
||||||
|
itemId,
|
||||||
|
quantity: 1,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
await userInventory.save();
|
||||||
|
|
||||||
|
const successEmbed = new EmbedBuilder()
|
||||||
|
.setColor("#00ff00")
|
||||||
|
.setTitle("🎉 Purchase Successful")
|
||||||
|
.setDescription(
|
||||||
|
`You've successfully purchased **${shopItem.name}** for **${shopItem.price}** coins!`
|
||||||
|
)
|
||||||
|
.setTimestamp()
|
||||||
|
.setFooter({
|
||||||
|
text: `Requested by ${user.username}`,
|
||||||
|
iconURL: user.displayAvatarURL(),
|
||||||
|
});
|
||||||
|
|
||||||
|
await interaction.reply({ embeds: [successEmbed] });
|
||||||
|
},
|
||||||
|
};
|
166
commands/economy/trade.js
Normal file
166
commands/economy/trade.js
Normal file
|
@ -0,0 +1,166 @@
|
||||||
|
const { SlashCommandBuilder } = require("discord.js");
|
||||||
|
const UserInventory = require("../../models/UserInventory");
|
||||||
|
const UserEconomy = require("../../models/UserEconomy");
|
||||||
|
const Trade = require("../../models/Trade");
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
data: new SlashCommandBuilder()
|
||||||
|
.setName("trade")
|
||||||
|
.setDescription("Trade an item and/or coins with another user")
|
||||||
|
.addUserOption((option) =>
|
||||||
|
option
|
||||||
|
.setName("user")
|
||||||
|
.setDescription("The user to trade with")
|
||||||
|
.setRequired(true)
|
||||||
|
)
|
||||||
|
.addStringOption((option) =>
|
||||||
|
option
|
||||||
|
.setName("item")
|
||||||
|
.setDescription("The ID of the item to trade")
|
||||||
|
.setRequired(true)
|
||||||
|
)
|
||||||
|
.addIntegerOption((option) =>
|
||||||
|
option
|
||||||
|
.setName("quantity")
|
||||||
|
.setDescription("Quantity of the item to trade")
|
||||||
|
.setRequired(true)
|
||||||
|
)
|
||||||
|
.addIntegerOption((option) =>
|
||||||
|
option
|
||||||
|
.setName("coins")
|
||||||
|
.setDescription("Amount of coins to trade")
|
||||||
|
.setRequired(false)
|
||||||
|
),
|
||||||
|
|
||||||
|
async execute(interaction) {
|
||||||
|
const { user, guild } = interaction;
|
||||||
|
const tradeUser = interaction.options.getUser("user");
|
||||||
|
const itemId = interaction.options.getString("item");
|
||||||
|
const quantity = interaction.options.getInteger("quantity");
|
||||||
|
const coins = interaction.options.getInteger("coins") || 0;
|
||||||
|
|
||||||
|
if (tradeUser.id === user.id) {
|
||||||
|
await interaction.reply("You can't trade items with yourself.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const userInventory = await UserInventory.findOne({
|
||||||
|
userId: user.id,
|
||||||
|
guildId: guild.id,
|
||||||
|
itemId,
|
||||||
|
});
|
||||||
|
if (!userInventory || userInventory.quantity < quantity) {
|
||||||
|
await interaction.reply("You don't have enough of this item to trade.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const tradeUserEconomy = await UserEconomy.findOne({
|
||||||
|
userId: tradeUser.id,
|
||||||
|
guildId: guild.id,
|
||||||
|
});
|
||||||
|
if (!tradeUserEconomy || tradeUserEconomy.balance < coins) {
|
||||||
|
await interaction.reply(
|
||||||
|
`${tradeUser.username} does not have enough coins to trade.`
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const tradeProposal = new Trade({
|
||||||
|
from: user.id,
|
||||||
|
to: tradeUser.id,
|
||||||
|
itemId,
|
||||||
|
quantity,
|
||||||
|
coins,
|
||||||
|
});
|
||||||
|
await tradeProposal.save();
|
||||||
|
|
||||||
|
await interaction.reply({
|
||||||
|
content: `Trade proposed: You are trading **${quantity}** of **${itemId}** and **${coins}** coins with ${tradeUser.username}.`,
|
||||||
|
ephemeral: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
await tradeUser.send(
|
||||||
|
`Trade proposal: You are being offered **${quantity}** of **${itemId}** and **${coins}** coins by ${user.username}. Type \`/accept ${tradeProposal._id}\` to accept or \`/reject ${tradeProposal._id}\` to reject the trade.`
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
|
async accept(interaction) {
|
||||||
|
const tradeId = interaction.options.getString("tradeId");
|
||||||
|
const tradeProposal = await Trade.findById(tradeId);
|
||||||
|
|
||||||
|
if (!tradeProposal) {
|
||||||
|
await interaction.reply("Trade not found or already completed.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const { from, to, itemId, quantity, coins } = tradeProposal;
|
||||||
|
|
||||||
|
const fromInventory = await UserInventory.findOne({
|
||||||
|
userId: from,
|
||||||
|
guildId: interaction.guild.id,
|
||||||
|
itemId,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!fromInventory || fromInventory.quantity < quantity) {
|
||||||
|
await interaction.reply(
|
||||||
|
"Trade cannot be completed because the item no longer exists in the sender's inventory."
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let toInventory = await UserInventory.findOne({
|
||||||
|
userId: to,
|
||||||
|
guildId: interaction.guild.id,
|
||||||
|
itemId,
|
||||||
|
});
|
||||||
|
if (toInventory) {
|
||||||
|
toInventory.quantity += quantity;
|
||||||
|
} else {
|
||||||
|
toInventory = new UserInventory({
|
||||||
|
userId: to,
|
||||||
|
guildId: interaction.guild.id,
|
||||||
|
itemId,
|
||||||
|
quantity,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
await toInventory.save();
|
||||||
|
|
||||||
|
const fromEconomy = await UserEconomy.findOne({
|
||||||
|
userId: from,
|
||||||
|
guildId: interaction.guild.id,
|
||||||
|
});
|
||||||
|
const toEconomy = await UserEconomy.findOne({
|
||||||
|
userId: to,
|
||||||
|
guildId: interaction.guild.id,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (fromEconomy) {
|
||||||
|
fromEconomy.balance -= coins;
|
||||||
|
await fromEconomy.save();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (toEconomy) {
|
||||||
|
toEconomy.balance += coins;
|
||||||
|
await toEconomy.save();
|
||||||
|
}
|
||||||
|
|
||||||
|
await Trade.deleteOne({ _id: tradeId });
|
||||||
|
|
||||||
|
await interaction.reply(
|
||||||
|
`Trade completed! You traded **${quantity}** of **${itemId}** and **${coins}** coins with ${interaction.user.username}.`
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
|
async reject(interaction) {
|
||||||
|
const tradeId = interaction.options.getString("tradeId");
|
||||||
|
const tradeProposal = await Trade.findById(tradeId);
|
||||||
|
|
||||||
|
if (!tradeProposal) {
|
||||||
|
await interaction.reply("Trade not found or already completed.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
await Trade.deleteOne({ _id: tradeId });
|
||||||
|
await interaction.reply(`Trade rejected.`);
|
||||||
|
},
|
||||||
|
};
|
70
commands/economy/work.js
Normal file
70
commands/economy/work.js
Normal file
|
@ -0,0 +1,70 @@
|
||||||
|
const { SlashCommandBuilder, EmbedBuilder } = require("discord.js");
|
||||||
|
const UserEconomy = require("../../models/UserEconomy");
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
data: new SlashCommandBuilder()
|
||||||
|
.setName("work")
|
||||||
|
.setDescription("Work to earn coins!"),
|
||||||
|
|
||||||
|
async execute(interaction) {
|
||||||
|
const { user, guild } = interaction;
|
||||||
|
const workReward = 100;
|
||||||
|
const cooldownTime = 60 * 60 * 1000;
|
||||||
|
|
||||||
|
let userEconomy = await UserEconomy.findOne({
|
||||||
|
userId: user.id,
|
||||||
|
guildId: guild.id,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!userEconomy) {
|
||||||
|
userEconomy = await UserEconomy.create({
|
||||||
|
userId: user.id,
|
||||||
|
guildId: guild.id,
|
||||||
|
lastWork: null,
|
||||||
|
balance: 0,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const now = new Date();
|
||||||
|
|
||||||
|
if (userEconomy.lastWork && now - userEconomy.lastWork < cooldownTime) {
|
||||||
|
const remainingTime = cooldownTime - (now - userEconomy.lastWork);
|
||||||
|
const remainingMinutes = Math.ceil(remainingTime / (60 * 1000));
|
||||||
|
|
||||||
|
const cooldownEmbed = new EmbedBuilder()
|
||||||
|
.setColor("#ff0000")
|
||||||
|
.setTitle("Cooldown")
|
||||||
|
.setDescription(
|
||||||
|
`You need to wait **${remainingMinutes}** minutes before you can work again.`
|
||||||
|
)
|
||||||
|
.setFooter({
|
||||||
|
text: `Requested in ${guild.name}`,
|
||||||
|
iconURL: guild.iconURL() || null,
|
||||||
|
});
|
||||||
|
|
||||||
|
await interaction.reply({ embeds: [cooldownEmbed] });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
userEconomy.balance += workReward;
|
||||||
|
userEconomy.lastWork = now;
|
||||||
|
await userEconomy.save();
|
||||||
|
|
||||||
|
const successEmbed = new EmbedBuilder()
|
||||||
|
.setColor("#00ff00")
|
||||||
|
.setTitle("Work Success")
|
||||||
|
.setDescription(`You worked hard and earned **${workReward}** coins!`)
|
||||||
|
.addFields({
|
||||||
|
name: "Total Balance",
|
||||||
|
value: `${userEconomy.balance} coins`,
|
||||||
|
inline: true,
|
||||||
|
})
|
||||||
|
.setTimestamp()
|
||||||
|
.setFooter({
|
||||||
|
text: `Requested by ${user.username}`,
|
||||||
|
iconURL: user.displayAvatarURL(),
|
||||||
|
});
|
||||||
|
|
||||||
|
await interaction.reply({ embeds: [successEmbed] });
|
||||||
|
},
|
||||||
|
};
|
4
index.js
4
index.js
|
@ -10,6 +10,7 @@ const mongoose = require("mongoose");
|
||||||
const fs = require("fs");
|
const fs = require("fs");
|
||||||
const path = require("path");
|
const path = require("path");
|
||||||
const ServerSettings = require("./models/ServerSettings");
|
const ServerSettings = require("./models/ServerSettings");
|
||||||
|
const seedShopItems = require("./utils/seedShopItems");
|
||||||
|
|
||||||
const client = new Client({
|
const client = new Client({
|
||||||
intents: [
|
intents: [
|
||||||
|
@ -61,6 +62,9 @@ client.once("ready", async () => {
|
||||||
console.log(`🤖 Logged in as ${client.user.tag}`);
|
console.log(`🤖 Logged in as ${client.user.tag}`);
|
||||||
console.log(`==============================`);
|
console.log(`==============================`);
|
||||||
|
|
||||||
|
// Seed the shop items
|
||||||
|
await seedShopItems();
|
||||||
|
|
||||||
// Register commands for all existing guilds
|
// Register commands for all existing guilds
|
||||||
const guilds = client.guilds.cache.map((guild) => guild.id);
|
const guilds = client.guilds.cache.map((guild) => guild.id);
|
||||||
for (const guildId of guilds) {
|
for (const guildId of guilds) {
|
||||||
|
|
10
models/ShopItem.js
Normal file
10
models/ShopItem.js
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
const mongoose = require("mongoose");
|
||||||
|
|
||||||
|
const shopItemSchema = new mongoose.Schema({
|
||||||
|
itemId: { type: String, required: true, unique: true },
|
||||||
|
name: { type: String, required: true },
|
||||||
|
price: { type: Number, required: true },
|
||||||
|
description: { type: String, required: true },
|
||||||
|
});
|
||||||
|
|
||||||
|
module.exports = mongoose.model("ShopItem", shopItemSchema);
|
12
models/Trade.js
Normal file
12
models/Trade.js
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
const mongoose = require("mongoose");
|
||||||
|
|
||||||
|
const tradeSchema = new mongoose.Schema({
|
||||||
|
from: { type: String, required: true },
|
||||||
|
to: { type: String, required: true },
|
||||||
|
itemId: { type: String, required: true },
|
||||||
|
quantity: { type: Number, required: true },
|
||||||
|
coins: { type: Number, required: true },
|
||||||
|
createdAt: { type: Date, default: Date.now, expires: "1d" },
|
||||||
|
});
|
||||||
|
|
||||||
|
module.exports = mongoose.model("Trade", tradeSchema);
|
11
models/UserEconomy.js
Normal file
11
models/UserEconomy.js
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
const mongoose = require("mongoose");
|
||||||
|
|
||||||
|
const userEconomySchema = new mongoose.Schema({
|
||||||
|
userId: { type: String, required: true, unique: true },
|
||||||
|
guildId: { type: String, required: true },
|
||||||
|
balance: { type: Number, default: 200 },
|
||||||
|
lastDaily: { type: Date, default: null },
|
||||||
|
lastWork: { type: Date, default: null },
|
||||||
|
});
|
||||||
|
|
||||||
|
module.exports = mongoose.model("UserEconomy", userEconomySchema);
|
10
models/UserInventory.js
Normal file
10
models/UserInventory.js
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
const mongoose = require("mongoose");
|
||||||
|
|
||||||
|
const userInventorySchema = new mongoose.Schema({
|
||||||
|
userId: { type: String, required: true },
|
||||||
|
guildId: { type: String, required: true },
|
||||||
|
itemId: { type: String, required: true },
|
||||||
|
quantity: { type: Number, default: 1 },
|
||||||
|
});
|
||||||
|
|
||||||
|
module.exports = mongoose.model("UserInventory", userInventorySchema);
|
87
utils/seedShopItems.js
Normal file
87
utils/seedShopItems.js
Normal file
|
@ -0,0 +1,87 @@
|
||||||
|
const ShopItem = require("../models/ShopItem");
|
||||||
|
|
||||||
|
async function seedShopItems() {
|
||||||
|
const items = [
|
||||||
|
// Valorant Skins
|
||||||
|
{
|
||||||
|
itemId: "prime_vandal",
|
||||||
|
name: "Prime Vandal",
|
||||||
|
price: 1200,
|
||||||
|
description:
|
||||||
|
"A futuristic skin for the Vandal with a sleek design and special effects.",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
itemId: "reaver_vandal",
|
||||||
|
name: "Reaver Vandal",
|
||||||
|
price: 1500,
|
||||||
|
description:
|
||||||
|
"One of the most popular Vandal skins with a haunting aesthetic and special animations.",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
itemId: "sovereign_ghost",
|
||||||
|
name: "Sovereign Ghost",
|
||||||
|
price: 800,
|
||||||
|
description:
|
||||||
|
"Golden elegance for the Ghost pistol with unique sound effects.",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
itemId: "araxys_operator",
|
||||||
|
name: "Araxys Operator",
|
||||||
|
price: 2000,
|
||||||
|
description:
|
||||||
|
"A top-tier sniper skin with alien-like animations and sound effects.",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
itemId: "glitchpop_bulldog",
|
||||||
|
name: "Glitchpop Bulldog",
|
||||||
|
price: 900,
|
||||||
|
description:
|
||||||
|
"A flashy skin for the Bulldog with vibrant colors and cyberpunk vibe.",
|
||||||
|
},
|
||||||
|
|
||||||
|
// CS2 Skins
|
||||||
|
{
|
||||||
|
itemId: "dragon_lore_awp",
|
||||||
|
name: "AWP Dragon Lore",
|
||||||
|
price: 2500,
|
||||||
|
description:
|
||||||
|
"A legendary skin for the AWP with dragon designs, a rare and coveted item.",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
itemId: "ak47_redline",
|
||||||
|
name: "AK-47 Redline",
|
||||||
|
price: 1000,
|
||||||
|
description:
|
||||||
|
"A simple yet iconic AK-47 skin with red and black color scheme.",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
itemId: "m4a4_howl",
|
||||||
|
name: "M4A4 Howl",
|
||||||
|
price: 2200,
|
||||||
|
description:
|
||||||
|
"A rare and valuable skin for the M4A4 with a striking wolf design.",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
itemId: "desert_eagle_kumicho_dragon",
|
||||||
|
name: "Desert Eagle Kumicho Dragon",
|
||||||
|
price: 800,
|
||||||
|
description:
|
||||||
|
"A Desert Eagle skin with an intricate dragon design and a metallic finish.",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
itemId: "usp_kill_confirmed",
|
||||||
|
name: "USP-S Kill Confirmed",
|
||||||
|
price: 1100,
|
||||||
|
description:
|
||||||
|
"A detailed skin for the USP-S with a unique comic-style design.",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
for (const item of items) {
|
||||||
|
await ShopItem.updateOne({ itemId: item.itemId }, item, { upsert: true });
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log("✅ Shop items seeded!");
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = seedShopItems;
|
Loading…
Reference in a new issue