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

chore(webui): unify Boosters code (#2808)

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

71c4835a
AMelonInsideLemon <166175391+AMelonInsideLemon@users.noreply.github.com>
提交于

代码差异

10 个文件 +83 -110
Modified src/controllers/custom/setBoosterController.ts +7 -32
@@ -1,44 +1,19 @@
1 1 import { getAccountIdForRequest } from "../../services/loginService.ts";
2 2 import { getInventory } from "../../services/inventoryService.ts";
3 3 import type { RequestHandler } from "express";
4 import { ExportBoosters } from "warframe-public-export-plus";
4 import type { IBooster } from "../../types/inventoryTypes/inventoryTypes.ts";
5 5 import { broadcastInventoryUpdate } from "../../services/wsService.ts";
6 6
7 const I32_MAX = 0x7fffffff;
8
9 7 export const setBoosterController: RequestHandler = async (req, res) => {
10 8 const accountId = await getAccountIdForRequest(req);
11 const requests = req.body as { ItemType: string; ExpiryDate: number }[];
9 const requests = req.body as IBooster[];
12 10 const inventory = await getInventory(accountId, "Boosters");
13 const boosters = inventory.Boosters;
14 if (
15 requests.some(request => {
16 if (typeof request.ItemType !== "string") return true;
17 if (Object.entries(ExportBoosters).find(([_, item]) => item.typeName === request.ItemType) === undefined)
18 return true;
19 if (typeof request.ExpiryDate !== "number") return true;
20 if (request.ExpiryDate < 0 || request.ExpiryDate > I32_MAX) return true;
21 return false;
22 })
23 ) {
24 res.status(400).send("Invalid ItemType provided.");
25 return;
26 }
27 const now = Math.trunc(Date.now() / 1000);
28 for (const { ItemType, ExpiryDate } of requests) {
29 if (ExpiryDate <= now) {
30 // remove expired boosters
31 const index = boosters.findIndex(item => item.ItemType === ItemType);
32 if (index !== -1) {
33 boosters.splice(index, 1);
34 }
11 for (const request of requests) {
12 const index = inventory.Boosters.findIndex(item => item.ItemType === request.ItemType);
13 if (index !== -1) {
14 inventory.Boosters[index].ExpiryDate = request.ExpiryDate;
35 15 } else {
36 const boosterItem = boosters.find(item => item.ItemType === ItemType);
37 if (boosterItem) {
38 boosterItem.ExpiryDate = ExpiryDate;
39 } else {
40 boosters.push({ ItemType, ExpiryDate });
41 }
16 inventory.Boosters.push(request);
42 17 }
43 18 }
44 19 await inventory.save();
Modified static/webui/index.html +2 -2
@@ -476,9 +476,9 @@
476 476 </div>
477 477 <div class="col-lg-6">
478 478 <div class="card" style="height: 400px;">
479 <h5 class="card-header" data-loc="inventory_Boosters"></h5>
479 <h5 class="card-header" data-loc="inventory_boosters"></h5>
480 480 <div class="card-body d-flex flex-column">
481 <form class="input-group mb-3" onsubmit="doAcquireBoosters();return false;">
481 <form class="input-group mb-3" onsubmit="doAcquireBooster();return false;">
482 482 <input class="form-control" id="acquire-type-Boosters" list="datalist-Boosters" />
483 483 <button class="btn btn-primary" type="submit" data-loc="general_addButton"></button>
484 484 </form>
Modified static/webui/script.js +67 -69
@@ -1007,6 +1007,67 @@ function updateInventory() {
1007 1007 document.getElementById("EvolutionProgress-list").appendChild(tr);
1008 1008 });
1009 1009
1010 document.getElementById("Boosters-list").innerHTML = "";
1011 data.Boosters.forEach(item => {
1012 if (item.ExpiryDate < Math.floor(Date.now() / 1000)) {
1013 // Booster has expired, skip it
1014 return;
1015 }
1016 const tr = document.createElement("tr");
1017 {
1018 const td = document.createElement("td");
1019 td.textContent = itemMap[item.ItemType]?.name ?? item.ItemType;
1020 tr.appendChild(td);
1021 }
1022 {
1023 const td = document.createElement("td");
1024 td.classList = "text-end text-nowrap";
1025 {
1026 const form = document.createElement("form");
1027 form.style.display = "inline-block";
1028 form.onsubmit = function (event) {
1029 event.preventDefault();
1030 const maxDate = new Date(input.max);
1031 const selectedDate = new Date(input.value);
1032 if (selectedDate > maxDate) {
1033 input.value = maxDate.toISOString().slice(0, 16);
1034 }
1035 doChangeBoosterExpiry(item.ItemType, input);
1036 };
1037
1038 const input = document.createElement("input");
1039 input.type = "datetime-local";
1040 input.classList = "form-control form-control-sm";
1041 input.value = formatDatetime("%Y-%m-%d %H:%M:%s", item.ExpiryDate * 1000);
1042 input.max = "2038-01-19T03:14";
1043 input.onblur = function () {
1044 const maxDate = new Date(input.max);
1045 const selectedDate = new Date(input.value);
1046 if (selectedDate > maxDate) {
1047 input.value = maxDate.toISOString().slice(0, 16);
1048 }
1049 doChangeBoosterExpiry(item.ItemType, input);
1050 };
1051
1052 form.appendChild(input);
1053 td.appendChild(form);
1054 }
1055 {
1056 const a = document.createElement("a");
1057 a.href = "#";
1058 a.onclick = function (event) {
1059 event.preventDefault();
1060 setBooster(item.ItemType, 0);
1061 };
1062 a.title = loc("code_remove");
1063 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>`;
1064 td.appendChild(a);
1065 }
1066 tr.appendChild(td);
1067 }
1068 document.getElementById("Boosters-list").appendChild(tr);
1069 });
1070
1010 1071 document.getElementById("FlavourItems-list").innerHTML = "";
1011 1072 data.FlavourItems.forEach(item => {
1012 1073 const datalist = document.getElementById("datalist-FlavourItems");
@@ -1619,63 +1680,6 @@ function updateInventory() {
1619 1680 }
1620 1681 document.getElementById("changeSyndicate").value = data.SupportedSyndicate ?? "";
1621 1682
1622 document.getElementById("Boosters-list").innerHTML = "";
1623 const now = Math.floor(Date.now() / 1000);
1624 data.Boosters.forEach(({ ItemType, ExpiryDate }) => {
1625 if (ExpiryDate < now) {
1626 // Booster has expired, skip it
1627 return;
1628 }
1629 const tr = document.createElement("tr");
1630 {
1631 const td = document.createElement("td");
1632 td.textContent = itemMap[ItemType]?.name ?? ItemType;
1633 tr.appendChild(td);
1634 }
1635 {
1636 const td = document.createElement("td");
1637 td.classList = "text-end text-nowrap";
1638 const timeString = formatDatetime("%Y-%m-%d %H:%M:%s", ExpiryDate * 1000);
1639 const inlineForm = document.createElement("form");
1640 const input = document.createElement("input");
1641
1642 inlineForm.style.display = "inline-block";
1643 inlineForm.onsubmit = function (event) {
1644 event.preventDefault();
1645 doChangeBoosterExpiry(ItemType, input);
1646 };
1647 input.type = "datetime-local";
1648 input.classList.add("form-control");
1649 input.classList.add("form-control-sm");
1650 input.value = timeString;
1651 let changed = false;
1652 input.onchange = function () {
1653 changed = true;
1654 };
1655 input.onblur = function () {
1656 if (changed) {
1657 doChangeBoosterExpiry(ItemType, input);
1658 }
1659 };
1660 inlineForm.appendChild(input);
1661
1662 td.appendChild(inlineForm);
1663
1664 const removeButton = document.createElement("a");
1665 removeButton.title = loc("code_remove");
1666 removeButton.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>`;
1667 removeButton.href = "#";
1668 removeButton.onclick = function (event) {
1669 event.preventDefault();
1670 setBooster(ItemType, 0);
1671 };
1672 td.appendChild(removeButton);
1673
1674 tr.appendChild(td);
1675 }
1676 document.getElementById("Boosters-list").appendChild(tr);
1677 });
1678
1679 1683 if (single.getCurrentPath().startsWith("/webui/guildView")) {
1680 1684 const guildReq = $.get("/custom/getGuild?guildId=" + window.guildId);
1681 1685 guildReq.done(guildData => {
@@ -3516,7 +3520,7 @@ function handleModularSelection(category) {
3516 3520 });
3517 3521 }
3518 3522
3519 function setBooster(ItemType, ExpiryDate, callback) {
3523 function setBooster(ItemType, ExpiryDate) {
3520 3524 revalidateAuthz().then(() => {
3521 3525 $.post({
3522 3526 url: "/custom/setBooster?" + window.authz,
@@ -3529,33 +3533,27 @@ function setBooster(ItemType, ExpiryDate, callback) {
3529 3533 ])
3530 3534 }).done(function () {
3531 3535 updateInventory();
3532 if (callback) callback();
3533 3536 });
3534 3537 });
3535 3538 }
3536 3539
3537 function doAcquireBoosters() {
3540 function doAcquireBooster() {
3538 3541 const uniqueName = getKey(document.getElementById("acquire-type-Boosters"));
3539 3542 if (!uniqueName) {
3540 3543 $("#acquire-type-Boosters").addClass("is-invalid").focus();
3541 3544 return;
3542 3545 }
3543 const ExpiryDate = Date.now() / 1000 + 3 * 24 * 60 * 60; // default 3 days
3544 setBooster(uniqueName, ExpiryDate, () => {
3545 $("#acquire-type-Boosters").val("");
3546 });
3546 setBooster(uniqueName, Math.floor(Date.now() / 1000 + 3 * 24 * 60 * 60));
3547 document.getElementById("acquire-type-Boosters").value = "";
3547 3548 }
3548 3549
3549 3550 function doChangeBoosterExpiry(ItemType, ExpiryDateInput) {
3550 console.log("Changing booster expiry for", ItemType, "to", ExpiryDateInput.value);
3551 // cast local datetime string to unix timestamp
3552 const ExpiryDate = Math.trunc(new Date(ExpiryDateInput.value).getTime() / 1000);
3551 const ExpiryDate = Math.floor(new Date(ExpiryDateInput.value).getTime() / 1000);
3553 3552 if (isNaN(ExpiryDate)) {
3554 3553 ExpiryDateInput.addClass("is-invalid").focus();
3555 return false;
3554 return;
3556 3555 }
3557 3556 setBooster(ItemType, ExpiryDate);
3558 return true;
3559 3557 }
3560 3558
3561 3559 function formatDatetime(fmt, date) {
Modified static/webui/translations/de.js +1 -1
@@ -109,7 +109,7 @@ dict = {
109 109 inventory_moaPets: `Moas`,
110 110 inventory_kubrowPets: `Bestien`,
111 111 inventory_evolutionProgress: `Incarnon-Entwicklungsfortschritte`,
112 inventory_Boosters: `Booster`,
112 inventory_boosters: `Booster`,
113 113 inventory_flavourItems: `<abbr title="Animationssets, Glyphen, Farbpaletten usw.">Sammlerstücke</abbr>`,
114 114 inventory_shipDecorations: `Schiffsdekorationen`,
115 115 inventory_bulkAddSuits: `Fehlende Warframes hinzufügen`,
Modified static/webui/translations/en.js +1 -1
@@ -108,7 +108,7 @@ dict = {
108 108 inventory_moaPets: `Moas`,
109 109 inventory_kubrowPets: `Beasts`,
110 110 inventory_evolutionProgress: `Incarnon Evolution Progress`,
111 inventory_Boosters: `Boosters`,
111 inventory_boosters: `Boosters`,
112 112 inventory_flavourItems: `<abbr title="Animation Sets, Glyphs, Palettes, etc.">Flavour Items</abbr>`,
113 113 inventory_shipDecorations: `Ship Decorations`,
114 114 inventory_bulkAddSuits: `Add Missing Warframes`,
Modified static/webui/translations/es.js +1 -1
@@ -109,7 +109,7 @@ dict = {
109 109 inventory_moaPets: `Moas`,
110 110 inventory_kubrowPets: `Bestias`,
111 111 inventory_evolutionProgress: `Progreso de evolución Incarnon`,
112 inventory_Boosters: `Potenciadores`,
112 inventory_boosters: `Potenciadores`,
113 113 inventory_flavourItems: `<abbr title="Conjuntos de animaciones, glifos, paletas, etc.">Ítems estéticos</abbr>`,
114 114 inventory_shipDecorations: `Decoraciones de nave`,
115 115 inventory_bulkAddSuits: `Agregar Warframes faltantes`,
Modified static/webui/translations/fr.js +1 -1
@@ -109,7 +109,7 @@ dict = {
109 109 inventory_moaPets: `Moas`,
110 110 inventory_kubrowPets: `Bêtes`,
111 111 inventory_evolutionProgress: `Progrès de l'évolution Incarnon`,
112 inventory_Boosters: `Boosters`,
112 inventory_boosters: `Boosters`,
113 113 inventory_flavourItems: `[UNTRANSLATED] <abbr title="Animation Sets, Glyphs, Palettes, etc.">Flavour Items</abbr>`,
114 114 inventory_shipDecorations: `Décorations du vaisseau`,
115 115 inventory_bulkAddSuits: `Ajouter les Warframes manquantes`,
Modified static/webui/translations/ru.js +1 -1
@@ -109,7 +109,7 @@ dict = {
109 109 inventory_moaPets: `МОА`,
110 110 inventory_kubrowPets: `Звери`,
111 111 inventory_evolutionProgress: `Прогресс эволюции Инкарнонов`,
112 inventory_Boosters: `Бустеры`,
112 inventory_boosters: `Бустеры`,
113 113 inventory_flavourItems: `<abbr title="Наборы анимаций, глифы, палитры и т. д.">Уникальные предметы</abbr>`,
114 114 inventory_shipDecorations: `Украшения корабля`,
115 115 inventory_bulkAddSuits: `Добавить отсутствующие Варфреймы`,
Modified static/webui/translations/uk.js +1 -1
@@ -109,7 +109,7 @@ dict = {
109 109 inventory_moaPets: `МОА`,
110 110 inventory_kubrowPets: `Тварини`,
111 111 inventory_evolutionProgress: `Прогрес еволюції Інкарнонів`,
112 inventory_Boosters: `Посилення`,
112 inventory_boosters: `Посилення`,
113 113 inventory_flavourItems: `<abbr title="Набори анімацій, гліфи, палітри і т. д.">Унікальні предмети</abbr>`,
114 114 inventory_shipDecorations: `Прикраси судна`,
115 115 inventory_bulkAddSuits: `Додати відсутні Ворфрейми`,
Modified static/webui/translations/zh.js +1 -1
@@ -109,7 +109,7 @@ dict = {
109 109 inventory_moaPets: `恐鸟`,
110 110 inventory_kubrowPets: `动物同伴`,
111 111 inventory_evolutionProgress: `灵化之源进度`,
112 inventory_Boosters: `加成器`,
112 inventory_boosters: `加成器`,
113 113 inventory_flavourItems: `<abbr title="动作表情、浮印、调色板等">装饰物品</abbr>`,
114 114 inventory_shipDecorations: `飞船装饰`,
115 115 inventory_bulkAddSuits: `添加缺失战甲`,