chore: update PE+ (#2765)
Some checks failed
Build Docker image / docker-amd64 (push) Waiting to run
Build Docker image / docker-arm64 (push) Has been cancelled
Build / build (push) Has been cancelled

Some things were deprecated in it

Reviewed-on: #2765
Co-authored-by: Sainan <63328889+Sainan@users.noreply.github.com>
Co-committed-by: Sainan <63328889+Sainan@users.noreply.github.com>
This commit is contained in:
Sainan 2025-09-09 23:54:46 -07:00 committed by Sainan
parent 5a9415ae0c
commit 8a7db2cd85
7 changed files with 52 additions and 50 deletions

8
package-lock.json generated
View File

@ -17,7 +17,7 @@
"morgan": "^1.10.0", "morgan": "^1.10.0",
"ncp": "^2.0.0", "ncp": "^2.0.0",
"undici": "^7.10.0", "undici": "^7.10.0",
"warframe-public-export-plus": "^0.5.83", "warframe-public-export-plus": "^0.5.86",
"warframe-riven-info": "^0.1.2", "warframe-riven-info": "^0.1.2",
"winston": "^3.17.0", "winston": "^3.17.0",
"winston-daily-rotate-file": "^5.0.0", "winston-daily-rotate-file": "^5.0.0",
@ -5532,9 +5532,9 @@
} }
}, },
"node_modules/warframe-public-export-plus": { "node_modules/warframe-public-export-plus": {
"version": "0.5.84", "version": "0.5.86",
"resolved": "https://registry.npmjs.org/warframe-public-export-plus/-/warframe-public-export-plus-0.5.84.tgz", "resolved": "https://registry.npmjs.org/warframe-public-export-plus/-/warframe-public-export-plus-0.5.86.tgz",
"integrity": "sha512-ZpI1Y5CgWDmCwM4/oQpv9u0GD6KFvsJ9f1vJVXYhm5VD9DdOJcFzXgXgg98HXJ5JHbO16ZGIj83117qdpd0RQA==" "integrity": "sha512-tWJudKs4WdjFNiF6ipav9md3sboPXJFvSItTfSmT9ko+Xgg1QP75vS/qPsuPw67pqzMaSnAbHpEzNn/rZ4mCug=="
}, },
"node_modules/warframe-riven-info": { "node_modules/warframe-riven-info": {
"version": "0.1.2", "version": "0.1.2",

View File

@ -35,7 +35,7 @@
"morgan": "^1.10.0", "morgan": "^1.10.0",
"ncp": "^2.0.0", "ncp": "^2.0.0",
"undici": "^7.10.0", "undici": "^7.10.0",
"warframe-public-export-plus": "^0.5.83", "warframe-public-export-plus": "^0.5.86",
"warframe-riven-info": "^0.1.2", "warframe-riven-info": "^0.1.2",
"winston": "^3.17.0", "winston": "^3.17.0",
"winston-daily-rotate-file": "^5.0.0", "winston-daily-rotate-file": "^5.0.0",

View File

@ -212,12 +212,12 @@ export const getInfNodes = (manifest: INemesisManifest, rank: number): IInfNode[
value.systemIndex === systemIndex && value.systemIndex === systemIndex &&
value.nodeType != 3 && // not hub value.nodeType != 3 && // not hub
value.nodeType != 7 && // not junction value.nodeType != 7 && // not junction
value.missionIndex && // must have a mission type and not assassination value.missionType != "MT_ASSASSINATION" &&
value.missionIndex != 28 && // not open world value.missionType != "MT_LANDSCAPE" &&
value.missionIndex != 32 && // not railjack value.missionType != "MT_RAILJACK" &&
value.missionIndex != 41 && // not saya's visions value.missionType != "MT_OFFERING" &&
value.missionIndex != 42 && // not face off value.missionType != "MT_PVPVE" &&
value.name.indexOf("1999NodeI") == -1 && // not stage defence value.name.indexOf("1999NodeI") == -1 && // not stage defense
value.name.indexOf("1999NodeJ") == -1 && // not lich bounty value.name.indexOf("1999NodeJ") == -1 && // not lich bounty
!isArchwingMission(value) !isArchwingMission(value)
) { ) {

View File

@ -2160,7 +2160,7 @@ export const addMissionComplete = (inventory: TInventoryDatabaseDocument, { Tag,
} }
}; };
export const addBooster = (ItemType: string, time: number, inventory: TInventoryDatabaseDocument): void => { export const addBooster = (ItemType: string, timeSecs: number, inventory: TInventoryDatabaseDocument): void => {
const currentTime = Math.floor(Date.now() / 1000); const currentTime = Math.floor(Date.now() / 1000);
const { Boosters } = inventory; const { Boosters } = inventory;
@ -2169,9 +2169,9 @@ export const addBooster = (ItemType: string, time: number, inventory: TInventory
if (itemIndex !== -1) { if (itemIndex !== -1) {
const existingBooster = Boosters[itemIndex]; const existingBooster = Boosters[itemIndex];
existingBooster.ExpiryDate = Math.max(existingBooster.ExpiryDate, currentTime) + time; existingBooster.ExpiryDate = Math.max(existingBooster.ExpiryDate, currentTime) + timeSecs;
} else { } else {
Boosters.push({ ItemType, ExpiryDate: currentTime + time }); Boosters.push({ ItemType, ExpiryDate: currentTime + timeSecs });
} }
}; };

View File

@ -1,4 +1,9 @@
import type { IMissionReward as IMissionRewardExternal, IRegion, IReward } from "warframe-public-export-plus"; import type {
IMissionReward as IMissionRewardExternal,
IRegion,
IReward,
TMissionType
} from "warframe-public-export-plus";
import { import {
ExportEnemies, ExportEnemies,
ExportFusionBundles, ExportFusionBundles,
@ -102,10 +107,9 @@ const getRotations = (rewardInfo: IRewardInfo, tierOverride?: number): number[]
} }
const region = ExportRegions[rewardInfo.node] as IRegion | undefined; const region = ExportRegions[rewardInfo.node] as IRegion | undefined;
const missionIndex: number | undefined = region?.missionIndex; const missionType: TMissionType | undefined = region?.missionType;
// For Rescue missions if (missionType == "MT_RESCUE" && rewardInfo.rewardTier) {
if (missionIndex == 3 && rewardInfo.rewardTier) {
return [rewardInfo.rewardTier]; return [rewardInfo.rewardTier];
} }
@ -123,7 +127,7 @@ const getRotations = (rewardInfo: IRewardInfo, tierOverride?: number): number[]
// Empty or absent rewardQualifications should not give rewards when: // Empty or absent rewardQualifications should not give rewards when:
// - Completing only 1 zone of (E)SO (https://onlyg.it/OpenWF/SpaceNinjaServer/issues/1823) // - Completing only 1 zone of (E)SO (https://onlyg.it/OpenWF/SpaceNinjaServer/issues/1823)
// - Aborting a railjack mission (https://onlyg.it/OpenWF/SpaceNinjaServer/issues/1741) // - Aborting a railjack mission (https://onlyg.it/OpenWF/SpaceNinjaServer/issues/1741)
if (rotationCount == 0 && missionIndex != 30 && missionIndex != 32) { if (rotationCount == 0 && missionType != "MT_ENDLESS_EXTERMINATION" && missionType != "MT_RAILJACK") {
return [0]; return [0];
} }
@ -1095,8 +1099,8 @@ const isEligibleForCreditReward = (rewardInfo: IRewardInfo, missions: IMission,
} }
// The rest here might not be needed anymore, but just to be sure we don't give undue credits... // The rest here might not be needed anymore, but just to be sure we don't give undue credits...
return ( return (
node.missionIndex != 23 && // junction node.missionType != "MT_JUNCTION" &&
node.missionIndex != 28 && // open world node.missionType != "MT_LANDSCAPE" &&
missions.Tag != "SolNode761" && // the index missions.Tag != "SolNode761" && // the index
missions.Tag != "SolNode762" && // the index missions.Tag != "SolNode762" && // the index
missions.Tag != "SolNode763" && // the index missions.Tag != "SolNode763" && // the index
@ -1792,14 +1796,14 @@ function getRandomMissionDrops(
let rewardManifests: string[]; let rewardManifests: string[];
if (RewardInfo.periodicMissionTag == "EliteAlert" || RewardInfo.periodicMissionTag == "EliteAlertB") { if (RewardInfo.periodicMissionTag == "EliteAlert" || RewardInfo.periodicMissionTag == "EliteAlertB") {
rewardManifests = ["/Lotus/Types/Game/MissionDecks/EliteAlertMissionRewards/EliteAlertMissionRewards"]; rewardManifests = ["/Lotus/Types/Game/MissionDecks/EliteAlertMissionRewards/EliteAlertMissionRewards"];
} else if (RewardInfo.invasionId && region.missionIndex == 0) { } else if (RewardInfo.invasionId && region.missionType == "MT_ASSASSINATION") {
// Invasion assassination has Phorid has the boss who should drop Nyx parts // Invasion assassination has Phorid has the boss who should drop Nyx parts
// TODO: Check that the invasion faction is indeed FC_INFESTATION once the Invasions in worldState are more dynamic // TODO: Check that the invasion faction is indeed FC_INFESTATION once the Invasions in worldState are more dynamic
rewardManifests = ["/Lotus/Types/Game/MissionDecks/BossMissionRewards/NyxRewards"]; rewardManifests = ["/Lotus/Types/Game/MissionDecks/BossMissionRewards/NyxRewards"];
} else if (RewardInfo.sortieId) { } else if (RewardInfo.sortieId) {
// Sortie mission types differ from the underlying node and hence also don't give rewards from the underlying nodes. // Sortie mission types differ from the underlying node and hence also don't give rewards from the underlying nodes.
// Assassinations in non-lite sorties are an exception to this. // Assassinations in non-lite sorties are an exception to this.
if (region.missionIndex == 0) { if (region.missionType == "MT_ASSASSINATION") {
const arr = RewardInfo.sortieId.split("_"); const arr = RewardInfo.sortieId.split("_");
let giveNodeReward = false; let giveNodeReward = false;
if (arr[1] != "Lite") { if (arr[1] != "Lite") {
@ -2165,7 +2169,7 @@ function getRandomMissionDrops(
const deck = ExportRewards["/Lotus/Types/Game/MissionDecks/NightmareModeRewards"]; const deck = ExportRewards["/Lotus/Types/Game/MissionDecks/NightmareModeRewards"];
let rotation = 0; let rotation = 0;
if (region.missionIndex === 3 && RewardInfo.rewardTier) { if (region.missionType == "MT_RESCUE" && RewardInfo.rewardTier) {
rotation = RewardInfo.rewardTier; rotation = RewardInfo.rewardTier;
} else if ([6, 7, 8, 10, 11].includes(region.systemIndex)) { } else if ([6, 7, 8, 10, 11].includes(region.systemIndex)) {
rotation = 2; rotation = 2;

View File

@ -20,7 +20,6 @@ import type {
import { PurchaseSource } from "../types/purchaseTypes.ts"; import { PurchaseSource } from "../types/purchaseTypes.ts";
import { logger } from "../utils/logger.ts"; import { logger } from "../utils/logger.ts";
import { getWorldState } from "./worldStateService.ts"; import { getWorldState } from "./worldStateService.ts";
import type { TRarity } from "warframe-public-export-plus";
import { import {
ExportBoosterPacks, ExportBoosterPacks,
ExportBoosters, ExportBoosters,
@ -419,7 +418,7 @@ export const handleBundleAcqusition = async (
component.typeName, component.typeName,
inventory, inventory,
component.purchaseQuantity * quantity, component.purchaseQuantity * quantity,
component.durability, component.durabilityDays,
true true
) )
).InventoryChanges ).InventoryChanges
@ -432,7 +431,7 @@ export const handleStoreItemAcquisition = async (
storeItemName: string, storeItemName: string,
inventory: TInventoryDatabaseDocument, inventory: TInventoryDatabaseDocument,
quantity: number = 1, quantity: number = 1,
durability: TRarity = "COMMON", durabilityDays: number = 3,
ignorePurchaseQuantity: boolean = false, ignorePurchaseQuantity: boolean = false,
premiumPurchase: boolean = true, premiumPurchase: boolean = true,
seed?: bigint seed?: bigint
@ -482,7 +481,7 @@ export const handleStoreItemAcquisition = async (
); );
break; break;
case "Boosters": case "Boosters":
purchaseResponse = handleBoostersPurchase(storeItemName, inventory, durability); purchaseResponse = handleBoostersPurchase(storeItemName, inventory, durabilityDays);
break; break;
} }
} }
@ -672,7 +671,7 @@ const handleTypesPurchase = async (
const handleBoostersPurchase = ( const handleBoostersPurchase = (
boosterStoreName: string, boosterStoreName: string,
inventory: TInventoryDatabaseDocument, inventory: TInventoryDatabaseDocument,
durability: TRarity durabilityDays: number
): { InventoryChanges: IInventoryChanges } => { ): { InventoryChanges: IInventoryChanges } => {
if (!(boosterStoreName in ExportBoosters)) { if (!(boosterStoreName in ExportBoosters)) {
logger.error(`unknown booster type: ${boosterStoreName}`); logger.error(`unknown booster type: ${boosterStoreName}`);
@ -680,7 +679,7 @@ const handleBoostersPurchase = (
} }
const ItemType = ExportBoosters[boosterStoreName].typeName; const ItemType = ExportBoosters[boosterStoreName].typeName;
const ExpiryDate = ExportMisc.boosterDurations[durability]; const ExpiryDate = durabilityDays * 86400;
addBooster(ItemType, ExpiryDate, inventory); addBooster(ItemType, ExpiryDate, inventory);

View File

@ -13,8 +13,8 @@ import { buildConfig } from "./buildConfigService.ts";
import { unixTimesInMs } from "../constants/timeConstants.ts"; import { unixTimesInMs } from "../constants/timeConstants.ts";
import { config } from "./configService.ts"; import { config } from "./configService.ts";
import { getRandomElement, getRandomInt, sequentiallyUniqueRandomElement, SRng } from "./rngService.ts"; import { getRandomElement, getRandomInt, sequentiallyUniqueRandomElement, SRng } from "./rngService.ts";
import type { IMissionReward, IRegion } from "warframe-public-export-plus"; import type { IMissionReward, IRegion, TFaction } from "warframe-public-export-plus";
import { eMissionType, ExportRegions, ExportSyndicates } from "warframe-public-export-plus"; import { ExportRegions, ExportSyndicates } from "warframe-public-export-plus";
import type { import type {
ICalendarDay, ICalendarDay,
ICalendarEvent, ICalendarEvent,
@ -87,11 +87,11 @@ const sortieFactionToSystemIndexes: Record<string, number[]> = {
FC_OROKIN: [14] FC_OROKIN: [14]
}; };
const sortieFactionToFactionIndexes: Record<string, number[]> = { const sortieFactionToFactions: Record<string, TFaction[]> = {
FC_GRINEER: [0], FC_GRINEER: ["FC_GRINEER"],
FC_CORPUS: [1], FC_CORPUS: ["FC_CORPUS"],
FC_INFESTATION: [0, 1, 2], FC_INFESTATION: ["FC_GRINEER", "FC_CORPUS", "FC_INFESTATION"],
FC_OROKIN: [3] FC_OROKIN: ["FC_OROKIN"]
}; };
const sortieBossNode: Record<Exclude<TSortieBoss, "SORTIE_BOSS_CORRUPTED_VOR">, string> = { const sortieBossNode: Record<Exclude<TSortieBoss, "SORTIE_BOSS_CORRUPTED_VOR">, string> = {
@ -271,7 +271,7 @@ export const getSortie = (day: number): ISortie => {
for (const [key, value] of Object.entries(ExportRegions)) { for (const [key, value] of Object.entries(ExportRegions)) {
if ( if (
sortieFactionToSystemIndexes[sortieBossToFaction[boss]].includes(value.systemIndex) && sortieFactionToSystemIndexes[sortieBossToFaction[boss]].includes(value.systemIndex) &&
sortieFactionToFactionIndexes[sortieBossToFaction[boss]].includes(value.factionIndex!) && sortieFactionToFactions[sortieBossToFaction[boss]].includes(value.faction!) &&
key in sortieTilesets && key in sortieTilesets &&
(key != "SolNode228" || sortieBossToFaction[boss] == "FC_GRINEER") // PoE does not work for non-infested enemies (key != "SolNode228" || sortieBossToFaction[boss] == "FC_GRINEER") // PoE does not work for non-infested enemies
) { ) {
@ -339,10 +339,10 @@ export const getSortie = (day: number): ISortie => {
modifiers.push("SORTIE_MODIFIER_HAZARD_RADIATION"); modifiers.push("SORTIE_MODIFIER_HAZARD_RADIATION");
} }
if (ExportRegions[node].factionIndex == 0) { if (ExportRegions[node].faction == "FC_GRINEER") {
// Grineer // Grineer
modifiers.push("SORTIE_MODIFIER_ARMOR"); modifiers.push("SORTIE_MODIFIER_ARMOR");
} else if (ExportRegions[node].factionIndex == 1) { } else if (ExportRegions[node].faction == "FC_CORPUS") {
// Corpus // Corpus
modifiers.push("SORTIE_MODIFIER_SHIELDS"); modifiers.push("SORTIE_MODIFIER_SHIELDS");
} }
@ -1306,7 +1306,7 @@ const createInvasion = (day: number, idx: number): IInvasion => {
), ),
Goal: 30000, // Value seems to range from 30000 to 98000 in intervals of 1000. Higher values are increasingly rare. I don't think this is relevant for the frontend besides dividing count by it. Goal: 30000, // Value seems to range from 30000 to 98000 in intervals of 1000. Higher values are increasingly rare. I don't think this is relevant for the frontend besides dividing count by it.
LocTag: isInfestationOutbreak LocTag: isInfestationOutbreak
? ExportRegions[node].missionIndex == 0 ? ExportRegions[node].missionType == "MT_ASSASSINATION"
? "/Lotus/Language/Menu/InfestedInvasionBoss" ? "/Lotus/Language/Menu/InfestedInvasionBoss"
: "/Lotus/Language/Menu/InfestedInvasionGeneric" : "/Lotus/Language/Menu/InfestedInvasionGeneric"
: attacker == "FC_CORPUS" : attacker == "FC_CORPUS"
@ -3179,7 +3179,7 @@ export const populateFissures = async (worldState: IWorldState): Promise<void> =
Activation: { $date: { $numberLong: "1000000000000" } }, Activation: { $date: { $numberLong: "1000000000000" } },
Expiry: { $date: { $numberLong: "2000000000000" } }, Expiry: { $date: { $numberLong: "2000000000000" } },
Node: node, Node: node,
MissionType: eMissionType[meta.missionIndex].tag, MissionType: meta.missionType,
Modifier: tier, Modifier: tier,
Hard: config.worldState.allTheFissures == "hard" Hard: config.worldState.allTheFissures == "hard"
}); });
@ -3199,7 +3199,7 @@ export const populateFissures = async (worldState: IWorldState): Promise<void> =
: toMongoDate(fissure.Activation), : toMongoDate(fissure.Activation),
Expiry: toMongoDate(fissure.Expiry), Expiry: toMongoDate(fissure.Expiry),
Node: fissure.Node, Node: fissure.Node,
MissionType: eMissionType[meta.missionIndex].tag, MissionType: meta.missionType,
Modifier: fissure.Modifier, Modifier: fissure.Modifier,
Hard: fissure.Hard Hard: fissure.Hard
}); });
@ -3246,13 +3246,12 @@ export const getLiteSortie = (week: number): ILiteSortie => {
for (const [key, value] of Object.entries(ExportRegions)) { for (const [key, value] of Object.entries(ExportRegions)) {
if ( if (
value.systemIndex === systemIndex && value.systemIndex === systemIndex &&
value.factionIndex !== undefined && (value.faction == "FC_GRINEER" || value.faction == "FC_CORPUS") &&
value.factionIndex < 2 &&
!isArchwingMission(value) && !isArchwingMission(value) &&
value.missionIndex != 0 && // Exclude MT_ASSASSINATION value.missionType != "MT_ASSASSINATION" &&
value.missionIndex != 23 && // Exclude junctions value.missionType != "MT_JUNCTION" &&
value.missionIndex != 28 && // Exclude open worlds value.missionType != "MT_LANDSCAPE" &&
value.missionIndex != 32 // Exclude railjack value.missionType != "MT_RAILJACK"
) { ) {
nodes.push(key); nodes.push(key);
} }
@ -3309,7 +3308,7 @@ export const isArchwingMission = (node: IRegion): boolean => {
return true; return true;
} }
// SettlementNode10 // SettlementNode10
if (node.missionIndex == 25) { if (node.missionType == "MT_RACE") {
return true; return true;
} }
return false; return false;