feat: nightwave challenge rotation
	
		
			
	
		
	
	
		
	
		
			All checks were successful
		
		
	
	
		
			
				
	
				Build / build (22) (push) Successful in 41s
				
			
		
			
				
	
				Build / build (18) (push) Successful in 1m10s
				
			
		
			
				
	
				Build / build (20) (push) Successful in 1m15s
				
			
		
			
				
	
				Build / build (18) (pull_request) Successful in 46s
				
			
		
			
				
	
				Build / build (20) (pull_request) Successful in 1m8s
				
			
		
			
				
	
				Build / build (22) (pull_request) Successful in 1m16s
				
			
		
		
	
	
				
					
				
			
		
			All checks were successful
		
		
	
	Build / build (22) (push) Successful in 41s
				
			Build / build (18) (push) Successful in 1m10s
				
			Build / build (20) (push) Successful in 1m15s
				
			Build / build (18) (pull_request) Successful in 46s
				
			Build / build (20) (pull_request) Successful in 1m8s
				
			Build / build (22) (pull_request) Successful in 1m16s
				
			This commit is contained in:
		
							parent
							
								
									2ec2b0278a
								
							
						
					
					
						commit
						8021f54084
					
				@ -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)
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
				
			|||||||
@ -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" } },
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user