Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 50405f36a7 | |||
| 2f87725282 |
@ -1,5 +1,3 @@
|
|||||||
export const EPOCH = 1734307200_000; // Monday, Dec 16, 2024 @ 00:00 UTC+0; should logically be the start of winter in 1999 iteration 0
|
|
||||||
|
|
||||||
const millisecondsPerSecond = 1000;
|
const millisecondsPerSecond = 1000;
|
||||||
const secondsPerMinute = 60;
|
const secondsPerMinute = 60;
|
||||||
const minutesPerHour = 60;
|
const minutesPerHour = 60;
|
||||||
|
|||||||
@ -1,17 +1,9 @@
|
|||||||
import type { RequestHandler } from "express";
|
import type { RequestHandler } from "express";
|
||||||
import { deleteSession } from "../../managers/sessionManager.ts";
|
import { deleteSession } from "../../managers/sessionManager.ts";
|
||||||
import { getAccountForRequest } from "../../services/loginService.ts";
|
|
||||||
import { version_compare } from "../../helpers/inventoryHelpers.ts";
|
|
||||||
|
|
||||||
const deleteSessionController: RequestHandler = async (_req, res) => {
|
const deleteSessionController: RequestHandler = (_req, res) => {
|
||||||
const account = await getAccountForRequest(_req);
|
|
||||||
deleteSession(_req.query.sessionId as string);
|
deleteSession(_req.query.sessionId as string);
|
||||||
if (account.BuildLabel && version_compare(account.BuildLabel, "2016.07.08.16.56") < 0) {
|
res.sendStatus(200);
|
||||||
// Pre-Specters of the Rail
|
|
||||||
res.send(_req.query.sessionId as string); // Unsure if this is correct, but the client is chill with it
|
|
||||||
} else {
|
|
||||||
res.sendStatus(200);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export { deleteSessionController };
|
export { deleteSessionController };
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
import type { RequestHandler } from "express";
|
import type { RequestHandler } from "express";
|
||||||
import { getAccountIdForRequest } from "../../services/loginService.ts";
|
import { getAccountIdForRequest } from "../../services/loginService.ts";
|
||||||
import { getInventory } from "../../services/inventoryService.ts";
|
import { getInventory } from "../../services/inventoryService.ts";
|
||||||
import { getSeasonChallengePools, getWorldState, pushWeeklyActs } from "../../services/worldStateService.ts";
|
import { EPOCH, getSeasonChallengePools, getWorldState, pushWeeklyActs } from "../../services/worldStateService.ts";
|
||||||
import { EPOCH, unixTimesInMs } from "../../constants/timeConstants.ts";
|
import { unixTimesInMs } from "../../constants/timeConstants.ts";
|
||||||
import type { ISeasonChallenge } from "../../types/worldStateTypes.ts";
|
import type { ISeasonChallenge } from "../../types/worldStateTypes.ts";
|
||||||
import { ExportChallenges } from "warframe-public-export-plus";
|
import { ExportChallenges } from "warframe-public-export-plus";
|
||||||
|
|
||||||
|
|||||||
@ -13,8 +13,8 @@ const hostSessionController: RequestHandler = async (req, res) => {
|
|||||||
const session = createNewSession(hostSessionRequest, account._id);
|
const session = createNewSession(hostSessionRequest, account._id);
|
||||||
logger.debug(`New Session Created`, { session });
|
logger.debug(`New Session Created`, { session });
|
||||||
|
|
||||||
if (account.BuildLabel && version_compare(account.BuildLabel, "2016.07.08.16.56") < 0) {
|
if (account.BuildLabel && version_compare(account.BuildLabel, "2015.03.21.08.17") < 0) {
|
||||||
// Pre-Specters of the Rail
|
// U15 or below
|
||||||
res.send(session.sessionId.toString());
|
res.send(session.sessionId.toString());
|
||||||
} else {
|
} else {
|
||||||
res.json({ sessionId: toOid2(session.sessionId, account.BuildLabel), rewardSeed: 99999999 });
|
res.json({ sessionId: toOid2(session.sessionId, account.BuildLabel), rewardSeed: 99999999 });
|
||||||
|
|||||||
@ -310,13 +310,12 @@ export const getInventoryResponse = async (
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (inventory.skipAllDialogue) {
|
if (inventory.skipAllDialogue) {
|
||||||
inventoryResponse.TauntHistory ??= [];
|
inventoryResponse.TauntHistory = [
|
||||||
if (!inventoryResponse.TauntHistory.find(x => x.node == "TreasureTutorial")) {
|
{
|
||||||
inventoryResponse.TauntHistory.push({
|
|
||||||
node: "TreasureTutorial",
|
node: "TreasureTutorial",
|
||||||
state: "TS_COMPLETED"
|
state: "TS_COMPLETED"
|
||||||
});
|
}
|
||||||
}
|
];
|
||||||
for (const str of allDialogue) {
|
for (const str of allDialogue) {
|
||||||
addString(inventoryResponse.NodeIntrosCompleted, str);
|
addString(inventoryResponse.NodeIntrosCompleted, str);
|
||||||
}
|
}
|
||||||
@ -354,11 +353,11 @@ export const getInventoryResponse = async (
|
|||||||
if (!xpBasedLevelCapDisabled) {
|
if (!xpBasedLevelCapDisabled) {
|
||||||
// This client has not been patched to accept any mastery rank, need to fake the XP.
|
// This client has not been patched to accept any mastery rank, need to fake the XP.
|
||||||
inventoryResponse.XPInfo = [];
|
inventoryResponse.XPInfo = [];
|
||||||
let numFrames = getExpRequiredForMr(Math.min(inventory.spoofMasteryRank, 5030)) / (30 * 200);
|
let numFrames = getExpRequiredForMr(Math.min(inventory.spoofMasteryRank, 5030)) / 6000;
|
||||||
while (numFrames-- > 0) {
|
while (numFrames-- > 0) {
|
||||||
inventoryResponse.XPInfo.push({
|
inventoryResponse.XPInfo.push({
|
||||||
ItemType: "/Lotus/Powersuits/Mag/Mag",
|
ItemType: "/Lotus/Powersuits/Mag/Mag",
|
||||||
XP: 900_000 // Enough for rank 30 as per https://wiki.warframe.com/w/Affinity
|
XP: 1_600_000
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -109,19 +109,12 @@ const createLoginResponse = (
|
|||||||
const resp: ILoginResponse = {
|
const resp: ILoginResponse = {
|
||||||
id: account.id,
|
id: account.id,
|
||||||
DisplayName: account.DisplayName,
|
DisplayName: account.DisplayName,
|
||||||
|
CountryCode: account.CountryCode,
|
||||||
AmazonAuthToken: account.AmazonAuthToken,
|
AmazonAuthToken: account.AmazonAuthToken,
|
||||||
AmazonRefreshToken: account.AmazonRefreshToken,
|
AmazonRefreshToken: account.AmazonRefreshToken,
|
||||||
Nonce: account.Nonce,
|
Nonce: account.Nonce,
|
||||||
BuildLabel: buildLabel
|
BuildLabel: buildLabel
|
||||||
};
|
};
|
||||||
if (version_compare(buildLabel, "2014.10.24.08.24") >= 0) {
|
|
||||||
// U15 and up
|
|
||||||
resp.CountryCode = account.CountryCode;
|
|
||||||
} else {
|
|
||||||
// U8
|
|
||||||
resp.NatHash = "0";
|
|
||||||
resp.SteamId = "0";
|
|
||||||
}
|
|
||||||
if (version_compare(buildLabel, "2015.02.13.10.41") >= 0) {
|
if (version_compare(buildLabel, "2015.02.13.10.41") >= 0) {
|
||||||
resp.NRS = [config.nrsAddress ?? myAddress];
|
resp.NRS = [config.nrsAddress ?? myAddress];
|
||||||
}
|
}
|
||||||
|
|||||||
@ -36,11 +36,6 @@ export const completeAllMissionsController: RequestHandler = async (req, res) =>
|
|||||||
}
|
}
|
||||||
addString(inventory.NodeIntrosCompleted, "TeshinHardModeUnlocked");
|
addString(inventory.NodeIntrosCompleted, "TeshinHardModeUnlocked");
|
||||||
addString(inventory.NodeIntrosCompleted, "CetusSyndicate_IntroJob");
|
addString(inventory.NodeIntrosCompleted, "CetusSyndicate_IntroJob");
|
||||||
let syndicate = inventory.Affiliations.find(x => x.Tag == "CetusSyndicate");
|
|
||||||
if (!syndicate) {
|
|
||||||
syndicate =
|
|
||||||
inventory.Affiliations[inventory.Affiliations.push({ Tag: "CetusSyndicate", Standing: 250, Title: 0 })]; // Non-zero standing avoids Konzu's "prove yourself" text. 250 is identical to newbie bounty + bonus
|
|
||||||
}
|
|
||||||
await inventory.save();
|
await inventory.save();
|
||||||
res.end();
|
res.end();
|
||||||
};
|
};
|
||||||
|
|||||||
@ -37,7 +37,7 @@ export const manageQuestsController: RequestHandler = async (req, res) => {
|
|||||||
switch (operation) {
|
switch (operation) {
|
||||||
case "completeAll": {
|
case "completeAll": {
|
||||||
for (const questKey of inventory.QuestKeys) {
|
for (const questKey of inventory.QuestKeys) {
|
||||||
await completeQuest(inventory, questKey.ItemType, undefined);
|
await completeQuest(inventory, questKey.ItemType);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -61,7 +61,6 @@ export const manageQuestsController: RequestHandler = async (req, res) => {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
inventory.QuestKeys.pull({ ItemType: questItemType });
|
inventory.QuestKeys.pull({ ItemType: questItemType });
|
||||||
if (inventory.ActiveQuest == questItemType) inventory.ActiveQuest = "";
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case "completeKey": {
|
case "completeKey": {
|
||||||
@ -72,7 +71,7 @@ export const manageQuestsController: RequestHandler = async (req, res) => {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
await completeQuest(inventory, questItemType, undefined);
|
await completeQuest(inventory, questItemType);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -137,7 +136,7 @@ export const manageQuestsController: RequestHandler = async (req, res) => {
|
|||||||
|
|
||||||
if (currentStage + 1 == questManifest.chainStages?.length) {
|
if (currentStage + 1 == questManifest.chainStages?.length) {
|
||||||
logger.debug(`Trying to complete last stage with nextStage, calling completeQuest instead`);
|
logger.debug(`Trying to complete last stage with nextStage, calling completeQuest instead`);
|
||||||
await completeQuest(inventory, questKey.ItemType, undefined, true);
|
await completeQuest(inventory, questKey.ItemType, true);
|
||||||
} else {
|
} else {
|
||||||
if (run > 0) {
|
if (run > 0) {
|
||||||
questKey.Progress[currentStage + 1].c = run;
|
questKey.Progress[currentStage + 1].c = run;
|
||||||
@ -151,14 +150,10 @@ export const manageQuestsController: RequestHandler = async (req, res) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (currentStage > 0) {
|
if (currentStage > 0) {
|
||||||
await giveKeyChainMissionReward(
|
await giveKeyChainMissionReward(inventory, {
|
||||||
inventory,
|
KeyChain: questKey.ItemType,
|
||||||
{
|
ChainStage: currentStage
|
||||||
KeyChain: questKey.ItemType,
|
});
|
||||||
ChainStage: currentStage
|
|
||||||
},
|
|
||||||
undefined
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -10,7 +10,6 @@ import { addPendingFriendController } from "../controllers/api/addPendingFriendC
|
|||||||
import { addToAllianceController } from "../controllers/api/addToAllianceController.ts";
|
import { addToAllianceController } from "../controllers/api/addToAllianceController.ts";
|
||||||
import { addToGuildController } from "../controllers/api/addToGuildController.ts";
|
import { addToGuildController } from "../controllers/api/addToGuildController.ts";
|
||||||
import { adoptPetController } from "../controllers/api/adoptPetController.ts";
|
import { adoptPetController } from "../controllers/api/adoptPetController.ts";
|
||||||
import { aggregateSessionsController } from "../controllers/dynamic/aggregateSessionsController.ts";
|
|
||||||
import { apartmentController } from "../controllers/api/apartmentController.ts";
|
import { apartmentController } from "../controllers/api/apartmentController.ts";
|
||||||
import { arcaneCommonController } from "../controllers/api/arcaneCommonController.ts";
|
import { arcaneCommonController } from "../controllers/api/arcaneCommonController.ts";
|
||||||
import { archonFusionController } from "../controllers/api/archonFusionController.ts";
|
import { archonFusionController } from "../controllers/api/archonFusionController.ts";
|
||||||
@ -171,7 +170,6 @@ import { upgradeOperatorController } from "../controllers/api/upgradeOperatorCon
|
|||||||
import { upgradesController } from "../controllers/api/upgradesController.ts";
|
import { upgradesController } from "../controllers/api/upgradesController.ts";
|
||||||
import { valenceSwapController } from "../controllers/api/valenceSwapController.ts";
|
import { valenceSwapController } from "../controllers/api/valenceSwapController.ts";
|
||||||
import { wishlistController } from "../controllers/api/wishlistController.ts";
|
import { wishlistController } from "../controllers/api/wishlistController.ts";
|
||||||
import { worldStateController } from "../controllers/dynamic/worldStateController.ts";
|
|
||||||
|
|
||||||
const apiRouter = express.Router();
|
const apiRouter = express.Router();
|
||||||
|
|
||||||
@ -237,7 +235,6 @@ apiRouter.get("/surveys.php", surveysController);
|
|||||||
apiRouter.get("/trading.php", tradingController);
|
apiRouter.get("/trading.php", tradingController);
|
||||||
apiRouter.get("/updateSession.php", updateSessionGetController);
|
apiRouter.get("/updateSession.php", updateSessionGetController);
|
||||||
apiRouter.get("/upgradeOperator.php", upgradeOperatorController);
|
apiRouter.get("/upgradeOperator.php", upgradeOperatorController);
|
||||||
apiRouter.get("/worldState.php", worldStateController); // U8
|
|
||||||
|
|
||||||
// post
|
// post
|
||||||
apiRouter.post("/abortDojoComponent.php", abortDojoComponentController);
|
apiRouter.post("/abortDojoComponent.php", abortDojoComponentController);
|
||||||
@ -249,7 +246,6 @@ apiRouter.post("/addPendingFriend.php", addPendingFriendController);
|
|||||||
apiRouter.post("/addToAlliance.php", addToAllianceController);
|
apiRouter.post("/addToAlliance.php", addToAllianceController);
|
||||||
apiRouter.post("/addToGuild.php", addToGuildController);
|
apiRouter.post("/addToGuild.php", addToGuildController);
|
||||||
apiRouter.post("/adoptPet.php", adoptPetController);
|
apiRouter.post("/adoptPet.php", adoptPetController);
|
||||||
apiRouter.post("/aggregateSessions.php", aggregateSessionsController); // Pre-Specters of the Rail builds
|
|
||||||
apiRouter.post("/arcaneCommon.php", arcaneCommonController);
|
apiRouter.post("/arcaneCommon.php", arcaneCommonController);
|
||||||
apiRouter.post("/archonFusion.php", archonFusionController);
|
apiRouter.post("/archonFusion.php", archonFusionController);
|
||||||
apiRouter.post("/artifacts.php", artifactsController);
|
apiRouter.post("/artifacts.php", artifactsController);
|
||||||
|
|||||||
@ -1,6 +1,5 @@
|
|||||||
import express from "express";
|
import express from "express";
|
||||||
import path from "path";
|
import path from "path";
|
||||||
import fs from "fs/promises";
|
|
||||||
import { repoDir, rootDir } from "../helpers/pathHelper.ts";
|
import { repoDir, rootDir } from "../helpers/pathHelper.ts";
|
||||||
import { args } from "../helpers/commandLineArguments.ts";
|
import { args } from "../helpers/commandLineArguments.ts";
|
||||||
|
|
||||||
@ -22,62 +21,50 @@ webuiRouter.use("/webui", (req, res, next) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Serve virtual routes
|
// Serve virtual routes
|
||||||
webuiRouter.get("/webui/inventory", async (_req, res) => {
|
webuiRouter.get("/webui/inventory", (_req, res) => {
|
||||||
res.set("Content-Type", "text/html;charset=utf8");
|
res.sendFile(path.join(baseDir, "static/webui/index.html"));
|
||||||
res.send(await fs.readFile(path.join(baseDir, "static/webui/index.html")));
|
|
||||||
});
|
});
|
||||||
webuiRouter.get("/webui/detailedView", async (_req, res) => {
|
webuiRouter.get("/webui/detailedView", (_req, res) => {
|
||||||
res.set("Content-Type", "text/html;charset=utf8");
|
res.sendFile(path.join(baseDir, "static/webui/index.html"));
|
||||||
res.send(await fs.readFile(path.join(baseDir, "static/webui/index.html")));
|
|
||||||
});
|
});
|
||||||
webuiRouter.get("/webui/mods", async (_req, res) => {
|
webuiRouter.get("/webui/mods", (_req, res) => {
|
||||||
res.set("Content-Type", "text/html;charset=utf8");
|
res.sendFile(path.join(baseDir, "static/webui/index.html"));
|
||||||
res.send(await fs.readFile(path.join(baseDir, "static/webui/index.html")));
|
|
||||||
});
|
});
|
||||||
webuiRouter.get("/webui/settings", async (_req, res) => {
|
webuiRouter.get("/webui/settings", (_req, res) => {
|
||||||
res.set("Content-Type", "text/html;charset=utf8");
|
res.sendFile(path.join(baseDir, "static/webui/index.html"));
|
||||||
res.send(await fs.readFile(path.join(baseDir, "static/webui/index.html")));
|
|
||||||
});
|
});
|
||||||
webuiRouter.get("/webui/quests", async (_req, res) => {
|
webuiRouter.get("/webui/quests", (_req, res) => {
|
||||||
res.set("Content-Type", "text/html;charset=utf8");
|
res.sendFile(path.join(baseDir, "static/webui/index.html"));
|
||||||
res.send(await fs.readFile(path.join(baseDir, "static/webui/index.html")));
|
|
||||||
});
|
});
|
||||||
webuiRouter.get("/webui/cheats", async (_req, res) => {
|
webuiRouter.get("/webui/cheats", (_req, res) => {
|
||||||
res.set("Content-Type", "text/html;charset=utf8");
|
res.sendFile(path.join(baseDir, "static/webui/index.html"));
|
||||||
res.send(await fs.readFile(path.join(baseDir, "static/webui/index.html")));
|
|
||||||
});
|
});
|
||||||
webuiRouter.get("/webui/import", async (_req, res) => {
|
webuiRouter.get("/webui/import", (_req, res) => {
|
||||||
res.set("Content-Type", "text/html;charset=utf8");
|
res.sendFile(path.join(baseDir, "static/webui/index.html"));
|
||||||
res.send(await fs.readFile(path.join(baseDir, "static/webui/index.html")));
|
|
||||||
});
|
});
|
||||||
webuiRouter.get("/webui/guildView", async (_req, res) => {
|
webuiRouter.get("/webui/guildView", (_req, res) => {
|
||||||
res.set("Content-Type", "text/html;charset=utf8");
|
res.sendFile(path.join(baseDir, "static/webui/index.html"));
|
||||||
res.send(await fs.readFile(path.join(baseDir, "static/webui/index.html")));
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// Serve static files
|
// Serve static files
|
||||||
webuiRouter.use("/webui", express.static(path.join(baseDir, "static/webui")));
|
webuiRouter.use("/webui", express.static(path.join(baseDir, "static/webui")));
|
||||||
|
|
||||||
// Serve favicon
|
// Serve favicon
|
||||||
webuiRouter.get("/favicon.ico", async (_req, res) => {
|
webuiRouter.get("/favicon.ico", (_req, res) => {
|
||||||
res.set("Content-Type", "image/vnd.microsoft.icon");
|
res.sendFile(path.join(repoDir, "static/fixed_responses/favicon.ico"));
|
||||||
res.send(await fs.readFile(path.join(repoDir, "static/fixed_responses/favicon.ico")));
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// Serve warframe-riven-info
|
// Serve warframe-riven-info
|
||||||
webuiRouter.get("/webui/riven-tool/", async (_req, res) => {
|
webuiRouter.get("/webui/riven-tool/", (_req, res) => {
|
||||||
res.set("Content-Type", "text/html;charset=utf8");
|
res.sendFile(path.join(repoDir, "node_modules/warframe-riven-info/index.html"));
|
||||||
res.send(await fs.readFile(path.join(repoDir, "node_modules/warframe-riven-info/index.html")));
|
|
||||||
});
|
});
|
||||||
webuiRouter.get("/webui/riven-tool/RivenParser.js", async (_req, res) => {
|
webuiRouter.get("/webui/riven-tool/RivenParser.js", (_req, res) => {
|
||||||
res.set("Content-Type", "text/javascript;charset=utf8");
|
res.sendFile(path.join(repoDir, "node_modules/warframe-riven-info/RivenParser.js"));
|
||||||
res.send(await fs.readFile(path.join(repoDir, "node_modules/warframe-riven-info/RivenParser.js")));
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// Serve translations
|
// Serve translations
|
||||||
webuiRouter.get("/translations/:file", async (req, res) => {
|
webuiRouter.get("/translations/:file", (req, res) => {
|
||||||
res.set("Content-Type", "text/javascript;charset=utf8");
|
res.sendFile(path.join(baseDir, `static/webui/translations/${req.params.file}`));
|
||||||
res.send(await fs.readFile(path.join(baseDir, `static/webui/translations/${req.params.file}`)));
|
|
||||||
});
|
});
|
||||||
|
|
||||||
export { webuiRouter };
|
export { webuiRouter };
|
||||||
|
|||||||
@ -1,425 +0,0 @@
|
|||||||
import type { TFaction, TMissionType } from "warframe-public-export-plus";
|
|
||||||
import type { CalendarSeasonType, IConquest, IConquestMission, TConquestType } from "../types/worldStateTypes.ts";
|
|
||||||
import { mixSeeds, SRng } from "./rngService.ts";
|
|
||||||
import { EPOCH } from "../constants/timeConstants.ts";
|
|
||||||
|
|
||||||
const missionAndFactionTypes: Record<TConquestType, Partial<Record<TMissionType, TFaction[]>>> = {
|
|
||||||
CT_LAB: {
|
|
||||||
MT_EXTERMINATION: ["FC_MITW"],
|
|
||||||
MT_SURVIVAL: ["FC_MITW"],
|
|
||||||
MT_ALCHEMY: ["FC_MITW"],
|
|
||||||
MT_DEFENSE: ["FC_MITW"],
|
|
||||||
MT_ARTIFACT: ["FC_MITW"]
|
|
||||||
},
|
|
||||||
CT_HEX: {
|
|
||||||
MT_EXTERMINATION: ["FC_SCALDRA", "FC_TECHROT"],
|
|
||||||
MT_SURVIVAL: ["FC_SCALDRA", "FC_TECHROT"],
|
|
||||||
MT_DEFENSE: ["FC_SCALDRA"],
|
|
||||||
MT_ENDLESS_CAPTURE: ["FC_TECHROT"]
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const assassinationFactionOptions: Record<TConquestType, TFaction[]> = {
|
|
||||||
CT_LAB: ["FC_MITW"],
|
|
||||||
CT_HEX: ["FC_SCALDRA"]
|
|
||||||
};
|
|
||||||
|
|
||||||
type TConquestDifficulty = "CD_NORMAL" | "CD_HARD";
|
|
||||||
|
|
||||||
interface IConquestConditional {
|
|
||||||
tag: string;
|
|
||||||
missionType?: TMissionType;
|
|
||||||
conquest?: TConquestType;
|
|
||||||
difficulty?: TConquestDifficulty;
|
|
||||||
season?: CalendarSeasonType;
|
|
||||||
}
|
|
||||||
|
|
||||||
const deviations: readonly IConquestConditional[] = [
|
|
||||||
{
|
|
||||||
tag: "AlchemicalShields",
|
|
||||||
missionType: "MT_ALCHEMY"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
tag: "ContaminationZone",
|
|
||||||
missionType: "MT_SURVIVAL",
|
|
||||||
conquest: "CT_HEX"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
tag: "DoubleTrouble",
|
|
||||||
missionType: "MT_ARTIFACT"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
tag: "EscalateImmediately",
|
|
||||||
missionType: "MT_EXTERMINATION",
|
|
||||||
conquest: "CT_HEX"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
tag: "EximusGrenadiers",
|
|
||||||
missionType: "MT_ALCHEMY"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
tag: "FortifiedFoes",
|
|
||||||
missionType: "MT_EXTERMINATION"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
tag: "FragileNodes",
|
|
||||||
missionType: "MT_ARTIFACT"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
tag: "GrowingIncursion",
|
|
||||||
missionType: "MT_EXTERMINATION",
|
|
||||||
conquest: "CT_LAB"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
tag: "HarshWords",
|
|
||||||
missionType: "MT_DEFENSE",
|
|
||||||
conquest: "CT_LAB"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
tag: "HighScalingLegacyte",
|
|
||||||
missionType: "MT_ENDLESS_CAPTURE",
|
|
||||||
conquest: "CT_HEX"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
tag: "DoubleTroubleLegacyte",
|
|
||||||
missionType: "MT_ENDLESS_CAPTURE",
|
|
||||||
conquest: "CT_HEX"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
tag: "HostileSecurity",
|
|
||||||
missionType: "MT_DEFENSE",
|
|
||||||
conquest: "CT_LAB"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
tag: "InfiniteTide",
|
|
||||||
missionType: "MT_ASSASSINATION",
|
|
||||||
conquest: "CT_LAB"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
tag: "LostInTranslation",
|
|
||||||
missionType: "MT_DEFENSE",
|
|
||||||
conquest: "CT_LAB"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
tag: "MutatedEnemies",
|
|
||||||
missionType: "MT_ENDLESS_CAPTURE",
|
|
||||||
conquest: "CT_HEX"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
tag: "NecramechActivation",
|
|
||||||
missionType: "MT_SURVIVAL",
|
|
||||||
conquest: "CT_LAB"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
tag: "Reinforcements",
|
|
||||||
missionType: "MT_ASSASSINATION",
|
|
||||||
conquest: "CT_LAB"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
tag: "StickyFingers",
|
|
||||||
missionType: "MT_ARTIFACT",
|
|
||||||
conquest: "CT_LAB"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
tag: "TankStrongArmor",
|
|
||||||
missionType: "MT_ASSASSINATION",
|
|
||||||
conquest: "CT_HEX"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
tag: "TankReinforcements",
|
|
||||||
missionType: "MT_ASSASSINATION",
|
|
||||||
conquest: "CT_HEX"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
tag: "TankSuperToxic",
|
|
||||||
missionType: "MT_ASSASSINATION",
|
|
||||||
conquest: "CT_HEX"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
tag: "TechrotConjunction",
|
|
||||||
missionType: "MT_SURVIVAL",
|
|
||||||
conquest: "CT_HEX"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
tag: "UnpoweredCapsules",
|
|
||||||
missionType: "MT_SURVIVAL",
|
|
||||||
conquest: "CT_LAB"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
tag: "VolatileGrenades",
|
|
||||||
missionType: "MT_ALCHEMY"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
tag: "GestatingTumors",
|
|
||||||
missionType: "MT_SURVIVAL",
|
|
||||||
conquest: "CT_HEX"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
tag: "ChemicalNoise",
|
|
||||||
missionType: "MT_DEFENSE",
|
|
||||||
conquest: "CT_HEX"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
tag: "ExplosiveEnergy",
|
|
||||||
missionType: "MT_DEFENSE",
|
|
||||||
conquest: "CT_HEX"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
tag: "DisruptiveSounds",
|
|
||||||
missionType: "MT_DEFENSE",
|
|
||||||
conquest: "CT_HEX"
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
const risks: readonly IConquestConditional[] = [
|
|
||||||
{
|
|
||||||
tag: "Voidburst"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
tag: "RegeneratingEnemies"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
tag: "VoidAberration"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
tag: "ShieldedFoes"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
tag: "PointBlank"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
tag: "Deflectors",
|
|
||||||
conquest: "CT_LAB"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
tag: "AcceleratedEnemies"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
tag: "DrainingResiduals"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
tag: "Quicksand"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
tag: "AntiMaterialWeapons",
|
|
||||||
conquest: "CT_LAB"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
tag: "ExplosiveCrawlers",
|
|
||||||
conquest: "CT_LAB"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
tag: "EMPBlackHole",
|
|
||||||
conquest: "CT_LAB"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
tag: "ArtilleryBeacons",
|
|
||||||
conquest: "CT_HEX"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
tag: "InfectedTechrot",
|
|
||||||
conquest: "CT_HEX"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
tag: "BalloonFest",
|
|
||||||
conquest: "CT_HEX"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
tag: "MiasmiteHive",
|
|
||||||
conquest: "CT_HEX"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
tag: "CompetitionSpillover",
|
|
||||||
conquest: "CT_HEX"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
tag: "HostileOvergrowth",
|
|
||||||
conquest: "CT_HEX"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
tag: "MurmurIncursion",
|
|
||||||
conquest: "CT_HEX"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
tag: "FactionSwarm_Techrot",
|
|
||||||
conquest: "CT_HEX",
|
|
||||||
difficulty: "CD_NORMAL"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
tag: "FactionSwarm_Scaldra",
|
|
||||||
conquest: "CT_HEX",
|
|
||||||
difficulty: "CD_NORMAL"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
tag: "HeavyWarfare",
|
|
||||||
conquest: "CT_HEX"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
tag: "ArcadeAutomata",
|
|
||||||
conquest: "CT_HEX",
|
|
||||||
difficulty: "CD_NORMAL"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
tag: "EfervonFog",
|
|
||||||
conquest: "CT_HEX"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
tag: "WinterFrost",
|
|
||||||
conquest: "CT_HEX",
|
|
||||||
season: "CST_WINTER"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
tag: "JadeSpring",
|
|
||||||
conquest: "CT_HEX",
|
|
||||||
season: "CST_SPRING"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
tag: "ExplosiveSummer",
|
|
||||||
conquest: "CT_HEX",
|
|
||||||
season: "CST_SUMMER"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
tag: "FallFog",
|
|
||||||
conquest: "CT_HEX",
|
|
||||||
season: "CST_FALL"
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
const filterConditionals = (
|
|
||||||
arr: readonly IConquestConditional[],
|
|
||||||
missionType: TMissionType | null,
|
|
||||||
conquest: TConquestType | null,
|
|
||||||
difficulty: TConquestDifficulty | null,
|
|
||||||
season: CalendarSeasonType | null
|
|
||||||
): string[] => {
|
|
||||||
const applicable = [];
|
|
||||||
for (const cond of arr) {
|
|
||||||
if (
|
|
||||||
(!cond.missionType || cond.missionType == missionType) &&
|
|
||||||
(!cond.conquest || cond.conquest == conquest) &&
|
|
||||||
(!cond.difficulty || cond.difficulty == difficulty) &&
|
|
||||||
(!cond.season || cond.season == season)
|
|
||||||
) {
|
|
||||||
applicable.push(cond.tag);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return applicable;
|
|
||||||
};
|
|
||||||
|
|
||||||
const buildMission = (
|
|
||||||
rng: SRng,
|
|
||||||
conquest: TConquestType,
|
|
||||||
missionType: TMissionType,
|
|
||||||
faction: TFaction,
|
|
||||||
season: CalendarSeasonType | null
|
|
||||||
): IConquestMission => {
|
|
||||||
const deviation = rng.randomElement(filterConditionals(deviations, missionType, conquest, null, season))!;
|
|
||||||
const easyRisk = rng.randomElement(filterConditionals(risks, missionType, conquest, "CD_NORMAL", season))!;
|
|
||||||
const hardRiskOptions = filterConditionals(risks, missionType, conquest, "CD_HARD", season);
|
|
||||||
{
|
|
||||||
const i = hardRiskOptions.indexOf(easyRisk);
|
|
||||||
if (i != -1) {
|
|
||||||
hardRiskOptions.splice(i, 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const hardRisk = rng.randomElement(hardRiskOptions)!;
|
|
||||||
return {
|
|
||||||
faction,
|
|
||||||
missionType,
|
|
||||||
difficulties: [
|
|
||||||
{
|
|
||||||
type: "CD_NORMAL",
|
|
||||||
deviation,
|
|
||||||
risks: [easyRisk]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: "CD_HARD",
|
|
||||||
deviation,
|
|
||||||
risks: [easyRisk, hardRisk]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
const conquestStartingDay: Record<TConquestType, number> = {
|
|
||||||
CT_LAB: 3703,
|
|
||||||
CT_HEX: 4053
|
|
||||||
};
|
|
||||||
|
|
||||||
// This function produces identical results to clients pre-40.0.0.
|
|
||||||
const getFrameVariables = (conquestType: TConquestType, time: number): [string, string, string, string] => {
|
|
||||||
const day = Math.floor((time - 1391990400_000) / 86400_000) - conquestStartingDay[conquestType];
|
|
||||||
const week = Math.floor(day / 7) + 1;
|
|
||||||
const frameVariables = [
|
|
||||||
"Framecurse",
|
|
||||||
"Knifestep",
|
|
||||||
"Exhaustion",
|
|
||||||
"Gearless",
|
|
||||||
"TimeDilation",
|
|
||||||
"Armorless",
|
|
||||||
"Starvation",
|
|
||||||
"ShieldDelay",
|
|
||||||
"Withering",
|
|
||||||
"ContactDamage",
|
|
||||||
"AbilityLockout",
|
|
||||||
"OperatorLockout",
|
|
||||||
"EnergyStarved",
|
|
||||||
"OverSensitive",
|
|
||||||
"AntiGuard",
|
|
||||||
"DecayingFlesh",
|
|
||||||
"VoidEnergyOverload",
|
|
||||||
"DullBlades",
|
|
||||||
"Undersupplied"
|
|
||||||
];
|
|
||||||
const mag = Math.floor(frameVariables.length / 4);
|
|
||||||
const rng = new SRng(conquestStartingDay[conquestType] + Math.floor(week / mag));
|
|
||||||
rng.shuffleArray(frameVariables);
|
|
||||||
const i = week % mag;
|
|
||||||
return [frameVariables[i], frameVariables[i + 1], frameVariables[i + 2], frameVariables[i + 3]];
|
|
||||||
};
|
|
||||||
|
|
||||||
export const getConquest = (
|
|
||||||
conquestType: TConquestType,
|
|
||||||
week: number,
|
|
||||||
season: CalendarSeasonType | null
|
|
||||||
): IConquest => {
|
|
||||||
const rng = new SRng(mixSeeds(conquestStartingDay[conquestType], week));
|
|
||||||
|
|
||||||
const missions: IConquestMission[] = [];
|
|
||||||
{
|
|
||||||
const missionOptions = Object.entries(missionAndFactionTypes[conquestType]);
|
|
||||||
{
|
|
||||||
const i = rng.randomInt(0, missionOptions.length - 1);
|
|
||||||
const [missionType, factionOptions] = missionOptions.splice(i, 1)[0];
|
|
||||||
missions.push(
|
|
||||||
buildMission(rng, conquestType, missionType as TMissionType, rng.randomElement(factionOptions)!, season)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
{
|
|
||||||
const i = rng.randomInt(0, missionOptions.length - 1);
|
|
||||||
const [missionType, factionOptions] = missionOptions.splice(i, 1)[0];
|
|
||||||
missions.push(
|
|
||||||
buildMission(rng, conquestType, missionType as TMissionType, rng.randomElement(factionOptions)!, season)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
missionOptions.push(["MT_ASSASSINATION", assassinationFactionOptions[conquestType]]);
|
|
||||||
{
|
|
||||||
const i = rng.randomInt(0, missionOptions.length - 1);
|
|
||||||
const [missionType, factionOptions] = missionOptions.splice(i, 1)[0];
|
|
||||||
missions.push(
|
|
||||||
buildMission(rng, conquestType, missionType as TMissionType, rng.randomElement(factionOptions)!, season)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const weekStart = EPOCH + week * 604800000;
|
|
||||||
const weekEnd = weekStart + 604800000;
|
|
||||||
return {
|
|
||||||
Activation: { $date: { $numberLong: weekStart.toString() } },
|
|
||||||
Expiry: { $date: { $numberLong: weekEnd.toString() } },
|
|
||||||
Type: conquestType,
|
|
||||||
Missions: missions,
|
|
||||||
Variables: getFrameVariables(conquestType, weekStart),
|
|
||||||
RandomSeed: rng.randomInt(0, 1_000_000)
|
|
||||||
};
|
|
||||||
};
|
|
||||||
@ -116,8 +116,8 @@ export const createInventory = async (
|
|||||||
if (config.skipTutorial) {
|
if (config.skipTutorial) {
|
||||||
inventory.PlayedParkourTutorial = true;
|
inventory.PlayedParkourTutorial = true;
|
||||||
await addStartingGear(inventory);
|
await addStartingGear(inventory);
|
||||||
await completeQuest(inventory, "/Lotus/Types/Keys/VorsPrize/VorsPrizeQuestKeyChain", undefined);
|
await completeQuest(inventory, "/Lotus/Types/Keys/VorsPrize/VorsPrizeQuestKeyChain");
|
||||||
await completeQuest(inventory, "/Lotus/Types/Keys/ModQuest/ModQuestKeyChain", undefined);
|
await completeQuest(inventory, "/Lotus/Types/Keys/ModQuest/ModQuestKeyChain");
|
||||||
|
|
||||||
const completedMissions = ["SolNode27", "SolNode89", "SolNode63", "SolNode85", "SolNode15", "SolNode79"];
|
const completedMissions = ["SolNode27", "SolNode89", "SolNode63", "SolNode85", "SolNode15", "SolNode79"];
|
||||||
|
|
||||||
@ -473,9 +473,7 @@ export const addItem = async (
|
|||||||
return addCustomization(inventory, typeName);
|
return addCustomization(inventory, typeName);
|
||||||
}
|
}
|
||||||
if (typeName in ExportUpgrades || typeName in ExportArcanes) {
|
if (typeName in ExportUpgrades || typeName in ExportArcanes) {
|
||||||
if (targetFingerprint && typeName.startsWith("/Lotus/Upgrades/Mods/Randomized/Raw")) {
|
if (targetFingerprint) {
|
||||||
logger.debug(`ignoring fingerprint for raw riven mod`);
|
|
||||||
} else if (targetFingerprint) {
|
|
||||||
if (quantity != 1) {
|
if (quantity != 1) {
|
||||||
logger.warn(`adding 1 of ${typeName} ${targetFingerprint} even tho quantity ${quantity} was requested`);
|
logger.warn(`adding 1 of ${typeName} ${targetFingerprint} even tho quantity ${quantity} was requested`);
|
||||||
}
|
}
|
||||||
@ -1571,7 +1569,6 @@ const addCrewShip = async (
|
|||||||
const questChanges = await completeQuest(
|
const questChanges = await completeQuest(
|
||||||
inventory,
|
inventory,
|
||||||
"/Lotus/Types/Keys/RailJackBuildQuest/RailjackBuildQuestKeyChain",
|
"/Lotus/Types/Keys/RailJackBuildQuest/RailjackBuildQuestKeyChain",
|
||||||
undefined,
|
|
||||||
false
|
false
|
||||||
);
|
);
|
||||||
if (questChanges) {
|
if (questChanges) {
|
||||||
|
|||||||
@ -40,8 +40,6 @@ import {
|
|||||||
} from "warframe-public-export-plus";
|
} from "warframe-public-export-plus";
|
||||||
import type { IMessage } from "../models/inboxModel.ts";
|
import type { IMessage } from "../models/inboxModel.ts";
|
||||||
import { logger } from "../utils/logger.ts";
|
import { logger } from "../utils/logger.ts";
|
||||||
import { version_compare } from "../helpers/inventoryHelpers.ts";
|
|
||||||
import vorsPrizePreU40Rewards from "../../static/fixed_responses/vorsPrizePreU40Rewards.json" with { type: "json" };
|
|
||||||
|
|
||||||
export type WeaponTypeInternal =
|
export type WeaponTypeInternal =
|
||||||
| "LongGuns"
|
| "LongGuns"
|
||||||
@ -229,13 +227,12 @@ export const getKeyChainItems = ({ KeyChain, ChainStage }: IKeyChainRequest): st
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const getLevelKeyRewards = (
|
export const getLevelKeyRewards = (
|
||||||
levelKey: string,
|
levelKey: string
|
||||||
buildLabel: string | undefined
|
|
||||||
): { levelKeyRewards?: IMissionReward; levelKeyRewards2?: TReward[] } => {
|
): { levelKeyRewards?: IMissionReward; levelKeyRewards2?: TReward[] } => {
|
||||||
const key = ExportKeys[levelKey] as IKey | undefined;
|
const key = ExportKeys[levelKey] as IKey | undefined;
|
||||||
|
|
||||||
const levelKeyRewards = key?.missionReward;
|
const levelKeyRewards = key?.missionReward;
|
||||||
let levelKeyRewards2 = key?.rewards;
|
const levelKeyRewards2 = key?.rewards;
|
||||||
|
|
||||||
if (!levelKeyRewards && !levelKeyRewards2) {
|
if (!levelKeyRewards && !levelKeyRewards2) {
|
||||||
logger.warn(
|
logger.warn(
|
||||||
@ -243,12 +240,6 @@ export const getLevelKeyRewards = (
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (buildLabel && version_compare(buildLabel, "2025.10.14.16.10") < 0) {
|
|
||||||
if (levelKey in vorsPrizePreU40Rewards) {
|
|
||||||
levelKeyRewards2 = vorsPrizePreU40Rewards[levelKey as keyof typeof vorsPrizePreU40Rewards] as TReward[];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
levelKeyRewards,
|
levelKeyRewards,
|
||||||
levelKeyRewards2
|
levelKeyRewards2
|
||||||
|
|||||||
@ -41,8 +41,8 @@ export const createAccount = async (accountData: IDatabaseAccountRequiredFields)
|
|||||||
await account.save();
|
await account.save();
|
||||||
const loadoutId = await createLoadout(account._id);
|
const loadoutId = await createLoadout(account._id);
|
||||||
const shipId = await createShip(account._id);
|
const shipId = await createShip(account._id);
|
||||||
await createPersonalRooms(account._id, shipId);
|
|
||||||
await createInventory(account._id, { loadOutPresetId: loadoutId, ship: shipId });
|
await createInventory(account._id, { loadOutPresetId: loadoutId, ship: shipId });
|
||||||
|
await createPersonalRooms(account._id, shipId);
|
||||||
await createStats(account._id.toString());
|
await createStats(account._id.toString());
|
||||||
return account.toJSON();
|
return account.toJSON();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@ -64,6 +64,17 @@ export const createPersonalRooms = async (accountId: Types.ObjectId, shipId: Typ
|
|||||||
personalRoomsOwnerId: accountId,
|
personalRoomsOwnerId: accountId,
|
||||||
activeShipId: shipId
|
activeShipId: shipId
|
||||||
});
|
});
|
||||||
|
if (config.skipTutorial) {
|
||||||
|
// unlocked during Vor's Prize and The Teacher quests
|
||||||
|
const defaultFeatures = [
|
||||||
|
"/Lotus/Types/Items/ShipFeatureItems/MercuryNavigationFeatureItem",
|
||||||
|
"/Lotus/Types/Items/ShipFeatureItems/ArsenalFeatureItem",
|
||||||
|
"/Lotus/Types/Items/ShipFeatureItems/SocialMenuFeatureItem",
|
||||||
|
"/Lotus/Types/Items/ShipFeatureItems/FoundryFeatureItem",
|
||||||
|
"/Lotus/Types/Items/ShipFeatureItems/ModsFeatureItem"
|
||||||
|
];
|
||||||
|
personalRooms.Ship.Features.push(...defaultFeatures);
|
||||||
|
}
|
||||||
await personalRooms.save();
|
await personalRooms.save();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -1133,8 +1133,7 @@ export const addMissionRewards = async (
|
|||||||
VoidTearParticipantsCurrWave: voidTearWave,
|
VoidTearParticipantsCurrWave: voidTearWave,
|
||||||
StrippedItems: strippedItems,
|
StrippedItems: strippedItems,
|
||||||
AffiliationChanges: AffiliationMods,
|
AffiliationChanges: AffiliationMods,
|
||||||
InvasionProgress: invasionProgress,
|
InvasionProgress: invasionProgress
|
||||||
EndOfMatchUpload: endOfMatchUpload
|
|
||||||
}: IMissionInventoryUpdateRequest,
|
}: IMissionInventoryUpdateRequest,
|
||||||
firstCompletion: boolean
|
firstCompletion: boolean
|
||||||
): Promise<AddMissionRewardsReturnType> => {
|
): Promise<AddMissionRewardsReturnType> => {
|
||||||
@ -1219,7 +1218,7 @@ export const addMissionRewards = async (
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (levelKeyName) {
|
if (levelKeyName) {
|
||||||
const fixedLevelRewards = getLevelKeyRewards(levelKeyName, account.BuildLabel);
|
const fixedLevelRewards = getLevelKeyRewards(levelKeyName);
|
||||||
//logger.debug(`fixedLevelRewards ${fixedLevelRewards}`);
|
//logger.debug(`fixedLevelRewards ${fixedLevelRewards}`);
|
||||||
if (fixedLevelRewards.levelKeyRewards) {
|
if (fixedLevelRewards.levelKeyRewards) {
|
||||||
missionCompletionCredits += addFixedLevelRewards(
|
missionCompletionCredits += addFixedLevelRewards(
|
||||||
@ -1393,77 +1392,73 @@ export const addMissionRewards = async (
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (strippedItems) {
|
if (strippedItems) {
|
||||||
if (endOfMatchUpload) {
|
for (const si of strippedItems) {
|
||||||
for (const si of strippedItems) {
|
if (si.DropTable in droptableAliases) {
|
||||||
if (si.DropTable in droptableAliases) {
|
logger.debug(`rewriting ${si.DropTable} to ${droptableAliases[si.DropTable]}`);
|
||||||
logger.debug(`rewriting ${si.DropTable} to ${droptableAliases[si.DropTable]}`);
|
si.DropTable = droptableAliases[si.DropTable];
|
||||||
si.DropTable = droptableAliases[si.DropTable];
|
}
|
||||||
}
|
const droptables = ExportEnemies.droptables[si.DropTable] ?? [];
|
||||||
const droptables = ExportEnemies.droptables[si.DropTable] ?? [];
|
if (si.DROP_MOD) {
|
||||||
if (si.DROP_MOD) {
|
const modDroptable = droptables.find(x => x.type == "mod");
|
||||||
const modDroptable = droptables.find(x => x.type == "mod");
|
if (modDroptable) {
|
||||||
if (modDroptable) {
|
for (let i = 0; i != si.DROP_MOD.length; ++i) {
|
||||||
for (let i = 0; i != si.DROP_MOD.length; ++i) {
|
const reward = getRandomReward(modDroptable.items)!;
|
||||||
const reward = getRandomReward(modDroptable.items)!;
|
logger.debug(`stripped droptable (mods pool) rolled`, reward);
|
||||||
logger.debug(`stripped droptable (mods pool) rolled`, reward);
|
await addItem(inventory, reward.type);
|
||||||
await addItem(inventory, reward.type);
|
MissionRewards.push({
|
||||||
MissionRewards.push({
|
StoreItem: toStoreItem(reward.type),
|
||||||
StoreItem: toStoreItem(reward.type),
|
ItemCount: 1,
|
||||||
ItemCount: 1,
|
FromEnemyCache: true // to show "identified"
|
||||||
FromEnemyCache: true // to show "identified"
|
});
|
||||||
});
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
logger.error(`unknown droptable ${si.DropTable} for DROP_MOD`);
|
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
if (si.DROP_BLUEPRINT) {
|
logger.error(`unknown droptable ${si.DropTable} for DROP_MOD`);
|
||||||
const blueprintDroptable = droptables.find(x => x.type == "blueprint");
|
|
||||||
if (blueprintDroptable) {
|
|
||||||
for (let i = 0; i != si.DROP_BLUEPRINT.length; ++i) {
|
|
||||||
const reward = getRandomReward(blueprintDroptable.items)!;
|
|
||||||
logger.debug(`stripped droptable (blueprints pool) rolled`, reward);
|
|
||||||
await addItem(inventory, reward.type);
|
|
||||||
MissionRewards.push({
|
|
||||||
StoreItem: toStoreItem(reward.type),
|
|
||||||
ItemCount: 1,
|
|
||||||
FromEnemyCache: true // to show "identified"
|
|
||||||
});
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
logger.error(`unknown droptable ${si.DropTable} for DROP_BLUEPRINT`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// e.g. H-09 Apex Turret Sumdali
|
|
||||||
if (si.DROP_MISC_ITEM) {
|
|
||||||
const resourceDroptable = droptables.find(x => x.type == "resource");
|
|
||||||
if (resourceDroptable) {
|
|
||||||
for (let i = 0; i != si.DROP_MISC_ITEM.length; ++i) {
|
|
||||||
const reward = getRandomReward(resourceDroptable.items)!;
|
|
||||||
logger.debug(`stripped droptable (resources pool) rolled`, reward);
|
|
||||||
if (Object.keys(await addItem(inventory, reward.type)).length == 0) {
|
|
||||||
logger.debug(`item already owned, skipping`);
|
|
||||||
} else {
|
|
||||||
MissionRewards.push({
|
|
||||||
StoreItem: toStoreItem(reward.type),
|
|
||||||
ItemCount: 1,
|
|
||||||
FromEnemyCache: true // to show "identified"
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
logger.error(`unknown droptable ${si.DropTable} for DROP_MISC_ITEM`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (si.DropTable == "/Lotus/Types/DropTables/ContainerDropTables/VoidVaultMissionRewardsDropTable") {
|
|
||||||
// Consume netracells search pulse; only when the container reward was picked up. Discussed in https://onlyg.it/OpenWF/SpaceNinjaServer/issues/2673
|
|
||||||
updateEntratiVault(inventory);
|
|
||||||
inventory.EntratiVaultCountLastPeriod! += 1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
if (si.DROP_BLUEPRINT) {
|
||||||
logger.debug(`ignoring StrippedItems in intermediate inventory update, deferring until extraction`);
|
const blueprintDroptable = droptables.find(x => x.type == "blueprint");
|
||||||
|
if (blueprintDroptable) {
|
||||||
|
for (let i = 0; i != si.DROP_BLUEPRINT.length; ++i) {
|
||||||
|
const reward = getRandomReward(blueprintDroptable.items)!;
|
||||||
|
logger.debug(`stripped droptable (blueprints pool) rolled`, reward);
|
||||||
|
await addItem(inventory, reward.type);
|
||||||
|
MissionRewards.push({
|
||||||
|
StoreItem: toStoreItem(reward.type),
|
||||||
|
ItemCount: 1,
|
||||||
|
FromEnemyCache: true // to show "identified"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
logger.error(`unknown droptable ${si.DropTable} for DROP_BLUEPRINT`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// e.g. H-09 Apex Turret Sumdali
|
||||||
|
if (si.DROP_MISC_ITEM) {
|
||||||
|
const resourceDroptable = droptables.find(x => x.type == "resource");
|
||||||
|
if (resourceDroptable) {
|
||||||
|
for (let i = 0; i != si.DROP_MISC_ITEM.length; ++i) {
|
||||||
|
const reward = getRandomReward(resourceDroptable.items)!;
|
||||||
|
logger.debug(`stripped droptable (resources pool) rolled`, reward);
|
||||||
|
if (Object.keys(await addItem(inventory, reward.type)).length == 0) {
|
||||||
|
logger.debug(`item already owned, skipping`);
|
||||||
|
} else {
|
||||||
|
MissionRewards.push({
|
||||||
|
StoreItem: toStoreItem(reward.type),
|
||||||
|
ItemCount: 1,
|
||||||
|
FromEnemyCache: true // to show "identified"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
logger.error(`unknown droptable ${si.DropTable} for DROP_MISC_ITEM`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (si.DropTable == "/Lotus/Types/DropTables/ContainerDropTables/VoidVaultMissionRewardsDropTable") {
|
||||||
|
// Consume netracells search pulse; only when the container reward was picked up. Discussed in https://onlyg.it/OpenWF/SpaceNinjaServer/issues/2673
|
||||||
|
updateEntratiVault(inventory);
|
||||||
|
inventory.EntratiVaultCountLastPeriod! += 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -2,25 +2,16 @@ import type { IKeyChainRequest } from "../types/requestTypes.ts";
|
|||||||
import { isEmptyObject } from "../helpers/general.ts";
|
import { isEmptyObject } from "../helpers/general.ts";
|
||||||
import type { TInventoryDatabaseDocument } from "../models/inventoryModels/inventoryModel.ts";
|
import type { TInventoryDatabaseDocument } from "../models/inventoryModels/inventoryModel.ts";
|
||||||
import { createMessage } from "./inboxService.ts";
|
import { createMessage } from "./inboxService.ts";
|
||||||
import {
|
import { addItem, addItems, addKeyChainItems, setupKahlSyndicate } from "./inventoryService.ts";
|
||||||
addEquipment,
|
|
||||||
addItem,
|
|
||||||
addItems,
|
|
||||||
addKeyChainItems,
|
|
||||||
addPowerSuit,
|
|
||||||
setupKahlSyndicate
|
|
||||||
} from "./inventoryService.ts";
|
|
||||||
import { fromStoreItem, getKeyChainMessage, getLevelKeyRewards } from "./itemDataService.ts";
|
import { fromStoreItem, getKeyChainMessage, getLevelKeyRewards } from "./itemDataService.ts";
|
||||||
import type { IQuestKeyClient, IQuestKeyDatabase, IQuestStage } from "../types/inventoryTypes/inventoryTypes.ts";
|
import type { IQuestKeyClient, IQuestKeyDatabase, IQuestStage } from "../types/inventoryTypes/inventoryTypes.ts";
|
||||||
import { logger } from "../utils/logger.ts";
|
import { logger } from "../utils/logger.ts";
|
||||||
import { ExportKeys, ExportRecipes } from "warframe-public-export-plus";
|
import { ExportKeys } from "warframe-public-export-plus";
|
||||||
import { addFixedLevelRewards } from "./missionInventoryUpdateService.ts";
|
import { addFixedLevelRewards } from "./missionInventoryUpdateService.ts";
|
||||||
import type { IInventoryChanges } from "../types/purchaseTypes.ts";
|
import type { IInventoryChanges } from "../types/purchaseTypes.ts";
|
||||||
import questCompletionItems from "../../static/fixed_responses/questCompletionRewards.json" with { type: "json" };
|
import questCompletionItems from "../../static/fixed_responses/questCompletionRewards.json" with { type: "json" };
|
||||||
import type { ITypeCount } from "../types/commonTypes.ts";
|
import type { ITypeCount } from "../types/commonTypes.ts";
|
||||||
import { addString } from "../helpers/stringHelpers.ts";
|
import { addString } from "../helpers/stringHelpers.ts";
|
||||||
import { unlockShipFeature } from "./personalRoomsService.ts";
|
|
||||||
import { EquipmentFeatures } from "../types/equipmentTypes.ts";
|
|
||||||
|
|
||||||
export interface IUpdateQuestRequest {
|
export interface IUpdateQuestRequest {
|
||||||
QuestKeys: IQuestKeyClient[];
|
QuestKeys: IQuestKeyClient[];
|
||||||
@ -113,10 +104,14 @@ export const resetQuestKeyToStage = (
|
|||||||
|
|
||||||
quest.Progress ??= [];
|
quest.Progress ??= [];
|
||||||
|
|
||||||
const run = quest.Progress[0]?.c ?? 0;
|
quest.Progress.splice(1 + ChainStage); // remove stages past the target
|
||||||
if (run >= 0) {
|
|
||||||
for (let i = ChainStage; i < quest.Progress.length; ++i) {
|
const questStage = quest.Progress[ChainStage];
|
||||||
quest.Progress[i].c = run - 1;
|
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
||||||
|
if (questStage) {
|
||||||
|
const run = quest.Progress[0].c;
|
||||||
|
if (run >= 0) {
|
||||||
|
questStage.c = run - 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -149,7 +144,6 @@ export const addQuestKey = (
|
|||||||
export const completeQuest = async (
|
export const completeQuest = async (
|
||||||
inventory: TInventoryDatabaseDocument,
|
inventory: TInventoryDatabaseDocument,
|
||||||
questKey: string,
|
questKey: string,
|
||||||
buildLabel: string | undefined,
|
|
||||||
sendMessages: boolean = false
|
sendMessages: boolean = false
|
||||||
): Promise<void | IQuestKeyClient> => {
|
): Promise<void | IQuestKeyClient> => {
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
||||||
@ -198,8 +192,7 @@ export const completeQuest = async (
|
|||||||
if (stage.c <= run) {
|
if (stage.c <= run) {
|
||||||
stage.c = run;
|
stage.c = run;
|
||||||
await giveKeyChainStageTriggered(inventory, { KeyChain: questKey, ChainStage: i }, sendMessages);
|
await giveKeyChainStageTriggered(inventory, { KeyChain: questKey, ChainStage: i }, sendMessages);
|
||||||
await giveKeyChainMissionReward(inventory, { KeyChain: questKey, ChainStage: i }, buildLabel);
|
await giveKeyChainMissionReward(inventory, { KeyChain: questKey, ChainStage: i });
|
||||||
await installShipFeatures(inventory, { KeyChain: questKey, ChainStage: i }, buildLabel);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -336,9 +329,6 @@ const handleQuestCompletion = async (
|
|||||||
logger.debug(`quest completion items`, questCompletionItems);
|
logger.debug(`quest completion items`, questCompletionItems);
|
||||||
if (questCompletionItems) {
|
if (questCompletionItems) {
|
||||||
await addItems(inventory, questCompletionItems, inventoryChanges);
|
await addItems(inventory, questCompletionItems, inventoryChanges);
|
||||||
for (const item of questCompletionItems) {
|
|
||||||
await removeRequiredItems(inventory, item.ItemType);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -388,12 +378,7 @@ export const giveKeyChainMessage = async (
|
|||||||
await createMessage(inventory.accountOwnerId, [keyChainMessage]);
|
await createMessage(inventory.accountOwnerId, [keyChainMessage]);
|
||||||
} else {
|
} else {
|
||||||
if (keyChainMessage.countedAtt?.length) await addItems(inventory, keyChainMessage.countedAtt);
|
if (keyChainMessage.countedAtt?.length) await addItems(inventory, keyChainMessage.countedAtt);
|
||||||
if (keyChainMessage.att?.length) {
|
if (keyChainMessage.att?.length) await addItems(inventory, keyChainMessage.att);
|
||||||
await addItems(inventory, keyChainMessage.att);
|
|
||||||
for (const reward of keyChainMessage.att) {
|
|
||||||
await removeRequiredItems(inventory, reward);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
updateQuestStage(inventory, keyChainInfo, { m: true });
|
updateQuestStage(inventory, keyChainInfo, { m: true });
|
||||||
@ -401,8 +386,7 @@ export const giveKeyChainMessage = async (
|
|||||||
|
|
||||||
export const giveKeyChainMissionReward = async (
|
export const giveKeyChainMissionReward = async (
|
||||||
inventory: TInventoryDatabaseDocument,
|
inventory: TInventoryDatabaseDocument,
|
||||||
keyChainInfo: IKeyChainRequest,
|
keyChainInfo: IKeyChainRequest
|
||||||
buildLabel: string | undefined
|
|
||||||
): Promise<void> => {
|
): Promise<void> => {
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
||||||
const chainStages = ExportKeys[keyChainInfo.KeyChain]?.chainStages;
|
const chainStages = ExportKeys[keyChainInfo.KeyChain]?.chainStages;
|
||||||
@ -411,7 +395,7 @@ export const giveKeyChainMissionReward = async (
|
|||||||
const missionName = chainStages[keyChainInfo.ChainStage].key;
|
const missionName = chainStages[keyChainInfo.ChainStage].key;
|
||||||
const questKey = inventory.QuestKeys.find(q => q.ItemType === keyChainInfo.KeyChain);
|
const questKey = inventory.QuestKeys.find(q => q.ItemType === keyChainInfo.KeyChain);
|
||||||
if (missionName && questKey) {
|
if (missionName && questKey) {
|
||||||
const fixedLevelRewards = getLevelKeyRewards(missionName, buildLabel);
|
const fixedLevelRewards = getLevelKeyRewards(missionName);
|
||||||
const run = questKey.Progress?.[0]?.c ?? 0;
|
const run = questKey.Progress?.[0]?.c ?? 0;
|
||||||
if (fixedLevelRewards.levelKeyRewards) {
|
if (fixedLevelRewards.levelKeyRewards) {
|
||||||
const missionRewards: { StoreItem: string; ItemCount: number }[] = [];
|
const missionRewards: { StoreItem: string; ItemCount: number }[] = [];
|
||||||
@ -419,7 +403,6 @@ export const giveKeyChainMissionReward = async (
|
|||||||
|
|
||||||
for (const reward of missionRewards) {
|
for (const reward of missionRewards) {
|
||||||
await addItem(inventory, fromStoreItem(reward.StoreItem), reward.ItemCount);
|
await addItem(inventory, fromStoreItem(reward.StoreItem), reward.ItemCount);
|
||||||
await removeRequiredItems(inventory, fromStoreItem(reward.StoreItem));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
updateQuestStage(inventory, keyChainInfo, { c: run });
|
updateQuestStage(inventory, keyChainInfo, { c: run });
|
||||||
@ -433,7 +416,6 @@ export const giveKeyChainMissionReward = async (
|
|||||||
await addItem(inventory, fromStoreItem(reward.itemType), reward.amount);
|
await addItem(inventory, fromStoreItem(reward.itemType), reward.amount);
|
||||||
} else {
|
} else {
|
||||||
await addItem(inventory, fromStoreItem(reward.itemType));
|
await addItem(inventory, fromStoreItem(reward.itemType));
|
||||||
await removeRequiredItems(inventory, fromStoreItem(reward.itemType));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -462,338 +444,3 @@ export const giveKeyChainStageTriggered = async (
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export const installShipFeatures = async (
|
|
||||||
inventory: TInventoryDatabaseDocument,
|
|
||||||
keyChainInfo: IKeyChainRequest,
|
|
||||||
buildLabel: string | undefined
|
|
||||||
): Promise<void> => {
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
||||||
const chainStages = ExportKeys[keyChainInfo.KeyChain]?.chainStages;
|
|
||||||
const questKey = inventory.QuestKeys.find(qk => qk.ItemType === keyChainInfo.KeyChain);
|
|
||||||
if (chainStages && questKey) {
|
|
||||||
if (keyChainInfo.ChainStage - 1 >= 0) {
|
|
||||||
const prevStage = chainStages[keyChainInfo.ChainStage - 1];
|
|
||||||
for (const item of prevStage.itemsToGiveWhenTriggered) {
|
|
||||||
if (item.startsWith("/Lotus/StoreItems/Types/Items/ShipFeatureItems/")) {
|
|
||||||
logger.debug(`installing ship feature ${fromStoreItem(item)}`);
|
|
||||||
await unlockShipFeature(inventory, fromStoreItem(item));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (prevStage.key) {
|
|
||||||
const fixedLevelRewards = getLevelKeyRewards(prevStage.key, buildLabel);
|
|
||||||
if (fixedLevelRewards.levelKeyRewards?.items) {
|
|
||||||
for (const item of fixedLevelRewards.levelKeyRewards.items) {
|
|
||||||
if (item.startsWith("/Lotus/StoreItems/Types/Items/ShipFeatureItems/")) {
|
|
||||||
logger.debug(`installing ship feature ${fromStoreItem(item)}`);
|
|
||||||
await unlockShipFeature(inventory, fromStoreItem(item));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (fixedLevelRewards.levelKeyRewards2) {
|
|
||||||
for (const item of fixedLevelRewards.levelKeyRewards2) {
|
|
||||||
if (
|
|
||||||
item.rewardType == "RT_STORE_ITEM" &&
|
|
||||||
item.itemType.startsWith("/Lotus/StoreItems/Types/Items/ShipFeatureItems/")
|
|
||||||
) {
|
|
||||||
logger.debug(`installing ship feature ${fromStoreItem(item.itemType)}`);
|
|
||||||
await unlockShipFeature(inventory, fromStoreItem(item.itemType));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
export const removeRequiredItems = async (inventory: TInventoryDatabaseDocument, typeName: string): Promise<void> => {
|
|
||||||
switch (typeName) {
|
|
||||||
case "/Lotus/Types/Recipes/WarframeRecipes/MagicianHelmetBlueprint": {
|
|
||||||
const recipeItem = inventory.Recipes.find(
|
|
||||||
i => i.ItemType == "/Lotus/Types/Keys/LimboQuest/LimboHelmetKeyBlueprint"
|
|
||||||
);
|
|
||||||
if (recipeItem && recipeItem.ItemCount > 0) {
|
|
||||||
const recipe = ExportRecipes[recipeItem.ItemType];
|
|
||||||
if (!inventory.MiscItems.find(i => i.ItemType == recipe.resultType)) {
|
|
||||||
await addItem(inventory, recipe.resultType);
|
|
||||||
if (recipe.consumeOnUse) await addItem(inventory, recipeItem.ItemType, -1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case "/Lotus/Types/Recipes/WarframeRecipes/MagicianSystemsBlueprint": {
|
|
||||||
const recipeItem = inventory.Recipes.find(
|
|
||||||
i => i.ItemType == "/Lotus/Types/Keys/LimboQuest/LimboSystemsKeyBlueprint"
|
|
||||||
);
|
|
||||||
if (recipeItem && recipeItem.ItemCount > 0) {
|
|
||||||
const recipe = ExportRecipes[recipeItem.ItemType];
|
|
||||||
if (!inventory.MiscItems.find(i => i.ItemType == recipe.resultType)) {
|
|
||||||
await addItem(inventory, recipe.resultType);
|
|
||||||
if (recipe.consumeOnUse) await addItem(inventory, recipeItem.ItemType, -1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case "/Lotus/Types/Recipes/WarframeRecipes/MagicianChassisBlueprint": {
|
|
||||||
const recipeItem = inventory.Recipes.find(
|
|
||||||
i => i.ItemType == "/Lotus/Types/Keys/LimboQuest/LimboChassisKeyBlueprint"
|
|
||||||
);
|
|
||||||
if (recipeItem && recipeItem.ItemCount > 0) {
|
|
||||||
const recipe = ExportRecipes[recipeItem.ItemType];
|
|
||||||
if (!inventory.MiscItems.find(i => i.ItemType == recipe.resultType)) {
|
|
||||||
await addItem(inventory, recipe.resultType);
|
|
||||||
if (recipe.consumeOnUse) await addItem(inventory, recipeItem.ItemType, -1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case "/Lotus/Types/Recipes/WarframeRecipes/BrawlerBlueprint": {
|
|
||||||
const recipeItem = inventory.Recipes.find(
|
|
||||||
i => i.ItemType == "/Lotus/Types/Recipes/Components/InfestedIrradiatedBaitBallBlueprint"
|
|
||||||
);
|
|
||||||
if (recipeItem && recipeItem.ItemCount > 0) {
|
|
||||||
const recipe = ExportRecipes[recipeItem.ItemType];
|
|
||||||
if (!inventory.MiscItems.find(i => i.ItemType == recipe.resultType)) {
|
|
||||||
await addItem(inventory, recipe.resultType);
|
|
||||||
await addItem(inventory, recipe.resultType, -1, false, undefined, undefined, true);
|
|
||||||
if (recipe.consumeOnUse) await addItem(inventory, recipeItem.ItemType, -1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case "/Lotus/Types/Game/CrewShip/RailJack/DefaultHarness": {
|
|
||||||
const recipeItem = inventory.Recipes.find(
|
|
||||||
i => i.ItemType == "/Lotus/Types/Recipes/ArchwingRecipes/StandardArchwing/StandardArchwingBlueprint"
|
|
||||||
);
|
|
||||||
if (recipeItem && recipeItem.ItemCount > 0) {
|
|
||||||
const recipe = ExportRecipes[recipeItem.ItemType];
|
|
||||||
if (!inventory.MiscItems.find(i => i.ItemType == recipe.resultType)) {
|
|
||||||
await addItem(inventory, recipe.resultType);
|
|
||||||
if (recipe.consumeOnUse) await addItem(inventory, recipeItem.ItemType, recipeItem.ItemCount * -1);
|
|
||||||
await addItems(inventory, [
|
|
||||||
{
|
|
||||||
ItemType:
|
|
||||||
"/Lotus/Types/Recipes/ArchwingRecipes/StandardArchwing/StandardArchwingWingsBlueprint",
|
|
||||||
ItemCount: -1
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ItemType:
|
|
||||||
"/Lotus/Types/Recipes/ArchwingRecipes/StandardArchwing/StandardArchwingChassisBlueprint",
|
|
||||||
ItemCount: -1
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ItemType:
|
|
||||||
"/Lotus/Types/Recipes/ArchwingRecipes/StandardArchwing/StandardArchwingSystemsBlueprint",
|
|
||||||
ItemCount: -1
|
|
||||||
}
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case "/Lotus/Types/Keys/ModQuest/ModQuestKeyChain": {
|
|
||||||
const recipeItem = inventory.Recipes.find(
|
|
||||||
i => i.ItemType == "/Lotus/Types/Recipes/Components/VorBoltRemoverBlueprint"
|
|
||||||
);
|
|
||||||
if (recipeItem && recipeItem.ItemCount > 0) {
|
|
||||||
const recipe = ExportRecipes[recipeItem.ItemType];
|
|
||||||
if (!inventory.MiscItems.find(i => i.ItemType == recipe.resultType)) {
|
|
||||||
await addItem(inventory, recipe.resultType);
|
|
||||||
if (recipe.consumeOnUse) await addItem(inventory, recipeItem.ItemType, -1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case "/Lotus/Types/Recipes/WarframeRecipes/ChromaBlueprint": {
|
|
||||||
await addItems(inventory, [
|
|
||||||
{
|
|
||||||
ItemType: "/Lotus/Types/Recipes/WarframeRecipes/ChromaBeaconABlueprint",
|
|
||||||
ItemCount: -1
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ItemType: "/Lotus/Types/Recipes/WarframeRecipes/ChromaBeaconBBlueprint",
|
|
||||||
ItemCount: -1
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ItemType: "/Lotus/Types/Recipes/WarframeRecipes/ChromaBeaconCBlueprint",
|
|
||||||
ItemCount: -1
|
|
||||||
}
|
|
||||||
]);
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case "/Lotus/Types/Recipes/WarframeRecipes/OctaviaBlueprint": {
|
|
||||||
const recipeItem = inventory.Recipes.find(
|
|
||||||
i => i.ItemType == "/Lotus/Types/Keys/BardQuest/BardQuestSequencerBlueprint"
|
|
||||||
);
|
|
||||||
if (recipeItem && recipeItem.ItemCount > 0) {
|
|
||||||
const recipe = ExportRecipes[recipeItem.ItemType];
|
|
||||||
if (!inventory.MiscItems.find(i => i.ItemType == recipe.resultType)) {
|
|
||||||
await addItem(inventory, recipe.resultType);
|
|
||||||
if (recipe.consumeOnUse) await addItem(inventory, recipeItem.ItemType, -1);
|
|
||||||
await addItems(inventory, [
|
|
||||||
{
|
|
||||||
ItemType: "/Lotus/Types/Keys/BardQuest/BardQuestSequencerPartA",
|
|
||||||
ItemCount: -1
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ItemType: "/Lotus/Types/Keys/BardQuest/BardQuestSequencerPartB",
|
|
||||||
ItemCount: -1
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ItemType: "/Lotus/Types/Keys/BardQuest/BardQuestSequencerPartC",
|
|
||||||
ItemCount: -1
|
|
||||||
}
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case "/Lotus/Types/Game/CrewShip/Ships/RailJack": {
|
|
||||||
const recipeItem = inventory.Recipes.find(
|
|
||||||
i => i.ItemType == "/Lotus/Types/Recipes/Railjack/RailjackCephalonBlueprint"
|
|
||||||
);
|
|
||||||
if (recipeItem && recipeItem.ItemCount > 0) {
|
|
||||||
const recipe = ExportRecipes[recipeItem.ItemType];
|
|
||||||
if (!inventory.MiscItems.find(i => i.ItemType == recipe.resultType)) {
|
|
||||||
await addItem(inventory, recipe.resultType);
|
|
||||||
if (recipe.consumeOnUse) await addItem(inventory, recipeItem.ItemType, recipeItem.ItemCount * -1);
|
|
||||||
await unlockShipFeature(inventory, recipe.resultType);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case "/Lotus/Types/Items/ShipDecos/MummyQuestVessel": {
|
|
||||||
const gearItem = inventory.Consumables.find(
|
|
||||||
i => i.ItemType == "/Lotus/Types/Keys/MummyQuest/MummyArtifact01GearItem"
|
|
||||||
);
|
|
||||||
if (gearItem && gearItem.ItemCount > 0) {
|
|
||||||
await addItem(inventory, gearItem.ItemType, gearItem.ItemCount * -1);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case "/Lotus/Types/Recipes/WarframeRecipes/ConcreteFrameBlueprint": {
|
|
||||||
const recipeItem = inventory.Recipes.find(
|
|
||||||
i => i.ItemType == "/Lotus/Types/Gameplay/EntratiLab/Quest/GargoyleRecipeItem"
|
|
||||||
);
|
|
||||||
if (recipeItem && recipeItem.ItemCount > 0) {
|
|
||||||
const recipe = ExportRecipes[recipeItem.ItemType];
|
|
||||||
if (!inventory.MiscItems.find(i => i.ItemType == recipe.resultType)) {
|
|
||||||
await addItem(inventory, recipe.resultType);
|
|
||||||
if (recipe.consumeOnUse) await addItem(inventory, recipeItem.ItemType, recipeItem.ItemCount * -1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case "/Lotus/Upgrades/Skins/Umbra/UmbraAltHelmet": {
|
|
||||||
const recipeItem = inventory.Recipes.find(
|
|
||||||
i => i.ItemType == "/Lotus/Types/Recipes/WarframeRecipes/ExcaliburUmbraBlueprint"
|
|
||||||
);
|
|
||||||
if (recipeItem && recipeItem.ItemCount > 0) {
|
|
||||||
const recipe = ExportRecipes[recipeItem.ItemType];
|
|
||||||
if (!inventory.MiscItems.find(i => i.ItemType == recipe.resultType)) {
|
|
||||||
const umbraModA = (
|
|
||||||
await addItem(
|
|
||||||
inventory,
|
|
||||||
"/Lotus/Upgrades/Mods/Sets/Umbra/WarframeUmbraModA",
|
|
||||||
1,
|
|
||||||
false,
|
|
||||||
undefined,
|
|
||||||
`{"lvl":5}`
|
|
||||||
)
|
|
||||||
).Upgrades![0];
|
|
||||||
const umbraModB = (
|
|
||||||
await addItem(
|
|
||||||
inventory,
|
|
||||||
"/Lotus/Upgrades/Mods/Sets/Umbra/WarframeUmbraModB",
|
|
||||||
1,
|
|
||||||
false,
|
|
||||||
undefined,
|
|
||||||
`{"lvl":5}`
|
|
||||||
)
|
|
||||||
).Upgrades![0];
|
|
||||||
const umbraModC = (
|
|
||||||
await addItem(
|
|
||||||
inventory,
|
|
||||||
"/Lotus/Upgrades/Mods/Sets/Umbra/WarframeUmbraModC",
|
|
||||||
1,
|
|
||||||
false,
|
|
||||||
undefined,
|
|
||||||
`{"lvl":5}`
|
|
||||||
)
|
|
||||||
).Upgrades![0];
|
|
||||||
const sacrificeModA = (
|
|
||||||
await addItem(
|
|
||||||
inventory,
|
|
||||||
"/Lotus/Upgrades/Mods/Sets/Sacrifice/MeleeSacrificeModA",
|
|
||||||
1,
|
|
||||||
false,
|
|
||||||
undefined,
|
|
||||||
`{"lvl":5}`
|
|
||||||
)
|
|
||||||
).Upgrades![0];
|
|
||||||
const sacrificeModB = (
|
|
||||||
await addItem(
|
|
||||||
inventory,
|
|
||||||
"/Lotus/Upgrades/Mods/Sets/Sacrifice/MeleeSacrificeModB",
|
|
||||||
1,
|
|
||||||
false,
|
|
||||||
undefined,
|
|
||||||
`{"lvl":5}`
|
|
||||||
)
|
|
||||||
).Upgrades![0];
|
|
||||||
|
|
||||||
await addPowerSuit(inventory, "/Lotus/Powersuits/Excalibur/ExcaliburUmbra", {
|
|
||||||
Configs: [
|
|
||||||
{
|
|
||||||
Upgrades: [
|
|
||||||
"",
|
|
||||||
"",
|
|
||||||
"",
|
|
||||||
"",
|
|
||||||
"",
|
|
||||||
umbraModA.ItemId.$oid,
|
|
||||||
umbraModB.ItemId.$oid,
|
|
||||||
umbraModC.ItemId.$oid
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
XP: 900_000,
|
|
||||||
Features: EquipmentFeatures.DOUBLE_CAPACITY
|
|
||||||
});
|
|
||||||
inventory.XPInfo.push({
|
|
||||||
ItemType: "/Lotus/Powersuits/Excalibur/ExcaliburUmbra",
|
|
||||||
XP: 900_000
|
|
||||||
});
|
|
||||||
|
|
||||||
addEquipment(inventory, "Melee", "/Lotus/Weapons/Tenno/Melee/Swords/UmbraKatana/UmbraKatana", {
|
|
||||||
Configs: [
|
|
||||||
{
|
|
||||||
Upgrades: ["", "", "", "", "", "", sacrificeModA.ItemId.$oid, sacrificeModB.ItemId.$oid]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
XP: 450_000,
|
|
||||||
Features: EquipmentFeatures.DOUBLE_CAPACITY
|
|
||||||
});
|
|
||||||
inventory.XPInfo.push({
|
|
||||||
ItemType: "/Lotus/Weapons/Tenno/Melee/Swords/UmbraKatana/UmbraKatana",
|
|
||||||
XP: 450_000
|
|
||||||
});
|
|
||||||
if (recipe.consumeOnUse) await addItem(inventory, recipeItem.ItemType, recipeItem.ItemCount * -1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|||||||
@ -12,8 +12,8 @@ let httpServer: http.Server | undefined;
|
|||||||
let httpsServer: https.Server | undefined;
|
let httpsServer: https.Server | undefined;
|
||||||
|
|
||||||
const tlsOptions = {
|
const tlsOptions = {
|
||||||
key: fs.readFileSync("static/cert/key.pem"),
|
key: fs.readFileSync("static/certs/key.pem"),
|
||||||
cert: fs.readFileSync("static/cert/cert.pem")
|
cert: fs.readFileSync("static/certs/cert.pem")
|
||||||
};
|
};
|
||||||
|
|
||||||
export const startWebServer = (): void => {
|
export const startWebServer = (): void => {
|
||||||
|
|||||||
@ -10,7 +10,7 @@ import invasionNodes from "../../static/fixed_responses/worldState/invasionNodes
|
|||||||
import invasionRewards from "../../static/fixed_responses/worldState/invasionRewards.json" with { type: "json" };
|
import invasionRewards from "../../static/fixed_responses/worldState/invasionRewards.json" with { type: "json" };
|
||||||
import pvpChallenges from "../../static/fixed_responses/worldState/pvpChallenges.json" with { type: "json" };
|
import pvpChallenges from "../../static/fixed_responses/worldState/pvpChallenges.json" with { type: "json" };
|
||||||
import { buildConfig } from "./buildConfigService.ts";
|
import { buildConfig } from "./buildConfigService.ts";
|
||||||
import { EPOCH, unixTimesInMs } from "../constants/timeConstants.ts";
|
import { unixTimesInMs } from "../constants/timeConstants.ts";
|
||||||
import { config } from "./configService.ts";
|
import { config } from "./configService.ts";
|
||||||
import { getRandomElement, getRandomInt, sequentiallyUniqueRandomElement, SRng } from "./rngService.ts";
|
import { getRandomElement, getRandomInt, sequentiallyUniqueRandomElement, SRng } from "./rngService.ts";
|
||||||
import type { IMissionReward, IRegion, TFaction } from "warframe-public-export-plus";
|
import type { IMissionReward, IRegion, TFaction } from "warframe-public-export-plus";
|
||||||
@ -41,7 +41,6 @@ import type {
|
|||||||
import { toMongoDate, toOid, version_compare } from "../helpers/inventoryHelpers.ts";
|
import { toMongoDate, toOid, version_compare } from "../helpers/inventoryHelpers.ts";
|
||||||
import { logger } from "../utils/logger.ts";
|
import { logger } from "../utils/logger.ts";
|
||||||
import { DailyDeal, Fissure } from "../models/worldStateModel.ts";
|
import { DailyDeal, Fissure } from "../models/worldStateModel.ts";
|
||||||
import { getConquest } from "./conquestService.ts";
|
|
||||||
|
|
||||||
const sortieBosses = [
|
const sortieBosses = [
|
||||||
"SORTIE_BOSS_HYENA",
|
"SORTIE_BOSS_HYENA",
|
||||||
@ -277,6 +276,8 @@ const microplanetEndlessJobs: readonly string[] = [
|
|||||||
"/Lotus/Types/Gameplay/InfestedMicroplanet/Jobs/DeimosEndlessPurifyBounty"
|
"/Lotus/Types/Gameplay/InfestedMicroplanet/Jobs/DeimosEndlessPurifyBounty"
|
||||||
];
|
];
|
||||||
|
|
||||||
|
export const EPOCH = 1734307200 * 1000; // Monday, Dec 16, 2024 @ 00:00 UTC+0; should logically be winter in 1999 iteration 0
|
||||||
|
|
||||||
const isBeforeNextExpectedWorldStateRefresh = (nowMs: number, thenMs: number): boolean => {
|
const isBeforeNextExpectedWorldStateRefresh = (nowMs: number, thenMs: number): boolean => {
|
||||||
return nowMs + 300_000 > thenMs;
|
return nowMs + 300_000 > thenMs;
|
||||||
};
|
};
|
||||||
@ -3181,7 +3182,7 @@ export const getWorldState = (buildLabel?: string): IWorldState => {
|
|||||||
// Nightwave Challenges
|
// Nightwave Challenges
|
||||||
const nightwaveSyndicateTag = getNightwaveSyndicateTag(buildLabel);
|
const nightwaveSyndicateTag = getNightwaveSyndicateTag(buildLabel);
|
||||||
if (nightwaveSyndicateTag) {
|
if (nightwaveSyndicateTag) {
|
||||||
const nightwaveStartTimestamp = nightwaveTagToActivation[nightwaveSyndicateTag] ?? 1747851300000;
|
const nightwaveStartTimestamp = 1747851300000;
|
||||||
const nightwaveSeason = nightwaveTagToSeason[nightwaveSyndicateTag];
|
const nightwaveSeason = nightwaveTagToSeason[nightwaveSyndicateTag];
|
||||||
worldState.SeasonInfo = {
|
worldState.SeasonInfo = {
|
||||||
Activation: { $date: { $numberLong: nightwaveStartTimestamp.toString() } },
|
Activation: { $date: { $numberLong: nightwaveStartTimestamp.toString() } },
|
||||||
@ -3468,18 +3469,6 @@ export const getWorldState = (buildLabel?: string): IWorldState => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Void Storms
|
|
||||||
const hour = Math.trunc(timeMs / unixTimesInMs.hour);
|
|
||||||
const overLastHourStormExpiry = hour * unixTimesInMs.hour + 10 * unixTimesInMs.minute;
|
|
||||||
const thisHourStormActivation = hour * unixTimesInMs.hour + 40 * unixTimesInMs.minute;
|
|
||||||
if (overLastHourStormExpiry > timeMs) {
|
|
||||||
pushVoidStorms(worldState.VoidStorms, hour - 2);
|
|
||||||
}
|
|
||||||
pushVoidStorms(worldState.VoidStorms, hour - 1);
|
|
||||||
if (isBeforeNextExpectedWorldStateRefresh(timeMs, thisHourStormActivation)) {
|
|
||||||
pushVoidStorms(worldState.VoidStorms, hour);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sortie & syndicate missions cycling every day (at 16:00 or 17:00 UTC depending on if London, OT is observing DST)
|
// Sortie & syndicate missions cycling every day (at 16:00 or 17:00 UTC depending on if London, OT is observing DST)
|
||||||
{
|
{
|
||||||
const rollover = getSortieTime(day);
|
const rollover = getSortieTime(day);
|
||||||
@ -3562,18 +3551,16 @@ export const getWorldState = (buildLabel?: string): IWorldState => {
|
|||||||
worldState.KnownCalendarSeasons.push(getCalendarSeason(week + 1));
|
worldState.KnownCalendarSeasons.push(getCalendarSeason(week + 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!buildLabel || version_compare(buildLabel, "2025.10.14.16.10") >= 0) {
|
// Void Storms
|
||||||
worldState.Conquests = [];
|
const hour = Math.trunc(timeMs / unixTimesInMs.hour);
|
||||||
{
|
const overLastHourStormExpiry = hour * unixTimesInMs.hour + 10 * unixTimesInMs.minute;
|
||||||
const season = (["CST_WINTER", "CST_SPRING", "CST_SUMMER", "CST_FALL"] as const)[week % 4];
|
const thisHourStormActivation = hour * unixTimesInMs.hour + 40 * unixTimesInMs.minute;
|
||||||
worldState.Conquests.push(getConquest("CT_LAB", week, null));
|
if (overLastHourStormExpiry > timeMs) {
|
||||||
worldState.Conquests.push(getConquest("CT_HEX", week, season));
|
pushVoidStorms(worldState.VoidStorms, hour - 2);
|
||||||
}
|
}
|
||||||
if (isBeforeNextExpectedWorldStateRefresh(timeMs, weekEnd)) {
|
pushVoidStorms(worldState.VoidStorms, hour - 1);
|
||||||
const season = (["CST_WINTER", "CST_SPRING", "CST_SUMMER", "CST_FALL"] as const)[(week + 1) % 4];
|
if (isBeforeNextExpectedWorldStateRefresh(timeMs, thisHourStormActivation)) {
|
||||||
worldState.Conquests.push(getConquest("CT_LAB", week, null));
|
pushVoidStorms(worldState.VoidStorms, hour);
|
||||||
worldState.Conquests.push(getConquest("CT_HEX", week, season));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sentient Anomaly + Xtra Cheese cycles
|
// Sentient Anomaly + Xtra Cheese cycles
|
||||||
@ -3822,10 +3809,6 @@ const nightwaveTagToSeason: Record<string, number> = {
|
|||||||
RadioLegionSyndicate: 0 // The Wolf of Saturn Six
|
RadioLegionSyndicate: 0 // The Wolf of Saturn Six
|
||||||
};
|
};
|
||||||
|
|
||||||
const nightwaveTagToActivation: Record<string, number> = {
|
|
||||||
RadioLegionIntermission14Syndicate: 1761589199000
|
|
||||||
};
|
|
||||||
|
|
||||||
const updateFissures = async (): Promise<void> => {
|
const updateFissures = async (): Promise<void> => {
|
||||||
const fissures = await Fissure.find();
|
const fissures = await Fissure.find();
|
||||||
|
|
||||||
|
|||||||
@ -14,7 +14,6 @@ import type { IOrbiterClient } from "../personalRoomsTypes.ts";
|
|||||||
import type { ICountedStoreItem } from "warframe-public-export-plus";
|
import type { ICountedStoreItem } from "warframe-public-export-plus";
|
||||||
import type { IEquipmentClient, IEquipmentDatabase, ITraits } from "../equipmentTypes.ts";
|
import type { IEquipmentClient, IEquipmentDatabase, ITraits } from "../equipmentTypes.ts";
|
||||||
import type { ILoadOutPresets } from "../saveLoadoutTypes.ts";
|
import type { ILoadOutPresets } from "../saveLoadoutTypes.ts";
|
||||||
import type { CalendarSeasonType } from "../worldStateTypes.ts";
|
|
||||||
|
|
||||||
export type InventoryDatabaseEquipment = {
|
export type InventoryDatabaseEquipment = {
|
||||||
[_ in TEquipmentKey]: IEquipmentDatabase[];
|
[_ in TEquipmentKey]: IEquipmentDatabase[];
|
||||||
@ -1181,7 +1180,7 @@ export interface IMarker {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface ISeasonProgress {
|
export interface ISeasonProgress {
|
||||||
SeasonType: CalendarSeasonType;
|
SeasonType: "CST_WINTER" | "CST_SPRING" | "CST_SUMMER" | "CST_FALL";
|
||||||
LastCompletedDayIdx: number;
|
LastCompletedDayIdx: number;
|
||||||
LastCompletedChallengeDayIdx: number;
|
LastCompletedChallengeDayIdx: number;
|
||||||
ActivatedChallenges: string[];
|
ActivatedChallenges: string[];
|
||||||
|
|||||||
@ -55,8 +55,6 @@ export interface ILoginResponse extends IAccountAndLoginResponseCommons {
|
|||||||
DTLS?: number;
|
DTLS?: number;
|
||||||
IRC?: string[];
|
IRC?: string[];
|
||||||
HUB?: string;
|
HUB?: string;
|
||||||
NatHash?: string;
|
|
||||||
SteamId?: string;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IGroup {
|
export interface IGroup {
|
||||||
|
|||||||
@ -32,7 +32,6 @@ export interface IWorldState {
|
|||||||
ActiveChallenges: ISeasonChallenge[];
|
ActiveChallenges: ISeasonChallenge[];
|
||||||
};
|
};
|
||||||
KnownCalendarSeasons: ICalendarSeason[];
|
KnownCalendarSeasons: ICalendarSeason[];
|
||||||
Conquests?: IConquest[];
|
|
||||||
Tmp?: string;
|
Tmp?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -353,11 +352,10 @@ export interface ISeasonChallenge {
|
|||||||
Challenge: string;
|
Challenge: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type CalendarSeasonType = "CST_WINTER" | "CST_SPRING" | "CST_SUMMER" | "CST_FALL";
|
|
||||||
export interface ICalendarSeason {
|
export interface ICalendarSeason {
|
||||||
Activation: IMongoDate;
|
Activation: IMongoDate;
|
||||||
Expiry: IMongoDate;
|
Expiry: IMongoDate;
|
||||||
Season: CalendarSeasonType;
|
Season: "CST_WINTER" | "CST_SPRING" | "CST_SUMMER" | "CST_FALL";
|
||||||
Days: ICalendarDay[];
|
Days: ICalendarDay[];
|
||||||
YearIteration: number;
|
YearIteration: number;
|
||||||
Version: number;
|
Version: number;
|
||||||
@ -418,33 +416,6 @@ export interface IGameMarketCategory {
|
|||||||
Items?: string[];
|
Items?: string[];
|
||||||
}
|
}
|
||||||
|
|
||||||
// >= 40.0.0
|
|
||||||
export type TConquestType = "CT_LAB" | "CT_HEX";
|
|
||||||
export interface IConquest {
|
|
||||||
Activation: IMongoDate;
|
|
||||||
Expiry: IMongoDate;
|
|
||||||
Type: TConquestType;
|
|
||||||
Missions: IConquestMission[];
|
|
||||||
Variables: [string, string, string, string];
|
|
||||||
RandomSeed: number;
|
|
||||||
}
|
|
||||||
export interface IConquestMission {
|
|
||||||
faction: TFaction;
|
|
||||||
missionType: TMissionType;
|
|
||||||
difficulties: [
|
|
||||||
{
|
|
||||||
type: "CD_NORMAL";
|
|
||||||
deviation: string;
|
|
||||||
risks: [string];
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: "CD_HARD";
|
|
||||||
deviation: string;
|
|
||||||
risks: [string, string];
|
|
||||||
}
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface ITmp {
|
export interface ITmp {
|
||||||
cavabegin: string;
|
cavabegin: string;
|
||||||
PurchasePlatformLockEnabled: boolean; // Seems unused
|
PurchasePlatformLockEnabled: boolean; // Seems unused
|
||||||
@ -452,8 +423,6 @@ export interface ITmp {
|
|||||||
ennnd?: boolean; // True if 1999 demo is available (no effect for >=38.6.0)
|
ennnd?: boolean; // True if 1999 demo is available (no effect for >=38.6.0)
|
||||||
mbrt?: boolean; // Related to mobile app rating request
|
mbrt?: boolean; // Related to mobile app rating request
|
||||||
fbst: IFbst;
|
fbst: IFbst;
|
||||||
lqo?: IConquestOverride;
|
|
||||||
hqo?: IConquestOverride;
|
|
||||||
sfn: number;
|
sfn: number;
|
||||||
edg?: TCircuitGameMode[]; // The Circuit game modes overwrite
|
edg?: TCircuitGameMode[]; // The Circuit game modes overwrite
|
||||||
}
|
}
|
||||||
@ -482,12 +451,3 @@ interface IFbst {
|
|||||||
e: number;
|
e: number;
|
||||||
n: number;
|
n: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
// < 40.0.0
|
|
||||||
interface IConquestOverride {
|
|
||||||
mt?: string[]; // mission types but "Exterminate" instead of "MT_EXTERMINATION", etc. and "DualDefense" instead of "Defense" for hex conquest
|
|
||||||
mv?: string[];
|
|
||||||
mf?: number[]; // hex conquest only
|
|
||||||
c?: [string, string][];
|
|
||||||
fv?: string[];
|
|
||||||
}
|
|
||||||
|
|||||||
@ -1,70 +0,0 @@
|
|||||||
-----BEGIN CERTIFICATE-----
|
|
||||||
MIIF/DCCBGSgAwIBAgIQH1nGumKdC869SnXDdjpRizANBgkqhkiG9w0BAQsFADBg
|
|
||||||
MQswCQYDVQQGEwJHQjEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMTcwNQYDVQQD
|
|
||||||
Ey5TZWN0aWdvIFB1YmxpYyBTZXJ2ZXIgQXV0aGVudGljYXRpb24gQ0EgRFYgUjM2
|
|
||||||
MB4XDTI1MTAzMTAwMDAwMFoXDTI2MDMwNjIzNTk1OVowGDEWMBQGA1UEAwwNKi5m
|
|
||||||
YWtldGxzLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKZt+8pe
|
|
||||||
ZABBMSORWDlJBKykSbbNeEX2vPNrsQBqa3aBzQLdp6dm8qw099a5mn/vuQzdtFhc
|
|
||||||
QbaemxoVViszzM3dpTlOgLyl2r4cr8KMXJ/rRMqLeaYks+BVYJyxKAlVIduJCpP+
|
|
||||||
cxYUIiz+zNGMucuFdanzeNfCRhakDkzHH/LKZFYDHeqdR8vdUnOH8n9xuGR7sC6I
|
|
||||||
PbfML8SXCnazMpcPAeIFzJeZW3fbFIQ5R6B7X38k9+wUzKXrJo0+Q8U1mIAsV7fh
|
|
||||||
4gn+xgrFOJ7T2Vd8EtHgnr5nzNRDk4prE+ecTxBveL4QGuNoPaABtor6OLBR54AQ
|
|
||||||
8ycj29lQ094BrJcCAwEAAaOCAngwggJ0MB8GA1UdIwQYMBaAFGjAEhYYDq/O9oem
|
|
||||||
MlejRlFdywcnMB0GA1UdDgQWBBRqYi9dBjbiV9wE6GEtzyzUM6cQmjAOBgNVHQ8B
|
|
||||||
Af8EBAMCBaAwDAYDVR0TAQH/BAIwADATBgNVHSUEDDAKBggrBgEFBQcDATBJBgNV
|
|
||||||
HSAEQjBAMDQGCysGAQQBsjEBAgIHMCUwIwYIKwYBBQUHAgEWF2h0dHBzOi8vc2Vj
|
|
||||||
dGlnby5jb20vQ1BTMAgGBmeBDAECATCBhAYIKwYBBQUHAQEEeDB2ME8GCCsGAQUF
|
|
||||||
BzAChkNodHRwOi8vY3J0LnNlY3RpZ28uY29tL1NlY3RpZ29QdWJsaWNTZXJ2ZXJB
|
|
||||||
dXRoZW50aWNhdGlvbkNBRFZSMzYuY3J0MCMGCCsGAQUFBzABhhdodHRwOi8vb2Nz
|
|
||||||
cC5zZWN0aWdvLmNvbTAlBgNVHREEHjAcgg0qLmZha2V0bHMuY29tggtmYWtldGxz
|
|
||||||
LmNvbTCCAQQGCisGAQQB1nkCBAIEgfUEgfIA8AB2AJaXZL9VWJet90OHaDcIQnfp
|
|
||||||
8DrV9qTzNm5GpD8PyqnGAAABmjqerq4AAAQDAEcwRQIgY1YdLRDkbq9U9qGLpX5M
|
|
||||||
IESNpCLFKVgoPLyNQQejtPUCIQCGlFB13fGO7GpVZLXyuOrXIWRZQUxnm1GqhvOP
|
|
||||||
BoovPgB2ANFuqaVoB35mNaA/N6XdvAOlPEESFNSIGPXpMbMjy5UEAAABmjqerwkA
|
|
||||||
AAQDAEcwRQIhAMxyLWnCpof354KMPYiWQmqd+2D+yyV5ZL7rmvIJw0ojAiAxxsid
|
|
||||||
se3hTmdo39MJLKyVqlZKUua5dmLckUYUImsogTANBgkqhkiG9w0BAQsFAAOCAYEA
|
|
||||||
ByJlO00LMIgL6d5xfouZHl1OL2w0DDiWHQa87BM9AqUFSgE1IsWyUAMTVoxNp3bM
|
|
||||||
c4fiBoJ9P32hDft2gJRCtJ+xOlU9ufQqCfpN9pBxe8eEldJdnHi7q9Y1dIVwRA+y
|
|
||||||
xY2r1xgTmjYgv1Uo5mQoOjgvrRdUNTyW0Rkp9+9zr6NFxi4orqypt4KKOFY2DlV9
|
|
||||||
wKmS4HPXSNR6QEylUR1+IsCP7iQzgTcZDYYLH2vAekJ1vFJkxZyB8a1vjuUxohPi
|
|
||||||
JoXnOqBu5T9JdE81/Rm01bHQ6XAiAHpQRCyZZ3TBUgpPd10DrV8K/gMuBduKOkgk
|
|
||||||
BnwNZjOCcCwgI66F5kmoeT95ovn8ApKO9aT3EfYXx3XM+xaWjEQRpXulB9AYjQvg
|
|
||||||
wxdW+cpHAa/ttPEnrb4y2Az4uYMM2016U5p1o6SP3/feGbWSsJ33OF4VvSaS1x0h
|
|
||||||
DgzfqIX4/8yeYsfNNsoSpcwV9UGBZ7Zs0Avy1Mm5ah0Z6CGGKVWb7Qqse1YR9MSa
|
|
||||||
-----END CERTIFICATE-----
|
|
||||||
-----BEGIN CERTIFICATE-----
|
|
||||||
MIIGTDCCBDSgAwIBAgIQOXpmzCdWNi4NqofKbqvjsTANBgkqhkiG9w0BAQwFADBf
|
|
||||||
MQswCQYDVQQGEwJHQjEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMTYwNAYDVQQD
|
|
||||||
Ey1TZWN0aWdvIFB1YmxpYyBTZXJ2ZXIgQXV0aGVudGljYXRpb24gUm9vdCBSNDYw
|
|
||||||
HhcNMjEwMzIyMDAwMDAwWhcNMzYwMzIxMjM1OTU5WjBgMQswCQYDVQQGEwJHQjEY
|
|
||||||
MBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMTcwNQYDVQQDEy5TZWN0aWdvIFB1Ymxp
|
|
||||||
YyBTZXJ2ZXIgQXV0aGVudGljYXRpb24gQ0EgRFYgUjM2MIIBojANBgkqhkiG9w0B
|
|
||||||
AQEFAAOCAY8AMIIBigKCAYEAljZf2HIz7+SPUPQCQObZYcrxLTHYdf1ZtMRe7Yeq
|
|
||||||
RPSwygz16qJ9cAWtWNTcuICc++p8Dct7zNGxCpqmEtqifO7NvuB5dEVexXn9RFFH
|
|
||||||
12Hm+NtPRQgXIFjx6MSJcNWuVO3XGE57L1mHlcQYj+g4hny90aFh2SCZCDEVkAja
|
|
||||||
EMMfYPKuCjHuuF+bzHFb/9gV8P9+ekcHENF2nR1efGWSKwnfG5RawlkaQDpRtZTm
|
|
||||||
M64TIsv/r7cyFO4nSjs1jLdXYdz5q3a4L0NoabZfbdxVb+CUEHfB0bpulZQtH1Rv
|
|
||||||
38e/lIdP7OTTIlZh6OYL6NhxP8So0/sht/4J9mqIGxRFc0/pC8suja+wcIUna0HB
|
|
||||||
pXKfXTKpzgis+zmXDL06ASJf5E4A2/m+Hp6b84sfPAwQ766rI65mh50S0Di9E3Pn
|
|
||||||
2WcaJc+PILsBmYpgtmgWTR9eV9otfKRUBfzHUHcVgarub/XluEpRlTtZudU5xbFN
|
|
||||||
xx/DgMrXLUAPaI60fZ6wA+PTAgMBAAGjggGBMIIBfTAfBgNVHSMEGDAWgBRWc1hk
|
|
||||||
lfmSGrASKgRieaFAFYghSTAdBgNVHQ4EFgQUaMASFhgOr872h6YyV6NGUV3LBycw
|
|
||||||
DgYDVR0PAQH/BAQDAgGGMBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0lBBYwFAYI
|
|
||||||
KwYBBQUHAwEGCCsGAQUFBwMCMBsGA1UdIAQUMBIwBgYEVR0gADAIBgZngQwBAgEw
|
|
||||||
VAYDVR0fBE0wSzBJoEegRYZDaHR0cDovL2NybC5zZWN0aWdvLmNvbS9TZWN0aWdv
|
|
||||||
UHVibGljU2VydmVyQXV0aGVudGljYXRpb25Sb290UjQ2LmNybDCBhAYIKwYBBQUH
|
|
||||||
AQEEeDB2ME8GCCsGAQUFBzAChkNodHRwOi8vY3J0LnNlY3RpZ28uY29tL1NlY3Rp
|
|
||||||
Z29QdWJsaWNTZXJ2ZXJBdXRoZW50aWNhdGlvblJvb3RSNDYucDdjMCMGCCsGAQUF
|
|
||||||
BzABhhdodHRwOi8vb2NzcC5zZWN0aWdvLmNvbTANBgkqhkiG9w0BAQwFAAOCAgEA
|
|
||||||
YtOC9Fy+TqECFw40IospI92kLGgoSZGPOSQXMBqmsGWZUQ7rux7cj1du6d9rD6C8
|
|
||||||
ze1B2eQjkrGkIL/OF1s7vSmgYVafsRoZd/IHUrkoQvX8FZwUsmPu7amgBfaY3g+d
|
|
||||||
q1x0jNGKb6I6Bzdl6LgMD9qxp+3i7GQOnd9J8LFSietY6Z4jUBzVoOoz8iAU84OF
|
|
||||||
h2HhAuiPw1ai0VnY38RTI+8kepGWVfGxfBWzwH9uIjeooIeaosVFvE8cmYUB4TSH
|
|
||||||
5dUyD0jHct2+8ceKEtIoFU/FfHq/mDaVnvcDCZXtIgitdMFQdMZaVehmObyhRdDD
|
|
||||||
4NQCs0gaI9AAgFj4L9QtkARzhQLNyRf87Kln+YU0lgCGr9HLg3rGO8q+Y4ppLsOd
|
|
||||||
unQZ6ZxPNGIfOApbPVf5hCe58EZwiWdHIMn9lPP6+F404y8NNugbQixBber+x536
|
|
||||||
WrZhFZLjEkhp7fFXf9r32rNPfb74X/U90Bdy4lzp3+X1ukh1BuMxA/EEhDoTOS3l
|
|
||||||
7ABvc7BYSQubQ2490OcdkIzUh3ZwDrakMVrbaTxUM2p24N6dB+ns2zptWCva6jzW
|
|
||||||
r8IWKIMxzxLPv5Kt3ePKcUdvkBU/smqujSczTzzSjIoR5QqQA6lN1ZRSnuHIWCvh
|
|
||||||
JEltkYnTAH41QJ6SAWO66GrrUESwN/cgZzL4JLEqz1Y=
|
|
||||||
-----END CERTIFICATE-----
|
|
||||||
@ -1,28 +0,0 @@
|
|||||||
-----BEGIN PRIVATE KEY-----
|
|
||||||
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCmbfvKXmQAQTEj
|
|
||||||
kVg5SQSspEm2zXhF9rzza7EAamt2gc0C3aenZvKsNPfWuZp/77kM3bRYXEG2npsa
|
|
||||||
FVYrM8zN3aU5ToC8pdq+HK/CjFyf60TKi3mmJLPgVWCcsSgJVSHbiQqT/nMWFCIs
|
|
||||||
/szRjLnLhXWp83jXwkYWpA5Mxx/yymRWAx3qnUfL3VJzh/J/cbhke7AuiD23zC/E
|
|
||||||
lwp2szKXDwHiBcyXmVt32xSEOUege19/JPfsFMyl6yaNPkPFNZiALFe34eIJ/sYK
|
|
||||||
xTie09lXfBLR4J6+Z8zUQ5OKaxPnnE8Qb3i+EBrjaD2gAbaK+jiwUeeAEPMnI9vZ
|
|
||||||
UNPeAayXAgMBAAECggEAOYwMJVRwFZp1KExIij5STHPePURc0yxW94CESpWBpQ+K
|
|
||||||
2PPV1c+GF7+U9v1ki9pTTTyX8HmuCzxaezFngza9GW4LhH49i3153oTCzW2FVZKf
|
|
||||||
Tb3eiXFldStwZZ3oLxntxCBltPilyLubeZ19KvQTBmmWXvaeEVTOsWN2wluUE3oT
|
|
||||||
QEEFJmvWSj6Ow5HwA2xZP5dD4gv7nCY1swTePVLgWtJDC3AWDmKv3mB28brmtaDw
|
|
||||||
wP/Oq9LLlHJDK+AzJEuUs+VDFQi7j6yqXWglSjO3Jwkkfkqg/SSoZ9BKdd6i0DLs
|
|
||||||
UnUWHHATpv0Lwsa7w8csQBwfskUxsXECZpwzpCgsIQKBgQDYl2wvwjjG6qZtr060
|
|
||||||
rj4PDkFLxFbtlmBiyW9ShM6iqK6FWQJJ1FNr6MdM2zBqw+n4tldpU3DnuZQphgZK
|
|
||||||
57jejWFsHH5DYkS8k0k021AYT2IyCFHoEF43LlbRDXQguw1fADnoy6FpJBaRzuxx
|
|
||||||
jPEHdB/aYqngmTXglFYkizN2BwKBgQDEthR1FV5iPdQXKSR+Yu2irBzpxY1xhdd2
|
|
||||||
V5082etd2vBvAT7e4k8MroNMuYqL8miu2SeTJEyNkpCVoxQPF4uavandoRuEFIZl
|
|
||||||
8VPVvG5xqYIqXAJ4XlSImEgUww+jJfyLzHT0TZi6rrdHV/8zUXEimjc6OBZVafDg
|
|
||||||
FP6Lqo/w8QKBgQCxx3B8rv3tgDNFOqzur0qvDvNXnnv/nfvVeiPO5sW5S52cRJgV
|
|
||||||
Q5uJqlLUaeGO8Oo+RGTxRhUZjwDnKGRH3XWn7wI1PBoDc0iaRIbFRPK0UYx3Js8c
|
|
||||||
HTtILdgC1fko2IA8JzJhO6tsYrvHyMHY3mgExzNSDMQFX5ySjw86BawixwKBgBGc
|
|
||||||
J0qwBgoPdOw53618179HXzNCXz45eCd9AnOPIrX9Qqb9Wo6DfgYpnVGCDrgmlF6K
|
|
||||||
zDMs/bly1ITA26vaNMI+lnVj1d3GJJ39s76fpteAEEoQgJwb/b9YuqM5Ly4w2WH+
|
|
||||||
hL3WMIUN3RSC+TKz6MfrPGR23vD4kfrNhlgkhcxRAoGAEb6nXwyWe5hg9+qE2fcf
|
|
||||||
W27VApoalmnDOGFHtGhUitbBw7mHPb6wsSh4mx5Ucccfb5WUO3Cq5aW3qsDdkM+a
|
|
||||||
YrBDbvw7PPcAX0vokpyFQvHH35AsIXQuYlQyGzcCdZkpFPIB5gVbLvbgxpBvEbVZ
|
|
||||||
mGJpw7X/6Pg0ux0Ze11cr2c=
|
|
||||||
-----END PRIVATE KEY-----
|
|
||||||
71
static/certs/cert.pem
Normal file
71
static/certs/cert.pem
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIGMDCCBRigAwIBAgIQX4800cgswlDH/QexMSnnnjANBgkqhkiG9w0BAQsFADCB
|
||||||
|
jzELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G
|
||||||
|
A1UEBxMHU2FsZm9yZDEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMTcwNQYDVQQD
|
||||||
|
Ey5TZWN0aWdvIFJTQSBEb21haW4gVmFsaWRhdGlvbiBTZWN1cmUgU2VydmVyIENB
|
||||||
|
MB4XDTI1MDMwNjAwMDAwMFoXDTI2MDMwNjIzNTk1OVowGDEWMBQGA1UEAwwNKi5m
|
||||||
|
YWtldGxzLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMe42XWK
|
||||||
|
HJuR7doFTX79zrEKfTlD2hjRIif3dHKJNTJNvZa52mIoHelP7RVUuFOhp7aZCNLh
|
||||||
|
IEzDyZObl8vwO6L2PVu5tbBEEoNixbpfhc8ZICEBuVo2UAhnJFcMJtuvtrCq+7ye
|
||||||
|
oczM/k/nh8FBz2WnLzWs4CZt1sa5knZXFmBmsHJQtQIC6vx7QzVcKGOlAosIEHSK
|
||||||
|
X4nIz5fLgWSzor1Gay56j31PTk+qRvlPQM2aKiLWnlLfRED4zHJqLe94itu8llPX
|
||||||
|
b6g+cLxxRKUpMqtG/15cDdBZwv40Dja7bmNfe1u4w2QCVLjvHVaVpNXbcRay/Mhn
|
||||||
|
M1w5LzDZmV58b18CAwEAAaOCAvwwggL4MB8GA1UdIwQYMBaAFI2MXsRUrYrhd+mb
|
||||||
|
+ZsF4bgBjWHhMB0GA1UdDgQWBBS6/x/N38wMJrQq/cE1oIcRERMonTAOBgNVHQ8B
|
||||||
|
Af8EBAMCBaAwDAYDVR0TAQH/BAIwADAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYB
|
||||||
|
BQUHAwIwSQYDVR0gBEIwQDA0BgsrBgEEAbIxAQICBzAlMCMGCCsGAQUFBwIBFhdo
|
||||||
|
dHRwczovL3NlY3RpZ28uY29tL0NQUzAIBgZngQwBAgEwgYQGCCsGAQUFBwEBBHgw
|
||||||
|
djBPBggrBgEFBQcwAoZDaHR0cDovL2NydC5zZWN0aWdvLmNvbS9TZWN0aWdvUlNB
|
||||||
|
RG9tYWluVmFsaWRhdGlvblNlY3VyZVNlcnZlckNBLmNydDAjBggrBgEFBQcwAYYX
|
||||||
|
aHR0cDovL29jc3Auc2VjdGlnby5jb20wJQYDVR0RBB4wHIINKi5mYWtldGxzLmNv
|
||||||
|
bYILZmFrZXRscy5jb20wggF+BgorBgEEAdZ5AgQCBIIBbgSCAWoBaAB2AJaXZL9V
|
||||||
|
WJet90OHaDcIQnfp8DrV9qTzNm5GpD8PyqnGAAABlWsz5fgAAAQDAEcwRQIgTN7Y
|
||||||
|
/mDqiD3RbGVLEOQK2wvXsboBolBRwGJFuFEsDScCIQCQ0qfb/0V8qqSxrkx/PiVS
|
||||||
|
1lSn5gBEnQUiQOkefcnW0gB2ABmG1Mcoqm/+ugNveCpNAZGqzi1yMQ+uzl1wQS0l
|
||||||
|
TMfUAAABlWsz5dAAAAQDAEcwRQIhAJnQJyrSCWWdi9Kyoa7XuMGyDKt183jJMY0E
|
||||||
|
71abTuBOAiBC+WnK1esG6xr8aVGHRcc+1U/I7LiaG3LCRMYtCKrTGwB2AMs49xWJ
|
||||||
|
fIShRF9bwd37yW7ymlnNRwppBYWwyxTDFFjnAAABlWsz5f4AAAQDAEcwRQIhAJUs
|
||||||
|
4PWDwyQJnCxCyEwFlFUY2uYQkGrQPA9f9Sw5Xk1fAiB63eQtZQGjvzvhOghy6z9a
|
||||||
|
8oGYbDfDQ/zfisMYO7rM6zANBgkqhkiG9w0BAQsFAAOCAQEAEHnSoeBbWiK3CS3a
|
||||||
|
px0BL+YXxRxdUcTMHgn5o+LlI9sWlpf+JLXmn7Z4QA6fAwT4k/Ue7xsmIq0OraDk
|
||||||
|
/pEVXWm1HO/9wUkGQg0DBi77BpfHircd7OWIMdt250Q8UAmZkOyhVgnwBcScqMwq
|
||||||
|
2T5CPaYvYGgYWx/qkIBv7JqhVbrP82rnF9b9ZUZ8GIE31chBmtMva9AsnAN5dmRw
|
||||||
|
81bVvPWXUfX30CYu5sxeWL06Zpy9nfJumxZri1SWXNTBjSvud2jsZ8tSCUAWLL/4
|
||||||
|
ui3Vien9m2oMOpaA8xbS88ZTk9Alm/o5febEKJZUPlytQzij8gQpiovFw2v+Cdei
|
||||||
|
+tFXKw==
|
||||||
|
-----END CERTIFICATE-----
|
||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIGEzCCA/ugAwIBAgIQfVtRJrR2uhHbdBYLvFMNpzANBgkqhkiG9w0BAQwFADCB
|
||||||
|
iDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0pl
|
||||||
|
cnNleSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNV
|
||||||
|
BAMTJVVTRVJUcnVzdCBSU0EgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTgx
|
||||||
|
MTAyMDAwMDAwWhcNMzAxMjMxMjM1OTU5WjCBjzELMAkGA1UEBhMCR0IxGzAZBgNV
|
||||||
|
BAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEYMBYGA1UE
|
||||||
|
ChMPU2VjdGlnbyBMaW1pdGVkMTcwNQYDVQQDEy5TZWN0aWdvIFJTQSBEb21haW4g
|
||||||
|
VmFsaWRhdGlvbiBTZWN1cmUgU2VydmVyIENBMIIBIjANBgkqhkiG9w0BAQEFAAOC
|
||||||
|
AQ8AMIIBCgKCAQEA1nMz1tc8INAA0hdFuNY+B6I/x0HuMjDJsGz99J/LEpgPLT+N
|
||||||
|
TQEMgg8Xf2Iu6bhIefsWg06t1zIlk7cHv7lQP6lMw0Aq6Tn/2YHKHxYyQdqAJrkj
|
||||||
|
eocgHuP/IJo8lURvh3UGkEC0MpMWCRAIIz7S3YcPb11RFGoKacVPAXJpz9OTTG0E
|
||||||
|
oKMbgn6xmrntxZ7FN3ifmgg0+1YuWMQJDgZkW7w33PGfKGioVrCSo1yfu4iYCBsk
|
||||||
|
Haswha6vsC6eep3BwEIc4gLw6uBK0u+QDrTBQBbwb4VCSmT3pDCg/r8uoydajotY
|
||||||
|
uK3DGReEY+1vVv2Dy2A0xHS+5p3b4eTlygxfFQIDAQABo4IBbjCCAWowHwYDVR0j
|
||||||
|
BBgwFoAUU3m/WqorSs9UgOHYm8Cd8rIDZsswHQYDVR0OBBYEFI2MXsRUrYrhd+mb
|
||||||
|
+ZsF4bgBjWHhMA4GA1UdDwEB/wQEAwIBhjASBgNVHRMBAf8ECDAGAQH/AgEAMB0G
|
||||||
|
A1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAbBgNVHSAEFDASMAYGBFUdIAAw
|
||||||
|
CAYGZ4EMAQIBMFAGA1UdHwRJMEcwRaBDoEGGP2h0dHA6Ly9jcmwudXNlcnRydXN0
|
||||||
|
LmNvbS9VU0VSVHJ1c3RSU0FDZXJ0aWZpY2F0aW9uQXV0aG9yaXR5LmNybDB2Bggr
|
||||||
|
BgEFBQcBAQRqMGgwPwYIKwYBBQUHMAKGM2h0dHA6Ly9jcnQudXNlcnRydXN0LmNv
|
||||||
|
bS9VU0VSVHJ1c3RSU0FBZGRUcnVzdENBLmNydDAlBggrBgEFBQcwAYYZaHR0cDov
|
||||||
|
L29jc3AudXNlcnRydXN0LmNvbTANBgkqhkiG9w0BAQwFAAOCAgEAMr9hvQ5Iw0/H
|
||||||
|
ukdN+Jx4GQHcEx2Ab/zDcLRSmjEzmldS+zGea6TvVKqJjUAXaPgREHzSyrHxVYbH
|
||||||
|
7rM2kYb2OVG/Rr8PoLq0935JxCo2F57kaDl6r5ROVm+yezu/Coa9zcV3HAO4OLGi
|
||||||
|
H19+24rcRki2aArPsrW04jTkZ6k4Zgle0rj8nSg6F0AnwnJOKf0hPHzPE/uWLMUx
|
||||||
|
RP0T7dWbqWlod3zu4f+k+TY4CFM5ooQ0nBnzvg6s1SQ36yOoeNDT5++SR2RiOSLv
|
||||||
|
xvcRviKFxmZEJCaOEDKNyJOuB56DPi/Z+fVGjmO+wea03KbNIaiGCpXZLoUmGv38
|
||||||
|
sbZXQm2V0TP2ORQGgkE49Y9Y3IBbpNV9lXj9p5v//cWoaasm56ekBYdbqbe4oyAL
|
||||||
|
l6lFhd2zi+WJN44pDfwGF/Y4QA5C5BIG+3vzxhFoYt/jmPQT2BVPi7Fp2RBgvGQq
|
||||||
|
6jG35LWjOhSbJuMLe/0CjraZwTiXWTb2qHSihrZe68Zk6s+go/lunrotEbaGmAhY
|
||||||
|
LcmsJWTyXnW0OMGuf1pGg+pRyrbxmRE1a6Vqe8YAsOf4vmSyrcjC8azjUeqkk+B5
|
||||||
|
yOGBQMkKW+ESPMFgKuOXwIlCypTPRpgSabuY0MLTDXJLR27lk8QyKGOHQ+SwMj4K
|
||||||
|
00u/I5sUKUErmgQfky3xxzlIPK1aEn8=
|
||||||
|
-----END CERTIFICATE-----
|
||||||
28
static/certs/key.pem
Normal file
28
static/certs/key.pem
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
-----BEGIN PRIVATE KEY-----
|
||||||
|
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDHuNl1ihybke3a
|
||||||
|
BU1+/c6xCn05Q9oY0SIn93RyiTUyTb2WudpiKB3pT+0VVLhToae2mQjS4SBMw8mT
|
||||||
|
m5fL8Dui9j1bubWwRBKDYsW6X4XPGSAhAblaNlAIZyRXDCbbr7awqvu8nqHMzP5P
|
||||||
|
54fBQc9lpy81rOAmbdbGuZJ2VxZgZrByULUCAur8e0M1XChjpQKLCBB0il+JyM+X
|
||||||
|
y4Fks6K9Rmsueo99T05Pqkb5T0DNmioi1p5S30RA+Mxyai3veIrbvJZT12+oPnC8
|
||||||
|
cUSlKTKrRv9eXA3QWcL+NA42u25jX3tbuMNkAlS47x1WlaTV23EWsvzIZzNcOS8w
|
||||||
|
2ZlefG9fAgMBAAECggEAT1Tti/LASks8300b60WFxG0WMJjzGMh5eMaiSpyVtNWM
|
||||||
|
aUKJrFOjDfnhgoeUcCPWKoG/L4Sc/+EFQMydDzTte120IasysEFZ2TZytAUdcZXZ
|
||||||
|
XUMCDQNl5vCRTsJU7Q5u0t4YAGRCgMcsfTDKi8lISGiQKBHzN1CJ74Xm13rgOInd
|
||||||
|
lAc0wd5S89sL6RYmRTj1LvuZ95EHXHqQGdv0fIFEyP3pF1iPwcoTuIVEeICqnEvW
|
||||||
|
vd8CVO68eH3HFIwioqjp4qW3pxPZMhVq4161805uAMkoQlE+7MtEVenmP++1u1gM
|
||||||
|
FjvAs3j9CZqOHZKcLlOtcGSwDlD++fCMMT4slLgLgQKBgQDy58E5nuYXdxlFQQk4
|
||||||
|
QccUKpyJ2aVXyp9xvTFBot/5Pik1SkuDzv2XU1OTxdxf3EongLy91nMJ2/6/39Je
|
||||||
|
lf0/2MjzCtJ/lSzZ/zpJAu86UkBkWBAA5loGIof6OKedbEIgqpJqtK59S+j3ExO9
|
||||||
|
eqa+uFrtt1UfaJG4A7TT+dIvIwKBgQDSfSOdSM5Dh3KsQHVnIWcIkzwTtlJlO+rG
|
||||||
|
6rDEADxw6Kp8VIL/dq4Foe8yW4VqLVrWUuZsU6jzC9GdnyYi6VaqZ/iSUtGkBMOT
|
||||||
|
WTTYhqXlURaQ13jhqdwCZJRbVI72JbXn2OGEv8DgXnk//QKED/8VdKqAzCSr1t1f
|
||||||
|
3yfwei0AlQKBgD19KU66yKg7/+umEP1quUiDmOjUbaSRqFcUe3mQD356m9ffnMob
|
||||||
|
BdrevxNzTNv/Wc4yKpUryic+x3gu4oQLF/annAbaQHsHejkdANYmpgRvedls6XAw
|
||||||
|
360Z5K4U1WlmVD8Mrs/QOTOCmdChxad7euZgqLPwat3ujKS2W3oljW1dAoGBAM4/
|
||||||
|
AB6lsDZLCfnuTxt2h1bHrh5CkAnR5AJ1BC+Ja6/WyvZ4eMOIroumWJKnStr3BgLr
|
||||||
|
yAxtDSbZddNUljGvIdRnfBEkRXbJlDlVN4rSpMtF4S6bcz7rCUDu/M9g05Qs70j2
|
||||||
|
IkPJAFzZNUWVzFlKs096uXbqkSQvrUq7ho8DqAThAoGBAL7Nrbr5LWcBgvwEhEla
|
||||||
|
VRfYb0FUrDwLIrVWntJjW566/pVQQ4BmatsblLjlQYWk9MCIYXWZbnB+2fRx9yjQ
|
||||||
|
Adggez7Dws/Mrh/wVudKgayHCy5Lgd8rYjNgC+VZf8XGrWX3QXMJ6UWAyQLTeoO7
|
||||||
|
hToW9o9CQMIhaR43G8di1kjF
|
||||||
|
-----END PRIVATE KEY-----
|
||||||
@ -1,160 +0,0 @@
|
|||||||
{
|
|
||||||
"/Lotus/Types/Keys/VorsPrize/MissionOne": [
|
|
||||||
{
|
|
||||||
"rewardType": "RT_STORE_ITEM",
|
|
||||||
"itemType": "/Lotus/StoreItems/Types/Items/ShipFeatureItems/SocialMenuFeatureItem"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"rewardType": "RT_STORE_ITEM",
|
|
||||||
"itemType": "/Lotus/StoreItems/Upgrades/Mods/Melee/WeaponMeleeDamageMod"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"rewardType": "RT_STORE_ITEM",
|
|
||||||
"itemType": "/Lotus/StoreItems/Upgrades/Mods/Rifle/WeaponDamageAmountMod"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"rewardType": "RT_STORE_ITEM",
|
|
||||||
"itemType": "/Lotus/StoreItems/Upgrades/Mods/Pistol/WeaponDamageAmountMod"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"rewardType": "RT_CREDITS",
|
|
||||||
"amount": 2500
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"/Lotus/Types/Keys/VorsPrize/MissionTwo": [
|
|
||||||
{
|
|
||||||
"rewardType": "RT_STORE_ITEM",
|
|
||||||
"itemType": "/Lotus/StoreItems/Types/Items/ShipFeatureItems/ModsFeatureItem"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"rewardType": "RT_STORE_ITEM",
|
|
||||||
"itemType": "/Lotus/StoreItems/Upgrades/Mods/Warframe/AvatarHealthMaxMod"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"rewardType": "RT_STORE_ITEM",
|
|
||||||
"itemType": "/Lotus/StoreItems/Upgrades/Mods/Warframe/AvatarShieldMaxMod"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"rewardType": "RT_STORE_ITEM",
|
|
||||||
"itemType": "/Lotus/StoreItems/Upgrades/Mods/Warframe/AvatarAbilityRangeMod"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"rewardType": "RT_STORE_ITEM",
|
|
||||||
"itemType": "/Lotus/StoreItems/Upgrades/Mods/Warframe/AvatarAbilityStrengthMod"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"rewardType": "RT_STORE_ITEM",
|
|
||||||
"itemType": "/Lotus/StoreItems/Upgrades/Mods/Warframe/AvatarAbilityDurationMod"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"rewardType": "RT_CREDITS",
|
|
||||||
"amount": 2500
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"/Lotus/Types/Keys/VorsPrize/MissionThree": [
|
|
||||||
{
|
|
||||||
"rewardType": "RT_STORE_ITEM",
|
|
||||||
"itemType": "/Lotus/StoreItems/Types/Items/ShipFeatureItems/FoundryFeatureItem"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"rewardType": "RT_STORE_ITEM",
|
|
||||||
"itemType": "/Lotus/StoreItems/Upgrades/Mods/Melee/WeaponFireRateMod"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"rewardType": "RT_STORE_ITEM",
|
|
||||||
"itemType": "/Lotus/StoreItems/Upgrades/Mods/Rifle/WeaponFactionDamageCorpus"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"rewardType": "RT_STORE_ITEM",
|
|
||||||
"itemType": "/Lotus/StoreItems/Upgrades/Mods/Rifle/WeaponFactionDamageGrineer"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"rewardType": "RT_STORE_ITEM",
|
|
||||||
"itemType": "/Lotus/StoreItems/Upgrades/Mods/Pistol/WeaponFireDamageMod"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"rewardType": "RT_STORE_ITEM",
|
|
||||||
"itemType": "/Lotus/StoreItems/Upgrades/Mods/Pistol/WeaponElectricityDamageMod"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"rewardType": "RT_CREDITS",
|
|
||||||
"amount": 2500
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"/Lotus/Types/Keys/VorsPrize/MissionFour": [
|
|
||||||
{
|
|
||||||
"rewardType": "RT_STORE_ITEM",
|
|
||||||
"itemType": "/Lotus/StoreItems/Upgrades/Mods/Warframe/AvatarPickupBonusMod"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"rewardType": "RT_STORE_ITEM",
|
|
||||||
"itemType": "/Lotus/StoreItems/Upgrades/Mods/Warframe/AvatarPowerMaxMod"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"rewardType": "RT_STORE_ITEM",
|
|
||||||
"itemType": "/Lotus/StoreItems/Upgrades/Mods/Warframe/AvatarEnemyRadarMod"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"rewardType": "RT_CREDITS",
|
|
||||||
"amount": 2500
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"/Lotus/Types/Keys/VorsPrize/MissionFive": [
|
|
||||||
{
|
|
||||||
"rewardType": "RT_STORE_ITEM",
|
|
||||||
"itemType": "/Lotus/StoreItems/Types/Items/ShipFeatureItems/MercuryNavigationFeatureItem"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"rewardType": "RT_STORE_ITEM",
|
|
||||||
"itemType": "/Lotus/StoreItems/Upgrades/Mods/FusionBundles/CommonFusionBundle"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"rewardType": "RT_STORE_ITEM",
|
|
||||||
"itemType": "/Lotus/StoreItems/Upgrades/Mods/FusionBundles/CommonFusionBundle"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"rewardType": "RT_STORE_ITEM",
|
|
||||||
"itemType": "/Lotus/StoreItems/Upgrades/Mods/FusionBundles/CommonFusionBundle"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"rewardType": "RT_STORE_ITEM",
|
|
||||||
"itemType": "/Lotus/StoreItems/Upgrades/Mods/FusionBundles/CommonFusionBundle"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"rewardType": "RT_STORE_ITEM",
|
|
||||||
"itemType": "/Lotus/StoreItems/Upgrades/Mods/FusionBundles/CommonFusionBundle"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"rewardType": "RT_STORE_ITEM",
|
|
||||||
"itemType": "/Lotus/StoreItems/Upgrades/Mods/FusionBundles/CommonFusionBundle"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"rewardType": "RT_STORE_ITEM",
|
|
||||||
"itemType": "/Lotus/StoreItems/Upgrades/Mods/FusionBundles/CommonFusionBundle"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"rewardType": "RT_STORE_ITEM",
|
|
||||||
"itemType": "/Lotus/StoreItems/Upgrades/Mods/FusionBundles/CommonFusionBundle"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"rewardType": "RT_STORE_ITEM",
|
|
||||||
"itemType": "/Lotus/StoreItems/Upgrades/Mods/FusionBundles/CommonFusionBundle"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"rewardType": "RT_STORE_ITEM",
|
|
||||||
"itemType": "/Lotus/StoreItems/Upgrades/Mods/FusionBundles/CommonFusionBundle"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"rewardType": "RT_STORE_ITEM",
|
|
||||||
"itemType": "/Lotus/StoreItems/Upgrades/Mods/FusionBundles/CommonFusionBundle"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"rewardType": "RT_STORE_ITEM",
|
|
||||||
"itemType": "/Lotus/StoreItems/Upgrades/Mods/FusionBundles/CommonFusionBundle"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"rewardType": "RT_CREDITS",
|
|
||||||
"amount": 5000
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
@ -1152,7 +1152,7 @@
|
|||||||
<button class="btn btn-primary" onclick="doHelminthUnlockAll();" data-loc="cheats_helminthUnlockAll"></button>
|
<button class="btn btn-primary" onclick="doHelminthUnlockAll();" data-loc="cheats_helminthUnlockAll"></button>
|
||||||
<button class="btn btn-primary" onclick="debounce(addMissingHelminthRecipes);" data-loc="cheats_addMissingSubsumedAbilities"></button>
|
<button class="btn btn-primary" onclick="debounce(addMissingHelminthRecipes);" data-loc="cheats_addMissingSubsumedAbilities"></button>
|
||||||
<button class="btn btn-primary" onclick="doIntrinsicsUnlockAll();" data-loc="cheats_intrinsicsUnlockAll"></button>
|
<button class="btn btn-primary" onclick="doIntrinsicsUnlockAll();" data-loc="cheats_intrinsicsUnlockAll"></button>
|
||||||
<button class="btn btn-primary" onclick="debounce(doMaxPlexus);" data-loc="cheats_maxPlexus"></button>
|
<button class="btn btn-primary" onclick="debounce(doMaxPlexus);" data-loc="inventory_maxPlexus"></button>
|
||||||
<button class="btn btn-primary" onclick="debounce(unlockAllProfitTakerStages);" data-loc="cheats_unlockAllProfitTakerStages"></button>
|
<button class="btn btn-primary" onclick="debounce(unlockAllProfitTakerStages);" data-loc="cheats_unlockAllProfitTakerStages"></button>
|
||||||
<button class="btn btn-primary" onclick="debounce(unlockAllSimarisResearchEntries);" data-loc="cheats_unlockAllSimarisResearchEntries"></button>
|
<button class="btn btn-primary" onclick="debounce(unlockAllSimarisResearchEntries);" data-loc="cheats_unlockAllSimarisResearchEntries"></button>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -169,7 +169,6 @@ function renameAccount(taken_name) {
|
|||||||
} else {
|
} else {
|
||||||
$(".displayname").text(newname);
|
$(".displayname").text(newname);
|
||||||
updateLocElements();
|
updateLocElements();
|
||||||
toast(loc("code_succRelog"));
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -647,7 +646,7 @@ function fetchItemList() {
|
|||||||
if ("badReason" in item) {
|
if ("badReason" in item) {
|
||||||
if (item.badReason == "starter") {
|
if (item.badReason == "starter") {
|
||||||
item.name = loc("code_starter").split("|MOD|").join(item.name);
|
item.name = loc("code_starter").split("|MOD|").join(item.name);
|
||||||
} else if (item.badReason != "notraw") {
|
} else {
|
||||||
item.name += " " + loc("code_badItem");
|
item.name += " " + loc("code_badItem");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1455,11 +1454,7 @@ function updateInventory() {
|
|||||||
{
|
{
|
||||||
const td = document.createElement("td");
|
const td = document.createElement("td");
|
||||||
td.textContent = itemMap[item.ItemType]?.name ?? item.ItemType;
|
td.textContent = itemMap[item.ItemType]?.name ?? item.ItemType;
|
||||||
if (itemMap[item.ItemType]?.badReason == "notraw") {
|
td.innerHTML += " <span title='" + loc("code_rank") + "'>★ " + rank + "/" + maxRank + "</span>";
|
||||||
// Assuming this is a riven with a pending challenge, so rank would be N/A, but otherwise it's fine.
|
|
||||||
} else {
|
|
||||||
td.innerHTML += " <span title='" + loc("code_rank") + "'>★ " + rank + "/" + maxRank + "</span>";
|
|
||||||
}
|
|
||||||
tr.appendChild(td);
|
tr.appendChild(td);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
|
|||||||
@ -51,7 +51,7 @@ dict = {
|
|||||||
code_focusUnlocked: `|COUNT| neue Fokus-Schulen freigeschaltet! Ein Inventar-Update wird benötigt, damit die Änderungen im Spiel sichtbar werden.`,
|
code_focusUnlocked: `|COUNT| neue Fokus-Schulen freigeschaltet! Ein Inventar-Update wird benötigt, damit die Änderungen im Spiel sichtbar werden.`,
|
||||||
code_addModsConfirm: `Bist du sicher, dass du |COUNT| Mods zu deinem Account hinzufügen möchtest?`,
|
code_addModsConfirm: `Bist du sicher, dass du |COUNT| Mods zu deinem Account hinzufügen möchtest?`,
|
||||||
code_succImport: `Erfolgreich importiert.`,
|
code_succImport: `Erfolgreich importiert.`,
|
||||||
code_succRelog: `Fertig. Bitte beachte, dass du dich neu anmelden musst, damit die Änderung im Spiel sichtbar wird.`,
|
code_succRelog: `Fertig. Bitte beachte, dass du dich neu anmelden musst, um Änderungen im Spiel zu sehen.`,
|
||||||
code_nothingToDo: `Fertig. Es gab nichts zu tun.`,
|
code_nothingToDo: `Fertig. Es gab nichts zu tun.`,
|
||||||
code_gild: `Veredeln`,
|
code_gild: `Veredeln`,
|
||||||
code_moa: `Moa`,
|
code_moa: `Moa`,
|
||||||
@ -134,6 +134,7 @@ dict = {
|
|||||||
inventory_bulkRankUpSentinels: `Alle Wächter auf Max. Rang`,
|
inventory_bulkRankUpSentinels: `Alle Wächter auf Max. Rang`,
|
||||||
inventory_bulkRankUpSentinelWeapons: `Alle Wächter-Waffen auf Max. Rang`,
|
inventory_bulkRankUpSentinelWeapons: `Alle Wächter-Waffen auf Max. Rang`,
|
||||||
inventory_bulkRankUpEvolutionProgress: `Alle Incarnon-Entwicklungsfortschritte auf Max. Rang`,
|
inventory_bulkRankUpEvolutionProgress: `Alle Incarnon-Entwicklungsfortschritte auf Max. Rang`,
|
||||||
|
inventory_maxPlexus: `Plexus auf Max. Rang`,
|
||||||
inventory_removeIsNew: `Entferne Ausrufezeichen bei neuem Equipment`,
|
inventory_removeIsNew: `Entferne Ausrufezeichen bei neuem Equipment`,
|
||||||
|
|
||||||
quests_list: `Quests`,
|
quests_list: `Quests`,
|
||||||
@ -259,7 +260,6 @@ dict = {
|
|||||||
cheats_helminthUnlockAll: `Helminth vollständig aufleveln`,
|
cheats_helminthUnlockAll: `Helminth vollständig aufleveln`,
|
||||||
cheats_addMissingSubsumedAbilities: `Fehlende konsumierte Fähigkeiten hinzufügen`,
|
cheats_addMissingSubsumedAbilities: `Fehlende konsumierte Fähigkeiten hinzufügen`,
|
||||||
cheats_intrinsicsUnlockAll: `Alle Inhärenzen auf Max. Rang`,
|
cheats_intrinsicsUnlockAll: `Alle Inhärenzen auf Max. Rang`,
|
||||||
cheats_maxPlexus: `Plexus auf Max. Rang`,
|
|
||||||
cheats_changeSupportedSyndicate: `Unterstütztes Syndikat`,
|
cheats_changeSupportedSyndicate: `Unterstütztes Syndikat`,
|
||||||
cheats_changeButton: `Ändern`,
|
cheats_changeButton: `Ändern`,
|
||||||
cheats_markAllAsRead: `Posteingang als gelesen markieren`,
|
cheats_markAllAsRead: `Posteingang als gelesen markieren`,
|
||||||
|
|||||||
@ -133,6 +133,7 @@ dict = {
|
|||||||
inventory_bulkRankUpSentinels: `Max Rank All Sentinels`,
|
inventory_bulkRankUpSentinels: `Max Rank All Sentinels`,
|
||||||
inventory_bulkRankUpSentinelWeapons: `Max Rank All Sentinel Weapons`,
|
inventory_bulkRankUpSentinelWeapons: `Max Rank All Sentinel Weapons`,
|
||||||
inventory_bulkRankUpEvolutionProgress: `Max Rank All Incarnon Evolution Progress`,
|
inventory_bulkRankUpEvolutionProgress: `Max Rank All Incarnon Evolution Progress`,
|
||||||
|
inventory_maxPlexus: `Max Rank Plexus`,
|
||||||
inventory_removeIsNew: `Remove New Equipment Exclamation Icon`,
|
inventory_removeIsNew: `Remove New Equipment Exclamation Icon`,
|
||||||
|
|
||||||
quests_list: `Quests`,
|
quests_list: `Quests`,
|
||||||
@ -258,7 +259,6 @@ dict = {
|
|||||||
cheats_helminthUnlockAll: `Fully Level Up Helminth`,
|
cheats_helminthUnlockAll: `Fully Level Up Helminth`,
|
||||||
cheats_addMissingSubsumedAbilities: `Add Missing Subsumed Abilities`,
|
cheats_addMissingSubsumedAbilities: `Add Missing Subsumed Abilities`,
|
||||||
cheats_intrinsicsUnlockAll: `Max Rank All Intrinsics`,
|
cheats_intrinsicsUnlockAll: `Max Rank All Intrinsics`,
|
||||||
cheats_maxPlexus: `Max Rank Plexus`,
|
|
||||||
cheats_changeSupportedSyndicate: `Supported syndicate`,
|
cheats_changeSupportedSyndicate: `Supported syndicate`,
|
||||||
cheats_changeButton: `Change`,
|
cheats_changeButton: `Change`,
|
||||||
cheats_markAllAsRead: `Mark Inbox As Read`,
|
cheats_markAllAsRead: `Mark Inbox As Read`,
|
||||||
|
|||||||
@ -134,6 +134,7 @@ dict = {
|
|||||||
inventory_bulkRankUpSentinels: `Maximizar rango de todos los centinelas`,
|
inventory_bulkRankUpSentinels: `Maximizar rango de todos los centinelas`,
|
||||||
inventory_bulkRankUpSentinelWeapons: `Maximizar rango de todas las armas de centinela`,
|
inventory_bulkRankUpSentinelWeapons: `Maximizar rango de todas las armas de centinela`,
|
||||||
inventory_bulkRankUpEvolutionProgress: `Maximizar todo el progreso de evolución Incarnon`,
|
inventory_bulkRankUpEvolutionProgress: `Maximizar todo el progreso de evolución Incarnon`,
|
||||||
|
inventory_maxPlexus: `Rango máximo de Plexus`,
|
||||||
inventory_removeIsNew: `[UNTRANSLATED] Remove New Equipment Exclamation Icon`,
|
inventory_removeIsNew: `[UNTRANSLATED] Remove New Equipment Exclamation Icon`,
|
||||||
|
|
||||||
quests_list: `Misiones`,
|
quests_list: `Misiones`,
|
||||||
@ -259,7 +260,6 @@ dict = {
|
|||||||
cheats_helminthUnlockAll: `Subir al máximo el Helminto`,
|
cheats_helminthUnlockAll: `Subir al máximo el Helminto`,
|
||||||
cheats_addMissingSubsumedAbilities: `Agregar habilidades subsumidas faltantes`,
|
cheats_addMissingSubsumedAbilities: `Agregar habilidades subsumidas faltantes`,
|
||||||
cheats_intrinsicsUnlockAll: `Maximizar todos los intrínsecos`,
|
cheats_intrinsicsUnlockAll: `Maximizar todos los intrínsecos`,
|
||||||
cheats_maxPlexus: `Rango máximo de Plexus`,
|
|
||||||
cheats_changeSupportedSyndicate: `Sindicatos disponibles`,
|
cheats_changeSupportedSyndicate: `Sindicatos disponibles`,
|
||||||
cheats_changeButton: `Cambiar`,
|
cheats_changeButton: `Cambiar`,
|
||||||
cheats_markAllAsRead: `Marcar bandeja de entrada como leída`,
|
cheats_markAllAsRead: `Marcar bandeja de entrada como leída`,
|
||||||
|
|||||||
@ -134,6 +134,7 @@ dict = {
|
|||||||
inventory_bulkRankUpSentinels: `Toutes les Sentinelles au rang max`,
|
inventory_bulkRankUpSentinels: `Toutes les Sentinelles au rang max`,
|
||||||
inventory_bulkRankUpSentinelWeapons: `Toutes les armes de Sentinelles au rang max`,
|
inventory_bulkRankUpSentinelWeapons: `Toutes les armes de Sentinelles au rang max`,
|
||||||
inventory_bulkRankUpEvolutionProgress: `Toutes les évolutions Incarnon au rang max`,
|
inventory_bulkRankUpEvolutionProgress: `Toutes les évolutions Incarnon au rang max`,
|
||||||
|
inventory_maxPlexus: `Plexus au rang max`,
|
||||||
inventory_removeIsNew: `[UNTRANSLATED] Remove New Equipment Exclamation Icon`,
|
inventory_removeIsNew: `[UNTRANSLATED] Remove New Equipment Exclamation Icon`,
|
||||||
|
|
||||||
quests_list: `Quêtes`,
|
quests_list: `Quêtes`,
|
||||||
@ -259,7 +260,6 @@ dict = {
|
|||||||
cheats_helminthUnlockAll: `Helminth niveau max`,
|
cheats_helminthUnlockAll: `Helminth niveau max`,
|
||||||
cheats_addMissingSubsumedAbilities: `Ajouter les capacités subsumées manquantes`,
|
cheats_addMissingSubsumedAbilities: `Ajouter les capacités subsumées manquantes`,
|
||||||
cheats_intrinsicsUnlockAll: `Inhérences niveau max`,
|
cheats_intrinsicsUnlockAll: `Inhérences niveau max`,
|
||||||
cheats_maxPlexus: `Plexus au rang max`,
|
|
||||||
cheats_changeSupportedSyndicate: `Allégeance`,
|
cheats_changeSupportedSyndicate: `Allégeance`,
|
||||||
cheats_changeButton: `Changer`,
|
cheats_changeButton: `Changer`,
|
||||||
cheats_markAllAsRead: `Marquer la boîte de réception comme lue`,
|
cheats_markAllAsRead: `Marquer la boîte de réception comme lue`,
|
||||||
|
|||||||
@ -134,6 +134,7 @@ dict = {
|
|||||||
inventory_bulkRankUpSentinels: `Макс. ранг всех Стражей`,
|
inventory_bulkRankUpSentinels: `Макс. ранг всех Стражей`,
|
||||||
inventory_bulkRankUpSentinelWeapons: `Макс. ранг всего оружия Стражей`,
|
inventory_bulkRankUpSentinelWeapons: `Макс. ранг всего оружия Стражей`,
|
||||||
inventory_bulkRankUpEvolutionProgress: `Макс. ранг всех эволюций Инкарнонов`,
|
inventory_bulkRankUpEvolutionProgress: `Макс. ранг всех эволюций Инкарнонов`,
|
||||||
|
inventory_maxPlexus: `Макс. ранг Плексуса`,
|
||||||
inventory_removeIsNew: `Удалить значок восклицательного знака нового снаряжения`,
|
inventory_removeIsNew: `Удалить значок восклицательного знака нового снаряжения`,
|
||||||
|
|
||||||
quests_list: `Квесты`,
|
quests_list: `Квесты`,
|
||||||
@ -259,7 +260,6 @@ dict = {
|
|||||||
cheats_helminthUnlockAll: `Полностью улучшить Гельминта`,
|
cheats_helminthUnlockAll: `Полностью улучшить Гельминта`,
|
||||||
cheats_addMissingSubsumedAbilities: `Добавить отсутствующие поглощённые способности`,
|
cheats_addMissingSubsumedAbilities: `Добавить отсутствующие поглощённые способности`,
|
||||||
cheats_intrinsicsUnlockAll: `Полностью улучшить Модуляры`,
|
cheats_intrinsicsUnlockAll: `Полностью улучшить Модуляры`,
|
||||||
cheats_maxPlexus: `Макс. ранг Плексуса`,
|
|
||||||
cheats_changeSupportedSyndicate: `Поддерживаемый синдикат`,
|
cheats_changeSupportedSyndicate: `Поддерживаемый синдикат`,
|
||||||
cheats_changeButton: `Изменить`,
|
cheats_changeButton: `Изменить`,
|
||||||
cheats_markAllAsRead: `Пометить все входящие как прочитанные`,
|
cheats_markAllAsRead: `Пометить все входящие как прочитанные`,
|
||||||
|
|||||||
@ -134,6 +134,7 @@ dict = {
|
|||||||
inventory_bulkRankUpSentinels: `Макс. рівень всіх Вартових`,
|
inventory_bulkRankUpSentinels: `Макс. рівень всіх Вартових`,
|
||||||
inventory_bulkRankUpSentinelWeapons: `Макс. рівень всієї зброї Вартових`,
|
inventory_bulkRankUpSentinelWeapons: `Макс. рівень всієї зброї Вартових`,
|
||||||
inventory_bulkRankUpEvolutionProgress: `Макс. рівень всіх еволюцій Інкарнонів`,
|
inventory_bulkRankUpEvolutionProgress: `Макс. рівень всіх еволюцій Інкарнонів`,
|
||||||
|
inventory_maxPlexus: `Макс. рівень Плексу`,
|
||||||
inventory_removeIsNew: `[UNTRANSLATED] Remove New Equipment Exclamation Icon`,
|
inventory_removeIsNew: `[UNTRANSLATED] Remove New Equipment Exclamation Icon`,
|
||||||
|
|
||||||
quests_list: `Пригоди`,
|
quests_list: `Пригоди`,
|
||||||
@ -259,7 +260,6 @@ dict = {
|
|||||||
cheats_helminthUnlockAll: `Повністю покращити Гельмінта`,
|
cheats_helminthUnlockAll: `Повністю покращити Гельмінта`,
|
||||||
cheats_addMissingSubsumedAbilities: `Додати відсутні поглинуті здібності`,
|
cheats_addMissingSubsumedAbilities: `Додати відсутні поглинуті здібності`,
|
||||||
cheats_intrinsicsUnlockAll: `Повністю покращити Кваліфікації`,
|
cheats_intrinsicsUnlockAll: `Повністю покращити Кваліфікації`,
|
||||||
cheats_maxPlexus: `Макс. рівень Плексу`,
|
|
||||||
cheats_changeSupportedSyndicate: `Підтримуваний синдикат`,
|
cheats_changeSupportedSyndicate: `Підтримуваний синдикат`,
|
||||||
cheats_changeButton: `Змінити`,
|
cheats_changeButton: `Змінити`,
|
||||||
cheats_markAllAsRead: `Помітити всі вхідні як прочитані`,
|
cheats_markAllAsRead: `Помітити всі вхідні як прочитані`,
|
||||||
|
|||||||
@ -134,6 +134,7 @@ dict = {
|
|||||||
inventory_bulkRankUpSentinels: `所有守护升满级`,
|
inventory_bulkRankUpSentinels: `所有守护升满级`,
|
||||||
inventory_bulkRankUpSentinelWeapons: `所有守护武器升满级`,
|
inventory_bulkRankUpSentinelWeapons: `所有守护武器升满级`,
|
||||||
inventory_bulkRankUpEvolutionProgress: `所有灵化之源进度最大等级`,
|
inventory_bulkRankUpEvolutionProgress: `所有灵化之源进度最大等级`,
|
||||||
|
inventory_maxPlexus: `最大深控等级`,
|
||||||
inventory_removeIsNew: `[UNTRANSLATED] Remove New Equipment Exclamation Icon`,
|
inventory_removeIsNew: `[UNTRANSLATED] Remove New Equipment Exclamation Icon`,
|
||||||
|
|
||||||
quests_list: `系列任务`,
|
quests_list: `系列任务`,
|
||||||
@ -259,7 +260,6 @@ dict = {
|
|||||||
cheats_helminthUnlockAll: `完全升级Helminth`,
|
cheats_helminthUnlockAll: `完全升级Helminth`,
|
||||||
cheats_addMissingSubsumedAbilities: `添加Helminth未汲取的战甲技能`,
|
cheats_addMissingSubsumedAbilities: `添加Helminth未汲取的战甲技能`,
|
||||||
cheats_intrinsicsUnlockAll: `所有内源之力最大等级`,
|
cheats_intrinsicsUnlockAll: `所有内源之力最大等级`,
|
||||||
cheats_maxPlexus: `最大深控等级`,
|
|
||||||
cheats_changeSupportedSyndicate: `支持的集团`,
|
cheats_changeSupportedSyndicate: `支持的集团`,
|
||||||
cheats_changeButton: `更改`,
|
cheats_changeButton: `更改`,
|
||||||
cheats_markAllAsRead: `收件箱全部标记为已读`,
|
cheats_markAllAsRead: `收件箱全部标记为已读`,
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user