Compare commits
10 Commits
d27934ab55
...
9ff1202a8f
Author | SHA1 | Date | |
---|---|---|---|
9ff1202a8f | |||
bb9e0211cc | |||
a14337be03 | |||
b0226d21cb | |||
4f1f9592b0 | |||
764cdd1ab8 | |||
0ba641a2ac | |||
eb7b51852b | |||
a3be376489 | |||
d94cd38120 |
@ -34,4 +34,5 @@ SpaceNinjaServer requires a `config.json`. To set it up, you can copy the [confi
|
|||||||
- `RadioLegion2Syndicate` for The Emissary
|
- `RadioLegion2Syndicate` for The Emissary
|
||||||
- `RadioLegionIntermissionSyndicate` for Intermission I
|
- `RadioLegionIntermissionSyndicate` for Intermission I
|
||||||
- `RadioLegionSyndicate` for The Wolf of Saturn Six
|
- `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`)
|
- `worldState.circuitGameModes` can be provided with an array of valid game modes (`Survival`, `VoidFlood`, `Excavation`, `Defense`, `Exterminate`, `Assassination`, `Alchemy`)
|
||||||
|
@ -75,6 +75,7 @@
|
|||||||
"vallisOverride": "",
|
"vallisOverride": "",
|
||||||
"duviriOverride": "",
|
"duviriOverride": "",
|
||||||
"nightwaveOverride": "",
|
"nightwaveOverride": "",
|
||||||
|
"allTheFissures": "",
|
||||||
"circuitGameModes": null,
|
"circuitGameModes": null,
|
||||||
"darvoStockMultiplier": 1
|
"darvoStockMultiplier": 1
|
||||||
},
|
},
|
||||||
|
12
package-lock.json
generated
12
package-lock.json
generated
@ -14,6 +14,7 @@
|
|||||||
"@types/websocket": "^1.0.10",
|
"@types/websocket": "^1.0.10",
|
||||||
"@types/ws": "^8.18.1",
|
"@types/ws": "^8.18.1",
|
||||||
"@typescript/native-preview": "^7.0.0-dev.20250625.1",
|
"@typescript/native-preview": "^7.0.0-dev.20250625.1",
|
||||||
|
"chokidar": "^4.0.3",
|
||||||
"crc-32": "^1.2.2",
|
"crc-32": "^1.2.2",
|
||||||
"express": "^5",
|
"express": "^5",
|
||||||
"json-with-bigint": "^3.4.4",
|
"json-with-bigint": "^3.4.4",
|
||||||
@ -22,7 +23,7 @@
|
|||||||
"ncp": "^2.0.0",
|
"ncp": "^2.0.0",
|
||||||
"typescript": "^5.5",
|
"typescript": "^5.5",
|
||||||
"undici": "^7.10.0",
|
"undici": "^7.10.0",
|
||||||
"warframe-public-export-plus": "^0.5.71",
|
"warframe-public-export-plus": "^0.5.72",
|
||||||
"warframe-riven-info": "^0.1.2",
|
"warframe-riven-info": "^0.1.2",
|
||||||
"winston": "^3.17.0",
|
"winston": "^3.17.0",
|
||||||
"winston-daily-rotate-file": "^5.0.0",
|
"winston-daily-rotate-file": "^5.0.0",
|
||||||
@ -31,7 +32,6 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@typescript-eslint/eslint-plugin": "^8.28.0",
|
"@typescript-eslint/eslint-plugin": "^8.28.0",
|
||||||
"@typescript-eslint/parser": "^8.28.0",
|
"@typescript-eslint/parser": "^8.28.0",
|
||||||
"chokidar": "^4.0.3",
|
|
||||||
"eslint": "^8",
|
"eslint": "^8",
|
||||||
"eslint-plugin-prettier": "^5.2.5",
|
"eslint-plugin-prettier": "^5.2.5",
|
||||||
"prettier": "^3.5.3",
|
"prettier": "^3.5.3",
|
||||||
@ -997,7 +997,6 @@
|
|||||||
"version": "4.0.3",
|
"version": "4.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz",
|
||||||
"integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==",
|
"integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"readdirp": "^4.0.1"
|
"readdirp": "^4.0.1"
|
||||||
@ -2803,7 +2802,6 @@
|
|||||||
"version": "4.1.2",
|
"version": "4.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz",
|
||||||
"integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==",
|
"integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 14.18.0"
|
"node": ">= 14.18.0"
|
||||||
@ -3388,9 +3386,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/warframe-public-export-plus": {
|
"node_modules/warframe-public-export-plus": {
|
||||||
"version": "0.5.71",
|
"version": "0.5.72",
|
||||||
"resolved": "https://registry.npmjs.org/warframe-public-export-plus/-/warframe-public-export-plus-0.5.71.tgz",
|
"resolved": "https://registry.npmjs.org/warframe-public-export-plus/-/warframe-public-export-plus-0.5.72.tgz",
|
||||||
"integrity": "sha512-TCS2wPRsBzuURJlIMDhygAHaLsKVZ7dGuC73WZ/iMyn3gKVwA98nnaIj24D+UceWS08fwq4ilWAfUzHJd6X29A=="
|
"integrity": "sha512-oOZgtU6L0MGcPRKfA6+bonu+Db1kie1lVdLmA7/DbheTPweNkBEx3Hx3Seib+hEaFW+nLj3T5GtmGxGcFHCHfg=="
|
||||||
},
|
},
|
||||||
"node_modules/warframe-riven-info": {
|
"node_modules/warframe-riven-info": {
|
||||||
"version": "0.1.2",
|
"version": "0.1.2",
|
||||||
|
@ -28,6 +28,7 @@
|
|||||||
"@types/websocket": "^1.0.10",
|
"@types/websocket": "^1.0.10",
|
||||||
"@types/ws": "^8.18.1",
|
"@types/ws": "^8.18.1",
|
||||||
"@typescript/native-preview": "^7.0.0-dev.20250625.1",
|
"@typescript/native-preview": "^7.0.0-dev.20250625.1",
|
||||||
|
"chokidar": "^4.0.3",
|
||||||
"crc-32": "^1.2.2",
|
"crc-32": "^1.2.2",
|
||||||
"express": "^5",
|
"express": "^5",
|
||||||
"json-with-bigint": "^3.4.4",
|
"json-with-bigint": "^3.4.4",
|
||||||
@ -36,7 +37,7 @@
|
|||||||
"ncp": "^2.0.0",
|
"ncp": "^2.0.0",
|
||||||
"typescript": "^5.5",
|
"typescript": "^5.5",
|
||||||
"undici": "^7.10.0",
|
"undici": "^7.10.0",
|
||||||
"warframe-public-export-plus": "^0.5.71",
|
"warframe-public-export-plus": "^0.5.72",
|
||||||
"warframe-riven-info": "^0.1.2",
|
"warframe-riven-info": "^0.1.2",
|
||||||
"winston": "^3.17.0",
|
"winston": "^3.17.0",
|
||||||
"winston-daily-rotate-file": "^5.0.0",
|
"winston-daily-rotate-file": "^5.0.0",
|
||||||
@ -45,7 +46,6 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@typescript-eslint/eslint-plugin": "^8.28.0",
|
"@typescript-eslint/eslint-plugin": "^8.28.0",
|
||||||
"@typescript-eslint/parser": "^8.28.0",
|
"@typescript-eslint/parser": "^8.28.0",
|
||||||
"chokidar": "^4.0.3",
|
|
||||||
"eslint": "^8",
|
"eslint": "^8",
|
||||||
"eslint-plugin-prettier": "^5.2.5",
|
"eslint-plugin-prettier": "^5.2.5",
|
||||||
"prettier": "^3.5.3",
|
"prettier": "^3.5.3",
|
||||||
|
@ -82,6 +82,7 @@ export interface IConfig {
|
|||||||
vallisOverride?: string;
|
vallisOverride?: string;
|
||||||
duviriOverride?: string;
|
duviriOverride?: string;
|
||||||
nightwaveOverride?: string;
|
nightwaveOverride?: string;
|
||||||
|
allTheFissures?: string;
|
||||||
circuitGameModes?: string[];
|
circuitGameModes?: string[];
|
||||||
darvoStockMultiplier?: number;
|
darvoStockMultiplier?: number;
|
||||||
};
|
};
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import fs from "fs";
|
import chokidar from "chokidar";
|
||||||
import fsPromises from "fs/promises";
|
import fsPromises from "fs/promises";
|
||||||
import { logger } from "../utils/logger";
|
import { logger } from "../utils/logger";
|
||||||
import { config, configPath, loadConfig } from "./configService";
|
import { config, configPath, loadConfig } from "./configService";
|
||||||
@ -6,12 +6,7 @@ import { getWebPorts, sendWsBroadcast, startWebServer, stopWebServer } from "./w
|
|||||||
import { Inbox } from "../models/inboxModel";
|
import { Inbox } from "../models/inboxModel";
|
||||||
|
|
||||||
let amnesia = false;
|
let amnesia = false;
|
||||||
fs.watchFile(configPath, (now, then) => {
|
chokidar.watch(configPath).on("change", () => {
|
||||||
// https://github.com/oven-sh/bun/issues/20542
|
|
||||||
if (process.versions.bun && now.mtimeMs == then.mtimeMs) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (amnesia) {
|
if (amnesia) {
|
||||||
amnesia = false;
|
amnesia = false;
|
||||||
} else {
|
} else {
|
||||||
|
@ -499,6 +499,7 @@ export const addItem = async (
|
|||||||
// - Blueprints for Ancient Protector Specter, Shield Osprey Specter, etc. have num=1 despite giving their purchaseQuantity.
|
// - Blueprints for Ancient Protector Specter, Shield Osprey Specter, etc. have num=1 despite giving their purchaseQuantity.
|
||||||
if (!exactQuantity) {
|
if (!exactQuantity) {
|
||||||
quantity *= ExportGear[typeName].purchaseQuantity ?? 1;
|
quantity *= ExportGear[typeName].purchaseQuantity ?? 1;
|
||||||
|
logger.debug(`non-exact acquisition of ${typeName}; factored quantity is ${quantity}`);
|
||||||
}
|
}
|
||||||
const consumablesChanges = [
|
const consumablesChanges = [
|
||||||
{
|
{
|
||||||
|
@ -398,18 +398,28 @@ export const handleStoreItemAcquisition = async (
|
|||||||
} else {
|
} else {
|
||||||
const storeCategory = getStoreItemCategory(storeItemName);
|
const storeCategory = getStoreItemCategory(storeItemName);
|
||||||
const internalName = fromStoreItem(storeItemName);
|
const internalName = fromStoreItem(storeItemName);
|
||||||
logger.debug(`store category ${storeCategory}`);
|
|
||||||
if (!ignorePurchaseQuantity) {
|
if (!ignorePurchaseQuantity) {
|
||||||
if (internalName in ExportGear) {
|
if (internalName in ExportGear) {
|
||||||
quantity *= ExportGear[internalName].purchaseQuantity || 1;
|
quantity *= ExportGear[internalName].purchaseQuantity || 1;
|
||||||
|
logger.debug(`factored quantity is ${quantity}`);
|
||||||
} else if (internalName in ExportResources) {
|
} else if (internalName in ExportResources) {
|
||||||
quantity *= ExportResources[internalName].purchaseQuantity || 1;
|
quantity *= ExportResources[internalName].purchaseQuantity || 1;
|
||||||
|
logger.debug(`factored quantity is ${quantity}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
logger.debug(`store category ${storeCategory}`);
|
||||||
switch (storeCategory) {
|
switch (storeCategory) {
|
||||||
default: {
|
default: {
|
||||||
purchaseResponse = {
|
purchaseResponse = {
|
||||||
InventoryChanges: await addItem(inventory, internalName, quantity, premiumPurchase, seed)
|
InventoryChanges: await addItem(
|
||||||
|
inventory,
|
||||||
|
internalName,
|
||||||
|
quantity,
|
||||||
|
premiumPurchase,
|
||||||
|
seed,
|
||||||
|
undefined,
|
||||||
|
true
|
||||||
|
)
|
||||||
};
|
};
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -551,7 +561,9 @@ const handleTypesPurchase = async (
|
|||||||
logger.debug(`type category ${typeCategory}`);
|
logger.debug(`type category ${typeCategory}`);
|
||||||
switch (typeCategory) {
|
switch (typeCategory) {
|
||||||
default:
|
default:
|
||||||
return { InventoryChanges: await addItem(inventory, typesName, quantity, premiumPurchase, seed) };
|
return {
|
||||||
|
InventoryChanges: await addItem(inventory, typesName, quantity, premiumPurchase, seed, undefined, true)
|
||||||
|
};
|
||||||
case "BoosterPacks":
|
case "BoosterPacks":
|
||||||
return handleBoosterPackPurchase(typesName, inventory, quantity);
|
return handleBoosterPackPurchase(typesName, inventory, quantity);
|
||||||
case "SlotItems":
|
case "SlotItems":
|
||||||
|
@ -1526,6 +1526,25 @@ export const getWorldState = (buildLabel?: string): IWorldState => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const populateFissures = async (worldState: IWorldState): Promise<void> => {
|
export const populateFissures = async (worldState: IWorldState): Promise<void> => {
|
||||||
|
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({});
|
const fissures = await Fissure.find({});
|
||||||
for (const fissure of fissures) {
|
for (const fissure of fissures) {
|
||||||
const meta = ExportRegions[fissure.Node];
|
const meta = ExportRegions[fissure.Node];
|
||||||
@ -1541,6 +1560,7 @@ export const populateFissures = async (worldState: IWorldState): Promise<void> =
|
|||||||
Hard: fissure.Hard
|
Hard: fissure.Hard
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export const populateDailyDeal = async (worldState: IWorldState): Promise<void> => {
|
export const populateDailyDeal = async (worldState: IWorldState): Promise<void> => {
|
||||||
|
@ -45,5 +45,6 @@
|
|||||||
"/Lotus/Weapons/Tenno/Zariman/Melee/Tonfas/ZarimanTonfaWeapon",
|
"/Lotus/Weapons/Tenno/Zariman/Melee/Tonfas/ZarimanTonfaWeapon",
|
||||||
"/Lotus/Weapons/Tenno/Zariman/Pistols/HeavyPistol/ZarimanHeavyPistol",
|
"/Lotus/Weapons/Tenno/Zariman/Pistols/HeavyPistol/ZarimanHeavyPistol",
|
||||||
"/Lotus/Weapons/Thanotech/EntFistIncarnon/EntFistIncarnon",
|
"/Lotus/Weapons/Thanotech/EntFistIncarnon/EntFistIncarnon",
|
||||||
"/Lotus/Weapons/Thanotech/EntratiWristGun/EntratiWristGunWeapon"
|
"/Lotus/Weapons/Thanotech/EntratiWristGun/EntratiWristGunWeapon",
|
||||||
|
"/Lotus/Weapons/Tenno/Zariman/Melee/HeavyScythe/ZarimanHeavyScythe/ZarimanHeavyScytheWeapon"
|
||||||
]
|
]
|
||||||
|
@ -248,7 +248,8 @@ const permanentEvolutionWeapons = new Set([
|
|||||||
"/Lotus/Weapons/Tenno/Zariman/Melee/Tonfas/ZarimanTonfaWeapon",
|
"/Lotus/Weapons/Tenno/Zariman/Melee/Tonfas/ZarimanTonfaWeapon",
|
||||||
"/Lotus/Weapons/Tenno/Zariman/Pistols/HeavyPistol/ZarimanHeavyPistol",
|
"/Lotus/Weapons/Tenno/Zariman/Pistols/HeavyPistol/ZarimanHeavyPistol",
|
||||||
"/Lotus/Weapons/Thanotech/EntFistIncarnon/EntFistIncarnon",
|
"/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 = {};
|
let uniqueLevelCaps = {};
|
||||||
|
@ -74,9 +74,9 @@ dict = {
|
|||||||
inventory_longGuns: `主要武器`,
|
inventory_longGuns: `主要武器`,
|
||||||
inventory_pistols: `次要武器`,
|
inventory_pistols: `次要武器`,
|
||||||
inventory_melee: `近战武器`,
|
inventory_melee: `近战武器`,
|
||||||
inventory_spaceSuits: `Archwings`,
|
inventory_spaceSuits: `载具`,
|
||||||
inventory_spaceGuns: `Archwing主武器`,
|
inventory_spaceGuns: `载具主武器`,
|
||||||
inventory_spaceMelee: `Archwing近战武器`,
|
inventory_spaceMelee: `载具近战武器`,
|
||||||
inventory_mechSuits: `殁世机甲`,
|
inventory_mechSuits: `殁世机甲`,
|
||||||
inventory_sentinels: `守护`,
|
inventory_sentinels: `守护`,
|
||||||
inventory_sentinelWeapons: `守护武器`,
|
inventory_sentinelWeapons: `守护武器`,
|
||||||
@ -88,15 +88,15 @@ dict = {
|
|||||||
inventory_Boosters: `加成器`,
|
inventory_Boosters: `加成器`,
|
||||||
inventory_bulkAddSuits: `添加缺失战甲`,
|
inventory_bulkAddSuits: `添加缺失战甲`,
|
||||||
inventory_bulkAddWeapons: `添加缺失武器`,
|
inventory_bulkAddWeapons: `添加缺失武器`,
|
||||||
inventory_bulkAddSpaceSuits: `添加缺失Archwing`,
|
inventory_bulkAddSpaceSuits: `添加缺失载具`,
|
||||||
inventory_bulkAddSpaceWeapons: `添加缺失Archwing武器`,
|
inventory_bulkAddSpaceWeapons: `添加缺失载具武器`,
|
||||||
inventory_bulkAddSentinels: `添加缺失守护`,
|
inventory_bulkAddSentinels: `添加缺失守护`,
|
||||||
inventory_bulkAddSentinelWeapons: `添加缺失守护武器`,
|
inventory_bulkAddSentinelWeapons: `添加缺失守护武器`,
|
||||||
inventory_bulkAddEvolutionProgress: `添加缺失的灵化之源`,
|
inventory_bulkAddEvolutionProgress: `添加缺失的灵化之源`,
|
||||||
inventory_bulkRankUpSuits: `所有战甲升满级`,
|
inventory_bulkRankUpSuits: `所有战甲升满级`,
|
||||||
inventory_bulkRankUpWeapons: `所有武器升满级`,
|
inventory_bulkRankUpWeapons: `所有武器升满级`,
|
||||||
inventory_bulkRankUpSpaceSuits: `所有Archwing升满级`,
|
inventory_bulkRankUpSpaceSuits: `所有载具升满级`,
|
||||||
inventory_bulkRankUpSpaceWeapons: `所有Archwing武器升满级`,
|
inventory_bulkRankUpSpaceWeapons: `所有载具武器升满级`,
|
||||||
inventory_bulkRankUpSentinels: `所有守护升满级`,
|
inventory_bulkRankUpSentinels: `所有守护升满级`,
|
||||||
inventory_bulkRankUpSentinelWeapons: `所有守护武器升满级`,
|
inventory_bulkRankUpSentinelWeapons: `所有守护武器升满级`,
|
||||||
inventory_bulkRankUpEvolutionProgress: `所有灵化之源最大等级`,
|
inventory_bulkRankUpEvolutionProgress: `所有灵化之源最大等级`,
|
||||||
@ -182,7 +182,7 @@ dict = {
|
|||||||
cheats_account: `账户`,
|
cheats_account: `账户`,
|
||||||
cheats_unlockAllFocusSchools: `解锁所有专精学派`,
|
cheats_unlockAllFocusSchools: `解锁所有专精学派`,
|
||||||
cheats_helminthUnlockAll: `完全升级Helminth`,
|
cheats_helminthUnlockAll: `完全升级Helminth`,
|
||||||
cheats_addMissingSubsumedAbilities: `[UNTRANSLATED] Add Missing Subsumed Abilities`,
|
cheats_addMissingSubsumedAbilities: `添加Helminth未汲取的战甲技能`,
|
||||||
cheats_intrinsicsUnlockAll: `所有内源之力最大等级`,
|
cheats_intrinsicsUnlockAll: `所有内源之力最大等级`,
|
||||||
cheats_changeSupportedSyndicate: `支持的集团`,
|
cheats_changeSupportedSyndicate: `支持的集团`,
|
||||||
cheats_changeButton: `更改`,
|
cheats_changeButton: `更改`,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user