Merge remote-tracking branch 'upstream/main' into finishOneInvasionFinishTheWholeThing
All checks were successful
Build / build (pull_request) Successful in 1m14s

This commit is contained in:
AlexisinGit 2025-08-28 23:09:03 +08:00
commit 219f04362b
14 changed files with 108 additions and 80 deletions

View File

@ -5,8 +5,7 @@ RUN apk add --no-cache bash jq
COPY . /app COPY . /app
WORKDIR /app WORKDIR /app
RUN npm i --omit=dev RUN npm i --omit=dev --omit=optional
RUN npm run build
RUN date '+%d %B %Y' > BUILD_DATE RUN date '+%d %B %Y' > BUILD_DATE
ENTRYPOINT ["/app/docker-entrypoint.sh"] ENTRYPOINT ["/app/docker-entrypoint.sh"]

View File

@ -11,7 +11,6 @@
"administratorNames": [], "administratorNames": [],
"autoCreateAccount": true, "autoCreateAccount": true,
"skipTutorial": false, "skipTutorial": false,
"skipAllDialogue": false,
"unlockAllScans": false, "unlockAllScans": false,
"unlockAllShipFeatures": false, "unlockAllShipFeatures": false,
"unlockAllShipDecorations": false, "unlockAllShipDecorations": false,
@ -27,9 +26,7 @@
"noDojoResearchCosts": false, "noDojoResearchCosts": false,
"noDojoResearchTime": false, "noDojoResearchTime": false,
"fastClanAscension": false, "fastClanAscension": false,
"missionsCanGiveAllRelics": false,
"unlockAllSimarisResearchEntries": false, "unlockAllSimarisResearchEntries": false,
"disableDailyTribute": false,
"finishOneInvasionFinishTheWholeThing": false, "finishOneInvasionFinishTheWholeThing": false,
"spoofMasteryRank": -1, "spoofMasteryRank": -1,
"relicRewardItemCountMultiplier": 1, "relicRewardItemCountMultiplier": 1,

View File

@ -5,4 +5,4 @@ if [ ! -f conf/config.json ]; then
jq --arg value "mongodb://openwfagent:spaceninjaserver@mongodb:27017/" '.mongodbUrl = $value' /app/config-vanilla.json > /app/conf/config.json jq --arg value "mongodb://openwfagent:spaceninjaserver@mongodb:27017/" '.mongodbUrl = $value' /app/config-vanilla.json > /app/conf/config.json
fi fi
exec npm run start -- --configPath conf/config.json exec npm run raw -- --configPath conf/config.json

View File

@ -81,7 +81,7 @@ export const crewShipFusionController: RequestHandler = async (req, res) => {
const newFval = (newPerc - rangeA[0]) / (rangeA[1] - rangeA[0]); const newFval = (newPerc - rangeA[0]) / (rangeA[1] - rangeA[0]);
buffA.Value = Math.trunc(newFval * 0x3fffffff); buffA.Value = Math.trunc(newFval * 0x3fffffff);
} }
if (inferiorFingerprint.SubroutineIndex) { if (inferiorFingerprint.SubroutineIndex !== undefined) {
const useSuperiorSubroutine = tierA < tierB ? !payload.UseSubroutineA : payload.UseSubroutineA; const useSuperiorSubroutine = tierA < tierB ? !payload.UseSubroutineA : payload.UseSubroutineA;
if (!useSuperiorSubroutine) { if (!useSuperiorSubroutine) {
fingerprint.SubroutineIndex = inferiorFingerprint.SubroutineIndex; fingerprint.SubroutineIndex = inferiorFingerprint.SubroutineIndex;

View File

@ -306,7 +306,7 @@ export const getInventoryResponse = async (
inventoryResponse.PrimeTokens = 999999999; inventoryResponse.PrimeTokens = 999999999;
} }
if (config.skipAllDialogue) { if (inventory.skipAllDialogue) {
inventoryResponse.TauntHistory = [ inventoryResponse.TauntHistory = [
{ {
node: "TreasureTutorial", node: "TreasureTutorial",

View File

@ -8,7 +8,6 @@ import {
setAccountGotLoginRewardToday setAccountGotLoginRewardToday
} from "../../services/loginRewardService.ts"; } from "../../services/loginRewardService.ts";
import { getInventory } from "../../services/inventoryService.ts"; import { getInventory } from "../../services/inventoryService.ts";
import { config } from "../../services/configService.ts";
import { sendWsBroadcastTo } from "../../services/wsService.ts"; import { sendWsBroadcastTo } from "../../services/wsService.ts";
export const loginRewardsController: RequestHandler = async (req, res) => { export const loginRewardsController: RequestHandler = async (req, res) => {
@ -17,41 +16,42 @@ export const loginRewardsController: RequestHandler = async (req, res) => {
const isMilestoneDay = account.LoginDays == 5 || account.LoginDays % 50 == 0; const isMilestoneDay = account.LoginDays == 5 || account.LoginDays % 50 == 0;
const nextMilestoneDay = account.LoginDays < 5 ? 5 : (Math.trunc(account.LoginDays / 50) + 1) * 50; const nextMilestoneDay = account.LoginDays < 5 ? 5 : (Math.trunc(account.LoginDays / 50) + 1) * 50;
if (today == account.LastLoginRewardDate || config.disableDailyTribute) { if (today != account.LastLoginRewardDate) {
res.json({ const inventory = await getInventory(account._id.toString());
DailyTributeInfo: { if (!inventory.disableDailyTribute) {
IsMilestoneDay: isMilestoneDay, const randomRewards = getRandomLoginRewards(account, inventory);
IsChooseRewardSet: isLoginRewardAChoice(account), const response: ILoginRewardsReponse = {
LoginDays: account.LoginDays, DailyTributeInfo: {
NextMilestoneReward: "", Rewards: randomRewards,
NextMilestoneDay: nextMilestoneDay IsMilestoneDay: isMilestoneDay,
} IsChooseRewardSet: randomRewards.length != 1,
} satisfies ILoginRewardsReponse); LoginDays: account.LoginDays,
return; NextMilestoneReward: "",
} NextMilestoneDay: nextMilestoneDay,
HasChosenReward: false
},
LastLoginRewardDate: today
};
if (!isMilestoneDay && randomRewards.length == 1) {
response.DailyTributeInfo.HasChosenReward = true;
response.DailyTributeInfo.ChosenReward = randomRewards[0];
response.DailyTributeInfo.NewInventory = await claimLoginReward(inventory, randomRewards[0]);
setAccountGotLoginRewardToday(account);
await Promise.all([inventory.save(), account.save()]);
const inventory = await getInventory(account._id.toString()); sendWsBroadcastTo(account._id.toString(), { update_inventory: true });
const randomRewards = getRandomLoginRewards(account, inventory); }
const response: ILoginRewardsReponse = { res.json(response);
return;
}
}
res.json({
DailyTributeInfo: { DailyTributeInfo: {
Rewards: randomRewards,
IsMilestoneDay: isMilestoneDay, IsMilestoneDay: isMilestoneDay,
IsChooseRewardSet: randomRewards.length != 1, IsChooseRewardSet: isLoginRewardAChoice(account),
LoginDays: account.LoginDays, LoginDays: account.LoginDays,
NextMilestoneReward: "", NextMilestoneReward: "",
NextMilestoneDay: nextMilestoneDay, NextMilestoneDay: nextMilestoneDay
HasChosenReward: false }
}, } satisfies ILoginRewardsReponse);
LastLoginRewardDate: today
};
if (!isMilestoneDay && randomRewards.length == 1) {
response.DailyTributeInfo.HasChosenReward = true;
response.DailyTributeInfo.ChosenReward = randomRewards[0];
response.DailyTributeInfo.NewInventory = await claimLoginReward(inventory, randomRewards[0]);
setAccountGotLoginRewardToday(account);
await Promise.all([inventory.save(), account.save()]);
sendWsBroadcastTo(account._id.toString(), { update_inventory: true });
}
res.json(response);
}; };

View File

@ -0,0 +1,16 @@
import { getInventory, updateCurrency } from "../../services/inventoryService.ts";
import { getAccountIdForRequest } from "../../services/loginService.ts";
import type { RequestHandler } from "express";
export const upgradeOperatorController: RequestHandler = async (req, res) => {
const accountId = await getAccountIdForRequest(req);
const inventory = await getInventory(
accountId,
"OperatorCustomizationSlotPurchases PremiumCredits PremiumCreditsFree"
);
inventory.OperatorCustomizationSlotPurchases ??= 0;
inventory.OperatorCustomizationSlotPurchases += 1;
const inventoryChanges = updateCurrency(inventory, 10, true);
await inventory.save();
res.json({ InventoryChanges: inventoryChanges });
};

View File

@ -17,11 +17,11 @@ export const crackRelic = async (
): Promise<IRngResult> => { ): Promise<IRngResult> => {
const relic = ExportRelics[participant.VoidProjection]; const relic = ExportRelics[participant.VoidProjection];
let weights = refinementToWeights[relic.quality]; let weights = refinementToWeights[relic.quality];
if (relic.quality == "VPQ_SILVER" && config.exceptionalRelicsAlwaysGiveBronzeReward) { if (relic.quality == "VPQ_SILVER" && inventory.exceptionalRelicsAlwaysGiveBronzeReward) {
weights = { COMMON: 1, UNCOMMON: 0, RARE: 0, LEGENDARY: 0 }; weights = { COMMON: 1, UNCOMMON: 0, RARE: 0, LEGENDARY: 0 };
} else if (relic.quality == "VPQ_GOLD" && config.flawlessRelicsAlwaysGiveSilverReward) { } else if (relic.quality == "VPQ_GOLD" && inventory.flawlessRelicsAlwaysGiveSilverReward) {
weights = { COMMON: 0, UNCOMMON: 1, RARE: 0, LEGENDARY: 0 }; weights = { COMMON: 0, UNCOMMON: 1, RARE: 0, LEGENDARY: 0 };
} else if (relic.quality == "VPQ_PLATINUM" && config.radiantRelicsAlwaysGiveGoldReward) { } else if (relic.quality == "VPQ_PLATINUM" && inventory.radiantRelicsAlwaysGiveGoldReward) {
weights = { COMMON: 0, UNCOMMON: 0, RARE: 1, LEGENDARY: 0 }; weights = { COMMON: 0, UNCOMMON: 0, RARE: 1, LEGENDARY: 0 };
} }
logger.debug(`opening a relic of quality ${relic.quality}; rarity weights are`, weights); logger.debug(`opening a relic of quality ${relic.quality}; rarity weights are`, weights);

View File

@ -1428,6 +1428,7 @@ const inventorySchema = new Schema<IInventoryDatabase, InventoryDocumentProps>(
accountOwnerId: Schema.Types.ObjectId, accountOwnerId: Schema.Types.ObjectId,
// SNS account cheats // SNS account cheats
skipAllDialogue: Boolean,
dontSubtractPurchaseCreditCost: Boolean, dontSubtractPurchaseCreditCost: Boolean,
dontSubtractPurchasePlatinumCost: Boolean, dontSubtractPurchasePlatinumCost: Boolean,
dontSubtractPurchaseItemCost: Boolean, dontSubtractPurchaseItemCost: Boolean,
@ -1455,6 +1456,11 @@ const inventorySchema = new Schema<IInventoryDatabase, InventoryDocumentProps>(
claimingBlueprintRefundsIngredients: Boolean, claimingBlueprintRefundsIngredients: Boolean,
instantResourceExtractorDrones: Boolean, instantResourceExtractorDrones: Boolean,
noResourceExtractorDronesDamage: Boolean, noResourceExtractorDronesDamage: Boolean,
missionsCanGiveAllRelics: Boolean,
exceptionalRelicsAlwaysGiveBronzeReward: Boolean,
flawlessRelicsAlwaysGiveSilverReward: Boolean,
radiantRelicsAlwaysGiveGoldReward: Boolean,
disableDailyTribute: Boolean,
SubscribedToEmails: { type: Number, default: 0 }, SubscribedToEmails: { type: Number, default: 0 },
SubscribedToEmailsPersonalized: { type: Number, default: 0 }, SubscribedToEmailsPersonalized: { type: Number, default: 0 },
@ -1564,6 +1570,7 @@ const inventorySchema = new Schema<IInventoryDatabase, InventoryDocumentProps>(
OperatorLoadOuts: [operatorConfigSchema], OperatorLoadOuts: [operatorConfigSchema],
//Drifter //Drifter
AdultOperatorLoadOuts: [operatorConfigSchema], AdultOperatorLoadOuts: [operatorConfigSchema],
OperatorCustomizationSlotPurchases: Number,
// Kahl // Kahl
KahlLoadOuts: [operatorConfigSchema], KahlLoadOuts: [operatorConfigSchema],

View File

@ -162,6 +162,7 @@ import { updateQuestController } from "../controllers/api/updateQuestController.
import { updateSessionGetController, updateSessionPostController } from "../controllers/api/updateSessionController.ts"; import { updateSessionGetController, updateSessionPostController } from "../controllers/api/updateSessionController.ts";
import { updateSongChallengeController } from "../controllers/api/updateSongChallengeController.ts"; import { updateSongChallengeController } from "../controllers/api/updateSongChallengeController.ts";
import { updateThemeController } from "../controllers/api/updateThemeController.ts"; import { updateThemeController } from "../controllers/api/updateThemeController.ts";
import { upgradeOperatorController } from "../controllers/api/upgradeOperatorController.ts";
import { upgradesController } from "../controllers/api/upgradesController.ts"; import { upgradesController } from "../controllers/api/upgradesController.ts";
import { valenceSwapController } from "../controllers/api/valenceSwapController.ts"; import { valenceSwapController } from "../controllers/api/valenceSwapController.ts";
import { wishlistController } from "../controllers/api/wishlistController.ts"; import { wishlistController } from "../controllers/api/wishlistController.ts";
@ -229,6 +230,7 @@ apiRouter.get("/startLibraryPersonalTarget.php", startLibraryPersonalTargetContr
apiRouter.get("/surveys.php", surveysController); apiRouter.get("/surveys.php", surveysController);
apiRouter.get("/trading.php", tradingController); apiRouter.get("/trading.php", tradingController);
apiRouter.get("/updateSession.php", updateSessionGetController); apiRouter.get("/updateSession.php", updateSessionGetController);
apiRouter.get("/upgradeOperator.php", upgradeOperatorController);
// post // post
apiRouter.post("/abortDojoComponent.php", abortDojoComponentController); apiRouter.post("/abortDojoComponent.php", abortDojoComponentController);

View File

@ -18,7 +18,6 @@ export interface IConfig extends IConfigRemovedOptions {
administratorNames?: string[]; administratorNames?: string[];
autoCreateAccount?: boolean; autoCreateAccount?: boolean;
skipTutorial?: boolean; skipTutorial?: boolean;
skipAllDialogue?: boolean;
unlockAllScans?: boolean; unlockAllScans?: boolean;
unlockAllShipFeatures?: boolean; unlockAllShipFeatures?: boolean;
unlockAllShipDecorations?: boolean; unlockAllShipDecorations?: boolean;
@ -35,12 +34,7 @@ export interface IConfig extends IConfigRemovedOptions {
noDojoResearchCosts?: boolean; noDojoResearchCosts?: boolean;
noDojoResearchTime?: boolean; noDojoResearchTime?: boolean;
fastClanAscension?: boolean; fastClanAscension?: boolean;
missionsCanGiveAllRelics?: boolean;
exceptionalRelicsAlwaysGiveBronzeReward?: boolean;
flawlessRelicsAlwaysGiveSilverReward?: boolean;
radiantRelicsAlwaysGiveGoldReward?: boolean;
unlockAllSimarisResearchEntries?: boolean; unlockAllSimarisResearchEntries?: boolean;
disableDailyTribute?: boolean;
finishOneInvasionFinishTheWholeThing?: boolean; finishOneInvasionFinishTheWholeThing?: boolean;
spoofMasteryRank?: number; spoofMasteryRank?: number;
relicRewardItemCountMultiplier?: number; relicRewardItemCountMultiplier?: number;
@ -95,6 +89,7 @@ export interface IConfig extends IConfigRemovedOptions {
} }
export const configRemovedOptionsKeys = [ export const configRemovedOptionsKeys = [
"skipAllDialogue",
"infiniteCredits", "infiniteCredits",
"infinitePlatinum", "infinitePlatinum",
"infiniteEndo", "infiniteEndo",
@ -123,7 +118,12 @@ export const configRemovedOptionsKeys = [
"instantResourceExtractorDrones", "instantResourceExtractorDrones",
"noResourceExtractorDronesDamage", "noResourceExtractorDronesDamage",
"baroAlwaysAvailable", "baroAlwaysAvailable",
"baroFullyStocked" "baroFullyStocked",
"missionsCanGiveAllRelics",
"exceptionalRelicsAlwaysGiveBronzeReward",
"flawlessRelicsAlwaysGiveSilverReward",
"radiantRelicsAlwaysGiveGoldReward",
"disableDailyTribute"
] as const; ] as const;
type IConfigRemovedOptions = { type IConfigRemovedOptions = {

View File

@ -2202,7 +2202,7 @@ function getRandomMissionDrops(
} }
} }
if (config.missionsCanGiveAllRelics) { if (inventory.missionsCanGiveAllRelics) {
for (const drop of drops) { for (const drop of drops) {
const itemType = fromStoreItem(drop.StoreItem); const itemType = fromStoreItem(drop.StoreItem);
if (itemType in ExportRelics) { if (itemType in ExportRelics) {

View File

@ -21,6 +21,7 @@ export type InventoryDatabaseEquipment = {
// Fields specific to SNS // Fields specific to SNS
export interface IAccountCheats { export interface IAccountCheats {
skipAllDialogue?: boolean;
dontSubtractPurchaseCreditCost?: boolean; dontSubtractPurchaseCreditCost?: boolean;
dontSubtractPurchasePlatinumCost?: boolean; dontSubtractPurchasePlatinumCost?: boolean;
dontSubtractPurchaseItemCost?: boolean; dontSubtractPurchaseItemCost?: boolean;
@ -48,6 +49,11 @@ export interface IAccountCheats {
claimingBlueprintRefundsIngredients?: boolean; claimingBlueprintRefundsIngredients?: boolean;
instantResourceExtractorDrones?: boolean; instantResourceExtractorDrones?: boolean;
noResourceExtractorDronesDamage?: boolean; noResourceExtractorDronesDamage?: boolean;
missionsCanGiveAllRelics?: boolean;
exceptionalRelicsAlwaysGiveBronzeReward?: boolean;
flawlessRelicsAlwaysGiveSilverReward?: boolean;
radiantRelicsAlwaysGiveGoldReward?: boolean;
disableDailyTribute?: boolean;
} }
export interface IInventoryDatabase export interface IInventoryDatabase
@ -374,6 +380,7 @@ export interface IInventoryClient extends IDailyAffiliations, InventoryClientEqu
CrewMembers: ICrewMemberClient[]; CrewMembers: ICrewMemberClient[];
LotusCustomization?: ILotusCustomization; LotusCustomization?: ILotusCustomization;
UseAdultOperatorLoadout?: boolean; UseAdultOperatorLoadout?: boolean;
OperatorCustomizationSlotPurchases?: number;
NemesisAbandonedRewards: string[]; NemesisAbandonedRewards: string[];
LastInventorySync?: IOid; LastInventorySync?: IOid;
NextRefill?: IMongoDate; NextRefill?: IMongoDate;

View File

@ -647,6 +647,10 @@
<div class="card"> <div class="card">
<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="skipAllDialogue" />
<label class="form-check-label" for="skipAllDialogue" data-loc="cheats_skipAllDialogue"></label>
</div>
<div class="form-check"> <div class="form-check">
<input class="form-check-input" type="checkbox" id="dontSubtractPurchaseCreditCost" /> <input class="form-check-input" type="checkbox" id="dontSubtractPurchaseCreditCost" />
<label class="form-check-label" for="dontSubtractPurchaseCreditCost" data-loc="cheats_dontSubtractPurchaseCreditCost"></label> <label class="form-check-label" for="dontSubtractPurchaseCreditCost" data-loc="cheats_dontSubtractPurchaseCreditCost"></label>
@ -754,6 +758,30 @@
<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>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" id="missionsCanGiveAllRelics" />
<label class="form-check-label" for="missionsCanGiveAllRelics" data-loc="cheats_missionsCanGiveAllRelics"></label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" id="exceptionalRelicsAlwaysGiveBronzeReward" />
<label class="form-check-label" for="exceptionalRelicsAlwaysGiveBronzeReward" data-loc="cheats_exceptionalRelicsAlwaysGiveBronzeReward"></label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" id="flawlessRelicsAlwaysGiveSilverReward" />
<label class="form-check-label" for="flawlessRelicsAlwaysGiveSilverReward" data-loc="cheats_flawlessRelicsAlwaysGiveSilverReward"></label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" id="radiantRelicsAlwaysGiveGoldReward" />
<label class="form-check-label" for="radiantRelicsAlwaysGiveGoldReward" data-loc="cheats_radiantRelicsAlwaysGiveGoldReward"></label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" id="unlockAllSimarisResearchEntries" />
<label class="form-check-label" for="unlockAllSimarisResearchEntries" data-loc="cheats_unlockAllSimarisResearchEntries"></label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" id="disableDailyTribute" />
<label class="form-check-label" for="disableDailyTribute" data-loc="cheats_disableDailyTribute"></label>
</div> </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>
@ -786,10 +814,6 @@
<input class="form-check-input" type="checkbox" id="skipTutorial" /> <input class="form-check-input" type="checkbox" id="skipTutorial" />
<label class="form-check-label" for="skipTutorial" data-loc="cheats_skipTutorial"></label> <label class="form-check-label" for="skipTutorial" data-loc="cheats_skipTutorial"></label>
</div> </div>
<div class="form-check">
<input class="form-check-input" type="checkbox" id="skipAllDialogue" />
<label class="form-check-label" for="skipAllDialogue" data-loc="cheats_skipAllDialogue"></label>
</div>
<div class="form-check"> <div class="form-check">
<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>
@ -854,30 +878,6 @@
<input class="form-check-input" type="checkbox" id="fastClanAscension" /> <input class="form-check-input" type="checkbox" id="fastClanAscension" />
<label class="form-check-label" for="fastClanAscension" data-loc="cheats_fastClanAscension"></label> <label class="form-check-label" for="fastClanAscension" data-loc="cheats_fastClanAscension"></label>
</div> </div>
<div class="form-check">
<input class="form-check-input" type="checkbox" id="missionsCanGiveAllRelics" />
<label class="form-check-label" for="missionsCanGiveAllRelics" data-loc="cheats_missionsCanGiveAllRelics"></label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" id="exceptionalRelicsAlwaysGiveBronzeReward" />
<label class="form-check-label" for="exceptionalRelicsAlwaysGiveBronzeReward" data-loc="cheats_exceptionalRelicsAlwaysGiveBronzeReward"></label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" id="flawlessRelicsAlwaysGiveSilverReward" />
<label class="form-check-label" for="flawlessRelicsAlwaysGiveSilverReward" data-loc="cheats_flawlessRelicsAlwaysGiveSilverReward"></label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" id="radiantRelicsAlwaysGiveGoldReward" />
<label class="form-check-label" for="radiantRelicsAlwaysGiveGoldReward" data-loc="cheats_radiantRelicsAlwaysGiveGoldReward"></label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" id="unlockAllSimarisResearchEntries" />
<label class="form-check-label" for="unlockAllSimarisResearchEntries" data-loc="cheats_unlockAllSimarisResearchEntries"></label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" id="disableDailyTribute" />
<label class="form-check-label" for="disableDailyTribute" data-loc="cheats_disableDailyTribute"></label>
</div>
<div class="form-check"> <div class="form-check">
<input class="form-check-input" type="checkbox" id="finishOneInvasionFinishTheWholeThing" /> <input class="form-check-input" type="checkbox" id="finishOneInvasionFinishTheWholeThing" />
<label class="form-check-label" for="finishOneInvasionFinishTheWholeThing" data-loc="cheats_finishOneInvasionFinishTheWholeThing"></label> <label class="form-check-label" for="finishOneInvasionFinishTheWholeThing" data-loc="cheats_finishOneInvasionFinishTheWholeThing"></label>