Autoupdate, Syndicates, void fisures, sotries
sotries needs more data(currently all worldstate data is taken from wfcd worldstate data package)
This commit is contained in:
parent
5fd9de3084
commit
554a1a6b22
@ -20,7 +20,7 @@
|
||||
"unlockAllShipDecorations": true,
|
||||
"unlockAllFlavourItems": true,
|
||||
"unlockAllSkins": true,
|
||||
"useStaticWorldState": true,
|
||||
"universalPolarityEverywhere": true,
|
||||
"useStaticWorldState": true,
|
||||
"spoofMasteryRank": -1
|
||||
}
|
||||
|
@ -15,9 +15,11 @@ import { statsRouter } from "@/src/routes/stats";
|
||||
import { webuiRouter } from "@/src/routes/webui";
|
||||
import { connectDatabase } from "@/src/services/mongoService";
|
||||
import { registerLogFileCreationListener } from "@/src/utils/logger";
|
||||
import { worldStateRunner } from "@/src/services/worldStateService";
|
||||
|
||||
void registerLogFileCreationListener();
|
||||
void connectDatabase();
|
||||
void worldStateRunner();
|
||||
|
||||
const app = express();
|
||||
|
||||
|
3659
src/constants/worldStateConstants.ts
Normal file
3659
src/constants/worldStateConstants.ts
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,18 +1,17 @@
|
||||
import { RequestHandler } from "express";
|
||||
import worldState from "@/static/fixed_responses/worldState.json";
|
||||
import buildConfig from "@/static/data/buildConfig.json";
|
||||
import { IWorldState } from "@/src/types/worldStateTypes";
|
||||
import { config } from "@/src/services/configService";
|
||||
import { getWorldState } from "@/src/services/worldStateService";
|
||||
|
||||
const worldStateController: RequestHandler = async (_req, res) => {
|
||||
let ws: IWorldState = {};
|
||||
let ws: { [k: string]: any } = {};
|
||||
if (config.useStaticWorldState) {
|
||||
ws = worldState;
|
||||
ws.BuildLabel = buildConfig.buildLabel;
|
||||
ws.Time = Math.round(Date.now() / 1000);
|
||||
} else {
|
||||
ws = (await getWorldState()).toJSON();
|
||||
ws = await getWorldState();
|
||||
ws.BuildLabel = buildConfig.buildLabel;
|
||||
ws.Time = Math.round(Date.now() / 1000);
|
||||
}
|
||||
|
@ -74,4 +74,13 @@ export const isObject = (objectCandidate: unknown): objectCandidate is Record<st
|
||||
);
|
||||
};
|
||||
|
||||
export const getRandomNumber = (min: number, max: number) => {
|
||||
return Math.floor(Math.random() * (max - min + 1) + min);
|
||||
};
|
||||
|
||||
export const getRandomKey = (keys: string[]) => {
|
||||
const randomIndex = Math.floor(Math.random() * keys.length);
|
||||
return keys[randomIndex];
|
||||
};
|
||||
|
||||
export { isString, isNumber, parseString, parseNumber, parseDateNumber, parseBoolean, parseEmail };
|
||||
|
30
src/helpers/worldstateHelpers.ts
Normal file
30
src/helpers/worldstateHelpers.ts
Normal file
@ -0,0 +1,30 @@
|
||||
import { ExportRegions } from "warframe-public-export-plus";
|
||||
import { unixTimesInMs } from "@/src/constants/timeConstants";
|
||||
import { logger } from "../utils/logger";
|
||||
|
||||
export const getRandomNodes = (n: number) => {
|
||||
const nodes = Object.entries(ExportRegions).map(([key]) => {
|
||||
return {
|
||||
nodeKey: key
|
||||
};
|
||||
}); // may be filter that?
|
||||
const output: string[] = [];
|
||||
for (let i = 0; i < n; i++) {
|
||||
logger.debug(i);
|
||||
const randomIndex = Math.floor(Math.random() * nodes.length);
|
||||
output[i] = nodes[randomIndex].nodeKey;
|
||||
}
|
||||
return output;
|
||||
};
|
||||
|
||||
export const getCurrentRotation = () => {
|
||||
const intervalMilliseconds = 2.5 * unixTimesInMs.hour;
|
||||
const rotations = ["A", "B", "C"];
|
||||
|
||||
const now = new Date();
|
||||
const currentTimeMs = now.getTime();
|
||||
|
||||
const intervalIndex = Math.floor(currentTimeMs / intervalMilliseconds) % 3;
|
||||
|
||||
return rotations[intervalIndex];
|
||||
};
|
@ -57,10 +57,10 @@ const EventSchema = new Schema<IEvent>({
|
||||
Messages: [messageSchema],
|
||||
Prop: String,
|
||||
Links: [linkSchema],
|
||||
Date: Date,
|
||||
Date: Number,
|
||||
Icon: String,
|
||||
EventStartDate: Date,
|
||||
EventEndDate: Date,
|
||||
EventStartDate: Number,
|
||||
EventEndDate: Number,
|
||||
ImageUrl: String,
|
||||
Priority: Boolean,
|
||||
MobileOnly: Boolean,
|
||||
@ -71,6 +71,9 @@ const EventSchema = new Schema<IEvent>({
|
||||
EventSchema.set("toJSON", {
|
||||
transform(_document, returnedObject) {
|
||||
returnedObject._id = { $oid: returnedObject._id.toString() };
|
||||
returnedObject.Date = { $date: { $numberLong: returnedObject.Date.toString() } };
|
||||
returnedObject.EventStartDate = { $date: { $numberLong: returnedObject.EventStartDate.toString() } };
|
||||
returnedObject.EventEndDate = { $date: { $numberLong: returnedObject.EventEndDate.toString() } };
|
||||
}
|
||||
});
|
||||
|
||||
@ -121,8 +124,8 @@ const MissionSchema = new Schema<IMission>(
|
||||
);
|
||||
|
||||
const AlertSchema = new Schema<IAlert>({
|
||||
Activation: Date,
|
||||
Expiry: Date,
|
||||
Activation: Number,
|
||||
Expiry: Number,
|
||||
MissionInfo: MissionSchema,
|
||||
ForceUnlock: Boolean,
|
||||
Tag: String
|
||||
@ -131,27 +134,26 @@ const AlertSchema = new Schema<IAlert>({
|
||||
AlertSchema.set("toJSON", {
|
||||
transform(_document, returnedObject) {
|
||||
returnedObject._id = { $oid: returnedObject._id.toString() };
|
||||
returnedObject.Activation = { $date: { $numberLong: returnedObject.Activation.toString() } };
|
||||
returnedObject.Expiry = { $date: { $numberLong: returnedObject.Expiry.toString() } };
|
||||
}
|
||||
});
|
||||
|
||||
const SortieMissionSchema = new Schema<ISortieMission>({
|
||||
missionType: String,
|
||||
modifierType: String,
|
||||
node: String,
|
||||
tileset: String
|
||||
});
|
||||
|
||||
SortieMissionSchema.set("toJSON", {
|
||||
transform(_document, returnedObject) {
|
||||
returnedObject._id = { $oid: returnedObject._id.toString() };
|
||||
}
|
||||
});
|
||||
const SortieMissionSchema = new Schema<ISortieMission>(
|
||||
{
|
||||
missionType: String,
|
||||
modifierType: String,
|
||||
node: String,
|
||||
tileset: String
|
||||
},
|
||||
{ _id: false }
|
||||
);
|
||||
|
||||
const LiteSortieSchema = new Schema<ILiteSortie>({
|
||||
Activation: Date,
|
||||
Expiry: Date,
|
||||
Activation: Number,
|
||||
Expiry: Number,
|
||||
Reward: String,
|
||||
Seed: String,
|
||||
Seed: Number,
|
||||
Boss: String,
|
||||
Missions: [SortieMissionSchema]
|
||||
});
|
||||
@ -159,15 +161,18 @@ const LiteSortieSchema = new Schema<ILiteSortie>({
|
||||
LiteSortieSchema.set("toJSON", {
|
||||
transform(_document, returnedObject) {
|
||||
returnedObject._id = { $oid: returnedObject._id.toString() };
|
||||
returnedObject.Activation = { $date: { $numberLong: returnedObject.Activation.toString() } };
|
||||
returnedObject.Expiry = { $date: { $numberLong: returnedObject.Expiry.toString() } };
|
||||
}
|
||||
});
|
||||
|
||||
const SortieSchema = new Schema<ISortie>({
|
||||
Activation: Date,
|
||||
Expiry: Date,
|
||||
Activation: Number,
|
||||
Expiry: Number,
|
||||
Reward: String,
|
||||
Seed: String,
|
||||
Seed: Number,
|
||||
Boss: String,
|
||||
ExtraDrops: [String],
|
||||
Variants: [SortieMissionSchema],
|
||||
Twitter: Boolean
|
||||
});
|
||||
@ -175,6 +180,8 @@ const SortieSchema = new Schema<ISortie>({
|
||||
SortieSchema.set("toJSON", {
|
||||
transform(_document, returnedObject) {
|
||||
returnedObject._id = { $oid: returnedObject._id.toString() };
|
||||
returnedObject.Activation = { $date: { $numberLong: returnedObject.Activation.toString() } };
|
||||
returnedObject.Expiry = { $date: { $numberLong: returnedObject.Expiry.toString() } };
|
||||
}
|
||||
});
|
||||
|
||||
@ -195,10 +202,10 @@ const JobSchema = new Schema<IJob>(
|
||||
);
|
||||
|
||||
const SyndicateMissionSchema = new Schema<ISyndicateMission>({
|
||||
Activation: Date,
|
||||
Expiry: Date,
|
||||
Activation: Number,
|
||||
Expiry: Number,
|
||||
Tag: String,
|
||||
Seed: String,
|
||||
Seed: Number,
|
||||
Nodes: [String],
|
||||
Jobs: [JobSchema]
|
||||
});
|
||||
@ -206,14 +213,16 @@ const SyndicateMissionSchema = new Schema<ISyndicateMission>({
|
||||
SyndicateMissionSchema.set("toJSON", {
|
||||
transform(_document, returnedObject) {
|
||||
returnedObject._id = { $oid: returnedObject._id.toString() };
|
||||
returnedObject.Activation = { $date: { $numberLong: returnedObject.Activation.toString() } };
|
||||
returnedObject.Expiry = { $date: { $numberLong: returnedObject.Expiry.toString() } };
|
||||
}
|
||||
});
|
||||
|
||||
const ActiveMissionSchema = new Schema<IActiveMission>({
|
||||
Activation: Date,
|
||||
Expiry: Date,
|
||||
Region: String,
|
||||
Seed: String,
|
||||
Activation: Number,
|
||||
Expiry: Number,
|
||||
Region: Number,
|
||||
Seed: Number,
|
||||
Node: String,
|
||||
MissionType: String,
|
||||
Modifier: String,
|
||||
@ -223,12 +232,14 @@ const ActiveMissionSchema = new Schema<IActiveMission>({
|
||||
ActiveMissionSchema.set("toJSON", {
|
||||
transform(_document, returnedObject) {
|
||||
returnedObject._id = { $oid: returnedObject._id.toString() };
|
||||
returnedObject.Activation = { $date: { $numberLong: returnedObject.Activation.toString() } };
|
||||
returnedObject.Expiry = { $date: { $numberLong: returnedObject.Expiry.toString() } };
|
||||
}
|
||||
});
|
||||
|
||||
const GlobalUpgradeSchema = new Schema<IGlobalUpgrade>({
|
||||
Activation: Date,
|
||||
Expiry: Date,
|
||||
Activation: Number,
|
||||
Expiry: Number,
|
||||
UpgradeType: String,
|
||||
OperationType: String,
|
||||
Value: String
|
||||
@ -237,14 +248,16 @@ const GlobalUpgradeSchema = new Schema<IGlobalUpgrade>({
|
||||
GlobalUpgradeSchema.set("toJSON", {
|
||||
transform(_document, returnedObject) {
|
||||
returnedObject._id = { $oid: returnedObject._id.toString() };
|
||||
returnedObject.Activation = { $date: { $numberLong: returnedObject.Activation.toString() } };
|
||||
returnedObject.Expiry = { $date: { $numberLong: returnedObject.Expiry.toString() } };
|
||||
}
|
||||
});
|
||||
|
||||
const FlashSaleSchema = new Schema<IFlashSale>(
|
||||
{
|
||||
TypeName: String,
|
||||
StartDate: Date,
|
||||
EndDate: Date,
|
||||
StartDate: Number,
|
||||
EndDate: Number,
|
||||
ShowInMarket: Boolean,
|
||||
HideFromMarket: Boolean,
|
||||
SupporterPack: Boolean,
|
||||
@ -257,6 +270,13 @@ const FlashSaleSchema = new Schema<IFlashSale>(
|
||||
{ _id: false }
|
||||
);
|
||||
|
||||
FlashSaleSchema.set("toJSON", {
|
||||
transform(_document, returnedObject) {
|
||||
returnedObject.StartDate = { $date: { $numberLong: returnedObject.StartDate.toString() } };
|
||||
returnedObject.EndDate = { $date: { $numberLong: returnedObject.EndDate.toString() } };
|
||||
}
|
||||
});
|
||||
|
||||
const ShopCategorySchema = new Schema<ICategory>(
|
||||
{
|
||||
CategoryName: String,
|
||||
@ -291,7 +311,7 @@ const InvasionMissionInfoSchema = new Schema<IInvasionMissionInfo>(
|
||||
);
|
||||
|
||||
const InvasionSchema = new Schema<IInvasion>({
|
||||
Activation: Date,
|
||||
Activation: Number,
|
||||
Faction: String,
|
||||
DefenderFaction: String,
|
||||
Node: String,
|
||||
@ -309,12 +329,13 @@ const InvasionSchema = new Schema<IInvasion>({
|
||||
InvasionSchema.set("toJSON", {
|
||||
transform(_document, returnedObject) {
|
||||
returnedObject._id = { $oid: returnedObject._id.toString() };
|
||||
returnedObject.Activation = { $date: { $numberLong: returnedObject.Activation.toString() } };
|
||||
}
|
||||
});
|
||||
|
||||
const NodeOverrideSchema = new Schema<INodeOverride>({
|
||||
Activation: Date,
|
||||
Expiry: Date,
|
||||
Activation: Number,
|
||||
Expiry: Number,
|
||||
Node: String,
|
||||
Faction: String,
|
||||
CustomNpcEncounters: [String],
|
||||
@ -324,6 +345,8 @@ const NodeOverrideSchema = new Schema<INodeOverride>({
|
||||
NodeOverrideSchema.set("toJSON", {
|
||||
transform(_document, returnedObject) {
|
||||
returnedObject._id = { $oid: returnedObject._id.toString() };
|
||||
returnedObject.Activation = { $date: { $numberLong: returnedObject.Activation.toString() } };
|
||||
returnedObject.Expiry = { $date: { $numberLong: returnedObject.Expiry.toString() } };
|
||||
}
|
||||
});
|
||||
|
||||
@ -338,16 +361,23 @@ const VoidTraderItemSchema = new Schema<IVoidTraderItem>(
|
||||
|
||||
const VoidTraderScheduleInfoSchema = new Schema<IVoidTraderScheduleInfo>(
|
||||
{
|
||||
Expiry: Date,
|
||||
PreviewHiddenUntil: Date,
|
||||
Expiry: Number,
|
||||
PreviewHiddenUntil: Number,
|
||||
FeaturedItem: String
|
||||
},
|
||||
{ _id: false }
|
||||
);
|
||||
|
||||
VoidTraderScheduleInfoSchema.set("toJSON", {
|
||||
transform(_document, returnedObject) {
|
||||
returnedObject.Expiry = { $date: { $numberLong: returnedObject.Expiry.toString() } };
|
||||
returnedObject.PreviewHiddenUntil = { $date: { $numberLong: returnedObject.PreviewHiddenUntil.toString() } };
|
||||
}
|
||||
});
|
||||
|
||||
const VoidTraderSchema = new Schema<IVoidTrader>({
|
||||
Activation: Date,
|
||||
Expiry: Date,
|
||||
Activation: Number,
|
||||
Expiry: Number,
|
||||
Character: String,
|
||||
Node: String,
|
||||
Completed: Boolean,
|
||||
@ -359,12 +389,14 @@ const VoidTraderSchema = new Schema<IVoidTrader>({
|
||||
VoidTraderSchema.set("toJSON", {
|
||||
transform(_document, returnedObject) {
|
||||
returnedObject._id = { $oid: returnedObject._id.toString() };
|
||||
returnedObject.Activation = { $date: { $numberLong: returnedObject.Activation.toString() } };
|
||||
returnedObject.Expiry = { $date: { $numberLong: returnedObject.Expiry.toString() } };
|
||||
}
|
||||
});
|
||||
|
||||
const VoidStormSchema = new Schema<IVoidStorm>({
|
||||
Activation: Date,
|
||||
Expiry: Date,
|
||||
Activation: Number,
|
||||
Expiry: Number,
|
||||
Node: String,
|
||||
ActiveMissionTier: String
|
||||
});
|
||||
@ -372,6 +404,8 @@ const VoidStormSchema = new Schema<IVoidStorm>({
|
||||
VoidStormSchema.set("toJSON", {
|
||||
transform(_document, returnedObject) {
|
||||
returnedObject._id = { $oid: returnedObject._id.toString() };
|
||||
returnedObject.Activation = { $date: { $numberLong: returnedObject.Activation.toString() } };
|
||||
returnedObject.Expiry = { $date: { $numberLong: returnedObject.Expiry.toString() } };
|
||||
}
|
||||
});
|
||||
|
||||
@ -384,8 +418,8 @@ const PrimeAccessAvailabilitySchema = new Schema<IPrimeAccessAvailability>(
|
||||
|
||||
const DailyDealSchema = new Schema<IDailyDeal>(
|
||||
{
|
||||
Activation: Date,
|
||||
Expiry: Date,
|
||||
Activation: Number,
|
||||
Expiry: Number,
|
||||
StoreItem: String,
|
||||
Discount: Number,
|
||||
OriginalPrice: Number,
|
||||
@ -396,6 +430,13 @@ const DailyDealSchema = new Schema<IDailyDeal>(
|
||||
{ _id: false }
|
||||
);
|
||||
|
||||
DailyDealSchema.set("toJSON", {
|
||||
transform(_document, returnedObject) {
|
||||
returnedObject.Activation = { $date: { $numberLong: returnedObject.Activation.toString() } };
|
||||
returnedObject.Expiry = { $date: { $numberLong: returnedObject.Expiry.toString() } };
|
||||
}
|
||||
});
|
||||
|
||||
const LibraryInfoSchema = new Schema<ILibraryInfo>(
|
||||
{
|
||||
LastCompletedTargetType: String
|
||||
@ -413,8 +454,8 @@ const PVPChallengeInstanceParam = new Schema<IPVPChallengeInstanceParam>(
|
||||
|
||||
const PVPChallengeInstanceSchema = new Schema<IPVPChallengeInstance>({
|
||||
challengeTypeRefID: String,
|
||||
startDate: Date,
|
||||
endDate: Date,
|
||||
startDate: Number,
|
||||
endDate: Number,
|
||||
params: [PVPChallengeInstanceParam],
|
||||
isGenerated: Boolean,
|
||||
PVPMode: String,
|
||||
@ -425,6 +466,8 @@ const PVPChallengeInstanceSchema = new Schema<IPVPChallengeInstance>({
|
||||
PVPChallengeInstanceSchema.set("toJSON", {
|
||||
transform(_document, returnedObject) {
|
||||
returnedObject._id = { $oid: returnedObject._id.toString() };
|
||||
returnedObject.startDate = { $date: { $numberLong: returnedObject.startDate.toString() } };
|
||||
returnedObject.endDate = { $date: { $numberLong: returnedObject.endDate.toString() } };
|
||||
}
|
||||
});
|
||||
|
||||
@ -451,8 +494,8 @@ FeaturedGuildShema.set("toJSON", {
|
||||
});
|
||||
|
||||
const ActiveChallengeSchema = new Schema<IActiveChallenge>({
|
||||
Activation: Date,
|
||||
Expiry: Date,
|
||||
Activation: Number,
|
||||
Expiry: Number,
|
||||
Daily: Boolean,
|
||||
Challenge: String
|
||||
});
|
||||
@ -460,6 +503,8 @@ const ActiveChallengeSchema = new Schema<IActiveChallenge>({
|
||||
FeaturedGuildShema.set("toJSON", {
|
||||
transform(_document, returnedObject) {
|
||||
returnedObject._id = { $oid: returnedObject._id.toString() };
|
||||
returnedObject.Activation = { $date: { $numberLong: returnedObject.Activation.toString() } };
|
||||
returnedObject.Expiry = { $date: { $numberLong: returnedObject.Expiry.toString() } };
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -1,8 +1,43 @@
|
||||
import { WorldState } from "@/src/models/worldStateModel";
|
||||
import { unixTimesInMs } from "@/src/constants/timeConstants";
|
||||
import {
|
||||
IActiveMission,
|
||||
ILiteSortie,
|
||||
ISortie,
|
||||
ISyndicateMission,
|
||||
IVoidStorm,
|
||||
IWorldState
|
||||
} from "@/src/types/worldStateTypes";
|
||||
import { getRandomNumber, getRandomKey } from "@/src/helpers/general";
|
||||
import { getRandomNodes, getCurrentRotation } from "@/src/helpers/worldstateHelpers";
|
||||
import { ExportRailjack, ExportRegions } from "warframe-public-export-plus";
|
||||
import { logger } from "@/src/utils/logger";
|
||||
import {
|
||||
factionSyndicates,
|
||||
neutralJobsSyndicates,
|
||||
neutralSyndicates,
|
||||
restSyndicates,
|
||||
CertusNormalJobs,
|
||||
CertusNarmerJobs,
|
||||
ZarimanNormalJobs,
|
||||
voidFisuresMissionTypes,
|
||||
validFisureMissionIndex,
|
||||
omniaNodes,
|
||||
liteSortiesBoss,
|
||||
endStates,
|
||||
modifierTypes,
|
||||
SortiesMissionTypes,
|
||||
voidTiers,
|
||||
FortunaNarmerJobs,
|
||||
FortunaNormalJobs
|
||||
} from "@/src/constants/worldStateConstants";
|
||||
|
||||
export const createWorldState = async () => {
|
||||
const worldState = new WorldState();
|
||||
await worldState.save();
|
||||
await updateSyndicateMissions();
|
||||
await updateVoidFisures();
|
||||
await updateSorties();
|
||||
return worldState;
|
||||
};
|
||||
|
||||
@ -11,6 +46,574 @@ export const getWorldState = async () => {
|
||||
if (!ws) {
|
||||
ws = await createWorldState();
|
||||
}
|
||||
|
||||
return ws;
|
||||
return ws.toJSON();
|
||||
};
|
||||
|
||||
export const worldStateRunner = async () => {
|
||||
await getWorldState();
|
||||
setInterval(async () => {
|
||||
logger.info("Update worldState");
|
||||
await updateSyndicateMissions();
|
||||
await updateVoidFisures();
|
||||
await updateSorties();
|
||||
}, unixTimesInMs.minute);
|
||||
};
|
||||
|
||||
const updateSyndicateMissions = async (): Promise<IWorldState> => {
|
||||
const currentDate = Date.now();
|
||||
const oneDayIntervalStart =
|
||||
Math.floor(currentDate / unixTimesInMs.day) * unixTimesInMs.day + 16 * unixTimesInMs.hour;
|
||||
const oneDayIntervalEnd = oneDayIntervalStart + unixTimesInMs.day;
|
||||
|
||||
const neutralJobsIntervalStart = Math.floor(currentDate / (2.5 * unixTimesInMs.hour)) * (2.5 * unixTimesInMs.hour);
|
||||
const neutralJobsIntervalEnd = neutralJobsIntervalStart + 2.5 * unixTimesInMs.hour;
|
||||
|
||||
const neutralSeed = getRandomNumber(1, 99999);
|
||||
|
||||
try {
|
||||
const ws = await WorldState.findOne();
|
||||
if (!ws) throw new Error("Missing worldState");
|
||||
|
||||
const syndicateArray = ws.SyndicateMissions || [];
|
||||
|
||||
const existingTags = syndicateArray.map(syndicate => syndicate.Tag);
|
||||
|
||||
const createNewSyndicateEntry = (tag: string): ISyndicateMission => {
|
||||
switch (true) {
|
||||
case factionSyndicates.includes(tag):
|
||||
return {
|
||||
Tag: tag,
|
||||
Seed: getRandomNumber(1, 99999),
|
||||
Nodes: getRandomNodes(7),
|
||||
Activation: oneDayIntervalStart,
|
||||
Expiry: oneDayIntervalEnd
|
||||
};
|
||||
case neutralJobsSyndicates.includes(tag):
|
||||
return {
|
||||
Tag: tag,
|
||||
Seed: neutralSeed,
|
||||
Nodes: [],
|
||||
Activation: neutralJobsIntervalStart,
|
||||
Expiry: neutralJobsIntervalEnd,
|
||||
Jobs: getJobs(tag)
|
||||
};
|
||||
case neutralSyndicates.includes(tag):
|
||||
return {
|
||||
Tag: tag,
|
||||
Seed: neutralSeed,
|
||||
Nodes: [],
|
||||
Activation: neutralJobsIntervalStart,
|
||||
Expiry: neutralJobsIntervalEnd
|
||||
};
|
||||
case restSyndicates.includes(tag):
|
||||
return {
|
||||
Tag: tag,
|
||||
Seed: getRandomNumber(1, 99999),
|
||||
Nodes: [],
|
||||
Activation: oneDayIntervalStart,
|
||||
Expiry: oneDayIntervalEnd
|
||||
};
|
||||
default:
|
||||
throw new Error(`Unhandled syndicate tag: ${tag}`);
|
||||
}
|
||||
};
|
||||
|
||||
[...factionSyndicates, ...neutralJobsSyndicates, ...neutralSyndicates, ...restSyndicates].forEach(tag => {
|
||||
if (!existingTags.includes(tag)) {
|
||||
syndicateArray.push(createNewSyndicateEntry(tag));
|
||||
} else {
|
||||
const syndicateIndex = existingTags.indexOf(tag);
|
||||
const shouldUpdate = currentDate >= syndicateArray[syndicateIndex].Expiry;
|
||||
|
||||
if (shouldUpdate) {
|
||||
syndicateArray[syndicateIndex] = {
|
||||
...syndicateArray[syndicateIndex],
|
||||
Tag: tag,
|
||||
Seed:
|
||||
neutralJobsSyndicates.includes(tag) || neutralSyndicates.includes(tag)
|
||||
? neutralSeed
|
||||
: getRandomNumber(1, 99999),
|
||||
Nodes:
|
||||
neutralJobsSyndicates.includes(tag) || neutralSyndicates.includes(tag)
|
||||
? []
|
||||
: getRandomNodes(7),
|
||||
Activation:
|
||||
neutralJobsSyndicates.includes(tag) || neutralSyndicates.includes(tag)
|
||||
? neutralJobsIntervalStart
|
||||
: oneDayIntervalStart,
|
||||
Expiry:
|
||||
neutralJobsSyndicates.includes(tag) || neutralSyndicates.includes(tag)
|
||||
? neutralJobsIntervalEnd
|
||||
: oneDayIntervalEnd,
|
||||
Jobs: neutralJobsSyndicates.includes(tag) ? getJobs(tag) : undefined
|
||||
};
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
ws.SyndicateMissions = syndicateArray;
|
||||
|
||||
await ws.save();
|
||||
return ws;
|
||||
} catch (error) {
|
||||
throw new Error(`Error while updating Syndicates ${error}`);
|
||||
}
|
||||
};
|
||||
|
||||
const getJobs = (tag: string) => {
|
||||
const rotration = getCurrentRotation();
|
||||
switch (tag) {
|
||||
case "CetusSyndicate":
|
||||
const Certusjobs = [
|
||||
{
|
||||
jobType: CertusNormalJobs[Math.floor(Math.random() * CertusNormalJobs.length)],
|
||||
rewards: `/Lotus/Types/Game/MissionDecks/EidolonJobMissionRewards/TierATable${rotration}Rewards`,
|
||||
masteryReq: 0,
|
||||
minEnemyLevel: 5,
|
||||
maxEnemyLevel: 15,
|
||||
xpAmounts: [410, 410, 410]
|
||||
},
|
||||
{
|
||||
jobType: CertusNormalJobs[Math.floor(Math.random() * CertusNormalJobs.length)],
|
||||
rewards: `/Lotus/Types/Game/MissionDecks/EidolonJobMissionRewards/TierBTable${rotration}Rewards`,
|
||||
masteryReq: 1,
|
||||
minEnemyLevel: 10,
|
||||
maxEnemyLevel: 30,
|
||||
xpAmounts: [750, 750, 750]
|
||||
},
|
||||
{
|
||||
jobType: CertusNormalJobs[Math.floor(Math.random() * CertusNormalJobs.length)],
|
||||
rewards: `/Lotus/Types/Game/MissionDecks/EidolonJobMissionRewards/TierCTable${rotration}Rewards`,
|
||||
masteryReq: 2,
|
||||
minEnemyLevel: 20,
|
||||
maxEnemyLevel: 40,
|
||||
xpAmounts: [580, 580, 580, 850]
|
||||
},
|
||||
{
|
||||
jobType: CertusNormalJobs[Math.floor(Math.random() * CertusNormalJobs.length)],
|
||||
rewards: `/Lotus/Types/Game/MissionDecks/EidolonJobMissionRewards/TierDTable${rotration}Rewards`,
|
||||
masteryReq: 3,
|
||||
minEnemyLevel: 30,
|
||||
maxEnemyLevel: 50,
|
||||
xpAmounts: [580, 580, 580, 580, 1130]
|
||||
},
|
||||
{
|
||||
jobType: CertusNormalJobs[Math.floor(Math.random() * CertusNormalJobs.length)],
|
||||
rewards: `/Lotus/Types/Game/MissionDecks/EidolonJobMissionRewards/TierETable${rotration}Rewards`,
|
||||
masteryReq: 5,
|
||||
minEnemyLevel: 40,
|
||||
maxEnemyLevel: 60,
|
||||
xpAmounts: [710, 710, 710, 710, 1390]
|
||||
},
|
||||
{
|
||||
jobType: CertusNormalJobs[Math.floor(Math.random() * CertusNormalJobs.length)],
|
||||
rewards: `/Lotus/Types/Game/MissionDecks/EidolonJobMissionRewards/TierETable${rotration}Rewards`,
|
||||
masteryReq: 10,
|
||||
minEnemyLevel: 100,
|
||||
maxEnemyLevel: 100,
|
||||
xpAmounts: [840, 840, 840, 840, 1660]
|
||||
},
|
||||
{
|
||||
jobType: CertusNarmerJobs[Math.floor(Math.random() * CertusNarmerJobs.length)],
|
||||
rewards: `/Lotus/Types/Game/MissionDecks/EidolonJobMissionRewards/NarmerTable${rotration}Rewards`,
|
||||
masteryReq: 0,
|
||||
minEnemyLevel: 50,
|
||||
maxEnemyLevel: 70,
|
||||
xpAmounts: [820, 820, 820, 820, 1610]
|
||||
}
|
||||
];
|
||||
return Certusjobs;
|
||||
|
||||
case "SolarisSyndicate":
|
||||
const FortunaJobs = [
|
||||
{
|
||||
jobType: FortunaNormalJobs[Math.floor(Math.random() * FortunaNormalJobs.length)],
|
||||
rewards: `/Lotus/Types/Game/MissionDecks/VenusJobMissionRewards/VenusTierATable${rotration}Rewards`,
|
||||
masteryReq: 0,
|
||||
minEnemyLevel: 5,
|
||||
maxEnemyLevel: 15,
|
||||
xpAmounts: [410, 410, 410]
|
||||
},
|
||||
{
|
||||
jobType: FortunaNormalJobs[Math.floor(Math.random() * FortunaNormalJobs.length)],
|
||||
rewards: `/Lotus/Types/Game/MissionDecks/VenusJobMissionRewards/VenusTierBTable${rotration}Rewards`,
|
||||
masteryReq: 1,
|
||||
minEnemyLevel: 10,
|
||||
maxEnemyLevel: 30,
|
||||
xpAmounts: [750, 750, 750]
|
||||
},
|
||||
{
|
||||
jobType: FortunaNormalJobs[Math.floor(Math.random() * FortunaNormalJobs.length)],
|
||||
rewards: `/Lotus/Types/Game/MissionDecks/VenusJobMissionRewards/VenusTierCTable${rotration}Rewards`,
|
||||
masteryReq: 2,
|
||||
minEnemyLevel: 20,
|
||||
maxEnemyLevel: 40,
|
||||
xpAmounts: [580, 580, 580, 850]
|
||||
},
|
||||
{
|
||||
jobType: FortunaNormalJobs[Math.floor(Math.random() * FortunaNormalJobs.length)],
|
||||
rewards: `/Lotus/Types/Game/MissionDecks/VenusJobMissionRewards/VenusTierDTable${rotration}Rewards`,
|
||||
masteryReq: 3,
|
||||
minEnemyLevel: 30,
|
||||
maxEnemyLevel: 50,
|
||||
xpAmounts: [580, 580, 580, 580, 1130]
|
||||
},
|
||||
{
|
||||
jobType: FortunaNormalJobs[Math.floor(Math.random() * FortunaNormalJobs.length)],
|
||||
rewards: `/Lotus/Types/Game/MissionDecks/VenusJobMissionRewards/VenusTierETable${rotration}Rewards`,
|
||||
masteryReq: 5,
|
||||
minEnemyLevel: 40,
|
||||
maxEnemyLevel: 60,
|
||||
xpAmounts: [710, 710, 710, 710, 1390]
|
||||
},
|
||||
{
|
||||
jobType: FortunaNormalJobs[Math.floor(Math.random() * FortunaNormalJobs.length)],
|
||||
rewards: `/Lotus/Types/Game/MissionDecks/VenusJobMissionRewards/VenusTierETable${rotration}Rewards`,
|
||||
masteryReq: 10,
|
||||
minEnemyLevel: 100,
|
||||
maxEnemyLevel: 100,
|
||||
xpAmounts: [840, 840, 840, 840, 1660]
|
||||
},
|
||||
{
|
||||
jobType: FortunaNarmerJobs[Math.floor(Math.random() * FortunaNarmerJobs.length)],
|
||||
rewards: `/Lotus/Types/Game/MissionDecks/VenusJobMissionRewards/VenusNarmerTable${rotration}Rewards`,
|
||||
masteryReq: 0,
|
||||
minEnemyLevel: 50,
|
||||
maxEnemyLevel: 70,
|
||||
xpAmounts: [820, 820, 820, 820, 1610]
|
||||
}
|
||||
];
|
||||
return FortunaJobs;
|
||||
|
||||
case "EntratiSyndicate":
|
||||
const ZarimanJobs = [
|
||||
{
|
||||
jobType: ZarimanNormalJobs[Math.floor(Math.random() * ZarimanNormalJobs.length)],
|
||||
rewards: `/Lotus/Types/Game/MissionDecks/DeimosMissionRewards/TierATable${getRandomKey(["A", "B", "C"])}Rewards`,
|
||||
masteryReq: 0,
|
||||
minEnemyLevel: 5,
|
||||
maxEnemyLevel: 15,
|
||||
xpAmounts: [5, 5, 5]
|
||||
},
|
||||
{
|
||||
jobType: ZarimanNormalJobs[Math.floor(Math.random() * ZarimanNormalJobs.length)],
|
||||
rewards: `/Lotus/Types/Game/MissionDecks/DeimosMissionRewards/TierCTable${getRandomKey(["A", "B", "C"])}Rewards`,
|
||||
masteryReq: 1,
|
||||
minEnemyLevel: 15,
|
||||
maxEnemyLevel: 25,
|
||||
xpAmounts: [9, 9, 9]
|
||||
},
|
||||
{
|
||||
jobType: ZarimanNormalJobs[Math.floor(Math.random() * ZarimanNormalJobs.length)],
|
||||
rewards: `/Lotus/Types/Game/MissionDecks/DeimosMissionRewards/TierBTable${getRandomKey(["A", "B", "C"])}Rewards`,
|
||||
masteryReq: 5,
|
||||
minEnemyLevel: 25,
|
||||
maxEnemyLevel: 30,
|
||||
endless: true,
|
||||
xpAmounts: [14, 14, 14]
|
||||
},
|
||||
{
|
||||
jobType: ZarimanNormalJobs[Math.floor(Math.random() * ZarimanNormalJobs.length)],
|
||||
rewards: `/Lotus/Types/Game/MissionDecks/DeimosMissionRewards/TierDTable${getRandomKey(["A", "B", "C"])}Rewards`,
|
||||
masteryReq: 2,
|
||||
minEnemyLevel: 30,
|
||||
maxEnemyLevel: 40,
|
||||
xpAmounts: [19, 19, 19, 29]
|
||||
},
|
||||
{
|
||||
jobType: ZarimanNormalJobs[Math.floor(Math.random() * ZarimanNormalJobs.length)],
|
||||
rewards: `/Lotus/Types/Game/MissionDecks/DeimosMissionRewards/TierETable${getRandomKey(["A", "B", "C"])}Rewards`,
|
||||
masteryReq: 3,
|
||||
minEnemyLevel: 40,
|
||||
maxEnemyLevel: 60,
|
||||
xpAmounts: [21, 21, 21, 21, 41]
|
||||
},
|
||||
{
|
||||
jobType: ZarimanNormalJobs[Math.floor(Math.random() * ZarimanNormalJobs.length)],
|
||||
rewards: `/Lotus/Types/Game/MissionDecks/DeimosMissionRewards/TierETable${getRandomKey(["A", "B", "C"])}Rewards`,
|
||||
masteryReq: 10,
|
||||
minEnemyLevel: 100,
|
||||
maxEnemyLevel: 100,
|
||||
xpAmounts: [25, 25, 25, 25, 50]
|
||||
},
|
||||
{
|
||||
rewards: `/Lotus/Types/Game/MissionDecks/DeimosMissionRewards/VaultBountyTierATable${getCurrentRotation()}Rewards`,
|
||||
masteryReq: 5,
|
||||
minEnemyLevel: 30,
|
||||
maxEnemyLevel: 40,
|
||||
xpAmounts: [2, 2, 2, 4],
|
||||
locationTag: "ChamberB",
|
||||
isVault: true
|
||||
},
|
||||
{
|
||||
rewards: `/Lotus/Types/Game/MissionDecks/DeimosMissionRewards/VaultBountyTierBTable${getCurrentRotation()}Rewards`,
|
||||
masteryReq: 5,
|
||||
minEnemyLevel: 40,
|
||||
maxEnemyLevel: 50,
|
||||
xpAmounts: [4, 4, 4, 5],
|
||||
locationTag: "ChamberA",
|
||||
isVault: true
|
||||
},
|
||||
{
|
||||
rewards: `/Lotus/Types/Game/MissionDecks/DeimosMissionRewards/VaultBountyTierCTable${getCurrentRotation()}Rewards`,
|
||||
masteryReq: 5,
|
||||
minEnemyLevel: 50,
|
||||
maxEnemyLevel: 60,
|
||||
xpAmounts: [5, 5, 5, 7],
|
||||
locationTag: "ChamberC",
|
||||
isVault: true
|
||||
}
|
||||
];
|
||||
return ZarimanJobs;
|
||||
|
||||
default:
|
||||
throw new Error(`Error while updating Syndicates: Unknown Jobs syndicate ${tag}`);
|
||||
}
|
||||
};
|
||||
|
||||
const updateVoidFisures = async () => {
|
||||
const curDate = Date.now();
|
||||
try {
|
||||
const ws = await WorldState.findOne();
|
||||
if (!ws) throw new Error("Missing worldState");
|
||||
const voidFisures = ws.ActiveMissions;
|
||||
const voidStorms = ws.VoidStorms;
|
||||
const voidFisuresByTier: { [key: string]: IActiveMission[] } = {
|
||||
VoidT1: [],
|
||||
VoidT2: [],
|
||||
VoidT3: [],
|
||||
VoidT4: [],
|
||||
VoidT5: [],
|
||||
VoidT6: []
|
||||
};
|
||||
const voidStormsByTier: { [key: string]: IVoidStorm[] } = {
|
||||
VoidT1: [],
|
||||
VoidT2: [],
|
||||
VoidT3: [],
|
||||
VoidT4: [],
|
||||
VoidT5: [],
|
||||
VoidT6: []
|
||||
};
|
||||
|
||||
if (voidFisures) {
|
||||
voidFisures.forEach(mission => {
|
||||
const tier = mission.Modifier;
|
||||
if (tier) {
|
||||
if (!voidFisuresByTier[tier]) {
|
||||
voidFisuresByTier[tier] = [];
|
||||
}
|
||||
voidFisuresByTier[tier].push(mission);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (voidStorms) {
|
||||
voidStorms.forEach(mission => {
|
||||
const tier = mission.ActiveMissionTier;
|
||||
if (tier) {
|
||||
if (!voidStormsByTier[tier]) {
|
||||
voidStormsByTier[tier] = [];
|
||||
}
|
||||
voidStormsByTier[tier].push(mission);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
voidTiers.forEach(voidTier => {
|
||||
if (voidFisuresByTier[voidTier].length < 3) {
|
||||
const nodeData = getRandomFisureNode(false, voidTier == "VoidT6");
|
||||
logger.debug(voidTier);
|
||||
if (!nodeData.missionIndex) nodeData.missionIndex = 1;
|
||||
const node = {
|
||||
Region: nodeData.systemIndex,
|
||||
Seed: getRandomNumber(1, 99999),
|
||||
Activation: curDate,
|
||||
Expiry: curDate + Math.floor(Math.random() * unixTimesInMs.hour),
|
||||
Node: nodeData.nodeKey,
|
||||
MissionType: voidFisuresMissionTypes[nodeData.missionIndex],
|
||||
Modifier: voidTier,
|
||||
Hard: Math.random() < 0.1
|
||||
} as IActiveMission;
|
||||
voidFisures?.push(node);
|
||||
}
|
||||
|
||||
if (voidStormsByTier[voidTier].length < 2) {
|
||||
const nodeData = getRandomFisureNode(true, voidTier == "VoidT6");
|
||||
logger.debug(voidTier);
|
||||
const node = {
|
||||
Activation: curDate,
|
||||
Expiry: curDate + Math.floor(Math.random() * unixTimesInMs.hour),
|
||||
Node: nodeData.nodeKey,
|
||||
ActiveMissionTier: voidTier
|
||||
} as IVoidStorm;
|
||||
voidStorms?.push(node);
|
||||
}
|
||||
});
|
||||
await ws.save();
|
||||
return ws;
|
||||
} catch (error) {
|
||||
throw new Error(`Error while updating VoidFisures: ${error}`);
|
||||
}
|
||||
};
|
||||
|
||||
const getRandomFisureNode = (isRailJack: boolean, isOmnia: boolean) => {
|
||||
const validNodes = Object.entries(ExportRegions)
|
||||
.map(([key, node]) => {
|
||||
return {
|
||||
...node,
|
||||
nodeKey: key
|
||||
};
|
||||
})
|
||||
.filter(node => {
|
||||
return validFisureMissionIndex.includes(node.missionIndex) && !node.missionName.includes("Archwing");
|
||||
});
|
||||
|
||||
if (isRailJack) {
|
||||
const railJackNodes = Object.keys(ExportRailjack.nodes);
|
||||
const randomKey = railJackNodes[Math.floor(Math.random() * railJackNodes.length)];
|
||||
return {
|
||||
nodeKey: randomKey
|
||||
};
|
||||
} else if (isOmnia) {
|
||||
const validOmniaNodes = validNodes.filter(node => {
|
||||
return omniaNodes.includes(node.nodeKey);
|
||||
});
|
||||
const randomNode = validOmniaNodes[Math.floor(Math.random() * validOmniaNodes.length)];
|
||||
return {
|
||||
nodeKey: randomNode.nodeKey,
|
||||
systemIndex: randomNode.systemIndex,
|
||||
missionIndex: randomNode.missionIndex
|
||||
};
|
||||
} else {
|
||||
const randomNode = validNodes[Math.floor(Math.random() * validNodes.length)];
|
||||
return {
|
||||
nodeKey: randomNode.nodeKey,
|
||||
systemIndex: randomNode.systemIndex,
|
||||
missionIndex: randomNode.missionIndex
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
const updateSorties = async () => {
|
||||
const currentDate = Date.now();
|
||||
const oneDayIntervalStart =
|
||||
Math.floor(currentDate / unixTimesInMs.day) * unixTimesInMs.day + 16 * unixTimesInMs.hour;
|
||||
const oneDayIntervalEnd = oneDayIntervalStart + unixTimesInMs.day;
|
||||
const oneWeekIntervalStart =
|
||||
Math.floor(currentDate / (unixTimesInMs.day * 7)) * unixTimesInMs.day * 7 + 16 * unixTimesInMs.hour;
|
||||
const oneWeekIntervalEnd = oneDayIntervalStart + unixTimesInMs.day * 7;
|
||||
const nodes = Object.entries(ExportRegions).map(([key, node]) => {
|
||||
return {
|
||||
nodeSystemIndex: node.systemIndex,
|
||||
nodeKey: key
|
||||
};
|
||||
});
|
||||
|
||||
try {
|
||||
const ws = await WorldState.findOne();
|
||||
if (!ws) throw new Error("Missing worldState");
|
||||
const liteSorties: ILiteSortie[] = ws?.LiteSorties;
|
||||
const sorties: ISortie[] = ws?.Sorties;
|
||||
|
||||
[...liteSorties, ...sorties].forEach((sortie, index, array) => {
|
||||
if (currentDate >= sortie.Expiry) array.splice(index, 1);
|
||||
});
|
||||
|
||||
if (liteSorties.length < 1) {
|
||||
const sortie: ILiteSortie = {
|
||||
Activation: oneWeekIntervalStart,
|
||||
Expiry: oneWeekIntervalEnd,
|
||||
Reward: "/Lotus/Types/Game/MissionDecks/ArchonSortieRewards",
|
||||
Seed: getRandomNumber(1, 99999),
|
||||
Boss: liteSortiesBoss[Math.floor(Math.random() * liteSortiesBoss.length)],
|
||||
Missions: [
|
||||
{
|
||||
missionType: SortiesMissionTypes[Math.floor(Math.random() * SortiesMissionTypes.length)],
|
||||
node: nodes[Math.floor(Math.random() * nodes.length)].nodeKey
|
||||
},
|
||||
{
|
||||
missionType: SortiesMissionTypes[Math.floor(Math.random() * SortiesMissionTypes.length)],
|
||||
node: nodes[Math.floor(Math.random() * nodes.length)].nodeKey
|
||||
},
|
||||
{
|
||||
missionType: SortiesMissionTypes[Math.floor(Math.random() * SortiesMissionTypes.length)],
|
||||
node: nodes[Math.floor(Math.random() * nodes.length)].nodeKey
|
||||
}
|
||||
]
|
||||
};
|
||||
liteSorties.push(sortie);
|
||||
}
|
||||
|
||||
if (sorties.length < 1) {
|
||||
const randomBoss = endStates[Math.floor(Math.random() * endStates.length)];
|
||||
const randomRegionIndex = [
|
||||
Math.floor(Math.random() * randomBoss.regions.length),
|
||||
Math.floor(Math.random() * randomBoss.regions.length),
|
||||
Math.floor(Math.random() * randomBoss.regions.length)
|
||||
];
|
||||
const randomRegionIndexFake = randomRegionIndex;
|
||||
randomRegionIndexFake.forEach((element, index, array) => {
|
||||
if (element == 13) {
|
||||
array[index] = element + 2;
|
||||
} else if (element == 14) {
|
||||
array[index] = element + 1;
|
||||
}
|
||||
});
|
||||
const filteredNodes = [
|
||||
nodes.filter(node => {
|
||||
return randomRegionIndexFake[0] === node.nodeSystemIndex;
|
||||
}),
|
||||
nodes.filter(node => {
|
||||
return randomRegionIndexFake[1] === node.nodeSystemIndex;
|
||||
}),
|
||||
nodes.filter(node => {
|
||||
return randomRegionIndexFake[2] === node.nodeSystemIndex;
|
||||
})
|
||||
];
|
||||
const sortie: ISortie = {
|
||||
Activation: oneDayIntervalStart,
|
||||
Expiry: oneDayIntervalEnd,
|
||||
ExtraDrops: [],
|
||||
Reward: "/Lotus/Types/Game/MissionDecks/SortieRewards",
|
||||
Seed: getRandomNumber(1, 99999),
|
||||
Boss: randomBoss.bossName,
|
||||
Variants: [
|
||||
{
|
||||
missionType:
|
||||
randomBoss.regions[randomRegionIndex[0]].missions[
|
||||
Math.floor(Math.random() * randomBoss.regions[randomRegionIndex[0]].missions.length)
|
||||
],
|
||||
modifierType: modifierTypes[Math.floor(Math.random() * modifierTypes.length)],
|
||||
node: filteredNodes[0][Math.floor(Math.random() * filteredNodes[0].length)].nodeKey,
|
||||
tileset: "CorpusShipTileset"
|
||||
},
|
||||
{
|
||||
missionType:
|
||||
randomBoss.regions[randomRegionIndex[1]].missions[
|
||||
Math.floor(Math.random() * randomBoss.regions[randomRegionIndex[1]].missions.length)
|
||||
],
|
||||
modifierType: modifierTypes[Math.floor(Math.random() * modifierTypes.length)],
|
||||
node: filteredNodes[1][Math.floor(Math.random() * filteredNodes[1].length)].nodeKey,
|
||||
tileset: "OrokinMoonTilesetCorpus"
|
||||
},
|
||||
{
|
||||
missionType:
|
||||
randomBoss.regions[randomRegionIndex[2]].missions[
|
||||
Math.floor(Math.random() * randomBoss.regions[randomRegionIndex[2]].missions.length)
|
||||
],
|
||||
modifierType: modifierTypes[Math.floor(Math.random() * modifierTypes.length)],
|
||||
node: filteredNodes[2][Math.floor(Math.random() * filteredNodes[2].length)].nodeKey,
|
||||
tileset: "CorpusShipTileset"
|
||||
}
|
||||
],
|
||||
Twitter: true
|
||||
};
|
||||
sorties.push(sortie);
|
||||
}
|
||||
|
||||
await ws.save();
|
||||
return ws;
|
||||
} catch (error) {
|
||||
throw new Error(`Error while updating Sorties ${error}`);
|
||||
}
|
||||
};
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { IMongoDate, IOid } from "@/src/types/commonTypes";
|
||||
import { IOid } from "@/src/types/commonTypes";
|
||||
|
||||
export interface IMessage {
|
||||
LanguageCode?: string;
|
||||
@ -11,8 +11,8 @@ export interface ILink {
|
||||
}
|
||||
|
||||
export interface IBaseWorldStateObject {
|
||||
Activation: IMongoDate;
|
||||
Expiry: IMongoDate;
|
||||
Activation: number;
|
||||
Expiry: number;
|
||||
_id?: IOid;
|
||||
}
|
||||
|
||||
@ -61,12 +61,11 @@ export interface IEvent {
|
||||
Icon?: string;
|
||||
Community?: boolean;
|
||||
Priority?: boolean;
|
||||
EventStartDate?: IMongoDate;
|
||||
EventEndDate?: IMongoDate;
|
||||
EventStartDate?: number;
|
||||
EventEndDate?: number;
|
||||
MobileOnly?: boolean;
|
||||
HideEndDateModifier?: boolean;
|
||||
Date?: IMongoDate;
|
||||
_id?: IOid;
|
||||
Date?: number;
|
||||
}
|
||||
|
||||
export interface IGoal extends IBaseWorldStateObject {
|
||||
@ -103,7 +102,7 @@ export interface ISortieMission {
|
||||
}
|
||||
|
||||
export interface ISortie extends Omit<ILiteSortie, "Missions"> {
|
||||
// ExtraDrops: []; Unknown
|
||||
ExtraDrops: string[]; //Unknown
|
||||
Variants: ISortieMission[];
|
||||
Twitter: boolean;
|
||||
}
|
||||
@ -150,8 +149,8 @@ export interface IGlobalUpgrade extends IBaseWorldStateObject {
|
||||
}
|
||||
|
||||
export interface IFlashSale {
|
||||
StartDate: IMongoDate;
|
||||
EndDate: IMongoDate;
|
||||
StartDate: number;
|
||||
EndDate: number;
|
||||
TypeName: string;
|
||||
ShowInMarket: boolean;
|
||||
HideFromMarket: boolean;
|
||||
@ -200,8 +199,8 @@ export interface IInvasionMissionInfo {
|
||||
}
|
||||
|
||||
export interface INodeOverride {
|
||||
Activation?: IMongoDate;
|
||||
Expiry?: IMongoDate;
|
||||
Activation?: number;
|
||||
Expiry?: number;
|
||||
Node: string;
|
||||
Faction?: string;
|
||||
CustomNpcEncounters?: string[];
|
||||
@ -224,7 +223,7 @@ export interface IVoidTraderItem {
|
||||
}
|
||||
|
||||
export interface IVoidTraderScheduleInfo extends Omit<IBaseWorldStateObject, "Activation" | "_id"> {
|
||||
PreviewHiddenUntil?: IMongoDate;
|
||||
PreviewHiddenUntil?: number;
|
||||
FeaturedItem?: string;
|
||||
}
|
||||
|
||||
@ -252,8 +251,8 @@ export interface ILibraryInfo {
|
||||
|
||||
export interface IPVPChallengeInstance {
|
||||
challengeTypeRefID: string;
|
||||
startDate: IMongoDate;
|
||||
endDate: IMongoDate;
|
||||
startDate: number;
|
||||
endDate: number;
|
||||
params: IPVPChallengeInstanceParam[];
|
||||
isGenerated: boolean;
|
||||
PVPMode: string;
|
||||
@ -302,8 +301,8 @@ export interface IWorldState {
|
||||
Events?: IEvent[];
|
||||
Goals?: IGoal[];
|
||||
Alerts?: IAlert[];
|
||||
Sorties?: ISortie[];
|
||||
LiteSorties?: ILiteSortie[];
|
||||
Sorties: ISortie[];
|
||||
LiteSorties: ILiteSortie[];
|
||||
SyndicateMissions?: ISyndicateMission[];
|
||||
ActiveMissions?: IActiveMission[];
|
||||
GlobalUpgrades?: IGlobalUpgrade[];
|
||||
|
@ -261,6 +261,10 @@
|
||||
Universal Polarity Everywhere
|
||||
</label>
|
||||
</div>
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" id="useStaticWorldState" />
|
||||
<label class="form-check-label" for="useStaticWorldState">Use Static WorldSatte</label>
|
||||
</div>
|
||||
<div class="form-group mt-2 mb-2">
|
||||
<label class="form-label" for="spoofMasteryRank">
|
||||
Spoofed Mastery Rank (-1 to disable)
|
||||
|
Loading…
x
Reference in New Issue
Block a user