diff --git a/README.md b/README.md index 0bd7de22..5b2425ef 100644 --- a/README.md +++ b/README.md @@ -34,4 +34,5 @@ SpaceNinjaServer requires a `config.json`. To set it up, you can copy the [confi - `RadioLegion2Syndicate` for The Emissary - `RadioLegionIntermissionSyndicate` for Intermission I - `RadioLegionSyndicate` for The Wolf of Saturn Six +- `allTheFissures` can be set to `normal` or `hard` to enable all fissures either in normal or steel path, respectively. - `worldState.circuitGameModes` can be provided with an array of valid game modes (`Survival`, `VoidFlood`, `Excavation`, `Defense`, `Exterminate`, `Assassination`, `Alchemy`) diff --git a/config.json.example b/config.json.example index 11da5729..baf51baa 100644 --- a/config.json.example +++ b/config.json.example @@ -74,6 +74,7 @@ "vallisOverride": "", "duviriOverride": "", "nightwaveOverride": "", + "allTheFissures": "", "circuitGameModes": null }, "dev": { diff --git a/package-lock.json b/package-lock.json index f9ab11d0..f272a944 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,6 +14,7 @@ "@types/websocket": "^1.0.10", "@types/ws": "^8.18.1", "@typescript/native-preview": "^7.0.0-dev.20250625.1", + "chokidar": "^4.0.3", "crc-32": "^1.2.2", "express": "^5", "json-with-bigint": "^3.4.4", @@ -22,7 +23,7 @@ "ncp": "^2.0.0", "typescript": "^5.5", "undici": "^7.10.0", - "warframe-public-export-plus": "^0.5.71", + "warframe-public-export-plus": "^0.5.72", "warframe-riven-info": "^0.1.2", "winston": "^3.17.0", "winston-daily-rotate-file": "^5.0.0", @@ -31,7 +32,6 @@ "devDependencies": { "@typescript-eslint/eslint-plugin": "^8.28.0", "@typescript-eslint/parser": "^8.28.0", - "chokidar": "^4.0.3", "eslint": "^8", "eslint-plugin-prettier": "^5.2.5", "prettier": "^3.5.3", @@ -997,7 +997,6 @@ "version": "4.0.3", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", - "dev": true, "license": "MIT", "dependencies": { "readdirp": "^4.0.1" @@ -2803,7 +2802,6 @@ "version": "4.1.2", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", - "dev": true, "license": "MIT", "engines": { "node": ">= 14.18.0" @@ -3388,9 +3386,9 @@ } }, "node_modules/warframe-public-export-plus": { - "version": "0.5.71", - "resolved": "https://registry.npmjs.org/warframe-public-export-plus/-/warframe-public-export-plus-0.5.71.tgz", - "integrity": "sha512-TCS2wPRsBzuURJlIMDhygAHaLsKVZ7dGuC73WZ/iMyn3gKVwA98nnaIj24D+UceWS08fwq4ilWAfUzHJd6X29A==" + "version": "0.5.72", + "resolved": "https://registry.npmjs.org/warframe-public-export-plus/-/warframe-public-export-plus-0.5.72.tgz", + "integrity": "sha512-oOZgtU6L0MGcPRKfA6+bonu+Db1kie1lVdLmA7/DbheTPweNkBEx3Hx3Seib+hEaFW+nLj3T5GtmGxGcFHCHfg==" }, "node_modules/warframe-riven-info": { "version": "0.1.2", diff --git a/package.json b/package.json index ed49ea11..de7411b4 100644 --- a/package.json +++ b/package.json @@ -28,6 +28,7 @@ "@types/websocket": "^1.0.10", "@types/ws": "^8.18.1", "@typescript/native-preview": "^7.0.0-dev.20250625.1", + "chokidar": "^4.0.3", "crc-32": "^1.2.2", "express": "^5", "json-with-bigint": "^3.4.4", @@ -36,7 +37,7 @@ "ncp": "^2.0.0", "typescript": "^5.5", "undici": "^7.10.0", - "warframe-public-export-plus": "^0.5.71", + "warframe-public-export-plus": "^0.5.72", "warframe-riven-info": "^0.1.2", "winston": "^3.17.0", "winston-daily-rotate-file": "^5.0.0", @@ -45,7 +46,6 @@ "devDependencies": { "@typescript-eslint/eslint-plugin": "^8.28.0", "@typescript-eslint/parser": "^8.28.0", - "chokidar": "^4.0.3", "eslint": "^8", "eslint-plugin-prettier": "^5.2.5", "prettier": "^3.5.3", diff --git a/src/controllers/api/updateChallengeProgressController.ts b/src/controllers/api/updateChallengeProgressController.ts index 68ae6c55..b75e820a 100644 --- a/src/controllers/api/updateChallengeProgressController.ts +++ b/src/controllers/api/updateChallengeProgressController.ts @@ -1,7 +1,7 @@ import { RequestHandler } from "express"; import { getJSONfromString } from "@/src/helpers/stringHelpers"; import { getAccountForRequest } from "@/src/services/loginService"; -import { addChallenges, getInventory } from "@/src/services/inventoryService"; +import { addCalendarProgress, addChallenges, getInventory } from "@/src/services/inventoryService"; import { IChallengeProgress, ISeasonChallenge } from "@/src/types/inventoryTypes/inventoryTypes"; import { IAffiliationMods } from "@/src/types/purchaseTypes"; import { getEntriesUnsafe } from "@/src/utils/ts-utils"; @@ -25,13 +25,17 @@ export const updateChallengeProgressController: RequestHandler = async (req, res ); } for (const [key, value] of getEntriesUnsafe(challenges)) { + if (value === undefined) { + logger.error(`Challenge progress update key ${key} has no value`); + continue; + } switch (key) { case "ChallengesFixVersion": inventory.ChallengesFixVersion = value; break; case "SeasonChallengeHistory": - value!.forEach(({ challenge, id }) => { + value.forEach(({ challenge, id }) => { const itemIndex = inventory.SeasonChallengeHistory.findIndex(i => i.challenge === challenge); if (itemIndex !== -1) { inventory.SeasonChallengeHistory[itemIndex].id = id; @@ -41,6 +45,10 @@ export const updateChallengeProgressController: RequestHandler = async (req, res }); break; + case "CalendarProgress": + addCalendarProgress(inventory, value); + break; + case "ChallengeProgress": case "SeasonChallengeCompletions": case "ChallengePTS": @@ -63,5 +71,6 @@ interface IUpdateChallengeProgressRequest { ChallengeProgress?: IChallengeProgress[]; SeasonChallengeHistory?: ISeasonChallenge[]; SeasonChallengeCompletions?: ISeasonChallenge[]; + CalendarProgress?: { challenge: string }[]; crossPlaySetting?: string; } diff --git a/src/controllers/custom/configController.ts b/src/controllers/custom/configController.ts new file mode 100644 index 00000000..2c1e10ac --- /dev/null +++ b/src/controllers/custom/configController.ts @@ -0,0 +1,42 @@ +import { RequestHandler } from "express"; +import { config } from "@/src/services/configService"; +import { getAccountForRequest, isAdministrator } from "@/src/services/loginService"; +import { saveConfig } from "@/src/services/configWatcherService"; + +export const getConfigController: RequestHandler = async (req, res) => { + const account = await getAccountForRequest(req); + if (isAdministrator(account)) { + const responseData: Record = {}; + for (const id of req.body as string[]) { + const [obj, idx] = configIdToIndexable(id); + responseData[id] = obj[idx] ?? null; + } + res.json(responseData); + } else { + res.status(401).end(); + } +}; + +export const setConfigController: RequestHandler = async (req, res) => { + const account = await getAccountForRequest(req); + if (isAdministrator(account)) { + for (const [id, value] of Object.entries(req.body as Record)) { + const [obj, idx] = configIdToIndexable(id); + obj[idx] = value; + } + await saveConfig(); + res.end(); + } else { + res.status(401).end(); + } +}; + +const configIdToIndexable = (id: string): [Record, string] => { + let obj = config as unknown as Record; + const arr = id.split("."); + while (arr.length > 1) { + obj = obj[arr[0]]; + arr.splice(0, 1); + } + return [obj, arr[0]]; +}; diff --git a/src/controllers/custom/getConfigDataController.ts b/src/controllers/custom/getConfigDataController.ts deleted file mode 100644 index 12208527..00000000 --- a/src/controllers/custom/getConfigDataController.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { RequestHandler } from "express"; -import { config } from "@/src/services/configService"; -import { getAccountForRequest, isAdministrator } from "@/src/services/loginService"; - -const getConfigDataController: RequestHandler = async (req, res) => { - const account = await getAccountForRequest(req); - if (isAdministrator(account)) { - res.json(config); - } else { - res.status(401).end(); - } -}; - -export { getConfigDataController }; diff --git a/src/controllers/custom/updateConfigDataController.ts b/src/controllers/custom/updateConfigDataController.ts deleted file mode 100644 index 7c87c372..00000000 --- a/src/controllers/custom/updateConfigDataController.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { RequestHandler } from "express"; -import { saveConfig } from "@/src/services/configWatcherService"; -import { getAccountForRequest, isAdministrator } from "@/src/services/loginService"; -import { config, IConfig } from "@/src/services/configService"; - -export const updateConfigDataController: RequestHandler = async (req, res) => { - const account = await getAccountForRequest(req); - if (isAdministrator(account)) { - const data = req.body as IUpdateConfigDataRequest; - config[data.key] = data.value; - await saveConfig(); - res.end(); - } else { - res.status(401).end(); - } -}; - -interface IUpdateConfigDataRequest { - key: keyof IConfig; - value: never; -} diff --git a/src/routes/custom.ts b/src/routes/custom.ts index 5ed4906e..e10bc721 100644 --- a/src/routes/custom.ts +++ b/src/routes/custom.ts @@ -25,8 +25,7 @@ import { manageQuestsController } from "@/src/controllers/custom/manageQuestsCon import { setEvolutionProgressController } from "@/src/controllers/custom/setEvolutionProgressController"; import { setBoosterController } from "@/src/controllers/custom/setBoosterController"; -import { getConfigDataController } from "@/src/controllers/custom/getConfigDataController"; -import { updateConfigDataController } from "@/src/controllers/custom/updateConfigDataController"; +import { getConfigController, setConfigController } from "@/src/controllers/custom/configController"; const customRouter = express.Router(); @@ -55,7 +54,7 @@ customRouter.post("/manageQuests", manageQuestsController); customRouter.post("/setEvolutionProgress", setEvolutionProgressController); customRouter.post("/setBooster", setBoosterController); -customRouter.get("/config", getConfigDataController); -customRouter.post("/config", updateConfigDataController); +customRouter.post("/getConfig", getConfigController); +customRouter.post("/setConfig", setConfigController); export { customRouter }; diff --git a/src/services/configService.ts b/src/services/configService.ts index fe74a584..4f2e93e7 100644 --- a/src/services/configService.ts +++ b/src/services/configService.ts @@ -81,6 +81,7 @@ export interface IConfig { vallisOverride?: string; duviriOverride?: string; nightwaveOverride?: string; + allTheFissures?: string; circuitGameModes?: string[]; }; dev?: { diff --git a/src/services/configWatcherService.ts b/src/services/configWatcherService.ts index 8df1acd9..cab235ff 100644 --- a/src/services/configWatcherService.ts +++ b/src/services/configWatcherService.ts @@ -1,4 +1,4 @@ -import fs from "fs"; +import chokidar from "chokidar"; import fsPromises from "fs/promises"; import { logger } from "../utils/logger"; import { config, configPath, loadConfig } from "./configService"; @@ -6,12 +6,7 @@ import { getWebPorts, sendWsBroadcast, startWebServer, stopWebServer } from "./w import { Inbox } from "../models/inboxModel"; let amnesia = false; -fs.watchFile(configPath, (now, then) => { - // https://github.com/oven-sh/bun/issues/20542 - if (process.versions.bun && now.mtimeMs == then.mtimeMs) { - return; - } - +chokidar.watch(configPath).on("change", () => { if (amnesia) { amnesia = false; } else { diff --git a/src/services/inventoryService.ts b/src/services/inventoryService.ts index a2145d3b..fafbca6c 100644 --- a/src/services/inventoryService.ts +++ b/src/services/inventoryService.ts @@ -499,6 +499,7 @@ export const addItem = async ( // - Blueprints for Ancient Protector Specter, Shield Osprey Specter, etc. have num=1 despite giving their purchaseQuantity. if (!exactQuantity) { quantity *= ExportGear[typeName].purchaseQuantity ?? 1; + logger.debug(`non-exact acquisition of ${typeName}; factored quantity is ${quantity}`); } const consumablesChanges = [ { @@ -1831,6 +1832,15 @@ export const addChallenges = ( return affiliationMods; }; +export const addCalendarProgress = (inventory: TInventoryDatabaseDocument, value: { challenge: string }[]): void => { + const calendarProgress = getCalendarProgress(inventory); + const currentSeason = getWorldState().KnownCalendarSeasons[0]; + calendarProgress.SeasonProgress.LastCompletedChallengeDayIdx = currentSeason.Days.findIndex( + day => day.events.length != 0 && day.events[0].challenge == value[value.length - 1].challenge + ); + checkCalendarChallengeCompletion(calendarProgress, currentSeason); +}; + export const addMissionComplete = (inventory: TInventoryDatabaseDocument, { Tag, Completes, Tier }: IMission): void => { const { Missions } = inventory; const itemIndex = Missions.findIndex(item => item.Tag === Tag); diff --git a/src/services/loginRewardService.ts b/src/services/loginRewardService.ts index c8a213ea..49a6501a 100644 --- a/src/services/loginRewardService.ts +++ b/src/services/loginRewardService.ts @@ -144,7 +144,8 @@ export const claimLoginReward = async ( case "RT_STORE_ITEM": case "RT_RECIPE": case "RT_RANDOM_RECIPE": - return (await handleStoreItemAcquisition(reward.StoreItemType, inventory, reward.Amount)).InventoryChanges; + return (await handleStoreItemAcquisition(reward.StoreItemType, inventory, reward.Amount, undefined, true)) + .InventoryChanges; case "RT_CREDITS": return updateCurrency(inventory, -reward.Amount, false); diff --git a/src/services/missionInventoryUpdateService.ts b/src/services/missionInventoryUpdateService.ts index ec3ee941..09bdc1c6 100644 --- a/src/services/missionInventoryUpdateService.ts +++ b/src/services/missionInventoryUpdateService.ts @@ -14,6 +14,7 @@ import { IRngResult, SRng, getRandomElement, getRandomReward } from "@/src/servi import { equipmentKeys, IMission, ITypeCount, TEquipmentKey } from "@/src/types/inventoryTypes/inventoryTypes"; import { addBooster, + addCalendarProgress, addChallenges, addConsumables, addCrewShipAmmo, @@ -33,10 +34,8 @@ import { addSkin, addStanding, applyClientEquipmentUpdates, - checkCalendarChallengeCompletion, combineInventoryChanges, generateRewardSeed, - getCalendarProgress, getDialogue, giveNemesisPetRecipe, giveNemesisWeaponRecipe, @@ -235,7 +234,7 @@ export const addMissionInventoryUpdates = async ( } for (const [key, value] of getEntriesUnsafe(inventoryUpdates)) { if (value === undefined) { - logger.error(`Inventory update key ${key} has no value `); + logger.error(`Inventory update key ${key} has no value`); continue; } switch (key) { @@ -671,12 +670,7 @@ export const addMissionInventoryUpdates = async ( break; } case "CalendarProgress": { - const calendarProgress = getCalendarProgress(inventory); - const currentSeason = getWorldState().KnownCalendarSeasons[0]; - calendarProgress.SeasonProgress.LastCompletedChallengeDayIdx = currentSeason.Days.findIndex( - x => x.events[0].challenge == value[value.length - 1].challenge - ); - checkCalendarChallengeCompletion(calendarProgress, currentSeason); + addCalendarProgress(inventory, value); break; } case "duviriCaveOffers": { diff --git a/src/services/purchaseService.ts b/src/services/purchaseService.ts index 59647fdf..0c4cad35 100644 --- a/src/services/purchaseService.ts +++ b/src/services/purchaseService.ts @@ -371,18 +371,28 @@ export const handleStoreItemAcquisition = async ( } else { const storeCategory = getStoreItemCategory(storeItemName); const internalName = fromStoreItem(storeItemName); - logger.debug(`store category ${storeCategory}`); if (!ignorePurchaseQuantity) { if (internalName in ExportGear) { quantity *= ExportGear[internalName].purchaseQuantity || 1; + logger.debug(`factored quantity is ${quantity}`); } else if (internalName in ExportResources) { quantity *= ExportResources[internalName].purchaseQuantity || 1; + logger.debug(`factored quantity is ${quantity}`); } } + logger.debug(`store category ${storeCategory}`); switch (storeCategory) { default: { purchaseResponse = { - InventoryChanges: await addItem(inventory, internalName, quantity, premiumPurchase, seed) + InventoryChanges: await addItem( + inventory, + internalName, + quantity, + premiumPurchase, + seed, + undefined, + true + ) }; break; } @@ -524,7 +534,9 @@ const handleTypesPurchase = async ( logger.debug(`type category ${typeCategory}`); switch (typeCategory) { default: - return { InventoryChanges: await addItem(inventory, typesName, quantity, premiumPurchase, seed) }; + return { + InventoryChanges: await addItem(inventory, typesName, quantity, premiumPurchase, seed, undefined, true) + }; case "BoosterPacks": return handleBoosterPackPurchase(typesName, inventory, quantity); case "SlotItems": diff --git a/src/services/saveLoadoutService.ts b/src/services/saveLoadoutService.ts index 0676d113..ff42ad82 100644 --- a/src/services/saveLoadoutService.ts +++ b/src/services/saveLoadoutService.ts @@ -149,7 +149,8 @@ export const handleInventoryItemConfigChange = async ( } else { const inventoryItem = inventory.WeaponSkins.id(itemId); if (!inventoryItem) { - throw new Error(`inventory item WeaponSkins not found with id ${itemId}`); + logger.warn(`inventory item WeaponSkins not found with id ${itemId}`); + continue; } if ("Favorite" in itemConfigEntries) { inventoryItem.Favorite = itemConfigEntries.Favorite; @@ -177,7 +178,8 @@ export const handleInventoryItemConfigChange = async ( const inventoryItem = inventory[equipmentName].id(itemId); if (!inventoryItem) { - throw new Error(`inventory item ${equipmentName} not found with id ${itemId}`); + logger.warn(`inventory item ${equipmentName} not found with id ${itemId}`); + continue; } for (const [configId, config] of Object.entries(itemConfigEntries)) { diff --git a/src/services/worldStateService.ts b/src/services/worldStateService.ts index 0a2bfd4f..5aba5813 100644 --- a/src/services/worldStateService.ts +++ b/src/services/worldStateService.ts @@ -1524,20 +1524,40 @@ export const getWorldState = (buildLabel?: string): IWorldState => { }; export const populateFissures = async (worldState: IWorldState): Promise => { - 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 - }); + if (config.worldState?.allTheFissures) { + let i = 0; + for (const [tier, nodes] of Object.entries(fissureMissions)) { + for (const node of nodes) { + const meta = ExportRegions[node]; + worldState.ActiveMissions.push({ + _id: { $oid: (i++).toString().padStart(8, "0") + "8e0c70ba050f1eb7" }, + Region: meta.systemIndex + 1, + Seed: 1337, + Activation: { $date: { $numberLong: "1000000000000" } }, + Expiry: { $date: { $numberLong: "2000000000000" } }, + Node: node, + MissionType: eMissionType[meta.missionIndex].tag, + Modifier: tier, + Hard: config.worldState.allTheFissures == "hard" + }); + } + } + } else { + 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 + }); + } } }; diff --git a/static/fixed_responses/allIncarnonList.json b/static/fixed_responses/allIncarnonList.json index 3d85db63..a27798e1 100644 --- a/static/fixed_responses/allIncarnonList.json +++ b/static/fixed_responses/allIncarnonList.json @@ -45,5 +45,6 @@ "/Lotus/Weapons/Tenno/Zariman/Melee/Tonfas/ZarimanTonfaWeapon", "/Lotus/Weapons/Tenno/Zariman/Pistols/HeavyPistol/ZarimanHeavyPistol", "/Lotus/Weapons/Thanotech/EntFistIncarnon/EntFistIncarnon", - "/Lotus/Weapons/Thanotech/EntratiWristGun/EntratiWristGunWeapon" + "/Lotus/Weapons/Thanotech/EntratiWristGun/EntratiWristGunWeapon", + "/Lotus/Weapons/Tenno/Zariman/Melee/HeavyScythe/ZarimanHeavyScythe/ZarimanHeavyScytheWeapon" ] diff --git a/static/webui/index.html b/static/webui/index.html index caf7be01..70ac6843 100644 --- a/static/webui/index.html +++ b/static/webui/index.html @@ -568,10 +568,10 @@
-
+

-
+
@@ -807,6 +807,93 @@
+
+
+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+
diff --git a/static/webui/script.js b/static/webui/script.js index 209d727e..479f0014 100644 --- a/static/webui/script.js +++ b/static/webui/script.js @@ -248,7 +248,8 @@ const permanentEvolutionWeapons = new Set([ "/Lotus/Weapons/Tenno/Zariman/Melee/Tonfas/ZarimanTonfaWeapon", "/Lotus/Weapons/Tenno/Zariman/Pistols/HeavyPistol/ZarimanHeavyPistol", "/Lotus/Weapons/Thanotech/EntFistIncarnon/EntFistIncarnon", - "/Lotus/Weapons/Thanotech/EntratiWristGun/EntratiWristGunWeapon" + "/Lotus/Weapons/Thanotech/EntratiWristGun/EntratiWristGunWeapon", + "/Lotus/Weapons/Tenno/Zariman/Melee/HeavyScythe/ZarimanHeavyScythe/ZarimanHeavyScytheWeapon" ]); let uniqueLevelCaps = {}; @@ -1846,16 +1847,28 @@ function doAcquireMod() { } } -const uiConfigs = [...$("#server-settings input[id]")].map(x => x.id); +const uiConfigs = [...$(".config-form input[id], .config-form select[id]")].map(x => x.id); for (const id of uiConfigs) { const elm = document.getElementById(id); - if (elm.type == "checkbox") { + if (elm.tagName == "SELECT") { + elm.onchange = function () { + let value = this.value; + if (!isNaN(parseInt(value))) { + value = parseInt(value); + } + $.post({ + url: "/custom/setConfig?" + window.authz, + contentType: "application/json", + data: JSON.stringify({ [id]: value }) + }); + }; + } else if (elm.type == "checkbox") { elm.onchange = function () { $.post({ - url: "/custom/config?" + window.authz, + url: "/custom/setConfig?" + window.authz, contentType: "application/json", - data: JSON.stringify({ key: id, value: this.checked }) + data: JSON.stringify({ [id]: this.checked }) }).then(() => { if (["infiniteCredits", "infinitePlatinum", "infiniteEndo", "infiniteRegalAya"].indexOf(id) != -1) { updateInventory(); @@ -1868,9 +1881,9 @@ for (const id of uiConfigs) { function doSaveConfig(id) { const elm = document.getElementById(id); $.post({ - url: "/custom/config?" + window.authz, + url: "/custom/setConfig?" + window.authz, contentType: "application/json", - data: JSON.stringify({ key: id, value: parseInt(elm.value) }) + data: JSON.stringify({ [id]: parseInt(elm.value) }) }); } @@ -1881,26 +1894,29 @@ single.getRoute("/webui/cheats").on("beforeload", function () { interval = setInterval(() => { if (window.authz) { clearInterval(interval); - fetch("/custom/config?" + window.authz).then(async res => { - if (res.status == 200) { + $.post({ + url: "/custom/getConfig?" + window.authz, + contentType: "application/json", + data: JSON.stringify(uiConfigs) + }) + .done(json => { //window.is_admin = true; - $("#server-settings-no-perms").addClass("d-none"); - $("#server-settings").removeClass("d-none"); - res.json().then(json => - Object.entries(json).forEach(entry => { - const [key, value] = entry; - var x = document.getElementById(`${key}`); - if (x != null) { - if (x.type == "checkbox") { - x.checked = value; - } else if (x.type == "number") { - x.setAttribute("value", `${value}`); - } + $(".config-admin-hide").addClass("d-none"); + $(".config-admin-show").removeClass("d-none"); + Object.entries(json).forEach(entry => { + const [key, value] = entry; + var x = document.getElementById(`${key}`); + if (x != null) { + if (x.type == "checkbox") { + x.checked = value; + } else if (x.type == "number") { + x.setAttribute("value", `${value}`); } - }) - ); - } else { - if ((await res.text()) == "Log-in expired") { + } + }); + }) + .fail(res => { + if (res.responseText == "Log-in expired") { revalidateAuthz().then(() => { if (single.getCurrentPath() == "/webui/cheats") { single.loadRoute("/webui/cheats"); @@ -1908,11 +1924,10 @@ single.getRoute("/webui/cheats").on("beforeload", function () { }); } else { //window.is_admin = false; - $("#server-settings-no-perms").removeClass("d-none"); - $("#server-settings").addClass("d-none"); + $(".config-admin-hide").removeClass("d-none"); + $(".config-admin-show").addClass("d-none"); } - } - }); + }); } }, 10); }); diff --git a/static/webui/translations/de.js b/static/webui/translations/de.js index a56103b6..22148c9d 100644 --- a/static/webui/translations/de.js +++ b/static/webui/translations/de.js @@ -186,6 +186,51 @@ dict = { cheats_changeSupportedSyndicate: `Unterstütztes Syndikat`, cheats_changeButton: `Ändern`, cheats_none: `Keines`, + + worldState: `[UNTRANSLATED] World State`, + worldState_creditBoost: `[UNTRANSLATED] Credit Boost`, + worldState_affinityBoost: `[UNTRANSLATED] Affinity Boost`, + worldState_resourceBoost: `[UNTRANSLATED] Resource Boost`, + worldState_starDays: `[UNTRANSLATED] Star Days`, + worldState_galleonOfGhouls: `[UNTRANSLATED] Galleon of Ghouls`, + disabled: `[UNTRANSLATED] Disabled`, + worldState_we1: `[UNTRANSLATED] Weekend 1`, + worldState_we2: `[UNTRANSLATED] Weekend 2`, + worldState_we3: `[UNTRANSLATED] Weekend 3`, + worldState_eidolonOverride: `[UNTRANSLATED] Eidolon Override`, + worldState_day: `[UNTRANSLATED] Day`, + worldState_night: `[UNTRANSLATED] Night`, + worldState_vallisOverride: `[UNTRANSLATED] Orb Vallis Override`, + worldState_warm: `[UNTRANSLATED] Warm`, + worldState_cold: `[UNTRANSLATED] Cold`, + worldState_duviriOverride: `[UNTRANSLATED] Duviri Override`, + worldState_joy: `[UNTRANSLATED] Joy`, + worldState_anger: `[UNTRANSLATED] Anger`, + worldState_envy: `[UNTRANSLATED] Envy`, + worldState_sorrow: `[UNTRANSLATED] Sorrow`, + worldState_fear: `[UNTRANSLATED] Fear`, + worldState_nightwaveOverride: `[UNTRANSLATED] Nightwave Override`, + worldState_RadioLegionIntermission13Syndicate: `[UNTRANSLATED] Nora's Mix Vol. 9`, + worldState_RadioLegionIntermission12Syndicate: `[UNTRANSLATED] Nora's Mix Vol. 8`, + worldState_RadioLegionIntermission11Syndicate: `[UNTRANSLATED] Nora's Mix Vol. 7`, + worldState_RadioLegionIntermission10Syndicate: `[UNTRANSLATED] Nora's Mix Vol. 6`, + worldState_RadioLegionIntermission9Syndicate: `[UNTRANSLATED] Nora's Mix Vol. 5`, + worldState_RadioLegionIntermission8Syndicate: `[UNTRANSLATED] Nora's Mix Vol. 4`, + worldState_RadioLegionIntermission7Syndicate: `[UNTRANSLATED] Nora's Mix Vol. 3`, + worldState_RadioLegionIntermission6Syndicate: `[UNTRANSLATED] Nora's Mix Vol. 2`, + worldState_RadioLegionIntermission5Syndicate: `[UNTRANSLATED] Nora's Mix Vol. 1`, + worldState_RadioLegionIntermission4Syndicate: `[UNTRANSLATED] Nora's Choice`, + worldState_RadioLegionIntermission3Syndicate: `[UNTRANSLATED] Intermission III`, + worldState_RadioLegion3Syndicate: `[UNTRANSLATED] Glassmaker`, + worldState_RadioLegionIntermission2Syndicate: `[UNTRANSLATED] Intermission II`, + worldState_RadioLegion2Syndicate: `[UNTRANSLATED] The Emissary`, + worldState_RadioLegionIntermissionSyndicate: `[UNTRANSLATED] Intermission I`, + worldState_RadioLegionSyndicate: `[UNTRANSLATED] The Wolf of Saturn Six`, + worldState_fissures: `[UNTRANSLATED] Fissures`, + normal: `[UNTRANSLATED] Normal`, + worldState_allAtOnceNormal: `[UNTRANSLATED] All At Once, Normal`, + worldState_allAtOnceSteelPath: `[UNTRANSLATED] All At Once, Steel Path`, + import_importNote: `Du kannst hier eine vollständige oder teilweise Inventarantwort (Client-Darstellung) einfügen. Alle Felder, die vom Importer unterstützt werden, werden in deinem Account überschrieben.`, import_submit: `Absenden`, import_samples: `[UNTRANSLATED] Samples:`, diff --git a/static/webui/translations/en.js b/static/webui/translations/en.js index 36d38301..22481df6 100644 --- a/static/webui/translations/en.js +++ b/static/webui/translations/en.js @@ -185,6 +185,51 @@ dict = { cheats_changeSupportedSyndicate: `Supported syndicate`, cheats_changeButton: `Change`, cheats_none: `None`, + + worldState: `World State`, + worldState_creditBoost: `Credit Boost`, + worldState_affinityBoost: `Affinity Boost`, + worldState_resourceBoost: `Resource Boost`, + worldState_starDays: `Star Days`, + worldState_galleonOfGhouls: `Galleon of Ghouls`, + disabled: `Disabled`, + worldState_we1: `Weekend 1`, + worldState_we2: `Weekend 2`, + worldState_we3: `Weekend 3`, + worldState_eidolonOverride: `Eidolon Override`, + worldState_day: `Day`, + worldState_night: `Night`, + worldState_vallisOverride: `Orb Vallis Override`, + worldState_warm: `Warm`, + worldState_cold: `Cold`, + worldState_duviriOverride: `Duviri Override`, + worldState_joy: `Joy`, + worldState_anger: `Anger`, + worldState_envy: `Envy`, + worldState_sorrow: `Sorrow`, + worldState_fear: `Fear`, + worldState_nightwaveOverride: `Nightwave Override`, + worldState_RadioLegionIntermission13Syndicate: `Nora's Mix Vol. 9`, + worldState_RadioLegionIntermission12Syndicate: `Nora's Mix Vol. 8`, + worldState_RadioLegionIntermission11Syndicate: `Nora's Mix Vol. 7`, + worldState_RadioLegionIntermission10Syndicate: `Nora's Mix Vol. 6`, + worldState_RadioLegionIntermission9Syndicate: `Nora's Mix Vol. 5`, + worldState_RadioLegionIntermission8Syndicate: `Nora's Mix Vol. 4`, + worldState_RadioLegionIntermission7Syndicate: `Nora's Mix Vol. 3`, + worldState_RadioLegionIntermission6Syndicate: `Nora's Mix Vol. 2`, + worldState_RadioLegionIntermission5Syndicate: `Nora's Mix Vol. 1`, + worldState_RadioLegionIntermission4Syndicate: `Nora's Choice`, + worldState_RadioLegionIntermission3Syndicate: `Intermission III`, + worldState_RadioLegion3Syndicate: `Glassmaker`, + worldState_RadioLegionIntermission2Syndicate: `Intermission II`, + worldState_RadioLegion2Syndicate: `The Emissary`, + worldState_RadioLegionIntermissionSyndicate: `Intermission I`, + worldState_RadioLegionSyndicate: `The Wolf of Saturn Six`, + worldState_fissures: `Fissures`, + normal: `Normal`, + worldState_allAtOnceNormal: `All At Once, Normal`, + worldState_allAtOnceSteelPath: `All At Once, Steel Path`, + import_importNote: `You can provide a full or partial inventory response (client respresentation) here. All fields that are supported by the importer will be overwritten in your account.`, import_submit: `Submit`, import_samples: `Samples:`, diff --git a/static/webui/translations/es.js b/static/webui/translations/es.js index 3fbb7bf1..0a7b7ac5 100644 --- a/static/webui/translations/es.js +++ b/static/webui/translations/es.js @@ -186,6 +186,51 @@ dict = { cheats_changeSupportedSyndicate: `Sindicatos disponibles`, cheats_changeButton: `Cambiar`, cheats_none: `Ninguno`, + + worldState: `[UNTRANSLATED] World State`, + worldState_creditBoost: `[UNTRANSLATED] Credit Boost`, + worldState_affinityBoost: `[UNTRANSLATED] Affinity Boost`, + worldState_resourceBoost: `[UNTRANSLATED] Resource Boost`, + worldState_starDays: `[UNTRANSLATED] Star Days`, + worldState_galleonOfGhouls: `[UNTRANSLATED] Galleon of Ghouls`, + disabled: `[UNTRANSLATED] Disabled`, + worldState_we1: `[UNTRANSLATED] Weekend 1`, + worldState_we2: `[UNTRANSLATED] Weekend 2`, + worldState_we3: `[UNTRANSLATED] Weekend 3`, + worldState_eidolonOverride: `[UNTRANSLATED] Eidolon Override`, + worldState_day: `[UNTRANSLATED] Day`, + worldState_night: `[UNTRANSLATED] Night`, + worldState_vallisOverride: `[UNTRANSLATED] Orb Vallis Override`, + worldState_warm: `[UNTRANSLATED] Warm`, + worldState_cold: `[UNTRANSLATED] Cold`, + worldState_duviriOverride: `[UNTRANSLATED] Duviri Override`, + worldState_joy: `[UNTRANSLATED] Joy`, + worldState_anger: `[UNTRANSLATED] Anger`, + worldState_envy: `[UNTRANSLATED] Envy`, + worldState_sorrow: `[UNTRANSLATED] Sorrow`, + worldState_fear: `[UNTRANSLATED] Fear`, + worldState_nightwaveOverride: `[UNTRANSLATED] Nightwave Override`, + worldState_RadioLegionIntermission13Syndicate: `[UNTRANSLATED] Nora's Mix Vol. 9`, + worldState_RadioLegionIntermission12Syndicate: `[UNTRANSLATED] Nora's Mix Vol. 8`, + worldState_RadioLegionIntermission11Syndicate: `[UNTRANSLATED] Nora's Mix Vol. 7`, + worldState_RadioLegionIntermission10Syndicate: `[UNTRANSLATED] Nora's Mix Vol. 6`, + worldState_RadioLegionIntermission9Syndicate: `[UNTRANSLATED] Nora's Mix Vol. 5`, + worldState_RadioLegionIntermission8Syndicate: `[UNTRANSLATED] Nora's Mix Vol. 4`, + worldState_RadioLegionIntermission7Syndicate: `[UNTRANSLATED] Nora's Mix Vol. 3`, + worldState_RadioLegionIntermission6Syndicate: `[UNTRANSLATED] Nora's Mix Vol. 2`, + worldState_RadioLegionIntermission5Syndicate: `[UNTRANSLATED] Nora's Mix Vol. 1`, + worldState_RadioLegionIntermission4Syndicate: `[UNTRANSLATED] Nora's Choice`, + worldState_RadioLegionIntermission3Syndicate: `[UNTRANSLATED] Intermission III`, + worldState_RadioLegion3Syndicate: `[UNTRANSLATED] Glassmaker`, + worldState_RadioLegionIntermission2Syndicate: `[UNTRANSLATED] Intermission II`, + worldState_RadioLegion2Syndicate: `[UNTRANSLATED] The Emissary`, + worldState_RadioLegionIntermissionSyndicate: `[UNTRANSLATED] Intermission I`, + worldState_RadioLegionSyndicate: `[UNTRANSLATED] The Wolf of Saturn Six`, + worldState_fissures: `[UNTRANSLATED] Fissures`, + normal: `[UNTRANSLATED] Normal`, + worldState_allAtOnceNormal: `[UNTRANSLATED] All At Once, Normal`, + worldState_allAtOnceSteelPath: `[UNTRANSLATED] All At Once, Steel Path`, + import_importNote: `Puedes proporcionar una respuesta de inventario completa o parcial (representación del cliente) aquí. Todos los campos compatibles con el importador serán sobrescritos en tu cuenta.`, import_submit: `Enviar`, import_samples: `Muestras:`, diff --git a/static/webui/translations/fr.js b/static/webui/translations/fr.js index a52f5bef..9dca3dbe 100644 --- a/static/webui/translations/fr.js +++ b/static/webui/translations/fr.js @@ -186,6 +186,51 @@ dict = { cheats_changeSupportedSyndicate: `Allégeance`, cheats_changeButton: `Changer`, cheats_none: `Aucun`, + + worldState: `[UNTRANSLATED] World State`, + worldState_creditBoost: `[UNTRANSLATED] Credit Boost`, + worldState_affinityBoost: `[UNTRANSLATED] Affinity Boost`, + worldState_resourceBoost: `[UNTRANSLATED] Resource Boost`, + worldState_starDays: `[UNTRANSLATED] Star Days`, + worldState_galleonOfGhouls: `[UNTRANSLATED] Galleon of Ghouls`, + disabled: `[UNTRANSLATED] Disabled`, + worldState_we1: `[UNTRANSLATED] Weekend 1`, + worldState_we2: `[UNTRANSLATED] Weekend 2`, + worldState_we3: `[UNTRANSLATED] Weekend 3`, + worldState_eidolonOverride: `[UNTRANSLATED] Eidolon Override`, + worldState_day: `[UNTRANSLATED] Day`, + worldState_night: `[UNTRANSLATED] Night`, + worldState_vallisOverride: `[UNTRANSLATED] Orb Vallis Override`, + worldState_warm: `[UNTRANSLATED] Warm`, + worldState_cold: `[UNTRANSLATED] Cold`, + worldState_duviriOverride: `[UNTRANSLATED] Duviri Override`, + worldState_joy: `[UNTRANSLATED] Joy`, + worldState_anger: `[UNTRANSLATED] Anger`, + worldState_envy: `[UNTRANSLATED] Envy`, + worldState_sorrow: `[UNTRANSLATED] Sorrow`, + worldState_fear: `[UNTRANSLATED] Fear`, + worldState_nightwaveOverride: `[UNTRANSLATED] Nightwave Override`, + worldState_RadioLegionIntermission13Syndicate: `[UNTRANSLATED] Nora's Mix Vol. 9`, + worldState_RadioLegionIntermission12Syndicate: `[UNTRANSLATED] Nora's Mix Vol. 8`, + worldState_RadioLegionIntermission11Syndicate: `[UNTRANSLATED] Nora's Mix Vol. 7`, + worldState_RadioLegionIntermission10Syndicate: `[UNTRANSLATED] Nora's Mix Vol. 6`, + worldState_RadioLegionIntermission9Syndicate: `[UNTRANSLATED] Nora's Mix Vol. 5`, + worldState_RadioLegionIntermission8Syndicate: `[UNTRANSLATED] Nora's Mix Vol. 4`, + worldState_RadioLegionIntermission7Syndicate: `[UNTRANSLATED] Nora's Mix Vol. 3`, + worldState_RadioLegionIntermission6Syndicate: `[UNTRANSLATED] Nora's Mix Vol. 2`, + worldState_RadioLegionIntermission5Syndicate: `[UNTRANSLATED] Nora's Mix Vol. 1`, + worldState_RadioLegionIntermission4Syndicate: `[UNTRANSLATED] Nora's Choice`, + worldState_RadioLegionIntermission3Syndicate: `[UNTRANSLATED] Intermission III`, + worldState_RadioLegion3Syndicate: `[UNTRANSLATED] Glassmaker`, + worldState_RadioLegionIntermission2Syndicate: `[UNTRANSLATED] Intermission II`, + worldState_RadioLegion2Syndicate: `[UNTRANSLATED] The Emissary`, + worldState_RadioLegionIntermissionSyndicate: `[UNTRANSLATED] Intermission I`, + worldState_RadioLegionSyndicate: `[UNTRANSLATED] The Wolf of Saturn Six`, + worldState_fissures: `[UNTRANSLATED] Fissures`, + normal: `[UNTRANSLATED] Normal`, + worldState_allAtOnceNormal: `[UNTRANSLATED] All At Once, Normal`, + worldState_allAtOnceSteelPath: `[UNTRANSLATED] All At Once, Steel Path`, + import_importNote: `Import manuel. Toutes les modifcations supportées par l'inventaire écraseront celles présentes dans la base de données.`, import_submit: `Soumettre`, import_samples: `Echantillons :`, diff --git a/static/webui/translations/ru.js b/static/webui/translations/ru.js index 26fef974..b276c0fb 100644 --- a/static/webui/translations/ru.js +++ b/static/webui/translations/ru.js @@ -186,6 +186,51 @@ dict = { cheats_changeSupportedSyndicate: `Поддерживаемый синдикат`, cheats_changeButton: `Изменить`, cheats_none: `Отсутствует`, + + worldState: `[UNTRANSLATED] World State`, + worldState_creditBoost: `[UNTRANSLATED] Credit Boost`, + worldState_affinityBoost: `[UNTRANSLATED] Affinity Boost`, + worldState_resourceBoost: `[UNTRANSLATED] Resource Boost`, + worldState_starDays: `[UNTRANSLATED] Star Days`, + worldState_galleonOfGhouls: `[UNTRANSLATED] Galleon of Ghouls`, + disabled: `[UNTRANSLATED] Disabled`, + worldState_we1: `[UNTRANSLATED] Weekend 1`, + worldState_we2: `[UNTRANSLATED] Weekend 2`, + worldState_we3: `[UNTRANSLATED] Weekend 3`, + worldState_eidolonOverride: `[UNTRANSLATED] Eidolon Override`, + worldState_day: `[UNTRANSLATED] Day`, + worldState_night: `[UNTRANSLATED] Night`, + worldState_vallisOverride: `[UNTRANSLATED] Orb Vallis Override`, + worldState_warm: `[UNTRANSLATED] Warm`, + worldState_cold: `[UNTRANSLATED] Cold`, + worldState_duviriOverride: `[UNTRANSLATED] Duviri Override`, + worldState_joy: `[UNTRANSLATED] Joy`, + worldState_anger: `[UNTRANSLATED] Anger`, + worldState_envy: `[UNTRANSLATED] Envy`, + worldState_sorrow: `[UNTRANSLATED] Sorrow`, + worldState_fear: `[UNTRANSLATED] Fear`, + worldState_nightwaveOverride: `[UNTRANSLATED] Nightwave Override`, + worldState_RadioLegionIntermission13Syndicate: `[UNTRANSLATED] Nora's Mix Vol. 9`, + worldState_RadioLegionIntermission12Syndicate: `[UNTRANSLATED] Nora's Mix Vol. 8`, + worldState_RadioLegionIntermission11Syndicate: `[UNTRANSLATED] Nora's Mix Vol. 7`, + worldState_RadioLegionIntermission10Syndicate: `[UNTRANSLATED] Nora's Mix Vol. 6`, + worldState_RadioLegionIntermission9Syndicate: `[UNTRANSLATED] Nora's Mix Vol. 5`, + worldState_RadioLegionIntermission8Syndicate: `[UNTRANSLATED] Nora's Mix Vol. 4`, + worldState_RadioLegionIntermission7Syndicate: `[UNTRANSLATED] Nora's Mix Vol. 3`, + worldState_RadioLegionIntermission6Syndicate: `[UNTRANSLATED] Nora's Mix Vol. 2`, + worldState_RadioLegionIntermission5Syndicate: `[UNTRANSLATED] Nora's Mix Vol. 1`, + worldState_RadioLegionIntermission4Syndicate: `[UNTRANSLATED] Nora's Choice`, + worldState_RadioLegionIntermission3Syndicate: `[UNTRANSLATED] Intermission III`, + worldState_RadioLegion3Syndicate: `[UNTRANSLATED] Glassmaker`, + worldState_RadioLegionIntermission2Syndicate: `[UNTRANSLATED] Intermission II`, + worldState_RadioLegion2Syndicate: `[UNTRANSLATED] The Emissary`, + worldState_RadioLegionIntermissionSyndicate: `[UNTRANSLATED] Intermission I`, + worldState_RadioLegionSyndicate: `[UNTRANSLATED] The Wolf of Saturn Six`, + worldState_fissures: `[UNTRANSLATED] Fissures`, + normal: `[UNTRANSLATED] Normal`, + worldState_allAtOnceNormal: `[UNTRANSLATED] All At Once, Normal`, + worldState_allAtOnceSteelPath: `[UNTRANSLATED] All At Once, Steel Path`, + import_importNote: `Вы можете загрузить полный или частичный ответ инвентаря (клиентское представление) здесь. Все поддерживаемые поля будут перезаписаны в вашем аккаунте.`, import_submit: `Отправить`, import_samples: `[UNTRANSLATED] Samples:`, diff --git a/static/webui/translations/zh.js b/static/webui/translations/zh.js index ca7f726a..46349a72 100644 --- a/static/webui/translations/zh.js +++ b/static/webui/translations/zh.js @@ -186,6 +186,51 @@ dict = { cheats_changeSupportedSyndicate: `支持的集团`, cheats_changeButton: `更改`, cheats_none: `无`, + + worldState: `[UNTRANSLATED] World State`, + worldState_creditBoost: `[UNTRANSLATED] Credit Boost`, + worldState_affinityBoost: `[UNTRANSLATED] Affinity Boost`, + worldState_resourceBoost: `[UNTRANSLATED] Resource Boost`, + worldState_starDays: `[UNTRANSLATED] Star Days`, + worldState_galleonOfGhouls: `[UNTRANSLATED] Galleon of Ghouls`, + disabled: `[UNTRANSLATED] Disabled`, + worldState_we1: `[UNTRANSLATED] Weekend 1`, + worldState_we2: `[UNTRANSLATED] Weekend 2`, + worldState_we3: `[UNTRANSLATED] Weekend 3`, + worldState_eidolonOverride: `[UNTRANSLATED] Eidolon Override`, + worldState_day: `[UNTRANSLATED] Day`, + worldState_night: `[UNTRANSLATED] Night`, + worldState_vallisOverride: `[UNTRANSLATED] Orb Vallis Override`, + worldState_warm: `[UNTRANSLATED] Warm`, + worldState_cold: `[UNTRANSLATED] Cold`, + worldState_duviriOverride: `[UNTRANSLATED] Duviri Override`, + worldState_joy: `[UNTRANSLATED] Joy`, + worldState_anger: `[UNTRANSLATED] Anger`, + worldState_envy: `[UNTRANSLATED] Envy`, + worldState_sorrow: `[UNTRANSLATED] Sorrow`, + worldState_fear: `[UNTRANSLATED] Fear`, + worldState_nightwaveOverride: `[UNTRANSLATED] Nightwave Override`, + worldState_RadioLegionIntermission13Syndicate: `[UNTRANSLATED] Nora's Mix Vol. 9`, + worldState_RadioLegionIntermission12Syndicate: `[UNTRANSLATED] Nora's Mix Vol. 8`, + worldState_RadioLegionIntermission11Syndicate: `[UNTRANSLATED] Nora's Mix Vol. 7`, + worldState_RadioLegionIntermission10Syndicate: `[UNTRANSLATED] Nora's Mix Vol. 6`, + worldState_RadioLegionIntermission9Syndicate: `[UNTRANSLATED] Nora's Mix Vol. 5`, + worldState_RadioLegionIntermission8Syndicate: `[UNTRANSLATED] Nora's Mix Vol. 4`, + worldState_RadioLegionIntermission7Syndicate: `[UNTRANSLATED] Nora's Mix Vol. 3`, + worldState_RadioLegionIntermission6Syndicate: `[UNTRANSLATED] Nora's Mix Vol. 2`, + worldState_RadioLegionIntermission5Syndicate: `[UNTRANSLATED] Nora's Mix Vol. 1`, + worldState_RadioLegionIntermission4Syndicate: `[UNTRANSLATED] Nora's Choice`, + worldState_RadioLegionIntermission3Syndicate: `[UNTRANSLATED] Intermission III`, + worldState_RadioLegion3Syndicate: `[UNTRANSLATED] Glassmaker`, + worldState_RadioLegionIntermission2Syndicate: `[UNTRANSLATED] Intermission II`, + worldState_RadioLegion2Syndicate: `[UNTRANSLATED] The Emissary`, + worldState_RadioLegionIntermissionSyndicate: `[UNTRANSLATED] Intermission I`, + worldState_RadioLegionSyndicate: `[UNTRANSLATED] The Wolf of Saturn Six`, + worldState_fissures: `[UNTRANSLATED] Fissures`, + normal: `[UNTRANSLATED] Normal`, + worldState_allAtOnceNormal: `[UNTRANSLATED] All At Once, Normal`, + worldState_allAtOnceSteelPath: `[UNTRANSLATED] All At Once, Steel Path`, + import_importNote: `您可以在此处提供完整或部分库存响应(客户端表示)。支持的所有字段将被覆盖到您的账户中。`, import_submit: `提交`, import_samples: `示例:`,