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

XFESpaceNinjaServer

A simple server for a small space ninja game

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

XFEstudio/XFESpaceNinjaServer

feat(webui): adding modular K-Drives, Amps and Zaw (#1374)

Reviewed-on: https://onlyg.it/OpenWF/SpaceNinjaServer/pulls/1374 Co-authored-by: AMelonInsideLemon <166175391+AMelonInsideLemon@users.noreply.github.com> Co-committed-by: AMelonInsideLemon <166175391+AMelonInsideLemon@users.noreply.github.com>

4cb883da
AMelonInsideLemon <166175391+AMelonInsideLemon@users.noreply.github.com>
提交于

代码差异

10 个文件 +193 -15
Added src/controllers/custom/addModularEquipmentController.ts +21 -0
@@ -0,0 +1,21 @@
1 import { getAccountIdForRequest } from "@/src/services/loginService";
2 import { getInventory, addEquipment, occupySlot, productCategoryToInventoryBin } from "@/src/services/inventoryService";
3 import { RequestHandler } from "express";
4 import { modularWeaponTypes } from "@/src/helpers/modularWeaponHelper";
5
6 export const addModularEquipmentController: RequestHandler = async (req, res) => {
7 const accountId = await getAccountIdForRequest(req);
8 const request = req.body as IAddModularEquipmentRequest;
9 const category = modularWeaponTypes[request.ItemType];
10 const inventoryBin = productCategoryToInventoryBin(category)!;
11 const inventory = await getInventory(accountId, `${category} ${inventoryBin}`);
12 addEquipment(inventory, category, request.ItemType, request.ModularParts);
13 occupySlot(inventory, inventoryBin, true);
14 await inventory.save();
15 res.end();
16 };
17
18 interface IAddModularEquipmentRequest {
19 ItemType: string;
20 ModularParts: string[];
21 }
Modified src/controllers/custom/getItemListsController.ts +6 -2
@@ -25,6 +25,7 @@ interface ListedItem {
25 25 fusionLimit?: number;
26 26 exalted?: string[];
27 27 badReason?: "starter" | "frivolous" | "notraw";
28 partType?: string;
28 29 }
29 30
30 31 const relicQualitySuffixes: Record<TRelicQuality, string> = {
@@ -50,6 +51,7 @@ const getItemListsController: RequestHandler = (req, response) => {
50 51 res.MechSuits = [];
51 52 res.miscitems = [];
52 53 res.Syndicates = [];
54 res.OperatorAmps = [];
53 55 for (const [uniqueName, item] of Object.entries(ExportWarframes)) {
54 56 res[item.productCategory].push({
55 57 uniqueName,
@@ -79,7 +81,8 @@ const getItemListsController: RequestHandler = (req, response) => {
79 81 ) {
80 82 res.ModularParts.push({
81 83 uniqueName,
82 name: getString(item.name, lang)
84 name: getString(item.name, lang),
85 partType: item.partType
83 86 });
84 87 if (uniqueName.split("/")[5] != "SentTrainingAmplifier") {
85 88 res.miscitems.push({
@@ -94,7 +97,8 @@ const getItemListsController: RequestHandler = (req, response) => {
94 97 item.productCategory == "Melee" ||
95 98 item.productCategory == "SpaceGuns" ||
96 99 item.productCategory == "SpaceMelee" ||
97 item.productCategory == "SentinelWeapons"
100 item.productCategory == "SentinelWeapons" ||
101 item.productCategory == "OperatorAmps"
98 102 ) {
99 103 res[item.productCategory].push({
100 104 uniqueName,
Modified src/routes/custom.ts +3 -1
@@ -13,8 +13,9 @@ import { unlockAllIntrinsicsController } from "@/src/controllers/custom/unlockAl
13 13
14 14 import { createAccountController } from "@/src/controllers/custom/createAccountController";
15 15 import { createMessageController } from "@/src/controllers/custom/createMessageController";
16 import { addCurrencyController } from "../controllers/custom/addCurrencyController";
16 import { addCurrencyController } from "@/src/controllers/custom/addCurrencyController";
17 17 import { addItemsController } from "@/src/controllers/custom/addItemsController";
18 import { addModularEquipmentController } from "@/src/controllers/custom/addModularEquipmentController";
18 19 import { addXpController } from "@/src/controllers/custom/addXpController";
19 20 import { importController } from "@/src/controllers/custom/importController";
20 21
@@ -39,6 +40,7 @@ customRouter.post("/createAccount", createAccountController);
39 40 customRouter.post("/createMessage", createMessageController);
40 41 customRouter.post("/addCurrency", addCurrencyController);
41 42 customRouter.post("/addItems", addItemsController);
43 customRouter.post("/addModularEquipment", addModularEquipmentController);
42 44 customRouter.post("/addXp", addXpController);
43 45 customRouter.post("/import", importController);
44 46 customRouter.post("/manageQuests", manageQuestsController);
Modified static/webui/index.html +34 -2
@@ -193,10 +193,15 @@
193 193 <div class="card mb-3" style="height: 400px;">
194 194 <h5 class="card-header" data-loc="inventory_melee"></h5>
195 195 <div class="card-body overflow-auto">
196 <form class="input-group mb-3" onsubmit="doAcquireEquipment('Melee');return false;">
196 <form class="input-group mb-3" onsubmit="handleModularSelection('Melee');return false;">
197 197 <input class="form-control" id="acquire-type-Melee" list="datalist-Melee" />
198 198 <button class="btn btn-primary" type="submit" data-loc="general_addButton"></button>
199 199 </form>
200 <form class="input-group mb-3" id="modular-Melee" style="display: none;">
201 <input class="form-control" id="acquire-type-Melee-BLADE" list="datalist-ModularParts-BLADE" />
202 <input class="form-control" id="acquire-type-Melee-HILT" list="datalist-ModularParts-HILT" />
203 <input class="form-control" id="acquire-type-Melee-HILT_WEIGHT" list="datalist-ModularParts-HILT_WEIGHT" />
204 </form>
200 205 <table class="table table-hover w-100">
201 206 <tbody id="Melee-list"></tbody>
202 207 </table>
@@ -299,6 +304,15 @@
299 304 <div class="card mb-3" style="height: 400px;">
300 305 <h5 class="card-header" data-loc="inventory_operatorAmps"></h5>
301 306 <div class="card-body overflow-auto">
307 <form class="input-group mb-3" onsubmit="handleModularSelection('OperatorAmps');return false;">
308 <input class="form-control" id="acquire-type-OperatorAmps" list="datalist-OperatorAmps" />
309 <button class="btn btn-primary" type="submit" data-loc="general_addButton"></button>
310 </form>
311 <form class="input-group mb-3" id="modular-OperatorAmps" style="display: none;">
312 <input class="form-control" id="acquire-type-OperatorAmps-AMP_OCULUS" list="datalist-ModularParts-AMP_OCULUS" />
313 <input class="form-control" id="acquire-type-OperatorAmps-AMP_CORE" list="datalist-ModularParts-AMP_CORE" />
314 <input class="form-control" id="acquire-type-OperatorAmps-AMP_BRACE" list="datalist-ModularParts-AMP_BRACE" />
315 </form>
302 316 <table class="table table-hover w-100">
303 317 <tbody id="OperatorAmps-list"></tbody>
304 318 </table>
@@ -309,6 +323,13 @@
309 323 <div class="card mb-3" style="height: 400px;">
310 324 <h5 class="card-header" data-loc="inventory_hoverboards"></h5>
311 325 <div class="card-body overflow-auto">
326 <form class="input-group mb-3" onsubmit="doAcquireModularEquipment('HoverBoards');return false;">
327 <input class="form-control" id="acquire-type-HoverBoards-HB_DECK" list="datalist-ModularParts-HB_DECK" />
328 <input class="form-control" id="acquire-type-HoverBoards-HB_ENGINE" list="datalist-ModularParts-HB_ENGINE" />
329 <input class="form-control" id="acquire-type-HoverBoards-HB_FRONT" list="datalist-ModularParts-HB_FRONT" />
330 <input class="form-control" id="acquire-type-HoverBoards-HB_JET" list="datalist-ModularParts-HB_JET" />
331 <button class="btn btn-primary" type="submit" data-loc="general_addButton"></button>
332 </form>
312 333 <table class="table table-hover w-100">
313 334 <tbody id="Hoverboards-list"></tbody>
314 335 </table>
@@ -604,7 +625,6 @@
604 625 <datalist id="datalist-SpaceMelee"></datalist>
605 626 <datalist id="datalist-SentinelWeapons"></datalist>
606 627 <datalist id="datalist-Sentinels"></datalist>
607 <datalist id="datalist-ModularParts"></datalist>
608 628 <datalist id="datalist-MechSuits"></datalist>
609 629 <datalist id="datalist-Syndicates"></datalist>
610 630 <datalist id="datalist-miscitems"></datalist>
@@ -613,6 +633,18 @@
613 633 <option data-key="/Lotus/Upgrades/CosmeticEnhancers/Peculiars/CyoteMod" value="Traumatic Peculiar"></option>
614 634 </datalist>
615 635 <datalist id="datalist-archonCrystalUpgrades"></datalist>
636 <datalist id="datalist-OperatorAmps"></datalist>
637 <datalist id="datalist-ModularParts"></datalist>
638 <datalist id="datalist-ModularParts-HB_DECK"></datalist>
639 <datalist id="datalist-ModularParts-HB_ENGINE"></datalist>
640 <datalist id="datalist-ModularParts-HB_FRONT"></datalist>
641 <datalist id="datalist-ModularParts-HB_JET"></datalist>
642 <datalist id="datalist-ModularParts-AMP_OCULUS"></datalist>
643 <datalist id="datalist-ModularParts-AMP_CORE"></datalist>
644 <datalist id="datalist-ModularParts-AMP_BRACE"></datalist>
645 <datalist id="datalist-ModularParts-BLADE"></datalist>
646 <datalist id="datalist-ModularParts-HILT"></datalist>
647 <datalist id="datalist-ModularParts-HILT_WEIGHT"></datalist>
616 648 <script src="/webui/libs/jquery-3.6.0.min.js"></script>
617 649 <script src="/webui/libs/whirlpool-js.min.js"></script>
618 650 <script src="/webui/libs/single.js"></script>
Modified static/webui/script.js +129 -5
@@ -185,6 +185,16 @@ function fetchItemList() {
185 185 name: loc("code_traumaticPeculiar")
186 186 });
187 187
188 // Add modular weapons
189 data.OperatorAmps.push({
190 uniqueName: "/Lotus/Weapons/Sentients/OperatorAmplifiers/OperatorAmpWeapon",
191 name: loc("code_amp")
192 });
193 data.Melee.push({
194 uniqueName: "/Lotus/Weapons/Ostron/Melee/LotusModularWeapon",
195 name: loc("code_zaw")
196 });
197
188 198 const itemMap = {
189 199 // Generics for rivens
190 200 "/Lotus/Weapons/Tenno/Archwing/Primary/ArchGun": { name: loc("code_archgun") },
@@ -201,14 +211,9 @@ function fetchItemList() {
201 211 "/Lotus/Weapons/SolarisUnited/Secondary/LotusModularSecondary": { name: loc("code_kitgun") },
202 212 "/Lotus/Weapons/SolarisUnited/Secondary/LotusModularSecondaryBeam": { name: loc("code_kitgun") },
203 213 "/Lotus/Weapons/SolarisUnited/Secondary/LotusModularSecondaryShotgun": { name: loc("code_kitgun") },
204 "/Lotus/Weapons/Ostron/Melee/LotusModularWeapon": { name: loc("code_zaw") },
205 214 "/Lotus/Weapons/Sentients/OperatorAmplifiers/SentTrainingAmplifier/OperatorTrainingAmpWeapon": {
206 215 name: loc("code_moteAmp")
207 216 },
208 "/Lotus/Weapons/Sentients/OperatorAmplifiers/OperatorAmpWeapon": { name: loc("code_amp") },
209 "/Lotus/Weapons/Operator/Pistols/DrifterPistol/DrifterPistolPlayerWeapon": {
210 name: loc("code_sirocco")
211 },
212 217 "/Lotus/Types/Vehicles/Hoverboard/HoverboardSuit": { name: loc("code_kDrive") }
213 218 };
214 219 for (const [type, items] of Object.entries(data)) {
@@ -233,6 +238,33 @@ function fetchItemList() {
233 238 if (type == "Syndicates" && item.uniqueName.startsWith("RadioLegion")) {
234 239 item.name += " (" + item.uniqueName + ")";
235 240 }
241 if (type == "ModularParts") {
242 const supportedModularParts = [
243 "LWPT_HB_DECK",
244 "LWPT_HB_ENGINE",
245 "LWPT_HB_FRONT",
246 "LWPT_HB_JET",
247 "LWPT_AMP_OCULUS",
248 "LWPT_AMP_CORE",
249 "LWPT_AMP_BRACE",
250 "LWPT_BLADE",
251 "LWPT_HILT",
252 "LWPT_HILT_WEIGHT"
253 ];
254 if (supportedModularParts.includes(item.partType)) {
255 const option = document.createElement("option");
256 option.setAttribute("data-key", item.uniqueName);
257 option.value = item.name;
258 document
259 .getElementById("datalist-" + type + "-" + item.partType.slice(5))
260 .appendChild(option);
261 } else {
262 const option = document.createElement("option");
263 option.setAttribute("data-key", item.uniqueName);
264 option.value = item.name;
265 document.getElementById("datalist-" + type).appendChild(option);
266 }
267 }
236 268 if (item.badReason != "notraw") {
237 269 const option = document.createElement("option");
238 270 option.setAttribute("data-key", item.uniqueName);
@@ -622,6 +654,67 @@ function doAcquireEquipment(category) {
622 654 });
623 655 }
624 656
657 function doAcquireModularEquipment(category, ItemType) {
658 let requiredParts;
659 let ModularParts = [];
660 switch (category) {
661 case "HoverBoards":
662 ItemType = "/Lotus/Types/Vehicles/Hoverboard/HoverboardSuit";
663 requiredParts = ["HB_DECK", "HB_ENGINE", "HB_FRONT", "HB_JET"];
664 break;
665 case "OperatorAmps":
666 requiredParts = ["AMP_OCULUS", "AMP_CORE", "AMP_BRACE"];
667 break;
668 case "Melee":
669 requiredParts = ["BLADE", "HILT", "HILT_WEIGHT"];
670 break;
671 }
672 requiredParts.forEach(part => {
673 const partName = getKey(document.getElementById("acquire-type-" + category + "-" + part));
674 if (partName) {
675 ModularParts.push(partName);
676 }
677 });
678 if (ModularParts.length != requiredParts.length) {
679 let isFirstPart = true;
680 requiredParts.forEach(part => {
681 const partSelector = document.getElementById("acquire-type-" + category + "-" + part);
682 if (!getKey(partSelector)) {
683 if (isFirstPart) {
684 isFirstPart = false;
685 $("#acquire-type-" + category + "-" + part)
686 .addClass("is-invalid")
687 .focus();
688 } else {
689 $("#acquire-type-" + category + "-" + part).addClass("is-invalid");
690 }
691 }
692 });
693 } else {
694 revalidateAuthz(() => {
695 const req = $.post({
696 url: "/custom/addModularEquipment?" + window.authz,
697 contentType: "application/json",
698 data: JSON.stringify({
699 ItemType,
700 ModularParts
701 })
702 });
703 req.done(() => {
704 const mainInput = document.getElementById("acquire-type-" + category);
705 if (mainInput) {
706 mainInput.value = "";
707 document.getElementById("modular-" + category).style.display = "none";
708 }
709 requiredParts.forEach(part => {
710 document.getElementById("acquire-type-" + category + "-" + part).value = "";
711 });
712 updateInventory();
713 });
714 });
715 }
716 }
717
625 718 $("input[list]").on("input", function () {
626 719 $(this).removeClass("is-invalid");
627 720 });
@@ -1220,3 +1313,34 @@ function toast(text) {
1220 1313 toast.appendChild(div);
1221 1314 new bootstrap.Toast(document.querySelector(".toast-container").appendChild(toast)).show();
1222 1315 }
1316
1317 function handleModularSelection(category) {
1318 const modularWeapons = [
1319 "/Lotus/Weapons/Sentients/OperatorAmplifiers/OperatorAmpWeapon",
1320 "/Lotus/Weapons/Ostron/Melee/LotusModularWeapon"
1321 ];
1322 const itemType = getKey(document.getElementById("acquire-type-" + category));
1323
1324 if (modularWeapons.includes(itemType)) {
1325 doAcquireModularEquipment(category, itemType);
1326 } else {
1327 doAcquireEquipment(category);
1328 }
1329 }
1330 {
1331 const modularWeapons = [
1332 "/Lotus/Weapons/Sentients/OperatorAmplifiers/OperatorAmpWeapon",
1333 "/Lotus/Weapons/Ostron/Melee/LotusModularWeapon"
1334 ];
1335 const supportedModularInventoryCategory = ["OperatorAmps", "Melee"];
1336 supportedModularInventoryCategory.forEach(inventoryCategory => {
1337 document.getElementById("acquire-type-" + inventoryCategory).addEventListener("input", function () {
1338 const modularFields = document.getElementById("modular-" + inventoryCategory);
1339 if (modularWeapons.includes(getKey(this))) {
1340 modularFields.style.display = "";
1341 } else {
1342 modularFields.style.display = "none";
1343 }
1344 });
1345 });
1346 }
Modified static/webui/translations/de.js +0 -1
@@ -15,7 +15,6 @@ dict = {
15 15 code_zaw: `Zaw`,
16 16 code_moteAmp: `Anfangsverstärker`,
17 17 code_amp: `Verstärker`,
18 code_sirocco: `Sirocco`,
19 18 code_kDrive: `K-Drive`,
20 19 code_legendaryCore: `Legendärer Kern`,
21 20 code_traumaticPeculiar: `Kuriose Mod: Traumatisch`,
Modified static/webui/translations/en.js +0 -1
@@ -14,7 +14,6 @@ dict = {
14 14 code_zaw: `Zaw`,
15 15 code_moteAmp: `Mote Amp`,
16 16 code_amp: `Amp`,
17 code_sirocco: `Sirocco`,
18 17 code_kDrive: `K-Drive`,
19 18 code_legendaryCore: `Legendary Core`,
20 19 code_traumaticPeculiar: `Traumatic Peculiar`,
Modified static/webui/translations/fr.js +0 -1
@@ -15,7 +15,6 @@ dict = {
15 15 code_zaw: `Zaw`,
16 16 code_moteAmp: `Amplificateur Faible`,
17 17 code_amp: `Amplificateur`,
18 code_sirocco: `Sirocco`,
19 18 code_kDrive: `K-Drive`,
20 19 code_legendaryCore: `Coeur Légendaire`,
21 20 code_traumaticPeculiar: `Traumatisme Atypique`,
Modified static/webui/translations/ru.js +0 -1
@@ -15,7 +15,6 @@ dict = {
15 15 code_zaw: `Зо`,
16 16 code_moteAmp: `Пылинка`,
17 17 code_amp: `Усилитель`,
18 code_sirocco: `Сирокко`,
19 18 code_kDrive: `К-Драйв`,
20 19 code_legendaryCore: `Легендарное ядро`,
21 20 code_traumaticPeculiar: `Травмирующая Странность`,
Modified static/webui/translations/zh.js +0 -1
@@ -15,7 +15,6 @@ dict = {
15 15 code_zaw: `自制近战`,
16 16 code_moteAmp: `微尘增幅器`,
17 17 code_amp: `增幅器`,
18 code_sirocco: `赤风`,
19 18 code_kDrive: `K式悬浮板`,
20 19 code_legendaryCore: `传奇核心`,
21 20 code_traumaticPeculiar: `创伤怪奇`,