From e7245bbb68267986cca6d2de6789ee9d6bc7ff39 Mon Sep 17 00:00:00 2001 From: Ordis <134585663+OrdisPrime@users.noreply.github.com> Date: Wed, 22 Nov 2023 16:09:32 +0100 Subject: [PATCH 01/11] typescript hates me --- src/controllers/api/inventoryController.ts | 1 + src/controllers/api/saveLoadout.ts | 50 ++++++++- src/helpers/general.ts | 8 ++ src/types/inventoryTypes/SuitTypes.ts | 1 + src/types/inventoryTypes/inventoryTypes.ts | 1 + src/types/saveLoadoutTypes.ts | 114 +++++++++++++++++++++ 6 files changed, 172 insertions(+), 3 deletions(-) create mode 100644 src/types/saveLoadoutTypes.ts diff --git a/src/controllers/api/inventoryController.ts b/src/controllers/api/inventoryController.ts index 078532dc..bada9ab7 100644 --- a/src/controllers/api/inventoryController.ts +++ b/src/controllers/api/inventoryController.ts @@ -28,6 +28,7 @@ const inventoryController: RequestHandler = async (request: Request, response: R if (config.testMission) inventoryResponse.Missions = testMissions; if (config.testQuestKey) inventoryResponse.QuestKeys = testQuestKeys; + inventoryResponse.DuviriInfo = { Seed: -5049874987509758080, NumCompletions: 0 }; response.json(inventoryResponse); }; diff --git a/src/controllers/api/saveLoadout.ts b/src/controllers/api/saveLoadout.ts index b83ad6b1..ec44ce4e 100644 --- a/src/controllers/api/saveLoadout.ts +++ b/src/controllers/api/saveLoadout.ts @@ -1,13 +1,57 @@ import { Inventory } from "@/src/models/inventoryModel"; import { RequestHandler } from "express"; import util from "util"; +import { EquipmentCategories, ISaveLoadoutRequest } from "@/src/types/saveLoadoutTypes"; +import { isObject } from "@/src/helpers/general"; +import { ISuitResponse } from "@/src/types/inventoryTypes/SuitTypes"; + +export const isObjectEmpty = (obj: Record) => { + return obj && Object.keys(obj).length === 0 && obj.constructor === Object; +}; + +export const handleInventoryItemConfigChange = (equipmentChanges: ISaveLoadoutRequest) => { + for (const [equipmentName, equipment] of Object.entries(equipmentChanges)) { + //console.log(equipmentName); + if (!isObjectEmpty(equipment)) { + // non-empty is a change in loadout(or suit...) + + switch (equipmentName) { + case "LoadOuts": { + console.log("loadout received"); + for (const [loadoutName, loadout] of Object.entries(equipment)) { + console.log(loadoutName, loadout); + //if (!isObjectEmpty(loadout)) + } + break; + } + default: + console.log("category not implemented", equipmentName); + } + // Object.keys(value).forEach(element => { + // console.log("name of inner objects keys", element); + // }); + // for (const innerValue of Object.values(value)) { + // console.log(innerValue); + // } + } + + // console.log(innerObjects); + // if (isObjectEmpty(innerObjects)) { + // console.log(innerObjects, "is empty"); + // } + } +}; // eslint-disable-next-line @typescript-eslint/no-misused-promises const saveLoadoutController: RequestHandler = async (req, res) => { - const body = JSON.parse(req.body); - console.log(util.inspect(body, { showHidden: false, depth: null, colors: true })); + //validate here + const body: ISaveLoadoutRequest = JSON.parse(req.body as string) as ISaveLoadoutRequest; + // console.log(util.inspect(body, { showHidden: false, depth: null, colors: true })); - res.sendStatus(200); + const { UpgradeVer, ...equipmentChanges } = body; + handleInventoryItemConfigChange(body); + + res.status(200).end(); }; export { saveLoadoutController }; diff --git a/src/helpers/general.ts b/src/helpers/general.ts index 8aa19a1a..cc13e4ec 100644 --- a/src/helpers/general.ts +++ b/src/helpers/general.ts @@ -55,4 +55,12 @@ const parseBoolean = (booleanCandidate: unknown): boolean => { return booleanCandidate; }; +export const isObject = (objectCandidate: unknown): objectCandidate is Record => { + return ( + (typeof objectCandidate === "object" || objectCandidate instanceof Object) && + objectCandidate !== null && + !Array.isArray(objectCandidate) + ); +}; + export { isString, isNumber, parseString, parseNumber, parseDateNumber, parseBoolean, parseEmail }; diff --git a/src/types/inventoryTypes/SuitTypes.ts b/src/types/inventoryTypes/SuitTypes.ts index 7e1f6825..dc71db19 100644 --- a/src/types/inventoryTypes/SuitTypes.ts +++ b/src/types/inventoryTypes/SuitTypes.ts @@ -9,6 +9,7 @@ export interface ISuitDocument extends Document, ISuitResponse { export interface ISuitResponse extends ISuitDatabase { ItemId: IOid; + //should omit _id which is not present in response } export interface ISuitDatabase { diff --git a/src/types/inventoryTypes/inventoryTypes.ts b/src/types/inventoryTypes/inventoryTypes.ts index 760b8659..450b6e10 100644 --- a/src/types/inventoryTypes/inventoryTypes.ts +++ b/src/types/inventoryTypes/inventoryTypes.ts @@ -14,6 +14,7 @@ export interface IInventoryDatabase extends Omit Date: Wed, 22 Nov 2023 09:42:26 -0600 Subject: [PATCH 02/11] improve some types --- .gitignore | 5 ++- .nvmrc | 1 + src/controllers/api/saveLoadout.ts | 12 +++++-- src/types/saveLoadoutTypes.ts | 57 +++++++++++++++++------------- 4 files changed, 47 insertions(+), 28 deletions(-) create mode 100644 .nvmrc diff --git a/.gitignore b/.gitignore index 70556674..23c4cd81 100644 --- a/.gitignore +++ b/.gitignore @@ -4,4 +4,7 @@ /.env /static/data/*.bin yarn.lock -/tmp \ No newline at end of file +/tmp + +# JetBrains/webstorm configs +.idea/ diff --git a/.nvmrc b/.nvmrc new file mode 100644 index 00000000..9de22568 --- /dev/null +++ b/.nvmrc @@ -0,0 +1 @@ +lts/iron diff --git a/src/controllers/api/saveLoadout.ts b/src/controllers/api/saveLoadout.ts index ec44ce4e..9be69fb6 100644 --- a/src/controllers/api/saveLoadout.ts +++ b/src/controllers/api/saveLoadout.ts @@ -1,7 +1,12 @@ import { Inventory } from "@/src/models/inventoryModel"; import { RequestHandler } from "express"; import util from "util"; -import { EquipmentCategories, ISaveLoadoutRequest } from "@/src/types/saveLoadoutTypes"; +import { + EquipmentCategories, + ISaveLoadoutEntry, + ISaveLoadoutLoadoutEntry, + ISaveLoadoutRequest +} from "@/src/types/saveLoadoutTypes"; import { isObject } from "@/src/helpers/general"; import { ISuitResponse } from "@/src/types/inventoryTypes/SuitTypes"; @@ -9,8 +14,11 @@ export const isObjectEmpty = (obj: Record) => { return obj && Object.keys(obj).length === 0 && obj.constructor === Object; }; +type EquipmentChangeEntry = number | ISaveLoadoutEntry | ISaveLoadoutLoadoutEntry; + export const handleInventoryItemConfigChange = (equipmentChanges: ISaveLoadoutRequest) => { - for (const [equipmentName, equipment] of Object.entries(equipmentChanges)) { + for (const [equipmentName, eqp] of Object.entries(equipmentChanges)) { + const equipment = eqp as EquipmentChangeEntry; //console.log(equipmentName); if (!isObjectEmpty(equipment)) { // non-empty is a change in loadout(or suit...) diff --git a/src/types/saveLoadoutTypes.ts b/src/types/saveLoadoutTypes.ts index ccac66e9..bf2c9d1b 100644 --- a/src/types/saveLoadoutTypes.ts +++ b/src/types/saveLoadoutTypes.ts @@ -1,30 +1,37 @@ export interface ISaveLoadoutRequest { - LoadOuts: { [key: string]: LoadOut }; - LongGuns: { [key: string]: Config }; - OperatorAmps: { [key: string]: Config }; - Pistols: { [key: string]: Config }; - Suits: { [key: string]: Config }; - Melee: {}; - Sentinels: {}; - SentinelWeapons: {}; - KubrowPets: {}; - SpaceSuits: {}; - SpaceGuns: {}; - SpaceMelee: {}; - Scoops: {}; - SpecialItems: {}; - MoaPets: {}; - Hoverboards: {}; - DataKnives: {}; - MechSuits: {}; - CrewShipHarnesses: {}; - Horses: {}; - DrifterMelee: {}; + LoadOuts: ISaveLoadoutLoadoutEntry; + LongGuns: ISaveLoadoutEntry; + OperatorAmps: ISaveLoadoutEntry; + Pistols: ISaveLoadoutEntry; + Suits: ISaveLoadoutEntry; + Melee: ISaveLoadoutEntry; + Sentinels: ISaveLoadoutEntry; + SentinelWeapons: ISaveLoadoutEntry; + KubrowPets: ISaveLoadoutEntry; + SpaceSuits: ISaveLoadoutEntry; + SpaceGuns: ISaveLoadoutEntry; + SpaceMelee: ISaveLoadoutEntry; + Scoops: ISaveLoadoutEntry; + SpecialItems: ISaveLoadoutEntry; + MoaPets: ISaveLoadoutEntry; + Hoverboards: ISaveLoadoutEntry; + DataKnives: ISaveLoadoutEntry; + MechSuits: ISaveLoadoutEntry; + CrewShipHarnesses: ISaveLoadoutEntry; + Horses: ISaveLoadoutEntry; + DrifterMelee: ISaveLoadoutEntry; UpgradeVer: number; - OperatorLoadOuts: {}; - AdultOperatorLoadOuts: {}; - KahlLoadOuts: {}; - CrewShips: {}; + OperatorLoadOuts: ISaveLoadoutEntry; + AdultOperatorLoadOuts: ISaveLoadoutEntry; + KahlLoadOuts: ISaveLoadoutEntry; + CrewShips: ISaveLoadoutEntry; +} + +export interface ISaveLoadoutEntry { + [key: string]: Config; +} +export interface ISaveLoadoutLoadoutEntry { + [key: string]: LoadOut; } export interface Config { -- 2.47.2 From 8df3030953ffc963705f59252a6ef3cf4c6c1128 Mon Sep 17 00:00:00 2001 From: Ordis <134585663+OrdisPrime@users.noreply.github.com> Date: Thu, 23 Nov 2023 16:57:03 +0100 Subject: [PATCH 03/11] god TS sucks. --- src/controllers/api/saveLoadout.ts | 100 ++++++++++++++++-------- src/types/saveLoadoutTypes.ts | 121 +++++++++++++++-------------- 2 files changed, 133 insertions(+), 88 deletions(-) diff --git a/src/controllers/api/saveLoadout.ts b/src/controllers/api/saveLoadout.ts index 9be69fb6..6d21715e 100644 --- a/src/controllers/api/saveLoadout.ts +++ b/src/controllers/api/saveLoadout.ts @@ -3,45 +3,83 @@ import { RequestHandler } from "express"; import util from "util"; import { EquipmentCategories, - ISaveLoadoutEntry, - ISaveLoadoutLoadoutEntry, - ISaveLoadoutRequest + IConfigEntry, + ILoadout, + ISaveLoadoutRequest, + ISaveLoadoutRequestNoUpgradeVer } from "@/src/types/saveLoadoutTypes"; -import { isObject } from "@/src/helpers/general"; -import { ISuitResponse } from "@/src/types/inventoryTypes/SuitTypes"; export const isObjectEmpty = (obj: Record) => { return obj && Object.keys(obj).length === 0 && obj.constructor === Object; }; -type EquipmentChangeEntry = number | ISaveLoadoutEntry | ISaveLoadoutLoadoutEntry; +type EquipmentChangeEntry = IConfigEntry | ILoadout; -export const handleInventoryItemConfigChange = (equipmentChanges: ISaveLoadoutRequest) => { - for (const [equipmentName, eqp] of Object.entries(equipmentChanges)) { - const equipment = eqp as EquipmentChangeEntry; - //console.log(equipmentName); - if (!isObjectEmpty(equipment)) { - // non-empty is a change in loadout(or suit...) +export const handleInventoryItemConfigChange = (equipmentChanges: ISaveLoadoutRequestNoUpgradeVer) => { + for (const [_equipmentName, _equipment] of Object.entries(equipmentChanges)) { + const equipment = _equipment as ISaveLoadoutRequestNoUpgradeVer[keyof ISaveLoadoutRequestNoUpgradeVer]; + const equipmentName = _equipmentName as keyof ISaveLoadoutRequestNoUpgradeVer; - switch (equipmentName) { - case "LoadOuts": { - console.log("loadout received"); - for (const [loadoutName, loadout] of Object.entries(equipment)) { - console.log(loadoutName, loadout); - //if (!isObjectEmpty(loadout)) - } - break; - } - default: - console.log("category not implemented", equipmentName); - } - // Object.keys(value).forEach(element => { - // console.log("name of inner objects keys", element); - // }); - // for (const innerValue of Object.values(value)) { - // console.log(innerValue); - // } + if (isObjectEmpty(equipment)) { + continue; } + // non-empty is a change in loadout(or suit...) + + switch (equipmentName) { + case "LoadOuts": { + console.log("loadout received"); + const _loadout = equipment as unknown as ILoadout; + + for (const [loadoutName, loadout] of Object.entries(_loadout)) { + console.log(loadoutName, loadout); + //const loadout = _loadout as ILoadoutEntry; + + // console.log(loadoutName, loadout); + // if (isObjectEmpty(loadout)) { + // continue; + // } + } + break; + } + case "LongGuns": { + const longGun = equipment as IConfigEntry; + // longGun["key"].PvpUpgrades; + break; + } + case "OperatorAmps": + case "Pistols": + case "Suits": + case "Melee": + case "Sentinels": + case "SentinelWeapons": + case "KubrowPets": + case "SpaceSuits": + case "SpaceGuns": + case "SpaceMelee": + case "Scoops": + case "SpecialItems": + case "MoaPets": + case "Hoverboards": + case "DataKnives": + case "MechSuits": + case "CrewShipHarnesses": + case "Horses": + case "DrifterMelee": + case "OperatorLoadOuts": + case "AdultOperatorLoadOuts": + case "KahlLoadOuts": + case "CrewShips": + + default: { + console.log("category not implemented", equipmentName); + } + } + // Object.keys(value).forEach(element => { + // console.log("name of inner objects keys", element); + // }); + // for (const innerValue of Object.values(value)) { + // console.log(innerValue); + // } // console.log(innerObjects); // if (isObjectEmpty(innerObjects)) { @@ -57,7 +95,7 @@ const saveLoadoutController: RequestHandler = async (req, res) => { // console.log(util.inspect(body, { showHidden: false, depth: null, colors: true })); const { UpgradeVer, ...equipmentChanges } = body; - handleInventoryItemConfigChange(body); + handleInventoryItemConfigChange(equipmentChanges); res.status(200).end(); }; diff --git a/src/types/saveLoadoutTypes.ts b/src/types/saveLoadoutTypes.ts index bf2c9d1b..4dba7f50 100644 --- a/src/types/saveLoadoutTypes.ts +++ b/src/types/saveLoadoutTypes.ts @@ -1,37 +1,72 @@ +import { IOid } from "@/src/types/commonTypes"; + export interface ISaveLoadoutRequest { - LoadOuts: ISaveLoadoutLoadoutEntry; - LongGuns: ISaveLoadoutEntry; - OperatorAmps: ISaveLoadoutEntry; - Pistols: ISaveLoadoutEntry; - Suits: ISaveLoadoutEntry; - Melee: ISaveLoadoutEntry; - Sentinels: ISaveLoadoutEntry; - SentinelWeapons: ISaveLoadoutEntry; - KubrowPets: ISaveLoadoutEntry; - SpaceSuits: ISaveLoadoutEntry; - SpaceGuns: ISaveLoadoutEntry; - SpaceMelee: ISaveLoadoutEntry; - Scoops: ISaveLoadoutEntry; - SpecialItems: ISaveLoadoutEntry; - MoaPets: ISaveLoadoutEntry; - Hoverboards: ISaveLoadoutEntry; - DataKnives: ISaveLoadoutEntry; - MechSuits: ISaveLoadoutEntry; - CrewShipHarnesses: ISaveLoadoutEntry; - Horses: ISaveLoadoutEntry; - DrifterMelee: ISaveLoadoutEntry; + LoadOuts: ILoadout; + LongGuns: IConfigEntry; + OperatorAmps: IConfigEntry; + Pistols: IConfigEntry; + Suits: IConfigEntry; + Melee: IConfigEntry; + Sentinels: IConfigEntry; + SentinelWeapons: IConfigEntry; + KubrowPets: IConfigEntry; + SpaceSuits: IConfigEntry; + SpaceGuns: IConfigEntry; + SpaceMelee: IConfigEntry; + Scoops: IConfigEntry; + SpecialItems: IConfigEntry; + MoaPets: IConfigEntry; + Hoverboards: IConfigEntry; + DataKnives: IConfigEntry; + MechSuits: IConfigEntry; + CrewShipHarnesses: IConfigEntry; + Horses: IConfigEntry; + DrifterMelee: IConfigEntry; UpgradeVer: number; - OperatorLoadOuts: ISaveLoadoutEntry; - AdultOperatorLoadOuts: ISaveLoadoutEntry; - KahlLoadOuts: ISaveLoadoutEntry; - CrewShips: ISaveLoadoutEntry; + OperatorLoadOuts: IConfigEntry; + AdultOperatorLoadOuts: IConfigEntry; + KahlLoadOuts: IConfigEntry; + CrewShips: IConfigEntry; } -export interface ISaveLoadoutEntry { +export interface ISaveLoadoutRequestNoUpgradeVer extends Omit {} + +export interface IConfigEntry { [key: string]: Config; } -export interface ISaveLoadoutLoadoutEntry { - [key: string]: LoadOut; + +export interface ILoadout { + NORMAL: ILoadoutKey; + SENTINEL: ILoadoutKey; + ARCHWING: ILoadoutKey; + NORMAL_PVP: ILoadoutKey; + LUNARO: ILoadoutKey; + OPERATOR: ILoadoutKey; + KDRIVE: ILoadoutKey; + DATAKNIFE: ILoadoutKey; + MECH: ILoadoutKey; + OPERATOR_ADULT: ILoadoutKey; + DRIFTER: ILoadoutKey; +} + +export interface ILoadoutKey { + [key: string]: ItemConfig; +} + +export interface ItemConfig { + ItemId: IOid; + PresetIcon: string; + Favorite: boolean; + s: M; + p: M; + l: M; + m: M; +} + +export interface M { + ItemId: IOid; + mod: number; + cus: number; } export interface Config { @@ -76,36 +111,8 @@ export interface Col { e1?: number; } -export interface LoadOuts { - NORMAL: LoadOut; - SENTINEL: LoadOut; - ARCHWING: LoadOut; - NORMAL_PVP: LoadOut; - LUNARO: LoadOut; - OPERATOR: LoadOut; - KDRIVE: LoadOut; - DATAKNIFE: LoadOut; - MECH: LoadOut; - OPERATOR_ADULT: LoadOut; - DRIFTER: LoadOut; -} - -type LoadOut = { - Upgrades: Config[]; - PvpUpgrades: Config[]; - Skins: string[]; - pricol: { [key: string]: number }; - attcol: Config; - sigcol: Config; - eyecol: Config; - facial: Config; - cloth: Config; - syancol: Config; - Songs: Config[]; -}; - export type EquipmentCategories = - | { LoadOuts: { [key in keyof LoadOuts]: LoadOut } } + | { LoadOuts: { [key in keyof ILoadout]: LoadOut } } | { LongGuns: Config } | { OperatorAmps: Config } // Replace 'any' with the actual type | { Pistols: Config } // Replace 'any' with the actual type -- 2.47.2 From 0a6a76c8f555ced8a4f1edc55f6a406700174e47 Mon Sep 17 00:00:00 2001 From: Ordis <134585663+OrdisPrime@users.noreply.github.com> Date: Wed, 29 Nov 2023 15:45:02 +0100 Subject: [PATCH 04/11] mongoose is great --- package-lock.json | 110 +++++++----------- package.json | 2 +- src/app.ts | 9 ++ src/controllers/api/inventoryController.ts | 7 +- src/controllers/api/saveLoadout.ts | 31 ++--- .../api/trainingResultController.ts | 2 +- .../{ => inventoryModels}/inventoryModel.ts | 8 +- src/models/inventoryModels/loadoutModel.ts | 105 +++++++++++++++++ src/services/inventoryService.ts | 2 +- src/services/saveLoadoutService.ts | 0 src/types/saveLoadoutTypes.ts | 23 +++- 11 files changed, 204 insertions(+), 95 deletions(-) rename src/models/{ => inventoryModels}/inventoryModel.ts (97%) create mode 100644 src/models/inventoryModels/loadoutModel.ts create mode 100644 src/services/saveLoadoutService.ts diff --git a/package-lock.json b/package-lock.json index b3e60e77..fdd59437 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,7 +11,7 @@ "dependencies": { "dotenv": "^16.1.3", "express": "^5.0.0-beta.1", - "mongoose": "^7.4.1", + "mongoose": "^8.0.2", "warframe-items": "1.1260.121" }, "devDependencies": { @@ -214,6 +214,14 @@ "@jridgewell/sourcemap-codec": "^1.4.10" } }, + "node_modules/@mongodb-js/saslprep": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@mongodb-js/saslprep/-/saslprep-1.1.1.tgz", + "integrity": "sha512-t7c5K033joZZMspnHg/gWPE4kandgc2OxE74aYOtGKfgB9VPuVJPix0H6fhmm2erj5PBJ21mqcx34lpIGtUCsQ==", + "dependencies": { + "sparse-bitfield": "^3.0.3" + } + }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -419,9 +427,9 @@ "dev": true }, "node_modules/@types/webidl-conversions": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@types/webidl-conversions/-/webidl-conversions-7.0.0.tgz", - "integrity": "sha512-xTE1E+YF4aWPJJeUzaZI5DRntlkY3+BCVJi0axFptnjGmAoWxkyREIh/XMrfxVLejwQxMCfDXdICo0VLxThrog==" + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/@types/webidl-conversions/-/webidl-conversions-7.0.3.tgz", + "integrity": "sha512-CiJJvcRtIgzadHCYXw7dqEnMNRjhGZlYK05Mj9OyktqV8uVT8fD2BFOB7S1uwBE3Kj2Z+4UyPmFw/Ixgw/LAlA==" }, "node_modules/@types/whatwg-url": { "version": "8.2.2", @@ -1140,11 +1148,11 @@ } }, "node_modules/bson": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/bson/-/bson-5.4.0.tgz", - "integrity": "sha512-WRZ5SQI5GfUuKnPTNmAYPiKIof3ORXAF4IRU5UcgmivNIon01rWQlw5RUH954dpu8yGL8T59YShVddIPaU/gFA==", + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/bson/-/bson-6.2.0.tgz", + "integrity": "sha512-ID1cI+7bazPDyL9wYy9GaQ8gEEohWvcUl/Yf0dIdutJxnmInEEyCsb4awy/OiBfall7zBA179Pahi3vCdFze3Q==", "engines": { - "node": ">=14.20.1" + "node": ">=16.20.1" } }, "node_modules/buffer-from": { @@ -2136,11 +2144,6 @@ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, - "node_modules/ip": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ip/-/ip-2.0.0.tgz", - "integrity": "sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ==" - }, "node_modules/ipaddr.js": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", @@ -2397,8 +2400,7 @@ "node_modules/memory-pager": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.5.0.tgz", - "integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==", - "optional": true + "integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==" }, "node_modules/merge-descriptors": { "version": "1.0.1", @@ -2506,26 +2508,25 @@ } }, "node_modules/mongodb": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-5.7.0.tgz", - "integrity": "sha512-zm82Bq33QbqtxDf58fLWBwTjARK3NSvKYjyz997KSy6hpat0prjeX/kxjbPVyZY60XYPDNETaHkHJI2UCzSLuw==", + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-6.2.0.tgz", + "integrity": "sha512-d7OSuGjGWDZ5usZPqfvb36laQ9CPhnWkAGHT61x5P95p/8nMVeH8asloMwW6GcYFeB0Vj4CB/1wOTDG2RA9BFA==", "dependencies": { - "bson": "^5.4.0", - "mongodb-connection-string-url": "^2.6.0", - "socks": "^2.7.1" + "@mongodb-js/saslprep": "^1.1.0", + "bson": "^6.2.0", + "mongodb-connection-string-url": "^2.6.0" }, "engines": { - "node": ">=14.20.1" - }, - "optionalDependencies": { - "saslprep": "^1.0.3" + "node": ">=16.20.1" }, "peerDependencies": { - "@aws-sdk/credential-providers": "^3.201.0", + "@aws-sdk/credential-providers": "^3.188.0", "@mongodb-js/zstd": "^1.1.0", + "gcp-metadata": "^5.2.0", "kerberos": "^2.0.1", - "mongodb-client-encryption": ">=2.3.0 <3", - "snappy": "^7.2.2" + "mongodb-client-encryption": ">=6.0.0 <7", + "snappy": "^7.2.2", + "socks": "^2.7.1" }, "peerDependenciesMeta": { "@aws-sdk/credential-providers": { @@ -2534,6 +2535,9 @@ "@mongodb-js/zstd": { "optional": true }, + "gcp-metadata": { + "optional": true + }, "kerberos": { "optional": true }, @@ -2542,6 +2546,9 @@ }, "snappy": { "optional": true + }, + "socks": { + "optional": true } } }, @@ -2555,20 +2562,20 @@ } }, "node_modules/mongoose": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-7.4.1.tgz", - "integrity": "sha512-o3E5KHHiHdaiwCJG3+9r70sncRKki71Ktf/TfXdW6myu+53rtZ56uLl5ylkQiCf60V3COJuOeekcxXVsjQ7cBA==", + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-8.0.2.tgz", + "integrity": "sha512-Vsi9GzTXjdBVzheT1HZOZ2jHNzzR9Xwb5OyLz/FvDEAhlwrRnXnuqJf0QHINUOQSm7aoyvnPks0q85HJkd6yDw==", "dependencies": { - "bson": "^5.4.0", + "bson": "^6.2.0", "kareem": "2.5.1", - "mongodb": "5.7.0", + "mongodb": "6.2.0", "mpath": "0.9.0", "mquery": "5.0.0", "ms": "2.1.3", "sift": "16.0.1" }, "engines": { - "node": ">=14.20.1" + "node": ">=16.20.1" }, "funding": { "type": "opencollective", @@ -3223,18 +3230,6 @@ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, - "node_modules/saslprep": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/saslprep/-/saslprep-1.0.3.tgz", - "integrity": "sha512-/MY/PEMbk2SuY5sScONwhUDsV2p77Znkb/q3nSVstq/yQzYJOH/Azh29p9oJLsl3LnQwSvZDKagDGBsBwSooag==", - "optional": true, - "dependencies": { - "sparse-bitfield": "^3.0.3" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/semver": { "version": "7.5.4", "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", @@ -3350,28 +3345,6 @@ "node": ">=8" } }, - "node_modules/smart-buffer": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", - "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", - "engines": { - "node": ">= 6.0.0", - "npm": ">= 3.0.0" - } - }, - "node_modules/socks": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/socks/-/socks-2.7.1.tgz", - "integrity": "sha512-7maUZy1N7uo6+WVEX6psASxtNlKaNVMlGQKkG/63nEDdLOWNbiUMoLK7X4uYoLhQstau72mLgfEWcXcwsaHbYQ==", - "dependencies": { - "ip": "^2.0.0", - "smart-buffer": "^4.2.0" - }, - "engines": { - "node": ">= 10.13.0", - "npm": ">= 3.0.0" - } - }, "node_modules/source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -3395,7 +3368,6 @@ "version": "3.0.3", "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz", "integrity": "sha512-kvzhi7vqKTfkh0PZU+2D2PIllw2ymqJKujUcyPMd9Y75Nv4nPbGJZXNhxsgdQab2BmlDct1YnfQCguEvHr7VsQ==", - "optional": true, "dependencies": { "memory-pager": "^1.0.2" } diff --git a/package.json b/package.json index 7c971d7a..7416d812 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,7 @@ "dependencies": { "dotenv": "^16.1.3", "express": "^5.0.0-beta.1", - "mongoose": "^7.4.1", + "mongoose": "^8.0.2", "warframe-items": "1.1260.121" }, "devDependencies": { diff --git a/src/app.ts b/src/app.ts index 3ca8bfc8..025453f4 100644 --- a/src/app.ts +++ b/src/app.ts @@ -14,6 +14,7 @@ import { customRouter } from "@/src/routes/custom"; import { dynamicController } from "@/src/routes/dynamic"; import { statsRouter } from "@/src/routes/stats"; import { connectDatabase } from "@/src/services/mongoService"; +import { LoadoutModel as Loadout } from "@/src/models/inventoryModels/loadoutModel"; void connectDatabase(); @@ -34,6 +35,14 @@ app.use("/:id/dynamic", dynamicController); app.post("/pay/steamPacks.php", steamPacksController); app.use("/stats", statsRouter); +// eslint-disable-next-line @typescript-eslint/no-misused-promises +app.post("/test", async (req, _res) => { + console.log("test hit", req.body); + const newLoadout = new Loadout({}); + await newLoadout.save(); + _res.end(); +}); + app.use(unknownEndpointHandler); //app.use(errorHandler) diff --git a/src/controllers/api/inventoryController.ts b/src/controllers/api/inventoryController.ts index bada9ab7..21099e1e 100644 --- a/src/controllers/api/inventoryController.ts +++ b/src/controllers/api/inventoryController.ts @@ -1,10 +1,11 @@ /* eslint-disable @typescript-eslint/no-misused-promises */ import { toInventoryResponse } from "@/src/helpers/inventoryHelpers"; -import { Inventory } from "@/src/models/inventoryModel"; +import { Inventory } from "@/src/models/inventoryModels/inventoryModel"; import { Request, RequestHandler, Response } from "express"; import config from "@/config.json"; import testMissions from "@/static/fixed_responses/testMissions.json"; import testQuestKeys from "@/static/fixed_responses/testQuestKeys.json"; +import { ILoadoutDatabase } from "@/src/types/saveLoadoutTypes"; const inventoryController: RequestHandler = async (request: Request, response: Response) => { const accountId = request.query.accountId; @@ -14,7 +15,9 @@ const inventoryController: RequestHandler = async (request: Request, response: R return; } - const inventory = await Inventory.findOne({ accountOwnerId: accountId }); + const inventory = await Inventory.findOne({ accountOwnerId: accountId }).populate<{ + LoadOutPresets: ILoadoutDatabase; + }>("LoadOutPresets"); if (!inventory) { response.status(400).json({ error: "inventory was undefined" }); diff --git a/src/controllers/api/saveLoadout.ts b/src/controllers/api/saveLoadout.ts index 6d21715e..842f2c77 100644 --- a/src/controllers/api/saveLoadout.ts +++ b/src/controllers/api/saveLoadout.ts @@ -1,26 +1,25 @@ -import { Inventory } from "@/src/models/inventoryModel"; +import { Inventory } from "@/src/models/inventoryModels/inventoryModel"; import { RequestHandler } from "express"; import util from "util"; import { EquipmentCategories, IConfigEntry, ILoadout, + ILoadoutKey, ISaveLoadoutRequest, ISaveLoadoutRequestNoUpgradeVer } from "@/src/types/saveLoadoutTypes"; -export const isObjectEmpty = (obj: Record) => { - return obj && Object.keys(obj).length === 0 && obj.constructor === Object; +export const isEmptyObject = (obj: unknown): boolean => { + return Boolean(obj && Object.keys(obj).length === 0 && obj.constructor === Object); }; -type EquipmentChangeEntry = IConfigEntry | ILoadout; - export const handleInventoryItemConfigChange = (equipmentChanges: ISaveLoadoutRequestNoUpgradeVer) => { for (const [_equipmentName, _equipment] of Object.entries(equipmentChanges)) { const equipment = _equipment as ISaveLoadoutRequestNoUpgradeVer[keyof ISaveLoadoutRequestNoUpgradeVer]; const equipmentName = _equipmentName as keyof ISaveLoadoutRequestNoUpgradeVer; - if (isObjectEmpty(equipment)) { + if (isEmptyObject(equipment)) { continue; } // non-empty is a change in loadout(or suit...) @@ -28,16 +27,20 @@ export const handleInventoryItemConfigChange = (equipmentChanges: ISaveLoadoutRe switch (equipmentName) { case "LoadOuts": { console.log("loadout received"); - const _loadout = equipment as unknown as ILoadout; - for (const [loadoutName, loadout] of Object.entries(_loadout)) { - console.log(loadoutName, loadout); - //const loadout = _loadout as ILoadoutEntry; + for (const [_loadoutName, _loadout] of Object.entries(equipment)) { + const loadout = _loadout as ILoadoutKey; + const loadoutName = _loadoutName as keyof ILoadout; - // console.log(loadoutName, loadout); - // if (isObjectEmpty(loadout)) { - // continue; - // } + console.log(_loadoutName, loadout); + + if (isEmptyObject(loadout)) { + continue; + } + // all non-empty entries are one loadout slot + for (const [_loadoutId, _loadoutConfig] of Object.entries(loadout)) { + console.log(loadout[_loadoutId].s); + } } break; } diff --git a/src/controllers/api/trainingResultController.ts b/src/controllers/api/trainingResultController.ts index 9feffe38..db2965bf 100644 --- a/src/controllers/api/trainingResultController.ts +++ b/src/controllers/api/trainingResultController.ts @@ -1,6 +1,6 @@ import { parseString } from "@/src/helpers/general"; import { getJSONfromString } from "@/src/helpers/stringHelpers"; -import { Inventory } from "@/src/models/inventoryModel"; +import { Inventory } from "@/src/models/inventoryModels/inventoryModel"; import { getInventory } from "@/src/services/inventoryService"; import { IMongoDate } from "@/src/types/commonTypes"; import { RequestHandler } from "express"; diff --git a/src/models/inventoryModel.ts b/src/models/inventoryModels/inventoryModel.ts similarity index 97% rename from src/models/inventoryModel.ts rename to src/models/inventoryModels/inventoryModel.ts index 5c753b86..b1ae88bd 100644 --- a/src/models/inventoryModel.ts +++ b/src/models/inventoryModels/inventoryModel.ts @@ -8,8 +8,8 @@ import { IInventoryResponse, IInventoryDatabaseDocument, IInventoryResponseDocument -} from "../types/inventoryTypes/inventoryTypes"; -import { IMongoDate, IOid } from "../types/commonTypes"; +} from "../../types/inventoryTypes/inventoryTypes"; +import { IMongoDate, IOid } from "../../types/commonTypes"; import { ISuitDatabase, ISuitDocument } from "@/src/types/inventoryTypes/SuitTypes"; import { IWeaponDatabase } from "@/src/types/inventoryTypes/weaponTypes"; @@ -191,7 +191,7 @@ FlavourItemSchema.set("toJSON", { } }); -const inventorySchema = new Schema({ +const inventorySchema = new Schema({ accountOwnerId: Schema.Types.ObjectId, SubscribedToEmails: Number, Created: Schema.Types.Mixed, @@ -229,7 +229,7 @@ const inventorySchema = new Schema({ + $oid: String +}); + +//create a mongoose schema based on interface M +const modSchema = new Schema({ + ItemId: { + type: oidSchema, + default: { $oid: "000000000000000000000000" } + }, + mod: Number, + cus: Number +}); + +//default initialization for +const loadoutConfigSchema = new Schema( + { + PresetIcon: String, + Favorite: Boolean, + s: {}, + p: {}, + l: {}, + m: {} + }, + { + virtuals: { + ItemId: { + get() { + return this._id.toString(); + } + } + } + } +); + +interface User { + firstName: string; + lastName: string; +} + +const UserSchema = new Schema( + { + firstName: String, + lastName: String + }, + { + virtuals: { + fullname: { + get() { + return `${this.firstName} ${this.lastName}`; + } + } + } + } +); + +// loadoutConfigSchema.virtual("ItemId").get(function (): string { +// return this._id +// }); + +loadoutConfigSchema.set("toJSON", { + virtuals: true, + transform(_doc, ret, _options) { + delete ret._id; + delete ret.__v; + } +}); + +const loadoutSchema = new Schema({ + NORMAL: [loadoutConfigSchema], + SENTINEL: [loadoutConfigSchema], + ARCHWING: [loadoutConfigSchema], + NORMAL_PVP: [loadoutConfigSchema], + LUNARO: [loadoutConfigSchema], + OPERATOR: [loadoutConfigSchema], + KDRIVE: [loadoutConfigSchema], + DATAKNIFE: [loadoutConfigSchema], + MECH: [loadoutConfigSchema], + OPERATOR_ADULT: [loadoutConfigSchema], + DRIFTER: [loadoutConfigSchema] +}); + +//create database typefor ILoadoutConfig +type loadoutDocumentProps = { + NORMAL: Types.DocumentArray; + SENTINEL: Types.DocumentArray; + ARCHWING: Types.DocumentArray; + NORMAL_PVP: Types.DocumentArray; + LUNARO: Types.DocumentArray; + OPERATOR: Types.DocumentArray; + KDRIVE: Types.DocumentArray; + DATAKNIFE: Types.DocumentArray; + MECH: Types.DocumentArray; + OPERATOR_ADULT: Types.DocumentArray; + DRIFTER: Types.DocumentArray; +}; + +type loadoutModelType = Model; + +export const LoadoutModel = model("Loadout", loadoutSchema); diff --git a/src/services/inventoryService.ts b/src/services/inventoryService.ts index 035881bd..1edb4acf 100644 --- a/src/services/inventoryService.ts +++ b/src/services/inventoryService.ts @@ -1,4 +1,4 @@ -import { Inventory } from "@/src/models/inventoryModel"; +import { Inventory } from "@/src/models/inventoryModels/inventoryModel"; import new_inventory from "@/static/fixed_responses/postTutorialInventory.json"; import config from "@/config.json"; import { Types } from "mongoose"; diff --git a/src/services/saveLoadoutService.ts b/src/services/saveLoadoutService.ts new file mode 100644 index 00000000..e69de29b diff --git a/src/types/saveLoadoutTypes.ts b/src/types/saveLoadoutTypes.ts index 4dba7f50..b834f0a1 100644 --- a/src/types/saveLoadoutTypes.ts +++ b/src/types/saveLoadoutTypes.ts @@ -1,4 +1,5 @@ import { IOid } from "@/src/types/commonTypes"; +import { Document, Mongoose } from "mongoose"; export interface ISaveLoadoutRequest { LoadOuts: ILoadout; @@ -49,11 +50,27 @@ export interface ILoadout { DRIFTER: ILoadoutKey; } -export interface ILoadoutKey { - [key: string]: ItemConfig; +export interface ILoadoutDatabase { + NORMAL: ILoadoutConfig; + SENTINEL: ILoadoutConfig; + ARCHWING: ILoadoutConfig; + NORMAL_PVP: ILoadoutConfig; + LUNARO: ILoadoutConfig; + OPERATOR: ILoadoutConfig; + KDRIVE: ILoadoutConfig; + DATAKNIFE: ILoadoutConfig; + MECH: ILoadoutConfig; + OPERATOR_ADULT: ILoadoutConfig; + DRIFTER: ILoadoutConfig; } -export interface ItemConfig { +export interface ILoadoutKey { + [key: string]: ILoadoutConfig; +} + +export type ILoadoutConfigDocument = ILoadoutConfig & Document; + +export interface ILoadoutConfig { ItemId: IOid; PresetIcon: string; Favorite: boolean; -- 2.47.2 From f271898ced6e639864879c347ea2184658936641 Mon Sep 17 00:00:00 2001 From: Ordis <134585663+OrdisPrime@users.noreply.github.com> Date: Sun, 3 Dec 2023 00:49:52 +0100 Subject: [PATCH 05/11] progress --- src/app.ts | 9 ++ src/controllers/api/saveLoadout.ts | 59 +++++++-- src/models/inventoryModels/inventoryModel.ts | 5 +- src/models/inventoryModels/loadoutModel.ts | 122 +++++++++---------- src/types/saveLoadoutTypes.ts | 65 +++++----- 5 files changed, 149 insertions(+), 111 deletions(-) diff --git a/src/app.ts b/src/app.ts index 025453f4..03fa5bd2 100644 --- a/src/app.ts +++ b/src/app.ts @@ -39,6 +39,15 @@ app.use("/stats", statsRouter); app.post("/test", async (req, _res) => { console.log("test hit", req.body); const newLoadout = new Loadout({}); + newLoadout.NORMAL.push({ + _id: "000000000000000000000000", + Favorite: false, + PresetIcon: "", + s: { ItemId: { $oid: "000000000000000000000000" }, mod: 0, cus: 0 }, + p: { ItemId: { $oid: "000000000000000000000000" }, mod: 0, cus: 0 }, + l: { ItemId: { $oid: "000000000000000000000000" }, mod: 0, cus: 0 }, + m: { ItemId: { $oid: "000000000000000000000000" }, mod: 0, cus: 0 } + }); await newLoadout.save(); _res.end(); }); diff --git a/src/controllers/api/saveLoadout.ts b/src/controllers/api/saveLoadout.ts index 842f2c77..0f029472 100644 --- a/src/controllers/api/saveLoadout.ts +++ b/src/controllers/api/saveLoadout.ts @@ -4,17 +4,24 @@ import util from "util"; import { EquipmentCategories, IConfigEntry, - ILoadout, + ILoadoutRequest, ILoadoutKey, ISaveLoadoutRequest, - ISaveLoadoutRequestNoUpgradeVer + ISaveLoadoutRequestNoUpgradeVer, + ILoadoutConfigDatabase } from "@/src/types/saveLoadoutTypes"; +import { LoadoutModel } from "@/src/models/inventoryModels/loadoutModel"; +import { Types } from "mongoose"; export const isEmptyObject = (obj: unknown): boolean => { return Boolean(obj && Object.keys(obj).length === 0 && obj.constructor === Object); }; -export const handleInventoryItemConfigChange = (equipmentChanges: ISaveLoadoutRequestNoUpgradeVer) => { +//setup default items on account creation or like originally in giveStartingItems.php + +//export const updateLoadout = (loadout: ISaveLoadoutRequest, accountId: string) => {}; + +export const handleInventoryItemConfigChange = async (equipmentChanges: ISaveLoadoutRequestNoUpgradeVer) => { for (const [_equipmentName, _equipment] of Object.entries(equipmentChanges)) { const equipment = _equipment as ISaveLoadoutRequestNoUpgradeVer[keyof ISaveLoadoutRequestNoUpgradeVer]; const equipmentName = _equipmentName as keyof ISaveLoadoutRequestNoUpgradeVer; @@ -28,23 +35,59 @@ export const handleInventoryItemConfigChange = (equipmentChanges: ISaveLoadoutRe case "LoadOuts": { console.log("loadout received"); - for (const [_loadoutName, _loadout] of Object.entries(equipment)) { + for (const [_loadoutSlot, _loadout] of Object.entries(equipment)) { + const loadoutSlot = _loadoutSlot as keyof ILoadoutRequest; const loadout = _loadout as ILoadoutKey; - const loadoutName = _loadoutName as keyof ILoadout; - console.log(_loadoutName, loadout); + //console.log("key", loadoutSlot, "value", loadout); if (isEmptyObject(loadout)) { continue; } // all non-empty entries are one loadout slot - for (const [_loadoutId, _loadoutConfig] of Object.entries(loadout)) { - console.log(loadout[_loadoutId].s); + for (const [loadoutId, loadoutConfig] of Object.entries(loadout)) { + // console.log("loadoutId", loadoutId, "loadoutconfig", loadoutConfig); + const loadout = await LoadoutModel.findById("656a184a9cefa0e5627689af"); + if (!loadout) { + throw new Error("loadout not found"); + } + + const oldLoadoutConfig = loadout[loadoutSlot].find( + loadout => loadout._id.toString() === loadoutId + ); + + // if no config with this id exists, create a new one + if (!oldLoadoutConfig) { + const { ItemId, ...loadoutConfigItemIdRemoved } = loadoutConfig; + loadout[loadoutSlot].push({ + _id: ItemId.$oid, + ...loadoutConfigItemIdRemoved + }); + await loadout.save(); + continue; + } + + const loadoutIndex = loadout[loadoutSlot].indexOf(oldLoadoutConfig); + + if (loadoutIndex === undefined || loadoutIndex === -1) { + throw new Error("loadout index not found"); + } + + //console.log("parent id", oldLoadoutConfig.ownerDocument()._id); + loadout[loadoutSlot][loadoutIndex].set(loadoutConfig); + //loadout.NORMAL[loadoutIndex].overwrite(loadoutConfig); + //console.log("db", loadout[loadoutSlot][loadoutIndex].schema); + + await loadout.save(); + //({ _id: loadoutId }, loadoutConfig); } } break; } case "LongGuns": { + console.log("longgun received"); + console.log(equipmentName, equipment); + const longGun = equipment as IConfigEntry; // longGun["key"].PvpUpgrades; break; diff --git a/src/models/inventoryModels/inventoryModel.ts b/src/models/inventoryModels/inventoryModel.ts index b1ae88bd..f39eb97f 100644 --- a/src/models/inventoryModels/inventoryModel.ts +++ b/src/models/inventoryModels/inventoryModel.ts @@ -152,7 +152,10 @@ suitConfigSchema.set("toJSON", { const suitSchema = new Schema({ ItemType: String, - Configs: [suitConfigSchema], + Configs: { + type: [suitConfigSchema], + default: [{}, {}, {}] + }, UpgradeVer: Number, XP: Number, InfestationDate: Date, diff --git a/src/models/inventoryModels/loadoutModel.ts b/src/models/inventoryModels/loadoutModel.ts index 31c6eb3d..3cf647bd 100644 --- a/src/models/inventoryModels/loadoutModel.ts +++ b/src/models/inventoryModels/loadoutModel.ts @@ -1,67 +1,43 @@ import { IOid } from "@/src/types/commonTypes"; -import { ILoadout, ILoadoutConfig, ILoadoutConfigDocument, ILoadoutDatabase, M } from "@/src/types/saveLoadoutTypes"; +import { ILoadoutConfigDatabase, ILoadoutDatabase, IEquipmentSelection } from "@/src/types/saveLoadoutTypes"; import { Model, Schema, Types, model } from "mongoose"; -//create a schema for the $oid type -const oidSchema = new Schema({ - $oid: String -}); +const oidSchema = new Schema( + { + $oid: String + }, + { + _id: false + } +); //create a mongoose schema based on interface M -const modSchema = new Schema({ - ItemId: { - type: oidSchema, - default: { $oid: "000000000000000000000000" } +const EquipmentSelectionSchema = new Schema( + { + ItemId: { + type: oidSchema, + default: { $oid: "000000000000000000000000" } + }, + mod: Number, + cus: Number }, - mod: Number, - cus: Number + { + _id: false + } +); + +const loadoutConfigSchema = new Schema({ + PresetIcon: String, + Favorite: Boolean, + s: EquipmentSelectionSchema, + p: EquipmentSelectionSchema, + l: EquipmentSelectionSchema, + m: EquipmentSelectionSchema }); -//default initialization for -const loadoutConfigSchema = new Schema( - { - PresetIcon: String, - Favorite: Boolean, - s: {}, - p: {}, - l: {}, - m: {} - }, - { - virtuals: { - ItemId: { - get() { - return this._id.toString(); - } - } - } - } -); - -interface User { - firstName: string; - lastName: string; -} - -const UserSchema = new Schema( - { - firstName: String, - lastName: String - }, - { - virtuals: { - fullname: { - get() { - return `${this.firstName} ${this.lastName}`; - } - } - } - } -); - -// loadoutConfigSchema.virtual("ItemId").get(function (): string { -// return this._id -// }); +loadoutConfigSchema.virtual("ItemId").get(function (): string { + return this._id.toString(); +}); loadoutConfigSchema.set("toJSON", { virtuals: true, @@ -85,19 +61,31 @@ const loadoutSchema = new Schema({ DRIFTER: [loadoutConfigSchema] }); +loadoutSchema.virtual("ItemId").get(function (): string { + return this._id.toString(); +}); + +loadoutSchema.set("toJSON", { + virtuals: true, + transform(_doc, ret, _options) { + delete ret._id; + delete ret.__v; + } +}); + //create database typefor ILoadoutConfig type loadoutDocumentProps = { - NORMAL: Types.DocumentArray; - SENTINEL: Types.DocumentArray; - ARCHWING: Types.DocumentArray; - NORMAL_PVP: Types.DocumentArray; - LUNARO: Types.DocumentArray; - OPERATOR: Types.DocumentArray; - KDRIVE: Types.DocumentArray; - DATAKNIFE: Types.DocumentArray; - MECH: Types.DocumentArray; - OPERATOR_ADULT: Types.DocumentArray; - DRIFTER: Types.DocumentArray; + NORMAL: Types.DocumentArray; + SENTINEL: Types.DocumentArray; + ARCHWING: Types.DocumentArray; + NORMAL_PVP: Types.DocumentArray; + LUNARO: Types.DocumentArray; + OPERATOR: Types.DocumentArray; + KDRIVE: Types.DocumentArray; + DATAKNIFE: Types.DocumentArray; + MECH: Types.DocumentArray; + OPERATOR_ADULT: Types.DocumentArray; + DRIFTER: Types.DocumentArray; }; type loadoutModelType = Model; diff --git a/src/types/saveLoadoutTypes.ts b/src/types/saveLoadoutTypes.ts index b834f0a1..38a9b8e3 100644 --- a/src/types/saveLoadoutTypes.ts +++ b/src/types/saveLoadoutTypes.ts @@ -1,8 +1,8 @@ import { IOid } from "@/src/types/commonTypes"; -import { Document, Mongoose } from "mongoose"; +import { Document, Mongoose, Types } from "mongoose"; export interface ISaveLoadoutRequest { - LoadOuts: ILoadout; + LoadOuts: ILoadoutRequest; LongGuns: IConfigEntry; OperatorAmps: IConfigEntry; Pistols: IConfigEntry; @@ -36,51 +36,46 @@ export interface IConfigEntry { [key: string]: Config; } -export interface ILoadout { - NORMAL: ILoadoutKey; - SENTINEL: ILoadoutKey; - ARCHWING: ILoadoutKey; - NORMAL_PVP: ILoadoutKey; - LUNARO: ILoadoutKey; - OPERATOR: ILoadoutKey; - KDRIVE: ILoadoutKey; - DATAKNIFE: ILoadoutKey; - MECH: ILoadoutKey; - OPERATOR_ADULT: ILoadoutKey; - DRIFTER: ILoadoutKey; +export interface ILoadoutRequest extends Omit {} + +export interface ILoadoutResponse extends ILoadoutDatabase { + ItemId: IOid; } export interface ILoadoutDatabase { - NORMAL: ILoadoutConfig; - SENTINEL: ILoadoutConfig; - ARCHWING: ILoadoutConfig; - NORMAL_PVP: ILoadoutConfig; - LUNARO: ILoadoutConfig; - OPERATOR: ILoadoutConfig; - KDRIVE: ILoadoutConfig; - DATAKNIFE: ILoadoutConfig; - MECH: ILoadoutConfig; - OPERATOR_ADULT: ILoadoutConfig; - DRIFTER: ILoadoutConfig; + NORMAL: ILoadoutConfigDatabase; + SENTINEL: ILoadoutConfigDatabase; + ARCHWING: ILoadoutConfigDatabase; + NORMAL_PVP: ILoadoutConfigDatabase; + LUNARO: ILoadoutConfigDatabase; + OPERATOR: ILoadoutConfigDatabase; + KDRIVE: ILoadoutConfigDatabase; + DATAKNIFE: ILoadoutConfigDatabase; + MECH: ILoadoutConfigDatabase; + OPERATOR_ADULT: ILoadoutConfigDatabase; + DRIFTER: ILoadoutConfigDatabase; } export interface ILoadoutKey { - [key: string]: ILoadoutConfig; + [key: string]: ILoadoutConfigClient; } -export type ILoadoutConfigDocument = ILoadoutConfig & Document; - -export interface ILoadoutConfig { +// for request and response from and to client +export interface ILoadoutConfigClient { ItemId: IOid; PresetIcon: string; Favorite: boolean; - s: M; - p: M; - l: M; - m: M; + s: IEquipmentSelection; + p: IEquipmentSelection; + l: IEquipmentSelection; + m: IEquipmentSelection; } -export interface M { +export interface ILoadoutConfigDatabase extends Omit { + _id: Types.ObjectId; +} + +export interface IEquipmentSelection { ItemId: IOid; mod: number; cus: number; @@ -129,7 +124,7 @@ export interface Col { } export type EquipmentCategories = - | { LoadOuts: { [key in keyof ILoadout]: LoadOut } } + | { LoadOuts: { [key in keyof ILoadoutRequest]: LoadOut } } | { LongGuns: Config } | { OperatorAmps: Config } // Replace 'any' with the actual type | { Pistols: Config } // Replace 'any' with the actual type -- 2.47.2 From 36e76a9a8452e03e7a2698fc6b780b61218e6140 Mon Sep 17 00:00:00 2001 From: Ordis <134585663+OrdisPrime@users.noreply.github.com> Date: Sun, 3 Dec 2023 01:58:06 +0100 Subject: [PATCH 06/11] loadouts workinhg --- src/models/inventoryModels/loadoutModel.ts | 26 +++++++++++++--------- src/types/saveLoadoutTypes.ts | 1 + 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/src/models/inventoryModels/loadoutModel.ts b/src/models/inventoryModels/loadoutModel.ts index 3cf647bd..44082497 100644 --- a/src/models/inventoryModels/loadoutModel.ts +++ b/src/models/inventoryModels/loadoutModel.ts @@ -26,17 +26,23 @@ const EquipmentSelectionSchema = new Schema( } ); -const loadoutConfigSchema = new Schema({ - PresetIcon: String, - Favorite: Boolean, - s: EquipmentSelectionSchema, - p: EquipmentSelectionSchema, - l: EquipmentSelectionSchema, - m: EquipmentSelectionSchema -}); +const loadoutConfigSchema = new Schema( + { + PresetIcon: String, + Favorite: Boolean, + n: String, + s: EquipmentSelectionSchema, + p: EquipmentSelectionSchema, + l: EquipmentSelectionSchema, + m: EquipmentSelectionSchema + }, + { + id: false + } +); -loadoutConfigSchema.virtual("ItemId").get(function (): string { - return this._id.toString(); +loadoutConfigSchema.virtual("ItemId").get(function () { + return { $oid: this._id.toString() } satisfies IOid; }); loadoutConfigSchema.set("toJSON", { diff --git a/src/types/saveLoadoutTypes.ts b/src/types/saveLoadoutTypes.ts index 38a9b8e3..92f496e9 100644 --- a/src/types/saveLoadoutTypes.ts +++ b/src/types/saveLoadoutTypes.ts @@ -63,6 +63,7 @@ export interface ILoadoutKey { // for request and response from and to client export interface ILoadoutConfigClient { ItemId: IOid; + n: string; PresetIcon: string; Favorite: boolean; s: IEquipmentSelection; -- 2.47.2 From 79c58f2558b936718161ca2a02b689100c2b1176 Mon Sep 17 00:00:00 2001 From: Ordis <134585663+OrdisPrime@users.noreply.github.com> Date: Thu, 7 Dec 2023 00:42:07 +0100 Subject: [PATCH 07/11] saveLoadout working: missing some types --- src/controllers/api/getShipController.ts | 6 +- src/controllers/api/inventoryController.ts | 2 +- src/controllers/api/saveLoadout.ts | 140 +-------- src/models/inventoryModels/inventoryModel.ts | 309 +++++++++++-------- src/models/inventoryModels/loadoutModel.ts | 11 +- src/models/shipModel.ts | 29 +- src/services/inventoryService.ts | 22 +- src/services/loginService.ts | 13 +- src/services/saveLoadoutService.ts | 179 +++++++++++ src/services/shipService.ts | 8 +- src/types/inventoryTypes/SuitTypes.ts | 41 ++- src/types/inventoryTypes/inventoryTypes.ts | 51 +-- src/types/inventoryTypes/weaponTypes.ts | 20 +- src/types/purchaseTypes.ts | 8 +- src/types/requestTypes.ts | 12 +- src/types/saveLoadoutTypes.ts | 163 ++++------ src/types/shipTypes.ts | 18 +- 17 files changed, 559 insertions(+), 473 deletions(-) diff --git a/src/controllers/api/getShipController.ts b/src/controllers/api/getShipController.ts index 7439acf1..18e99d2f 100644 --- a/src/controllers/api/getShipController.ts +++ b/src/controllers/api/getShipController.ts @@ -1,10 +1,14 @@ import { Ship } from "@/src/models/shipModel"; +import { ILoadoutDatabase } from "@/src/types/saveLoadoutTypes"; import { RequestHandler } from "express"; // eslint-disable-next-line @typescript-eslint/no-misused-promises const getShipController: RequestHandler = async (req, res) => { const accountId = req.query.accountId; - const ship = await Ship.findOne({ ShipOwnerId: accountId }); + const ship = await Ship.findOne({ ShipOwnerId: accountId }).populate<{ + LoadOutInventory: { LoadOutPresets: ILoadoutDatabase }; + }>("LoadOutInventory.LoadOutPresets"); + if (!ship) { res.status(500).json({ error: "error finding a corresponding ship" }); return; diff --git a/src/controllers/api/inventoryController.ts b/src/controllers/api/inventoryController.ts index 21099e1e..77ae6372 100644 --- a/src/controllers/api/inventoryController.ts +++ b/src/controllers/api/inventoryController.ts @@ -31,7 +31,7 @@ const inventoryController: RequestHandler = async (request: Request, response: R if (config.testMission) inventoryResponse.Missions = testMissions; if (config.testQuestKey) inventoryResponse.QuestKeys = testQuestKeys; - inventoryResponse.DuviriInfo = { Seed: -5049874987509758080, NumCompletions: 0 }; + inventoryResponse.DuviriInfo = { Seed: -123123123123123123, NumCompletions: 0 }; response.json(inventoryResponse); }; diff --git a/src/controllers/api/saveLoadout.ts b/src/controllers/api/saveLoadout.ts index 0f029472..5aa4ccb4 100644 --- a/src/controllers/api/saveLoadout.ts +++ b/src/controllers/api/saveLoadout.ts @@ -1,147 +1,19 @@ -import { Inventory } from "@/src/models/inventoryModels/inventoryModel"; import { RequestHandler } from "express"; import util from "util"; -import { - EquipmentCategories, - IConfigEntry, - ILoadoutRequest, - ILoadoutKey, - ISaveLoadoutRequest, - ISaveLoadoutRequestNoUpgradeVer, - ILoadoutConfigDatabase -} from "@/src/types/saveLoadoutTypes"; -import { LoadoutModel } from "@/src/models/inventoryModels/loadoutModel"; -import { Types } from "mongoose"; - -export const isEmptyObject = (obj: unknown): boolean => { - return Boolean(obj && Object.keys(obj).length === 0 && obj.constructor === Object); -}; - -//setup default items on account creation or like originally in giveStartingItems.php - -//export const updateLoadout = (loadout: ISaveLoadoutRequest, accountId: string) => {}; - -export const handleInventoryItemConfigChange = async (equipmentChanges: ISaveLoadoutRequestNoUpgradeVer) => { - for (const [_equipmentName, _equipment] of Object.entries(equipmentChanges)) { - const equipment = _equipment as ISaveLoadoutRequestNoUpgradeVer[keyof ISaveLoadoutRequestNoUpgradeVer]; - const equipmentName = _equipmentName as keyof ISaveLoadoutRequestNoUpgradeVer; - - if (isEmptyObject(equipment)) { - continue; - } - // non-empty is a change in loadout(or suit...) - - switch (equipmentName) { - case "LoadOuts": { - console.log("loadout received"); - - for (const [_loadoutSlot, _loadout] of Object.entries(equipment)) { - const loadoutSlot = _loadoutSlot as keyof ILoadoutRequest; - const loadout = _loadout as ILoadoutKey; - - //console.log("key", loadoutSlot, "value", loadout); - - if (isEmptyObject(loadout)) { - continue; - } - // all non-empty entries are one loadout slot - for (const [loadoutId, loadoutConfig] of Object.entries(loadout)) { - // console.log("loadoutId", loadoutId, "loadoutconfig", loadoutConfig); - const loadout = await LoadoutModel.findById("656a184a9cefa0e5627689af"); - if (!loadout) { - throw new Error("loadout not found"); - } - - const oldLoadoutConfig = loadout[loadoutSlot].find( - loadout => loadout._id.toString() === loadoutId - ); - - // if no config with this id exists, create a new one - if (!oldLoadoutConfig) { - const { ItemId, ...loadoutConfigItemIdRemoved } = loadoutConfig; - loadout[loadoutSlot].push({ - _id: ItemId.$oid, - ...loadoutConfigItemIdRemoved - }); - await loadout.save(); - continue; - } - - const loadoutIndex = loadout[loadoutSlot].indexOf(oldLoadoutConfig); - - if (loadoutIndex === undefined || loadoutIndex === -1) { - throw new Error("loadout index not found"); - } - - //console.log("parent id", oldLoadoutConfig.ownerDocument()._id); - loadout[loadoutSlot][loadoutIndex].set(loadoutConfig); - //loadout.NORMAL[loadoutIndex].overwrite(loadoutConfig); - //console.log("db", loadout[loadoutSlot][loadoutIndex].schema); - - await loadout.save(); - //({ _id: loadoutId }, loadoutConfig); - } - } - break; - } - case "LongGuns": { - console.log("longgun received"); - console.log(equipmentName, equipment); - - const longGun = equipment as IConfigEntry; - // longGun["key"].PvpUpgrades; - break; - } - case "OperatorAmps": - case "Pistols": - case "Suits": - case "Melee": - case "Sentinels": - case "SentinelWeapons": - case "KubrowPets": - case "SpaceSuits": - case "SpaceGuns": - case "SpaceMelee": - case "Scoops": - case "SpecialItems": - case "MoaPets": - case "Hoverboards": - case "DataKnives": - case "MechSuits": - case "CrewShipHarnesses": - case "Horses": - case "DrifterMelee": - case "OperatorLoadOuts": - case "AdultOperatorLoadOuts": - case "KahlLoadOuts": - case "CrewShips": - - default: { - console.log("category not implemented", equipmentName); - } - } - // Object.keys(value).forEach(element => { - // console.log("name of inner objects keys", element); - // }); - // for (const innerValue of Object.values(value)) { - // console.log(innerValue); - // } - - // console.log(innerObjects); - // if (isObjectEmpty(innerObjects)) { - // console.log(innerObjects, "is empty"); - // } - } -}; +import { ISaveLoadoutRequest } from "@/src/types/saveLoadoutTypes"; +import { handleInventoryItemConfigChange } from "@/src/services/saveLoadoutService"; +import { parseString } from "@/src/helpers/general"; // eslint-disable-next-line @typescript-eslint/no-misused-promises const saveLoadoutController: RequestHandler = async (req, res) => { //validate here + const accountId = parseString(req.query.accountId); const body: ISaveLoadoutRequest = JSON.parse(req.body as string) as ISaveLoadoutRequest; // console.log(util.inspect(body, { showHidden: false, depth: null, colors: true })); + // eslint-disable-next-line @typescript-eslint/no-unused-vars const { UpgradeVer, ...equipmentChanges } = body; - handleInventoryItemConfigChange(equipmentChanges); + await handleInventoryItemConfigChange(equipmentChanges, accountId); res.status(200).end(); }; diff --git a/src/models/inventoryModels/inventoryModel.ts b/src/models/inventoryModels/inventoryModel.ts index f39eb97f..21aed851 100644 --- a/src/models/inventoryModels/inventoryModel.ts +++ b/src/models/inventoryModels/inventoryModel.ts @@ -7,176 +7,206 @@ import { IBooster, IInventoryResponse, IInventoryDatabaseDocument, - IInventoryResponseDocument + ISlots } from "../../types/inventoryTypes/inventoryTypes"; import { IMongoDate, IOid } from "../../types/commonTypes"; -import { ISuitDatabase, ISuitDocument } from "@/src/types/inventoryTypes/SuitTypes"; +import { + IItemConfig, + ISuitDatabase, + IOperatorConfigClient, + IOperatorConfigDatabase +} from "@/src/types/inventoryTypes/SuitTypes"; import { IWeaponDatabase } from "@/src/types/inventoryTypes/weaponTypes"; +import { IAbilityOverride, IColor, IPolarity } from "@/src/types/inventoryTypes/commonInventoryTypes"; -const abilityOverrideSchema = new Schema({ +const polaritySchema = new Schema({ + Slot: Number, + Value: String +}); + +const abilityOverrideSchema = new Schema({ Ability: String, Index: Number }); -const colorSchema = new Schema({ - t0: Number, - t1: Number, - t2: Number, - t3: Number, - en: Number, - e1: Number, - m0: Number, - m1: Number +const colorSchema = new Schema( + { + t0: Number, + t1: Number, + t2: Number, + t3: Number, + en: Number, + e1: Number, + m0: Number, + m1: Number + }, + { _id: false } +); + +const operatorConfigSchema = new Schema( + { + Skins: [String], + pricol: colorSchema, + attcol: colorSchema, + sigcol: colorSchema, + eyecol: colorSchema, + facial: colorSchema, + syancol: colorSchema, + Upgrades: [String], + Name: String, // not sure if possible in operator + ugly: Boolean // not sure if possible in operator + }, + { id: false } +); + +operatorConfigSchema.virtual("ItemId").get(function () { + return { $oid: this._id.toString() } satisfies IOid; }); -const weaponConfigSchema = new Schema({ - Skins: [String], - pricol: colorSchema, - attcol: colorSchema, - eyecol: colorSchema, - sigcol: colorSchema, - Upgrades: [String], - Songs: [ - { - m: String, - b: String, - p: String, - s: String - } - ], - Name: String, - AbilityOverride: abilityOverrideSchema, - PvpUpgrades: [String], - ugly: Boolean -}); - -// longGunConfigSchema.set("toJSON", { -// transform(_document, returnedObject: ISuitDocument) { -// // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call -// returnedObject.ItemId = { $oid: returnedObject._id.toString() } satisfies Oid; -// delete returnedObject._id; -// delete returnedObject.__v; -// } -// }); - -const WeaponSchema = new Schema({ - ItemType: String, - Configs: [weaponConfigSchema], - UpgradeVer: Number, - XP: Number, - Features: Number, - Polarized: Number, - Polarity: Schema.Types.Mixed, //todo - FocusLens: String, - ModSlotPurchases: Number, - UpgradeType: Schema.Types.Mixed, //todo - UpgradeFingerprint: String, - ItemName: String, - ModularParts: [String], - UnlockLevel: Number -}); - -const BoosterSchema = new Schema({ - ExpiryDate: Number, - ItemType: String -}); - -const RawUpgrades = new Schema({ - ItemType: String, - ItemCount: Number -}); - -RawUpgrades.set("toJSON", { +operatorConfigSchema.set("toJSON", { + virtuals: true, transform(_document, returnedObject) { - // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call - returnedObject.LastAdded = { $oid: returnedObject._id.toString() } satisfies IOid; delete returnedObject._id; delete returnedObject.__v; } }); +///TODO: clearly seperate the different config schemas. (suit and weapon and so on) +const ItemConfigSchema = new Schema( + { + Skins: [String], + pricol: colorSchema, + attcol: colorSchema, + sigcol: colorSchema, + eyecol: colorSchema, + facial: colorSchema, + syancol: colorSchema, + Upgrades: [String], + Songs: [ + { + m: String, + b: String, + p: String, + s: String + } + ], + Name: String, + AbilityOverride: abilityOverrideSchema, + PvpUpgrades: [String], + ugly: Boolean + }, + { _id: false } +); + +ItemConfigSchema.set("toJSON", { + transform(_document, returnedObject) { + delete returnedObject.__v; + } +}); + +//TODO: migrate to one schema for weapons and suits.. and possibly others +const WeaponSchema = new Schema( + { + ItemType: String, + Configs: [ItemConfigSchema], + UpgradeVer: Number, + XP: Number, + Features: Number, + Polarized: Number, + Polarity: [polaritySchema], + FocusLens: String, + ModSlotPurchases: Number, + UpgradeType: Schema.Types.Mixed, //todo + UpgradeFingerprint: String, + ItemName: String, + ModularParts: [String], + UnlockLevel: Number + }, + { id: false } +); + +WeaponSchema.virtual("ItemId").get(function () { + return { $oid: this._id.toString() } satisfies IOid; +}); + +WeaponSchema.set("toJSON", { + virtuals: true, + transform(_document, returnedObject) { + delete returnedObject._id; + delete returnedObject.__v; + } +}); + +const BoosterSchema = new Schema({ + ExpiryDate: Number, + ItemType: String +}); + +const RawUpgrades = new Schema({ + ItemType: String, + ItemCount: Number +}); + +RawUpgrades.virtual("LastAdded").get(function () { + return { $oid: this._id.toString() } satisfies IOid; +}); + +RawUpgrades.set("toJSON", { + virtuals: true, + transform(_document, returnedObject) { + delete returnedObject._id; + delete returnedObject.__v; + } +}); + +//TODO: validate what this is const Upgrade = new Schema({ UpgradeFingerprint: String, ItemType: String }); +Upgrade.virtual("ItemId").get(function () { + return { $oid: this._id.toString() } satisfies IOid; +}); + Upgrade.set("toJSON", { - transform(_document, returnedObject) { - // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call - returnedObject.ItemId = { $oid: returnedObject._id.toString() } satisfies IOid; - delete returnedObject._id; - delete returnedObject.__v; - } -}); - -WeaponSchema.set("toJSON", { - transform(_document, returnedObject) { - // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call - returnedObject.ItemId = { $oid: returnedObject._id.toString() } satisfies IOid; - delete returnedObject._id; - delete returnedObject.__v; - } -}); - -const polaritySchema = new Schema({ - Slot: Number, - Value: String -}); - -const suitConfigSchema = new Schema({ - Skins: [String], - pricol: colorSchema, - attcol: colorSchema, - eyecol: colorSchema, - sigcol: colorSchema, - Upgrades: [String], - Songs: [ - { - m: String, - b: String, - p: String, - s: String - } - ], - Name: String, - AbilityOverride: abilityOverrideSchema, - PvpUpgrades: [String], - ugly: Boolean -}); - -suitConfigSchema.set("toJSON", { + virtuals: true, transform(_document, returnedObject) { delete returnedObject._id; delete returnedObject.__v; } }); -const suitSchema = new Schema({ - ItemType: String, - Configs: { - type: [suitConfigSchema], - default: [{}, {}, {}] +//TODO: reduce weapon and suit schemas to one schema if reasonable +const suitSchema = new Schema( + { + ItemType: String, + Configs: [ItemConfigSchema], + UpgradeVer: Number, + XP: Number, + InfestationDate: Date, + Features: Number, + Polarity: [polaritySchema], + Polarized: Number, + ModSlotPurchases: Number, + FocusLens: String, + UnlockLevel: Number }, - UpgradeVer: Number, - XP: Number, - InfestationDate: Date, - Features: Number, - Polarity: [polaritySchema], - Polarized: Number, - ModSlotPurchases: Number, - FocusLens: String, - UnlockLevel: Number + { id: false } +); + +suitSchema.virtual("ItemId").get(function () { + return { $oid: this._id.toString() } satisfies IOid; }); suitSchema.set("toJSON", { + virtuals: true, transform(_document, returnedObject) { - // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call - returnedObject.ItemId = { $oid: returnedObject._id.toString() } satisfies IOid; delete returnedObject._id; delete returnedObject.__v; } }); -const slotsBinSchema = new Schema( +const slotsBinSchema = new Schema( { Slots: Number }, @@ -305,7 +335,7 @@ const inventorySchema = new Schema({ BountyScore: Number, ChallengeInstanceStates: [Schema.Types.Mixed], LoginMilestoneRewards: [String], - OperatorLoadOuts: [Schema.Types.Mixed], + OperatorLoadOuts: [operatorConfigSchema], DailyAffiliationVentkids: Number, DailyAffiliationVox: Number, RecentVendorPurchases: [Schema.Types.Mixed], @@ -342,7 +372,7 @@ const inventorySchema = new Schema({ CrewShipHarnesses: [Schema.Types.Mixed], CrewShipRawSalvage: [Schema.Types.Mixed], CrewMembers: [Schema.Types.Mixed], - AdultOperatorLoadOuts: [Schema.Types.Mixed], + AdultOperatorLoadOuts: [operatorConfigSchema], LotusCustomization: Schema.Types.Mixed, UseAdultOperatorLoadout: Boolean, DailyAffiliationZariman: Number, @@ -363,7 +393,10 @@ const inventorySchema = new Schema({ HasResetAccount: Boolean, PendingCoupon: Schema.Types.Mixed, Harvestable: Boolean, - DeathSquadable: Boolean + DeathSquadable: Boolean, + Horses: [Schema.Types.Mixed], + DrifterMelee: [Schema.Types.Mixed], + KahlLoadOuts: [Schema.Types.Mixed] }); inventorySchema.set("toJSON", { @@ -390,9 +423,11 @@ type InventoryDocumentProps = { RawUpgrades: Types.DocumentArray; MiscItems: Types.DocumentArray; Boosters: Types.DocumentArray; + OperatorLoadOuts: Types.DocumentArray; + AdultOperatorLoadOuts: Types.DocumentArray; }; -type InventoryModelType = Model; +type InventoryModelType = Model; const Inventory = model("Inventory", inventorySchema); diff --git a/src/models/inventoryModels/loadoutModel.ts b/src/models/inventoryModels/loadoutModel.ts index 44082497..37a8d104 100644 --- a/src/models/inventoryModels/loadoutModel.ts +++ b/src/models/inventoryModels/loadoutModel.ts @@ -53,7 +53,7 @@ loadoutConfigSchema.set("toJSON", { } }); -const loadoutSchema = new Schema({ +export const loadoutSchema = new Schema({ NORMAL: [loadoutConfigSchema], SENTINEL: [loadoutConfigSchema], ARCHWING: [loadoutConfigSchema], @@ -64,18 +64,15 @@ const loadoutSchema = new Schema({ DATAKNIFE: [loadoutConfigSchema], MECH: [loadoutConfigSchema], OPERATOR_ADULT: [loadoutConfigSchema], - DRIFTER: [loadoutConfigSchema] -}); - -loadoutSchema.virtual("ItemId").get(function (): string { - return this._id.toString(); + DRIFTER: [loadoutConfigSchema], + loadoutOwnerId: Schema.Types.ObjectId }); loadoutSchema.set("toJSON", { - virtuals: true, transform(_doc, ret, _options) { delete ret._id; delete ret.__v; + delete ret.loadoutOwnerId; } }); diff --git a/src/models/shipModel.ts b/src/models/shipModel.ts index bd56d933..4b16ebd2 100644 --- a/src/models/shipModel.ts +++ b/src/models/shipModel.ts @@ -1,6 +1,7 @@ import { Schema, model } from "mongoose"; import { IShip } from "../types/shipTypes"; import { IOid } from "../types/commonTypes"; +import { loadoutSchema } from "@/src/models/inventoryModels/loadoutModel"; const roomSchema = new Schema( { @@ -10,16 +11,22 @@ const roomSchema = new Schema( { _id: false } ); -const shipSchema = new Schema({ - Rooms: [roomSchema], - Features: [String], - ContentUrlSignature: String +const shipSchema = new Schema( + { + Rooms: [roomSchema], + Features: [String], + ContentUrlSignature: String + }, + { id: false } +); + +shipSchema.virtual("ShipId").get(function () { + return { $oid: this._id.toString() } satisfies IOid; }); shipSchema.set("toJSON", { + virtuals: true, transform(_document, returnedObject) { - // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call - returnedObject.ShipId = { $oid: returnedObject._id.toString() } satisfies IOid; delete returnedObject._id; } }); @@ -35,10 +42,16 @@ apartmentSchema.set("toJSON", { } }); -const shipDatabaseSchema = new Schema({ +const shipDatabaseSchema = new Schema({ ShipOwnerId: Schema.Types.ObjectId, Ship: shipSchema, - Apartment: apartmentSchema + Apartment: apartmentSchema, + LoadOutInventory: { + LoadOutPresets: { + type: Schema.Types.ObjectId, + ref: "Loadout" + } + } }); shipDatabaseSchema.set("toJSON", { diff --git a/src/services/inventoryService.ts b/src/services/inventoryService.ts index 1edb4acf..534dbfa8 100644 --- a/src/services/inventoryService.ts +++ b/src/services/inventoryService.ts @@ -2,9 +2,9 @@ import { Inventory } from "@/src/models/inventoryModels/inventoryModel"; import new_inventory from "@/static/fixed_responses/postTutorialInventory.json"; import config from "@/config.json"; import { Types } from "mongoose"; -import { ISuitDatabase, ISuitResponse } from "@/src/types/inventoryTypes/SuitTypes"; +import { ISuitDatabase, ISuitClient } from "@/src/types/inventoryTypes/SuitTypes"; import { SlotType } from "@/src/types/purchaseTypes"; -import { IWeaponDatabase, IWeaponResponse } from "@/src/types/inventoryTypes/weaponTypes"; +import { IWeaponDatabase, IWeaponClient } from "@/src/types/inventoryTypes/weaponTypes"; import { IChallengeProgress, IConsumable, @@ -17,9 +17,13 @@ import { import { IGenericUpdate } from "../types/genericUpdate"; import { IArtifactsRequest, IMissionInventoryUpdateRequest } from "../types/requestTypes"; -const createInventory = async (accountOwnerId: Types.ObjectId) => { +const createInventory = async (accountOwnerId: Types.ObjectId, loadOutPresetId: Types.ObjectId) => { try { - const inventory = new Inventory({ ...new_inventory, accountOwnerId: accountOwnerId }); + const inventory = new Inventory({ + ...new_inventory, + accountOwnerId: accountOwnerId, + LoadOutPresets: loadOutPresetId + }); if (config.skipStoryModeChoice) { inventory.StoryModeChoice = "WARFRAME"; } @@ -27,6 +31,7 @@ const createInventory = async (accountOwnerId: Types.ObjectId) => { inventory.PlayedParkourTutorial = true; inventory.ReceivedStartingGear = true; } + await inventory.save(); } catch (error) { if (error instanceof Error) { @@ -48,7 +53,7 @@ export const getInventory = async (accountOwnerId: string) => { return inventory; }; -const addPowerSuit = async (powersuitName: string, accountId: string): Promise => { +const addPowerSuit = async (powersuitName: string, accountId: string): Promise => { const inventory = await getInventory(accountId); const suitIndex = inventory.Suits.push({ ItemType: powersuitName, Configs: [], UpgradeVer: 101, XP: 0 }); const changedInventory = await inventory.save(); @@ -107,7 +112,7 @@ export const addWeapon = async ( weaponType: WeaponTypeInternal, weaponName: string, accountId: string -): Promise => { +): Promise => { const inventory = await getInventory(accountId); let weaponIndex; @@ -139,7 +144,7 @@ export const addCustomization = async (customizatonName: string, accountId: stri const addGearExpByCategory = ( inventory: IInventoryDatabaseDocument, - gearArray: ISuitDatabase[] | IWeaponDatabase[] | undefined, + gearArray: ISuitClient[] | IWeaponClient[] | undefined, categoryName: "Pistols" | "LongGuns" | "Melee" | "Suits" ) => { const category = inventory[categoryName]; @@ -242,7 +247,6 @@ const addMissionComplete = (inventory: IInventoryDatabaseDocument, { Tag, Comple }; const gearKeys = ["Suits", "Pistols", "LongGuns", "Melee"] as const; -type GearKeysType = (typeof gearKeys)[number]; export const missionInventoryUpdate = async (data: IMissionInventoryUpdateRequest, accountId: string) => { const { RawUpgrades, MiscItems, RegularCredits, ChallengeProgress, FusionPoints, Consumables, Recipes, Missions } = @@ -256,7 +260,7 @@ export const missionInventoryUpdate = async (data: IMissionInventoryUpdateReques inventory.FusionPoints += FusionPoints || 0; // Gear XP - gearKeys.forEach((key: GearKeysType) => addGearExpByCategory(inventory, data[key], key)); + gearKeys.forEach(key => addGearExpByCategory(inventory, data[key], key)); // other addMods(inventory, RawUpgrades); diff --git a/src/services/loginService.ts b/src/services/loginService.ts index 9e7959f0..1753c85b 100644 --- a/src/services/loginService.ts +++ b/src/services/loginService.ts @@ -2,6 +2,8 @@ import { Account } from "@/src/models/loginModel"; import { createInventory } from "@/src/services/inventoryService"; import { IDatabaseAccount } from "@/src/types/loginTypes"; import { createShip } from "./shipService"; +import { Types } from "mongoose"; +import { LoadoutModel } from "@/src/models/inventoryModels/loadoutModel"; const isCorrectPassword = (requestPassword: string, databasePassword: string): boolean => { return requestPassword === databasePassword; @@ -11,8 +13,9 @@ const createAccount = async (accountData: IDatabaseAccount) => { const account = new Account(accountData); try { await account.save(); - await createInventory(account._id); - await createShip(account._id); + const loadoutId = await createLoadout(account._id); + await createInventory(account._id, loadoutId); + await createShip(account._id, loadoutId); return account.toJSON(); } catch (error) { if (error instanceof Error) { @@ -23,3 +26,9 @@ const createAccount = async (accountData: IDatabaseAccount) => { }; export { isCorrectPassword, createAccount }; + +export const createLoadout = async (accountId: Types.ObjectId) => { + const loadout = new LoadoutModel({ loadoutOwnerId: accountId }); + const savedLoadout = await loadout.save(); + return savedLoadout._id; +}; diff --git a/src/services/saveLoadoutService.ts b/src/services/saveLoadoutService.ts index e69de29b..d47254e9 100644 --- a/src/services/saveLoadoutService.ts +++ b/src/services/saveLoadoutService.ts @@ -0,0 +1,179 @@ +import { + IItemEntry, + ILoadoutClient, + ILoadoutEntry, + IOperatorConfigEntry, + ISaveLoadoutRequestNoUpgradeVer +} from "@/src/types/saveLoadoutTypes"; +import { LoadoutModel } from "@/src/models/inventoryModels/loadoutModel"; +import { getInventory } from "@/src/services/inventoryService"; +import { IOid } from "@/src/types/commonTypes"; + +export const isEmptyObject = (obj: unknown): boolean => { + return Boolean(obj && Object.keys(obj).length === 0 && obj.constructor === Object); +}; + +//setup default items on account creation or like originally in giveStartingItems.php + +//export const updateLoadout = (loadout: ISaveLoadoutRequest, accountId: string) => {}; + +//support multiple loadouts and multiple items and multiple configs per item +export const handleInventoryItemConfigChange = async ( + equipmentChanges: ISaveLoadoutRequestNoUpgradeVer, + accountId: string +) => { + for (const [_equipmentName, _equipment] of Object.entries(equipmentChanges)) { + const equipment = _equipment as ISaveLoadoutRequestNoUpgradeVer[keyof ISaveLoadoutRequestNoUpgradeVer]; + const equipmentName = _equipmentName as keyof ISaveLoadoutRequestNoUpgradeVer; + + if (isEmptyObject(equipment)) { + continue; + } + // non-empty is a change in loadout(or suit...) + + switch (equipmentName) { + case "OperatorLoadOuts": + case "AdultOperatorLoadOuts": { + console.log("loadout received", equipmentName); + + const inventory = await getInventory(accountId); + const operatorConfig = equipment as IOperatorConfigEntry; + const operatorLoadout = inventory[equipmentName]; + + // all non-empty entries are one loadout slot + for (const [loadoutId, loadoutConfig] of Object.entries(operatorConfig)) { + // console.log("loadoutId", loadoutId, "loadoutconfig", loadoutConfig); + const loadout = operatorLoadout.find(loadout => loadout._id?.toString() === loadoutId); + + // if no config with this id exists, create a new one + if (!loadout) { + const { ItemId, ...loadoutConfigItemIdRemoved } = loadoutConfig; + operatorLoadout.push({ + _id: ItemId.$oid, + ...loadoutConfigItemIdRemoved + }); + await inventory.save(); + continue; + } + loadout.set(loadoutConfig); + + //({ _id: loadoutId }, loadoutConfig); + } + await inventory.save(); + break; + } + case "LoadOuts": { + console.log("loadout received"); + + for (const [_loadoutSlot, _loadout] of Object.entries(equipment)) { + const loadoutSlot = _loadoutSlot as keyof ILoadoutClient; + const newLoadout = _loadout as ILoadoutEntry; + + //console.log("key", loadoutSlot, "value", loadout); + + // empty loadout slot like: "NORMAL": {} + if (isEmptyObject(newLoadout)) { + continue; + } + + const loadout = await LoadoutModel.findOne({ loadoutOwnerId: accountId }); + //const {, ...loadout } = loadoutWithLoadoutOwnerId; + + if (!loadout) { + throw new Error("loadout not found"); + } + // all non-empty entries are one loadout slot + for (const [loadoutId, loadoutConfig] of Object.entries(newLoadout)) { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + //const { loadoutOwnerId, ...loadout } = loadoutWithLoadoutOwnerId; + // console.log("loadoutId", loadoutId, "loadoutconfig", loadoutConfig); + + const oldLoadoutConfig = loadout[loadoutSlot].find( + loadout => loadout._id.toString() === loadoutId + ); + + // if no config with this id exists, create a new one + if (!oldLoadoutConfig) { + const { ItemId, ...loadoutConfigItemIdRemoved } = loadoutConfig; + loadout[loadoutSlot].push({ + _id: ItemId.$oid, + ...loadoutConfigItemIdRemoved + }); + await loadout.save(); + continue; + } + + const loadoutIndex = loadout[loadoutSlot].indexOf(oldLoadoutConfig); + + if (loadoutIndex === undefined || loadoutIndex === -1) { + throw new Error("loadout index not found"); + } + + //console.log("parent id", oldLoadoutConfig.ownerDocument()._id); + loadout[loadoutSlot][loadoutIndex].set(loadoutConfig); + //loadout.NORMAL[loadoutIndex].overwrite(loadoutConfig); + //console.log("db", loadout[loadoutSlot][loadoutIndex].schema); + + await loadout.save(); + //({ _id: loadoutId }, loadoutConfig); + } + } + break; + } + case "LongGuns": + case "Pistols": + case "Suits": + case "Melee": { + console.log("? ???? ?", equipmentName, equipment); + + const itemEntry = equipment as IItemEntry; + const inventory = await getInventory(accountId); + for (const [itemId, itemConfig] of Object.entries(itemEntry)) { + const inventoryItem = inventory[equipmentName].find(item => item._id.toString() === itemId); + + if (!inventoryItem) { + throw new Error(`inventory item ${equipmentName} not found with id ${itemId}`); + } + + //config ids are 0,1,2 can there be a 3? + for (const [configId, config] of Object.entries(itemConfig)) { + inventoryItem.Configs[parseInt(configId)] = config; + } + } + await inventory.save(); + break; + } + case "CurrentLoadOutIds": { + //TODO: remove duplicate getInventory after finding out when currentloadOutId is sent + const loadoutIds = equipment as IOid[]; + const inventory = await getInventory(accountId); + inventory.CurrentLoadOutIds = loadoutIds; + await inventory.save(); + break; + } + default: { + console.log("category not implemented", equipmentName); + } + } + + //case "OperatorAmps": + // case "Sentinels": + // case "SentinelWeapons": + // case "KubrowPets": + // case "SpaceSuits": + // case "SpaceGuns": + // case "SpaceMelee": + // case "Scoops": + // case "SpecialItems": + // case "MoaPets": + // case "Hoverboards": + // case "DataKnives": + // case "MechSuits": + // case "CrewShipHarnesses": + // case "Horses": + // case "DrifterMelee": + + // case "CrewShips": + //case "KahlLoadOuts": not sure yet how to handle kahl: it is not sent in inventory + } +}; diff --git a/src/services/shipService.ts b/src/services/shipService.ts index bce95805..5b35cce3 100644 --- a/src/services/shipService.ts +++ b/src/services/shipService.ts @@ -2,9 +2,13 @@ import { Ship } from "@/src/models/shipModel"; import new_ship from "@/static/fixed_responses/ship.json"; import { Types } from "mongoose"; -const createShip = async (accountOwnerId: Types.ObjectId) => { +const createShip = async (accountOwnerId: Types.ObjectId, loadoutId: Types.ObjectId) => { try { - const ship = new Ship({ ...new_ship, ShipOwnerId: accountOwnerId }); + const ship = new Ship({ + ...new_ship, + ShipOwnerId: accountOwnerId, + LoadOutInventory: { LoadOutPresets: loadoutId } + }); await ship.save(); } catch (error) { if (error instanceof Error) { diff --git a/src/types/inventoryTypes/SuitTypes.ts b/src/types/inventoryTypes/SuitTypes.ts index dc71db19..fb63283a 100644 --- a/src/types/inventoryTypes/SuitTypes.ts +++ b/src/types/inventoryTypes/SuitTypes.ts @@ -1,20 +1,14 @@ import { IOid } from "@/src/types/commonTypes"; import { IAbilityOverride, IColor, IPolarity } from "@/src/types/inventoryTypes/commonInventoryTypes"; -import { Document, Types } from "mongoose"; +import { Types } from "mongoose"; -// export interface ISuitDocument extends ISuitResponse, Document {} -export interface ISuitDocument extends Document, ISuitResponse { - _id: Types.ObjectId; -} - -export interface ISuitResponse extends ISuitDatabase { +export interface ISuitClient extends ISuitDatabase { ItemId: IOid; - //should omit _id which is not present in response } export interface ISuitDatabase { ItemType: string; - Configs: SuitConfig[]; + Configs: IItemConfig[]; UpgradeVer?: number; XP?: number; InfestationDate?: Date; @@ -25,26 +19,43 @@ export interface ISuitDatabase { FocusLens?: string; UnlockLevel?: number; _id: Types.ObjectId; - ItemId?: IOid; } -export interface SuitConfig { - Skins?: string[]; +interface IItemConfigBase { + Skins: string[]; pricol?: IColor; attcol?: IColor; - eyecol?: IColor; sigcol?: IColor; + eyecol?: IColor; + facial?: IColor; + syancol?: IColor; + cloth?: IColor; Upgrades?: string[]; - Songs?: Song[]; Name?: string; + ugly?: boolean; +} + +export interface IItemConfig extends IItemConfigBase { + Songs?: ISong[]; AbilityOverride?: IAbilityOverride; PvpUpgrades?: string[]; ugly?: boolean; } -export interface Song { +export interface ISong { m?: string; b?: string; p?: string; s: string; } + +//TODO: Consider renaming it to loadout instead of config +export interface IOperatorConfigDatabase extends IItemConfigBase { + _id: Types.ObjectId; + AbilityOverride?: IAbilityOverride; // not present in adultOperator + OperatorAmp?: IOid; // not present in adultOperator +} + +export interface IOperatorConfigClient extends Omit { + ItemId: IOid; +} diff --git a/src/types/inventoryTypes/inventoryTypes.ts b/src/types/inventoryTypes/inventoryTypes.ts index 450b6e10..db0383f8 100644 --- a/src/types/inventoryTypes/inventoryTypes.ts +++ b/src/types/inventoryTypes/inventoryTypes.ts @@ -2,19 +2,33 @@ import { Document, Types } from "mongoose"; import { IOid, IMongoDate } from "../commonTypes"; import { IAbilityOverride, IColor, FocusSchool, IPolarity } from "@/src/types/inventoryTypes/commonInventoryTypes"; -import { ISuitDatabase } from "@/src/types/inventoryTypes/SuitTypes"; +import { IOperatorConfigClient, ISuitDatabase } from "@/src/types/inventoryTypes/SuitTypes"; import { IOperatorLoadOutSigcol, IWeaponDatabase } from "@/src/types/inventoryTypes/weaponTypes"; +import { IItemConfig } from "@/src/types/saveLoadoutTypes"; +//Document extends will be deleted soon. TODO: delete and migrate uses to ... export interface IInventoryDatabaseDocument extends IInventoryDatabase, Document {} -export interface IInventoryDatabase extends Omit { +export interface IInventoryDatabase extends Omit { accountOwnerId: Types.ObjectId; - TrainingDate: Date; + TrainingDate: Date; // TrainingDate changed from IMongoDate to Date + LoadOutPresets: Types.ObjectId; // LoadOutPresets changed from ILoadOutPresets to Types.ObjectId for population } export interface IInventoryResponseDocument extends IInventoryResponse, Document {} +export interface IGenericItem { + ItemType: string; + XP?: number; + Configs: IItemConfig[]; + UpgradeVer: number; + ItemId: IOid; +} + export interface IInventoryResponse { - DuviriInfo: { Seed: number; NumCompletions: number }; + KahlLoadOuts: IGenericItem[]; + DrifterMelee: IGenericItem[]; + Horses: IGenericItem[]; + DuviriInfo: { Seed: number; NumCompletions: number }; // TODO: add to schema SubscribedToEmails: number; Created: IMongoDate; RewardSeed: number; @@ -22,14 +36,14 @@ export interface IInventoryResponse { PremiumCredits: number; PremiumCreditsFree: number; FusionPoints: number; - SuitBin: ICrewShipSalvageBinClass; - WeaponBin: ICrewShipSalvageBinClass; - SentinelBin: ICrewShipSalvageBinClass; - SpaceSuitBin: ICrewShipSalvageBinClass; - SpaceWeaponBin: ICrewShipSalvageBinClass; + SuitBin: ISlots; + WeaponBin: ISlots; + SentinelBin: ISlots; + SpaceSuitBin: ISlots; + SpaceWeaponBin: ISlots; PvpBonusLoadoutBin: ICrewMemberBinClass; - PveBonusLoadoutBin: ICrewShipSalvageBinClass; - RandomModBin: ICrewShipSalvageBinClass; + PveBonusLoadoutBin: ISlots; + RandomModBin: ISlots; TradesRemaining: number; DailyAffiliation: number; DailyAffiliationPvp: number; @@ -103,7 +117,7 @@ export interface IInventoryResponse { ActiveAvatarImageType: string; KubrowPets: IKubrowPet[]; ShipDecorations: IConsumable[]; - OperatorAmpBin: ICrewShipSalvageBinClass; + OperatorAmpBin: ISlots; DailyAffiliationCetus: number; DailyAffiliationQuills: number; DiscoveredMarkers: IDiscoveredMarker[]; @@ -124,7 +138,7 @@ export interface IInventoryResponse { BountyScore: number; ChallengeInstanceStates: IChallengeInstanceState[]; LoginMilestoneRewards: string[]; - OperatorLoadOuts: IOperatorLoadOut[]; + OperatorLoadOuts: IOperatorConfigClient[]; DailyAffiliationVentkids: number; DailyAffiliationVox: number; RecentVendorPurchases: Array; @@ -141,7 +155,7 @@ export interface IInventoryResponse { Settings: ISettings; PersonalTechProjects: IPersonalTechProject[]; CrewShips: ICrewShip[]; - CrewShipSalvageBin: ICrewShipSalvageBinClass; + CrewShipSalvageBin: ISlots; PlayerSkills: IPlayerSkills; CrewShipAmmo: IConsumable[]; CrewShipSalvagedWeaponSkins: ICrewShipSalvagedWeaponSkin[]; @@ -161,7 +175,7 @@ export interface IInventoryResponse { CrewShipHarnesses: ICrewShipHarness[]; CrewShipRawSalvage: IConsumable[]; CrewMembers: ICrewMember[]; - AdultOperatorLoadOuts: IAdultOperatorLoadOut[]; + AdultOperatorLoadOuts: IOperatorConfigClient[]; LotusCustomization: ILotusCustomization; UseAdultOperatorLoadout: boolean; DailyAffiliationZariman: number; @@ -311,8 +325,8 @@ export interface ICrewShipHarnessConfig { Upgrades?: string[]; } -export interface ICrewShipSalvageBinClass { - Extra: number; +export interface ISlots { + Extra?: number; Slots: number; } @@ -624,6 +638,7 @@ export interface ILibraryPersonalProgress { Completed: boolean; } +//this needs to be checked against ILoadoutDatabase export interface ILoadOutPresets { NORMAL: INormal[]; NORMAL_PVP: IArchwing[]; @@ -871,7 +886,7 @@ export enum GivingSlotOrderInfo { LotusUpgradesModsPistolDualStatElectEventPistolMod = "/Lotus/Upgrades/Mods/Pistol/DualStat/ElectEventPistolMod" } -export interface PeriodicMissionCompletion { +export interface IPeriodicMissionCompletion { date: IMongoDate; tag: string; count?: number; diff --git a/src/types/inventoryTypes/weaponTypes.ts b/src/types/inventoryTypes/weaponTypes.ts index 365c869b..0d92ef6d 100644 --- a/src/types/inventoryTypes/weaponTypes.ts +++ b/src/types/inventoryTypes/weaponTypes.ts @@ -1,14 +1,15 @@ import { IOid } from "@/src/types/commonTypes"; -import { IColor, IPolarity } from "@/src/types/inventoryTypes/commonInventoryTypes"; +import { IItemConfig } from "@/src/types/inventoryTypes/SuitTypes"; +import { IPolarity } from "@/src/types/inventoryTypes/commonInventoryTypes"; import { Types } from "mongoose"; -export interface IWeaponResponse extends IWeaponDatabase { +export interface IWeaponClient extends Omit { ItemId: IOid; } export interface IWeaponDatabase { ItemType: string; - Configs: WeaponConfig[]; + Configs: IItemConfig[]; UpgradeVer?: number; XP?: number; Features?: number; @@ -21,18 +22,7 @@ export interface IWeaponDatabase { ItemName?: string; ModularParts?: string[]; UnlockLevel?: number; - _id?: Types.ObjectId; - ItemId?: IOid; -} - -export interface WeaponConfig { - Skins?: string[]; - pricol?: IColor; - Upgrades?: string[]; - attcol?: IColor; - eyecol?: IOperatorLoadOutSigcol; - Name?: string; - PvpUpgrades?: string[]; + _id: Types.ObjectId; } export interface IOperatorLoadOutSigcol { diff --git a/src/types/purchaseTypes.ts b/src/types/purchaseTypes.ts index 6df9719d..ca98dc95 100644 --- a/src/types/purchaseTypes.ts +++ b/src/types/purchaseTypes.ts @@ -1,6 +1,6 @@ import { ISuitDatabase } from "@/src/types/inventoryTypes/SuitTypes"; import { IFlavourItem } from "@/src/types/inventoryTypes/inventoryTypes"; -import { IWeaponResponse } from "@/src/types/inventoryTypes/weaponTypes"; +import { IWeaponClient } from "@/src/types/inventoryTypes/weaponTypes"; export interface IPurchaseRequest { PurchaseParams: IPurchaseParams; @@ -23,9 +23,9 @@ export interface IPurchaseResponse { SuitBin?: IBinChanges; WeaponBin?: IBinChanges; Suits?: ISuitDatabase[]; - LongGuns?: IWeaponResponse[]; - Pistols?: IWeaponResponse[]; - Melee?: IWeaponResponse[]; + LongGuns?: IWeaponClient[]; + Pistols?: IWeaponClient[]; + Melee?: IWeaponClient[]; PremiumCredits?: number; RegularCredits?: number; FlavourItems?: IFlavourItem[]; diff --git a/src/types/requestTypes.ts b/src/types/requestTypes.ts index 050955d9..ecbd35e0 100644 --- a/src/types/requestTypes.ts +++ b/src/types/requestTypes.ts @@ -7,8 +7,8 @@ import { IMission, IRawUpgrade } from "./inventoryTypes/inventoryTypes"; -import { IWeaponDatabase } from "./inventoryTypes/weaponTypes"; -import { ISuitDatabase } from "./inventoryTypes/SuitTypes"; +import { IWeaponClient } from "./inventoryTypes/weaponTypes"; +import { ISuitClient } from "./inventoryTypes/SuitTypes"; interface IArtifactsRequest { Upgrade: ICrewShipSalvagedWeaponSkin; @@ -20,10 +20,10 @@ interface IArtifactsRequest { interface IMissionInventoryUpdateRequest { rewardsMultiplier?: number; ActiveBoosters?: IBooster[]; - LongGuns?: IWeaponDatabase[]; - Pistols?: IWeaponDatabase[]; - Suits?: ISuitDatabase[]; - Melee?: IWeaponDatabase[]; + LongGuns?: IWeaponClient[]; + Pistols?: IWeaponClient[]; + Suits?: ISuitClient[]; + Melee?: IWeaponClient[]; RawUpgrades?: IRawUpgrade[]; MiscItems?: IMiscItem[]; Consumables?: IConsumable[]; diff --git a/src/types/saveLoadoutTypes.ts b/src/types/saveLoadoutTypes.ts index 92f496e9..5e630be5 100644 --- a/src/types/saveLoadoutTypes.ts +++ b/src/types/saveLoadoutTypes.ts @@ -1,64 +1,76 @@ import { IOid } from "@/src/types/commonTypes"; -import { Document, Mongoose, Types } from "mongoose"; +import { IItemConfig, IOperatorConfigClient } from "@/src/types/inventoryTypes/SuitTypes"; +import { Types } from "mongoose"; export interface ISaveLoadoutRequest { - LoadOuts: ILoadoutRequest; - LongGuns: IConfigEntry; - OperatorAmps: IConfigEntry; - Pistols: IConfigEntry; - Suits: IConfigEntry; - Melee: IConfigEntry; - Sentinels: IConfigEntry; - SentinelWeapons: IConfigEntry; - KubrowPets: IConfigEntry; - SpaceSuits: IConfigEntry; - SpaceGuns: IConfigEntry; - SpaceMelee: IConfigEntry; - Scoops: IConfigEntry; - SpecialItems: IConfigEntry; - MoaPets: IConfigEntry; - Hoverboards: IConfigEntry; - DataKnives: IConfigEntry; - MechSuits: IConfigEntry; - CrewShipHarnesses: IConfigEntry; - Horses: IConfigEntry; - DrifterMelee: IConfigEntry; + LoadOuts: ILoadoutClient; + LongGuns: IItemEntry; + OperatorAmps: IItemEntry; + Pistols: IItemEntry; + Suits: IItemEntry; + Melee: IItemEntry; + Sentinels: IItemEntry; + SentinelWeapons: IItemEntry; + KubrowPets: IItemEntry; + SpaceSuits: IItemEntry; + SpaceGuns: IItemEntry; + SpaceMelee: IItemEntry; + Scoops: IItemEntry; + SpecialItems: IItemEntry; + MoaPets: IItemEntry; + Hoverboards: IItemEntry; + DataKnives: IItemEntry; + MechSuits: IItemEntry; + CrewShipHarnesses: IItemEntry; + Horses: IItemEntry; + DrifterMelee: IItemEntry; UpgradeVer: number; - OperatorLoadOuts: IConfigEntry; - AdultOperatorLoadOuts: IConfigEntry; - KahlLoadOuts: IConfigEntry; - CrewShips: IConfigEntry; + OperatorLoadOuts: IOperatorConfigEntry; + AdultOperatorLoadOuts: IOperatorConfigEntry; + KahlLoadOuts: IItemEntry; + CrewShips: IItemEntry; + CurrentLoadOutIds: IOid[]; + ValidNewLoadoutId: string; } export interface ISaveLoadoutRequestNoUpgradeVer extends Omit {} +export interface IOperatorConfigEntry { + [configId: string]: IOperatorConfigClient; +} + +export interface IItemEntry { + [itemId: string]: IConfigEntry; +} + export interface IConfigEntry { - [key: string]: Config; + [configId: string]: IItemConfig; } -export interface ILoadoutRequest extends Omit {} - -export interface ILoadoutResponse extends ILoadoutDatabase { - ItemId: IOid; -} +export interface ILoadoutClient extends Omit {} export interface ILoadoutDatabase { - NORMAL: ILoadoutConfigDatabase; - SENTINEL: ILoadoutConfigDatabase; - ARCHWING: ILoadoutConfigDatabase; - NORMAL_PVP: ILoadoutConfigDatabase; - LUNARO: ILoadoutConfigDatabase; - OPERATOR: ILoadoutConfigDatabase; - KDRIVE: ILoadoutConfigDatabase; - DATAKNIFE: ILoadoutConfigDatabase; - MECH: ILoadoutConfigDatabase; - OPERATOR_ADULT: ILoadoutConfigDatabase; - DRIFTER: ILoadoutConfigDatabase; + NORMAL: ILoadoutEntry; + SENTINEL: ILoadoutEntry; + ARCHWING: ILoadoutEntry; + NORMAL_PVP: ILoadoutEntry; + LUNARO: ILoadoutEntry; + OPERATOR: ILoadoutEntry; + KDRIVE: ILoadoutEntry; + DATAKNIFE: ILoadoutEntry; + MECH: ILoadoutEntry; + OPERATOR_ADULT: ILoadoutEntry; + DRIFTER: ILoadoutEntry; + _id: Types.ObjectId; + loadoutOwnerId: Types.ObjectId; } -export interface ILoadoutKey { +export interface ILoadoutEntry { [key: string]: ILoadoutConfigClient; } +export interface ILoadoutConfigDatabase extends Omit { + _id: Types.ObjectId; +} // for request and response from and to client export interface ILoadoutConfigClient { @@ -72,70 +84,9 @@ export interface ILoadoutConfigClient { m: IEquipmentSelection; } -export interface ILoadoutConfigDatabase extends Omit { - _id: Types.ObjectId; -} - export interface IEquipmentSelection { ItemId: IOid; mod: number; cus: number; } - -export interface Config { - Upgrades: any[]; - PvpUpgrades: any[]; - Skins: string[]; - pricol: Pricol; - attcol: Pricol; - sigcol: Sigcol; - eyecol: Pricol; - facial: Pricol; - cloth: Pricol; - syancol: Pricol; - Songs: any[]; -} - -export interface Pricol { - t0: number; - t1: number; - t2: number; - t3: number; - m0: number; - m1: number; - en: number; -} - -export interface Sigcol { - t0: number; - t1: number; - m0: number; - en: number; -} - -export interface Col { - t0: number; - t1: number; - t2: number; - t3: number; - m0?: number; - m1?: number; - en: number; - e1?: number; -} - -export type EquipmentCategories = - | { LoadOuts: { [key in keyof ILoadoutRequest]: LoadOut } } - | { LongGuns: Config } - | { OperatorAmps: Config } // Replace 'any' with the actual type - | { Pistols: Config } // Replace 'any' with the actual type - | { Suits: { [key: string]: Config } } - | { Melee: Config } // Replace 'any' with the actual type - | { Sentinels: Config } // Replace 'any' with the actual type - | { SentinelWeapons: Config } // Replace 'any' with the actual type - // Add other categories based on your needs - | { UpgradeVer: number } - | { OperatorLoadOuts: Config } // Replace 'any' with the actual type - | { AdultOperatorLoadOuts: Config } // Replace 'any' with the actual type - | { KahlLoadOuts: Config } // Replace 'any' with the actual type - | { CrewShips: Config }; // Replace 'any' with the actual type +export { IItemConfig }; diff --git a/src/types/shipTypes.ts b/src/types/shipTypes.ts index aac1ef27..522837e5 100644 --- a/src/types/shipTypes.ts +++ b/src/types/shipTypes.ts @@ -3,26 +3,28 @@ import { IOid } from "@/src/types/commonTypes"; export interface IShip { ShipOwnerId: Types.ObjectId; - Ship: IShipClassResponse; - Apartment: IApartmentClass; + Ship: IShipResponse; + Apartment: IApartment; + LoadOutInventory: { LoadOutPresets: Types.ObjectId }; } -export interface IShipClassResponse extends IShipClassDatabase { +export interface IShipResponse extends IShipDatabase { ShipId: IOid; } -export interface IShipClassDatabase { - Rooms: IRoomsClass[]; +export interface IShipDatabase { + Rooms: IRooms[]; Features: string[]; ContentUrlSignature: string; } -export interface IRoomsClass { +// TODO: add Apartment.Gardening +export interface IRooms { Name: string; MaxCapacity: number; } -export interface IApartmentClass { - Rooms: IRoomsClass[]; +export interface IApartment { + Rooms: IRooms[]; FavouriteLoadouts: string[]; } -- 2.47.2 From ee6f9cb985b0c6f629e571e2ab9be08490c8067e Mon Sep 17 00:00:00 2001 From: Ordis <134585663+OrdisPrime@users.noreply.github.com> Date: Thu, 14 Dec 2023 14:44:45 +0100 Subject: [PATCH 08/11] working --- package-lock.json | 6 +- src/controllers/api/focusController.ts | 6 + .../api/genericUpdateController.ts | 32 ++-- src/controllers/api/getShipController.ts | 71 ++++++++ src/controllers/api/inventoryController.ts | 1 - src/controllers/api/loginController.ts | 2 +- src/controllers/api/saveLoadout.ts | 15 +- .../api/setBootLocationController.ts | 6 + src/controllers/api/viewController.ts | 8 - src/controllers/stats/viewController.ts | 3 +- src/helpers/inventoryHelpers.ts | 8 +- src/models/inventoryModels/inventoryModel.ts | 154 +++++++++++++----- src/routes/api.ts | 6 +- src/routes/stats.ts | 2 +- src/services/inventoryService.ts | 24 ++- src/services/purchaseService.ts | 44 ++++- src/services/saveLoadoutService.ts | 49 ++++-- src/types/inventoryTypes/SuitTypes.ts | 43 +---- .../inventoryTypes/commonInventoryTypes.ts | 44 +++++ src/types/inventoryTypes/inventoryTypes.ts | 143 +++++----------- src/types/inventoryTypes/weaponTypes.ts | 2 +- src/types/purchaseTypes.ts | 3 +- src/types/saveLoadoutTypes.ts | 4 +- .../postTutorialInventory.json | 21 ++- static/fixed_responses/testQuestKeys.json | 30 ++++ 25 files changed, 473 insertions(+), 254 deletions(-) create mode 100644 src/controllers/api/focusController.ts create mode 100644 src/controllers/api/setBootLocationController.ts delete mode 100644 src/controllers/api/viewController.ts diff --git a/package-lock.json b/package-lock.json index fdd59437..de59907c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -327,9 +327,9 @@ } }, "node_modules/@types/express": { - "version": "4.17.20", - "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.20.tgz", - "integrity": "sha512-rOaqlkgEvOW495xErXMsmyX3WKBInbhG5eqojXYi3cGUaLoRDlXa5d52fkfWZT963AZ3v2eZ4MbKE6WpDAGVsw==", + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz", + "integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==", "dev": true, "dependencies": { "@types/body-parser": "*", diff --git a/src/controllers/api/focusController.ts b/src/controllers/api/focusController.ts new file mode 100644 index 00000000..f5d945fc --- /dev/null +++ b/src/controllers/api/focusController.ts @@ -0,0 +1,6 @@ +import { Handler } from "express"; + +export const focusController: Handler = (_req, _res) => { + //console.log("focusController", req.query); + _res.sendStatus(400); +}; diff --git a/src/controllers/api/genericUpdateController.ts b/src/controllers/api/genericUpdateController.ts index 63453c94..f77e366f 100644 --- a/src/controllers/api/genericUpdateController.ts +++ b/src/controllers/api/genericUpdateController.ts @@ -3,26 +3,24 @@ import { IGenericUpdate } from "@/src/types/genericUpdate"; import { RequestHandler } from "express"; // TODO: Nightwave evidence submission support is the only thing missing. -// TODO: Also, you might want to test this, because I definitely didn't. -const genericUpdateController: RequestHandler = async (request, response) => { - const accountId = request.query.accountId as string; +// TODO: this was added by someone without testing. It may not work. +// eslint-disable-next-line @typescript-eslint/no-misused-promises +const genericUpdateController: RequestHandler = async (_request, response) => { + // const accountId = request.query.accountId as string; - const [body] = String(request.body).split("\n"); + // const [body] = String(request.body).split("\n"); - let reply = {}; - try { - const update = JSON.parse(body) as IGenericUpdate; - if (typeof update !== "object") { - throw new Error("Invalid data format"); - } + // let reply = {}; + // try { + // const update = JSON.parse(body) as IGenericUpdate; + // if (typeof update !== "object") { + // throw new Error("Invalid data format"); + // } - reply = await updateGeneric(update, accountId); - } catch (err) { - console.error("Error parsing JSON data:", err); - } - - // Response support added for when Nightwave is supported below. - // response.json(reply); + // reply = await updateGeneric(update, accountId); + // } catch (err) { + // console.error("Error parsing JSON data:", err); + // } response.json({}); }; diff --git a/src/controllers/api/getShipController.ts b/src/controllers/api/getShipController.ts index 18e99d2f..b0501365 100644 --- a/src/controllers/api/getShipController.ts +++ b/src/controllers/api/getShipController.ts @@ -13,6 +13,77 @@ const getShipController: RequestHandler = async (req, res) => { res.status(500).json({ error: "error finding a corresponding ship" }); return; } + + ship.Ship.Features = [ + "/Lotus/Types/Items/ShipFeatureItems/AdvancedOrdisFeatureItem", + "/Lotus/Types/Items/ShipFeatureItems/AlchemyRoomFeatureItem", + "/Lotus/Types/Items/ShipFeatureItems/AlertsFeatureItem", + "/Lotus/Types/Items/ShipFeatureItems/ArsenalFeatureItem", + "/Lotus/Types/Items/ShipFeatureItems/CeresNavigationFeatureItem", + "/Lotus/Types/Items/ShipFeatureItems/ClanFeatureItem", + "/Lotus/Types/Items/ShipFeatureItems/EarthNavigationFeatureItem", + "/Lotus/Types/Items/ShipFeatureItems/EidolonArchwingFoundryUpgradeFeatureBlueprint", + "/Lotus/Types/Items/ShipFeatureItems/EidolonArchwingFoundryUpgradeFeatureItem", + "/Lotus/Types/Items/ShipFeatureItems/ErisNavigationFeatureItem", + "/Lotus/Types/Items/ShipFeatureItems/EuropaNavigationFeatureItem", + "/Lotus/Types/Items/ShipFeatureItems/FoundryConcurrentBuildFormaFeatureItem", + "/Lotus/Types/Items/ShipFeatureItems/FoundryFeatureItem", + "/Lotus/Types/Items/ShipFeatureItems/FoundryVesselUpgradeFeatureBlueprint", + "/Lotus/Types/Items/ShipFeatureItems/FoundryVesselUpgradeFeatureItem", + "/Lotus/Types/Items/ShipFeatureItems/GeneticFoundryCatbrowUpgradeFeatureBlueprint", + "/Lotus/Types/Items/ShipFeatureItems/GeneticFoundryCatbrowUpgradeFeatureItem", + "/Lotus/Types/Items/ShipFeatureItems/GeneticFoundryFeatureItem", + "/Lotus/Types/Items/ShipFeatureItems/GeneticFoundryUpgradeFeatureBlueprint", + "/Lotus/Types/Items/ShipFeatureItems/GeneticFoundryUpgradeFeatureItem", + "/Lotus/Types/Items/ShipFeatureItems/InfestedFoundryArchonShardBlueprint", + "/Lotus/Types/Items/ShipFeatureItems/InfestedFoundryArchonShardFeatureItem", + "/Lotus/Types/Items/ShipFeatureItems/InfestedFoundryBlueprint", + "/Lotus/Types/Items/ShipFeatureItems/InfestedFoundryItem", + "/Lotus/Types/Items/ShipFeatureItems/InfestedFoundryUpgradeBlueprint", + "/Lotus/Types/Items/ShipFeatureItems/InfestedFoundryUpgradeFeatureItem", + "/Lotus/Types/Items/ShipFeatureItems/JupiterNavigationFeatureItem", + "/Lotus/Types/Items/ShipFeatureItems/MarketTierOneFeatureItem", + "/Lotus/Types/Items/ShipFeatureItems/MarketTierTwoFeatureItem", + "/Lotus/Types/Items/ShipFeatureItems/MarsNavigationFeatureItem", + "/Lotus/Types/Items/ShipFeatureItems/MercuryNavigationFeatureItem", + "/Lotus/Types/Items/ShipFeatureItems/ModsFeatureItem", + "/Lotus/Types/Items/ShipFeatureItems/ModsFusionFeatureItem", + "/Lotus/Types/Items/ShipFeatureItems/ModsTransmuteFeatureItem", + "/Lotus/Types/Items/ShipFeatureItems/NeptuneNavigationFeatureItem", + "/Lotus/Types/Items/ShipFeatureItems/PersonalQuartersFeatureBlueprint", + "/Lotus/Types/Items/ShipFeatureItems/PersonalQuartersFeatureItem", + "/Lotus/Types/Items/ShipFeatureItems/PhobosNavigationFeatureItem", + "/Lotus/Types/Items/ShipFeatureItems/PlutoNavigationFeatureItem", + "/Lotus/Types/Items/ShipFeatureItems/Railjack/DamagedRailjackHoodBraceFeatureItem", + "/Lotus/Types/Items/ShipFeatureItems/Railjack/DamagedRailjackHoodFeatureItem", + "/Lotus/Types/Items/ShipFeatureItems/Railjack/DamagedRailjackHullFeatureItem", + "/Lotus/Types/Items/ShipFeatureItems/Railjack/DamagedRailjackNacelleLeftFeatureItem", + "/Lotus/Types/Items/ShipFeatureItems/Railjack/DamagedRailjackNacelleRightFeatureItem", + "/Lotus/Types/Items/ShipFeatureItems/Railjack/DamagedRailjackTailFeatureItem", + "/Lotus/Types/Items/ShipFeatureItems/Railjack/RailjackHoodBraceFeatureItem", + "/Lotus/Types/Items/ShipFeatureItems/Railjack/RailjackHoodBraceFeatureItemBlueprint", + "/Lotus/Types/Items/ShipFeatureItems/Railjack/RailjackHoodFeatureItem", + "/Lotus/Types/Items/ShipFeatureItems/Railjack/RailjackHoodFeatureItemBlueprint", + "/Lotus/Types/Items/ShipFeatureItems/Railjack/RailjackHullFeatureItem", + "/Lotus/Types/Items/ShipFeatureItems/Railjack/RailjackHullFeatureItemBlueprint", + "/Lotus/Types/Items/ShipFeatureItems/Railjack/RailjackNacelleLeftFeatureItem", + "/Lotus/Types/Items/ShipFeatureItems/Railjack/RailjackNacelleLeftFeatureItemBlueprint", + "/Lotus/Types/Items/ShipFeatureItems/Railjack/RailjackNacelleRightFeatureItem", + "/Lotus/Types/Items/ShipFeatureItems/Railjack/RailjackNacelleRightFeatureItemBlueprint", + "/Lotus/Types/Items/ShipFeatureItems/Railjack/RailjackTailFeatureItem", + "/Lotus/Types/Items/ShipFeatureItems/Railjack/RailjackTailFeatureItemBlueprint", + "/Lotus/Types/Items/ShipFeatureItems/RailjackCephalonShipFeatureItem", + "/Lotus/Types/Items/ShipFeatureItems/RailjackKeyShipFeatureItem", + "/Lotus/Types/Items/ShipFeatureItems/SaturnNavigationFeatureItem", + "/Lotus/Types/Items/ShipFeatureItems/SednaNavigationFeatureItem", + "/Lotus/Types/Items/ShipFeatureItems/ShipFeatureItem", + "/Lotus/Types/Items/ShipFeatureItems/SocialMenuFeatureItem", + "/Lotus/Types/Items/ShipFeatureItems/SolarChartFeatureItem", + "/Lotus/Types/Items/ShipFeatureItems/UranusNavigationFeatureItem", + "/Lotus/Types/Items/ShipFeatureItems/VenusNavigationFeatureItem", + "/Lotus/Types/Items/ShipFeatureItems/VoidProjectionFeatureItem" + ]; + res.json(ship); }; diff --git a/src/controllers/api/inventoryController.ts b/src/controllers/api/inventoryController.ts index 77ae6372..c12387a9 100644 --- a/src/controllers/api/inventoryController.ts +++ b/src/controllers/api/inventoryController.ts @@ -31,7 +31,6 @@ const inventoryController: RequestHandler = async (request: Request, response: R if (config.testMission) inventoryResponse.Missions = testMissions; if (config.testQuestKey) inventoryResponse.QuestKeys = testQuestKeys; - inventoryResponse.DuviriInfo = { Seed: -123123123123123123, NumCompletions: 0 }; response.json(inventoryResponse); }; diff --git a/src/controllers/api/loginController.ts b/src/controllers/api/loginController.ts index e48e6df0..e488f080 100644 --- a/src/controllers/api/loginController.ts +++ b/src/controllers/api/loginController.ts @@ -50,7 +50,7 @@ const loginController: RequestHandler = async (request, response) => { return; } catch (error: unknown) { if (error instanceof Error) { - throw new Error("error creating account"); + throw new Error("error creating account", error); } } } diff --git a/src/controllers/api/saveLoadout.ts b/src/controllers/api/saveLoadout.ts index 5aa4ccb4..d520c8d0 100644 --- a/src/controllers/api/saveLoadout.ts +++ b/src/controllers/api/saveLoadout.ts @@ -8,14 +8,17 @@ import { parseString } from "@/src/helpers/general"; const saveLoadoutController: RequestHandler = async (req, res) => { //validate here const accountId = parseString(req.query.accountId); - const body: ISaveLoadoutRequest = JSON.parse(req.body as string) as ISaveLoadoutRequest; - // console.log(util.inspect(body, { showHidden: false, depth: null, colors: true })); - // eslint-disable-next-line @typescript-eslint/no-unused-vars - const { UpgradeVer, ...equipmentChanges } = body; - await handleInventoryItemConfigChange(equipmentChanges, accountId); + try { + const body: ISaveLoadoutRequest = JSON.parse(req.body as string) as ISaveLoadoutRequest; + // console.log(util.inspect(body, { showHidden: false, depth: null, colors: true })); - res.status(200).end(); + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const { UpgradeVer, ...equipmentChanges } = body; + await handleInventoryItemConfigChange(equipmentChanges, accountId); + } catch (error) { + res.status(200).end(); + } }; export { saveLoadoutController }; diff --git a/src/controllers/api/setBootLocationController.ts b/src/controllers/api/setBootLocationController.ts new file mode 100644 index 00000000..a2e745bc --- /dev/null +++ b/src/controllers/api/setBootLocationController.ts @@ -0,0 +1,6 @@ +import { Request, Response } from "express"; + +export const setBootLocationController = (req: Request, res: Response) => { + console.log("setBootLocationController", req.query); + res.end(); +}; diff --git a/src/controllers/api/viewController.ts b/src/controllers/api/viewController.ts deleted file mode 100644 index e63d3b1a..00000000 --- a/src/controllers/api/viewController.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { RequestHandler } from "express"; -import view from "@/static/fixed_responses/view.json"; - -const viewController: RequestHandler = (_req, res) => { - res.json(view); -}; - -export { viewController }; diff --git a/src/controllers/stats/viewController.ts b/src/controllers/stats/viewController.ts index 4e988ccc..e63d3b1a 100644 --- a/src/controllers/stats/viewController.ts +++ b/src/controllers/stats/viewController.ts @@ -1,7 +1,8 @@ import { RequestHandler } from "express"; +import view from "@/static/fixed_responses/view.json"; const viewController: RequestHandler = (_req, res) => { - res.json({}); + res.json(view); }; export { viewController }; diff --git a/src/helpers/inventoryHelpers.ts b/src/helpers/inventoryHelpers.ts index 45b6ff14..517fcfd4 100644 --- a/src/helpers/inventoryHelpers.ts +++ b/src/helpers/inventoryHelpers.ts @@ -1,10 +1,14 @@ +import { IOid } from "@/src/types/commonTypes"; import { IInventoryDatabase, IInventoryResponse } from "@/src/types/inventoryTypes/inventoryTypes"; +import { Types } from "mongoose"; // a schema's toJSON is responsible for changing Oid and Date to their corresponding Response versions __id to "ItemId":{"$oid":"6450f720bc562ebf030222d4"}, and a Date to "date":{"$date":{"$numberLong":"unix timestamp"}) -const toInventoryResponse = (inventoryDatabase: IInventoryDatabase): IInventoryResponse => { +export const toInventoryResponse = (inventoryDatabase: IInventoryDatabase): IInventoryResponse => { // eslint-disable-next-line @typescript-eslint/no-unused-vars const { accountOwnerId, ...inventoryResponse } = inventoryDatabase; return inventoryResponse as unknown as IInventoryResponse; }; -export { toInventoryResponse }; +export const toOid = (objectId: Types.ObjectId) => { + return { $oid: objectId.toString() } satisfies IOid; +}; diff --git a/src/models/inventoryModels/inventoryModel.ts b/src/models/inventoryModels/inventoryModel.ts index 21aed851..deb3d10f 100644 --- a/src/models/inventoryModels/inventoryModel.ts +++ b/src/models/inventoryModels/inventoryModel.ts @@ -7,17 +7,23 @@ import { IBooster, IInventoryResponse, IInventoryDatabaseDocument, - ISlots + ISlots, + IGenericItem, + IMailbox, + IDuviriInfo } from "../../types/inventoryTypes/inventoryTypes"; import { IMongoDate, IOid } from "../../types/commonTypes"; -import { - IItemConfig, - ISuitDatabase, - IOperatorConfigClient, - IOperatorConfigDatabase -} from "@/src/types/inventoryTypes/SuitTypes"; +import { ISuitDatabase } from "@/src/types/inventoryTypes/SuitTypes"; import { IWeaponDatabase } from "@/src/types/inventoryTypes/weaponTypes"; -import { IAbilityOverride, IColor, IPolarity } from "@/src/types/inventoryTypes/commonInventoryTypes"; +import { + IAbilityOverride, + IColor, + IItemConfig, + IOperatorConfigClient, + IOperatorConfigDatabase, + IPolarity +} from "@/src/types/inventoryTypes/commonInventoryTypes"; +import { toOid } from "@/src/helpers/inventoryHelpers"; const polaritySchema = new Schema({ Slot: Number, @@ -51,6 +57,7 @@ const operatorConfigSchema = new Schema( eyecol: colorSchema, facial: colorSchema, syancol: colorSchema, + cloth: colorSchema, Upgrades: [String], Name: String, // not sure if possible in operator ugly: Boolean // not sure if possible in operator @@ -141,10 +148,13 @@ const BoosterSchema = new Schema({ ItemType: String }); -const RawUpgrades = new Schema({ - ItemType: String, - ItemCount: Number -}); +const RawUpgrades = new Schema( + { + ItemType: String, + ItemCount: Number + }, + { id: false } +); RawUpgrades.virtual("LastAdded").get(function () { return { $oid: this._id.toString() } satisfies IOid; @@ -158,7 +168,7 @@ RawUpgrades.set("toJSON", { } }); -//TODO: validate what this is +//TODO: find out what this is const Upgrade = new Schema({ UpgradeFingerprint: String, ItemType: String @@ -208,14 +218,18 @@ suitSchema.set("toJSON", { const slotsBinSchema = new Schema( { - Slots: Number + Slots: Number, + Extra: Number }, { _id: false } ); -const FlavourItemSchema = new Schema({ - ItemType: String -}); +const FlavourItemSchema = new Schema( + { + ItemType: String + }, + { _id: false } +); FlavourItemSchema.set("toJSON", { transform(_document, returnedObject) { @@ -224,7 +238,70 @@ FlavourItemSchema.set("toJSON", { } }); +const GenericItemSchema = new Schema( + { + ItemType: String, + Configs: [ItemConfigSchema], + UpgradeVer: Number //this is probably just __v + }, + { id: false } +); + +GenericItemSchema.virtual("ItemId").get(function () { + return { $oid: this._id.toString() } satisfies IOid; +}); + +GenericItemSchema.set("toJSON", { + virtuals: true, + transform(_document, returnedObject) { + delete returnedObject._id; + delete returnedObject.__v; + } +}); + +// "Mailbox": { "LastInboxId": { "$oid": "123456780000000000000000" } } +const MailboxSchema = new Schema( + { + LastInboxId: { + type: Schema.Types.ObjectId, + set: (v: IMailbox["LastInboxId"]) => v.$oid.toString() + } + }, + { id: false, _id: false } +); + +MailboxSchema.set("toJSON", { + transform(_document, returnedObject) { + delete returnedObject.__v; + //TODO: there is a lot of any here + returnedObject.LastInboxId = toOid(returnedObject.LastInboxId as Types.ObjectId); + } +}); + +const DuviriInfoSchema = new Schema( + { + Seed: Number, + NumCompletions: Number + }, + { + _id: false, + id: false + } +); + +DuviriInfoSchema.set("toJSON", { + transform(_document, returnedObject) { + delete returnedObject.__v; + } +}); + const inventorySchema = new Schema({ + Horses: [GenericItemSchema], + DrifterMelee: [GenericItemSchema], + DrifterGuns: [GenericItemSchema], + DuviriInfo: DuviriInfoSchema, + Mailbox: MailboxSchema, + KahlLoadOuts: [Schema.Types.Mixed], accountOwnerId: Schema.Types.ObjectId, SubscribedToEmails: Number, Created: Schema.Types.Mixed, @@ -236,11 +313,15 @@ const inventorySchema = new Schema({ SuitBin: slotsBinSchema, WeaponBin: slotsBinSchema, SentinelBin: slotsBinSchema, - SpaceSuitBin: Schema.Types.Mixed, - SpaceWeaponBin: Schema.Types.Mixed, - PvpBonusLoadoutBin: Schema.Types.Mixed, - PveBonusLoadoutBin: Schema.Types.Mixed, - RandomModBin: Schema.Types.Mixed, + SpaceSuitBin: slotsBinSchema, + SpaceWeaponBin: slotsBinSchema, + PvpBonusLoadoutBin: slotsBinSchema, + PveBonusLoadoutBin: slotsBinSchema, + RandomModBin: slotsBinSchema, + OperatorAmpBin: slotsBinSchema, + CrewShipSalvageBin: slotsBinSchema, + MechBin: slotsBinSchema, + CrewMemberBin: slotsBinSchema, TradesRemaining: Number, DailyAffiliation: Number, DailyAffiliationPvp: Number, @@ -260,7 +341,7 @@ const inventorySchema = new Schema({ Ships: [Schema.Types.Mixed], QuestKeys: [Schema.Types.Mixed], FlavourItems: [FlavourItemSchema], - Scoops: [Schema.Types.Mixed], + Scoops: [GenericItemSchema], TrainingRetriesLeft: Number, LoadOutPresets: { type: Schema.Types.ObjectId, ref: "Loadout" }, CurrentLoadOutIds: [Schema.Types.Mixed], @@ -294,14 +375,14 @@ const inventorySchema = new Schema({ Affiliations: [Schema.Types.Mixed], QualifyingInvasions: [Schema.Types.Mixed], FactionScores: [Number], - SpaceSuits: [Schema.Types.Mixed], - SpaceMelee: [Schema.Types.Mixed], + SpaceSuits: [GenericItemSchema], + SpaceMelee: [GenericItemSchema], SpaceGuns: [Schema.Types.Mixed], ArchwingEnabled: Boolean, PendingSpectreLoadouts: [Schema.Types.Mixed], SpectreLoadouts: [Schema.Types.Mixed], - SentinelWeapons: [Schema.Types.Mixed], - Sentinels: [Schema.Types.Mixed], + Sentinels: [WeaponSchema], + SentinelWeapons: [WeaponSchema], EmailItems: [Schema.Types.Mixed], CompletedSyndicates: [String], FocusXP: Schema.Types.Mixed, @@ -314,7 +395,6 @@ const inventorySchema = new Schema({ ActiveAvatarImageType: String, KubrowPets: [Schema.Types.Mixed], ShipDecorations: [Schema.Types.Mixed], - OperatorAmpBin: Schema.Types.Mixed, DailyAffiliationCetus: Number, DailyAffiliationQuills: Number, DiscoveredMarkers: [Schema.Types.Mixed], @@ -346,13 +426,12 @@ const inventorySchema = new Schema({ MoaPets: [Schema.Types.Mixed], EquippedInstrument: String, InvasionChainProgress: [Schema.Types.Mixed], - DataKnives: [Schema.Types.Mixed], + DataKnives: [GenericItemSchema], NemesisHistory: [Schema.Types.Mixed], LastNemesisAllySpawnTime: Schema.Types.Mixed, Settings: Schema.Types.Mixed, PersonalTechProjects: [Schema.Types.Mixed], CrewShips: [Schema.Types.Mixed], - CrewShipSalvageBin: Schema.Types.Mixed, PlayerSkills: Schema.Types.Mixed, CrewShipAmmo: [Schema.Types.Mixed], CrewShipSalvagedWeaponSkins: [Schema.Types.Mixed], @@ -362,13 +441,11 @@ const inventorySchema = new Schema({ TradeBannedUntil: Schema.Types.Mixed, PlayedParkourTutorial: Boolean, SubscribedToEmailsPersonalized: Number, - MechBin: Schema.Types.Mixed, DailyAffiliationEntrati: Number, DailyAffiliationNecraloid: Number, - MechSuits: [Schema.Types.Mixed], + MechSuits: [suitSchema], InfestedFoundry: Schema.Types.Mixed, BlessingCooldown: Schema.Types.Mixed, - CrewMemberBin: Schema.Types.Mixed, CrewShipHarnesses: [Schema.Types.Mixed], CrewShipRawSalvage: [Schema.Types.Mixed], CrewMembers: [Schema.Types.Mixed], @@ -393,10 +470,7 @@ const inventorySchema = new Schema({ HasResetAccount: Boolean, PendingCoupon: Schema.Types.Mixed, Harvestable: Boolean, - DeathSquadable: Boolean, - Horses: [Schema.Types.Mixed], - DrifterMelee: [Schema.Types.Mixed], - KahlLoadOuts: [Schema.Types.Mixed] + DeathSquadable: Boolean }); inventorySchema.set("toJSON", { @@ -425,6 +499,12 @@ type InventoryDocumentProps = { Boosters: Types.DocumentArray; OperatorLoadOuts: Types.DocumentArray; AdultOperatorLoadOuts: Types.DocumentArray; + MechSuits: Types.DocumentArray; + Scoops: Types.DocumentArray; + DataKnives: Types.DocumentArray; + DrifterMelee: Types.DocumentArray; + Sentinels: Types.DocumentArray; + Horses: Types.DocumentArray; }; type InventoryModelType = Model; diff --git a/src/routes/api.ts b/src/routes/api.ts index de269c34..66f55d0f 100644 --- a/src/routes/api.ts +++ b/src/routes/api.ts @@ -26,13 +26,14 @@ import { setActiveQuestController } from "@/src/controllers/api/setActiveQuestCo import { surveysController } from "@/src/controllers/api/surveysController"; import { updateChallengeProgressController } from "@/src/controllers/api/updateChallengeProgressController"; import { updateSessionGetController, updateSessionPostController } from "@/src/controllers/api/updateSessionController"; -import { viewController } from "@/src/controllers/api/viewController"; import { joinSessionController } from "@/src/controllers/api/joinSessionController"; import { saveLoadoutController } from "@/src/controllers/api/saveLoadout"; import { trainingResultController } from "@/src/controllers/api/trainingResultController"; import { artifactsController } from "../controllers/api/artifactsController"; import express from "express"; +import { setBootLocationController } from "@/src/controllers/api/setBootLocationController"; +import { focusController } from "@/src/controllers/api/focusController"; const apiRouter = express.Router(); @@ -46,7 +47,6 @@ apiRouter.get("/loginRewards.php", loginRewardsController); apiRouter.get("/checkDailyMissionBonus.php", checkDailyMissionBonusController); apiRouter.get("/inbox.php", inboxController); apiRouter.get("/getShip.php", getShipController); -apiRouter.get("/view.php", viewController); apiRouter.get("/drones.php", dronesController); apiRouter.get("/getIgnoredUsers.php", getIgnoredUsersController); apiRouter.get("/getNewRewardSeed.php", getNewRewardSeedController); @@ -58,8 +58,10 @@ apiRouter.get("/hub", hubController); apiRouter.get("/modularWeaponSale.php", modularWeaponSaleController); apiRouter.get("/deleteSession.php", deleteSessionController); apiRouter.get("/logout.php", logoutController); +apiRouter.get("/setBootLocation.php", setBootLocationController); // post +apiRouter.post("/focus.php", focusController); apiRouter.post("/artifacts.php", artifactsController); apiRouter.post("/findSessions.php", findSessionsController); // eslint-disable-next-line @typescript-eslint/no-misused-promises diff --git a/src/routes/stats.ts b/src/routes/stats.ts index a0df739f..59290675 100644 --- a/src/routes/stats.ts +++ b/src/routes/stats.ts @@ -1,4 +1,4 @@ -import { viewController } from "../controllers/api/viewController"; +import { viewController } from "../controllers/stats/viewController"; import { uploadController } from "@/src/controllers/stats/uploadController"; import express from "express"; diff --git a/src/services/inventoryService.ts b/src/services/inventoryService.ts index 534dbfa8..93d62603 100644 --- a/src/services/inventoryService.ts +++ b/src/services/inventoryService.ts @@ -17,7 +17,7 @@ import { import { IGenericUpdate } from "../types/genericUpdate"; import { IArtifactsRequest, IMissionInventoryUpdateRequest } from "../types/requestTypes"; -const createInventory = async (accountOwnerId: Types.ObjectId, loadOutPresetId: Types.ObjectId) => { +export const createInventory = async (accountOwnerId: Types.ObjectId, loadOutPresetId: Types.ObjectId) => { try { const inventory = new Inventory({ ...new_inventory, @@ -53,13 +53,28 @@ export const getInventory = async (accountOwnerId: string) => { return inventory; }; -const addPowerSuit = async (powersuitName: string, accountId: string): Promise => { +//TODO: genericMethod for all the add methods, they share a lot of logic +export const addSentinel = async (sentinelName: string, accountId: string) => { + const inventory = await getInventory(accountId); + const sentinelIndex = inventory.Sentinels.push({ ItemType: sentinelName, Configs: [], XP: 0 }); + const changedInventory = await inventory.save(); + return changedInventory.Sentinels[sentinelIndex - 1].toJSON(); +}; + +export const addPowerSuit = async (powersuitName: string, accountId: string): Promise => { const inventory = await getInventory(accountId); const suitIndex = inventory.Suits.push({ ItemType: powersuitName, Configs: [], UpgradeVer: 101, XP: 0 }); const changedInventory = await inventory.save(); return changedInventory.Suits[suitIndex - 1].toJSON(); }; +export const addMechSuit = async (mechsuitName: string, accountId: string) => { + const inventory = await getInventory(accountId); + const suitIndex = inventory.MechSuits.push({ ItemType: mechsuitName, Configs: [], UpgradeVer: 101, XP: 0 }); + const changedInventory = await inventory.save(); + return changedInventory.MechSuits[suitIndex - 1].toJSON(); +}; + export const updateSlots = async (slotType: SlotType, accountId: string, slots: number) => { const inventory = await getInventory(accountId); @@ -70,6 +85,9 @@ export const updateSlots = async (slotType: SlotType, accountId: string, slots: case SlotType.WEAPON: inventory.WeaponBin.Slots += slots; break; + case SlotType.MECHSUIT: + inventory.MechBin.Slots += slots; + break; default: throw new Error("invalid slot type"); } @@ -343,5 +361,3 @@ export const upgradeMod = async (artifactsData: IArtifactsRequest, accountId: st throw error; } }; - -export { createInventory, addPowerSuit }; diff --git a/src/services/purchaseService.ts b/src/services/purchaseService.ts index 8b88cd86..b6d80c21 100644 --- a/src/services/purchaseService.ts +++ b/src/services/purchaseService.ts @@ -1,6 +1,14 @@ import { getWeaponType } from "@/src/helpers/purchaseHelpers"; import { getSubstringFromKeyword } from "@/src/helpers/stringHelpers"; -import { addBooster, addCustomization, addPowerSuit, addWeapon, updateSlots } from "@/src/services/inventoryService"; +import { + addBooster, + addCustomization, + addMechSuit, + addPowerSuit, + addSentinel, + addWeapon, + updateSlots +} from "@/src/services/inventoryService"; import { IPurchaseRequest, SlotType } from "@/src/types/purchaseTypes"; export const getStoreItemCategory = (storeItem: string) => { @@ -72,8 +80,25 @@ const handleWeaponsPurchase = async (weaponName: string, accountId: string) => { }; const handlePowersuitPurchase = async (powersuitName: string, accountId: string) => { + if (powersuitName.includes("EntratiMech")) { + const mechSuit = await addMechSuit(powersuitName, accountId); + await updateSlots(SlotType.MECHSUIT, accountId, -1); + console.log("mech suit", mechSuit); + + return { + InventoryChanges: { + MechBin: { + count: 1, + platinum: 0, + Slots: -1 + }, + MechSuits: [mechSuit] + } + }; + } + const suit = await addPowerSuit(powersuitName, accountId); - await updateSlots(SlotType.WEAPON, accountId, -1); + await updateSlots(SlotType.SUIT, accountId, -1); return { InventoryChanges: { @@ -95,13 +120,24 @@ const handleTypesPurchase = async (typesName: string, accountId: string) => { return await handleSuitCustomizationsPurchase(typesName, accountId); // case "Recipes": // break; - // case "Sentinels": - // break; + case "Sentinels": + return await handleSentinelPurchase(typesName, accountId); default: throw new Error(`unknown Types category: ${typeCategory} not implemented or new`); } }; +const handleSentinelPurchase = async (sentinelName: string, accountId: string) => { + const sentinel = await addSentinel(sentinelName, accountId); + + return { + InventoryChanges: { + SentinelBin: { count: 1, platinum: 0, Slots: -1 }, + Sentinels: [sentinel] + } + }; +}; + const handleSuitCustomizationsPurchase = async (customizationName: string, accountId: string) => { const customization = await addCustomization(customizationName, accountId); diff --git a/src/services/saveLoadoutService.ts b/src/services/saveLoadoutService.ts index d47254e9..8d690e62 100644 --- a/src/services/saveLoadoutService.ts +++ b/src/services/saveLoadoutService.ts @@ -15,13 +15,20 @@ export const isEmptyObject = (obj: unknown): boolean => { //setup default items on account creation or like originally in giveStartingItems.php -//export const updateLoadout = (loadout: ISaveLoadoutRequest, accountId: string) => {}; +//TODO: avoid multiple saves for less db calls +//TODO: change update functions to only add and not save + +/* loadouts has loadoutconfigs +operatorloadouts has itemconfig, but no multiple config ids +itemconfig has multiple config ids +*/ -//support multiple loadouts and multiple items and multiple configs per item export const handleInventoryItemConfigChange = async ( equipmentChanges: ISaveLoadoutRequestNoUpgradeVer, accountId: string ) => { + const inventory = await getInventory(accountId); + for (const [_equipmentName, _equipment] of Object.entries(equipmentChanges)) { const equipment = _equipment as ISaveLoadoutRequestNoUpgradeVer[keyof ISaveLoadoutRequestNoUpgradeVer]; const equipmentName = _equipmentName as keyof ISaveLoadoutRequestNoUpgradeVer; @@ -34,12 +41,10 @@ export const handleInventoryItemConfigChange = async ( switch (equipmentName) { case "OperatorLoadOuts": case "AdultOperatorLoadOuts": { - console.log("loadout received", equipmentName); - const inventory = await getInventory(accountId); const operatorConfig = equipment as IOperatorConfigEntry; const operatorLoadout = inventory[equipmentName]; - + console.log("loadout received", equipmentName, operatorConfig); // all non-empty entries are one loadout slot for (const [loadoutId, loadoutConfig] of Object.entries(operatorConfig)) { // console.log("loadoutId", loadoutId, "loadoutconfig", loadoutConfig); @@ -123,20 +128,25 @@ export const handleInventoryItemConfigChange = async ( case "LongGuns": case "Pistols": case "Suits": - case "Melee": { + case "Melee": + case "Scoops": + case "DataKnives": + case "DrifterMelee": + case "Sentinels": + case "Horses": { console.log("? ???? ?", equipmentName, equipment); - const itemEntry = equipment as IItemEntry; + const itemEntries = equipment as IItemEntry; const inventory = await getInventory(accountId); - for (const [itemId, itemConfig] of Object.entries(itemEntry)) { - const inventoryItem = inventory[equipmentName].find(item => item._id.toString() === itemId); + for (const [itemId, itemConfigEntries] of Object.entries(itemEntries)) { + const inventoryItem = inventory[equipmentName].find(item => item._id?.toString() === itemId); if (!inventoryItem) { throw new Error(`inventory item ${equipmentName} not found with id ${itemId}`); } //config ids are 0,1,2 can there be a 3? - for (const [configId, config] of Object.entries(itemConfig)) { + for (const [configId, config] of Object.entries(itemConfigEntries)) { inventoryItem.Configs[parseInt(configId)] = config; } } @@ -145,35 +155,40 @@ export const handleInventoryItemConfigChange = async ( } case "CurrentLoadOutIds": { //TODO: remove duplicate getInventory after finding out when currentloadOutId is sent - const loadoutIds = equipment as IOid[]; + const loadoutIds = equipment as IOid[]; // TODO: Check for more than just an array of oids, I think i remember one instance const inventory = await getInventory(accountId); inventory.CurrentLoadOutIds = loadoutIds; await inventory.save(); break; } + case "EquippedGear": { + inventory.EquippedGear = equipment as string[]; + break; + } default: { - console.log("category not implemented", equipmentName); + console.log("category not implemented", equipmentName, equipment); } } //case "OperatorAmps": - // case "Sentinels": + // case "SentinelWeapons": // case "KubrowPets": // case "SpaceSuits": // case "SpaceGuns": // case "SpaceMelee": - // case "Scoops": + // case "SpecialItems": // case "MoaPets": // case "Hoverboards": - // case "DataKnives": + // case "MechSuits": // case "CrewShipHarnesses": - // case "Horses": - // case "DrifterMelee": + + // // case "CrewShips": //case "KahlLoadOuts": not sure yet how to handle kahl: it is not sent in inventory } + await inventory.save(); }; diff --git a/src/types/inventoryTypes/SuitTypes.ts b/src/types/inventoryTypes/SuitTypes.ts index fb63283a..f075587c 100644 --- a/src/types/inventoryTypes/SuitTypes.ts +++ b/src/types/inventoryTypes/SuitTypes.ts @@ -1,6 +1,7 @@ import { IOid } from "@/src/types/commonTypes"; -import { IAbilityOverride, IColor, IPolarity } from "@/src/types/inventoryTypes/commonInventoryTypes"; +import { IPolarity } from "@/src/types/inventoryTypes/commonInventoryTypes"; import { Types } from "mongoose"; +import { IItemConfig } from "./commonInventoryTypes"; export interface ISuitClient extends ISuitDatabase { ItemId: IOid; @@ -19,43 +20,5 @@ export interface ISuitDatabase { FocusLens?: string; UnlockLevel?: number; _id: Types.ObjectId; -} - -interface IItemConfigBase { - Skins: string[]; - pricol?: IColor; - attcol?: IColor; - sigcol?: IColor; - eyecol?: IColor; - facial?: IColor; - syancol?: IColor; - cloth?: IColor; - Upgrades?: string[]; - Name?: string; - ugly?: boolean; -} - -export interface IItemConfig extends IItemConfigBase { - Songs?: ISong[]; - AbilityOverride?: IAbilityOverride; - PvpUpgrades?: string[]; - ugly?: boolean; -} - -export interface ISong { - m?: string; - b?: string; - p?: string; - s: string; -} - -//TODO: Consider renaming it to loadout instead of config -export interface IOperatorConfigDatabase extends IItemConfigBase { - _id: Types.ObjectId; - AbilityOverride?: IAbilityOverride; // not present in adultOperator - OperatorAmp?: IOid; // not present in adultOperator -} - -export interface IOperatorConfigClient extends Omit { - ItemId: IOid; + ItemId?: IOid; // only in response } diff --git a/src/types/inventoryTypes/commonInventoryTypes.ts b/src/types/inventoryTypes/commonInventoryTypes.ts index 0664407f..b86cb719 100644 --- a/src/types/inventoryTypes/commonInventoryTypes.ts +++ b/src/types/inventoryTypes/commonInventoryTypes.ts @@ -1,3 +1,6 @@ +import { IOid } from "@/src/types/commonTypes"; +import { Types } from "mongoose"; + export interface IPolarity { Slot: number; Value: FocusSchool; @@ -41,3 +44,44 @@ export interface Isigcol { t1: number; en: number; } + +interface IItemConfigBase { + Skins: string[]; + pricol?: IColor; + attcol?: IColor; + sigcol?: IColor; + eyecol?: IColor; + facial?: IColor; + syancol?: IColor; + cloth?: IColor; + Upgrades?: string[]; + Name?: string; + ugly?: boolean; +} + +//TODO: Proper names for the different config types, this should be something like +//IItemConfigPlayable +export interface IItemConfig extends IItemConfigBase { + Songs?: ISong[]; + AbilityOverride?: IAbilityOverride; + PvpUpgrades?: string[]; + ugly?: boolean; +} + +export interface ISong { + m?: string; + b?: string; + p?: string; + s: string; +} + +//TODO: Consider renaming it to loadout instead of config +export interface IOperatorConfigDatabase extends IItemConfigBase { + _id: Types.ObjectId; + AbilityOverride?: IAbilityOverride; // not present in adultOperator + OperatorAmp?: IOid; // not present in adultOperator +} + +export interface IOperatorConfigClient extends Omit { + ItemId: IOid; +} diff --git a/src/types/inventoryTypes/inventoryTypes.ts b/src/types/inventoryTypes/inventoryTypes.ts index db0383f8..2674599a 100644 --- a/src/types/inventoryTypes/inventoryTypes.ts +++ b/src/types/inventoryTypes/inventoryTypes.ts @@ -1,17 +1,24 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ import { Document, Types } from "mongoose"; import { IOid, IMongoDate } from "../commonTypes"; -import { IAbilityOverride, IColor, FocusSchool, IPolarity } from "@/src/types/inventoryTypes/commonInventoryTypes"; -import { IOperatorConfigClient, ISuitDatabase } from "@/src/types/inventoryTypes/SuitTypes"; +import { + IAbilityOverride, + IColor, + FocusSchool, + IPolarity, + IItemConfig, + IOperatorConfigClient +} from "@/src/types/inventoryTypes/commonInventoryTypes"; +import { ISuitDatabase } from "@/src/types/inventoryTypes/SuitTypes"; import { IOperatorLoadOutSigcol, IWeaponDatabase } from "@/src/types/inventoryTypes/weaponTypes"; -import { IItemConfig } from "@/src/types/saveLoadoutTypes"; //Document extends will be deleted soon. TODO: delete and migrate uses to ... export interface IInventoryDatabaseDocument extends IInventoryDatabase, Document {} -export interface IInventoryDatabase extends Omit { +export interface IInventoryDatabase extends Omit { accountOwnerId: Types.ObjectId; TrainingDate: Date; // TrainingDate changed from IMongoDate to Date LoadOutPresets: Types.ObjectId; // LoadOutPresets changed from ILoadOutPresets to Types.ObjectId for population + Mailbox: Types.ObjectId; // Mailbox changed from IMailbox to Types.ObjectId } export interface IInventoryResponseDocument extends IInventoryResponse, Document {} @@ -22,13 +29,25 @@ export interface IGenericItem { Configs: IItemConfig[]; UpgradeVer: number; ItemId: IOid; + Features?: number; //space suit has this +} + +export interface IDuviriInfo { + Seed: number; + NumCompletions: number; +} + +export interface IMailbox { + LastInboxId: IOid; } export interface IInventoryResponse { - KahlLoadOuts: IGenericItem[]; - DrifterMelee: IGenericItem[]; Horses: IGenericItem[]; - DuviriInfo: { Seed: number; NumCompletions: number }; // TODO: add to schema + DrifterMelee: IGenericItem[]; + DrifterGuns: IGenericItem[]; + DuviriInfo: IDuviriInfo; + Mailbox: IMailbox; + KahlLoadOuts: IGenericItem[]; SubscribedToEmails: number; Created: IMongoDate; RewardSeed: number; @@ -41,9 +60,13 @@ export interface IInventoryResponse { SentinelBin: ISlots; SpaceSuitBin: ISlots; SpaceWeaponBin: ISlots; - PvpBonusLoadoutBin: ICrewMemberBinClass; + PvpBonusLoadoutBin: ISlots; PveBonusLoadoutBin: ISlots; RandomModBin: ISlots; + MechBin: ISlots; + CrewMemberBin: ISlots; + OperatorAmpBin: ISlots; + CrewShipSalvageBin: ISlots; TradesRemaining: number; DailyAffiliation: number; DailyAffiliationPvp: number; @@ -63,7 +86,7 @@ export interface IInventoryResponse { Ships: IShip[]; QuestKeys: IQuestKey[]; FlavourItems: IFlavourItem[]; - Scoops: IScoop[]; + Scoops: IGenericItem[]; TrainingRetriesLeft: number; LoadOutPresets: ILoadOutPresets; CurrentLoadOutIds: Array; @@ -97,14 +120,14 @@ export interface IInventoryResponse { Affiliations: IAffiliation[]; QualifyingInvasions: any[]; FactionScores: number[]; - SpaceSuits: ISpace[]; - SpaceMelee: ISpace[]; + SpaceSuits: IGenericItem[]; + SpaceMelee: IGenericItem[]; SpaceGuns: ISpaceGun[]; ArchwingEnabled: boolean; PendingSpectreLoadouts: any[]; SpectreLoadouts: ISpectreLoadout[]; - SentinelWeapons: ISentinelWeapon[]; - Sentinels: ISentinel[]; + SentinelWeapons: IWeaponDatabase[]; + Sentinels: IWeaponDatabase[]; EmailItems: IEmailItem[]; CompletedSyndicates: string[]; FocusXP: IFocusXP; @@ -117,7 +140,6 @@ export interface IInventoryResponse { ActiveAvatarImageType: string; KubrowPets: IKubrowPet[]; ShipDecorations: IConsumable[]; - OperatorAmpBin: ISlots; DailyAffiliationCetus: number; DailyAffiliationQuills: number; DiscoveredMarkers: IDiscoveredMarker[]; @@ -149,13 +171,12 @@ export interface IInventoryResponse { MoaPets: IMoaPet[]; EquippedInstrument: string; InvasionChainProgress: IInvasionChainProgress[]; - DataKnives: IDataKnife[]; + DataKnives: IGenericItem[]; NemesisHistory: INemesisHistory[]; LastNemesisAllySpawnTime: IMongoDate; Settings: ISettings; PersonalTechProjects: IPersonalTechProject[]; CrewShips: ICrewShip[]; - CrewShipSalvageBin: ISlots; PlayerSkills: IPlayerSkills; CrewShipAmmo: IConsumable[]; CrewShipSalvagedWeaponSkins: ICrewShipSalvagedWeaponSkin[]; @@ -165,13 +186,11 @@ export interface IInventoryResponse { TradeBannedUntil: IMongoDate; PlayedParkourTutorial: boolean; SubscribedToEmailsPersonalized: number; - MechBin: ICrewMemberBinClass; DailyAffiliationEntrati: number; DailyAffiliationNecraloid: number; - MechSuits: IMechSuit[]; + MechSuits: ISuitDatabase[]; InfestedFoundry: IInfestedFoundry; BlessingCooldown: IMongoDate; - CrewMemberBin: ICrewMemberBinClass; CrewShipHarnesses: ICrewShipHarness[]; CrewShipRawSalvage: IConsumable[]; CrewMembers: ICrewMember[]; @@ -275,10 +294,6 @@ export interface IConsumable { ItemType: string; } -export interface ICrewMemberBinClass { - Slots: number; -} - export interface ICrewMember { ItemType: string; NemesisFingerprint: number; @@ -418,22 +433,6 @@ export interface IPortGuns { PRIMARY_A: IL; } -export interface IDataKnife { - ItemType: string; - XP: number; - Configs: IDataKnifeConfig[]; - UpgradeVer: number; - ItemId: IOid; -} - -export interface IDataKnifeConfig { - Upgrades?: string[]; - pricol?: IColor; - Skins: string[]; - attcol?: IColor; - sigcol?: IColor; -} - export interface IDiscoveredMarker { tag: string; discoveryState: number[]; @@ -733,17 +732,6 @@ export interface ILotusCustomization { Persona: string; } -export interface IMechSuit { - ItemType: string; - Configs: IDataKnifeConfig[]; - Features: number; - UpgradeVer: number; - XP: number; - Polarity: IPolarity[]; - Polarized: number; - ItemId: IOid; -} - export interface IMission { Completes: number; Tier?: number; @@ -932,6 +920,7 @@ export interface IQuestKey { Progress?: IProgress[]; unlock?: boolean; Completed?: boolean; + CustomData?: string; ItemType: string; CompletionDate?: IMongoDate; } @@ -949,17 +938,6 @@ export interface IRawUpgrade { LastAdded?: IOid; } -export interface IScoop { - ItemType: string; - Configs: IScoopConfig[]; - UpgradeVer: number; - ItemId: IOid; -} - -export interface IScoopConfig { - pricol?: IColor; -} - export interface ISeasonChallengeHistory { challenge: string; id: string; @@ -969,40 +947,6 @@ export interface ISentientSpawnChanceBoosters { numOceanMissionsCompleted: number; } -export interface ISentinelWeapon { - ItemType: string; - Configs: ISentinelWeaponConfig[]; - UpgradeVer?: number; - XP?: number; - ItemId: IOid; - Features?: number; - Polarity?: IPolarity[]; - Polarized?: number; -} - -export interface ISentinelWeaponConfig { - Skins?: FluffySkin[]; - Upgrades?: string[]; -} - -export enum FluffySkin { - Empty = "", - LotusUpgradesSkinsHolsterCustomizationsGlaiveInPlace = "/Lotus/Upgrades/Skins/HolsterCustomizations/GlaiveInPlace", - LotusUpgradesSkinsHolsterCustomizationsPistolHipsR = "/Lotus/Upgrades/Skins/HolsterCustomizations/PistolHipsR", - LotusUpgradesSkinsHolsterCustomizationsRifleUpperBack = "/Lotus/Upgrades/Skins/HolsterCustomizations/RifleUpperBack" -} - -export interface ISentinel { - ItemType: string; - Configs: IKubrowPetConfig[]; - UpgradeVer: number; - XP: number; - Features?: number; - Polarity?: IPolarity[]; - Polarized?: number; - ItemId: IOid; -} - export interface ISettings { FriendInvRestriction: string; GiftMode: string; @@ -1038,15 +982,6 @@ export interface ISpaceGunConfig { Upgrades?: string[]; } -export interface ISpace { - ItemType: string; - Configs: IKubrowPetConfig[]; - XP: number; - UpgradeVer: number; - ItemId: IOid; - Features?: number; -} - export interface ISpecialItem { ItemType: string; Configs: ISpecialItemConfig[]; diff --git a/src/types/inventoryTypes/weaponTypes.ts b/src/types/inventoryTypes/weaponTypes.ts index 0d92ef6d..7cc390f3 100644 --- a/src/types/inventoryTypes/weaponTypes.ts +++ b/src/types/inventoryTypes/weaponTypes.ts @@ -1,5 +1,5 @@ import { IOid } from "@/src/types/commonTypes"; -import { IItemConfig } from "@/src/types/inventoryTypes/SuitTypes"; +import { IItemConfig } from "./commonInventoryTypes"; import { IPolarity } from "@/src/types/inventoryTypes/commonInventoryTypes"; import { Types } from "mongoose"; diff --git a/src/types/purchaseTypes.ts b/src/types/purchaseTypes.ts index ca98dc95..ce1e6270 100644 --- a/src/types/purchaseTypes.ts +++ b/src/types/purchaseTypes.ts @@ -40,5 +40,6 @@ export type IBinChanges = { export enum SlotType { SUIT = "SuitBin", - WEAPON = "WeaponBin" + WEAPON = "WeaponBin", + MECHSUIT = "MechBin" } diff --git a/src/types/saveLoadoutTypes.ts b/src/types/saveLoadoutTypes.ts index 5e630be5..61020029 100644 --- a/src/types/saveLoadoutTypes.ts +++ b/src/types/saveLoadoutTypes.ts @@ -1,5 +1,5 @@ import { IOid } from "@/src/types/commonTypes"; -import { IItemConfig, IOperatorConfigClient } from "@/src/types/inventoryTypes/SuitTypes"; +import { IItemConfig, IOperatorConfigClient } from "@/src/types/inventoryTypes/commonInventoryTypes"; import { Types } from "mongoose"; export interface ISaveLoadoutRequest { @@ -31,6 +31,7 @@ export interface ISaveLoadoutRequest { CrewShips: IItemEntry; CurrentLoadOutIds: IOid[]; ValidNewLoadoutId: string; + EquippedGear: string[]; } export interface ISaveLoadoutRequestNoUpgradeVer extends Omit {} @@ -89,4 +90,3 @@ export interface IEquipmentSelection { mod: number; cus: number; } -export { IItemConfig }; diff --git a/static/fixed_responses/postTutorialInventory.json b/static/fixed_responses/postTutorialInventory.json index 31d9a61f..9bcab784 100644 --- a/static/fixed_responses/postTutorialInventory.json +++ b/static/fixed_responses/postTutorialInventory.json @@ -5,7 +5,7 @@ "RewardSeed": -5604904486637265640, "CrewMemberBin": { "Slots": 3 }, "CrewShipSalvageBin": { "Slots": 8 }, - "DrifterMelee": [{ "ItemType": "/Lotus/Types/Friendly/PlayerControllable/Weapons/DuviriDualSwords", "ItemId": { "$oid": "647bd268c547fe5b2909e715" } }], + "DrifterMelee": [{ "ItemType": "/Lotus/Types/Friendly/PlayerControllable/Weapons/DuviriDualSwords", "ItemId": { "$oid": "647bd27cf856530b4f3bf343" } }], "FusionPoints": 0, "MechBin": { "Slots": 4 }, "OperatorAmpBin": { "Slots": 8 }, @@ -84,7 +84,24 @@ "CrewShipWeaponSkins": [], "DrifterGuns": [], "Drones": [], - "Horses": [], + "Horses": [ + { + "ItemType": "/Lotus/Types/NeutralCreatures/ErsatzHorse/ErsatzHorsePowerSuit", + "Configs": [ + { + "Skins": ["", "", "/Lotus/Upgrades/Skins/Horse/ErsatzHorseTailDefault"] + }, + { + "Skins": ["", "", "/Lotus/Upgrades/Skins/Horse/ErsatzHorseTailDefault"] + }, + { + "Skins": ["", "", "/Lotus/Upgrades/Skins/Horse/ErsatzHorseTailDefault"] + } + ], + "UpgradeVer": 101, + "ItemId": { "$oid": "647bd27cf856530b4f3bf343" } + } + ], "Hoverboards": [], "KubrowPets": [], "KubrowPetEggs": [], diff --git a/static/fixed_responses/testQuestKeys.json b/static/fixed_responses/testQuestKeys.json index df32ed3d..1a822001 100644 --- a/static/fixed_responses/testQuestKeys.json +++ b/static/fixed_responses/testQuestKeys.json @@ -7,5 +7,35 @@ }, { "ItemType": "/Lotus/Types/Keys/DuviriQuest/DuviriQuestKeyChain" + }, + { + "ItemType": "/Lotus/Types/Keys/WarWithinQuest/WarWithinQuestKeyChain" + }, + { + "ItemType": "/Lotus/Types/Keys/SacrificeQuest/SacrificeQuestKeyChain" + }, + { + "ItemType": "/Lotus/Types/Keys/NewWarIntroQuest/NewWarIntroKeyChain" + }, + { + "ItemType": "/Lotus/Types/Keys/NewWarQuest/NewWarQuestKeyChain" + }, + { + "ItemType": "/Lotus/Types/Keys/ApostasyQuest/ApostasyKeyChain" + }, + { + "ItemType": "/Lotus/Types/Keys/WarWithinQuest/WarWithinQuestKeyChain" + }, + { + "ItemType": "/Lotus/Types/Keys/OrokinMoonQuest/OrokinMoonQuestKeyChain" + }, + { + "ItemType": "/Lotus/Types/Keys/ZarimanQuest/ZarimanQuestKeyChain" + }, + { + "ItemType": "/Lotus/Types/Keys/DuviriQuest/DuviriQuestKeyChain" + }, + { + "ItemType": "/Lotus/Types/Keys/ArchwingQuest/ArchwingQuestKeyChain" } ] -- 2.47.2 From 647fd85bab62f4cd8a961576e82d5ee736fc5a8d Mon Sep 17 00:00:00 2001 From: Ordis <134585663+OrdisPrime@users.noreply.github.com> Date: Thu, 14 Dec 2023 17:21:03 +0100 Subject: [PATCH 09/11] cleanup a bit --- src/controllers/api/saveLoadout.ts | 2 +- src/services/saveLoadoutService.ts | 82 +++++++++--------------------- 2 files changed, 25 insertions(+), 59 deletions(-) diff --git a/src/controllers/api/saveLoadout.ts b/src/controllers/api/saveLoadout.ts index d520c8d0..9a973699 100644 --- a/src/controllers/api/saveLoadout.ts +++ b/src/controllers/api/saveLoadout.ts @@ -17,7 +17,7 @@ const saveLoadoutController: RequestHandler = async (req, res) => { const { UpgradeVer, ...equipmentChanges } = body; await handleInventoryItemConfigChange(equipmentChanges, accountId); } catch (error) { - res.status(200).end(); + res.status(400).json({ error: error.message }); } }; diff --git a/src/services/saveLoadoutService.ts b/src/services/saveLoadoutService.ts index 8d690e62..43006cc9 100644 --- a/src/services/saveLoadoutService.ts +++ b/src/services/saveLoadoutService.ts @@ -13,16 +13,14 @@ export const isEmptyObject = (obj: unknown): boolean => { return Boolean(obj && Object.keys(obj).length === 0 && obj.constructor === Object); }; -//setup default items on account creation or like originally in giveStartingItems.php +//TODO: setup default items on account creation or like originally in giveStartingItems.php -//TODO: avoid multiple saves for less db calls -//TODO: change update functions to only add and not save +//TODO: change update functions to only add and not save perhaps, functions that add and return inventory perhaps /* loadouts has loadoutconfigs operatorloadouts has itemconfig, but no multiple config ids itemconfig has multiple config ids */ - export const handleInventoryItemConfigChange = async ( equipmentChanges: ISaveLoadoutRequestNoUpgradeVer, accountId: string @@ -37,14 +35,12 @@ export const handleInventoryItemConfigChange = async ( continue; } // non-empty is a change in loadout(or suit...) - switch (equipmentName) { case "OperatorLoadOuts": case "AdultOperatorLoadOuts": { - const inventory = await getInventory(accountId); const operatorConfig = equipment as IOperatorConfigEntry; const operatorLoadout = inventory[equipmentName]; - console.log("loadout received", equipmentName, operatorConfig); + //console.log("loadout received", equipmentName, operatorConfig); // all non-empty entries are one loadout slot for (const [loadoutId, loadoutConfig] of Object.entries(operatorConfig)) { // console.log("loadoutId", loadoutId, "loadoutconfig", loadoutConfig); @@ -57,42 +53,30 @@ export const handleInventoryItemConfigChange = async ( _id: ItemId.$oid, ...loadoutConfigItemIdRemoved }); - await inventory.save(); continue; } loadout.set(loadoutConfig); - - //({ _id: loadoutId }, loadoutConfig); } - await inventory.save(); break; } case "LoadOuts": { - console.log("loadout received"); + //console.log("loadout received"); + const loadout = await LoadoutModel.findOne({ loadoutOwnerId: accountId }); + if (!loadout) { + throw new Error("loadout not found"); + } for (const [_loadoutSlot, _loadout] of Object.entries(equipment)) { const loadoutSlot = _loadoutSlot as keyof ILoadoutClient; const newLoadout = _loadout as ILoadoutEntry; - //console.log("key", loadoutSlot, "value", loadout); - // empty loadout slot like: "NORMAL": {} if (isEmptyObject(newLoadout)) { continue; } - const loadout = await LoadoutModel.findOne({ loadoutOwnerId: accountId }); - //const {, ...loadout } = loadoutWithLoadoutOwnerId; - - if (!loadout) { - throw new Error("loadout not found"); - } // all non-empty entries are one loadout slot for (const [loadoutId, loadoutConfig] of Object.entries(newLoadout)) { - // eslint-disable-next-line @typescript-eslint/no-unused-vars - //const { loadoutOwnerId, ...loadout } = loadoutWithLoadoutOwnerId; - // console.log("loadoutId", loadoutId, "loadoutconfig", loadoutConfig); - const oldLoadoutConfig = loadout[loadoutSlot].find( loadout => loadout._id.toString() === loadoutId ); @@ -104,25 +88,19 @@ export const handleInventoryItemConfigChange = async ( _id: ItemId.$oid, ...loadoutConfigItemIdRemoved }); - await loadout.save(); continue; } const loadoutIndex = loadout[loadoutSlot].indexOf(oldLoadoutConfig); - if (loadoutIndex === undefined || loadoutIndex === -1) { throw new Error("loadout index not found"); } - //console.log("parent id", oldLoadoutConfig.ownerDocument()._id); + //perhaps .overwrite() is better loadout[loadoutSlot][loadoutIndex].set(loadoutConfig); - //loadout.NORMAL[loadoutIndex].overwrite(loadoutConfig); - //console.log("db", loadout[loadoutSlot][loadoutIndex].schema); - - await loadout.save(); - //({ _id: loadoutId }, loadoutConfig); } } + await loadout.save(); break; } case "LongGuns": @@ -134,10 +112,9 @@ export const handleInventoryItemConfigChange = async ( case "DrifterMelee": case "Sentinels": case "Horses": { - console.log("? ???? ?", equipmentName, equipment); + //console.log("general Item config saved", equipmentName, equipment); const itemEntries = equipment as IItemEntry; - const inventory = await getInventory(accountId); for (const [itemId, itemConfigEntries] of Object.entries(itemEntries)) { const inventoryItem = inventory[equipmentName].find(item => item._id?.toString() === itemId); @@ -150,15 +127,11 @@ export const handleInventoryItemConfigChange = async ( inventoryItem.Configs[parseInt(configId)] = config; } } - await inventory.save(); break; } case "CurrentLoadOutIds": { - //TODO: remove duplicate getInventory after finding out when currentloadOutId is sent const loadoutIds = equipment as IOid[]; // TODO: Check for more than just an array of oids, I think i remember one instance - const inventory = await getInventory(accountId); inventory.CurrentLoadOutIds = loadoutIds; - await inventory.save(); break; } case "EquippedGear": { @@ -168,27 +141,20 @@ export const handleInventoryItemConfigChange = async ( default: { console.log("category not implemented", equipmentName, equipment); } + //case "OperatorAmps": + // case "SentinelWeapons": + // case "KubrowPets": + // case "SpaceSuits": + // case "SpaceGuns": + // case "SpaceMelee": + // case "SpecialItems": + // case "MoaPets": + // case "Hoverboards": + // case "MechSuits": + // case "CrewShipHarnesses": + // case "CrewShips": + //case "KahlLoadOuts": not sure yet how to handle kahl: it is not sent in inventory } - - //case "OperatorAmps": - - // case "SentinelWeapons": - // case "KubrowPets": - // case "SpaceSuits": - // case "SpaceGuns": - // case "SpaceMelee": - - // case "SpecialItems": - // case "MoaPets": - // case "Hoverboards": - - // case "MechSuits": - // case "CrewShipHarnesses": - - // - - // case "CrewShips": - //case "KahlLoadOuts": not sure yet how to handle kahl: it is not sent in inventory } await inventory.save(); }; -- 2.47.2 From 7ac305036c221fa82a6c43230c61368601c4059c Mon Sep 17 00:00:00 2001 From: Ordis <134585663+OrdisPrime@users.noreply.github.com> Date: Thu, 14 Dec 2023 17:28:34 +0100 Subject: [PATCH 10/11] cleanup2 --- src/app.ts | 18 ------------------ src/controllers/api/saveLoadout.ts | 6 ++++-- src/helpers/inventoryHelpers.ts | 2 +- 3 files changed, 5 insertions(+), 21 deletions(-) diff --git a/src/app.ts b/src/app.ts index 03fa5bd2..3ca8bfc8 100644 --- a/src/app.ts +++ b/src/app.ts @@ -14,7 +14,6 @@ import { customRouter } from "@/src/routes/custom"; import { dynamicController } from "@/src/routes/dynamic"; import { statsRouter } from "@/src/routes/stats"; import { connectDatabase } from "@/src/services/mongoService"; -import { LoadoutModel as Loadout } from "@/src/models/inventoryModels/loadoutModel"; void connectDatabase(); @@ -35,23 +34,6 @@ app.use("/:id/dynamic", dynamicController); app.post("/pay/steamPacks.php", steamPacksController); app.use("/stats", statsRouter); -// eslint-disable-next-line @typescript-eslint/no-misused-promises -app.post("/test", async (req, _res) => { - console.log("test hit", req.body); - const newLoadout = new Loadout({}); - newLoadout.NORMAL.push({ - _id: "000000000000000000000000", - Favorite: false, - PresetIcon: "", - s: { ItemId: { $oid: "000000000000000000000000" }, mod: 0, cus: 0 }, - p: { ItemId: { $oid: "000000000000000000000000" }, mod: 0, cus: 0 }, - l: { ItemId: { $oid: "000000000000000000000000" }, mod: 0, cus: 0 }, - m: { ItemId: { $oid: "000000000000000000000000" }, mod: 0, cus: 0 } - }); - await newLoadout.save(); - _res.end(); -}); - app.use(unknownEndpointHandler); //app.use(errorHandler) diff --git a/src/controllers/api/saveLoadout.ts b/src/controllers/api/saveLoadout.ts index 9a973699..cd04f541 100644 --- a/src/controllers/api/saveLoadout.ts +++ b/src/controllers/api/saveLoadout.ts @@ -16,8 +16,10 @@ const saveLoadoutController: RequestHandler = async (req, res) => { // eslint-disable-next-line @typescript-eslint/no-unused-vars const { UpgradeVer, ...equipmentChanges } = body; await handleInventoryItemConfigChange(equipmentChanges, accountId); - } catch (error) { - res.status(400).json({ error: error.message }); + } catch (error: unknown) { + if (error instanceof Error) { + res.status(400).json({ error: error.message }); + } } }; diff --git a/src/helpers/inventoryHelpers.ts b/src/helpers/inventoryHelpers.ts index 517fcfd4..92c1726f 100644 --- a/src/helpers/inventoryHelpers.ts +++ b/src/helpers/inventoryHelpers.ts @@ -2,7 +2,7 @@ import { IOid } from "@/src/types/commonTypes"; import { IInventoryDatabase, IInventoryResponse } from "@/src/types/inventoryTypes/inventoryTypes"; import { Types } from "mongoose"; -// a schema's toJSON is responsible for changing Oid and Date to their corresponding Response versions __id to "ItemId":{"$oid":"6450f720bc562ebf030222d4"}, and a Date to "date":{"$date":{"$numberLong":"unix timestamp"}) +//TODO: this needs to be addressed: a schema's toJSON is responsible for changing Oid and Date to their corresponding Response versions __id to "ItemId":{"$oid":"6450f720bc562ebf030222d4"}, and a Date to "date":{"$date":{"$numberLong":"unix timestamp"}) export const toInventoryResponse = (inventoryDatabase: IInventoryDatabase): IInventoryResponse => { // eslint-disable-next-line @typescript-eslint/no-unused-vars const { accountOwnerId, ...inventoryResponse } = inventoryDatabase; -- 2.47.2 From 014772b7bfc2d571b8034ecb239aafacf92fed3a Mon Sep 17 00:00:00 2001 From: Ordis <134585663+OrdisPrime@users.noreply.github.com> Date: Thu, 14 Dec 2023 17:33:23 +0100 Subject: [PATCH 11/11] fix missing response --- src/controllers/api/saveLoadout.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/controllers/api/saveLoadout.ts b/src/controllers/api/saveLoadout.ts index cd04f541..31431798 100644 --- a/src/controllers/api/saveLoadout.ts +++ b/src/controllers/api/saveLoadout.ts @@ -16,6 +16,7 @@ const saveLoadoutController: RequestHandler = async (req, res) => { // eslint-disable-next-line @typescript-eslint/no-unused-vars const { UpgradeVer, ...equipmentChanges } = body; await handleInventoryItemConfigChange(equipmentChanges, accountId); + res.status(200).end(); } catch (error: unknown) { if (error instanceof Error) { res.status(400).json({ error: error.message }); -- 2.47.2