返回提交历史
Modified
config-vanilla.json
+0
-3
Modified
src/controllers/api/getShipController.ts
+0
-6
Modified
src/controllers/api/inventoryController.ts
+1
-30
Added
src/controllers/custom/unlockAllCapturaScenesController.ts
+36
-0
Added
src/controllers/custom/unlockAllScansController.ts
+23
-0
Added
src/controllers/custom/unlockAllShipFeaturesController.ts
+19
-0
Modified
src/controllers/stats/viewController.ts
+1
-22
Modified
src/routes/custom.ts
+6
-0
Modified
src/services/configService.ts
+3
-3
Modified
static/webui/index.html
+3
-12
Modified
static/webui/script.js
+18
-0
XFEstudio/SpaceNinjaServer
chore: buttonify unlockAllScans, unlockAllShipFeatures, unlockAllCapturaScenes (#2738)
Re #2361. Mostly done via ChatGPT Codex. Reviewed-on: https://onlyg.it/OpenWF/SpaceNinjaServer/pulls/2738 Co-authored-by: Sainan <63328889+Sainan@users.noreply.github.com> Co-committed-by: Sainan <63328889+Sainan@users.noreply.github.com>
2cfb21b9
代码差异
11 个文件
+110
-76
@@ -10,12 +10,9 @@
10
10
"administratorNames": [],
11
11
"autoCreateAccount": true,
12
12
"skipTutorial": false,
13
"unlockAllScans": false,
14
"unlockAllShipFeatures": false,
15
13
"unlockAllShipDecorations": false,
16
14
"unlockAllFlavourItems": false,
17
15
"unlockAllSkins": false,
18
"unlockAllCapturaScenes": false,
19
16
"fullyStockedVendors": false,
20
17
"skipClanKeyCrafting": false,
21
18
"noDojoRoomBuildStage": false,
@@ -1,6 +1,4 @@
1
1
import type { RequestHandler } from "express";
2
import { config } from "../../services/configService.ts";
3
import allShipFeatures from "../../../static/fixed_responses/allShipFeatures.json" with { type: "json" };
4
2
import { getAccountIdForRequest } from "../../services/loginService.ts";
5
3
import { createGarden, getPersonalRooms } from "../../services/personalRoomsService.ts";
6
4
import type { IGetShipResponse, IPersonalRoomsClient } from "../../types/personalRoomsTypes.ts";
@@ -31,9 +29,5 @@ export const getShipController: RequestHandler = async (req, res) => {
31
29
TailorShop: personalRooms.TailorShop
32
30
};
33
31
34
if (config.unlockAllShipFeatures) {
35
getShipResponse.Ship.Features = allShipFeatures;
36
}
37
38
32
res.json(getShipResponse);
39
33
};
@@ -10,7 +10,7 @@ import { equipmentKeys } from "../../types/inventoryTypes/inventoryTypes.ts";
10
10
import type { IPolarity } from "../../types/inventoryTypes/commonInventoryTypes.ts";
11
11
import { ArtifactPolarity } from "../../types/inventoryTypes/commonInventoryTypes.ts";
12
12
import type { ICountedItem } from "warframe-public-export-plus";
13
import { eFaction, ExportCustoms, ExportFlavour, ExportResources, ExportVirtuals } from "warframe-public-export-plus";
13
import { eFaction, ExportCustoms, ExportFlavour, ExportResources } from "warframe-public-export-plus";
14
14
import { applyCheatsToInfestedFoundry, handleSubsumeCompletion } from "../../services/infestedFoundryService.ts";
15
15
import {
16
16
addEmailItem,
@@ -358,17 +358,6 @@ export const getInventoryResponse = async (
358
358
}
359
359
}
360
360
361
if (config.unlockAllCapturaScenes) {
362
for (const uniqueName of Object.keys(ExportResources)) {
363
if (resourceInheritsFrom(uniqueName, "/Lotus/Types/Items/MiscItems/PhotoboothTile")) {
364
inventoryResponse.MiscItems.push({
365
ItemType: uniqueName,
366
ItemCount: 1
367
});
368
}
369
}
370
}
371
372
361
if (typeof config.spoofMasteryRank === "number" && config.spoofMasteryRank >= 0) {
373
362
inventoryResponse.PlayerLevel = config.spoofMasteryRank;
374
363
if (!xpBasedLevelCapDisabled) {
@@ -495,21 +484,3 @@ const getExpRequiredForMr = (rank: number): number => {
495
484
}
496
485
return 2_250_000 + 147_500 * (rank - 30);
497
486
};
498
499
const resourceInheritsFrom = (resourceName: string, targetName: string): boolean => {
500
let parentName = resourceGetParent(resourceName);
501
for (; parentName != undefined; parentName = resourceGetParent(parentName)) {
502
if (parentName == targetName) {
503
return true;
504
}
505
}
506
return false;
507
};
508
509
const resourceGetParent = (resourceName: string): string | undefined => {
510
if (resourceName in ExportResources) {
511
return ExportResources[resourceName].parentName;
512
}
513
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
514
return ExportVirtuals[resourceName]?.parentName;
515
};
@@ -0,0 +1,36 @@
1
import type { RequestHandler } from "express";
2
import { ExportResources, ExportVirtuals } from "warframe-public-export-plus";
3
import { getAccountIdForRequest } from "../../services/loginService.ts";
4
import { addItem, getInventory } from "../../services/inventoryService.ts";
5
6
export const unlockAllCapturaScenesController: RequestHandler = async (req, res) => {
7
const accountId = await getAccountIdForRequest(req);
8
const inventory = await getInventory(accountId);
9
10
for (const uniqueName of Object.keys(ExportResources)) {
11
if (resourceInheritsFrom(uniqueName, "/Lotus/Types/Items/MiscItems/PhotoboothTile")) {
12
await addItem(inventory, uniqueName, 1);
13
}
14
}
15
16
await inventory.save();
17
res.end();
18
};
19
20
const resourceInheritsFrom = (resourceName: string, targetName: string): boolean => {
21
let parentName = resourceGetParent(resourceName);
22
for (; parentName != undefined; parentName = resourceGetParent(parentName)) {
23
if (parentName == targetName) {
24
return true;
25
}
26
}
27
return false;
28
};
29
30
const resourceGetParent = (resourceName: string): string | undefined => {
31
if (resourceName in ExportResources) {
32
return ExportResources[resourceName].parentName;
33
}
34
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
35
return ExportVirtuals[resourceName]?.parentName;
36
};
@@ -0,0 +1,23 @@
1
import type { RequestHandler } from "express";
2
import allScans from "../../../static/fixed_responses/allScans.json" with { type: "json" };
3
import { ExportEnemies } from "warframe-public-export-plus";
4
import { getAccountIdForRequest } from "../../services/loginService.ts";
5
import { getStats } from "../../services/statsService.ts";
6
7
export const unlockAllScansController: RequestHandler = async (req, res) => {
8
const accountId = await getAccountIdForRequest(req);
9
const stats = await getStats(accountId);
10
11
const scanTypes = new Set<string>(allScans);
12
for (const type of Object.keys(ExportEnemies.avatars)) {
13
scanTypes.add(type);
14
}
15
16
stats.Scans = [];
17
for (const type of scanTypes) {
18
stats.Scans.push({ type, scans: 9999 });
19
}
20
21
await stats.save();
22
res.end();
23
};
@@ -0,0 +1,19 @@
1
import type { RequestHandler } from "express";
2
import allShipFeatures from "../../../static/fixed_responses/allShipFeatures.json" with { type: "json" };
3
import { getAccountIdForRequest } from "../../services/loginService.ts";
4
import { getPersonalRooms } from "../../services/personalRoomsService.ts";
5
6
export const unlockAllShipFeaturesController: RequestHandler = async (req, res) => {
7
const accountId = await getAccountIdForRequest(req);
8
const personalRooms = await getPersonalRooms(accountId);
9
10
const featureSet = new Set(personalRooms.Ship.Features);
11
for (const feature of allShipFeatures) {
12
if (!featureSet.has(feature)) {
13
personalRooms.Ship.Features.push(feature);
14
}
15
}
16
17
await personalRooms.save();
18
res.end();
19
};
@@ -1,8 +1,5 @@
1
1
import type { RequestHandler } from "express";
2
2
import { getAccountIdForRequest } from "../../services/loginService.ts";
3
import { config } from "../../services/configService.ts";
4
import allScans from "../../../static/fixed_responses/allScans.json" with { type: "json" };
5
import { ExportEnemies } from "warframe-public-export-plus";
6
3
import { getInventory } from "../../services/inventoryService.ts";
7
4
import { getStats } from "../../services/statsService.ts";
8
5
import type { IStatsClient } from "../../types/statTypes.ts";
@@ -12,7 +9,7 @@ const viewController: RequestHandler = async (req, res) => {
12
9
const inventory = await getInventory(accountId, "XPInfo");
13
10
const playerStats = await getStats(accountId);
14
11
15
const responseJson = playerStats.toJSON() as IStatsClient;
12
const responseJson = playerStats.toJSON<IStatsClient>();
16
13
responseJson.Weapons ??= [];
17
14
for (const item of inventory.XPInfo) {
18
15
const weaponIndex = responseJson.Weapons.findIndex(element => element.type == item.ItemType);
@@ -22,24 +19,6 @@ const viewController: RequestHandler = async (req, res) => {
22
19
responseJson.Weapons.push({ type: item.ItemType, xp: item.XP });
23
20
}
24
21
}
25
if (config.unlockAllScans) {
26
const scans = new Set(allScans);
27
for (const type of Object.keys(ExportEnemies.avatars)) {
28
if (!scans.has(type)) scans.add(type);
29
}
30
31
// Take any existing scans and also set them to 9999
32
if (responseJson.Scans) {
33
for (const scan of responseJson.Scans) {
34
scans.add(scan.type);
35
}
36
}
37
responseJson.Scans = [];
38
39
for (const type of scans) {
40
responseJson.Scans.push({ type: type, scans: 9999 });
41
}
42
}
43
22
res.json(responseJson);
44
23
};
45
24
@@ -16,6 +16,9 @@ import { completeAllMissionsController } from "../controllers/custom/completeAll
16
16
import { addMissingHelminthBlueprintsController } from "../controllers/custom/addMissingHelminthBlueprintsController.ts";
17
17
import { unlockAllProfitTakerStagesController } from "../controllers/custom/unlockAllProfitTakerStagesController.ts";
18
18
import { unlockAllSimarisResearchEntriesController } from "../controllers/custom/unlockAllSimarisResearchEntriesController.ts";
19
import { unlockAllScansController } from "../controllers/custom/unlockAllScansController.ts";
20
import { unlockAllShipFeaturesController } from "../controllers/custom/unlockAllShipFeaturesController.ts";
21
import { unlockAllCapturaScenesController } from "../controllers/custom/unlockAllCapturaScenesController.ts";
19
22
20
23
import { abilityOverrideController } from "../controllers/custom/abilityOverrideController.ts";
21
24
import { createAccountController } from "../controllers/custom/createAccountController.ts";
@@ -52,6 +55,9 @@ customRouter.get("/completeAllMissions", completeAllMissionsController);
52
55
customRouter.get("/addMissingHelminthBlueprints", addMissingHelminthBlueprintsController);
53
56
customRouter.get("/unlockAllProfitTakerStages", unlockAllProfitTakerStagesController);
54
57
customRouter.get("/unlockAllSimarisResearchEntries", unlockAllSimarisResearchEntriesController);
58
customRouter.get("/unlockAllScans", unlockAllScansController);
59
customRouter.get("/unlockAllShipFeatures", unlockAllShipFeaturesController);
60
customRouter.get("/unlockAllCapturaScenes", unlockAllCapturaScenesController);
55
61
56
62
customRouter.post("/abilityOverride", abilityOverrideController);
57
63
customRouter.post("/createAccount", createAccountController);
@@ -18,12 +18,9 @@ export interface IConfig {
18
18
administratorNames?: string[];
19
19
autoCreateAccount?: boolean;
20
20
skipTutorial?: boolean;
21
unlockAllScans?: boolean;
22
unlockAllShipFeatures?: boolean;
23
21
unlockAllShipDecorations?: boolean;
24
22
unlockAllFlavourItems?: boolean;
25
23
unlockAllSkins?: boolean;
26
unlockAllCapturaScenes?: boolean;
27
24
unlockAllDecoRecipes?: boolean;
28
25
fullyStockedVendors?: boolean;
29
26
skipClanKeyCrafting?: boolean;
@@ -106,6 +103,9 @@ export const configRemovedOptionsKeys = [
106
103
"unlockArcanesEverywhere",
107
104
"unlockAllProfitTakerStages",
108
105
"unlockAllSimarisResearchEntries",
106
"unlockAllScans",
107
"unlockAllShipFeatures",
108
"unlockAllCapturaScenes",
109
109
"noDailyStandingLimits",
110
110
"noDailyFocusLimit",
111
111
"noArgonCrystalDecay",
@@ -808,8 +808,11 @@
808
808
<label class="form-check-label" for="finishInvasionsInOneMission" data-loc="cheats_finishInvasionsInOneMission"></label>
809
809
</div>
810
810
<div class="mt-2 mb-2 d-flex flex-wrap gap-2">
811
<button class="btn btn-primary" onclick="debounce(doUnlockAllShipFeatures);" data-loc="cheats_unlockAllShipFeatures"></button>
811
812
<button class="btn btn-primary" onclick="debounce(unlockAllMissions);" data-loc="cheats_unlockAllMissions"></button>
812
813
<button class="btn btn-primary" onclick="debounce(markAllAsRead);" data-loc="cheats_markAllAsRead"></button>
814
<button class="btn btn-primary" onclick="debounce(doUnlockAllScans);" data-loc="cheats_unlockAllScans"></button>
815
<button class="btn btn-primary" onclick="debounce(doUnlockAllCapturaScenes);" data-loc="cheats_unlockAllCapturaScenes"></button>
813
816
<button class="btn btn-primary" onclick="doUnlockAllFocusSchools();" data-loc="cheats_unlockAllFocusSchools"></button>
814
817
<button class="btn btn-primary" onclick="doHelminthUnlockAll();" data-loc="cheats_helminthUnlockAll"></button>
815
818
<button class="btn btn-primary" onclick="debounce(addMissingHelminthRecipes);" data-loc="cheats_addMissingSubsumedAbilities"></button>
@@ -840,14 +843,6 @@
840
843
<input class="form-check-input" type="checkbox" id="skipTutorial" />
841
844
<label class="form-check-label" for="skipTutorial" data-loc="cheats_skipTutorial"></label>
842
845
</div>
843
<div class="form-check">
844
<input class="form-check-input" type="checkbox" id="unlockAllScans" />
845
<label class="form-check-label" for="unlockAllScans" data-loc="cheats_unlockAllScans"></label>
846
</div>
847
<div class="form-check">
848
<input class="form-check-input" type="checkbox" id="unlockAllShipFeatures" />
849
<label class="form-check-label" for="unlockAllShipFeatures" data-loc="cheats_unlockAllShipFeatures"></label>
850
</div>
851
846
<div class="form-check">
852
847
<input class="form-check-input" type="checkbox" id="unlockAllShipDecorations" />
853
848
<label class="form-check-label" for="unlockAllShipDecorations" data-loc="cheats_unlockAllShipDecorations"></label>
@@ -860,10 +855,6 @@
860
855
<input class="form-check-input" type="checkbox" id="unlockAllSkins" />
861
856
<label class="form-check-label" for="unlockAllSkins" data-loc="cheats_unlockAllSkins"></label>
862
857
</div>
863
<div class="form-check">
864
<input class="form-check-input" type="checkbox" id="unlockAllCapturaScenes" />
865
<label class="form-check-label" for="unlockAllCapturaScenes" data-loc="cheats_unlockAllCapturaScenes"></label>
866
</div>
867
858
<div class="form-check">
868
859
<input class="form-check-input" type="checkbox" id="unlockAllDecoRecipes" />
869
860
<label class="form-check-label" for="unlockAllDecoRecipes" data-loc="cheats_unlockAllDecoRecipes"></label>
@@ -2750,6 +2750,24 @@ async function doMaxPlexus() {
2750
2750
}
2751
2751
}
2752
2752
2753
async function doUnlockAllScans() {
2754
await revalidateAuthz();
2755
await fetch("/custom/unlockAllScans?" + window.authz);
2756
toast(loc("cheats_unlockSucc"));
2757
}
2758
2759
async function doUnlockAllShipFeatures() {
2760
await revalidateAuthz();
2761
await fetch("/custom/unlockAllShipFeatures?" + window.authz);
2762
toast(loc("cheats_unlockSucc"));
2763
}
2764
2765
async function doUnlockAllCapturaScenes() {
2766
await revalidateAuthz();
2767
await fetch("/custom/unlockAllCapturaScenes?" + window.authz);
2768
toast(loc("cheats_unlockSucc"));
2769
}
2770
2753
2771
async function unlockAllMissions() {
2754
2772
await revalidateAuthz();
2755
2773
await fetch("/custom/completeAllMissions?" + window.authz);