forked from OpenWF/SpaceNinjaServer
		
	feat: add nightwaveOverride to config (#2120)
Reviewed-on: OpenWF/SpaceNinjaServer#2120 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:
		
							parent
							
								
									8f5f2fc206
								
							
						
					
					
						commit
						5c5296d565
					
				
							
								
								
									
										17
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										17
									
								
								README.md
									
									
									
									
									
								
							@ -15,3 +15,20 @@ SpaceNinjaServer requires a `config.json`. To set it up, you can copy the [confi
 | 
				
			|||||||
- `logger.level` can be `fatal`, `error`, `warn`, `info`, `http`, `debug`, or `trace`.
 | 
					- `logger.level` can be `fatal`, `error`, `warn`, `info`, `http`, `debug`, or `trace`.
 | 
				
			||||||
- `myIrcAddresses` can be used to point to an IRC server. If not provided, defaults to `[ myAddress ]`.
 | 
					- `myIrcAddresses` can be used to point to an IRC server. If not provided, defaults to `[ myAddress ]`.
 | 
				
			||||||
- `worldState.lockTime` will lock the time provided in worldState if nonzero, e.g. `1743202800` for night in POE.
 | 
					- `worldState.lockTime` will lock the time provided in worldState if nonzero, e.g. `1743202800` for night in POE.
 | 
				
			||||||
 | 
					- `worldState.nightwaveOverride` will lock the nightwave season, assuming the client is new enough for it. Valid values:
 | 
				
			||||||
 | 
					  - `RadioLegionIntermission13Syndicate` for Nora's Mix Vol. 9
 | 
				
			||||||
 | 
					  - `RadioLegionIntermission12Syndicate` for Nora's Mix Vol. 8
 | 
				
			||||||
 | 
					  - `RadioLegionIntermission11Syndicate` for Nora's Mix Vol. 7
 | 
				
			||||||
 | 
					  - `RadioLegionIntermission10Syndicate` for Nora's Mix Vol. 6
 | 
				
			||||||
 | 
					  - `RadioLegionIntermission9Syndicate` for Nora's Mix Vol. 5
 | 
				
			||||||
 | 
					  - `RadioLegionIntermission8Syndicate` for Nora's Mix Vol. 4
 | 
				
			||||||
 | 
					  - `RadioLegionIntermission7Syndicate` for Nora's Mix Vol. 3
 | 
				
			||||||
 | 
					  - `RadioLegionIntermission6Syndicate` for Nora's Mix Vol. 2
 | 
				
			||||||
 | 
					  - `RadioLegionIntermission5Syndicate` for Nora's Mix Vol. 1
 | 
				
			||||||
 | 
					  - `RadioLegionIntermission4Syndicate` for Nora's Choice
 | 
				
			||||||
 | 
					  - `RadioLegionIntermission3Syndicate` for Intermission III
 | 
				
			||||||
 | 
					  - `RadioLegion3Syndicate` for Glassmaker
 | 
				
			||||||
 | 
					  - `RadioLegionIntermission2Syndicate` for Intermission II
 | 
				
			||||||
 | 
					  - `RadioLegion2Syndicate` for The Emissary
 | 
				
			||||||
 | 
					  - `RadioLegionIntermissionSyndicate` for Intermission I
 | 
				
			||||||
 | 
					  - `RadioLegionSyndicate` for The Wolf of Saturn Six
 | 
				
			||||||
 | 
				
			|||||||
@ -55,6 +55,7 @@
 | 
				
			|||||||
    "affinityBoost": false,
 | 
					    "affinityBoost": false,
 | 
				
			||||||
    "resourceBoost": false,
 | 
					    "resourceBoost": false,
 | 
				
			||||||
    "starDays": true,
 | 
					    "starDays": true,
 | 
				
			||||||
    "lockTime": 0
 | 
					    "lockTime": 0,
 | 
				
			||||||
 | 
					    "nightwaveOverride": ""
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -62,6 +62,7 @@ interface IConfig {
 | 
				
			|||||||
        resourceBoost?: boolean;
 | 
					        resourceBoost?: boolean;
 | 
				
			||||||
        starDays?: boolean;
 | 
					        starDays?: boolean;
 | 
				
			||||||
        lockTime?: number;
 | 
					        lockTime?: number;
 | 
				
			||||||
 | 
					        nightwaveOverride?: string;
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -348,6 +348,7 @@ interface IRotatingSeasonChallengePools {
 | 
				
			|||||||
    daily: string[];
 | 
					    daily: string[];
 | 
				
			||||||
    weekly: string[];
 | 
					    weekly: string[];
 | 
				
			||||||
    hardWeekly: string[];
 | 
					    hardWeekly: string[];
 | 
				
			||||||
 | 
					    hasWeeklyPermanent: boolean;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const getSeasonChallengePools = (syndicateTag: string): IRotatingSeasonChallengePools => {
 | 
					const getSeasonChallengePools = (syndicateTag: string): IRotatingSeasonChallengePools => {
 | 
				
			||||||
@ -359,7 +360,12 @@ const getSeasonChallengePools = (syndicateTag: string): IRotatingSeasonChallenge
 | 
				
			|||||||
                x.startsWith("/Lotus/Types/Challenges/Seasons/Weekly/") &&
 | 
					                x.startsWith("/Lotus/Types/Challenges/Seasons/Weekly/") &&
 | 
				
			||||||
                !x.startsWith("/Lotus/Types/Challenges/Seasons/Weekly/SeasonWeeklyPermanent")
 | 
					                !x.startsWith("/Lotus/Types/Challenges/Seasons/Weekly/SeasonWeeklyPermanent")
 | 
				
			||||||
        ),
 | 
					        ),
 | 
				
			||||||
        hardWeekly: syndicate.weeklyChallenges!.filter(x => x.startsWith("/Lotus/Types/Challenges/Seasons/WeeklyHard/"))
 | 
					        hardWeekly: syndicate.weeklyChallenges!.filter(x =>
 | 
				
			||||||
 | 
					            x.startsWith("/Lotus/Types/Challenges/Seasons/WeeklyHard/")
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        hasWeeklyPermanent: !!syndicate.weeklyChallenges!.find(x =>
 | 
				
			||||||
 | 
					            x.startsWith("/Lotus/Types/Challenges/Seasons/Weekly/SeasonWeeklyPermanent")
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -416,26 +422,34 @@ const pushWeeklyActs = (
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    activeChallenges.push(getSeasonWeeklyChallenge(pools, week, 0));
 | 
					    activeChallenges.push(getSeasonWeeklyChallenge(pools, week, 0));
 | 
				
			||||||
    activeChallenges.push(getSeasonWeeklyChallenge(pools, week, 1));
 | 
					    activeChallenges.push(getSeasonWeeklyChallenge(pools, week, 1));
 | 
				
			||||||
    activeChallenges.push(getSeasonWeeklyHardChallenge(pools, week, 2));
 | 
					    if (pools.hasWeeklyPermanent) {
 | 
				
			||||||
    activeChallenges.push(getSeasonWeeklyHardChallenge(pools, week, 3));
 | 
					        activeChallenges.push({
 | 
				
			||||||
    activeChallenges.push({
 | 
					            _id: { $oid: "67e1b96e9d00cb47" + (week * 7 + 0).toString().padStart(8, "0") },
 | 
				
			||||||
        _id: { $oid: "67e1b96e9d00cb47" + (week * 7 + 0).toString().padStart(8, "0") },
 | 
					            Activation: { $date: { $numberLong: weekStart.toString() } },
 | 
				
			||||||
        Activation: { $date: { $numberLong: weekStart.toString() } },
 | 
					            Expiry: { $date: { $numberLong: weekEnd.toString() } },
 | 
				
			||||||
        Expiry: { $date: { $numberLong: weekEnd.toString() } },
 | 
					            Challenge: "/Lotus/Types/Challenges/Seasons/Weekly/SeasonWeeklyPermanentCompleteMissions"
 | 
				
			||||||
        Challenge: "/Lotus/Types/Challenges/Seasons/Weekly/SeasonWeeklyPermanentCompleteMissions"
 | 
					        });
 | 
				
			||||||
    });
 | 
					        activeChallenges.push({
 | 
				
			||||||
    activeChallenges.push({
 | 
					            _id: { $oid: "67e1b96e9d00cb47" + (week * 7 + 1).toString().padStart(8, "0") },
 | 
				
			||||||
        _id: { $oid: "67e1b96e9d00cb47" + (week * 7 + 1).toString().padStart(8, "0") },
 | 
					            Activation: { $date: { $numberLong: weekStart.toString() } },
 | 
				
			||||||
        Activation: { $date: { $numberLong: weekStart.toString() } },
 | 
					            Expiry: { $date: { $numberLong: weekEnd.toString() } },
 | 
				
			||||||
        Expiry: { $date: { $numberLong: weekEnd.toString() } },
 | 
					            Challenge: "/Lotus/Types/Challenges/Seasons/Weekly/SeasonWeeklyPermanentKillEximus"
 | 
				
			||||||
        Challenge: "/Lotus/Types/Challenges/Seasons/Weekly/SeasonWeeklyPermanentKillEximus"
 | 
					        });
 | 
				
			||||||
    });
 | 
					        activeChallenges.push({
 | 
				
			||||||
    activeChallenges.push({
 | 
					            _id: { $oid: "67e1b96e9d00cb47" + (week * 7 + 2).toString().padStart(8, "0") },
 | 
				
			||||||
        _id: { $oid: "67e1b96e9d00cb47" + (week * 7 + 2).toString().padStart(8, "0") },
 | 
					            Activation: { $date: { $numberLong: weekStart.toString() } },
 | 
				
			||||||
        Activation: { $date: { $numberLong: weekStart.toString() } },
 | 
					            Expiry: { $date: { $numberLong: weekEnd.toString() } },
 | 
				
			||||||
        Expiry: { $date: { $numberLong: weekEnd.toString() } },
 | 
					            Challenge: "/Lotus/Types/Challenges/Seasons/Weekly/SeasonWeeklyPermanentKillEnemies"
 | 
				
			||||||
        Challenge: "/Lotus/Types/Challenges/Seasons/Weekly/SeasonWeeklyPermanentKillEnemies"
 | 
					        });
 | 
				
			||||||
    });
 | 
					        activeChallenges.push(getSeasonWeeklyHardChallenge(pools, week, 2));
 | 
				
			||||||
 | 
					        activeChallenges.push(getSeasonWeeklyHardChallenge(pools, week, 3));
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        activeChallenges.push(getSeasonWeeklyChallenge(pools, week, 2));
 | 
				
			||||||
 | 
					        activeChallenges.push(getSeasonWeeklyChallenge(pools, week, 3));
 | 
				
			||||||
 | 
					        activeChallenges.push(getSeasonWeeklyChallenge(pools, week, 4));
 | 
				
			||||||
 | 
					        activeChallenges.push(getSeasonWeeklyHardChallenge(pools, week, 5));
 | 
				
			||||||
 | 
					        activeChallenges.push(getSeasonWeeklyHardChallenge(pools, week, 6));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const pushClassicBounties = (syndicateMissions: ISyndicateMissionInfo[], bountyCycle: number): void => {
 | 
					export const pushClassicBounties = (syndicateMissions: ISyndicateMissionInfo[], bountyCycle: number): void => {
 | 
				
			||||||
@ -1258,6 +1272,9 @@ export const isArchwingMission = (node: IRegion): boolean => {
 | 
				
			|||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const getNightwaveSyndicateTag = (buildLabel: string | undefined): string | undefined => {
 | 
					export const getNightwaveSyndicateTag = (buildLabel: string | undefined): string | undefined => {
 | 
				
			||||||
 | 
					    if (config.worldState?.nightwaveOverride) {
 | 
				
			||||||
 | 
					        return config.worldState.nightwaveOverride;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    if (!buildLabel || version_compare(buildLabel, "2025.05.20.10.18") >= 0) {
 | 
					    if (!buildLabel || version_compare(buildLabel, "2025.05.20.10.18") >= 0) {
 | 
				
			||||||
        return "RadioLegionIntermission13Syndicate";
 | 
					        return "RadioLegionIntermission13Syndicate";
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -1268,6 +1285,20 @@ export const getNightwaveSyndicateTag = (buildLabel: string | undefined): string
 | 
				
			|||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const nightwaveTagToSeason: Record<string, number> = {
 | 
					const nightwaveTagToSeason: Record<string, number> = {
 | 
				
			||||||
    RadioLegionIntermission13Syndicate: 15,
 | 
					    RadioLegionIntermission13Syndicate: 15, // Nora's Mix Vol. 9
 | 
				
			||||||
    RadioLegionIntermission12Syndicate: 14
 | 
					    RadioLegionIntermission12Syndicate: 14, // Nora's Mix Vol. 8
 | 
				
			||||||
 | 
					    RadioLegionIntermission11Syndicate: 13, // Nora's Mix Vol. 7
 | 
				
			||||||
 | 
					    RadioLegionIntermission10Syndicate: 12, // Nora's Mix Vol. 6
 | 
				
			||||||
 | 
					    RadioLegionIntermission9Syndicate: 11, // Nora's Mix Vol. 5
 | 
				
			||||||
 | 
					    RadioLegionIntermission8Syndicate: 10, // Nora's Mix Vol. 4
 | 
				
			||||||
 | 
					    RadioLegionIntermission7Syndicate: 9, // Nora's Mix Vol. 3
 | 
				
			||||||
 | 
					    RadioLegionIntermission6Syndicate: 8, // Nora's Mix Vol. 2
 | 
				
			||||||
 | 
					    RadioLegionIntermission5Syndicate: 7, // Nora's Mix Vol. 1
 | 
				
			||||||
 | 
					    RadioLegionIntermission4Syndicate: 6, // Nora's Choice
 | 
				
			||||||
 | 
					    RadioLegionIntermission3Syndicate: 5, // Intermission III
 | 
				
			||||||
 | 
					    RadioLegion3Syndicate: 4, // Glassmaker
 | 
				
			||||||
 | 
					    RadioLegionIntermission2Syndicate: 3, // Intermission II
 | 
				
			||||||
 | 
					    RadioLegion2Syndicate: 2, // The Emissary
 | 
				
			||||||
 | 
					    RadioLegionIntermissionSyndicate: 1, // Intermission I
 | 
				
			||||||
 | 
					    RadioLegionSyndicate: 0 // The Wolf of Saturn Six
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user