XFE Git
XFE Studio Git
Git 首页 全局搜索
XFE 主站 文档 NuGet

XFESpaceNinjaServer

A simple server for a small space ninja game

公开
关注 0 Fork 0 Star 0
返回提交历史

XFEstudio/XFESpaceNinjaServer

chore: use PE+ data as readonly (#4446)

This helped me identify and fix 2 bugs afaict Reviewed-on: https://onlyg.it/OpenWF/SpaceNinjaServer/pulls/4446 Co-authored-by: Sainan <63328889+Sainan@users.noreply.github.com> Co-committed-by: Sainan <63328889+Sainan@users.noreply.github.com>

12c4cb97
Sainan <63328889+Sainan@users.noreply.github.com>
提交于

代码差异

15 个文件 +82 -75
Modified package-lock.json +4 -4
@@ -16,7 +16,7 @@
16 16 "mongoose": "^9.6.2",
17 17 "morgan": "^1.10.0",
18 18 "undici": "^7.10.0",
19 "warframe-public-export-plus": "^0.6.6",
19 "warframe-public-export-plus": "^0.6.7",
20 20 "warframe-riven-info": "^0.1.2",
21 21 "winston": "^3.17.0",
22 22 "winston-daily-rotate-file": "^5.0.0",
@@ -4894,9 +4894,9 @@
4894 4894 }
4895 4895 },
4896 4896 "node_modules/warframe-public-export-plus": {
4897 "version": "0.6.6",
4898 "resolved": "https://registry.npmjs.org/warframe-public-export-plus/-/warframe-public-export-plus-0.6.6.tgz",
4899 "integrity": "sha512-7xcbSCm9gJQsGecdFURdZzoarUQWoirOyCD2faMLW0/3dmnG/53x4HC/4YDekMxFKzOsClNdJMC1snqagH4ioQ=="
4897 "version": "0.6.7",
4898 "resolved": "https://registry.npmjs.org/warframe-public-export-plus/-/warframe-public-export-plus-0.6.7.tgz",
4899 "integrity": "sha512-Ybe14BSi1WBIBmZNsNoaUqX5ZvrljcqY+4yuXcexz9ajZaSaSeJk9LDtEF5fZU0iCzhyKmOLCokCp16Kb+2ABw=="
4900 4900 },
4901 4901 "node_modules/warframe-riven-info": {
4902 4902 "version": "0.1.2",
Modified package.json +1 -1
@@ -36,7 +36,7 @@
36 36 "mongoose": "^9.6.2",
37 37 "morgan": "^1.10.0",
38 38 "undici": "^7.10.0",
39 "warframe-public-export-plus": "^0.6.6",
39 "warframe-public-export-plus": "^0.6.7",
40 40 "warframe-riven-info": "^0.1.2",
41 41 "winston": "^3.17.0",
42 42 "winston-daily-rotate-file": "^5.0.0",
Modified src/controllers/api/inventoryController.ts +1 -1
@@ -282,7 +282,7 @@ export const inventoryController: RequestHandler = async (request, response) =>
282 282 }
283 283 if (invasion.Completed) {
284 284 let factionSidedWith: string | undefined;
285 let battlePay: ICountedItem[] | undefined;
285 let battlePay: readonly ICountedItem[] | undefined;
286 286 if (qi.AttackerScore >= 3) {
287 287 factionSidedWith = invasion.Faction;
288 288 battlePay = invasion.AttackerReward.countedItems;
Modified src/controllers/api/modularWeaponCraftingController.ts +1 -1
@@ -38,7 +38,7 @@ export const modularWeaponCraftingController: RequestHandler = async (req, res)
38 38 const category = modularWeaponTypes[data.WeaponType];
39 39 const inventory = await getInventory(accountId, undefined); // Projection is complicated a bit by defaultWeapon for MoaPets
40 40
41 let defaultUpgrades: IDefaultUpgrade[] | undefined;
41 let defaultUpgrades: readonly IDefaultUpgrade[] | undefined;
42 42 const defaultOverwrites: Partial<IKubrowPetDatabase> = {
43 43 ModularParts: data.Parts
44 44 };
Modified src/controllers/custom/getItemListsController.ts +1 -1
@@ -46,7 +46,7 @@ interface ListedItem {
46 46 name: string;
47 47 subtype?: string;
48 48 fusionLimit?: number;
49 exalted?: string[];
49 exalted?: readonly string[];
50 50 badReason?: "starter" | "frivolous" | "notraw";
51 51 partType?: string;
52 52 chainLength?: number;
Modified src/services/inventoryService.ts +2 -2
@@ -1373,7 +1373,7 @@ export const addItem = async (
1373 1373
1374 1374 export const addItems = async (
1375 1375 inventory: TInventoryDatabaseDocument,
1376 items: ITypeCount[] | string[],
1376 items: readonly ITypeCount[] | readonly string[],
1377 1377 inventoryChanges: IInventoryChanges = {}
1378 1378 ): Promise<IInventoryChanges> => {
1379 1379 let inventoryDelta;
@@ -1390,7 +1390,7 @@ export const addItems = async (
1390 1390
1391 1391 export const applyDefaultUpgrades = (
1392 1392 inventory: TInventoryDatabaseDocument,
1393 defaultUpgrades: IDefaultUpgrade[] | undefined,
1393 defaultUpgrades: readonly IDefaultUpgrade[] | undefined,
1394 1394 inventoryChanges: IInventoryChanges
1395 1395 ): IItemConfigDatabase[] => {
1396 1396 const modsToGive: IRawUpgrade[] = [];
Modified src/services/itemDataService.ts +40 -37
@@ -85,6 +85,7 @@ import type { TInventorySlot } from "../types/inventoryTypes/inventoryTypes.ts";
85 85 import { shouldDoServerQol } from "./configService.ts";
86 86 import { buildLabelToVersionInt, wikiDateToBuildVersionInt } from "../helpers/versionHelper.ts";
87 87 import baro from "../constants/baro.ts";
88 import type { Mutable } from "../utils/ts-utils.ts";
88 89
89 90 export type WeaponTypeInternal =
90 91 | "LongGuns"
@@ -3574,85 +3575,86 @@ export const getRecipe = (uniqueName: string, buildLabel: string): IRecipe | und
3574 3575
3575 3576 if (uniqueName.startsWith("/Lotus/StoreItems/Types/Recipes/EidolonRecipes/Arcanes/")) {
3576 3577 if (version_compare(buildLabel, gameToBuildVersion["22.2.4"]) >= 0) {
3578 const wdata = structuredClone(data) as Mutable<IRecipe>;
3577 3579 if (uniqueName.endsWith("ArmourOnOperatorModeBlueprint")) {
3578 data.ingredients[0].ItemCount = 20;
3579 data.ingredients[3] = {
3580 wdata.ingredients[0].ItemCount = 20;
3581 wdata.ingredients[3] = {
3580 3582 ItemType: "/Lotus/Types/Items/MiscItems/Cryotic",
3581 3583 ItemCount: 7100
3582 3584 };
3583 3585 } else if (uniqueName.endsWith("AttackSpeedOnKillBlueprint")) {
3584 data.ingredients[0].ItemCount = 20;
3585 data.ingredients[3] = {
3586 wdata.ingredients[0].ItemCount = 20;
3587 wdata.ingredients[3] = {
3586 3588 ItemType: "/Lotus/Types/Items/MiscItems/Plastids",
3587 3589 ItemCount: 3500
3588 3590 };
3589 3591 } else if (uniqueName.endsWith("CriticalChanceOnHeadshotBlueprint")) {
3590 data.ingredients[0].ItemCount = 3;
3591 data.ingredients[3] = {
3592 wdata.ingredients[0].ItemCount = 3;
3593 wdata.ingredients[3] = {
3592 3594 ItemType: "/Lotus/Types/Items/MiscItems/Rubedo",
3593 3595 ItemCount: 5200
3594 3596 };
3595 3597 } else if (uniqueName.endsWith("HealOnTransferenceInBlueprint")) {
3596 data.ingredients[0].ItemCount = 3;
3597 data.ingredients[1].ItemCount = 3;
3598 data.ingredients[3] = {
3598 wdata.ingredients[0].ItemCount = 3;
3599 wdata.ingredients[1].ItemCount = 3;
3600 wdata.ingredients[3] = {
3599 3601 ItemType: "/Lotus/Types/Items/MiscItems/OxiumAlloy",
3600 3602 ItemCount: 2300
3601 3603 };
3602 3604 } else if (uniqueName.endsWith("HealOnTransferenceOutBlueprint")) {
3603 data.ingredients[0].ItemCount = 3;
3604 data.ingredients[1].ItemCount = 3;
3605 data.ingredients[3] = {
3605 wdata.ingredients[0].ItemCount = 3;
3606 wdata.ingredients[1].ItemCount = 3;
3607 wdata.ingredients[3] = {
3606 3608 ItemType: "/Lotus/Types/Items/MiscItems/PolymerBundle",
3607 3609 ItemCount: 8700
3608 3610 };
3609 3611 } else if (uniqueName.endsWith("HealOnVoidDashBlueprint")) {
3610 data.ingredients[0].ItemCount = 3;
3611 data.ingredients[1].ItemCount = 3;
3612 data.ingredients[3] = {
3612 wdata.ingredients[0].ItemCount = 3;
3613 wdata.ingredients[1].ItemCount = 3;
3614 wdata.ingredients[3] = {
3613 3615 ItemType: "/Lotus/Types/Items/MiscItems/Salvage",
3614 3616 ItemCount: 9200
3615 3617 };
3616 3618 } else if (uniqueName.endsWith("HealthOnOperatorModeBlueprint")) {
3617 data.ingredients[0].ItemCount = 20;
3618 data.ingredients[3] = {
3619 wdata.ingredients[0].ItemCount = 20;
3620 wdata.ingredients[3] = {
3619 3621 ItemType: "/Lotus/Types/Items/MiscItems/AlloyPlate",
3620 3622 ItemCount: 6400
3621 3623 };
3622 3624 } else if (uniqueName.endsWith("ImmunityFallDamageOnVoidDashBlueprint")) {
3623 data.ingredients[0].ItemCount = 3;
3624 data.ingredients[3] = {
3625 wdata.ingredients[0].ItemCount = 3;
3626 wdata.ingredients[3] = {
3625 3627 ItemType: "/Lotus/Types/Items/MiscItems/Ferrite",
3626 3628 ItemCount: 7600
3627 3629 };
3628 3630 } else if (uniqueName.endsWith("IncreasedCriticalDamageOnCriticalStrikeBlueprint")) {
3629 data.ingredients[0].ItemCount = 3;
3630 data.ingredients[3] = {
3631 wdata.ingredients[0].ItemCount = 3;
3632 wdata.ingredients[3] = {
3631 3633 ItemType: "/Lotus/Types/Items/MiscItems/Circuits",
3632 3634 ItemCount: 4400
3633 3635 };
3634 3636 } else if (uniqueName.endsWith("IncreasedDamageOnStatusProcBlueprint")) {
3635 data.ingredients[0].ItemCount = 3;
3636 data.ingredients[3] = {
3637 wdata.ingredients[0].ItemCount = 3;
3638 wdata.ingredients[3] = {
3637 3639 ItemType: "/Lotus/Types/Items/MiscItems/Rubedo",
3638 3640 ItemCount: 4100
3639 3641 };
3640 3642 } else if (uniqueName.endsWith("OperatorAmmoRegenOnKillBlueprint")) {
3641 data.ingredients[0].ItemCount = 20;
3642 data.ingredients[3] = {
3643 wdata.ingredients[0].ItemCount = 20;
3644 wdata.ingredients[3] = {
3643 3645 ItemType: "/Lotus/Types/Items/MiscItems/Circuits",
3644 3646 ItemCount: 3200
3645 3647 };
3646 3648 } else if (uniqueName.endsWith("SpeedOnVoidDashBlueprint")) {
3647 data.ingredients[0].ItemCount = 3;
3648 data.ingredients[1].ItemCount = 3;
3649 data.ingredients[3] = {
3649 wdata.ingredients[0].ItemCount = 3;
3650 wdata.ingredients[1].ItemCount = 3;
3651 wdata.ingredients[3] = {
3650 3652 ItemType: "/Lotus/Types/Items/MiscItems/Nanospores",
3651 3653 ItemCount: 8100
3652 3654 };
3653 3655 } else if (uniqueName.endsWith("StatusChanceOnHeadshotBlueprint")) {
3654 data.ingredients[0].ItemCount = 3;
3655 data.ingredients[3] = {
3656 wdata.ingredients[0].ItemCount = 3;
3657 wdata.ingredients[3] = {
3656 3658 ItemType: "/Lotus/Types/Items/MiscItems/Plastids",
3657 3659 ItemCount: 4800
3658 3660 };
@@ -3660,16 +3662,17 @@ export const getRecipe = (uniqueName: string, buildLabel: string): IRecipe | und
3660 3662 uniqueName.endsWith("ChannelKillEnergyRateBlueprint") ||
3661 3663 uniqueName.endsWith("CritChannelingDamageBlueprint")
3662 3664 ) {
3663 data.ingredients[0].ItemCount = 10;
3665 wdata.ingredients[0].ItemCount = 10;
3664 3666 } else if (
3665 3667 uniqueName.endsWith("FinisherLifestealBlueprint") ||
3666 3668 uniqueName.endsWith("GroundSlamPullBlueprint") ||
3667 3669 uniqueName.endsWith("StatusChannelingDamageBlueprint") ||
3668 3670 uniqueName.endsWith("StatusTriggerRadialDamageBlueprint")
3669 3671 ) {
3670 data.ingredients[0].ItemCount = 10;
3671 data.ingredients[2].ItemCount = 5;
3672 wdata.ingredients[0].ItemCount = 10;
3673 wdata.ingredients[2].ItemCount = 5;
3672 3674 }
3675 data = wdata;
3673 3676 }
3674 3677 if (version_compare(buildLabel, "2017.12.08.15.29") >= 0) {
3675 3678 // Should be 22.3.4 - 2017-11-16
@@ -3815,7 +3818,7 @@ export const getNormalizedString = (key: string, dict: Record<string, string>):
3815 3818 return getString(key, dict).replaceAll("‘", "'").replaceAll("’", "'").replaceAll("\r\n", " ");
3816 3819 };
3817 3820
3818 export const getKeyChainItems = ({ KeyChain, ChainStage }: IKeyChainRequest, buildLabel: string): string[] => {
3821 export const getKeyChainItems = ({ KeyChain, ChainStage }: IKeyChainRequest, buildLabel: string): readonly string[] => {
3819 3822 const chainStages = getKey(KeyChain, buildLabel)?.chainStages;
3820 3823 if (!chainStages) {
3821 3824 throw new Error(`KeyChain ${KeyChain} does not contain chain stages`);
@@ -3839,7 +3842,7 @@ export const getKeyChainItems = ({ KeyChain, ChainStage }: IKeyChainRequest, bui
3839 3842 export const getLevelKeyRewards = (
3840 3843 levelKey: string,
3841 3844 buildLabel: string
3842 ): { levelKeyRewards?: IMissionReward; levelKeyRewards2?: TReward[]; levelMission?: Partial<IRegion> } => {
3845 ): { levelKeyRewards?: IMissionReward; levelKeyRewards2?: readonly TReward[]; levelMission?: Partial<IRegion> } => {
3843 3846 const key = getKey(levelKey, buildLabel);
3844 3847
3845 3848 const levelKeyRewards = key?.missionReward;
@@ -4024,7 +4027,7 @@ export const getBoosterPack = async (
4024 4027 version_compare(buildLabel, gameToBuildVersion["18.16.0"]) < 0 &&
4025 4028 uniqueName == "/Lotus/Types/BoosterPacks/RandomKey"
4026 4029 ) {
4027 const boosterPack: IBoosterPack = {
4030 const boosterPack: Mutable<IBoosterPack> = {
4028 4031 name: "/Lotus/Language/Items/RandomKey",
4029 4032 description: "/Lotus/Language/Items/RandomKeyDesc",
4030 4033 icon: "/Lotus/Interface/Icons/Store/OrokinKey.png",
@@ -4264,7 +4267,7 @@ export const getKey = (uniqueName: string, buildLabel: string = BL_LATEST): IKey
4264 4267 return ExportKeys[uniqueName] ?? supplementalKeys[uniqueName];
4265 4268 };
4266 4269
4267 export const getMissionDeck = (uniqueName: string, buildLabel: string): TMissionDeck | undefined => {
4270 export const getMissionDeck = (uniqueName: string, buildLabel: string): Readonly<TMissionDeck> | undefined => {
4268 4271 if (
4269 4272 uniqueName == "/Lotus/Types/Game/MissionDecks/BossMissionRewards/YinYangRewards" &&
4270 4273 !shouldDoServerQol("tylRegorDropsTwoEquinoxParts", buildLabel, gameToBuildVersion["42.0.0"])
Modified src/services/missionInventoryUpdateService.ts +5 -5
@@ -218,13 +218,13 @@ const getRotations = async (rewardInfo: IRewardInfo, buildLabel: string, tierOve
218 218 return rotatedValues;
219 219 };
220 220
221 const getRandomRewardByChance = (pool: IReward[], rng?: SRng): IRngResult | undefined => {
221 const getRandomRewardByChance = (pool: readonly IReward[], rng?: SRng): IRngResult | undefined => {
222 222 if (rng) {
223 const res = rng.randomReward(pool as IRngResult[]);
223 const res = rng.randomReward(pool as readonly IRngResult[]);
224 224 rng.randomFloat(); // something related to rewards multiplier
225 225 return res;
226 226 }
227 return getRandomReward(pool as IRngResult[]);
227 return getRandomReward(pool as readonly IRngResult[]);
228 228 };
229 229
230 230 //type TMissionInventoryUpdateKeys = keyof IMissionInventoryUpdateRequest;
@@ -2056,7 +2056,7 @@ async function getRandomMissionDrops(
2056 2056 }
2057 2057 const region = await getRegion(RewardInfo.node, buildLabel);
2058 2058 if (region) {
2059 let rewardManifests: string[];
2059 let rewardManifests: readonly string[];
2060 2060 if (RewardInfo.periodicMissionTag == "EliteAlert" || RewardInfo.periodicMissionTag == "EliteAlertB") {
2061 2061 rewardManifests = ["/Lotus/Types/Game/MissionDecks/EliteAlertMissionRewards/EliteAlertMissionRewards"];
2062 2062 } else if (RewardInfo.invasionId && region.missionType == "MT_ASSASSINATION") {
@@ -2362,7 +2362,7 @@ async function getRandomMissionDrops(
2362 2362 for (let dropitem = 0; dropitem < droptimes; ++dropitem) {
2363 2363 const drop = getRandomRewardByChance(table![0], rng);
2364 2364 drops.push({ StoreItem: drop!.type, ItemCount: drop!.itemCount });
2365 table![0] = table![0].filter((item: IReward) => item.type !== drop!.type);
2365 //table![0] = table![0].filter((item: IReward) => item.type !== drop!.type);
2366 2366 }
2367 2367 }
2368 2368 }
Modified src/services/purchaseService.ts +1 -1
@@ -464,7 +464,7 @@ export const handlePurchase = async (
464 464
465 465 const handleItemPrices = async (
466 466 inventory: TInventoryDatabaseDocument,
467 itemPrices: IMiscItem[],
467 itemPrices: readonly IMiscItem[],
468 468 purchaseQuantity: number,
469 469 inventoryChanges: IInventoryChanges
470 470 ): Promise<void> => {
Modified src/services/rngService.ts +4 -4
@@ -34,7 +34,7 @@ export const generateRewardSeed = (): bigint => {
34 34 };
35 35
36 36 export const getRewardAtPercentage = <T extends { probability: number }>(
37 pool: T[],
37 pool: readonly T[],
38 38 percentage: number
39 39 ): T | undefined => {
40 40 if (pool.length == 0) return;
@@ -52,7 +52,7 @@ export const getRewardAtPercentage = <T extends { probability: number }>(
52 52 return pool[pool.length - 1];
53 53 };
54 54
55 export const getRandomReward = <T extends { probability: number }>(pool: T[]): T | undefined => {
55 export const getRandomReward = <T extends { probability: number }>(pool: readonly T[]): T | undefined => {
56 56 return getRewardAtPercentage(pool, Math.random());
57 57 };
58 58
@@ -75,7 +75,7 @@ export const getRandomWeightedReward = <T extends { rarity: TRarity }>(
75 75 };
76 76
77 77 export const getRandomWeightedRewardUc = <T extends { Rarity: TRarity }>(
78 pool: T[],
78 pool: readonly T[],
79 79 weights: Record<TRarity, number>
80 80 ): (T & { probability: number }) | undefined => {
81 81 const resultPool: (T & { probability: number })[] = [];
@@ -137,7 +137,7 @@ export class SRng {
137 137 return (Number(this.state >> 38n) & 0xffffff) * 0.000000059604645;
138 138 }
139 139
140 randomReward<T extends { probability: number }>(pool: T[]): T | undefined {
140 randomReward<T extends { probability: number }>(pool: readonly T[]): T | undefined {
141 141 return getRewardAtPercentage(pool, this.randomFloat());
142 142 }
143 143
Modified src/services/worldStateService.ts +1 -1
@@ -826,7 +826,7 @@ const validateSortieSeed = (seed: number, enemyFaction: TFaction, variants: ISor
826 826 };
827 827
828 828 interface IRotatingSeasonChallengePools {
829 daily: string[];
829 daily: readonly string[];
830 830 weekly: string[];
831 831 hardWeekly: string[];
832 832 weeklyPermanent: string[];
Modified src/types/inboxTypes.ts +2 -2
@@ -40,8 +40,8 @@ export interface IMessage {
40 40 highPriority?: boolean;
41 41 lowPrioNewPlayers?: boolean;
42 42 transmission?: string;
43 att?: string[];
44 countedAtt?: ITypeCount[];
43 att?: readonly string[];
44 countedAtt?: readonly ITypeCount[];
45 45 startDate?: Date;
46 46 endDate?: Date;
47 47 QuestReq?: string;
Modified src/types/publicExportTypes.ts +14 -14
Modified src/types/worldStateTypes.ts +1 -1
Modified src/utils/ts-utils.ts +4 -0