返回提交历史
Modified
src/helpers/inventoryHelpers.ts
+21
-8
Modified
src/services/worldStateService.ts
+47
-44
Modified
src/types/commonTypes.ts
+7
-0
Modified
src/types/worldStateTypes.ts
+5
-5
Modified
static/fixed_responses/gameToBuildVersion.json
+2
-0
XFEstudio/XFESpaceNinjaServer
feat: legacy conclave challanges generator (#3144)
Re #1192 Reviewed-on: https://onlyg.it/OpenWF/SpaceNinjaServer/pulls/3144 Reviewed-by: Sainan <63328889+sainan@users.noreply.github.com> Co-authored-by: AMelonInsideLemon <166175391+AMelonInsideLemon@users.noreply.github.com> Co-committed-by: AMelonInsideLemon <166175391+AMelonInsideLemon@users.noreply.github.com>
7fa06db4
代码差异
5 个文件
+82
-57
@@ -1,4 +1,4 @@
1
import type { IMongoDate, IOid, IOidWithLegacySupport } from "../types/commonTypes.ts";
1
import type { IMongoDateWithLegacySupport, IMongoDate, IOid, IOidWithLegacySupport } from "../types/commonTypes.ts";
2
2
import { Types } from "mongoose";
3
3
import type { TRarity } from "warframe-public-export-plus";
4
4
import type { IFusionTreasure } from "../types/inventoryTypes/inventoryTypes.ts";
@@ -31,13 +31,25 @@ export const toOid = (objectId: Types.ObjectId): IOid => {
31
31
return { $oid: objectId.toString() };
32
32
};
33
33
34
export function toOid2(objectId: Types.ObjectId, buildLabel: undefined): IOid;
35
export function toOid2(objectId: Types.ObjectId, buildLabel: string | undefined): IOidWithLegacySupport;
36
export function toOid2(objectId: Types.ObjectId, buildLabel: string | undefined): IOidWithLegacySupport {
34
export function toOid2(objectId: Types.ObjectId | string, buildLabel: undefined): IOid;
35
export function toOid2(objectId: Types.ObjectId | string, buildLabel: string | undefined): IOidWithLegacySupport;
36
export function toOid2(objectId: Types.ObjectId | string, buildLabel: string | undefined): IOidWithLegacySupport {
37
const oid = typeof objectId == "string" ? objectId : objectId.toString();
37
38
if (buildLabel && version_compare(buildLabel, gameToBuildVersion["19.5.0"]) <= 0) {
38
return { $id: objectId.toString() };
39
return { $id: oid };
39
40
}
40
return { $oid: objectId.toString() };
41
return { $oid: oid };
42
}
43
44
export function toMongoDate2(value: Date | number, buildLabel: undefined): IMongoDate;
45
export function toMongoDate2(value: Date | number, buildLabel: string | undefined): IMongoDateWithLegacySupport;
46
export function toMongoDate2(value: Date | number, buildLabel: string | undefined): IMongoDateWithLegacySupport {
47
const ms = value instanceof Date ? value.getTime() : value;
48
if (buildLabel && version_compare(buildLabel, gameToBuildVersion["19.5.0"]) <= 0) {
49
return { sec: Math.floor(ms / 1000), usec: (ms % 1000) * 1000 };
50
}
51
52
return { $date: { $numberLong: ms.toString() } };
41
53
}
42
54
43
55
export const toLegacyOid = (oid: IOidWithLegacySupport): void => {
@@ -60,8 +72,9 @@ export const toMongoDate = (date: Date): IMongoDate => {
60
72
return { $date: { $numberLong: date.getTime().toString() } };
61
73
};
62
74
63
export const fromMongoDate = (date: IMongoDate): Date => {
64
return new Date(parseInt(date.$date.$numberLong));
75
export const fromMongoDate = (date: IMongoDateWithLegacySupport): Date => {
76
if ("$date" in date) return new Date(parseInt(date.$date.$numberLong));
77
return new Date(date.sec * 1000 + Math.floor(date.usec / 1000));
65
78
};
66
79
67
80
export const parseFusionTreasure = (name: string, count: number): IFusionTreasure => {
@@ -38,7 +38,7 @@ import type {
38
38
TCircuitGameMode,
39
39
IFlashSale
40
40
} from "../types/worldStateTypes.ts";
41
import { toMongoDate, toOid, version_compare } from "../helpers/inventoryHelpers.ts";
41
import { toMongoDate, toMongoDate2, toOid, toOid2, version_compare } from "../helpers/inventoryHelpers.ts";
42
42
import { logger } from "../utils/logger.ts";
43
43
import { DailyDeal, Fissure } from "../models/worldStateModel.ts";
44
44
import { factionToInt, getConquest, getMissionTypeForLegacyOverride } from "./conquestService.ts";
@@ -3561,20 +3561,27 @@ export const getWorldState = (buildLabel?: string): IWorldState => {
3561
3561
pushSyndicateMissions(worldState, sdy, rng.randomInt(0, 100_000), "ba6f84724fa48061", "SteelMeridianSyndicate");
3562
3562
}
3563
3563
3564
{
3565
const conclaveDayStart = EPOCH + day * unixTimesInMs.day + 5 * unixTimesInMs.hour + 30 * unixTimesInMs.minute;
3566
const conclaveDayEnd = conclaveDayStart + unixTimesInMs.day;
3567
const conclaveWeekStart = weekStart + 40 * unixTimesInMs.minute - 2 * unixTimesInMs.day;
3568
const conclaveWeekEnd = conclaveWeekStart + unixTimesInMs.week;
3564
if (buildLabel && version_compare(buildLabel, gameToBuildVersion["17.7.1"]) >= 0) {
3565
if (version_compare(buildLabel, gameToBuildVersion["18.0.2"]) >= 0) {
3566
const conclaveWeekStart = weekStart + 40 * unixTimesInMs.minute - 2 * unixTimesInMs.day;
3567
const conclaveWeekEnd = conclaveWeekStart + unixTimesInMs.week;
3569
3568
3570
pushConclaveWeakly(worldState.PVPChallengeInstances, week);
3571
pushConclaveDailys(worldState.PVPChallengeInstances, day);
3569
pushConclaveWeakly(worldState.PVPChallengeInstances, week, buildLabel);
3572
3570
3573
if (isBeforeNextExpectedWorldStateRefresh(timeMs, conclaveDayEnd)) {
3574
pushConclaveDailys(worldState.PVPChallengeInstances, day + 1);
3571
if (isBeforeNextExpectedWorldStateRefresh(timeMs, conclaveWeekEnd)) {
3572
pushConclaveWeakly(worldState.PVPChallengeInstances, week + 1, buildLabel);
3573
}
3575
3574
}
3576
if (isBeforeNextExpectedWorldStateRefresh(timeMs, conclaveWeekEnd)) {
3577
pushConclaveWeakly(worldState.PVPChallengeInstances, week + 1);
3575
3576
{
3577
const conclaveDayStart =
3578
EPOCH + day * unixTimesInMs.day + 5 * unixTimesInMs.hour + 30 * unixTimesInMs.minute;
3579
const conclaveDayEnd = conclaveDayStart + unixTimesInMs.day;
3580
pushConclaveDailys(worldState.PVPChallengeInstances, day, buildLabel);
3581
3582
if (isBeforeNextExpectedWorldStateRefresh(timeMs, conclaveDayEnd)) {
3583
pushConclaveDailys(worldState.PVPChallengeInstances, day + 1, buildLabel);
3584
}
3578
3585
}
3579
3586
}
3580
3587
@@ -4018,8 +4025,10 @@ const pushConclaveDaily = (
4018
4025
DuringSingleMatch?: boolean;
4019
4026
}[],
4020
4027
day: number,
4021
id: number
4028
id: number,
4029
buildLabel: string
4022
4030
): void => {
4031
if (version_compare(buildLabel, gameToBuildVersion["18.0.2"]) < 0) PVPMode = PVPMode.replace("PVPMODE_", "");
4023
4032
const conclaveDayStart = EPOCH + day * unixTimesInMs.day + 5 * unixTimesInMs.hour + 30 * unixTimesInMs.minute;
4024
4033
const conclaveDayEnd = conclaveDayStart + unixTimesInMs.day;
4025
4034
const challengeId = day * 8 + id;
@@ -4038,12 +4047,10 @@ const pushConclaveDaily = (
4038
4047
activeChallenges.some(x => x.PVPMode == PVPMode)
4039
4048
);
4040
4049
activeChallenges.push({
4041
_id: {
4042
$oid: "689ec5d985b55902" + challengeId.toString().padStart(8, "0")
4043
},
4050
_id: toOid2("689ec5d985b55902" + challengeId.toString().padStart(8, "0"), buildLabel),
4044
4051
challengeTypeRefID: challenge.key,
4045
startDate: { $date: { $numberLong: conclaveDayStart.toString() } },
4046
endDate: { $date: { $numberLong: conclaveDayEnd.toString() } },
4052
startDate: toMongoDate2(conclaveDayStart, buildLabel),
4053
endDate: toMongoDate2(conclaveDayEnd, buildLabel),
4047
4054
params: [{ n: "ScriptParamValue", v: challenge.ScriptParamValue }],
4048
4055
isGenerated: true,
4049
4056
PVPMode,
@@ -4052,14 +4059,10 @@ const pushConclaveDaily = (
4052
4059
});
4053
4060
};
4054
4061
4055
const pushConclaveDailys = (activeChallenges: IPVPChallengeInstance[], day: number): void => {
4056
const modes = [
4057
"PVPMODE_SPEEDBALL",
4058
"PVPMODE_CAPTURETHEFLAG",
4059
"PVPMODE_DEATHMATCH",
4060
"PVPMODE_TEAMDEATHMATCH"
4061
] as const;
4062
4062
const pushConclaveDailys = (activeChallenges: IPVPChallengeInstance[], day: number, buildLabel: string): void => {
4063
const modes = ["PVPMODE_CAPTURETHEFLAG", "PVPMODE_DEATHMATCH", "PVPMODE_TEAMDEATHMATCH"];
4064
// closest known version to Update: Lunaro
4065
if (version_compare(buildLabel, gameToBuildVersion["18.13.3"]) > 0) modes.push("PVPMODE_SPEEDBALL");
4063
4066
const challengesMap: Record<
4064
4067
string,
4065
4068
{
@@ -4078,22 +4081,22 @@ const pushConclaveDailys = (activeChallenges: IPVPChallengeInstance[], day: numb
4078
4081
}
4079
4082
4080
4083
modes.forEach((mode, index) => {
4081
pushConclaveDaily(activeChallenges, mode, challengesMap[mode], day, index * 2);
4082
pushConclaveDaily(activeChallenges, mode, challengesMap[mode], day, index * 2 + 1);
4084
pushConclaveDaily(activeChallenges, mode, challengesMap[mode], day, index * 2, buildLabel);
4085
pushConclaveDaily(activeChallenges, mode, challengesMap[mode], day, index * 2 + 1, buildLabel);
4083
4086
});
4084
4087
};
4085
4088
4086
const pushConclaveWeakly = (activeChallenges: IPVPChallengeInstance[], week: number): void => {
4089
const pushConclaveWeakly = (activeChallenges: IPVPChallengeInstance[], week: number, buildLabel: string): void => {
4087
4090
const weekStart = EPOCH + week * unixTimesInMs.week;
4088
4091
const conclaveWeekStart = weekStart + 40 * unixTimesInMs.minute - 2 * unixTimesInMs.day;
4089
4092
const conclaveWeekEnd = conclaveWeekStart + unixTimesInMs.week;
4090
4093
const conclaveIdStart = ((conclaveWeekStart / 1000) & 0xffffffff).toString(16).padStart(8, "0").padEnd(23, "0");
4091
4094
activeChallenges.push(
4092
4095
{
4093
_id: { $oid: conclaveIdStart + "1" },
4096
_id: toOid2(conclaveIdStart + "1", buildLabel),
4094
4097
challengeTypeRefID: "/Lotus/PVPChallengeTypes/PVPTimedChallengeGameModeWins",
4095
startDate: { $date: { $numberLong: conclaveWeekStart.toString() } },
4096
endDate: { $date: { $numberLong: conclaveWeekEnd.toString() } },
4098
startDate: toMongoDate2(conclaveWeekStart, buildLabel),
4099
endDate: toMongoDate2(conclaveWeekEnd, buildLabel),
4097
4100
params: [{ n: "ScriptParamValue", v: 6 }],
4098
4101
isGenerated: true,
4099
4102
PVPMode: "PVPMODE_ALL",
@@ -4101,10 +4104,10 @@ const pushConclaveWeakly = (activeChallenges: IPVPChallengeInstance[], week: num
4101
4104
Category: "PVPChallengeTypeCategory_WEEKLY"
4102
4105
},
4103
4106
{
4104
_id: { $oid: conclaveIdStart + "2" },
4107
_id: toOid2(conclaveIdStart + "2", buildLabel),
4105
4108
challengeTypeRefID: "/Lotus/PVPChallengeTypes/PVPTimedChallengeGameModeComplete",
4106
startDate: { $date: { $numberLong: conclaveWeekStart.toString() } },
4107
endDate: { $date: { $numberLong: conclaveWeekEnd.toString() } },
4109
startDate: toMongoDate2(conclaveWeekStart, buildLabel),
4110
endDate: toMongoDate2(conclaveWeekEnd, buildLabel),
4108
4111
params: [{ n: "ScriptParamValue", v: 20 }],
4109
4112
isGenerated: true,
4110
4113
PVPMode: "PVPMODE_ALL",
@@ -4112,10 +4115,10 @@ const pushConclaveWeakly = (activeChallenges: IPVPChallengeInstance[], week: num
4112
4115
Category: "PVPChallengeTypeCategory_WEEKLY"
4113
4116
},
4114
4117
{
4115
_id: { $oid: conclaveIdStart + "3" },
4118
_id: toOid2(conclaveIdStart + "3", buildLabel),
4116
4119
challengeTypeRefID: "/Lotus/PVPChallengeTypes/PVPTimedChallengeOtherChallengeCompleteANY",
4117
startDate: { $date: { $numberLong: conclaveWeekStart.toString() } },
4118
endDate: { $date: { $numberLong: conclaveWeekEnd.toString() } },
4120
startDate: toMongoDate2(conclaveWeekStart, buildLabel),
4121
endDate: toMongoDate2(conclaveWeekEnd, buildLabel),
4119
4122
params: [{ n: "ScriptParamValue", v: 10 }],
4120
4123
isGenerated: true,
4121
4124
PVPMode: "PVPMODE_ALL",
@@ -4123,17 +4126,17 @@ const pushConclaveWeakly = (activeChallenges: IPVPChallengeInstance[], week: num
4123
4126
Category: "PVPChallengeTypeCategory_WEEKLY"
4124
4127
},
4125
4128
{
4126
_id: { $oid: conclaveIdStart + "4" },
4129
_id: toOid2(conclaveIdStart + "4", buildLabel),
4127
4130
challengeTypeRefID: "/Lotus/PVPChallengeTypes/PVPTimedChallengeWeeklyStandardSet",
4128
startDate: { $date: { $numberLong: conclaveWeekStart.toString() } },
4129
endDate: { $date: { $numberLong: conclaveWeekEnd.toString() } },
4131
startDate: toMongoDate2(conclaveWeekStart, buildLabel),
4132
endDate: toMongoDate2(conclaveWeekEnd, buildLabel),
4130
4133
params: [{ n: "ScriptParamValue", v: 0 }],
4131
4134
isGenerated: true,
4132
4135
PVPMode: "PVPMODE_NONE",
4133
4136
subChallenges: [
4134
{ $oid: conclaveIdStart + "1" },
4135
{ $oid: conclaveIdStart + "2" },
4136
{ $oid: conclaveIdStart + "3" }
4137
toOid2(conclaveIdStart + "1", buildLabel),
4138
toOid2(conclaveIdStart + "2", buildLabel),
4139
toOid2(conclaveIdStart + "3", buildLabel)
4137
4140
],
4138
4141
Category: "PVPChallengeTypeCategory_WEEKLY_ROOT"
4139
4142
}
@@ -13,6 +13,13 @@ export interface IMongoDate {
13
13
};
14
14
}
15
15
16
export type IMongoDateWithLegacySupport =
17
| IMongoDate
18
| {
19
sec: number;
20
usec: number;
21
};
22
16
23
export interface ITypeCount {
17
24
ItemType: string;
18
25
ItemCount: number;
@@ -1,5 +1,5 @@
1
1
import type { IMissionReward, TFaction, TMissionType } from "warframe-public-export-plus";
2
import type { IMongoDate, IOid } from "./commonTypes.ts";
2
import type { IMongoDateWithLegacySupport, IMongoDate, IOid, IOidWithLegacySupport } from "./commonTypes.ts";
3
3
4
4
export interface IWorldState {
5
5
WorldSeed?: string;
@@ -350,17 +350,17 @@ export interface IDailyDealDatabase {
350
350
}
351
351
352
352
export interface IPVPChallengeInstance {
353
_id: IOid;
353
_id: IOidWithLegacySupport;
354
354
challengeTypeRefID: string;
355
startDate: IMongoDate;
356
endDate: IMongoDate;
355
startDate: IMongoDateWithLegacySupport;
356
endDate: IMongoDateWithLegacySupport;
357
357
params: {
358
358
n: string; // "ScriptParamValue";
359
359
v: number;
360
360
}[];
361
361
isGenerated: boolean;
362
362
PVPMode: string;
363
subChallenges: IOid[];
363
subChallenges: IOidWithLegacySupport[];
364
364
Category: string; // "PVPChallengeTypeCategory_WEEKLY" | "PVPChallengeTypeCategory_WEEKLY_ROOT" | "PVPChallengeTypeCategory_DAILY";
365
365
}
366
366
@@ -29,7 +29,9 @@
29
29
"19.5.0": "2016.12.21.19.13",
30
30
"18.18.0": "2016.08.19.17.12",
31
31
"18.16.0": "2016.07.08.16.56",
32
"18.13.3": "2016.06.02.12.11",
32
33
"18.0.2": "2015.12.05.18.07",
34
"17.7.1": "2015.10.15.12.24",
33
35
"16.5.5": "2015.05.14.16.29",
34
36
"16.0.2": "2015.03.21.08.17",
35
37
"15.14.1": "2015.02.13.10.41",