diff --git a/package-lock.json b/package-lock.json index 95bfdf39..09f0c344 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,7 +12,7 @@ "copyfiles": "^2.4.1", "express": "^5", "mongoose": "^8.9.2", - "warframe-public-export-plus": "^0.5.19", + "warframe-public-export-plus": "^0.5.21", "warframe-riven-info": "^0.1.2", "winston": "^3.17.0", "winston-daily-rotate-file": "^5.0.0" @@ -3778,9 +3778,9 @@ } }, "node_modules/warframe-public-export-plus": { - "version": "0.5.19", - "resolved": "https://registry.npmjs.org/warframe-public-export-plus/-/warframe-public-export-plus-0.5.19.tgz", - "integrity": "sha512-ERCPAe4ojJXts6tyNPBvNsFcgAwJuV3M04iDfXhudJfpJrg0qseDO4AExjSyFo+WUvKoWROMCy9dCRzxIbNATw==" + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/warframe-public-export-plus/-/warframe-public-export-plus-0.5.21.tgz", + "integrity": "sha512-06k63L99wfX+lPx7ReYzGiMK/7NtNEiO97r+kemrtn4QIEKCfvBvmKiJcYbkSo79x35CQ+6FQfMtDilf6DGz6Q==" }, "node_modules/warframe-riven-info": { "version": "0.1.2", diff --git a/package.json b/package.json index 4f789119..b241a343 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,7 @@ "copyfiles": "^2.4.1", "express": "^5", "mongoose": "^8.9.2", - "warframe-public-export-plus": "^0.5.19", + "warframe-public-export-plus": "^0.5.21", "warframe-riven-info": "^0.1.2", "winston": "^3.17.0", "winston-daily-rotate-file": "^5.0.0" diff --git a/src/controllers/api/activateRandomModController.ts b/src/controllers/api/activateRandomModController.ts new file mode 100644 index 00000000..a0ef4745 --- /dev/null +++ b/src/controllers/api/activateRandomModController.ts @@ -0,0 +1,98 @@ +import { getJSONfromString } from "@/src/helpers/stringHelpers"; +import { addMods, getInventory } from "@/src/services/inventoryService"; +import { getAccountIdForRequest } from "@/src/services/loginService"; +import { getRandomElement, getRandomInt, getRandomReward, IRngResult } from "@/src/services/rngService"; +import { logger } from "@/src/utils/logger"; +import { RequestHandler } from "express"; +import { ExportUpgrades } from "warframe-public-export-plus"; + +export const activateRandomModController: RequestHandler = async (req, res) => { + const accountId = await getAccountIdForRequest(req); + const inventory = await getInventory(accountId); + const request = getJSONfromString(String(req.body)) as IActiveRandomModRequest; + addMods(inventory, [ + { + ItemType: request.ItemType, + ItemCount: -1 + } + ]); + const rivenType = getRandomElement(rivenRawToRealWeighted[request.ItemType]); + const challenge = getRandomElement(ExportUpgrades[rivenType].availableChallenges!); + const fingerprintChallenge: IRandomModChallenge = { + Type: challenge.fullName, + Progress: 0, + Required: getRandomInt(challenge.countRange[0], challenge.countRange[1]) + }; + if (Math.random() < challenge.complicationChance) { + const complicationsAsRngResults: IRngResult[] = []; + for (const complication of challenge.complications) { + complicationsAsRngResults.push({ + type: complication.fullName, + itemCount: 1, + probability: complication.weight + }); + } + fingerprintChallenge.Complication = getRandomReward(complicationsAsRngResults)!.type; + logger.debug( + `riven rolled challenge ${fingerprintChallenge.Type} with complication ${fingerprintChallenge.Complication}` + ); + const complication = challenge.complications.find(x => x.fullName == fingerprintChallenge.Complication)!; + fingerprintChallenge.Required *= complication.countMultiplier; + } else { + logger.debug(`riven rolled challenge ${fingerprintChallenge.Type}`); + } + const upgradeIndex = + inventory.Upgrades.push({ + ItemType: rivenType, + UpgradeFingerprint: JSON.stringify({ challenge: fingerprintChallenge }) + }) - 1; + await inventory.save(); + res.json({ + NewMod: inventory.Upgrades[upgradeIndex].toJSON() + }); +}; + +interface IActiveRandomModRequest { + ItemType: string; +} + +interface IRandomModChallenge { + Type: string; + Progress: number; + Required: number; + Complication?: string; +} + +const rivenRawToRealWeighted: Record = { + "/Lotus/Upgrades/Mods/Randomized/RawArchgunRandomMod": [ + "/Lotus/Upgrades/Mods/Randomized/LotusArchgunRandomModRare" + ], + "/Lotus/Upgrades/Mods/Randomized/RawMeleeRandomMod": [ + "/Lotus/Upgrades/Mods/Randomized/PlayerMeleeWeaponRandomModRare" + ], + "/Lotus/Upgrades/Mods/Randomized/RawModularMeleeRandomMod": [ + "/Lotus/Upgrades/Mods/Randomized/LotusModularMeleeRandomModRare" + ], + "/Lotus/Upgrades/Mods/Randomized/RawModularPistolRandomMod": [ + "/Lotus/Upgrades/Mods/Randomized/LotusModularPistolRandomModRare" + ], + "/Lotus/Upgrades/Mods/Randomized/RawPistolRandomMod": ["/Lotus/Upgrades/Mods/Randomized/LotusPistolRandomModRare"], + "/Lotus/Upgrades/Mods/Randomized/RawRifleRandomMod": ["/Lotus/Upgrades/Mods/Randomized/LotusRifleRandomModRare"], + "/Lotus/Upgrades/Mods/Randomized/RawShotgunRandomMod": [ + "/Lotus/Upgrades/Mods/Randomized/LotusShotgunRandomModRare" + ], + "/Lotus/Upgrades/Mods/Randomized/RawSentinelWeaponRandomMod": [ + "/Lotus/Upgrades/Mods/Randomized/LotusRifleRandomModRare", + "/Lotus/Upgrades/Mods/Randomized/LotusRifleRandomModRare", + "/Lotus/Upgrades/Mods/Randomized/LotusRifleRandomModRare", + "/Lotus/Upgrades/Mods/Randomized/LotusRifleRandomModRare", + "/Lotus/Upgrades/Mods/Randomized/LotusRifleRandomModRare", + "/Lotus/Upgrades/Mods/Randomized/LotusRifleRandomModRare", + "/Lotus/Upgrades/Mods/Randomized/LotusRifleRandomModRare", + "/Lotus/Upgrades/Mods/Randomized/LotusRifleRandomModRare", + "/Lotus/Upgrades/Mods/Randomized/LotusRifleRandomModRare", + "/Lotus/Upgrades/Mods/Randomized/LotusShotgunRandomModRare", + "/Lotus/Upgrades/Mods/Randomized/LotusPistolRandomModRare", + "/Lotus/Upgrades/Mods/Randomized/PlayerMeleeWeaponRandomModRare" + ] +}; diff --git a/src/routes/api.ts b/src/routes/api.ts index 4194f44c..bdefaac8 100644 --- a/src/routes/api.ts +++ b/src/routes/api.ts @@ -1,4 +1,5 @@ import express from "express"; +import { activateRandomModController } from "@/src/controllers/api/activateRandomModController"; import { addFriendImageController } from "@/src/controllers/api/addFriendImageController"; import { arcaneCommonController } from "@/src/controllers/api/arcaneCommonController"; import { artifactsController } from "../controllers/api/artifactsController"; @@ -107,6 +108,7 @@ apiRouter.get("/surveys.php", surveysController); apiRouter.get("/updateSession.php", updateSessionGetController); // post +apiRouter.post("/activateRandomMod.php", activateRandomModController); apiRouter.post("/addFriendImage.php", addFriendImageController); apiRouter.post("/arcaneCommon.php", arcaneCommonController); apiRouter.post("/artifacts.php", artifactsController); diff --git a/src/services/rngService.ts b/src/services/rngService.ts index fad3a4ff..df235860 100644 --- a/src/services/rngService.ts +++ b/src/services/rngService.ts @@ -6,6 +6,18 @@ export interface IRngResult { probability: number; } +export const getRandomElement = (arr: T[]): T => { + return arr[Math.floor(Math.random() * arr.length)]; +}; + +// Returns a random integer between min (inclusive) and max (inclusive). +// https://stackoverflow.com/a/1527820 +export const getRandomInt = (min: number, max: number): number => { + min = Math.ceil(min); + max = Math.floor(max); + return Math.floor(Math.random() * (max - min + 1)) + min; +}; + export const getRandomReward = (pool: IRngResult[]): IRngResult | undefined => { if (pool.length == 0) return;