From 870c96485452aa6eca27b07a1be8d789367dc1c0 Mon Sep 17 00:00:00 2001 From: Sainan <63328889+Sainan@users.noreply.github.com> Date: Mon, 9 Jun 2025 06:54:58 -0700 Subject: [PATCH] feat: add eidolonOverride & vallisOverride to replace lockTime (#2135) I think for now it's best to keep the client time somewhat in sync with the server/database time to avoid various issues. Reviewed-on: https://onlyg.it/OpenWF/SpaceNinjaServer/pulls/2135 Co-authored-by: Sainan <63328889+Sainan@users.noreply.github.com> Co-committed-by: Sainan <63328889+Sainan@users.noreply.github.com> --- README.md | 3 +- config.json.example | 3 +- src/services/configService.ts | 3 +- src/services/worldStateService.ts | 55 ++++++++++++++++++++++++++++++- 4 files changed, 60 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 24d3b2fb..e8d2b419 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,8 @@ 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`. - `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.eidolonOverride` can be set to `day` or `night` to lock the time to day/fass and night/vome on Plains of Eidolon/Cambion Drift. +- `worldState.vallisOverride` can be set to `warm` or `cold` to lock the temperature on Orb Vallis. - `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 diff --git a/config.json.example b/config.json.example index 4000024f..b9ebaab0 100644 --- a/config.json.example +++ b/config.json.example @@ -55,7 +55,8 @@ "affinityBoost": false, "resourceBoost": false, "starDays": true, - "lockTime": 0, + "eidolonOverride": "", + "vallisOverride": "", "nightwaveOverride": "" } } diff --git a/src/services/configService.ts b/src/services/configService.ts index ba67cf06..dc8a78bc 100644 --- a/src/services/configService.ts +++ b/src/services/configService.ts @@ -61,7 +61,8 @@ interface IConfig { affinityBoost?: boolean; resourceBoost?: boolean; starDays?: boolean; - lockTime?: number; + eidolonOverride?: string; + vallisOverride?: string; nightwaveOverride?: string; }; } diff --git a/src/services/worldStateService.ts b/src/services/worldStateService.ts index 5bea6f20..e2041907 100644 --- a/src/services/worldStateService.ts +++ b/src/services/worldStateService.ts @@ -939,8 +939,61 @@ const getCalendarSeason = (week: number): ICalendarSeason => { }; }; +const doesTimeSatsifyConstraints = (timeSecs: number): boolean => { + if (config.worldState?.eidolonOverride) { + const eidolonEpoch = 1391992660; + const eidolonCycle = Math.trunc((timeSecs - eidolonEpoch) / 9000); + const eidolonCycleStart = eidolonEpoch + eidolonCycle * 9000; + const eidolonCycleEnd = eidolonCycleStart + 9000; + const eidolonCycleNightStart = eidolonCycleEnd - 3000; + if (config.worldState.eidolonOverride == "day") { + if ( + //timeSecs < eidolonCycleStart || + isBeforeNextExpectedWorldStateRefresh(timeSecs * 1000, eidolonCycleNightStart * 1000) + ) { + return false; + } + } else { + if ( + timeSecs < eidolonCycleNightStart || + isBeforeNextExpectedWorldStateRefresh(timeSecs * 1000, eidolonCycleEnd * 1000) + ) { + return false; + } + } + } + + if (config.worldState?.vallisOverride) { + const vallisEpoch = 1541837628; + const vallisCycle = Math.trunc((timeSecs - vallisEpoch) / 1600); + const vallisCycleStart = vallisEpoch + vallisCycle * 1600; + const vallisCycleEnd = vallisCycleStart + 1600; + const vallisCycleColdStart = vallisCycleStart + 400; + if (config.worldState.vallisOverride == "cold") { + if ( + timeSecs < vallisCycleColdStart || + isBeforeNextExpectedWorldStateRefresh(timeSecs * 1000, vallisCycleEnd * 1000) + ) { + return false; + } + } else { + if ( + //timeSecs < vallisCycleStart || + isBeforeNextExpectedWorldStateRefresh(timeSecs * 1000, vallisCycleColdStart * 1000) + ) { + return false; + } + } + } + + return true; +}; + export const getWorldState = (buildLabel?: string): IWorldState => { - const timeSecs = config.worldState?.lockTime || Math.round(Date.now() / 1000); + let timeSecs = Math.round(Date.now() / 1000); + while (!doesTimeSatsifyConstraints(timeSecs)) { + timeSecs -= 60; + } const timeMs = timeSecs * 1000; const day = Math.trunc((timeMs - EPOCH) / 86400000); const week = Math.trunc(day / 7);