saveLoadout and misc. (#99)

Co-authored-by: Matej Voboril <tobiah@pm.me>
This commit is contained in:
OrdisPrime 2023-12-14 17:34:15 +01:00 committed by GitHub
parent 125d03d03a
commit dd99e8782c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
36 changed files with 1123 additions and 480 deletions

5
.gitignore vendored
View File

@ -4,4 +4,7 @@
/.env
/static/data/*.bin
yarn.lock
/tmp
/tmp
# JetBrains/webstorm configs
.idea/

1
.nvmrc Normal file
View File

@ -0,0 +1 @@
lts/iron

116
package-lock.json generated
View File

@ -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",
@ -319,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": "*",
@ -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"
}

View File

@ -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": {

View File

@ -0,0 +1,6 @@
import { Handler } from "express";
export const focusController: Handler = (_req, _res) => {
//console.log("focusController", req.query);
_res.sendStatus(400);
};

View File

@ -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({});
};

View File

@ -1,14 +1,89 @@
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;
}
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);
};

View File

@ -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" });

View File

@ -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);
}
}
}

View File

@ -1,13 +1,27 @@
import { Inventory } from "@/src/models/inventoryModel";
import { RequestHandler } from "express";
import util from "util";
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) => {
const body = JSON.parse(req.body);
console.log(util.inspect(body, { showHidden: false, depth: null, colors: true }));
//validate here
const accountId = parseString(req.query.accountId);
res.sendStatus(200);
try {
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);
res.status(200).end();
} catch (error: unknown) {
if (error instanceof Error) {
res.status(400).json({ error: error.message });
}
}
};
export { saveLoadoutController };

View File

@ -0,0 +1,6 @@
import { Request, Response } from "express";
export const setBootLocationController = (req: Request, res: Response) => {
console.log("setBootLocationController", req.query);
res.end();
};

View File

@ -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";

View File

@ -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 };

View File

@ -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 };

View File

@ -55,4 +55,12 @@ const parseBoolean = (booleanCandidate: unknown): boolean => {
return booleanCandidate;
};
export const isObject = (objectCandidate: unknown): objectCandidate is Record<string, unknown> => {
return (
(typeof objectCandidate === "object" || objectCandidate instanceof Object) &&
objectCandidate !== null &&
!Array.isArray(objectCandidate)
);
};
export { isString, isNumber, parseString, parseNumber, parseDateNumber, parseBoolean, parseEmail };

View File

@ -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 => {
//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;
return inventoryResponse as unknown as IInventoryResponse;
};
export { toInventoryResponse };
export const toOid = (objectId: Types.ObjectId) => {
return { $oid: objectId.toString() } satisfies IOid;
};

View File

@ -7,182 +7,229 @@ import {
IBooster,
IInventoryResponse,
IInventoryDatabaseDocument,
IInventoryResponseDocument
} from "../types/inventoryTypes/inventoryTypes";
import { IMongoDate, IOid } from "../types/commonTypes";
import { ISuitDatabase, ISuitDocument } from "@/src/types/inventoryTypes/SuitTypes";
ISlots,
IGenericItem,
IMailbox,
IDuviriInfo
} from "../../types/inventoryTypes/inventoryTypes";
import { IMongoDate, IOid } from "../../types/commonTypes";
import { ISuitDatabase } from "@/src/types/inventoryTypes/SuitTypes";
import { IWeaponDatabase } from "@/src/types/inventoryTypes/weaponTypes";
import {
IAbilityOverride,
IColor,
IItemConfig,
IOperatorConfigClient,
IOperatorConfigDatabase,
IPolarity
} from "@/src/types/inventoryTypes/commonInventoryTypes";
import { toOid } from "@/src/helpers/inventoryHelpers";
const abilityOverrideSchema = new Schema({
const polaritySchema = new Schema<IPolarity>({
Slot: Number,
Value: String
});
const abilityOverrideSchema = new Schema<IAbilityOverride>({
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<IColor>(
{
t0: Number,
t1: Number,
t2: Number,
t3: Number,
en: Number,
e1: Number,
m0: Number,
m1: Number
},
{ _id: false }
);
const operatorConfigSchema = new Schema<IOperatorConfigDatabase>(
{
Skins: [String],
pricol: colorSchema,
attcol: colorSchema,
sigcol: colorSchema,
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
},
{ 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<IItemConfig>(
{
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<IWeaponDatabase>(
{
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<IBooster>({
ExpiryDate: Number,
ItemType: String
});
const RawUpgrades = new Schema<IRawUpgrade>(
{
ItemType: String,
ItemCount: Number
},
{ id: false }
);
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: find out 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<ISuitDatabase>({
ItemType: String,
Configs: [suitConfigSchema],
UpgradeVer: Number,
XP: Number,
InfestationDate: Date,
Features: Number,
Polarity: [polaritySchema],
Polarized: Number,
ModSlotPurchases: Number,
FocusLens: String,
UnlockLevel: Number
//TODO: reduce weapon and suit schemas to one schema if reasonable
const suitSchema = new Schema<ISuitDatabase>(
{
ItemType: String,
Configs: [ItemConfigSchema],
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<ISlots>(
{
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) {
@ -191,7 +238,70 @@ FlavourItemSchema.set("toJSON", {
}
});
const inventorySchema = new Schema<IInventoryDatabaseDocument, InventoryDocumentProps>({
const GenericItemSchema = new Schema<IGenericItem>(
{
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<IMailbox>(
{
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<IDuviriInfo>(
{
Seed: Number,
NumCompletions: Number
},
{
_id: false,
id: false
}
);
DuviriInfoSchema.set("toJSON", {
transform(_document, returnedObject) {
delete returnedObject.__v;
}
});
const inventorySchema = new Schema<IInventoryDatabase, InventoryDocumentProps>({
Horses: [GenericItemSchema],
DrifterMelee: [GenericItemSchema],
DrifterGuns: [GenericItemSchema],
DuviriInfo: DuviriInfoSchema,
Mailbox: MailboxSchema,
KahlLoadOuts: [Schema.Types.Mixed],
accountOwnerId: Schema.Types.ObjectId,
SubscribedToEmails: Number,
Created: Schema.Types.Mixed,
@ -203,11 +313,15 @@ const inventorySchema = new Schema<IInventoryDatabaseDocument, InventoryDocument
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,
@ -227,9 +341,9 @@ const inventorySchema = new Schema<IInventoryDatabaseDocument, InventoryDocument
Ships: [Schema.Types.Mixed],
QuestKeys: [Schema.Types.Mixed],
FlavourItems: [FlavourItemSchema],
Scoops: [Schema.Types.Mixed],
Scoops: [GenericItemSchema],
TrainingRetriesLeft: Number,
LoadOutPresets: Schema.Types.Mixed,
LoadOutPresets: { type: Schema.Types.ObjectId, ref: "Loadout" },
CurrentLoadOutIds: [Schema.Types.Mixed],
Missions: [Schema.Types.Mixed],
RandomUpgradesIdentified: Number,
@ -261,14 +375,14 @@ const inventorySchema = new Schema<IInventoryDatabaseDocument, InventoryDocument
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,
@ -281,7 +395,6 @@ const inventorySchema = new Schema<IInventoryDatabaseDocument, InventoryDocument
ActiveAvatarImageType: String,
KubrowPets: [Schema.Types.Mixed],
ShipDecorations: [Schema.Types.Mixed],
OperatorAmpBin: Schema.Types.Mixed,
DailyAffiliationCetus: Number,
DailyAffiliationQuills: Number,
DiscoveredMarkers: [Schema.Types.Mixed],
@ -302,7 +415,7 @@ const inventorySchema = new Schema<IInventoryDatabaseDocument, InventoryDocument
BountyScore: Number,
ChallengeInstanceStates: [Schema.Types.Mixed],
LoginMilestoneRewards: [String],
OperatorLoadOuts: [Schema.Types.Mixed],
OperatorLoadOuts: [operatorConfigSchema],
DailyAffiliationVentkids: Number,
DailyAffiliationVox: Number,
RecentVendorPurchases: [Schema.Types.Mixed],
@ -313,13 +426,12 @@ const inventorySchema = new Schema<IInventoryDatabaseDocument, InventoryDocument
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],
@ -329,17 +441,15 @@ const inventorySchema = new Schema<IInventoryDatabaseDocument, InventoryDocument
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],
AdultOperatorLoadOuts: [Schema.Types.Mixed],
AdultOperatorLoadOuts: [operatorConfigSchema],
LotusCustomization: Schema.Types.Mixed,
UseAdultOperatorLoadout: Boolean,
DailyAffiliationZariman: Number,
@ -387,9 +497,17 @@ type InventoryDocumentProps = {
RawUpgrades: Types.DocumentArray<IRawUpgrade>;
MiscItems: Types.DocumentArray<IMiscItem>;
Boosters: Types.DocumentArray<IBooster>;
OperatorLoadOuts: Types.DocumentArray<IOperatorConfigClient>;
AdultOperatorLoadOuts: Types.DocumentArray<IOperatorConfigClient>;
MechSuits: Types.DocumentArray<ISuitDatabase>;
Scoops: Types.DocumentArray<IGenericItem>;
DataKnives: Types.DocumentArray<IGenericItem>;
DrifterMelee: Types.DocumentArray<IGenericItem>;
Sentinels: Types.DocumentArray<IWeaponDatabase>;
Horses: Types.DocumentArray<IGenericItem>;
};
type InventoryModelType = Model<IInventoryDatabase, object, InventoryDocumentProps>;
type InventoryModelType = Model<IInventoryDatabase, {}, InventoryDocumentProps>;
const Inventory = model<IInventoryDatabase, InventoryModelType>("Inventory", inventorySchema);

View File

@ -0,0 +1,96 @@
import { IOid } from "@/src/types/commonTypes";
import { ILoadoutConfigDatabase, ILoadoutDatabase, IEquipmentSelection } from "@/src/types/saveLoadoutTypes";
import { Model, Schema, Types, model } from "mongoose";
const oidSchema = new Schema<IOid>(
{
$oid: String
},
{
_id: false
}
);
//create a mongoose schema based on interface M
const EquipmentSelectionSchema = new Schema<IEquipmentSelection>(
{
ItemId: {
type: oidSchema,
default: { $oid: "000000000000000000000000" }
},
mod: Number,
cus: Number
},
{
_id: false
}
);
const loadoutConfigSchema = new Schema<ILoadoutConfigDatabase>(
{
PresetIcon: String,
Favorite: Boolean,
n: String,
s: EquipmentSelectionSchema,
p: EquipmentSelectionSchema,
l: EquipmentSelectionSchema,
m: EquipmentSelectionSchema
},
{
id: false
}
);
loadoutConfigSchema.virtual("ItemId").get(function () {
return { $oid: this._id.toString() } satisfies IOid;
});
loadoutConfigSchema.set("toJSON", {
virtuals: true,
transform(_doc, ret, _options) {
delete ret._id;
delete ret.__v;
}
});
export const loadoutSchema = new Schema<ILoadoutDatabase, loadoutModelType>({
NORMAL: [loadoutConfigSchema],
SENTINEL: [loadoutConfigSchema],
ARCHWING: [loadoutConfigSchema],
NORMAL_PVP: [loadoutConfigSchema],
LUNARO: [loadoutConfigSchema],
OPERATOR: [loadoutConfigSchema],
KDRIVE: [loadoutConfigSchema],
DATAKNIFE: [loadoutConfigSchema],
MECH: [loadoutConfigSchema],
OPERATOR_ADULT: [loadoutConfigSchema],
DRIFTER: [loadoutConfigSchema],
loadoutOwnerId: Schema.Types.ObjectId
});
loadoutSchema.set("toJSON", {
transform(_doc, ret, _options) {
delete ret._id;
delete ret.__v;
delete ret.loadoutOwnerId;
}
});
//create database typefor ILoadoutConfig
type loadoutDocumentProps = {
NORMAL: Types.DocumentArray<ILoadoutConfigDatabase>;
SENTINEL: Types.DocumentArray<ILoadoutConfigDatabase>;
ARCHWING: Types.DocumentArray<ILoadoutConfigDatabase>;
NORMAL_PVP: Types.DocumentArray<ILoadoutConfigDatabase>;
LUNARO: Types.DocumentArray<ILoadoutConfigDatabase>;
OPERATOR: Types.DocumentArray<ILoadoutConfigDatabase>;
KDRIVE: Types.DocumentArray<ILoadoutConfigDatabase>;
DATAKNIFE: Types.DocumentArray<ILoadoutConfigDatabase>;
MECH: Types.DocumentArray<ILoadoutConfigDatabase>;
OPERATOR_ADULT: Types.DocumentArray<ILoadoutConfigDatabase>;
DRIFTER: Types.DocumentArray<ILoadoutConfigDatabase>;
};
type loadoutModelType = Model<ILoadoutDatabase, {}, loadoutDocumentProps>;
export const LoadoutModel = model<ILoadoutDatabase, loadoutModelType>("Loadout", loadoutSchema);

View File

@ -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<IShip>({
ShipOwnerId: Schema.Types.ObjectId,
Ship: shipSchema,
Apartment: apartmentSchema
Apartment: apartmentSchema,
LoadOutInventory: {
LoadOutPresets: {
type: Schema.Types.ObjectId,
ref: "Loadout"
}
}
});
shipDatabaseSchema.set("toJSON", {

View File

@ -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

View File

@ -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";

View File

@ -1,10 +1,10 @@
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";
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) => {
export 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,13 +53,28 @@ export const getInventory = async (accountOwnerId: string) => {
return inventory;
};
const addPowerSuit = async (powersuitName: string, accountId: string): Promise<ISuitResponse> => {
//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<ISuitClient> => {
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);
@ -65,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");
}
@ -107,7 +130,7 @@ export const addWeapon = async (
weaponType: WeaponTypeInternal,
weaponName: string,
accountId: string
): Promise<IWeaponResponse> => {
): Promise<IWeaponClient> => {
const inventory = await getInventory(accountId);
let weaponIndex;
@ -139,7 +162,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 +265,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 +278,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);
@ -339,5 +361,3 @@ export const upgradeMod = async (artifactsData: IArtifactsRequest, accountId: st
throw error;
}
};
export { createInventory, addPowerSuit };

View File

@ -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;
};

View File

@ -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);

View File

@ -0,0 +1,160 @@
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);
};
//TODO: setup default items on account creation or like originally in giveStartingItems.php
//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
) => {
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;
if (isEmptyObject(equipment)) {
continue;
}
// non-empty is a change in loadout(or suit...)
switch (equipmentName) {
case "OperatorLoadOuts":
case "AdultOperatorLoadOuts": {
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);
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
});
continue;
}
loadout.set(loadoutConfig);
}
break;
}
case "LoadOuts": {
//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;
// empty loadout slot like: "NORMAL": {}
if (isEmptyObject(newLoadout)) {
continue;
}
// all non-empty entries are one loadout slot
for (const [loadoutId, loadoutConfig] of Object.entries(newLoadout)) {
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
});
continue;
}
const loadoutIndex = loadout[loadoutSlot].indexOf(oldLoadoutConfig);
if (loadoutIndex === undefined || loadoutIndex === -1) {
throw new Error("loadout index not found");
}
//perhaps .overwrite() is better
loadout[loadoutSlot][loadoutIndex].set(loadoutConfig);
}
}
await loadout.save();
break;
}
case "LongGuns":
case "Pistols":
case "Suits":
case "Melee":
case "Scoops":
case "DataKnives":
case "DrifterMelee":
case "Sentinels":
case "Horses": {
//console.log("general Item config saved", equipmentName, equipment);
const itemEntries = equipment as IItemEntry;
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(itemConfigEntries)) {
inventoryItem.Configs[parseInt(configId)] = config;
}
}
break;
}
case "CurrentLoadOutIds": {
const loadoutIds = equipment as IOid[]; // TODO: Check for more than just an array of oids, I think i remember one instance
inventory.CurrentLoadOutIds = loadoutIds;
break;
}
case "EquippedGear": {
inventory.EquippedGear = equipment as string[];
break;
}
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
}
}
await inventory.save();
};

View File

@ -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) {

View File

@ -1,19 +1,15 @@
import { IOid } from "@/src/types/commonTypes";
import { IAbilityOverride, IColor, IPolarity } from "@/src/types/inventoryTypes/commonInventoryTypes";
import { Document, Types } from "mongoose";
import { IPolarity } from "@/src/types/inventoryTypes/commonInventoryTypes";
import { Types } from "mongoose";
import { IItemConfig } from "./commonInventoryTypes";
// 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;
}
export interface ISuitDatabase {
ItemType: string;
Configs: SuitConfig[];
Configs: IItemConfig[];
UpgradeVer?: number;
XP?: number;
InfestationDate?: Date;
@ -24,26 +20,5 @@ export interface ISuitDatabase {
FocusLens?: string;
UnlockLevel?: number;
_id: Types.ObjectId;
ItemId?: IOid;
}
export interface SuitConfig {
Skins?: string[];
pricol?: IColor;
attcol?: IColor;
eyecol?: IColor;
sigcol?: IColor;
Upgrades?: string[];
Songs?: Song[];
Name?: string;
AbilityOverride?: IAbilityOverride;
PvpUpgrades?: string[];
ugly?: boolean;
}
export interface Song {
m?: string;
b?: string;
p?: string;
s: string;
ItemId?: IOid; // only in response
}

View File

@ -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<IOperatorConfigDatabase, "_id"> {
ItemId: IOid;
}

View File

@ -1,19 +1,53 @@
/* 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 {
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";
//Document extends will be deleted soon. TODO: delete and migrate uses to ...
export interface IInventoryDatabaseDocument extends IInventoryDatabase, Document {}
export interface IInventoryDatabase extends Omit<IInventoryResponse, "TrainingDate"> {
export interface IInventoryDatabase extends Omit<IInventoryResponse, "TrainingDate" | "LoadOutPresets" | "Mailbox"> {
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
Mailbox: Types.ObjectId; // Mailbox changed from IMailbox to Types.ObjectId
}
export interface IInventoryResponseDocument extends IInventoryResponse, Document {}
export interface IGenericItem {
ItemType: string;
XP?: number;
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 {
Horses: IGenericItem[];
DrifterMelee: IGenericItem[];
DrifterGuns: IGenericItem[];
DuviriInfo: IDuviriInfo;
Mailbox: IMailbox;
KahlLoadOuts: IGenericItem[];
SubscribedToEmails: number;
Created: IMongoDate;
RewardSeed: number;
@ -21,14 +55,18 @@ export interface IInventoryResponse {
PremiumCredits: number;
PremiumCreditsFree: number;
FusionPoints: number;
SuitBin: ICrewShipSalvageBinClass;
WeaponBin: ICrewShipSalvageBinClass;
SentinelBin: ICrewShipSalvageBinClass;
SpaceSuitBin: ICrewShipSalvageBinClass;
SpaceWeaponBin: ICrewShipSalvageBinClass;
PvpBonusLoadoutBin: ICrewMemberBinClass;
PveBonusLoadoutBin: ICrewShipSalvageBinClass;
RandomModBin: ICrewShipSalvageBinClass;
SuitBin: ISlots;
WeaponBin: ISlots;
SentinelBin: ISlots;
SpaceSuitBin: ISlots;
SpaceWeaponBin: ISlots;
PvpBonusLoadoutBin: ISlots;
PveBonusLoadoutBin: ISlots;
RandomModBin: ISlots;
MechBin: ISlots;
CrewMemberBin: ISlots;
OperatorAmpBin: ISlots;
CrewShipSalvageBin: ISlots;
TradesRemaining: number;
DailyAffiliation: number;
DailyAffiliationPvp: number;
@ -48,7 +86,7 @@ export interface IInventoryResponse {
Ships: IShip[];
QuestKeys: IQuestKey[];
FlavourItems: IFlavourItem[];
Scoops: IScoop[];
Scoops: IGenericItem[];
TrainingRetriesLeft: number;
LoadOutPresets: ILoadOutPresets;
CurrentLoadOutIds: Array<any[] | IOid>;
@ -82,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;
@ -102,7 +140,6 @@ export interface IInventoryResponse {
ActiveAvatarImageType: string;
KubrowPets: IKubrowPet[];
ShipDecorations: IConsumable[];
OperatorAmpBin: ICrewShipSalvageBinClass;
DailyAffiliationCetus: number;
DailyAffiliationQuills: number;
DiscoveredMarkers: IDiscoveredMarker[];
@ -123,7 +160,7 @@ export interface IInventoryResponse {
BountyScore: number;
ChallengeInstanceStates: IChallengeInstanceState[];
LoginMilestoneRewards: string[];
OperatorLoadOuts: IOperatorLoadOut[];
OperatorLoadOuts: IOperatorConfigClient[];
DailyAffiliationVentkids: number;
DailyAffiliationVox: number;
RecentVendorPurchases: Array<number | string>;
@ -134,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: ICrewShipSalvageBinClass;
PlayerSkills: IPlayerSkills;
CrewShipAmmo: IConsumable[];
CrewShipSalvagedWeaponSkins: ICrewShipSalvagedWeaponSkin[];
@ -150,17 +186,15 @@ 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[];
AdultOperatorLoadOuts: IAdultOperatorLoadOut[];
AdultOperatorLoadOuts: IOperatorConfigClient[];
LotusCustomization: ILotusCustomization;
UseAdultOperatorLoadout: boolean;
DailyAffiliationZariman: number;
@ -260,10 +294,6 @@ export interface IConsumable {
ItemType: string;
}
export interface ICrewMemberBinClass {
Slots: number;
}
export interface ICrewMember {
ItemType: string;
NemesisFingerprint: number;
@ -310,8 +340,8 @@ export interface ICrewShipHarnessConfig {
Upgrades?: string[];
}
export interface ICrewShipSalvageBinClass {
Extra: number;
export interface ISlots {
Extra?: number;
Slots: number;
}
@ -403,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[];
@ -623,6 +637,7 @@ export interface ILibraryPersonalProgress {
Completed: boolean;
}
//this needs to be checked against ILoadoutDatabase
export interface ILoadOutPresets {
NORMAL: INormal[];
NORMAL_PVP: IArchwing[];
@ -717,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;
@ -870,7 +874,7 @@ export enum GivingSlotOrderInfo {
LotusUpgradesModsPistolDualStatElectEventPistolMod = "/Lotus/Upgrades/Mods/Pistol/DualStat/ElectEventPistolMod"
}
export interface PeriodicMissionCompletion {
export interface IPeriodicMissionCompletion {
date: IMongoDate;
tag: string;
count?: number;
@ -916,6 +920,7 @@ export interface IQuestKey {
Progress?: IProgress[];
unlock?: boolean;
Completed?: boolean;
CustomData?: string;
ItemType: string;
CompletionDate?: IMongoDate;
}
@ -933,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;
@ -953,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;
@ -1022,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[];

View File

@ -1,14 +1,15 @@
import { IOid } from "@/src/types/commonTypes";
import { IColor, IPolarity } from "@/src/types/inventoryTypes/commonInventoryTypes";
import { IItemConfig } from "./commonInventoryTypes";
import { IPolarity } from "@/src/types/inventoryTypes/commonInventoryTypes";
import { Types } from "mongoose";
export interface IWeaponResponse extends IWeaponDatabase {
export interface IWeaponClient extends Omit<IWeaponDatabase, "_id"> {
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 {

View File

@ -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[];
@ -40,5 +40,6 @@ export type IBinChanges = {
export enum SlotType {
SUIT = "SuitBin",
WEAPON = "WeaponBin"
WEAPON = "WeaponBin",
MECHSUIT = "MechBin"
}

View File

@ -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[];

View File

@ -0,0 +1,92 @@
import { IOid } from "@/src/types/commonTypes";
import { IItemConfig, IOperatorConfigClient } from "@/src/types/inventoryTypes/commonInventoryTypes";
import { Types } from "mongoose";
export interface ISaveLoadoutRequest {
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: IOperatorConfigEntry;
AdultOperatorLoadOuts: IOperatorConfigEntry;
KahlLoadOuts: IItemEntry;
CrewShips: IItemEntry;
CurrentLoadOutIds: IOid[];
ValidNewLoadoutId: string;
EquippedGear: string[];
}
export interface ISaveLoadoutRequestNoUpgradeVer extends Omit<ISaveLoadoutRequest, "UpgradeVer"> {}
export interface IOperatorConfigEntry {
[configId: string]: IOperatorConfigClient;
}
export interface IItemEntry {
[itemId: string]: IConfigEntry;
}
export interface IConfigEntry {
[configId: string]: IItemConfig;
}
export interface ILoadoutClient extends Omit<ILoadoutDatabase, "_id" | "loadoutOwnerId"> {}
export interface ILoadoutDatabase {
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 ILoadoutEntry {
[key: string]: ILoadoutConfigClient;
}
export interface ILoadoutConfigDatabase extends Omit<ILoadoutConfigClient, "ItemId"> {
_id: Types.ObjectId;
}
// for request and response from and to client
export interface ILoadoutConfigClient {
ItemId: IOid;
n: string;
PresetIcon: string;
Favorite: boolean;
s: IEquipmentSelection;
p: IEquipmentSelection;
l: IEquipmentSelection;
m: IEquipmentSelection;
}
export interface IEquipmentSelection {
ItemId: IOid;
mod: number;
cus: number;
}

View File

@ -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[];
}

View File

@ -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": [],

View File

@ -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"
}
]