diff --git a/Api/launcher.js b/Api/launcher.js index 2f5d396..37517d1 100644 --- a/Api/launcher.js +++ b/Api/launcher.js @@ -1,6 +1,7 @@ const express = require("express"); const app = express.Router(); const User = require("../model/user.js"); +const log = require("../structs/log.js"); const bcrypt = require("bcrypt"); //Api for launcher login (If u want a POST requesto just replace "app.get" to "app.post" and "req.query" to "req.body") @@ -26,7 +27,7 @@ app.get("/api/launcher/login", async (req, res) => { return res.status(400).send('Error!'); } } catch (err) { - console.error('Launcher Api Error:', err); + log.error('Launcher Api Error:', err); return res.status(500).send('Error encountered, look at the console'); } }); diff --git a/Api/vbucks.js b/Api/vbucks.js index 1f2fdaa..7ac60fa 100644 --- a/Api/vbucks.js +++ b/Api/vbucks.js @@ -2,6 +2,7 @@ const express = require("express"); const app = express.Router(); const User = require("../model/user.js"); const Profile = require("../model/profiles.js"); +const log = require("../structs/log.js"); const fs = require("fs"); const uuid = require("uuid"); const config = JSON.parse(fs.readFileSync("./Config/config.json").toString()); @@ -36,16 +37,22 @@ app.get("/api/reload/vbucks", async (req, res) => { } const filter = { accountId: user.accountId }; - const update = { $inc: { 'profiles.common_core.items.Currency:MtxPurchased.quantity': addValue } }; + const updateCommonCore = { $inc: { 'profiles.common_core.items.Currency:MtxPurchased.quantity': addValue } }; + const updateProfile0 = { $inc: { 'profiles.profile0.items.Currency:MtxPurchased.quantity': addValue } }; const options = { new: true }; - const updatedProfile = await Profile.findOneAndUpdate(filter, update, options); + + const updatedProfile = await Profile.findOneAndUpdate(filter, updateCommonCore, options); if (!updatedProfile) { return res.status(404).json({ code: "404", error: "Profile not found or V-Bucks item missing." }); } + await Profile.updateOne(filter, updateProfile0); + const common_core = updatedProfile.profiles.common_core; - const newQuantity = common_core.items['Currency:MtxPurchased'].quantity; + const newQuantityCommonCore = common_core.items['Currency:MtxPurchased'].quantity; + const profile0 = updatedProfile.profiles.profile0; + const newQuantityProfile0 = profile0.items['Currency:MtxPurchased'].quantity + addValue; const purchaseId = uuid.v4(); const lootList = [{ @@ -71,7 +78,12 @@ app.get("/api/reload/vbucks", async (req, res) => { { "changeType": "itemQuantityChanged", "itemId": "Currency:MtxPurchased", - "quantity": newQuantity + "quantity": newQuantityCommonCore + }, + { // for s1, s2 and s3 + "changeType": "itemQuantityChanged", + "itemId": "Currency:MtxPurchased", + "quantity": newQuantityProfile0 }, { "changeType": "itemAdded", @@ -82,19 +94,20 @@ app.get("/api/reload/vbucks", async (req, res) => { common_core.rvn += 1; common_core.commandRevision += 1; - await Profile.updateOne(filter, { $set: { 'profiles.common_core': common_core } }); + await Profile.updateOne(filter, { $set: { 'profiles.common_core': common_core, 'profiles.profile0.items.Currency:MtxPurchased.quantity': newQuantityProfile0 } }); return res.status(200).json({ profileRevision: common_core.rvn, profileCommandRevision: common_core.commandRevision, profileChanges: ApplyProfileChanges, - newQuantity + newQuantityCommonCore, + newQuantityProfile0 }); } catch (err) { - console.error("Server error:", err); + log.error("Server error:", err); return res.status(500).json({ code: "500", error: "Server error. Check console logs for more details." }); } }); -module.exports = app; \ No newline at end of file +module.exports = app; diff --git a/CalderaService/calderaservice.js b/CalderaService/calderaservice.js index ffa52eb..65e7179 100644 --- a/CalderaService/calderaservice.js +++ b/CalderaService/calderaservice.js @@ -2,6 +2,7 @@ var http = require('http'); const uuid = require("uuid"); const tokencreator = require("./tokencreator.js"); +const log = require("../structs/log.js"); global.JWT_SECRET = uuid.v4(); @@ -28,7 +29,7 @@ function createCalderaService() { caldera = ""; body = ""; } catch (error) { - console.log(error) + log.error(error) res.statusCode(400); res.end(); } diff --git a/DiscordBot/commands/Admin/addall.js b/DiscordBot/commands/Admin/addall.js index eb5f30b..d16b20f 100644 --- a/DiscordBot/commands/Admin/addall.js +++ b/DiscordBot/commands/Admin/addall.js @@ -3,6 +3,7 @@ const path = require("path"); const fs = require("fs"); const Users = require('../../../model/user.js'); const Profiles = require('../../../model/profiles.js'); +const log = require("../../../structs/log.js"); const destr = require("destr"); const config = require('../../../Config/config.json') @@ -62,7 +63,7 @@ module.exports = { .setTimestamp(); await interaction.editReply({ embeds: [embed], ephemeral: true }); } catch (error) { - console.error("An error occurred:", error); + log.error("An error occurred:", error); interaction.editReply({ content: "An error occurred while processing the request." }); } } diff --git a/DiscordBot/commands/Admin/additem.js b/DiscordBot/commands/Admin/additem.js index 35c3002..c00d409 100644 --- a/DiscordBot/commands/Admin/additem.js +++ b/DiscordBot/commands/Admin/additem.js @@ -5,6 +5,7 @@ const path = require('path'); const destr = require('destr'); const config = require('../../../Config/config.json'); const uuid = require("uuid"); +const log = require("../../../structs/log.js"); const { MessageEmbed } = require('discord.js'); module.exports = { @@ -163,7 +164,7 @@ module.exports = { }; }); } catch (err) { - console.log(err); + log.error(err); await interaction.editReply({ content: "An unexpected error occurred", ephemeral: true }); } } diff --git a/DiscordBot/commands/Admin/addvbucks.js b/DiscordBot/commands/Admin/addvbucks.js index 5adbd49..d7f0393 100644 --- a/DiscordBot/commands/Admin/addvbucks.js +++ b/DiscordBot/commands/Admin/addvbucks.js @@ -44,18 +44,24 @@ module.exports = { } const filter = { accountId: user.accountId }; - const update = { $inc: { 'profiles.common_core.items.Currency:MtxPurchased.quantity': vbucks } }; + const updateCommonCore = { $inc: { 'profiles.common_core.items.Currency:MtxPurchased.quantity': vbucks } }; + const updateProfile0 = { $inc: { 'profiles.profile0.items.Currency:MtxPurchased.quantity': vbucks } }; const options = { new: true }; - const updatedProfile = await Profiles.findOneAndUpdate(filter, update, options); + const updatedProfile = await Profiles.findOneAndUpdate(filter, updateCommonCore, options); if (!updatedProfile) { return interaction.editReply({ content: "That user does not own an account", ephemeral: true }); } - const common_core = updatedProfile.profiles["common_core"]; - const newQuantity = common_core.items['Currency:MtxPurchased'].quantity; + await Profiles.updateOne(filter, updateProfile0); - if (newQuantity < 0 || newQuantity >= 1000000) { + const common_core = updatedProfile.profiles["common_core"]; + const profile0 = updatedProfile.profiles["profile0"]; + + const newQuantityCommonCore = common_core.items['Currency:MtxPurchased'].quantity; + const newQuantityProfile0 = profile0.items['Currency:MtxPurchased'].quantity + vbucks; + + if (newQuantityCommonCore < 0 || newQuantityCommonCore >= 1000000) { return interaction.editReply({ content: "V-Bucks amount is out of valid range after the update.", ephemeral: true @@ -86,7 +92,12 @@ module.exports = { { "changeType": "itemQuantityChanged", "itemId": "Currency:MtxPurchased", - "quantity": newQuantity + "quantity": newQuantityCommonCore + }, + { // for s1, s2 and s3 + "changeType": "itemQuantityChanged", + "itemId": "Currency:MtxPurchased", + "quantity": newQuantityProfile0 }, { "changeType": "itemAdded", @@ -99,7 +110,12 @@ module.exports = { common_core.commandRevision += 1; common_core.updated = new Date().toISOString(); - await Profiles.updateOne(filter, { $set: { 'profiles.common_core': common_core } }); + await Profiles.updateOne(filter, { + $set: { + 'profiles.common_core': common_core, + 'profiles.profile0.items.Currency:MtxPurchased.quantity': newQuantityProfile0 + } + }); const embed = new MessageEmbed() .setTitle("V-Bucks Updated") @@ -118,7 +134,8 @@ module.exports = { profileRevision: common_core.rvn, profileCommandRevision: common_core.commandRevision, profileChanges: ApplyProfileChanges, - newQuantity + newQuantityCommonCore, + newQuantityProfile0 }; } }; \ No newline at end of file diff --git a/DiscordBot/commands/Admin/createhostaccount.js b/DiscordBot/commands/Admin/createhostaccount.js index 36d2185..049429e 100644 --- a/DiscordBot/commands/Admin/createhostaccount.js +++ b/DiscordBot/commands/Admin/createhostaccount.js @@ -1,6 +1,7 @@ const { MessageEmbed } = require("discord.js"); const functions = require("../../../structs/functions.js"); const User = require("../../../model/user.js"); +const log = require("../../../structs/log.js"); module.exports = { commandInfo: { @@ -58,7 +59,7 @@ module.exports = { }); }); } catch (error) { - console.error(error); + log.error(error); return interaction.editReply({ content: "An error occurred while creating the host account.", ephemeral: true diff --git a/DiscordBot/commands/Admin/delete.js b/DiscordBot/commands/Admin/delete.js index 9f83162..3783fb3 100644 --- a/DiscordBot/commands/Admin/delete.js +++ b/DiscordBot/commands/Admin/delete.js @@ -1,8 +1,11 @@ const { MessageEmbed } = require("discord.js"); +const fs = require("fs"); +const path = require("path"); const Users = require('../../../model/user.js'); const Profiles = require('../../../model/profiles.js'); const SACCodes = require('../../../model/saccodes.js'); const Friends = require('../../../model/friends.js'); +const log = require("../../../structs/log.js"); const config = require('../../../Config/config.json'); module.exports = { @@ -27,26 +30,50 @@ module.exports = { const username = interaction.options.getString('username'); const deleteAccount = await Users.findOne({ username: username }); - const accountId = deleteAccount.accountId; if (!deleteAccount) { await interaction.editReply({ content: "The selected user does not have **an account**", ephemeral: true }); return; } - await Users.deleteOne({ username: username }).catch(error => { - // Nothing Uwu or just use: log.debug('No SAC codes found or error occurred:', error); + const accountId = deleteAccount.accountId; + let somethingDeleted = false; + + await Users.deleteOne({ username: username }).then(() => { + somethingDeleted = true; + }).catch(error => { + log.error('Error deleting from Users:', error); }); - await Profiles.deleteOne({ accountId: accountId }).catch(error => { - // Nothing Uwu or just use: log.debug('No SAC codes found or error occurred:', error); + + await Profiles.deleteOne({ accountId: accountId }).then(() => { + somethingDeleted = true; + }).catch(error => { + log.error('Error deleting from Profiles:', error); }); - await Friends.deleteOne({ accountId: accountId }).catch(error => { - // Nothing Uwu or just use: log.debug('No SAC codes found or error occurred:', error); + + await Friends.deleteOne({ accountId: accountId }).then(() => { + somethingDeleted = true; + }).catch(error => { + log.error('Error deleting from Friends:', error); }); - await SACCodes.deleteOne({ owneraccountId: accountId }).catch(error => { - // Nothing Uwu or just use: log.debug('No SAC codes found or error occurred:', error); + + await SACCodes.deleteOne({ owneraccountId: accountId }).then(() => { + somethingDeleted = true; + }).catch(error => { + log.error('Error deleting from SACCodes:', error); }); + const clientSettingsPath = path.join(__dirname, '../../../ClientSettings', accountId); + if (fs.existsSync(clientSettingsPath)) { + fs.rmSync(clientSettingsPath, { recursive: true, force: true }); + somethingDeleted = true; + } + + if (!somethingDeleted) { + await interaction.editReply({ content: `No data found to delete for **${username}**.`, ephemeral: true }); + return; + } + const embed = new MessageEmbed() .setTitle("Account deleted") .setDescription(`The account for **${username}** has been **deleted**`) @@ -65,7 +92,7 @@ module.exports = { await user.send({ content: `Your account has been deleted by <@${interaction.user.id}>` }); } } catch (error) { - // Nothing Uwu or just use: console.error('Could not send DM:', error); + log.error('Could not send DM:', error); } } }; \ No newline at end of file diff --git a/DiscordBot/commands/Admin/deletediscord.js b/DiscordBot/commands/Admin/deletediscord.js index b4eadf2..bc9a021 100644 --- a/DiscordBot/commands/Admin/deletediscord.js +++ b/DiscordBot/commands/Admin/deletediscord.js @@ -1,14 +1,17 @@ const { MessageEmbed } = require("discord.js"); +const fs = require("fs"); +const path = require("path"); const Users = require('../../../model/user.js'); const Profiles = require('../../../model/profiles.js'); const SACCodes = require('../../../model/saccodes.js'); const Friends = require('../../../model/friends.js'); -const config = require('../../../Config/config.json') +const log = require("../../../structs/log.js"); +const config = require('../../../Config/config.json'); module.exports = { commandInfo: { name: "deletediscord", - description: "Deletes a users account", + description: "Deletes a user's account", options: [ { name: "username", @@ -27,27 +30,51 @@ module.exports = { const discordId = interaction.options.getUser('username').id; const user = interaction.options.getUser('username'); - const deleteAccount = await Users.findOne({ discordId: discordId }) - const accountId = deleteAccount.accountId; + const deleteAccount = await Users.findOne({ discordId: discordId }); - if (deleteAccount == null) { + if (!deleteAccount) { await interaction.editReply({ content: "The selected user does not have **an account**", ephemeral: true }); return; } - await Users.deleteOne({ username: username }).catch(error => { - // Nothing Uwu or just use: log.debug('No SAC codes found or error occurred:', error); + const accountId = deleteAccount.accountId; + let somethingDeleted = false; + + await Users.deleteOne({ discordId: discordId }).then(() => { + somethingDeleted = true; + }).catch(error => { + log.error('Error deleting from Users:', error); }); - await Profiles.deleteOne({ accountId: accountId }).catch(error => { - // Nothing Uwu or just use: log.debug('No SAC codes found or error occurred:', error); + + await Profiles.deleteOne({ accountId: accountId }).then(() => { + somethingDeleted = true; + }).catch(error => { + log.error('Error deleting from Profiles:', error); }); - await Friends.deleteOne({ accountId: accountId }).catch(error => { - // Nothing Uwu or just use: log.debug('No SAC codes found or error occurred:', error); + + await Friends.deleteOne({ accountId: accountId }).then(() => { + somethingDeleted = true; + }).catch(error => { + log.error('Error deleting from Friends:', error); }); - await SACCodes.deleteOne({ owneraccountId: accountId }).catch(error => { - // Nothing Uwu or just use: log.debug('No SAC codes found or error occurred:', error); + + await SACCodes.deleteOne({ owneraccountId: accountId }).then(() => { + somethingDeleted = true; + }).catch(error => { + log.error('Error deleting from SACCodes:', error); }); + const clientSettingsPath = path.join(__dirname, '../../../ClientSettings', accountId); + if (fs.existsSync(clientSettingsPath)) { + fs.rmSync(clientSettingsPath, { recursive: true, force: true }); + somethingDeleted = true; + } + + if (!somethingDeleted) { + await interaction.editReply({ content: `No data found to delete for **${user.username}**.`, ephemeral: true }); + return; + } + const embed = new MessageEmbed() .setTitle("Account deleted") .setDescription("The account has been **deleted**") @@ -57,12 +84,13 @@ module.exports = { iconURL: "https://i.imgur.com/2RImwlb.png" }) .setTimestamp(); + await interaction.editReply({ embeds: [embed], ephemeral: true }); try { await user.send({ content: `Your account has been deleted by <@${interaction.user.id}>` }); } catch (error) { - // Nothing Uwu or just use: console.error('Could not send DM:', error); + log.error('Could not send DM:', error); } } -} \ No newline at end of file +}; \ No newline at end of file diff --git a/DiscordBot/commands/Admin/removeall.js b/DiscordBot/commands/Admin/removeall.js index 3af0371..78f61f5 100644 --- a/DiscordBot/commands/Admin/removeall.js +++ b/DiscordBot/commands/Admin/removeall.js @@ -3,6 +3,7 @@ const path = require("path"); const fs = require("fs"); const Users = require('../../../model/user.js'); const Profiles = require('../../../model/profiles.js'); +const log = require("../../../structs/log.js"); const destr = require("destr"); const config = require('../../../Config/config.json') @@ -62,7 +63,7 @@ module.exports = { .setTimestamp(); await interaction.editReply({ embeds: [embed], ephemeral: true }); } catch (error) { - console.error("An error occurred:", error); + log.error("An error occurred:", error); interaction.editReply({ content: "An error occurred while processing the request." }); } } diff --git a/DiscordBot/commands/Admin/removeitem.js b/DiscordBot/commands/Admin/removeitem.js index 4807016..d041c5d 100644 --- a/DiscordBot/commands/Admin/removeitem.js +++ b/DiscordBot/commands/Admin/removeitem.js @@ -4,6 +4,7 @@ const Profiles = require('../../../model/profiles.js'); const fs = require('fs'); const path = require('path'); const destr = require('destr'); +const log = require("../../../structs/log.js"); const config = require('../../../Config/config.json'); module.exports = { @@ -28,7 +29,6 @@ module.exports = { execute: async (interaction) => { if (!config.moderators.includes(interaction.user.id)) { - console.log("User does not have moderator permissions."); return interaction.reply({ content: "You do not have moderator permissions.", ephemeral: true }); } @@ -110,7 +110,7 @@ module.exports = { .setTimestamp(); await interaction.editReply({ embeds: [embed] }); } catch (err) { - console.log("An error occurred:", err); + log.error("An error occurred:", err); interaction.editReply({ content: "An error occurred. Please try again later." }); } } diff --git a/DiscordBot/commands/Admin/removevbucks.js b/DiscordBot/commands/Admin/removevbucks.js index 3ba1cdf..b9e6b54 100644 --- a/DiscordBot/commands/Admin/removevbucks.js +++ b/DiscordBot/commands/Admin/removevbucks.js @@ -1,54 +1,99 @@ const Users = require('../../../model/user'); const Profiles = require('../../../model/profiles'); -const config = require('../../../Config/config.json') +const config = require('../../../Config/config.json'); +const { MessageEmbed } = require('discord.js'); module.exports = { commandInfo: { name: "removevbucks", - description: "Lets you change a users amount of vbucks", + description: "Lets you change a user's amount of V-Bucks", options: [ { name: "user", - description: "The user you want to change the vbucks of", + description: "The user you want to change the V-Bucks of", required: true, type: 6 }, { name: "vbucks", - description: "The amount of vbucks you want to remove (Can be a negative number to take vbucks)", + description: "The amount of V-Bucks you want to remove (Can be a negative number to add V-Bucks)", required: true, type: 4 } ] }, execute: async (interaction) => { - await interaction.deferReply({ ephemeral: true }); + await interaction.deferReply({ ephemeral: true }); - if (!config.moderators.includes(interaction.user.id)) { - return interaction.editReply({ content: "You do not have moderator permissions.", ephemeral: true }); + if (!config.moderators.includes(interaction.user.id)) { + return interaction.editReply({ content: "You do not have moderator permissions.", ephemeral: true }); + } + + const selectedUser = interaction.options.getUser('user'); + const selectedUserId = selectedUser?.id; + const user = await Users.findOne({ discordId: selectedUserId }); + + if (!user) { + return interaction.editReply({ content: "That user does not own an account", ephemeral: true }); + } + + const vbucks = parseInt(interaction.options.getInteger('vbucks')); + if (isNaN(vbucks) || vbucks === 0) { + return interaction.editReply({ content: "Invalid V-Bucks amount specified.", ephemeral: true }); + } + + const filter = { accountId: user.accountId }; + const updateCommonCore = { $inc: { 'profiles.common_core.items.Currency:MtxPurchased.quantity': -vbucks } }; + const updateProfile0 = { $inc: { 'profiles.profile0.items.Currency:MtxPurchased.quantity': -vbucks } }; + + const updatedProfile = await Profiles.findOneAndUpdate(filter, updateCommonCore, { new: true }); + if (!updatedProfile) { + return interaction.editReply({ content: "That user does not own an account", ephemeral: true }); + } + + await Profiles.updateOne(filter, updateProfile0); + + const profile0 = updatedProfile.profiles["profile0"]; + const common_core = updatedProfile.profiles["common_core"]; + + const newQuantityCommonCore = common_core.items['Currency:MtxPurchased'].quantity; + const newQuantityProfile0 = profile0.items['Currency:MtxPurchased'].quantity; + + common_core.rvn += 1; + common_core.commandRevision += 1; + + await Profiles.updateOne(filter, { + $set: { + 'profiles.common_core': common_core, + 'profiles.profile0.items.Currency:MtxPurchased.quantity': newQuantityProfile0 + } + }); + + if (newQuantityCommonCore < 0 || newQuantityCommonCore >= 1000000) { + return interaction.editReply({ + content: "V-Bucks amount is out of valid range after the update.", + ephemeral: true + }); + } + + const embed = new MessageEmbed() + .setTitle("V-Bucks Updated") + .setDescription(`Successfully removed **${vbucks}** V-Bucks from <@${selectedUserId}>`) + .setThumbnail("https://i.imgur.com/yLbihQa.png") + .setColor("GREEN") + .setFooter({ + text: "Reload Backend", + iconURL: "https://i.imgur.com/2RImwlb.png" + }) + .setTimestamp(); + + await interaction.editReply({ embeds: [embed], ephemeral: true }); + + return { + profileRevision: common_core.rvn, + profileCommandRevision: common_core.commandRevision, + newQuantityCommonCore, + newQuantityProfile0 + }; } - - const selectedUser = interaction.options.getUser('user'); - const selectedUserId = selectedUser?.id; - const user = await Users.findOne({ discordId: selectedUserId }); - if (!user) - return interaction.editReply({ content: "That user does not own an account", ephemeral: true }); - const vbucks = parseInt(interaction.options.getInteger('vbucks')); - const profile = await Profiles.findOneAndUpdate({ accountId: user.accountId }, { $inc: { 'profiles.common_core.items.Currency:MtxPurchased.quantity': - vbucks } }); - if (!profile) - return interaction.editReply({ content: "That user does not own an account", ephemeral: true }); - - const embed = new MessageEmbed() - .setTitle("Vbucks Changed") - .setDescription("Successfully changed the amount of vbucks for <@" + selectedUserId + "> to **" + vbucks + "**") - .setThumbnail("https://i.imgur.com/yLbihQa.png") - .setColor("GREEN") - .setFooter({ - text: "Reload Backend", - iconURL: "https://i.imgur.com/2RImwlb.png" - }) - .setTimestamp(); - - await interaction.editReply({ embeds: [embed], ephemeral: true }); -} -} \ No newline at end of file +}; \ No newline at end of file diff --git a/DiscordBot/commands/User/claimvbucks.js b/DiscordBot/commands/User/claimvbucks.js index a6d6733..487b92b 100644 --- a/DiscordBot/commands/User/claimvbucks.js +++ b/DiscordBot/commands/User/claimvbucks.js @@ -1,6 +1,7 @@ const { MessageEmbed } = require("discord.js"); const Users = require('../../../model/user.js'); const Profiles = require('../../../model/profiles.js'); +const log = require("../../../structs/log.js"); module.exports = { commandInfo: { @@ -8,46 +9,80 @@ module.exports = { description: "Claim your daily 250 V-Bucks" }, async execute(interaction) { - try { - await interaction.deferReply({ ephemeral: true }); + try { + await interaction.deferReply({ ephemeral: true }); - const user = await Users.findOne({ discordId: interaction.user.id }); - if (!user) { - return interaction.followUp({ content: "You are not registered", ephemeral: true }); - } + const user = await Users.findOne({ discordId: interaction.user.id }); + if (!user) { + return interaction.followUp({ content: "You are not registered", ephemeral: true }); + } - const userProfile = await Profiles.findOne({ accountId: user?.accountId }); - - const lastClaimed = userProfile?.profiles?.lastVbucksClaim; - if (lastClaimed && (Date.now() - new Date(lastClaimed).getTime() < 24 * 60 * 60 * 1000)) { - const timeLeft = 24 - Math.floor((Date.now() - new Date(lastClaimed).getTime()) / (1000 * 60 * 60)); - return interaction.followUp({ - content: `You have already claimed your daily **V-Bucks.** Please wait the remainder: **${timeLeft} hours.**`, + const userProfile = await Profiles.findOne({ accountId: user?.accountId }); + + const lastClaimed = userProfile?.profiles?.lastVbucksClaim; + if (lastClaimed && (Date.now() - new Date(lastClaimed).getTime() < 24 * 60 * 60 * 1000)) { + const timeLeft = 24 - Math.floor((Date.now() - new Date(lastClaimed).getTime()) / (1000 * 60 * 60)); + return interaction.followUp({ + content: `You have already claimed your daily **V-Bucks.** Please wait the remainder: **${timeLeft} hours.**`, + ephemeral: true + }); + } + + const filter = { accountId: user?.accountId }; + const updateCommonCore = { $inc: { 'profiles.common_core.items.Currency:MtxPurchased.quantity': 250 } }; //250 is vbucks for day but u can change it + const updateProfile0 = { $inc: { 'profiles.profile0.items.Currency:MtxPurchased.quantity': 250 } }; //250 is vbucks for day but u can change it + + const userUpdatedProfile = await Profiles.findOneAndUpdate( + filter, + { + ...updateCommonCore, + $set: { 'profiles.lastVbucksClaim': Date.now() } + }, + { new: true } + ); + + await Profiles.updateOne(filter, updateProfile0); + + const common_core = userUpdatedProfile.profiles["common_core"]; + const profile0 = userUpdatedProfile.profiles["profile0"]; + + const newQuantityCommonCore = common_core.items['Currency:MtxPurchased'].quantity; + const newQuantityProfile0 = profile0.items['Currency:MtxPurchased'].quantity; + + common_core.rvn += 1; + common_core.commandRevision += 1; + + await Profiles.updateOne(filter, { + $set: { + 'profiles.common_core': common_core, + 'profiles.profile0.items.Currency:MtxPurchased.quantity': newQuantityProfile0 + } + }); + + const embed = new MessageEmbed() + .setTitle("Daily V-Bucks Claimed!") + .setDescription(`You have claimed your daily **250 V-Bucks**!`) + .setThumbnail("https://i.imgur.com/yLbihQa.png") + .setColor("#1eff00") + .setFooter({ + text: "Reload Backend", + iconURL: "https://i.imgur.com/2RImwlb.png" + }); + + await interaction.followUp({ + embeds: [embed], ephemeral: true }); + + return { + profileRevision: common_core.rvn, + profileCommandRevision: common_core.commandRevision, + newQuantityCommonCore, + newQuantityProfile0 + }; + + } catch (error) { + log.error(error); } - - await Profiles.findOneAndUpdate( - { accountId: user?.accountId }, - { - $inc: { 'profiles.common_core.items.Currency:MtxPurchased.quantity': 250 }, //250 is vbucks for day but u can change it - 'profiles.lastVbucksClaim': Date.now() - } - ); - - const embed = new MessageEmbed() - .setTitle("Daily V-Bucks Claimed!") - .setDescription(`You have claimed your daily **250 V-Bucks**!`) - .setThumbnail("https://i.imgur.com/yLbihQa.png") - .setColor("#1eff00") - .setFooter({ - text: "Reload Backend", - iconURL: "https://i.imgur.com/2RImwlb.png" - }) - - await interaction.followUp({ embeds: [embed], ephemeral: true }); - } catch (error) { - console.error(error); } -} -} \ No newline at end of file +}; \ No newline at end of file diff --git a/DiscordBot/commands/User/giftvbucks.js b/DiscordBot/commands/User/giftvbucks.js index 25541e4..8e11fae 100644 --- a/DiscordBot/commands/User/giftvbucks.js +++ b/DiscordBot/commands/User/giftvbucks.js @@ -1,6 +1,8 @@ -const { SlashCommandBuilder, MessageEmbed } = require("discord.js"); +const { MessageEmbed } = require("discord.js"); const Users = require("../../../model/user.js"); const Profiles = require("../../../model/profiles.js"); +const log = require("../../../structs/log.js"); +const uuid = require("uuid"); const cooldowns = new Map(); @@ -23,7 +25,7 @@ module.exports = { }, ], }, - async execute(interaction, client) { + async execute(interaction) { const recieverUser = interaction.options.getUser("user"); try { @@ -72,7 +74,93 @@ module.exports = { } const currentuser = await Profiles.findOne({ accountId: sender?.accountId }); - + const recieverProfile = await Profiles.findOne({ accountId: recieveuser?.accountId }); + + if (!currentuser || !recieverProfile) { + return interaction.editReply({ content: "Profile failure or account does not exist", ephemeral: true }); + } + + const senderCommonCore = currentuser.profiles.common_core; + const recieverCommonCore = recieverProfile.profiles.common_core; + + const senderProfile0 = currentuser.profiles.profile0; + const recieverProfile0 = recieverProfile.profiles.profile0; + + const sendervbucks = senderCommonCore.items['Currency:MtxPurchased']; + const recievervbucks = recieverCommonCore.items['Currency:MtxPurchased']; + + if (!sendervbucks) { + return interaction.editReply({ content: "User Profile failure or account does not exist", ephemeral: true }); + } + + if (!recievervbucks) { + return interaction.editReply({ content: "Profile failure or account does not exist", ephemeral: true }); + } + + sendervbucks.quantity -= vbucks; + recievervbucks.quantity += vbucks; + + senderProfile0.items['Currency:MtxPurchased'].quantity -= vbucks; + recieverProfile0.items['Currency:MtxPurchased'].quantity += vbucks; + + const purchaseId = uuid.v4(); + const lootList = [{ + "itemType": "Currency:MtxGiveaway", + "itemGuid": "Currency:MtxGiveaway", + "quantity": vbucks + }]; + + recieverCommonCore.items[purchaseId] = { + "templateId": `GiftBox:GB_MakeGood`, + "attributes": { + "fromAccountId": sender.accountId, + "lootList": lootList, + "params": { + "userMessage": `You received a gift from ${sender.username || "Unknown Player"}!` + }, + "giftedOn": new Date().toISOString() + }, + "quantity": 1 + }; + + senderCommonCore.rvn += 1; + senderCommonCore.commandRevision += 1; + + recieverCommonCore.rvn += 1; + recieverCommonCore.commandRevision += 1; + + await Profiles.updateOne({ accountId: sender?.accountId }, { + $set: { + 'profiles.common_core': senderCommonCore, + 'profiles.profile0': senderProfile0 + } + }); + + await Profiles.updateOne({ accountId: recieveuser?.accountId }, { + $set: { + 'profiles.common_core': recieverCommonCore, + 'profiles.profile0': recieverProfile0 + } + }); + + let ApplyProfileChanges = [ + { + "changeType": "itemQuantityChanged", + "itemId": "Currency:MtxPurchased", + "quantity": recieverCommonCore.items['Currency:MtxPurchased'].quantity + }, + { + "changeType": "itemQuantityChanged", + "itemId": "Currency:MtxPurchased", + "quantity": recieverProfile0.items['Currency:MtxPurchased'].quantity + }, + { + "changeType": "itemAdded", + "itemId": purchaseId, + "templateId": "GiftBox:GB_MakeGood" + } + ]; + const embed = new MessageEmbed() .setTitle("Gift Sent!") .setDescription(`Gifted **${vbucks} V-Bucks** to **${recieveuser.username}**`) @@ -85,20 +173,17 @@ module.exports = { await interaction.editReply({ embeds: [embed], ephemeral: true }); - const recievervbucks = await Profiles.findOneAndUpdate({ accountId: recieveuser?.accountId }, { $inc: { 'profiles.common_core.items.Currency:MtxPurchased.quantity': vbucks } }); - const sendervbucks = await Profiles.findOneAndUpdate({ accountId: currentuser?.accountId }, { $inc: { 'profiles.common_core.items.Currency:MtxPurchased.quantity': -vbucks } }); - - if (!sendervbucks) { - return interaction.editReply({ content: "User Profile failure or account does not exist", ephemeral: true }); - } - - if (!recievervbucks) { - return interaction.editReply({ content: "Profile failure or account does not exist", ephemeral: true }); - } - cooldowns.set(cooldownKey, currentTime); + + return { + profileRevision: recieverCommonCore.rvn, + profileCommandRevision: recieverCommonCore.commandRevision, + profileChanges: ApplyProfileChanges, + newQuantityCommonCore: recieverCommonCore.items['Currency:MtxPurchased'].quantity, + newQuantityProfile0: recieverProfile0.items['Currency:MtxPurchased'].quantity + }; } catch (error) { - //console.log(error) + log.error(error); } }, }; \ No newline at end of file diff --git a/Website/Data/js/registerUser.js b/Website/Data/js/registerUser.js index f71a39b..5479798 100644 --- a/Website/Data/js/registerUser.js +++ b/Website/Data/js/registerUser.js @@ -1,4 +1,5 @@ const functions = require('../../../structs/functions'); +const log = require("../../../structs/log.js"); module.exports = async (req, res) => { const { discordId, username, email, password } = req.body; @@ -12,7 +13,7 @@ module.exports = async (req, res) => { res.json({ success: false, message: result.message }); } } catch (error) { - console.error('Error registering user:', error); + log.error('Error registering user:', error); res.json({ success: false, message: 'Failed to create account.' }); } }; \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 0a9c668..78a3def 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "reloadbackend", - "version": "1.1.3", + "version": "1.1.4", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "reloadbackend", - "version": "1.1.3", + "version": "1.1.4", "license": "BSD-3-Clause license", "dependencies": { "axios": "^1.7.7", diff --git a/package.json b/package.json index 326e020..4542dbc 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "reloadbackend", - "version": "1.1.3", + "version": "1.1.4", "description": "Created by Burlone, This is a modded backend, all main backend credits to lawin", "main": "index.js", "dependencies": { diff --git a/routes/mcp.js b/routes/mcp.js index 90390fe..ae16691 100644 --- a/routes/mcp.js +++ b/routes/mcp.js @@ -221,7 +221,7 @@ app.post("/fortnite/api/game/v2/profile/*/client/ClientQuestLogin", verifyToken, StatChanged = true; } - } catch (err) { console.error(err); } + } catch (err) { log.error(err); } for (var key in profile.items) { if (key.startsWith("QS") && Number.isInteger(Number(key[2])) && Number.isInteger(Number(key[3])) && key[4] === "-") { @@ -738,6 +738,7 @@ app.post("/fortnite/api/game/v2/profile/*/client/GiftCatalogEntry", verifyToken, } let profile = profiles.profiles[req.query.profileId]; + let profile0 = profiles.profiles["profile0"]; log.debug(`GiftCatalogEntry: Validated profile for profileId: ${req.query.profileId}`); if (req.query.profileId != "common_core") { @@ -887,12 +888,20 @@ app.post("/fortnite/api/game/v2/profile/*/client/GiftCatalogEntry", verifyToken, } profile.items[key].quantity -= price; + profile0.items[key].quantity -= price; - ApplyProfileChanges.push({ - "changeType": "itemQuantityChanged", - "itemId": key, - "quantity": profile.items[key].quantity - }); + ApplyProfileChanges.push( + { + "changeType": "itemQuantityChanged", + "itemId": key, + "quantity": profile.items[key].quantity + }, + { + "changeType": "itemQuantityChanged", + "itemId": key, + "quantity": profile0.items[key].quantity + } + ); paid = true; log.debug(`GiftCatalogEntry: Currency deducted: ${price}, remaining ${profile.items[key].quantity}`); @@ -985,12 +994,22 @@ app.post("/fortnite/api/game/v2/profile/*/client/GiftCatalogEntry", verifyToken, } common_core.items[giftBoxItemID] = giftBoxItem; + profile0.items[giftBoxItemID] = giftBoxItem; - if (receiverId == req.user.accountId) ApplyProfileChanges.push({ - "changeType": "itemAdded", - "itemId": giftBoxItemID, - "item": common_core.items[giftBoxItemID] - }); + if (receiverId == req.user.accountId) { + ApplyProfileChanges.push( + { + "changeType": "itemAdded", + "itemId": giftBoxItemID, + "item": common_core.items[giftBoxItemID] + }, + { + "changeType": "itemAdded", + "itemId": giftBoxItemID, + "item": profile0.items[giftBoxItemID] + } + ); + } athena.rvn += 1; athena.commandRevision += 1; @@ -1000,7 +1019,17 @@ app.post("/fortnite/api/game/v2/profile/*/client/GiftCatalogEntry", verifyToken, common_core.commandRevision += 1; common_core.updated = new Date().toISOString(); - await receiverProfiles.updateOne({ $set: { [`profiles.athena`]: athena, [`profiles.common_core`]: common_core } }); + profile0.rvn += 1; + profile0.commandRevision += 1; + profile0.updated = new Date().toISOString(); + + await receiverProfiles.updateOne({ + $set: { + [`profiles.athena`]: athena, + [`profiles.common_core`]: common_core, + [`profiles.profile0`]: profile0 + } + }); global.giftReceived[receiverId] = true; @@ -1019,7 +1048,12 @@ app.post("/fortnite/api/game/v2/profile/*/client/GiftCatalogEntry", verifyToken, profile.commandRevision += 1; profile.updated = new Date().toISOString(); - await profiles.updateOne({ $set: { [`profiles.${req.query.profileId}`]: profile } }); + await profiles.updateOne({ + $set: { + [`profiles.${req.query.profileId}`]: profile, + [`profiles.profile0`]: profile0 + } + }); } if (QueryRevision != ProfileRevisionCheck) { @@ -1576,6 +1610,7 @@ app.post("/fortnite/api/game/v2/profile/*/client/RequestRestedStateIncrease", as app.post("/fortnite/api/game/v2/profile/*/client/RefundMtxPurchase", verifyToken, async (req, res) => { const profiles = await Profile.findOne({ accountId: req.params[0] }); let profile = profiles.profiles[req.query.profileId]; + let profile0 = profiles.profiles["profile0"]; const ItemProfile = profiles.profiles.athena; const memory = functions.GetVersionInfo(req); @@ -1608,13 +1643,21 @@ app.post("/fortnite/api/game/v2/profile/*/client/RefundMtxPurchase", verifyToken if (profile.items[key].templateId.toLowerCase().startsWith("currency:mtx")) { if (profile.items[key].attributes.platform.toLowerCase() == profile.stats.attributes.current_mtx_platform.toLowerCase() || profile.items[key].attributes.platform.toLowerCase() == "shared") { profile.items[key].quantity += profile.stats.attributes.mtx_purchase_history.purchases[i].totalMtxPaid; - - ApplyProfileChanges.push({ - "changeType": "itemQuantityChanged", - "itemId": key, - "quantity": profile.items[key].quantity - }) - + profile0.items[key].quantity += profile.stats.attributes.mtx_purchase_history.purchases[i].totalMtxPaid; + + ApplyProfileChanges.push( + { + "changeType": "itemQuantityChanged", + "itemId": key, + "quantity": profile.items[key].quantity + }, + { + "changeType": "itemQuantityChanged", + "itemId": key, + "quantity": profile0.items[key].quantity + } + ); + break; } } @@ -1635,6 +1678,8 @@ app.post("/fortnite/api/game/v2/profile/*/client/RefundMtxPurchase", verifyToken ItemProfile.commandRevision += 1; profile.rvn += 1; profile.commandRevision += 1; + profile0.rvn += 1; + profile0.commandRevision += 1; StatChanged = true; } @@ -1648,8 +1693,13 @@ app.post("/fortnite/api/game/v2/profile/*/client/RefundMtxPurchase", verifyToken MultiUpdate[0].profileRevision = ItemProfile.rvn || 0; MultiUpdate[0].profileCommandRevision = ItemProfile.commandRevision || 0; - await profiles.updateOne({ $set: { [`profiles.${req.query.profileId}`]: profile} }); - await profiles.updateOne({ $set: { [`profiles.athena`]: ItemProfile} }); + await profiles.updateOne({ + $set: { + [`profiles.${req.query.profileId}`]: profile, + [`profiles.profile0`]: profile0, + [`profiles.athena`]: ItemProfile + } + }); } if (QueryRevision != ProfileRevisionCheck) { @@ -1739,6 +1789,7 @@ app.post("/fortnite/api/game/v2/profile/*/client/PurchaseCatalogEntry", verifyTo let profile = profiles.profiles[req.query.profileId]; let athena = profiles.profiles["athena"]; + let profile0 = profiles.profiles["profile0"]; log.debug(`PurchaseCatalogEntry: Validated profile for profileId: ${req.query.profileId}`); if (req.query.profileId != "common_core" && req.query.profileId != "profile0") { @@ -1797,6 +1848,7 @@ app.post("/fortnite/api/game/v2/profile/*/client/PurchaseCatalogEntry", verifyTo if (!profile.items) profile.items = {}; if (!athena.items) athena.items = {}; + if (!profile0.items) profile0.items = {}; let findOfferId = functions.getOfferID(req.body.offerId); if (!findOfferId) { @@ -1839,11 +1891,19 @@ app.post("/fortnite/api/game/v2/profile/*/client/PurchaseCatalogEntry", verifyTo } profile.items[key].quantity -= totalPrice; - ApplyProfileChanges.push({ - "changeType": "itemQuantityChanged", - "itemId": key, - "quantity": profile.items[key].quantity - }); + profile0.items[key].quantity -= totalPrice; + ApplyProfileChanges.push( + { + "changeType": "itemQuantityChanged", + "itemId": key, + "quantity": profile.items[key].quantity + }, + { + "changeType": "itemQuantityChanged", + "itemId": key, + "quantity": profile0.items[key].quantity + } + ); paid = true; log.debug(`PurchaseCatalogEntry: Currency deducted: ${totalPrice}, remaining ${profile.items[key].quantity}`); break; @@ -1995,6 +2055,7 @@ app.post("/fortnite/api/game/v2/profile/*/client/PurchaseCatalogEntry", verifyTo if (profile.items[key].templateId.toLowerCase().startsWith("currency:mtx")) { if (profile.items[key].attributes.platform.toLowerCase() == profile.stats.attributes.current_mtx_platform.toLowerCase() || profile.items[key].attributes.platform.toLowerCase() == "shared") { profile.items[key].quantity += PaidTier[item]; + profile0.items[key].quantity += PaidTier[item]; break; } } @@ -2110,6 +2171,7 @@ app.post("/fortnite/api/game/v2/profile/*/client/PurchaseCatalogEntry", verifyTo if (profile.items[key].templateId.toLowerCase().startsWith("currency:mtx")) { if (profile.items[key].attributes.platform.toLowerCase() == profile.stats.attributes.current_mtx_platform.toLowerCase() || profile.items[key].attributes.platform.toLowerCase() == "shared") { profile.items[key].quantity += FreeTier[item]; + profile0.items[key].quantity += PaidTier[item]; break; } } @@ -2193,6 +2255,7 @@ app.post("/fortnite/api/game/v2/profile/*/client/PurchaseCatalogEntry", verifyTo if (profile.items[key].templateId.toLowerCase().startsWith("currency:mtx")) { if (profile.items[key].attributes.platform.toLowerCase() == profile.stats.attributes.current_mtx_platform.toLowerCase() || profile.items[key].attributes.platform.toLowerCase() == "shared") { profile.items[key].quantity += PaidTier[item]; + profile0.items[key].quantity += PaidTier[item]; break; } } @@ -2292,7 +2355,13 @@ app.post("/fortnite/api/game/v2/profile/*/client/PurchaseCatalogEntry", verifyTo profile.rvn += 1; profile.commandRevision += 1; profile.updated = new Date().toISOString(); - await profiles?.updateOne({ $set: { [`profiles.${req.query.profileId}`]: profile, [`profiles.athena`]: athena } }); + await profiles?.updateOne({ + $set: { + [`profiles.${req.query.profileId}`]: profile, + [`profiles.athena`]: athena, + [`profiles.profile0`]: profile0 + } + }); } if (QueryRevision != ProfileRevisionCheck) { @@ -2315,7 +2384,13 @@ app.post("/fortnite/api/game/v2/profile/*/client/PurchaseCatalogEntry", verifyTo }); if (ApplyProfileChanges.length > 0) { - await profiles?.updateOne({ $set: { [`profiles.${req.query.profileId}`]: profile, [`profiles.athena`]: athena } }); + await profiles?.updateOne({ + $set: { + [`profiles.${req.query.profileId}`]: profile, + [`profiles.athena`]: athena, + [`profiles.profile0`]: profile0 + } + }); } return; } @@ -2391,12 +2466,20 @@ app.post("/fortnite/api/game/v2/profile/*/client/PurchaseCatalogEntry", verifyTo } profile.items[key].quantity -= findOfferId.offerId.prices[0].finalPrice; + profile0.items[key].quantity -= findOfferId.offerId.prices[0].finalPrice;; - ApplyProfileChanges.push({ - "changeType": "itemQuantityChanged", - "itemId": key, - "quantity": profile.items[key].quantity - }); + ApplyProfileChanges.push( + { + "changeType": "itemQuantityChanged", + "itemId": key, + "quantity": profile.items[key].quantity + }, + { + "changeType": "itemQuantityChanged", + "itemId": key, + "quantity": profile0.items[key].quantity + } + ); paid = true; log.debug(`PurchaseCatalogEntry: Currency deducted: ${findOfferId.offerId.prices[0].finalPrice}, remaining ${profile.items[key].quantity}`); @@ -2414,14 +2497,29 @@ app.post("/fortnite/api/game/v2/profile/*/client/PurchaseCatalogEntry", verifyTo if (findOfferId.offerId.itemGrants.length != 0) { + if (!profile.stats.attributes.mtx_purchase_history) { + profile.stats.attributes.mtx_purchase_history = { purchases: [] }; + } + if (!profile0.stats.attributes.mtx_purchase_history) { + profile0.stats.attributes.mtx_purchase_history = { purchases: [] }; + } + var purchaseId = functions.MakeID(); profile.stats.attributes.mtx_purchase_history.purchases.push({"purchaseId":purchaseId,"offerId":`v2:/${purchaseId}`,"purchaseDate":new Date().toISOString(),"freeRefundEligible":false,"fulfillments":[],"lootResult":Notifications[0].lootResult.items,"totalMtxPaid":findOfferId.offerId.prices[0].finalPrice,"metadata":{},"gameContext":""}) + profile0.stats.attributes.mtx_purchase_history.purchases.push({"purchaseId":purchaseId,"offerId":`v2:/${purchaseId}`,"purchaseDate":new Date().toISOString(),"freeRefundEligible":false,"fulfillments":[],"lootResult":Notifications[0].lootResult.items,"totalMtxPaid":findOfferId.offerId.prices[0].finalPrice,"metadata":{},"gameContext":""}) - ApplyProfileChanges.push({ - "changeType": "statModified", - "name": "mtx_purchase_history", - "value": profile.stats.attributes.mtx_purchase_history - }) + ApplyProfileChanges.push( + { + "changeType": "statModified", + "name": "mtx_purchase_history", + "value": profile.stats.attributes.mtx_purchase_history + }, + { + "changeType": "statModified", + "name": "mtx_purchase_history", + "value": profile0.stats.attributes.mtx_purchase_history + } + ); log.debug(`PurchaseCatalogEntry: Successfully added the item to refunding tab`); } @@ -2444,7 +2542,13 @@ app.post("/fortnite/api/game/v2/profile/*/client/PurchaseCatalogEntry", verifyTo profile.rvn += 1; profile.commandRevision += 1; profile.updated = new Date().toISOString(); - await profiles?.updateOne({ $set: { [`profiles.${req.query.profileId}`]: profile, [`profiles.athena`]: athena } }); + await profiles?.updateOne({ + $set: { + [`profiles.${req.query.profileId}`]: profile, + [`profiles.athena`]: athena, + [`profiles.profile0`]: profile0 + } + }); } if (QueryRevision != ProfileRevisionCheck) { @@ -2503,7 +2607,13 @@ app.post("/fortnite/api/game/v2/profile/*/client/PurchaseCatalogEntry", verifyTo }); if (ApplyProfileChanges.length > 0) { - await profiles?.updateOne({ $set: { [`profiles.${req.query.profileId}`]: profile, [`profiles.athena`]: athena } }); + await profiles?.updateOne({ + $set: { + [`profiles.${req.query.profileId}`]: profile, + [`profiles.athena`]: athena, + [`profiles.profile0`]: profile0 + } + }); } return; @@ -3160,7 +3270,7 @@ app.post("/fortnite/api/game/v2/profile/:accountId/client/SetCosmeticLockerName" "profile": profile }]; }; - console.log(ApplyProfileChanges) + if (ApplyProfileChanges.length > 0) { profile.rvn += 1; profile.commandRevision += 1;