From 7adebcdab13554c5185c32c50b253874e958290f Mon Sep 17 00:00:00 2001 From: kxtzownsu Date: Sat, 25 Jul 2026 11:39:53 -0400 Subject: [PATCH 1/7] feat: modernize packages & refactor config system DiscordJS @ v13 and UUID @ v9 is now deprecated. This commit updates us to DiscordJS @ v14 and UUID @ v11. (uuid@11 is the latest we can go, as past that CommonJS is deprecated). This commit also switches us to use bcryptjs, which doesn't require any API changes. Finally, this commit will switch us to use a proper `.env` configuration style while still making sure most of the code doesn't need to be changed to support this new style. Signed-off-by: kxtzownsu --- .env.example | 115 ++ .gitignore | 1 + Api/launcher.js | 13 +- Api/vbucks.js | 2 +- CalderaService/tokencreator.js | 3 +- Config/config.js | 140 ++ Config/config.json | 113 -- DiscordBot/commands/Admin/addall.js | 2 +- DiscordBot/commands/Admin/additem.js | 10 +- DiscordBot/commands/Admin/addvbucks.js | 8 +- DiscordBot/commands/Admin/ban.js | 3 +- .../commands/Admin/createcustommatchcode.js | 2 +- .../commands/Admin/createhostaccount.js | 4 +- DiscordBot/commands/Admin/createsac.js | 2 +- .../commands/Admin/custommatchcodelist.js | 2 +- DiscordBot/commands/Admin/delete.js | 8 +- DiscordBot/commands/Admin/deletediscord.js | 8 +- DiscordBot/commands/Admin/deletesac.js | 2 +- DiscordBot/commands/Admin/kick.js | 3 +- DiscordBot/commands/Admin/removeall.js | 2 +- DiscordBot/commands/Admin/removeitem.js | 8 +- DiscordBot/commands/Admin/removevbucks.js | 8 +- DiscordBot/commands/Admin/unban.js | 3 +- DiscordBot/commands/User/change-password.js | 4 +- DiscordBot/index.js | 10 +- README.md | 21 +- Website/website.js | 2 +- index.js | 8 +- package.json | 11 +- pnpm-lock.yaml | 1731 +++++++++++++++++ routes/auth.js | 4 +- routes/main.js | 2 +- routes/matchmaking.js | 2 +- routes/mcp.js | 2 +- routes/reports.js | 2 +- routes/timeline.js | 2 +- structs/autorotate.js | 2 +- structs/checkforupdate.js | 2 +- structs/functions.js | 2 +- structs/log.js | 2 +- xmpp/xmpp.js | 4 +- 41 files changed, 2076 insertions(+), 199 deletions(-) create mode 100644 .env.example create mode 100644 Config/config.js delete mode 100644 Config/config.json create mode 100644 pnpm-lock.yaml diff --git a/.env.example b/.env.example new file mode 100644 index 00000000..0740d38f --- /dev/null +++ b/.env.example @@ -0,0 +1,115 @@ +############ +## README ## +############ +# The '.env' system in this repository acts as an override for configuration options. +# You do not need to pass in *every* value in here for your '.env', only the ones you want to change. +# For example, if I wanted to change DISCORD_USE_BOT to false but keep everything as the default, the contents of +# '.env' would only have to be 'DISCORD_USE_BOT=false', nothing else. + +## ok now the .env.example starts here! ## + +# comma-separated discord ids allowed to use mod commands +MODERATORS=discordId,discordId2 + +DISCORD_USE_BOT=true +DISCORD_BOT_TOKEN= +DISCORD_ENABLE_INGAME_PLAYER_COUNT=true + +MONGODB_DATABASE=mongodb://127.0.0.1/Reload + +# disabling global chat can help the server perform faster (less resources used) +CHAT_ENABLE_GLOBAL_CHAT=false + +ENABLE_DEBUG_LOGS=false +ENABLE_FORMATTED_LOGS=false +ENABLE_REBOOT_USER=true +ENABLE_CROSS_BANS=false + +# if you want to use the backend on reboot, leave 3551 as the port +PORT=3551 + +API_KEY=ur-api-key +API_REASON_KILL=25 +API_REASON_WIN=50 + +WEBSITE_USE_WEBSITE=false +WEBSITE_CLIENT_ID=your-client-id-here +WEBSITE_CLIENT_SECRET=your-client-secret-here +WEBSITE_REDIRECT_URI=http://127.0.0.1:${WEBSITE_PORT}/oauth2/callback +WEBSITE_PORT=100 + +# to add more gameservers add ip:port:playlist, comma-separated +# example: 127.0.0.1:7777:example_playlist1,127.0.0.2:7777:example_playlist2 +MATCHMAKER_IP=127.0.0.1:80 +GAME_SERVER_IP=127.0.0.1:7777:playlist_defaultsolo + +# for BATTLEPASS_SEASON enter only the number of your season (2 to 20) +ENABLE_BATTLEPASS=false +BATTLEPASS_SEASON=2 + +# for VERSION_JOINABLE you can set a season like 9.10, not just 9 +ENABLE_ONLY_ONE_VERSION_JOINABLE=false +VERSION_JOINABLE=2 + +# if USE_AUTO_ROTATE is enabled it will automatically rotate the item shop +# using ROTATE_TIME, SEASON_LIMIT caps which seasons rotate (up to 10 recommended), +# ROTATE_TIME is UTC 24h, ITEM_SHOP_WEBHOOK needs a webhook to your item shop channel +USE_AUTO_ROTATE=false +ENABLE_AUTO_ROTATE_DEBUG_LOGS=false +ENABLE_DISCORD_WEBHOOK=false +CHAPTER_LIMIT=1 +SEASON_LIMIT=10 +ROTATE_TIME=00:00 +EXCLUDED_ITEMS=CID_VIP_Athena_Commando_M_GalileoGondola_SG,CID_636_Athena_Commando_M_GalileoGondola_78MFZ,CID_637_Athena_Commando_M_GalileoOutrigger_7Q0YU,CID_VIP_Athena_Commando_M_GalileoFerry_SG,CID_VIP_Athena_Commando_F_GalileoRocket_SG,CID_568_Athena_Commando_M_RebirthSoldier +ITEM_SHOP_WEBHOOK= +DAILY_ITEMS_AMOUNT=6 +FEATURED_ITEMS_AMOUNT=2 + +# enabling ENABLE_REPORTS turns on in-game reports, rate limited per player +ENABLE_REPORTS=false +REPORT_CHANNEL_ID=your-discord-channel-id-here + +# if true, sets all quests except daily quests as completed +COMPLETED_SEASONAL_QUESTS=false + +# SAC rewards give the creator-code supporter a % of vbucks spent, in vbucks +# e.g: if your reward % is 25, with an item that is 1000, the SAC code's owner will get 250 vbucks. +ENABLE_SAC_REWARDS=false +PERCENTAGE_SAC_REWARDS=0 + +# RESTART_TIME format: [number][y,M,w,d,h,m,s], e.g. 5m (capital M = month) +ENABLE_AUTO_BACKEND_RESTART=false +RESTART_TIME= + +# sends a message in the channel when the backend comes online +ENABLE_BACKEND_STATUS=false +BACKEND_STATUS_CHANNEL_ID= + +# use HTTPS (VPS side, or your own domain A record). needs certs in ssl/ +ENABLE_HTTPS=false +SSL_CERT=./ssl/example_certificate.crt +SSL_CA= +SSL_KEY=./ssl/example_private.key + +# caldera service is for newer game versions, see CalderaService/guids.json for supported GAME_VERSION +ENABLE_CALDERA_SERVICE=false +GAME_VERSION=27.11 +CALDERA_SERVICE_PORT=5000 + +# in-game world events +ENABLE_GEODE_EVENT=false +GEODE_EVENT_START_DATE=2020-01-01T00:00:00.000Z +ENABLE_CRACK_IN_THE_SKY=false +ENABLE_S4_ODDITY_PRECURSOR=false +ENABLE_S4_ODDITY_EXECUTION=false +S4_ODDITY_EVENT_START_DATE=2020-01-01T00:00:00.000Z +S4_ODDITY_EVENTS_INTERVAL=0 +ENABLE_S5_ODDITY_PRECURSOR=false +S5_ODDITY_PRECURSOR_DATE=2020-01-01T00:00:00.000Z +ENABLE_S5_ODDITY_EXECUTION=false +S5_ODDITY_EXECUTION_DATE=2020-01-01T00:00:00.000Z +ENABLE_CUBE_LIGHTNING=false +CUBE_SPAWN_DATE=2020-01-01T00:00:00.000Z +ENABLE_BLOCKBUSTER_RISKY_EVENT=false +ENABLE_CUBE_LAKE=false +CUBE_LAKE_DATE=2020-01-01T00:00:00.000Z diff --git a/.gitignore b/.gitignore index b89df4ee..c1b32bab 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ ClientSettings/ *.Sav node_modules/ +.env \ No newline at end of file diff --git a/Api/launcher.js b/Api/launcher.js index 37517d18..a6d80202 100644 --- a/Api/launcher.js +++ b/Api/launcher.js @@ -1,12 +1,13 @@ +const bcrypt = require("bcryptjs"); 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") -app.get("/api/launcher/login", async (req, res) => { - const { email, password } = req.query; +const app = express.Router(); + +app.post("/api/launcher/login", async (req, res) => { + const { email, password } = req.body; if (!email) return res.status(400).send('The email was not entered.'); if (!password) return res.status(400).send('The password was not entered.'); @@ -27,7 +28,7 @@ app.get("/api/launcher/login", async (req, res) => { return res.status(400).send('Error!'); } } catch (err) { - log.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 7ac60fa2..88055139 100644 --- a/Api/vbucks.js +++ b/Api/vbucks.js @@ -5,7 +5,7 @@ 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()); +const config = require('../Config/config.js'); app.get("/api/reload/vbucks", async (req, res) => { const { apikey, username, reason } = req.query; diff --git a/CalderaService/tokencreator.js b/CalderaService/tokencreator.js index d1296972..eac57695 100644 --- a/CalderaService/tokencreator.js +++ b/CalderaService/tokencreator.js @@ -1,9 +1,8 @@ const jwt = require("jsonwebtoken"); -const fs = require("fs"); const guids = require("./guids.json") -const config = JSON.parse(fs.readFileSync("./Config/config.json").toString()); +const config = require('../Config/config.js'); var CalderaGenerated = 0; diff --git a/Config/config.js b/Config/config.js new file mode 100644 index 00000000..e3c74697 --- /dev/null +++ b/Config/config.js @@ -0,0 +1,140 @@ +require('dotenv').config(); + +function bool(key, fallback) { + const raw = process.env[key]; + if (raw === undefined || raw === '') return fallback; + return raw === 'true' || raw === '1'; +} + +function num(key, fallback) { + const raw = process.env[key]; + if (raw === undefined || raw === '') return fallback; + return Number(raw); +} + +function str(key, fallback) { + const raw = process.env[key]; + return raw === undefined ? fallback : raw; +} + +function arr(key, fallback) { + const raw = process.env[key]; + if (raw === undefined || raw === '') return fallback; + return raw.split(',').map((item) => item.trim()); +} + +const websitePort = num('WEBSITE_PORT', 100); + +const config = { + moderators: arr('MODERATORS', []), + + discord: { + bUseDiscordBot: bool('DISCORD_USE_BOT', true), + bot_token: str('DISCORD_BOT_TOKEN', ''), + bEnableInGamePlayerCount: bool('DISCORD_ENABLE_INGAME_PLAYER_COUNT', true), + }, + + mongodb: { + database: str('MONGODB_DATABASE', 'mongodb://127.0.0.1/Reload'), + }, + + chat: { + EnableGlobalChat: bool('CHAT_ENABLE_GLOBAL_CHAT', false), + }, + + bEnableDebugLogs: bool('ENABLE_DEBUG_LOGS', false), + bEnableFormattedLogs: bool('ENABLE_FORMATTED_LOGS', false), + bEnableRebootUser: bool('ENABLE_REBOOT_USER', true), + bEnableCrossBans: bool('ENABLE_CROSS_BANS', false), + + port: num('PORT', 3551), + + Api: { + bApiKey: str('API_KEY', 'ur-api-key'), + reasons: { + Kill: num('API_REASON_KILL', 25), + Win: num('API_REASON_WIN', 50), + }, + }, + + Website: { + bUseWebsite: bool('WEBSITE_USE_WEBSITE', false), + clientId: str('WEBSITE_CLIENT_ID', 'your-client-id-here'), + clientSecret: str('WEBSITE_CLIENT_SECRET', 'your-client-secret-here'), + websitePort: websitePort, + redirectUri: str( + 'WEBSITE_REDIRECT_URI', + 'http://127.0.0.1:${websitePort}/oauth2/callback' + ).replace('${websitePort}', websitePort), + }, + + matchmakerIP: str('MATCHMAKER_IP', '127.0.0.1:80'), + gameServerIP: arr('GAME_SERVER_IP', ['127.0.0.1:7777:playlist_defaultsolo']), + + bEnableBattlepass: bool('ENABLE_BATTLEPASS', false), + bBattlePassSeason: num('BATTLEPASS_SEASON', 2), + + bEnableOnlyOneVersionJoinable: bool('ENABLE_ONLY_ONE_VERSION_JOINABLE', false), + bVersionJoinable: num('VERSION_JOINABLE', 2), + + bUseAutoRotate: bool('USE_AUTO_ROTATE', false), + bEnableAutoRotateDebugLogs: bool('ENABLE_AUTO_ROTATE_DEBUG_LOGS', false), + bEnableDiscordWebhook: bool('ENABLE_DISCORD_WEBHOOK', false), + bChapterlimit: str('CHAPTER_LIMIT', '1'), + bSeasonlimit: str('SEASON_LIMIT', '10'), + bRotateTime: str('ROTATE_TIME', '00:00'), + bExcludedItems: arr('EXCLUDED_ITEMS', [ + 'CID_VIP_Athena_Commando_M_GalileoGondola_SG', + 'CID_636_Athena_Commando_M_GalileoGondola_78MFZ', + 'CID_637_Athena_Commando_M_GalileoOutrigger_7Q0YU', + 'CID_VIP_Athena_Commando_M_GalileoFerry_SG', + 'CID_VIP_Athena_Commando_F_GalileoRocket_SG', + 'CID_568_Athena_Commando_M_RebirthSoldier', + ]), + bItemShopWebhook: str('ITEM_SHOP_WEBHOOK', ''), + bDailyItemsAmount: num('DAILY_ITEMS_AMOUNT', 6), + bFeaturedItemsAmount: num('FEATURED_ITEMS_AMOUNT', 2), + + bEnableReports: bool('ENABLE_REPORTS', false), + bReportChannelId: str('REPORT_CHANNEL_ID', 'your-discord-channel-id-here'), + + bCompletedSeasonalQuests: bool('COMPLETED_SEASONAL_QUESTS', false), + + bEnableSACRewards: bool('ENABLE_SAC_REWARDS', false), + bPercentageSACRewards: num('PERCENTAGE_SAC_REWARDS', 0), + + bEnableAutoBackendRestart: bool('ENABLE_AUTO_BACKEND_RESTART', false), + bRestartTime: str('RESTART_TIME', ''), + + bEnableBackendStatus: bool('ENABLE_BACKEND_STATUS', false), + bBackendStatusChannelId: str('BACKEND_STATUS_CHANNEL_ID', ''), + + bEnableHTTPS: bool('ENABLE_HTTPS', false), + ssl: { + cert: str('SSL_CERT', './ssl/example_certificate.crt'), + key: str('SSL_KEY', './ssl/example_private.key'), + }, + + bEnableCalderaService: bool('ENABLE_CALDERA_SERVICE', false), + bGameVersion: str('GAME_VERSION', '27.11'), + bCalderaServicePort: num('CALDERA_SERVICE_PORT', 5000), + + bEnableGeodeEvent: bool('ENABLE_GEODE_EVENT', false), + geodeEventStartDate: str('GEODE_EVENT_START_DATE', '2020-01-01T00:00:00.000Z'), + bEnableCrackInTheSky: bool('ENABLE_CRACK_IN_THE_SKY', false), + bEnableS4OddityPrecursor: bool('ENABLE_S4_ODDITY_PRECURSOR', false), + bEnableS4OddityExecution: bool('ENABLE_S4_ODDITY_EXECUTION', false), + S4OddityEventStartDate: str('S4_ODDITY_EVENT_START_DATE', '2020-01-01T00:00:00.000Z'), + S4OddityEventsInterval: num('S4_ODDITY_EVENTS_INTERVAL', 0), + bEnableS5OddityPrecursor: bool('ENABLE_S5_ODDITY_PRECURSOR', false), + S5OddityPrecursorDate: str('S5_ODDITY_PRECURSOR_DATE', '2020-01-01T00:00:00.000Z'), + bEnableS5OddityExecution: bool('ENABLE_S5_ODDITY_EXECUTION', false), + S5OddityExecutionDate: str('S5_ODDITY_EXECUTION_DATE', '2020-01-01T00:00:00.000Z'), + bEnableCubeLightning: bool('ENABLE_CUBE_LIGHTNING', false), + cubeSpawnDate: str('CUBE_SPAWN_DATE', '2020-01-01T00:00:00.000Z'), + bEnableBlockbusterRiskyEvent: bool('ENABLE_BLOCKBUSTER_RISKY_EVENT', false), + bEnableCubeLake: bool('ENABLE_CUBE_LAKE', false), + cubeLakeDate: str('CUBE_LAKE_DATE', '2020-01-01T00:00:00.000Z'), +}; + +module.exports = config; \ No newline at end of file diff --git a/Config/config.json b/Config/config.json deleted file mode 100644 index 95cef10e..00000000 --- a/Config/config.json +++ /dev/null @@ -1,113 +0,0 @@ -{ - "moderators": ["discordId", "discordId2"], - "discord": { - "bUseDiscordBot": true, - "bot_token": "", - "bEnableInGamePlayerCount": true - }, - "mongodb": { - "database": "mongodb://127.0.0.1/Reload" - }, - "chat": { - "//": "Disabling global chat can help the server to perform faster as less resources are used.", - "EnableGlobalChat": false - }, - - "bEnableDebugLogs": false, - "bEnableFormattedLogs": false, - "bEnableRebootUser": true, - "bEnableCrossBans": false, - - "//": "If you want to use the backend on reboot, leave 3551 as the port", - "port": 3551, - - "Api": { - "bApiKey": "ur-api-key", - "reasons": { - "Kill": 25, - "Win": 50 - } - }, - - "Website": { - "bUseWebsite": false, - "clientId": "your-client-id-here", - "clientSecret": "your-client-secret-here", - "redirectUri": "http://127.0.0.1:${websiteport}/oauth2/callback", - "websiteport": 100 - }, - - "//": "to add more gameserver on 'gameServerIP' add ip:port:playlist", - "matchmakerIP": "127.0.0.1:80", - "gameServerIP": ["127.0.0.1:7777:playlist_defaultsolo"], - - "//": "For 'BattlePassSeason' enter only the number of your season (from 2 to 20)", - "bEnableBattlepass": false, - "bBattlePassSeason": 2, - - "//": "For 'bVersionJoinable' you can set a season that is also `9.10` and not just `9`", - "bEnableOnlyOneVersionJoinable": false, - "bVersionJoinable": 2, - - "//": "If 'bUseAutoRotate' is enabled it will automatically rotate the item shop using the time you put in 'bRotateTime', you can select the season limit with 'bSeasonLimit' (please only do up to season 10, it might be a bit broken after!), 'bRotateTime' means what time the shop rotates (it is UTC and uses the 24 hour clock, not 12 hour), for 'bItemShopWebhook' you have to generate a webhook to your item shop channel and put the link here, you can select how many cosmetics are in daily: 'bDailyItemsAmount' and featured: 'bFeaturedItemsAmount'", - "bUseAutoRotate": false, - "bEnableAutoRotateDebugLogs": false, - "bEnableDiscordWebhook": false, - "bChapterlimit": "1", - "bSeasonlimit": "10", - "bRotateTime": "00:00", - "bExcludedItems": ["CID_VIP_Athena_Commando_M_GalileoGondola_SG", "CID_636_Athena_Commando_M_GalileoGondola_78MFZ", "CID_637_Athena_Commando_M_GalileoOutrigger_7Q0YU", "CID_VIP_Athena_Commando_M_GalileoFerry_SG", "CID_VIP_Athena_Commando_F_GalileoRocket_SG", "CID_568_Athena_Commando_M_RebirthSoldier"], - "bItemShopWebhook": "", - "bDailyItemsAmount": 6, - "bFeaturedItemsAmount": 2, - - "//": "By enabling 'bEnableReports' in-game reports will work, a player will not be able to spam reports", - "bEnableReports": false, - "bReportChannelId": "your-discord-channel-id-here", - - "//": "If bCompletedSeasonalQuests is set to 'true' it will set all quests except daily quests as completed", - "bCompletedSeasonalQuests": false, - - "//": "If 'bEnableSACRewards' is enabled it will give the person who supports a creator a percentage of vbucks based on how much percentage you put in 'bPercentageSACRewards' it will give in vbucks, so if you set '25%' and there is a 1000 item in the shop vbucks will give 250 vbucks to the one who supports a creator", - "bEnableSACRewards": false, - "bPercentageSACRewards": 0, - - "//": "For 'bRestartTime' use this format: [number][y, M, w, d, h, m, s] so 5m, for Month u need to add the big M not the m", - "bEnableAutoBackendRestart": false, - "bRestartTime": "", - - "//": "If active it will send a message in the channel when the backend goes online", - "bEnableBackendStatus": false, - "bBackendStatusChannelId": "", - - "//": "Use HTTPS (For VPS Side Only, Or If You Were To Setup A Type Record To Your Own Public Adress From Your Domain) (You Also Need To Change The Examples In SSl Folder!)", - "bEnableHTTPS": false, "//": "Only Enable if You Have SSL Certificate In The ssl Folder", - "ssl": { - "cert": "./ssl/example_certificate.crt", - "//ca//": "./ssl/example_ca_bundle.crt", "//": "Optional (Only If You Have A CA Bundle from your ssl certificate)", - "key": "./ssl/example_private.key" - }, - - "//": "The Caldera Service is used for newer versions of the game! For see what season are now supported look CalderaService/guids.json and add the version on 'bGameVersion'", - "bEnableCalderaService": false, - "bGameVersion": "27.11", - "bCalderaServicePort": 5000, - - "//": "These are all the events you can add to the game, like the rift in the sky!", - "bEnableGeodeEvent": false, - "geodeEventStartDate": "2020-01-01T00:00:00.000Z", - "bEnableCrackInTheSky": false, - "bEnableS4OddityPrecursor": false, - "bEnableS4OddityExecution": false, - "S4OddityEventStartDate": "2020-01-01T00:00:00.000Z", - "S4OddityEventsInterval": 0, - "bEnableS5OddityPrecursor": false, - "S5OddityPrecursorDate": "2020-01-01T00:00:00.000Z", - "bEnableS5OddityExecution": false, - "S5OddityExecutionDate": "2020-01-01T00:00:00.000Z", - "bEnableCubeLightning": false, - "cubeSpawnDate": "2020-01-01T00:00:00.000Z", - "bEnableBlockbusterRiskyEvent": false, - "bEnableCubeLake": false, - "cubeLakeDate": "2020-01-01T00:00:00.000Z" -} \ No newline at end of file diff --git a/DiscordBot/commands/Admin/addall.js b/DiscordBot/commands/Admin/addall.js index d16b20f6..79eb4b14 100644 --- a/DiscordBot/commands/Admin/addall.js +++ b/DiscordBot/commands/Admin/addall.js @@ -5,7 +5,7 @@ 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') +const config = require('../../../Config/config.js') module.exports = { commandInfo: { diff --git a/DiscordBot/commands/Admin/additem.js b/DiscordBot/commands/Admin/additem.js index 23b79863..edc582a5 100644 --- a/DiscordBot/commands/Admin/additem.js +++ b/DiscordBot/commands/Admin/additem.js @@ -3,10 +3,10 @@ const Profiles = require('../../../model/profiles.js'); const fs = require('fs'); const path = require('path'); const destr = require('destr'); -const config = require('../../../Config/config.json'); +const config = require('../../../Config/config.js'); const uuid = require("uuid"); const log = require("../../../structs/log.js"); -const { MessageEmbed } = require('discord.js'); +const { EmbedBuilder, Colors } = require('discord.js'); module.exports = { commandInfo: { @@ -144,11 +144,11 @@ module.exports = { } ); - const embed = new MessageEmbed() + const embed = new EmbedBuilder() .setTitle("Cosmetic Gift Sent") .setDescription(`Successfully gave the user the cosmetic **${cosmeticname}** with a GiftBox`) .setThumbnail(cosmeticimage) - .setColor("GREEN") + .setColor(Colors.Green) .setFooter({ text: "Reload Backend", iconURL: "https://i.imgur.com/2RImwlb.png" @@ -168,4 +168,4 @@ module.exports = { await interaction.editReply({ content: "An unexpected error occurred", ephemeral: true }); } } -}; +}; \ No newline at end of file diff --git a/DiscordBot/commands/Admin/addvbucks.js b/DiscordBot/commands/Admin/addvbucks.js index d7f03932..4780ba1a 100644 --- a/DiscordBot/commands/Admin/addvbucks.js +++ b/DiscordBot/commands/Admin/addvbucks.js @@ -1,8 +1,8 @@ const Users = require('../../../model/user'); const Profiles = require('../../../model/profiles'); -const config = require('../../../Config/config.json'); +const config = require('../../../Config/config.js'); const uuid = require("uuid"); -const { MessageEmbed } = require("discord.js"); +const { EmbedBuilder, Colors } = require("discord.js"); module.exports = { commandInfo: { @@ -117,11 +117,11 @@ module.exports = { } }); - const embed = new MessageEmbed() + const embed = new EmbedBuilder() .setTitle("V-Bucks Updated") .setDescription(`Successfully added **${vbucks}** V-Bucks to <@${selectedUserId}> with a GiftBox`) .setThumbnail("https://i.imgur.com/yLbihQa.png") - .setColor("GREEN") + .setColor(Colors.Green) .setFooter({ text: "Reload Backend", iconURL: "https://i.imgur.com/2RImwlb.png" diff --git a/DiscordBot/commands/Admin/ban.js b/DiscordBot/commands/Admin/ban.js index 3f4243d4..157ca6da 100644 --- a/DiscordBot/commands/Admin/ban.js +++ b/DiscordBot/commands/Admin/ban.js @@ -1,7 +1,6 @@ const User = require("../../../model/user.js"); const functions = require("../../../structs/functions.js"); -const fs = require("fs"); -const config = JSON.parse(fs.readFileSync("./Config/config.json").toString()); +const config = require('../../../Config/config.js'); module.exports = { commandInfo: { diff --git a/DiscordBot/commands/Admin/createcustommatchcode.js b/DiscordBot/commands/Admin/createcustommatchcode.js index c5d089e0..65c85aa8 100644 --- a/DiscordBot/commands/Admin/createcustommatchcode.js +++ b/DiscordBot/commands/Admin/createcustommatchcode.js @@ -1,7 +1,7 @@ const MMCodes = require("../../../model/mmcodes.js"); const { MessageEmbed } = require("discord.js"); const log = require("../../../structs/log.js"); -const config = require('../../../Config/config.json') +const config = require('../../../Config/config.js') module.exports = { commandInfo: { diff --git a/DiscordBot/commands/Admin/createhostaccount.js b/DiscordBot/commands/Admin/createhostaccount.js index 049429ea..248f592a 100644 --- a/DiscordBot/commands/Admin/createhostaccount.js +++ b/DiscordBot/commands/Admin/createhostaccount.js @@ -1,4 +1,4 @@ -const { MessageEmbed } = require("discord.js"); +const { EmbedBuilder } = require("discord.js"); const functions = require("../../../structs/functions.js"); const User = require("../../../model/user.js"); const log = require("../../../structs/log.js"); @@ -35,7 +35,7 @@ module.exports = { try { await functions.registerUser(null, username, email, password).then(async (resp) => { - let embed = new MessageEmbed() + let embed = new EmbedBuilder() .setColor(resp.status >= 400 ? "#ff0000" : "#56ff00") .addFields( { name: "Message", value: resp.message }, diff --git a/DiscordBot/commands/Admin/createsac.js b/DiscordBot/commands/Admin/createsac.js index 93179adf..8185e5e7 100644 --- a/DiscordBot/commands/Admin/createsac.js +++ b/DiscordBot/commands/Admin/createsac.js @@ -1,5 +1,5 @@ const functions = require("../../../structs/functions.js"); -const config = require("../../../Config/config.json"); +const config = require("../../../Config/config.js"); module.exports = { commandInfo: { diff --git a/DiscordBot/commands/Admin/custommatchcodelist.js b/DiscordBot/commands/Admin/custommatchcodelist.js index 331116a2..ab689941 100644 --- a/DiscordBot/commands/Admin/custommatchcodelist.js +++ b/DiscordBot/commands/Admin/custommatchcodelist.js @@ -1,7 +1,7 @@ const MMCodes = require("../../../model/mmcodes.js"); const { MessageEmbed } = require("discord.js"); const log = require("../../../structs/log.js"); -const config = require('../../../Config/config.json') +const config = require('../../../Config/config.js') module.exports = { commandInfo: { diff --git a/DiscordBot/commands/Admin/delete.js b/DiscordBot/commands/Admin/delete.js index 3783fb32..b4bfbf78 100644 --- a/DiscordBot/commands/Admin/delete.js +++ b/DiscordBot/commands/Admin/delete.js @@ -1,4 +1,4 @@ -const { MessageEmbed } = require("discord.js"); +const { EmbedBuilder, Colors } = require("discord.js"); const fs = require("fs"); const path = require("path"); const Users = require('../../../model/user.js'); @@ -6,7 +6,7 @@ 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'); +const config = require('../../../Config/config.js'); module.exports = { commandInfo: { @@ -74,10 +74,10 @@ module.exports = { return; } - const embed = new MessageEmbed() + const embed = new EmbedBuilder() .setTitle("Account deleted") .setDescription(`The account for **${username}** has been **deleted**`) - .setColor("GREEN") + .setColor(Colors.Green) .setFooter({ text: "Reload Backend", iconURL: "https://i.imgur.com/2RImwlb.png" diff --git a/DiscordBot/commands/Admin/deletediscord.js b/DiscordBot/commands/Admin/deletediscord.js index 4d59cf4f..3b126d4f 100644 --- a/DiscordBot/commands/Admin/deletediscord.js +++ b/DiscordBot/commands/Admin/deletediscord.js @@ -1,4 +1,4 @@ -const { MessageEmbed } = require("discord.js"); +const { EmbedBuilder, Colors } = require("discord.js"); const fs = require("fs"); const path = require("path"); const Users = require('../../../model/user.js'); @@ -6,7 +6,7 @@ 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'); +const config = require('../../../Config/config.js'); module.exports = { commandInfo: { @@ -75,10 +75,10 @@ module.exports = { return; } - const embed = new MessageEmbed() + const embed = new EmbedBuilder() .setTitle("Account deleted") .setDescription("The account has been **deleted**") - .setColor("GREEN") + .setColor(Colors.Green) .setFooter({ text: "Reload Backend", iconURL: "https://i.imgur.com/2RImwlb.png" diff --git a/DiscordBot/commands/Admin/deletesac.js b/DiscordBot/commands/Admin/deletesac.js index 2591bd92..bb8bbe4e 100644 --- a/DiscordBot/commands/Admin/deletesac.js +++ b/DiscordBot/commands/Admin/deletesac.js @@ -1,4 +1,4 @@ -const config = require("../../../Config/config.json"); +const config = require("../../../Config/config.js"); const SACCodes = require("../../../model/saccodes.js"); module.exports = { diff --git a/DiscordBot/commands/Admin/kick.js b/DiscordBot/commands/Admin/kick.js index 45da5f6f..f4a0aa69 100644 --- a/DiscordBot/commands/Admin/kick.js +++ b/DiscordBot/commands/Admin/kick.js @@ -1,7 +1,6 @@ const User = require("../../../model/user.js"); const functions = require("../../../structs/functions.js"); -const fs = require("fs"); -const config = JSON.parse(fs.readFileSync("./Config/config.json").toString()); +const config = require('../../../Config/config.js'); module.exports = { commandInfo: { diff --git a/DiscordBot/commands/Admin/removeall.js b/DiscordBot/commands/Admin/removeall.js index 78f61f5a..c74736e8 100644 --- a/DiscordBot/commands/Admin/removeall.js +++ b/DiscordBot/commands/Admin/removeall.js @@ -5,7 +5,7 @@ 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') +const config = require('../../../Config/config.js') module.exports = { commandInfo: { diff --git a/DiscordBot/commands/Admin/removeitem.js b/DiscordBot/commands/Admin/removeitem.js index d041c5dd..1cd8a7b5 100644 --- a/DiscordBot/commands/Admin/removeitem.js +++ b/DiscordBot/commands/Admin/removeitem.js @@ -1,11 +1,11 @@ -const { MessageEmbed } = require("discord.js"); +const { EmbedBuilder, Colors } = require("discord.js"); const Users = require('../../../model/user.js'); 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'); +const config = require('../../../Config/config.js'); module.exports = { commandInfo: { @@ -98,11 +98,11 @@ module.exports = { return interaction.editReply({ content: "An error occurred while removing the cosmetic" }); }); - const embed = new MessageEmbed() + const embed = new EmbedBuilder() .setTitle("Cosmetic Removed") .setDescription(`Successfully removed for ${selectedUser} the cosmetic **` + cosmeticname + `**`) .setThumbnail(cosmeticimage) - .setColor("GREEN") + .setColor(Colors.Green) .setFooter({ text: "Reload Backend", iconURL: "https://i.imgur.com/2RImwlb.png" diff --git a/DiscordBot/commands/Admin/removevbucks.js b/DiscordBot/commands/Admin/removevbucks.js index b9e6b540..aaedccf2 100644 --- a/DiscordBot/commands/Admin/removevbucks.js +++ b/DiscordBot/commands/Admin/removevbucks.js @@ -1,7 +1,7 @@ const Users = require('../../../model/user'); const Profiles = require('../../../model/profiles'); -const config = require('../../../Config/config.json'); -const { MessageEmbed } = require('discord.js'); +const config = require('../../../Config/config.js'); +const { EmbedBuilder, Colors } = require('discord.js'); module.exports = { commandInfo: { @@ -76,11 +76,11 @@ module.exports = { }); } - const embed = new MessageEmbed() + const embed = new EmbedBuilder() .setTitle("V-Bucks Updated") .setDescription(`Successfully removed **${vbucks}** V-Bucks from <@${selectedUserId}>`) .setThumbnail("https://i.imgur.com/yLbihQa.png") - .setColor("GREEN") + .setColor(Colors.Green) .setFooter({ text: "Reload Backend", iconURL: "https://i.imgur.com/2RImwlb.png" diff --git a/DiscordBot/commands/Admin/unban.js b/DiscordBot/commands/Admin/unban.js index 9507569d..36ddfe19 100644 --- a/DiscordBot/commands/Admin/unban.js +++ b/DiscordBot/commands/Admin/unban.js @@ -1,6 +1,5 @@ const User = require("../../../model/user.js"); -const fs = require("fs"); -const config = JSON.parse(fs.readFileSync("./Config/config.json").toString()); +const config = require('../../../Config/config.js'); module.exports = { commandInfo: { diff --git a/DiscordBot/commands/User/change-password.js b/DiscordBot/commands/User/change-password.js index e95b0a37..7821d3dd 100644 --- a/DiscordBot/commands/User/change-password.js +++ b/DiscordBot/commands/User/change-password.js @@ -1,7 +1,7 @@ -const { MessageEmbed } = require("discord.js"); +const MessageEmbed = require("discord.js"); const User = require("../../../model/user.js"); -const bcrypt = require("bcrypt"); const functions = require("../../../structs/functions.js"); +const bcrypt = require("bcryptjs"); module.exports = { commandInfo: { diff --git a/DiscordBot/index.js b/DiscordBot/index.js index 881b3094..f416a0ea 100644 --- a/DiscordBot/index.js +++ b/DiscordBot/index.js @@ -1,17 +1,17 @@ -const { Client, Intents, MessageEmbed } = require("discord.js"); -const client = new Client({ intents: [Intents.FLAGS.GUILDS, Intents.FLAGS.GUILD_MESSAGES, Intents.FLAGS.GUILD_MEMBERS, Intents.FLAGS.GUILD_BANS] }); +const { Client, GatewayIntentBits, Partials, MessageEmbed } = require("discord.js"); +const client = new Client({ intents: [GatewayIntentBits.Guilds, GatewayIntentBits.GuildMessages, GatewayIntentBits.GuildMembers, GatewayIntentBits.GuildBans] }); const fs = require("fs"); const path = require("path"); -const config = JSON.parse(fs.readFileSync("./Config/config.json").toString()); +const config = require('../Config/config.js'); const log = require("../structs/log.js"); const Users = require("../model/user.js"); -client.once("ready", () => { +client.once("clientReady", () => { log.bot("Bot is up and running!"); if (config.bEnableBackendStatus) { if (!config.bBackendStatusChannelId || config.bBackendStatusChannelId.trim() === "") { - log.error("The channel ID has not been set in config.json for bEnableBackendStatus."); + log.error("BACKEND_STATUS_CHANNEL_ID has not been set in .env for ENABLE_BACKEND_STATUS."); } else { const channel = client.channels.cache.get(config.bBackendStatusChannelId); if (!channel) { diff --git a/README.md b/README.md index bc01a237..d3e67933 100644 --- a/README.md +++ b/README.md @@ -95,22 +95,23 @@ Created by [Burlone](https://github.com/burlone0), This is a modded backend, all - `/removeitem {user} {cosmeticname}` - Allows you to remove a cosmetic (skin, pickaxe, glider, etc.) from a user - `/unban {targetUsername}` - Unban a user from the backend by their username. ### How to set up moderators? -1) Go to **Config/config.json** in the directory you extracted Reload Backend into. -2) Open it, you should see a **"moderators"** section in the file. -3) You have to get your discord id and replace discordId with it. -4) You can set multiple moderators like this `["discordId","discordId2"]`. +1) Go to **.env** in the directory you extracted Reload Backend into. +2) Open it, you should see a **MODERATORS** line in the file. +3) You have to get your discord id and replace `discordId` with it. +4) You can set multiple moderators like this `MODERATORS=discordId,discordId2`. + ### How to setup multiple gameservers -1) Go to **Config/config.json** in the directory you extracted Reload Backend into. -2) Open it, you should see a **"gameServerIP"** section in the file. -3) To add more gameservers you will have to do it like this `"gameServerIP": ["127.0.0.1:7777:playlist_defaultsolo", "127.0.0.1:7777:playlist_defaultduo"],` -4) You have now added solos and duos to your matchmaking +1) Go to **.env** in the directory you extracted Reload Backend into. +2) Open it, you should see a **GAME_SERVER_IP** line in the file. +3) To add more gameservers you will have to do it like this `GAME_SERVER_IP=127.0.0.1:7777:playlist_defaultsolo,127.0.0.1:7777:playlist_defaultduo` +4) You have now added solos and duos to your matchmaking ## How to start Reload Backend 1) Install [NodeJS](https://nodejs.org/en/) and [MongoDB](https://www.mongodb.com/try/download/community). 2) **Download** and **Extract** Reload Backend to a safe location. 3) Run **"install_packages.bat"** to install all the required modules. -4) Go to **Config/config.json** in the directory you extracted Reload Backend into. -5) Open it, set your discord bot token **(DO NOT SHARE THIS TOKEN)** and **save it**. The discord bot will be used for creating accounts and managing your account (You can disable the discord bot by entering "bUseDiscordBot" to false in "Config/config.json"). +4) Copy **.env.example** to **.env** in the directory you extracted Reload Backend into. +5) Open it, set your discord bot token **(DO NOT SHARE THIS TOKEN)** in `DISCORD_BOT_TOKEN` and **save it**. The discord bot will be used for creating accounts and managing your account (You can disable the discord bot by setting `DISCORD_USE_BOT=false` in `.env`). 6) Run **"start.bat"**, if there is no errors, it should work. 7) Use something to redirect the Fortnite servers to **localhost:8080** (Which could be fiddler, ssl bypass that redirects servers, etc...) 8) When Fortnite launches and is connected to the backend, enter your email and password (or launch with an exchange code) then press login. It should let you in and everything should be working fine. diff --git a/Website/website.js b/Website/website.js index e2f38e3a..5b29b070 100644 --- a/Website/website.js +++ b/Website/website.js @@ -1,7 +1,7 @@ module.exports = function(websiteApp) { const express = require("express"); const path = require("path"); - const config = require("../Config/config.json"); + const config = require("../Config/config.js"); const DISCORD_API_URL = 'https://discord.com/api'; const CLIENT_ID = config.Website.clientId; diff --git a/index.js b/index.js index 5e6f7135..f35d1d8e 100644 --- a/index.js +++ b/index.js @@ -5,7 +5,7 @@ const rateLimit = require("express-rate-limit"); const jwt = require("jsonwebtoken"); const path = require("path"); const kv = require("./structs/kv.js"); -const config = JSON.parse(fs.readFileSync("./Config/config.json").toString()); +const config = require('./Config/config.js'); const WebSocket = require('ws'); const https = require("https"); @@ -104,7 +104,8 @@ fs.readdirSync("./routes").forEach(fileName => { try { app.use(require(`./routes/${fileName}`)); } catch (err) { - log.error(`Routes Error: Failed to load ${fileName}`) + log.error(`Routes Error: Failed to load ${fileName} - ${err.message}`); + log.error(err.stack); } }); @@ -112,7 +113,8 @@ fs.readdirSync("./Api").forEach(fileName => { try { app.use(require(`./Api/${fileName}`)); } catch (err) { - log.error(`Reload API Error: Failed to load ${fileName}`) + log.error(`Reload API Error: Failed to load ${fileName} - ${err.message}`); + log.error(err.stack); } }); diff --git a/package.json b/package.json index 864edefd..5e5b16c3 100644 --- a/package.json +++ b/package.json @@ -6,9 +6,9 @@ "dependencies": { "axios": "^1.7.7", "bad-words": "^3.0.4", - "bcrypt": "^5.1.0", + "bcryptjs": "^3.0.3", "destr": "^2.0.3", - "discord.js": "^13.7.0", + "discord.js": "^14.27.0", "dotenv": "^16.0.3", "express": "^4.21.1", "express-rate-limit": "^6.7.0", @@ -16,15 +16,18 @@ "jsonwebtoken": "^8.5.1", "keyv": "^4.2.2", "mongoose": "^6.6.5", + "node-fetch": "^3.3.2", "path": "^0.12.7", + "qs": "^6.15.3", "sjcl": "^1.0.8", - "uuid": "^9.0.0", + "uuid": "^11.1.1", "ws": "^8.9.0", "xml-parser": "^1.2.1", "xmlbuilder": "^15.1.1" }, "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" + "test": "echo \"Error: no test specified\" && exit 1", + "start": "node index.js" }, "repository": { "type": "git", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml new file mode 100644 index 00000000..f131097c --- /dev/null +++ b/pnpm-lock.yaml @@ -0,0 +1,1731 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + dependencies: + axios: + specifier: ^1.7.7 + version: 1.18.1 + bad-words: + specifier: ^3.0.4 + version: 3.0.4 + bcryptjs: + specifier: ^3.0.3 + version: 3.0.3 + destr: + specifier: ^2.0.3 + version: 2.0.5 + discord.js: + specifier: ^14.27.0 + version: 14.27.0 + dotenv: + specifier: ^16.0.3 + version: 16.6.1 + express: + specifier: ^4.21.1 + version: 4.22.2 + express-rate-limit: + specifier: ^6.7.0 + version: 6.11.2(express@4.22.2) + ioredis: + specifier: ^5.4.1 + version: 5.11.1 + jsonwebtoken: + specifier: ^8.5.1 + version: 8.5.1 + keyv: + specifier: ^4.2.2 + version: 4.5.4 + mongoose: + specifier: ^6.6.5 + version: 6.13.10 + node-fetch: + specifier: ^3.3.2 + version: 3.3.2 + path: + specifier: ^0.12.7 + version: 0.12.7 + qs: + specifier: ^6.15.3 + version: 6.15.3 + sjcl: + specifier: ^1.0.8 + version: 1.0.9 + uuid: + specifier: ^11.1.1 + version: 11.1.1 + ws: + specifier: ^8.9.0 + version: 8.21.1 + xml-parser: + specifier: ^1.2.1 + version: 1.2.1 + xmlbuilder: + specifier: ^15.1.1 + version: 15.1.1 + +packages: + + '@aws-sdk/core@3.976.0': + resolution: {integrity: sha512-0cjRaEdlVoOrsNb9pP5q1Syyc8pXw5xSj2Np2ryReRTr9FppIIRVSdZK4lbnfmc2Hvgux/xBOUU6baB7z8//uA==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/credential-provider-cognito-identity@3.972.59': + resolution: {integrity: sha512-iWPfye2ZOCmAHKmN1EwAyeHZdZxZymctAnEOD+7jzwqc5gZlK1lwG1lzGVtpH0+d/NnyrK670ycqBNKD4zUGZA==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/credential-provider-env@3.972.60': + resolution: {integrity: sha512-BAkxdoe7tpDDqCghGpuOeHQRbm/2znVvOQm0AvpQbA2tbfMN46doN4zx65fv85ImP3KADwc2zQPmbrlI9MPfMg==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/credential-provider-http@3.972.62': + resolution: {integrity: sha512-g/0fGqKTb9xpKdd9AtpmV5Eo3DFKbnkpA2+w0peISSlu7NfAoWOuYBFxsu+yWBtxU89ka55ezoZBCbFaS8pjYQ==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/credential-provider-ini@3.973.5': + resolution: {integrity: sha512-ylubazcRfq2TVus/qXucSXeC42Qdjp5HQxTu68K/BsdMiZlcSLD1zkpoCgApXZX1Y6YJhtGGs7ZHhO/GuIgBlw==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/credential-provider-login@3.972.67': + resolution: {integrity: sha512-CCygIKJ9YbI3n84OClSaSppkgKKHVj2TGT33c6FRORZrYNZQ1POmD+ip0FLYokiJAK7sSdc3YVkOsBm90oxWMQ==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/credential-provider-node@3.972.71': + resolution: {integrity: sha512-HIg7Q2osBzajQwL+1Vkyh2E7Gim3eTNb9RHIsOxDGjW0eZg4oEKtRs5sioCnc73ilhaOm4gX2lHVF8J7+nt2rg==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/credential-provider-process@3.972.60': + resolution: {integrity: sha512-YIo3f99hM43QdYG8hDzwGemnR/pU95b0kramqSJUTleCqaB7+HwKf7YZFHqvOgTqZTPx/mRmNIqoDRr3U0Z3Tw==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/credential-provider-sso@3.973.4': + resolution: {integrity: sha512-BPdmL8sSBOCv4ngZ+3LHxyc3CNqDCEK37CHioCk7zGrTMY5sUtkH8q+o6qA80nn6w3/fyBPGNE7OIRlmoOxRQA==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/credential-provider-web-identity@3.972.66': + resolution: {integrity: sha512-kSAziJboOmZmsR9/MTbiNjowl2BPes1bQuJpne4qAZ62ubi8fjfr/aupJSQje6udBoYxXTQbsL0e0kby2la3ng==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/credential-providers@3.1094.0': + resolution: {integrity: sha512-FRqTIDsiKFl2GRv9gwjcmWbak5VVuuU6ZiZK1hjLje2PemTnSt/EQuXyG6TgqvYyaDNERRfosj5Kqdb2qjCyOw==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/nested-clients@3.997.34': + resolution: {integrity: sha512-Y9REVrSwmLM+Qy6sZJ7ofMC2S3Hr3tPP/4CzL5U1olPP7OGoF+6+Px0E49cVQBtSxJtyeLJMf0UaBErfeSahAA==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/signature-v4-multi-region@3.996.41': + resolution: {integrity: sha512-QMUytg+FQMGouc8gHS00KoYih3+N6cqmVI/pQGOIo7Nr7OpQaiXjSYOuL+vsPZ1tymY4LAQ8MYcHJmws5LRxng==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/token-providers@3.1092.0': + resolution: {integrity: sha512-hBYUAr6iBLNFcsiWTgtBb0stdSw39VOUq4Sp4A5caCNf66BAZplWN4FleKrVpJx5li2YgdnK2DqoFSMWC642FQ==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/types@3.974.2': + resolution: {integrity: sha512-3W6IUtSxFbH6X7Wb7DzGCV5QiFQsd0g8bOfntpmDxQlzBoKWUMBu/JPQR0DwkE+Hpnxd6db1tXbOwdeHddG6cA==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/xml-builder@3.972.36': + resolution: {integrity: sha512-RdGmS1GLrtaTOLE1ElSluMldNrpk9Emq6uYs8SS8iHlu5xTAmM9rRkM91o48+rIRryBtyO9t+uLYCoMG6jVMVA==} + engines: {node: '>=20.0.0'} + + '@aws/lambda-invoke-store@0.3.0': + resolution: {integrity: sha512-sl4Bm6yiMNYrZKkqqDFWN0UfnWhlS8ivKxrYl+6t0gCLrqr8y3B2IqZZbFRkfaVVp7C/baApyh71P+LeE1A2sQ==} + engines: {node: '>=18.0.0'} + + '@discordjs/builders@1.14.1': + resolution: {integrity: sha512-gSKkhXLqs96TCzk66VZuHHl8z2bQMJFGwrXC0f33ngK+FLNau4hU1PYny3DNJfNdSH+gVMzE85/d5FQ2BpcNwQ==} + engines: {node: '>=16.11.0'} + + '@discordjs/collection@1.5.3': + resolution: {integrity: sha512-SVb428OMd3WO1paV3rm6tSjM4wC+Kecaa1EUGX7vc6/fddvw/6lg90z4QtCqm21zvVe92vMMDt9+DkIvjXImQQ==} + engines: {node: '>=16.11.0'} + + '@discordjs/collection@2.1.1': + resolution: {integrity: sha512-LiSusze9Tc7qF03sLCujF5iZp7K+vRNEDBZ86FT9aQAv3vxMLihUvKvpsCWiQ2DJq1tVckopKm1rxomgNUc9hg==} + engines: {node: '>=18'} + + '@discordjs/formatters@0.6.2': + resolution: {integrity: sha512-y4UPwWhH6vChKRkGdMB4odasUbHOUwy7KL+OVwF86PvT6QVOwElx+TiI1/6kcmcEe+g5YRXJFiXSXUdabqZOvQ==} + engines: {node: '>=16.11.0'} + + '@discordjs/rest@2.6.3': + resolution: {integrity: sha512-wvOylxNYJkwKjctS/Mn5GP1w9r3/rzyH+ThD1JlAca6zEdlHs8QWBBUQJpU5Q+W6DoIj/Ljh1IPlZs7hTU+UAg==} + engines: {node: '>=18'} + + '@discordjs/util@1.2.0': + resolution: {integrity: sha512-3LKP7F2+atl9vJFhaBjn4nOaSWahZ/yWjOvA4e5pnXkt2qyXRCHLxoBQy81GFtLGCq7K9lPm9R517M1U+/90Qg==} + engines: {node: '>=18'} + + '@discordjs/ws@1.2.3': + resolution: {integrity: sha512-wPlQDxEmlDg5IxhJPuxXr3Vy9AjYq5xCvFWGJyD7w7Np8ZGu+Mc+97LCoEc/+AYCo2IDpKioiH0/c/mj5ZR9Uw==} + engines: {node: '>=16.11.0'} + + '@ioredis/commands@1.10.0': + resolution: {integrity: sha512-UmeW7z4LfctwoQ5wkhVzgq8tXkreED2xZGpX+Bg+zA+WJFZCT6c062AfCK/Dfk81xZnnwdhJCUMkitihRaoC2Q==} + + '@mongodb-js/saslprep@1.4.12': + resolution: {integrity: sha512-QAfAMwNgnYxZ2C6D1HgeP7Gc4i/uvJRim415PCIL9ptRxWMNbWeLBYb2/9R4pGKny/s1FVu2JA2cxCUBUOggrA==} + + '@sapphire/async-queue@1.5.5': + resolution: {integrity: sha512-cvGzxbba6sav2zZkH8GPf2oGk9yYoD5qrNWdu9fRehifgnFZJMV+nuy2nON2roRO4yQQ+v7MK/Pktl/HgfsUXg==} + engines: {node: '>=v14.0.0', npm: '>=7.0.0'} + + '@sapphire/shapeshift@4.0.0': + resolution: {integrity: sha512-d9dUmWVA7MMiKobL3VpLF8P2aeanRTu6ypG2OIaEv/ZHH/SUQ2iHOVyi5wAPjQ+HmnMuL0whK9ez8I/raWbtIg==} + engines: {node: '>=v16'} + + '@sapphire/snowflake@3.5.5': + resolution: {integrity: sha512-xzvBr1Q1c4lCe7i6sRnrofxeO1QTP/LKQ6A6qy0iB4x5yfiSfARMEQEghojzTNALDTcv8En04qYNIco9/K9eZQ==} + engines: {node: '>=v14.0.0', npm: '>=7.0.0'} + + '@smithy/core@3.29.8': + resolution: {integrity: sha512-rpCbCV+TimOBi3VLNBMmtTvgfOWcFIEAru3+TFlG87SL2F+te4jOnnNR+cf3uR4eJ5Qf4LnT80fqnBKgPRS6zA==} + engines: {node: '>=18.0.0'} + + '@smithy/credential-provider-imds@4.4.13': + resolution: {integrity: sha512-X+2HNZhWi5i3rJsCas0LPf6fTQUaKyJ40zd8aTO/bwpRfpU3biYaqLr7C1WMibL7PVKJalpi1PyybjGPNoHC8Q==} + engines: {node: '>=18.0.0'} + + '@smithy/fetch-http-handler@5.6.10': + resolution: {integrity: sha512-5/Yj9mS2JjTsB3B8ZX7euh77mrY9aXW23ag1yAmFykSRmA6vldqBrgqmSeQ50EjY+5SB8+aE4w14B6LKbBVEhQ==} + engines: {node: '>=18.0.0'} + + '@smithy/node-http-handler@4.9.10': + resolution: {integrity: sha512-ETQz9v/Z+nTQc6fRWTXxUpxJqwpmzB3Tn3WKAdHwWkeT+m+HE5czs6GNG8vW+4vyxXSls65RVcvOZwk7Q/PS/Q==} + engines: {node: '>=18.0.0'} + + '@smithy/signature-v4@5.6.9': + resolution: {integrity: sha512-g5rnEii/mkT0mjVJmlsaOfyNBtHNTecD9Lo4NP8D5HzMUEnZNpz7/FbvBCjNcV4vteHFAxOGiLUYNxPkDZZAPw==} + engines: {node: '>=18.0.0'} + + '@smithy/types@4.16.1': + resolution: {integrity: sha512-0JFs3V2y2M9tKW5na/qxe69Zv+uxLMO7QBbhxF/FHu/Gp2NFZAAL9tWl9PU02xxo07pb3G9FTyjNc6D5uZrJIg==} + engines: {node: '>=18.0.0'} + + '@types/node@26.1.1': + resolution: {integrity: sha512-nxAkRSVkN1Y0JC1W8ky/fTfkGsMmcrRsbx+3XoZE+rMOX71kLYTV7fLXpqud1GpbpP5TuffXFqfX7fH2GgZREw==} + + '@types/webidl-conversions@7.0.3': + resolution: {integrity: sha512-CiJJvcRtIgzadHCYXw7dqEnMNRjhGZlYK05Mj9OyktqV8uVT8fD2BFOB7S1uwBE3Kj2Z+4UyPmFw/Ixgw/LAlA==} + + '@types/whatwg-url@8.2.2': + resolution: {integrity: sha512-FtQu10RWgn3D9U4aazdwIE2yzphmTJREDqNdODHrbrZmmMqI0vMheC/6NE/J1Yveaj8H+ela+YwWTjq5PGmuhA==} + + '@types/ws@8.18.1': + resolution: {integrity: sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==} + + '@vladfrangu/async_event_emitter@2.4.7': + resolution: {integrity: sha512-Xfe6rpCTxSxfbswi/W/Pz7zp1WWSNn4A0eW4mLkQUewCrXXtMj31lCg+iQyTkh/CkusZSq9eDflu7tjEDXUY6g==} + engines: {node: '>=v14.0.0', npm: '>=7.0.0'} + + accepts@1.3.8: + resolution: {integrity: sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==} + engines: {node: '>= 0.6'} + + agent-base@6.0.2: + resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==} + engines: {node: '>= 6.0.0'} + + array-flatten@1.1.1: + resolution: {integrity: sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==} + + asynckit@0.4.0: + resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + + axios@1.18.1: + resolution: {integrity: sha512-3nTvFlvpn9Zu/RkHUqtc7/+al4UpRW5az71ap5zccp6e8RAYEzhMTecX8Dz1wWDYrPpUoB1HAQEGEAEvUr7S9g==} + + bad-words@3.0.4: + resolution: {integrity: sha512-v/Q9uRPH4+yzDVLL4vR1+S9KoFgOEUl5s4axd6NIAq8SV2mradgi4E8lma/Y0cw1ltVdvyegCQQKffCPRCp8fg==} + engines: {node: '>=8.0.0'} + + badwords-list@1.0.0: + resolution: {integrity: sha512-oWhaSG67e+HQj3OGHQt2ucP+vAPm1wTbdp2aDHeuh4xlGXBdWwzZ//pfu6swf5gZ8iX0b7JgmSo8BhgybbqszA==} + + base64-js@1.5.1: + resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} + + bcryptjs@3.0.3: + resolution: {integrity: sha512-GlF5wPWnSa/X5LKM1o0wz0suXIINz1iHRLvTS+sLyi7XPbe5ycmYI3DlZqVGZZtDgl4DmasFg7gOB3JYbphV5g==} + hasBin: true + + body-parser@1.20.6: + resolution: {integrity: sha512-p5tAzS57i5MV9fZFDj9LeIiTZEufbSe2eDozP+ElheSUq1m74CRq1jI4mYNDdVs9vQztXFLuk/Gd6BWTdwRJ5g==} + engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} + + bowser@2.14.1: + resolution: {integrity: sha512-tzPjzCxygAKWFOJP011oxFHs57HzIhOEracIgAePE4pqB3LikALKnSzUyU4MGs9/iCEUuHlAJTjTc5M+u7YEGg==} + + bson@4.7.2: + resolution: {integrity: sha512-Ry9wCtIZ5kGqkJoi6aD8KjxFZEx78guTQDnpXWiNthsxzrxAK/i8E6pCHAIZTbaEFWcOCvbecMukfK7XUvyLpQ==} + engines: {node: '>=6.9.0'} + + buffer-equal-constant-time@1.0.1: + resolution: {integrity: sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==} + + buffer@5.7.1: + resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==} + + bytes@3.1.2: + resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} + engines: {node: '>= 0.8'} + + call-bind-apply-helpers@1.0.2: + resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} + engines: {node: '>= 0.4'} + + call-bound@1.0.4: + resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==} + engines: {node: '>= 0.4'} + + cluster-key-slot@1.1.1: + resolution: {integrity: sha512-rwHwUfXL40Chm1r08yrhU3qpUvdVlgkKNeyeGPOxnW8/SyVDvgRaed/Uz54AqWNaTCAThlj6QAs3TZcKI0xDEw==} + engines: {node: '>=0.10.0'} + + combined-stream@1.0.8: + resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} + engines: {node: '>= 0.8'} + + content-disposition@0.5.4: + resolution: {integrity: sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==} + engines: {node: '>= 0.6'} + + content-type@1.0.5: + resolution: {integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==} + engines: {node: '>= 0.6'} + + cookie-signature@1.0.7: + resolution: {integrity: sha512-NXdYc3dLr47pBkpUCHtKSwIOQXLVn8dZEuywboCOJY/osA0wFSLlSawr3KN8qXJEyX66FcONTH8EIlVuK0yyFA==} + + cookie@0.7.2: + resolution: {integrity: sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==} + engines: {node: '>= 0.6'} + + data-uri-to-buffer@4.0.1: + resolution: {integrity: sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==} + engines: {node: '>= 12'} + + debug@2.6.9: + resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + debug@4.4.3: + resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + delayed-stream@1.0.0: + resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} + engines: {node: '>=0.4.0'} + + denque@2.1.0: + resolution: {integrity: sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==} + engines: {node: '>=0.10'} + + depd@2.0.0: + resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} + engines: {node: '>= 0.8'} + + destr@2.0.5: + resolution: {integrity: sha512-ugFTXCtDZunbzasqBxrK93Ik/DRYsO6S/fedkWEMKqt04xZ4csmnmwGDBAb07QWNaGMAmnTIemsYZCksjATwsA==} + + destroy@1.2.0: + resolution: {integrity: sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==} + engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} + + discord-api-types@0.38.50: + resolution: {integrity: sha512-J2n/bpIETX3DQ6AJ7/0xbsTLmYiJQtO/LKcXKC1YDbB56OUwtDbdXOFE8Q4g8jVGHBR2VAy1+D4ngaIgkMNV9w==} + + discord.js@14.27.0: + resolution: {integrity: sha512-qHbFlFG2N7y3LjPySYsL6A1+BnX6bkTVgo842EX0CqVPk/KTMwZkojPHEXKsQUpWZNyz5BISNHK1cPpQw0+m4A==} + engines: {node: '>=18'} + + dotenv@16.6.1: + resolution: {integrity: sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==} + engines: {node: '>=12'} + + dunder-proto@1.0.1: + resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} + engines: {node: '>= 0.4'} + + ecdsa-sig-formatter@1.0.11: + resolution: {integrity: sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==} + + ee-first@1.1.1: + resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} + + encodeurl@2.0.0: + resolution: {integrity: sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==} + engines: {node: '>= 0.8'} + + es-define-property@1.0.1: + resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} + engines: {node: '>= 0.4'} + + es-errors@1.3.0: + resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} + engines: {node: '>= 0.4'} + + es-object-atoms@1.1.2: + resolution: {integrity: sha512-HWcBoN6NileqtSydK2FqHbS/LoDd2pqrnQHLyJzBj4kOp/ky2MWMN694xOfkK8/SnUsW2DH7EfyVlydKCsm1Zw==} + engines: {node: '>= 0.4'} + + es-set-tostringtag@2.1.0: + resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==} + engines: {node: '>= 0.4'} + + escape-html@1.0.3: + resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} + + etag@1.8.1: + resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==} + engines: {node: '>= 0.6'} + + express-rate-limit@6.11.2: + resolution: {integrity: sha512-a7uwwfNTh1U60ssiIkuLFWHt4hAC5yxlLGU2VP0X4YNlyEDZAqF4tK3GD3NSitVBrCQmQ0++0uOyFOgC2y4DDw==} + engines: {node: '>= 14'} + peerDependencies: + express: ^4 || ^5 + + express@4.22.2: + resolution: {integrity: sha512-IuL+Elrou2ZvCFHs18/CIzy2Nzvo25nZ1/D2eIZlz7c+QUayAcYoiM2BthCjs+EBHVpjYjcuLDAiCWgeIX3X1Q==} + engines: {node: '>= 0.10.0'} + + fast-deep-equal@3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + + fetch-blob@3.2.0: + resolution: {integrity: sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==} + engines: {node: ^12.20 || >= 14.13} + + finalhandler@1.3.2: + resolution: {integrity: sha512-aA4RyPcd3badbdABGDuTXCMTtOneUCAYH/gxoYRTZlIJdF0YPWuGqiAsIrhNnnqdXGswYk6dGujem4w80UJFhg==} + engines: {node: '>= 0.8'} + + follow-redirects@1.16.0: + resolution: {integrity: sha512-y5rN/uOsadFT/JfYwhxRS5R7Qce+g3zG97+JrtFZlC9klX/W5hD7iiLzScI4nZqUS7DNUdhPgw4xI8W2LuXlUw==} + engines: {node: '>=4.0'} + peerDependencies: + debug: '*' + peerDependenciesMeta: + debug: + optional: true + + form-data@4.0.6: + resolution: {integrity: sha512-vKatAh4SlVfgbv+YtmhiRjhEMJsYpsG1Y2rMQtR+SVSbytsSD1YGzDIcrAJmdFec88u/+VoGmxnl+80gL1tRCQ==} + engines: {node: '>= 6'} + + formdata-polyfill@4.0.10: + resolution: {integrity: sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==} + engines: {node: '>=12.20.0'} + + forwarded@0.2.0: + resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==} + engines: {node: '>= 0.6'} + + fresh@0.5.2: + resolution: {integrity: sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==} + engines: {node: '>= 0.6'} + + function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + + get-intrinsic@1.3.0: + resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} + engines: {node: '>= 0.4'} + + get-proto@1.0.1: + resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} + engines: {node: '>= 0.4'} + + gopd@1.2.0: + resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} + engines: {node: '>= 0.4'} + + has-symbols@1.1.0: + resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} + engines: {node: '>= 0.4'} + + has-tostringtag@1.0.2: + resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} + engines: {node: '>= 0.4'} + + hasown@2.0.4: + resolution: {integrity: sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==} + engines: {node: '>= 0.4'} + + http-errors@2.0.1: + resolution: {integrity: sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==} + engines: {node: '>= 0.8'} + + https-proxy-agent@5.0.1: + resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==} + engines: {node: '>= 6'} + + iconv-lite@0.4.24: + resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} + engines: {node: '>=0.10.0'} + + ieee754@1.2.1: + resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} + + inherits@2.0.3: + resolution: {integrity: sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==} + + inherits@2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + + ioredis@5.11.1: + resolution: {integrity: sha512-ehuGcf94bQXhfagULNXrJdfnWO38v070jxSx/qE87Kjzmu2fU7ro5EFAb+OPituLqgfyuQaym5DlrNydW2sJ9A==} + engines: {node: '>=12.22.0'} + + ip-address@10.2.0: + resolution: {integrity: sha512-/+S6j4E9AHvW9SWMSEY9Xfy66O5PWvVEJ08O0y5JGyEKQpojb0K0GKpz/v5HJ/G0vi3D2sjGK78119oXZeE0qA==} + engines: {node: '>= 12'} + + ipaddr.js@1.9.1: + resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} + engines: {node: '>= 0.10'} + + json-buffer@3.0.1: + resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} + + jsonwebtoken@8.5.1: + resolution: {integrity: sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w==} + engines: {node: '>=4', npm: '>=1.4.28'} + + jwa@1.4.2: + resolution: {integrity: sha512-eeH5JO+21J78qMvTIDdBXidBd6nG2kZjg5Ohz/1fpa28Z4CcsWUzJ1ZZyFq/3z3N17aZy+ZuBoHljASbL1WfOw==} + + jws@3.2.3: + resolution: {integrity: sha512-byiJ0FLRdLdSVSReO/U4E7RoEyOCKnEnEPMjq3HxWtvzLsV08/i5RQKsFVNkCldrCaPr2vDNAOMsfs8T/Hze7g==} + + kareem@2.5.1: + resolution: {integrity: sha512-7jFxRVm+jD+rkq3kY0iZDJfsO2/t4BBPeEb2qKn2lR/9KhuksYk5hxzfRYWMPV8P/x2d0kHD306YyWLzjjH+uA==} + engines: {node: '>=12.0.0'} + + keyv@4.5.4: + resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} + + lodash.includes@4.3.0: + resolution: {integrity: sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==} + + lodash.isboolean@3.0.3: + resolution: {integrity: sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==} + + lodash.isinteger@4.0.4: + resolution: {integrity: sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==} + + lodash.isnumber@3.0.3: + resolution: {integrity: sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==} + + lodash.isplainobject@4.0.6: + resolution: {integrity: sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==} + + lodash.isstring@4.0.1: + resolution: {integrity: sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==} + + lodash.once@4.1.1: + resolution: {integrity: sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==} + + lodash.snakecase@4.1.1: + resolution: {integrity: sha512-QZ1d4xoBHYUeuouhEq3lk3Uq7ldgyFXGBhg04+oRLnIz8o9T65Eh+8YdroUwn846zchkA9yDsDl5CVVaV2nqYw==} + + lodash@4.18.1: + resolution: {integrity: sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==} + + magic-bytes.js@1.13.0: + resolution: {integrity: sha512-afO2mnxW7GDTXMm5/AoN1WuOcdoKhtgXjIvHmobqTD1grNplhGdv3PFOyjCVmrnOZBIT/gD/koDKpYG+0mvHcg==} + + math-intrinsics@1.1.0: + resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} + engines: {node: '>= 0.4'} + + media-typer@0.3.0: + resolution: {integrity: sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==} + engines: {node: '>= 0.6'} + + memory-pager@1.5.0: + resolution: {integrity: sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==} + + merge-descriptors@1.0.3: + resolution: {integrity: sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==} + + methods@1.1.2: + resolution: {integrity: sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==} + engines: {node: '>= 0.6'} + + mime-db@1.52.0: + resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} + engines: {node: '>= 0.6'} + + mime-types@2.1.35: + resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} + engines: {node: '>= 0.6'} + + mime@1.6.0: + resolution: {integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==} + engines: {node: '>=4'} + hasBin: true + + mongodb-connection-string-url@2.6.0: + resolution: {integrity: sha512-WvTZlI9ab0QYtTYnuMLgobULWhokRjtC7db9LtcVfJ+Hsnyr5eo6ZtNAt3Ly24XZScGMelOcGtm7lSn0332tPQ==} + + mongodb@4.17.2: + resolution: {integrity: sha512-mLV7SEiov2LHleRJPMPrK2PMyhXFZt2UQLC4VD4pnth3jMjYKHhtqfwwkkvS/NXuo/Fp3vbhaNcXrIDaLRb9Tg==} + engines: {node: '>=12.9.0'} + + mongoose@6.13.10: + resolution: {integrity: sha512-5Xya7crlTwBrl3Gp1XCZMSnKI1WTLYzKkRdKaBiD51AprGtLQtgNoFO7v/qG0O5PixjfxzLuN3f3MChDOOFQOQ==} + engines: {node: '>=12.0.0'} + + mpath@0.9.0: + resolution: {integrity: sha512-ikJRQTk8hw5DEoFVxHG1Gn9T/xcjtdnOKIU1JTmGjZZlg9LST2mBLmcX3/ICIbgJydT2GOc15RnNy5mHmzfSew==} + engines: {node: '>=4.0.0'} + + mquery@4.0.3: + resolution: {integrity: sha512-J5heI+P08I6VJ2Ky3+33IpCdAvlYGTSUjwTPxkAr8i8EoduPMBX2OY/wa3IKZIQl7MU4SbFk8ndgSKyB/cl1zA==} + engines: {node: '>=12.0.0'} + + ms@2.0.0: + resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} + + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + negotiator@0.6.3: + resolution: {integrity: sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==} + engines: {node: '>= 0.6'} + + node-domexception@1.0.0: + resolution: {integrity: sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==} + engines: {node: '>=10.5.0'} + deprecated: Use your platform's native DOMException instead + + node-fetch@3.3.2: + resolution: {integrity: sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + object-inspect@1.13.4: + resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==} + engines: {node: '>= 0.4'} + + on-finished@2.4.1: + resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} + engines: {node: '>= 0.8'} + + parseurl@1.3.3: + resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==} + engines: {node: '>= 0.8'} + + path-to-regexp@0.1.13: + resolution: {integrity: sha512-A/AGNMFN3c8bOlvV9RreMdrv7jsmF9XIfDeCd87+I8RNg6s78BhJxMu69NEMHBSJFxKidViTEdruRwEk/WIKqA==} + + path@0.12.7: + resolution: {integrity: sha512-aXXC6s+1w7otVF9UletFkFcDsJeO7lSZBPUQhtb5O0xJe8LtYhj/GxldoL09bBj9+ZmE2hNoHqQSFMN5fikh4Q==} + + process@0.11.10: + resolution: {integrity: sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==} + engines: {node: '>= 0.6.0'} + + proxy-addr@2.0.7: + resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} + engines: {node: '>= 0.10'} + + proxy-from-env@2.1.0: + resolution: {integrity: sha512-cJ+oHTW1VAEa8cJslgmUZrc+sjRKgAKl3Zyse6+PV38hZe/V6Z14TbCuXcan9F9ghlz4QrFr2c92TNF82UkYHA==} + engines: {node: '>=10'} + + punycode@2.3.1: + resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} + engines: {node: '>=6'} + + qs@6.15.3: + resolution: {integrity: sha512-O9gl3zCl5h5blw1KGUzQKhA5oUXSl8rwUIM5o0S3nCXMliSvy5Dzx7/DJcI+SwgICv+IneSZwhBh1oSyEHA71A==} + engines: {node: '>=0.6'} + + range-parser@1.2.1: + resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==} + engines: {node: '>= 0.6'} + + raw-body@2.5.3: + resolution: {integrity: sha512-s4VSOf6yN0rvbRZGxs8Om5CWj6seneMwK3oDb4lWDH0UPhWcxwOWw5+qk24bxq87szX1ydrwylIOp2uG1ojUpA==} + engines: {node: '>= 0.8'} + + redis-errors@1.2.0: + resolution: {integrity: sha512-1qny3OExCf0UvUV/5wpYKf2YwPcOqXzkwKKSmKHiE6ZMQs5heeE/c8eXK+PNllPvmjgAbfnsbpkGZWy8cBpn9w==} + engines: {node: '>=4'} + + redis-parser@3.0.0: + resolution: {integrity: sha512-DJnGAeenTdpMEH6uAJRK/uiyEIH9WVsUmoLwzudwGJUwZPp80PDBWPHXSAGNPwNvIXAbe7MSUB1zQFugFml66A==} + engines: {node: '>=4'} + + safe-buffer@5.2.1: + resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + + safer-buffer@2.1.2: + resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + + semver@5.7.2: + resolution: {integrity: sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==} + hasBin: true + + send@0.19.2: + resolution: {integrity: sha512-VMbMxbDeehAxpOtWJXlcUS5E8iXh6QmN+BkRX1GARS3wRaXEEgzCcB10gTQazO42tpNIya8xIyNx8fll1OFPrg==} + engines: {node: '>= 0.8.0'} + + serve-static@1.16.3: + resolution: {integrity: sha512-x0RTqQel6g5SY7Lg6ZreMmsOzncHFU7nhnRWkKgWuMTu5NN0DR5oruckMqRvacAN9d5w6ARnRBXl9xhDCgfMeA==} + engines: {node: '>= 0.8.0'} + + setprototypeof@1.2.0: + resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} + + side-channel-list@1.0.1: + resolution: {integrity: sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w==} + engines: {node: '>= 0.4'} + + side-channel-map@1.0.1: + resolution: {integrity: sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==} + engines: {node: '>= 0.4'} + + side-channel-weakmap@1.0.2: + resolution: {integrity: sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==} + engines: {node: '>= 0.4'} + + side-channel@1.1.1: + resolution: {integrity: sha512-6x6dK6zJdpTzF4sQeNYxwtvBzf6Eg4GtlesS94HOvTudUeyK2WXAaIfmDgsyslYrRBeFIlsi54AYsFGUuhmvrQ==} + engines: {node: '>= 0.4'} + + sift@16.0.1: + resolution: {integrity: sha512-Wv6BjQ5zbhW7VFefWusVP33T/EM0vYikCaQ2qR8yULbsilAT8/wQaXvuQ3ptGLpoKx+lihJE3y2UTgKDyyNHZQ==} + + sjcl@1.0.9: + resolution: {integrity: sha512-dWM71tkSHxe7zEZj0/COjtJdmErIxp7UMp8a6D4xx8dTTtJLc4lFL+HAX8s6lvASyQQ2iYMHwa7rhhQq7MT5MA==} + + smart-buffer@4.2.0: + resolution: {integrity: sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==} + engines: {node: '>= 6.0.0', npm: '>= 3.0.0'} + + socks@2.8.9: + resolution: {integrity: sha512-LJhUYUvItdQ0LkJTmPeaEObWXAqFyfmP85x0tch/ez9cahmhlBBLbIqDFnvBnUJGagb0JbIQrkBs1wJ+yRYpEw==} + engines: {node: '>= 10.0.0', npm: '>= 3.0.0'} + + sparse-bitfield@3.0.3: + resolution: {integrity: sha512-kvzhi7vqKTfkh0PZU+2D2PIllw2ymqJKujUcyPMd9Y75Nv4nPbGJZXNhxsgdQab2BmlDct1YnfQCguEvHr7VsQ==} + + standard-as-callback@2.1.0: + resolution: {integrity: sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A==} + + statuses@2.0.2: + resolution: {integrity: sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==} + engines: {node: '>= 0.8'} + + toidentifier@1.0.1: + resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} + engines: {node: '>=0.6'} + + tr46@3.0.0: + resolution: {integrity: sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==} + engines: {node: '>=12'} + + ts-mixer@6.0.4: + resolution: {integrity: sha512-ufKpbmrugz5Aou4wcr5Wc1UUFWOLhq+Fm6qa6P0w0K5Qw2yhaUoiWszhCVuNQyNwrlGiscHOmqYoAox1PtvgjA==} + + tslib@2.8.1: + resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + + type-is@1.6.18: + resolution: {integrity: sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==} + engines: {node: '>= 0.6'} + + undici-types@8.3.0: + resolution: {integrity: sha512-j375ScV60dom+YkPFIfTLcOiPxkN/buHz5GobjLhixFuANaNs3C9l4GmrWqejgXWJ7BbJcFYpTEUkS1Ge8bpZQ==} + + undici@6.27.0: + resolution: {integrity: sha512-YmfV3YnEDzXRC5lZ2jWtWWHKGUm1zIt8AhesR1tens+HTNv+YZlN/dp6G727LOvMJ8xjP9Be7Y2Sdr96LDm+pg==} + engines: {node: '>=18.17'} + + unpipe@1.0.0: + resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} + engines: {node: '>= 0.8'} + + util@0.10.4: + resolution: {integrity: sha512-0Pm9hTQ3se5ll1XihRic3FDIku70C+iHUdT/W926rSgHV5QgXsYbKZN8MSC3tJtSkhuROzvsQjAaFENRXr+19A==} + + utils-merge@1.0.1: + resolution: {integrity: sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==} + engines: {node: '>= 0.4.0'} + + uuid@11.1.1: + resolution: {integrity: sha512-vIYxrBCC/N/K+Js3qSN88go7kIfNPssr/hHCesKCQNAjmgvYS2oqr69kIufEG+O4+PfezOH4EbIeHCfFov8ZgQ==} + hasBin: true + + vary@1.1.2: + resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} + engines: {node: '>= 0.8'} + + web-streams-polyfill@3.3.3: + resolution: {integrity: sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==} + engines: {node: '>= 8'} + + webidl-conversions@7.0.0: + resolution: {integrity: sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==} + engines: {node: '>=12'} + + whatwg-url@11.0.0: + resolution: {integrity: sha512-RKT8HExMpoYx4igMiVMY83lN6UeITKJlBQ+vR/8ZJ8OCdSiN3RwCq+9gH0+Xzj0+5IrM6i4j/6LuvzbZIQgEcQ==} + engines: {node: '>=12'} + + ws@8.21.1: + resolution: {integrity: sha512-+0NTnW77fFN/DjQi6k/Sq/Yvk4Sgajw7urW8V+asjXnRgDs9gyGkdb7EzgfhA4goXsRIZKE28fzIXBHEzhuiWw==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + + xml-parser@1.2.1: + resolution: {integrity: sha512-lPUzzmS0zdwcNtyNndCl2IwH172ozkUDqmfmH3FcuDzHVl552Kr6oNfsvteHabqTWhsrMgpijqZ/yT7Wo1/Pzw==} + + xmlbuilder@15.1.1: + resolution: {integrity: sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg==} + engines: {node: '>=8.0'} + +snapshots: + + '@aws-sdk/core@3.976.0': + dependencies: + '@aws-sdk/types': 3.974.2 + '@aws-sdk/xml-builder': 3.972.36 + '@aws/lambda-invoke-store': 0.3.0 + '@smithy/core': 3.29.8 + '@smithy/signature-v4': 5.6.9 + '@smithy/types': 4.16.1 + bowser: 2.14.1 + tslib: 2.8.1 + optional: true + + '@aws-sdk/credential-provider-cognito-identity@3.972.59': + dependencies: + '@aws-sdk/nested-clients': 3.997.34 + '@aws-sdk/types': 3.974.2 + '@smithy/core': 3.29.8 + '@smithy/types': 4.16.1 + tslib: 2.8.1 + optional: true + + '@aws-sdk/credential-provider-env@3.972.60': + dependencies: + '@aws-sdk/core': 3.976.0 + '@aws-sdk/types': 3.974.2 + '@smithy/core': 3.29.8 + '@smithy/types': 4.16.1 + tslib: 2.8.1 + optional: true + + '@aws-sdk/credential-provider-http@3.972.62': + dependencies: + '@aws-sdk/core': 3.976.0 + '@aws-sdk/types': 3.974.2 + '@smithy/core': 3.29.8 + '@smithy/fetch-http-handler': 5.6.10 + '@smithy/node-http-handler': 4.9.10 + '@smithy/types': 4.16.1 + tslib: 2.8.1 + optional: true + + '@aws-sdk/credential-provider-ini@3.973.5': + dependencies: + '@aws-sdk/core': 3.976.0 + '@aws-sdk/credential-provider-env': 3.972.60 + '@aws-sdk/credential-provider-http': 3.972.62 + '@aws-sdk/credential-provider-login': 3.972.67 + '@aws-sdk/credential-provider-process': 3.972.60 + '@aws-sdk/credential-provider-sso': 3.973.4 + '@aws-sdk/credential-provider-web-identity': 3.972.66 + '@aws-sdk/nested-clients': 3.997.34 + '@aws-sdk/types': 3.974.2 + '@smithy/core': 3.29.8 + '@smithy/credential-provider-imds': 4.4.13 + '@smithy/types': 4.16.1 + tslib: 2.8.1 + optional: true + + '@aws-sdk/credential-provider-login@3.972.67': + dependencies: + '@aws-sdk/core': 3.976.0 + '@aws-sdk/nested-clients': 3.997.34 + '@aws-sdk/types': 3.974.2 + '@smithy/core': 3.29.8 + '@smithy/types': 4.16.1 + tslib: 2.8.1 + optional: true + + '@aws-sdk/credential-provider-node@3.972.71': + dependencies: + '@aws-sdk/credential-provider-env': 3.972.60 + '@aws-sdk/credential-provider-http': 3.972.62 + '@aws-sdk/credential-provider-ini': 3.973.5 + '@aws-sdk/credential-provider-process': 3.972.60 + '@aws-sdk/credential-provider-sso': 3.973.4 + '@aws-sdk/credential-provider-web-identity': 3.972.66 + '@aws-sdk/types': 3.974.2 + '@smithy/core': 3.29.8 + '@smithy/credential-provider-imds': 4.4.13 + '@smithy/types': 4.16.1 + tslib: 2.8.1 + optional: true + + '@aws-sdk/credential-provider-process@3.972.60': + dependencies: + '@aws-sdk/core': 3.976.0 + '@aws-sdk/types': 3.974.2 + '@smithy/core': 3.29.8 + '@smithy/types': 4.16.1 + tslib: 2.8.1 + optional: true + + '@aws-sdk/credential-provider-sso@3.973.4': + dependencies: + '@aws-sdk/core': 3.976.0 + '@aws-sdk/nested-clients': 3.997.34 + '@aws-sdk/token-providers': 3.1092.0 + '@aws-sdk/types': 3.974.2 + '@smithy/core': 3.29.8 + '@smithy/types': 4.16.1 + tslib: 2.8.1 + optional: true + + '@aws-sdk/credential-provider-web-identity@3.972.66': + dependencies: + '@aws-sdk/core': 3.976.0 + '@aws-sdk/nested-clients': 3.997.34 + '@aws-sdk/types': 3.974.2 + '@smithy/core': 3.29.8 + '@smithy/types': 4.16.1 + tslib: 2.8.1 + optional: true + + '@aws-sdk/credential-providers@3.1094.0': + dependencies: + '@aws-sdk/core': 3.976.0 + '@aws-sdk/credential-provider-cognito-identity': 3.972.59 + '@aws-sdk/credential-provider-env': 3.972.60 + '@aws-sdk/credential-provider-http': 3.972.62 + '@aws-sdk/credential-provider-ini': 3.973.5 + '@aws-sdk/credential-provider-login': 3.972.67 + '@aws-sdk/credential-provider-node': 3.972.71 + '@aws-sdk/credential-provider-process': 3.972.60 + '@aws-sdk/credential-provider-sso': 3.973.4 + '@aws-sdk/credential-provider-web-identity': 3.972.66 + '@aws-sdk/nested-clients': 3.997.34 + '@aws-sdk/types': 3.974.2 + '@smithy/core': 3.29.8 + '@smithy/credential-provider-imds': 4.4.13 + '@smithy/types': 4.16.1 + tslib: 2.8.1 + optional: true + + '@aws-sdk/nested-clients@3.997.34': + dependencies: + '@aws-sdk/core': 3.976.0 + '@aws-sdk/signature-v4-multi-region': 3.996.41 + '@aws-sdk/types': 3.974.2 + '@smithy/core': 3.29.8 + '@smithy/fetch-http-handler': 5.6.10 + '@smithy/node-http-handler': 4.9.10 + '@smithy/types': 4.16.1 + tslib: 2.8.1 + optional: true + + '@aws-sdk/signature-v4-multi-region@3.996.41': + dependencies: + '@aws-sdk/types': 3.974.2 + '@smithy/signature-v4': 5.6.9 + '@smithy/types': 4.16.1 + tslib: 2.8.1 + optional: true + + '@aws-sdk/token-providers@3.1092.0': + dependencies: + '@aws-sdk/core': 3.976.0 + '@aws-sdk/nested-clients': 3.997.34 + '@aws-sdk/types': 3.974.2 + '@smithy/core': 3.29.8 + '@smithy/types': 4.16.1 + tslib: 2.8.1 + optional: true + + '@aws-sdk/types@3.974.2': + dependencies: + '@smithy/types': 4.16.1 + tslib: 2.8.1 + optional: true + + '@aws-sdk/xml-builder@3.972.36': + dependencies: + '@smithy/types': 4.16.1 + tslib: 2.8.1 + optional: true + + '@aws/lambda-invoke-store@0.3.0': + optional: true + + '@discordjs/builders@1.14.1': + dependencies: + '@discordjs/formatters': 0.6.2 + '@discordjs/util': 1.2.0 + '@sapphire/shapeshift': 4.0.0 + discord-api-types: 0.38.50 + fast-deep-equal: 3.1.3 + ts-mixer: 6.0.4 + tslib: 2.8.1 + + '@discordjs/collection@1.5.3': {} + + '@discordjs/collection@2.1.1': {} + + '@discordjs/formatters@0.6.2': + dependencies: + discord-api-types: 0.38.50 + + '@discordjs/rest@2.6.3': + dependencies: + '@discordjs/collection': 2.1.1 + '@discordjs/util': 1.2.0 + '@sapphire/async-queue': 1.5.5 + '@sapphire/snowflake': 3.5.5 + '@vladfrangu/async_event_emitter': 2.4.7 + discord-api-types: 0.38.50 + magic-bytes.js: 1.13.0 + tslib: 2.8.1 + undici: 6.27.0 + + '@discordjs/util@1.2.0': + dependencies: + discord-api-types: 0.38.50 + + '@discordjs/ws@1.2.3': + dependencies: + '@discordjs/collection': 2.1.1 + '@discordjs/rest': 2.6.3 + '@discordjs/util': 1.2.0 + '@sapphire/async-queue': 1.5.5 + '@types/ws': 8.18.1 + '@vladfrangu/async_event_emitter': 2.4.7 + discord-api-types: 0.38.50 + tslib: 2.8.1 + ws: 8.21.1 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + '@ioredis/commands@1.10.0': {} + + '@mongodb-js/saslprep@1.4.12': + dependencies: + sparse-bitfield: 3.0.3 + optional: true + + '@sapphire/async-queue@1.5.5': {} + + '@sapphire/shapeshift@4.0.0': + dependencies: + fast-deep-equal: 3.1.3 + lodash: 4.18.1 + + '@sapphire/snowflake@3.5.5': {} + + '@smithy/core@3.29.8': + dependencies: + '@smithy/types': 4.16.1 + tslib: 2.8.1 + optional: true + + '@smithy/credential-provider-imds@4.4.13': + dependencies: + '@smithy/core': 3.29.8 + '@smithy/types': 4.16.1 + tslib: 2.8.1 + optional: true + + '@smithy/fetch-http-handler@5.6.10': + dependencies: + '@smithy/core': 3.29.8 + '@smithy/types': 4.16.1 + tslib: 2.8.1 + optional: true + + '@smithy/node-http-handler@4.9.10': + dependencies: + '@smithy/core': 3.29.8 + '@smithy/types': 4.16.1 + tslib: 2.8.1 + optional: true + + '@smithy/signature-v4@5.6.9': + dependencies: + '@smithy/core': 3.29.8 + '@smithy/types': 4.16.1 + tslib: 2.8.1 + optional: true + + '@smithy/types@4.16.1': + dependencies: + tslib: 2.8.1 + optional: true + + '@types/node@26.1.1': + dependencies: + undici-types: 8.3.0 + + '@types/webidl-conversions@7.0.3': {} + + '@types/whatwg-url@8.2.2': + dependencies: + '@types/node': 26.1.1 + '@types/webidl-conversions': 7.0.3 + + '@types/ws@8.18.1': + dependencies: + '@types/node': 26.1.1 + + '@vladfrangu/async_event_emitter@2.4.7': {} + + accepts@1.3.8: + dependencies: + mime-types: 2.1.35 + negotiator: 0.6.3 + + agent-base@6.0.2: + dependencies: + debug: 4.4.3 + transitivePeerDependencies: + - supports-color + + array-flatten@1.1.1: {} + + asynckit@0.4.0: {} + + axios@1.18.1: + dependencies: + follow-redirects: 1.16.0 + form-data: 4.0.6 + https-proxy-agent: 5.0.1 + proxy-from-env: 2.1.0 + transitivePeerDependencies: + - debug + - supports-color + + bad-words@3.0.4: + dependencies: + badwords-list: 1.0.0 + + badwords-list@1.0.0: {} + + base64-js@1.5.1: {} + + bcryptjs@3.0.3: {} + + body-parser@1.20.6: + dependencies: + bytes: 3.1.2 + content-type: 1.0.5 + debug: 2.6.9 + depd: 2.0.0 + destroy: 1.2.0 + http-errors: 2.0.1 + iconv-lite: 0.4.24 + on-finished: 2.4.1 + qs: 6.15.3 + raw-body: 2.5.3 + type-is: 1.6.18 + unpipe: 1.0.0 + transitivePeerDependencies: + - supports-color + + bowser@2.14.1: + optional: true + + bson@4.7.2: + dependencies: + buffer: 5.7.1 + + buffer-equal-constant-time@1.0.1: {} + + buffer@5.7.1: + dependencies: + base64-js: 1.5.1 + ieee754: 1.2.1 + + bytes@3.1.2: {} + + call-bind-apply-helpers@1.0.2: + dependencies: + es-errors: 1.3.0 + function-bind: 1.1.2 + + call-bound@1.0.4: + dependencies: + call-bind-apply-helpers: 1.0.2 + get-intrinsic: 1.3.0 + + cluster-key-slot@1.1.1: {} + + combined-stream@1.0.8: + dependencies: + delayed-stream: 1.0.0 + + content-disposition@0.5.4: + dependencies: + safe-buffer: 5.2.1 + + content-type@1.0.5: {} + + cookie-signature@1.0.7: {} + + cookie@0.7.2: {} + + data-uri-to-buffer@4.0.1: {} + + debug@2.6.9: + dependencies: + ms: 2.0.0 + + debug@4.4.3: + dependencies: + ms: 2.1.3 + + delayed-stream@1.0.0: {} + + denque@2.1.0: {} + + depd@2.0.0: {} + + destr@2.0.5: {} + + destroy@1.2.0: {} + + discord-api-types@0.38.50: {} + + discord.js@14.27.0: + dependencies: + '@discordjs/builders': 1.14.1 + '@discordjs/collection': 1.5.3 + '@discordjs/formatters': 0.6.2 + '@discordjs/rest': 2.6.3 + '@discordjs/util': 1.2.0 + '@discordjs/ws': 1.2.3 + '@sapphire/snowflake': 3.5.5 + discord-api-types: 0.38.50 + fast-deep-equal: 3.1.3 + lodash.snakecase: 4.1.1 + magic-bytes.js: 1.13.0 + tslib: 2.8.1 + undici: 6.27.0 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + dotenv@16.6.1: {} + + dunder-proto@1.0.1: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-errors: 1.3.0 + gopd: 1.2.0 + + ecdsa-sig-formatter@1.0.11: + dependencies: + safe-buffer: 5.2.1 + + ee-first@1.1.1: {} + + encodeurl@2.0.0: {} + + es-define-property@1.0.1: {} + + es-errors@1.3.0: {} + + es-object-atoms@1.1.2: + dependencies: + es-errors: 1.3.0 + + es-set-tostringtag@2.1.0: + dependencies: + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + has-tostringtag: 1.0.2 + hasown: 2.0.4 + + escape-html@1.0.3: {} + + etag@1.8.1: {} + + express-rate-limit@6.11.2(express@4.22.2): + dependencies: + express: 4.22.2 + + express@4.22.2: + dependencies: + accepts: 1.3.8 + array-flatten: 1.1.1 + body-parser: 1.20.6 + content-disposition: 0.5.4 + content-type: 1.0.5 + cookie: 0.7.2 + cookie-signature: 1.0.7 + debug: 2.6.9 + depd: 2.0.0 + encodeurl: 2.0.0 + escape-html: 1.0.3 + etag: 1.8.1 + finalhandler: 1.3.2 + fresh: 0.5.2 + http-errors: 2.0.1 + merge-descriptors: 1.0.3 + methods: 1.1.2 + on-finished: 2.4.1 + parseurl: 1.3.3 + path-to-regexp: 0.1.13 + proxy-addr: 2.0.7 + qs: 6.15.3 + range-parser: 1.2.1 + safe-buffer: 5.2.1 + send: 0.19.2 + serve-static: 1.16.3 + setprototypeof: 1.2.0 + statuses: 2.0.2 + type-is: 1.6.18 + utils-merge: 1.0.1 + vary: 1.1.2 + transitivePeerDependencies: + - supports-color + + fast-deep-equal@3.1.3: {} + + fetch-blob@3.2.0: + dependencies: + node-domexception: 1.0.0 + web-streams-polyfill: 3.3.3 + + finalhandler@1.3.2: + dependencies: + debug: 2.6.9 + encodeurl: 2.0.0 + escape-html: 1.0.3 + on-finished: 2.4.1 + parseurl: 1.3.3 + statuses: 2.0.2 + unpipe: 1.0.0 + transitivePeerDependencies: + - supports-color + + follow-redirects@1.16.0: {} + + form-data@4.0.6: + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + es-set-tostringtag: 2.1.0 + hasown: 2.0.4 + mime-types: 2.1.35 + + formdata-polyfill@4.0.10: + dependencies: + fetch-blob: 3.2.0 + + forwarded@0.2.0: {} + + fresh@0.5.2: {} + + function-bind@1.1.2: {} + + get-intrinsic@1.3.0: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-define-property: 1.0.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.2 + function-bind: 1.1.2 + get-proto: 1.0.1 + gopd: 1.2.0 + has-symbols: 1.1.0 + hasown: 2.0.4 + math-intrinsics: 1.1.0 + + get-proto@1.0.1: + dependencies: + dunder-proto: 1.0.1 + es-object-atoms: 1.1.2 + + gopd@1.2.0: {} + + has-symbols@1.1.0: {} + + has-tostringtag@1.0.2: + dependencies: + has-symbols: 1.1.0 + + hasown@2.0.4: + dependencies: + function-bind: 1.1.2 + + http-errors@2.0.1: + dependencies: + depd: 2.0.0 + inherits: 2.0.4 + setprototypeof: 1.2.0 + statuses: 2.0.2 + toidentifier: 1.0.1 + + https-proxy-agent@5.0.1: + dependencies: + agent-base: 6.0.2 + debug: 4.4.3 + transitivePeerDependencies: + - supports-color + + iconv-lite@0.4.24: + dependencies: + safer-buffer: 2.1.2 + + ieee754@1.2.1: {} + + inherits@2.0.3: {} + + inherits@2.0.4: {} + + ioredis@5.11.1: + dependencies: + '@ioredis/commands': 1.10.0 + cluster-key-slot: 1.1.1 + debug: 4.4.3 + denque: 2.1.0 + redis-errors: 1.2.0 + redis-parser: 3.0.0 + standard-as-callback: 2.1.0 + transitivePeerDependencies: + - supports-color + + ip-address@10.2.0: {} + + ipaddr.js@1.9.1: {} + + json-buffer@3.0.1: {} + + jsonwebtoken@8.5.1: + dependencies: + jws: 3.2.3 + lodash.includes: 4.3.0 + lodash.isboolean: 3.0.3 + lodash.isinteger: 4.0.4 + lodash.isnumber: 3.0.3 + lodash.isplainobject: 4.0.6 + lodash.isstring: 4.0.1 + lodash.once: 4.1.1 + ms: 2.1.3 + semver: 5.7.2 + + jwa@1.4.2: + dependencies: + buffer-equal-constant-time: 1.0.1 + ecdsa-sig-formatter: 1.0.11 + safe-buffer: 5.2.1 + + jws@3.2.3: + dependencies: + jwa: 1.4.2 + safe-buffer: 5.2.1 + + kareem@2.5.1: {} + + keyv@4.5.4: + dependencies: + json-buffer: 3.0.1 + + lodash.includes@4.3.0: {} + + lodash.isboolean@3.0.3: {} + + lodash.isinteger@4.0.4: {} + + lodash.isnumber@3.0.3: {} + + lodash.isplainobject@4.0.6: {} + + lodash.isstring@4.0.1: {} + + lodash.once@4.1.1: {} + + lodash.snakecase@4.1.1: {} + + lodash@4.18.1: {} + + magic-bytes.js@1.13.0: {} + + math-intrinsics@1.1.0: {} + + media-typer@0.3.0: {} + + memory-pager@1.5.0: + optional: true + + merge-descriptors@1.0.3: {} + + methods@1.1.2: {} + + mime-db@1.52.0: {} + + mime-types@2.1.35: + dependencies: + mime-db: 1.52.0 + + mime@1.6.0: {} + + mongodb-connection-string-url@2.6.0: + dependencies: + '@types/whatwg-url': 8.2.2 + whatwg-url: 11.0.0 + + mongodb@4.17.2: + dependencies: + bson: 4.7.2 + mongodb-connection-string-url: 2.6.0 + socks: 2.8.9 + optionalDependencies: + '@aws-sdk/credential-providers': 3.1094.0 + '@mongodb-js/saslprep': 1.4.12 + + mongoose@6.13.10: + dependencies: + bson: 4.7.2 + kareem: 2.5.1 + mongodb: 4.17.2 + mpath: 0.9.0 + mquery: 4.0.3 + ms: 2.1.3 + sift: 16.0.1 + transitivePeerDependencies: + - supports-color + + mpath@0.9.0: {} + + mquery@4.0.3: + dependencies: + debug: 4.4.3 + transitivePeerDependencies: + - supports-color + + ms@2.0.0: {} + + ms@2.1.3: {} + + negotiator@0.6.3: {} + + node-domexception@1.0.0: {} + + node-fetch@3.3.2: + dependencies: + data-uri-to-buffer: 4.0.1 + fetch-blob: 3.2.0 + formdata-polyfill: 4.0.10 + + object-inspect@1.13.4: {} + + on-finished@2.4.1: + dependencies: + ee-first: 1.1.1 + + parseurl@1.3.3: {} + + path-to-regexp@0.1.13: {} + + path@0.12.7: + dependencies: + process: 0.11.10 + util: 0.10.4 + + process@0.11.10: {} + + proxy-addr@2.0.7: + dependencies: + forwarded: 0.2.0 + ipaddr.js: 1.9.1 + + proxy-from-env@2.1.0: {} + + punycode@2.3.1: {} + + qs@6.15.3: + dependencies: + es-define-property: 1.0.1 + side-channel: 1.1.1 + + range-parser@1.2.1: {} + + raw-body@2.5.3: + dependencies: + bytes: 3.1.2 + http-errors: 2.0.1 + iconv-lite: 0.4.24 + unpipe: 1.0.0 + + redis-errors@1.2.0: {} + + redis-parser@3.0.0: + dependencies: + redis-errors: 1.2.0 + + safe-buffer@5.2.1: {} + + safer-buffer@2.1.2: {} + + semver@5.7.2: {} + + send@0.19.2: + dependencies: + debug: 2.6.9 + depd: 2.0.0 + destroy: 1.2.0 + encodeurl: 2.0.0 + escape-html: 1.0.3 + etag: 1.8.1 + fresh: 0.5.2 + http-errors: 2.0.1 + mime: 1.6.0 + ms: 2.1.3 + on-finished: 2.4.1 + range-parser: 1.2.1 + statuses: 2.0.2 + transitivePeerDependencies: + - supports-color + + serve-static@1.16.3: + dependencies: + encodeurl: 2.0.0 + escape-html: 1.0.3 + parseurl: 1.3.3 + send: 0.19.2 + transitivePeerDependencies: + - supports-color + + setprototypeof@1.2.0: {} + + side-channel-list@1.0.1: + dependencies: + es-errors: 1.3.0 + object-inspect: 1.13.4 + + side-channel-map@1.0.1: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + object-inspect: 1.13.4 + + side-channel-weakmap@1.0.2: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + object-inspect: 1.13.4 + side-channel-map: 1.0.1 + + side-channel@1.1.1: + dependencies: + es-errors: 1.3.0 + object-inspect: 1.13.4 + side-channel-list: 1.0.1 + side-channel-map: 1.0.1 + side-channel-weakmap: 1.0.2 + + sift@16.0.1: {} + + sjcl@1.0.9: {} + + smart-buffer@4.2.0: {} + + socks@2.8.9: + dependencies: + ip-address: 10.2.0 + smart-buffer: 4.2.0 + + sparse-bitfield@3.0.3: + dependencies: + memory-pager: 1.5.0 + optional: true + + standard-as-callback@2.1.0: {} + + statuses@2.0.2: {} + + toidentifier@1.0.1: {} + + tr46@3.0.0: + dependencies: + punycode: 2.3.1 + + ts-mixer@6.0.4: {} + + tslib@2.8.1: {} + + type-is@1.6.18: + dependencies: + media-typer: 0.3.0 + mime-types: 2.1.35 + + undici-types@8.3.0: {} + + undici@6.27.0: {} + + unpipe@1.0.0: {} + + util@0.10.4: + dependencies: + inherits: 2.0.3 + + utils-merge@1.0.1: {} + + uuid@11.1.1: {} + + vary@1.1.2: {} + + web-streams-polyfill@3.3.3: {} + + webidl-conversions@7.0.0: {} + + whatwg-url@11.0.0: + dependencies: + tr46: 3.0.0 + webidl-conversions: 7.0.0 + + ws@8.21.1: {} + + xml-parser@1.2.1: + dependencies: + debug: 2.6.9 + transitivePeerDependencies: + - supports-color + + xmlbuilder@15.1.1: {} diff --git a/routes/auth.js b/routes/auth.js index 62c50a37..119c1fcc 100644 --- a/routes/auth.js +++ b/routes/auth.js @@ -1,12 +1,12 @@ const express = require("express"); const app = express.Router(); const jwt = require("jsonwebtoken"); -const bcrypt = require("bcrypt"); +const bcrypt = require("bcryptjs"); const error = require("../structs/error.js"); const functions = require("../structs/functions.js"); const log = require("../structs/log.js"); -const config = require('../Config/config.json') +const config = require('../Config/config.js') const tokenCreation = require("../tokenManager/tokenCreation.js"); const { verifyToken, verifyClient } = require("../tokenManager/tokenVerify.js"); diff --git a/routes/main.js b/routes/main.js index bc77ac8f..d1cc05ab 100644 --- a/routes/main.js +++ b/routes/main.js @@ -7,7 +7,7 @@ const path = require("path"); const { verifyToken, verifyClient } = require("../tokenManager/tokenVerify.js"); -const config = JSON.parse(fs.readFileSync("./Config/config.json").toString()); +const config = require('../Config/config.js'); app.post("/fortnite/api/game/v2/chat/*/*/*/pc", (req, res) => { log.debug("POST /fortnite/api/game/v2/chat/*/*/*/pc called"); diff --git a/routes/matchmaking.js b/routes/matchmaking.js index cc7005fd..94e428f8 100644 --- a/routes/matchmaking.js +++ b/routes/matchmaking.js @@ -1,6 +1,6 @@ const express = require("express"); const app = express.Router(); -const config = require("../Config/config.json"); +const config = require("../Config/config.js"); const functions = require("../structs/functions.js"); const log = require("../structs/log.js"); const MMCode = require("../model/mmcodes.js"); diff --git a/routes/mcp.js b/routes/mcp.js index ae166912..460c2f48 100644 --- a/routes/mcp.js +++ b/routes/mcp.js @@ -9,7 +9,7 @@ const profileManager = require("../structs/profile.js"); const error = require("../structs/error.js"); const functions = require("../structs/functions.js"); const log = require("../structs/log.js"); -const config = require('../Config/config.json') +const config = require('../Config/config.js') const fs = require("fs"); const path = require("path"); const catalog = functions.getItemShop(); diff --git a/routes/reports.js b/routes/reports.js index 73245421..61def29b 100644 --- a/routes/reports.js +++ b/routes/reports.js @@ -4,7 +4,7 @@ const { verifyToken } = require("../tokenManager/tokenVerify.js"); const User = require("../model/user.js"); const Profiles = require("../model/profiles.js"); const { Client, Intents, TextChannel } = require('discord.js'); -const config = require('../Config/config.json'); +const config = require('../Config/config.js'); const log = require("../structs/log.js"); app.post("/fortnite/api/game/v2/toxicity/account/:unsafeReporter/report/:reportedPlayer", verifyToken, async (req, res) => { diff --git a/routes/timeline.js b/routes/timeline.js index b4330d3d..71e118da 100644 --- a/routes/timeline.js +++ b/routes/timeline.js @@ -2,7 +2,7 @@ const express = require("express"); const app = express.Router(); const functions = require("../structs/functions.js"); const fs = require("fs") -const config = JSON.parse(fs.readFileSync("./Config/config.json").toString()); +const config = require('../Config/config.js'); app.get("/fortnite/api/calendar/v1/timeline", async (req, res) => { const memory = functions.GetVersionInfo(req); diff --git a/structs/autorotate.js b/structs/autorotate.js index 2efb0fe5..459ac17d 100644 --- a/structs/autorotate.js +++ b/structs/autorotate.js @@ -1,7 +1,7 @@ const axios = require('axios'); const fs = require('fs'); const path = require('path'); -const config = require('../Config/config.json'); +const config = require('../Config/config.js'); const log = require("./log.js"); const webhook = config.bItemShopWebhook; diff --git a/structs/checkforupdate.js b/structs/checkforupdate.js index 6bb5737e..bb4b04e7 100644 --- a/structs/checkforupdate.js +++ b/structs/checkforupdate.js @@ -1,5 +1,5 @@ const log = require("../structs/log.js"); -const fetch = require("node-fetch"); +const fetch = require("node-fetch").default; class CheckForUpdate { static async checkForUpdate(currentVersion) { diff --git a/structs/functions.js b/structs/functions.js index 6ac053da..89cf158f 100644 --- a/structs/functions.js +++ b/structs/functions.js @@ -1,6 +1,6 @@ const XMLBuilder = require("xmlbuilder"); const uuid = require("uuid"); -const bcrypt = require("bcrypt"); +const bcrypt = require("bcryptjs"); const fs = require("fs"); const crypto = require("crypto"); const path = require("path"); diff --git a/structs/log.js b/structs/log.js index e52fb0a3..2f70e901 100644 --- a/structs/log.js +++ b/structs/log.js @@ -1,5 +1,5 @@ const fs = require("fs"); -const config = JSON.parse(fs.readFileSync("./Config/config.json").toString()); +const config = require('../Config/config.js'); function getTimestamp() { const now = new Date(); diff --git a/xmpp/xmpp.js b/xmpp/xmpp.js index 2e637556..71be0509 100644 --- a/xmpp/xmpp.js +++ b/xmpp/xmpp.js @@ -4,7 +4,7 @@ const XMLParser = require("xml-parser"); const express = require("express"); const fs = require("fs"); const https = require("https"); -const config = JSON.parse(fs.readFileSync("./Config/config.json").toString()); +const config = require('../Config/config.js'); const app = express(); const log = require("../structs/log.js"); @@ -13,7 +13,7 @@ const User = require("../model/user.js"); const Friends = require("../model/friends.js"); const matchmaker = require("../matchmaker/matchmaker.js") -const port = config.bEnableHTTPS ? 443 : 80; +const port = config.bEnableHTTPS ? 443 : 3008; let wss; let httpsOptions; From 03f7b114f3147949b47b8d55438921f30ec9c9a4 Mon Sep 17 00:00:00 2001 From: kxtzownsu Date: Sat, 25 Jul 2026 12:03:43 -0400 Subject: [PATCH 2/7] bug: update fully to discordjs@v14 Previously, we were still using DJS@v13-specific APIs. Now, this uses the proper DJS@v14 APIs. Signed-off-by: kxtzownsu --- DiscordBot/commands/Admin/addall.js | 6 +++--- DiscordBot/commands/Admin/createcustommatchcode.js | 6 +++--- DiscordBot/commands/Admin/custommatchcodelist.js | 6 +++--- DiscordBot/commands/Admin/removeall.js | 6 +++--- DiscordBot/commands/User/change-email.js | 6 +++--- DiscordBot/commands/User/change-password.js | 6 +++--- DiscordBot/commands/User/change-username.js | 6 +++--- DiscordBot/commands/User/claimvbucks.js | 4 ++-- DiscordBot/commands/User/create.js | 4 ++-- DiscordBot/commands/User/details.js | 6 +++--- DiscordBot/commands/User/exchange-code.js | 4 ++-- DiscordBot/commands/User/giftvbucks.js | 6 +++--- DiscordBot/commands/User/lookup.js | 6 +++--- DiscordBot/commands/User/vbucksamount.js | 6 +++--- DiscordBot/index.js | 11 ++++++----- 15 files changed, 45 insertions(+), 44 deletions(-) diff --git a/DiscordBot/commands/Admin/addall.js b/DiscordBot/commands/Admin/addall.js index 79eb4b14..aaa27f9c 100644 --- a/DiscordBot/commands/Admin/addall.js +++ b/DiscordBot/commands/Admin/addall.js @@ -1,4 +1,4 @@ -const { MessageEmbed } = require("discord.js"); +const { EmbedBuilder, Colors } = require("discord.js"); const path = require("path"); const fs = require("fs"); const Users = require('../../../model/user.js'); @@ -52,10 +52,10 @@ module.exports = { } }); - const embed = new MessageEmbed() + const embed = new EmbedBuilder() .setTitle("Full Locker Added") .setDescription("Successfully added all skins (Full Locker) to the selected account") - .setColor("GREEN") + .setColor(Colors.Green) .setFooter({ text: "Reload Backend", iconURL: "https://i.imgur.com/2RImwlb.png" diff --git a/DiscordBot/commands/Admin/createcustommatchcode.js b/DiscordBot/commands/Admin/createcustommatchcode.js index 65c85aa8..90b81a1f 100644 --- a/DiscordBot/commands/Admin/createcustommatchcode.js +++ b/DiscordBot/commands/Admin/createcustommatchcode.js @@ -1,5 +1,5 @@ const MMCodes = require("../../../model/mmcodes.js"); -const { MessageEmbed } = require("discord.js"); +const { EmbedBuilder, Colors } = require("discord.js"); const log = require("../../../structs/log.js"); const config = require('../../../Config/config.js') @@ -62,10 +62,10 @@ module.exports = { }); await newCode.save(); - const embed = new MessageEmbed() + const embed = new EmbedBuilder() .setTitle("Successfully Created Custom Game Code!") .setDescription("Your code has been created. You can now use it to host custom games.") - .setColor("GREEN") + .setColor(Colors.Green) .addFields([ { name: "Code", diff --git a/DiscordBot/commands/Admin/custommatchcodelist.js b/DiscordBot/commands/Admin/custommatchcodelist.js index ab689941..7b717265 100644 --- a/DiscordBot/commands/Admin/custommatchcodelist.js +++ b/DiscordBot/commands/Admin/custommatchcodelist.js @@ -1,5 +1,5 @@ const MMCodes = require("../../../model/mmcodes.js"); -const { MessageEmbed } = require("discord.js"); +const { EmbedBuilder, Colors } = require("discord.js"); const log = require("../../../structs/log.js"); const config = require('../../../Config/config.js') @@ -20,10 +20,10 @@ module.exports = { return interaction.reply({ content: "No custom matchmaking codes found.", ephemeral: true }); } - const embed = new MessageEmbed() + const embed = new EmbedBuilder() .setTitle("Custom Matchmaking Codes") .setDescription("Here is the list of all custom matchmaking codes:") - .setColor("GREEN") + .setColor(Colors.Green) .setTimestamp() .setThumbnail("https://i.imgur.com/2RImwlb.png") .setFooter({ diff --git a/DiscordBot/commands/Admin/removeall.js b/DiscordBot/commands/Admin/removeall.js index c74736e8..7b66335f 100644 --- a/DiscordBot/commands/Admin/removeall.js +++ b/DiscordBot/commands/Admin/removeall.js @@ -1,4 +1,4 @@ -const { MessageEmbed } = require("discord.js"); +const { EmbedBuilder, Colors } = require("discord.js"); const path = require("path"); const fs = require("fs"); const Users = require('../../../model/user.js'); @@ -52,10 +52,10 @@ module.exports = { } }); - const embed = new MessageEmbed() + const embed = new EmbedBuilder() .setTitle("Full Locker Removed") .setDescription("Successfully removed all skins to the selected account") - .setColor("GREEN") + .setColor(Colors.Green) .setFooter({ text: "Reload Backend", iconURL: "https://i.imgur.com/2RImwlb.png" diff --git a/DiscordBot/commands/User/change-email.js b/DiscordBot/commands/User/change-email.js index fcd36e77..f5961d55 100644 --- a/DiscordBot/commands/User/change-email.js +++ b/DiscordBot/commands/User/change-email.js @@ -1,4 +1,4 @@ -const { MessageEmbed } = require("discord.js"); +const { EmbedBuilder, Colors } = require("discord.js"); const Users = require('../../../model/user.js'); const functions = require("../../../structs/functions.js"); @@ -52,10 +52,10 @@ module.exports = { await functions.UpdateTokens(); } - const embed = new MessageEmbed() + const embed = new EmbedBuilder() .setTitle("Email changed") .setDescription("Your account email has been changed.") - .setColor("GREEN") + .setColor(Colors.Green) .setFooter({ text: "Reload Backend", iconURL: "https://i.imgur.com/2RImwlb.png", diff --git a/DiscordBot/commands/User/change-password.js b/DiscordBot/commands/User/change-password.js index 7821d3dd..b399d98d 100644 --- a/DiscordBot/commands/User/change-password.js +++ b/DiscordBot/commands/User/change-password.js @@ -1,4 +1,4 @@ -const MessageEmbed = require("discord.js"); +const { EmbedBuilder, Colors } = require("discord.js"); const User = require("../../../model/user.js"); const functions = require("../../../structs/functions.js"); const bcrypt = require("bcryptjs"); @@ -49,10 +49,10 @@ module.exports = { await functions.UpdateTokens(); } - const embed = new MessageEmbed() + const embed = new EmbedBuilder() .setTitle("Password changed") .setDescription("Your account password has been changed.") - .setColor("GREEN") + .setColor(Colors.Green) .setFooter({ text: "Reload Backend", iconURL: "https://i.imgur.com/2RImwlb.png", diff --git a/DiscordBot/commands/User/change-username.js b/DiscordBot/commands/User/change-username.js index dd58ad1a..e3b5db36 100644 --- a/DiscordBot/commands/User/change-username.js +++ b/DiscordBot/commands/User/change-username.js @@ -1,4 +1,4 @@ -const { MessageEmbed } = require("discord.js"); +const { EmbedBuilder, Colors } = require("discord.js"); const User = require("../../../model/user.js"); const Badwords = require("bad-words"); const functions = require("../../../structs/functions.js"); @@ -58,10 +58,10 @@ module.exports = { await functions.UpdateTokens(); } - const embed = new MessageEmbed() + const embed = new EmbedBuilder() .setTitle("Username changed") .setDescription(`Your account username has been changed to **${username}**.`) - .setColor("GREEN") + .setColor(Colors.Green) .setFooter({ text: "Reload Backend", iconURL: "https://i.imgur.com/2RImwlb.png", diff --git a/DiscordBot/commands/User/claimvbucks.js b/DiscordBot/commands/User/claimvbucks.js index 487b92bd..1a931888 100644 --- a/DiscordBot/commands/User/claimvbucks.js +++ b/DiscordBot/commands/User/claimvbucks.js @@ -1,4 +1,4 @@ -const { MessageEmbed } = require("discord.js"); +const { EmbedBuilder } = require("discord.js"); const Users = require('../../../model/user.js'); const Profiles = require('../../../model/profiles.js'); const log = require("../../../structs/log.js"); @@ -59,7 +59,7 @@ module.exports = { } }); - const embed = new MessageEmbed() + const embed = new EmbedBuilder() .setTitle("Daily V-Bucks Claimed!") .setDescription(`You have claimed your daily **250 V-Bucks**!`) .setThumbnail("https://i.imgur.com/yLbihQa.png") diff --git a/DiscordBot/commands/User/create.js b/DiscordBot/commands/User/create.js index 0389dfee..732d5795 100644 --- a/DiscordBot/commands/User/create.js +++ b/DiscordBot/commands/User/create.js @@ -1,4 +1,4 @@ -const { MessageEmbed } = require("discord.js"); +const { EmbedBuilder } = require("discord.js"); const User = require("../../../model/user.js") const functions = require("../../../structs/functions.js"); @@ -67,7 +67,7 @@ module.exports = { } await functions.registerUser(discordId, username, email, password).then(resp => { - let embed = new MessageEmbed() + let embed = new EmbedBuilder() .setColor(resp.status >= 400 ? "#ff0000" : "#56ff00") .setThumbnail(interaction.user.avatarURL({ format: 'png', dynamic: true, size: 256 })) .addFields({ diff --git a/DiscordBot/commands/User/details.js b/DiscordBot/commands/User/details.js index dada33b8..3763b77f 100644 --- a/DiscordBot/commands/User/details.js +++ b/DiscordBot/commands/User/details.js @@ -1,4 +1,4 @@ -const { MessageEmbed } = require("discord.js"); +const { EmbedBuilder, Colors } = require("discord.js"); const User = require("../../../model/user.js"); const Profiles = require('../../../model/profiles.js'); @@ -17,8 +17,8 @@ module.exports = { let onlineStatus = global.Clients.some(i => i.accountId == user.accountId); - let embed = new MessageEmbed() - .setColor("GREEN") + let embed = new EmbedBuilder() + .setColor(Colors.Green) .setDescription("These are your account details") .setFields( { name: 'Username:', value: user.username }, diff --git a/DiscordBot/commands/User/exchange-code.js b/DiscordBot/commands/User/exchange-code.js index cdedf71e..f1a3a17a 100644 --- a/DiscordBot/commands/User/exchange-code.js +++ b/DiscordBot/commands/User/exchange-code.js @@ -1,4 +1,4 @@ -const { MessageEmbed } = require("discord.js"); +const { EmbedBuilder } = require("discord.js"); const User = require("../../../model/user.js"); const functions = require("../../../structs/functions.js"); @@ -27,7 +27,7 @@ module.exports = { if (exchangeCode != -1) global.exchangeCodes.splice(exchangeCode, 1); }, 300000) // remove exchange code in 5 minutes if unused - let embed = new MessageEmbed() + let embed = new EmbedBuilder() .setColor("#56ff00") .setAuthor({ name: interaction.user.tag, iconURL: interaction.user.avatarURL() }) .setFields( diff --git a/DiscordBot/commands/User/giftvbucks.js b/DiscordBot/commands/User/giftvbucks.js index 8e11faef..861fd0d6 100644 --- a/DiscordBot/commands/User/giftvbucks.js +++ b/DiscordBot/commands/User/giftvbucks.js @@ -1,4 +1,4 @@ -const { MessageEmbed } = require("discord.js"); +const { EmbedBuilder, Colors } = require("discord.js"); const Users = require("../../../model/user.js"); const Profiles = require("../../../model/profiles.js"); const log = require("../../../structs/log.js"); @@ -161,11 +161,11 @@ module.exports = { } ]; - const embed = new MessageEmbed() + const embed = new EmbedBuilder() .setTitle("Gift Sent!") .setDescription(`Gifted **${vbucks} V-Bucks** to **${recieveuser.username}**`) .setThumbnail("https://i.imgur.com/yLbihQa.png") - .setColor("GREEN") + .setColor(Colors.Green) .setFooter({ text: "Reload Backend", iconURL: "https://i.imgur.com/2RImwlb.png" diff --git a/DiscordBot/commands/User/lookup.js b/DiscordBot/commands/User/lookup.js index 9a43e58a..7f191be1 100644 --- a/DiscordBot/commands/User/lookup.js +++ b/DiscordBot/commands/User/lookup.js @@ -1,4 +1,4 @@ -const { MessageEmbed } = require("discord.js"); +const { EmbedBuilder, Colors } = require("discord.js"); const Users = require("../../../model/user.js"); module.exports = { @@ -25,8 +25,8 @@ module.exports = { let onlineStatus = global.Clients.some(i => i.accountId == user.accountId); - let embed = new MessageEmbed() - .setColor("GREEN") + let embed = new EmbedBuilder() + .setColor(Colors.Green) .setDescription(`**User Information:**\n- **Discord User:** <@${user.discordId}>\n- **DiscordID:** ${user.discordId}\n- **In-Game Username:** ${user.username}\n- **Banned:** ${user.banned ? "Yes" : "No"}\n- **Online:** ${onlineStatus ? "Yes" : "No"}`) .setFooter({ text: "Reload Backend", diff --git a/DiscordBot/commands/User/vbucksamount.js b/DiscordBot/commands/User/vbucksamount.js index 0c799583..c8cee91c 100644 --- a/DiscordBot/commands/User/vbucksamount.js +++ b/DiscordBot/commands/User/vbucksamount.js @@ -1,4 +1,4 @@ -const { MessageEmbed } = require("discord.js"); +const { EmbedBuilder, Colors } = require("discord.js"); const Profiles = require('../../../model/profiles.js'); const Users = require('../../../model/user.js'); @@ -18,7 +18,7 @@ module.exports = { { return interaction.editReply({ content: "You are not registered!", ephemeral: true }); } - const embed = new MessageEmbed() + const embed = new EmbedBuilder() .setTitle("V-Bucks Count:") .setDescription(`You currently have **` + currency + " V-Bucks** in your Account!") .setTimestamp() @@ -27,7 +27,7 @@ module.exports = { text: "Reload Backend", iconURL: "https://i.imgur.com/2RImwlb.png" }) - .setColor("WHITE") + .setColor(Colors.White) await interaction.editReply({ embeds: [embed], ephemeral: true }); } } \ No newline at end of file diff --git a/DiscordBot/index.js b/DiscordBot/index.js index f416a0ea..615d9b90 100644 --- a/DiscordBot/index.js +++ b/DiscordBot/index.js @@ -1,10 +1,11 @@ -const { Client, GatewayIntentBits, Partials, MessageEmbed } = require("discord.js"); +const { Client, GatewayIntentBits, Partials, EmbedBuilder, Colors, ActivityType } = require("discord.js"); const client = new Client({ intents: [GatewayIntentBits.Guilds, GatewayIntentBits.GuildMessages, GatewayIntentBits.GuildMembers, GatewayIntentBits.GuildBans] }); const fs = require("fs"); const path = require("path"); const config = require('../Config/config.js'); const log = require("../structs/log.js"); const Users = require("../model/user.js"); +const functions = require("../structs/functions.js"); client.once("clientReady", () => { log.bot("Bot is up and running!"); @@ -17,10 +18,10 @@ client.once("clientReady", () => { if (!channel) { log.error(`Cannot find the channel with ID ${config.bBackendStatusChannelId}`); } else { - const embed = new MessageEmbed() + const embed = new EmbedBuilder() .setTitle("Backend Online") .setDescription("Reload Backend is now online") - .setColor("GREEN") + .setColor(Colors.Green) .setThumbnail("https://i.imgur.com/2RImwlb.png") .setFooter({ text: "Reload Backend", @@ -38,7 +39,7 @@ client.once("clientReady", () => { if (config.discord.bEnableInGamePlayerCount) { function updateBotStatus() { if (global.Clients && Array.isArray(global.Clients)) { - client.user.setActivity(`${global.Clients.length} player(s)`, { type: "WATCHING" }); + client.user.setActivity(`${global.Clients.length} player(s)`, { type: ActivityType.Watching }); } } @@ -64,7 +65,7 @@ client.once("clientReady", () => { }); client.on("interactionCreate", async interaction => { - if (!interaction.isApplicationCommand()) return; + if (!interaction.isChatInputCommand()) return; const executeCommand = (dir, commandName) => { const commandPath = path.join(dir, commandName + ".js"); From 2f1f6635518916593751abb4dd6d0e46d5190412 Mon Sep 17 00:00:00 2001 From: kxtzownsu Date: Sat, 25 Jul 2026 12:05:18 -0400 Subject: [PATCH 3/7] oops I forgot I did this Signed-off-by: kxtzownsu --- Api/launcher.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Api/launcher.js b/Api/launcher.js index a6d80202..d95ee791 100644 --- a/Api/launcher.js +++ b/Api/launcher.js @@ -6,8 +6,9 @@ const log = require("../structs/log.js"); const app = express.Router(); -app.post("/api/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("/api/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.'); From 59262b133cc192ac0430d517e0d32358bea76646 Mon Sep 17 00:00:00 2001 From: kxtzownsu Date: Sat, 25 Jul 2026 12:18:25 -0400 Subject: [PATCH 4/7] update readme with `.env` stuff Signed-off-by: kxtzownsu --- README.md | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index d3e67933..4d6c533e 100644 --- a/README.md +++ b/README.md @@ -64,6 +64,8 @@ Created by [Burlone](https://github.com/burlone0), This is a modded backend, all - [ ] Create a support with save the world - [ ] Create a support with creative +> **Note:** `.env` is an override file, not a full config. Only put the configuration values you want to change in there. `.env.example` & `Config/config.js` already specify all of the default options. + ## Discord Bot Commands ### User Commands: - `/create {email} {username} {password}` - Creates an account on the backend (You can only create 1 account). @@ -94,11 +96,13 @@ Created by [Burlone](https://github.com/burlone0), This is a modded backend, all - `/removevbucks {user} {vbucks}` - Lets you change a users amount of vbucks - `/removeitem {user} {cosmeticname}` - Allows you to remove a cosmetic (skin, pickaxe, glider, etc.) from a user - `/unban {targetUsername}` - Unban a user from the backend by their username. + ### How to set up moderators? -1) Go to **.env** in the directory you extracted Reload Backend into. -2) Open it, you should see a **MODERATORS** line in the file. -3) You have to get your discord id and replace `discordId` with it. -4) You can set multiple moderators like this `MODERATORS=discordId,discordId2`. +1) Go to/Create **.env** in the directory you extracted Reload Backend into. +2) Open it, it will either be blank or have your custom config if you already added some config options. +3) Get your moderator's discord IDs +4) Add them to the file like this `MODERATORS=discordId,discordId2`. +P.S: you can add only one moderator, or multiple, if you want. They must all however be on the same line. You cannot have multiple `MODERATORS` lines. ### How to setup multiple gameservers 1) Go to **.env** in the directory you extracted Reload Backend into. @@ -106,12 +110,19 @@ Created by [Burlone](https://github.com/burlone0), This is a modded backend, all 3) To add more gameservers you will have to do it like this `GAME_SERVER_IP=127.0.0.1:7777:playlist_defaultsolo,127.0.0.1:7777:playlist_defaultduo` 4) You have now added solos and duos to your matchmaking +### How to set up the Discord bot +1) Go to/Create **.env** in the directory you extracted Reload Backend into. +2) Open it, it will either be blank or have your custom config if you already added some config options. +3) Get your Discord bot token from the [Discord Developer Portal](https://discord.com/developers/applications) **(DO NOT SHARE THIS TOKEN)**. +4) Add it to the file like this `DISCORD_BOT_TOKEN=your-bot-token-here`. +P.S: if you don't want the Discord bot to run at all, set `DISCORD_USE_BOT=false` instead, and you can skip getting a token. + ## How to start Reload Backend 1) Install [NodeJS](https://nodejs.org/en/) and [MongoDB](https://www.mongodb.com/try/download/community). 2) **Download** and **Extract** Reload Backend to a safe location. 3) Run **"install_packages.bat"** to install all the required modules. -4) Copy **.env.example** to **.env** in the directory you extracted Reload Backend into. -5) Open it, set your discord bot token **(DO NOT SHARE THIS TOKEN)** in `DISCORD_BOT_TOKEN` and **save it**. The discord bot will be used for creating accounts and managing your account (You can disable the discord bot by setting `DISCORD_USE_BOT=false` in `.env`). +4) Go to/Create **.env** in the directory you extracted Reload Backend into. This file only needs the options you want to change from default, not every value found in `.env.example`. +5) Set up the Discord bot (see [How to set up the Discord bot](#how-to-set-up-the-discord-bot)), or set `DISCORD_USE_BOT=false` if you don't want to use it. 6) Run **"start.bat"**, if there is no errors, it should work. 7) Use something to redirect the Fortnite servers to **localhost:8080** (Which could be fiddler, ssl bypass that redirects servers, etc...) 8) When Fortnite launches and is connected to the backend, enter your email and password (or launch with an exchange code) then press login. It should let you in and everything should be working fine. From 35de2950efda10d6f91427df3ab747af081f7a06 Mon Sep 17 00:00:00 2001 From: kxtzownsu <116377025+kxtzownsu@users.noreply.github.com> Date: Sat, 25 Jul 2026 12:22:59 -0400 Subject: [PATCH 5/7] ok i like how this looks compared to the old one --- README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 4d6c533e..bf3cb186 100644 --- a/README.md +++ b/README.md @@ -64,8 +64,6 @@ Created by [Burlone](https://github.com/burlone0), This is a modded backend, all - [ ] Create a support with save the world - [ ] Create a support with creative -> **Note:** `.env` is an override file, not a full config. Only put the configuration values you want to change in there. `.env.example` & `Config/config.js` already specify all of the default options. - ## Discord Bot Commands ### User Commands: - `/create {email} {username} {password}` - Creates an account on the backend (You can only create 1 account). @@ -97,6 +95,9 @@ Created by [Burlone](https://github.com/burlone0), This is a modded backend, all - `/removeitem {user} {cosmeticname}` - Allows you to remove a cosmetic (skin, pickaxe, glider, etc.) from a user - `/unban {targetUsername}` - Unban a user from the backend by their username. +>[!IMPORTANT] +>**Note:** `.env` is an override file, not a full config. Only put the configuration values you want to change in there. `.env.example` & `Config/config.js` already specify all of the default options. + ### How to set up moderators? 1) Go to/Create **.env** in the directory you extracted Reload Backend into. 2) Open it, it will either be blank or have your custom config if you already added some config options. From 3b4980b6a70d220587459d0335a5bd9965d144a5 Mon Sep 17 00:00:00 2001 From: kxtzownsu Date: Sat, 25 Jul 2026 12:33:32 -0400 Subject: [PATCH 6/7] feat: add Linux instructions to README.md Signed-off-by: kxtzownsu --- README.md | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index bf3cb186..21496879 100644 --- a/README.md +++ b/README.md @@ -118,16 +118,34 @@ Created by [Burlone](https://github.com/burlone0), This is a modded backend, all 4) Add it to the file like this `DISCORD_BOT_TOKEN=your-bot-token-here`. P.S: if you don't want the Discord bot to run at all, set `DISCORD_USE_BOT=false` instead, and you can skip getting a token. -## How to start Reload Backend +>[!IMPORTANT] +>It is recommended, but not required, that you run your backend on the same machine you play Fortnite on. +>If you are trying to host multiple people, it is recommeneded to use a VPS and Linux, but it is not required to use Linux. Depending on the provider, a VPS can also run Windows if you do not want to use Linux. + +## How to start Reload Backend on Windows 1) Install [NodeJS](https://nodejs.org/en/) and [MongoDB](https://www.mongodb.com/try/download/community). 2) **Download** and **Extract** Reload Backend to a safe location. 3) Run **"install_packages.bat"** to install all the required modules. 4) Go to/Create **.env** in the directory you extracted Reload Backend into. This file only needs the options you want to change from default, not every value found in `.env.example`. 5) Set up the Discord bot (see [How to set up the Discord bot](#how-to-set-up-the-discord-bot)), or set `DISCORD_USE_BOT=false` if you don't want to use it. 6) Run **"start.bat"**, if there is no errors, it should work. -7) Use something to redirect the Fortnite servers to **localhost:8080** (Which could be fiddler, ssl bypass that redirects servers, etc...) +7) Use something to redirect the Fortnite servers to **localhost:3551** or whatever IP your backend is running on (Which could be fiddler, ssl bypass that redirects servers, etc...) 8) When Fortnite launches and is connected to the backend, enter your email and password (or launch with an exchange code) then press login. It should let you in and everything should be working fine. +## How to start Reload Backend on Linux +>[!IMPORTANT] +>Fortnite is natively ran on Windows. At the time of writing this, there is no way to play Fortnite on Linux. +>This is only if you do not want to host your backend on a Windows machine. +1) Install [NodeJS](https://nodejs.org/en/), [MongoDB](https://www.mongodb.com/try/download/community) and `git`. +2) In your home directory, or any other directory that you wish, run this command: `git clone https://github.com/Project-Reload/Reload-Backend` +3) Then, do `cd Reload-Backend` to enter the directory. +4) Run `npm i` (this will also work with `pnpm` if you prefer that) +5) Go to/Create **.env** in the directory you extracted Reload Backend into. This file only needs the options you want to change from default, not every value found in `.env.example`. +6) Set up the Discord bot (see [How to set up the Discord bot](#how-to-set-up-the-discord-bot)), or set `DISCORD_USE_BOT=false` if you don't want to use it. +7) Run `npm start` to start the backend (again, thiswill also work with `pnpm`) +8) Use something to redirect the Fortnite servers to **:3551** or whatever port you specified in `.env` (Which could be fiddler, ssl bypass that redirects servers, etc...) +9) When Fortnite launches and is connected to the backend, enter your email and password (or launch with an exchange code) then press login. It should let you in and everything should be working fine. + ## Caldera Service Recreates a service that is used for the startup of newer Fortnite builds. From 6af51c384f86c5df64cdbee91bcb87eb1c064bb4 Mon Sep 17 00:00:00 2001 From: kxtzownsu Date: Sat, 25 Jul 2026 12:38:50 -0400 Subject: [PATCH 7/7] feat: add XMPP_PORT{_HTTPS} to config options This allows us to change the XMPP port if needed. (e.g: routing via nginx) Signed-off-by: kxtzownsu --- .env.example | 2 ++ Config/config.js | 2 ++ xmpp/xmpp.js | 2 +- 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/.env.example b/.env.example index 0740d38f..e2a9d2aa 100644 --- a/.env.example +++ b/.env.example @@ -27,6 +27,8 @@ ENABLE_CROSS_BANS=false # if you want to use the backend on reboot, leave 3551 as the port PORT=3551 +XMPP_PORT=80 +XMPP_PORT_HTTPS=443 API_KEY=ur-api-key API_REASON_KILL=25 diff --git a/Config/config.js b/Config/config.js index e3c74697..c5c66060 100644 --- a/Config/config.js +++ b/Config/config.js @@ -48,6 +48,8 @@ const config = { bEnableCrossBans: bool('ENABLE_CROSS_BANS', false), port: num('PORT', 3551), + xmppPort: num('XMPP_PORT', 80), + xmppPortHTTPS: num('XMPP_PORT_HTTPS', 443), Api: { bApiKey: str('API_KEY', 'ur-api-key'), diff --git a/xmpp/xmpp.js b/xmpp/xmpp.js index 71be0509..ba483cbc 100644 --- a/xmpp/xmpp.js +++ b/xmpp/xmpp.js @@ -13,7 +13,7 @@ const User = require("../model/user.js"); const Friends = require("../model/friends.js"); const matchmaker = require("../matchmaker/matchmaker.js") -const port = config.bEnableHTTPS ? 443 : 3008; +const port = config.bEnableHTTPS ? config.xmppPortHTTPS : config.xmppPort; let wss; let httpsOptions;