chore: move more cheats to account section #2680

Merged
Sainan merged 2 commits from AMelonInsideLemon/SpaceNinjaServer:move-to-account-section into main 2025-08-24 15:16:43 -07:00
18 changed files with 193 additions and 190 deletions

View File

@ -13,38 +13,15 @@
"skipTutorial": false, "skipTutorial": false,
"skipAllDialogue": false, "skipAllDialogue": false,
"unlockAllScans": false, "unlockAllScans": false,
"claimingBlueprintRefundsIngredients": false,
"dontSubtractPurchaseCreditCost": false,
"dontSubtractPurchasePlatinumCost": false,
"dontSubtractPurchaseItemCost": false,
"dontSubtractPurchaseStandingCost": false,
"dontSubtractVoidTraces": false,
"dontSubtractConsumables": false,
"unlockAllShipFeatures": false, "unlockAllShipFeatures": false,
"unlockAllShipDecorations": false, "unlockAllShipDecorations": false,
"unlockAllFlavourItems": false, "unlockAllFlavourItems": false,
"unlockAllSkins": false, "unlockAllSkins": false,
"unlockAllCapturaScenes": false, "unlockAllCapturaScenes": false,
"universalPolarityEverywhere": false,
"unlockDoubleCapacityPotatoesEverywhere": false,
"unlockExilusEverywhere": false,
"unlockArcanesEverywhere": false,
"noDailyStandingLimits": false,
"noDailyFocusLimit": false,
"noArgonCrystalDecay": false,
"noMasteryRankUpCooldown": false,
"noVendorPurchaseLimits": false,
"noDeathMarks": false,
"noKimCooldowns": false,
"fullyStockedVendors": false, "fullyStockedVendors": false,
AMelonInsideLemon marked this conversation as resolved Outdated

You removed these from configService but not here:

    noArgonCrystalDecay?: boolean;
    noMasteryRankUpCooldown?: boolean;
    noVendorPurchaseLimits?: boolean;
    noDeathMarks?: boolean;
    noKimCooldowns?: boolean;
You removed these from configService but not here: ```ts noArgonCrystalDecay?: boolean; noMasteryRankUpCooldown?: boolean; noVendorPurchaseLimits?: boolean; noDeathMarks?: boolean; noKimCooldowns?: boolean; ```
"baroAlwaysAvailable": false, "baroAlwaysAvailable": false,
"baroFullyStocked": false, "baroFullyStocked": false,
"syndicateMissionsRepeatable": false,
"unlockAllProfitTakerStages": false, "unlockAllProfitTakerStages": false,
"instantFinishRivenChallenge": false,
"instantResourceExtractorDrones": false,
"noResourceExtractorDronesDamage": false,
"skipClanKeyCrafting": false,
"noDojoRoomBuildStage": false, "noDojoRoomBuildStage": false,
"noDecoBuildStage": false, "noDecoBuildStage": false,
"fastDojoRoomDestruction": false, "fastDojoRoomDestruction": false,

View File

@ -10,11 +10,10 @@ import { getAccountIdForRequest } from "@/src/services/loginService";
import { getRandomElement } from "@/src/services/rngService"; import { getRandomElement } from "@/src/services/rngService";
import { RequestHandler } from "express"; import { RequestHandler } from "express";
import { ExportUpgrades } from "warframe-public-export-plus"; import { ExportUpgrades } from "warframe-public-export-plus";
import { config } from "@/src/services/configService";
export const activateRandomModController: RequestHandler = async (req, res) => { export const activateRandomModController: RequestHandler = async (req, res) => {
const accountId = await getAccountIdForRequest(req); const accountId = await getAccountIdForRequest(req);
const inventory = await getInventory(accountId); const inventory = await getInventory(accountId, "RawUpgrades Upgrades instantFinishRivenChallenge");
const request = getJSONfromString<IActiveRandomModRequest>(String(req.body)); const request = getJSONfromString<IActiveRandomModRequest>(String(req.body));
addMods(inventory, [ addMods(inventory, [
{ {
@ -23,7 +22,7 @@ export const activateRandomModController: RequestHandler = async (req, res) => {
} }
]); ]);
const rivenType = getRandomElement(rivenRawToRealWeighted[request.ItemType])!; const rivenType = getRandomElement(rivenRawToRealWeighted[request.ItemType])!;
const fingerprint = config.instantFinishRivenChallenge const fingerprint = inventory.instantFinishRivenChallenge
? createUnveiledRivenFingerprint(ExportUpgrades[rivenType]) ? createUnveiledRivenFingerprint(ExportUpgrades[rivenType])
: createVeiledRivenFingerprint(ExportUpgrades[rivenType]); : createVeiledRivenFingerprint(ExportUpgrades[rivenType]);
const upgradeIndex = const upgradeIndex =

View File

@ -23,7 +23,6 @@ import { InventorySlot, IPendingRecipeDatabase } from "@/src/types/inventoryType
import { toOid2 } from "@/src/helpers/inventoryHelpers"; import { toOid2 } from "@/src/helpers/inventoryHelpers";
import { TInventoryDatabaseDocument } from "@/src/models/inventoryModels/inventoryModel"; import { TInventoryDatabaseDocument } from "@/src/models/inventoryModels/inventoryModel";
import { IRecipe } from "warframe-public-export-plus"; import { IRecipe } from "warframe-public-export-plus";
import { config } from "@/src/services/configService";
import { EquipmentFeatures, IEquipmentClient, Status } from "@/src/types/equipmentTypes"; import { EquipmentFeatures, IEquipmentClient, Status } from "@/src/types/equipmentTypes";
interface IClaimCompletedRecipeRequest { interface IClaimCompletedRecipeRequest {
@ -247,7 +246,7 @@ export const claimCompletedRecipeController: RequestHandler = async (req, res) =
} }
} }
if ( if (
config.claimingBlueprintRefundsIngredients && inventory.claimingBlueprintRefundsIngredients &&
recipe.secretIngredientAction != "SIA_CREATE_KUBROW" // Can't refund the egg recipe.secretIngredientAction != "SIA_CREATE_KUBROW" // Can't refund the egg
) { ) {
await refundRecipeIngredients(inventory, InventoryChanges, recipe, pendingRecipe); await refundRecipeIngredients(inventory, InventoryChanges, recipe, pendingRecipe);

View File

@ -95,7 +95,10 @@ export const confirmGuildInvitationPostController: RequestHandler = async (req,
await GuildMember.deleteMany({ accountId: guildMember.accountId, status: 1 }); await GuildMember.deleteMany({ accountId: guildMember.accountId, status: 1 });
// Update inventory of new member // Update inventory of new member
const inventory = await getInventory(guildMember.accountId.toString(), "GuildId LevelKeys Recipes"); const inventory = await getInventory(
guildMember.accountId.toString(),
"GuildId LevelKeys Recipes skipClanKeyCrafting"
);
inventory.GuildId = new Types.ObjectId(req.query.clanId as string); inventory.GuildId = new Types.ObjectId(req.query.clanId as string);
giveClanKey(inventory); giveClanKey(inventory);
await inventory.save(); await inventory.save();

View File

@ -27,7 +27,7 @@ export const createGuildController: RequestHandler = async (req, res) => {
rank: 0 rank: 0
}); });
const inventory = await getInventory(account._id.toString(), "GuildId LevelKeys Recipes"); const inventory = await getInventory(account._id.toString(), "GuildId LevelKeys Recipes skipClanKeyCrafting");
inventory.GuildId = guild._id; inventory.GuildId = guild._id;
const inventoryChanges: IInventoryChanges = {}; const inventoryChanges: IInventoryChanges = {};
giveClanKey(inventory, inventoryChanges); giveClanKey(inventory, inventoryChanges);

View File

@ -1,5 +1,4 @@
import { toMongoDate, toOid } from "@/src/helpers/inventoryHelpers"; import { toMongoDate, toOid } from "@/src/helpers/inventoryHelpers";
import { config } from "@/src/services/configService";
import { addMiscItems, getInventory } from "@/src/services/inventoryService"; import { addMiscItems, getInventory } from "@/src/services/inventoryService";
import { fromStoreItem } from "@/src/services/itemDataService"; import { fromStoreItem } from "@/src/services/itemDataService";
import { getAccountIdForRequest } from "@/src/services/loginService"; import { getAccountIdForRequest } from "@/src/services/loginService";
@ -39,10 +38,13 @@ export const dronesController: RequestHandler = async (req, res) => {
ActiveDrones: activeDrones ActiveDrones: activeDrones
}); });
} else if ("droneId" in req.query && "systemIndex" in req.query) { } else if ("droneId" in req.query && "systemIndex" in req.query) {
const inventory = await getInventory(accountId, "Drones"); const inventory = await getInventory(
accountId,
"Drones instantResourceExtractorDrones noResourceExtractorDronesDamage"
);
const drone = inventory.Drones.id(req.query.droneId as string)!; const drone = inventory.Drones.id(req.query.droneId as string)!;
const droneMeta = ExportDrones[drone.ItemType]; const droneMeta = ExportDrones[drone.ItemType];
drone.DeployTime = config.instantResourceExtractorDrones ? new Date(0) : new Date(); drone.DeployTime = inventory.instantResourceExtractorDrones ? new Date(0) : new Date();
if (drone.RepairStart) { if (drone.RepairStart) {
const repairMinutes = (Date.now() - drone.RepairStart.getTime()) / 60_000; const repairMinutes = (Date.now() - drone.RepairStart.getTime()) / 60_000;
const hpPerMinute = droneMeta.repairRate / 60; const hpPerMinute = droneMeta.repairRate / 60;
@ -51,11 +53,11 @@ export const dronesController: RequestHandler = async (req, res) => {
} }
drone.System = parseInt(req.query.systemIndex as string); drone.System = parseInt(req.query.systemIndex as string);
const system = ExportSystems[drone.System - 1]; const system = ExportSystems[drone.System - 1];
drone.DamageTime = config.instantResourceExtractorDrones drone.DamageTime = inventory.instantResourceExtractorDrones
? new Date() ? new Date()
: new Date(Date.now() + getRandomInt(3 * 3600 * 1000, 4 * 3600 * 1000)); : new Date(Date.now() + getRandomInt(3 * 3600 * 1000, 4 * 3600 * 1000));
drone.PendingDamage = drone.PendingDamage =
!config.noResourceExtractorDronesDamage && Math.random() < system.damageChance !inventory.noResourceExtractorDronesDamage && Math.random() < system.damageChance
? getRandomInt(system.droneDamage.minValue, system.droneDamage.maxValue) ? getRandomInt(system.droneDamage.minValue, system.droneDamage.maxValue)
: 0; : 0;
const resource = getRandomWeightedRewardUc(system.resources, droneMeta.probabilities)!; const resource = getRandomWeightedRewardUc(system.resources, droneMeta.probabilities)!;

View File

@ -68,7 +68,7 @@ export const inventoryController: RequestHandler = async (request, response) =>
const lastLoginDay = Math.trunc(inventory.NextRefill.getTime() / 86400000) - 1; const lastLoginDay = Math.trunc(inventory.NextRefill.getTime() / 86400000) - 1;
const daysPassed = today - lastLoginDay; const daysPassed = today - lastLoginDay;
if (config.noArgonCrystalDecay) { if (inventory.noArgonCrystalDecay) {
inventory.FoundToday = undefined; inventory.FoundToday = undefined;
} else { } else {
for (let i = 0; i != daysPassed; ++i) { for (let i = 0; i != daysPassed; ++i) {
@ -387,7 +387,7 @@ export const getInventoryResponse = async (
} }
} }
if (config.universalPolarityEverywhere) { if (inventory.universalPolarityEverywhere) {
const Polarity: IPolarity[] = []; const Polarity: IPolarity[] = [];
// 12 is needed for necramechs. 15 is needed for plexus/crewshipharness. // 12 is needed for necramechs. 15 is needed for plexus/crewshipharness.
for (let i = 0; i != 15; ++i) { for (let i = 0; i != 15; ++i) {
@ -405,7 +405,7 @@ export const getInventoryResponse = async (
} }
} }
if (config.unlockDoubleCapacityPotatoesEverywhere) { if (inventory.unlockDoubleCapacityPotatoesEverywhere) {
for (const key of equipmentKeys) { for (const key of equipmentKeys) {
if (key in inventoryResponse) { if (key in inventoryResponse) {
for (const equipment of inventoryResponse[key]) { for (const equipment of inventoryResponse[key]) {
@ -416,7 +416,7 @@ export const getInventoryResponse = async (
} }
} }
if (config.unlockExilusEverywhere) { if (inventory.unlockExilusEverywhere) {
for (const key of equipmentKeys) { for (const key of equipmentKeys) {
if (key in inventoryResponse) { if (key in inventoryResponse) {
for (const equipment of inventoryResponse[key]) { for (const equipment of inventoryResponse[key]) {
@ -427,7 +427,7 @@ export const getInventoryResponse = async (
} }
} }
if (config.unlockArcanesEverywhere) { if (inventory.unlockArcanesEverywhere) {
for (const key of equipmentKeys) { for (const key of equipmentKeys) {
if (key in inventoryResponse) { if (key in inventoryResponse) {
for (const equipment of inventoryResponse[key]) { for (const equipment of inventoryResponse[key]) {
@ -438,14 +438,14 @@ export const getInventoryResponse = async (
} }
} }
if (config.noDailyStandingLimits) { if (inventory.noDailyStandingLimits) {
const spoofedDailyAffiliation = Math.max(999_999, 16000 + inventoryResponse.PlayerLevel * 500); const spoofedDailyAffiliation = Math.max(999_999, 16000 + inventoryResponse.PlayerLevel * 500);
for (const key of allDailyAffiliationKeys) { for (const key of allDailyAffiliationKeys) {
inventoryResponse[key] = spoofedDailyAffiliation; inventoryResponse[key] = spoofedDailyAffiliation;
} }
} }
if (config.noDailyFocusLimit) { if (inventory.noDailyFocusLimit) {
inventoryResponse.DailyFocus = Math.max(999_999, 250000 + inventoryResponse.PlayerLevel * 5000); inventoryResponse.DailyFocus = Math.max(999_999, 250000 + inventoryResponse.PlayerLevel * 5000);
} }

View File

@ -2,14 +2,13 @@ import { RequestHandler } from "express";
import { getAccountIdForRequest } from "@/src/services/loginService"; import { getAccountIdForRequest } from "@/src/services/loginService";
import { addMiscItems, getInventory } from "@/src/services/inventoryService"; import { addMiscItems, getInventory } from "@/src/services/inventoryService";
import { ExportRelics, IRelic } from "warframe-public-export-plus"; import { ExportRelics, IRelic } from "warframe-public-export-plus";
import { config } from "@/src/services/configService";
export const projectionManagerController: RequestHandler = async (req, res) => { export const projectionManagerController: RequestHandler = async (req, res) => {
const accountId = await getAccountIdForRequest(req); const accountId = await getAccountIdForRequest(req);
const inventory = await getInventory(accountId); const inventory = await getInventory(accountId, "MiscItems dontSubtractVoidTraces");
const request = JSON.parse(String(req.body)) as IProjectionUpgradeRequest; const request = JSON.parse(String(req.body)) as IProjectionUpgradeRequest;
const [era, category, currentQuality] = parseProjection(request.projectionType); const [era, category, currentQuality] = parseProjection(request.projectionType);
const upgradeCost = config.dontSubtractVoidTraces const upgradeCost = inventory.dontSubtractVoidTraces
? 0 ? 0
: qualityNumberToCost[request.qualityTag] - qualityNumberToCost[qualityKeywordToNumber[currentQuality]]; : qualityNumberToCost[request.qualityTag] - qualityNumberToCost[qualityKeywordToNumber[currentQuality]];
const newProjectionType = findProjection(era, category, qualityNumberToKeyword[request.qualityTag]); const newProjectionType = findProjection(era, category, qualityNumberToKeyword[request.qualityTag]);

View File

@ -1,4 +1,3 @@
import { config } from "@/src/services/configService";
import { addEmailItem, getDialogue, getInventory, updateCurrency } from "@/src/services/inventoryService"; import { addEmailItem, getDialogue, getInventory, updateCurrency } from "@/src/services/inventoryService";
import { getAccountIdForRequest } from "@/src/services/loginService"; import { getAccountIdForRequest } from "@/src/services/loginService";
import { ICompletedDialogue } from "@/src/types/inventoryTypes/inventoryTypes"; import { ICompletedDialogue } from "@/src/types/inventoryTypes/inventoryTypes";
@ -9,7 +8,7 @@ export const saveDialogueController: RequestHandler = async (req, res) => {
const accountId = await getAccountIdForRequest(req); const accountId = await getAccountIdForRequest(req);
const request = JSON.parse(String(req.body)) as SaveDialogueRequest; const request = JSON.parse(String(req.body)) as SaveDialogueRequest;
if ("YearIteration" in request) { if ("YearIteration" in request) {
const inventory = await getInventory(accountId, "DialogueHistory"); const inventory = await getInventory(accountId, "DialogueHistory noKimCooldowns");
inventory.DialogueHistory ??= {}; inventory.DialogueHistory ??= {};
inventory.DialogueHistory.YearIteration = request.YearIteration; inventory.DialogueHistory.YearIteration = request.YearIteration;
await inventory.save(); await inventory.save();
@ -17,7 +16,7 @@ export const saveDialogueController: RequestHandler = async (req, res) => {
} else { } else {
const inventory = await getInventory(accountId); const inventory = await getInventory(accountId);
const inventoryChanges: IInventoryChanges = {}; const inventoryChanges: IInventoryChanges = {};
const tomorrowAt0Utc = config.noKimCooldowns const tomorrowAt0Utc = inventory.noKimCooldowns
? Date.now() ? Date.now()
: (Math.trunc(Date.now() / 86400_000) + 1) * 86400_000; : (Math.trunc(Date.now() / 86400_000) + 1) * 86400_000;
inventory.DialogueHistory ??= {}; inventory.DialogueHistory ??= {};

View File

@ -6,7 +6,6 @@ import { RequestHandler } from "express";
import { unixTimesInMs } from "@/src/constants/timeConstants"; import { unixTimesInMs } from "@/src/constants/timeConstants";
import { IInventoryChanges } from "@/src/types/purchaseTypes"; import { IInventoryChanges } from "@/src/types/purchaseTypes";
import { createMessage } from "@/src/services/inboxService"; import { createMessage } from "@/src/services/inboxService";
import { config } from "@/src/services/configService";
interface ITrainingResultsRequest { interface ITrainingResultsRequest {
numLevelsGained: number; numLevelsGained: number;
@ -23,11 +22,11 @@ const trainingResultController: RequestHandler = async (req, res): Promise<void>
const trainingResults = getJSONfromString<ITrainingResultsRequest>(String(req.body)); const trainingResults = getJSONfromString<ITrainingResultsRequest>(String(req.body));
const inventory = await getInventory(accountId, "TrainingDate PlayerLevel TradesRemaining"); const inventory = await getInventory(accountId, "TrainingDate PlayerLevel TradesRemaining noMasteryRankUpCooldown");
if (trainingResults.numLevelsGained == 1) { if (trainingResults.numLevelsGained == 1) {
let time = Date.now(); let time = Date.now();
if (!config.noMasteryRankUpCooldown) { if (!inventory.noMasteryRankUpCooldown) {
time += unixTimesInMs.hour * 23; time += unixTimesInMs.hour * 23;
} }
inventory.TrainingDate = new Date(time); inventory.TrainingDate = new Date(time);

View File

@ -1427,11 +1427,34 @@ const inventorySchema = new Schema<IInventoryDatabase, InventoryDocumentProps>(
accountOwnerId: Schema.Types.ObjectId, accountOwnerId: Schema.Types.ObjectId,
// SNS account cheats // SNS account cheats
dontSubtractPurchaseCreditCost: Boolean,
dontSubtractPurchasePlatinumCost: Boolean,
dontSubtractPurchaseItemCost: Boolean,
dontSubtractPurchaseStandingCost: Boolean,
dontSubtractVoidTraces: Boolean,
dontSubtractConsumables: Boolean,
infiniteCredits: Boolean, infiniteCredits: Boolean,
infinitePlatinum: Boolean, infinitePlatinum: Boolean,
infiniteEndo: Boolean, infiniteEndo: Boolean,
infiniteRegalAya: Boolean, infiniteRegalAya: Boolean,
infiniteHelminthMaterials: Boolean, infiniteHelminthMaterials: Boolean,
universalPolarityEverywhere: Boolean,
unlockDoubleCapacityPotatoesEverywhere: Boolean,
unlockExilusEverywhere: Boolean,
unlockArcanesEverywhere: Boolean,
syndicateMissionsRepeatable: Boolean,
instantFinishRivenChallenge: Boolean,
noDailyStandingLimits: Boolean,
noDailyFocusLimit: Boolean,
noArgonCrystalDecay: Boolean,
noMasteryRankUpCooldown: Boolean,
noVendorPurchaseLimits: Boolean,
noDeathMarks: Boolean,
noKimCooldowns: Boolean,
skipClanKeyCrafting: Boolean,
claimingBlueprintRefundsIngredients: Boolean,
instantResourceExtractorDrones: Boolean,
noResourceExtractorDronesDamage: Boolean,
SubscribedToEmails: { type: Number, default: 0 }, SubscribedToEmails: { type: Number, default: 0 },
SubscribedToEmailsPersonalized: { type: Number, default: 0 }, SubscribedToEmailsPersonalized: { type: Number, default: 0 },

View File

@ -20,39 +20,16 @@ export interface IConfig {
skipTutorial?: boolean; skipTutorial?: boolean;
skipAllDialogue?: boolean; skipAllDialogue?: boolean;
unlockAllScans?: boolean; unlockAllScans?: boolean;
claimingBlueprintRefundsIngredients?: boolean;
dontSubtractPurchaseCreditCost?: boolean;
dontSubtractPurchasePlatinumCost?: boolean;
dontSubtractPurchaseItemCost?: boolean;
dontSubtractPurchaseStandingCost?: boolean;
dontSubtractVoidTraces?: boolean;
dontSubtractConsumables?: boolean;
unlockAllShipFeatures?: boolean; unlockAllShipFeatures?: boolean;
unlockAllShipDecorations?: boolean; unlockAllShipDecorations?: boolean;
unlockAllFlavourItems?: boolean; unlockAllFlavourItems?: boolean;
unlockAllSkins?: boolean; unlockAllSkins?: boolean;
unlockAllCapturaScenes?: boolean; unlockAllCapturaScenes?: boolean;
unlockAllDecoRecipes?: boolean; unlockAllDecoRecipes?: boolean;
universalPolarityEverywhere?: boolean;
unlockDoubleCapacityPotatoesEverywhere?: boolean;
unlockExilusEverywhere?: boolean;
unlockArcanesEverywhere?: boolean;
noDailyStandingLimits?: boolean;
noDailyFocusLimit?: boolean;
noArgonCrystalDecay?: boolean;
noMasteryRankUpCooldown?: boolean;
noVendorPurchaseLimits?: boolean;
noDeathMarks?: boolean;
noKimCooldowns?: boolean;
fullyStockedVendors?: boolean; fullyStockedVendors?: boolean;
baroAlwaysAvailable?: boolean; baroAlwaysAvailable?: boolean;
baroFullyStocked?: boolean; baroFullyStocked?: boolean;
syndicateMissionsRepeatable?: boolean;
unlockAllProfitTakerStages?: boolean; unlockAllProfitTakerStages?: boolean;
instantFinishRivenChallenge?: boolean;
instantResourceExtractorDrones?: boolean;
noResourceExtractorDronesDamage?: boolean;
skipClanKeyCrafting?: boolean;
noDojoRoomBuildStage?: boolean; noDojoRoomBuildStage?: boolean;
noDojoDecoBuildStage?: boolean; noDojoDecoBuildStage?: boolean;
fastDojoRoomDestruction?: boolean; fastDojoRoomDestruction?: boolean;

View File

@ -690,7 +690,7 @@ export const checkClanAscensionHasRequiredContributors = async (guild: TGuildDat
}; };
export const giveClanKey = (inventory: TInventoryDatabaseDocument, inventoryChanges?: IInventoryChanges): void => { export const giveClanKey = (inventory: TInventoryDatabaseDocument, inventoryChanges?: IInventoryChanges): void => {
if (config.skipClanKeyCrafting) { if (inventory.skipClanKeyCrafting) {
const levelKeyChanges = [ const levelKeyChanges = [
{ {
ItemType: "/Lotus/Types/Keys/DojoKey", ItemType: "/Lotus/Types/Keys/DojoKey",

View File

@ -1299,15 +1299,19 @@ const standingLimitBinToInventoryKey: Record<
export const allDailyAffiliationKeys: (keyof IDailyAffiliations)[] = Object.values(standingLimitBinToInventoryKey); export const allDailyAffiliationKeys: (keyof IDailyAffiliations)[] = Object.values(standingLimitBinToInventoryKey);
const getStandingLimit = (inventory: IDailyAffiliations, bin: TStandingLimitBin): number => { const getStandingLimit = (inventory: TInventoryDatabaseDocument, bin: TStandingLimitBin): number => {
if (bin == "STANDING_LIMIT_BIN_NONE" || config.noDailyStandingLimits) { if (bin == "STANDING_LIMIT_BIN_NONE" || inventory.noDailyStandingLimits) {
return Number.MAX_SAFE_INTEGER; return Number.MAX_SAFE_INTEGER;
} }
return inventory[standingLimitBinToInventoryKey[bin]]; return inventory[standingLimitBinToInventoryKey[bin]];
}; };
const updateStandingLimit = (inventory: IDailyAffiliations, bin: TStandingLimitBin, subtrahend: number): void => { const updateStandingLimit = (
if (bin != "STANDING_LIMIT_BIN_NONE" && !config.noDailyStandingLimits) { inventory: TInventoryDatabaseDocument,
bin: TStandingLimitBin,
subtrahend: number
): void => {
if (bin != "STANDING_LIMIT_BIN_NONE" && !inventory.noDailyStandingLimits) {
inventory[standingLimitBinToInventoryKey[bin]] -= subtrahend; inventory[standingLimitBinToInventoryKey[bin]] -= subtrahend;
} }
}; };
@ -1922,7 +1926,7 @@ export const addFocusXpIncreases = (inventory: TInventoryDatabaseDocument, focus
inventory.FocusXP.AP_WARD += focusXpPlus[FocusType.AP_WARD]; inventory.FocusXP.AP_WARD += focusXpPlus[FocusType.AP_WARD];
} }
if (!config.noDailyFocusLimit) { if (!inventory.noDailyFocusLimit) {
inventory.DailyFocus -= focusXpPlus.reduce((a, b) => a + b, 0); inventory.DailyFocus -= focusXpPlus.reduce((a, b) => a + b, 0);
} }
}; };

View File

@ -295,7 +295,7 @@ export const addMissionInventoryUpdates = async (
addMiscItems(inventory, value); addMiscItems(inventory, value);
break; break;
case "Consumables": case "Consumables":
if (config.dontSubtractConsumables) { if (inventory.dontSubtractConsumables) {
addConsumables( addConsumables(
inventory, inventory,
value.filter(x => x.ItemCount > 0) value.filter(x => x.ItemCount > 0)
@ -466,7 +466,7 @@ export const addMissionInventoryUpdates = async (
}); });
break; break;
case "SyndicateId": { case "SyndicateId": {
if (!config.syndicateMissionsRepeatable) { if (!inventory.syndicateMissionsRepeatable) {
inventory.CompletedSyndicates.push(value); inventory.CompletedSyndicates.push(value);
} }
break; break;
@ -486,7 +486,7 @@ export const addMissionInventoryUpdates = async (
break; break;
} }
case "DeathMarks": { case "DeathMarks": {
if (!config.noDeathMarks) { if (!inventory.noDeathMarks) {
for (const bossName of value) { for (const bossName of value) {
if (inventory.DeathMarks.indexOf(bossName) == -1) { if (inventory.DeathMarks.indexOf(bossName) == -1) {
// It's a new death mark; we have to say the line. // It's a new death mark; we have to say the line.
@ -1550,7 +1550,7 @@ export const addMissionRewards = async (
const dialogue = getDialogue(inventory, buddy); const dialogue = getDialogue(inventory, buddy);
if (Date.now() >= dialogue.BountyChemExpiry.getTime()) { if (Date.now() >= dialogue.BountyChemExpiry.getTime()) {
logger.debug(`Giving 20 chemistry for ${buddy}`); logger.debug(`Giving 20 chemistry for ${buddy}`);
const tomorrowAt0Utc = config.noKimCooldowns const tomorrowAt0Utc = inventory.noKimCooldowns
? Date.now() ? Date.now()
: (Math.trunc(Date.now() / 86400_000) + 1) * 86400_000; : (Math.trunc(Date.now() / 86400_000) + 1) * 86400_000;
dialogue.Chemistry += 20; dialogue.Chemistry += 20;

View File

@ -31,7 +31,6 @@ import {
ExportVendors, ExportVendors,
TRarity TRarity
} from "warframe-public-export-plus"; } from "warframe-public-export-plus";
import { config } from "@/src/services/configService";
import { TInventoryDatabaseDocument } from "@/src/models/inventoryModels/inventoryModel"; import { TInventoryDatabaseDocument } from "@/src/models/inventoryModels/inventoryModel";
import { fromStoreItem, toStoreItem } from "@/src/services/itemDataService"; import { fromStoreItem, toStoreItem } from "@/src/services/itemDataService";
import { DailyDeal } from "@/src/models/worldStateModel"; import { DailyDeal } from "@/src/models/worldStateModel";
@ -63,7 +62,7 @@ const tallyVendorPurchase = (
numPurchased: number, numPurchased: number,
Expiry: Date Expiry: Date
): void => { ): void => {
if (!config.noVendorPurchaseLimits) { if (!inventory.noVendorPurchaseLimits) {
inventory.RecentVendorPurchases ??= []; inventory.RecentVendorPurchases ??= [];
let vendorPurchases = inventory.RecentVendorPurchases.find(x => x.VendorType == VendorType); let vendorPurchases = inventory.RecentVendorPurchases.find(x => x.VendorType == VendorType);
if (!vendorPurchases) { if (!vendorPurchases) {
@ -130,12 +129,12 @@ export const handlePurchase = async (
if (!offer) { if (!offer) {
throw new Error(`unknown vendor offer: ${ItemId ? ItemId : purchaseRequest.PurchaseParams.StoreItem}`); throw new Error(`unknown vendor offer: ${ItemId ? ItemId : purchaseRequest.PurchaseParams.StoreItem}`);
} }
if (!config.dontSubtractPurchaseCreditCost) { if (!inventory.dontSubtractPurchaseCreditCost) {
if (offer.RegularPrice) { if (offer.RegularPrice) {
updateCurrency(inventory, offer.RegularPrice[0], false, prePurchaseInventoryChanges); updateCurrency(inventory, offer.RegularPrice[0], false, prePurchaseInventoryChanges);
} }
} }
if (!config.dontSubtractPurchasePlatinumCost) { if (!inventory.dontSubtractPurchasePlatinumCost) {
if (offer.PremiumPrice) { if (offer.PremiumPrice) {
updateCurrency(inventory, offer.PremiumPrice[0], true, prePurchaseInventoryChanges); updateCurrency(inventory, offer.PremiumPrice[0], true, prePurchaseInventoryChanges);
} }
@ -156,7 +155,7 @@ export const handlePurchase = async (
}); });
} }
} }
if (!config.dontSubtractPurchaseItemCost) { if (!inventory.dontSubtractPurchaseItemCost) {
if (offer.ItemPrices) { if (offer.ItemPrices) {
handleItemPrices( handleItemPrices(
inventory, inventory,
@ -223,14 +222,14 @@ export const handlePurchase = async (
x => x.ItemType == purchaseRequest.PurchaseParams.StoreItem x => x.ItemType == purchaseRequest.PurchaseParams.StoreItem
); );
if (offer) { if (offer) {
if (!config.dontSubtractPurchaseCreditCost) { if (!inventory.dontSubtractPurchaseCreditCost) {
updateCurrency(inventory, offer.RegularPrice, false, purchaseResponse.InventoryChanges); updateCurrency(inventory, offer.RegularPrice, false, purchaseResponse.InventoryChanges);
} }
if (purchaseRequest.PurchaseParams.ExpectedPrice) { if (purchaseRequest.PurchaseParams.ExpectedPrice) {
throw new Error(`vendor purchase should not have an expected price`); throw new Error(`vendor purchase should not have an expected price`);
} }
if (offer.PrimePrice && !config.dontSubtractPurchaseItemCost) { if (offer.PrimePrice && !inventory.dontSubtractPurchaseItemCost) {
const invItem: IMiscItem = { const invItem: IMiscItem = {
ItemType: "/Lotus/Types/Items/MiscItems/PrimeBucks", ItemType: "/Lotus/Types/Items/MiscItems/PrimeBucks",
ItemCount: offer.PrimePrice * purchaseRequest.PurchaseParams.Quantity * -1 ItemCount: offer.PrimePrice * purchaseRequest.PurchaseParams.Quantity * -1
@ -267,7 +266,7 @@ export const handlePurchase = async (
Title: lastTitle Title: lastTitle
} }
]; ];
} else if (!config.dontSubtractPurchaseStandingCost) { } else if (!inventory.dontSubtractPurchaseStandingCost) {
const syndicate = ExportSyndicates[syndicateTag]; const syndicate = ExportSyndicates[syndicateTag];
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
if (syndicate) { if (syndicate) {
@ -301,13 +300,13 @@ export const handlePurchase = async (
const vendor = ExportVendors[purchaseRequest.PurchaseParams.SourceId!]; const vendor = ExportVendors[purchaseRequest.PurchaseParams.SourceId!];
const offer = vendor.items.find(x => x.storeItem == purchaseRequest.PurchaseParams.StoreItem); const offer = vendor.items.find(x => x.storeItem == purchaseRequest.PurchaseParams.StoreItem);
if (offer) { if (offer) {
if (typeof offer.credits == "number" && !config.dontSubtractPurchaseCreditCost) { if (typeof offer.credits == "number" && !inventory.dontSubtractPurchaseCreditCost) {
updateCurrency(inventory, offer.credits, false, purchaseResponse.InventoryChanges); updateCurrency(inventory, offer.credits, false, purchaseResponse.InventoryChanges);
} }
if (typeof offer.platinum == "number" && !config.dontSubtractPurchasePlatinumCost) { if (typeof offer.platinum == "number" && !inventory.dontSubtractPurchasePlatinumCost) {
updateCurrency(inventory, offer.platinum, true, purchaseResponse.InventoryChanges); updateCurrency(inventory, offer.platinum, true, purchaseResponse.InventoryChanges);
} }
if (offer.itemPrices && !config.dontSubtractPurchaseItemCost) { if (offer.itemPrices && !inventory.dontSubtractPurchaseItemCost) {
handleItemPrices( handleItemPrices(
inventory, inventory,
offer.itemPrices, offer.itemPrices,
@ -335,7 +334,7 @@ export const handlePurchase = async (
); );
if (offer) { if (offer) {
if (offer.RegularPrice) { if (offer.RegularPrice) {
if (!config.dontSubtractPurchaseItemCost) { if (!inventory.dontSubtractPurchaseItemCost) {
const invItem: IMiscItem = { const invItem: IMiscItem = {
ItemType: "/Lotus/Types/Items/MiscItems/SchismKey", ItemType: "/Lotus/Types/Items/MiscItems/SchismKey",
ItemCount: offer.RegularPrice * purchaseRequest.PurchaseParams.Quantity * -1 ItemCount: offer.RegularPrice * purchaseRequest.PurchaseParams.Quantity * -1
@ -394,11 +393,11 @@ export const handleDailyDealPurchase = async (
dailyDeal.AmountSold += 1; dailyDeal.AmountSold += 1;
await dailyDeal.save(); await dailyDeal.save();
if (!config.dontSubtractPurchasePlatinumCost) { if (!inventory.dontSubtractPurchasePlatinumCost) {
updateCurrency(inventory, dailyDeal.SalePrice, true, purchaseResponse.InventoryChanges); updateCurrency(inventory, dailyDeal.SalePrice, true, purchaseResponse.InventoryChanges);
} }
if (!config.noVendorPurchaseLimits) { if (!inventory.noVendorPurchaseLimits) {
inventory.UsedDailyDeals.push(purchaseParams.StoreItem); inventory.UsedDailyDeals.push(purchaseParams.StoreItem);
purchaseResponse.DailyDealUsed = purchaseParams.StoreItem; purchaseResponse.DailyDealUsed = purchaseParams.StoreItem;
} }

View File

@ -21,11 +21,34 @@ export type InventoryDatabaseEquipment = {
// Fields specific to SNS // Fields specific to SNS
export interface IAccountCheats { export interface IAccountCheats {
dontSubtractPurchaseCreditCost?: boolean;
dontSubtractPurchasePlatinumCost?: boolean;
dontSubtractPurchaseItemCost?: boolean;
dontSubtractPurchaseStandingCost?: boolean;
dontSubtractVoidTraces?: boolean;
dontSubtractConsumables?: boolean;
infiniteCredits?: boolean; infiniteCredits?: boolean;
infinitePlatinum?: boolean; infinitePlatinum?: boolean;
infiniteEndo?: boolean; infiniteEndo?: boolean;
infiniteRegalAya?: boolean; infiniteRegalAya?: boolean;
infiniteHelminthMaterials?: boolean; infiniteHelminthMaterials?: boolean;
universalPolarityEverywhere?: boolean;
unlockDoubleCapacityPotatoesEverywhere?: boolean;
unlockExilusEverywhere?: boolean;
unlockArcanesEverywhere?: boolean;
syndicateMissionsRepeatable?: boolean;
instantFinishRivenChallenge?: boolean;
noDailyStandingLimits?: boolean;
noDailyFocusLimit?: boolean;
noArgonCrystalDecay?: boolean;
noMasteryRankUpCooldown?: boolean;
noVendorPurchaseLimits?: boolean;
noDeathMarks?: boolean;
noKimCooldowns?: boolean;
skipClanKeyCrafting?: boolean;
claimingBlueprintRefundsIngredients?: boolean;
instantResourceExtractorDrones?: boolean;
noResourceExtractorDronesDamage?: boolean;
} }
export interface IInventoryDatabase export interface IInventoryDatabase

View File

@ -663,34 +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="claimingBlueprintRefundsIngredients" />
<label class="form-check-label" for="claimingBlueprintRefundsIngredients" data-loc="cheats_claimingBlueprintRefundsIngredients"></label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" id="dontSubtractPurchaseCreditCost" />
<label class="form-check-label" for="dontSubtractPurchaseCreditCost" data-loc="cheats_dontSubtractPurchaseCreditCost"></label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" id="dontSubtractPurchasePlatinumCost" />
<label class="form-check-label" for="dontSubtractPurchasePlatinumCost" data-loc="cheats_dontSubtractPurchasePlatinumCost"></label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" id="dontSubtractPurchaseItemCost" />
<label class="form-check-label" for="dontSubtractPurchaseItemCost" data-loc="cheats_dontSubtractPurchaseItemCost"></label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" id="dontSubtractPurchaseStandingCost" />
<label class="form-check-label" for="dontSubtractPurchaseStandingCost" data-loc="cheats_dontSubtractPurchaseStandingCost"></label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" id="dontSubtractVoidTraces" />
<label class="form-check-label" for="dontSubtractVoidTraces" data-loc="cheats_dontSubtractVoidTraces"></label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" id="dontSubtractConsumables" />
<label class="form-check-label" for="dontSubtractConsumables" data-loc="cheats_dontSubtractConsumables"></label>
</div>
<div class="form-check"> <div class="form-check">
<input class="form-check-input" type="checkbox" id="unlockAllShipFeatures" /> <input class="form-check-input" type="checkbox" id="unlockAllShipFeatures" />
<label class="form-check-label" for="unlockAllShipFeatures" data-loc="cheats_unlockAllShipFeatures"></label> <label class="form-check-label" for="unlockAllShipFeatures" data-loc="cheats_unlockAllShipFeatures"></label>
@ -715,50 +687,6 @@
<input class="form-check-input" type="checkbox" id="unlockAllDecoRecipes" /> <input class="form-check-input" type="checkbox" id="unlockAllDecoRecipes" />
<label class="form-check-label" for="unlockAllDecoRecipes" data-loc="cheats_unlockAllDecoRecipes"></label> <label class="form-check-label" for="unlockAllDecoRecipes" data-loc="cheats_unlockAllDecoRecipes"></label>
</div> </div>
<div class="form-check">
<input class="form-check-input" type="checkbox" id="universalPolarityEverywhere" />
<label class="form-check-label" for="universalPolarityEverywhere" data-loc="cheats_universalPolarityEverywhere"></label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" id="unlockDoubleCapacityPotatoesEverywhere" />
<label class="form-check-label" for="unlockDoubleCapacityPotatoesEverywhere" data-loc="cheats_unlockDoubleCapacityPotatoesEverywhere"></label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" id="unlockExilusEverywhere" />
<label class="form-check-label" for="unlockExilusEverywhere" data-loc="cheats_unlockExilusEverywhere"></label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" id="unlockArcanesEverywhere" />
<label class="form-check-label" for="unlockArcanesEverywhere" data-loc="cheats_unlockArcanesEverywhere"></label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" id="noDailyStandingLimits" />
<label class="form-check-label" for="noDailyStandingLimits" data-loc="cheats_noDailyStandingLimits"></label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" id="noDailyFocusLimit" />
<label class="form-check-label" for="noDailyFocusLimit" data-loc="cheats_noDailyFocusLimit"></label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" id="noArgonCrystalDecay" />
<label class="form-check-label" for="noArgonCrystalDecay" data-loc="cheats_noArgonCrystalDecay"></label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" id="noMasteryRankUpCooldown" />
<label class="form-check-label" for="noMasteryRankUpCooldown" data-loc="cheats_noMasteryRankUpCooldown"></label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" id="noVendorPurchaseLimits" />
<label class="form-check-label" for="noVendorPurchaseLimits" data-loc="cheats_noVendorPurchaseLimits"></label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" id="noDeathMarks" />
<label class="form-check-label" for="noDeathMarks" data-loc="cheats_noDeathMarks"></label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" id="noKimCooldowns" />
<label class="form-check-label" for="noKimCooldowns" data-loc="cheats_noKimCooldowns"></label>
</div>
<div class="form-check"> <div class="form-check">
<input class="form-check-input" type="checkbox" id="fullyStockedVendors" /> <input class="form-check-input" type="checkbox" id="fullyStockedVendors" />
<label class="form-check-label" for="fullyStockedVendors" data-loc="cheats_fullyStockedVendors"></label> <label class="form-check-label" for="fullyStockedVendors" data-loc="cheats_fullyStockedVendors"></label>
@ -771,30 +699,10 @@
<input class="form-check-input" type="checkbox" id="baroFullyStocked" /> <input class="form-check-input" type="checkbox" id="baroFullyStocked" />
<label class="form-check-label" for="baroFullyStocked" data-loc="cheats_baroFullyStocked"></label> <label class="form-check-label" for="baroFullyStocked" data-loc="cheats_baroFullyStocked"></label>
</div> </div>
<div class="form-check">
<input class="form-check-input" type="checkbox" id="syndicateMissionsRepeatable" />
<label class="form-check-label" for="syndicateMissionsRepeatable" data-loc="cheats_syndicateMissionsRepeatable"></label>
</div>
<div class="form-check"> <div class="form-check">
<input class="form-check-input" type="checkbox" id="unlockAllProfitTakerStages" /> <input class="form-check-input" type="checkbox" id="unlockAllProfitTakerStages" />
<label class="form-check-label" for="unlockAllProfitTakerStages" data-loc="cheats_unlockAllProfitTakerStages"></label> <label class="form-check-label" for="unlockAllProfitTakerStages" data-loc="cheats_unlockAllProfitTakerStages"></label>
</div> </div>
<div class="form-check">
<input class="form-check-input" type="checkbox" id="instantFinishRivenChallenge" />
<label class="form-check-label" for="instantFinishRivenChallenge" data-loc="cheats_instantFinishRivenChallenge"></label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" id="instantResourceExtractorDrones" />
<label class="form-check-label" for="instantResourceExtractorDrones" data-loc="cheats_instantResourceExtractorDrones"></label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" id="noResourceExtractorDronesDamage" />
<label class="form-check-label" for="noResourceExtractorDronesDamage" data-loc="cheats_noResourceExtractorDronesDamage"></label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" id="skipClanKeyCrafting" />
<label class="form-check-label" for="skipClanKeyCrafting" data-loc="cheats_skipClanKeyCrafting"></label>
</div>
<div class="form-check"> <div class="form-check">
<input class="form-check-input" type="checkbox" id="noDojoRoomBuildStage" /> <input class="form-check-input" type="checkbox" id="noDojoRoomBuildStage" />
<label class="form-check-label" for="noDojoRoomBuildStage" data-loc="cheats_noDojoRoomBuildStage"></label> <label class="form-check-label" for="noDojoRoomBuildStage" data-loc="cheats_noDojoRoomBuildStage"></label>
@ -872,6 +780,30 @@
<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" id="account-cheats"> <div class="card-body" id="account-cheats">
<div class="form-check">
<input class="form-check-input" type="checkbox" id="dontSubtractPurchaseCreditCost" />
<label class="form-check-label" for="dontSubtractPurchaseCreditCost" data-loc="cheats_dontSubtractPurchaseCreditCost"></label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" id="dontSubtractPurchasePlatinumCost" />
<label class="form-check-label" for="dontSubtractPurchasePlatinumCost" data-loc="cheats_dontSubtractPurchasePlatinumCost"></label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" id="dontSubtractPurchaseItemCost" />
<label class="form-check-label" for="dontSubtractPurchaseItemCost" data-loc="cheats_dontSubtractPurchaseItemCost"></label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" id="dontSubtractPurchaseStandingCost" />
<label class="form-check-label" for="dontSubtractPurchaseStandingCost" data-loc="cheats_dontSubtractPurchaseStandingCost"></label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" id="dontSubtractVoidTraces" />
<label class="form-check-label" for="dontSubtractVoidTraces" data-loc="cheats_dontSubtractVoidTraces"></label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" id="dontSubtractConsumables" />
<label class="form-check-label" for="dontSubtractConsumables" data-loc="cheats_dontSubtractConsumables"></label>
</div>
<div class="form-check"> <div class="form-check">
<input class="form-check-input" type="checkbox" id="infiniteCredits" /> <input class="form-check-input" type="checkbox" id="infiniteCredits" />
<label class="form-check-label" for="infiniteCredits" data-loc="cheats_infiniteCredits"></label> <label class="form-check-label" for="infiniteCredits" data-loc="cheats_infiniteCredits"></label>
@ -892,6 +824,74 @@
<input class="form-check-input" type="checkbox" id="infiniteHelminthMaterials" /> <input class="form-check-input" type="checkbox" id="infiniteHelminthMaterials" />
<label class="form-check-label" for="infiniteHelminthMaterials" data-loc="cheats_infiniteHelminthMaterials"></label> <label class="form-check-label" for="infiniteHelminthMaterials" data-loc="cheats_infiniteHelminthMaterials"></label>
</div> </div>
<div class="form-check">
<input class="form-check-input" type="checkbox" id="universalPolarityEverywhere" />
<label class="form-check-label" for="universalPolarityEverywhere" data-loc="cheats_universalPolarityEverywhere"></label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" id="unlockDoubleCapacityPotatoesEverywhere" />
<label class="form-check-label" for="unlockDoubleCapacityPotatoesEverywhere" data-loc="cheats_unlockDoubleCapacityPotatoesEverywhere"></label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" id="unlockExilusEverywhere" />
<label class="form-check-label" for="unlockExilusEverywhere" data-loc="cheats_unlockExilusEverywhere"></label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" id="unlockArcanesEverywhere" />
<label class="form-check-label" for="unlockArcanesEverywhere" data-loc="cheats_unlockArcanesEverywhere"></label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" id="syndicateMissionsRepeatable" />
<label class="form-check-label" for="syndicateMissionsRepeatable" data-loc="cheats_syndicateMissionsRepeatable"></label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" id="instantFinishRivenChallenge" />
<label class="form-check-label" for="instantFinishRivenChallenge" data-loc="cheats_instantFinishRivenChallenge"></label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" id="noDailyStandingLimits" />
<label class="form-check-label" for="noDailyStandingLimits" data-loc="cheats_noDailyStandingLimits"></label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" id="noDailyFocusLimit" />
<label class="form-check-label" for="noDailyFocusLimit" data-loc="cheats_noDailyFocusLimit"></label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" id="noArgonCrystalDecay" />
<label class="form-check-label" for="noArgonCrystalDecay" data-loc="cheats_noArgonCrystalDecay"></label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" id="noMasteryRankUpCooldown" />
<label class="form-check-label" for="noMasteryRankUpCooldown" data-loc="cheats_noMasteryRankUpCooldown"></label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" id="noVendorPurchaseLimits" />
<label class="form-check-label" for="noVendorPurchaseLimits" data-loc="cheats_noVendorPurchaseLimits"></label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" id="noDeathMarks" />
<label class="form-check-label" for="noDeathMarks" data-loc="cheats_noDeathMarks"></label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" id="noKimCooldowns" />
<label class="form-check-label" for="noKimCooldowns" data-loc="cheats_noKimCooldowns"></label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" id="noResourceExtractorDronesDamage" />
<label class="form-check-label" for="noResourceExtractorDronesDamage" data-loc="cheats_noResourceExtractorDronesDamage"></label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" id="instantResourceExtractorDrones" />
<label class="form-check-label" for="instantResourceExtractorDrones" data-loc="cheats_instantResourceExtractorDrones"></label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" id="skipClanKeyCrafting" />
<label class="form-check-label" for="skipClanKeyCrafting" data-loc="cheats_skipClanKeyCrafting"></label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" id="claimingBlueprintRefundsIngredients" />
<label class="form-check-label" for="claimingBlueprintRefundsIngredients" data-loc="cheats_claimingBlueprintRefundsIngredients"></label>
</div>
<div class="mt-2 mb-2 d-flex flex-wrap gap-2"> <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>