feat: handle EmailItems received during mission (#1088)

Closes #1087

Reviewed-on: OpenWF/SpaceNinjaServer#1088
This commit is contained in:
Sainan 2025-03-07 00:41:18 -08:00
parent 530713ce5c
commit 59fd816b0c
5 changed files with 50 additions and 14 deletions

View File

@ -54,7 +54,7 @@ export const missionInventoryUpdateController: RequestHandler = async (req, res)
logger.debug("mission report:", missionReport);
const inventory = await getInventory(accountId);
const inventoryUpdates = addMissionInventoryUpdates(inventory, missionReport);
const inventoryUpdates = await addMissionInventoryUpdates(inventory, missionReport);
if (missionReport.MissionStatus !== "GS_SUCCESS") {
await inventory.save();

View File

@ -428,10 +428,8 @@ export const addItem = async (
};
}
if (typeName in ExportEmailItems) {
const emailItem = ExportEmailItems[typeName];
await createMessage(inventory.accountOwnerId.toString(), [convertInboxMessage(emailItem.message)]);
return {
InventoryChanges: {}
InventoryChanges: await addEmailItem(inventory, typeName)
};
}
@ -943,6 +941,28 @@ const addDrone = (
return inventoryChanges;
};
export const addEmailItem = async (
inventory: TInventoryDatabaseDocument,
typeName: string,
inventoryChanges: IInventoryChanges = {}
): Promise<IInventoryChanges> => {
const meta = ExportEmailItems[typeName];
const emailItem = inventory.EmailItems.find(x => x.ItemType == typeName);
if (!emailItem || !meta.sendOnlyOnce) {
await createMessage(inventory.accountOwnerId.toString(), [convertInboxMessage(meta.message)]);
if (emailItem) {
emailItem.ItemCount += 1;
} else {
inventory.EmailItems.push({ ItemType: typeName, ItemCount: 1 });
}
inventoryChanges.EmailItems ??= [];
inventoryChanges.EmailItems.push({ ItemType: typeName, ItemCount: 1 });
}
return inventoryChanges;
};
//TODO: wrong id is not erroring
export const addGearExpByCategory = (
inventory: TInventoryDatabaseDocument,

View File

@ -14,6 +14,7 @@ import {
addConsumables,
addCrewShipAmmo,
addCrewShipRawSalvage,
addEmailItem,
addFocusXpIncreases,
addFusionTreasures,
addGearExpByCategory,
@ -61,10 +62,10 @@ const getRandomRewardByChance = (pool: IReward[]): IRngResult | undefined => {
//type TignoredInventoryUpdateKeys = (typeof ignoredInventoryUpdateKeys)[number];
//const knownUnhandledKeys: readonly string[] = ["test"] as const; // for unimplemented but important keys
export const addMissionInventoryUpdates = (
export const addMissionInventoryUpdates = async (
inventory: HydratedDocument<IInventoryDatabase, InventoryDocumentProps>,
inventoryUpdates: IMissionInventoryUpdateRequest
): Partial<IInventoryDatabase> | undefined => {
): Promise<Partial<IInventoryDatabase> | undefined> => {
//TODO: type this properly
const inventoryChanges: Partial<IInventoryDatabase> = {};
if (inventoryUpdates.MissionFailed === true) {
@ -156,6 +157,12 @@ export const addMissionInventoryUpdates = (
inventoryChanges.FusionPoints = fusionPoints;
break;
}
case "EmailItems": {
for (const tc of value) {
await addEmailItem(inventory, tc.ItemType);
}
break;
}
case "FocusXpIncreases": {
addFocusXpIncreases(inventory, value);
break;
@ -237,32 +244,32 @@ export const addMissionInventoryUpdates = (
});
break;
case "CollectibleScans":
value.forEach(scan => {
for (const scan of value) {
const entry = inventory.CollectibleSeries?.find(x => x.CollectibleType == scan.CollectibleType);
if (entry) {
entry.Count = scan.Count;
entry.Tracking = scan.Tracking;
if (entry.CollectibleType == "/Lotus/Objects/Orokin/Props/CollectibleSeriesOne") {
const progress = entry.Count / entry.ReqScans;
entry.IncentiveStates.forEach(gate => {
for (const gate of entry.IncentiveStates) {
gate.complete = progress >= gate.threshold;
if (gate.complete && !gate.sent) {
gate.sent = true;
if (gate.threshold == 0.5) {
void createMessage(inventory.accountOwnerId.toString(), [kuriaMessage50]);
await createMessage(inventory.accountOwnerId.toString(), [kuriaMessage50]);
} else {
void createMessage(inventory.accountOwnerId.toString(), [kuriaMessage75]);
await createMessage(inventory.accountOwnerId.toString(), [kuriaMessage75]);
}
}
}
});
if (progress >= 1.0) {
void createMessage(inventory.accountOwnerId.toString(), [kuriaMessage100]);
await createMessage(inventory.accountOwnerId.toString(), [kuriaMessage100]);
}
}
} else {
logger.warn(`${scan.CollectibleType} was not found in inventory, ignoring scans`);
}
});
}
break;
case "Upgrades":
value.forEach(clientUpgrade => {

View File

@ -1,5 +1,11 @@
import { IEquipmentClient } from "./inventoryTypes/commonInventoryTypes";
import { IDroneClient, IInfestedFoundryClient, IMiscItem, TEquipmentKey } from "./inventoryTypes/inventoryTypes";
import {
IDroneClient,
IInfestedFoundryClient,
IMiscItem,
ITypeCount,
TEquipmentKey
} from "./inventoryTypes/inventoryTypes";
export interface IPurchaseRequest {
PurchaseParams: IPurchaseParams;
@ -33,6 +39,7 @@ export type IInventoryChanges = {
InfestedFoundry?: IInfestedFoundryClient;
Drones?: IDroneClient[];
MiscItems?: IMiscItem[];
EmailItems?: ITypeCount[];
} & Record<
Exclude<
string,
@ -44,6 +51,7 @@ export type IInventoryChanges = {
| "InfestedFoundry"
| "Drones"
| "MiscItems"
| "EmailItems"
>,
number | object[]
>;

View File

@ -46,6 +46,7 @@ export type IMissionInventoryUpdateRequest = {
CrewShipRawSalvage?: ITypeCount[];
CrewShipAmmo?: ITypeCount[];
BonusMiscItems?: ITypeCount[];
EmailItems?: ITypeCount[];
SyndicateId?: string;
SortieId?: string;