From b22618d43d29eb639b4688e81eac183b46876f22 Mon Sep 17 00:00:00 2001 From: Sainan Date: Sun, 16 Jun 2024 20:01:55 +0200 Subject: [PATCH 1/5] rename IEquipmentKey to TEquipmentKey --- src/controllers/api/upgradesController.ts | 16 ++++++++-------- src/types/inventoryTypes/inventoryTypes.ts | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/controllers/api/upgradesController.ts b/src/controllers/api/upgradesController.ts index 88c01dc7..25b548e6 100644 --- a/src/controllers/api/upgradesController.ts +++ b/src/controllers/api/upgradesController.ts @@ -1,7 +1,7 @@ import { RequestHandler } from "express"; import { IUpgradesRequest } from "@/src/types/requestTypes"; import { FocusSchool, IEquipmentDatabase } from "@/src/types/inventoryTypes/commonInventoryTypes"; -import { IMiscItem, IEquipmentKey } from "@/src/types/inventoryTypes/inventoryTypes"; +import { IMiscItem, TEquipmentKey } from "@/src/types/inventoryTypes/inventoryTypes"; import { getAccountIdForRequest } from "@/src/services/loginService"; import { addMiscItems, getInventory, updateCurrency } from "@/src/services/inventoryService"; @@ -28,7 +28,7 @@ export const upgradesController: RequestHandler = async (req, res) => { switch (operation.UpgradeRequirement) { case "/Lotus/Types/Items/MiscItems/OrokinReactor": case "/Lotus/Types/Items/MiscItems/OrokinCatalyst": - for (const item of inventory[payload.ItemCategory as IEquipmentKey] as IEquipmentDatabase[]) { + for (const item of inventory[payload.ItemCategory as TEquipmentKey] as IEquipmentDatabase[]) { if (item._id.toString() == payload.ItemId.$oid) { item.Features ??= 0; item.Features |= 1; @@ -38,7 +38,7 @@ export const upgradesController: RequestHandler = async (req, res) => { break; case "/Lotus/Types/Items/MiscItems/UtilityUnlocker": case "/Lotus/Types/Items/MiscItems/WeaponUtilityUnlocker": - for (const item of inventory[payload.ItemCategory as IEquipmentKey] as IEquipmentDatabase[]) { + for (const item of inventory[payload.ItemCategory as TEquipmentKey] as IEquipmentDatabase[]) { if (item._id.toString() == payload.ItemId.$oid) { item.Features ??= 0; item.Features |= 2; @@ -49,7 +49,7 @@ export const upgradesController: RequestHandler = async (req, res) => { case "/Lotus/Types/Items/MiscItems/WeaponPrimaryArcaneUnlocker": case "/Lotus/Types/Items/MiscItems/WeaponSecondaryArcaneUnlocker": case "/Lotus/Types/Items/MiscItems/WeaponMeleeArcaneUnlocker": - for (const item of inventory[payload.ItemCategory as IEquipmentKey] as IEquipmentDatabase[]) { + for (const item of inventory[payload.ItemCategory as TEquipmentKey] as IEquipmentDatabase[]) { if (item._id.toString() == payload.ItemId.$oid) { item.Features ??= 0; item.Features |= 32; @@ -61,7 +61,7 @@ export const upgradesController: RequestHandler = async (req, res) => { case "/Lotus/Types/Items/MiscItems/FormaUmbra": case "/Lotus/Types/Items/MiscItems/FormaAura": case "/Lotus/Types/Items/MiscItems/FormaStance": - for (const item of inventory[payload.ItemCategory as IEquipmentKey] as IEquipmentDatabase[]) { + for (const item of inventory[payload.ItemCategory as TEquipmentKey] as IEquipmentDatabase[]) { if (item._id.toString() == payload.ItemId.$oid) { item.XP = 0; setSlotPolarity(item, operation.PolarizeSlot, operation.PolarizeValue); @@ -72,7 +72,7 @@ export const upgradesController: RequestHandler = async (req, res) => { } break; case "/Lotus/Types/Items/MiscItems/ModSlotUnlocker": - for (const item of inventory[payload.ItemCategory as IEquipmentKey] as IEquipmentDatabase[]) { + for (const item of inventory[payload.ItemCategory as TEquipmentKey] as IEquipmentDatabase[]) { if (item._id.toString() == payload.ItemId.$oid) { item.ModSlotPurchases ??= 0; item.ModSlotPurchases += 1; @@ -87,7 +87,7 @@ export const upgradesController: RequestHandler = async (req, res) => { } break; case "/Lotus/Types/Items/MiscItems/CustomizationSlotUnlocker": - for (const item of inventory[payload.ItemCategory as IEquipmentKey] as IEquipmentDatabase[]) { + for (const item of inventory[payload.ItemCategory as TEquipmentKey] as IEquipmentDatabase[]) { if (item._id.toString() == payload.ItemId.$oid) { item.CustomizationSlotPurchases ??= 0; item.CustomizationSlotPurchases += 1; @@ -103,7 +103,7 @@ export const upgradesController: RequestHandler = async (req, res) => { break; case "": console.assert(operation.OperationType == "UOT_SWAP_POLARITY"); - for (const item of inventory[payload.ItemCategory as IEquipmentKey] as IEquipmentDatabase[]) { + for (const item of inventory[payload.ItemCategory as TEquipmentKey] as IEquipmentDatabase[]) { if (item._id.toString() == payload.ItemId.$oid) { for (let i = 0; i != operation.PolarityRemap.length; ++i) { if (operation.PolarityRemap[i].Slot != i) { diff --git a/src/types/inventoryTypes/inventoryTypes.ts b/src/types/inventoryTypes/inventoryTypes.ts index 4b4f589a..ec492353 100644 --- a/src/types/inventoryTypes/inventoryTypes.ts +++ b/src/types/inventoryTypes/inventoryTypes.ts @@ -59,7 +59,7 @@ export interface ITypeCount { ItemCount: number; } -export type IEquipmentKey = +export type TEquipmentKey = | "Suits" | "LongGuns" | "Pistols" -- 2.47.2 From 5fc3b748a1a734a58c31fcb637d8dd0512464fe1 Mon Sep 17 00:00:00 2001 From: Sainan Date: Sun, 16 Jun 2024 20:08:38 +0200 Subject: [PATCH 2/5] feat: implement entitling of weapons --- src/controllers/api/nameWeaponController.ts | 23 +++++++++++++++++++++ src/routes/api.ts | 2 ++ 2 files changed, 25 insertions(+) create mode 100644 src/controllers/api/nameWeaponController.ts diff --git a/src/controllers/api/nameWeaponController.ts b/src/controllers/api/nameWeaponController.ts new file mode 100644 index 00000000..7caf40b5 --- /dev/null +++ b/src/controllers/api/nameWeaponController.ts @@ -0,0 +1,23 @@ +import { RequestHandler } from "express"; +import { getAccountIdForRequest } from "@/src/services/loginService"; +import { getInventory, updateCurrency } from "@/src/services/inventoryService"; +import { getJSONfromString } from "@/src/helpers/stringHelpers"; +import { TEquipmentKey } from "@/src/types/inventoryTypes/inventoryTypes"; + +interface INameWeaponRequest { + ItemName: string; +} + +export const nameWeaponController: RequestHandler = async (req, res) => { + const accountId = await getAccountIdForRequest(req); + const inventory = await getInventory(accountId); + const body = getJSONfromString(req.body.toString()) as INameWeaponRequest; + const item = inventory[req.query.Category as string as TEquipmentKey].find( + item => item._id.toString() == (req.query.ItemId as string) + )!; + item.ItemName = body.ItemName; + await inventory.save(); + res.json({ + InventoryChanges: await updateCurrency(15, true, accountId) + }); +}; diff --git a/src/routes/api.ts b/src/routes/api.ts index 2ed9bdcb..8a059bfe 100644 --- a/src/routes/api.ts +++ b/src/routes/api.ts @@ -55,6 +55,7 @@ import { getGuildDojoController } from "@/src/controllers/api/getGuildDojoContro import { syndicateSacrificeController } from "../controllers/api/syndicateSacrificeController"; import { startDojoRecipeController } from "@/src/controllers/api/startDojoRecipeController"; import { queueDojoComponentDestructionController } from "@/src/controllers/api/queueDojoComponentDestructionController"; +import { nameWeaponController } from "@/src/controllers/api/nameWeaponController"; const apiRouter = express.Router(); @@ -120,5 +121,6 @@ apiRouter.post("/upgrades.php", upgradesController); apiRouter.post("/guildTech.php", guildTechController); apiRouter.post("/syndicateSacrifice.php", syndicateSacrificeController); apiRouter.post("/startDojoRecipe.php", startDojoRecipeController); +apiRouter.post("/nameWeapon.php", nameWeaponController); export { apiRouter }; -- 2.47.2 From 1750cb5a718e2bdddf4ade2685aaf2f934e5f29a Mon Sep 17 00:00:00 2001 From: Sainan Date: Sun, 16 Jun 2024 20:12:16 +0200 Subject: [PATCH 3/5] Show custom names on WebUI --- static/webui/script.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/static/webui/script.js b/static/webui/script.js index 0475a730..50838db4 100644 --- a/static/webui/script.js +++ b/static/webui/script.js @@ -132,6 +132,9 @@ function updateInventory() { { const td = document.createElement("td"); td.textContent = itemMap[item.ItemType]?.name ?? item.ItemType; + if (item.ItemName) { + td.textContent = item.ItemName + " (" + td.textContent + ")"; + } tr.appendChild(td); } { @@ -173,6 +176,9 @@ function updateInventory() { { const td = document.createElement("td"); td.textContent = itemMap[item.ItemType]?.name ?? item.ItemType; + if (item.ItemName) { + td.textContent = item.ItemName + " (" + td.textContent + ")"; + } tr.appendChild(td); } { -- 2.47.2 From 389140a935f2605f5c705769557c500c7879dc33 Mon Sep 17 00:00:00 2001 From: Sainan Date: Sun, 16 Jun 2024 20:36:03 +0200 Subject: [PATCH 4/5] improve(webui): Use icons for actions --- static/webui/script.js | 52 ++++++++++++++++-------------------------- static/webui/style.css | 7 ++++++ 2 files changed, 27 insertions(+), 32 deletions(-) diff --git a/static/webui/script.js b/static/webui/script.js index 50838db4..a4696e14 100644 --- a/static/webui/script.js +++ b/static/webui/script.js @@ -147,12 +147,9 @@ function updateInventory() { event.preventDefault(); addGearExp("Suits", item.ItemId.$oid, 1_600_000 - item.XP); }; - a.textContent = "Make Rank 30"; + a.title = "Make Rank 30"; + a.innerHTML = ``; td.appendChild(a); - - const span = document.createElement("span"); - span.innerHTML = " · "; - td.appendChild(span); } { const a = document.createElement("a"); @@ -161,7 +158,8 @@ function updateInventory() { event.preventDefault(); disposeOfGear("Suits", item.ItemId.$oid); }; - a.textContent = "Remove"; + a.title = "Remove"; + a.innerHTML = ``; td.appendChild(a); } tr.appendChild(td); @@ -191,12 +189,9 @@ function updateInventory() { event.preventDefault(); addGearExp(category, item.ItemId.$oid, 800_000 - item.XP); }; - a.textContent = "Make Rank 30"; + a.title = "Make Rank 30"; + a.innerHTML = ``; td.appendChild(a); - - const span = document.createElement("span"); - span.innerHTML = " · "; - td.appendChild(span); } { const a = document.createElement("a"); @@ -205,7 +200,8 @@ function updateInventory() { event.preventDefault(); disposeOfGear(category, item.ItemId.$oid); }; - a.textContent = "Remove"; + a.title = "Remove"; + a.innerHTML = ``; td.appendChild(a); } tr.appendChild(td); @@ -247,14 +243,10 @@ function updateInventory() { }) ); a.target = "_blank"; - a.textContent = "View Stats"; + a.title = "View Stats"; + a.innerHTML = ``; td.appendChild(a); } - { - const span = document.createElement("span"); - span.innerHTML = " · "; - td.appendChild(span); - } { const a = document.createElement("a"); a.href = "#"; @@ -262,7 +254,8 @@ function updateInventory() { event.preventDefault(); disposeOfGear("Upgrades", item.ItemId.$oid); }; - a.textContent = "Remove"; + a.title = "Remove"; + a.innerHTML = ``; td.appendChild(a); } tr.appendChild(td); @@ -288,12 +281,9 @@ function updateInventory() { event.preventDefault(); setFingerprint(item.ItemType, item.ItemId, { lvl: maxRank }); }; - a.textContent = "Max Rank"; + a.title = "Max Rank"; + a.innerHTML = ``; td.appendChild(a); - - const span = document.createElement("span"); - span.innerHTML = " · "; - td.appendChild(span); } { const a = document.createElement("a"); @@ -302,7 +292,8 @@ function updateInventory() { event.preventDefault(); disposeOfGear("Upgrades", item.ItemId.$oid); }; - a.textContent = "Remove"; + a.title = "Remove"; + a.innerHTML = ``; td.appendChild(a); } tr.appendChild(td); @@ -333,14 +324,10 @@ function updateInventory() { event.preventDefault(); setFingerprint(item.ItemType, item.LastAdded, { lvl: maxRank }); }; - a.textContent = "Max Rank"; + a.title = "Max Rank"; + a.innerHTML = ``; td.appendChild(a); } - { - const span = document.createElement("span"); - span.innerHTML = " · "; - td.appendChild(span); - } { const a = document.createElement("a"); a.href = "#"; @@ -348,7 +335,8 @@ function updateInventory() { event.preventDefault(); disposeOfItems("Upgrades", item.ItemType, item.ItemCount); }; - a.textContent = "Remove"; + a.title = "Remove"; + a.innerHTML = ``; td.appendChild(a); } tr.appendChild(td); diff --git a/static/webui/style.css b/static/webui/style.css index 119d4fd2..341588cd 100644 --- a/static/webui/style.css +++ b/static/webui/style.css @@ -20,3 +20,10 @@ body:not(.logged-in) .nav-item.dropdown, body:not(.logged-in) #refresh-note { display: none; } + +td.text-end > a > svg { + fill: currentColor; + height: 1em; + margin-left: 0.5em; + margin-bottom: 4px; /* to centre the icon */ +} -- 2.47.2 From f572a601c4d2cf7a73ed7a17ca3791c0179fc292 Mon Sep 17 00:00:00 2001 From: Sainan Date: Sun, 16 Jun 2024 20:36:23 +0200 Subject: [PATCH 5/5] feat(webui): add option to rename items --- src/controllers/api/nameWeaponController.ts | 8 +++-- static/webui/script.js | 38 +++++++++++++++++++++ 2 files changed, 44 insertions(+), 2 deletions(-) diff --git a/src/controllers/api/nameWeaponController.ts b/src/controllers/api/nameWeaponController.ts index 7caf40b5..7543cbc4 100644 --- a/src/controllers/api/nameWeaponController.ts +++ b/src/controllers/api/nameWeaponController.ts @@ -15,9 +15,13 @@ export const nameWeaponController: RequestHandler = async (req, res) => { const item = inventory[req.query.Category as string as TEquipmentKey].find( item => item._id.toString() == (req.query.ItemId as string) )!; - item.ItemName = body.ItemName; + if (body.ItemName != "") { + item.ItemName = body.ItemName; + } else { + item.ItemName = undefined; + } await inventory.save(); res.json({ - InventoryChanges: await updateCurrency(15, true, accountId) + InventoryChanges: await updateCurrency("webui" in req.query ? 0 : 15, true, accountId) }); }; diff --git a/static/webui/script.js b/static/webui/script.js index a4696e14..6a9d525d 100644 --- a/static/webui/script.js +++ b/static/webui/script.js @@ -151,6 +151,18 @@ function updateInventory() { a.innerHTML = ``; td.appendChild(a); } + { + const a = document.createElement("a"); + a.href = "#"; + a.onclick = function (event) { + event.preventDefault(); + const name = prompt("Enter new custom name:"); + renameGear("Suits", item.ItemId.$oid, name); + }; + a.title = "Rename"; + a.innerHTML = ``; + td.appendChild(a); + } { const a = document.createElement("a"); a.href = "#"; @@ -193,6 +205,18 @@ function updateInventory() { a.innerHTML = ``; td.appendChild(a); } + { + const a = document.createElement("a"); + a.href = "#"; + a.onclick = function (event) { + event.preventDefault(); + const name = prompt("Enter new custom name:"); + renameGear(category, item.ItemId.$oid, name); + }; + a.title = "Rename"; + a.innerHTML = ``; + td.appendChild(a); + } { const a = document.createElement("a"); a.href = "#"; @@ -426,6 +450,20 @@ function addGearExp(category, oid, xp) { }); } +function renameGear(category, oid, name) { + revalidateAuthz(() => { + $.post({ + url: "/api/nameWeapon.php?" + window.authz + "&Category=" + category + "&ItemId=" + oid + "&webui=1", + contentType: "text/plain", + data: JSON.stringify({ + ItemName: name + }) + }).done(function () { + updateInventory(); + }); + }); +} + function disposeOfGear(category, oid) { const data = { SellCurrency: "SC_RegularCredits", -- 2.47.2