feat: dynamic void fissure missions (#2214)
Closes #1512 Reviewed-on: #2214 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
3c64f17e34
commit
95136e6059
@ -1,6 +1,15 @@
|
|||||||
import { RequestHandler } from "express";
|
import { RequestHandler } from "express";
|
||||||
import { getWorldState } from "@/src/services/worldStateService";
|
import { getWorldState, populateFissures } from "@/src/services/worldStateService";
|
||||||
|
import { version_compare } from "@/src/helpers/inventoryHelpers";
|
||||||
|
|
||||||
export const worldStateController: RequestHandler = (req, res) => {
|
export const worldStateController: RequestHandler = async (req, res) => {
|
||||||
res.json(getWorldState(req.query.buildLabel as string | undefined));
|
const buildLabel = req.query.buildLabel as string | undefined;
|
||||||
|
const worldState = getWorldState(buildLabel);
|
||||||
|
|
||||||
|
// Omitting void fissures for versions prior to Dante Unbound to avoid script errors.
|
||||||
|
if (!buildLabel || version_compare(buildLabel, "2024.03.24.20.00") >= 0) {
|
||||||
|
await populateFissures(worldState);
|
||||||
|
}
|
||||||
|
|
||||||
|
res.json(worldState);
|
||||||
};
|
};
|
||||||
|
@ -22,6 +22,7 @@ import { JSONStringify } from "json-with-bigint";
|
|||||||
import { startWebServer } from "./services/webService";
|
import { startWebServer } from "./services/webService";
|
||||||
|
|
||||||
import { validateConfig } from "@/src/services/configWatcherService";
|
import { validateConfig } from "@/src/services/configWatcherService";
|
||||||
|
import { updateWorldStateCollections } from "./services/worldStateService";
|
||||||
|
|
||||||
// Patch JSON.stringify to work flawlessly with Bigints.
|
// Patch JSON.stringify to work flawlessly with Bigints.
|
||||||
JSON.stringify = JSONStringify;
|
JSON.stringify = JSONStringify;
|
||||||
@ -33,6 +34,11 @@ mongoose
|
|||||||
.then(() => {
|
.then(() => {
|
||||||
logger.info("Connected to MongoDB");
|
logger.info("Connected to MongoDB");
|
||||||
startWebServer();
|
startWebServer();
|
||||||
|
|
||||||
|
void updateWorldStateCollections();
|
||||||
|
setInterval(() => {
|
||||||
|
void updateWorldStateCollections();
|
||||||
|
}, 60_000);
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch(error => {
|
||||||
if (error instanceof Error) {
|
if (error instanceof Error) {
|
||||||
|
14
src/models/worldStateModel.ts
Normal file
14
src/models/worldStateModel.ts
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
import { IFissureDatabase } from "@/src/types/worldStateTypes";
|
||||||
|
import { model, Schema } from "mongoose";
|
||||||
|
|
||||||
|
const fissureSchema = new Schema<IFissureDatabase>({
|
||||||
|
Activation: Date,
|
||||||
|
Expiry: Date,
|
||||||
|
Node: String, // must be unique
|
||||||
|
Modifier: String,
|
||||||
|
Hard: Boolean
|
||||||
|
});
|
||||||
|
|
||||||
|
fissureSchema.index({ Expiry: 1 }, { expireAfterSeconds: 0 }); // With this, MongoDB will automatically delete expired entries.
|
||||||
|
|
||||||
|
export const Fissure = model<IFissureDatabase>("Fissure", fissureSchema);
|
@ -1,12 +1,13 @@
|
|||||||
import staticWorldState from "@/static/fixed_responses/worldState/worldState.json";
|
import staticWorldState from "@/static/fixed_responses/worldState/worldState.json";
|
||||||
|
import fissureMissions from "@/static/fixed_responses/worldState/fissureMissions.json";
|
||||||
import sortieTilesets from "@/static/fixed_responses/worldState/sortieTilesets.json";
|
import sortieTilesets from "@/static/fixed_responses/worldState/sortieTilesets.json";
|
||||||
import sortieTilesetMissions from "@/static/fixed_responses/worldState/sortieTilesetMissions.json";
|
import sortieTilesetMissions from "@/static/fixed_responses/worldState/sortieTilesetMissions.json";
|
||||||
import syndicateMissions from "@/static/fixed_responses/worldState/syndicateMissions.json";
|
import syndicateMissions from "@/static/fixed_responses/worldState/syndicateMissions.json";
|
||||||
import { buildConfig } from "@/src/services/buildConfigService";
|
import { buildConfig } from "@/src/services/buildConfigService";
|
||||||
import { unixTimesInMs } from "@/src/constants/timeConstants";
|
import { unixTimesInMs } from "@/src/constants/timeConstants";
|
||||||
import { config } from "@/src/services/configService";
|
import { config } from "@/src/services/configService";
|
||||||
import { SRng } from "@/src/services/rngService";
|
import { getRandomElement, getRandomInt, SRng } from "@/src/services/rngService";
|
||||||
import { ExportRegions, ExportSyndicates, IRegion } from "warframe-public-export-plus";
|
import { eMissionType, ExportRegions, ExportSyndicates, IRegion } from "warframe-public-export-plus";
|
||||||
import {
|
import {
|
||||||
ICalendarDay,
|
ICalendarDay,
|
||||||
ICalendarEvent,
|
ICalendarEvent,
|
||||||
@ -21,8 +22,9 @@ import {
|
|||||||
IWorldState,
|
IWorldState,
|
||||||
TCircuitGameMode
|
TCircuitGameMode
|
||||||
} from "../types/worldStateTypes";
|
} from "../types/worldStateTypes";
|
||||||
import { version_compare } from "../helpers/inventoryHelpers";
|
import { toMongoDate, toOid, version_compare } from "../helpers/inventoryHelpers";
|
||||||
import { logger } from "../utils/logger";
|
import { logger } from "../utils/logger";
|
||||||
|
import { Fissure } from "../models/worldStateModel";
|
||||||
|
|
||||||
const sortieBosses = [
|
const sortieBosses = [
|
||||||
"SORTIE_BOSS_HYENA",
|
"SORTIE_BOSS_HYENA",
|
||||||
@ -1110,6 +1112,7 @@ export const getWorldState = (buildLabel?: string): IWorldState => {
|
|||||||
Alerts: [],
|
Alerts: [],
|
||||||
Sorties: [],
|
Sorties: [],
|
||||||
LiteSorties: [],
|
LiteSorties: [],
|
||||||
|
ActiveMissions: [],
|
||||||
GlobalUpgrades: [],
|
GlobalUpgrades: [],
|
||||||
VoidStorms: [],
|
VoidStorms: [],
|
||||||
EndlessXpChoices: [],
|
EndlessXpChoices: [],
|
||||||
@ -1118,14 +1121,10 @@ export const getWorldState = (buildLabel?: string): IWorldState => {
|
|||||||
SyndicateMissions: [...staticWorldState.SyndicateMissions]
|
SyndicateMissions: [...staticWorldState.SyndicateMissions]
|
||||||
};
|
};
|
||||||
|
|
||||||
// Omit void fissures for versions prior to Dante Unbound to avoid script errors.
|
|
||||||
if (buildLabel && version_compare(buildLabel, "2024.03.24.20.00") < 0) {
|
|
||||||
worldState.ActiveMissions = [];
|
|
||||||
if (version_compare(buildLabel, "2017.10.12.17.04") < 0) {
|
|
||||||
// Old versions seem to really get hung up on not being able to load these.
|
// Old versions seem to really get hung up on not being able to load these.
|
||||||
|
if (buildLabel && version_compare(buildLabel, "2017.10.12.17.04") < 0) {
|
||||||
worldState.PVPChallengeInstances = [];
|
worldState.PVPChallengeInstances = [];
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (config.worldState?.starDays) {
|
if (config.worldState?.starDays) {
|
||||||
worldState.Goals.push({
|
worldState.Goals.push({
|
||||||
@ -1364,6 +1363,24 @@ export const getWorldState = (buildLabel?: string): IWorldState => {
|
|||||||
return worldState;
|
return worldState;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const populateFissures = async (worldState: IWorldState): Promise<void> => {
|
||||||
|
const fissures = await Fissure.find({});
|
||||||
|
for (const fissure of fissures) {
|
||||||
|
const meta = ExportRegions[fissure.Node];
|
||||||
|
worldState.ActiveMissions.push({
|
||||||
|
_id: toOid(fissure._id),
|
||||||
|
Region: meta.systemIndex + 1,
|
||||||
|
Seed: 1337,
|
||||||
|
Activation: toMongoDate(fissure.Activation),
|
||||||
|
Expiry: toMongoDate(fissure.Expiry),
|
||||||
|
Node: fissure.Node,
|
||||||
|
MissionType: eMissionType[meta.missionIndex].tag,
|
||||||
|
Modifier: fissure.Modifier,
|
||||||
|
Hard: fissure.Hard
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
export const idToBountyCycle = (id: string): number => {
|
export const idToBountyCycle = (id: string): number => {
|
||||||
return Math.trunc((parseInt(id.substring(0, 8), 16) * 1000) / 9000_000);
|
return Math.trunc((parseInt(id.substring(0, 8), 16) * 1000) / 9000_000);
|
||||||
};
|
};
|
||||||
@ -1491,3 +1508,57 @@ const nightwaveTagToSeason: Record<string, number> = {
|
|||||||
RadioLegionIntermissionSyndicate: 1, // Intermission I
|
RadioLegionIntermissionSyndicate: 1, // Intermission I
|
||||||
RadioLegionSyndicate: 0 // The Wolf of Saturn Six
|
RadioLegionSyndicate: 0 // The Wolf of Saturn Six
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const updateWorldStateCollections = async (): Promise<void> => {
|
||||||
|
const fissures = await Fissure.find();
|
||||||
|
|
||||||
|
const activeNodes = new Set<string>();
|
||||||
|
const tierToFurthestExpiry: Record<string, number> = {
|
||||||
|
VoidT1: 0,
|
||||||
|
VoidT2: 0,
|
||||||
|
VoidT3: 0,
|
||||||
|
VoidT4: 0,
|
||||||
|
VoidT5: 0,
|
||||||
|
VoidT6: 0,
|
||||||
|
VoidT1Hard: 0,
|
||||||
|
VoidT2Hard: 0,
|
||||||
|
VoidT3Hard: 0,
|
||||||
|
VoidT4Hard: 0,
|
||||||
|
VoidT5Hard: 0,
|
||||||
|
VoidT6Hard: 0
|
||||||
|
};
|
||||||
|
for (const fissure of fissures) {
|
||||||
|
activeNodes.add(fissure.Node);
|
||||||
|
|
||||||
|
const key = fissure.Modifier + (fissure.Hard ? "Hard" : "");
|
||||||
|
tierToFurthestExpiry[key] = Math.max(tierToFurthestExpiry[key], fissure.Expiry.getTime());
|
||||||
|
}
|
||||||
|
|
||||||
|
const deadline = Date.now() - 6 * unixTimesInMs.minute;
|
||||||
|
for (const [tier, expiry] of Object.entries(tierToFurthestExpiry)) {
|
||||||
|
if (expiry < deadline) {
|
||||||
|
const numFissures = getRandomInt(1, 3);
|
||||||
|
for (let i = 0; i != numFissures; ++i) {
|
||||||
|
const modifier = tier.replace("Hard", "") as
|
||||||
|
| "VoidT1"
|
||||||
|
| "VoidT2"
|
||||||
|
| "VoidT3"
|
||||||
|
| "VoidT4"
|
||||||
|
| "VoidT5"
|
||||||
|
| "VoidT6";
|
||||||
|
let node: string;
|
||||||
|
do {
|
||||||
|
node = getRandomElement(fissureMissions[modifier])!;
|
||||||
|
} while (activeNodes.has(node));
|
||||||
|
activeNodes.add(node);
|
||||||
|
await Fissure.insertOne({
|
||||||
|
Activation: new Date(),
|
||||||
|
Expiry: new Date(Date.now() + getRandomInt(60, 120) * unixTimesInMs.minute),
|
||||||
|
Node: node,
|
||||||
|
Modifier: modifier,
|
||||||
|
Hard: tier.indexOf("Hard") != -1 ? true : undefined
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
@ -9,8 +9,8 @@ export interface IWorldState {
|
|||||||
Sorties: ISortie[];
|
Sorties: ISortie[];
|
||||||
LiteSorties: ILiteSortie[];
|
LiteSorties: ILiteSortie[];
|
||||||
SyndicateMissions: ISyndicateMissionInfo[];
|
SyndicateMissions: ISyndicateMissionInfo[];
|
||||||
GlobalUpgrades: IGlobalUpgrade[];
|
|
||||||
ActiveMissions: IFissure[];
|
ActiveMissions: IFissure[];
|
||||||
|
GlobalUpgrades: IGlobalUpgrade[];
|
||||||
NodeOverrides: INodeOverride[];
|
NodeOverrides: INodeOverride[];
|
||||||
VoidStorms: IVoidStorm[];
|
VoidStorms: IVoidStorm[];
|
||||||
PVPChallengeInstances: IPVPChallengeInstance[];
|
PVPChallengeInstances: IPVPChallengeInstance[];
|
||||||
@ -86,6 +86,14 @@ export interface IFissure {
|
|||||||
Hard?: boolean;
|
Hard?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface IFissureDatabase {
|
||||||
|
Activation: Date;
|
||||||
|
Expiry: Date;
|
||||||
|
Node: string;
|
||||||
|
Modifier: "VoidT1" | "VoidT2" | "VoidT3" | "VoidT4" | "VoidT5" | "VoidT6";
|
||||||
|
Hard?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
export interface INodeOverride {
|
export interface INodeOverride {
|
||||||
_id: IOid;
|
_id: IOid;
|
||||||
Activation?: IMongoDate;
|
Activation?: IMongoDate;
|
||||||
|
154
static/fixed_responses/worldState/fissureMissions.json
Normal file
154
static/fixed_responses/worldState/fissureMissions.json
Normal file
@ -0,0 +1,154 @@
|
|||||||
|
{
|
||||||
|
"VoidT1": [
|
||||||
|
"SolNode23",
|
||||||
|
"SolNode66",
|
||||||
|
"SolNode45",
|
||||||
|
"SolNode41",
|
||||||
|
"SolNode59",
|
||||||
|
"SolNode39",
|
||||||
|
"SolNode75",
|
||||||
|
"SolNode113",
|
||||||
|
"SolNode85",
|
||||||
|
"SolNode58",
|
||||||
|
"SolNode101",
|
||||||
|
"SolNode109",
|
||||||
|
"SolNode26",
|
||||||
|
"SolNode15",
|
||||||
|
"SolNode61",
|
||||||
|
"SolNode123",
|
||||||
|
"SolNode16",
|
||||||
|
"SolNode79",
|
||||||
|
"SolNode2",
|
||||||
|
"SolNode22",
|
||||||
|
"SolNode68",
|
||||||
|
"SolNode89",
|
||||||
|
"SolNode11",
|
||||||
|
"SolNode46",
|
||||||
|
"SolNode36",
|
||||||
|
"SolNode27",
|
||||||
|
"SolNode14",
|
||||||
|
"SolNode106",
|
||||||
|
"SolNode30",
|
||||||
|
"SolNode107",
|
||||||
|
"SolNode63",
|
||||||
|
"SolNode128"
|
||||||
|
],
|
||||||
|
"VoidT2": [
|
||||||
|
"SolNode141",
|
||||||
|
"SolNode149",
|
||||||
|
"SolNode10",
|
||||||
|
"SolNode93",
|
||||||
|
"SettlementNode11",
|
||||||
|
"SolNode137",
|
||||||
|
"SolNode132",
|
||||||
|
"SolNode73",
|
||||||
|
"SolNode82",
|
||||||
|
"SolNode25",
|
||||||
|
"SolNode88",
|
||||||
|
"SolNode126",
|
||||||
|
"SolNode135",
|
||||||
|
"SolNode74",
|
||||||
|
"SettlementNode15",
|
||||||
|
"SolNode147",
|
||||||
|
"SolNode67",
|
||||||
|
"SolNode20",
|
||||||
|
"SolNode42",
|
||||||
|
"SolNode18",
|
||||||
|
"SolNode31",
|
||||||
|
"SolNode139",
|
||||||
|
"SettlementNode12",
|
||||||
|
"SolNode100",
|
||||||
|
"SolNode140",
|
||||||
|
"SolNode70",
|
||||||
|
"SettlementNode1",
|
||||||
|
"SettlementNode14",
|
||||||
|
"SolNode50",
|
||||||
|
"SettlementNode2",
|
||||||
|
"SolNode146",
|
||||||
|
"SettlementNode3",
|
||||||
|
"SolNode97",
|
||||||
|
"SolNode125",
|
||||||
|
"SolNode19",
|
||||||
|
"SolNode121",
|
||||||
|
"SolNode96",
|
||||||
|
"SolNode131"
|
||||||
|
],
|
||||||
|
"VoidT3": [
|
||||||
|
"SolNode62",
|
||||||
|
"SolNode17",
|
||||||
|
"SolNode403",
|
||||||
|
"SolNode6",
|
||||||
|
"SolNode118",
|
||||||
|
"SolNode211",
|
||||||
|
"SolNode217",
|
||||||
|
"SolNode401",
|
||||||
|
"SolNode64",
|
||||||
|
"SolNode405",
|
||||||
|
"SolNode84",
|
||||||
|
"SolNode402",
|
||||||
|
"SolNode408",
|
||||||
|
"SolNode122",
|
||||||
|
"SolNode57",
|
||||||
|
"SolNode216",
|
||||||
|
"SolNode205",
|
||||||
|
"SolNode215",
|
||||||
|
"SolNode404",
|
||||||
|
"SolNode209",
|
||||||
|
"SolNode406",
|
||||||
|
"SolNode204",
|
||||||
|
"SolNode203",
|
||||||
|
"SolNode409",
|
||||||
|
"SolNode400",
|
||||||
|
"SolNode212",
|
||||||
|
"SolNode1",
|
||||||
|
"SolNode412",
|
||||||
|
"SolNode49",
|
||||||
|
"SolNode78",
|
||||||
|
"SolNode410",
|
||||||
|
"SolNode407",
|
||||||
|
"SolNode220"
|
||||||
|
],
|
||||||
|
"VoidT4": [
|
||||||
|
"SolNode188",
|
||||||
|
"SolNode403",
|
||||||
|
"SolNode189",
|
||||||
|
"SolNode21",
|
||||||
|
"SolNode102",
|
||||||
|
"SolNode171",
|
||||||
|
"SolNode196",
|
||||||
|
"SolNode184",
|
||||||
|
"SolNode185",
|
||||||
|
"SolNode76",
|
||||||
|
"SolNode195",
|
||||||
|
"SolNode164",
|
||||||
|
"SolNode401",
|
||||||
|
"SolNode405",
|
||||||
|
"SolNode56",
|
||||||
|
"SolNode402",
|
||||||
|
"SolNode408",
|
||||||
|
"SolNode4",
|
||||||
|
"SolNode181",
|
||||||
|
"SolNode406",
|
||||||
|
"SolNode162",
|
||||||
|
"SolNode72",
|
||||||
|
"SolNode407",
|
||||||
|
"SolNode177",
|
||||||
|
"SolNode404",
|
||||||
|
"SolNode400",
|
||||||
|
"SolNode409",
|
||||||
|
"SolNode43",
|
||||||
|
"SolNode166",
|
||||||
|
"SolNode172",
|
||||||
|
"SolNode412",
|
||||||
|
"SolNode187",
|
||||||
|
"SolNode38",
|
||||||
|
"SolNode175",
|
||||||
|
"SolNode81",
|
||||||
|
"SolNode48",
|
||||||
|
"SolNode410",
|
||||||
|
"SolNode153",
|
||||||
|
"SolNode173"
|
||||||
|
],
|
||||||
|
"VoidT5": ["SolNode747", "SolNode743", "SolNode742", "SolNode744", "SolNode745", "SolNode748", "SolNode746", "SolNode741"],
|
||||||
|
"VoidT6": ["SolNode717", "SolNode309", "SolNode718", "SolNode232", "SolNode230", "SolNode310"]
|
||||||
|
}
|
@ -327,195 +327,6 @@
|
|||||||
"Nodes": []
|
"Nodes": []
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"ActiveMissions": [
|
|
||||||
{
|
|
||||||
"_id": { "$oid": "663a7509d93367863785932d" },
|
|
||||||
"Region": 15,
|
|
||||||
"Seed": 80795,
|
|
||||||
"Activation": { "$date": { "$numberLong": "1715107081517" } },
|
|
||||||
"Expiry": { "$date": { "$numberLong": "2000000000000" } },
|
|
||||||
"Node": "SolNode400",
|
|
||||||
"MissionType": "MT_EXTERMINATION",
|
|
||||||
"Modifier": "VoidT3",
|
|
||||||
"Hard": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"_id": { "$oid": "663a75f959a5964cadb39879" },
|
|
||||||
"Region": 19,
|
|
||||||
"Seed": 32067,
|
|
||||||
"Activation": { "$date": { "$numberLong": "1715107321237" } },
|
|
||||||
"Expiry": { "$date": { "$numberLong": "2000000000000" } },
|
|
||||||
"Node": "SolNode747",
|
|
||||||
"MissionType": "MT_INTEL",
|
|
||||||
"Modifier": "VoidT5",
|
|
||||||
"Hard": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"_id": { "$oid": "663a779d3e347839ff301814" },
|
|
||||||
"Region": 7,
|
|
||||||
"Seed": 51739,
|
|
||||||
"Activation": { "$date": { "$numberLong": "1715107741454" } },
|
|
||||||
"Expiry": { "$date": { "$numberLong": "2000000000000" } },
|
|
||||||
"Node": "SolNode64",
|
|
||||||
"MissionType": "MT_TERRITORY",
|
|
||||||
"Modifier": "VoidT3"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"_id": { "$oid": "663a77d916c199f4644ee67d" },
|
|
||||||
"Region": 17,
|
|
||||||
"Seed": 61179,
|
|
||||||
"Activation": { "$date": { "$numberLong": "1715107801647" } },
|
|
||||||
"Expiry": { "$date": { "$numberLong": "2000000000000" } },
|
|
||||||
"Node": "SolNode718",
|
|
||||||
"MissionType": "MT_ALCHEMY",
|
|
||||||
"Modifier": "VoidT6"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"_id": { "$oid": "663a78c98a609b49b8410726" },
|
|
||||||
"Region": 3,
|
|
||||||
"Seed": 9520,
|
|
||||||
"Activation": { "$date": { "$numberLong": "1715108041501" } },
|
|
||||||
"Expiry": { "$date": { "$numberLong": "2000000000000" } },
|
|
||||||
"Node": "SolNode79",
|
|
||||||
"MissionType": "MT_INTEL",
|
|
||||||
"Modifier": "VoidT1",
|
|
||||||
"Hard": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"_id": { "$oid": "663a7df15eeabaac79b0a061" },
|
|
||||||
"Region": 6,
|
|
||||||
"Seed": 48861,
|
|
||||||
"Activation": { "$date": { "$numberLong": "1715109361974" } },
|
|
||||||
"Expiry": { "$date": { "$numberLong": "2000000000000" } },
|
|
||||||
"Node": "SolNode67",
|
|
||||||
"MissionType": "MT_INTEL",
|
|
||||||
"Modifier": "VoidT2",
|
|
||||||
"Hard": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"_id": { "$oid": "663a7df25eeabaac79b0a062" },
|
|
||||||
"Region": 5,
|
|
||||||
"Seed": 13550,
|
|
||||||
"Activation": { "$date": { "$numberLong": "1715109361974" } },
|
|
||||||
"Expiry": { "$date": { "$numberLong": "2000000000000" } },
|
|
||||||
"Node": "SolNode10",
|
|
||||||
"MissionType": "MT_SABOTAGE",
|
|
||||||
"Modifier": "VoidT2",
|
|
||||||
"Hard": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"_id": { "$oid": "663a83cdec0d5181435f1324" },
|
|
||||||
"Region": 19,
|
|
||||||
"Seed": 39392,
|
|
||||||
"Activation": { "$date": { "$numberLong": "1715110861506" } },
|
|
||||||
"Expiry": { "$date": { "$numberLong": "2000000000000" } },
|
|
||||||
"Node": "SolNode742",
|
|
||||||
"MissionType": "MT_DEFENSE",
|
|
||||||
"Modifier": "VoidT5"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"_id": { "$oid": "663a83cdec0d5181435f1325" },
|
|
||||||
"Region": 19,
|
|
||||||
"Seed": 88668,
|
|
||||||
"Activation": { "$date": { "$numberLong": "1715110861506" } },
|
|
||||||
"Expiry": { "$date": { "$numberLong": "2000000000000" } },
|
|
||||||
"Node": "SolNode743",
|
|
||||||
"MissionType": "MT_MOBILE_DEFENSE",
|
|
||||||
"Modifier": "VoidT5"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"_id": { "$oid": "663a83cdec0d5181435f1326" },
|
|
||||||
"Region": 19,
|
|
||||||
"Seed": 73823,
|
|
||||||
"Activation": { "$date": { "$numberLong": "1715110861506" } },
|
|
||||||
"Expiry": { "$date": { "$numberLong": "2000000000000" } },
|
|
||||||
"Node": "SolNode741",
|
|
||||||
"MissionType": "MT_ASSAULT",
|
|
||||||
"Modifier": "VoidT5"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"_id": { "$oid": "663a878d23d1514873170466" },
|
|
||||||
"Region": 9,
|
|
||||||
"Seed": 88696,
|
|
||||||
"Activation": { "$date": { "$numberLong": "1715111821951" } },
|
|
||||||
"Expiry": { "$date": { "$numberLong": "2000000000000" } },
|
|
||||||
"Node": "SolNode4",
|
|
||||||
"MissionType": "MT_EXTERMINATION",
|
|
||||||
"Modifier": "VoidT4",
|
|
||||||
"Hard": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"_id": { "$oid": "663a887d4903098c10992fe6" },
|
|
||||||
"Region": 6,
|
|
||||||
"Seed": 66337,
|
|
||||||
"Activation": { "$date": { "$numberLong": "1715112061729" } },
|
|
||||||
"Expiry": { "$date": { "$numberLong": "2000000000000" } },
|
|
||||||
"Node": "SolNode18",
|
|
||||||
"MissionType": "MT_TERRITORY",
|
|
||||||
"Modifier": "VoidT2"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"_id": { "$oid": "663a887d4903098c10992fe7" },
|
|
||||||
"Region": 10,
|
|
||||||
"Seed": 5135,
|
|
||||||
"Activation": { "$date": { "$numberLong": "1715112061729" } },
|
|
||||||
"Expiry": { "$date": { "$numberLong": "2000000000000" } },
|
|
||||||
"Node": "SolNode149",
|
|
||||||
"MissionType": "MT_DEFENSE",
|
|
||||||
"Modifier": "VoidT2"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"_id": { "$oid": "663a8931586c301b1fbe63d3" },
|
|
||||||
"Region": 15,
|
|
||||||
"Seed": 32180,
|
|
||||||
"Activation": { "$date": { "$numberLong": "1715112241196" } },
|
|
||||||
"Expiry": { "$date": { "$numberLong": "2000000000000" } },
|
|
||||||
"Node": "SolNode408",
|
|
||||||
"MissionType": "MT_DEFENSE",
|
|
||||||
"Modifier": "VoidT4"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"_id": { "$oid": "663a8931586c301b1fbe63d4" },
|
|
||||||
"Region": 12,
|
|
||||||
"Seed": 22521,
|
|
||||||
"Activation": { "$date": { "$numberLong": "1715112241196" } },
|
|
||||||
"Expiry": { "$date": { "$numberLong": "2000000000000" } },
|
|
||||||
"Node": "SolNode181",
|
|
||||||
"MissionType": "MT_EXTERMINATION",
|
|
||||||
"Modifier": "VoidT4"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"_id": { "$oid": "663a8931586c301b1fbe63d5" },
|
|
||||||
"Region": 2,
|
|
||||||
"Seed": 28500,
|
|
||||||
"Activation": { "$date": { "$numberLong": "1715112241196" } },
|
|
||||||
"Expiry": { "$date": { "$numberLong": "2000000000000" } },
|
|
||||||
"Node": "SolNode128",
|
|
||||||
"MissionType": "MT_EXTERMINATION",
|
|
||||||
"Modifier": "VoidT1"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"_id": { "$oid": "663a8931586c301b1fbe63d6" },
|
|
||||||
"Region": 3,
|
|
||||||
"Seed": 24747,
|
|
||||||
"Activation": { "$date": { "$numberLong": "1715112241196" } },
|
|
||||||
"Expiry": { "$date": { "$numberLong": "2000000000000" } },
|
|
||||||
"Node": "SolNode26",
|
|
||||||
"MissionType": "MT_DEFENSE",
|
|
||||||
"Modifier": "VoidT1"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"_id": { "$oid": "663a8931586c301b1fbe63d7" },
|
|
||||||
"Region": 17,
|
|
||||||
"Seed": 63914,
|
|
||||||
"Activation": { "$date": { "$numberLong": "1715112241196" } },
|
|
||||||
"Expiry": { "$date": { "$numberLong": "2000000000000" } },
|
|
||||||
"Node": "SolNode717",
|
|
||||||
"MissionType": "MT_SURVIVAL",
|
|
||||||
"Modifier": "VoidT6",
|
|
||||||
"Hard": true
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"NodeOverrides": [
|
"NodeOverrides": [
|
||||||
{ "_id": { "$oid": "549b18e9b029cef5991d6aec" }, "Node": "EuropaHUB", "Hide": true },
|
{ "_id": { "$oid": "549b18e9b029cef5991d6aec" }, "Node": "EuropaHUB", "Hide": true },
|
||||||
{ "_id": { "$oid": "54a1737aeb658f6cbccf70ff" }, "Node": "ErisHUB", "Hide": true },
|
{ "_id": { "$oid": "54a1737aeb658f6cbccf70ff" }, "Node": "ErisHUB", "Hide": true },
|
||||||
|
Loading…
x
Reference in New Issue
Block a user