diff --git a/src/controllers/custom/setUmbraEchoesController.ts b/src/controllers/custom/setUmbraEchoesController.ts new file mode 100644 index 00000000..290ea764 --- /dev/null +++ b/src/controllers/custom/setUmbraEchoesController.ts @@ -0,0 +1,22 @@ +import { getAccountIdForRequest } from "../../services/loginService.ts"; +import { getInventory } from "../../services/inventoryService.ts"; +import type { RequestHandler } from "express"; +import { broadcastInventoryUpdate } from "../../services/wsService.ts"; + +export const setUmbraEchoesController: RequestHandler = async (req, res) => { + const accountId = await getAccountIdForRequest(req); + const request = req.body as ISetUmbraEchoesRequest; + const inventory = await getInventory(accountId, "Suits"); + const suit = inventory.Suits.id(request.oid); + if (suit) { + suit.UmbraDate = request.UmbraDate ? new Date(request.UmbraDate) : undefined; + await inventory.save(); + broadcastInventoryUpdate(req); + } + res.end(); +}; + +interface ISetUmbraEchoesRequest { + oid: string; + UmbraDate: number; +} diff --git a/src/controllers/stats/leaderboardController.ts b/src/controllers/stats/leaderboardController.ts index bd269a27..d0d21138 100644 --- a/src/controllers/stats/leaderboardController.ts +++ b/src/controllers/stats/leaderboardController.ts @@ -1,7 +1,7 @@ import { getLeaderboard } from "../../services/leaderboardService.ts"; import type { RequestHandler } from "express"; -export const leaderboardController: RequestHandler = async (req, res) => { +export const leaderboardPostController: RequestHandler = async (req, res) => { const payload = JSON.parse(String(req.body)) as ILeaderboardRequest; res.json({ results: await getLeaderboard( @@ -15,6 +15,33 @@ export const leaderboardController: RequestHandler = async (req, res) => { }); }; +export const leaderboardGetController: RequestHandler = async (req, res) => { + const payload: ILeaderboardRequest = { + field: "archived." + String(req.query.field), + before: Number(req.query.before), + after: Number(req.query.after), + pivotId: req.query.pivotAccountId ? String(req.query.pivotAccountId) : undefined, + guildId: undefined, + guildTier: undefined + }; + res.json({ + players: ( + await getLeaderboard( + payload.field, + payload.before, + payload.after, + payload.pivotId, + payload.guildId, + payload.guildTier + ) + ).map(entry => ({ + DisplayName: entry.n, + score: entry.s, + rank: entry.r + })) + }); +}; + interface ILeaderboardRequest { field: string; before: number; diff --git a/src/routes/custom.ts b/src/routes/custom.ts index 1a6fca1f..3978a41f 100644 --- a/src/routes/custom.ts +++ b/src/routes/custom.ts @@ -46,6 +46,7 @@ import { updateFingerprintController } from "../controllers/custom/updateFingerp import { unlockLevelCapController } from "../controllers/custom/unlockLevelCapController.ts"; import { changeModularPartsController } from "../controllers/custom/changeModularPartsController.ts"; import { setInvigorationController } from "../controllers/custom/setInvigorationController.ts"; +import { setUmbraEchoesController } from "../controllers/custom/setUmbraEchoesController.ts"; import { setAccountCheatController } from "../controllers/custom/setAccountCheatController.ts"; import { setGuildCheatController } from "../controllers/custom/setGuildCheatController.ts"; @@ -97,6 +98,7 @@ customRouter.post("/updateFingerprint", updateFingerprintController); customRouter.post("/unlockLevelCap", unlockLevelCapController); customRouter.post("/changeModularParts", changeModularPartsController); customRouter.post("/setInvigoration", setInvigorationController); +customRouter.post("/setUmbraEchoes", setUmbraEchoesController); customRouter.post("/setAccountCheat", setAccountCheatController); customRouter.post("/setGuildCheat", setGuildCheatController); diff --git a/src/routes/stats.ts b/src/routes/stats.ts index 8f3dfe5b..ad8d6879 100644 --- a/src/routes/stats.ts +++ b/src/routes/stats.ts @@ -1,14 +1,15 @@ import express from "express"; import { viewController } from "../controllers/stats/viewController.ts"; import { uploadController } from "../controllers/stats/uploadController.ts"; -import { leaderboardController } from "../controllers/stats/leaderboardController.ts"; +import { leaderboardPostController, leaderboardGetController } from "../controllers/stats/leaderboardController.ts"; const statsRouter = express.Router(); statsRouter.get("/view.php", viewController); statsRouter.get("/profileStats.php", viewController); +statsRouter.get("/leaderboard.php", leaderboardGetController); statsRouter.post("/upload.php", uploadController); -statsRouter.post("/leaderboardWeekly.php", leaderboardController); -statsRouter.post("/leaderboardArchived.php", leaderboardController); +statsRouter.post("/leaderboardWeekly.php", leaderboardPostController); +statsRouter.post("/leaderboardArchived.php", leaderboardPostController); export { statsRouter }; diff --git a/static/webui/index.html b/static/webui/index.html index 7c052786..6f356c97 100644 --- a/static/webui/index.html +++ b/static/webui/index.html @@ -822,6 +822,22 @@ +
+
+
+

+
+
+ + +
+
+ + +
+
+
+
diff --git a/static/webui/script.js b/static/webui/script.js index ace99d86..7eabcebe 100644 --- a/static/webui/script.js +++ b/static/webui/script.js @@ -1652,6 +1652,12 @@ function updateInventory() { formatDatetime("%Y-%m-%d %H:%M", Number(item.UpgradesExpiry?.$date.$numberLong)) || ""; } + if (item.ItemType != "/Lotus/Powersuits/Excalibur/ExcaliburUmbra") { + document.getElementById("umbraEchoes-card").classList.remove("d-none"); + document.getElementById("umbraEchoes-expiry").value = + formatDatetime("%Y-%m-%d %H:%M", Number(item.UmbraDate?.$date.$numberLong)) || ""; + } + { document.getElementById("loadout-card").classList.remove("d-none"); const maxModConfigNum = Math.min(2 + (item.ModSlotPurchases ?? 0), 5); @@ -3519,6 +3525,7 @@ single.getRoute("#detailedView-route").on("beforeload", function () { document.getElementById("loadout-card").classList.add("d-none"); document.getElementById("archonShards-card").classList.add("d-none"); document.getElementById("edit-suit-invigorations-card").classList.add("d-none"); + document.getElementById("umbraEchoes-card").classList.add("d-none"); document.getElementById("modularParts-card").classList.add("d-none"); document.getElementById("modularParts-form").innerHTML = ""; document.getElementById("valenceBonus-card").classList.add("d-none"); @@ -4257,6 +4264,25 @@ function setInvigoration(data) { }); } +function submitUmbraEchoes(event) { + event.preventDefault(); + const expiry = document.getElementById("umbraEchoes-expiry").value; + setUmbraEchoes({ + UmbraDate: expiry ? new Date(expiry).getTime() : Date.now() + 1 * 24 * 60 * 60 * 1000 + }); +} + +function setUmbraEchoes(data) { + const oid = new URLSearchParams(window.location.search).get("itemId"); + $.post({ + url: "/custom/setUmbraEchoes?" + window.authz, + contentType: "application/json", + data: JSON.stringify({ oid, ...data }) + }).done(function () { + updateInventory(); + }); +} + function handleAbilityOverride(event, configIndex) { event.preventDefault(); const urlParams = new URLSearchParams(window.location.search); diff --git a/static/webui/translations/de.js b/static/webui/translations/de.js index 2ce7e4c9..37fb291c 100644 --- a/static/webui/translations/de.js +++ b/static/webui/translations/de.js @@ -163,6 +163,7 @@ dict = { detailedView_invigorationLabel: `Kräftigung`, detailedView_loadoutLabel: `Loadouts`, detailedView_equipmentFeaturesLabel: `[UNTRANSLATED] Equipment Features`, + detailedView_umbraEchoesLabel: `[UNTRANSLATED] Echoes Of Umbra`, invigorations_offensive_AbilityStrength: `+200% Fähigkeitsstärke`, invigorations_offensive_AbilityRange: `+100% Fähigkeitsreichweite`, @@ -193,6 +194,9 @@ dict = { abilityOverride_label: `Fähigkeitsüberschreibung`, abilityOverride_onSlot: `auf Slot`, + detailedView_umbraEchoesDescription: `Wird ein Warframe mit dieser Flüssigkeit injiziert, kann er selbstständig an der Seite des Operators kämpfen.`, + detailedView_umbraEchoesExpiryLabel: `[UNTRANSLATED] Echo Expiry (optional)`, + mods_addRiven: `Riven hinzufügen`, mods_fingerprint: `Fingerabdruck`, mods_fingerprintHelp: `Benötigst du Hilfe mit dem Fingerabdruck?`, diff --git a/static/webui/translations/en.js b/static/webui/translations/en.js index dcb8267a..47ef0d1d 100644 --- a/static/webui/translations/en.js +++ b/static/webui/translations/en.js @@ -162,6 +162,7 @@ dict = { detailedView_invigorationLabel: `Invigoration`, detailedView_loadoutLabel: `Loadouts`, detailedView_equipmentFeaturesLabel: `Equipment Features`, + detailedView_umbraEchoesLabel: `Echoes Of Umbra`, invigorations_offensive_AbilityStrength: `+200% Ability Strength`, invigorations_offensive_AbilityRange: `+100% Ability Range`, @@ -192,6 +193,9 @@ dict = { abilityOverride_label: `Ability Override`, abilityOverride_onSlot: `on slot`, + detailedView_umbraEchoesDescription: `Injecting this fluid into a Warframe will imbue it with the ability to fight autonomously alongside the Operator.`, + detailedView_umbraEchoesExpiryLabel: `Echo Expiry (optional)`, + mods_addRiven: `Add Riven`, mods_fingerprint: `Fingerprint`, mods_fingerprintHelp: `Need help with the fingerprint?`, diff --git a/static/webui/translations/es.js b/static/webui/translations/es.js index 836b7c4c..e8109a60 100644 --- a/static/webui/translations/es.js +++ b/static/webui/translations/es.js @@ -163,6 +163,7 @@ dict = { detailedView_invigorationLabel: `Fortalecimiento`, detailedView_loadoutLabel: `Equipamientos`, detailedView_equipmentFeaturesLabel: `[UNTRANSLATED] Equipment Features`, + detailedView_umbraEchoesLabel: `[UNTRANSLATED] Echoes Of Umbra`, invigorations_offensive_AbilityStrength: `+200% Fuerza de Habilidad`, invigorations_offensive_AbilityRange: `+100% Alcance de Habilidad`, @@ -193,6 +194,9 @@ dict = { abilityOverride_label: `Intercambio de Habilidad`, abilityOverride_onSlot: `en el espacio`, + detailedView_umbraEchoesDescription: `Inyectar este fluido en un warframe lo imbuirá con la capacidad para luchar autónomamente junto a su operador.`, + detailedView_umbraEchoesExpiryLabel: `[UNTRANSLATED] Echo Expiry (optional)`, + mods_addRiven: `Agregar Agrietado`, mods_fingerprint: `Huella digital`, mods_fingerprintHelp: `¿Necesitas ayuda con la huella digital?`, diff --git a/static/webui/translations/fr.js b/static/webui/translations/fr.js index 7d0119eb..606d68f8 100644 --- a/static/webui/translations/fr.js +++ b/static/webui/translations/fr.js @@ -163,6 +163,7 @@ dict = { detailedView_invigorationLabel: `Dynamisation`, detailedView_loadoutLabel: `Équipements`, detailedView_equipmentFeaturesLabel: `[UNTRANSLATED] Equipment Features`, + detailedView_umbraEchoesLabel: `[UNTRANSLATED] Echoes Of Umbra`, invigorations_offensive_AbilityStrength: `+200% de puissance de pouvoir`, invigorations_offensive_AbilityRange: `+100% de portée de pouvoir`, @@ -193,6 +194,9 @@ dict = { abilityOverride_label: `Remplacement de pouvoir`, abilityOverride_onSlot: `Sur l'emplacement`, + detailedView_umbraEchoesDescription: `L'injection de ce fluide dans une Warframe lui donnera la possibilité de se battre de manière autonome aux côtés de l'Opérateur.`, + detailedView_umbraEchoesExpiryLabel: `[UNTRANSLATED] Echo Expiry (optional)`, + mods_addRiven: `Ajouter un riven`, mods_fingerprint: `Empreinte`, mods_fingerprintHelp: `Besoin d'aide pour l'empreinte ?`, diff --git a/static/webui/translations/ru.js b/static/webui/translations/ru.js index 567d4736..727d8d3f 100644 --- a/static/webui/translations/ru.js +++ b/static/webui/translations/ru.js @@ -163,6 +163,7 @@ dict = { detailedView_invigorationLabel: `Воодушевление`, detailedView_loadoutLabel: `Конфигурации`, detailedView_equipmentFeaturesLabel: `Модификаторы снаряжения`, + detailedView_umbraEchoesLabel: `Эхо Умбры`, invigorations_offensive_AbilityStrength: `+200% к силе способностей.`, invigorations_offensive_AbilityRange: `+100% к зоне поражения способностей.`, @@ -193,6 +194,9 @@ dict = { abilityOverride_label: `Переопределение способности`, abilityOverride_onSlot: `в ячейке`, + detailedView_umbraEchoesDescription: `Введение этой жидкости в варфрейм позволит ему автономно сражаться бок о бок с оператором.`, + detailedView_umbraEchoesExpiryLabel: `Срок действия Эха (необязательно)`, + mods_addRiven: `Добавить мод Разлома`, mods_fingerprint: `Отпечаток`, mods_fingerprintHelp: `Нужна помощь с отпечатком?`, diff --git a/static/webui/translations/uk.js b/static/webui/translations/uk.js index 64e99c88..49fa93b1 100644 --- a/static/webui/translations/uk.js +++ b/static/webui/translations/uk.js @@ -163,6 +163,7 @@ dict = { detailedView_invigorationLabel: `Зміцнення`, detailedView_loadoutLabel: `Конфігурації`, detailedView_equipmentFeaturesLabel: `[UNTRANSLATED] Equipment Features`, + detailedView_umbraEchoesLabel: `[UNTRANSLATED] Echoes Of Umbra`, invigorations_offensive_AbilityStrength: `+200% до потужності здібностей.`, invigorations_offensive_AbilityRange: `+100% до досяжності здібностей.`, @@ -193,6 +194,9 @@ dict = { abilityOverride_label: `Перевизначення здібностей`, abilityOverride_onSlot: `у комірці`, + detailedView_umbraEchoesDescription: `Рідина, яка після введення дозволяє ворфрейму використовувати єдність і битися самостійно пліч-о-пліч з оператором.`, + detailedView_umbraEchoesExpiryLabel: `[UNTRANSLATED] Echo Expiry (optional)`, + mods_addRiven: `Добавити модифікатор Розколу`, mods_fingerprint: `Відбиток`, mods_fingerprintHelp: `Потрібна допомога з відбитком?`, diff --git a/static/webui/translations/zh.js b/static/webui/translations/zh.js index 8d36c529..a5df62fc 100644 --- a/static/webui/translations/zh.js +++ b/static/webui/translations/zh.js @@ -163,6 +163,7 @@ dict = { detailedView_invigorationLabel: `活化`, detailedView_loadoutLabel: `配置`, detailedView_equipmentFeaturesLabel: `[UNTRANSLATED] Equipment Features`, + detailedView_umbraEchoesLabel: `[UNTRANSLATED] Echoes Of Umbra`, invigorations_offensive_AbilityStrength: `+200%技能强度`, invigorations_offensive_AbilityRange: `+100%技能范围`, @@ -193,6 +194,9 @@ dict = { abilityOverride_label: `技能替换`, abilityOverride_onSlot: `槽位`, + detailedView_umbraEchoesDescription: `将这种液体注入战甲内,使其具有与指挥官并肩作战的能力。`, + detailedView_umbraEchoesExpiryLabel: `[UNTRANSLATED] Echo Expiry (optional)`, + mods_addRiven: `添加裂罅MOD`, mods_fingerprint: `印记`, mods_fingerprintHelp: `需要印记相关的帮助?`,