chore(webui): update Chinese translation #2410
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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
1
.github/workflows/build.yml
vendored
1
.github/workflows/build.yml
vendored
@ -19,6 +19,7 @@ jobs:
|
||||
- run: npm run lint:ci
|
||||
- run: npm run prettier
|
||||
- run: npm run update-translations
|
||||
- run: npm run fix-imports
|
||||
- name: Fail if there are uncommitted changes
|
||||
run: |
|
||||
if [[ -n "$(git status --porcelain)" ]]; then
|
||||
|
@ -78,7 +78,9 @@
|
||||
"nightwaveOverride": "",
|
||||
"allTheFissures": "",
|
||||
"circuitGameModes": null,
|
||||
"darvoStockMultiplier": 1
|
||||
"darvoStockMultiplier": 1,
|
||||
"varziaOverride": "",
|
||||
"varziaFullyStocked": false
|
||||
},
|
||||
"dev": {
|
||||
"keepVendorsExpired": false
|
||||
|
2196
package-lock.json
generated
2196
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -19,7 +19,9 @@
|
||||
"lint:ci": "eslint --ext .ts --rule \"prettier/prettier: off\" .",
|
||||
"lint:fix": "eslint --fix --ext .ts .",
|
||||
"prettier": "prettier --write .",
|
||||
"update-translations": "cd scripts && node update-translations.js"
|
||||
"update-translations": "cd scripts && node update-translations.js",
|
||||
"fix-imports": "cd scripts && node fix-imports.js",
|
||||
"fix": "npm run update-translations && npm run fix-imports && npm run prettier"
|
||||
},
|
||||
"license": "GNU",
|
||||
"dependencies": {
|
||||
@ -37,7 +39,7 @@
|
||||
"ncp": "^2.0.0",
|
||||
"typescript": "^5.5",
|
||||
"undici": "^7.10.0",
|
||||
"warframe-public-export-plus": "^0.5.76",
|
||||
"warframe-public-export-plus": "^0.5.77",
|
||||
"warframe-riven-info": "^0.1.2",
|
||||
"winston": "^3.17.0",
|
||||
"winston-daily-rotate-file": "^5.0.0",
|
||||
@ -47,6 +49,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"
|
||||
|
46
scripts/fix-imports.js
Normal file
46
scripts/fix-imports.js
Normal file
@ -0,0 +1,46 @@
|
||||
/* eslint-disable */
|
||||
const fs = require("fs");
|
||||
const path = require("path");
|
||||
|
||||
const root = path.join(process.cwd(), "..");
|
||||
|
||||
function listFiles(dir) {
|
||||
const entries = fs.readdirSync(dir, { withFileTypes: true });
|
||||
let results = [];
|
||||
for (const entry of entries) {
|
||||
const fullPath = path.join(dir, entry.name);
|
||||
if (entry.isDirectory()) {
|
||||
results = results.concat(listFiles(fullPath));
|
||||
} else {
|
||||
results.push(fullPath);
|
||||
}
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
const files = listFiles(path.join(root, "src"));
|
||||
|
||||
for (const file of files) {
|
||||
let content;
|
||||
try {
|
||||
content = fs.readFileSync(file, "utf8");
|
||||
} catch (e) {
|
||||
continue;
|
||||
}
|
||||
const dir = path.dirname(file);
|
||||
const fixedContent = content.replaceAll(/} from "([^"]+)";/g, (sub, importPath) => {
|
||||
if (!importPath.startsWith("@/")) {
|
||||
const fullImportPath = path.resolve(dir, importPath);
|
||||
if (fs.existsSync(fullImportPath + ".ts")) {
|
||||
const relative = path.relative(root, fullImportPath).replace(/\\/g, "/");
|
||||
const fixedPath = "@/" + relative;
|
||||
console.log(`${importPath} -> ${fixedPath}`);
|
||||
return sub.split(importPath).join(fixedPath);
|
||||
}
|
||||
}
|
||||
return sub;
|
||||
});
|
||||
if (content != fixedContent) {
|
||||
fs.writeFileSync(file, fixedContent, "utf8");
|
||||
}
|
||||
}
|
@ -24,7 +24,6 @@ export const artifactsController: RequestHandler = async (req, res) => {
|
||||
|
||||
if (itemIndex !== -1) {
|
||||
Upgrades[itemIndex].UpgradeFingerprint = stringifiedUpgradeFingerprint;
|
||||
inventory.markModified(`Upgrades.${itemIndex}.UpgradeFingerprint`);
|
||||
} else {
|
||||
itemIndex =
|
||||
Upgrades.push({
|
||||
|
@ -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);
|
||||
|
@ -1,12 +1,15 @@
|
||||
import { getJSONfromString } from "@/src/helpers/stringHelpers";
|
||||
import { Guild } from "@/src/models/guildModel";
|
||||
import { getAccountForRequest } from "@/src/services/loginService";
|
||||
import { hasAccessToDojo, hasGuildPermission } from "@/src/services/guildService";
|
||||
import { getInventory } from "@/src/services/inventoryService";
|
||||
import { getAccountForRequest, getAccountIdForRequest } from "@/src/services/loginService";
|
||||
import { GuildPermission } from "@/src/types/guildTypes";
|
||||
import { logger } from "@/src/utils/logger";
|
||||
import { RequestHandler } from "express";
|
||||
|
||||
export const customObstacleCourseLeaderboardController: RequestHandler = async (req, res) => {
|
||||
const data = getJSONfromString<ICustomObstacleCourseLeaderboardRequest>(String(req.body));
|
||||
const guild = (await Guild.findById(data.g, "DojoComponents"))!;
|
||||
const guild = (await Guild.findById(data.g, "DojoComponents Ranks"))!;
|
||||
const component = guild.DojoComponents.id(data.c)!;
|
||||
if (req.query.act == "f") {
|
||||
res.json({
|
||||
@ -34,6 +37,19 @@ export const customObstacleCourseLeaderboardController: RequestHandler = async (
|
||||
entry.r = ++r;
|
||||
}
|
||||
await guild.save();
|
||||
res.status(200).end();
|
||||
} else if (req.query.act == "c") {
|
||||
// TOVERIFY: What clan permission is actually needed for this?
|
||||
const accountId = await getAccountIdForRequest(req);
|
||||
const inventory = await getInventory(accountId, "GuildId LevelKeys");
|
||||
if (!hasAccessToDojo(inventory) || !(await hasGuildPermission(guild, accountId, GuildPermission.Decorator))) {
|
||||
res.status(400).end();
|
||||
return;
|
||||
}
|
||||
|
||||
component.Leaderboard = undefined;
|
||||
await guild.save();
|
||||
|
||||
res.status(200).end();
|
||||
} else {
|
||||
logger.debug(`data provided to ${req.path}: ${String(req.body)}`);
|
||||
|
@ -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: {
|
||||
|
@ -6,9 +6,8 @@ import { getAccountIdForRequest } from "@/src/services/loginService";
|
||||
import { createGarden, getPersonalRooms } from "@/src/services/personalRoomsService";
|
||||
import { IMongoDate } from "@/src/types/commonTypes";
|
||||
import { IMissionReward } from "@/src/types/missionTypes";
|
||||
import { IPersonalRoomsClient } from "@/src/types/personalRoomsTypes";
|
||||
import { IGardeningClient, IPersonalRoomsClient } from "@/src/types/personalRoomsTypes";
|
||||
import { IInventoryChanges } from "@/src/types/purchaseTypes";
|
||||
import { IGardeningClient } from "@/src/types/shipTypes";
|
||||
import { RequestHandler } from "express";
|
||||
import { dict_en, ExportResources } from "warframe-public-export-plus";
|
||||
|
||||
|
@ -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,10 +3,9 @@ import { config } from "@/src/services/configService";
|
||||
import allShipFeatures from "@/static/fixed_responses/allShipFeatures.json";
|
||||
import { getAccountIdForRequest } from "@/src/services/loginService";
|
||||
import { createGarden, getPersonalRooms } from "@/src/services/personalRoomsService";
|
||||
import { toOid } from "@/src/helpers/inventoryHelpers";
|
||||
import { IGetShipResponse } from "@/src/types/shipTypes";
|
||||
import { IPersonalRoomsClient } from "@/src/types/personalRoomsTypes";
|
||||
import { IGetShipResponse, IPersonalRoomsClient } from "@/src/types/personalRoomsTypes";
|
||||
import { getLoadout } from "@/src/services/loadoutService";
|
||||
import { toOid } from "@/src/helpers/inventoryHelpers";
|
||||
|
||||
export const getShipController: RequestHandler = async (req, res) => {
|
||||
const accountId = await getAccountIdForRequest(req);
|
||||
@ -26,15 +25,7 @@ export const getShipController: RequestHandler = async (req, res) => {
|
||||
LoadOutInventory: { LoadOutPresets: loadout.toJSON() },
|
||||
Ship: {
|
||||
...personalRooms.Ship,
|
||||
ShipId: toOid(personalRoomsDb.activeShipId),
|
||||
ShipInterior: {
|
||||
Colors: personalRooms.ShipInteriorColors,
|
||||
ShipAttachments: { HOOD_ORNAMENT: "" },
|
||||
SkinFlavourItem: ""
|
||||
},
|
||||
FavouriteLoadoutId: personalRooms.Ship.FavouriteLoadoutId
|
||||
? toOid(personalRooms.Ship.FavouriteLoadoutId)
|
||||
: undefined
|
||||
ShipId: toOid(personalRoomsDb.activeShipId)
|
||||
},
|
||||
Apartment: personalRooms.Apartment,
|
||||
TailorShop: personalRooms.TailorShop
|
||||
|
@ -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);
|
||||
|
@ -1,7 +1,6 @@
|
||||
import { getAccountIdForRequest } from "@/src/services/loginService";
|
||||
import { getInventory, updateCurrency } from "@/src/services/inventoryService";
|
||||
import { getInventory, updateCurrency, updateSlots } from "@/src/services/inventoryService";
|
||||
import { RequestHandler } from "express";
|
||||
import { updateSlots } from "@/src/services/inventoryService";
|
||||
import { InventorySlot } from "@/src/types/inventoryTypes/inventoryTypes";
|
||||
import { logger } from "@/src/utils/logger";
|
||||
|
||||
|
@ -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 { getInventoryResponse } from "./inventoryController";
|
||||
import { getInventory } from "@/src/services/inventoryService";
|
||||
import { getInventoryResponse } from "@/src/controllers/api/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) => {
|
||||
|
@ -2,7 +2,7 @@ import { getAccountIdForRequest } from "@/src/services/loginService";
|
||||
import { getJSONfromString } from "@/src/helpers/stringHelpers";
|
||||
import { getInventory } from "@/src/services/inventoryService";
|
||||
import { RequestHandler } from "express";
|
||||
import { ISettings } from "../../types/inventoryTypes/inventoryTypes";
|
||||
import { ISettings } from "@/src/types/inventoryTypes/inventoryTypes";
|
||||
|
||||
interface ISaveSettingsRequest {
|
||||
Settings: ISettings;
|
||||
|
@ -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;
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { RequestHandler } from "express";
|
||||
import { getAccountIdForRequest } from "@/src/services/loginService";
|
||||
import { getPersonalRooms } from "@/src/services/personalRoomsService";
|
||||
import { TBootLocation } from "@/src/types/shipTypes";
|
||||
import { TBootLocation } from "@/src/types/personalRoomsTypes";
|
||||
import { getInventory } from "@/src/services/inventoryService";
|
||||
|
||||
export const setBootLocationController: RequestHandler = async (req, res) => {
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { getAccountIdForRequest } from "@/src/services/loginService";
|
||||
import { IPictureFrameInfo, ISetPlacedDecoInfoRequest } from "@/src/types/shipTypes";
|
||||
import { IPictureFrameInfo, ISetPlacedDecoInfoRequest } from "@/src/types/personalRoomsTypes";
|
||||
import { RequestHandler } from "express";
|
||||
import { handleSetPlacedDecoInfo } from "@/src/services/shipCustomizationsService";
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { getAccountIdForRequest } from "@/src/services/loginService";
|
||||
import { setShipCustomizations } from "@/src/services/shipCustomizationsService";
|
||||
import { ISetShipCustomizationsRequest } from "@/src/types/shipTypes";
|
||||
import { ISetShipCustomizationsRequest } from "@/src/types/personalRoomsTypes";
|
||||
import { logger } from "@/src/utils/logger";
|
||||
import { RequestHandler } from "express";
|
||||
|
||||
|
@ -3,7 +3,7 @@ import { RequestHandler } from "express";
|
||||
import { getPersonalRooms } from "@/src/services/personalRoomsService";
|
||||
import { IOid } from "@/src/types/commonTypes";
|
||||
import { Types } from "mongoose";
|
||||
import { IFavouriteLoadoutDatabase, TBootLocation } from "@/src/types/shipTypes";
|
||||
import { IFavouriteLoadoutDatabase, TBootLocation } from "@/src/types/personalRoomsTypes";
|
||||
|
||||
export const setShipFavouriteLoadoutController: 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 { 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) => {
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { getAccountIdForRequest } from "@/src/services/loginService";
|
||||
import { IShipDecorationsRequest } from "@/src/types/shipTypes";
|
||||
import { IShipDecorationsRequest } from "@/src/types/personalRoomsTypes";
|
||||
import { logger } from "@/src/utils/logger";
|
||||
import { RequestHandler } from "express";
|
||||
import { handleSetShipDecorations } from "@/src/services/shipCustomizationsService";
|
||||
|
@ -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);
|
||||
|
@ -21,6 +21,7 @@ import {
|
||||
TRelicQuality
|
||||
} from "warframe-public-export-plus";
|
||||
import allIncarnons from "@/static/fixed_responses/allIncarnonList.json";
|
||||
import varzia from "@/static/fixed_responses/worldState/varzia.json";
|
||||
|
||||
interface ListedItem {
|
||||
uniqueName: string;
|
||||
@ -55,6 +56,7 @@ interface ItemLists {
|
||||
EvolutionProgress: ListedItem[];
|
||||
mods: ListedItem[];
|
||||
Boosters: ListedItem[];
|
||||
VarziaOffers: ListedItem[];
|
||||
//circuitGameModes: ListedItem[];
|
||||
}
|
||||
|
||||
@ -91,7 +93,8 @@ const getItemListsController: RequestHandler = (req, response) => {
|
||||
KubrowPets: [],
|
||||
EvolutionProgress: [],
|
||||
mods: [],
|
||||
Boosters: []
|
||||
Boosters: [],
|
||||
VarziaOffers: []
|
||||
/*circuitGameModes: [
|
||||
{
|
||||
uniqueName: "Survival",
|
||||
@ -338,6 +341,13 @@ const getItemListsController: RequestHandler = (req, response) => {
|
||||
});
|
||||
}
|
||||
|
||||
for (const item of Object.values(varzia.primeDualPacks)) {
|
||||
res.VarziaOffers.push({
|
||||
uniqueName: item.ItemType,
|
||||
name: getString(getItemName(item.ItemType) || "", lang)
|
||||
});
|
||||
}
|
||||
|
||||
response.json(res);
|
||||
};
|
||||
|
||||
|
@ -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");
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { IAccountCreation } from "@/src/types/customTypes";
|
||||
import { IDatabaseAccountRequiredFields } from "@/src/types/loginTypes";
|
||||
import crypto from "crypto";
|
||||
import { isString, parseEmail, parseString } from "../general";
|
||||
import { isString, parseEmail, parseString } from "@/src/helpers/general";
|
||||
|
||||
const getWhirlpoolHash = (rawPassword: string): string => {
|
||||
const whirlpool = crypto.createHash("whirlpool");
|
||||
|
@ -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,4 +1,4 @@
|
||||
import { TEquipmentKey } from "../types/inventoryTypes/inventoryTypes";
|
||||
import { TEquipmentKey } from "@/src/types/inventoryTypes/inventoryTypes";
|
||||
|
||||
export const modularWeaponTypes: Record<string, TEquipmentKey> = {
|
||||
"/Lotus/Weapons/SolarisUnited/Primary/LotusModularPrimary": "LongGuns",
|
||||
|
@ -1,12 +1,9 @@
|
||||
import { ExportRegions, ExportWarframes } from "warframe-public-export-plus";
|
||||
import { IInfNode, TNemesisFaction } from "@/src/types/inventoryTypes/inventoryTypes";
|
||||
import { 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";
|
||||
import { generateRewardSeed, getRewardAtPercentage, SRng } from "@/src/services/rngService";
|
||||
import { TInventoryDatabaseDocument } from "@/src/models/inventoryModels/inventoryModel";
|
||||
import { IOid } from "@/src/types/commonTypes";
|
||||
import { isArchwingMission } from "@/src/services/worldStateService";
|
||||
|
||||
type TInnateDamageTag =
|
||||
| "InnateElectricityDamage"
|
||||
@ -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!;
|
||||
};
|
||||
|
@ -5,8 +5,8 @@ import { getRandomWeightedReward, IRngResult } from "@/src/services/rngService";
|
||||
import { logger } from "@/src/utils/logger";
|
||||
import { addMiscItems, combineInventoryChanges } from "@/src/services/inventoryService";
|
||||
import { handleStoreItemAcquisition } from "@/src/services/purchaseService";
|
||||
import { IInventoryChanges } from "../types/purchaseTypes";
|
||||
import { config } from "../services/configService";
|
||||
import { IInventoryChanges } from "@/src/types/purchaseTypes";
|
||||
import { config } from "@/src/services/configService";
|
||||
|
||||
export const crackRelic = async (
|
||||
inventory: TInventoryDatabaseDocument,
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { IUpgrade } from "warframe-public-export-plus";
|
||||
import { getRandomElement, getRandomInt, getRandomReward } from "../services/rngService";
|
||||
import { getRandomElement, getRandomInt, getRandomReward } from "@/src/services/rngService";
|
||||
|
||||
export type RivenFingerprint = IVeiledRivenFingerprint | IUnveiledRivenFingerprint;
|
||||
|
||||
|
@ -19,10 +19,10 @@ logger.info("Starting up...");
|
||||
// Proceed with normal startup: bring up config watcher service, validate config, connect to MongoDB, and finally start listening for HTTP.
|
||||
import mongoose from "mongoose";
|
||||
import { JSONStringify } from "json-with-bigint";
|
||||
import { startWebServer } from "./services/webService";
|
||||
import { startWebServer } from "@/src/services/webService";
|
||||
|
||||
import { syncConfigWithDatabase, validateConfig } from "@/src/services/configWatcherService";
|
||||
import { updateWorldStateCollections } from "./services/worldStateService";
|
||||
import { updateWorldStateCollections } from "@/src/services/worldStateService";
|
||||
|
||||
// Patch JSON.stringify to work flawlessly with Bigints.
|
||||
JSON.stringify = JSONStringify;
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { NextFunction, Request, Response } from "express";
|
||||
import { logger } from "../utils/logger";
|
||||
import { logger } from "@/src/utils/logger";
|
||||
|
||||
export const errorHandler = (err: Error, req: Request, res: Response, _next: NextFunction): void => {
|
||||
if (err.message == "Invalid accountId-nonce pair") {
|
||||
|
25
src/models/commonModel.ts
Normal file
25
src/models/commonModel.ts
Normal file
@ -0,0 +1,25 @@
|
||||
import { Schema } from "mongoose";
|
||||
import { IColor, IShipCustomization } from "@/src/types/inventoryTypes/commonInventoryTypes";
|
||||
|
||||
export const colorSchema = new Schema<IColor>(
|
||||
{
|
||||
t0: Number,
|
||||
t1: Number,
|
||||
t2: Number,
|
||||
t3: Number,
|
||||
en: Number,
|
||||
e1: Number,
|
||||
m0: Number,
|
||||
m1: Number
|
||||
},
|
||||
{ _id: false }
|
||||
);
|
||||
|
||||
export const shipCustomizationSchema = new Schema<IShipCustomization>(
|
||||
{
|
||||
SkinFlavourItem: String,
|
||||
Colors: colorSchema,
|
||||
ShipAttachments: { HOOD_ORNAMENT: String }
|
||||
},
|
||||
{ _id: false }
|
||||
);
|
@ -17,8 +17,8 @@ import {
|
||||
GuildPermission
|
||||
} from "@/src/types/guildTypes";
|
||||
import { Document, Model, model, Schema, Types } from "mongoose";
|
||||
import { fusionTreasuresSchema, typeCountSchema } from "./inventoryModels/inventoryModel";
|
||||
import { pictureFrameInfoSchema } from "./personalRoomsModel";
|
||||
import { fusionTreasuresSchema, typeCountSchema } from "@/src/models/inventoryModels/inventoryModel";
|
||||
import { pictureFrameInfoSchema } from "@/src/models/personalRoomsModel";
|
||||
|
||||
const dojoDecoSchema = new Schema<IDojoDecoDatabase>({
|
||||
Type: String,
|
||||
|
@ -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,25 +37,15 @@ import {
|
||||
IEvolutionProgress,
|
||||
IEndlessXpProgressDatabase,
|
||||
IEndlessXpProgressClient,
|
||||
ICrewShipCustomization,
|
||||
ICrewShipWeapon,
|
||||
ICrewShipWeaponEmplacements,
|
||||
IShipExterior,
|
||||
IHelminthFoodRecord,
|
||||
ICrewShipMembersDatabase,
|
||||
IDialogueHistoryDatabase,
|
||||
IDialogueDatabase,
|
||||
IDialogueGift,
|
||||
ICompletedDialogue,
|
||||
IDialogueClient,
|
||||
IUpgradeDatabase,
|
||||
ICrewShipMemberDatabase,
|
||||
ICrewShipMemberClient,
|
||||
TEquipmentKey,
|
||||
equipmentKeys,
|
||||
IKubrowPetDetailsDatabase,
|
||||
ITraits,
|
||||
IKubrowPetDetailsClient,
|
||||
IKubrowPetEggDatabase,
|
||||
IKubrowPetEggClient,
|
||||
ICustomMarkers,
|
||||
@ -96,27 +84,39 @@ import {
|
||||
IInvasionProgressClient,
|
||||
IAccolades,
|
||||
IHubNpcCustomization,
|
||||
ILotusCustomization,
|
||||
IEndlessXpReward,
|
||||
IPersonalGoalProgressDatabase,
|
||||
IPersonalGoalProgressClient,
|
||||
IKubrowPetPrintClient,
|
||||
IKubrowPetPrintDatabase
|
||||
} from "../../types/inventoryTypes/inventoryTypes";
|
||||
import { IOid } from "../../types/commonTypes";
|
||||
} from "@/src/types/inventoryTypes/inventoryTypes";
|
||||
import { IOid, ITypeCount } from "@/src/types/commonTypes";
|
||||
import {
|
||||
IAbilityOverride,
|
||||
IColor,
|
||||
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 { EquipmentSelectionSchema, oidSchema } from "@/src/models/inventoryModels/loadoutModel";
|
||||
import { ICountedStoreItem } from "warframe-public-export-plus";
|
||||
import { colorSchema, shipCustomizationSchema } from "@/src/models/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 });
|
||||
|
||||
@ -166,20 +166,6 @@ const abilityOverrideSchema = new Schema<IAbilityOverride>(
|
||||
{ _id: false }
|
||||
);
|
||||
|
||||
export const colorSchema = new Schema<IColor>(
|
||||
{
|
||||
t0: Number,
|
||||
t1: Number,
|
||||
t2: Number,
|
||||
t3: Number,
|
||||
en: Number,
|
||||
e1: Number,
|
||||
m0: Number,
|
||||
m1: Number
|
||||
},
|
||||
{ _id: false }
|
||||
);
|
||||
|
||||
const operatorConfigSchema = new Schema<IOperatorConfigDatabase>(
|
||||
{
|
||||
Skins: [String],
|
||||
@ -896,18 +882,9 @@ const crewShipWeaponSchema = new Schema<ICrewShipWeapon>(
|
||||
{ _id: false }
|
||||
);
|
||||
|
||||
const shipExteriorSchema = new Schema<IShipExterior>(
|
||||
{
|
||||
SkinFlavourItem: String,
|
||||
Colors: colorSchema,
|
||||
ShipAttachments: { HOOD_ORNAMENT: String }
|
||||
},
|
||||
{ _id: false }
|
||||
);
|
||||
|
||||
const crewShipCustomizationSchema = new Schema<ICrewShipCustomization>(
|
||||
{
|
||||
CrewshipInterior: shipExteriorSchema
|
||||
CrewshipInterior: shipCustomizationSchema
|
||||
},
|
||||
{ _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";
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { Document, model, Schema, Types } from "mongoose";
|
||||
import { ILeaderboardEntryDatabase } from "../types/leaderboardTypes";
|
||||
import { ILeaderboardEntryDatabase } from "@/src/types/leaderboardTypes";
|
||||
|
||||
const leaderboardEntrySchema = new Schema<ILeaderboardEntryDatabase>(
|
||||
{
|
||||
|
@ -1,19 +1,22 @@
|
||||
import { toMongoDate, toOid } from "@/src/helpers/inventoryHelpers";
|
||||
import { colorSchema } from "@/src/models/inventoryModels/inventoryModel";
|
||||
import { IOrbiter, IPersonalRoomsDatabase, PersonalRoomsModelType } from "@/src/types/personalRoomsTypes";
|
||||
import {
|
||||
IApartmentDatabase,
|
||||
IFavouriteLoadoutDatabase,
|
||||
IGardeningDatabase,
|
||||
IPlacedDecosDatabase,
|
||||
IOrbiterClient,
|
||||
IOrbiterDatabase,
|
||||
IPersonalRoomsDatabase,
|
||||
IPictureFrameInfo,
|
||||
IPlacedDecosDatabase,
|
||||
IPlantClient,
|
||||
IPlantDatabase,
|
||||
IPlanterDatabase,
|
||||
IRoom,
|
||||
ITailorShopDatabase,
|
||||
IApartmentDatabase,
|
||||
IPlanterDatabase,
|
||||
IPlantDatabase,
|
||||
IPlantClient
|
||||
} from "@/src/types/shipTypes";
|
||||
PersonalRoomsModelType
|
||||
} from "@/src/types/personalRoomsTypes";
|
||||
import { Schema, Types, model } from "mongoose";
|
||||
import { colorSchema, shipCustomizationSchema } from "@/src/models/commonModel";
|
||||
|
||||
export const pictureFrameInfoSchema = new Schema<IPictureFrameInfo>(
|
||||
{
|
||||
@ -137,10 +140,11 @@ const apartmentDefault: IApartmentDatabase = {
|
||||
}
|
||||
};
|
||||
|
||||
const orbiterSchema = new Schema<IOrbiter>(
|
||||
const orbiterSchema = new Schema<IOrbiterDatabase>(
|
||||
{
|
||||
Features: [String],
|
||||
Rooms: [roomSchema],
|
||||
ShipInterior: shipCustomizationSchema,
|
||||
VignetteFish: { type: [String], default: undefined },
|
||||
FavouriteLoadoutId: Schema.Types.ObjectId,
|
||||
Wallpaper: String,
|
||||
@ -150,7 +154,18 @@ const orbiterSchema = new Schema<IOrbiter>(
|
||||
},
|
||||
{ _id: false }
|
||||
);
|
||||
const orbiterDefault: IOrbiter = {
|
||||
orbiterSchema.set("toJSON", {
|
||||
virtuals: true,
|
||||
transform(_doc, obj) {
|
||||
const db = obj as IOrbiterDatabase;
|
||||
const client = obj as IOrbiterClient;
|
||||
|
||||
if (db.FavouriteLoadoutId) {
|
||||
client.FavouriteLoadoutId = toOid(db.FavouriteLoadoutId);
|
||||
}
|
||||
}
|
||||
});
|
||||
const orbiterDefault: IOrbiterDatabase = {
|
||||
Features: ["/Lotus/Types/Items/ShipFeatureItems/EarthNavigationFeatureItem"], //TODO: potentially remove after missionstarting gear
|
||||
Rooms: [
|
||||
{ Name: "AlchemyRoom", MaxCapacity: 1600 },
|
||||
@ -197,7 +212,6 @@ const tailorShopDefault: ITailorShopDatabase = {
|
||||
export const personalRoomsSchema = new Schema<IPersonalRoomsDatabase>({
|
||||
personalRoomsOwnerId: Schema.Types.ObjectId,
|
||||
activeShipId: Schema.Types.ObjectId,
|
||||
ShipInteriorColors: colorSchema,
|
||||
Ship: { type: orbiterSchema, default: orbiterDefault },
|
||||
Apartment: { type: apartmentSchema, default: apartmentDefault },
|
||||
TailorShop: { type: tailorShopSchema, default: tailorShopDefault }
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { Document, Schema, Types, model } from "mongoose";
|
||||
import { IShipDatabase } from "../types/shipTypes";
|
||||
import { IShipDatabase } from "@/src/types/shipTypes";
|
||||
import { toOid } from "@/src/helpers/inventoryHelpers";
|
||||
import { colorSchema } from "@/src/models/inventoryModels/inventoryModel";
|
||||
import { colorSchema } from "@/src/models/commonModel";
|
||||
import { IShipInventory } from "@/src/types/inventoryTypes/inventoryTypes";
|
||||
|
||||
const shipSchema = new Schema<IShipDatabase>(
|
||||
|
@ -89,6 +89,8 @@ export interface IConfig {
|
||||
allTheFissures?: string;
|
||||
circuitGameModes?: string[];
|
||||
darvoStockMultiplier?: number;
|
||||
varziaOverride?: string;
|
||||
varziaFullyStocked?: boolean;
|
||||
};
|
||||
dev?: {
|
||||
keepVendorsExpired?: boolean;
|
||||
|
@ -1,9 +1,11 @@
|
||||
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 { Inbox } from "../models/inboxModel";
|
||||
import { logger } from "@/src/utils/logger";
|
||||
import { config, configPath, loadConfig } from "@/src/services/configService";
|
||||
import { getWebPorts, startWebServer, stopWebServer } from "@/src/services/webService";
|
||||
import { sendWsBroadcast } from "@/src/services/wsService";
|
||||
import { Inbox } from "@/src/models/inboxModel";
|
||||
import varzia from "@/static/fixed_responses/worldState/varzia.json";
|
||||
|
||||
let amnesia = false;
|
||||
chokidar.watch(configPath).on("change", () => {
|
||||
@ -57,6 +59,13 @@ export const validateConfig = (): void => {
|
||||
config.worldState.galleonOfGhouls = 0;
|
||||
modified = true;
|
||||
}
|
||||
if (
|
||||
config.worldState?.varziaOverride &&
|
||||
!varzia.primeDualPacks.some(p => p.ItemType === config.worldState?.varziaOverride)
|
||||
) {
|
||||
config.worldState.varziaOverride = "";
|
||||
modified = true;
|
||||
}
|
||||
if (modified) {
|
||||
logger.info(`Updating config file to fix some issues with it.`);
|
||||
void saveConfig();
|
||||
|
@ -1,10 +1,10 @@
|
||||
import { IFriendInfo } from "../types/friendTypes";
|
||||
import { getInventory } from "./inventoryService";
|
||||
import { config } from "./configService";
|
||||
import { Account } from "../models/loginModel";
|
||||
import { IFriendInfo } from "@/src/types/friendTypes";
|
||||
import { getInventory } from "@/src/services/inventoryService";
|
||||
import { config } from "@/src/services/configService";
|
||||
import { Account } from "@/src/models/loginModel";
|
||||
import { Types } from "mongoose";
|
||||
import { Friendship } from "../models/friendModel";
|
||||
import { fromOid, toMongoDate } from "../helpers/inventoryHelpers";
|
||||
import { Friendship } from "@/src/models/friendModel";
|
||||
import { fromOid, toMongoDate } from "@/src/helpers/inventoryHelpers";
|
||||
|
||||
export const addAccountDataToFriendInfo = async (info: IFriendInfo): Promise<void> => {
|
||||
const account = (await Account.findById(fromOid(info._id), "DisplayName LastLogin"))!;
|
||||
|
@ -22,16 +22,17 @@ import {
|
||||
import { toMongoDate, toOid, toOid2 } from "@/src/helpers/inventoryHelpers";
|
||||
import { Types } from "mongoose";
|
||||
import { ExportDojoRecipes, ExportResources, IDojoBuild, IDojoResearch } from "warframe-public-export-plus";
|
||||
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 { IInventoryChanges } from "../types/purchaseTypes";
|
||||
import { parallelForeach } from "../utils/async-utils";
|
||||
import { logger } from "@/src/utils/logger";
|
||||
import { config } from "@/src/services/configService";
|
||||
import { getRandomInt } from "@/src/services/rngService";
|
||||
import { Inbox } from "@/src/models/inboxModel";
|
||||
import { IFusionTreasure } from "@/src/types/inventoryTypes/inventoryTypes";
|
||||
import { IInventoryChanges } from "@/src/types/purchaseTypes";
|
||||
import { parallelForeach } from "@/src/utils/async-utils";
|
||||
import allDecoRecipes from "@/static/fixed_responses/allDecoRecipes.json";
|
||||
import { createMessage } from "./inboxService";
|
||||
import { addAccountDataToFriendInfo, addInventoryDataToFriendInfo } from "./friendService";
|
||||
import { createMessage } from "@/src/services/inboxService";
|
||||
import { addAccountDataToFriendInfo, addInventoryDataToFriendInfo } from "@/src/services/friendService";
|
||||
import { ITypeCount } from "@/src/types/commonTypes";
|
||||
|
||||
export const getGuildForRequest = async (req: Request): Promise<TGuildDatabaseDocument> => {
|
||||
const accountId = await getAccountIdForRequest(req);
|
||||
|
@ -1,18 +1,12 @@
|
||||
import { Types } from "mongoose";
|
||||
import {
|
||||
IEquipmentClient,
|
||||
IEquipmentDatabase,
|
||||
IItemConfig,
|
||||
IOperatorConfigClient,
|
||||
IOperatorConfigDatabase
|
||||
} from "../types/inventoryTypes/commonInventoryTypes";
|
||||
import { IMongoDate } from "../types/commonTypes";
|
||||
} from "@/src/types/inventoryTypes/commonInventoryTypes";
|
||||
import { IMongoDate } from "@/src/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,
|
||||
@ -35,10 +25,25 @@ import {
|
||||
IUpgradeDatabase,
|
||||
IWeaponSkinClient,
|
||||
IWeaponSkinDatabase
|
||||
} from "../types/inventoryTypes/inventoryTypes";
|
||||
import { TInventoryDatabaseDocument } from "../models/inventoryModels/inventoryModel";
|
||||
import { ILoadoutConfigDatabase, ILoadoutDatabase } from "../types/saveLoadoutTypes";
|
||||
import { slotNames } from "../types/purchaseTypes";
|
||||
} from "@/src/types/inventoryTypes/inventoryTypes";
|
||||
import { TInventoryDatabaseDocument } from "@/src/models/inventoryModels/inventoryModel";
|
||||
import {
|
||||
ILoadoutConfigClient,
|
||||
ILoadoutConfigDatabase,
|
||||
ILoadoutDatabase,
|
||||
ILoadOutPresets
|
||||
} from "@/src/types/saveLoadoutTypes";
|
||||
import { slotNames } from "@/src/types/purchaseTypes";
|
||||
import {
|
||||
ICrewShipMemberClient,
|
||||
ICrewShipMemberDatabase,
|
||||
ICrewShipMembersClient,
|
||||
ICrewShipMembersDatabase,
|
||||
IEquipmentClient,
|
||||
IEquipmentDatabase,
|
||||
IKubrowPetDetailsClient,
|
||||
IKubrowPetDetailsDatabase
|
||||
} from "@/src/types/equipmentTypes";
|
||||
|
||||
const convertDate = (value: IMongoDate): Date => {
|
||||
return new Date(parseInt(value.$date.$numberLong));
|
||||
|
@ -2,8 +2,8 @@ import { IMessageDatabase, Inbox } from "@/src/models/inboxModel";
|
||||
import { getAccountForRequest } from "@/src/services/loginService";
|
||||
import { HydratedDocument, Types } from "mongoose";
|
||||
import { Request } from "express";
|
||||
import { unixTimesInMs } from "../constants/timeConstants";
|
||||
import { config } from "./configService";
|
||||
import { unixTimesInMs } from "@/src/constants/timeConstants";
|
||||
import { config } from "@/src/services/configService";
|
||||
|
||||
export const getAllMessagesSorted = async (accountId: string): Promise<HydratedDocument<IMessageDatabase>[]> => {
|
||||
const inbox = await Inbox.find({ ownerId: accountId }).sort({ date: -1 });
|
||||
|
@ -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 { addRecipes } from "./inventoryService";
|
||||
import { config } from "./configService";
|
||||
import { TInventoryDatabaseDocument } from "@/src/models/inventoryModels/inventoryModel";
|
||||
import { IInfestedFoundryClient, IInfestedFoundryDatabase } from "@/src/types/inventoryTypes/inventoryTypes";
|
||||
import { addRecipes } from "@/src/services/inventoryService";
|
||||
import { config } from "@/src/services/configService";
|
||||
import { ITypeCount } from "@/src/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,25 +21,17 @@ import {
|
||||
TPartialStartingGear,
|
||||
ILoreFragmentScan,
|
||||
ICrewMemberClient,
|
||||
Status,
|
||||
IKubrowPetDetailsDatabase,
|
||||
ITraits,
|
||||
ICalendarProgress,
|
||||
INemesisWeaponTargetFingerprint,
|
||||
INemesisPetTargetFingerprint,
|
||||
IDialogueDatabase,
|
||||
IKubrowPetPrintClient
|
||||
} from "@/src/types/inventoryTypes/inventoryTypes";
|
||||
import { IGenericUpdate, IUpdateNodeIntrosResponse } from "../types/genericUpdate";
|
||||
import { IKeyChainRequest, IMissionInventoryUpdateRequest } from "../types/requestTypes";
|
||||
import { IGenericUpdate, IUpdateNodeIntrosResponse } from "@/src/types/genericUpdate";
|
||||
import { IKeyChainRequest, IMissionInventoryUpdateRequest } from "@/src/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 "@/src/types/inventoryTypes/commonInventoryTypes";
|
||||
import {
|
||||
ExportArcanes,
|
||||
ExportBoosters,
|
||||
@ -69,7 +59,7 @@ import {
|
||||
ISentinel,
|
||||
TStandingLimitBin
|
||||
} from "warframe-public-export-plus";
|
||||
import { createShip } from "./shipService";
|
||||
import { createShip } from "@/src/services/shipService";
|
||||
import {
|
||||
catbrowDetails,
|
||||
fromMongoDate,
|
||||
@ -78,19 +68,34 @@ import {
|
||||
kubrowFurPatternsWeights,
|
||||
kubrowWeights,
|
||||
toOid
|
||||
} from "../helpers/inventoryHelpers";
|
||||
} from "@/src/helpers/inventoryHelpers";
|
||||
import { addQuestKey, completeQuest } from "@/src/services/questService";
|
||||
import { handleBundleAcqusition } from "./purchaseService";
|
||||
import { handleBundleAcqusition } from "@/src/services/purchaseService";
|
||||
import libraryDailyTasks from "@/static/fixed_responses/libraryDailyTasks.json";
|
||||
import { getRandomElement, getRandomInt, getRandomWeightedReward, SRng } from "./rngService";
|
||||
import { createMessage, IMessageCreationTemplate } from "./inboxService";
|
||||
import {
|
||||
generateRewardSeed,
|
||||
getRandomElement,
|
||||
getRandomInt,
|
||||
getRandomWeightedReward,
|
||||
SRng
|
||||
} from "@/src/services/rngService";
|
||||
import { createMessage, IMessageCreationTemplate } from "@/src/services/inboxService";
|
||||
import { getMaxStanding, getMinStanding } from "@/src/helpers/syndicateStandingHelper";
|
||||
import { getNightwaveSyndicateTag, getWorldState } from "./worldStateService";
|
||||
import { getNightwaveSyndicateTag, getWorldState } from "@/src/services/worldStateService";
|
||||
import { ICalendarSeason } from "@/src/types/worldStateTypes";
|
||||
import { generateNemesisProfile, INemesisProfile } from "../helpers/nemesisHelpers";
|
||||
import { TAccountDocument } from "./loginService";
|
||||
import { unixTimesInMs } from "../constants/timeConstants";
|
||||
import { addString } from "../helpers/stringHelpers";
|
||||
import { generateNemesisProfile, INemesisProfile } from "@/src/helpers/nemesisHelpers";
|
||||
import { TAccountDocument } from "@/src/services/loginService";
|
||||
import { unixTimesInMs } from "@/src/constants/timeConstants";
|
||||
import { addString } from "@/src/helpers/stringHelpers";
|
||||
import {
|
||||
EquipmentFeatures,
|
||||
IEquipmentClient,
|
||||
IEquipmentDatabase,
|
||||
IKubrowPetDetailsDatabase,
|
||||
ITraits,
|
||||
Status
|
||||
} from "@/src/types/equipmentTypes";
|
||||
import { ITypeCount } from "@/src/types/commonTypes";
|
||||
|
||||
export const createInventory = async (
|
||||
accountOwnerId: Types.ObjectId,
|
||||
@ -132,17 +137,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",
|
||||
@ -1395,7 +1389,11 @@ export const addSkin = (
|
||||
if (inventory.WeaponSkins.some(x => x.ItemType == typeName)) {
|
||||
logger.debug(`refusing to add WeaponSkin ${typeName} because account already owns it`);
|
||||
} else {
|
||||
const index = inventory.WeaponSkins.push({ ItemType: typeName, IsNew: true }) - 1;
|
||||
const index =
|
||||
inventory.WeaponSkins.push({
|
||||
ItemType: typeName,
|
||||
IsNew: typeName.startsWith("/Lotus/Upgrades/Skins/RailJack/") ? undefined : true // railjack skins are incompatible with this flag
|
||||
}) - 1;
|
||||
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
||||
inventoryChanges.WeaponSkins ??= [];
|
||||
(inventoryChanges.WeaponSkins as IWeaponSkinClient[]).push(
|
||||
|
@ -17,6 +17,7 @@ import {
|
||||
dict_zh,
|
||||
ExportArcanes,
|
||||
ExportBoosters,
|
||||
ExportBundles,
|
||||
ExportCustoms,
|
||||
ExportDrones,
|
||||
ExportGear,
|
||||
@ -32,7 +33,7 @@ import {
|
||||
IRecipe,
|
||||
TReward
|
||||
} from "warframe-public-export-plus";
|
||||
import { IMessage } from "../models/inboxModel";
|
||||
import { IMessage } from "@/src/models/inboxModel";
|
||||
|
||||
export type WeaponTypeInternal =
|
||||
| "LongGuns"
|
||||
@ -117,6 +118,9 @@ export const getItemName = (uniqueName: string): string | undefined => {
|
||||
if (uniqueName in ExportArcanes) {
|
||||
return ExportArcanes[uniqueName].name;
|
||||
}
|
||||
if (uniqueName in ExportBundles) {
|
||||
return ExportBundles[uniqueName].name;
|
||||
}
|
||||
if (uniqueName in ExportCustoms) {
|
||||
return ExportCustoms[uniqueName].name;
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { Guild } from "../models/guildModel";
|
||||
import { Leaderboard, TLeaderboardEntryDocument } from "../models/leaderboardModel";
|
||||
import { ILeaderboardEntryClient } from "../types/leaderboardTypes";
|
||||
import { Guild } from "@/src/models/guildModel";
|
||||
import { Leaderboard, TLeaderboardEntryDocument } from "@/src/models/leaderboardModel";
|
||||
import { ILeaderboardEntryClient } from "@/src/types/leaderboardTypes";
|
||||
|
||||
export const submitLeaderboardScore = async (
|
||||
schedule: "weekly" | "daily",
|
||||
|
@ -1,10 +1,10 @@
|
||||
import randomRewards from "@/static/fixed_responses/loginRewards/randomRewards.json";
|
||||
import { IInventoryChanges } from "../types/purchaseTypes";
|
||||
import { TAccountDocument } from "./loginService";
|
||||
import { mixSeeds, SRng } from "./rngService";
|
||||
import { TInventoryDatabaseDocument } from "../models/inventoryModels/inventoryModel";
|
||||
import { addBooster, updateCurrency } from "./inventoryService";
|
||||
import { handleStoreItemAcquisition } from "./purchaseService";
|
||||
import { IInventoryChanges } from "@/src/types/purchaseTypes";
|
||||
import { TAccountDocument } from "@/src/services/loginService";
|
||||
import { mixSeeds, SRng } from "@/src/services/rngService";
|
||||
import { TInventoryDatabaseDocument } from "@/src/models/inventoryModels/inventoryModel";
|
||||
import { addBooster, updateCurrency } from "@/src/services/inventoryService";
|
||||
import { handleStoreItemAcquisition } from "@/src/services/purchaseService";
|
||||
import {
|
||||
ExportBoosterPacks,
|
||||
ExportBoosters,
|
||||
@ -12,7 +12,7 @@ import {
|
||||
ExportWarframes,
|
||||
ExportWeapons
|
||||
} from "warframe-public-export-plus";
|
||||
import { toStoreItem } from "./itemDataService";
|
||||
import { toStoreItem } from "@/src/services/itemDataService";
|
||||
|
||||
export interface ILoginRewardsReponse {
|
||||
DailyTributeInfo: {
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { Account } from "@/src/models/loginModel";
|
||||
import { createInventory } from "@/src/services/inventoryService";
|
||||
import { IDatabaseAccountJson, IDatabaseAccountRequiredFields } from "@/src/types/loginTypes";
|
||||
import { createShip } from "./shipService";
|
||||
import { createShip } from "@/src/services/shipService";
|
||||
import { Document, Types } from "mongoose";
|
||||
import { Loadout } from "@/src/models/inventoryModels/loadoutModel";
|
||||
import { PersonalRooms } from "@/src/models/personalRoomsModel";
|
||||
|
@ -8,10 +8,10 @@ import {
|
||||
IRegion,
|
||||
IReward
|
||||
} from "warframe-public-export-plus";
|
||||
import { IMissionInventoryUpdateRequest, IRewardInfo } from "../types/requestTypes";
|
||||
import { IMissionInventoryUpdateRequest, IRewardInfo } from "@/src/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,11 +47,10 @@ 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 { handleStoreItemAcquisition } from "@/src/services/purchaseService";
|
||||
import { IMissionCredits, IMissionReward } from "@/src/types/missionTypes";
|
||||
import { crackRelic } from "@/src/helpers/relicHelper";
|
||||
import { createMessage } from "./inboxService";
|
||||
import { createMessage } from "@/src/services/inboxService";
|
||||
import kuriaMessage50 from "@/static/fixed_responses/kuriaMessages/fiftyPercent.json";
|
||||
import kuriaMessage75 from "@/static/fixed_responses/kuriaMessages/seventyFivePercent.json";
|
||||
import kuriaMessage100 from "@/static/fixed_responses/kuriaMessages/oneHundredPercent.json";
|
||||
@ -65,8 +63,8 @@ import {
|
||||
getNemesisManifest,
|
||||
getNemesisPasscode
|
||||
} from "@/src/helpers/nemesisHelpers";
|
||||
import { Loadout } from "../models/inventoryModels/loadoutModel";
|
||||
import { ILoadoutConfigDatabase } from "../types/saveLoadoutTypes";
|
||||
import { Loadout } from "@/src/models/inventoryModels/loadoutModel";
|
||||
import { ILoadoutConfigDatabase } from "@/src/types/saveLoadoutTypes";
|
||||
import {
|
||||
getLiteSortie,
|
||||
getSortie,
|
||||
@ -75,12 +73,14 @@ import {
|
||||
idToDay,
|
||||
idToWeek,
|
||||
pushClassicBounties
|
||||
} from "./worldStateService";
|
||||
import { config } from "./configService";
|
||||
} from "@/src/services/worldStateService";
|
||||
import { config } from "@/src/services/configService";
|
||||
import libraryDailyTasks from "@/static/fixed_responses/libraryDailyTasks.json";
|
||||
import { ISyndicateMissionInfo } from "../types/worldStateTypes";
|
||||
import { fromOid } from "../helpers/inventoryHelpers";
|
||||
import { TAccountDocument } from "./loginService";
|
||||
import { ISyndicateMissionInfo } from "@/src/types/worldStateTypes";
|
||||
import { fromOid } from "@/src/helpers/inventoryHelpers";
|
||||
import { TAccountDocument } from "@/src/services/loginService";
|
||||
import { ITypeCount } from "@/src/types/commonTypes";
|
||||
import { IEquipmentClient } from "@/src/types/equipmentTypes";
|
||||
|
||||
const getRotations = (rewardInfo: IRewardInfo, tierOverride?: number): number[] => {
|
||||
// For Spy missions, e.g. 3 vaults cracked = A, B, C
|
||||
|
@ -1,8 +1,7 @@
|
||||
import { PersonalRooms } from "@/src/models/personalRoomsModel";
|
||||
import { addItem, getInventory } from "@/src/services/inventoryService";
|
||||
import { TPersonalRoomsDatabaseDocument } from "../types/personalRoomsTypes";
|
||||
import { IGardeningDatabase } from "../types/shipTypes";
|
||||
import { getRandomElement } from "./rngService";
|
||||
import { IGardeningDatabase, TPersonalRoomsDatabaseDocument } from "@/src/types/personalRoomsTypes";
|
||||
import { getRandomElement } from "@/src/services/rngService";
|
||||
|
||||
export const getPersonalRooms = async (
|
||||
accountId: string,
|
||||
|
@ -20,8 +20,7 @@ import {
|
||||
IPurchaseParams
|
||||
} from "@/src/types/purchaseTypes";
|
||||
import { logger } from "@/src/utils/logger";
|
||||
import { getWorldState } from "./worldStateService";
|
||||
import staticWorldState from "@/static/fixed_responses/worldState/worldState.json";
|
||||
import { getWorldState } from "@/src/services/worldStateService";
|
||||
import {
|
||||
ExportBoosterPacks,
|
||||
ExportBoosters,
|
||||
@ -33,11 +32,11 @@ import {
|
||||
ExportVendors,
|
||||
TRarity
|
||||
} from "warframe-public-export-plus";
|
||||
import { config } from "./configService";
|
||||
import { TInventoryDatabaseDocument } from "../models/inventoryModels/inventoryModel";
|
||||
import { fromStoreItem, toStoreItem } from "./itemDataService";
|
||||
import { DailyDeal } from "../models/worldStateModel";
|
||||
import { fromMongoDate, toMongoDate } from "../helpers/inventoryHelpers";
|
||||
import { config } from "@/src/services/configService";
|
||||
import { TInventoryDatabaseDocument } from "@/src/models/inventoryModels/inventoryModel";
|
||||
import { fromStoreItem, toStoreItem } from "@/src/services/itemDataService";
|
||||
import { DailyDeal } from "@/src/models/worldStateModel";
|
||||
import { fromMongoDate, toMongoDate } from "@/src/helpers/inventoryHelpers";
|
||||
|
||||
export const getStoreItemCategory = (storeItem: string): string => {
|
||||
const storeItemString = getSubstringFromKeyword(storeItem, "StoreItems/");
|
||||
@ -305,14 +304,15 @@ export const handlePurchase = async (
|
||||
}
|
||||
break;
|
||||
case PurchaseSource.PrimeVaultTrader: {
|
||||
if (purchaseRequest.PurchaseParams.SourceId! != staticWorldState.PrimeVaultTraders[0]._id.$oid) {
|
||||
const worldState = getWorldState();
|
||||
if (purchaseRequest.PurchaseParams.SourceId! != worldState.PrimeVaultTraders[0]._id.$oid) {
|
||||
throw new Error("invalid request source");
|
||||
}
|
||||
const offer =
|
||||
staticWorldState.PrimeVaultTraders[0].Manifest.find(
|
||||
worldState.PrimeVaultTraders[0].Manifest.find(
|
||||
x => x.ItemType == purchaseRequest.PurchaseParams.StoreItem
|
||||
) ??
|
||||
staticWorldState.PrimeVaultTraders[0].EvergreenManifest.find(
|
||||
worldState.PrimeVaultTraders[0].EvergreenManifest.find(
|
||||
x => x.ItemType == purchaseRequest.PurchaseParams.StoreItem
|
||||
);
|
||||
if (offer) {
|
||||
|
@ -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 { addFixedLevelRewards } from "@/src/services/missionInventoryUpdateService";
|
||||
import { IInventoryChanges } from "@/src/types/purchaseTypes";
|
||||
import questCompletionItems from "@/static/fixed_responses/questCompletionRewards.json";
|
||||
import { ITypeCount } from "@/src/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
|
||||
|
@ -13,8 +13,8 @@ import { Types } from "mongoose";
|
||||
import { isEmptyObject } from "@/src/helpers/general";
|
||||
import { logger } from "@/src/utils/logger";
|
||||
import { equipmentKeys, TEquipmentKey } from "@/src/types/inventoryTypes/inventoryTypes";
|
||||
import { IItemConfig } from "../types/inventoryTypes/commonInventoryTypes";
|
||||
import { importCrewMemberId } from "./importService";
|
||||
import { IItemConfig } from "@/src/types/inventoryTypes/commonInventoryTypes";
|
||||
import { importCrewMemberId } from "@/src/services/importService";
|
||||
|
||||
//TODO: setup default items on account creation or like originally in giveStartingItems.php
|
||||
|
||||
@ -172,6 +172,16 @@ export const handleInventoryItemConfigChange = async (
|
||||
// seems always equal to the id of loadout config NORMAL[0], likely has no purpose and we're free to ignore it
|
||||
break;
|
||||
}
|
||||
case "ActiveCrewShip": {
|
||||
if (inventory.CrewShips.length != 1) {
|
||||
logger.warn(`saving railjack changes with broken inventory?`);
|
||||
} else if (!inventory.CrewShips[0]._id.equals(equipmentChanges.ActiveCrewShip.$oid)) {
|
||||
logger.warn(
|
||||
`client provided CrewShip id ${equipmentChanges.ActiveCrewShip.$oid} but id in inventory is ${inventory.CrewShips[0]._id.toString()}`
|
||||
);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
if (equipmentKeys.includes(equipmentName as TEquipmentKey)) {
|
||||
logger.debug(`general Item config saved of type ${equipmentName}`, {
|
||||
@ -221,7 +231,7 @@ export const handleInventoryItemConfigChange = async (
|
||||
}
|
||||
break;
|
||||
} else {
|
||||
logger.error(`loadout category not implemented, changes will be lost: ${equipmentName}`, {
|
||||
logger.warn(`unknown saveLoadout field: ${equipmentName}`, {
|
||||
config: equipment
|
||||
});
|
||||
}
|
||||
|
@ -6,7 +6,7 @@ import { mixSeeds, SRng } from "@/src/services/rngService";
|
||||
import { IItemManifest, IVendorInfo, IVendorManifest } from "@/src/types/vendorTypes";
|
||||
import { logger } from "@/src/utils/logger";
|
||||
import { ExportVendors, IRange, IVendor, IVendorOffer } from "warframe-public-export-plus";
|
||||
import { config } from "./configService";
|
||||
import { config } from "@/src/services/configService";
|
||||
|
||||
interface IGeneratableVendorInfo extends Omit<IVendorInfo, "ItemManifest" | "Expiry"> {
|
||||
cycleOffset?: number;
|
||||
@ -299,9 +299,12 @@ const generateVendorManifest = (
|
||||
? numUncountedOffers + numCountedOffers
|
||||
: manifest.numItems
|
||||
? numUncountedOffers +
|
||||
(useRng
|
||||
Math.min(
|
||||
Object.values(remainingItemCapacity).reduce((a, b) => a + b, 0),
|
||||
useRng
|
||||
? rng.randomInt(manifest.numItems.minValue, manifest.numItems.maxValue)
|
||||
: manifest.numItems.minValue)
|
||||
: manifest.numItems.minValue
|
||||
)
|
||||
: manifest.items.length;
|
||||
let i = 0;
|
||||
const rollableOffers = manifest.items.filter(x => x.probability !== undefined) as (Omit<
|
||||
@ -495,4 +498,13 @@ if (args.dev) {
|
||||
) {
|
||||
logger.warn(`self test failed for /Lotus/Types/Game/VendorManifests/Ostron/MaskSalesmanManifest`);
|
||||
}
|
||||
|
||||
// strange case where numItems is 5 even tho only 3 offers can possibly be generated
|
||||
const loid = getVendorManifestByTypeName(
|
||||
"/Lotus/Types/Game/VendorManifests/EntratiLabs/EntratiLabsCommisionsManifest",
|
||||
false
|
||||
)!.VendorInfo.ItemManifest;
|
||||
if (loid.length != 3) {
|
||||
logger.warn(`self test failed for /Lotus/Types/Game/VendorManifests/EntratiLabs/EntratiLabsCommisionsManifest`);
|
||||
}
|
||||
}
|
||||
|
@ -1,21 +1,22 @@
|
||||
import { getPersonalRooms } from "@/src/services/personalRoomsService";
|
||||
import { getShip } from "@/src/services/shipService";
|
||||
import {
|
||||
ISetPlacedDecoInfoRequest,
|
||||
ISetShipCustomizationsRequest,
|
||||
IShipDecorationsRequest,
|
||||
IShipDecorationsResponse,
|
||||
ISetPlacedDecoInfoRequest,
|
||||
TBootLocation
|
||||
} from "@/src/types/shipTypes";
|
||||
RoomsType,
|
||||
TBootLocation,
|
||||
TPersonalRoomsDatabaseDocument
|
||||
} from "@/src/types/personalRoomsTypes";
|
||||
import { logger } from "@/src/utils/logger";
|
||||
import { Types } from "mongoose";
|
||||
import { addFusionTreasures, addShipDecorations, getInventory } from "./inventoryService";
|
||||
import { config } from "./configService";
|
||||
import { Guild } from "../models/guildModel";
|
||||
import { hasGuildPermission } from "./guildService";
|
||||
import { GuildPermission } from "../types/guildTypes";
|
||||
import { addFusionTreasures, addShipDecorations, getInventory } from "@/src/services/inventoryService";
|
||||
import { config } from "@/src/services/configService";
|
||||
import { Guild } from "@/src/models/guildModel";
|
||||
import { hasGuildPermission } from "@/src/services/guildService";
|
||||
import { GuildPermission } from "@/src/types/guildTypes";
|
||||
import { ExportResources } from "warframe-public-export-plus";
|
||||
import { RoomsType, TPersonalRoomsDatabaseDocument } from "../types/personalRoomsTypes";
|
||||
|
||||
export const setShipCustomizations = async (
|
||||
accountId: string,
|
||||
@ -39,7 +40,7 @@ export const setShipCustomizations = async (
|
||||
personalRooms.TailorShop.LevelDecosVisible = shipCustomization.Customization.LevelDecosVisible;
|
||||
personalRooms.TailorShop.CustomJson = shipCustomization.Customization.CustomJson;
|
||||
} else {
|
||||
personalRooms.ShipInteriorColors = shipCustomization.Customization.Colors;
|
||||
personalRooms.Ship.ShipInterior = shipCustomization.Customization;
|
||||
}
|
||||
await personalRooms.save();
|
||||
}
|
||||
|
@ -10,7 +10,7 @@ import {
|
||||
} from "@/src/types/statTypes";
|
||||
import { logger } from "@/src/utils/logger";
|
||||
import { addEmailItem, getInventory } from "@/src/services/inventoryService";
|
||||
import { submitLeaderboardScore } from "./leaderboardService";
|
||||
import { submitLeaderboardScore } from "@/src/services/leaderboardService";
|
||||
|
||||
export const createStats = async (accountId: string): Promise<TStatsDatabaseDocument> => {
|
||||
const stats = new Stats({ accountOwnerId: accountId });
|
||||
|
@ -1,21 +1,15 @@
|
||||
import http from "http";
|
||||
import https from "https";
|
||||
import fs from "node:fs";
|
||||
import { config } from "./configService";
|
||||
import { logger } from "../utils/logger";
|
||||
import { app } from "../app";
|
||||
import { config } from "@/src/services/configService";
|
||||
import { logger } from "@/src/utils/logger";
|
||||
import { app } from "@/src/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 "@/src/services/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);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -1,5 +1,6 @@
|
||||
import staticWorldState from "@/static/fixed_responses/worldState/worldState.json";
|
||||
import baro from "@/static/fixed_responses/worldState/baro.json";
|
||||
import varzia from "@/static/fixed_responses/worldState/varzia.json";
|
||||
import fissureMissions from "@/static/fixed_responses/worldState/fissureMissions.json";
|
||||
import sortieTilesets from "@/static/fixed_responses/worldState/sortieTilesets.json";
|
||||
import sortieTilesetMissions from "@/static/fixed_responses/worldState/sortieTilesetMissions.json";
|
||||
@ -15,6 +16,8 @@ import {
|
||||
ICalendarEvent,
|
||||
ICalendarSeason,
|
||||
ILiteSortie,
|
||||
IPrimeVaultTrader,
|
||||
IPrimeVaultTraderOffer,
|
||||
ISeasonChallenge,
|
||||
ISortie,
|
||||
ISortieMission,
|
||||
@ -25,10 +28,10 @@ import {
|
||||
IVoidTraderOffer,
|
||||
IWorldState,
|
||||
TCircuitGameMode
|
||||
} from "../types/worldStateTypes";
|
||||
import { toMongoDate, toOid, version_compare } from "../helpers/inventoryHelpers";
|
||||
import { logger } from "../utils/logger";
|
||||
import { DailyDeal, Fissure } from "../models/worldStateModel";
|
||||
} from "@/src/types/worldStateTypes";
|
||||
import { toMongoDate, toOid, version_compare } from "@/src/helpers/inventoryHelpers";
|
||||
import { logger } from "@/src/utils/logger";
|
||||
import { DailyDeal, Fissure } from "@/src/models/worldStateModel";
|
||||
|
||||
const sortieBosses = [
|
||||
"SORTIE_BOSS_HYENA",
|
||||
@ -1101,6 +1104,80 @@ const doesTimeSatsifyConstraints = (timeSecs: number): boolean => {
|
||||
return true;
|
||||
};
|
||||
|
||||
const getVarziaRotation = (week: number): string => {
|
||||
const seed = new SRng(week).randomInt(0, 100_000);
|
||||
const rng = new SRng(seed);
|
||||
return rng.randomElement(varzia.primeDualPacks)!.ItemType;
|
||||
};
|
||||
|
||||
const getVarziaManifest = (dualPack: string): IPrimeVaultTraderOffer[] => {
|
||||
const rotrationManifest = varzia.primeDualPacks.find(pack => pack.ItemType === dualPack);
|
||||
if (!rotrationManifest) return [];
|
||||
|
||||
const mainPack = [{ ItemType: rotrationManifest.ItemType, PrimePrice: 10 }];
|
||||
const singlePacks: IPrimeVaultTraderOffer[] = [];
|
||||
const items: IPrimeVaultTraderOffer[] = [];
|
||||
const bobbleHeads: IPrimeVaultTraderOffer[] = [];
|
||||
|
||||
for (const singlePackType of rotrationManifest.SinglePacks) {
|
||||
singlePacks.push({ ItemType: singlePackType, PrimePrice: 6 });
|
||||
|
||||
const sp = varzia.primeSinglePacks.find(pack => pack.ItemType === singlePackType);
|
||||
if (sp) {
|
||||
items.push(...sp.Items);
|
||||
sp.BobbleHeads.forEach(bobbleHead => {
|
||||
bobbleHeads.push({ ItemType: bobbleHead, PrimePrice: 1 });
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const relics = rotrationManifest.Relics.map(relic => ({ ItemType: relic, RegularPrice: 1 }));
|
||||
|
||||
return [singlePacks[0], ...mainPack, singlePacks[1], ...items, ...bobbleHeads, ...relics];
|
||||
};
|
||||
|
||||
const getAllVarziaManifests = (): IPrimeVaultTraderOffer[] => {
|
||||
const dualPacks: IPrimeVaultTraderOffer[] = [];
|
||||
const singlePacks: IPrimeVaultTraderOffer[] = [];
|
||||
const items: IPrimeVaultTraderOffer[] = [];
|
||||
const bobbleHeads: IPrimeVaultTraderOffer[] = [];
|
||||
const relics: IPrimeVaultTraderOffer[] = [];
|
||||
|
||||
const singlePackSet = new Set<string>();
|
||||
const itemsSet = new Set<string>();
|
||||
const bobbleHeadsSet = new Set<string>();
|
||||
|
||||
varzia.primeDualPacks.forEach(dualPack => {
|
||||
dualPacks.push({ ItemType: dualPack.ItemType, PrimePrice: 10 });
|
||||
|
||||
dualPack.SinglePacks.forEach(singlePackType => {
|
||||
if (!singlePackSet.has(singlePackType)) {
|
||||
singlePackSet.add(singlePackType);
|
||||
singlePacks.push({ ItemType: singlePackType, PrimePrice: 6 });
|
||||
}
|
||||
|
||||
const sp = varzia.primeSinglePacks.find(pack => pack.ItemType === singlePackType)!;
|
||||
sp.Items.forEach(item => {
|
||||
if (!itemsSet.has(item.ItemType)) {
|
||||
itemsSet.add(item.ItemType);
|
||||
items.push(item);
|
||||
}
|
||||
});
|
||||
|
||||
sp.BobbleHeads.forEach(bobbleHead => {
|
||||
if (!bobbleHeadsSet.has(bobbleHead)) {
|
||||
bobbleHeadsSet.add(bobbleHead);
|
||||
bobbleHeads.push({ ItemType: bobbleHead, PrimePrice: 1 });
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
relics.push(...dualPack.Relics.map(relic => ({ ItemType: relic, RegularPrice: 1 })));
|
||||
});
|
||||
|
||||
return [...dualPacks, ...singlePacks, ...items, ...bobbleHeads, ...relics];
|
||||
};
|
||||
|
||||
export const getWorldState = (buildLabel?: string): IWorldState => {
|
||||
let timeSecs = Math.round(Date.now() / 1000);
|
||||
while (!doesTimeSatsifyConstraints(timeSecs)) {
|
||||
@ -1122,6 +1199,7 @@ export const getWorldState = (buildLabel?: string): IWorldState => {
|
||||
ActiveMissions: [],
|
||||
GlobalUpgrades: [],
|
||||
VoidTraders: [],
|
||||
PrimeVaultTraders: [],
|
||||
VoidStorms: [],
|
||||
DailyDeals: [],
|
||||
EndlessXpChoices: [],
|
||||
@ -1393,6 +1471,30 @@ export const getWorldState = (buildLabel?: string): IWorldState => {
|
||||
}
|
||||
}
|
||||
|
||||
// Varzia
|
||||
{
|
||||
const pt: IPrimeVaultTrader = {
|
||||
_id: { $oid: ((weekStart / 1000) & 0xffffffff).toString(16).padStart(8, "0") + "c36af423770eaa97" },
|
||||
Activation: { $date: { $numberLong: weekStart.toString() } },
|
||||
Expiry: { $date: { $numberLong: weekEnd.toString() } },
|
||||
Node: "TradeHUB1",
|
||||
Manifest: [],
|
||||
EvergreenManifest: varzia.evergreen,
|
||||
ScheduleInfo: []
|
||||
};
|
||||
worldState.PrimeVaultTraders.push(pt);
|
||||
const rotation = config.worldState?.varziaOverride || getVarziaRotation(week);
|
||||
pt.Manifest = config.worldState?.varziaFullyStocked ? getAllVarziaManifests() : getVarziaManifest(rotation);
|
||||
if (config.worldState?.varziaOverride || config.worldState?.varziaFullyStocked) {
|
||||
pt.Expiry = { $date: { $numberLong: "2000000000000" } };
|
||||
} else {
|
||||
pt.ScheduleInfo.push({
|
||||
Expiry: { $date: { $numberLong: (weekEnd + unixTimesInMs.week).toString() } },
|
||||
FeaturedItem: getVarziaRotation(week + 1)
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Sortie & syndicate missions cycling every day (at 16:00 or 17:00 UTC depending on if London, OT is observing DST)
|
||||
{
|
||||
const rollover = getSortieTime(day);
|
||||
|
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 "@/src/models/loginModel";
|
||||
import { createAccount, createNonce, getUsernameFromEmail, isCorrectPassword } from "@/src/services/loginService";
|
||||
import { IDatabaseAccountJson } from "@/src/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;
|
||||
|
155
src/types/equipmentTypes.ts
Normal file
155
src/types/equipmentTypes.ts
Normal file
@ -0,0 +1,155 @@
|
||||
import { Types } from "mongoose";
|
||||
import { IMongoDate, IOid, IOidWithLegacySupport } from "@/src/types/commonTypes";
|
||||
import {
|
||||
ICrewShipCustomization,
|
||||
IFlavourItem,
|
||||
IItemConfig,
|
||||
IPolarity
|
||||
} from "@/src/types/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,5 +1,5 @@
|
||||
import { Types } from "mongoose";
|
||||
import { IMongoDate, IOidWithLegacySupport } from "./commonTypes";
|
||||
import { IMongoDate, IOidWithLegacySupport } from "@/src/types/commonTypes";
|
||||
|
||||
export interface IFriendInfo {
|
||||
_id: IOidWithLegacySupport;
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { IInventoryChanges } from "./purchaseTypes";
|
||||
import { IInventoryChanges } from "@/src/types/purchaseTypes";
|
||||
|
||||
export interface IGenericUpdate {
|
||||
NodeIntrosCompleted: string | string[];
|
||||
|
@ -1,8 +1,8 @@
|
||||
import { Types } from "mongoose";
|
||||
import { IOid, IMongoDate, IOidWithLegacySupport } from "@/src/types/commonTypes";
|
||||
import { IFusionTreasure, IMiscItem, ITypeCount } from "@/src/types/inventoryTypes/inventoryTypes";
|
||||
import { IPictureFrameInfo } from "./shipTypes";
|
||||
import { IFriendInfo } from "./friendTypes";
|
||||
import { IOid, IMongoDate, IOidWithLegacySupport, ITypeCount } from "@/src/types/commonTypes";
|
||||
import { IFusionTreasure, IMiscItem } from "@/src/types/inventoryTypes/inventoryTypes";
|
||||
import { IPictureFrameInfo } from "@/src/types/personalRoomsTypes";
|
||||
import { IFriendInfo } from "@/src/types/friendTypes";
|
||||
|
||||
export interface IGuildClient {
|
||||
_id: IOidWithLegacySupport;
|
||||
|
@ -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 "@/src/types/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 { IOrbiter } from "../personalRoomsTypes";
|
||||
import { IOrbiterClient } from "@/src/types/personalRoomsTypes";
|
||||
import { ICountedStoreItem } from "warframe-public-export-plus";
|
||||
import { IEquipmentClient, IEquipmentDatabase, ITraits } from "@/src/types/equipmentTypes";
|
||||
import { ILoadOutPresets } from "@/src/types/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",
|
||||
@ -381,7 +378,7 @@ export interface IInventoryClient extends IDailyAffiliations, InventoryClientEqu
|
||||
BrandedSuits?: IOidWithLegacySupport[];
|
||||
LockedWeaponGroup?: ILockedWeaponGroupClient;
|
||||
HubNpcCustomizations?: IHubNpcCustomization[];
|
||||
Ship?: IOrbiter; // U22 and below, response only
|
||||
Ship?: IOrbiterClient; // U22 and below, response only
|
||||
ClaimedJunctionChallengeRewards?: string[]; // U39
|
||||
SpecialItemRewardAttenuation?: IRewardAttenuation[]; // Baro's Void Surplus
|
||||
}
|
||||
@ -552,64 +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: IShipExterior;
|
||||
}
|
||||
|
||||
export interface IShipExterior {
|
||||
SkinFlavourItem?: string;
|
||||
Colors?: IColor;
|
||||
ShipAttachments?: IShipAttachments;
|
||||
}
|
||||
|
||||
export interface IShipAttachments {
|
||||
HOOD_ORNAMENT: string;
|
||||
}
|
||||
|
||||
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[];
|
||||
@ -740,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;
|
||||
@ -808,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"
|
||||
}
|
||||
@ -857,10 +723,6 @@ export interface ILoreFragmentScan {
|
||||
ItemType: string;
|
||||
}
|
||||
|
||||
export interface ILotusCustomization extends IItemConfig {
|
||||
Persona: string;
|
||||
}
|
||||
|
||||
export interface IMissionDatabase {
|
||||
Tag: string;
|
||||
Completes: number;
|
||||
@ -1104,7 +966,7 @@ export interface ISettings {
|
||||
|
||||
export interface IShipInventory {
|
||||
ItemType: string;
|
||||
ShipExterior: IShipExterior;
|
||||
ShipExterior: IShipCustomization;
|
||||
AirSupportPower: string;
|
||||
ItemId: IOid;
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { IAffiliationMods, IInventoryChanges } from "./purchaseTypes";
|
||||
import { IAffiliationMods, IInventoryChanges } from "@/src/types/purchaseTypes";
|
||||
|
||||
export const inventoryFields = ["RawUpgrades", "MiscItems", "Consumables", "Recipes"] as const;
|
||||
export type IInventoryFieldType = (typeof inventoryFields)[number];
|
||||
|
@ -1,18 +1,35 @@
|
||||
import { IColor } from "@/src/types/inventoryTypes/commonInventoryTypes";
|
||||
import {
|
||||
IRoom,
|
||||
IPlacedDecosDatabase,
|
||||
ITailorShop,
|
||||
ITailorShopDatabase,
|
||||
TBootLocation,
|
||||
IApartmentDatabase,
|
||||
IApartmentClient
|
||||
} from "@/src/types/shipTypes";
|
||||
import { IColor, IShipAttachments, IShipCustomization } from "@/src/types/inventoryTypes/commonInventoryTypes";
|
||||
import { Document, Model, Types } from "mongoose";
|
||||
import { ILoadoutClient } from "@/src/types/saveLoadoutTypes";
|
||||
import { IMongoDate, IOid } from "@/src/types/commonTypes";
|
||||
|
||||
export interface IOrbiter {
|
||||
export interface IGetShipResponse {
|
||||
ShipOwnerId: string;
|
||||
Ship: IOrbiterClient;
|
||||
Apartment: IApartmentClient;
|
||||
TailorShop: ITailorShop;
|
||||
LoadOutInventory: { LoadOutPresets: ILoadoutClient };
|
||||
}
|
||||
|
||||
export type TBootLocation = "LISET" | "DRIFTER_CAMP" | "APARTMENT" | "SHOP";
|
||||
|
||||
export interface IOrbiterClient {
|
||||
Features: string[];
|
||||
ShipId: IOid;
|
||||
ShipInterior: IShipCustomization;
|
||||
Rooms: IRoom[];
|
||||
VignetteFish?: string[];
|
||||
FavouriteLoadoutId?: IOid;
|
||||
Wallpaper?: string;
|
||||
Vignette?: string;
|
||||
BootLocation?: TBootLocation;
|
||||
ContentUrlSignature?: string;
|
||||
}
|
||||
|
||||
export interface IOrbiterDatabase {
|
||||
Features: string[];
|
||||
Rooms: IRoom[];
|
||||
ShipInterior?: IShipCustomization;
|
||||
VignetteFish?: string[];
|
||||
FavouriteLoadoutId?: Types.ObjectId;
|
||||
Wallpaper?: string;
|
||||
@ -22,25 +39,169 @@ export interface IOrbiter {
|
||||
}
|
||||
|
||||
export interface IPersonalRoomsClient {
|
||||
ShipInteriorColors: IColor;
|
||||
Ship: IOrbiter;
|
||||
Ship: IOrbiterClient;
|
||||
Apartment: IApartmentClient;
|
||||
TailorShop: ITailorShop;
|
||||
}
|
||||
|
||||
export interface IPersonalRoomsDatabase {
|
||||
ShipInteriorColors: IColor;
|
||||
personalRoomsOwnerId: Types.ObjectId;
|
||||
activeShipId: Types.ObjectId;
|
||||
Ship: IOrbiter;
|
||||
|
||||
Ship: IOrbiterDatabase;
|
||||
Apartment: IApartmentDatabase;
|
||||
TailorShop: ITailorShopDatabase;
|
||||
}
|
||||
|
||||
export interface IRoom {
|
||||
Name: string;
|
||||
MaxCapacity: number;
|
||||
PlacedDecos?: IPlacedDecosDatabase[];
|
||||
}
|
||||
|
||||
export interface IPlantClient {
|
||||
PlantType: string;
|
||||
EndTime: IMongoDate;
|
||||
PlotIndex: number;
|
||||
}
|
||||
|
||||
export interface IPlantDatabase extends Omit<IPlantClient, "EndTime"> {
|
||||
EndTime: Date;
|
||||
}
|
||||
|
||||
export interface IPlanterClient {
|
||||
Name: string;
|
||||
Plants: IPlantClient[];
|
||||
}
|
||||
|
||||
export interface IPlanterDatabase {
|
||||
Name: string;
|
||||
Plants: IPlantDatabase[];
|
||||
}
|
||||
|
||||
export interface IGardeningClient {
|
||||
Planters: IPlanterClient[];
|
||||
}
|
||||
|
||||
export interface IGardeningDatabase {
|
||||
Planters: IPlanterDatabase[];
|
||||
}
|
||||
|
||||
export interface IApartmentClient {
|
||||
Gardening: IGardeningClient;
|
||||
Rooms: IRoom[];
|
||||
FavouriteLoadouts: IFavouriteLoadout[];
|
||||
}
|
||||
|
||||
export interface IApartmentDatabase {
|
||||
Gardening: IGardeningDatabase;
|
||||
Rooms: IRoom[];
|
||||
FavouriteLoadouts: IFavouriteLoadoutDatabase[];
|
||||
}
|
||||
|
||||
export interface IPlacedDecosDatabase {
|
||||
Type: string;
|
||||
Pos: [number, number, number];
|
||||
Rot: [number, number, number];
|
||||
Scale?: number;
|
||||
Sockets?: number;
|
||||
PictureFrameInfo?: IPictureFrameInfo;
|
||||
_id: Types.ObjectId;
|
||||
}
|
||||
|
||||
export interface IPlacedDecosClient extends Omit<IPlacedDecosDatabase, "_id"> {
|
||||
id: IOid;
|
||||
}
|
||||
|
||||
export interface ISetShipCustomizationsRequest {
|
||||
ShipId: string;
|
||||
Customization: {
|
||||
SkinFlavourItem?: string;
|
||||
Colors?: IColor;
|
||||
ShipAttachments?: IShipAttachments;
|
||||
LevelDecosVisible?: boolean;
|
||||
CustomJson?: string;
|
||||
};
|
||||
IsExterior: boolean;
|
||||
AirSupportPower?: string;
|
||||
IsShop?: boolean;
|
||||
}
|
||||
|
||||
export interface IShipDecorationsRequest {
|
||||
Type: string;
|
||||
Pos: [number, number, number];
|
||||
Rot: [number, number, number];
|
||||
Room: string;
|
||||
BootLocation?: TBootLocation;
|
||||
IsApartment?: boolean;
|
||||
RemoveId?: string;
|
||||
MoveId?: string;
|
||||
OldRoom?: string;
|
||||
Scale?: number;
|
||||
Sockets?: number;
|
||||
}
|
||||
|
||||
export interface IShipDecorationsResponse {
|
||||
DecoId?: string;
|
||||
Room?: string;
|
||||
IsApartment?: boolean;
|
||||
MaxCapacityIncrease?: number;
|
||||
OldRoom?: string;
|
||||
NewRoom?: string;
|
||||
}
|
||||
|
||||
export interface ISetPlacedDecoInfoRequest {
|
||||
DecoType: string;
|
||||
DecoId: string;
|
||||
Room: string;
|
||||
PictureFrameInfo: IPictureFrameInfo;
|
||||
BootLocation?: TBootLocation;
|
||||
ComponentId?: string;
|
||||
GuildId?: string;
|
||||
}
|
||||
|
||||
export interface IPictureFrameInfo {
|
||||
Image: string;
|
||||
Filter: string;
|
||||
XOffset: number;
|
||||
YOffset: number;
|
||||
Scale: number;
|
||||
InvertX: boolean;
|
||||
InvertY: boolean;
|
||||
ColorCorrection: number;
|
||||
Text: string;
|
||||
TextScale: number;
|
||||
TextColorA: number;
|
||||
TextColorB: number;
|
||||
TextOrientation: number;
|
||||
}
|
||||
|
||||
export interface IFavouriteLoadout {
|
||||
Tag: string;
|
||||
LoadoutId: IOid;
|
||||
}
|
||||
|
||||
export interface IFavouriteLoadoutDatabase {
|
||||
Tag: string;
|
||||
LoadoutId: Types.ObjectId;
|
||||
}
|
||||
|
||||
export interface ITailorShopDatabase {
|
||||
FavouriteLoadouts: IFavouriteLoadoutDatabase[];
|
||||
Colors?: IColor;
|
||||
CustomJson?: string;
|
||||
LevelDecosVisible?: boolean;
|
||||
Rooms: IRoom[];
|
||||
}
|
||||
|
||||
export interface ITailorShop extends Omit<ITailorShopDatabase, "FavouriteLoadouts"> {
|
||||
FavouriteLoadouts: IFavouriteLoadout[];
|
||||
}
|
||||
|
||||
export type RoomsType = { Name: string; MaxCapacity: number; PlacedDecos: Types.DocumentArray<IPlacedDecosDatabase> };
|
||||
|
||||
export type PersonalRoomsDocumentProps = {
|
||||
Ship: Omit<IOrbiter, "Rooms"> & {
|
||||
Ship: Omit<IOrbiterDatabase, "Rooms"> & {
|
||||
Rooms: RoomsType[];
|
||||
};
|
||||
Apartment: Omit<IApartmentDatabase, "Rooms"> & {
|
||||
|
@ -1,15 +1,15 @@
|
||||
import { IEquipmentClient } from "./inventoryTypes/commonInventoryTypes";
|
||||
import { ITypeCount } from "@/src/types/commonTypes";
|
||||
import { IEquipmentClient } from "@/src/types/equipmentTypes";
|
||||
import {
|
||||
IDroneClient,
|
||||
IInfestedFoundryClient,
|
||||
IMiscItem,
|
||||
INemesisClient,
|
||||
ITypeCount,
|
||||
IRecentVendorPurchaseClient,
|
||||
TEquipmentKey,
|
||||
ICrewMemberClient,
|
||||
IKubrowPetPrintClient
|
||||
} from "./inventoryTypes/inventoryTypes";
|
||||
} from "@/src/types/inventoryTypes/inventoryTypes";
|
||||
|
||||
export enum PurchaseSource {
|
||||
Market = 0,
|
||||
|
@ -1,10 +1,9 @@
|
||||
import { IOid } from "./commonTypes";
|
||||
import { ArtifactPolarity, IPolarity, IEquipmentClient } from "@/src/types/inventoryTypes/commonInventoryTypes";
|
||||
import { IOid, ITypeCount } from "@/src/types/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";
|
||||
} from "@/src/types/inventoryTypes/inventoryTypes";
|
||||
import { IGroup } from "@/src/types/loginTypes";
|
||||
import { ILoadOutPresets } from "@/src/types/saveLoadoutTypes";
|
||||
import { IEquipmentClient } from "@/src/types/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 "@/src/types/equipmentTypes";
|
||||
|
||||
export interface ISaveLoadoutRequest {
|
||||
LoadOuts: ILoadoutClient;
|
||||
@ -40,6 +39,7 @@ export interface ISaveLoadoutRequest {
|
||||
CrewShips: IItemEntry;
|
||||
CurrentLoadOutIds: IOid[];
|
||||
ValidNewLoadoutId: string;
|
||||
ActiveCrewShip: IOid;
|
||||
EquippedGear: string[];
|
||||
EquippedEmotes: string[];
|
||||
UseAdultOperatorLoadout: boolean;
|
||||
@ -72,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[];
|
||||
@ -89,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.
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user