返回提交历史
Modified
src/services/inventoryService.ts
+19
-3
Modified
src/services/purchaseService.ts
+52
-14
Modified
src/types/purchaseTypes.ts
+1
-19
XFEstudio/XFESpaceNinjaServer
fix: not being able to buy incarnon bundles (#337)
5597db67
代码差异
3 个文件
+72
-36
@@ -2,7 +2,7 @@ import { Inventory } from "@/src/models/inventoryModels/inventoryModel";
2
2
import new_inventory from "@/static/fixed_responses/postTutorialInventory.json";
3
3
import { config } from "@/src/services/configService";
4
4
import { Types } from "mongoose";
5
import { SlotNames } from "@/src/types/purchaseTypes";
5
import { SlotNames, IInventoryChanges } from "@/src/types/purchaseTypes";
6
6
import {
7
7
IChallengeProgress,
8
8
IConsumable,
@@ -26,7 +26,7 @@ import { logger } from "@/src/utils/logger";
26
26
import { WeaponTypeInternal, getWeaponType, getExalted } from "@/src/services/itemDataService";
27
27
import { ISyndicateSacrifice, ISyndicateSacrificeResponse } from "../types/syndicateTypes";
28
28
import { IEquipmentClient } from "../types/inventoryTypes/commonInventoryTypes";
29
import { ExportRecipes } from "warframe-public-export-plus";
29
import { ExportRecipes, ExportResources } from "warframe-public-export-plus";
30
30
31
31
export const createInventory = async (
32
32
accountOwnerId: Types.ObjectId,
@@ -70,7 +70,7 @@ export const addItem = async (
70
70
accountId: string,
71
71
typeName: string,
72
72
quantity: number = 1
73
): Promise<{ InventoryChanges: object }> => {
73
): Promise<{ InventoryChanges: IInventoryChanges }> => {
74
74
// Strict typing
75
75
if (typeName in ExportRecipes) {
76
76
const inventory = await getInventory(accountId);
@@ -88,6 +88,22 @@ export const addItem = async (
88
88
}
89
89
};
90
90
}
91
if (typeName in ExportResources) {
92
const inventory = await getInventory(accountId);
93
const miscItemChanges = [
94
{
95
ItemType: typeName,
96
ItemCount: quantity
97
} satisfies IMiscItem
98
];
99
addMiscItems(inventory, miscItemChanges);
100
await inventory.save();
101
return {
102
InventoryChanges: {
103
MiscItems: miscItemChanges
104
}
105
};
106
}
91
107
92
108
// Path-based duck typing
93
109
switch (typeName.substr(1).split("/")[1]) {
@@ -1,7 +1,7 @@
1
1
import { parseSlotPurchaseName } from "@/src/helpers/purchaseHelpers";
2
2
import { getSubstringFromKeyword } from "@/src/helpers/stringHelpers";
3
3
import { addItem, addBooster, updateCurrency, updateSlots } from "@/src/services/inventoryService";
4
import { IPurchaseRequest, SlotPurchase } from "@/src/types/purchaseTypes";
4
import { IPurchaseRequest, SlotPurchase, IInventoryChanges, IBinChanges } from "@/src/types/purchaseTypes";
5
5
import { logger } from "@/src/utils/logger";
6
6
import { ExportBundles, TRarity } from "warframe-public-export-plus";
7
7
@@ -46,12 +46,37 @@ export const handlePurchase = async (purchaseRequest: IPurchaseRequest, accountI
46
46
return purchaseResponse;
47
47
};
48
48
49
const addInventoryChanges = (InventoryChanges: IInventoryChanges, delta: IInventoryChanges): void => {
50
for (const key in delta) {
51
if (!(key in InventoryChanges)) {
52
InventoryChanges[key] = delta[key];
53
} else if (Array.isArray(delta[key])) {
54
const left = InventoryChanges[key] as object[];
55
const right = delta[key] as object[];
56
for (const item of right) {
57
left.push(item);
58
}
59
} else {
60
console.assert(key.substring(-3) == "Bin");
61
const left = InventoryChanges[key] as IBinChanges;
62
const right = delta[key] as IBinChanges;
63
left.count += right.count;
64
left.platinum += right.platinum;
65
left.Slots += right.Slots;
66
if (right.Extra) {
67
left.Extra ??= 0;
68
left.Extra += right.Extra;
69
}
70
}
71
}
72
};
73
49
74
const handleStoreItemAcquisition = async (
50
75
storeItemName: string,
51
76
accountId: string,
52
77
quantity: number,
53
78
durability: TRarity
54
): Promise<{ InventoryChanges: object }> => {
79
): Promise<{ InventoryChanges: IInventoryChanges }> => {
55
80
let purchaseResponse = {
56
81
InventoryChanges: {}
57
82
};
@@ -60,15 +85,17 @@ const handleStoreItemAcquisition = async (
60
85
const bundle = ExportBundles[storeItemName];
61
86
logger.debug("acquiring bundle", bundle);
62
87
for (const component of bundle.components) {
63
purchaseResponse = {
64
...purchaseResponse,
65
...(await handleStoreItemAcquisition(
66
component.typeName,
67
accountId,
68
component.purchaseQuantity,
69
component.durability
70
))
71
};
88
addInventoryChanges(
89
purchaseResponse.InventoryChanges,
90
(
91
await handleStoreItemAcquisition(
92
component.typeName,
93
accountId,
94
component.purchaseQuantity,
95
component.durability
96
)
97
).InventoryChanges
98
);
72
99
}
73
100
} else {
74
101
const storeCategory = getStoreItemCategory(storeItemName);
@@ -106,7 +133,10 @@ export const slotPurchaseNameToSlotName: SlotPurchase = {
106
133
// // new slot above base = extra + 1 and slots +1
107
134
// // new frame = slots -1
108
135
// // number of frames = extra - slots + 2
109
const handleSlotPurchase = async (slotPurchaseNameFull: string, accountId: string) => {
136
const handleSlotPurchase = async (
137
slotPurchaseNameFull: string,
138
accountId: string
139
): Promise<{ InventoryChanges: IInventoryChanges }> => {
110
140
logger.debug(`slot name ${slotPurchaseNameFull}`);
111
141
const slotPurchaseName = parseSlotPurchaseName(
112
142
slotPurchaseNameFull.substring(slotPurchaseNameFull.lastIndexOf("/") + 1)
@@ -133,7 +163,11 @@ const handleSlotPurchase = async (slotPurchaseNameFull: string, accountId: strin
133
163
};
134
164
135
165
//TODO: change to getInventory, apply changes then save at the end
136
const handleTypesPurchase = async (typesName: string, accountId: string, quantity: number) => {
166
const handleTypesPurchase = async (
167
typesName: string,
168
accountId: string,
169
quantity: number
170
): Promise<{ InventoryChanges: IInventoryChanges }> => {
137
171
const typeCategory = getStoreItemTypesCategory(typesName);
138
172
logger.debug(`type category ${typeCategory}`);
139
173
switch (typeCategory) {
@@ -158,7 +192,11 @@ const boosterDuration: Record<TRarity, number> = {
158
192
LEGENDARY: 90 * 86400
159
193
};
160
194
161
const handleBoostersPurchase = async (boosterStoreName: string, accountId: string, durability: TRarity) => {
195
const handleBoostersPurchase = async (
196
boosterStoreName: string,
197
accountId: string,
198
durability: TRarity
199
): Promise<{ InventoryChanges: IInventoryChanges }> => {
162
200
const ItemType = boosterStoreName.replace("StoreItem", "");
163
201
if (!boosterCollection.find(x => x == ItemType)) {
164
202
logger.error(`unknown booster type: ${ItemType}`);
@@ -1,6 +1,3 @@
1
import { IFlavourItem } from "@/src/types/inventoryTypes/inventoryTypes";
2
import { IEquipmentClient } from "./inventoryTypes/commonInventoryTypes";
3
4
1
export interface IPurchaseRequest {
5
2
PurchaseParams: IPurchaseParams;
6
3
buildLabel: string;
@@ -17,22 +14,7 @@ export interface IPurchaseParams {
17
14
ExpectedPrice: number;
18
15
}
19
16
20
export interface IPurchaseResponse {
21
InventoryChanges: {
22
SuitBin?: IBinChanges;
23
WeaponBin?: IBinChanges;
24
MechBin?: IBinChanges;
25
MechSuits?: IEquipmentClient[];
26
Suits?: IEquipmentClient[];
27
LongGuns?: IEquipmentClient[];
28
Pistols?: IEquipmentClient[];
29
Melee?: IEquipmentClient[];
30
PremiumCredits?: number;
31
PremiumCreditsFree?: number;
32
RegularCredits?: number;
33
FlavourItems?: IFlavourItem[];
34
};
35
}
17
export type IInventoryChanges = Record<string, IBinChanges | object[]>;
36
18
37
19
export type IBinChanges = {
38
20
count: number;