XFE Git
XFE Studio Git
Git 首页 全局搜索
XFE 主站 文档 NuGet

SpaceNinjaServer

A simple server for a small space ninja game

公开
关注 0 Fork 1 Star 0
返回提交历史

XFEstudio/SpaceNinjaServer

feat(webui): add options to add and remove archon shard upgrades (#437)

afbc1801
Sainan <sainan@calamity.gg>
提交于

代码差异

10 个文件 +333 -59
Modified src/controllers/api/infestedFoundryController.ts +1 -4
@@ -13,10 +13,7 @@ export const infestedFoundryController: RequestHandler = async (req, res) => {
13 13 const request = getJSONfromString(String(req.body)) as IShardInstallRequest;
14 14 const inventory = await getInventory(accountId);
15 15 const suit = inventory.Suits.find(suit => suit._id.toString() == request.SuitId.$oid)!;
16 if (
17 !suit.ArchonCrystalUpgrades ||
18 suit.ArchonCrystalUpgrades.length != 5 // we shouldn't have an array like this, but older inventories may disagree...
19 ) {
16 if (!suit.ArchonCrystalUpgrades || suit.ArchonCrystalUpgrades.length != 5) {
20 17 suit.ArchonCrystalUpgrades = [{}, {}, {}, {}, {}];
21 18 }
22 19 suit.ArchonCrystalUpgrades[request.Slot] = {
Modified src/controllers/custom/getItemListsController.ts +3 -1
@@ -8,6 +8,7 @@ import {
8 8 ExportWarframes,
9 9 ExportWeapons
10 10 } from "warframe-public-export-plus";
11 import archonCrystalUpgrades from "@/static/fixed_responses/webuiArchonCrystalUpgrades.json";
11 12
12 13 interface ListedItem {
13 14 uniqueName: string;
@@ -77,7 +78,8 @@ const getItemListsController: RequestHandler = (_req, res) => {
77 78 weapons,
78 79 miscitems,
79 80 mods,
80 badItems
81 badItems,
82 archonCrystalUpgrades
81 83 });
82 84 };
83 85
Added src/controllers/custom/popArchonCrystalUpgradeController.ts +18 -0
@@ -0,0 +1,18 @@
1 import { RequestHandler } from "express";
2 import { getAccountIdForRequest } from "@/src/services/loginService";
3 import { getInventory } from "@/src/services/inventoryService";
4
5 // eslint-disable-next-line @typescript-eslint/no-misused-promises
6 export const popArchonCrystalUpgradeController: RequestHandler = async (req, res) => {
7 const accountId = await getAccountIdForRequest(req);
8 const inventory = await getInventory(accountId);
9 const suit = inventory.Suits.find(suit => suit._id.toString() == (req.query.oid as string));
10 if (suit && suit.ArchonCrystalUpgrades) {
11 suit.ArchonCrystalUpgrades = suit.ArchonCrystalUpgrades.filter(
12 x => x.UpgradeType != (req.query.type as string)
13 );
14 await inventory.save();
15 res.end();
16 }
17 res.status(400).end();
18 };
Added src/controllers/custom/pushArchonCrystalUpgradeController.ts +20 -0
@@ -0,0 +1,20 @@
1 import { RequestHandler } from "express";
2 import { getAccountIdForRequest } from "@/src/services/loginService";
3 import { getInventory } from "@/src/services/inventoryService";
4
5 // eslint-disable-next-line @typescript-eslint/no-misused-promises
6 export const pushArchonCrystalUpgradeController: RequestHandler = async (req, res) => {
7 const accountId = await getAccountIdForRequest(req);
8 const inventory = await getInventory(accountId);
9 const suit = inventory.Suits.find(suit => suit._id.toString() == (req.query.oid as string));
10 if (suit) {
11 suit.ArchonCrystalUpgrades ??= [];
12 const count = (req.query.count as number | undefined) ?? 1;
13 for (let i = 0; i != count; ++i) {
14 suit.ArchonCrystalUpgrades.push({ UpgradeType: req.query.type as string });
15 }
16 await inventory.save();
17 res.end();
18 }
19 res.status(400).end();
20 };
Modified src/routes/custom.ts +7 -0
@@ -1,13 +1,20 @@
1 1 import express from "express";
2
2 3 import { getItemListsController } from "@/src/controllers/custom/getItemListsController";
4 import { pushArchonCrystalUpgradeController } from "@/src/controllers/custom/pushArchonCrystalUpgradeController";
5 import { popArchonCrystalUpgradeController } from "@/src/controllers/custom/popArchonCrystalUpgradeController";
6
3 7 import { createAccountController } from "@/src/controllers/custom/createAccountController";
4 8 import { addItemController } from "@/src/controllers/custom/addItemController";
9
5 10 import { getConfigDataController } from "@/src/controllers/custom/getConfigDataController";
6 11 import { updateConfigDataController } from "@/src/controllers/custom/updateConfigDataController";
7 12
8 13 const customRouter = express.Router();
9 14
10 15 customRouter.get("/getItemLists", getItemListsController);
16 customRouter.get("/pushArchonCrystalUpgrade", pushArchonCrystalUpgradeController);
17 customRouter.get("/popArchonCrystalUpgrade", popArchonCrystalUpgradeController);
11 18
12 19 customRouter.post("/createAccount", createAccountController);
13 20 customRouter.post("/addItem", addItemController);
Modified src/routes/webui.ts +3 -0
@@ -22,6 +22,9 @@ webuiRouter.use("/webui", (req, res, next) => {
22 22 webuiRouter.get("/webui/inventory", (_req, res) => {
23 23 res.sendFile(path.join(rootDir, "static/webui/index.html"));
24 24 });
25 webuiRouter.get(/webui\/powersuit\/(.+)/, (_req, res) => {
26 res.sendFile(path.join(rootDir, "static/webui/index.html"));
27 });
25 28 webuiRouter.get("/webui/mods", (_req, res) => {
26 29 res.sendFile(path.join(rootDir, "static/webui/index.html"));
27 30 });
Added static/fixed_responses/webuiArchonCrystalUpgrades.json +81 -0
@@ -0,0 +1,81 @@
1 {
2 "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeEquilibrium": "+20% Energy from Health pickups, +20% Health from Energy pickups",
3 "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeEquilibriumMythic": "+30% Energy from Health pickups, +30% Health from Energy pickups",
4 "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeMeleeCritDamage": "+25% Melee Critical Damage",
5 "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeMeleeCritDamageMythic": "+37.5% Melee Critical Damage",
6 "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradePrimaryStatusChance": "+25% Primary Status Chance",
7 "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradePrimaryStatusChanceMythic": "+37.5% Primary Status Chance",
8 "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeSecondaryCritChance": "+25% Secondary Critical Chance",
9 "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeSecondaryCritChanceMythic": "+37.5% Secondary Critical Chance",
10 "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeWarframeAbilityDuration": "+10% Ability Duration",
11 "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeWarframeAbilityDurationMythic": "+15% Ability Duration",
12 "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeWarframeAbilityStrength": "+10% Ability Strength",
13 "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeWarframeAbilityStrengthMythic": "+15% Ability Strength",
14 "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeWarframeArmourMax": "+150 Armor",
15 "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeWarframeArmourMaxMythic": "+225 Armor",
16 "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeWarframeBlastProc": "+5 Shields on inflicting Blast Status",
17 "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeWarframeBlastProcMythic": "+7.5 Shields on inflicting Blast Status",
18 "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeWarframeCastingSpeed": "+25% Casting Speed",
19 "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeWarframeCastingSpeedMythic": "+37.5% Casting Speed",
20 "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeWarframeCorrosiveDamageBoost": "+10% Ability Damage on enemies affected by Corrosion Status",
21 "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeWarframeCorrosiveDamageBoostMythic": "+15% Ability Damage on enemies affected by Corrosion Status",
22 "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeWarframeCorrosiveStack": "Increase max stacks of Corrosion Status by +2",
23 "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeWarframeCorrosiveStackMythic": "Increase max stacks of Corrosion Status by +3",
24 "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeWarframeCritDamageBoost": "+25% Melee Critical Damage (Doubles over 500 Energy)",
25 "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeWarframeCritDamageBoostMythic": "+37% Melee Critical Damage (Doubles over 500 Energy)",
26 "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeWarframeElectricDamage": "+30% Primary Electricity Damage (+10% per additional Shard)",
27 "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeWarframeElectricDamageMythic": "+45% Primary Electricity Damage (+15% per additional Shard)",
28 "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeWarframeElectricDamageBoost": "+10% Ability Damage on enemies affected by Electricity Status",
29 "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeWarframeElectricDamageBoostMythic": "+15% Ability Damage on enemies affected by Electricity Status",
30 "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeWarframeEnergyMax": "+50 Energy Max",
31 "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeWarframeEnergyMaxMythic": "+75 Energy Max",
32 "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeWarframeGlobeEffectEnergy": "+50% Energy Orb Effectiveness",
33 "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeWarframeGlobeEffectEnergyMythic": "+75% Energy Orb Effectiveness",
34 "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeWarframeGlobeEffectHealth": "+100% Health Orb Effectiveness",
35 "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeWarframeGlobeEffectHealthMythic": "+150% Health Orb Effectiveness",
36 "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeWarframeHealthMax": "+150 Health",
37 "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeWarframeHealthMaxMythic": "+225 Health",
38 "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeWarframeHPBoostFromImpact": "+1 Health per enemy killed with Blast Damage (Max 300 Health)",
39 "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeWarframeHPBoostFromImpactMythic": "+2 Health per enemy killed with Blast Damage (Max 450 Health)",
40 "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeWarframeParkourVelocity": "+15% Parkour Velocity",
41 "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeWarframeParkourVelocityMythic": "+22.5% Parkour Velocity",
42 "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeWarframeRadiationDamageBoost": "+10% Ability Damage on enemies affected by Radiation Status",
43 "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeWarframeRadiationDamageBoostMythic": "+15% Ability Damage on enemies affected by Radiation Status",
44 "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeWarframeRegen": "+5 Health Regen/s",
45 "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeWarframeRegenMythic": "+7.5 Health Regen/s",
46 "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeWarframeShieldMax": "+150 Shield",
47 "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeWarframeShieldMaxMythic": "+225 Shield",
48 "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeWarframeStartingEnergy": "+30% Energy on Spawn",
49 "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeWarframeStartingEnergyMythic": "+45% Energy on Spawn",
50 "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeWarframeToxinDamage": "+30% Toxin Status Effect Damage",
51 "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeWarframeToxinDamageMythic": "+45% Toxin Status Effect Damage",
52 "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeWarframeToxinHeal": "+2 Health on damaging enemies with Toxin Status",
53 "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeWarframeToxinHealMythic": "+3 Health on damaging enemies with Toxin Status",
54 "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeWeaponCritBoostFromHeat": "+1% Secondary Critical Chance per Heat-affected enemy killed (Max 50%)",
55 "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeWeaponCritBoostFromHeatMythic": "+1.5% Secondary Critical Chance per Heat-affected enemy killed (Max 75%)",
56
57 "/Lotus/Upgrades/Mods/Warframe/AvatarEnergyRegenMod": "+0.5 Energy Regen/s",
58 "/Lotus/Upgrades/Mods/Warframe/AvatarEnemyRadarMod": "+5m Enemy Radar",
59 "/Lotus/Upgrades/Mods/Warframe/AvatarLootRadarMod": "+7m Loot Radar",
60
61 "/Lotus/Upgrades/Mods/Rifle/WeaponAmmoMaxMod": "+15% Ammo Max",
62
63 "/Lotus/Upgrades/Mods/Aura/EnemyArmorReductionAuraMod": "-3% Enemy Armor",
64
65 "/Lotus/Upgrades/Mods/DataSpike/Assassin/OnExecutionAmmoMod": "100% Primary and Secondary Magazine Refill on Mercy",
66 "/Lotus/Upgrades/Mods/DataSpike/Assassin/OnExecutionHealthDropMod": "100% chance to drop a Health Orb on Mercy",
67 "/Lotus/Upgrades/Mods/DataSpike/Assassin/OnExecutionEnergyDropMod": "50% chance to drop an Energy Orb on Mercy",
68 "/Lotus/Upgrades/Mods/DataSpike/Cipher/OnFailHackResetMod": "+50% to retry on Hacking failure",
69 "/Lotus/Upgrades/Mods/DataSpike/Cipher/DamageReductionOnHackMod": "75% Damage Reduction while Hacking",
70 "/Lotus/Upgrades/Mods/DataSpike/Assassin/OnExecutionReviveCompanionMod": "Mercy Kills reduce Companion Recovery by 15s",
71 "/Lotus/Upgrades/Mods/DataSpike/Assassin/OnExecutionParkourSpeedMod": "+60% Parkour Speed after a Mercy for 15s",
72 "/Lotus/Upgrades/Mods/Warframe/AvatarTimeLimitIncreaseMod": "+8s to Hacking",
73 "/Lotus/Upgrades/Mods/DataSpike/Cipher/ElectrifyOnHackMod": "Shock enemies within 20m while Hacking",
74 "/Lotus/Upgrades/Mods/DataSpike/Assassin/OnExecutionTerrifyMod": "50% chance for enemies within 15m to cower in fear for 8 seconds on Mercy",
75 "/Lotus/Upgrades/Mods/DataSpike/Cipher/OnHackLockersMod": "Unlock 5 lockers within 20m after Hacking",
76 "/Lotus/Upgrades/Mods/DataSpike/Assassin/OnExecutionBlindMod": "Blind enemies within 18m on Mercy",
77 "/Lotus/Upgrades/Mods/DataSpike/Assassin/OnExecutionDrainPowerMod": "100% chance for next ability cast to gain +50% Ability Strength on Mercy",
78 "/Lotus/Upgrades/Mods/DataSpike/Cipher/OnHackSprintSpeedMod": "+75% Sprint Speed for 15s after Hacking",
79 "/Lotus/Upgrades/Mods/DataSpike/Assassin/SwiftExecuteMod": "Speed of Mercy Kills increased by 50%",
80 "/Lotus/Upgrades/Mods/DataSpike/Cipher/OnHackInvisMod": "Invisible for 15 seconds after hacking"
81 }
Modified static/webui/index.html +30 -10
@@ -3,8 +3,8 @@
3 3 <head>
4 4 <title>OpenWF WebUI</title>
5 5 <meta name="viewport" content="width=device-width, initial-scale=1" />
6 <link rel="stylesheet" href="libs/bootstrap.min.css" />
7 <link rel="stylesheet" href="style.css" />
6 <link rel="stylesheet" href="/webui/libs/bootstrap.min.css" />
7 <link rel="stylesheet" href="/webui/style.css" />
8 8 </head>
9 9 <body>
10 10 <nav class="navbar sticky-top bg-body-tertiary">
@@ -63,7 +63,7 @@
63 63 </form>
64 64 </div>
65 65 <div data-route="/webui/inventory" data-title="Inventory | OpenWF WebUI">
66 <p id="refresh-note" class="mb-4">
66 <p class="mb-4">
67 67 Note: Changes made here will only be reflected in-game when the game re-downloads your
68 68 inventory. Visiting the navigation should be the easiest way to trigger that.
69 69 </p>
@@ -106,8 +106,27 @@
106 106 </div>
107 107 </div>
108 108 </div>
109 <div id="powersuit-route" data-route="~ /webui/powersuit/(.+)" data-title="Inventory | OpenWF WebUI">
110 <h3 class="mb-0"></h3>
111 <p class="text-body-secondary"></p>
112 <div class="card mb-4">
113 <h5 class="card-header">Archon Shard Slots</h5>
114 <div class="card-body">
115 <p>You can use these unlimited slots to apply a wide range of upgrades.</p>
116 <form class="input-group mb-3" onsubmit="doPushArchonCrystalUpgrade();return false;">
117 <input type="number" id="archon-crystal-add-count" min="1" value="1" class="form-control" style="max-width:100px" />
118 <span class="input-group-text">x</span>
119 <input class="form-control" list="datalist-archonCrystalUpgrades" />
120 <button class="btn btn-primary" type="submit">Add</button>
121 </form>
122 <table class="table table-hover w-100">
123 <tbody id="crystals-list"></tbody>
124 </table>
125 </div>
126 </div>
127 </div>
109 128 <div data-route="/webui/mods" data-title="Mods | OpenWF WebUI">
110 <p id="refresh-note" class="mb-4">
129 <p class="mb-4">
111 130 Note: Changes made here will only be reflected in-game when the game re-downloads your
112 131 inventory. Visiting the navigation should be the easiest way to trigger that.
113 132 </p>
@@ -259,11 +278,12 @@
259 278 <datalist id="datalist-weapons"></datalist>
260 279 <datalist id="datalist-miscitems"></datalist>
261 280 <datalist id="datalist-mods"></datalist>
262 <script src="libs/jquery-3.6.0.min.js"></script>
263 <script src="libs/whirlpool-js.min.js"></script>
264 <script src="libs/single.js"></script>
265 <script src="riven-tool/RivenParser.js"></script>
266 <script src="script.js"></script>
267 <script src="libs/bootstrap.bundle.min.js"></script>
281 <datalist id="datalist-archonCrystalUpgrades"></datalist>
282 <script src="/webui/libs/jquery-3.6.0.min.js"></script>
283 <script src="/webui/libs/whirlpool-js.min.js"></script>
284 <script src="/webui/libs/single.js"></script>
285 <script src="/webui/riven-tool/RivenParser.js"></script>
286 <script src="/webui/script.js"></script>
287 <script src="/webui/libs/bootstrap.bundle.min.js"></script>
268 288 </body>
269 289 </html>
Modified static/webui/script.js +170 -43
@@ -15,7 +15,6 @@ function loginFromLocalStorage() {
15 15 window.accountId = data.id;
16 16 window.authz = "accountId=" + data.id + "&nonce=" + data.Nonce;
17 17 updateInventory();
18 fetchSettings();
19 18 },
20 19 () => {
21 20 logout();
@@ -88,6 +87,8 @@ single.on("route_load", function (event) {
88 87 window.itemListPromise = new Promise(resolve => {
89 88 const req = $.get("/custom/getItemLists");
90 89 req.done(data => {
90 window.archonCrystalUpgrades = data.archonCrystalUpgrades;
91
91 92 const itemMap = {
92 93 // Generics for rivens
93 94 "/Lotus/Weapons/Tenno/Archwing/Primary/ArchGun": { name: "Archgun" },
@@ -105,7 +106,14 @@ window.itemListPromise = new Promise(resolve => {
105 106 "/Lotus/Upgrades/CosmeticEnhancers/Peculiars/CyoteMod": { name: "Traumatic Peculiar" }
106 107 };
107 108 for (const [type, items] of Object.entries(data)) {
108 if (type != "badItems") {
109 if (type == "archonCrystalUpgrades") {
110 Object.entries(items).forEach(([uniqueName, name]) => {
111 const option = document.createElement("option");
112 option.setAttribute("data-key", uniqueName);
113 option.value = name;
114 document.getElementById("datalist-" + type).appendChild(option);
115 });
116 } else if (type != "badItems") {
109 117 items.forEach(item => {
110 118 if (item.uniqueName in data.badItems) {
111 119 item.name += " (Imposter)";
@@ -127,6 +135,9 @@ function updateInventory() {
127 135 const req = $.get("/api/inventory.php?" + window.authz + "&xpBasedLevelCapDisabled=1");
128 136 req.done(data => {
129 137 window.itemListPromise.then(itemMap => {
138 window.didInitialInventoryUpdate = true;
139
140 // Populate inventory route
130 141 document.getElementById("warframe-list").innerHTML = "";
131 142 data.Suits.forEach(item => {
132 143 const tr = document.createElement("tr");
@@ -152,13 +163,21 @@ function updateInventory() {
152 163 a.innerHTML = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 384 512"><!--!Font Awesome Free 6.5.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons, Inc.--><path d="M214.6 41.4c-12.5-12.5-32.8-12.5-45.3 0l-160 160c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0L160 141.2V448c0 17.7 14.3 32 32 32s32-14.3 32-32V141.2L329.4 246.6c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3l-160-160z"/></svg>`;
153 164 td.appendChild(a);
154 165 }
166 {
167 const a = document.createElement("a");
168 a.href = "/webui/powersuit/" + item.ItemId.$oid;
169 a.innerHTML = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--!Font Awesome Free 6.5.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons, Inc.--><path d="M278.5 215.6L23 471c-9.4 9.4-9.4 24.6 0 33.9s24.6 9.4 33.9 0l57-57h68c49.7 0 97.9-14.4 139-41c11.1-7.2 5.5-23-7.8-23c-5.1 0-9.2-4.1-9.2-9.2c0-4.1 2.7-7.6 6.5-8.8l81-24.3c2.5-.8 4.8-2.1 6.7-4l22.4-22.4c10.1-10.1 2.9-27.3-11.3-27.3l-32.2 0c-5.1 0-9.2-4.1-9.2-9.2c0-4.1 2.7-7.6 6.5-8.8l112-33.6c4-1.2 7.4-3.9 9.3-7.7C506.4 207.6 512 184.1 512 160c0-41-16.3-80.3-45.3-109.3l-5.5-5.5C432.3 16.3 393 0 352 0s-80.3 16.3-109.3 45.3L139 149C91 197 64 262.1 64 330v55.3L253.6 195.8c6.2-6.2 16.4-6.2 22.6 0c5.4 5.4 6.1 13.6 2.2 19.8z"/></svg>`;
170 td.appendChild(a);
171 }
155 172 {
156 173 const a = document.createElement("a");
157 174 a.href = "#";
158 175 a.onclick = function (event) {
159 176 event.preventDefault();
160 177 const name = prompt("Enter new custom name:");
161 renameGear("Suits", item.ItemId.$oid, name);
178 if (name !== null) {
179 renameGear("Suits", item.ItemId.$oid, name);
180 }
162 181 };
163 182 a.title = "Rename";
164 183 a.innerHTML = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--!Font Awesome Free 6.5.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons, Inc.--><path d="M0 80V229.5c0 17 6.7 33.3 18.7 45.3l176 176c25 25 65.5 25 90.5 0L418.7 317.3c25-25 25-65.5 0-90.5l-176-176c-12-12-28.3-18.7-45.3-18.7H48C21.5 32 0 53.5 0 80zm112 32a32 32 0 1 1 0 64 32 32 0 1 1 0-64z"/></svg>`;
@@ -179,7 +198,6 @@ function updateInventory() {
179 198 }
180 199 document.getElementById("warframe-list").appendChild(tr);
181 200 });
182
183 201 document.getElementById("weapon-list").innerHTML = "";
184 202 ["LongGuns", "Pistols", "Melee"].forEach(category => {
185 203 data[category].forEach(item => {
@@ -212,7 +230,9 @@ function updateInventory() {
212 230 a.onclick = function (event) {
213 231 event.preventDefault();
214 232 const name = prompt("Enter new custom name:");
215 renameGear(category, item.ItemId.$oid, name);
233 if (name !== null) {
234 renameGear(category, item.ItemId.$oid, name);
235 }
216 236 };
217 237 a.title = "Rename";
218 238 a.innerHTML = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--!Font Awesome Free 6.5.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons, Inc.--><path d="M0 80V229.5c0 17 6.7 33.3 18.7 45.3l176 176c25 25 65.5 25 90.5 0L418.7 317.3c25-25 25-65.5 0-90.5l-176-176c-12-12-28.3-18.7-45.3-18.7H48C21.5 32 0 53.5 0 80zm112 32a32 32 0 1 1 0 64 32 32 0 1 1 0-64z"/></svg>`;
@@ -235,6 +255,7 @@ function updateInventory() {
235 255 });
236 256 });
237 257
258 // Populate mods route
238 259 document.getElementById("riven-list").innerHTML = "";
239 260 document.getElementById("mods-list").innerHTML = "";
240 261 data.Upgrades.forEach(item => {
@@ -369,6 +390,56 @@ function updateInventory() {
369 390 document.getElementById("mods-list").appendChild(tr);
370 391 }
371 392 });
393
394 // Populate powersuit route
395 if (single.getCurrentPath().substr(0, 17) == "/webui/powersuit/") {
396 const oid = single.getCurrentPath().substr(17);
397 const item = data.Suits.find(x => x.ItemId.$oid == oid);
398 if (item) {
399 if (item.ItemName) {
400 $("#powersuit-route h3").text(item.ItemName);
401 $("#powersuit-route .text-body-secondary").text(itemMap[item.ItemType]?.name ?? item.ItemType);
402 } else {
403 $("#powersuit-route h3").text(itemMap[item.ItemType]?.name ?? item.ItemType);
404 $("#powersuit-route .text-body-secondary").text("");
405 }
406
407 const uniqueUpgrades = {};
408 (item.ArchonCrystalUpgrades ?? []).forEach(upgrade => {
409 uniqueUpgrades[upgrade.UpgradeType] ??= 0;
410 uniqueUpgrades[upgrade.UpgradeType] += 1;
411 });
412
413 document.getElementById("crystals-list").innerHTML = "";
414 Object.entries(uniqueUpgrades).forEach(([upgradeType, count]) => {
415 const tr = document.createElement("tr");
416 {
417 const td = document.createElement("td");
418 td.textContent = count + "x " + (archonCrystalUpgrades[upgradeType] ?? upgradeType);
419 tr.appendChild(td);
420 }
421 {
422 const td = document.createElement("td");
423 td.classList = "text-end";
424 {
425 const a = document.createElement("a");
426 a.href = "#";
427 a.onclick = function (event) {
428 event.preventDefault();
429 doPopArchonCrystalUpgrade(upgradeType);
430 };
431 a.title = "Remove";
432 a.innerHTML = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--!Font Awesome Free 6.5.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons, Inc.--><path d="M135.2 17.7L128 32H32C14.3 32 0 46.3 0 64S14.3 96 32 96H416c17.7 0 32-14.3 32-32s-14.3-32-32-32H320l-7.2-14.3C307.4 6.8 296.3 0 284.2 0H163.8c-12.1 0-23.2 6.8-28.6 17.7zM416 128H32L53.2 467c1.6 25.3 22.6 45 47.9 45H346.9c25.3 0 46.3-19.7 47.9-45L416 128z"/></svg>`;
433 td.appendChild(a);
434 }
435 tr.appendChild(td);
436 }
437 document.getElementById("crystals-list").appendChild(tr);
438 });
439 } else {
440 single.loadRoute("/webui/inventory");
441 }
442 }
372 443 });
373 444 });
374 445 }
@@ -656,26 +727,6 @@ $("#mod-to-acquire").on("input", () => {
656 727 $("#mod-to-acquire").removeClass("is-invalid");
657 728 });
658 729
659 function fetchSettings() {
660 fetch("/custom/config")
661 .then(response => response.json())
662 .then(json =>
663 Object.entries(json).forEach(entry => {
664 const [key, value] = entry;
665 var x = document.getElementById(`${key}`);
666 if (x != null) {
667 if (x.type == "checkbox") {
668 if (value === true) {
669 x.setAttribute("checked", "checked");
670 }
671 } else if (x.type == "number") {
672 x.setAttribute("value", `${value}`);
673 }
674 }
675 })
676 );
677 }
678
679 730 const uiConfigs = [
680 731 "autoCreateAccount",
681 732 "skipStoryModeChoice",
@@ -721,27 +772,52 @@ function doChangeSettings() {
721 772
722 773 // Cheats route
723 774
724 fetch("http://localhost:61558/ping", { mode: "no-cors" }).then(() => {
725 $("#client-cheats-nok").addClass("d-none");
726 $("#client-cheats-ok").removeClass("d-none");
775 single.getRoute("/webui/cheats").on("beforeload", function () {
776 fetch("/custom/config")
777 .then(response => response.json())
778 .then(json =>
779 Object.entries(json).forEach(entry => {
780 const [key, value] = entry;
781 var x = document.getElementById(`${key}`);
782 if (x != null) {
783 if (x.type == "checkbox") {
784 if (value === true) {
785 x.setAttribute("checked", "checked");
786 }
787 } else if (x.type == "number") {
788 x.setAttribute("value", `${value}`);
789 }
790 }
791 })
792 );
793
794 fetch("http://localhost:61558/ping", { mode: "no-cors" })
795 .then(() => {
796 $("#client-cheats-ok").removeClass("d-none");
797 $("#client-cheats-nok").addClass("d-none");
727 798
728 fetch("http://localhost:61558/skip_mission_start_timer")
729 .then(res => res.text())
730 .then(res => {
731 document.getElementById("skip_mission_start_timer").checked = res == "1";
732 });
733 document.getElementById("skip_mission_start_timer").onchange = function () {
734 fetch("http://localhost:61558/skip_mission_start_timer?" + this.checked);
735 };
799 fetch("http://localhost:61558/skip_mission_start_timer")
800 .then(res => res.text())
801 .then(res => {
802 document.getElementById("skip_mission_start_timer").checked = res == "1";
803 });
804 document.getElementById("skip_mission_start_timer").onchange = function () {
805 fetch("http://localhost:61558/skip_mission_start_timer?" + this.checked);
806 };
736 807
737 fetch("http://localhost:61558/fov_override")
738 .then(res => res.text())
739 .then(res => {
740 document.getElementById("fov_override").value = parseFloat(res) * 10000;
808 fetch("http://localhost:61558/fov_override")
809 .then(res => res.text())
810 .then(res => {
811 document.getElementById("fov_override").value = parseFloat(res) * 10000;
812 });
813 document.getElementById("fov_override").oninput = function () {
814 fetch("http://localhost:61558/fov_override?" + this.value);
815 };
816 })
817 .catch(function () {
818 $("#client-cheats-nok").removeClass("d-none");
819 $("#client-cheats-ok").addClass("d-none");
741 820 });
742 document.getElementById("fov_override").oninput = function () {
743 fetch("http://localhost:61558/fov_override?" + this.value);
744 };
745 821 });
746 822
747 823 function doUnlockAllFocusSchools() {
@@ -798,3 +874,54 @@ function unlockFocusSchool(upgradeType) {
798 874 });
799 875 });
800 876 }
877
878 // Powersuit Route
879
880 single.getRoute("#powersuit-route").on("beforeload", function () {
881 this.element.querySelector("h3").textContent = "Loading...";
882 if (window.didInitialInventoryUpdate) {
883 updateInventory();
884 }
885 });
886
887 function doPushArchonCrystalUpgrade() {
888 const uniqueName = getKey(document.querySelector("[list='datalist-archonCrystalUpgrades']"));
889 if (!uniqueName) {
890 $("[list='datalist-archonCrystalUpgrades']").addClass("is-invalid").focus();
891 return;
892 }
893 revalidateAuthz(() => {
894 $.get(
895 "/custom/pushArchonCrystalUpgrade?" +
896 window.authz +
897 "&oid=" +
898 single.getCurrentPath().substr(17) +
899 "&type=" +
900 uniqueName +
901 "&count=" +
902 $("#archon-crystal-add-count").val()
903 ).done(function () {
904 $("[list='datalist-archonCrystalUpgrades']").val("");
905 updateInventory();
906 });
907 });
908 }
909
910 $("[list='datalist-archonCrystalUpgrades']").on("input", () => {
911 $("[list='datalist-archonCrystalUpgrades']").removeClass("is-invalid");
912 });
913
914 function doPopArchonCrystalUpgrade(type) {
915 revalidateAuthz(() => {
916 $.get(
917 "/custom/popArchonCrystalUpgrade?" +
918 window.authz +
919 "&oid=" +
920 single.getCurrentPath().substr(17) +
921 "&type=" +
922 type
923 ).done(function () {
924 updateInventory();
925 });
926 });
927 }
Modified static/webui/style.css +0 -1
@@ -6,7 +6,6 @@
6 6 body.logged-in #sidebar {
7 7 position: sticky;
8 8 top: 5rem;
9 height: 100px;
10 9 margin-right: 3rem;
11 10 }
12 11