SpaceNinjaServer/src/services/configService.ts

212 lines
7.0 KiB
TypeScript
Raw Normal View History

import fs from "fs";
import path from "path";
import { repoDir } from "../helpers/pathHelper.ts";
import { args } from "../helpers/commandLineArguments.ts";
import { Inbox } from "../models/inboxModel.ts";
import type { Request } from "express";
2024-05-15 21:55:59 +02:00
export interface IConfig {
2024-05-15 21:55:59 +02:00
mongodbUrl: string;
logger: {
files: boolean;
level: string; // "fatal" | "error" | "warn" | "info" | "http" | "debug" | "trace";
};
2024-05-15 21:55:59 +02:00
myAddress: string;
bindAddress?: string;
httpPort?: number;
httpsPort?: number;
ircAddress?: string;
hubAddress?: string;
nrsAddress?: string;
administratorNames?: string[];
2024-05-15 21:55:59 +02:00
autoCreateAccount?: boolean;
skipTutorial?: boolean;
2024-05-29 22:08:41 +02:00
unlockAllSkins?: boolean;
fullyStockedVendors?: boolean;
skipClanKeyCrafting?: boolean;
spoofMasteryRank?: number;
relicRewardItemCountMultiplier?: number;
nightwaveStandingMultiplier?: number;
unfaithfulBugFixes?: {
ignore1999LastRegionPlayed?: boolean;
fixXtraCheeseTimer?: boolean;
useAnniversaryTagForOldGoals?: boolean;
};
worldState?: {
creditBoost?: boolean;
affinityBoost?: boolean;
resourceBoost?: boolean;
tennoLiveRelay?: boolean;
baroTennoConRelay?: boolean;
baroAlwaysAvailable?: boolean;
baroFullyStocked?: boolean;
varziaFullyStocked?: boolean;
wolfHunt?: boolean;
orphixVenom?: boolean;
longShadow?: boolean;
hallowedFlame?: boolean;
anniversary?: number;
hallowedNightmares?: boolean;
hallowedNightmaresRewardsOverride?: number;
naberusNightsOverride?: boolean;
proxyRebellion?: boolean;
proxyRebellionRewardsOverride?: number;
voidCorruption2025Week1?: boolean;
voidCorruption2025Week2?: boolean;
voidCorruption2025Week3?: boolean;
voidCorruption2025Week4?: boolean;
qtccAlerts?: boolean;
galleonOfGhouls?: number;
ghoulEmergenceOverride?: boolean;
plagueStarOverride?: boolean;
starDaysOverride?: boolean;
dogDaysOverride?: boolean;
dogDaysRewardsOverride?: number;
bellyOfTheBeast?: boolean;
bellyOfTheBeastProgressOverride?: number;
eightClaw?: boolean;
eightClawProgressOverride?: number;
thermiaFracturesOverride?: boolean;
thermiaFracturesProgressOverride?: number;
eidolonOverride?: string;
vallisOverride?: string;
duviriOverride?: string;
nightwaveOverride?: string;
allTheFissures?: string;
varziaOverride?: string;
circuitGameModes?: string[];
darvoStockMultiplier?: number;
};
dev?: {
keepVendorsExpired?: boolean;
};
2024-05-15 21:55:59 +02:00
}
export const configRemovedOptionsKeys = [
"NRS",
"myIrcAddresses",
"skipAllDialogue",
"infiniteCredits",
"infinitePlatinum",
"infiniteEndo",
"infiniteRegalAya",
"infiniteHelminthMaterials",
"claimingBlueprintRefundsIngredients",
"dontSubtractPurchaseCreditCost",
"dontSubtractPurchasePlatinumCost",
"dontSubtractPurchaseItemCost",
"dontSubtractPurchaseStandingCost",
"dontSubtractVoidTraces",
"dontSubtractConsumables",
"universalPolarityEverywhere",
"unlockDoubleCapacityPotatoesEverywhere",
"unlockExilusEverywhere",
"unlockArcanesEverywhere",
"unlockAllProfitTakerStages",
"unlockAllSimarisResearchEntries",
"unlockAllScans",
"unlockAllShipFeatures",
"unlockAllCapturaScenes",
"noDailyStandingLimits",
"noDailyFocusLimit",
"noArgonCrystalDecay",
"noMasteryRankUpCooldown",
"noVendorPurchaseLimits",
"noDecoBuildStage",
"noDeathMarks",
"noKimCooldowns",
"syndicateMissionsRepeatable",
"instantFinishRivenChallenge",
"instantResourceExtractorDrones",
"noResourceExtractorDronesDamage",
"baroAlwaysAvailable",
"baroFullyStocked",
"missionsCanGiveAllRelics",
"exceptionalRelicsAlwaysGiveBronzeReward",
"flawlessRelicsAlwaysGiveSilverReward",
"radiantRelicsAlwaysGiveGoldReward",
"disableDailyTribute",
"noDojoRoomBuildStage",
"noDojoDecoBuildStage",
"fastDojoRoomDestruction",
"noDojoResearchCosts",
"noDojoResearchTime",
"fastClanAscension",
"unlockAllFlavourItems",
"unlockAllShipDecorations",
"unlockAllDecoRecipes"
];
export const configPath = path.join(repoDir, args.configPath ?? "config.json");
2024-05-15 21:55:59 +02:00
export const config: IConfig = {
mongodbUrl: "mongodb://127.0.0.1:27017/openWF",
logger: {
files: true,
level: "trace"
},
myAddress: "localhost"
};
export const loadConfig = (): void => {
const newConfig = JSON.parse(fs.readFileSync(configPath, "utf-8")) as IConfig;
// Set all values to undefined now so if the new config.json omits some fields that were previously present, it's correct in-memory.
for (const key of Object.keys(config)) {
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
(config as any)[key] = undefined;
}
Object.assign(config, newConfig);
};
export const syncConfigWithDatabase = (): void => {
// Event messages are deleted after endDate. Since we don't use beginDate/endDate and instead have config toggles, we need to delete the messages once those bools are false.
// Also, for some reason, I can't just do `Inbox.deleteMany(...)`; - it needs this whole circus.
if (!config.worldState?.creditBoost) {
void Inbox.deleteMany({ globaUpgradeId: "5b23106f283a555109666672" }).then(() => {});
}
if (!config.worldState?.affinityBoost) {
void Inbox.deleteMany({ globaUpgradeId: "5b23106f283a555109666673" }).then(() => {});
}
if (!config.worldState?.resourceBoost) {
void Inbox.deleteMany({ globaUpgradeId: "5b23106f283a555109666674" }).then(() => {});
}
if (!config.worldState?.galleonOfGhouls) {
void Inbox.deleteMany({ goalTag: "GalleonRobbery" }).then(() => {});
}
};
export const getReflexiveAddress = (request: Request): { myAddress: string; myUrlBase: string } => {
let myAddress: string;
let myUrlBase: string = request.protocol + "://";
if (request.host.indexOf("warframe.com") == -1) {
// Client request was redirected cleanly, so we know it can reach us how it's reaching us now.
myAddress = request.hostname;
myUrlBase += request.host;
} else {
// Don't know how the client reached us, hoping the config does.
myAddress = config.myAddress;
myUrlBase += myAddress;
const port: number = request.protocol == "http" ? config.httpPort || 80 : config.httpsPort || 443;
if (port != (request.protocol == "http" ? 80 : 443)) {
myUrlBase += ":" + port;
}
}
return { myAddress, myUrlBase };
};
export interface IBindings {
address: string;
httpPort: number;
httpsPort: number;
}
export const configGetWebBindings = (): IBindings => {
return {
address: config.bindAddress || "0.0.0.0",
httpPort: config.httpPort || 80,
httpsPort: config.httpsPort || 443
};
};