返回提交历史
Modified
src/services/worldStateService.ts
+44
-31
XFEstudio/XFESpaceNinjaServer
fix: eidolon clock drift (#3641)
Reviewed-on: https://onlyg.it/OpenWF/SpaceNinjaServer/pulls/3641 Co-authored-by: Sainan <63328889+Sainan@users.noreply.github.com> Co-committed-by: Sainan <63328889+Sainan@users.noreply.github.com>
3011d08e
代码差异
1 个文件
+44
-31
@@ -832,6 +832,13 @@ export const pushWeeklyActs = (
832
832
pushSeasonWeeklyChallenge(activeChallenges, pools.hardWeekly, nightwaveSeason, week, 6);
833
833
};
834
834
835
const eidolonEpoch = 1391990400;
836
const timeOfDayRate = 0.0026670000515878;
837
const eidolonCycleDuration = 24 / timeOfDayRate;
838
const eidolonHourDuration = eidolonCycleDuration / 24;
839
840
const bountyEpoch = eidolonEpoch + 5 * eidolonHourDuration;
841
835
842
const generateXpAmounts = (rng: SRng, stageCount: number, minXp: number, maxXp: number): number[] => {
836
843
const step = minXp < 1000 ? 1 : 10;
837
844
const totalDeciXp = rng.randomInt(minXp / step, maxXp / step);
@@ -868,8 +875,8 @@ export const pushClassicBounties = (
868
875
const deimosDTable = String.fromCharCode(65 + (bountyCycle % 2));
869
876
870
877
const seed = new SRng(bountyCycle).randomInt(0, 100_000);
871
const bountyCycleStart = bountyCycle * 9000000;
872
const bountyCycleEnd = bountyCycleStart + 9000000;
878
const bountyCycleStart = Math.trunc((bountyEpoch + bountyCycle * eidolonCycleDuration) * 1000);
879
const bountyCycleEnd = Math.trunc(bountyCycleStart + eidolonCycleDuration * 1000);
873
880
874
881
if (!buildLabel || version_compare(buildLabel, gameToBuildVersion["22.0.0"]) >= 0) {
875
882
const rng = new SRng(seed);
@@ -1451,45 +1458,51 @@ interface ITimeConstraint {
1451
1458
const eidolonDayConstraint: ITimeConstraint = {
1452
1459
name: "eidolon day",
1453
1460
isValidTime: (timeSecs: number): boolean => {
1454
const eidolonEpoch = 1391992660;
1455
const eidolonCycle = Math.trunc((timeSecs - eidolonEpoch) / 9000);
1456
const eidolonCycleStart = eidolonEpoch + eidolonCycle * 9000;
1457
const eidolonCycleEnd = eidolonCycleStart + 9000;
1458
const eidolonCycleNightStart = eidolonCycleEnd - 3000;
1459
return !isBeforeNextExpectedWorldStateRefresh(timeSecs * 1000, eidolonCycleNightStart * 1000);
1461
const eidolonCycle = Math.trunc((timeSecs - eidolonEpoch) / eidolonCycleDuration);
1462
const eidolonCycleStart = eidolonEpoch + eidolonCycle * eidolonCycleDuration;
1463
const hour = 24 * (((timeSecs - eidolonEpoch) % eidolonCycleDuration) / eidolonCycleDuration);
1464
// const isDay = hour > 5 && hour < 21.9;
1465
if (hour > 5) {
1466
const eidolonCycleNightStart = eidolonCycleStart + 21.9 * eidolonHourDuration;
1467
return !isBeforeNextExpectedWorldStateRefresh(timeSecs * 1000, eidolonCycleNightStart * 1000);
1468
}
1469
return false;
1460
1470
},
1461
1471
getIdealTimeBefore: (timeSecs: number): number => {
1462
const eidolonEpoch = 1391992660;
1463
const eidolonCycle = Math.trunc((timeSecs - eidolonEpoch) / 9000);
1464
const eidolonCycleStart = eidolonEpoch + eidolonCycle * 9000;
1465
return eidolonCycleStart;
1472
const eidolonCycle = Math.trunc((timeSecs - eidolonEpoch) / eidolonCycleDuration);
1473
const eidolonCycleStart = eidolonEpoch + eidolonCycle * eidolonCycleDuration;
1474
const hour = 24 * (((timeSecs - eidolonEpoch) % eidolonCycleDuration) / eidolonCycleDuration);
1475
if (hour > 5) {
1476
return Math.trunc(eidolonCycleStart + 5 * eidolonHourDuration); // Today's morning
1477
} else {
1478
return Math.trunc(eidolonCycleStart - eidolonCycleDuration + 5 * eidolonHourDuration); // Yesterday's morning
1479
}
1466
1480
}
1467
1481
};
1468
1482
1469
1483
const eidolonNightConstraint: ITimeConstraint = {
1470
1484
name: "eidolon night",
1471
1485
isValidTime: (timeSecs: number): boolean => {
1472
const eidolonEpoch = 1391992660;
1473
const eidolonCycle = Math.trunc((timeSecs - eidolonEpoch) / 9000);
1474
const eidolonCycleStart = eidolonEpoch + eidolonCycle * 9000;
1475
const eidolonCycleEnd = eidolonCycleStart + 9000;
1476
const eidolonCycleNightStart = eidolonCycleEnd - 3000;
1477
return (
1478
timeSecs >= eidolonCycleNightStart &&
1479
!isBeforeNextExpectedWorldStateRefresh(timeSecs * 1000, eidolonCycleEnd * 1000)
1480
);
1486
const eidolonCycle = Math.trunc((timeSecs - eidolonEpoch) / eidolonCycleDuration);
1487
const eidolonCycleStart = eidolonEpoch + eidolonCycle * eidolonCycleDuration;
1488
const hour = 24 * (((timeSecs - eidolonEpoch) % eidolonCycleDuration) / eidolonCycleDuration);
1489
if (hour > 5) {
1490
const eidolonCycleNightStart = eidolonCycleStart + 21.9 * eidolonHourDuration;
1491
return timeSecs >= eidolonCycleNightStart;
1492
} else {
1493
const eidolonCycleDayStart = eidolonCycleStart + 5 * eidolonHourDuration;
1494
return !isBeforeNextExpectedWorldStateRefresh(timeSecs * 1000, eidolonCycleDayStart * 1000);
1495
}
1481
1496
},
1482
1497
getIdealTimeBefore: (timeSecs: number): number => {
1483
const eidolonEpoch = 1391992660;
1484
const eidolonCycle = Math.trunc((timeSecs - eidolonEpoch) / 9000);
1485
const eidolonCycleStart = eidolonEpoch + eidolonCycle * 9000;
1486
const eidolonCycleEnd = eidolonCycleStart + 9000;
1487
const eidolonCycleNightStart = eidolonCycleEnd - 3000;
1498
const eidolonCycle = Math.trunc((timeSecs - eidolonEpoch) / eidolonCycleDuration);
1499
const eidolonCycleStart = eidolonEpoch + eidolonCycle * eidolonCycleDuration;
1500
const eidolonCycleNightStart = eidolonCycleStart + 21.9 * eidolonHourDuration;
1488
1501
if (eidolonCycleNightStart > timeSecs) {
1489
1502
// Night hasn't started yet, but we need to return a time in the past.
1490
return eidolonCycleNightStart - 9000;
1503
return Math.trunc(eidolonCycleNightStart - eidolonCycleDuration);
1491
1504
}
1492
return eidolonCycleNightStart;
1505
return Math.trunc(eidolonCycleNightStart);
1493
1506
}
1494
1507
};
1495
1508
@@ -3576,11 +3589,11 @@ export const getWorldState = (buildLabel?: string): IWorldState => {
3576
3589
worldState.NodeOverrides.find(x => x.Node == "SolNode802")!.Seed = new SRng(week).randomInt(0, 0xff_ffff);
3577
3590
3578
3591
// Holdfast, Cavia, & Hex bounties cycling every 2.5 hours; unfaithful implementation
3579
let bountyCycle = Math.trunc(timeSecs / 9000);
3592
let bountyCycle = Math.trunc((timeSecs - bountyEpoch) / eidolonCycleDuration);
3580
3593
let bountyCycleEnd: number | undefined;
3581
3594
do {
3582
const bountyCycleStart = bountyCycle * 9000000;
3583
bountyCycleEnd = bountyCycleStart + 9000000;
3595
const bountyCycleStart = Math.trunc((bountyEpoch + bountyCycle * eidolonCycleDuration) * 1000);
3596
bountyCycleEnd = Math.trunc(bountyCycleStart + eidolonCycleDuration * 1000);
3584
3597
worldState.SyndicateMissions.push({
3585
3598
_id: { $oid: ((bountyCycleStart / 1000) & 0xffffffff).toString(16).padStart(8, "0") + "0000000000000029" },
3586
3599
Activation: { $date: { $numberLong: bountyCycleStart.toString() } },