Merge pull request #125 from PRO100KatYT/main

Pull Request #125
This commit is contained in:
Lawin
2024-05-24 22:41:25 +01:00
committed by GitHub
45 changed files with 304028 additions and 127620 deletions

View File

@@ -2,23 +2,31 @@ const Express = require("express");
const express = Express.Router();
const functions = require("./functions.js");
express.get("/content/api/pages/fortnite-game/spark-tracks", async (req, res) => {
const sparkTracks = require("./../responses/Athena/sparkTracks.json");
res.json(sparkTracks)
})
express.get("/content/api/pages/*", async (req, res) => {
const contentpages = functions.getContentPages(req);
res.json(contentpages)
})
express.post("/api/v1/fortnite-br/surfaces/motd/target", async (req, res) => {
const motdTarget = JSON.parse(JSON.stringify(require("./../responses/Athena/motdTarget.json")));
express.post("/api/v1/fortnite-br/surfaces/*/target", async (req, res) => {
const motd = JSON.parse(JSON.stringify(require("./../responses/Athena/motd.json")));
const fields = ["title", "body", "TeaserTitle", "FullScreenTitle", "FullScreenBody"];
try {
motdTarget.contentItems.forEach(item => {
item.contentFields.title = item.contentFields.title[req.body.language];
item.contentFields.body = item.contentFields.body[req.body.language];
motd.contentItems.forEach(item => {
fields.forEach(field => {
item.contentFields[field] = item.contentFields[field][req.body.language];
})
})
} catch (err) {}
res.json(motdTarget)
res.json(motd)
})
module.exports = express;

View File

@@ -2,15 +2,27 @@ const Express = require("express");
const express = Express.Router();
const discovery = require("./../responses/Athena/Discovery/discovery_frontend.json");
express.post("*/api/v2/discovery/surface/*", async (req, res) => {
res.json(discovery.v2);
});
express.post("*/discovery/surface/*", async (req, res) => {
res.json(discovery);
})
res.json(discovery.v1);
});
express.get("/fortnite/api/discovery/accessToken/:branch", async (req, res) => {
res.json({
"branchName": req.params.branch,
"appId": "Fortnite",
"token": "lawinstokenlol"
});
});
express.post("/links/api/fn/mnemonic", async (req, res) => {
var MnemonicArray = [];
for (var i in discovery.Panels[0].Pages[0].results) {
MnemonicArray.push(discovery.Panels[0].Pages[0].results[i].linkData)
for (var i in discovery.v2.Panels[1].Pages[0].results) {
MnemonicArray.push(discovery.v2.Panels[1].Pages[0].results[i].linkData)
}
res.json(MnemonicArray);
@@ -23,8 +35,8 @@ express.get("/links/api/fn/mnemonic/:playlist/related", async (req, res) => {
};
if (req.params.playlist) {
for (var i in discovery.Panels[0].Pages[0].results) {
var linkData = discovery.Panels[0].Pages[0].results[i].linkData;
for (var i in discovery.v2.Panels[1].Pages[0].results) {
var linkData = discovery.v2.Panels[1].Pages[0].results[i].linkData;
if (linkData.mnemonic == req.params.playlist) {
response.links[req.params.playlist] = linkData;
}
@@ -35,9 +47,9 @@ express.get("/links/api/fn/mnemonic/:playlist/related", async (req, res) => {
})
express.get("/links/api/fn/mnemonic/*", async (req, res) => {
for (var i in discovery.Panels[0].Pages[0].results) {
if (discovery.Panels[0].Pages[0].results[i].linkData.mnemonic == req.url.split("/").slice(-1)[0]) {
res.json(discovery.Panels[0].Pages[0].results[i].linkData);
for (var i in discovery.v2.Panels[1].Pages[0].results) {
if (discovery.v2.Panels[1].Pages[0].results[i].linkData.mnemonic == req.url.split("/").slice(-1)[0]) {
res.json(discovery.v2.Panels[1].Pages[0].results[i].linkData);
}
}
})

View File

@@ -75,7 +75,7 @@ function getItemShop() {
for (var value in CatalogConfig) {
if (Array.isArray(CatalogConfig[value].itemGrants)) {
if (CatalogConfig[value].itemGrants.length != 0) {
const CatalogEntry = {"devName":"","offerId":"","fulfillmentIds":[],"dailyLimit":-1,"weeklyLimit":-1,"monthlyLimit":-1,"categories":[],"prices":[{"currencyType":"MtxCurrency","currencySubType":"","regularPrice":0,"finalPrice":0,"saleExpiration":"9999-12-02T01:12:00Z","basePrice":0}],"meta":{"SectionId":"Featured","TileSize":"Small"},"matchFilter":"","filterWeight":0,"appStoreId":[],"requirements":[],"offerType":"StaticPrice","giftInfo":{"bIsEnabled":false,"forcedGiftBoxTemplateId":"","purchaseRequirements":[],"giftRecordIds":[]},"refundable":true,"metaInfo":[{"key":"SectionId","value":"Featured"},{"key":"TileSize","value":"Small"}],"displayAssetPath":"","itemGrants":[],"sortPriority":0,"catalogGroupPriority":0};
const CatalogEntry = {"devName":"","offerId":"","fulfillmentIds":[],"dailyLimit":-1,"weeklyLimit":-1,"monthlyLimit":-1,"categories":[],"prices":[{"currencyType":"MtxCurrency","currencySubType":"","regularPrice":0,"finalPrice":0,"saleExpiration":"9999-12-02T01:12:00Z","basePrice":0}],"meta":{"NewDisplayAssetPath":"","SectionId":"Featured","LayoutId":"LawinServer.99","TileSize":"Small","AnalyticOfferGroupId":"LawinServer/Attitude8","FirstSeen":"2/2/2020"},"matchFilter":"","filterWeight":0,"appStoreId":[],"requirements":[],"offerType":"StaticPrice","giftInfo":{"bIsEnabled":false,"forcedGiftBoxTemplateId":"","purchaseRequirements":[],"giftRecordIds":[]},"refundable":true,"metaInfo":[{"key":"NewDisplayAssetPath","value":"="},{"key":"SectionId","value":"Featured"},{"key":"LayoutId","value":"LawinServer.99"},{"key":"TileSize","value":"Small"},{"key":"AnalyticOfferGroupId","value":"LawinServer/Attitude8"},{"key":"FirstSeen","value":"2/2/2020"}],"displayAssetPath":"","itemGrants":[],"sortPriority":0,"catalogGroupPriority":0};
if (value.toLowerCase().startsWith("daily")) {
catalog.storefronts.forEach((storefront, i) => {
@@ -132,7 +132,7 @@ function getItemShop() {
CatalogEntry.prices[0].finalPrice = CatalogConfig[value].price
CatalogEntry.meta.TileSize = "Normal"
CatalogEntry.metaInfo[1].value = "Normal"
CatalogEntry.metaInfo[3].value = "Normal"
if (CatalogEntry.itemGrants.length != 0) {
catalog.storefronts[i].catalogEntries.push(CatalogEntry);
@@ -282,15 +282,18 @@ function getContentPages(req) {
contentpages.specialoffervideo.bSpecialOfferEnabled = "true";
}
} else if (memory.season == 24) {
backgrounds[0].backgroundimage = "https://cdn2.unrealengine.com/t-ch4s2-bp-lobby-4096x2048-edde08d15f7e.jpg"
}
else if (memory.season == 25) {
backgrounds[0].backgroundimage = "https://cdn2.unrealengine.com/t-ch4s2-bp-lobby-4096x2048-edde08d15f7e.jpg";
} else if (memory.season == 25) {
backgrounds[0].backgroundimage = "https://cdn2.unrealengine.com/s25-lobby-4k-4096x2048-4a832928e11f.jpg";
backgrounds[1].backgroundimage = "https://cdn2.unrealengine.com/fn-shop-ch4s3-04-1920x1080-785ce1d90213.png";
if (memory.build == 25.11) {
backgrounds[0].backgroundimage = "https://cdn2.unrealengine.com/t-s25-14dos-lobby-4096x2048-2be24969eee3.jpg";
}
} else if (memory.season == 27) {
backgrounds[0].stage = "rufus";
} else {
backgrounds[0].stage = "defaultnotris";
backgrounds[0].backgroundimage = "https://fortnite-public-service-prod11.ol.epicgames.com/images/lightlobbybg.png";
}
} catch (err) {}

View File

@@ -145,8 +145,10 @@ express.get("/socialban/api/public/v1/*", async (req, res) => {
});
})
express.get("/fortnite/api/game/v2/events/tournamentandhistory/*/EU/WindowsClient", async (req, res) => {
res.json({});
express.get("/fortnite/api/game/v2/events/tournamentandhistory/*", async (req, res) => {
const tournamentandhistory = require("./../responses/Athena/Tournament/tournamentandhistory.json");
res.json(tournamentandhistory)
})
express.get("/fortnite/api/statsv2/account/:accountId", async (req, res) => {
@@ -176,6 +178,22 @@ express.get("/fortnite/api/stats/accountId/:accountId/bulk/window/alltime", asyn
})
})
express.get("/d98eeaac-2bfa-4bf4-8a59-bdc95469c693", async (req, res) => {
res.json({
"playlist": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPE1QRCB4bWxucz0idXJuOm1wZWc6ZGFzaDpzY2hlbWE6bXBkOjIwMTEiIHhtbG5zOnhzaT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEtaW5zdGFuY2UiIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB4c2k6c2NoZW1hTG9jYXRpb249InVybjptcGVnOkRBU0g6c2NoZW1hOk1QRDoyMDExIGh0dHA6Ly9zdGFuZGFyZHMuaXNvLm9yZy9pdHRmL1B1YmxpY2x5QXZhaWxhYmxlU3RhbmRhcmRzL01QRUctREFTSF9zY2hlbWFfZmlsZXMvREFTSC1NUEQueHNkIiBwcm9maWxlcz0idXJuOm1wZWc6ZGFzaDpwcm9maWxlOmlzb2ZmLWxpdmU6MjAxMSIgdHlwZT0ic3RhdGljIiBtZWRpYVByZXNlbnRhdGlvbkR1cmF0aW9uPSJQVDMwLjIxM1MiIG1heFNlZ21lbnREdXJhdGlvbj0iUFQyLjAwMFMiIG1pbkJ1ZmZlclRpbWU9IlBUNC4xMDZTIj4KICA8QmFzZVVSTD5odHRwczovL2ZvcnRuaXRlLXB1YmxpYy1zZXJ2aWNlLXByb2QxMS5vbC5lcGljZ2FtZXMuY29tL2F1ZGlvL0phbVRyYWNrcy9PR1JlbWl4LzwvQmFzZVVSTD4KICA8UHJvZ3JhbUluZm9ybWF0aW9uPjwvUHJvZ3JhbUluZm9ybWF0aW9uPgogIDxQZXJpb2QgaWQ9IjAiIHN0YXJ0PSJQVDBTIj4KICAgIDxBZGFwdGF0aW9uU2V0IGlkPSIwIiBjb250ZW50VHlwZT0iYXVkaW8iIHN0YXJ0V2l0aFNBUD0iMSIgc2VnbWVudEFsaWdubWVudD0idHJ1ZSIgYml0c3RyZWFtU3dpdGNoaW5nPSJ0cnVlIj4KICAgICAgPFJlcHJlc2VudGF0aW9uIGlkPSIwIiBhdWRpb1NhbXBsaW5nUmF0ZT0iNDgwMDAiIGJhbmR3aWR0aD0iMTI4MDAwIiBtaW1lVHlwZT0iYXVkaW8vbXA0IiBjb2RlY3M9Im1wNGEuNDAuMiI+CiAgICAgICAgPFNlZ21lbnRUZW1wbGF0ZSBkdXJhdGlvbj0iMjAwMDAwMCIgdGltZXNjYWxlPSIxMDAwMDAwIiBpbml0aWFsaXphdGlvbj0iaW5pdF8kUmVwcmVzZW50YXRpb25JRCQubXA0IiBtZWRpYT0ic2VnbWVudF8kUmVwcmVzZW50YXRpb25JRCRfJE51bWJlciQubTRzIiBzdGFydE51bWJlcj0iMSI+PC9TZWdtZW50VGVtcGxhdGU+CiAgICAgICAgPEF1ZGlvQ2hhbm5lbENvbmZpZ3VyYXRpb24gc2NoZW1lSWRVcmk9InVybjptcGVnOmRhc2g6MjMwMDM6MzphdWRpb19jaGFubmVsX2NvbmZpZ3VyYXRpb246MjAxMSIgdmFsdWU9IjIiPjwvQXVkaW9DaGFubmVsQ29uZmlndXJhdGlvbj4KICAgICAgPC9SZXByZXNlbnRhdGlvbj4KICAgIDwvQWRhcHRhdGlvblNldD4KICA8L1BlcmlvZD4KPC9NUEQ+",
"playlistType": "application/dash+xml",
"metadata": {
"assetId": "",
"baseUrls": [
"https://fortnite-public-service-prod11.ol.epicgames.com/audio/JamTracks/OGRemix/"
],
"supportsCaching": true,
"ucp": "a",
"version": "f2528fa1-5f30-42ff-8ae5-a03e3b023a0a"
}
})
})
express.post("/fortnite/api/feedback/*", async (req, res) => {
res.status(200);
res.end();
@@ -199,9 +217,60 @@ express.get("/fortnite/api/game/v2/enabled_features", async (req, res) => {
})
express.get("/api/v1/events/Fortnite/download/*", async (req, res) => {
res.json({})
const tournament = require("./../responses/Athena/Tournament/tournament.json");
res.json(tournament)
})
express.get("/api/v1/events/Fortnite/:eventId/history/:accountId", async (req, res) => {
var history = require("./../responses/Athena/Tournament/history.json");
history[0].scoreKey.eventId = req.params.eventId;
history[0].teamId = req.params.accountId;
history[0].teamAccountIds.push(req.params.accountId);
res.json(history)
})
express.get("/api/v1/leaderboards/Fortnite/:eventId/:eventWindowId/:accountId", async (req, res) => {
var leaderboards = require("./../responses/Athena/Tournament/leaderboard.json");
var heroNames = require("./../responses/Campaign/heroNames.json");
heroNames = heroNames.sort(() => Math.random() - 0.5);
heroNames.unshift(req.params.accountId);
leaderboards.eventId = req.params.eventId;
leaderboards.eventWindowId = req.params.eventWindowId;
var entryTemplate = leaderboards.entryTemplate;
for (var i = 0; i < heroNames.length; i++) {
var entry = { ...entryTemplate };
entry.eventId = req.params.eventId;
entry.eventWindowId = req.params.eventWindowId;
entry.teamAccountIds = [heroNames[i]];
entry.teamId = heroNames[i];
entry.pointsEarned = entry.score = 69 - i;
var splittedPoints = Math.floor(Math.random() * entry.pointsEarned);
entry.pointBreakdown = {
"PLACEMENT_STAT_INDEX:13": {
"timesAchieved": 13,
"pointsEarned": splittedPoints
},
"TEAM_ELIMS_STAT_INDEX:37": {
"timesAchieved": 13,
"pointsEarned": entry.pointsEarned - splittedPoints
}
};
entry.rank = i + 1;
leaderboards.entries.push(entry)
}
res.json(leaderboards)
})
express.get("/fortnite/api/game/v2/twitch/*", async (req, res) => {
res.status(200);
res.end();
@@ -264,46 +333,13 @@ express.post("/fortnite/api/leaderboards/type/group/stat/:statName/window/:statW
});
express.post("/fortnite/api/leaderboards/type/global/stat/:statName/window/:statWindow", async (req, res) => {
var HeroNames = [
"Hawk",
"Banshee",
"Wildcat",
"Jonsey",
"Spitfire",
"Ramirez",
"Headhunter",
"Renegade",
"Harper",
"Knox",
"Hype",
"Bull",
"Hazard",
"Penny",
"Izza",
"Kyle",
"Luna",
"Crash",
"Edge",
"Scorpion",
"Scorch",
"Ken",
"Mari",
"Sarah",
"Grizzly",
"Eagle Eye",
"Southie",
"A.C.",
"Buzz",
"Quinn",
"Jess",
"Deadeye"
]
var heroNames = require("./../responses/Campaign/heroNames.json");
var entries = [];
for (var i = 0; i < HeroNames.length; i++) {
for (var i = 0; i < heroNames.length; i++) {
entries.push({
"accountId": HeroNames[i],
"accountId": heroNames[i],
"value": Math.floor(Math.random() * 68) + 1
})
}
@@ -480,7 +516,8 @@ express.get("/region", async (req, res) => {
// Parental Controls
express.all("/v1/epic-settings/public/users/*/values", async (req, res) => {
res.json({})
const epicsettings = require("./../responses/epic-settings.json");
res.json(epicsettings)
})
express.get("/fortnite/api/game/v2/br-inventory/account/*", async (req, res) => {

View File

@@ -716,7 +716,6 @@ express.post("/fortnite/api/game/v2/profile/*/client/SetPinnedQuests", async (re
// Replace Daily Quests
express.post("/fortnite/api/game/v2/profile/*/client/FortRerollDailyQuest", async (req, res) => {
const profile = require(`./../profiles/${req.query.profileId || "athena"}.json`);
var DailyQuestIDS = JSON.parse(JSON.stringify(require("./../responses/quests.json")));
// do not change any of these or you will end up breaking it
var ApplyProfileChanges = [];
@@ -725,13 +724,8 @@ express.post("/fortnite/api/game/v2/profile/*/client/FortRerollDailyQuest", asyn
var QueryRevision = req.query.rvn || -1;
var StatChanged = false;
if (req.query.profileId == "profile0" || req.query.profileId == "campaign") {
DailyQuestIDS = DailyQuestIDS.SaveTheWorld.Daily
}
if (req.query.profileId == "athena") {
DailyQuestIDS = DailyQuestIDS.BattleRoyale.Daily
}
var DailyQuestPath = req.query.profileId == "profile0" || req.query.profileId == "campaign" ? "./../responses/Campaign/quests.json" : "./../responses/Athena/quests.json";
var DailyQuestIDS = JSON.parse(JSON.stringify(require(DailyQuestPath))).Daily;
const NewQuestID = functions.MakeID();
var randomNumber = Math.floor(Math.random() * DailyQuestIDS.length);
@@ -753,19 +747,12 @@ express.post("/fortnite/api/game/v2/profile/*/client/FortRerollDailyQuest", asyn
"creation_time": new Date().toISOString(),
"level": -1,
"item_seen": false,
"playlists": [],
"sent_new_notification": false,
"challenge_bundle_id": "",
"xp_reward_scalar": 1,
"challenge_linked_quest_given": "",
"quest_pool": "",
"quest_state": "Active",
"bucket": "",
"last_state_change_time": new Date().toISOString(),
"challenge_linked_quest_parent": "",
"max_level_bonus": 0,
"xp": 0,
"quest_rarity": "uncommon",
"favorite": false
},
"quantity": 1
@@ -886,7 +873,8 @@ express.post("/fortnite/api/game/v2/profile/*/client/MarkNewQuestNotificationSen
// Check for new quests
express.post("/fortnite/api/game/v2/profile/*/client/ClientQuestLogin", async (req, res) => {
const profile = require(`./../profiles/${req.query.profileId || "athena"}.json`);
var QuestIDS = JSON.parse(JSON.stringify(require("./../responses/quests.json")));
var AthenaQuestIDS = JSON.parse(JSON.stringify(require("./../responses/Athena/quests.json")));
var CampaignQuestIDS = JSON.parse(JSON.stringify(require("./../responses/Campaign/quests.json")));
const memory = functions.GetVersionInfo(req);
// do not change any of these or you will end up breaking it
@@ -901,12 +889,14 @@ express.post("/fortnite/api/game/v2/profile/*/client/ClientQuestLogin", async (r
var DailyQuestIDS;
var SeasonQuestIDS;
const SeasonPrefix = memory.season < 10 ? `0${memory.season}` : memory.season;
try {
if (req.query.profileId == "profile0" || req.query.profileId == "campaign") {
DailyQuestIDS = QuestIDS.SaveTheWorld.Daily
DailyQuestIDS = CampaignQuestIDS.Daily
if (QuestIDS.SaveTheWorld.hasOwnProperty(`Season${memory.season}`)) {
SeasonQuestIDS = QuestIDS.SaveTheWorld[`Season${memory.season}`]
if (CampaignQuestIDS.hasOwnProperty(`Season${SeasonPrefix}`)) {
SeasonQuestIDS = CampaignQuestIDS[`Season${SeasonPrefix}`]
}
for (var key in profile.items) {
@@ -947,7 +937,6 @@ express.post("/fortnite/api/game/v2/profile/*/client/ClientQuestLogin", async (r
"last_state_change_time": new Date().toISOString(),
"level": -1,
"sent_new_notification": true,
"quest_rarity": "uncommon",
"xp_reward_scalar": 1
},
"quantity": 1
@@ -964,10 +953,10 @@ express.post("/fortnite/api/game/v2/profile/*/client/ClientQuestLogin", async (r
}
if (req.query.profileId == "athena") {
DailyQuestIDS = QuestIDS.BattleRoyale.Daily
DailyQuestIDS = AthenaQuestIDS.Daily
if (QuestIDS.BattleRoyale.hasOwnProperty(`Season${memory.season}`)) {
SeasonQuestIDS = QuestIDS.BattleRoyale[`Season${memory.season}`]
if (AthenaQuestIDS.hasOwnProperty(`Season${SeasonPrefix}`)) {
SeasonQuestIDS = AthenaQuestIDS[`Season${SeasonPrefix}`]
}
for (var key in profile.items) {
@@ -1010,19 +999,12 @@ express.post("/fortnite/api/game/v2/profile/*/client/ClientQuestLogin", async (r
"creation_time": new Date().toISOString(),
"level": -1,
"item_seen": false,
"playlists": [],
"sent_new_notification": false,
"challenge_bundle_id": "",
"xp_reward_scalar": 1,
"challenge_linked_quest_given": "",
"quest_pool": "",
"quest_state": "Active",
"bucket": "",
"last_state_change_time": new Date().toISOString(),
"challenge_linked_quest_parent": "",
"max_level_bonus": 0,
"xp": 0,
"quest_rarity": "uncommon",
"favorite": false
},
"quantity": 1
@@ -1051,8 +1033,8 @@ express.post("/fortnite/api/game/v2/profile/*/client/ClientQuestLogin", async (r
} catch (err) {}
for (var key in profile.items) {
if (key.split("")[0] == "S" && (Number.isInteger(Number(key.split("")[1]))) && (key.split("")[2] == "-" || (Number.isInteger(Number(key.split("")[2])) && key.split("")[3] == "-"))) {
if (!key.startsWith(`S${memory.season}-`)) {
if (key.startsWith("QS") && Number.isInteger(Number(key[2])) && Number.isInteger(Number(key[3])) && key[4] === "-") {
if (!key.startsWith(`QS${SeasonPrefix}-`)) {
delete profile.items[key];
ApplyProfileChanges.push({
@@ -1066,18 +1048,20 @@ express.post("/fortnite/api/game/v2/profile/*/client/ClientQuestLogin", async (r
}
if (SeasonQuestIDS) {
var QuestsToAdd = [];
if (req.query.profileId == "athena") {
for (var ChallengeBundleSchedule in SeasonQuestIDS.ChallengeBundleSchedules) {
if (profile.items.hasOwnProperty(ChallengeBundleSchedule.itemGuid)) {
for (var ChallengeBundleScheduleID in SeasonQuestIDS.ChallengeBundleSchedules) {
if (profile.items.hasOwnProperty(ChallengeBundleScheduleID)) {
ApplyProfileChanges.push({
"changeType": "itemRemoved",
"itemId": ChallengeBundleSchedule.itemGuid
"itemId": ChallengeBundleScheduleID
})
}
ChallengeBundleSchedule = SeasonQuestIDS.ChallengeBundleSchedules[ChallengeBundleSchedule];
var ChallengeBundleSchedule = SeasonQuestIDS.ChallengeBundleSchedules[ChallengeBundleScheduleID];
profile.items[ChallengeBundleSchedule.itemGuid] = {
profile.items[ChallengeBundleScheduleID] = {
"templateId": ChallengeBundleSchedule.templateId,
"attributes": {
"unlock_epoch": new Date().toISOString(),
@@ -1093,28 +1077,28 @@ express.post("/fortnite/api/game/v2/profile/*/client/ClientQuestLogin", async (r
ApplyProfileChanges.push({
"changeType": "itemAdded",
"itemId": ChallengeBundleSchedule.itemGuid,
"item": profile.items[ChallengeBundleSchedule.itemGuid]
"itemId": ChallengeBundleScheduleID,
"item": profile.items[ChallengeBundleScheduleID]
})
StatChanged = true;
}
for (var ChallengeBundle in SeasonQuestIDS.ChallengeBundles) {
if (profile.items.hasOwnProperty(ChallengeBundle.itemGuid)) {
for (var ChallengeBundleID in SeasonQuestIDS.ChallengeBundles) {
if (profile.items.hasOwnProperty(ChallengeBundleID)) {
ApplyProfileChanges.push({
"changeType": "itemRemoved",
"itemId": ChallengeBundle.itemGuid
"itemId": ChallengeBundleID
})
}
ChallengeBundle = SeasonQuestIDS.ChallengeBundles[ChallengeBundle];
var ChallengeBundle = SeasonQuestIDS.ChallengeBundles[ChallengeBundleID];
if (config.Profile.bCompletedSeasonalQuests == true && ChallengeBundle.hasOwnProperty("questStages")) {
ChallengeBundle.grantedquestinstanceids = ChallengeBundle.grantedquestinstanceids.concat(ChallengeBundle.questStages);
}
profile.items[ChallengeBundle.itemGuid] = {
profile.items[ChallengeBundleID] = {
"templateId": ChallengeBundle.templateId,
"attributes": {
"has_unlock_by_completion": false,
@@ -1133,77 +1117,93 @@ express.post("/fortnite/api/game/v2/profile/*/client/ClientQuestLogin", async (r
"quantity": 1
}
profile.items[ChallengeBundle.itemGuid].attributes.num_granted_bundle_quests = ChallengeBundle.grantedquestinstanceids.length;
QuestsToAdd = QuestsToAdd.concat(ChallengeBundle.grantedquestinstanceids);
profile.items[ChallengeBundleID].attributes.num_granted_bundle_quests = ChallengeBundle.grantedquestinstanceids.length;
if (config.Profile.bCompletedSeasonalQuests == true) {
profile.items[ChallengeBundle.itemGuid].attributes.num_quests_completed = ChallengeBundle.grantedquestinstanceids.length;
profile.items[ChallengeBundle.itemGuid].attributes.num_progress_quests_completed = ChallengeBundle.grantedquestinstanceids.length;
profile.items[ChallengeBundleID].attributes.num_quests_completed = ChallengeBundle.grantedquestinstanceids.length;
profile.items[ChallengeBundleID].attributes.num_progress_quests_completed = ChallengeBundle.grantedquestinstanceids.length;
}
ApplyProfileChanges.push({
"changeType": "itemAdded",
"itemId": ChallengeBundle.itemGuid,
"item": profile.items[ChallengeBundle.itemGuid]
"itemId": ChallengeBundleID,
"item": profile.items[ChallengeBundleID]
})
StatChanged = true;
}
} else { // For STW just get all the Quests available due to no ChallengeBundles
for (var key in SeasonQuestIDS.Quests) {
QuestsToAdd.push(key)
}
}
for (var Quest in SeasonQuestIDS.Quests) {
if (profile.items.hasOwnProperty(Quest.itemGuid)) {
function ParseQuest(QuestID) {
var Quest = SeasonQuestIDS.Quests[QuestID];
if (profile.items.hasOwnProperty(QuestID)) {
ApplyProfileChanges.push({
"changeType": "itemRemoved",
"itemId": Quest.itemGuid
"itemId": QuestID
})
}
Quest = SeasonQuestIDS.Quests[Quest];
profile.items[Quest.itemGuid] = {
profile.items[QuestID] = {
"templateId": Quest.templateId,
"attributes": {
"creation_time": new Date().toISOString(),
"level": -1,
"item_seen": true,
"playlists": [],
"sent_new_notification": true,
"challenge_bundle_id": Quest.challenge_bundle_id || "",
"xp_reward_scalar": 1,
"challenge_linked_quest_given": "",
"quest_pool": "",
"quest_state": "Active",
"bucket": "",
"last_state_change_time": new Date().toISOString(),
"challenge_linked_quest_parent": "",
"max_level_bonus": 0,
"xp": 0,
"quest_rarity": "uncommon",
"favorite": false
},
"quantity": 1
}
if (config.Profile.bCompletedSeasonalQuests == true) {
profile.items[Quest.itemGuid].attributes.quest_state = "Claimed";
profile.items[QuestID].attributes.quest_state = "Claimed";
if (Quest.hasOwnProperty("rewards")) {
for (var reward in Quest.rewards) {
if (Quest.rewards[reward].templateId.startsWith("Quest:")) {
for (var Q in SeasonQuestIDS.Quests) {
if (SeasonQuestIDS.Quests[Q].templateId == Quest.rewards[reward].templateId) {
SeasonQuestIDS.ChallengeBundles[SeasonQuestIDS.Quests[Q].challenge_bundle_id].grantedquestinstanceids.push(Q)
ParseQuest(Q)
}
}
}
}
}
}
for (var i in Quest.objectives) {
if (config.Profile.bCompletedSeasonalQuests == true) {
profile.items[Quest.itemGuid].attributes[`completion_${Quest.objectives[i].name.toLowerCase()}`] = Quest.objectives[i].count;
profile.items[QuestID].attributes[`completion_${i}`] = Quest.objectives[i];
} else {
profile.items[Quest.itemGuid].attributes[`completion_${Quest.objectives[i].name.toLowerCase()}`] = 0;
profile.items[QuestID].attributes[`completion_${i}`] = 0;
}
}
ApplyProfileChanges.push({
"changeType": "itemAdded",
"itemId": Quest.itemGuid,
"item": profile.items[Quest.itemGuid]
"itemId": QuestID,
"item": profile.items[QuestID]
})
StatChanged = true;
}
for (var Quest in QuestsToAdd) {
ParseQuest(QuestsToAdd[Quest])
}
}
if (StatChanged == true) {
@@ -7875,6 +7875,153 @@ express.post("/fortnite/api/game/v2/profile/*/client/SetCosmeticLockerSlot", asy
res.end();
});
// Set BR Locker 3
express.post("/fortnite/api/game/v2/profile/*/client/PutModularCosmeticLoadout", async (req, res) => {
const profile = require(`./../profiles/${req.query.profileId || "athena"}.json`);
// do not change any of these or you will end up breaking it
var ApplyProfileChanges = [];
var BaseRevision = profile.rvn || 0;
var QueryRevision = req.query.rvn || -1;
var StatChanged = false;
if (!profile.stats.attributes.hasOwnProperty("loadout_presets")) {
profile.stats.attributes.loadout_presets = {};
ApplyProfileChanges.push({
"changeType": "statModified",
"name": "loadout_presets",
"value": {}
})
StatChanged = true;
}
if (!profile.stats.attributes.loadout_presets.hasOwnProperty(req.body.loadoutType)) {
const NewLoadoutID = functions.MakeID();
profile.items[NewLoadoutID] = {
"templateId": req.body.loadoutType,
"attributes": {},
"quantity": 1
}
ApplyProfileChanges.push({
"changeType": "itemAdded",
"itemId": NewLoadoutID,
"item": profile.items[NewLoadoutID]
})
profile.stats.attributes.loadout_presets[req.body.loadoutType] = {
[req.body.presetId]: NewLoadoutID
};
ApplyProfileChanges.push({
"changeType": "statModified",
"name": "loadout_presets",
"value": profile.stats.attributes.loadout_presets
})
StatChanged = true;
}
var LoadoutGUID = [];
try {
LoadoutGUID = profile.stats.attributes.loadout_presets[req.body.loadoutType][req.body.presetId];
profile.items[LoadoutGUID].attributes = JSON.parse(req.body.loadoutData);
ApplyProfileChanges.push({
"changeType": "itemAttrChanged",
"itemId": LoadoutGUID,
"attributeName": "slots",
"attributeValue": profile.items[LoadoutGUID].attributes.slots
})
StatChanged = true;
} catch (err) {}
if (StatChanged == true) {
profile.rvn += 1;
profile.commandRevision += 1;
fs.writeFileSync(`./profiles/${req.query.profileId || "athena"}.json`, JSON.stringify(profile, null, 2));
}
// this doesn't work properly on version v12.20 and above but whatever
if (QueryRevision != BaseRevision) {
ApplyProfileChanges = [{
"changeType": "fullProfileUpdate",
"profile": profile
}];
}
res.json({
"profileRevision": profile.rvn || 0,
"profileId": req.query.profileId || "athena",
"profileChangesBaseRevision": BaseRevision,
"profileChanges": ApplyProfileChanges,
"profileCommandRevision": profile.commandRevision || 0,
"serverTime": new Date().toISOString(),
"responseVersion": 1
})
res.end();
});
// Set Active Archetype (e.g. main vehicle in v30.00+)
express.post("/fortnite/api/game/v2/profile/*/client/SetActiveArchetype", async (req, res) => {
const profile = require(`./../profiles/${req.query.profileId || "athena"}.json`);
// do not change any of these or you will end up breaking it
var ApplyProfileChanges = [];
var BaseRevision = profile.rvn || 0;
var QueryRevision = req.query.rvn || -1;
var StatChanged = false;
if (req.body.archetypeGroup && req.body.archetype) {
if (!profile.stats.attributes.hasOwnProperty("loadout_archetype_values")) {
profile.stats.attributes.loadout_archetype_values = {}
}
profile.stats.attributes.loadout_archetype_values[req.body.archetypeGroup] = req.body.archetype;
StatChanged = true;
}
if (StatChanged == true) {
profile.rvn += 1;
profile.commandRevision += 1;
ApplyProfileChanges.push({
"changeType": "statModified",
"name": "loadout_archetype_values",
"value": profile.stats.attributes.loadout_archetype_values
})
fs.writeFileSync(`./profiles/${req.query.profileId || "athena"}.json`, JSON.stringify(profile, null, 2));
}
// this doesn't work properly on version v12.20 and above but whatever
if (QueryRevision != BaseRevision) {
ApplyProfileChanges = [{
"changeType": "fullProfileUpdate",
"profile": profile
}];
}
res.json({
"profileRevision": profile.rvn || 0,
"profileId": req.query.profileId || "athena",
"profileChangesBaseRevision": BaseRevision,
"profileChanges": ApplyProfileChanges,
"profileCommandRevision": profile.commandRevision || 0,
"serverTime": new Date().toISOString(),
"responseVersion": 1
})
res.end();
});
// Set hero variants STW
express.post("/fortnite/api/game/v2/profile/*/client/SetHeroCosmeticVariants", async (req, res) => {
const profile = require(`./../profiles/${req.query.profileId || "campaign"}.json`);

File diff suppressed because it is too large Load Diff