chore: replace unlockAllMissions config with an account cheats button #2241

Merged
Sainan merged 2 commits from unlock-all-missions into main 2025-06-22 06:37:21 -07:00
9 changed files with 91 additions and 76 deletions

View File

@ -13,7 +13,6 @@
"skipTutorial": false,
"skipAllDialogue": false,
"unlockAllScans": false,
"unlockAllMissions": false,
"infiniteCredits": false,
"infinitePlatinum": false,
"infiniteEndo": false,

View File

@ -6,13 +6,7 @@ import allDialogue from "@/static/fixed_responses/allDialogue.json";
import { ILoadoutDatabase } from "@/src/types/saveLoadoutTypes";
import { IInventoryClient, IShipInventory, equipmentKeys } from "@/src/types/inventoryTypes/inventoryTypes";
import { IPolarity, ArtifactPolarity, EquipmentFeatures } from "@/src/types/inventoryTypes/commonInventoryTypes";
import {
ExportCustoms,
ExportFlavour,
ExportRegions,
ExportResources,
ExportVirtuals
} from "warframe-public-export-plus";
import { ExportCustoms, ExportFlavour, ExportResources, ExportVirtuals } from "warframe-public-export-plus";
import { applyCheatsToInfestedFoundry, handleSubsumeCompletion } from "@/src/services/infestedFoundryService";
import {
addMiscItems,
@ -22,7 +16,7 @@ import {
generateRewardSeed
} from "@/src/services/inventoryService";
import { logger } from "@/src/utils/logger";
import { catBreadHash } from "@/src/helpers/stringHelpers";
import { addString, catBreadHash } from "@/src/helpers/stringHelpers";
import { Types } from "mongoose";
import { getNemesisManifest } from "@/src/helpers/nemesisHelpers";
import { getPersonalRooms } from "@/src/services/personalRoomsService";
@ -167,18 +161,6 @@ export const getInventoryResponse = async (
}
}
if (config.unlockAllMissions) {
inventoryResponse.Missions = [];
for (const tag of Object.keys(ExportRegions)) {
inventoryResponse.Missions.push({
Completes: 1,
Tier: 1,
Tag: tag
});
}
addString(inventoryResponse.NodeIntrosCompleted, "TeshinHardModeUnlocked");
}
if (config.unlockAllShipDecorations) {
inventoryResponse.ShipDecorations = [];
for (const [uniqueName, item] of Object.entries(ExportResources)) {
@ -362,12 +344,6 @@ const allEudicoHeistJobs = [
"/Lotus/Types/Gameplay/Venus/Jobs/Heists/HeistProfitTakerBountyFour"
];
const addString = (arr: string[], str: string): void => {
if (arr.indexOf(str) == -1) {
arr.push(str);
}
};
const getExpRequiredForMr = (rank: number): number => {
if (rank <= 30) {
return 2500 * rank * rank;

View File

@ -0,0 +1,34 @@
import { addString } from "@/src/helpers/stringHelpers";
import { getInventory } from "@/src/services/inventoryService";
import { getAccountIdForRequest } from "@/src/services/loginService";
import { addFixedLevelRewards } from "@/src/services/missionInventoryUpdateService";
import { handleStoreItemAcquisition } from "@/src/services/purchaseService";
import { IMissionReward } from "@/src/types/missionTypes";
import { RequestHandler } from "express";
import { ExportRegions } from "warframe-public-export-plus";
export const completeAllMissionsController: RequestHandler = async (req, res) => {
const accountId = await getAccountIdForRequest(req);
const inventory = await getInventory(accountId);
const MissionRewards: IMissionReward[] = [];
for (const [tag, node] of Object.entries(ExportRegions)) {
if (!inventory.Missions.find(x => x.Tag == tag)) {
inventory.Missions.push({
Completes: 1,
Tier: 1,
Tag: tag
});
if (node.missionReward) {
console.log(node.missionReward);
addFixedLevelRewards(node.missionReward, inventory, MissionRewards);
}
}
}
for (const reward of MissionRewards) {
await handleStoreItemAcquisition(reward.StoreItem, inventory, reward.ItemCount, undefined, true);
}
addString(inventory.NodeIntrosCompleted, "TeshinHardModeUnlocked");
await inventory.save();
res.end();
};

View File

@ -54,3 +54,9 @@ export const regexEscape = (str: string): string => {
str = str.split("}").join("\\}");
return str;
};
export const addString = (arr: string[], str: string): void => {
if (arr.indexOf(str) == -1) {
arr.push(str);
}
};

View File

@ -12,6 +12,7 @@ import { ircDroppedController } from "@/src/controllers/custom/ircDroppedControl
import { unlockAllIntrinsicsController } from "@/src/controllers/custom/unlockAllIntrinsicsController";
import { addMissingMaxRankModsController } from "@/src/controllers/custom/addMissingMaxRankModsController";
import { webuiFileChangeDetectedController } from "@/src/controllers/custom/webuiFileChangeDetectedController";
import { completeAllMissionsController } from "@/src/controllers/custom/completeAllMissionsController";
import { createAccountController } from "@/src/controllers/custom/createAccountController";
import { createMessageController } from "@/src/controllers/custom/createMessageController";
@ -40,6 +41,7 @@ customRouter.get("/ircDropped", ircDroppedController);
customRouter.get("/unlockAllIntrinsics", unlockAllIntrinsicsController);
customRouter.get("/addMissingMaxRankMods", addMissingMaxRankModsController);
customRouter.get("/webuiFileChangeDetected", webuiFileChangeDetectedController);
customRouter.get("/completeAllMissions", completeAllMissionsController);
customRouter.post("/createAccount", createAccountController);
customRouter.post("/createMessage", createMessageController);

View File

@ -19,7 +19,6 @@ export interface IConfig {
skipTutorial?: boolean;
skipAllDialogue?: boolean;
unlockAllScans?: boolean;
unlockAllMissions?: boolean;
infiniteCredits?: boolean;
infinitePlatinum?: boolean;
infiniteEndo?: boolean;

View File

@ -1367,7 +1367,7 @@ export const addFixedLevelRewards = (
if (rewards.countedItems) {
for (const item of rewards.countedItems) {
MissionRewards.push({
StoreItem: `/Lotus/StoreItems${item.ItemType.substring("Lotus/".length)}`,
StoreItem: toStoreItem(item.ItemType),
ItemCount: item.ItemCount
});
}

View File

@ -452,9 +452,6 @@
<button class="btn btn-success" onclick="maxRankAllEquipment(['SentinelWeapons']);" data-loc="inventory_bulkRankUpSentinelWeapons"></button>
<button class="btn btn-success" onclick="maxRankAllEvolutions();" data-loc="inventory_bulkRankUpEvolutionProgress"></button>
</div>
<div class="mb-2 d-flex flex-wrap gap-2">
<button class="btn btn-primary" onclick="debounce(doMaxPlexus);" data-loc="inventory_maxPlexus"></button>
</div>
</div>
</div>
</div>
@ -587,10 +584,6 @@
<input class="form-check-input" type="checkbox" id="unlockAllScans" />
<label class="form-check-label" for="unlockAllScans" data-loc="cheats_unlockAllScans"></label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" id="unlockAllMissions" />
<label class="form-check-label" for="unlockAllMissions" data-loc="cheats_unlockAllMissions"></label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" id="infiniteCredits" />
<label class="form-check-label" for="infiniteCredits" data-loc="cheats_infiniteCredits"></label>
@ -782,9 +775,11 @@
<h5 class="card-header" data-loc="cheats_account"></h5>
<div class="card-body">
<div class="mb-2 d-flex flex-wrap gap-2">
<button class="btn btn-primary" onclick="debounce(doUnlockAllMissions);" data-loc="cheats_unlockAllMissions"></button>
<button class="btn btn-primary" onclick="doUnlockAllFocusSchools();" data-loc="cheats_unlockAllFocusSchools"></button>
<button class="btn btn-primary" onclick="doHelminthUnlockAll();" data-loc="cheats_helminthUnlockAll"></button>
<button class="btn btn-primary" onclick="doIntrinsicsUnlockAll();" data-loc="cheats_intrinsicsUnlockAll"></button>
<button class="btn btn-primary" onclick="debounce(doMaxPlexus);" data-loc="inventory_maxPlexus"></button>
</div>
<form class="mt-2" onsubmit="doChangeSupportedSyndicate(); return false;">
<label class="form-label" for="changeSyndicate" data-loc="cheats_changeSupportedSyndicate"></label>

View File

@ -111,11 +111,9 @@ function doLogin() {
window.registerSubmit = false;
}
function revalidateAuthz(succ_cb) {
getWebSocket().then(() => {
// We have a websocket connection, so authz should be good.
succ_cb();
});
async function revalidateAuthz() {
await getWebSocket();
// We have a websocket connection, so authz should be good.
}
function logout() {
@ -135,7 +133,7 @@ function doLogout() {
function renameAccount() {
const newname = window.prompt(loc("code_changeNameConfirm"));
if (newname) {
revalidateAuthz(() => {
revalidateAuthz().then(() => {
fetch("/custom/renameAccount?" + window.authz + "&newname=" + newname).then(() => {
$(".displayname").text(newname);
updateLocElements();
@ -146,7 +144,7 @@ function renameAccount() {
function deleteAccount() {
if (window.confirm(loc("code_deleteAccountConfirm"))) {
revalidateAuthz(() => {
revalidateAuthz().then(() => {
fetch("/custom/deleteAccount?" + window.authz).then(() => {
logout();
single.loadRoute("/webui/"); // Show login screen
@ -646,7 +644,7 @@ function updateInventory() {
a.href = "#";
a.onclick = function (event) {
event.preventDefault();
revalidateAuthz(() => {
revalidateAuthz().then(() => {
const promises = [];
if (item.XP < maxXP) {
promises.push(addGearExp(category, item.ItemId.$oid, maxXP - item.XP));
@ -1236,7 +1234,7 @@ function doAcquireEquipment(category) {
.focus();
return;
}
revalidateAuthz(() => {
revalidateAuthz().then(() => {
const req = $.post({
url: "/custom/addItems?" + window.authz,
contentType: "application/json",
@ -1363,7 +1361,7 @@ function doAcquireModularEquipment(category, WeaponType) {
}
});
if (category == "KubrowPets") Parts.unshift(WeaponType);
revalidateAuthz(() => {
revalidateAuthz().then(() => {
const req = $.post({
url: "/api/modularWeaponCrafting.php?" + window.authz,
contentType: "application/octet-stream",
@ -1416,7 +1414,7 @@ $("input[list]").on("input", function () {
});
function dispatchAddItemsRequestsBatch(requests) {
revalidateAuthz(() => {
revalidateAuthz().then(() => {
const req = $.post({
url: "/custom/addItems?" + window.authz,
contentType: "application/json",
@ -1460,7 +1458,7 @@ function addMissingEvolutionProgress() {
}
function maxRankAllEvolutions() {
revalidateAuthz(() => {
revalidateAuthz().then(() => {
const req = $.get("/api/inventory.php?" + window.authz + "&xpBasedLevelCapDisabled=1");
req.done(data => {
const requests = [];
@ -1484,7 +1482,7 @@ function maxRankAllEvolutions() {
}
function maxRankAllEquipment(categories) {
revalidateAuthz(() => {
revalidateAuthz().then(() => {
const req = $.get("/api/inventory.php?" + window.authz + "&xpBasedLevelCapDisabled=1");
req.done(data => {
window.itemListPromise.then(itemMap => {
@ -1558,7 +1556,7 @@ function addGearExp(category, oid, xp) {
}
function sendBatchGearExp(data) {
revalidateAuthz(() => {
revalidateAuthz().then(() => {
$.post({
url: "/custom/addXp?" + window.authz,
contentType: "application/json",
@ -1571,7 +1569,7 @@ function sendBatchGearExp(data) {
}
function renameGear(category, oid, name) {
revalidateAuthz(() => {
revalidateAuthz().then(() => {
if (category == "KubrowPets") {
$.post({
url: "/api/renamePet.php?" + window.authz + "&webui=1",
@ -1599,7 +1597,7 @@ function renameGear(category, oid, name) {
function disposeOfGear(category, oid) {
if (category == "KubrowPets") {
revalidateAuthz(() => {
revalidateAuthz().then(() => {
$.post({
url: "/api/releasePet.php?" + window.authz,
contentType: "application/octet-stream",
@ -1621,7 +1619,7 @@ function disposeOfGear(category, oid) {
Count: 0
}
];
revalidateAuthz(() => {
revalidateAuthz().then(() => {
$.post({
url: "/api/sell.php?" + window.authz,
contentType: "text/plain",
@ -1643,7 +1641,7 @@ function disposeOfItems(category, type, count) {
Count: count
}
];
revalidateAuthz(() => {
revalidateAuthz().then(() => {
$.post({
url: "/api/sell.php?" + window.authz,
contentType: "text/plain",
@ -1653,7 +1651,7 @@ function disposeOfItems(category, type, count) {
}
function gildEquipment(category, oid) {
revalidateAuthz(() => {
revalidateAuthz().then(() => {
$.post({
url: "/api/gildWeapon.php?" + window.authz + "&ItemId=" + oid + "&Category=" + category,
contentType: "application/octet-stream",
@ -1667,7 +1665,7 @@ function gildEquipment(category, oid) {
}
function maturePet(oid, revert) {
revalidateAuthz(() => {
revalidateAuthz().then(() => {
$.post({
url: "/api/maturePet.php?" + window.authz,
contentType: "application/octet-stream",
@ -1682,7 +1680,7 @@ function maturePet(oid, revert) {
}
function setEvolutionProgress(requests) {
revalidateAuthz(() => {
revalidateAuthz().then(() => {
const req = $.post({
url: "/custom/setEvolutionProgress?" + window.authz,
contentType: "application/json",
@ -1702,7 +1700,7 @@ function doAcquireMiscItems() {
}
const count = parseInt($("#miscitem-count").val());
if (count != 0) {
revalidateAuthz(() => {
revalidateAuthz().then(() => {
$.post({
url: "/custom/addItems?" + window.authz,
contentType: "application/json",
@ -1743,7 +1741,7 @@ function doAcquireRiven() {
return;
}
const uniqueName = "/Lotus/Upgrades/Mods/Randomized/" + $("#addriven-type").val();
revalidateAuthz(() => {
revalidateAuthz().then(() => {
// Add riven type to inventory
$.post({
url: "/custom/addItems?" + window.authz,
@ -1790,7 +1788,7 @@ $("#addriven-fingerprint").on("input", () => {
});
function setFingerprint(ItemType, ItemId, fingerprint) {
revalidateAuthz(() => {
revalidateAuthz().then(() => {
$.post({
url: "/api/artifacts.php?" + window.authz,
contentType: "text/plain",
@ -1818,7 +1816,7 @@ function doAcquireMod() {
}
const count = parseInt($("#mod-count").val());
if (count != 0) {
revalidateAuthz(() => {
revalidateAuthz().then(() => {
$.post({
url: "/custom/addItems?" + window.authz,
contentType: "application/json",
@ -1895,7 +1893,7 @@ single.getRoute("/webui/cheats").on("beforeload", function () {
);
} else {
if ((await res.text()) == "Log-in expired") {
revalidateAuthz(() => {
revalidateAuthz().then(() => {
if (single.getCurrentPath() == "/webui/cheats") {
single.loadRoute("/webui/cheats");
}
@ -1912,7 +1910,7 @@ single.getRoute("/webui/cheats").on("beforeload", function () {
});
function doUnlockAllFocusSchools() {
revalidateAuthz(() => {
revalidateAuthz().then(() => {
$.get("/api/inventory.php?" + window.authz + "&xpBasedLevelCapDisabled=1").done(async data => {
const missingFocusUpgrades = {
"/Lotus/Upgrades/Focus/Attack/AttackFocusAbility": true,
@ -1963,13 +1961,13 @@ function unlockFocusSchool(upgradeType) {
}
function doHelminthUnlockAll() {
revalidateAuthz(() => {
revalidateAuthz().then(() => {
$.post("/api/infestedFoundry.php?" + window.authz + "&mode=custom_unlockall");
});
}
function doIntrinsicsUnlockAll() {
revalidateAuthz(() => {
revalidateAuthz().then(() => {
$.get("/custom/unlockAllIntrinsics?" + window.authz);
});
}
@ -1981,7 +1979,7 @@ function doAddAllMods() {
}
modsAll.delete("/Lotus/Upgrades/Mods/Fusers/LegendaryModFuser");
revalidateAuthz(() => {
revalidateAuthz().then(() => {
const req = $.get("/api/inventory.php?" + window.authz + "&xpBasedLevelCapDisabled=1");
req.done(data => {
for (const modOwned of data.RawUpgrades) {
@ -2013,7 +2011,7 @@ function doAddAllMods() {
}
function doRemoveUnrankedMods() {
revalidateAuthz(() => {
revalidateAuthz().then(() => {
const req = $.get("/api/inventory.php?" + window.authz + "&xpBasedLevelCapDisabled=1");
req.done(inventory => {
window.itemListPromise.then(itemMap => {
@ -2038,7 +2036,7 @@ function doRemoveUnrankedMods() {
}
function doAddMissingMaxRankMods() {
revalidateAuthz(() => {
revalidateAuthz().then(() => {
fetch("/custom/addMissingMaxRankMods?" + window.authz).then(() => {
updateInventory();
});
@ -2060,7 +2058,7 @@ function doPushArchonCrystalUpgrade() {
$("[list='datalist-archonCrystalUpgrades']").addClass("is-invalid").focus();
return;
}
revalidateAuthz(() => {
revalidateAuthz().then(() => {
$.get(
"/custom/pushArchonCrystalUpgrade?" +
window.authz +
@ -2078,7 +2076,7 @@ function doPushArchonCrystalUpgrade() {
}
function doPopArchonCrystalUpgrade(type) {
revalidateAuthz(() => {
revalidateAuthz().then(() => {
$.get(
"/custom/popArchonCrystalUpgrade?" +
window.authz +
@ -2093,7 +2091,7 @@ function doPopArchonCrystalUpgrade(type) {
}
function doImport() {
revalidateAuthz(() => {
revalidateAuthz().then(() => {
$.post({
url: "/custom/import?" + window.authz,
contentType: "application/json",
@ -2110,7 +2108,7 @@ function doImport() {
function doChangeSupportedSyndicate() {
const uniqueName = document.getElementById("changeSyndicate").value;
revalidateAuthz(() => {
revalidateAuthz().then(() => {
$.get("/api/setSupportedSyndicate.php?" + window.authz + "&syndicate=" + uniqueName).done(function () {
updateInventory();
});
@ -2118,7 +2116,7 @@ function doChangeSupportedSyndicate() {
}
function doAddCurrency(currency) {
revalidateAuthz(() => {
revalidateAuthz().then(() => {
$.post({
url: "/custom/addCurrency?" + window.authz,
contentType: "application/json",
@ -2133,7 +2131,7 @@ function doAddCurrency(currency) {
}
function doQuestUpdate(operation, itemType) {
revalidateAuthz(() => {
revalidateAuthz().then(() => {
$.post({
url: "/custom/manageQuests?" + window.authz + "&operation=" + operation + "&itemType=" + itemType,
contentType: "application/json"
@ -2144,7 +2142,7 @@ function doQuestUpdate(operation, itemType) {
}
function doBulkQuestUpdate(operation) {
revalidateAuthz(() => {
revalidateAuthz().then(() => {
$.post({
url: "/custom/manageQuests?" + window.authz + "&operation=" + operation,
contentType: "application/json"
@ -2242,7 +2240,7 @@ function handleModularSelection(category) {
}
function setBooster(ItemType, ExpiryDate, callback) {
revalidateAuthz(() => {
revalidateAuthz().then(() => {
$.post({
url: "/custom/setBooster?" + window.authz,
contentType: "application/json",
@ -2332,3 +2330,9 @@ async function doMaxPlexus() {
toast(loc("code_noEquipmentToRankUp"));
}
}
async function doUnlockAllMissions() {
await revalidateAuthz();
await fetch("/custom/completeAllMissions?" + window.authz);
updateInventory();
}