chore: add warning coverage for cyclic includes (#2407)
and some initial refactoring to avoid it where possible Reviewed-on: OpenWF/SpaceNinjaServer#2407 Co-authored-by: Sainan <63328889+Sainan@users.noreply.github.com> Co-committed-by: Sainan <63328889+Sainan@users.noreply.github.com>
This commit is contained in:
		
							parent
							
								
									5089f67146
								
							
						
					
					
						commit
						a75e6d6b95
					
				
							
								
								
									
										18
									
								
								.eslintrc
									
									
									
									
									
								
							
							
						
						
									
										18
									
								
								.eslintrc
									
									
									
									
									
								
							@ -1,10 +1,12 @@
 | 
			
		||||
{
 | 
			
		||||
    "plugins": ["@typescript-eslint", "prettier", "import"],
 | 
			
		||||
    "extends": [
 | 
			
		||||
        "eslint:recommended",
 | 
			
		||||
        "plugin:@typescript-eslint/recommended",
 | 
			
		||||
        "plugin:@typescript-eslint/recommended-requiring-type-checking"
 | 
			
		||||
        "plugin:@typescript-eslint/recommended-requiring-type-checking",
 | 
			
		||||
        "plugin:import/recommended",
 | 
			
		||||
        "plugin:import/typescript"
 | 
			
		||||
    ],
 | 
			
		||||
    "plugins": ["@typescript-eslint", "prettier"],
 | 
			
		||||
    "env": {
 | 
			
		||||
        "browser": true,
 | 
			
		||||
        "es6": true,
 | 
			
		||||
@ -26,11 +28,19 @@
 | 
			
		||||
        "no-case-declarations": "error",
 | 
			
		||||
        "prettier/prettier": "error",
 | 
			
		||||
        "no-mixed-spaces-and-tabs": "error",
 | 
			
		||||
        "require-await": "off",
 | 
			
		||||
        "@typescript-eslint/require-await": "error"
 | 
			
		||||
        "@typescript-eslint/require-await": "error",
 | 
			
		||||
        "import/no-named-as-default-member": "off",
 | 
			
		||||
        "import/no-cycle": "warn"
 | 
			
		||||
    },
 | 
			
		||||
    "parser": "@typescript-eslint/parser",
 | 
			
		||||
    "parserOptions": {
 | 
			
		||||
        "project": "./tsconfig.json"
 | 
			
		||||
    },
 | 
			
		||||
    "settings": {
 | 
			
		||||
        "import/extensions": [ ".ts" ],
 | 
			
		||||
        "import/resolver": {
 | 
			
		||||
            "typescript": true,
 | 
			
		||||
            "node": true
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										2188
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										2188
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@ -47,6 +47,8 @@
 | 
			
		||||
    "@typescript-eslint/eslint-plugin": "^8.28.0",
 | 
			
		||||
    "@typescript-eslint/parser": "^8.28.0",
 | 
			
		||||
    "eslint": "^8",
 | 
			
		||||
    "eslint-import-resolver-typescript": "^4.4.4",
 | 
			
		||||
    "eslint-plugin-import": "^2.32.0",
 | 
			
		||||
    "eslint-plugin-prettier": "^5.2.5",
 | 
			
		||||
    "prettier": "^3.5.3",
 | 
			
		||||
    "tree-kill": "^1.2.2"
 | 
			
		||||
 | 
			
		||||
@ -17,12 +17,12 @@ import {
 | 
			
		||||
    addKubrowPetPrint
 | 
			
		||||
} from "@/src/services/inventoryService";
 | 
			
		||||
import { IInventoryChanges } from "@/src/types/purchaseTypes";
 | 
			
		||||
import { IEquipmentClient } from "@/src/types/inventoryTypes/commonInventoryTypes";
 | 
			
		||||
import { InventorySlot, IPendingRecipeDatabase, Status } from "@/src/types/inventoryTypes/inventoryTypes";
 | 
			
		||||
import { InventorySlot, IPendingRecipeDatabase } from "@/src/types/inventoryTypes/inventoryTypes";
 | 
			
		||||
import { toOid2 } from "@/src/helpers/inventoryHelpers";
 | 
			
		||||
import { TInventoryDatabaseDocument } from "@/src/models/inventoryModels/inventoryModel";
 | 
			
		||||
import { IRecipe } from "warframe-public-export-plus";
 | 
			
		||||
import { config } from "@/src/services/configService";
 | 
			
		||||
import { IEquipmentClient, Status } from "@/src/types/equipmentTypes";
 | 
			
		||||
 | 
			
		||||
interface IClaimCompletedRecipeRequest {
 | 
			
		||||
    RecipeIds: IOid[];
 | 
			
		||||
 | 
			
		||||
@ -21,7 +21,8 @@ import {
 | 
			
		||||
    updateCurrency
 | 
			
		||||
} from "@/src/services/inventoryService";
 | 
			
		||||
import { getAccountIdForRequest } from "@/src/services/loginService";
 | 
			
		||||
import { IFusionTreasure, IMiscItem, ITypeCount } from "@/src/types/inventoryTypes/inventoryTypes";
 | 
			
		||||
import { ITypeCount } from "@/src/types/commonTypes";
 | 
			
		||||
import { IFusionTreasure, IMiscItem } from "@/src/types/inventoryTypes/inventoryTypes";
 | 
			
		||||
import { RequestHandler } from "express";
 | 
			
		||||
 | 
			
		||||
export const contributeToVaultController: RequestHandler = async (req, res) => {
 | 
			
		||||
 | 
			
		||||
@ -12,7 +12,7 @@ import { getJSONfromString } from "@/src/helpers/stringHelpers";
 | 
			
		||||
import { IInventoryChanges } from "@/src/types/purchaseTypes";
 | 
			
		||||
import { getRandomInt } from "@/src/services/rngService";
 | 
			
		||||
import { IFingerprintStat } from "@/src/helpers/rivenHelper";
 | 
			
		||||
import { IEquipmentDatabase } from "@/src/types/inventoryTypes/commonInventoryTypes";
 | 
			
		||||
import { IEquipmentDatabase } from "@/src/types/equipmentTypes";
 | 
			
		||||
 | 
			
		||||
export const crewShipIdentifySalvageController: RequestHandler = async (req, res) => {
 | 
			
		||||
    const accountId = await getAccountIdForRequest(req);
 | 
			
		||||
 | 
			
		||||
@ -3,7 +3,7 @@ import { getAccountIdForRequest } from "@/src/services/loginService";
 | 
			
		||||
import { addMiscItems, getInventory } from "@/src/services/inventoryService";
 | 
			
		||||
import { getJSONfromString } from "@/src/helpers/stringHelpers";
 | 
			
		||||
import { getRecipe, WeaponTypeInternal } from "@/src/services/itemDataService";
 | 
			
		||||
import { EquipmentFeatures } from "@/src/types/inventoryTypes/commonInventoryTypes";
 | 
			
		||||
import { EquipmentFeatures } from "@/src/types/equipmentTypes";
 | 
			
		||||
 | 
			
		||||
export const evolveWeaponController: RequestHandler = async (req, res) => {
 | 
			
		||||
    const accountId = await getAccountIdForRequest(req);
 | 
			
		||||
 | 
			
		||||
@ -4,7 +4,6 @@ import { getInventory, addMiscItems, addEquipment, occupySlot } from "@/src/serv
 | 
			
		||||
import { IMiscItem, TFocusPolarity, TEquipmentKey, InventorySlot } from "@/src/types/inventoryTypes/inventoryTypes";
 | 
			
		||||
import { logger } from "@/src/utils/logger";
 | 
			
		||||
import { ExportFocusUpgrades } from "warframe-public-export-plus";
 | 
			
		||||
import { IEquipmentClient } from "@/src/types/inventoryTypes/commonInventoryTypes";
 | 
			
		||||
import { Inventory } from "@/src/models/inventoryModels/inventoryModel";
 | 
			
		||||
 | 
			
		||||
export const focusController: RequestHandler = async (req, res) => {
 | 
			
		||||
@ -116,7 +115,7 @@ export const focusController: RequestHandler = async (req, res) => {
 | 
			
		||||
            });
 | 
			
		||||
            occupySlot(inventory, InventorySlot.AMPS, false);
 | 
			
		||||
            await inventory.save();
 | 
			
		||||
            res.json((inventoryChanges.OperatorAmps as IEquipmentClient[])[0]);
 | 
			
		||||
            res.json(inventoryChanges.OperatorAmps![0]);
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
        case FocusOperation.UnbindUpgrade: {
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,6 @@
 | 
			
		||||
import { Inventory } from "@/src/models/inventoryModels/inventoryModel";
 | 
			
		||||
import { generateRewardSeed } from "@/src/services/inventoryService";
 | 
			
		||||
import { getAccountIdForRequest } from "@/src/services/loginService";
 | 
			
		||||
import { generateRewardSeed } from "@/src/services/rngService";
 | 
			
		||||
import { RequestHandler } from "express";
 | 
			
		||||
 | 
			
		||||
export const getNewRewardSeedController: RequestHandler = async (req, res) => {
 | 
			
		||||
 | 
			
		||||
@ -3,9 +3,10 @@ import { getAccountIdForRequest } from "@/src/services/loginService";
 | 
			
		||||
import { getJSONfromString } from "@/src/helpers/stringHelpers";
 | 
			
		||||
import { addMiscItems, getInventory } from "@/src/services/inventoryService";
 | 
			
		||||
import { TEquipmentKey } from "@/src/types/inventoryTypes/inventoryTypes";
 | 
			
		||||
import { ArtifactPolarity, EquipmentFeatures, IEquipmentClient } from "@/src/types/inventoryTypes/commonInventoryTypes";
 | 
			
		||||
import { ArtifactPolarity } from "@/src/types/inventoryTypes/commonInventoryTypes";
 | 
			
		||||
import { ExportRecipes } from "warframe-public-export-plus";
 | 
			
		||||
import { IInventoryChanges } from "@/src/types/purchaseTypes";
 | 
			
		||||
import { EquipmentFeatures, IEquipmentClient } from "@/src/types/equipmentTypes";
 | 
			
		||||
 | 
			
		||||
interface IGildWeaponRequest {
 | 
			
		||||
    ItemName: string;
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,8 @@
 | 
			
		||||
import { getJSONfromString } from "@/src/helpers/stringHelpers";
 | 
			
		||||
import { addLoreFragmentScans, addShipDecorations, getInventory } from "@/src/services/inventoryService";
 | 
			
		||||
import { getAccountIdForRequest } from "@/src/services/loginService";
 | 
			
		||||
import { ILoreFragmentScan, ITypeCount } from "@/src/types/inventoryTypes/inventoryTypes";
 | 
			
		||||
import { ITypeCount } from "@/src/types/commonTypes";
 | 
			
		||||
import { ILoreFragmentScan } from "@/src/types/inventoryTypes/inventoryTypes";
 | 
			
		||||
import { RequestHandler } from "express";
 | 
			
		||||
 | 
			
		||||
export const giveShipDecoAndLoreFragmentController: RequestHandler = async (req, res) => {
 | 
			
		||||
 | 
			
		||||
@ -5,7 +5,7 @@ import { config } from "@/src/services/configService";
 | 
			
		||||
import allDialogue from "@/static/fixed_responses/allDialogue.json";
 | 
			
		||||
import { ILoadoutDatabase } from "@/src/types/saveLoadoutTypes";
 | 
			
		||||
import { IInventoryClient, IShipInventory, equipmentKeys } from "@/src/types/inventoryTypes/inventoryTypes";
 | 
			
		||||
import { IPolarity, ArtifactPolarity, EquipmentFeatures } from "@/src/types/inventoryTypes/commonInventoryTypes";
 | 
			
		||||
import { IPolarity, ArtifactPolarity } from "@/src/types/inventoryTypes/commonInventoryTypes";
 | 
			
		||||
import { ExportCustoms, ExportFlavour, ExportResources, ExportVirtuals } from "warframe-public-export-plus";
 | 
			
		||||
import { applyCheatsToInfestedFoundry, handleSubsumeCompletion } from "@/src/services/infestedFoundryService";
 | 
			
		||||
import {
 | 
			
		||||
@ -14,7 +14,6 @@ import {
 | 
			
		||||
    allDailyAffiliationKeys,
 | 
			
		||||
    cleanupInventory,
 | 
			
		||||
    createLibraryDailyTask,
 | 
			
		||||
    generateRewardSeed,
 | 
			
		||||
    getCalendarProgress
 | 
			
		||||
} from "@/src/services/inventoryService";
 | 
			
		||||
import { logger } from "@/src/utils/logger";
 | 
			
		||||
@ -28,6 +27,8 @@ import { toLegacyOid, toOid, version_compare } from "@/src/helpers/inventoryHelp
 | 
			
		||||
import { Inbox } from "@/src/models/inboxModel";
 | 
			
		||||
import { unixTimesInMs } from "@/src/constants/timeConstants";
 | 
			
		||||
import { DailyDeal } from "@/src/models/worldStateModel";
 | 
			
		||||
import { EquipmentFeatures } from "@/src/types/equipmentTypes";
 | 
			
		||||
import { generateRewardSeed } from "@/src/services/rngService";
 | 
			
		||||
 | 
			
		||||
export const inventoryController: RequestHandler = async (request, response) => {
 | 
			
		||||
    const account = await getAccountForRequest(request);
 | 
			
		||||
 | 
			
		||||
@ -8,7 +8,7 @@ import { createAccount, createNonce, getUsernameFromEmail, isCorrectPassword } f
 | 
			
		||||
import { IDatabaseAccountJson, ILoginRequest, ILoginResponse } from "@/src/types/loginTypes";
 | 
			
		||||
import { logger } from "@/src/utils/logger";
 | 
			
		||||
import { version_compare } from "@/src/helpers/inventoryHelpers";
 | 
			
		||||
import { sendWsBroadcastTo } from "@/src/services/webService";
 | 
			
		||||
import { sendWsBroadcastTo } from "@/src/services/wsService";
 | 
			
		||||
 | 
			
		||||
export const loginController: RequestHandler = async (request, response) => {
 | 
			
		||||
    const loginRequest = JSON.parse(String(request.body)) as ILoginRequest; // parse octet stream of json data to json object
 | 
			
		||||
 | 
			
		||||
@ -9,7 +9,7 @@ import {
 | 
			
		||||
} from "@/src/services/loginRewardService";
 | 
			
		||||
import { getInventory } from "@/src/services/inventoryService";
 | 
			
		||||
import { config } from "@/src/services/configService";
 | 
			
		||||
import { sendWsBroadcastTo } from "@/src/services/webService";
 | 
			
		||||
import { sendWsBroadcastTo } from "@/src/services/wsService";
 | 
			
		||||
 | 
			
		||||
export const loginRewardsController: RequestHandler = async (req, res) => {
 | 
			
		||||
    const account = await getAccountForRequest(req);
 | 
			
		||||
 | 
			
		||||
@ -6,7 +6,7 @@ import {
 | 
			
		||||
} from "@/src/services/loginRewardService";
 | 
			
		||||
import { getAccountForRequest } from "@/src/services/loginService";
 | 
			
		||||
import { handleStoreItemAcquisition } from "@/src/services/purchaseService";
 | 
			
		||||
import { sendWsBroadcastTo } from "@/src/services/webService";
 | 
			
		||||
import { sendWsBroadcastTo } from "@/src/services/wsService";
 | 
			
		||||
import { IInventoryChanges } from "@/src/types/purchaseTypes";
 | 
			
		||||
import { logger } from "@/src/utils/logger";
 | 
			
		||||
import { RequestHandler } from "express";
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,6 @@
 | 
			
		||||
import { RequestHandler } from "express";
 | 
			
		||||
import { Account } from "@/src/models/loginModel";
 | 
			
		||||
import { sendWsBroadcastTo } from "@/src/services/webService";
 | 
			
		||||
import { sendWsBroadcastTo } from "@/src/services/wsService";
 | 
			
		||||
 | 
			
		||||
export const logoutController: RequestHandler = async (req, res) => {
 | 
			
		||||
    if (!req.query.accountId) {
 | 
			
		||||
 | 
			
		||||
@ -3,11 +3,12 @@ import { getJSONfromString } from "@/src/helpers/stringHelpers";
 | 
			
		||||
import { getAccountForRequest } from "@/src/services/loginService";
 | 
			
		||||
import { IMissionInventoryUpdateRequest } from "@/src/types/requestTypes";
 | 
			
		||||
import { addMissionInventoryUpdates, addMissionRewards } from "@/src/services/missionInventoryUpdateService";
 | 
			
		||||
import { generateRewardSeed, getInventory } from "@/src/services/inventoryService";
 | 
			
		||||
import { getInventory } from "@/src/services/inventoryService";
 | 
			
		||||
import { getInventoryResponse } from "./inventoryController";
 | 
			
		||||
import { logger } from "@/src/utils/logger";
 | 
			
		||||
import { IMissionInventoryUpdateResponse } from "@/src/types/missionTypes";
 | 
			
		||||
import { sendWsBroadcastTo } from "@/src/services/webService";
 | 
			
		||||
import { sendWsBroadcastTo } from "@/src/services/wsService";
 | 
			
		||||
import { generateRewardSeed } from "@/src/services/rngService";
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
**** INPUT ****
 | 
			
		||||
 | 
			
		||||
@ -15,10 +15,9 @@ import {
 | 
			
		||||
import { IInventoryChanges } from "@/src/types/purchaseTypes";
 | 
			
		||||
import { getDefaultUpgrades } from "@/src/services/itemDataService";
 | 
			
		||||
import { modularWeaponTypes } from "@/src/helpers/modularWeaponHelper";
 | 
			
		||||
import { IEquipmentDatabase } from "@/src/types/inventoryTypes/commonInventoryTypes";
 | 
			
		||||
import { getRandomInt } from "@/src/services/rngService";
 | 
			
		||||
import { ExportSentinels, ExportWeapons, IDefaultUpgrade } from "warframe-public-export-plus";
 | 
			
		||||
import { Status } from "@/src/types/inventoryTypes/inventoryTypes";
 | 
			
		||||
import { IEquipmentDatabase, Status } from "@/src/types/equipmentTypes";
 | 
			
		||||
 | 
			
		||||
interface IModularCraftRequest {
 | 
			
		||||
    WeaponType: string;
 | 
			
		||||
 | 
			
		||||
@ -3,7 +3,7 @@ import { ExportWeapons } from "warframe-public-export-plus";
 | 
			
		||||
import { IMongoDate } from "@/src/types/commonTypes";
 | 
			
		||||
import { toMongoDate } from "@/src/helpers/inventoryHelpers";
 | 
			
		||||
import { SRng } from "@/src/services/rngService";
 | 
			
		||||
import { ArtifactPolarity, EquipmentFeatures } from "@/src/types/inventoryTypes/commonInventoryTypes";
 | 
			
		||||
import { ArtifactPolarity } from "@/src/types/inventoryTypes/commonInventoryTypes";
 | 
			
		||||
import { getJSONfromString } from "@/src/helpers/stringHelpers";
 | 
			
		||||
import {
 | 
			
		||||
    addEquipment,
 | 
			
		||||
@ -17,6 +17,7 @@ import { getDefaultUpgrades } from "@/src/services/itemDataService";
 | 
			
		||||
import { getAccountIdForRequest } from "@/src/services/loginService";
 | 
			
		||||
import { modularWeaponTypes } from "@/src/helpers/modularWeaponHelper";
 | 
			
		||||
import { IInventoryChanges } from "@/src/types/purchaseTypes";
 | 
			
		||||
import { EquipmentFeatures } from "@/src/types/equipmentTypes";
 | 
			
		||||
 | 
			
		||||
export const modularWeaponSaleController: RequestHandler = async (req, res) => {
 | 
			
		||||
    const partTypeToParts: Record<string, string[]> = {};
 | 
			
		||||
 | 
			
		||||
@ -3,7 +3,7 @@ import { getAccountIdForRequest } from "@/src/services/loginService";
 | 
			
		||||
import { getInventory, updateCurrency } from "@/src/services/inventoryService";
 | 
			
		||||
import { getJSONfromString } from "@/src/helpers/stringHelpers";
 | 
			
		||||
import { TEquipmentKey } from "@/src/types/inventoryTypes/inventoryTypes";
 | 
			
		||||
import { sendWsBroadcastTo } from "@/src/services/webService";
 | 
			
		||||
import { sendWsBroadcastTo } from "@/src/services/wsService";
 | 
			
		||||
 | 
			
		||||
interface INameWeaponRequest {
 | 
			
		||||
    ItemName: string;
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,6 @@
 | 
			
		||||
import { version_compare } from "@/src/helpers/inventoryHelpers";
 | 
			
		||||
import {
 | 
			
		||||
    antivirusMods,
 | 
			
		||||
    consumeModCharge,
 | 
			
		||||
    decodeNemesisGuess,
 | 
			
		||||
    encodeNemesisGuess,
 | 
			
		||||
    getInfNodes,
 | 
			
		||||
@ -17,12 +16,13 @@ import {
 | 
			
		||||
    parseUpgrade
 | 
			
		||||
} from "@/src/helpers/nemesisHelpers";
 | 
			
		||||
import { getJSONfromString } from "@/src/helpers/stringHelpers";
 | 
			
		||||
import { TInventoryDatabaseDocument } from "@/src/models/inventoryModels/inventoryModel";
 | 
			
		||||
import { Loadout } from "@/src/models/inventoryModels/loadoutModel";
 | 
			
		||||
import { freeUpSlot, getInventory } from "@/src/services/inventoryService";
 | 
			
		||||
import { addMods, freeUpSlot, getInventory } from "@/src/services/inventoryService";
 | 
			
		||||
import { getAccountForRequest } from "@/src/services/loginService";
 | 
			
		||||
import { SRng } from "@/src/services/rngService";
 | 
			
		||||
import { IMongoDate, IOid } from "@/src/types/commonTypes";
 | 
			
		||||
import { IEquipmentClient } from "@/src/types/inventoryTypes/commonInventoryTypes";
 | 
			
		||||
import { IEquipmentClient } from "@/src/types/equipmentTypes";
 | 
			
		||||
import {
 | 
			
		||||
    IInnateDamageFingerprint,
 | 
			
		||||
    IInventoryClient,
 | 
			
		||||
@ -36,6 +36,7 @@ import {
 | 
			
		||||
} from "@/src/types/inventoryTypes/inventoryTypes";
 | 
			
		||||
import { logger } from "@/src/utils/logger";
 | 
			
		||||
import { RequestHandler } from "express";
 | 
			
		||||
import { Types } from "mongoose";
 | 
			
		||||
 | 
			
		||||
export const nemesisController: RequestHandler = async (req, res) => {
 | 
			
		||||
    const account = await getAccountForRequest(req);
 | 
			
		||||
@ -391,3 +392,54 @@ interface IKnife {
 | 
			
		||||
    AttachedUpgrades: IUpgradeClient[];
 | 
			
		||||
    HiddenWhenHolstered: boolean;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const consumeModCharge = (
 | 
			
		||||
    response: IKnifeResponse,
 | 
			
		||||
    inventory: TInventoryDatabaseDocument,
 | 
			
		||||
    upgrade: { ItemId: IOid; ItemType: string },
 | 
			
		||||
    dataknifeUpgrades: string[]
 | 
			
		||||
): void => {
 | 
			
		||||
    response.UpgradeIds ??= [];
 | 
			
		||||
    response.UpgradeTypes ??= [];
 | 
			
		||||
    response.UpgradeFingerprints ??= [];
 | 
			
		||||
    response.UpgradeNew ??= [];
 | 
			
		||||
    response.HasKnife = true;
 | 
			
		||||
 | 
			
		||||
    if (upgrade.ItemId.$oid != "000000000000000000000000") {
 | 
			
		||||
        const dbUpgrade = inventory.Upgrades.id(upgrade.ItemId.$oid)!;
 | 
			
		||||
        const fingerprint = JSON.parse(dbUpgrade.UpgradeFingerprint!) as { lvl: number };
 | 
			
		||||
        fingerprint.lvl += 1;
 | 
			
		||||
        dbUpgrade.UpgradeFingerprint = JSON.stringify(fingerprint);
 | 
			
		||||
 | 
			
		||||
        response.UpgradeIds.push(upgrade.ItemId.$oid);
 | 
			
		||||
        response.UpgradeTypes.push(upgrade.ItemType);
 | 
			
		||||
        response.UpgradeFingerprints.push(fingerprint);
 | 
			
		||||
        response.UpgradeNew.push(false);
 | 
			
		||||
    } else {
 | 
			
		||||
        const id = new Types.ObjectId();
 | 
			
		||||
        inventory.Upgrades.push({
 | 
			
		||||
            _id: id,
 | 
			
		||||
            ItemType: upgrade.ItemType,
 | 
			
		||||
            UpgradeFingerprint: `{"lvl":1}`
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        addMods(inventory, [
 | 
			
		||||
            {
 | 
			
		||||
                ItemType: upgrade.ItemType,
 | 
			
		||||
                ItemCount: -1
 | 
			
		||||
            }
 | 
			
		||||
        ]);
 | 
			
		||||
 | 
			
		||||
        const dataknifeRawUpgradeIndex = dataknifeUpgrades.indexOf(upgrade.ItemType);
 | 
			
		||||
        if (dataknifeRawUpgradeIndex != -1) {
 | 
			
		||||
            dataknifeUpgrades[dataknifeRawUpgradeIndex] = id.toString();
 | 
			
		||||
        } else {
 | 
			
		||||
            logger.warn(`${upgrade.ItemType} not found in dataknife config`);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        response.UpgradeIds.push(id.toString());
 | 
			
		||||
        response.UpgradeTypes.push(upgrade.ItemType);
 | 
			
		||||
        response.UpgradeFingerprints.push({ lvl: 1 });
 | 
			
		||||
        response.UpgradeNew.push(true);
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@ -3,7 +3,7 @@ import { getAccountIdForRequest } from "@/src/services/loginService";
 | 
			
		||||
import { IPurchaseRequest } from "@/src/types/purchaseTypes";
 | 
			
		||||
import { handlePurchase } from "@/src/services/purchaseService";
 | 
			
		||||
import { getInventory } from "@/src/services/inventoryService";
 | 
			
		||||
import { sendWsBroadcastTo } from "@/src/services/webService";
 | 
			
		||||
import { sendWsBroadcastTo } from "@/src/services/wsService";
 | 
			
		||||
 | 
			
		||||
export const purchaseController: RequestHandler = async (req, res) => {
 | 
			
		||||
    const purchaseRequest = JSON.parse(String(req.body)) as IPurchaseRequest;
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,7 @@
 | 
			
		||||
import { getJSONfromString } from "@/src/helpers/stringHelpers";
 | 
			
		||||
import { getInventory, updateCurrency } from "@/src/services/inventoryService";
 | 
			
		||||
import { getAccountIdForRequest } from "@/src/services/loginService";
 | 
			
		||||
import { sendWsBroadcastTo } from "@/src/services/webService";
 | 
			
		||||
import { sendWsBroadcastTo } from "@/src/services/wsService";
 | 
			
		||||
import { IInventoryChanges } from "@/src/types/purchaseTypes";
 | 
			
		||||
import { RequestHandler } from "express";
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,7 @@
 | 
			
		||||
import { getJSONfromString } from "@/src/helpers/stringHelpers";
 | 
			
		||||
import { getInventory } from "@/src/services/inventoryService";
 | 
			
		||||
import { getAccountIdForRequest } from "@/src/services/loginService";
 | 
			
		||||
import { Status } from "@/src/types/inventoryTypes/inventoryTypes";
 | 
			
		||||
import { Status } from "@/src/types/equipmentTypes";
 | 
			
		||||
import { RequestHandler } from "express";
 | 
			
		||||
 | 
			
		||||
export const retrievePetFromStasisController: RequestHandler = async (req, res) => {
 | 
			
		||||
 | 
			
		||||
@ -15,7 +15,7 @@ import { InventorySlot } from "@/src/types/inventoryTypes/inventoryTypes";
 | 
			
		||||
import { ExportDojoRecipes } from "warframe-public-export-plus";
 | 
			
		||||
import { IInventoryChanges } from "@/src/types/purchaseTypes";
 | 
			
		||||
import { TInventoryDatabaseDocument } from "@/src/models/inventoryModels/inventoryModel";
 | 
			
		||||
import { sendWsBroadcastTo } from "@/src/services/webService";
 | 
			
		||||
import { sendWsBroadcastTo } from "@/src/services/wsService";
 | 
			
		||||
 | 
			
		||||
export const sellController: RequestHandler = async (req, res) => {
 | 
			
		||||
    const payload = JSON.parse(String(req.body)) as ISellRequest;
 | 
			
		||||
 | 
			
		||||
@ -2,7 +2,7 @@ import { fromMongoDate, fromOid } from "@/src/helpers/inventoryHelpers";
 | 
			
		||||
import { getJSONfromString } from "@/src/helpers/stringHelpers";
 | 
			
		||||
import { getInventory } from "@/src/services/inventoryService";
 | 
			
		||||
import { getAccountIdForRequest } from "@/src/services/loginService";
 | 
			
		||||
import { IEquipmentClient } from "@/src/types/inventoryTypes/commonInventoryTypes";
 | 
			
		||||
import { IEquipmentClient } from "@/src/types/equipmentTypes";
 | 
			
		||||
import { RequestHandler } from "express";
 | 
			
		||||
 | 
			
		||||
export const setSuitInfectionController: RequestHandler = async (req, res) => {
 | 
			
		||||
 | 
			
		||||
@ -6,7 +6,7 @@ import { IOid } from "@/src/types/commonTypes";
 | 
			
		||||
import { ExportSyndicates, ExportWeapons } from "warframe-public-export-plus";
 | 
			
		||||
import { logger } from "@/src/utils/logger";
 | 
			
		||||
import { IAffiliationMods, IInventoryChanges } from "@/src/types/purchaseTypes";
 | 
			
		||||
import { EquipmentFeatures } from "@/src/types/inventoryTypes/commonInventoryTypes";
 | 
			
		||||
import { EquipmentFeatures } from "@/src/types/equipmentTypes";
 | 
			
		||||
 | 
			
		||||
export const syndicateStandingBonusController: RequestHandler = async (req, res) => {
 | 
			
		||||
    const accountId = await getAccountIdForRequest(req);
 | 
			
		||||
 | 
			
		||||
@ -2,7 +2,7 @@ import { fromMongoDate, fromOid } from "@/src/helpers/inventoryHelpers";
 | 
			
		||||
import { getJSONfromString } from "@/src/helpers/stringHelpers";
 | 
			
		||||
import { addMiscItem, getInventory } from "@/src/services/inventoryService";
 | 
			
		||||
import { getAccountIdForRequest } from "@/src/services/loginService";
 | 
			
		||||
import { IEquipmentClient } from "@/src/types/inventoryTypes/commonInventoryTypes";
 | 
			
		||||
import { IEquipmentClient } from "@/src/types/equipmentTypes";
 | 
			
		||||
import { RequestHandler } from "express";
 | 
			
		||||
 | 
			
		||||
export const umbraController: RequestHandler = async (req, res) => {
 | 
			
		||||
 | 
			
		||||
@ -1,11 +1,6 @@
 | 
			
		||||
import { RequestHandler } from "express";
 | 
			
		||||
import { IUpgradesRequest } from "@/src/types/requestTypes";
 | 
			
		||||
import {
 | 
			
		||||
    ArtifactPolarity,
 | 
			
		||||
    IEquipmentDatabase,
 | 
			
		||||
    EquipmentFeatures,
 | 
			
		||||
    IAbilityOverride
 | 
			
		||||
} from "@/src/types/inventoryTypes/commonInventoryTypes";
 | 
			
		||||
import { ArtifactPolarity, IAbilityOverride } from "@/src/types/inventoryTypes/commonInventoryTypes";
 | 
			
		||||
import { IInventoryClient, IMiscItem } from "@/src/types/inventoryTypes/inventoryTypes";
 | 
			
		||||
import { getAccountIdForRequest } from "@/src/services/loginService";
 | 
			
		||||
import { addMiscItems, addRecipes, getInventory, updateCurrency } from "@/src/services/inventoryService";
 | 
			
		||||
@ -13,7 +8,8 @@ import { getRecipeByResult } from "@/src/services/itemDataService";
 | 
			
		||||
import { IInventoryChanges } from "@/src/types/purchaseTypes";
 | 
			
		||||
import { addInfestedFoundryXP, applyCheatsToInfestedFoundry } from "@/src/services/infestedFoundryService";
 | 
			
		||||
import { config } from "@/src/services/configService";
 | 
			
		||||
import { sendWsBroadcastTo } from "@/src/services/webService";
 | 
			
		||||
import { sendWsBroadcastTo } from "@/src/services/wsService";
 | 
			
		||||
import { EquipmentFeatures, IEquipmentDatabase } from "@/src/types/equipmentTypes";
 | 
			
		||||
 | 
			
		||||
export const upgradesController: RequestHandler = async (req, res) => {
 | 
			
		||||
    const accountId = await getAccountIdForRequest(req);
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,7 @@
 | 
			
		||||
import { applyClientEquipmentUpdates, getInventory } from "@/src/services/inventoryService";
 | 
			
		||||
import { getAccountIdForRequest } from "@/src/services/loginService";
 | 
			
		||||
import { IOid } from "@/src/types/commonTypes";
 | 
			
		||||
import { IEquipmentClient } from "@/src/types/inventoryTypes/commonInventoryTypes";
 | 
			
		||||
import { IEquipmentClient } from "@/src/types/equipmentTypes";
 | 
			
		||||
import { TEquipmentKey } from "@/src/types/inventoryTypes/inventoryTypes";
 | 
			
		||||
import { RequestHandler } from "express";
 | 
			
		||||
import { ExportMisc } from "warframe-public-export-plus";
 | 
			
		||||
 | 
			
		||||
@ -2,7 +2,7 @@ import { RequestHandler } from "express";
 | 
			
		||||
import { config } from "@/src/services/configService";
 | 
			
		||||
import { getAccountForRequest, isAdministrator } from "@/src/services/loginService";
 | 
			
		||||
import { saveConfig } from "@/src/services/configWatcherService";
 | 
			
		||||
import { sendWsBroadcastExcept } from "@/src/services/webService";
 | 
			
		||||
import { sendWsBroadcastExcept } from "@/src/services/wsService";
 | 
			
		||||
 | 
			
		||||
export const getConfigController: RequestHandler = async (req, res) => {
 | 
			
		||||
    const account = await getAccountForRequest(req);
 | 
			
		||||
 | 
			
		||||
@ -1,5 +1,5 @@
 | 
			
		||||
import { args } from "@/src/helpers/commandLineArguments";
 | 
			
		||||
import { sendWsBroadcast } from "@/src/services/webService";
 | 
			
		||||
import { sendWsBroadcast } from "@/src/services/wsService";
 | 
			
		||||
import { RequestHandler } from "express";
 | 
			
		||||
 | 
			
		||||
export const webuiFileChangeDetectedController: RequestHandler = (req, res) => {
 | 
			
		||||
 | 
			
		||||
@ -6,13 +6,11 @@ import { Account } from "@/src/models/loginModel";
 | 
			
		||||
import { Stats, TStatsDatabaseDocument } from "@/src/models/statsModel";
 | 
			
		||||
import { allDailyAffiliationKeys } from "@/src/services/inventoryService";
 | 
			
		||||
import { IMongoDate, IOid } from "@/src/types/commonTypes";
 | 
			
		||||
import { IEquipmentClient } from "@/src/types/inventoryTypes/commonInventoryTypes";
 | 
			
		||||
import {
 | 
			
		||||
    IAffiliation,
 | 
			
		||||
    IAlignment,
 | 
			
		||||
    IChallengeProgress,
 | 
			
		||||
    IDailyAffiliations,
 | 
			
		||||
    ILoadoutConfigClient,
 | 
			
		||||
    IMission,
 | 
			
		||||
    IPlayerSkills,
 | 
			
		||||
    ITypeXPItem
 | 
			
		||||
@ -23,6 +21,8 @@ import { ExportCustoms, ExportDojoRecipes } from "warframe-public-export-plus";
 | 
			
		||||
import { IStatsClient } from "@/src/types/statTypes";
 | 
			
		||||
import { toStoreItem } from "@/src/services/itemDataService";
 | 
			
		||||
import { FlattenMaps } from "mongoose";
 | 
			
		||||
import { IEquipmentClient } from "@/src/types/equipmentTypes";
 | 
			
		||||
import { ILoadoutConfigClient } from "@/src/types/saveLoadoutTypes";
 | 
			
		||||
 | 
			
		||||
const getProfileViewingDataByPlayerIdImpl = async (playerId: string): Promise<IProfileViewingData | undefined> => {
 | 
			
		||||
    const account = await Account.findById(playerId, "DisplayName");
 | 
			
		||||
 | 
			
		||||
@ -9,11 +9,11 @@ export const isEmptyObject = (obj: object): boolean => {
 | 
			
		||||
};
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
const isString = (text: unknown): text is string => {
 | 
			
		||||
export const isString = (text: unknown): text is string => {
 | 
			
		||||
    return typeof text === "string" || text instanceof String;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const parseString = (data: unknown): string => {
 | 
			
		||||
export const parseString = (data: unknown): string => {
 | 
			
		||||
    if (!isString(data)) {
 | 
			
		||||
        throw new Error("data is not a string");
 | 
			
		||||
    }
 | 
			
		||||
@ -21,11 +21,11 @@ const parseString = (data: unknown): string => {
 | 
			
		||||
    return data;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const isNumber = (number: unknown): number is number => {
 | 
			
		||||
export const isNumber = (number: unknown): number is number => {
 | 
			
		||||
    return typeof number === "number" && !isNaN(number);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const parseNumber = (data: unknown): number => {
 | 
			
		||||
export const parseNumber = (data: unknown): number => {
 | 
			
		||||
    if (!isNumber(data)) {
 | 
			
		||||
        throw new Error("data is not a number");
 | 
			
		||||
    }
 | 
			
		||||
@ -33,11 +33,11 @@ const parseNumber = (data: unknown): number => {
 | 
			
		||||
    return Number(data);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const isDate = (date: string): boolean => {
 | 
			
		||||
export const isDate = (date: string): boolean => {
 | 
			
		||||
    return Date.parse(date) != 0;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const parseDateNumber = (date: unknown): string => {
 | 
			
		||||
export const parseDateNumber = (date: unknown): string => {
 | 
			
		||||
    if (!isString(date) || !isDate(date)) {
 | 
			
		||||
        throw new Error("date could not be parsed");
 | 
			
		||||
    }
 | 
			
		||||
@ -45,18 +45,18 @@ const parseDateNumber = (date: unknown): string => {
 | 
			
		||||
    return date;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const parseEmail = (email: unknown): string => {
 | 
			
		||||
export const parseEmail = (email: unknown): string => {
 | 
			
		||||
    if (!isString(email)) {
 | 
			
		||||
        throw new Error("incorrect email");
 | 
			
		||||
    }
 | 
			
		||||
    return email;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const isBoolean = (booleanCandidate: unknown): booleanCandidate is boolean => {
 | 
			
		||||
export const isBoolean = (booleanCandidate: unknown): booleanCandidate is boolean => {
 | 
			
		||||
    return typeof booleanCandidate === "boolean";
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const parseBoolean = (booleanCandidate: unknown): boolean => {
 | 
			
		||||
export const parseBoolean = (booleanCandidate: unknown): boolean => {
 | 
			
		||||
    if (!isBoolean(booleanCandidate)) {
 | 
			
		||||
        throw new Error("argument was not a boolean");
 | 
			
		||||
    }
 | 
			
		||||
@ -70,5 +70,3 @@ export const isObject = (objectCandidate: unknown): objectCandidate is Record<st
 | 
			
		||||
        !Array.isArray(objectCandidate)
 | 
			
		||||
    );
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export { isString, isNumber, parseString, parseNumber, parseDateNumber, parseBoolean, parseEmail };
 | 
			
		||||
 | 
			
		||||
@ -1,11 +1,8 @@
 | 
			
		||||
import { ExportRegions, ExportWarframes } from "warframe-public-export-plus";
 | 
			
		||||
import { IInfNode, TNemesisFaction } from "@/src/types/inventoryTypes/inventoryTypes";
 | 
			
		||||
import { getRewardAtPercentage, SRng } from "@/src/services/rngService";
 | 
			
		||||
import { generateRewardSeed, getRewardAtPercentage, SRng } from "@/src/services/rngService";
 | 
			
		||||
import { TInventoryDatabaseDocument } from "../models/inventoryModels/inventoryModel";
 | 
			
		||||
import { logger } from "../utils/logger";
 | 
			
		||||
import { IOid } from "../types/commonTypes";
 | 
			
		||||
import { Types } from "mongoose";
 | 
			
		||||
import { addMods, generateRewardSeed } from "../services/inventoryService";
 | 
			
		||||
import { isArchwingMission } from "../services/worldStateService";
 | 
			
		||||
 | 
			
		||||
type TInnateDamageTag =
 | 
			
		||||
@ -364,57 +361,6 @@ export const parseUpgrade = (
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export const consumeModCharge = (
 | 
			
		||||
    response: IKnifeResponse,
 | 
			
		||||
    inventory: TInventoryDatabaseDocument,
 | 
			
		||||
    upgrade: { ItemId: IOid; ItemType: string },
 | 
			
		||||
    dataknifeUpgrades: string[]
 | 
			
		||||
): void => {
 | 
			
		||||
    response.UpgradeIds ??= [];
 | 
			
		||||
    response.UpgradeTypes ??= [];
 | 
			
		||||
    response.UpgradeFingerprints ??= [];
 | 
			
		||||
    response.UpgradeNew ??= [];
 | 
			
		||||
    response.HasKnife = true;
 | 
			
		||||
 | 
			
		||||
    if (upgrade.ItemId.$oid != "000000000000000000000000") {
 | 
			
		||||
        const dbUpgrade = inventory.Upgrades.id(upgrade.ItemId.$oid)!;
 | 
			
		||||
        const fingerprint = JSON.parse(dbUpgrade.UpgradeFingerprint!) as { lvl: number };
 | 
			
		||||
        fingerprint.lvl += 1;
 | 
			
		||||
        dbUpgrade.UpgradeFingerprint = JSON.stringify(fingerprint);
 | 
			
		||||
 | 
			
		||||
        response.UpgradeIds.push(upgrade.ItemId.$oid);
 | 
			
		||||
        response.UpgradeTypes.push(upgrade.ItemType);
 | 
			
		||||
        response.UpgradeFingerprints.push(fingerprint);
 | 
			
		||||
        response.UpgradeNew.push(false);
 | 
			
		||||
    } else {
 | 
			
		||||
        const id = new Types.ObjectId();
 | 
			
		||||
        inventory.Upgrades.push({
 | 
			
		||||
            _id: id,
 | 
			
		||||
            ItemType: upgrade.ItemType,
 | 
			
		||||
            UpgradeFingerprint: `{"lvl":1}`
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        addMods(inventory, [
 | 
			
		||||
            {
 | 
			
		||||
                ItemType: upgrade.ItemType,
 | 
			
		||||
                ItemCount: -1
 | 
			
		||||
            }
 | 
			
		||||
        ]);
 | 
			
		||||
 | 
			
		||||
        const dataknifeRawUpgradeIndex = dataknifeUpgrades.indexOf(upgrade.ItemType);
 | 
			
		||||
        if (dataknifeRawUpgradeIndex != -1) {
 | 
			
		||||
            dataknifeUpgrades[dataknifeRawUpgradeIndex] = id.toString();
 | 
			
		||||
        } else {
 | 
			
		||||
            logger.warn(`${upgrade.ItemType} not found in dataknife config`);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        response.UpgradeIds.push(id.toString());
 | 
			
		||||
        response.UpgradeTypes.push(upgrade.ItemType);
 | 
			
		||||
        response.UpgradeFingerprints.push({ lvl: 1 });
 | 
			
		||||
        response.UpgradeNew.push(true);
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export const getInnateDamageTag = (KillingSuit: string): TInnateDamageTag => {
 | 
			
		||||
    return ExportWarframes[KillingSuit].nemesisUpgradeTag!;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,5 @@
 | 
			
		||||
import { Schema } from "mongoose";
 | 
			
		||||
import { IColor } from "@/src/types/inventoryTypes/commonInventoryTypes";
 | 
			
		||||
import { IShipCustomization } from "@/src/types/personalRoomsTypes";
 | 
			
		||||
import { IColor, IShipCustomization } from "@/src/types/inventoryTypes/commonInventoryTypes";
 | 
			
		||||
 | 
			
		||||
export const colorSchema = new Schema<IColor>(
 | 
			
		||||
    {
 | 
			
		||||
 | 
			
		||||
@ -1,8 +1,7 @@
 | 
			
		||||
import { model, Schema, Types } from "mongoose";
 | 
			
		||||
import { toMongoDate, toOid } from "@/src/helpers/inventoryHelpers";
 | 
			
		||||
import { typeCountSchema } from "@/src/models/inventoryModels/inventoryModel";
 | 
			
		||||
import { IMongoDate, IOid } from "@/src/types/commonTypes";
 | 
			
		||||
import { ITypeCount } from "@/src/types/inventoryTypes/inventoryTypes";
 | 
			
		||||
import { IMongoDate, IOid, ITypeCount } from "@/src/types/commonTypes";
 | 
			
		||||
 | 
			
		||||
export interface IMessageClient
 | 
			
		||||
    extends Omit<IMessageDatabase, "_id" | "date" | "startDate" | "endDate" | "ownerId" | "attVisualOnly" | "expiry"> {
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,5 @@
 | 
			
		||||
import { Document, Model, Schema, Types, model } from "mongoose";
 | 
			
		||||
import {
 | 
			
		||||
    IFlavourItem,
 | 
			
		||||
    IRawUpgrade,
 | 
			
		||||
    IMiscItem,
 | 
			
		||||
    IInventoryDatabase,
 | 
			
		||||
@ -10,7 +9,6 @@ import {
 | 
			
		||||
    IDuviriInfo,
 | 
			
		||||
    IPendingRecipeDatabase,
 | 
			
		||||
    IPendingRecipeClient,
 | 
			
		||||
    ITypeCount,
 | 
			
		||||
    IFocusXP,
 | 
			
		||||
    IFocusUpgrade,
 | 
			
		||||
    ITypeXPItem,
 | 
			
		||||
@ -39,24 +37,15 @@ import {
 | 
			
		||||
    IEvolutionProgress,
 | 
			
		||||
    IEndlessXpProgressDatabase,
 | 
			
		||||
    IEndlessXpProgressClient,
 | 
			
		||||
    ICrewShipCustomization,
 | 
			
		||||
    ICrewShipWeapon,
 | 
			
		||||
    ICrewShipWeaponEmplacements,
 | 
			
		||||
    IHelminthFoodRecord,
 | 
			
		||||
    ICrewShipMembersDatabase,
 | 
			
		||||
    IDialogueHistoryDatabase,
 | 
			
		||||
    IDialogueDatabase,
 | 
			
		||||
    IDialogueGift,
 | 
			
		||||
    ICompletedDialogue,
 | 
			
		||||
    IDialogueClient,
 | 
			
		||||
    IUpgradeDatabase,
 | 
			
		||||
    ICrewShipMemberDatabase,
 | 
			
		||||
    ICrewShipMemberClient,
 | 
			
		||||
    TEquipmentKey,
 | 
			
		||||
    equipmentKeys,
 | 
			
		||||
    IKubrowPetDetailsDatabase,
 | 
			
		||||
    ITraits,
 | 
			
		||||
    IKubrowPetDetailsClient,
 | 
			
		||||
    IKubrowPetEggDatabase,
 | 
			
		||||
    IKubrowPetEggClient,
 | 
			
		||||
    ICustomMarkers,
 | 
			
		||||
@ -95,27 +84,39 @@ import {
 | 
			
		||||
    IInvasionProgressClient,
 | 
			
		||||
    IAccolades,
 | 
			
		||||
    IHubNpcCustomization,
 | 
			
		||||
    ILotusCustomization,
 | 
			
		||||
    IEndlessXpReward,
 | 
			
		||||
    IPersonalGoalProgressDatabase,
 | 
			
		||||
    IPersonalGoalProgressClient,
 | 
			
		||||
    IKubrowPetPrintClient,
 | 
			
		||||
    IKubrowPetPrintDatabase
 | 
			
		||||
} from "../../types/inventoryTypes/inventoryTypes";
 | 
			
		||||
import { IOid } from "../../types/commonTypes";
 | 
			
		||||
import { IOid, ITypeCount } from "../../types/commonTypes";
 | 
			
		||||
import {
 | 
			
		||||
    IAbilityOverride,
 | 
			
		||||
    ICrewShipCustomization,
 | 
			
		||||
    IFlavourItem,
 | 
			
		||||
    IItemConfig,
 | 
			
		||||
    ILotusCustomization,
 | 
			
		||||
    IOperatorConfigDatabase,
 | 
			
		||||
    IPolarity,
 | 
			
		||||
    IEquipmentDatabase,
 | 
			
		||||
    IArchonCrystalUpgrade,
 | 
			
		||||
    IEquipmentClient
 | 
			
		||||
    IPolarity
 | 
			
		||||
} from "@/src/types/inventoryTypes/commonInventoryTypes";
 | 
			
		||||
import { toMongoDate, toOid } from "@/src/helpers/inventoryHelpers";
 | 
			
		||||
import { EquipmentSelectionSchema, oidSchema } from "./loadoutModel";
 | 
			
		||||
import { ICountedStoreItem } from "warframe-public-export-plus";
 | 
			
		||||
import { colorSchema, shipCustomizationSchema } from "../commonModel";
 | 
			
		||||
import {
 | 
			
		||||
    IArchonCrystalUpgrade,
 | 
			
		||||
    ICrewShipMemberClient,
 | 
			
		||||
    ICrewShipMemberDatabase,
 | 
			
		||||
    ICrewShipMembersDatabase,
 | 
			
		||||
    ICrewShipWeapon,
 | 
			
		||||
    ICrewShipWeaponEmplacements,
 | 
			
		||||
    IEquipmentClient,
 | 
			
		||||
    IEquipmentDatabase,
 | 
			
		||||
    IKubrowPetDetailsClient,
 | 
			
		||||
    IKubrowPetDetailsDatabase,
 | 
			
		||||
    ITraits
 | 
			
		||||
} from "@/src/types/equipmentTypes";
 | 
			
		||||
 | 
			
		||||
export const typeCountSchema = new Schema<ITypeCount>({ ItemType: String, ItemCount: Number }, { _id: false });
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,5 +1,5 @@
 | 
			
		||||
import { IOid } from "@/src/types/commonTypes";
 | 
			
		||||
import { IEquipmentSelection } from "@/src/types/inventoryTypes/commonInventoryTypes";
 | 
			
		||||
import { IEquipmentSelection } from "@/src/types/equipmentTypes";
 | 
			
		||||
import { ILoadoutConfigDatabase, ILoadoutDatabase } from "@/src/types/saveLoadoutTypes";
 | 
			
		||||
import { Document, Model, Schema, Types, model } from "mongoose";
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -2,7 +2,8 @@ import chokidar from "chokidar";
 | 
			
		||||
import fsPromises from "fs/promises";
 | 
			
		||||
import { logger } from "../utils/logger";
 | 
			
		||||
import { config, configPath, loadConfig } from "./configService";
 | 
			
		||||
import { getWebPorts, sendWsBroadcast, startWebServer, stopWebServer } from "./webService";
 | 
			
		||||
import { getWebPorts, startWebServer, stopWebServer } from "./webService";
 | 
			
		||||
import { sendWsBroadcast } from "./wsService";
 | 
			
		||||
import { Inbox } from "../models/inboxModel";
 | 
			
		||||
import varzia from "@/static/fixed_responses/worldState/varzia.json";
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -26,12 +26,13 @@ import { logger } from "../utils/logger";
 | 
			
		||||
import { config } from "./configService";
 | 
			
		||||
import { getRandomInt } from "./rngService";
 | 
			
		||||
import { Inbox } from "../models/inboxModel";
 | 
			
		||||
import { IFusionTreasure, ITypeCount } from "../types/inventoryTypes/inventoryTypes";
 | 
			
		||||
import { IFusionTreasure } from "../types/inventoryTypes/inventoryTypes";
 | 
			
		||||
import { IInventoryChanges } from "../types/purchaseTypes";
 | 
			
		||||
import { parallelForeach } from "../utils/async-utils";
 | 
			
		||||
import allDecoRecipes from "@/static/fixed_responses/allDecoRecipes.json";
 | 
			
		||||
import { createMessage } from "./inboxService";
 | 
			
		||||
import { addAccountDataToFriendInfo, addInventoryDataToFriendInfo } from "./friendService";
 | 
			
		||||
import { ITypeCount } from "../types/commonTypes";
 | 
			
		||||
 | 
			
		||||
export const getGuildForRequest = async (req: Request): Promise<TGuildDatabaseDocument> => {
 | 
			
		||||
    const accountId = await getAccountIdForRequest(req);
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,5 @@
 | 
			
		||||
import { Types } from "mongoose";
 | 
			
		||||
import {
 | 
			
		||||
    IEquipmentClient,
 | 
			
		||||
    IEquipmentDatabase,
 | 
			
		||||
    IItemConfig,
 | 
			
		||||
    IOperatorConfigClient,
 | 
			
		||||
    IOperatorConfigDatabase
 | 
			
		||||
@ -9,10 +7,6 @@ import {
 | 
			
		||||
import { IMongoDate } from "../types/commonTypes";
 | 
			
		||||
import {
 | 
			
		||||
    equipmentKeys,
 | 
			
		||||
    ICrewShipMemberClient,
 | 
			
		||||
    ICrewShipMemberDatabase,
 | 
			
		||||
    ICrewShipMembersClient,
 | 
			
		||||
    ICrewShipMembersDatabase,
 | 
			
		||||
    IDialogueClient,
 | 
			
		||||
    IDialogueDatabase,
 | 
			
		||||
    IDialogueHistoryClient,
 | 
			
		||||
@ -20,10 +14,6 @@ import {
 | 
			
		||||
    IInfestedFoundryClient,
 | 
			
		||||
    IInfestedFoundryDatabase,
 | 
			
		||||
    IInventoryClient,
 | 
			
		||||
    IKubrowPetDetailsClient,
 | 
			
		||||
    IKubrowPetDetailsDatabase,
 | 
			
		||||
    ILoadoutConfigClient,
 | 
			
		||||
    ILoadOutPresets,
 | 
			
		||||
    INemesisClient,
 | 
			
		||||
    INemesisDatabase,
 | 
			
		||||
    IPendingRecipeClient,
 | 
			
		||||
@ -37,8 +27,23 @@ import {
 | 
			
		||||
    IWeaponSkinDatabase
 | 
			
		||||
} from "../types/inventoryTypes/inventoryTypes";
 | 
			
		||||
import { TInventoryDatabaseDocument } from "../models/inventoryModels/inventoryModel";
 | 
			
		||||
import { ILoadoutConfigDatabase, ILoadoutDatabase } from "../types/saveLoadoutTypes";
 | 
			
		||||
import {
 | 
			
		||||
    ILoadoutConfigClient,
 | 
			
		||||
    ILoadoutConfigDatabase,
 | 
			
		||||
    ILoadoutDatabase,
 | 
			
		||||
    ILoadOutPresets
 | 
			
		||||
} from "../types/saveLoadoutTypes";
 | 
			
		||||
import { slotNames } from "../types/purchaseTypes";
 | 
			
		||||
import {
 | 
			
		||||
    ICrewShipMemberClient,
 | 
			
		||||
    ICrewShipMemberDatabase,
 | 
			
		||||
    ICrewShipMembersClient,
 | 
			
		||||
    ICrewShipMembersDatabase,
 | 
			
		||||
    IEquipmentClient,
 | 
			
		||||
    IEquipmentDatabase,
 | 
			
		||||
    IKubrowPetDetailsClient,
 | 
			
		||||
    IKubrowPetDetailsDatabase
 | 
			
		||||
} from "../types/equipmentTypes";
 | 
			
		||||
 | 
			
		||||
const convertDate = (value: IMongoDate): Date => {
 | 
			
		||||
    return new Date(parseInt(value.$date.$numberLong));
 | 
			
		||||
 | 
			
		||||
@ -1,8 +1,9 @@
 | 
			
		||||
import { ExportRecipes } from "warframe-public-export-plus";
 | 
			
		||||
import { TInventoryDatabaseDocument } from "../models/inventoryModels/inventoryModel";
 | 
			
		||||
import { IInfestedFoundryClient, IInfestedFoundryDatabase, ITypeCount } from "../types/inventoryTypes/inventoryTypes";
 | 
			
		||||
import { IInfestedFoundryClient, IInfestedFoundryDatabase } from "../types/inventoryTypes/inventoryTypes";
 | 
			
		||||
import { addRecipes } from "./inventoryService";
 | 
			
		||||
import { config } from "./configService";
 | 
			
		||||
import { ITypeCount } from "../types/commonTypes";
 | 
			
		||||
 | 
			
		||||
export const addInfestedFoundryXP = (infestedFoundry: IInfestedFoundryDatabase, delta: number): ITypeCount[] => {
 | 
			
		||||
    const recipeChanges: ITypeCount[] = [];
 | 
			
		||||
 | 
			
		||||
@ -4,12 +4,10 @@ import { Types } from "mongoose";
 | 
			
		||||
import { SlotNames, IInventoryChanges, IBinChanges, slotNames, IAffiliationMods } from "@/src/types/purchaseTypes";
 | 
			
		||||
import {
 | 
			
		||||
    IChallengeProgress,
 | 
			
		||||
    IFlavourItem,
 | 
			
		||||
    IMiscItem,
 | 
			
		||||
    IMission,
 | 
			
		||||
    IRawUpgrade,
 | 
			
		||||
    ISeasonChallenge,
 | 
			
		||||
    ITypeCount,
 | 
			
		||||
    InventorySlot,
 | 
			
		||||
    IWeaponSkinClient,
 | 
			
		||||
    TEquipmentKey,
 | 
			
		||||
@ -23,9 +21,6 @@ import {
 | 
			
		||||
    TPartialStartingGear,
 | 
			
		||||
    ILoreFragmentScan,
 | 
			
		||||
    ICrewMemberClient,
 | 
			
		||||
    Status,
 | 
			
		||||
    IKubrowPetDetailsDatabase,
 | 
			
		||||
    ITraits,
 | 
			
		||||
    ICalendarProgress,
 | 
			
		||||
    INemesisWeaponTargetFingerprint,
 | 
			
		||||
    INemesisPetTargetFingerprint,
 | 
			
		||||
@ -36,12 +31,7 @@ import { IGenericUpdate, IUpdateNodeIntrosResponse } from "../types/genericUpdat
 | 
			
		||||
import { IKeyChainRequest, IMissionInventoryUpdateRequest } from "../types/requestTypes";
 | 
			
		||||
import { logger } from "@/src/utils/logger";
 | 
			
		||||
import { convertInboxMessage, fromStoreItem, getKeyChainItems } from "@/src/services/itemDataService";
 | 
			
		||||
import {
 | 
			
		||||
    EquipmentFeatures,
 | 
			
		||||
    IEquipmentClient,
 | 
			
		||||
    IEquipmentDatabase,
 | 
			
		||||
    IItemConfig
 | 
			
		||||
} from "../types/inventoryTypes/commonInventoryTypes";
 | 
			
		||||
import { IFlavourItem, IItemConfig } from "../types/inventoryTypes/commonInventoryTypes";
 | 
			
		||||
import {
 | 
			
		||||
    ExportArcanes,
 | 
			
		||||
    ExportBoosters,
 | 
			
		||||
@ -82,7 +72,7 @@ import {
 | 
			
		||||
import { addQuestKey, completeQuest } from "@/src/services/questService";
 | 
			
		||||
import { handleBundleAcqusition } from "./purchaseService";
 | 
			
		||||
import libraryDailyTasks from "@/static/fixed_responses/libraryDailyTasks.json";
 | 
			
		||||
import { getRandomElement, getRandomInt, getRandomWeightedReward, SRng } from "./rngService";
 | 
			
		||||
import { generateRewardSeed, getRandomElement, getRandomInt, getRandomWeightedReward, SRng } from "./rngService";
 | 
			
		||||
import { createMessage, IMessageCreationTemplate } from "./inboxService";
 | 
			
		||||
import { getMaxStanding, getMinStanding } from "@/src/helpers/syndicateStandingHelper";
 | 
			
		||||
import { getNightwaveSyndicateTag, getWorldState } from "./worldStateService";
 | 
			
		||||
@ -91,6 +81,15 @@ import { generateNemesisProfile, INemesisProfile } from "../helpers/nemesisHelpe
 | 
			
		||||
import { TAccountDocument } from "./loginService";
 | 
			
		||||
import { unixTimesInMs } from "../constants/timeConstants";
 | 
			
		||||
import { addString } from "../helpers/stringHelpers";
 | 
			
		||||
import {
 | 
			
		||||
    EquipmentFeatures,
 | 
			
		||||
    IEquipmentClient,
 | 
			
		||||
    IEquipmentDatabase,
 | 
			
		||||
    IKubrowPetDetailsDatabase,
 | 
			
		||||
    ITraits,
 | 
			
		||||
    Status
 | 
			
		||||
} from "../types/equipmentTypes";
 | 
			
		||||
import { ITypeCount } from "../types/commonTypes";
 | 
			
		||||
 | 
			
		||||
export const createInventory = async (
 | 
			
		||||
    accountOwnerId: Types.ObjectId,
 | 
			
		||||
@ -132,17 +131,6 @@ export const createInventory = async (
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export const generateRewardSeed = (): bigint => {
 | 
			
		||||
    const hiDword = getRandomInt(0, 0x7fffffff);
 | 
			
		||||
    const loDword = getRandomInt(0, 0xffffffff);
 | 
			
		||||
    let seed = (BigInt(hiDword) << 32n) | BigInt(loDword);
 | 
			
		||||
    if (Math.random() < 0.5) {
 | 
			
		||||
        seed *= -1n;
 | 
			
		||||
        seed -= 1n;
 | 
			
		||||
    }
 | 
			
		||||
    return seed;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
//TODO: RawUpgrades might need to return a LastAdded
 | 
			
		||||
const awakeningRewards = [
 | 
			
		||||
    "/Lotus/Types/StoreItems/AvatarImages/AvatarImageItem1",
 | 
			
		||||
 | 
			
		||||
@ -10,8 +10,8 @@ import {
 | 
			
		||||
} from "warframe-public-export-plus";
 | 
			
		||||
import { IMissionInventoryUpdateRequest, IRewardInfo } from "../types/requestTypes";
 | 
			
		||||
import { logger } from "@/src/utils/logger";
 | 
			
		||||
import { IRngResult, SRng, getRandomElement, getRandomReward } from "@/src/services/rngService";
 | 
			
		||||
import { equipmentKeys, IMission, ITypeCount, TEquipmentKey } from "@/src/types/inventoryTypes/inventoryTypes";
 | 
			
		||||
import { IRngResult, SRng, generateRewardSeed, getRandomElement, getRandomReward } from "@/src/services/rngService";
 | 
			
		||||
import { equipmentKeys, IMission, TEquipmentKey } from "@/src/types/inventoryTypes/inventoryTypes";
 | 
			
		||||
import {
 | 
			
		||||
    addBooster,
 | 
			
		||||
    addCalendarProgress,
 | 
			
		||||
@ -35,7 +35,6 @@ import {
 | 
			
		||||
    addStanding,
 | 
			
		||||
    applyClientEquipmentUpdates,
 | 
			
		||||
    combineInventoryChanges,
 | 
			
		||||
    generateRewardSeed,
 | 
			
		||||
    getDialogue,
 | 
			
		||||
    giveNemesisPetRecipe,
 | 
			
		||||
    giveNemesisWeaponRecipe,
 | 
			
		||||
@ -48,7 +47,6 @@ import { IAffiliationMods, IInventoryChanges } from "@/src/types/purchaseTypes";
 | 
			
		||||
import { fromStoreItem, getLevelKeyRewards, isStoreItem, toStoreItem } from "@/src/services/itemDataService";
 | 
			
		||||
import { TInventoryDatabaseDocument } from "@/src/models/inventoryModels/inventoryModel";
 | 
			
		||||
import { getEntriesUnsafe } from "@/src/utils/ts-utils";
 | 
			
		||||
import { IEquipmentClient } from "@/src/types/inventoryTypes/commonInventoryTypes";
 | 
			
		||||
import { handleStoreItemAcquisition } from "./purchaseService";
 | 
			
		||||
import { IMissionCredits, IMissionReward } from "../types/missionTypes";
 | 
			
		||||
import { crackRelic } from "@/src/helpers/relicHelper";
 | 
			
		||||
@ -81,6 +79,8 @@ import libraryDailyTasks from "@/static/fixed_responses/libraryDailyTasks.json";
 | 
			
		||||
import { ISyndicateMissionInfo } from "../types/worldStateTypes";
 | 
			
		||||
import { fromOid } from "../helpers/inventoryHelpers";
 | 
			
		||||
import { TAccountDocument } from "./loginService";
 | 
			
		||||
import { ITypeCount } from "../types/commonTypes";
 | 
			
		||||
import { IEquipmentClient } from "../types/equipmentTypes";
 | 
			
		||||
 | 
			
		||||
const getRotations = (rewardInfo: IRewardInfo, tierOverride?: number): number[] => {
 | 
			
		||||
    // For Spy missions, e.g. 3 vaults cracked = A, B, C
 | 
			
		||||
 | 
			
		||||
@ -4,13 +4,14 @@ import { TInventoryDatabaseDocument } from "@/src/models/inventoryModels/invento
 | 
			
		||||
import { createMessage } from "@/src/services/inboxService";
 | 
			
		||||
import { addItem, addItems, addKeyChainItems, setupKahlSyndicate } from "@/src/services/inventoryService";
 | 
			
		||||
import { fromStoreItem, getKeyChainMessage, getLevelKeyRewards } from "@/src/services/itemDataService";
 | 
			
		||||
import { IQuestKeyClient, IQuestKeyDatabase, IQuestStage, ITypeCount } from "@/src/types/inventoryTypes/inventoryTypes";
 | 
			
		||||
import { IQuestKeyClient, IQuestKeyDatabase, IQuestStage } from "@/src/types/inventoryTypes/inventoryTypes";
 | 
			
		||||
import { logger } from "@/src/utils/logger";
 | 
			
		||||
import { Types } from "mongoose";
 | 
			
		||||
import { ExportKeys } from "warframe-public-export-plus";
 | 
			
		||||
import { addFixedLevelRewards } from "./missionInventoryUpdateService";
 | 
			
		||||
import { IInventoryChanges } from "../types/purchaseTypes";
 | 
			
		||||
import questCompletionItems from "@/static/fixed_responses/questCompletionRewards.json";
 | 
			
		||||
import { ITypeCount } from "../types/commonTypes";
 | 
			
		||||
 | 
			
		||||
export interface IUpdateQuestRequest {
 | 
			
		||||
    QuestKeys: Omit<IQuestKeyDatabase, "CompletionDate">[];
 | 
			
		||||
 | 
			
		||||
@ -18,6 +18,17 @@ export const getRandomInt = (min: number, max: number): number => {
 | 
			
		||||
    return Math.floor(Math.random() * (max - min + 1)) + min;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export const generateRewardSeed = (): bigint => {
 | 
			
		||||
    const hiDword = getRandomInt(0, 0x7fffffff);
 | 
			
		||||
    const loDword = getRandomInt(0, 0xffffffff);
 | 
			
		||||
    let seed = (BigInt(hiDword) << 32n) | BigInt(loDword);
 | 
			
		||||
    if (Math.random() < 0.5) {
 | 
			
		||||
        seed *= -1n;
 | 
			
		||||
        seed -= 1n;
 | 
			
		||||
    }
 | 
			
		||||
    return seed;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export const getRewardAtPercentage = <T extends { probability: number }>(
 | 
			
		||||
    pool: T[],
 | 
			
		||||
    percentage: number
 | 
			
		||||
 | 
			
		||||
@ -5,17 +5,11 @@ import { config } from "./configService";
 | 
			
		||||
import { logger } from "../utils/logger";
 | 
			
		||||
import { app } from "../app";
 | 
			
		||||
import { AddressInfo } from "node:net";
 | 
			
		||||
import ws from "ws";
 | 
			
		||||
import { Account } from "../models/loginModel";
 | 
			
		||||
import { createAccount, createNonce, getUsernameFromEmail, isCorrectPassword } from "./loginService";
 | 
			
		||||
import { IDatabaseAccountJson } from "../types/loginTypes";
 | 
			
		||||
import { HydratedDocument } from "mongoose";
 | 
			
		||||
import { Agent, WebSocket as UnidiciWebSocket } from "undici";
 | 
			
		||||
import { startWsServer, startWssServer, stopWsServers } from "./wsService";
 | 
			
		||||
 | 
			
		||||
let httpServer: http.Server | undefined;
 | 
			
		||||
let httpsServer: https.Server | undefined;
 | 
			
		||||
let wsServer: ws.Server | undefined;
 | 
			
		||||
let wssServer: ws.Server | undefined;
 | 
			
		||||
 | 
			
		||||
const tlsOptions = {
 | 
			
		||||
    key: fs.readFileSync("static/certs/key.pem"),
 | 
			
		||||
@ -29,16 +23,14 @@ export const startWebServer = (): void => {
 | 
			
		||||
    // eslint-disable-next-line @typescript-eslint/no-misused-promises
 | 
			
		||||
    httpServer = http.createServer(app);
 | 
			
		||||
    httpServer.listen(httpPort, () => {
 | 
			
		||||
        wsServer = new ws.Server({ server: httpServer });
 | 
			
		||||
        wsServer.on("connection", wsOnConnect);
 | 
			
		||||
        startWsServer(httpServer!);
 | 
			
		||||
 | 
			
		||||
        logger.info("HTTP server started on port " + httpPort);
 | 
			
		||||
 | 
			
		||||
        // eslint-disable-next-line @typescript-eslint/no-misused-promises
 | 
			
		||||
        httpsServer = https.createServer(tlsOptions, app);
 | 
			
		||||
        httpsServer.listen(httpsPort, () => {
 | 
			
		||||
            wssServer = new ws.Server({ server: httpsServer });
 | 
			
		||||
            wssServer.on("connection", wsOnConnect);
 | 
			
		||||
            startWssServer(httpsServer!);
 | 
			
		||||
 | 
			
		||||
            logger.info("HTTPS server started on port " + httpsPort);
 | 
			
		||||
 | 
			
		||||
@ -115,182 +107,6 @@ export const stopWebServer = async (): Promise<void> => {
 | 
			
		||||
            })
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
    if (wsServer) {
 | 
			
		||||
        promises.push(
 | 
			
		||||
            new Promise(resolve => {
 | 
			
		||||
                wsServer!.close(() => {
 | 
			
		||||
                    resolve();
 | 
			
		||||
                });
 | 
			
		||||
            })
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
    if (wssServer) {
 | 
			
		||||
        promises.push(
 | 
			
		||||
            new Promise(resolve => {
 | 
			
		||||
                wssServer!.close(() => {
 | 
			
		||||
                    resolve();
 | 
			
		||||
                });
 | 
			
		||||
            })
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
    stopWsServers(promises);
 | 
			
		||||
    await Promise.all(promises);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
let lastWsid: number = 0;
 | 
			
		||||
 | 
			
		||||
interface IWsCustomData extends ws {
 | 
			
		||||
    id?: number;
 | 
			
		||||
    accountId?: string;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
interface IWsMsgFromClient {
 | 
			
		||||
    auth?: {
 | 
			
		||||
        email: string;
 | 
			
		||||
        password: string;
 | 
			
		||||
        isRegister: boolean;
 | 
			
		||||
    };
 | 
			
		||||
    logout?: boolean;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
interface IWsMsgToClient {
 | 
			
		||||
    //wsid?: number;
 | 
			
		||||
    reload?: boolean;
 | 
			
		||||
    ports?: {
 | 
			
		||||
        http: number | undefined;
 | 
			
		||||
        https: number | undefined;
 | 
			
		||||
    };
 | 
			
		||||
    config_reloaded?: boolean;
 | 
			
		||||
    auth_succ?: {
 | 
			
		||||
        id: string;
 | 
			
		||||
        DisplayName: string;
 | 
			
		||||
        Nonce: number;
 | 
			
		||||
    };
 | 
			
		||||
    auth_fail?: {
 | 
			
		||||
        isRegister: boolean;
 | 
			
		||||
    };
 | 
			
		||||
    logged_out?: boolean;
 | 
			
		||||
    update_inventory?: boolean;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const wsOnConnect = (ws: ws, req: http.IncomingMessage): void => {
 | 
			
		||||
    if (req.url == "/custom/selftest") {
 | 
			
		||||
        ws.send("SpaceNinjaServer");
 | 
			
		||||
        ws.close();
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    (ws as IWsCustomData).id = ++lastWsid;
 | 
			
		||||
    ws.send(JSON.stringify({ wsid: lastWsid }));
 | 
			
		||||
 | 
			
		||||
    // eslint-disable-next-line @typescript-eslint/no-misused-promises
 | 
			
		||||
    ws.on("message", async msg => {
 | 
			
		||||
        const data = JSON.parse(String(msg)) as IWsMsgFromClient;
 | 
			
		||||
        if (data.auth) {
 | 
			
		||||
            let account: IDatabaseAccountJson | null = await Account.findOne({ email: data.auth.email });
 | 
			
		||||
            if (account) {
 | 
			
		||||
                if (isCorrectPassword(data.auth.password, account.password)) {
 | 
			
		||||
                    if (!account.Nonce) {
 | 
			
		||||
                        account.ClientType = "webui";
 | 
			
		||||
                        account.Nonce = createNonce();
 | 
			
		||||
                        await (account as HydratedDocument<IDatabaseAccountJson>).save();
 | 
			
		||||
                    }
 | 
			
		||||
                } else {
 | 
			
		||||
                    account = null;
 | 
			
		||||
                }
 | 
			
		||||
            } else if (data.auth.isRegister) {
 | 
			
		||||
                const name = await getUsernameFromEmail(data.auth.email);
 | 
			
		||||
                account = await createAccount({
 | 
			
		||||
                    email: data.auth.email,
 | 
			
		||||
                    password: data.auth.password,
 | 
			
		||||
                    ClientType: "webui",
 | 
			
		||||
                    LastLogin: new Date(),
 | 
			
		||||
                    DisplayName: name,
 | 
			
		||||
                    Nonce: createNonce()
 | 
			
		||||
                });
 | 
			
		||||
            }
 | 
			
		||||
            if (account) {
 | 
			
		||||
                (ws as IWsCustomData).accountId = account.id;
 | 
			
		||||
                ws.send(
 | 
			
		||||
                    JSON.stringify({
 | 
			
		||||
                        auth_succ: {
 | 
			
		||||
                            id: account.id,
 | 
			
		||||
                            DisplayName: account.DisplayName,
 | 
			
		||||
                            Nonce: account.Nonce
 | 
			
		||||
                        }
 | 
			
		||||
                    } satisfies IWsMsgToClient)
 | 
			
		||||
                );
 | 
			
		||||
            } else {
 | 
			
		||||
                ws.send(
 | 
			
		||||
                    JSON.stringify({
 | 
			
		||||
                        auth_fail: {
 | 
			
		||||
                            isRegister: data.auth.isRegister
 | 
			
		||||
                        }
 | 
			
		||||
                    } satisfies IWsMsgToClient)
 | 
			
		||||
                );
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        if (data.logout) {
 | 
			
		||||
            const accountId = (ws as IWsCustomData).accountId;
 | 
			
		||||
            (ws as IWsCustomData).accountId = undefined;
 | 
			
		||||
            await Account.updateOne(
 | 
			
		||||
                {
 | 
			
		||||
                    _id: accountId,
 | 
			
		||||
                    ClientType: "webui"
 | 
			
		||||
                },
 | 
			
		||||
                {
 | 
			
		||||
                    Nonce: 0
 | 
			
		||||
                }
 | 
			
		||||
            );
 | 
			
		||||
        }
 | 
			
		||||
    });
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export const sendWsBroadcast = (data: IWsMsgToClient): void => {
 | 
			
		||||
    const msg = JSON.stringify(data);
 | 
			
		||||
    if (wsServer) {
 | 
			
		||||
        for (const client of wsServer.clients) {
 | 
			
		||||
            client.send(msg);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    if (wssServer) {
 | 
			
		||||
        for (const client of wssServer.clients) {
 | 
			
		||||
            client.send(msg);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export const sendWsBroadcastTo = (accountId: string, data: IWsMsgToClient): void => {
 | 
			
		||||
    const msg = JSON.stringify(data);
 | 
			
		||||
    if (wsServer) {
 | 
			
		||||
        for (const client of wsServer.clients) {
 | 
			
		||||
            if ((client as IWsCustomData).accountId == accountId) {
 | 
			
		||||
                client.send(msg);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    if (wssServer) {
 | 
			
		||||
        for (const client of wssServer.clients) {
 | 
			
		||||
            if ((client as IWsCustomData).accountId == accountId) {
 | 
			
		||||
                client.send(msg);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export const sendWsBroadcastExcept = (wsid: number | undefined, data: IWsMsgToClient): void => {
 | 
			
		||||
    const msg = JSON.stringify(data);
 | 
			
		||||
    if (wsServer) {
 | 
			
		||||
        for (const client of wsServer.clients) {
 | 
			
		||||
            if ((client as IWsCustomData).id != wsid) {
 | 
			
		||||
                client.send(msg);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    if (wssServer) {
 | 
			
		||||
        for (const client of wssServer.clients) {
 | 
			
		||||
            if ((client as IWsCustomData).id != wsid) {
 | 
			
		||||
                client.send(msg);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										200
									
								
								src/services/wsService.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										200
									
								
								src/services/wsService.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,200 @@
 | 
			
		||||
import http from "http";
 | 
			
		||||
import https from "https";
 | 
			
		||||
import ws from "ws";
 | 
			
		||||
import { Account } from "../models/loginModel";
 | 
			
		||||
import { createAccount, createNonce, getUsernameFromEmail, isCorrectPassword } from "./loginService";
 | 
			
		||||
import { IDatabaseAccountJson } from "../types/loginTypes";
 | 
			
		||||
import { HydratedDocument } from "mongoose";
 | 
			
		||||
 | 
			
		||||
let wsServer: ws.Server | undefined;
 | 
			
		||||
let wssServer: ws.Server | undefined;
 | 
			
		||||
 | 
			
		||||
export const startWsServer = (httpServer: http.Server): void => {
 | 
			
		||||
    wsServer = new ws.Server({ server: httpServer });
 | 
			
		||||
    wsServer.on("connection", wsOnConnect);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export const startWssServer = (httpsServer: https.Server): void => {
 | 
			
		||||
    wssServer = new ws.Server({ server: httpsServer });
 | 
			
		||||
    wssServer.on("connection", wsOnConnect);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export const stopWsServers = (promises: Promise<void>[]): void => {
 | 
			
		||||
    if (wsServer) {
 | 
			
		||||
        promises.push(
 | 
			
		||||
            new Promise(resolve => {
 | 
			
		||||
                wsServer!.close(() => {
 | 
			
		||||
                    resolve();
 | 
			
		||||
                });
 | 
			
		||||
            })
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
    if (wssServer) {
 | 
			
		||||
        promises.push(
 | 
			
		||||
            new Promise(resolve => {
 | 
			
		||||
                wssServer!.close(() => {
 | 
			
		||||
                    resolve();
 | 
			
		||||
                });
 | 
			
		||||
            })
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
let lastWsid: number = 0;
 | 
			
		||||
 | 
			
		||||
interface IWsCustomData extends ws {
 | 
			
		||||
    id?: number;
 | 
			
		||||
    accountId?: string;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
interface IWsMsgFromClient {
 | 
			
		||||
    auth?: {
 | 
			
		||||
        email: string;
 | 
			
		||||
        password: string;
 | 
			
		||||
        isRegister: boolean;
 | 
			
		||||
    };
 | 
			
		||||
    logout?: boolean;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
interface IWsMsgToClient {
 | 
			
		||||
    //wsid?: number;
 | 
			
		||||
    reload?: boolean;
 | 
			
		||||
    ports?: {
 | 
			
		||||
        http: number | undefined;
 | 
			
		||||
        https: number | undefined;
 | 
			
		||||
    };
 | 
			
		||||
    config_reloaded?: boolean;
 | 
			
		||||
    auth_succ?: {
 | 
			
		||||
        id: string;
 | 
			
		||||
        DisplayName: string;
 | 
			
		||||
        Nonce: number;
 | 
			
		||||
    };
 | 
			
		||||
    auth_fail?: {
 | 
			
		||||
        isRegister: boolean;
 | 
			
		||||
    };
 | 
			
		||||
    logged_out?: boolean;
 | 
			
		||||
    update_inventory?: boolean;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const wsOnConnect = (ws: ws, req: http.IncomingMessage): void => {
 | 
			
		||||
    if (req.url == "/custom/selftest") {
 | 
			
		||||
        ws.send("SpaceNinjaServer");
 | 
			
		||||
        ws.close();
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    (ws as IWsCustomData).id = ++lastWsid;
 | 
			
		||||
    ws.send(JSON.stringify({ wsid: lastWsid }));
 | 
			
		||||
 | 
			
		||||
    // eslint-disable-next-line @typescript-eslint/no-misused-promises
 | 
			
		||||
    ws.on("message", async msg => {
 | 
			
		||||
        const data = JSON.parse(String(msg)) as IWsMsgFromClient;
 | 
			
		||||
        if (data.auth) {
 | 
			
		||||
            let account: IDatabaseAccountJson | null = await Account.findOne({ email: data.auth.email });
 | 
			
		||||
            if (account) {
 | 
			
		||||
                if (isCorrectPassword(data.auth.password, account.password)) {
 | 
			
		||||
                    if (!account.Nonce) {
 | 
			
		||||
                        account.ClientType = "webui";
 | 
			
		||||
                        account.Nonce = createNonce();
 | 
			
		||||
                        await (account as HydratedDocument<IDatabaseAccountJson>).save();
 | 
			
		||||
                    }
 | 
			
		||||
                } else {
 | 
			
		||||
                    account = null;
 | 
			
		||||
                }
 | 
			
		||||
            } else if (data.auth.isRegister) {
 | 
			
		||||
                const name = await getUsernameFromEmail(data.auth.email);
 | 
			
		||||
                account = await createAccount({
 | 
			
		||||
                    email: data.auth.email,
 | 
			
		||||
                    password: data.auth.password,
 | 
			
		||||
                    ClientType: "webui",
 | 
			
		||||
                    LastLogin: new Date(),
 | 
			
		||||
                    DisplayName: name,
 | 
			
		||||
                    Nonce: createNonce()
 | 
			
		||||
                });
 | 
			
		||||
            }
 | 
			
		||||
            if (account) {
 | 
			
		||||
                (ws as IWsCustomData).accountId = account.id;
 | 
			
		||||
                ws.send(
 | 
			
		||||
                    JSON.stringify({
 | 
			
		||||
                        auth_succ: {
 | 
			
		||||
                            id: account.id,
 | 
			
		||||
                            DisplayName: account.DisplayName,
 | 
			
		||||
                            Nonce: account.Nonce
 | 
			
		||||
                        }
 | 
			
		||||
                    } satisfies IWsMsgToClient)
 | 
			
		||||
                );
 | 
			
		||||
            } else {
 | 
			
		||||
                ws.send(
 | 
			
		||||
                    JSON.stringify({
 | 
			
		||||
                        auth_fail: {
 | 
			
		||||
                            isRegister: data.auth.isRegister
 | 
			
		||||
                        }
 | 
			
		||||
                    } satisfies IWsMsgToClient)
 | 
			
		||||
                );
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        if (data.logout) {
 | 
			
		||||
            const accountId = (ws as IWsCustomData).accountId;
 | 
			
		||||
            (ws as IWsCustomData).accountId = undefined;
 | 
			
		||||
            await Account.updateOne(
 | 
			
		||||
                {
 | 
			
		||||
                    _id: accountId,
 | 
			
		||||
                    ClientType: "webui"
 | 
			
		||||
                },
 | 
			
		||||
                {
 | 
			
		||||
                    Nonce: 0
 | 
			
		||||
                }
 | 
			
		||||
            );
 | 
			
		||||
        }
 | 
			
		||||
    });
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export const sendWsBroadcast = (data: IWsMsgToClient): void => {
 | 
			
		||||
    const msg = JSON.stringify(data);
 | 
			
		||||
    if (wsServer) {
 | 
			
		||||
        for (const client of wsServer.clients) {
 | 
			
		||||
            client.send(msg);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    if (wssServer) {
 | 
			
		||||
        for (const client of wssServer.clients) {
 | 
			
		||||
            client.send(msg);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export const sendWsBroadcastTo = (accountId: string, data: IWsMsgToClient): void => {
 | 
			
		||||
    const msg = JSON.stringify(data);
 | 
			
		||||
    if (wsServer) {
 | 
			
		||||
        for (const client of wsServer.clients) {
 | 
			
		||||
            if ((client as IWsCustomData).accountId == accountId) {
 | 
			
		||||
                client.send(msg);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    if (wssServer) {
 | 
			
		||||
        for (const client of wssServer.clients) {
 | 
			
		||||
            if ((client as IWsCustomData).accountId == accountId) {
 | 
			
		||||
                client.send(msg);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export const sendWsBroadcastExcept = (wsid: number | undefined, data: IWsMsgToClient): void => {
 | 
			
		||||
    const msg = JSON.stringify(data);
 | 
			
		||||
    if (wsServer) {
 | 
			
		||||
        for (const client of wsServer.clients) {
 | 
			
		||||
            if ((client as IWsCustomData).id != wsid) {
 | 
			
		||||
                client.send(msg);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    if (wssServer) {
 | 
			
		||||
        for (const client of wssServer.clients) {
 | 
			
		||||
            if ((client as IWsCustomData).id != wsid) {
 | 
			
		||||
                client.send(msg);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
@ -1,5 +1,3 @@
 | 
			
		||||
import { ITypeCount } from "@/src/types/inventoryTypes/inventoryTypes";
 | 
			
		||||
 | 
			
		||||
export interface IOid {
 | 
			
		||||
    $oid: string;
 | 
			
		||||
}
 | 
			
		||||
@ -15,6 +13,11 @@ export interface IMongoDate {
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface ITypeCount {
 | 
			
		||||
    ItemType: string;
 | 
			
		||||
    ItemCount: number;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface IReward {
 | 
			
		||||
    items: ITypeCount[];
 | 
			
		||||
    credits: number;
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										150
									
								
								src/types/equipmentTypes.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										150
									
								
								src/types/equipmentTypes.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,150 @@
 | 
			
		||||
import { Types } from "mongoose";
 | 
			
		||||
import { IMongoDate, IOid, IOidWithLegacySupport } from "./commonTypes";
 | 
			
		||||
import { ICrewShipCustomization, IFlavourItem, IItemConfig, IPolarity } from "./inventoryTypes/commonInventoryTypes";
 | 
			
		||||
 | 
			
		||||
export interface IEquipmentSelection {
 | 
			
		||||
    ItemId: IOid;
 | 
			
		||||
    mod?: number;
 | 
			
		||||
    cus?: number;
 | 
			
		||||
    ItemType?: string;
 | 
			
		||||
    hide?: boolean;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export enum EquipmentFeatures {
 | 
			
		||||
    DOUBLE_CAPACITY = 1,
 | 
			
		||||
    UTILITY_SLOT = 2,
 | 
			
		||||
    GRAVIMAG_INSTALLED = 4,
 | 
			
		||||
    GILDED = 8,
 | 
			
		||||
    ARCANE_SLOT = 32,
 | 
			
		||||
    INCARNON_GENESIS = 512,
 | 
			
		||||
    VALENCE_SWAP = 1024
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface IEquipmentDatabase {
 | 
			
		||||
    ItemType: string;
 | 
			
		||||
    ItemName?: string;
 | 
			
		||||
    Configs: IItemConfig[];
 | 
			
		||||
    UpgradeVer?: number;
 | 
			
		||||
    XP?: number;
 | 
			
		||||
    Features?: number;
 | 
			
		||||
    Polarized?: number;
 | 
			
		||||
    Polarity?: IPolarity[];
 | 
			
		||||
    FocusLens?: string;
 | 
			
		||||
    ModSlotPurchases?: number;
 | 
			
		||||
    CustomizationSlotPurchases?: number;
 | 
			
		||||
    UpgradeType?: string;
 | 
			
		||||
    UpgradeFingerprint?: string;
 | 
			
		||||
    InfestationDate?: Date;
 | 
			
		||||
    InfestationDays?: number;
 | 
			
		||||
    InfestationType?: string;
 | 
			
		||||
    ModularParts?: string[];
 | 
			
		||||
    UnlockLevel?: number;
 | 
			
		||||
    Expiry?: Date;
 | 
			
		||||
    SkillTree?: string;
 | 
			
		||||
    OffensiveUpgrade?: string;
 | 
			
		||||
    DefensiveUpgrade?: string;
 | 
			
		||||
    UpgradesExpiry?: Date;
 | 
			
		||||
    UmbraDate?: Date; // related to scrapped "echoes of umbra" feature
 | 
			
		||||
    ArchonCrystalUpgrades?: IArchonCrystalUpgrade[];
 | 
			
		||||
    Weapon?: ICrewShipWeapon;
 | 
			
		||||
    Customization?: ICrewShipCustomization;
 | 
			
		||||
    RailjackImage?: IFlavourItem;
 | 
			
		||||
    CrewMembers?: ICrewShipMembersDatabase;
 | 
			
		||||
    Details?: IKubrowPetDetailsDatabase;
 | 
			
		||||
    Favorite?: boolean;
 | 
			
		||||
    IsNew?: boolean;
 | 
			
		||||
    _id: Types.ObjectId;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface IEquipmentClient
 | 
			
		||||
    extends Omit<
 | 
			
		||||
        IEquipmentDatabase,
 | 
			
		||||
        "_id" | "InfestationDate" | "Expiry" | "UpgradesExpiry" | "UmbraDate" | "CrewMembers" | "Details"
 | 
			
		||||
    > {
 | 
			
		||||
    ItemId: IOidWithLegacySupport;
 | 
			
		||||
    InfestationDate?: IMongoDate;
 | 
			
		||||
    Expiry?: IMongoDate;
 | 
			
		||||
    UpgradesExpiry?: IMongoDate;
 | 
			
		||||
    UmbraDate?: IMongoDate;
 | 
			
		||||
    CrewMembers?: ICrewShipMembersClient;
 | 
			
		||||
    Details?: IKubrowPetDetailsClient;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface IArchonCrystalUpgrade {
 | 
			
		||||
    UpgradeType?: string;
 | 
			
		||||
    Color?: string;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface ITraits {
 | 
			
		||||
    BaseColor: string;
 | 
			
		||||
    SecondaryColor: string;
 | 
			
		||||
    TertiaryColor: string;
 | 
			
		||||
    AccentColor: string;
 | 
			
		||||
    EyeColor: string;
 | 
			
		||||
    FurPattern: string;
 | 
			
		||||
    Personality: string;
 | 
			
		||||
    BodyType: string;
 | 
			
		||||
    Head?: string;
 | 
			
		||||
    Tail?: string;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface IKubrowPetDetailsDatabase {
 | 
			
		||||
    Name?: string;
 | 
			
		||||
    IsPuppy?: boolean;
 | 
			
		||||
    HasCollar: boolean;
 | 
			
		||||
    PrintsRemaining: number;
 | 
			
		||||
    Status: Status;
 | 
			
		||||
    HatchDate?: Date;
 | 
			
		||||
    DominantTraits: ITraits;
 | 
			
		||||
    RecessiveTraits: ITraits;
 | 
			
		||||
    IsMale: boolean;
 | 
			
		||||
    Size: number;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface IKubrowPetDetailsClient extends Omit<IKubrowPetDetailsDatabase, "HatchDate"> {
 | 
			
		||||
    HatchDate: IMongoDate;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export enum Status {
 | 
			
		||||
    StatusAvailable = "STATUS_AVAILABLE",
 | 
			
		||||
    StatusStasis = "STATUS_STASIS",
 | 
			
		||||
    StatusIncubating = "STATUS_INCUBATING"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// inventory.CrewShips[0].Weapon
 | 
			
		||||
export interface ICrewShipWeapon {
 | 
			
		||||
    PILOT?: ICrewShipWeaponEmplacements;
 | 
			
		||||
    PORT_GUNS?: ICrewShipWeaponEmplacements;
 | 
			
		||||
    STARBOARD_GUNS?: ICrewShipWeaponEmplacements;
 | 
			
		||||
    ARTILLERY?: ICrewShipWeaponEmplacements;
 | 
			
		||||
    SCANNER?: ICrewShipWeaponEmplacements;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface ICrewShipWeaponEmplacements {
 | 
			
		||||
    PRIMARY_A?: IEquipmentSelection;
 | 
			
		||||
    PRIMARY_B?: IEquipmentSelection;
 | 
			
		||||
    SECONDARY_A?: IEquipmentSelection;
 | 
			
		||||
    SECONDARY_B?: IEquipmentSelection;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface ICrewShipMembersClient {
 | 
			
		||||
    SLOT_A?: ICrewShipMemberClient;
 | 
			
		||||
    SLOT_B?: ICrewShipMemberClient;
 | 
			
		||||
    SLOT_C?: ICrewShipMemberClient;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface ICrewShipMembersDatabase {
 | 
			
		||||
    SLOT_A?: ICrewShipMemberDatabase;
 | 
			
		||||
    SLOT_B?: ICrewShipMemberDatabase;
 | 
			
		||||
    SLOT_C?: ICrewShipMemberDatabase;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface ICrewShipMemberClient {
 | 
			
		||||
    ItemId?: IOid;
 | 
			
		||||
    NemesisFingerprint?: number | bigint;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface ICrewShipMemberDatabase {
 | 
			
		||||
    ItemId?: Types.ObjectId;
 | 
			
		||||
    NemesisFingerprint?: bigint;
 | 
			
		||||
}
 | 
			
		||||
@ -1,6 +1,6 @@
 | 
			
		||||
import { Types } from "mongoose";
 | 
			
		||||
import { IOid, IMongoDate, IOidWithLegacySupport } from "@/src/types/commonTypes";
 | 
			
		||||
import { IFusionTreasure, IMiscItem, ITypeCount } from "@/src/types/inventoryTypes/inventoryTypes";
 | 
			
		||||
import { IOid, IMongoDate, IOidWithLegacySupport, ITypeCount } from "@/src/types/commonTypes";
 | 
			
		||||
import { IFusionTreasure, IMiscItem } from "@/src/types/inventoryTypes/inventoryTypes";
 | 
			
		||||
import { IPictureFrameInfo } from "./personalRoomsTypes";
 | 
			
		||||
import { IFriendInfo } from "./friendTypes";
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,14 +1,5 @@
 | 
			
		||||
import { IMongoDate, IOid, IOidWithLegacySupport } from "@/src/types/commonTypes";
 | 
			
		||||
import { IOid } from "@/src/types/commonTypes";
 | 
			
		||||
import { Types } from "mongoose";
 | 
			
		||||
import {
 | 
			
		||||
    ICrewShipCustomization,
 | 
			
		||||
    ICrewShipMembersClient,
 | 
			
		||||
    ICrewShipMembersDatabase,
 | 
			
		||||
    ICrewShipWeapon,
 | 
			
		||||
    IFlavourItem,
 | 
			
		||||
    IKubrowPetDetailsClient,
 | 
			
		||||
    IKubrowPetDetailsDatabase
 | 
			
		||||
} from "@/src/types/inventoryTypes/inventoryTypes";
 | 
			
		||||
 | 
			
		||||
export interface IPolarity {
 | 
			
		||||
    Slot: number;
 | 
			
		||||
@ -79,75 +70,24 @@ export interface IOperatorConfigClient extends Omit<IOperatorConfigDatabase, "_i
 | 
			
		||||
    ItemId: IOid;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface IEquipmentSelection {
 | 
			
		||||
    ItemId: IOid;
 | 
			
		||||
    mod?: number;
 | 
			
		||||
    cus?: number;
 | 
			
		||||
    ItemType?: string;
 | 
			
		||||
    hide?: boolean;
 | 
			
		||||
export interface ILotusCustomization extends IItemConfig {
 | 
			
		||||
    Persona: string;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface IEquipmentClient
 | 
			
		||||
    extends Omit<
 | 
			
		||||
        IEquipmentDatabase,
 | 
			
		||||
        "_id" | "InfestationDate" | "Expiry" | "UpgradesExpiry" | "UmbraDate" | "CrewMembers" | "Details"
 | 
			
		||||
    > {
 | 
			
		||||
    ItemId: IOidWithLegacySupport;
 | 
			
		||||
    InfestationDate?: IMongoDate;
 | 
			
		||||
    Expiry?: IMongoDate;
 | 
			
		||||
    UpgradesExpiry?: IMongoDate;
 | 
			
		||||
    UmbraDate?: IMongoDate;
 | 
			
		||||
    CrewMembers?: ICrewShipMembersClient;
 | 
			
		||||
    Details?: IKubrowPetDetailsClient;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export enum EquipmentFeatures {
 | 
			
		||||
    DOUBLE_CAPACITY = 1,
 | 
			
		||||
    UTILITY_SLOT = 2,
 | 
			
		||||
    GRAVIMAG_INSTALLED = 4,
 | 
			
		||||
    GILDED = 8,
 | 
			
		||||
    ARCANE_SLOT = 32,
 | 
			
		||||
    INCARNON_GENESIS = 512,
 | 
			
		||||
    VALENCE_SWAP = 1024
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface IEquipmentDatabase {
 | 
			
		||||
export interface IFlavourItem {
 | 
			
		||||
    ItemType: string;
 | 
			
		||||
    ItemName?: string;
 | 
			
		||||
    Configs: IItemConfig[];
 | 
			
		||||
    UpgradeVer?: number;
 | 
			
		||||
    XP?: number;
 | 
			
		||||
    Features?: number;
 | 
			
		||||
    Polarized?: number;
 | 
			
		||||
    Polarity?: IPolarity[];
 | 
			
		||||
    FocusLens?: string;
 | 
			
		||||
    ModSlotPurchases?: number;
 | 
			
		||||
    CustomizationSlotPurchases?: number;
 | 
			
		||||
    UpgradeType?: string;
 | 
			
		||||
    UpgradeFingerprint?: string;
 | 
			
		||||
    InfestationDate?: Date;
 | 
			
		||||
    InfestationDays?: number;
 | 
			
		||||
    InfestationType?: string;
 | 
			
		||||
    ModularParts?: string[];
 | 
			
		||||
    UnlockLevel?: number;
 | 
			
		||||
    Expiry?: Date;
 | 
			
		||||
    SkillTree?: string;
 | 
			
		||||
    OffensiveUpgrade?: string;
 | 
			
		||||
    DefensiveUpgrade?: string;
 | 
			
		||||
    UpgradesExpiry?: Date;
 | 
			
		||||
    UmbraDate?: Date; // related to scrapped "echoes of umbra" feature
 | 
			
		||||
    ArchonCrystalUpgrades?: IArchonCrystalUpgrade[];
 | 
			
		||||
    Weapon?: ICrewShipWeapon;
 | 
			
		||||
    Customization?: ICrewShipCustomization;
 | 
			
		||||
    RailjackImage?: IFlavourItem;
 | 
			
		||||
    CrewMembers?: ICrewShipMembersDatabase;
 | 
			
		||||
    Details?: IKubrowPetDetailsDatabase;
 | 
			
		||||
    Favorite?: boolean;
 | 
			
		||||
    IsNew?: boolean;
 | 
			
		||||
    _id: Types.ObjectId;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface IArchonCrystalUpgrade {
 | 
			
		||||
    UpgradeType?: string;
 | 
			
		||||
    Color?: string;
 | 
			
		||||
export interface IShipAttachments {
 | 
			
		||||
    HOOD_ORNAMENT?: string;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface IShipCustomization {
 | 
			
		||||
    SkinFlavourItem?: string;
 | 
			
		||||
    Colors?: IColor;
 | 
			
		||||
    ShipAttachments?: IShipAttachments;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface ICrewShipCustomization {
 | 
			
		||||
    CrewshipInterior: IShipCustomization;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -1,18 +1,20 @@
 | 
			
		||||
/* eslint-disable @typescript-eslint/no-explicit-any */
 | 
			
		||||
import { Types } from "mongoose";
 | 
			
		||||
import { IOid, IMongoDate, IOidWithLegacySupport } from "../commonTypes";
 | 
			
		||||
import { IOid, IMongoDate, IOidWithLegacySupport, ITypeCount } from "../commonTypes";
 | 
			
		||||
import {
 | 
			
		||||
    IColor,
 | 
			
		||||
    IItemConfig,
 | 
			
		||||
    IOperatorConfigClient,
 | 
			
		||||
    IEquipmentSelection,
 | 
			
		||||
    IEquipmentDatabase,
 | 
			
		||||
    IEquipmentClient,
 | 
			
		||||
    IOperatorConfigDatabase
 | 
			
		||||
    IOperatorConfigDatabase,
 | 
			
		||||
    IFlavourItem,
 | 
			
		||||
    ILotusCustomization,
 | 
			
		||||
    IShipCustomization
 | 
			
		||||
} from "@/src/types/inventoryTypes/commonInventoryTypes";
 | 
			
		||||
import { IFingerprintStat, RivenFingerprint } from "@/src/helpers/rivenHelper";
 | 
			
		||||
import { IOrbiterClient, IShipCustomization } from "../personalRoomsTypes";
 | 
			
		||||
import { IOrbiterClient } from "../personalRoomsTypes";
 | 
			
		||||
import { ICountedStoreItem } from "warframe-public-export-plus";
 | 
			
		||||
import { IEquipmentClient, IEquipmentDatabase, ITraits } from "../equipmentTypes";
 | 
			
		||||
import { ILoadOutPresets } from "../saveLoadoutTypes";
 | 
			
		||||
 | 
			
		||||
export type InventoryDatabaseEquipment = {
 | 
			
		||||
    [_ in TEquipmentKey]: IEquipmentDatabase[];
 | 
			
		||||
@ -110,11 +112,6 @@ export interface IQuestKeyDatabase {
 | 
			
		||||
    CompletionDate?: Date;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface ITypeCount {
 | 
			
		||||
    ItemType: string;
 | 
			
		||||
    ItemCount: number;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export const equipmentKeys = [
 | 
			
		||||
    "Suits",
 | 
			
		||||
    "LongGuns",
 | 
			
		||||
@ -552,54 +549,8 @@ export interface IUpgradeFromClient {
 | 
			
		||||
    LastAdded: IOidWithLegacySupport;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface ICrewShipMembersClient {
 | 
			
		||||
    SLOT_A?: ICrewShipMemberClient;
 | 
			
		||||
    SLOT_B?: ICrewShipMemberClient;
 | 
			
		||||
    SLOT_C?: ICrewShipMemberClient;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface ICrewShipMembersDatabase {
 | 
			
		||||
    SLOT_A?: ICrewShipMemberDatabase;
 | 
			
		||||
    SLOT_B?: ICrewShipMemberDatabase;
 | 
			
		||||
    SLOT_C?: ICrewShipMemberDatabase;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface ICrewShipMemberClient {
 | 
			
		||||
    ItemId?: IOid;
 | 
			
		||||
    NemesisFingerprint?: number | bigint;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface ICrewShipMemberDatabase {
 | 
			
		||||
    ItemId?: Types.ObjectId;
 | 
			
		||||
    NemesisFingerprint?: bigint;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface ICrewShipCustomization {
 | 
			
		||||
    CrewshipInterior: IShipCustomization;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface IFlavourItem {
 | 
			
		||||
    ItemType: string;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export type IMiscItem = ITypeCount;
 | 
			
		||||
 | 
			
		||||
// inventory.CrewShips[0].Weapon
 | 
			
		||||
export interface ICrewShipWeapon {
 | 
			
		||||
    PILOT?: ICrewShipWeaponEmplacements;
 | 
			
		||||
    PORT_GUNS?: ICrewShipWeaponEmplacements;
 | 
			
		||||
    STARBOARD_GUNS?: ICrewShipWeaponEmplacements;
 | 
			
		||||
    ARTILLERY?: ICrewShipWeaponEmplacements;
 | 
			
		||||
    SCANNER?: ICrewShipWeaponEmplacements;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface ICrewShipWeaponEmplacements {
 | 
			
		||||
    PRIMARY_A?: IEquipmentSelection;
 | 
			
		||||
    PRIMARY_B?: IEquipmentSelection;
 | 
			
		||||
    SECONDARY_A?: IEquipmentSelection;
 | 
			
		||||
    SECONDARY_B?: IEquipmentSelection;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface IDiscoveredMarker {
 | 
			
		||||
    tag: string;
 | 
			
		||||
    discoveryState: number[];
 | 
			
		||||
@ -730,42 +681,6 @@ export interface IKubrowPetPrintDatabase extends Omit<IKubrowPetPrintClient, "It
 | 
			
		||||
    _id: Types.ObjectId;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface ITraits {
 | 
			
		||||
    BaseColor: string;
 | 
			
		||||
    SecondaryColor: string;
 | 
			
		||||
    TertiaryColor: string;
 | 
			
		||||
    AccentColor: string;
 | 
			
		||||
    EyeColor: string;
 | 
			
		||||
    FurPattern: string;
 | 
			
		||||
    Personality: string;
 | 
			
		||||
    BodyType: string;
 | 
			
		||||
    Head?: string;
 | 
			
		||||
    Tail?: string;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface IKubrowPetDetailsDatabase {
 | 
			
		||||
    Name?: string;
 | 
			
		||||
    IsPuppy?: boolean;
 | 
			
		||||
    HasCollar: boolean;
 | 
			
		||||
    PrintsRemaining: number;
 | 
			
		||||
    Status: Status;
 | 
			
		||||
    HatchDate?: Date;
 | 
			
		||||
    DominantTraits: ITraits;
 | 
			
		||||
    RecessiveTraits: ITraits;
 | 
			
		||||
    IsMale: boolean;
 | 
			
		||||
    Size: number;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface IKubrowPetDetailsClient extends Omit<IKubrowPetDetailsDatabase, "HatchDate"> {
 | 
			
		||||
    HatchDate: IMongoDate;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export enum Status {
 | 
			
		||||
    StatusAvailable = "STATUS_AVAILABLE",
 | 
			
		||||
    StatusStasis = "STATUS_STASIS",
 | 
			
		||||
    StatusIncubating = "STATUS_INCUBATING"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface ILastSortieRewardClient {
 | 
			
		||||
    SortieId: IOid;
 | 
			
		||||
    StoreItem: string;
 | 
			
		||||
@ -798,45 +713,6 @@ export interface ILibraryPersonalProgress {
 | 
			
		||||
    Completed: boolean;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// keep in sync with ILoadoutDatabase
 | 
			
		||||
export interface ILoadOutPresets {
 | 
			
		||||
    NORMAL: ILoadoutConfigClient[];
 | 
			
		||||
    NORMAL_PVP: ILoadoutConfigClient[];
 | 
			
		||||
    LUNARO: ILoadoutConfigClient[];
 | 
			
		||||
    ARCHWING: ILoadoutConfigClient[];
 | 
			
		||||
    SENTINEL: ILoadoutConfigClient[];
 | 
			
		||||
    OPERATOR: ILoadoutConfigClient[];
 | 
			
		||||
    GEAR: ILoadoutConfigClient[];
 | 
			
		||||
    KDRIVE: ILoadoutConfigClient[];
 | 
			
		||||
    DATAKNIFE: ILoadoutConfigClient[];
 | 
			
		||||
    MECH: ILoadoutConfigClient[];
 | 
			
		||||
    OPERATOR_ADULT: ILoadoutConfigClient[];
 | 
			
		||||
    DRIFTER: ILoadoutConfigClient[];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export enum FocusSchool {
 | 
			
		||||
    Attack = "AP_ATTACK",
 | 
			
		||||
    Defense = "AP_DEFENSE",
 | 
			
		||||
    Power = "AP_POWER",
 | 
			
		||||
    Tactic = "AP_TACTIC",
 | 
			
		||||
    Ward = "AP_WARD"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface ILoadoutConfigClient {
 | 
			
		||||
    FocusSchool?: FocusSchool;
 | 
			
		||||
    PresetIcon?: string;
 | 
			
		||||
    Favorite?: boolean;
 | 
			
		||||
    n?: string; // Loadout name
 | 
			
		||||
    s?: IEquipmentSelection; // Suit
 | 
			
		||||
    p?: IEquipmentSelection; // Secondary weapon
 | 
			
		||||
    l?: IEquipmentSelection; // Primary weapon
 | 
			
		||||
    m?: IEquipmentSelection; // Melee weapon
 | 
			
		||||
    h?: IEquipmentSelection; // Gravimag weapon
 | 
			
		||||
    a?: IEquipmentSelection; // Necromech exalted weapon
 | 
			
		||||
    ItemId: IOid;
 | 
			
		||||
    Remove?: boolean; // when client wants to remove a config, it only includes ItemId & Remove.
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export enum UpgradeType {
 | 
			
		||||
    LotusWeaponsGrineerKuvaLichUpgradesInnateDamageRandomMod = "/Lotus/Weapons/Grineer/KuvaLich/Upgrades/InnateDamageRandomMod"
 | 
			
		||||
}
 | 
			
		||||
@ -847,10 +723,6 @@ export interface ILoreFragmentScan {
 | 
			
		||||
    ItemType: string;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface ILotusCustomization extends IItemConfig {
 | 
			
		||||
    Persona: string;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface IMissionDatabase {
 | 
			
		||||
    Tag: string;
 | 
			
		||||
    Completes: number;
 | 
			
		||||
 | 
			
		||||
@ -1,4 +1,4 @@
 | 
			
		||||
import { IColor } from "@/src/types/inventoryTypes/commonInventoryTypes";
 | 
			
		||||
import { IColor, IShipAttachments, IShipCustomization } from "@/src/types/inventoryTypes/commonInventoryTypes";
 | 
			
		||||
import { Document, Model, Types } from "mongoose";
 | 
			
		||||
import { ILoadoutClient } from "./saveLoadoutTypes";
 | 
			
		||||
import { IMongoDate, IOid } from "./commonTypes";
 | 
			
		||||
@ -11,16 +11,6 @@ export interface IGetShipResponse {
 | 
			
		||||
    LoadOutInventory: { LoadOutPresets: ILoadoutClient };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface IShipAttachments {
 | 
			
		||||
    HOOD_ORNAMENT?: string;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface IShipCustomization {
 | 
			
		||||
    SkinFlavourItem?: string;
 | 
			
		||||
    Colors?: IColor;
 | 
			
		||||
    ShipAttachments?: IShipAttachments;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export type TBootLocation = "LISET" | "DRIFTER_CAMP" | "APARTMENT" | "SHOP";
 | 
			
		||||
 | 
			
		||||
export interface IOrbiterClient {
 | 
			
		||||
 | 
			
		||||
@ -1,10 +1,10 @@
 | 
			
		||||
import { IEquipmentClient } from "./inventoryTypes/commonInventoryTypes";
 | 
			
		||||
import { ITypeCount } from "./commonTypes";
 | 
			
		||||
import { IEquipmentClient } from "./equipmentTypes";
 | 
			
		||||
import {
 | 
			
		||||
    IDroneClient,
 | 
			
		||||
    IInfestedFoundryClient,
 | 
			
		||||
    IMiscItem,
 | 
			
		||||
    INemesisClient,
 | 
			
		||||
    ITypeCount,
 | 
			
		||||
    IRecentVendorPurchaseClient,
 | 
			
		||||
    TEquipmentKey,
 | 
			
		||||
    ICrewMemberClient,
 | 
			
		||||
 | 
			
		||||
@ -1,10 +1,9 @@
 | 
			
		||||
import { IOid } from "./commonTypes";
 | 
			
		||||
import { ArtifactPolarity, IPolarity, IEquipmentClient } from "@/src/types/inventoryTypes/commonInventoryTypes";
 | 
			
		||||
import { IOid, ITypeCount } from "./commonTypes";
 | 
			
		||||
import { ArtifactPolarity, IPolarity } from "@/src/types/inventoryTypes/commonInventoryTypes";
 | 
			
		||||
import {
 | 
			
		||||
    IBooster,
 | 
			
		||||
    IChallengeProgress,
 | 
			
		||||
    IEvolutionProgress,
 | 
			
		||||
    ITypeCount,
 | 
			
		||||
    IMission,
 | 
			
		||||
    IRawUpgrade,
 | 
			
		||||
    ISeasonChallenge,
 | 
			
		||||
@ -19,13 +18,14 @@ import {
 | 
			
		||||
    ICollectibleEntry,
 | 
			
		||||
    IDiscoveredMarker,
 | 
			
		||||
    ILockedWeaponGroupClient,
 | 
			
		||||
    ILoadOutPresets,
 | 
			
		||||
    IInvasionProgressClient,
 | 
			
		||||
    IWeaponSkinClient,
 | 
			
		||||
    IKubrowPetEggClient,
 | 
			
		||||
    INemesisClient
 | 
			
		||||
} from "./inventoryTypes/inventoryTypes";
 | 
			
		||||
import { IGroup } from "./loginTypes";
 | 
			
		||||
import { ILoadOutPresets } from "./saveLoadoutTypes";
 | 
			
		||||
import { IEquipmentClient } from "./equipmentTypes";
 | 
			
		||||
 | 
			
		||||
export interface IAffiliationChange {
 | 
			
		||||
    Tag: string;
 | 
			
		||||
 | 
			
		||||
@ -1,14 +1,13 @@
 | 
			
		||||
import { IOid } from "@/src/types/commonTypes";
 | 
			
		||||
import { IItemConfig, IOperatorConfigClient } from "@/src/types/inventoryTypes/commonInventoryTypes";
 | 
			
		||||
import { Types } from "mongoose";
 | 
			
		||||
import {
 | 
			
		||||
    ICrewShipCustomization,
 | 
			
		||||
    ICrewShipMembersClient,
 | 
			
		||||
    ICrewShipWeapon,
 | 
			
		||||
    IFlavourItem,
 | 
			
		||||
    ILoadoutConfigClient,
 | 
			
		||||
    ILotusCustomization
 | 
			
		||||
} from "./inventoryTypes/inventoryTypes";
 | 
			
		||||
    IItemConfig,
 | 
			
		||||
    ILotusCustomization,
 | 
			
		||||
    IOperatorConfigClient
 | 
			
		||||
} from "@/src/types/inventoryTypes/commonInventoryTypes";
 | 
			
		||||
import { Types } from "mongoose";
 | 
			
		||||
import { ICrewShipMembersClient, ICrewShipWeapon, IEquipmentSelection } from "./equipmentTypes";
 | 
			
		||||
 | 
			
		||||
export interface ISaveLoadoutRequest {
 | 
			
		||||
    LoadOuts: ILoadoutClient;
 | 
			
		||||
@ -73,7 +72,6 @@ export type IConfigEntry = {
 | 
			
		||||
 | 
			
		||||
export type ILoadoutClient = Omit<ILoadoutDatabase, "_id" | "loadoutOwnerId">;
 | 
			
		||||
 | 
			
		||||
// keep in sync with ILoadOutPresets
 | 
			
		||||
export interface ILoadoutDatabase {
 | 
			
		||||
    NORMAL: ILoadoutConfigDatabase[];
 | 
			
		||||
    SENTINEL: ILoadoutConfigDatabase[];
 | 
			
		||||
@ -90,9 +88,48 @@ export interface ILoadoutDatabase {
 | 
			
		||||
    loadoutOwnerId: Types.ObjectId;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface ILoadOutPresets {
 | 
			
		||||
    NORMAL: ILoadoutConfigClient[];
 | 
			
		||||
    NORMAL_PVP: ILoadoutConfigClient[];
 | 
			
		||||
    LUNARO: ILoadoutConfigClient[];
 | 
			
		||||
    ARCHWING: ILoadoutConfigClient[];
 | 
			
		||||
    SENTINEL: ILoadoutConfigClient[];
 | 
			
		||||
    OPERATOR: ILoadoutConfigClient[];
 | 
			
		||||
    GEAR: ILoadoutConfigClient[];
 | 
			
		||||
    KDRIVE: ILoadoutConfigClient[];
 | 
			
		||||
    DATAKNIFE: ILoadoutConfigClient[];
 | 
			
		||||
    MECH: ILoadoutConfigClient[];
 | 
			
		||||
    OPERATOR_ADULT: ILoadoutConfigClient[];
 | 
			
		||||
    DRIFTER: ILoadoutConfigClient[];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface ILoadoutEntry {
 | 
			
		||||
    [key: string]: ILoadoutConfigClient;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface ILoadoutConfigDatabase extends Omit<ILoadoutConfigClient, "ItemId"> {
 | 
			
		||||
    _id: Types.ObjectId;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export enum FocusSchool {
 | 
			
		||||
    Attack = "AP_ATTACK",
 | 
			
		||||
    Defense = "AP_DEFENSE",
 | 
			
		||||
    Power = "AP_POWER",
 | 
			
		||||
    Tactic = "AP_TACTIC",
 | 
			
		||||
    Ward = "AP_WARD"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface ILoadoutConfigClient {
 | 
			
		||||
    FocusSchool?: FocusSchool;
 | 
			
		||||
    PresetIcon?: string;
 | 
			
		||||
    Favorite?: boolean;
 | 
			
		||||
    n?: string; // Loadout name
 | 
			
		||||
    s?: IEquipmentSelection; // Suit
 | 
			
		||||
    p?: IEquipmentSelection; // Secondary weapon
 | 
			
		||||
    l?: IEquipmentSelection; // Primary weapon
 | 
			
		||||
    m?: IEquipmentSelection; // Melee weapon
 | 
			
		||||
    h?: IEquipmentSelection; // Gravimag weapon
 | 
			
		||||
    a?: IEquipmentSelection; // Necromech exalted weapon
 | 
			
		||||
    ItemId: IOid;
 | 
			
		||||
    Remove?: boolean; // when client wants to remove a config, it only includes ItemId & Remove.
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,5 @@
 | 
			
		||||
import { Types } from "mongoose";
 | 
			
		||||
import { IColor } from "@/src/types/inventoryTypes/commonInventoryTypes";
 | 
			
		||||
import { IShipAttachments } from "./personalRoomsTypes";
 | 
			
		||||
import { IColor, IShipAttachments } from "@/src/types/inventoryTypes/commonInventoryTypes";
 | 
			
		||||
 | 
			
		||||
export interface IShipDatabase {
 | 
			
		||||
    ItemType: string;
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user