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: descent generation (#3134)

Re #3129 Reviewed-on: https://onlyg.it/OpenWF/SpaceNinjaServer/pulls/3134 Co-authored-by: Sainan <63328889+Sainan@users.noreply.github.com> Co-committed-by: Sainan <63328889+Sainan@users.noreply.github.com>

5e37cd91
Sainan <63328889+Sainan@users.noreply.github.com>
提交于

代码差异

9 个文件 +1454 -4
Added src/controllers/api/descentRewardsController.ts +357 -0
@@ -0,0 +1,357 @@
1 import type { RequestHandler } from "express";
2 import { getAccountForRequest } from "../../services/loginService.ts";
3 import { getJSONfromString } from "../../helpers/stringHelpers.ts";
4 import type { TDescentCategory } from "../../types/inventoryTypes/inventoryTypes.ts";
5 import { getInventory } from "../../services/inventoryService.ts";
6 import type { ICountedStoreItem } from "warframe-public-export-plus";
7 import { getRandomElement, getRandomInt } from "../../services/rngService.ts";
8 import { logger } from "../../utils/logger.ts";
9 import { version_compare } from "../../helpers/inventoryHelpers.ts";
10 import gameToBuildVersion from "../../../static/fixed_responses/gameToBuildVersion.json" with { type: "json" };
11
12 export const descentRewardsController: RequestHandler = async (req, res) => {
13 const account = await getAccountForRequest(req);
14 if (account.BuildLabel && version_compare(account.BuildLabel, gameToBuildVersion["41.0.0"]) < 0) {
15 throw new Error(
16 `account logged into ${account.BuildLabel} (< 41.0.0) but is now attempting to call a >= 41.0.0 endpoint ?!`
17 );
18 }
19 const payload = getJSONfromString<IDescentRewardsRequest>(String(req.body));
20 if (payload.Mode == "r") {
21 const inventory = await getInventory(account._id.toString(), "DescentRewards");
22 inventory.DescentRewards ??= [];
23 let entry = inventory.DescentRewards.find(x => x.Category == payload.Category);
24 if (!entry) {
25 entry = {
26 Category: payload.Category,
27 Expiry: new Date(0),
28 FloorsClaimed: 0,
29 PendingRewards: [],
30 Seed: 0,
31 SelectedUpgrades: []
32 };
33 inventory.DescentRewards.push(entry);
34 }
35
36 const weekStart = 1734307200_000 + Math.trunc((Date.now() - 1734307200_000) / 604800000) * 604800000;
37 const weekEnd = weekStart + 604800000;
38
39 if (entry.Expiry.getTime() != weekEnd) {
40 entry.Expiry = new Date(weekEnd);
41 entry.FloorsClaimed = 0;
42 entry.PendingRewards = [
43 {
44 FloorCheckpoint: 2,
45 Rewards: [getRandomElement(bronzeRewards[payload.Category])!]
46 },
47 {
48 FloorCheckpoint: 4,
49 Rewards: [
50 getRandomElement(
51 payload.Category == "DM_COH_NORMAL" ? bronzeRewards.DM_COH_NORMAL : spSilverRewards
52 )!
53 ]
54 },
55 {
56 FloorCheckpoint: 6,
57 Rewards: [getRandomElement(arcaneRewards)!]
58 },
59 {
60 FloorCheckpoint: 9,
61 Rewards: [getRandomElement(bronzeRewards[payload.Category])!]
62 },
63 {
64 FloorCheckpoint: 11,
65 Rewards: [
66 getRandomElement(
67 payload.Category == "DM_COH_NORMAL" ? bronzeRewards.DM_COH_NORMAL : spSilverRewards
68 )!
69 ]
70 },
71 {
72 FloorCheckpoint: 13,
73 Rewards: [getRandomElement(arcaneRewards)!]
74 },
75 {
76 FloorCheckpoint: 16,
77 Rewards: [getRandomElement(bronzeRewards[payload.Category])!]
78 },
79 {
80 FloorCheckpoint: 18,
81 Rewards: [
82 payload.Category == "DM_COH_NORMAL"
83 ? getRandomElement(bronzeRewards.DM_COH_NORMAL)!
84 : {
85 StoreItem: "/Lotus/StoreItems/Types/Items/MiscItems/SteelEssence",
86 ItemCount: 25
87 }
88 ]
89 },
90 {
91 FloorCheckpoint: 20,
92 Rewards: [getRandomElement(tripleArcaneRewards)!]
93 },
94 {
95 FloorCheckpoint: 21,
96 Rewards: [getRandomElement(finalRewards[payload.Category])!]
97 }
98 ];
99 entry.Seed = getRandomInt(-1_000_000_000, 1_000_000_000);
100 entry.SelectedUpgrades = [];
101 }
102
103 await inventory.save();
104 res.json({
105 Expiry: { $date: { $numberLong: weekEnd.toString() } },
106 FloorClaimed: entry.FloorsClaimed,
107 PendingRewards: entry.PendingRewards,
108 Seed: entry.Seed,
109 SelectedUpgrades: entry.SelectedUpgrades
110 });
111 } else {
112 logger.debug(`data provided to ${req.path}: ${String(req.body)}`);
113 throw new Error(`unexpected descentRewards mode: ${payload.Mode}`);
114 }
115 };
116
117 type IDescentRewardsRequest =
118 | {
119 Mode: "r";
120 Category: TDescentCategory;
121 }
122 | {
123 Mode: "something else";
124 };
125
126 // https://wiki.warframe.com/w/The_Descendia#Rewards
127
128 const bronzeRewards: Record<TDescentCategory, ICountedStoreItem[]> = {
129 DM_COH_NORMAL: [
130 {
131 StoreItem: "/Lotus/StoreItems/Types/PickUps/Credits/10000Credits",
132 ItemCount: 3
133 },
134 {
135 StoreItem: "/Lotus/StoreItems/Upgrades/Mods/FusionBundles/JunctionRewardNPFusionBundleA",
136 ItemCount: 1
137 },
138 {
139 StoreItem: "/Lotus/StoreItems/Types/Items/MiscItems/DistillPoints",
140 ItemCount: 50
141 },
142 {
143 StoreItem: "/Lotus/StoreItems/Types/Gameplay/Tau/Resources/CoHResourceCommonItem",
144 ItemCount: 25
145 },
146 {
147 StoreItem: "/Lotus/StoreItems/Types/Gameplay/Tau/Resources/CoHResourceRareItem",
148 ItemCount: 5
149 }
150 ],
151 DM_COH_HARD: [
152 {
153 StoreItem: "/Lotus/StoreItems/Types/Gameplay/Tau/Resources/CoHResourceCommonItem",
154 ItemCount: 75
155 },
156 {
157 StoreItem: "/Lotus/StoreItems/Types/Gameplay/Tau/Resources/CoHResourceRareItem",
158 ItemCount: 15
159 }
160 ]
161 };
162
163 const arcaneRewards: ICountedStoreItem[] = [
164 {
165 StoreItem: "/Lotus/StoreItems/Upgrades/CosmeticEnhancers/Offensive/DamageForBonusArmour",
166 ItemCount: 1
167 },
168 {
169 StoreItem: "/Lotus/StoreItems/Upgrades/CosmeticEnhancers/Offensive/SplitStatusProcsOnStackedStatusHit",
170 ItemCount: 1
171 },
172 {
173 StoreItem: "/Lotus/StoreItems/Upgrades/CosmeticEnhancers/Offensive/MultishotForMaxEnergy",
174 ItemCount: 1
175 },
176 {
177 StoreItem: "/Lotus/StoreItems/Upgrades/CosmeticEnhancers/Utility/AbilityDurationOnCast",
178 ItemCount: 1
179 },
180 {
181 StoreItem: "/Lotus/StoreItems/Upgrades/CosmeticEnhancers/Defensive/ShieldMaxForAbilityStrength",
182 ItemCount: 1
183 },
184 {
185 StoreItem: "/Lotus/StoreItems/Upgrades/CosmeticEnhancers/Defensive/MaxDPSTakenForArmour",
186 ItemCount: 1
187 },
188 {
189 StoreItem: "/Lotus/StoreItems/Upgrades/CosmeticEnhancers/Defensive/StealDefensiveStatsOnRoll",
190 ItemCount: 1
191 },
192 {
193 StoreItem: "/Lotus/StoreItems/Upgrades/CosmeticEnhancers/Offensive/RadialDamageOnMaxRadiationStackHit",
194 ItemCount: 1
195 },
196 {
197 StoreItem: "/Lotus/StoreItems/Upgrades/CosmeticEnhancers/Utility/FreezeEnemiesOnRoll",
198 ItemCount: 1
199 }
200 ];
201
202 const tripleArcaneRewards: ICountedStoreItem[] = [
203 {
204 StoreItem: "/Lotus/StoreItems/Upgrades/CosmeticEnhancers/Offensive/DamageForBonusArmour",
205 ItemCount: 3
206 },
207 {
208 StoreItem: "/Lotus/StoreItems/Upgrades/CosmeticEnhancers/Offensive/SplitStatusProcsOnStackedStatusHit",
209 ItemCount: 3
210 },
211 {
212 StoreItem: "/Lotus/StoreItems/Upgrades/CosmeticEnhancers/Offensive/MultishotForMaxEnergy",
213 ItemCount: 3
214 },
215 {
216 StoreItem: "/Lotus/StoreItems/Upgrades/CosmeticEnhancers/Utility/AbilityDurationOnCast",
217 ItemCount: 3
218 },
219 {
220 StoreItem: "/Lotus/StoreItems/Upgrades/CosmeticEnhancers/Defensive/ShieldMaxForAbilityStrength",
221 ItemCount: 3
222 },
223 {
224 StoreItem: "/Lotus/StoreItems/Upgrades/CosmeticEnhancers/Defensive/MaxDPSTakenForArmour",
225 ItemCount: 3
226 },
227 {
228 StoreItem: "/Lotus/StoreItems/Upgrades/CosmeticEnhancers/Defensive/StealDefensiveStatsOnRoll",
229 ItemCount: 3
230 },
231 {
232 StoreItem: "/Lotus/StoreItems/Upgrades/CosmeticEnhancers/Offensive/RadialDamageOnMaxRadiationStackHit",
233 ItemCount: 3
234 },
235 {
236 StoreItem: "/Lotus/StoreItems/Upgrades/CosmeticEnhancers/Utility/FreezeEnemiesOnRoll",
237 ItemCount: 3
238 }
239 ];
240
241 const spSilverRewards: ICountedStoreItem[] = [
242 {
243 StoreItem: "/Lotus/StoreItems/Types/Recipes/Components/FormaBlueprint",
244 ItemCount: 1
245 },
246 {
247 StoreItem: "/Lotus/StoreItems/Upgrades/Mods/Randomized/RawMeleeRandomMod",
248 ItemCount: 1
249 },
250 {
251 StoreItem: "/Lotus/StoreItems/Upgrades/Mods/Randomized/RawPistolRandomMod",
252 ItemCount: 1
253 },
254 {
255 StoreItem: "/Lotus/StoreItems/Upgrades/Mods/Randomized/RawRifleRandomMod",
256 ItemCount: 1
257 },
258 {
259 StoreItem: "/Lotus/StoreItems/Upgrades/Mods/Randomized/RawShotgunRandomMod",
260 ItemCount: 1
261 },
262 {
263 StoreItem: "/Lotus/StoreItems/Upgrades/Mods/Randomized/RawModularMeleeRandomMod",
264 ItemCount: 1
265 },
266 {
267 StoreItem: "/Lotus/StoreItems/Upgrades/Mods/Randomized/RawModularPistolRandomMod",
268 ItemCount: 1
269 },
270 {
271 StoreItem: "/Lotus/StoreItems/Types/Items/MiscItems/WeaponPrimaryArcaneUnlocker",
272 ItemCount: 1
273 },
274 {
275 StoreItem: "/Lotus/StoreItems/Types/Items/MiscItems/WeaponSecondaryArcaneUnlocker",
276 ItemCount: 1
277 },
278 {
279 StoreItem: "/Lotus/StoreItems/Types/Items/MiscItems/WeaponMeleeArcaneUnlocker",
280 ItemCount: 1
281 },
282 {
283 StoreItem: "/Lotus/StoreItems/Types/Items/MiscItems/WeaponAmpArcaneUnlocker",
284 ItemCount: 1
285 }
286 ];
287
288 const finalRewards: Record<TDescentCategory, ICountedStoreItem[]> = {
289 DM_COH_NORMAL: [
290 {
291 StoreItem: "/Lotus/StoreItems/Types/Recipes/Components/FormaBlueprint",
292 ItemCount: 1
293 },
294 {
295 StoreItem: "/Lotus/StoreItems/Types/Items/MiscItems/WeaponPrimaryArcaneUnlocker",
296 ItemCount: 1
297 },
298 {
299 StoreItem: "/Lotus/StoreItems/Types/Items/MiscItems/WeaponSecondaryArcaneUnlocker",
300 ItemCount: 1
301 },
302 {
303 StoreItem: "/Lotus/StoreItems/Types/Items/MiscItems/WeaponMeleeArcaneUnlocker",
304 ItemCount: 1
305 },
306 {
307 StoreItem: "/Lotus/StoreItems/Types/Items/MiscItems/WeaponAmpArcaneUnlocker",
308 ItemCount: 1
309 }
310 ],
311 DM_COH_HARD: [
312 {
313 StoreItem: "/Lotus/StoreItems/Types/Items/MiscItems/OrokinCatalyst",
314 ItemCount: 1
315 },
316 {
317 StoreItem: "/Lotus/StoreItems/Types/Items/MiscItems/OrokinReactor",
318 ItemCount: 1
319 },
320 {
321 StoreItem: "/Lotus/StoreItems/Types/Recipes/Components/FormaAuraBlueprint",
322 ItemCount: 1
323 },
324 {
325 StoreItem: "/Lotus/StoreItems/Types/Recipes/Lens/AttackLensOstronBlueprint",
326 ItemCount: 1
327 },
328 {
329 StoreItem: "/Lotus/StoreItems/Types/Recipes/Lens/DefenseLensOstronBlueprint",
330 ItemCount: 1
331 },
332 {
333 StoreItem: "/Lotus/StoreItems/Types/Recipes/Lens/PowerLensOstronBlueprint",
334 ItemCount: 1
335 },
336 {
337 StoreItem: "/Lotus/StoreItems/Types/Recipes/Lens/TacticLensOstronBlueprint",
338 ItemCount: 1
339 },
340 {
341 StoreItem: "/Lotus/StoreItems/Types/Recipes/Lens/WardLensOstronBlueprint",
342 ItemCount: 1
343 },
344 {
345 StoreItem: "/Lotus/StoreItems/Types/Gameplay/NarmerSorties/ArchonCrystalAmar",
346 ItemCount: 1
347 },
348 {
349 StoreItem: "/Lotus/StoreItems/Types/Gameplay/NarmerSorties/ArchonCrystalNira",
350 ItemCount: 1
351 },
352 {
353 StoreItem: "/Lotus/StoreItems/Types/Gameplay/NarmerSorties/ArchonCrystalBoreal",
354 ItemCount: 1
355 }
356 ]
357 };
Modified src/controllers/api/purchaseController.ts +8 -2
@@ -1,5 +1,5 @@
1 1 import type { RequestHandler } from "express";
2 import { getAccountIdForRequest } from "../../services/loginService.ts";
2 import { getAccountForRequest } from "../../services/loginService.ts";
3 3 import type { IPurchaseRequest } from "../../types/purchaseTypes.ts";
4 4 import { handlePurchase } from "../../services/purchaseService.ts";
5 5 import { getInventory } from "../../services/inventoryService.ts";
@@ -7,7 +7,13 @@ import { sendWsBroadcastTo } from "../../services/wsService.ts";
7 7
8 8 export const purchaseController: RequestHandler = async (req, res) => {
9 9 const purchaseRequest = JSON.parse(String(req.body)) as IPurchaseRequest;
10 const accountId = await getAccountIdForRequest(req);
10 const account = await getAccountForRequest(req);
11 if (purchaseRequest.buildLabel && account.BuildLabel && purchaseRequest.buildLabel != account.BuildLabel) {
12 throw new Error(
13 `account logged into ${account.BuildLabel} but is now attempting a purchase in ${purchaseRequest.buildLabel} ?!`
14 );
15 }
16 const accountId = account._id.toString();
11 17 const inventory = await getInventory(accountId);
12 18 const response = await handlePurchase(purchaseRequest, inventory);
13 19 await inventory.save();
Modified src/models/inventoryModels/inventoryModel.ts +34 -1
@@ -92,7 +92,10 @@ import type {
92 92 INokkoColony,
93 93 IJournalEntry,
94 94 IDialogueResetDateClient,
95 IDialogueResetDateDatabase
95 IDialogueResetDateDatabase,
96 IDescentLevelReward,
97 IDescentCategoryRewardClient,
98 IDescentCategoryRewardDatabase
96 99 } from "../../types/inventoryTypes/inventoryTypes.ts";
97 100 import { equipmentKeys } from "../../types/inventoryTypes/inventoryTypes.ts";
98 101 import type { IOid, ITypeCount } from "../../types/commonTypes.ts";
@@ -867,6 +870,34 @@ endlessXpProgressSchema.set("toJSON", {
867 870 }
868 871 });
869 872
873 const descentLevelRewardSchema = new Schema<IDescentLevelReward>(
874 {
875 FloorCheckpoint: Number,
876 Rewards: [countedStoreItemSchema]
877 },
878 { _id: false }
879 );
880
881 const descentCategoryRewardSchema = new Schema<IDescentCategoryRewardDatabase>(
882 {
883 Category: { type: String, required: true },
884 Expiry: Date,
885 FloorsClaimed: { type: Number, default: 0 },
886 PendingRewards: { type: [descentLevelRewardSchema], default: [] },
887 Seed: Number,
888 SelectedUpgrades: { type: [String], default: [] }
889 },
890 { _id: false }
891 );
892 descentCategoryRewardSchema.set("toJSON", {
893 transform(_doc, ret: Record<string, any>) {
894 const db = ret as IDescentCategoryRewardDatabase;
895 const client = ret as IDescentCategoryRewardClient;
896
897 client.Expiry = toMongoDate(db.Expiry);
898 }
899 });
900
870 901 const crewShipWeaponEmplacementsSchema = new Schema<ICrewShipWeaponEmplacementsDatabase>(
871 902 {
872 903 PRIMARY_A: EquipmentSelectionSchema,
@@ -1862,6 +1893,8 @@ const inventorySchema = new Schema<IInventoryDatabase, InventoryDocumentProps>(
1862 1893
1863 1894 EndlessXP: { type: [endlessXpProgressSchema], default: undefined },
1864 1895
1896 DescentRewards: { type: [descentCategoryRewardSchema], default: undefined },
1897
1865 1898 DialogueHistory: dialogueHistorySchema,
1866 1899 CalendarProgress: calenderProgressSchema,
1867 1900
Modified src/routes/api.ts +3 -1
@@ -46,6 +46,7 @@ import { customObstacleCourseLeaderboardController } from "../controllers/api/cu
46 46 import { declineAllianceInviteController } from "../controllers/api/declineAllianceInviteController.ts";
47 47 import { declineGuildInviteController } from "../controllers/api/declineGuildInviteController.ts";
48 48 import { deleteSessionController } from "../controllers/api/deleteSessionController.ts";
49 import { descentRewardsController } from "../controllers/api/descentRewardsController.ts";
49 50 import { destroyDojoDecoController } from "../controllers/api/destroyDojoDecoController.ts";
50 51 import { divvyAllianceVaultController } from "../controllers/api/divvyAllianceVaultController.ts";
51 52 import { dojoComponentRushController } from "../controllers/api/dojoComponentRushController.ts";
@@ -280,6 +281,7 @@ apiRouter.post("/crewShipFusion.php", crewShipFusionController);
280 281 apiRouter.post("/crewShipIdentifySalvage.php", crewShipIdentifySalvageController);
281 282 apiRouter.post("/customizeGuildRanks.php", customizeGuildRanksController);
282 283 apiRouter.post("/customObstacleCourseLeaderboard.php", customObstacleCourseLeaderboardController);
284 apiRouter.post("/descentRewards.php", descentRewardsController);
283 285 apiRouter.post("/destroyDojoDeco.php", destroyDojoDecoController);
284 286 apiRouter.post("/dojoComponentRush.php", dojoComponentRushController);
285 287 apiRouter.post("/drones.php", dronesController);
@@ -312,6 +314,7 @@ apiRouter.post("/hubBlessing.php", hubBlessingController);
312 314 apiRouter.post("/inbox.php", inboxController); // from ~U15, don't know when they changed it to GET
313 315 apiRouter.post("/infestedFoundry.php", infestedFoundryController);
314 316 apiRouter.post("/instantCompleteRecipe.php", claimCompletedRecipeController); // U8
317 apiRouter.post("/inventory.php", inventoryController); // used by companion app
315 318 apiRouter.post("/inventorySlots.php", inventorySlotsController);
316 319 apiRouter.post("/joinSession.php", joinSessionController);
317 320 apiRouter.post("/login.php", loginController);
@@ -381,6 +384,5 @@ apiRouter.post("/updateTheme.php", updateThemeController);
381 384 apiRouter.post("/upgrades.php", upgradesController);
382 385 apiRouter.post("/valenceSwap.php", valenceSwapController);
383 386 apiRouter.post("/wishlist.php", wishlistController);
384 apiRouter.post("/inventory.php", inventoryController); // used by companion app
385 387
386 388 export { apiRouter };
Modified src/services/worldStateService.ts +8 -0
@@ -43,6 +43,7 @@ import { logger } from "../utils/logger.ts";
43 43 import { DailyDeal, Fissure } from "../models/worldStateModel.ts";
44 44 import { factionToInt, getConquest, getMissionTypeForLegacyOverride } from "./conquestService.ts";
45 45 import gameToBuildVersion from "../../static/fixed_responses/gameToBuildVersion.json" with { type: "json" };
46 import { getDescent } from "./descentService.ts";
46 47
47 48 const sortieBosses = [
48 49 "SORTIE_BOSS_HYENA",
@@ -3612,6 +3613,13 @@ export const getWorldState = (buildLabel?: string): IWorldState => {
3612 3613 }
3613 3614 }
3614 3615
3616 if (!buildLabel || version_compare(buildLabel, gameToBuildVersion["41.0.0"]) >= 0) {
3617 worldState.Descents = [getDescent(week)];
3618 if (isBeforeNextExpectedWorldStateRefresh(timeMs, weekEnd)) {
3619 worldState.Descents.push(getDescent(week + 1));
3620 }
3621 }
3622
3615 3623 // Sentient Anomaly + Xtra Cheese cycles
3616 3624 const halfHour = Math.trunc(timeMs / (unixTimesInMs.hour / 2));
3617 3625 const hourInSeconds = 3600;
Modified src/types/inventoryTypes/inventoryTypes.ts +23 -0
@@ -111,6 +111,7 @@ export interface IInventoryDatabase
111 111 | "QualifyingInvasions"
112 112 | "LastInventorySync"
113 113 | "EndlessXP"
114 | "DescentRewards"
114 115 | "PersonalGoalProgress"
115 116 | "CurrentLoadOutIds"
116 117 | TEquipmentKey
@@ -156,6 +157,7 @@ export interface IInventoryDatabase
156 157 QualifyingInvasions: IInvasionProgressDatabase[];
157 158 LastInventorySync?: Types.ObjectId;
158 159 EndlessXP?: IEndlessXpProgressDatabase[];
160 DescentRewards?: IDescentCategoryRewardDatabase[];
159 161 PersonalGoalProgress?: IGoalProgressDatabase[];
160 162 MissionRelicRewards?: ITypeCount[];
161 163 }
@@ -419,6 +421,7 @@ export interface IInventoryClient extends IDailyAffiliations, InventoryClientEqu
419 421 Harvestable: boolean;
420 422 DeathSquadable: boolean;
421 423 EndlessXP?: IEndlessXpProgressClient[];
424 DescentRewards?: IDescentCategoryRewardClient[];
422 425 DialogueHistory?: IDialogueHistoryClient;
423 426 CalendarProgress?: ICalendarProgress;
424 427 SongChallenges?: ISongChallenge[];
@@ -1129,6 +1132,26 @@ export interface IEndlessXpReward {
1129 1132 Rewards: ICountedStoreItem[];
1130 1133 }
1131 1134
1135 export type TDescentCategory = "DM_COH_NORMAL" | "DM_COH_HARD";
1136
1137 export interface IDescentCategoryRewardClient {
1138 Category: TDescentCategory;
1139 Expiry: IMongoDate;
1140 FloorsClaimed: number;
1141 PendingRewards: IDescentLevelReward[];
1142 Seed: number;
1143 SelectedUpgrades: string[];
1144 }
1145
1146 export interface IDescentCategoryRewardDatabase extends Omit<IDescentCategoryRewardClient, "Expiry"> {
1147 Expiry: Date;
1148 }
1149
1150 export interface IDescentLevelReward {
1151 FloorCheckpoint: number;
1152 Rewards: ICountedStoreItem[];
1153 }
1154
1132 1155 export interface IDialogueHistoryClient {
1133 1156 YearIteration?: number;
1134 1157 Resets?: number; // added in 38.5.0, removed in 41.0.0
Modified src/types/worldStateTypes.ts +17 -0
@@ -36,6 +36,7 @@ export interface IWorldState {
36 36 };
37 37 KnownCalendarSeasons: ICalendarSeason[];
38 38 Conquests?: IConquest[];
39 Descents?: IDescent[];
39 40 Tmp?: string;
40 41 }
41 42
@@ -468,6 +469,22 @@ export interface IConquestMission {
468 469 ];
469 470 }
470 471
472 export interface IDescent {
473 Activation: IMongoDate;
474 Expiry: IMongoDate;
475 RandSeed: number;
476 Challenges: IDescentFloor[];
477 }
478
479 export interface IDescentFloor {
480 Index: number; // 1..21
481 Type: string;
482 Challenge: string;
483 Level: string;
484 Specs: string[];
485 Auras: string[];
486 }
487
471 488 export interface ITmp {
472 489 cavabegin: string;
473 490 PurchasePlatformLockEnabled: boolean; // Seems unused
Modified static/fixed_responses/gameToBuildVersion.json +1 -0
@@ -1,4 +1,5 @@
1 1 {
2 "41.0.0": "2025.12.09.14.18",
2 3 "40.0.0": "2025.09.25.17.01",
3 4 "39.1.0": "2025.08.26.09.49",
4 5 "38.6.0": "2025.05.20.10.18",