From 3aca930f340d454c4bc590ecdd49914d0750a158 Mon Sep 17 00:00:00 2001 From: Sainan Date: Sun, 30 Jun 2024 07:02:27 +0200 Subject: [PATCH 1/3] improve(webui): only send requests for cheats tab when it's opened --- static/webui/script.js | 82 ++++++++++++++++++++++-------------------- 1 file changed, 43 insertions(+), 39 deletions(-) diff --git a/static/webui/script.js b/static/webui/script.js index ffabd833..e9d3a390 100644 --- a/static/webui/script.js +++ b/static/webui/script.js @@ -15,7 +15,6 @@ function loginFromLocalStorage() { window.accountId = data.id; window.authz = "accountId=" + data.id + "&nonce=" + data.Nonce; updateInventory(); - fetchSettings(); }, () => { logout(); @@ -656,26 +655,6 @@ $("#mod-to-acquire").on("input", () => { $("#mod-to-acquire").removeClass("is-invalid"); }); -function fetchSettings() { - fetch("/custom/config") - .then(response => response.json()) - .then(json => - Object.entries(json).forEach(entry => { - const [key, value] = entry; - var x = document.getElementById(`${key}`); - if (x != null) { - if (x.type == "checkbox") { - if (value === true) { - x.setAttribute("checked", "checked"); - } - } else if (x.type == "number") { - x.setAttribute("value", `${value}`); - } - } - }) - ); -} - const uiConfigs = [ "autoCreateAccount", "skipStoryModeChoice", @@ -721,27 +700,52 @@ function doChangeSettings() { // Cheats route -fetch("http://localhost:61558/ping", { mode: "no-cors" }).then(() => { - $("#client-cheats-nok").addClass("d-none"); - $("#client-cheats-ok").removeClass("d-none"); +single.getRoute("/webui/cheats").on("beforeload", function () { + fetch("/custom/config") + .then(response => response.json()) + .then(json => + Object.entries(json).forEach(entry => { + const [key, value] = entry; + var x = document.getElementById(`${key}`); + if (x != null) { + if (x.type == "checkbox") { + if (value === true) { + x.setAttribute("checked", "checked"); + } + } else if (x.type == "number") { + x.setAttribute("value", `${value}`); + } + } + }) + ); - fetch("http://localhost:61558/skip_mission_start_timer") - .then(res => res.text()) - .then(res => { - document.getElementById("skip_mission_start_timer").checked = res == "1"; - }); - document.getElementById("skip_mission_start_timer").onchange = function () { - fetch("http://localhost:61558/skip_mission_start_timer?" + this.checked); - }; + fetch("http://localhost:61558/ping", { mode: "no-cors" }) + .then(() => { + $("#client-cheats-ok").removeClass("d-none"); + $("#client-cheats-nok").addClass("d-none"); - fetch("http://localhost:61558/fov_override") - .then(res => res.text()) - .then(res => { - document.getElementById("fov_override").value = parseFloat(res) * 10000; + fetch("http://localhost:61558/skip_mission_start_timer") + .then(res => res.text()) + .then(res => { + document.getElementById("skip_mission_start_timer").checked = res == "1"; + }); + document.getElementById("skip_mission_start_timer").onchange = function () { + fetch("http://localhost:61558/skip_mission_start_timer?" + this.checked); + }; + + fetch("http://localhost:61558/fov_override") + .then(res => res.text()) + .then(res => { + document.getElementById("fov_override").value = parseFloat(res) * 10000; + }); + document.getElementById("fov_override").oninput = function () { + fetch("http://localhost:61558/fov_override?" + this.value); + }; + }) + .catch(function () { + $("#client-cheats-nok").removeClass("d-none"); + $("#client-cheats-ok").addClass("d-none"); }); - document.getElementById("fov_override").oninput = function () { - fetch("http://localhost:61558/fov_override?" + this.value); - }; }); function doUnlockAllFocusSchools() { -- 2.47.2 From 9228a8befcb1f86949f29f5919e13fa96c390fe0 Mon Sep 17 00:00:00 2001 From: Sainan Date: Sun, 30 Jun 2024 11:22:01 +0200 Subject: [PATCH 2/3] handle rename item being cancelled --- static/webui/script.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/static/webui/script.js b/static/webui/script.js index e9d3a390..f8ce59fa 100644 --- a/static/webui/script.js +++ b/static/webui/script.js @@ -157,7 +157,9 @@ function updateInventory() { a.onclick = function (event) { event.preventDefault(); const name = prompt("Enter new custom name:"); - renameGear("Suits", item.ItemId.$oid, name); + if (name !== null) { + renameGear("Suits", item.ItemId.$oid, name); + } }; a.title = "Rename"; a.innerHTML = ``; @@ -211,7 +213,9 @@ function updateInventory() { a.onclick = function (event) { event.preventDefault(); const name = prompt("Enter new custom name:"); - renameGear(category, item.ItemId.$oid, name); + if (name !== null) { + renameGear(category, item.ItemId.$oid, name); + } }; a.title = "Rename"; a.innerHTML = ``; -- 2.47.2 From e93c893786a19e2ae5a156c8ea42e6ee55a635d4 Mon Sep 17 00:00:00 2001 From: Sainan Date: Sun, 30 Jun 2024 11:45:59 +0200 Subject: [PATCH 3/3] feat(webui): add options to add and remove archon shard upgrades --- .../api/infestedFoundryController.ts | 5 +- .../custom/getItemListsController.ts | 4 +- .../popArchonCrystalUpgradeController.ts | 18 +++ .../pushArchonCrystalUpgradeController.ts | 20 +++ src/routes/custom.ts | 7 + src/routes/webui.ts | 3 + .../webuiArchonCrystalUpgrades.json | 81 ++++++++++++ static/webui/index.html | 40 ++++-- static/webui/script.js | 123 +++++++++++++++++- static/webui/style.css | 1 - 10 files changed, 284 insertions(+), 18 deletions(-) create mode 100644 src/controllers/custom/popArchonCrystalUpgradeController.ts create mode 100644 src/controllers/custom/pushArchonCrystalUpgradeController.ts create mode 100644 static/fixed_responses/webuiArchonCrystalUpgrades.json diff --git a/src/controllers/api/infestedFoundryController.ts b/src/controllers/api/infestedFoundryController.ts index ddf6925d..cbfa0fa8 100644 --- a/src/controllers/api/infestedFoundryController.ts +++ b/src/controllers/api/infestedFoundryController.ts @@ -13,10 +13,7 @@ export const infestedFoundryController: RequestHandler = async (req, res) => { const request = getJSONfromString(String(req.body)) as IShardInstallRequest; const inventory = await getInventory(accountId); const suit = inventory.Suits.find(suit => suit._id.toString() == request.SuitId.$oid)!; - if ( - !suit.ArchonCrystalUpgrades || - suit.ArchonCrystalUpgrades.length != 5 // we shouldn't have an array like this, but older inventories may disagree... - ) { + if (!suit.ArchonCrystalUpgrades || suit.ArchonCrystalUpgrades.length != 5) { suit.ArchonCrystalUpgrades = [{}, {}, {}, {}, {}]; } suit.ArchonCrystalUpgrades[request.Slot] = { diff --git a/src/controllers/custom/getItemListsController.ts b/src/controllers/custom/getItemListsController.ts index a3e794a0..962b8857 100644 --- a/src/controllers/custom/getItemListsController.ts +++ b/src/controllers/custom/getItemListsController.ts @@ -8,6 +8,7 @@ import { ExportWarframes, ExportWeapons } from "warframe-public-export-plus"; +import archonCrystalUpgrades from "@/static/fixed_responses/webuiArchonCrystalUpgrades.json"; interface ListedItem { uniqueName: string; @@ -77,7 +78,8 @@ const getItemListsController: RequestHandler = (_req, res) => { weapons, miscitems, mods, - badItems + badItems, + archonCrystalUpgrades }); }; diff --git a/src/controllers/custom/popArchonCrystalUpgradeController.ts b/src/controllers/custom/popArchonCrystalUpgradeController.ts new file mode 100644 index 00000000..041fec96 --- /dev/null +++ b/src/controllers/custom/popArchonCrystalUpgradeController.ts @@ -0,0 +1,18 @@ +import { RequestHandler } from "express"; +import { getAccountIdForRequest } from "@/src/services/loginService"; +import { getInventory } from "@/src/services/inventoryService"; + +// eslint-disable-next-line @typescript-eslint/no-misused-promises +export const popArchonCrystalUpgradeController: RequestHandler = async (req, res) => { + const accountId = await getAccountIdForRequest(req); + const inventory = await getInventory(accountId); + const suit = inventory.Suits.find(suit => suit._id.toString() == (req.query.oid as string)); + if (suit && suit.ArchonCrystalUpgrades) { + suit.ArchonCrystalUpgrades = suit.ArchonCrystalUpgrades.filter( + x => x.UpgradeType != (req.query.type as string) + ); + await inventory.save(); + res.end(); + } + res.status(400).end(); +}; diff --git a/src/controllers/custom/pushArchonCrystalUpgradeController.ts b/src/controllers/custom/pushArchonCrystalUpgradeController.ts new file mode 100644 index 00000000..cbe1023d --- /dev/null +++ b/src/controllers/custom/pushArchonCrystalUpgradeController.ts @@ -0,0 +1,20 @@ +import { RequestHandler } from "express"; +import { getAccountIdForRequest } from "@/src/services/loginService"; +import { getInventory } from "@/src/services/inventoryService"; + +// eslint-disable-next-line @typescript-eslint/no-misused-promises +export const pushArchonCrystalUpgradeController: RequestHandler = async (req, res) => { + const accountId = await getAccountIdForRequest(req); + const inventory = await getInventory(accountId); + const suit = inventory.Suits.find(suit => suit._id.toString() == (req.query.oid as string)); + if (suit) { + suit.ArchonCrystalUpgrades ??= []; + const count = (req.query.count as number | undefined) ?? 1; + for (let i = 0; i != count; ++i) { + suit.ArchonCrystalUpgrades.push({ UpgradeType: req.query.type as string }); + } + await inventory.save(); + res.end(); + } + res.status(400).end(); +}; diff --git a/src/routes/custom.ts b/src/routes/custom.ts index 476c5997..0d00bbd2 100644 --- a/src/routes/custom.ts +++ b/src/routes/custom.ts @@ -1,13 +1,20 @@ import express from "express"; + import { getItemListsController } from "@/src/controllers/custom/getItemListsController"; +import { pushArchonCrystalUpgradeController } from "@/src/controllers/custom/pushArchonCrystalUpgradeController"; +import { popArchonCrystalUpgradeController } from "@/src/controllers/custom/popArchonCrystalUpgradeController"; + import { createAccountController } from "@/src/controllers/custom/createAccountController"; import { addItemController } from "@/src/controllers/custom/addItemController"; + import { getConfigDataController } from "@/src/controllers/custom/getConfigDataController"; import { updateConfigDataController } from "@/src/controllers/custom/updateConfigDataController"; const customRouter = express.Router(); customRouter.get("/getItemLists", getItemListsController); +customRouter.get("/pushArchonCrystalUpgrade", pushArchonCrystalUpgradeController); +customRouter.get("/popArchonCrystalUpgrade", popArchonCrystalUpgradeController); customRouter.post("/createAccount", createAccountController); customRouter.post("/addItem", addItemController); diff --git a/src/routes/webui.ts b/src/routes/webui.ts index 27ac95e5..2fc5652a 100644 --- a/src/routes/webui.ts +++ b/src/routes/webui.ts @@ -22,6 +22,9 @@ webuiRouter.use("/webui", (req, res, next) => { webuiRouter.get("/webui/inventory", (_req, res) => { res.sendFile(path.join(rootDir, "static/webui/index.html")); }); +webuiRouter.get(/webui\/powersuit\/(.+)/, (_req, res) => { + res.sendFile(path.join(rootDir, "static/webui/index.html")); +}); webuiRouter.get("/webui/mods", (_req, res) => { res.sendFile(path.join(rootDir, "static/webui/index.html")); }); diff --git a/static/fixed_responses/webuiArchonCrystalUpgrades.json b/static/fixed_responses/webuiArchonCrystalUpgrades.json new file mode 100644 index 00000000..b133c0b5 --- /dev/null +++ b/static/fixed_responses/webuiArchonCrystalUpgrades.json @@ -0,0 +1,81 @@ +{ + "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeEquilibrium": "+20% Energy from Health pickups, +20% Health from Energy pickups", + "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeEquilibriumMythic": "+30% Energy from Health pickups, +30% Health from Energy pickups", + "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeMeleeCritDamage": "+25% Melee Critical Damage", + "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeMeleeCritDamageMythic": "+37.5% Melee Critical Damage", + "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradePrimaryStatusChance": "+25% Primary Status Chance", + "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradePrimaryStatusChanceMythic": "+37.5% Primary Status Chance", + "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeSecondaryCritChance": "+25% Secondary Critical Chance", + "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeSecondaryCritChanceMythic": "+37.5% Secondary Critical Chance", + "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeWarframeAbilityDuration": "+10% Ability Duration", + "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeWarframeAbilityDurationMythic": "+15% Ability Duration", + "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeWarframeAbilityStrength": "+10% Ability Strength", + "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeWarframeAbilityStrengthMythic": "+15% Ability Strength", + "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeWarframeArmourMax": "+150 Armor", + "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeWarframeArmourMaxMythic": "+225 Armor", + "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeWarframeBlastProc": "+5 Shields on inflicting Blast Status", + "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeWarframeBlastProcMythic": "+7.5 Shields on inflicting Blast Status", + "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeWarframeCastingSpeed": "+25% Casting Speed", + "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeWarframeCastingSpeedMythic": "+37.5% Casting Speed", + "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeWarframeCorrosiveDamageBoost": "+10% Ability Damage on enemies affected by Corrosion Status", + "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeWarframeCorrosiveDamageBoostMythic": "+15% Ability Damage on enemies affected by Corrosion Status", + "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeWarframeCorrosiveStack": "Increase max stacks of Corrosion Status by +2", + "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeWarframeCorrosiveStackMythic": "Increase max stacks of Corrosion Status by +3", + "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeWarframeCritDamageBoost": "+25% Melee Critical Damage (Doubles over 500 Energy)", + "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeWarframeCritDamageBoostMythic": "+37% Melee Critical Damage (Doubles over 500 Energy)", + "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeWarframeElectricDamage": "+30% Primary Electricity Damage (+10% per additional Shard)", + "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeWarframeElectricDamageMythic": "+45% Primary Electricity Damage (+15% per additional Shard)", + "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeWarframeElectricDamageBoost": "+10% Ability Damage on enemies affected by Electricity Status", + "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeWarframeElectricDamageBoostMythic": "+15% Ability Damage on enemies affected by Electricity Status", + "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeWarframeEnergyMax": "+50 Energy Max", + "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeWarframeEnergyMaxMythic": "+75 Energy Max", + "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeWarframeGlobeEffectEnergy": "+50% Energy Orb Effectiveness", + "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeWarframeGlobeEffectEnergyMythic": "+75% Energy Orb Effectiveness", + "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeWarframeGlobeEffectHealth": "+100% Health Orb Effectiveness", + "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeWarframeGlobeEffectHealthMythic": "+150% Health Orb Effectiveness", + "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeWarframeHealthMax": "+150 Health", + "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeWarframeHealthMaxMythic": "+225 Health", + "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeWarframeHPBoostFromImpact": "+1 Health per enemy killed with Blast Damage (Max 300 Health)", + "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeWarframeHPBoostFromImpactMythic": "+2 Health per enemy killed with Blast Damage (Max 450 Health)", + "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeWarframeParkourVelocity": "+15% Parkour Velocity", + "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeWarframeParkourVelocityMythic": "+22.5% Parkour Velocity", + "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeWarframeRadiationDamageBoost": "+10% Ability Damage on enemies affected by Radiation Status", + "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeWarframeRadiationDamageBoostMythic": "+15% Ability Damage on enemies affected by Radiation Status", + "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeWarframeRegen": "+5 Health Regen/s", + "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeWarframeRegenMythic": "+7.5 Health Regen/s", + "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeWarframeShieldMax": "+150 Shield", + "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeWarframeShieldMaxMythic": "+225 Shield", + "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeWarframeStartingEnergy": "+30% Energy on Spawn", + "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeWarframeStartingEnergyMythic": "+45% Energy on Spawn", + "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeWarframeToxinDamage": "+30% Toxin Status Effect Damage", + "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeWarframeToxinDamageMythic": "+45% Toxin Status Effect Damage", + "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeWarframeToxinHeal": "+2 Health on damaging enemies with Toxin Status", + "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeWarframeToxinHealMythic": "+3 Health on damaging enemies with Toxin Status", + "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeWeaponCritBoostFromHeat": "+1% Secondary Critical Chance per Heat-affected enemy killed (Max 50%)", + "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeWeaponCritBoostFromHeatMythic": "+1.5% Secondary Critical Chance per Heat-affected enemy killed (Max 75%)", + + "/Lotus/Upgrades/Mods/Warframe/AvatarEnergyRegenMod": "+0.5 Energy Regen/s", + "/Lotus/Upgrades/Mods/Warframe/AvatarEnemyRadarMod": "+5m Enemy Radar", + "/Lotus/Upgrades/Mods/Warframe/AvatarLootRadarMod": "+7m Loot Radar", + + "/Lotus/Upgrades/Mods/Rifle/WeaponAmmoMaxMod": "+15% Ammo Max", + + "/Lotus/Upgrades/Mods/Aura/EnemyArmorReductionAuraMod": "-3% Enemy Armor", + + "/Lotus/Upgrades/Mods/DataSpike/Assassin/OnExecutionAmmoMod": "100% Primary and Secondary Magazine Refill on Mercy", + "/Lotus/Upgrades/Mods/DataSpike/Assassin/OnExecutionHealthDropMod": "100% chance to drop a Health Orb on Mercy", + "/Lotus/Upgrades/Mods/DataSpike/Assassin/OnExecutionEnergyDropMod": "50% chance to drop an Energy Orb on Mercy", + "/Lotus/Upgrades/Mods/DataSpike/Cipher/OnFailHackResetMod": "+50% to retry on Hacking failure", + "/Lotus/Upgrades/Mods/DataSpike/Cipher/DamageReductionOnHackMod": "75% Damage Reduction while Hacking", + "/Lotus/Upgrades/Mods/DataSpike/Assassin/OnExecutionReviveCompanionMod": "Mercy Kills reduce Companion Recovery by 15s", + "/Lotus/Upgrades/Mods/DataSpike/Assassin/OnExecutionParkourSpeedMod": "+60% Parkour Speed after a Mercy for 15s", + "/Lotus/Upgrades/Mods/Warframe/AvatarTimeLimitIncreaseMod": "+8s to Hacking", + "/Lotus/Upgrades/Mods/DataSpike/Cipher/ElectrifyOnHackMod": "Shock enemies within 20m while Hacking", + "/Lotus/Upgrades/Mods/DataSpike/Assassin/OnExecutionTerrifyMod": "50% chance for enemies within 15m to cower in fear for 8 seconds on Mercy", + "/Lotus/Upgrades/Mods/DataSpike/Cipher/OnHackLockersMod": "Unlock 5 lockers within 20m after Hacking", + "/Lotus/Upgrades/Mods/DataSpike/Assassin/OnExecutionBlindMod": "Blind enemies within 18m on Mercy", + "/Lotus/Upgrades/Mods/DataSpike/Assassin/OnExecutionDrainPowerMod": "100% chance for next ability cast to gain +50% Ability Strength on Mercy", + "/Lotus/Upgrades/Mods/DataSpike/Cipher/OnHackSprintSpeedMod": "+75% Sprint Speed for 15s after Hacking", + "/Lotus/Upgrades/Mods/DataSpike/Assassin/SwiftExecuteMod": "Speed of Mercy Kills increased by 50%", + "/Lotus/Upgrades/Mods/DataSpike/Cipher/OnHackInvisMod": "Invisible for 15 seconds after hacking" +} diff --git a/static/webui/index.html b/static/webui/index.html index 423c51a1..5b49578e 100644 --- a/static/webui/index.html +++ b/static/webui/index.html @@ -3,8 +3,8 @@ OpenWF WebUI - - + +