返回提交历史
Modified
src/services/missionInventoryUpdateService.ts
+18
-3
Modified
src/services/worldStateService.ts
+32
-28
XFEstudio/XFESpaceNinjaServer
fix: don't give sortie assassination rewards if mission type differs (#1992)
Closes #1987 Reviewed-on: https://onlyg.it/OpenWF/SpaceNinjaServer/pulls/1992 Co-authored-by: Sainan <63328889+Sainan@users.noreply.github.com> Co-committed-by: Sainan <63328889+Sainan@users.noreply.github.com>
da6d75c7
代码差异
2 个文件
+50
-31
@@ -58,7 +58,7 @@ import conservationAnimals from "@/static/fixed_responses/conservationAnimals.js
58
58
import { getInfNodes, getWeaponsForManifest, sendCodaFinishedMessage } from "@/src/helpers/nemesisHelpers";
59
59
import { Loadout } from "../models/inventoryModels/loadoutModel";
60
60
import { ILoadoutConfigDatabase } from "../types/saveLoadoutTypes";
61
import { getLiteSortie, getWorldState, idToWeek } from "./worldStateService";
61
import { getLiteSortie, getSortie, getWorldState, idToDay, idToWeek } from "./worldStateService";
62
62
import { config } from "./configService";
63
63
import libraryDailyTasks from "@/static/fixed_responses/libraryDailyTasks.json";
64
64
@@ -1357,9 +1357,24 @@ function getRandomMissionDrops(
1357
1357
// Invasion assassination has Phorid has the boss who should drop Nyx parts
1358
1358
// TODO: Check that the invasion faction is indeed FC_INFESTATION once the Invasions in worldState are more dynamic
1359
1359
rewardManifests = ["/Lotus/Types/Game/MissionDecks/BossMissionRewards/NyxRewards"];
1360
} else if (RewardInfo.sortieId && region.missionIndex != 0) {
1360
} else if (RewardInfo.sortieId) {
1361
1361
// Sortie mission types differ from the underlying node and hence also don't give rewards from the underlying nodes. Assassinations are an exception to this.
1362
rewardManifests = [];
1362
if (region.missionIndex == 0) {
1363
const arr = RewardInfo.sortieId.split("_");
1364
let sortieId = arr[1];
1365
if (sortieId == "Lite") {
1366
sortieId = arr[2];
1367
}
1368
const sortie = getSortie(idToDay(sortieId));
1369
const mission = sortie.Variants.find(x => x.node == arr[0])!;
1370
if (mission.missionType == "MT_ASSASSINATION") {
1371
rewardManifests = region.rewardManifests;
1372
} else {
1373
rewardManifests = [];
1374
}
1375
} else {
1376
rewardManifests = [];
1377
}
1363
1378
} else {
1364
1379
rewardManifests = region.rewardManifests;
1365
1380
}
@@ -12,6 +12,7 @@ import {
12
12
ICalendarSeason,
13
13
ILiteSortie,
14
14
ISeasonChallenge,
15
ISortie,
15
16
ISortieMission,
16
17
IWorldState
17
18
} from "../types/worldStateTypes";
@@ -193,12 +194,6 @@ const pushSyndicateMissions = (
193
194
idSuffix: string,
194
195
syndicateTag: string
195
196
): void => {
196
const dayStart = getSortieTime(day);
197
if (Date.now() >= dayStart) {
198
return; // The client does not seem to respect activation.
199
}
200
const dayEnd = getSortieTime(day + 1);
201
202
197
const nodeOptions: string[] = [...syndicateMissions];
203
198
204
199
const rng = new CRng(seed);
@@ -209,6 +204,8 @@ const pushSyndicateMissions = (
209
204
nodeOptions.splice(index, 1);
210
205
}
211
206
207
const dayStart = getSortieTime(day);
208
const dayEnd = getSortieTime(day + 1);
212
209
worldState.SyndicateMissions.push({
213
210
_id: { $oid: ((dayStart / 1000) & 0xffffffff).toString(16).padStart(8, "0") + idSuffix },
214
211
Activation: { $date: { $numberLong: dayStart.toString() } },
@@ -219,16 +216,7 @@ const pushSyndicateMissions = (
219
216
});
220
217
};
221
218
222
const pushSortieIfRelevant = (worldState: IWorldState, day: number): void => {
223
const dayStart = getSortieTime(day);
224
if (!isBeforeNextExpectedWorldStateRefresh(dayStart)) {
225
return;
226
}
227
const dayEnd = getSortieTime(day + 1);
228
if (Date.now() >= dayEnd) {
229
return;
230
}
231
219
export const getSortie = (day: number): ISortie => {
232
220
const seed = new CRng(day).randomInt(0, 0xffff);
233
221
const rng = new CRng(seed);
234
222
@@ -375,7 +363,9 @@ const pushSortieIfRelevant = (worldState: IWorldState, day: number): void => {
375
363
missionTypes.add(missionType);
376
364
}
377
365
378
worldState.Sorties.push({
366
const dayStart = getSortieTime(day);
367
const dayEnd = getSortieTime(day + 1);
368
return {
379
369
_id: { $oid: ((dayStart / 1000) & 0xffffffff).toString(16).padStart(8, "0") + "d4d932c97c0a3acd" },
380
370
Activation: { $date: { $numberLong: dayStart.toString() } },
381
371
Expiry: { $date: { $numberLong: dayEnd.toString() } },
@@ -383,14 +373,7 @@ const pushSortieIfRelevant = (worldState: IWorldState, day: number): void => {
383
373
Seed: seed,
384
374
Boss: boss,
385
375
Variants: selectedNodes
386
});
387
388
pushSyndicateMissions(worldState, day, rng.randomInt(0, 0xffff), "ba6f84724fa48049", "ArbitersSyndicate");
389
pushSyndicateMissions(worldState, day, rng.randomInt(0, 0xffff), "ba6f84724fa4804a", "CephalonSudaSyndicate");
390
pushSyndicateMissions(worldState, day, rng.randomInt(0, 0xffff), "ba6f84724fa4804e", "NewLokaSyndicate");
391
pushSyndicateMissions(worldState, day, rng.randomInt(0, 0xffff), "ba6f84724fa48050", "PerrinSyndicate");
392
pushSyndicateMissions(worldState, day, rng.randomInt(0, 0xffff), "ba6f84724fa4805e", "RedVeilSyndicate");
393
pushSyndicateMissions(worldState, day, rng.randomInt(0, 0xffff), "ba6f84724fa48061", "SteelMeridianSyndicate");
376
};
394
377
};
395
378
396
379
const dailyChallenges = Object.keys(ExportNightwave.challenges).filter(x =>
@@ -1099,8 +1082,25 @@ export const getWorldState = (buildLabel?: string): IWorldState => {
1099
1082
}
1100
1083
1101
1084
// Sortie & syndicate missions cycling every day (at 16:00 or 17:00 UTC depending on if London, OT is observing DST)
1102
pushSortieIfRelevant(worldState, day - 1);
1103
pushSortieIfRelevant(worldState, day);
1085
{
1086
const rollover = getSortieTime(day);
1087
1088
if (Date.now() < rollover) {
1089
worldState.Sorties.push(getSortie(day - 1));
1090
}
1091
if (isBeforeNextExpectedWorldStateRefresh(rollover)) {
1092
worldState.Sorties.push(getSortie(day));
1093
}
1094
1095
// The client does not seem to respect activation for classic syndicate missions, so only pushing current ones.
1096
const rng = new CRng(Date.now() >= rollover ? day : day - 1);
1097
pushSyndicateMissions(worldState, day, rng.randomInt(0, 0xffff), "ba6f84724fa48049", "ArbitersSyndicate");
1098
pushSyndicateMissions(worldState, day, rng.randomInt(0, 0xffff), "ba6f84724fa4804a", "CephalonSudaSyndicate");
1099
pushSyndicateMissions(worldState, day, rng.randomInt(0, 0xffff), "ba6f84724fa4804e", "NewLokaSyndicate");
1100
pushSyndicateMissions(worldState, day, rng.randomInt(0, 0xffff), "ba6f84724fa48050", "PerrinSyndicate");
1101
pushSyndicateMissions(worldState, day, rng.randomInt(0, 0xffff), "ba6f84724fa4805e", "RedVeilSyndicate");
1102
pushSyndicateMissions(worldState, day, rng.randomInt(0, 0xffff), "ba6f84724fa48061", "SteelMeridianSyndicate");
1103
}
1104
1104
1105
1105
// Archon Hunt cycling every week
1106
1106
worldState.LiteSorties.push(getLiteSortie(week));
@@ -1178,8 +1178,12 @@ export const getWorldState = (buildLabel?: string): IWorldState => {
1178
1178
return worldState;
1179
1179
};
1180
1180
1181
export const idToDay = (id: string): number => {
1182
return Math.trunc((parseInt(id.substring(0, 8), 16) * 1000 - EPOCH) / 86400_000);
1183
};
1184
1181
1185
export const idToWeek = (id: string): number => {
1182
return (parseInt(id.substring(0, 8), 16) * 1000 - EPOCH) / 604800000;
1186
return Math.trunc((parseInt(id.substring(0, 8), 16) * 1000 - EPOCH) / 604800_000);
1183
1187
};
1184
1188
1185
1189
export const getLiteSortie = (week: number): ILiteSortie => {