chore: make addItem return InventoryChanges directly (#1299)

Reviewed-on: OpenWF/SpaceNinjaServer#1299
This commit is contained in:
Sainan 2025-03-23 08:26:46 -07:00
parent cf125b5355
commit aa12708738
5 changed files with 76 additions and 134 deletions

View File

@ -118,7 +118,7 @@ export const claimCompletedRecipeController: RequestHandler = async (req, res) =
} }
InventoryChanges = { InventoryChanges = {
...InventoryChanges, ...InventoryChanges,
...(await addItem(inventory, recipe.resultType, recipe.num, false)).InventoryChanges ...(await addItem(inventory, recipe.resultType, recipe.num, false))
}; };
await inventory.save(); await inventory.save();
res.json({ InventoryChanges }); res.json({ InventoryChanges });

View File

@ -87,7 +87,7 @@ export const addStartingGear = async (
for (const item of awakeningRewards) { for (const item of awakeningRewards) {
const inventoryDelta = await addItem(inventory, item); const inventoryDelta = await addItem(inventory, item);
combineInventoryChanges(inventoryChanges, inventoryDelta.InventoryChanges); combineInventoryChanges(inventoryChanges, inventoryDelta);
} }
inventory.PlayedParkourTutorial = true; inventory.PlayedParkourTutorial = true;

View File

@ -194,7 +194,7 @@ export const guildTechController: RequestHandler = async (req, res) => {
ItemCount: x.ItemCount * -1 ItemCount: x.ItemCount * -1
})); }));
addMiscItems(inventory, inventoryChanges.MiscItems); addMiscItems(inventory, inventoryChanges.MiscItems);
combineInventoryChanges(inventoryChanges, (await addItem(inventory, recipe.resultType)).InventoryChanges); combineInventoryChanges(inventoryChanges, await addItem(inventory, recipe.resultType));
await inventory.save(); await inventory.save();
// Not a mistake: This response uses `inventoryChanges` instead of `InventoryChanges`. // Not a mistake: This response uses `inventoryChanges` instead of `InventoryChanges`.
res.json({ inventoryChanges: inventoryChanges }); res.json({ inventoryChanges: inventoryChanges });

View File

@ -234,10 +234,10 @@ export const addItem = async (
typeName: string, typeName: string,
quantity: number = 1, quantity: number = 1,
premiumPurchase: boolean = false premiumPurchase: boolean = false
): Promise<{ InventoryChanges: IInventoryChanges }> => { ): Promise<IInventoryChanges> => {
// Bundles are technically StoreItems but a) they don't have a normal counterpart, and b) they are used in non-StoreItem contexts, e.g. email attachments. // Bundles are technically StoreItems but a) they don't have a normal counterpart, and b) they are used in non-StoreItem contexts, e.g. email attachments.
if (typeName in ExportBundles) { if (typeName in ExportBundles) {
return { InventoryChanges: await handleBundleAcqusition(typeName, inventory, quantity) }; return await handleBundleAcqusition(typeName, inventory, quantity);
} }
// Strict typing // Strict typing
@ -250,9 +250,7 @@ export const addItem = async (
]; ];
addRecipes(inventory, recipeChanges); addRecipes(inventory, recipeChanges);
return { return {
InventoryChanges: { Recipes: recipeChanges
Recipes: recipeChanges
}
}; };
} }
if (typeName in ExportResources) { if (typeName in ExportResources) {
@ -265,9 +263,7 @@ export const addItem = async (
]; ];
addMiscItems(inventory, miscItemChanges); addMiscItems(inventory, miscItemChanges);
return { return {
InventoryChanges: { MiscItems: miscItemChanges
MiscItems: miscItemChanges
}
}; };
} else if (ExportResources[typeName].productCategory == "FusionTreasures") { } else if (ExportResources[typeName].productCategory == "FusionTreasures") {
const fusionTreasureChanges = [ const fusionTreasureChanges = [
@ -279,25 +275,21 @@ export const addItem = async (
]; ];
addFusionTreasures(inventory, fusionTreasureChanges); addFusionTreasures(inventory, fusionTreasureChanges);
return { return {
InventoryChanges: { FusionTreasures: fusionTreasureChanges
FusionTreasures: fusionTreasureChanges
}
}; };
} else if (ExportResources[typeName].productCategory == "Ships") { } else if (ExportResources[typeName].productCategory == "Ships") {
const oid = await createShip(inventory.accountOwnerId, typeName); const oid = await createShip(inventory.accountOwnerId, typeName);
inventory.Ships.push(oid); inventory.Ships.push(oid);
return { return {
InventoryChanges: { Ships: [
Ships: [ {
{ ItemId: { $oid: oid.toString() },
ItemId: { $oid: oid.toString() }, ItemType: typeName
ItemType: typeName }
} ]
]
}
}; };
} else if (ExportResources[typeName].productCategory == "CrewShips") { } else if (ExportResources[typeName].productCategory == "CrewShips") {
const inventoryChanges = { return {
...addCrewShip(inventory, typeName), ...addCrewShip(inventory, typeName),
// fix to unlock railjack modding, item bellow supposed to be obtained from archwing quest // fix to unlock railjack modding, item bellow supposed to be obtained from archwing quest
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
@ -305,8 +297,6 @@ export const addItem = async (
? addCrewShipHarness(inventory, "/Lotus/Types/Game/CrewShip/RailJack/DefaultHarness") ? addCrewShipHarness(inventory, "/Lotus/Types/Game/CrewShip/RailJack/DefaultHarness")
: {}) : {})
}; };
return { InventoryChanges: inventoryChanges };
} else if (ExportResources[typeName].productCategory == "ShipDecorations") { } else if (ExportResources[typeName].productCategory == "ShipDecorations") {
const changes = [ const changes = [
{ {
@ -316,9 +306,7 @@ export const addItem = async (
]; ];
addShipDecorations(inventory, changes); addShipDecorations(inventory, changes);
return { return {
InventoryChanges: { ShipDecorations: changes
ShipDecorations: changes
}
}; };
} else if (ExportResources[typeName].productCategory == "KubrowPetEggs") { } else if (ExportResources[typeName].productCategory == "KubrowPetEggs") {
const changes: IKubrowPetEggClient[] = []; const changes: IKubrowPetEggClient[] = [];
@ -339,9 +327,7 @@ export const addItem = async (
}); });
} }
return { return {
InventoryChanges: { KubrowPetEggs: changes
KubrowPetEggs: changes
}
}; };
} else { } else {
throw new Error(`unknown product category: ${ExportResources[typeName].productCategory}`); throw new Error(`unknown product category: ${ExportResources[typeName].productCategory}`);
@ -349,14 +335,13 @@ export const addItem = async (
} }
if (typeName in ExportCustoms) { if (typeName in ExportCustoms) {
if (ExportCustoms[typeName].productCategory == "CrewShipWeaponSkins") { if (ExportCustoms[typeName].productCategory == "CrewShipWeaponSkins") {
return { InventoryChanges: addCrewShipWeaponSkin(inventory, typeName) }; return addCrewShipWeaponSkin(inventory, typeName);
} else { } else {
return { InventoryChanges: addSkin(inventory, typeName) }; return addSkin(inventory, typeName);
} }
} }
if (typeName in ExportFlavour) { if (typeName in ExportFlavour) {
const inventoryChanges = addCustomization(inventory, typeName); return addCustomization(inventory, typeName);
return { InventoryChanges: inventoryChanges };
} }
if (typeName in ExportUpgrades || typeName in ExportArcanes) { if (typeName in ExportUpgrades || typeName in ExportArcanes) {
const changes = [ const changes = [
@ -367,9 +352,7 @@ export const addItem = async (
]; ];
addMods(inventory, changes); addMods(inventory, changes);
return { return {
InventoryChanges: { RawUpgrades: changes
RawUpgrades: changes
}
}; };
} }
if (typeName in ExportGear) { if (typeName in ExportGear) {
@ -381,9 +364,7 @@ export const addItem = async (
]; ];
addConsumables(inventory, consumablesChanges); addConsumables(inventory, consumablesChanges);
return { return {
InventoryChanges: { Consumables: consumablesChanges
Consumables: consumablesChanges
}
}; };
} }
if (typeName in ExportWeapons) { if (typeName in ExportWeapons) {
@ -426,14 +407,12 @@ export const addItem = async (
); );
if (weapon.additionalItems) { if (weapon.additionalItems) {
for (const item of weapon.additionalItems) { for (const item of weapon.additionalItems) {
combineInventoryChanges(inventoryChanges, (await addItem(inventory, item, 1)).InventoryChanges); combineInventoryChanges(inventoryChanges, await addItem(inventory, item, 1));
} }
} }
return { return {
InventoryChanges: { ...inventoryChanges,
...inventoryChanges, ...occupySlot(inventory, InventorySlot.WEAPONS, premiumPurchase)
...occupySlot(inventory, InventorySlot.WEAPONS, premiumPurchase)
}
}; };
} else { } else {
// Modular weapon parts // Modular weapon parts
@ -445,36 +424,28 @@ export const addItem = async (
]; ];
addMiscItems(inventory, miscItemChanges); addMiscItems(inventory, miscItemChanges);
return { return {
InventoryChanges: { MiscItems: miscItemChanges
MiscItems: miscItemChanges
}
}; };
} }
} }
if (typeName in ExportRailjackWeapons) { if (typeName in ExportRailjackWeapons) {
return { return {
InventoryChanges: { ...addCrewShipWeapon(inventory, typeName),
...addCrewShipWeapon(inventory, typeName), ...occupySlot(inventory, InventorySlot.RJ_COMPONENT_AND_ARMAMENTS, premiumPurchase)
...occupySlot(inventory, InventorySlot.RJ_COMPONENT_AND_ARMAMENTS, premiumPurchase)
}
}; };
} }
if (typeName in ExportMisc.creditBundles) { if (typeName in ExportMisc.creditBundles) {
const creditsTotal = ExportMisc.creditBundles[typeName] * quantity; const creditsTotal = ExportMisc.creditBundles[typeName] * quantity;
inventory.RegularCredits += creditsTotal; inventory.RegularCredits += creditsTotal;
return { return {
InventoryChanges: { RegularCredits: creditsTotal
RegularCredits: creditsTotal
}
}; };
} }
if (typeName in ExportFusionBundles) { if (typeName in ExportFusionBundles) {
const fusionPointsTotal = ExportFusionBundles[typeName].fusionPoints * quantity; const fusionPointsTotal = ExportFusionBundles[typeName].fusionPoints * quantity;
inventory.FusionPoints += fusionPointsTotal; inventory.FusionPoints += fusionPointsTotal;
return { return {
InventoryChanges: { FusionPoints: fusionPointsTotal
FusionPoints: fusionPointsTotal
}
}; };
} }
if (typeName in ExportKeys) { if (typeName in ExportKeys) {
@ -483,8 +454,8 @@ export const addItem = async (
if (key.chainStages) { if (key.chainStages) {
const key = addQuestKey(inventory, { ItemType: typeName }); const key = addQuestKey(inventory, { ItemType: typeName });
if (!key) return { InventoryChanges: {} }; if (!key) return {};
return { InventoryChanges: { QuestKeys: [key] } }; return { QuestKeys: [key] };
} else { } else {
const key = { ItemType: typeName, ItemCount: quantity }; const key = { ItemType: typeName, ItemCount: quantity };
@ -494,19 +465,14 @@ export const addItem = async (
} else { } else {
inventory.LevelKeys.push(key); inventory.LevelKeys.push(key);
} }
return { InventoryChanges: { LevelKeys: [key] } }; return { LevelKeys: [key] };
} }
} }
if (typeName in ExportDrones) { if (typeName in ExportDrones) {
const inventoryChanges = addDrone(inventory, typeName); return addDrone(inventory, typeName);
return {
InventoryChanges: inventoryChanges
};
} }
if (typeName in ExportEmailItems) { if (typeName in ExportEmailItems) {
return { return await addEmailItem(inventory, typeName);
InventoryChanges: await addEmailItem(inventory, typeName)
};
} }
// Path-based duck typing // Path-based duck typing
@ -515,42 +481,36 @@ export const addItem = async (
switch (typeName.substr(1).split("/")[2]) { switch (typeName.substr(1).split("/")[2]) {
default: { default: {
return { return {
InventoryChanges: { ...addPowerSuit(
...addPowerSuit( inventory,
inventory, typeName,
typeName, {},
{}, premiumPurchase ? EquipmentFeatures.DOUBLE_CAPACITY : undefined
premiumPurchase ? EquipmentFeatures.DOUBLE_CAPACITY : undefined ),
), ...occupySlot(inventory, InventorySlot.SUITS, premiumPurchase)
...occupySlot(inventory, InventorySlot.SUITS, premiumPurchase)
}
}; };
} }
case "Archwing": { case "Archwing": {
inventory.ArchwingEnabled = true; inventory.ArchwingEnabled = true;
return { return {
InventoryChanges: { ...addSpaceSuit(
...addSpaceSuit( inventory,
inventory, typeName,
typeName, {},
{}, premiumPurchase ? EquipmentFeatures.DOUBLE_CAPACITY : undefined
premiumPurchase ? EquipmentFeatures.DOUBLE_CAPACITY : undefined ),
), ...occupySlot(inventory, InventorySlot.SPACESUITS, premiumPurchase)
...occupySlot(inventory, InventorySlot.SPACESUITS, premiumPurchase)
}
}; };
} }
case "EntratiMech": { case "EntratiMech": {
return { return {
InventoryChanges: { ...addMechSuit(
...addMechSuit( inventory,
inventory, typeName,
typeName, {},
{}, premiumPurchase ? EquipmentFeatures.DOUBLE_CAPACITY : undefined
premiumPurchase ? EquipmentFeatures.DOUBLE_CAPACITY : undefined ),
), ...occupySlot(inventory, InventorySlot.MECHSUITS, premiumPurchase)
...occupySlot(inventory, InventorySlot.MECHSUITS, premiumPurchase)
}
}; };
} }
} }
@ -568,9 +528,7 @@ export const addItem = async (
]; ];
addMods(inventory, changes); addMods(inventory, changes);
return { return {
InventoryChanges: { RawUpgrades: changes
RawUpgrades: changes
}
}; };
} }
break; break;
@ -587,9 +545,7 @@ export const addItem = async (
]; ];
addMiscItems(inventory, miscItemChanges); addMiscItems(inventory, miscItemChanges);
return { return {
InventoryChanges: { MiscItems: miscItemChanges
MiscItems: miscItemChanges
}
}; };
} else { } else {
const changes = [ const changes = [
@ -600,9 +556,7 @@ export const addItem = async (
]; ];
addMods(inventory, changes); addMods(inventory, changes);
return { return {
InventoryChanges: { RawUpgrades: changes
RawUpgrades: changes
}
}; };
} }
} }
@ -613,9 +567,7 @@ export const addItem = async (
case "Types": case "Types":
switch (typeName.substr(1).split("/")[2]) { switch (typeName.substr(1).split("/")[2]) {
case "Sentinels": { case "Sentinels": {
return { return addSentinel(inventory, typeName, premiumPurchase);
InventoryChanges: addSentinel(inventory, typeName, premiumPurchase)
};
} }
case "Game": { case "Game": {
if (typeName.substr(1).split("/")[3] == "Projections") { if (typeName.substr(1).split("/")[3] == "Projections") {
@ -629,9 +581,7 @@ export const addItem = async (
addMiscItems(inventory, miscItemChanges); addMiscItems(inventory, miscItemChanges);
inventory.HasOwnedVoidProjectionsPreviously = true; inventory.HasOwnedVoidProjectionsPreviously = true;
return { return {
InventoryChanges: { MiscItems: miscItemChanges
MiscItems: miscItemChanges
}
}; };
} }
break; break;
@ -639,27 +589,23 @@ export const addItem = async (
case "NeutralCreatures": { case "NeutralCreatures": {
const horseIndex = inventory.Horses.push({ ItemType: typeName }); const horseIndex = inventory.Horses.push({ ItemType: typeName });
return { return {
InventoryChanges: { Horses: [inventory.Horses[horseIndex - 1].toJSON<IEquipmentClient>()]
Horses: [inventory.Horses[horseIndex - 1].toJSON<IEquipmentClient>()]
}
}; };
} }
case "Recipes": { case "Recipes": {
inventory.MiscItems.push({ ItemType: typeName, ItemCount: quantity }); inventory.MiscItems.push({ ItemType: typeName, ItemCount: quantity });
return { return {
InventoryChanges: { MiscItems: [
MiscItems: [ {
{ ItemType: typeName,
ItemType: typeName, ItemCount: quantity
ItemCount: quantity }
} ]
]
}
}; };
} }
case "Vehicles": case "Vehicles":
if (typeName == "/Lotus/Types/Vehicles/Motorcycle/MotorcyclePowerSuit") { if (typeName == "/Lotus/Types/Vehicles/Motorcycle/MotorcyclePowerSuit") {
return { InventoryChanges: addMotorcycle(inventory, typeName) }; return addMotorcycle(inventory, typeName);
} }
break; break;
} }
@ -680,7 +626,7 @@ export const addItems = async (
} else { } else {
inventoryDelta = await addItem(inventory, item.ItemType, item.ItemCount, true); inventoryDelta = await addItem(inventory, item.ItemType, item.ItemCount, true);
} }
combineInventoryChanges(inventoryChanges, inventoryDelta.InventoryChanges); combineInventoryChanges(inventoryChanges, inventoryDelta);
} }
return inventoryChanges; return inventoryChanges;
}; };
@ -1388,12 +1334,11 @@ export const addKeyChainItems = async (
const nonStoreItems = keyChainItems.map(item => fromStoreItem(item)); const nonStoreItems = keyChainItems.map(item => fromStoreItem(item));
//TODO: inventoryChanges is not typed correctly const inventoryChanges: IInventoryChanges = {};
const inventoryChanges = {};
for (const item of nonStoreItems) { for (const item of nonStoreItems) {
const inventoryChangesDelta = await addItem(inventory, item); const inventoryChangesDelta = await addItem(inventory, item);
combineInventoryChanges(inventoryChanges, inventoryChangesDelta.InventoryChanges); combineInventoryChanges(inventoryChanges, inventoryChangesDelta);
} }
return inventoryChanges; return inventoryChanges;

View File

@ -333,7 +333,7 @@ export const handleStoreItemAcquisition = async (
} }
switch (storeCategory) { switch (storeCategory) {
default: { default: {
purchaseResponse = await addItem(inventory, internalName, quantity, true); purchaseResponse = { InventoryChanges: await addItem(inventory, internalName, quantity, true) };
break; break;
} }
case "Types": case "Types":
@ -418,10 +418,7 @@ const handleBoosterPackPurchase = async (
if (typeName == "/Lotus/Types/BoosterPacks/1999StickersPackEchoesArchimedeaFixed") { if (typeName == "/Lotus/Types/BoosterPacks/1999StickersPackEchoesArchimedeaFixed") {
for (const result of pack.components) { for (const result of pack.components) {
purchaseResponse.BoosterPackItems += toStoreItem(result.Item) + ',{"lvl":0};'; purchaseResponse.BoosterPackItems += toStoreItem(result.Item) + ',{"lvl":0};';
combineInventoryChanges( combineInventoryChanges(purchaseResponse.InventoryChanges, await addItem(inventory, result.Item, 1));
purchaseResponse.InventoryChanges,
(await addItem(inventory, result.Item, 1)).InventoryChanges
);
} }
} else { } else {
for (let i = 0; i != quantity; ++i) { for (let i = 0; i != quantity; ++i) {
@ -432,7 +429,7 @@ const handleBoosterPackPurchase = async (
purchaseResponse.BoosterPackItems += toStoreItem(result.Item) + ',{"lvl":0};'; purchaseResponse.BoosterPackItems += toStoreItem(result.Item) + ',{"lvl":0};';
combineInventoryChanges( combineInventoryChanges(
purchaseResponse.InventoryChanges, purchaseResponse.InventoryChanges,
(await addItem(inventory, result.Item, 1)).InventoryChanges await addItem(inventory, result.Item, 1)
); );
} }
} }
@ -468,7 +465,7 @@ const handleTypesPurchase = async (
logger.debug(`type category ${typeCategory}`); logger.debug(`type category ${typeCategory}`);
switch (typeCategory) { switch (typeCategory) {
default: default:
return await addItem(inventory, typesName, quantity); return { InventoryChanges: await addItem(inventory, typesName, quantity) };
case "BoosterPacks": case "BoosterPacks":
return handleBoosterPackPurchase(typesName, inventory, quantity); return handleBoosterPackPurchase(typesName, inventory, quantity);
case "SlotItems": case "SlotItems":