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

SpaceNinjaServer

A simple server for a small space ninja game

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

XFEstudio/SpaceNinjaServer

Purchase Loadouts and Inventory Slots (#105)

1ab411e3
OrdisPrime <134585663+OrdisPrime@users.noreply.github.com>
提交于

代码差异

15 个文件 +285 -80
Modified config.json +2 -1
@@ -7,5 +7,6 @@
7 7 "skipStoryModeChoice": true,
8 8 "skipTutorial": true,
9 9 "testMission": true,
10 "testQuestKey": true
10 "testQuestKey": true,
11 "infinitePlatinum": false
11 12 }
Modified src/controllers/api/getCreditsController.ts +24 -4
@@ -1,7 +1,27 @@
1 1 import { RequestHandler } from "express";
2 import config from "@/config.json";
3 import { getInventory } from "@/src/services/inventoryService";
4 import { parseString } from "@/src/helpers/general";
2 5
3 const getCreditsController: RequestHandler = (_req, res) => {
4 res.json({ RegularCredits: 42069, TradesRemaining: 1, PremiumCreditsFree: 42069, PremiumCredits: 42069 });
5 };
6 // eslint-disable-next-line @typescript-eslint/no-misused-promises
7 export const getCreditsController: RequestHandler = async (req, res) => {
8 if (config.infinitePlatinum) {
9 res.json({
10 RegularCredits: 999999999,
11 TradesRemaining: 999999999,
12 PremiumCreditsFree: 999999999,
13 PremiumCredits: 999999999
14 });
15 return;
16 }
17
18 const accountId = parseString(req.query.accountId);
6 19
7 export { getCreditsController };
20 const inventory = await getInventory(accountId);
21 res.json({
22 RegularCredits: inventory.RegularCredits,
23 TradesRemaining: inventory.TradesRemaining,
24 PremiumCreditsFree: inventory.PremiumCreditsFree,
25 PremiumCredits: inventory.PremiumCredits
26 });
27 };
Added src/controllers/api/inventorySlotsController.ts +36 -0
@@ -0,0 +1,36 @@
1 import { parseString } from "@/src/helpers/general";
2 import { getInventory, updateCurrency } from "@/src/services/inventoryService";
3 import { RequestHandler } from "express";
4 import { updateSlots } from "@/src/services/inventoryService";
5 import { SlotNameToInventoryName } from "@/src/types/purchaseTypes";
6
7 /*
8 loadout slots are additionally purchased slots only
9 1 slot per mastery rank is automatically given above mr10, without database needing to save the mastery slots
10 extra = everything above the base + 2 slots (e.g. for warframes)
11 new slot = extra + 1 and slots +1
12 using slot = slots -1, except for when purchased with platinum, then slots are included in price
13
14 e.g. number of frames:
15 19 slots, 71 extra
16 = 71 - 19 + 2 = 54
17 19 actually available slots in ingame inventory = 17 extra + 2 Base (base amount depends on slot) (+ 1 for every mastery rank above 10)
18 number of frames = extra - slots + 2
19 */
20
21 // eslint-disable-next-line @typescript-eslint/no-misused-promises
22 export const inventorySlotsController: RequestHandler = async (req, res) => {
23 const accountId = parseString(req.query.accountId);
24 //const body = JSON.parse(req.body as string) as IInventorySlotsRequest;
25
26 //console.log(body);
27
28 //TODO: check which slot was purchased because pvpBonus is also possible
29
30 const currencyChanges = await updateCurrency(-20, true, accountId);
31 await updateSlots(accountId, SlotNameToInventoryName.LOADOUT, 1, 1);
32
33 //console.log({ InventoryChanges: currencyChanges }, " added loadout changes:");
34
35 res.json({ InventoryChanges: currencyChanges });
36 };
Modified src/controllers/api/purchaseController.ts +1 -3
@@ -3,11 +3,9 @@ import { toPurchaseRequest } from "@/src/helpers/purchaseHelpers";
3 3 import { handlePurchase } from "@/src/services/purchaseService";
4 4 import { Request, Response } from "express";
5 5
6 const purchaseController = async (req: Request, res: Response) => {
6 export const purchaseController = async (req: Request, res: Response) => {
7 7 const purchaseRequest = toPurchaseRequest(JSON.parse(String(req.body)));
8 8 const accountId = parseString(req.query.accountId);
9 9 const response = await handlePurchase(purchaseRequest, accountId);
10 10 res.json(response);
11 11 };
12
13 export { purchaseController };
Modified src/controllers/api/saveLoadout.ts +10 -4
@@ -5,7 +5,7 @@ import { handleInventoryItemConfigChange } from "@/src/services/saveLoadoutServi
5 5 import { parseString } from "@/src/helpers/general";
6 6
7 7 // eslint-disable-next-line @typescript-eslint/no-misused-promises
8 const saveLoadoutController: RequestHandler = async (req, res) => {
8 export const saveLoadoutController: RequestHandler = async (req, res) => {
9 9 //validate here
10 10 const accountId = parseString(req.query.accountId);
11 11
@@ -15,13 +15,19 @@ const saveLoadoutController: RequestHandler = async (req, res) => {
15 15
16 16 // eslint-disable-next-line @typescript-eslint/no-unused-vars
17 17 const { UpgradeVer, ...equipmentChanges } = body;
18 await handleInventoryItemConfigChange(equipmentChanges, accountId);
18 const newLoadoutId = await handleInventoryItemConfigChange(equipmentChanges, accountId);
19
20 //send back new loadout id, if new loadout was added
21 if (newLoadoutId) {
22 res.send(newLoadoutId);
23 }
19 24 res.status(200).end();
20 25 } catch (error: unknown) {
21 26 if (error instanceof Error) {
27 console.log("error in saveLoadoutController", error.message);
22 28 res.status(400).json({ error: error.message });
29 } else {
30 res.status(400).json({ error: "unknown error" });
23 31 }
24 32 }
25 33 };
26
27 export { saveLoadoutController };
Modified src/helpers/general.ts +4 -0
@@ -1,3 +1,7 @@
1 export const isEmptyObject = (obj: unknown): boolean => {
2 return Boolean(obj && Object.keys(obj).length === 0 && obj.constructor === Object);
3 };
4
1 5 const isString = (text: unknown): text is string => {
2 6 return typeof text === "string" || text instanceof String;
3 7 };
Modified src/helpers/purchaseHelpers.ts +12 -4
@@ -1,9 +1,10 @@
1 1 import { parseBoolean, parseNumber, parseString } from "@/src/helpers/general";
2 2 import { WeaponTypeInternal } from "@/src/services/inventoryService";
3 import { IPurchaseRequest } from "@/src/types/purchaseTypes";
3 import { slotPurchaseNameToSlotName } from "@/src/services/purchaseService";
4 import { IPurchaseRequest, SlotPurchaseName } from "@/src/types/purchaseTypes";
4 5 import { weapons } from "@/static/data/items";
5 6
6 const toPurchaseRequest = (purchaseRequest: unknown): IPurchaseRequest => {
7 export const toPurchaseRequest = (purchaseRequest: unknown): IPurchaseRequest => {
7 8 if (!purchaseRequest || typeof purchaseRequest !== "object") {
8 9 throw new Error("incorrect or missing purchase request data");
9 10 }
@@ -40,7 +41,7 @@ const toPurchaseRequest = (purchaseRequest: unknown): IPurchaseRequest => {
40 41 throw new Error("invalid purchaseRequest");
41 42 };
42 43
43 const getWeaponType = (weaponName: string) => {
44 export const getWeaponType = (weaponName: string) => {
44 45 const weaponInfo = weapons.find(i => i.uniqueName === weaponName);
45 46
46 47 if (!weaponInfo) {
@@ -56,4 +57,11 @@ const getWeaponType = (weaponName: string) => {
56 57 return weaponType;
57 58 };
58 59
59 export { toPurchaseRequest, getWeaponType };
60 export const isSlotPurchaseName = (slotPurchaseName: string): slotPurchaseName is SlotPurchaseName => {
61 return slotPurchaseName in slotPurchaseNameToSlotName;
62 };
63
64 export const parseSlotPurchaseName = (slotPurchaseName: string) => {
65 if (!isSlotPurchaseName(slotPurchaseName)) throw new Error(`invalid slot name ${slotPurchaseName}`);
66 return slotPurchaseName;
67 };
Modified src/routes/api.ts +2 -0
@@ -34,6 +34,7 @@ import { artifactsController } from "../controllers/api/artifactsController";
34 34 import express from "express";
35 35 import { setBootLocationController } from "@/src/controllers/api/setBootLocationController";
36 36 import { focusController } from "@/src/controllers/api/focusController";
37 import { inventorySlotsController } from "@/src/controllers/api/inventorySlotsController";
37 38
38 39 const apiRouter = express.Router();
39 40
@@ -61,6 +62,7 @@ apiRouter.get("/logout.php", logoutController);
61 62 apiRouter.get("/setBootLocation.php", setBootLocationController);
62 63
63 64 // post
65 apiRouter.post("/inventorySlots.php", inventorySlotsController);
64 66 apiRouter.post("/focus.php", focusController);
65 67 apiRouter.post("/artifacts.php", artifactsController);
66 68 apiRouter.post("/findSessions.php", findSessionsController);
Modified src/services/inventoryService.ts +44 -24
@@ -2,9 +2,9 @@ import { Inventory } from "@/src/models/inventoryModels/inventoryModel";
2 2 import new_inventory from "@/static/fixed_responses/postTutorialInventory.json";
3 3 import config from "@/config.json";
4 4 import { Types } from "mongoose";
5 import { ISuitDatabase, ISuitClient } from "@/src/types/inventoryTypes/SuitTypes";
6 import { SlotType } from "@/src/types/purchaseTypes";
7 import { IWeaponDatabase, IWeaponClient } from "@/src/types/inventoryTypes/weaponTypes";
5 import { ISuitClient } from "@/src/types/inventoryTypes/SuitTypes";
6 import { SlotNames } from "@/src/types/purchaseTypes";
7 import { IWeaponClient } from "@/src/types/inventoryTypes/weaponTypes";
8 8 import {
9 9 IChallengeProgress,
10 10 IConsumable,
@@ -41,8 +41,6 @@ export const createInventory = async (accountOwnerId: Types.ObjectId, loadOutPre
41 41 }
42 42 };
43 43
44 //const updateInventory = async (accountOwnerId: Types.ObjectId, inventoryChanges: any) => {};
45
46 44 export const getInventory = async (accountOwnerId: string) => {
47 45 const inventory = await Inventory.findOne({ accountOwnerId: accountOwnerId });
48 46
@@ -53,7 +51,7 @@ export const getInventory = async (accountOwnerId: string) => {
53 51 return inventory;
54 52 };
55 53
56 //TODO: genericMethod for all the add methods, they share a lot of logic
54 //TODO: maybe genericMethod for all the add methods, they share a lot of logic
57 55 export const addSentinel = async (sentinelName: string, accountId: string) => {
58 56 const inventory = await getInventory(accountId);
59 57 const sentinelIndex = inventory.Sentinels.push({ ItemType: sentinelName, Configs: [], XP: 0 });
@@ -75,32 +73,54 @@ export const addMechSuit = async (mechsuitName: string, accountId: string) => {
75 73 return changedInventory.MechSuits[suitIndex - 1].toJSON();
76 74 };
77 75
78 export const updateSlots = async (slotType: SlotType, accountId: string, slots: number) => {
76 export const updateSlots = async (accountId: string, slotName: SlotNames, slotAmount: number, extraAmount: number) => {
79 77 const inventory = await getInventory(accountId);
80 78
81 switch (slotType) {
82 case SlotType.SUIT:
83 inventory.SuitBin.Slots += slots;
84 break;
85 case SlotType.WEAPON:
86 inventory.WeaponBin.Slots += slots;
87 break;
88 case SlotType.MECHSUIT:
89 inventory.MechBin.Slots += slots;
90 break;
91 default:
92 throw new Error("invalid slot type");
79 inventory[slotName].Slots += slotAmount;
80 if (inventory[slotName].Extra === undefined) {
81 inventory[slotName].Extra = extraAmount;
82 } else {
83 inventory[slotName].Extra += extraAmount;
93 84 }
85
94 86 await inventory.save();
95 87 };
96 88
97 89 export const updateCurrency = async (price: number, usePremium: boolean, accountId: string) => {
98 const currencyName = usePremium ? "PremiumCredits" : "RegularCredits";
99
100 90 const inventory = await getInventory(accountId);
101 inventory[currencyName] = inventory[currencyName] - price;
91
92 if (usePremium) {
93 if (inventory.PremiumCreditsFree > 0) {
94 inventory.PremiumCreditsFree += price;
95 }
96 inventory.PremiumCredits += price;
97 } else {
98 inventory.RegularCredits += price;
99 }
100
101 const modifiedPaths = inventory.modifiedPaths();
102
103 type currencyKeys = "RegularCredits" | "PremiumCredits" | "PremiumCreditsFree";
104
105 const currencyChanges = {} as Record<currencyKeys, number>;
106 modifiedPaths.forEach(path => {
107 currencyChanges[path as currencyKeys] = -price;
108 });
109
110 console.log(currencyChanges, "changes");
111
112 //let changes = {} as keyof currencyKeys;
113
114 // const obj2 = modifiedPaths.reduce(
115 // (obj, key) => {
116 // obj[key as keyof currencyKeys] = price;
117 // return obj;
118 // },
119 // {} as Record<keyof currencyKeys, number>
120 // );
121
102 122 await inventory.save();
103 return { [currencyName]: -price };
123 return currencyChanges;
104 124 };
105 125
106 126 // TODO: AffiliationMods support (Nightwave).
@@ -157,7 +177,7 @@ export const addCustomization = async (customizatonName: string, accountId: stri
157 177
158 178 const flavourItemIndex = inventory.FlavourItems.push({ ItemType: customizatonName }) - 1;
159 179 const changedInventory = await inventory.save();
160 return changedInventory.FlavourItems[flavourItemIndex].toJSON(); //mongoose bug forces as FlavourItem
180 return changedInventory.FlavourItems[flavourItemIndex].toJSON();
161 181 };
162 182
163 183 const addGearExpByCategory = (
Modified src/services/purchaseService.ts +80 -22
@@ -1,4 +1,4 @@
1 import { getWeaponType } from "@/src/helpers/purchaseHelpers";
1 import { getWeaponType, parseSlotPurchaseName } from "@/src/helpers/purchaseHelpers";
2 2 import { getSubstringFromKeyword } from "@/src/helpers/stringHelpers";
3 3 import {
4 4 addBooster,
@@ -7,9 +7,10 @@ import {
7 7 addPowerSuit,
8 8 addSentinel,
9 9 addWeapon,
10 updateCurrency,
10 11 updateSlots
11 12 } from "@/src/services/inventoryService";
12 import { IPurchaseRequest, SlotType } from "@/src/types/purchaseTypes";
13 import { IPurchaseRequest, IPurchaseResponse, SlotNameToInventoryName, SlotPurchase } from "@/src/types/purchaseTypes";
13 14
14 15 export const getStoreItemCategory = (storeItem: string) => {
15 16 const storeItemString = getSubstringFromKeyword(storeItem, "StoreItems/");
@@ -32,57 +33,109 @@ export const handlePurchase = async (purchaseRequest: IPurchaseRequest, accountI
32 33 const internalName = purchaseRequest.PurchaseParams.StoreItem.replace("/StoreItems", "");
33 34 console.log("Store category", storeCategory);
34 35
35 let purchaseResponse;
36 let inventoryChanges;
36 37 switch (storeCategory) {
37 38 case "Powersuits":
38 purchaseResponse = await handlePowersuitPurchase(internalName, accountId);
39 inventoryChanges = await handlePowersuitPurchase(internalName, accountId);
39 40 break;
40 41 case "Weapons":
41 purchaseResponse = await handleWeaponsPurchase(internalName, accountId);
42 inventoryChanges = await handleWeaponsPurchase(internalName, accountId);
42 43 break;
43 44 case "Types":
44 purchaseResponse = await handleTypesPurchase(internalName, accountId);
45 inventoryChanges = await handleTypesPurchase(internalName, accountId);
45 46 break;
46 47 case "Boosters":
47 purchaseResponse = await handleBoostersPurchase(internalName, accountId);
48 inventoryChanges = await handleBoostersPurchase(internalName, accountId);
48 49 break;
49 50
50 51 default:
51 52 throw new Error(`unknown store category: ${storeCategory} not implemented or new`);
52 53 }
53 54
54 // const currencyResponse = await updateCurrency(
55 // purchaseRequest.PurchaseParams.ExpectedPrice,
56 // purchaseRequest.PurchaseParams.UsePremium,
57 // accountId
58 // );
55 if (!inventoryChanges) throw new Error("purchase response was undefined");
59 56
60 // (purchaseResponse as IPurchaseResponse).InventoryChanges = {
61 // ...purchaseResponse.InventoryChanges,
62 // ...currencyResponse
63 // };
57 const currencyChanges = await updateCurrency(
58 purchaseRequest.PurchaseParams.ExpectedPrice,
59 purchaseRequest.PurchaseParams.UsePremium,
60 accountId
61 );
64 62
65 return purchaseResponse;
63 inventoryChanges.InventoryChanges = {
64 ...currencyChanges,
65 ...inventoryChanges.InventoryChanges
66 };
67
68 return inventoryChanges;
69 };
70
71 export const slotPurchaseNameToSlotName: SlotPurchase = {
72 SuitSlotItem: { name: "SuitBin", slotsPerPurchase: 1 },
73 TwoSentinelSlotItem: { name: "SentinelBin", slotsPerPurchase: 2 },
74 TwoWeaponSlotItem: { name: "WeaponBin", slotsPerPurchase: 2 },
75 SpaceSuitSlotItem: { name: "SpaceSuitBin", slotsPerPurchase: 1 },
76 TwoSpaceWeaponSlotItem: { name: "SpaceWeaponBin", slotsPerPurchase: 2 },
77 MechSlotItem: { name: "MechBin", slotsPerPurchase: 1 },
78 TwoOperatorWeaponSlotItem: { name: "OperatorAmpBin", slotsPerPurchase: 2 },
79 RandomModSlotItem: { name: "RandomModBin", slotsPerPurchase: 3 },
80 TwoCrewShipSalvageSlotItem: { name: "CrewShipSalvageBin", slotsPerPurchase: 2 },
81 CrewMemberSlotItem: { name: "CrewMemberBin", slotsPerPurchase: 1 }
82 };
83
84 // // extra = everything above the base +2 slots (depending on slot type)
85 // // new slot above base = extra + 1 and slots +1
86 // // new frame = slots -1
87 // // number of frames = extra - slots + 2
88 const handleSlotPurchase = async (slotPurchaseNameFull: string, accountId: string) => {
89 console.log("slot name", slotPurchaseNameFull);
90 const slotPurchaseName = parseSlotPurchaseName(
91 slotPurchaseNameFull.substring(slotPurchaseNameFull.lastIndexOf("/") + 1)
92 );
93 console.log(slotPurchaseName, "slot purchase name");
94
95 await updateSlots(
96 accountId,
97 slotPurchaseNameToSlotName[slotPurchaseName].name,
98 slotPurchaseNameToSlotName[slotPurchaseName].slotsPerPurchase,
99 slotPurchaseNameToSlotName[slotPurchaseName].slotsPerPurchase
100 );
101
102 console.log(
103 slotPurchaseNameToSlotName[slotPurchaseName].name,
104 slotPurchaseNameToSlotName[slotPurchaseName].slotsPerPurchase,
105 "slots added"
106 );
107
108 return {
109 InventoryChanges: {
110 [slotPurchaseNameToSlotName[slotPurchaseName].name]: {
111 count: 0,
112 platinum: 1,
113 Slots: slotPurchaseNameToSlotName[slotPurchaseName].slotsPerPurchase,
114 Extra: slotPurchaseNameToSlotName[slotPurchaseName].slotsPerPurchase
115 }
116 }
117 };
66 118 };
67 119
68 120 const handleWeaponsPurchase = async (weaponName: string, accountId: string) => {
69 121 const weaponType = getWeaponType(weaponName);
70 122 const addedWeapon = await addWeapon(weaponType, weaponName, accountId);
71 123
72 await updateSlots(SlotType.WEAPON, accountId, -1);
124 await updateSlots(accountId, SlotNameToInventoryName.WEAPON, 0, 1);
73 125
74 126 return {
75 127 InventoryChanges: {
76 128 WeaponBin: { count: 1, platinum: 0, Slots: -1 },
77 129 [weaponType]: [addedWeapon]
78 130 }
79 };
131 } as IPurchaseResponse;
80 132 };
81 133
82 134 const handlePowersuitPurchase = async (powersuitName: string, accountId: string) => {
83 135 if (powersuitName.includes("EntratiMech")) {
84 136 const mechSuit = await addMechSuit(powersuitName, accountId);
85 await updateSlots(SlotType.MECHSUIT, accountId, -1);
137
138 await updateSlots(accountId, SlotNameToInventoryName.MECHSUIT, 0, 1);
86 139 console.log("mech suit", mechSuit);
87 140
88 141 return {
@@ -94,11 +147,11 @@ const handlePowersuitPurchase = async (powersuitName: string, accountId: string)
94 147 },
95 148 MechSuits: [mechSuit]
96 149 }
97 };
150 } as IPurchaseResponse;
98 151 }
99 152
100 153 const suit = await addPowerSuit(powersuitName, accountId);
101 await updateSlots(SlotType.SUIT, accountId, -1);
154 await updateSlots(accountId, SlotNameToInventoryName.SUIT, 0, 1);
102 155
103 156 return {
104 157 InventoryChanges: {
@@ -112,6 +165,7 @@ const handlePowersuitPurchase = async (powersuitName: string, accountId: string)
112 165 };
113 166 };
114 167
168 //TODO: change to getInventory, apply changes then save at the end
115 169 const handleTypesPurchase = async (typesName: string, accountId: string) => {
116 170 const typeCategory = getStoreItemTypesCategory(typesName);
117 171 console.log("type category", typeCategory);
@@ -122,6 +176,8 @@ const handleTypesPurchase = async (typesName: string, accountId: string) => {
122 176 // break;
123 177 case "Sentinels":
124 178 return await handleSentinelPurchase(typesName, accountId);
179 case "SlotItems":
180 return await handleSlotPurchase(typesName, accountId);
125 181 default:
126 182 throw new Error(`unknown Types category: ${typeCategory} not implemented or new`);
127 183 }
@@ -130,6 +186,8 @@ const handleTypesPurchase = async (typesName: string, accountId: string) => {
130 186 const handleSentinelPurchase = async (sentinelName: string, accountId: string) => {
131 187 const sentinel = await addSentinel(sentinelName, accountId);
132 188
189 await updateSlots(accountId, SlotNameToInventoryName.SENTINEL, 0, 1);
190
133 191 return {
134 192 InventoryChanges: {
135 193 SentinelBin: { count: 1, platinum: 0, Slots: -1 },
Modified src/services/saveLoadoutService.ts +22 -8
@@ -8,10 +8,8 @@ import {
8 8 import { LoadoutModel } from "@/src/models/inventoryModels/loadoutModel";
9 9 import { getInventory } from "@/src/services/inventoryService";
10 10 import { IOid } from "@/src/types/commonTypes";
11
12 export const isEmptyObject = (obj: unknown): boolean => {
13 return Boolean(obj && Object.keys(obj).length === 0 && obj.constructor === Object);
14 };
11 import { Types } from "mongoose";
12 import { isEmptyObject } from "@/src/helpers/general";
15 13
16 14 //TODO: setup default items on account creation or like originally in giveStartingItems.php
17 15
@@ -24,7 +22,7 @@ itemconfig has multiple config ids
24 22 export const handleInventoryItemConfigChange = async (
25 23 equipmentChanges: ISaveLoadoutRequestNoUpgradeVer,
26 24 accountId: string
27 ) => {
25 ): Promise<string | void> => {
28 26 const inventory = await getInventory(accountId);
29 27
30 28 for (const [_equipmentName, _equipment] of Object.entries(equipmentChanges)) {
@@ -40,7 +38,7 @@ export const handleInventoryItemConfigChange = async (
40 38 case "AdultOperatorLoadOuts": {
41 39 const operatorConfig = equipment as IOperatorConfigEntry;
42 40 const operatorLoadout = inventory[equipmentName];
43 //console.log("loadout received", equipmentName, operatorConfig);
41 console.log("operator loadout received", equipmentName, operatorConfig);
44 42 // all non-empty entries are one loadout slot
45 43 for (const [loadoutId, loadoutConfig] of Object.entries(operatorConfig)) {
46 44 // console.log("loadoutId", loadoutId, "loadoutconfig", loadoutConfig);
@@ -60,12 +58,13 @@ export const handleInventoryItemConfigChange = async (
60 58 break;
61 59 }
62 60 case "LoadOuts": {
63 //console.log("loadout received");
61 console.log("loadout received");
64 62 const loadout = await LoadoutModel.findOne({ loadoutOwnerId: accountId });
65 63 if (!loadout) {
66 64 throw new Error("loadout not found");
67 65 }
68 66
67 let newLoadoutId: Types.ObjectId | undefined;
69 68 for (const [_loadoutSlot, _loadout] of Object.entries(equipment)) {
70 69 const loadoutSlot = _loadoutSlot as keyof ILoadoutClient;
71 70 const newLoadout = _loadout as ILoadoutEntry;
@@ -84,6 +83,16 @@ export const handleInventoryItemConfigChange = async (
84 83 // if no config with this id exists, create a new one
85 84 if (!oldLoadoutConfig) {
86 85 const { ItemId, ...loadoutConfigItemIdRemoved } = loadoutConfig;
86
87 //save the new object id and assign it for every ffff return at the end
88 if (ItemId.$oid === "ffffffffffffffffffffffff") {
89 if (!newLoadoutId) {
90 newLoadoutId = new Types.ObjectId();
91 }
92 loadout[loadoutSlot].push({ _id: newLoadoutId, ...loadoutConfigItemIdRemoved });
93 continue;
94 }
95
87 96 loadout[loadoutSlot].push({
88 97 _id: ItemId.$oid,
89 98 ...loadoutConfigItemIdRemoved
@@ -101,6 +110,11 @@ export const handleInventoryItemConfigChange = async (
101 110 }
102 111 }
103 112 await loadout.save();
113
114 //only return an id if a new loadout was added
115 if (newLoadoutId) {
116 return newLoadoutId.toString();
117 }
104 118 break;
105 119 }
106 120 case "LongGuns":
@@ -112,7 +126,7 @@ export const handleInventoryItemConfigChange = async (
112 126 case "DrifterMelee":
113 127 case "Sentinels":
114 128 case "Horses": {
115 //console.log("general Item config saved", equipmentName, equipment);
129 console.log("general Item config saved", equipmentName, equipment);
116 130
117 131 const itemEntries = equipment as IItemEntry;
118 132 for (const [itemId, itemConfigEntries] of Object.entries(itemEntries)) {
Modified src/types/inventoryTypes/SuitTypes.ts +1 -1
@@ -3,7 +3,7 @@ import { IPolarity } from "@/src/types/inventoryTypes/commonInventoryTypes";
3 3 import { Types } from "mongoose";
4 4 import { IItemConfig } from "./commonInventoryTypes";
5 5
6 export interface ISuitClient extends ISuitDatabase {
6 export interface ISuitClient extends Omit<ISuitDatabase, "_id"> {
7 7 ItemId: IOid;
8 8 }
9 9
Modified src/types/inventoryTypes/inventoryTypes.ts +1 -1
Modified src/types/purchaseTypes.ts +40 -4
Modified src/types/requestTypes.ts +6 -4