XFE Git
XFE Studio Git
Git 首页 全局搜索
XFE 主站 文档 NuGet

SpaceNinjaServer

A simple server for a small space ninja game

公开
关注 0 Fork 1 Star 0
返回提交历史

XFEstudio/SpaceNinjaServer

feat: activate riven mod (get a random challenge) (#721)

83617ae2
Sainan <sainan@calamity.inc>
提交于

代码差异

5 个文件 +117 -5
Modified package-lock.json +4 -4
@@ -12,7 +12,7 @@
12 12 "copyfiles": "^2.4.1",
13 13 "express": "^5",
14 14 "mongoose": "^8.9.2",
15 "warframe-public-export-plus": "^0.5.19",
15 "warframe-public-export-plus": "^0.5.21",
16 16 "warframe-riven-info": "^0.1.2",
17 17 "winston": "^3.17.0",
18 18 "winston-daily-rotate-file": "^5.0.0"
@@ -3778,9 +3778,9 @@
3778 3778 }
3779 3779 },
3780 3780 "node_modules/warframe-public-export-plus": {
3781 "version": "0.5.19",
3782 "resolved": "https://registry.npmjs.org/warframe-public-export-plus/-/warframe-public-export-plus-0.5.19.tgz",
3783 "integrity": "sha512-ERCPAe4ojJXts6tyNPBvNsFcgAwJuV3M04iDfXhudJfpJrg0qseDO4AExjSyFo+WUvKoWROMCy9dCRzxIbNATw=="
3781 "version": "0.5.21",
3782 "resolved": "https://registry.npmjs.org/warframe-public-export-plus/-/warframe-public-export-plus-0.5.21.tgz",
3783 "integrity": "sha512-06k63L99wfX+lPx7ReYzGiMK/7NtNEiO97r+kemrtn4QIEKCfvBvmKiJcYbkSo79x35CQ+6FQfMtDilf6DGz6Q=="
3784 3784 },
3785 3785 "node_modules/warframe-riven-info": {
3786 3786 "version": "0.1.2",
Modified package.json +1 -1
@@ -16,7 +16,7 @@
16 16 "copyfiles": "^2.4.1",
17 17 "express": "^5",
18 18 "mongoose": "^8.9.2",
19 "warframe-public-export-plus": "^0.5.19",
19 "warframe-public-export-plus": "^0.5.21",
20 20 "warframe-riven-info": "^0.1.2",
21 21 "winston": "^3.17.0",
22 22 "winston-daily-rotate-file": "^5.0.0"
Added src/controllers/api/activateRandomModController.ts +98 -0
@@ -0,0 +1,98 @@
1 import { getJSONfromString } from "@/src/helpers/stringHelpers";
2 import { addMods, getInventory } from "@/src/services/inventoryService";
3 import { getAccountIdForRequest } from "@/src/services/loginService";
4 import { getRandomElement, getRandomInt, getRandomReward, IRngResult } from "@/src/services/rngService";
5 import { logger } from "@/src/utils/logger";
6 import { RequestHandler } from "express";
7 import { ExportUpgrades } from "warframe-public-export-plus";
8
9 export const activateRandomModController: RequestHandler = async (req, res) => {
10 const accountId = await getAccountIdForRequest(req);
11 const inventory = await getInventory(accountId);
12 const request = getJSONfromString(String(req.body)) as IActiveRandomModRequest;
13 addMods(inventory, [
14 {
15 ItemType: request.ItemType,
16 ItemCount: -1
17 }
18 ]);
19 const rivenType = getRandomElement(rivenRawToRealWeighted[request.ItemType]);
20 const challenge = getRandomElement(ExportUpgrades[rivenType].availableChallenges!);
21 const fingerprintChallenge: IRandomModChallenge = {
22 Type: challenge.fullName,
23 Progress: 0,
24 Required: getRandomInt(challenge.countRange[0], challenge.countRange[1])
25 };
26 if (Math.random() < challenge.complicationChance) {
27 const complicationsAsRngResults: IRngResult[] = [];
28 for (const complication of challenge.complications) {
29 complicationsAsRngResults.push({
30 type: complication.fullName,
31 itemCount: 1,
32 probability: complication.weight
33 });
34 }
35 fingerprintChallenge.Complication = getRandomReward(complicationsAsRngResults)!.type;
36 logger.debug(
37 `riven rolled challenge ${fingerprintChallenge.Type} with complication ${fingerprintChallenge.Complication}`
38 );
39 const complication = challenge.complications.find(x => x.fullName == fingerprintChallenge.Complication)!;
40 fingerprintChallenge.Required *= complication.countMultiplier;
41 } else {
42 logger.debug(`riven rolled challenge ${fingerprintChallenge.Type}`);
43 }
44 const upgradeIndex =
45 inventory.Upgrades.push({
46 ItemType: rivenType,
47 UpgradeFingerprint: JSON.stringify({ challenge: fingerprintChallenge })
48 }) - 1;
49 await inventory.save();
50 res.json({
51 NewMod: inventory.Upgrades[upgradeIndex].toJSON()
52 });
53 };
54
55 interface IActiveRandomModRequest {
56 ItemType: string;
57 }
58
59 interface IRandomModChallenge {
60 Type: string;
61 Progress: number;
62 Required: number;
63 Complication?: string;
64 }
65
66 const rivenRawToRealWeighted: Record<string, string[]> = {
67 "/Lotus/Upgrades/Mods/Randomized/RawArchgunRandomMod": [
68 "/Lotus/Upgrades/Mods/Randomized/LotusArchgunRandomModRare"
69 ],
70 "/Lotus/Upgrades/Mods/Randomized/RawMeleeRandomMod": [
71 "/Lotus/Upgrades/Mods/Randomized/PlayerMeleeWeaponRandomModRare"
72 ],
73 "/Lotus/Upgrades/Mods/Randomized/RawModularMeleeRandomMod": [
74 "/Lotus/Upgrades/Mods/Randomized/LotusModularMeleeRandomModRare"
75 ],
76 "/Lotus/Upgrades/Mods/Randomized/RawModularPistolRandomMod": [
77 "/Lotus/Upgrades/Mods/Randomized/LotusModularPistolRandomModRare"
78 ],
79 "/Lotus/Upgrades/Mods/Randomized/RawPistolRandomMod": ["/Lotus/Upgrades/Mods/Randomized/LotusPistolRandomModRare"],
80 "/Lotus/Upgrades/Mods/Randomized/RawRifleRandomMod": ["/Lotus/Upgrades/Mods/Randomized/LotusRifleRandomModRare"],
81 "/Lotus/Upgrades/Mods/Randomized/RawShotgunRandomMod": [
82 "/Lotus/Upgrades/Mods/Randomized/LotusShotgunRandomModRare"
83 ],
84 "/Lotus/Upgrades/Mods/Randomized/RawSentinelWeaponRandomMod": [
85 "/Lotus/Upgrades/Mods/Randomized/LotusRifleRandomModRare",
86 "/Lotus/Upgrades/Mods/Randomized/LotusRifleRandomModRare",
87 "/Lotus/Upgrades/Mods/Randomized/LotusRifleRandomModRare",
88 "/Lotus/Upgrades/Mods/Randomized/LotusRifleRandomModRare",
89 "/Lotus/Upgrades/Mods/Randomized/LotusRifleRandomModRare",
90 "/Lotus/Upgrades/Mods/Randomized/LotusRifleRandomModRare",
91 "/Lotus/Upgrades/Mods/Randomized/LotusRifleRandomModRare",
92 "/Lotus/Upgrades/Mods/Randomized/LotusRifleRandomModRare",
93 "/Lotus/Upgrades/Mods/Randomized/LotusRifleRandomModRare",
94 "/Lotus/Upgrades/Mods/Randomized/LotusShotgunRandomModRare",
95 "/Lotus/Upgrades/Mods/Randomized/LotusPistolRandomModRare",
96 "/Lotus/Upgrades/Mods/Randomized/PlayerMeleeWeaponRandomModRare"
97 ]
98 };
Modified src/routes/api.ts +2 -0
@@ -1,4 +1,5 @@
1 1 import express from "express";
2 import { activateRandomModController } from "@/src/controllers/api/activateRandomModController";
2 3 import { addFriendImageController } from "@/src/controllers/api/addFriendImageController";
3 4 import { arcaneCommonController } from "@/src/controllers/api/arcaneCommonController";
4 5 import { artifactsController } from "../controllers/api/artifactsController";
@@ -108,6 +109,7 @@ apiRouter.get("/surveys.php", surveysController);
108 109 apiRouter.get("/updateSession.php", updateSessionGetController);
109 110
110 111 // post
112 apiRouter.post("/activateRandomMod.php", activateRandomModController);
111 113 apiRouter.post("/addFriendImage.php", addFriendImageController);
112 114 apiRouter.post("/arcaneCommon.php", arcaneCommonController);
113 115 apiRouter.post("/artifacts.php", artifactsController);
Modified src/services/rngService.ts +12 -0
@@ -6,6 +6,18 @@ export interface IRngResult {
6 6 probability: number;
7 7 }
8 8
9 export const getRandomElement = <T>(arr: T[]): T => {
10 return arr[Math.floor(Math.random() * arr.length)];
11 };
12
13 // Returns a random integer between min (inclusive) and max (inclusive).
14 // https://stackoverflow.com/a/1527820
15 export const getRandomInt = (min: number, max: number): number => {
16 min = Math.ceil(min);
17 max = Math.floor(max);
18 return Math.floor(Math.random() * (max - min + 1)) + min;
19 };
20
9 21 export const getRandomReward = (pool: IRngResult[]): IRngResult | undefined => {
10 22 if (pool.length == 0) return;
11 23