feat: nightwave challenge rotation (#1317)
Some checks failed
Build Docker image / docker (push) Waiting to run
Build / build (18) (push) Has been cancelled
Build / build (22) (push) Has been cancelled
Build / build (20) (push) Has been cancelled

Reviewed-on: #1317
This commit is contained in:
Sainan 2025-03-25 06:38:30 -07:00
parent 31c1fc245f
commit eccea4ae54
2 changed files with 114 additions and 80 deletions

View File

@ -9,9 +9,16 @@ import { IMongoDate, IOid } from "@/src/types/commonTypes";
import { unixTimesInMs } from "@/src/constants/timeConstants"; import { unixTimesInMs } from "@/src/constants/timeConstants";
import { config } from "@/src/services/configService"; import { config } from "@/src/services/configService";
import { CRng } from "@/src/services/rngService"; import { CRng } from "@/src/services/rngService";
import { ExportRegions } from "warframe-public-export-plus"; import { ExportNightwave, ExportRegions } from "warframe-public-export-plus";
const EPOCH = 1734307200 * 1000; // Monday, Dec 16, 2024 @ 00:00 UTC+0; should logically be winter in 1999 iteration 0
export const worldStateController: RequestHandler = (req, res) => { export const worldStateController: RequestHandler = (req, res) => {
const day = Math.trunc((Date.now() - EPOCH) / 86400000);
const week = Math.trunc(day / 7);
const weekStart = EPOCH + week * 604800000;
const weekEnd = weekStart + 604800000;
const worldState: IWorldState = { const worldState: IWorldState = {
BuildLabel: BuildLabel:
typeof req.query.buildLabel == "string" typeof req.query.buildLabel == "string"
@ -22,6 +29,42 @@ export const worldStateController: RequestHandler = (req, res) => {
GlobalUpgrades: [], GlobalUpgrades: [],
LiteSorties: [], LiteSorties: [],
EndlessXpChoices: [], EndlessXpChoices: [],
SeasonInfo: {
Activation: { $date: { $numberLong: "1715796000000" } },
Expiry: { $date: { $numberLong: "2000000000000" } },
AffiliationTag: "RadioLegionIntermission12Syndicate",
Season: 14,
Phase: 0,
Params: "",
ActiveChallenges: [
getSeasonDailyChallenge(day - 2),
getSeasonDailyChallenge(day - 1),
getSeasonDailyChallenge(day - 0),
getSeasonWeeklyChallenge(week, 0),
getSeasonWeeklyChallenge(week, 1),
getSeasonWeeklyHardChallenge(week, 2),
getSeasonWeeklyHardChallenge(week, 3),
{
_id: { $oid: "67e1b96e9d00cb47" + (week * 7 + 0).toString().padStart(8, "0") },
Activation: { $date: { $numberLong: weekStart.toString() } },
Expiry: { $date: { $numberLong: weekEnd.toString() } },
Challenge:
"/Lotus/Types/Challenges/Seasons/Weekly/SeasonWeeklyPermanentCompleteMissions" + (week - 12)
},
{
_id: { $oid: "67e1b96e9d00cb47" + (week * 7 + 1).toString().padStart(8, "0") },
Activation: { $date: { $numberLong: weekStart.toString() } },
Expiry: { $date: { $numberLong: weekEnd.toString() } },
Challenge: "/Lotus/Types/Challenges/Seasons/Weekly/SeasonWeeklyPermanentKillEximus" + (week - 12)
},
{
_id: { $oid: "67e1b96e9d00cb47" + (week * 7 + 2).toString().padStart(8, "0") },
Activation: { $date: { $numberLong: weekStart.toString() } },
Expiry: { $date: { $numberLong: weekEnd.toString() } },
Challenge: "/Lotus/Types/Challenges/Seasons/Weekly/SeasonWeeklyPermanentKillEnemies" + (week - 12)
}
]
},
...staticWorldState ...staticWorldState
}; };
@ -42,12 +85,6 @@ export const worldStateController: RequestHandler = (req, res) => {
}); });
} }
const EPOCH = 1734307200 * 1000; // Monday, Dec 16, 2024 @ 00:00 UTC+0; should logically be winter in 1999 iteration 0
const day = Math.trunc((Date.now() - EPOCH) / 86400000);
const week = Math.trunc(day / 7);
const weekStart = EPOCH + week * 604800000;
const weekEnd = weekStart + 604800000;
// Elite Sanctuary Onslaught cycling every week // Elite Sanctuary Onslaught cycling every week
worldState.NodeOverrides.find(x => x.Node == "SolNode802")!.Seed = week; // unfaithful worldState.NodeOverrides.find(x => x.Node == "SolNode802")!.Seed = week; // unfaithful
@ -264,6 +301,15 @@ interface IWorldState {
LiteSorties: ILiteSortie[]; LiteSorties: ILiteSortie[];
NodeOverrides: INodeOverride[]; NodeOverrides: INodeOverride[];
EndlessXpChoices: IEndlessXpChoice[]; EndlessXpChoices: IEndlessXpChoice[];
SeasonInfo: {
Activation: IMongoDate;
Expiry: IMongoDate;
AffiliationTag: string;
Season: number;
Phase: number;
Params: string;
ActiveChallenges: ISeasonChallenge[];
};
KnownCalendarSeasons: ICalendarSeason[]; KnownCalendarSeasons: ICalendarSeason[];
Tmp?: string; Tmp?: string;
} }
@ -333,6 +379,14 @@ interface IEndlessXpChoice {
Choices: string[]; Choices: string[];
} }
interface ISeasonChallenge {
_id: IOid;
Daily?: boolean;
Activation: IMongoDate;
Expiry: IMongoDate;
Challenge: string;
}
interface ICalendarSeason { interface ICalendarSeason {
Activation: IMongoDate; Activation: IMongoDate;
Expiry: IMongoDate; Expiry: IMongoDate;
@ -342,3 +396,56 @@ interface ICalendarSeason {
}[]; }[];
YearIteration: number; YearIteration: number;
} }
const dailyChallenges = Object.keys(ExportNightwave.challenges).filter(x =>
x.startsWith("/Lotus/Types/Challenges/Seasons/Daily/")
);
const getSeasonDailyChallenge = (day: number): ISeasonChallenge => {
const dayStart = EPOCH + day * 86400000;
const dayEnd = EPOCH + (day + 3) * 86400000;
const rng = new CRng(day);
return {
_id: { $oid: "67e1b5ca9d00cb47" + day.toString().padStart(8, "0") },
Daily: true,
Activation: { $date: { $numberLong: dayStart.toString() } },
Expiry: { $date: { $numberLong: dayEnd.toString() } },
Challenge: rng.randomElement(dailyChallenges)
};
};
const weeklyChallenges = Object.keys(ExportNightwave.challenges).filter(
x =>
x.startsWith("/Lotus/Types/Challenges/Seasons/Weekly/") &&
!x.startsWith("/Lotus/Types/Challenges/Seasons/Weekly/SeasonWeeklyPermanent")
);
const getSeasonWeeklyChallenge = (week: number, id: number): ISeasonChallenge => {
const weekStart = EPOCH + week * 604800000;
const weekEnd = weekStart + 604800000;
const challengeId = week * 7 + id;
const rng = new CRng(challengeId);
return {
_id: { $oid: "67e1bb2d9d00cb47" + challengeId.toString().padStart(8, "0") },
Activation: { $date: { $numberLong: weekStart.toString() } },
Expiry: { $date: { $numberLong: weekEnd.toString() } },
Challenge: rng.randomElement(weeklyChallenges)
};
};
const weeklyHardChallenges = Object.keys(ExportNightwave.challenges).filter(x =>
x.startsWith("/Lotus/Types/Challenges/Seasons/WeeklyHard/")
);
const getSeasonWeeklyHardChallenge = (week: number, id: number): ISeasonChallenge => {
const weekStart = EPOCH + week * 604800000;
const weekEnd = weekStart + 604800000;
const challengeId = week * 7 + id;
const rng = new CRng(challengeId);
return {
_id: { $oid: "67e1bb2d9d00cb47" + challengeId.toString().padStart(8, "0") },
Activation: { $date: { $numberLong: weekStart.toString() } },
Expiry: { $date: { $numberLong: weekEnd.toString() } },
Challenge: rng.randomElement(weeklyHardChallenges)
};
};

View File

@ -2976,79 +2976,6 @@
"TwitchPromos": [], "TwitchPromos": [],
"ExperimentRecommended": [], "ExperimentRecommended": [],
"ForceLogoutVersion": 0, "ForceLogoutVersion": 0,
"SeasonInfo": {
"Activation": { "$date": { "$numberLong": "1715796000000" } },
"Expiry": { "$date": { "$numberLong": "2000000000000" } },
"AffiliationTag": "RadioLegionIntermission12Syndicate",
"Season": 14,
"Phase": 0,
"Params": "",
"ActiveChallenges": [
{
"_id": { "$oid": "001300010000000000000008" },
"Daily": true,
"Activation": { "$date": { "$numberLong": "1715558400000" } },
"Expiry": { "$date": { "$numberLong": "2000000000000" } },
"Challenge": "/Lotus/Types/Challenges/Seasons/Daily/SeasonDailyFeedMeMore"
},
{
"_id": { "$oid": "001300010000000000000009" },
"Daily": true,
"Activation": { "$date": { "$numberLong": "1715644800000" } },
"Expiry": { "$date": { "$numberLong": "2000000000000" } },
"Challenge": "/Lotus/Types/Challenges/Seasons/Daily/SeasonDailyTwoForOne"
},
{
"_id": { "$oid": "001300010000000000000010" },
"Daily": true,
"Activation": { "$date": { "$numberLong": "1715731200000" } },
"Expiry": { "$date": { "$numberLong": "2000000000000" } },
"Challenge": "/Lotus/Types/Challenges/Seasons/Daily/SeasonDailyKillEnemiesWithFinishers"
},
{
"_id": { "$oid": "001300010000000000000001" },
"Activation": { "$date": { "$numberLong": "1715558400000" } },
"Expiry": { "$date": { "$numberLong": "2000000000000" } },
"Challenge": "/Lotus/Types/Challenges/Seasons/Weekly/SeasonWeeklyPermanentCompleteMissions"
},
{
"_id": { "$oid": "001300010000000000000002" },
"Activation": { "$date": { "$numberLong": "1715558400000" } },
"Expiry": { "$date": { "$numberLong": "2000000000000" } },
"Challenge": "/Lotus/Types/Challenges/Seasons/Weekly/SeasonWeeklyPermanentKillEximus"
},
{
"_id": { "$oid": "001300010000000000000003" },
"Activation": { "$date": { "$numberLong": "1715558400000" } },
"Expiry": { "$date": { "$numberLong": "2000000000000" } },
"Challenge": "/Lotus/Types/Challenges/Seasons/Weekly/SeasonWeeklyPermanentKillEnemies"
},
{
"_id": { "$oid": "001300010000000000000004" },
"Activation": { "$date": { "$numberLong": "1715558400000" } },
"Expiry": { "$date": { "$numberLong": "2000000000000" } },
"Challenge": "/Lotus/Types/Challenges/Seasons/Weekly/SeasonWeeklyOpenLockers"
},
{
"_id": { "$oid": "001300010000000000000005" },
"Activation": { "$date": { "$numberLong": "1715558400000" } },
"Expiry": { "$date": { "$numberLong": "2000000000000" } },
"Challenge": "/Lotus/Types/Challenges/Seasons/Weekly/SeasonWeeklyBloodthirsty"
},
{
"_id": { "$oid": "001300010000000000000006" },
"Activation": { "$date": { "$numberLong": "1715558400000" } },
"Expiry": { "$date": { "$numberLong": "2000000000000" } },
"Challenge": "/Lotus/Types/Challenges/Seasons/WeeklyHard/SeasonWeeklyHardEliteSanctuaryOnslaught"
},
{
"_id": { "$oid": "001300010000000000000007" },
"Activation": { "$date": { "$numberLong": "1715558400000" } },
"Expiry": { "$date": { "$numberLong": "2000000000000" } },
"Challenge": "/Lotus/Types/Challenges/Seasons/WeeklyHard/SeasonWeeklyHardCompleteSortie"
}
]
},
"KnownCalendarSeasons": [ "KnownCalendarSeasons": [
{ {
"Activation": { "$date": { "$numberLong": "1733961600000" } }, "Activation": { "$date": { "$numberLong": "1733961600000" } },