chore: make 'infinite' cheats per-account toggles
All checks were successful
Build / build (pull_request) Successful in 50s

This commit is contained in:
Sainan 2025-08-13 23:09:27 +02:00
parent 7bc5065251
commit ec5eba3e90
16 changed files with 120 additions and 69 deletions

View File

@ -13,11 +13,6 @@
"skipTutorial": false, "skipTutorial": false,
"skipAllDialogue": false, "skipAllDialogue": false,
"unlockAllScans": false, "unlockAllScans": false,
"infiniteCredits": false,
"infinitePlatinum": false,
"infiniteEndo": false,
"infiniteRegalAya": false,
"infiniteHelminthMaterials": false,
"claimingBlueprintRefundsIngredients": false, "claimingBlueprintRefundsIngredients": false,
"dontSubtractPurchaseCreditCost": false, "dontSubtractPurchaseCreditCost": false,
"dontSubtractPurchasePlatinumCost": false, "dontSubtractPurchasePlatinumCost": false,

View File

@ -3,7 +3,6 @@ import { getAccountIdForRequest } from "@/src/services/loginService";
import { RequestHandler } from "express"; import { RequestHandler } from "express";
import { IInventoryClient, IUpgradeClient } from "@/src/types/inventoryTypes/inventoryTypes"; import { IInventoryClient, IUpgradeClient } from "@/src/types/inventoryTypes/inventoryTypes";
import { addMods, getInventory } from "@/src/services/inventoryService"; import { addMods, getInventory } from "@/src/services/inventoryService";
import { config } from "@/src/services/configService";
export const artifactsController: RequestHandler = async (req, res) => { export const artifactsController: RequestHandler = async (req, res) => {
const accountId = await getAccountIdForRequest(req); const accountId = await getAccountIdForRequest(req);
@ -34,10 +33,10 @@ export const artifactsController: RequestHandler = async (req, res) => {
addMods(inventory, [{ ItemType, ItemCount: -1 }]); addMods(inventory, [{ ItemType, ItemCount: -1 }]);
} }
if (!config.infiniteCredits) { if (!inventory.infiniteCredits) {
inventory.RegularCredits -= Cost; inventory.RegularCredits -= Cost;
} }
if (!config.infiniteEndo) { if (!inventory.infiniteEndo) {
inventory.FusionPoints -= FusionPointCost; inventory.FusionPoints -= FusionPointCost;
} }

View File

@ -1,5 +1,4 @@
import { RequestHandler } from "express"; import { RequestHandler } from "express";
import { config } from "@/src/services/configService";
import { getAccountIdForRequest } from "@/src/services/loginService"; import { getAccountIdForRequest } from "@/src/services/loginService";
import { getInventory } from "@/src/services/inventoryService"; import { getInventory } from "@/src/services/inventoryService";
@ -9,7 +8,7 @@ export const creditsController: RequestHandler = async (req, res) => {
getAccountIdForRequest(req), getAccountIdForRequest(req),
getInventory( getInventory(
req.query.accountId as string, req.query.accountId as string,
"RegularCredits TradesRemaining PremiumCreditsFree PremiumCredits" "RegularCredits TradesRemaining PremiumCreditsFree PremiumCredits infiniteCredits infinitePlatinum"
) )
]) ])
)[1]; )[1];
@ -21,10 +20,10 @@ export const creditsController: RequestHandler = async (req, res) => {
PremiumCredits: inventory.PremiumCredits PremiumCredits: inventory.PremiumCredits
}; };
if (config.infiniteCredits) { if (inventory.infiniteCredits) {
response.RegularCredits = 999999999; response.RegularCredits = 999999999;
} }
if (config.infinitePlatinum) { if (inventory.infinitePlatinum) {
response.PremiumCreditsFree = 0; response.PremiumCreditsFree = 0;
response.PremiumCredits = 999999999; response.PremiumCredits = 999999999;
} }

View File

@ -15,7 +15,6 @@ import { getRecipe } from "@/src/services/itemDataService";
import { toMongoDate, version_compare } from "@/src/helpers/inventoryHelpers"; import { toMongoDate, version_compare } from "@/src/helpers/inventoryHelpers";
import { logger } from "@/src/utils/logger"; import { logger } from "@/src/utils/logger";
import { colorToShard } from "@/src/helpers/shardHelper"; import { colorToShard } from "@/src/helpers/shardHelper";
import { config } from "@/src/services/configService";
import { import {
addInfestedFoundryXP, addInfestedFoundryXP,
applyCheatsToInfestedFoundry, applyCheatsToInfestedFoundry,
@ -73,7 +72,7 @@ export const infestedFoundryController: RequestHandler = async (req, res) => {
addMiscItems(inventory, miscItemChanges); addMiscItems(inventory, miscItemChanges);
// consume resources // consume resources
if (!config.infiniteHelminthMaterials) { if (!inventory.infiniteHelminthMaterials) {
let type: string; let type: string;
let count: number; let count: number;
if (account.BuildLabel && version_compare(account.BuildLabel, "2025.05.20.10.18") < 0) { if (account.BuildLabel && version_compare(account.BuildLabel, "2025.05.20.10.18") < 0) {
@ -99,7 +98,7 @@ export const infestedFoundryController: RequestHandler = async (req, res) => {
await inventory.save(); await inventory.save();
const infestedFoundry = inventory.toJSON<IInventoryClient>().InfestedFoundry!; const infestedFoundry = inventory.toJSON<IInventoryClient>().InfestedFoundry!;
applyCheatsToInfestedFoundry(infestedFoundry); applyCheatsToInfestedFoundry(inventory, infestedFoundry);
res.json({ res.json({
InventoryChanges: { InventoryChanges: {
MiscItems: miscItemChanges, MiscItems: miscItemChanges,
@ -129,13 +128,14 @@ export const infestedFoundryController: RequestHandler = async (req, res) => {
case "c": { case "c": {
// consume items // consume items
if (config.infiniteHelminthMaterials) { const inventory = await getInventory(account._id.toString());
if (inventory.infiniteHelminthMaterials) {
res.status(400).end(); res.status(400).end();
return; return;
} }
const request = getJSONfromString<IHelminthFeedRequest>(String(req.body)); const request = getJSONfromString<IHelminthFeedRequest>(String(req.body));
const inventory = await getInventory(account._id.toString());
inventory.InfestedFoundry ??= {}; inventory.InfestedFoundry ??= {};
inventory.InfestedFoundry.Resources ??= []; inventory.InfestedFoundry.Resources ??= [];
@ -240,7 +240,7 @@ export const infestedFoundryController: RequestHandler = async (req, res) => {
} }
await inventory.save(); await inventory.save();
const infestedFoundry = inventory.toJSON<IInventoryClient>().InfestedFoundry!; const infestedFoundry = inventory.toJSON<IInventoryClient>().InfestedFoundry!;
applyCheatsToInfestedFoundry(infestedFoundry); applyCheatsToInfestedFoundry(inventory, infestedFoundry);
res.json({ res.json({
InventoryChanges: { InventoryChanges: {
InfestedFoundry: infestedFoundry InfestedFoundry: infestedFoundry
@ -254,7 +254,7 @@ export const infestedFoundryController: RequestHandler = async (req, res) => {
const request = getJSONfromString<IHelminthSubsumeRequest>(String(req.body)); const request = getJSONfromString<IHelminthSubsumeRequest>(String(req.body));
const inventory = await getInventory(account._id.toString()); const inventory = await getInventory(account._id.toString());
const recipe = getRecipe(request.Recipe)!; const recipe = getRecipe(request.Recipe)!;
if (!config.infiniteHelminthMaterials) { if (!inventory.infiniteHelminthMaterials) {
for (const ingredient of recipe.secretIngredients!) { for (const ingredient of recipe.secretIngredients!) {
const resource = inventory.InfestedFoundry!.Resources!.find(x => x.ItemType == ingredient.ItemType); const resource = inventory.InfestedFoundry!.Resources!.find(x => x.ItemType == ingredient.ItemType);
if (resource) { if (resource) {
@ -280,7 +280,7 @@ export const infestedFoundryController: RequestHandler = async (req, res) => {
freeUpSlot(inventory, InventorySlot.SUITS); freeUpSlot(inventory, InventorySlot.SUITS);
await inventory.save(); await inventory.save();
const infestedFoundry = inventory.toJSON<IInventoryClient>().InfestedFoundry!; const infestedFoundry = inventory.toJSON<IInventoryClient>().InfestedFoundry!;
applyCheatsToInfestedFoundry(infestedFoundry); applyCheatsToInfestedFoundry(inventory, infestedFoundry);
res.json({ res.json({
InventoryChanges: { InventoryChanges: {
Recipes: recipeChanges, Recipes: recipeChanges,
@ -307,7 +307,7 @@ export const infestedFoundryController: RequestHandler = async (req, res) => {
const recipeChanges = handleSubsumeCompletion(inventory); const recipeChanges = handleSubsumeCompletion(inventory);
await inventory.save(); await inventory.save();
const infestedFoundry = inventory.toJSON<IInventoryClient>().InfestedFoundry!; const infestedFoundry = inventory.toJSON<IInventoryClient>().InfestedFoundry!;
applyCheatsToInfestedFoundry(infestedFoundry); applyCheatsToInfestedFoundry(inventory, infestedFoundry);
res.json({ res.json({
InventoryChanges: { InventoryChanges: {
...currencyChanges, ...currencyChanges,
@ -328,7 +328,7 @@ export const infestedFoundryController: RequestHandler = async (req, res) => {
suit.UpgradesExpiry = upgradesExpiry; suit.UpgradesExpiry = upgradesExpiry;
const recipeChanges = addInfestedFoundryXP(inventory.InfestedFoundry!, 4800_00); const recipeChanges = addInfestedFoundryXP(inventory.InfestedFoundry!, 4800_00);
addRecipes(inventory, recipeChanges); addRecipes(inventory, recipeChanges);
if (!config.infiniteHelminthMaterials) { if (!inventory.infiniteHelminthMaterials) {
for (let i = 0; i != request.ResourceTypes.length; ++i) { for (let i = 0; i != request.ResourceTypes.length; ++i) {
inventory.InfestedFoundry!.Resources!.find(x => x.ItemType == request.ResourceTypes[i])!.Count -= inventory.InfestedFoundry!.Resources!.find(x => x.ItemType == request.ResourceTypes[i])!.Count -=
request.ResourceCosts[i]; request.ResourceCosts[i];
@ -338,7 +338,7 @@ export const infestedFoundryController: RequestHandler = async (req, res) => {
inventory.InfestedFoundry!.InvigorationsApplied += 1; inventory.InfestedFoundry!.InvigorationsApplied += 1;
await inventory.save(); await inventory.save();
const infestedFoundry = inventory.toJSON<IInventoryClient>().InfestedFoundry!; const infestedFoundry = inventory.toJSON<IInventoryClient>().InfestedFoundry!;
applyCheatsToInfestedFoundry(infestedFoundry); applyCheatsToInfestedFoundry(inventory, infestedFoundry);
res.json({ res.json({
SuitId: request.SuitId, SuitId: request.SuitId,
OffensiveUpgrade: request.OffensiveUpgradeType, OffensiveUpgrade: request.OffensiveUpgradeType,

View File

@ -295,17 +295,17 @@ export const getInventoryResponse = async (
}; };
} }
if (config.infiniteCredits) { if (inventory.infiniteCredits) {
inventoryResponse.RegularCredits = 999999999; inventoryResponse.RegularCredits = 999999999;
} }
if (config.infinitePlatinum) { if (inventory.infinitePlatinum) {
inventoryResponse.PremiumCreditsFree = 0; inventoryResponse.PremiumCreditsFree = 0;
inventoryResponse.PremiumCredits = 999999999; inventoryResponse.PremiumCredits = 999999999;
} }
if (config.infiniteEndo) { if (inventory.infiniteEndo) {
inventoryResponse.FusionPoints = 999999999; inventoryResponse.FusionPoints = 999999999;
} }
if (config.infiniteRegalAya) { if (inventory.infiniteRegalAya) {
inventoryResponse.PrimeTokens = 999999999; inventoryResponse.PrimeTokens = 999999999;
} }
@ -450,7 +450,7 @@ export const getInventoryResponse = async (
} }
if (inventoryResponse.InfestedFoundry) { if (inventoryResponse.InfestedFoundry) {
applyCheatsToInfestedFoundry(inventoryResponse.InfestedFoundry); applyCheatsToInfestedFoundry(inventory, inventoryResponse.InfestedFoundry);
} }
// Set 2FA enabled so trading post can be used // Set 2FA enabled so trading post can be used

View File

@ -7,7 +7,6 @@ import { addMiscItems, addRecipes, getInventory, updateCurrency } from "@/src/se
import { getRecipeByResult } from "@/src/services/itemDataService"; import { getRecipeByResult } from "@/src/services/itemDataService";
import { IInventoryChanges } from "@/src/types/purchaseTypes"; import { IInventoryChanges } from "@/src/types/purchaseTypes";
import { addInfestedFoundryXP, applyCheatsToInfestedFoundry } from "@/src/services/infestedFoundryService"; import { addInfestedFoundryXP, applyCheatsToInfestedFoundry } from "@/src/services/infestedFoundryService";
import { config } from "@/src/services/configService";
import { sendWsBroadcastTo } from "@/src/services/wsService"; import { sendWsBroadcastTo } from "@/src/services/wsService";
import { EquipmentFeatures, IEquipmentDatabase } from "@/src/types/equipmentTypes"; import { EquipmentFeatures, IEquipmentDatabase } from "@/src/types/equipmentTypes";
@ -52,7 +51,7 @@ export const upgradesController: RequestHandler = async (req, res) => {
const recipe = getRecipeByResult(operation.UpgradeRequirement)!; const recipe = getRecipeByResult(operation.UpgradeRequirement)!;
for (const ingredient of recipe.ingredients) { for (const ingredient of recipe.ingredients) {
totalPercentagePointsConsumed += ingredient.ItemCount / 10; totalPercentagePointsConsumed += ingredient.ItemCount / 10;
if (!config.infiniteHelminthMaterials) { if (!inventory.infiniteHelminthMaterials) {
inventory.InfestedFoundry!.Resources!.find(x => x.ItemType == ingredient.ItemType)!.Count -= inventory.InfestedFoundry!.Resources!.find(x => x.ItemType == ingredient.ItemType)!.Count -=
ingredient.ItemCount; ingredient.ItemCount;
} }
@ -69,7 +68,7 @@ export const upgradesController: RequestHandler = async (req, res) => {
inventoryChanges.Recipes = recipeChanges; inventoryChanges.Recipes = recipeChanges;
inventoryChanges.InfestedFoundry = inventory.toJSON<IInventoryClient>().InfestedFoundry; inventoryChanges.InfestedFoundry = inventory.toJSON<IInventoryClient>().InfestedFoundry;
applyCheatsToInfestedFoundry(inventoryChanges.InfestedFoundry!); applyCheatsToInfestedFoundry(inventory, inventoryChanges.InfestedFoundry!);
} else } else
switch (operation.UpgradeRequirement) { switch (operation.UpgradeRequirement) {
case "/Lotus/Types/Items/MiscItems/OrokinReactor": case "/Lotus/Types/Items/MiscItems/OrokinReactor":

View File

@ -0,0 +1,18 @@
import { getInventory } from "@/src/services/inventoryService";
import { getAccountIdForRequest } from "@/src/services/loginService";
import { IAccountCheats } from "@/src/types/inventoryTypes/inventoryTypes";
import { RequestHandler } from "express";
export const setAccountCheatController: RequestHandler = async (req, res) => {
const accountId = await getAccountIdForRequest(req);
const payload = req.body as ISetAccountCheatRequest;
const inventory = await getInventory(accountId, payload.key);
inventory[payload.key] = payload.value;
await inventory.save();
res.end();
};
interface ISetAccountCheatRequest {
key: keyof IAccountCheats;
value: boolean;
}

View File

@ -1425,6 +1425,14 @@ const hubNpcCustomizationSchema = new Schema<IHubNpcCustomization>(
const inventorySchema = new Schema<IInventoryDatabase, InventoryDocumentProps>( const inventorySchema = new Schema<IInventoryDatabase, InventoryDocumentProps>(
{ {
accountOwnerId: Schema.Types.ObjectId, accountOwnerId: Schema.Types.ObjectId,
// SNS account cheats
infiniteCredits: Boolean,
infinitePlatinum: Boolean,
infiniteEndo: Boolean,
infiniteRegalAya: Boolean,
infiniteHelminthMaterials: Boolean,
SubscribedToEmails: { type: Number, default: 0 }, SubscribedToEmails: { type: Number, default: 0 },
SubscribedToEmailsPersonalized: { type: Number, default: 0 }, SubscribedToEmailsPersonalized: { type: Number, default: 0 },
RewardSeed: BigInt, RewardSeed: BigInt,

View File

@ -28,6 +28,7 @@ import { setBoosterController } from "@/src/controllers/custom/setBoosterControl
import { updateFingerprintController } from "@/src/controllers/custom/updateFingerprintController"; import { updateFingerprintController } from "@/src/controllers/custom/updateFingerprintController";
import { changeModularPartsController } from "@/src/controllers/custom/changeModularPartsController"; import { changeModularPartsController } from "@/src/controllers/custom/changeModularPartsController";
import { editSuitInvigorationUpgradeController } from "@/src/controllers/custom/editSuitInvigorationUpgradeController"; import { editSuitInvigorationUpgradeController } from "@/src/controllers/custom/editSuitInvigorationUpgradeController";
import { setAccountCheatController } from "@/src/controllers/custom/setAccountCheatController";
import { getConfigController, setConfigController } from "@/src/controllers/custom/configController"; import { getConfigController, setConfigController } from "@/src/controllers/custom/configController";
@ -61,6 +62,7 @@ customRouter.post("/setBooster", setBoosterController);
customRouter.post("/updateFingerprint", updateFingerprintController); customRouter.post("/updateFingerprint", updateFingerprintController);
customRouter.post("/changeModularParts", changeModularPartsController); customRouter.post("/changeModularParts", changeModularPartsController);
customRouter.post("/editSuitInvigorationUpgrade", editSuitInvigorationUpgradeController); customRouter.post("/editSuitInvigorationUpgrade", editSuitInvigorationUpgradeController);
customRouter.post("/setAccountCheat", setAccountCheatController);
customRouter.post("/getConfig", getConfigController); customRouter.post("/getConfig", getConfigController);
customRouter.post("/setConfig", setConfigController); customRouter.post("/setConfig", setConfigController);

View File

@ -20,11 +20,6 @@ export interface IConfig {
skipTutorial?: boolean; skipTutorial?: boolean;
skipAllDialogue?: boolean; skipAllDialogue?: boolean;
unlockAllScans?: boolean; unlockAllScans?: boolean;
infiniteCredits?: boolean;
infinitePlatinum?: boolean;
infiniteEndo?: boolean;
infiniteRegalAya?: boolean;
infiniteHelminthMaterials?: boolean;
claimingBlueprintRefundsIngredients?: boolean; claimingBlueprintRefundsIngredients?: boolean;
dontSubtractPurchaseCreditCost?: boolean; dontSubtractPurchaseCreditCost?: boolean;
dontSubtractPurchasePlatinumCost?: boolean; dontSubtractPurchasePlatinumCost?: boolean;

View File

@ -1,8 +1,11 @@
import { ExportRecipes } from "warframe-public-export-plus"; import { ExportRecipes } from "warframe-public-export-plus";
import { TInventoryDatabaseDocument } from "@/src/models/inventoryModels/inventoryModel"; import { TInventoryDatabaseDocument } from "@/src/models/inventoryModels/inventoryModel";
import { IInfestedFoundryClient, IInfestedFoundryDatabase } from "@/src/types/inventoryTypes/inventoryTypes"; import {
IAccountCheats,
IInfestedFoundryClient,
IInfestedFoundryDatabase
} from "@/src/types/inventoryTypes/inventoryTypes";
import { addRecipes } from "@/src/services/inventoryService"; import { addRecipes } from "@/src/services/inventoryService";
import { config } from "@/src/services/configService";
import { ITypeCount } from "@/src/types/commonTypes"; import { ITypeCount } from "@/src/types/commonTypes";
export const addInfestedFoundryXP = (infestedFoundry: IInfestedFoundryDatabase, delta: number): ITypeCount[] => { export const addInfestedFoundryXP = (infestedFoundry: IInfestedFoundryDatabase, delta: number): ITypeCount[] => {
@ -97,8 +100,8 @@ export const handleSubsumeCompletion = (inventory: TInventoryDatabaseDocument):
return recipeChanges; return recipeChanges;
}; };
export const applyCheatsToInfestedFoundry = (infestedFoundry: IInfestedFoundryClient): void => { export const applyCheatsToInfestedFoundry = (cheats: IAccountCheats, infestedFoundry: IInfestedFoundryClient): void => {
if (config.infiniteHelminthMaterials) { if (cheats.infiniteHelminthMaterials) {
infestedFoundry.Resources = [ infestedFoundry.Resources = [
{ ItemType: "/Lotus/Types/Items/InfestedFoundry/HelminthCalx", Count: 1000 }, { ItemType: "/Lotus/Types/Items/InfestedFoundry/HelminthCalx", Count: 1000 },
{ ItemType: "/Lotus/Types/Items/InfestedFoundry/HelminthBiotics", Count: 1000 }, { ItemType: "/Lotus/Types/Items/InfestedFoundry/HelminthBiotics", Count: 1000 },

View File

@ -1201,8 +1201,8 @@ export const updateSlots = (
} }
}; };
const isCurrencyTracked = (usePremium: boolean): boolean => { const isCurrencyTracked = (inventory: TInventoryDatabaseDocument, usePremium: boolean): boolean => {
return usePremium ? !config.infinitePlatinum : !config.infiniteCredits; return usePremium ? !inventory.infinitePlatinum : !inventory.infiniteCredits;
}; };
export const updateCurrency = ( export const updateCurrency = (
@ -1211,7 +1211,7 @@ export const updateCurrency = (
usePremium: boolean, usePremium: boolean,
inventoryChanges: IInventoryChanges = {} inventoryChanges: IInventoryChanges = {}
): IInventoryChanges => { ): IInventoryChanges => {
if (price != 0 && isCurrencyTracked(usePremium)) { if (price != 0 && isCurrencyTracked(inventory, usePremium)) {
if (usePremium) { if (usePremium) {
if (inventory.PremiumCreditsFree > 0) { if (inventory.PremiumCreditsFree > 0) {
const premiumCreditsFreeDelta = Math.min(price, inventory.PremiumCreditsFree) * -1; const premiumCreditsFreeDelta = Math.min(price, inventory.PremiumCreditsFree) * -1;

View File

@ -328,7 +328,7 @@ export const handlePurchase = async (
purchaseResponse.InventoryChanges.MiscItems ??= []; purchaseResponse.InventoryChanges.MiscItems ??= [];
purchaseResponse.InventoryChanges.MiscItems.push(invItem); purchaseResponse.InventoryChanges.MiscItems.push(invItem);
} }
} else if (!config.infiniteRegalAya) { } else if (!inventory.infiniteRegalAya) {
inventory.PrimeTokens -= offer.PrimePrice! * purchaseRequest.PurchaseParams.Quantity; inventory.PrimeTokens -= offer.PrimePrice! * purchaseRequest.PurchaseParams.Quantity;
purchaseResponse.InventoryChanges.PrimeTokens ??= 0; purchaseResponse.InventoryChanges.PrimeTokens ??= 0;

View File

@ -19,6 +19,15 @@ export type InventoryDatabaseEquipment = {
[_ in TEquipmentKey]: IEquipmentDatabase[]; [_ in TEquipmentKey]: IEquipmentDatabase[];
}; };
// Fields specific to SNS
export interface IAccountCheats {
infiniteCredits?: boolean;
infinitePlatinum?: boolean;
infiniteEndo?: boolean;
infiniteRegalAya?: boolean;
infiniteHelminthMaterials?: boolean;
}
export interface IInventoryDatabase export interface IInventoryDatabase
extends Omit< extends Omit<
IInventoryClient, IInventoryClient,
@ -61,7 +70,8 @@ export interface IInventoryDatabase
| "PersonalGoalProgress" | "PersonalGoalProgress"
| TEquipmentKey | TEquipmentKey
>, >,
InventoryDatabaseEquipment { InventoryDatabaseEquipment,
IAccountCheats {
accountOwnerId: Types.ObjectId; accountOwnerId: Types.ObjectId;
Created: Date; Created: Date;
TrainingDate: Date; TrainingDate: Date;

View File

@ -663,26 +663,6 @@
<input class="form-check-input" type="checkbox" id="unlockAllScans" /> <input class="form-check-input" type="checkbox" id="unlockAllScans" />
<label class="form-check-label" for="unlockAllScans" data-loc="cheats_unlockAllScans"></label> <label class="form-check-label" for="unlockAllScans" data-loc="cheats_unlockAllScans"></label>
</div> </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>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" id="infinitePlatinum" />
<label class="form-check-label" for="infinitePlatinum" data-loc="cheats_infinitePlatinum"></label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" id="infiniteEndo" />
<label class="form-check-label" for="infiniteEndo" data-loc="cheats_infiniteEndo"></label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" id="infiniteRegalAya" />
<label class="form-check-label" for="infiniteRegalAya" data-loc="cheats_infiniteRegalAya"></label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" id="infiniteHelminthMaterials" />
<label class="form-check-label" for="infiniteHelminthMaterials" data-loc="cheats_infiniteHelminthMaterials"></label>
</div>
<div class="form-check"> <div class="form-check">
<input class="form-check-input" type="checkbox" id="claimingBlueprintRefundsIngredients" /> <input class="form-check-input" type="checkbox" id="claimingBlueprintRefundsIngredients" />
<label class="form-check-label" for="claimingBlueprintRefundsIngredients" data-loc="cheats_claimingBlueprintRefundsIngredients"></label> <label class="form-check-label" for="claimingBlueprintRefundsIngredients" data-loc="cheats_claimingBlueprintRefundsIngredients"></label>
@ -891,8 +871,28 @@
<div class="col-md-6"> <div class="col-md-6">
<div class="card mb-3"> <div class="card mb-3">
<h5 class="card-header" data-loc="cheats_account"></h5> <h5 class="card-header" data-loc="cheats_account"></h5>
<div class="card-body"> <div class="card-body" id="account-cheats">
<div class="mb-2 d-flex flex-wrap gap-2"> <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>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" id="infinitePlatinum" />
<label class="form-check-label" for="infinitePlatinum" data-loc="cheats_infinitePlatinum"></label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" id="infiniteEndo" />
<label class="form-check-label" for="infiniteEndo" data-loc="cheats_infiniteEndo"></label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" id="infiniteRegalAya" />
<label class="form-check-label" for="infiniteRegalAya" data-loc="cheats_infiniteRegalAya"></label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" id="infiniteHelminthMaterials" />
<label class="form-check-label" for="infiniteHelminthMaterials" data-loc="cheats_infiniteHelminthMaterials"></label>
</div>
<div class="mt-2 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="debounce(doUnlockAllMissions);" data-loc="cheats_unlockAllMissions"></button>
<button class="btn btn-primary" onclick="debounce(markAllAsRead);" data-loc="cheats_markAllAsRead"></button> <button class="btn btn-primary" onclick="debounce(markAllAsRead);" data-loc="cheats_markAllAsRead"></button>
<button class="btn btn-primary" onclick="doUnlockAllFocusSchools();" data-loc="cheats_unlockAllFocusSchools"></button> <button class="btn btn-primary" onclick="doUnlockAllFocusSchools();" data-loc="cheats_unlockAllFocusSchools"></button>

View File

@ -605,6 +605,8 @@ function fetchItemList() {
} }
fetchItemList(); fetchItemList();
const accountCheats = document.querySelectorAll("#account-cheats input[id]");
// Assumes that caller revalidates authz // Assumes that caller revalidates authz
function updateInventory() { function updateInventory() {
const req = $.get("/api/inventory.php?" + window.authz + "&xpBasedLevelCapDisabled=1"); const req = $.get("/api/inventory.php?" + window.authz + "&xpBasedLevelCapDisabled=1");
@ -1473,6 +1475,10 @@ function updateInventory() {
} }
document.getElementById("Boosters-list").appendChild(tr); document.getElementById("Boosters-list").appendChild(tr);
}); });
for (const elm of accountCheats) {
elm.checked = !!data[elm.id];
}
}); });
}); });
} }
@ -2109,6 +2115,8 @@ function doAcquireModMax() {
alert("doAcquireModMax: " + uniqueName); alert("doAcquireModMax: " + uniqueName);
} }
// Cheats route
const uiConfigs = [...$(".config-form input[id], .config-form select[id]")].map(x => x.id); const uiConfigs = [...$(".config-form input[id], .config-form select[id]")].map(x => x.id);
for (const id of uiConfigs) { for (const id of uiConfigs) {
@ -2193,8 +2201,6 @@ function doSaveConfigStringArray(id) {
}); });
} }
// Cheats route
single.getRoute("/webui/cheats").on("beforeload", function () { single.getRoute("/webui/cheats").on("beforeload", function () {
let interval; let interval;
interval = setInterval(() => { interval = setInterval(() => {
@ -2306,6 +2312,23 @@ function doIntrinsicsUnlockAll() {
}); });
} }
document.querySelectorAll("#account-cheats input[type=checkbox]").forEach(elm => {
elm.onchange = function () {
revalidateAuthz().then(() => {
$.post({
url: "/custom/setAccountCheat?" + window.authz /*+ "&wsid=" + wsid*/,
contentType: "application/json",
data: JSON.stringify({
key: elm.id,
value: elm.checked
})
});
});
};
});
// Mods route
function doAddAllMods() { function doAddAllMods() {
let modsAll = new Set(); let modsAll = new Set();
for (const child of document.getElementById("datalist-mods").children) { for (const child of document.getElementById("datalist-mods").children) {