SpaceNinjaServer/src/services/itemDataService.ts
Sainan 729ea0abff
Some checks failed
Build Docker image / docker (push) Has been cancelled
Build / build (push) Has been cancelled
fix: look ahead for key chain messages (#1603)
This is required for the railjack quest:
- request has ChainStage 1 when it wants message from index 3
- request has ChainStage 4 when it wants message from index 6
- ...

Reviewed-on: #1603
Co-authored-by: Sainan <63328889+Sainan@users.noreply.github.com>
Co-committed-by: Sainan <63328889+Sainan@users.noreply.github.com>
2025-04-13 05:51:27 -07:00

242 lines
6.9 KiB
TypeScript

import { IKeyChainRequest } from "@/src/types/requestTypes";
import { getIndexAfter } from "@/src/helpers/stringHelpers";
import {
dict_de,
dict_en,
dict_es,
dict_fr,
dict_it,
dict_ja,
dict_ko,
dict_pl,
dict_pt,
dict_ru,
dict_tc,
dict_th,
dict_tr,
dict_uk,
dict_zh,
ExportArcanes,
ExportCustoms,
ExportDrones,
ExportGear,
ExportKeys,
ExportRecipes,
ExportResources,
ExportSentinels,
ExportWarframes,
ExportWeapons,
IDefaultUpgrade,
IInboxMessage,
IMissionReward,
IRecipe,
TReward
} from "warframe-public-export-plus";
import { IMessage } from "../models/inboxModel";
export type WeaponTypeInternal =
| "LongGuns"
| "Pistols"
| "Melee"
| "SpaceMelee"
| "SpaceGuns"
| "SentinelWeapons"
| "OperatorAmps"
| "SpecialItems";
export const getRecipe = (uniqueName: string): IRecipe | undefined => {
return ExportRecipes[uniqueName];
};
export const getRecipeByResult = (resultType: string): IRecipe | undefined => {
return Object.values(ExportRecipes).find(x => x.resultType == resultType);
};
export const getItemCategoryByUniqueName = (uniqueName: string): string => {
//Lotus/Types/Items/MiscItems/PolymerBundle
let splitWord = "Items/";
if (!uniqueName.includes("/Items/")) {
splitWord = "/Types/";
}
const index = getIndexAfter(uniqueName, splitWord);
if (index === -1) {
throw new Error(`error parsing item category ${uniqueName}`);
}
const category = uniqueName.substring(index).split("/")[0];
return category;
};
export const getItemName = (uniqueName: string): string | undefined => {
if (uniqueName in ExportArcanes) {
return ExportArcanes[uniqueName].name;
}
if (uniqueName in ExportCustoms) {
return ExportCustoms[uniqueName].name;
}
if (uniqueName in ExportDrones) {
return ExportDrones[uniqueName].name;
}
if (uniqueName in ExportKeys) {
return ExportKeys[uniqueName].name;
}
if (uniqueName in ExportGear) {
return ExportGear[uniqueName].name;
}
if (uniqueName in ExportResources) {
return ExportResources[uniqueName].name;
}
if (uniqueName in ExportSentinels) {
return ExportSentinels[uniqueName].name;
}
if (uniqueName in ExportWarframes) {
return ExportWarframes[uniqueName].name;
}
if (uniqueName in ExportWeapons) {
return ExportWeapons[uniqueName].name;
}
return undefined;
};
export const getDict = (lang: string): Record<string, string> => {
switch (lang) {
case "de":
return dict_de;
case "es":
return dict_es;
case "fr":
return dict_fr;
case "it":
return dict_it;
case "ja":
return dict_ja;
case "ko":
return dict_ko;
case "pl":
return dict_pl;
case "pt":
return dict_pt;
case "ru":
return dict_ru;
case "tc":
return dict_tc;
case "th":
return dict_th;
case "tr":
return dict_tr;
case "uk":
return dict_uk;
case "zh":
return dict_zh;
}
return dict_en;
};
export const getString = (key: string, dict: Record<string, string>): string => {
return dict[key] ?? key;
};
export const getKeyChainItems = ({ KeyChain, ChainStage }: IKeyChainRequest): string[] => {
const chainStages = ExportKeys[KeyChain].chainStages;
if (!chainStages) {
throw new Error(`KeyChain ${KeyChain} does not contain chain stages`);
}
const keyChainStage = chainStages[ChainStage];
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
if (!keyChainStage) {
throw new Error(`KeyChainStage ${ChainStage} not found`);
}
if (keyChainStage.itemsToGiveWhenTriggered.length === 0) {
throw new Error(
`client requested key chain items in KeyChain ${KeyChain} at stage ${ChainStage}, but they did not exist`
);
}
return keyChainStage.itemsToGiveWhenTriggered;
};
export const getLevelKeyRewards = (
levelKey: string
): { levelKeyRewards?: IMissionReward; levelKeyRewards2?: TReward[] } => {
if (!(levelKey in ExportKeys)) {
throw new Error(`LevelKey ${levelKey} not found`);
}
const levelKeyRewards = ExportKeys[levelKey].missionReward;
const levelKeyRewards2 = ExportKeys[levelKey].rewards;
if (!levelKeyRewards && !levelKeyRewards2) {
throw new Error(`LevelKey ${levelKey} does not contain either rewards1 or rewards2`);
}
return {
levelKeyRewards,
levelKeyRewards2
};
};
export const getKeyChainMessage = ({ KeyChain, ChainStage }: IKeyChainRequest): IMessage => {
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
const chainStages = ExportKeys[KeyChain]?.chainStages;
if (!chainStages) {
throw new Error(`KeyChain ${KeyChain} does not contain chain stages`);
}
let i = ChainStage;
let chainStageMessage = chainStages[i].messageToSendWhenTriggered;
while (!chainStageMessage) {
if (++i >= chainStages.length) {
break;
}
chainStageMessage = chainStages[i].messageToSendWhenTriggered;
}
if (!chainStageMessage) {
throw new Error(
`client requested key chain message in keychain ${KeyChain} at stage ${ChainStage} but they did not exist`
);
}
return convertInboxMessage(chainStageMessage);
};
export const convertInboxMessage = (message: IInboxMessage): IMessage => {
return {
sndr: message.sender,
msg: message.body,
sub: message.title,
att: message.attachments.length > 0 ? message.attachments : undefined,
countedAtt: message.countedAttachments.length > 0 ? message.countedAttachments : undefined,
icon: message.icon ?? "",
transmission: message.transmission ?? "",
highPriority: message.highPriority ?? false,
r: false
} satisfies IMessage;
};
export const isStoreItem = (type: string): boolean => {
return type.startsWith("/Lotus/StoreItems/");
};
export const toStoreItem = (type: string): string => {
return "/Lotus/StoreItems/" + type.substring("/Lotus/".length);
};
export const fromStoreItem = (type: string): string => {
return "/Lotus/" + type.substring("/Lotus/StoreItems/".length);
};
export const getDefaultUpgrades = (parts: string[]): IDefaultUpgrade[] | undefined => {
const allDefaultUpgrades: IDefaultUpgrade[] = [];
for (const part of parts) {
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
const defaultUpgrades = ExportWeapons[part]?.defaultUpgrades;
if (defaultUpgrades) {
allDefaultUpgrades.push(...defaultUpgrades);
}
}
return allDefaultUpgrades.length == 0 ? undefined : allDefaultUpgrades;
};