From 01e5bee3c8ce56776ea69a5970d1f0bab87b0d84 Mon Sep 17 00:00:00 2001 From: Burlone <108557545+burlone0@users.noreply.github.com> Date: Sun, 6 Oct 2024 11:40:39 +0200 Subject: [PATCH] "Big update" (24h Shop, Update Checker etc) --- CloudStorage/DefaultGame.ini | 11 +++++++++ Config/config.json | 1 + DiscordBot/commands/Admin/delete.js | 5 ++++- DiscordBot/commands/Admin/deletediscord.js | 3 +++ README.md | 1 + index.js | 17 ++++++++++++++ routes/auth.js | 26 +++++++++++++++++----- routes/launcher.js | 10 ++++----- routes/storefront.js | 6 ++++- routes/timeline.js | 11 ++++++--- structs/checkforupdate.js | 19 ++++++++++++++++ structs/functions.js | 7 +++++- structs/log.js | 8 ++++++- 13 files changed, 108 insertions(+), 17 deletions(-) create mode 100644 structs/checkforupdate.js diff --git a/CloudStorage/DefaultGame.ini b/CloudStorage/DefaultGame.ini index 88b477e..47a84e8 100644 --- a/CloudStorage/DefaultGame.ini +++ b/CloudStorage/DefaultGame.ini @@ -50,6 +50,17 @@ bEnableCreativeMode=false ; Change "false" to "true" if u want Enable Creative s +TextReplacements=(Category=Game, bIsMinimalPatch=True, Namespace="", Key="40D1ADD648EDBD000A8F7E88E8D90341", NativeString="ITEM SHOP", LocalizedStrings=(("en","Item Shop"))) +# +TextReplacements=(Category=Game, bIsMinimalPatch=True, Namespace="", Key="NetworkConnectionLost", NativeString="Network Connection Lost", LocalizedStrings=(("en","https://discord.gg/PmYMpY9thJ"))) +# +TextReplacements=(Category=Game, bIsMinimalPatch=True, Namespace="NetworkErrors", Key="ReturnToMainMenuTimeout", NativeString="Ack! We lost our connection to the match. Sorry about that. Make sure your internet connection is still good and try again. If it keeps up, visit {CheckStatusURL}.", LocalizedStrings=(("en","https://discord.gg/PmYMpY9thJ"))) +# +TextReplacements=(Category=Game, bIsMinimalPatch=True, Namespace="", Key="C87986DE4542C0450F7EA1AC940B8F0D", NativeString="DRAT! WE'RE SORRY", LocalizedStrings=(("ar","https://discord.gg/PmYMpY9thJ"),("en","https://discord.gg/PmYMpY9thJ"),("de","https://discord.gg/PmYMpY9thJ"),("es","https://discord.gg/PmYMpY9thJ"),("es-419","https://discord.gg/PmYMpY9thJ"),("fr","https://discord.gg/PmYMpY9thJ"),("it","https://discord.gg/PmYMpY9thJ"),("ja","https://discord.gg/PmYMpY9thJ"),("ko","https://discord.gg/PmYMpY9thJ"),("pl","https://discord.gg/PmYMpY9thJ"),("pt-BR","https://discord.gg/PmYMpY9thJ"),("ru","ОШИБКА"),("tr","https://discord.gg/PmYMpY9thJ"),("zh-CN","https://discord.gg/PmYMpY9thJ"),("zh-Hant","https://discord.gg/PmYMpY9thJ"))) +# +TextReplacements=(Category=Game, bIsMinimalPatch=True, Namespace="", Key="4A40FB5E4D1A000D740EB18B21C70CE9", NativeString="UH OH! SOMETHING GOOFED", LocalizedStrings=(("ar","https://discord.gg/PmYMpY9thJ"),("en","https://discord.gg/PmYMpY9thJ"),("de","https://discord.gg/PmYMpY9thJ"),("es","https://discord.gg/PmYMpY9thJ"),("es-419","https://discord.gg/PmYMpY9thJ"),("fr","https://discord.gg/PmYMpY9thJ"),("it","https://discord.gg/PmYMpY9thJ"),("ja","https://discord.gg/PmYMpY9thJ"),("ko","https://discord.gg/PmYMpY9thJ"),("pl","https://discord.gg/PmYMpY9thJ"),("pt-BR","https://discord.gg/PmYMpY9thJ"),("ru","ОШИБКА"),("tr","https://discord.gg/PmYMpY9thJ"),("zh-CN","https://discord.gg/PmYMpY9thJ"),("zh-Hant","https://discord.gg/PmYMpY9thJ"))) +# +TextReplacements=(Category=Game, bIsMinimalPatch=True, Namespace="", Key="1B9B2D834DA0883E9514348620A95123", NativeString="WHOOPS!", LocalizedStrings=(("ar","https://discord.gg/PmYMpY9thJ"),("en","https://discord.gg/PmYMpY9thJ"),("de","https://discord.gg/PmYMpY9thJ"),("es","https://discord.gg/PmYMpY9thJ"),("es-419","https://discord.gg/PmYMpY9thJ"),("fr","https://discord.gg/PmYMpY9thJ"),("it","https://discord.gg/PmYMpY9thJ"),("ja","https://discord.gg/PmYMpY9thJ"),("ko","https://discord.gg/PmYMpY9thJ"),("pl","https://discord.gg/PmYMpY9thJ"),("pt-BR","https://discord.gg/PmYMpY9thJ"),("ru","ОШИБКА"),("tr","https://discord.gg/PmYMpY9thJ"),("zh-CN","https://discord.gg/PmYMpY9thJ"),("zh-Hant","https://discord.gg/PmYMpY9thJ"))) +# +TextReplacements=(Category=Game, bIsMinimalPatch=True, Namespace="", Key="E1FD8EAB445872DB7AF2209988DA1C93", NativeString="THAT WASN'T SUPPOSED TO HAPPEN", LocalizedStrings=(("ar","https://discord.gg/PmYMpY9thJ"),("en","https://discord.gg/PmYMpY9thJ"),("de","https://discord.gg/PmYMpY9thJ"),("es","https://discord.gg/PmYMpY9thJ"),("es-419","https://discord.gg/PmYMpY9thJ"),("fr","https://discord.gg/PmYMpY9thJ"),("it","https://discord.gg/PmYMpY9thJ"),("ja","https://discord.gg/PmYMpY9thJ"),("ko","https://discord.gg/PmYMpY9thJ"),("pl","https://discord.gg/PmYMpY9thJ"),("pt-BR","https://discord.gg/PmYMpY9thJ"),("ru","ОШИБКА"),("tr","https://discord.gg/PmYMpY9thJ"),("zh-CN","https://discord.gg/PmYMpY9thJ"),("zh-Hant","https://discord.gg/PmYMpY9thJ"))) +# +TextReplacements=(Category=Game, bIsMinimalPatch=True, Namespace="", Key="E211A281448782354CD492AFB98CCE7B", NativeString="WE HIT A ROADBLOCK", LocalizedStrings=(("ar","https://discord.gg/PmYMpY9thJ"),("en","https://discord.gg/PmYMpY9thJ"),("de","https://discord.gg/PmYMpY9thJ"),("es","https://discord.gg/PmYMpY9thJ"),("es-419","https://discord.gg/PmYMpY9thJ"),("fr","https://discord.gg/PmYMpY9thJ"),("it","https://discord.gg/PmYMpY9thJ"),("ja","https://discord.gg/PmYMpY9thJ"),("ko","https://discord.gg/PmYMpY9thJ"),("pl","https://discord.gg/PmYMpY9thJ"),("pt-BR","https://discord.gg/PmYMpY9thJ"),("ru","ОШИБКА"),("tr","https://discord.gg/PmYMpY9thJ"),("zh-CN","https://discord.gg/PmYMpY9thJ"),("zh-Hant","https://discord.gg/PmYMpY9thJ"))) +# +TextReplacements=(Category=Game, bIsMinimalPatch=True, Namespace="", Key="96CCC52841C1364F2BB12184E3CB2396", NativeString="NOT THE LLAMA YOU'RE LOOKING FOR", LocalizedStrings=(("ar","https://discord.gg/PmYMpY9thJ"),("en","https://discord.gg/PmYMpY9thJ"),("de","https://discord.gg/PmYMpY9thJ"),("es","https://discord.gg/PmYMpY9thJ"),("es-419","https://discord.gg/PmYMpY9thJ"),("fr","https://discord.gg/PmYMpY9thJ"),("it","https://discord.gg/PmYMpY9thJ"),("ja","https://discord.gg/PmYMpY9thJ"),("ko","https://discord.gg/PmYMpY9thJ"),("pl","https://discord.gg/PmYMpY9thJ"),("pt-BR","https://discord.gg/PmYMpY9thJ"),("ru","ОШИБКА"),("tr","https://discord.gg/PmYMpY9thJ"),("zh-CN","https://discord.gg/PmYMpY9thJ"),("zh-Hant","https://discord.gg/PmYMpY9thJ"))) +# +TextReplacements=(Category=Game, bIsMinimalPatch=True, Namespace="", Key="47218EFD4023FB7C729C71A3A83FF01D", NativeString="THERE WAS A PROBLEM", LocalizedStrings=(("ar","https://discord.gg/PmYMpY9thJ"),("en","https://discord.gg/PmYMpY9thJ"),("de","https://discord.gg/PmYMpY9thJ"),("es","https://discord.gg/PmYMpY9thJ"),("es-419","https://discord.gg/PmYMpY9thJ"),("fr","https://discord.gg/PmYMpY9thJ"),("it","https://discord.gg/PmYMpY9thJ"),("ja","https://discord.gg/PmYMpY9thJ"),("ko","https://discord.gg/PmYMpY9thJ"),("pl","https://discord.gg/PmYMpY9thJ"),("pt-BR","https://discord.gg/PmYMpY9thJ"),("ru","ОШИБКА"),("tr","https://discord.gg/PmYMpY9thJ"),("zh-CN","https://discord.gg/PmYMpY9thJ"),("zh-Hant","https://discord.gg/PmYMpY9thJ"))) +# +TextReplacements=(Category=Game, bIsMinimalPatch=True, Namespace="", Key="10D2167A4B5AFCAB75963CBC54D06038", NativeString="THERE WAS AN ERROR", LocalizedStrings=(("ar","https://discord.gg/PmYMpY9thJ"),("en","https://discord.gg/PmYMpY9thJ"),("de","https://discord.gg/PmYMpY9thJ"),("es","https://discord.gg/PmYMpY9thJ"),("es-419","https://discord.gg/PmYMpY9thJ"),("fr","https://discord.gg/PmYMpY9thJ"),("it","https://discord.gg/PmYMpY9thJ"),("ja","https://discord.gg/PmYMpY9thJ"),("ko","https://discord.gg/PmYMpY9thJ"),("pl","https://discord.gg/PmYMpY9thJ"),("pt-BR","https://discord.gg/PmYMpY9thJ"),("ru","ОШИБКА"),("tr","https://discord.gg/PmYMpY9thJ"),("zh-CN","https://discord.gg/PmYMpY9thJ"),("zh-Hant","https://discord.gg/PmYMpY9thJ"))) + # +TextReplacements=(Category=Game, bIsMinimalPatch=True, Namespace="", Key="930565094674D02FD5511282C666EB04", NativeString="SAVE THE WORLD", LocalizedStrings=(("ar", "UNAVAILABLE"),("en", "UNAVAILABLE"),("de", "UNAVAILABLE"),("es", "UNAVAILABLE"),("es-419", "UNAVAILABLE"),("fr", "UNAVAILABLE"),("it", "UNAVAILABLE"),("ja", "UNAVAILABLE"),("ko", "UNAVAILABLE"),("pl", "UNAVAILABLE"),("pt-BR", "UNAVAILABLE"),("ru", "UNAVAILABLE"),("tr", "UNAVAILABLE"),("zh-CN", "UNAVAILABLE"),("zh-Hant", "UNAVAILABLE"))) # +TextReplacements=(Category=Game, bIsMinimalPatch=True, Namespace="", Key="226846CB47F043C86848BBBD8394B556", NativeString="SAVE THE WORLD", LocalizedStrings=(("ar", "UNAVAILABLE"),("en", "UNAVAILABLE"),("de", "UNAVAILABLE"),("es", "UNAVAILABLE"),("es-419", "UNAVAILABLE"),("fr", "UNAVAILABLE"),("it", "UNAVAILABLE"),("ja", "UNAVAILABLE"),("ko", "UNAVAILABLE"),("pl", "UNAVAILABLE"),("pt-BR", "UNAVAILABLE"),("ru", "UNAVAILABLE"),("tr", "UNAVAILABLE"),("zh-CN", "UNAVAILABLE"),("zh-Hant", "UNAVAILABLE"))) # +TextReplacements=(Category=Game, bIsMinimalPatch=True, Namespace="", Key="0BDA5AB64D20E843B2CF009897EBA8FC", NativeString="BATTLE ROYALE", LocalizedStrings=(("ar", "BATTLE ROYALE"),("en", "BATTLE ROYALE"),("de", "BATTLE ROYALE"),("es", "BATTLE ROYALE"),("es-419", "BATTLE ROYALE"),("fr", "BATTLE ROYALE"),("it", "BATTLE ROYALE"),("ja", "BATTLE ROYALE"),("ko", "BATTLE ROYALE"),("pl", "BATTLE ROYALE"),("pt-BR", "BATTLE ROYALE"),("ru", "BATTLE ROYALE"),("tr", "BATTLE ROYALE"),("zh-CN", "BATTLE ROYALE"),("zh-Hant", "BATTLE ROYALE"))) diff --git a/Config/config.json b/Config/config.json index 326768f..22f491f 100644 --- a/Config/config.json +++ b/Config/config.json @@ -13,6 +13,7 @@ }, "bEnableDebugLogs": false, + "bEnableRebootUser": true, "//": "If you want to use the backend on reboot, leave 3551 as the port", "port": 3551, diff --git a/DiscordBot/commands/Admin/delete.js b/DiscordBot/commands/Admin/delete.js index fb080d0..bb82729 100644 --- a/DiscordBot/commands/Admin/delete.js +++ b/DiscordBot/commands/Admin/delete.js @@ -1,6 +1,7 @@ -const { MessageEmbed, PermissionFlagsBits, SlashCommandBuilder } = require("discord.js"); +const { MessageEmbed } = require("discord.js"); const Users = require('../../../model/user.js'); const Profiles = require('../../../model/profiles.js'); +const SACCodes = require('../../../model/saccodes.js'); const config = require('../../../Config/config.json'); module.exports = { @@ -25,6 +26,7 @@ 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 }); @@ -33,6 +35,7 @@ module.exports = { await Users.deleteOne({ username: username }); await Profiles.deleteOne({ username: username }); + await SACCodes.deleteOne({ owneraccountId: accountId }); const embed = new MessageEmbed() .setTitle("Account deleted") diff --git a/DiscordBot/commands/Admin/deletediscord.js b/DiscordBot/commands/Admin/deletediscord.js index 53317be..fc07388 100644 --- a/DiscordBot/commands/Admin/deletediscord.js +++ b/DiscordBot/commands/Admin/deletediscord.js @@ -1,6 +1,7 @@ const { MessageEmbed } = require("discord.js"); const Users = require('../../../model/user.js'); const Profiles = require('../../../model/profiles.js'); +const SACCodes = require('../../../model/saccodes.js'); const config = require('../../../Config/config.json') module.exports = { @@ -26,6 +27,7 @@ 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; if (deleteAccount == null) { await interaction.editReply({ content: "The selected user does not have **an account**", ephemeral: true }); @@ -34,6 +36,7 @@ module.exports = { await Users.deleteOne({ discordId: discordId }) await Profiles.deleteOne({ discordId: discordId }) + await SACCodes.deleteOne({ owneraccountId: accountId }); const embed = new MessageEmbed() .setTitle("Account deleted") diff --git a/README.md b/README.md index 7600996..d7996f9 100644 --- a/README.md +++ b/README.md @@ -112,6 +112,7 @@ This **project/backend** is licensed under the **BSD 3-Clause License.** ## Credits ### Credits to: * [Lawin](https://github.com/Lawin0129) - For the backend base (LawinServerV2) +* [Momentum](https://github.com/Nexus-FN/Momentum) - For some files * [Burlone](https://github.com/burlone0) - For having modded most things, let's say he modded everything * [NotTacos](https://github.com/PhysicalDrive) - For adding the working challenges (Backend Part) * [zvivsp](https://github.com/zvivsp) - For creating the graphics diff --git a/index.js b/index.js index efeac64..ed2d4e2 100644 --- a/index.js +++ b/index.js @@ -10,6 +10,7 @@ const config = JSON.parse(fs.readFileSync("./Config/config.json").toString()); const log = require("./structs/log.js"); const error = require("./structs/error.js"); const functions = require("./structs/functions.js"); +const CheckForUpdate = require("./structs/checkforupdate.js"); const app = express(); @@ -46,6 +47,22 @@ global.kv = kv; global.exchangeCodes = []; +const packageJson = JSON.parse(fs.readFileSync(path.join(__dirname, "./package.json")).toString()); +if (!packageJson) throw new Error("Failed to parse package.json"); +const version = packageJson.version; + +const checkUpdates = async () => { + try { + await CheckForUpdate.checkForUpdate(version); + } catch (err) { + log.error("Failed to check for updates"); + } +}; + +checkUpdates(); + +setInterval(checkUpdates, 60000); + mongoose.set('strictQuery', true); mongoose.connect(config.mongodb.database, () => { diff --git a/routes/auth.js b/routes/auth.js index f2ad0f8..4cd6f2f 100644 --- a/routes/auth.js +++ b/routes/auth.js @@ -65,8 +65,23 @@ app.post("/account/api/oauth/token", async (req, res) => { ); } const { username: email, password: password } = req.body; - - req.user = await User.findOne({ email: email.toLowerCase() }).lean(); + const regex = /@projectreboot\.dev$/; + rebootAccount = regex.test(email); + log.debug(`Reboot account: ${rebootAccount}`); + if (rebootAccount && config.bEnableRebootUser) { + const findUser = await User.findOne({ email: email.toLowerCase() }); + if (findUser) { + req.user = findUser; + } + else { + const numberWith8Digits = Math.floor(10000000 + Math.random() * 90000000); + const registerUser = await functions.registerUser(numberWith8Digits, `reboot_${email.split("@")[0]}`, email, password, true); + req.user = await User.findOne({ email: email.toLowerCase() }); + } + } + else { + req.user = await User.findOne({ email: email.toLowerCase() }).lean(); + } let err = () => error.createError( "errors.com.epicgames.account.invalid_account_credentials", @@ -78,11 +93,12 @@ app.post("/account/api/oauth/token", async (req, res) => { log.debug("Invalid username or password"); return err(); } else { - if (!await bcrypt.compare(password, req.user.password)) { - log.debug("Invalid password"); - return err(); + if (!rebootAccount) { + if (!(await bcrypt.compare(password, req.user.password))) + return err(); } } + break; case "refresh_token": diff --git a/routes/launcher.js b/routes/launcher.js index 2e93992..d6f2f5e 100644 --- a/routes/launcher.js +++ b/routes/launcher.js @@ -3,13 +3,13 @@ const app = express.Router(); const User = require("../model/user.js"); const bcrypt = require("bcrypt"); -//Api for launcher login -app.post("/launcher/login", async (req, res) => { - const { email, password } = req.body; - +//Api for launcher login (If u want a POST requesto just replace "app.get" to "app.post" and "req.query" to "req.body") +app.get("/launcher/login", async (req, res) => { + const { email, password } = req.query; + if (!email) return res.status(400).send('The email was not entered.'); if (!password) return res.status(400).send('The password was not entered.'); - + try { const user = await User.findOne({ email: email }); if (!user) return res.status(404).send('User not found.'); diff --git a/routes/storefront.js b/routes/storefront.js index f7026cb..8e5a757 100644 --- a/routes/storefront.js +++ b/routes/storefront.js @@ -10,7 +10,11 @@ const keychain = require("../responses/keychain.json"); app.get("/fortnite/api/storefront/v2/catalog", (req, res) => { log.debug("Request to /fortnite/api/storefront/v2/catalog"); - if (req.headers["user-agent"].includes("2870186")) return res.status(404).end(); + if (req.headers["user-agent"] == undefined) return; + if (req.headers["user-agent"].includes("2870186")) { + return res.status(404).end(); + } + res.json(functions.getItemShop()); }); diff --git a/routes/timeline.js b/routes/timeline.js index 4f033a0..8015dcd 100644 --- a/routes/timeline.js +++ b/routes/timeline.js @@ -6,6 +6,11 @@ const config = JSON.parse(fs.readFileSync("./Config/config.json").toString()); app.get("/fortnite/api/calendar/v1/timeline", async (req, res) => { const memory = functions.GetVersionInfo(req); + + const todayAtMidnight = new Date(); + todayAtMidnight.setHours(24, 0, 0, 0) + const todayOneMinuteBeforeMidnight = new Date(todayAtMidnight.getTime() - 60000); + const isoDate = todayOneMinuteBeforeMidnight.toISOString(); var activeEvents = [ { @@ -1140,11 +1145,11 @@ app.get("/fortnite/api/calendar/v1/timeline", async (req, res) => { "seasonBegin": "2020-01-01T13:00:00Z", "seasonEnd": "9999-01-01T14:00:00Z", "seasonDisplayedEnd": "9999-01-01T07:30:00Z", - "weeklyStoreEnd": "9999-01-01T00:00:00Z", + "weeklyStoreEnd": isoDate, "sectionStoreEnds": { - "Featured": "9999-01-01T00:00:00.000Z" + "Featured": isoDate }, - "dailyStoreEnd": "9999-01-01T00:00:00Z" + "dailyStoreEnd": isoDate }; var states = [{ diff --git a/structs/checkforupdate.js b/structs/checkforupdate.js new file mode 100644 index 0000000..0fa4f72 --- /dev/null +++ b/structs/checkforupdate.js @@ -0,0 +1,19 @@ +const log = require("../structs/log.js"); +const fetch = require("node-fetch"); + +class CheckForUpdate { + static async checkForUpdate(currentVersion) { + const packageJson = await fetch('https://raw.githubusercontent.com/Project-Reload/Reload-Backend/refs/heads/main/package.json') + .then(res => res.json()); + + const latestVersion = packageJson.version.replace(/\./g, ""); + const currentVersionFormatted = currentVersion.replace(/\./g, ""); + + if (parseFloat(latestVersion) > parseFloat(currentVersionFormatted)) { + const message = `A new version of the Backend has been released! ${currentVersion} -> ${packageJson.version}`; + log.checkforupdate(`${message}\nDownload it from the GitHub repo.`); + } + } +} + +module.exports = CheckForUpdate; \ No newline at end of file diff --git a/structs/functions.js b/structs/functions.js index 9e58580..af9ce83 100644 --- a/structs/functions.js +++ b/structs/functions.js @@ -192,6 +192,11 @@ function getContentPages(req) { function getItemShop() { const catalog = JSON.parse(fs.readFileSync(path.join(__dirname, "..", "responses", "catalog.json")).toString()); const CatalogConfig = JSON.parse(fs.readFileSync(path.join(__dirname, "..", "Config", "catalog_config.json").toString())); + + const todayAtMidnight = new Date(); + todayAtMidnight.setHours(24, 0, 0, 0) + const todayOneMinuteBeforeMidnight = new Date(todayAtMidnight.getTime() - 60000); + const isoDate = todayOneMinuteBeforeMidnight.toISOString(); try { for (let value in CatalogConfig) { @@ -223,7 +228,7 @@ function getItemShop() { "currencySubType": "", "regularPrice": CatalogConfig[value].price, "finalPrice": CatalogConfig[value].price, - "saleExpiration": "9999-12-02T01:12:00Z", + "saleExpiration": isoDate, "basePrice": CatalogConfig[value].price }]; diff --git a/structs/log.js b/structs/log.js index 9926e6d..b00d583 100644 --- a/structs/log.js +++ b/structs/log.js @@ -40,6 +40,11 @@ function AutoRotation(...args) { } } +function checkforupdate(...args) { + let msg = args.join(" "); + console.log(`\x1b[33mReload Update Log\x1b[0m: ${msg}`); +} + module.exports = { backend, bot, @@ -47,5 +52,6 @@ module.exports = { error, debug, website, - AutoRotation + AutoRotation, + checkforupdate }; \ No newline at end of file