feat: import (#831)

This commit is contained in:
Sainan 2025-01-20 12:19:32 +01:00 committed by GitHub
parent ee0bee5d7b
commit c9b48ace36
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
18 changed files with 450 additions and 98 deletions

View File

@ -44,7 +44,7 @@ export const arcaneCommonController: RequestHandler = async (req, res) => {
ItemType: json.arcane.ItemType,
UpgradeFingerprint: JSON.stringify({ lvl: json.newRank })
});
upgradeId = inventory.Upgrades[newLength - 1]._id!.toString();
upgradeId = inventory.Upgrades[newLength - 1]._id.toString();
}
// Remove RawUpgrades

View File

@ -1,7 +1,7 @@
import { getJSONfromString } from "@/src/helpers/stringHelpers";
import { getAccountIdForRequest } from "@/src/services/loginService";
import { RequestHandler } from "express";
import { ICrewShipSalvagedWeaponSkin } from "@/src/types/inventoryTypes/inventoryTypes";
import { IInventoryClient, IUpgradeClient } from "@/src/types/inventoryTypes/inventoryTypes";
import { addMods, getInventory } from "@/src/services/inventoryService";
import { config } from "@/src/services/configService";
@ -20,7 +20,7 @@ export const artifactsController: RequestHandler = async (req, res) => {
parsedUpgradeFingerprint.lvl += LevelDiff;
const stringifiedUpgradeFingerprint = JSON.stringify(parsedUpgradeFingerprint);
let itemIndex = Upgrades.findIndex(upgrade => upgrade._id?.equals(ItemId!.$oid));
let itemIndex = Upgrades.findIndex(upgrade => upgrade._id.equals(ItemId.$oid));
if (itemIndex !== -1) {
Upgrades[itemIndex].UpgradeFingerprint = stringifiedUpgradeFingerprint;
@ -58,7 +58,7 @@ export const artifactsController: RequestHandler = async (req, res) => {
}
const changedInventory = await inventory.save();
const itemId = changedInventory.toJSON().Upgrades[itemIndex]?.ItemId?.$oid;
const itemId = changedInventory.toJSON<IInventoryClient>().Upgrades[itemIndex].ItemId.$oid;
if (!itemId) {
throw new Error("Item Id not found in upgradeMod");
@ -68,7 +68,7 @@ export const artifactsController: RequestHandler = async (req, res) => {
};
interface IArtifactsRequest {
Upgrade: ICrewShipSalvagedWeaponSkin;
Upgrade: IUpgradeClient;
LevelDiff: number;
Cost: number;
FusionPointCost: number;

View File

@ -4,10 +4,10 @@ import allShipFeatures from "@/static/fixed_responses/allShipFeatures.json";
import { getAccountIdForRequest } from "@/src/services/loginService";
import { getPersonalRooms } from "@/src/services/personalRoomsService";
import { getShip } from "@/src/services/shipService";
import { Loadout } from "@/src/models/inventoryModels/loadoutModel";
import { toOid } from "@/src/helpers/inventoryHelpers";
import { IGetShipResponse } from "@/src/types/shipTypes";
import { IPersonalRooms } from "@/src/types/personalRoomsTypes";
import { getLoadout } from "@/src/services/loadoutService";
export const getShipController: RequestHandler = async (req, res) => {
const accountId = await getAccountIdForRequest(req);
@ -38,13 +38,3 @@ export const getShipController: RequestHandler = async (req, res) => {
res.json(getShipResponse);
};
export const getLoadout = async (accountId: string) => {
const loadout = await Loadout.findOne({ loadoutOwnerId: accountId });
if (!loadout) {
throw new Error(`loadout not found for account ${accountId}`);
}
return loadout;
};

View File

@ -6,7 +6,7 @@ import { IOid } from "@/src/types/commonTypes";
import {
IConsumedSuit,
IHelminthFoodRecord,
IInfestedFoundry,
IInfestedFoundryDatabase,
IMiscItem,
ITypeCount
} from "@/src/types/inventoryTypes/inventoryTypes";
@ -356,7 +356,7 @@ interface IHelminthFeedRequest {
}[];
}
export const addInfestedFoundryXP = (infestedFoundry: IInfestedFoundry, delta: number): ITypeCount[] => {
export const addInfestedFoundryXP = (infestedFoundry: IInfestedFoundryDatabase, delta: number): ITypeCount[] => {
const recipeChanges: ITypeCount[] = [];
infestedFoundry.XP ??= 0;
const prevXP = infestedFoundry.XP;

View File

@ -4,7 +4,7 @@ import { Inventory } from "@/src/models/inventoryModels/inventoryModel";
import { config } from "@/src/services/configService";
import allDialogue from "@/static/fixed_responses/allDialogue.json";
import { ILoadoutDatabase } from "@/src/types/saveLoadoutTypes";
import { IInventoryResponse, IShipInventory, equipmentKeys } from "@/src/types/inventoryTypes/inventoryTypes";
import { IInventoryClient, IShipInventory, equipmentKeys } from "@/src/types/inventoryTypes/inventoryTypes";
import { IPolarity, ArtifactPolarity, EquipmentFeatures } from "@/src/types/inventoryTypes/commonInventoryTypes";
import {
ExportCustoms,
@ -55,7 +55,7 @@ export const inventoryController: RequestHandler = async (request, response) =>
const inventoryWithLoadOutPresetsAndShips = await inventoryWithLoadOutPresets.populate<{ Ships: IShipInventory }>(
"Ships"
);
const inventoryResponse = inventoryWithLoadOutPresetsAndShips.toJSON<IInventoryResponse>();
const inventoryResponse = inventoryWithLoadOutPresetsAndShips.toJSON<IInventoryClient>();
if (config.infiniteCredits) {
inventoryResponse.RegularCredits = 999999999;
@ -147,8 +147,9 @@ export const inventoryController: RequestHandler = async (request, response) =>
}
if (config.unlockAllSkins) {
inventoryResponse.WeaponSkins = [];
for (const uniqueName in ExportCustoms) {
const missingWeaponSkins = new Set(Object.keys(ExportCustoms));
inventoryResponse.WeaponSkins.forEach(x => missingWeaponSkins.delete(x.ItemType));
for (const uniqueName of missingWeaponSkins) {
inventoryResponse.WeaponSkins.push({
ItemId: {
$oid: "ca70ca70ca70ca70" + catBreadHash(uniqueName).toString(16).padStart(8, "0")

View File

@ -6,7 +6,7 @@ import {
EquipmentFeatures,
IAbilityOverride
} from "@/src/types/inventoryTypes/commonInventoryTypes";
import { IMiscItem } from "@/src/types/inventoryTypes/inventoryTypes";
import { IInventoryClient, IMiscItem } from "@/src/types/inventoryTypes/inventoryTypes";
import { getAccountIdForRequest } from "@/src/services/loginService";
import { addMiscItems, addRecipes, getInventory, updateCurrency } from "@/src/services/inventoryService";
import { getRecipeByResult } from "@/src/services/itemDataService";
@ -62,7 +62,7 @@ export const upgradesController: RequestHandler = async (req, res) => {
addRecipes(inventory, recipeChanges);
inventoryChanges.Recipes = recipeChanges;
inventoryChanges.InfestedFoundry = inventory.toJSON().InfestedFoundry;
inventoryChanges.InfestedFoundry = inventory.toJSON<IInventoryClient>().InfestedFoundry;
} else
switch (operation.UpgradeRequirement) {
case "/Lotus/Types/Items/MiscItems/OrokinReactor":

View File

@ -2,6 +2,7 @@ import { RequestHandler } from "express";
import { getDict, getItemName, getString } from "@/src/services/itemDataService";
import {
ExportArcanes,
ExportAvionics,
ExportGear,
ExportRecipes,
ExportResources,
@ -137,6 +138,13 @@ const getItemListsController: RequestHandler = (req, response) => {
badItems[uniqueName] = true;
}
}
for (const [uniqueName, upgrade] of Object.entries(ExportAvionics)) {
res.mods.push({
uniqueName,
name: getString(upgrade.name, lang),
fusionLimit: upgrade.fusionLimit
});
}
for (const [uniqueName, arcane] of Object.entries(ExportArcanes)) {
res.mods.push({
uniqueName,

View File

@ -0,0 +1,27 @@
import { importInventory, importLoadOutPresets } from "@/src/services/importService";
import { getInventory } from "@/src/services/inventoryService";
import { getLoadout } from "@/src/services/loadoutService";
import { getAccountIdForRequest } from "@/src/services/loginService";
import { IInventoryClient } from "@/src/types/inventoryTypes/inventoryTypes";
import { RequestHandler } from "express";
export const importController: RequestHandler = async (req, res) => {
const accountId = await getAccountIdForRequest(req);
const request = JSON.parse(String(req.body)) as IImportRequest;
const inventory = await getInventory(accountId);
importInventory(inventory, request.inventory);
await inventory.save();
if (request.inventory.LoadOutPresets) {
const loadout = await getLoadout(accountId);
importLoadOutPresets(loadout, request.inventory.LoadOutPresets);
await loadout.save();
}
res.end();
};
interface IImportRequest {
inventory: Partial<IInventoryClient>;
}

View File

@ -2,11 +2,10 @@ import { Document, Model, Schema, Types, model } from "mongoose";
import {
IFlavourItem,
IRawUpgrade,
ICrewShipSalvagedWeaponSkin,
IMiscItem,
IInventoryDatabase,
IBooster,
IInventoryResponse,
IInventoryClient,
ISlots,
IMailbox,
IDuviriInfo,
@ -14,7 +13,7 @@ import {
IPendingRecipeResponse,
ITypeCount,
IFocusXP,
IFocusUpgrades,
IFocusUpgrade,
ITypeXPItem,
IChallengeProgress,
IStepSequencer,
@ -24,7 +23,7 @@ import {
ISeasonChallenge,
IPlayerSkills,
ISettings,
IInfestedFoundry,
IInfestedFoundryDatabase,
IHelminthResource,
IConsumedSuit,
IQuestProgress,
@ -43,7 +42,6 @@ import {
ICrewShipCustomization,
ICrewShipWeapon,
ICrewShipMembersClient,
ICrewShip,
ICrewShipPilotWeapon,
IShipExterior,
IHelminthFoodRecord,
@ -52,7 +50,9 @@ import {
IDialogueDatabase,
IDialogueGift,
ICompletedDialogue,
IDialogueClient
IDialogueClient,
IUpgradeDatabase,
ICrewShipDatabase
} from "../../types/inventoryTypes/inventoryTypes";
import { IOid } from "../../types/commonTypes";
import {
@ -62,7 +62,6 @@ import {
IOperatorConfigDatabase,
IPolarity,
IEquipmentDatabase,
IOperatorConfigClient,
IArchonCrystalUpgrade
} from "@/src/types/inventoryTypes/commonInventoryTypes";
import { toMongoDate, toOid } from "@/src/helpers/inventoryHelpers";
@ -81,7 +80,7 @@ const focusXPSchema = new Schema<IFocusXP>(
{ _id: false }
);
const focusUpgradesSchema = new Schema<IFocusUpgrades>(
const focusUpgradeSchema = new Schema<IFocusUpgrade>(
{
ItemType: String,
Level: Number,
@ -288,7 +287,7 @@ RawUpgrades.set("toJSON", {
}
});
const upgradesSchema = new Schema<ICrewShipSalvagedWeaponSkin>(
const upgradeSchema = new Schema<IUpgradeDatabase>(
{
UpgradeFingerprint: String,
PendingRerollFingerprint: { type: String, required: false },
@ -297,11 +296,11 @@ const upgradesSchema = new Schema<ICrewShipSalvagedWeaponSkin>(
{ id: false }
);
upgradesSchema.virtual("ItemId").get(function () {
upgradeSchema.virtual("ItemId").get(function () {
return toOid(this._id);
});
upgradesSchema.set("toJSON", {
upgradeSchema.set("toJSON", {
virtuals: true,
transform(_document, returnedObject) {
delete returnedObject._id;
@ -493,7 +492,7 @@ const helminthResourceSchema = new Schema<IHelminthResource>(
{ _id: false }
);
const infestedFoundrySchema = new Schema<IInfestedFoundry>(
const infestedFoundrySchema = new Schema<IInfestedFoundryDatabase>(
{
Name: String,
Resources: { type: [helminthResourceSchema], default: undefined },
@ -695,7 +694,7 @@ crewShipMembersSchema.set("toJSON", {
}
});
const crewShipSchema = new Schema<ICrewShip>({
const crewShipSchema = new Schema<ICrewShipDatabase>({
ItemType: { type: String, required: true },
Configs: { type: [ItemConfigSchema], default: [] },
Weapon: { type: crewShipWeaponSchema, default: undefined },
@ -837,7 +836,7 @@ const inventorySchema = new Schema<IInventoryDatabase, InventoryDocumentProps>(
//Curent active like Active school focuses is = "Zenurik"
FocusAbility: String,
//The treeways of the Focus school.(Active and passive Ability)
FocusUpgrades: [focusUpgradesSchema],
FocusUpgrades: [focusUpgradeSchema],
//Achievement
ChallengeProgress: [challengeProgressSchema],
@ -848,7 +847,7 @@ const inventorySchema = new Schema<IInventoryDatabase, InventoryDocumentProps>(
//Non Upgrade Mods Example:I have 999 item WeaponElectricityDamageMod (only "ItemCount"+"ItemType")
RawUpgrades: [RawUpgrades],
//Upgrade Mods\Riven\Arcane Example:"UpgradeFingerprint"+"ItemType"+""
Upgrades: [upgradesSchema],
Upgrades: [upgradeSchema],
//Warframe
Suits: [EquipmentSchema],
@ -1142,7 +1141,7 @@ inventorySchema.set("toJSON", {
delete returnedObject.accountOwnerId;
const inventoryDatabase = returnedObject as IInventoryDatabase;
const inventoryResponse = returnedObject as IInventoryResponse;
const inventoryResponse = returnedObject as IInventoryClient;
inventoryResponse.TrainingDate = toMongoDate(inventoryDatabase.TrainingDate);
inventoryResponse.Created = toMongoDate(inventoryDatabase.Created);
@ -1164,12 +1163,12 @@ type InventoryDocumentProps = {
OperatorAmps: Types.DocumentArray<IEquipmentDatabase>;
FlavourItems: Types.DocumentArray<IFlavourItem>;
RawUpgrades: Types.DocumentArray<IRawUpgrade>;
Upgrades: Types.DocumentArray<ICrewShipSalvagedWeaponSkin>;
Upgrades: Types.DocumentArray<IUpgradeDatabase>;
MiscItems: Types.DocumentArray<IMiscItem>;
Boosters: Types.DocumentArray<IBooster>;
OperatorLoadOuts: Types.DocumentArray<IOperatorConfigClient>;
OperatorLoadOuts: Types.DocumentArray<IOperatorConfigDatabase>;
SpecialItems: Types.DocumentArray<IEquipmentDatabase>;
AdultOperatorLoadOuts: Types.DocumentArray<IOperatorConfigClient>; //TODO: this should still contain _id
AdultOperatorLoadOuts: Types.DocumentArray<IOperatorConfigDatabase>;
MechSuits: Types.DocumentArray<IEquipmentDatabase>;
Scoops: Types.DocumentArray<IEquipmentDatabase>;
DataKnives: Types.DocumentArray<IEquipmentDatabase>;
@ -1185,7 +1184,7 @@ type InventoryDocumentProps = {
Hoverboards: Types.DocumentArray<IEquipmentDatabase>;
MoaPets: Types.DocumentArray<IEquipmentDatabase>;
WeaponSkins: Types.DocumentArray<IWeaponSkinDatabase>;
CrewShips: Types.DocumentArray<ICrewShip>;
CrewShips: Types.DocumentArray<ICrewShipDatabase>;
CrewShipHarnesses: Types.DocumentArray<IEquipmentDatabase>;
};

View File

@ -9,6 +9,7 @@ import { renameAccountController } from "@/src/controllers/custom/renameAccountC
import { createAccountController } from "@/src/controllers/custom/createAccountController";
import { addItemsController } from "@/src/controllers/custom/addItemsController";
import { importController } from "@/src/controllers/custom/importController";
import { getConfigDataController } from "@/src/controllers/custom/getConfigDataController";
import { updateConfigDataController } from "@/src/controllers/custom/updateConfigDataController";
@ -24,6 +25,7 @@ customRouter.get("/renameAccount", renameAccountController);
customRouter.post("/createAccount", createAccountController);
customRouter.post("/addItems", addItemsController);
customRouter.post("/import", importController);
customRouter.get("/config", getConfigDataController);
customRouter.post("/config", updateConfigDataController);

View File

@ -34,6 +34,9 @@ webuiRouter.get("/webui/settings", (_req, res) => {
webuiRouter.get("/webui/cheats", (_req, res) => {
res.sendFile(path.join(rootDir, "static/webui/index.html"));
});
webuiRouter.get("/webui/import", (_req, res) => {
res.sendFile(path.join(rootDir, "static/webui/index.html"));
});
// Serve static files
webuiRouter.use("/webui", express.static(path.join(rootDir, "static/webui")));

View File

@ -0,0 +1,247 @@
import { Types } from "mongoose";
import {
IEquipmentClient,
IEquipmentDatabase,
IOperatorConfigClient,
IOperatorConfigDatabase
} from "../types/inventoryTypes/commonInventoryTypes";
import { IMongoDate } from "../types/commonTypes";
import {
equipmentKeys,
ICrewShipClient,
ICrewShipDatabase,
ICrewShipMembersClient,
ICrewShipMembersDatabase,
IDialogueClient,
IDialogueDatabase,
IDialogueHistoryClient,
IDialogueHistoryDatabase,
IInfestedFoundryClient,
IInfestedFoundryDatabase,
IInventoryClient,
ILoadoutConfigClient,
ILoadOutPresets,
ISlots,
IUpgradeClient,
IUpgradeDatabase,
IWeaponSkinClient,
IWeaponSkinDatabase
} from "../types/inventoryTypes/inventoryTypes";
import { TInventoryDatabaseDocument } from "../models/inventoryModels/inventoryModel";
import { ILoadoutConfigDatabase, ILoadoutDatabase } from "../types/saveLoadoutTypes";
const convertDate = (value: IMongoDate): Date => {
return new Date(parseInt(value.$date.$numberLong));
};
const convertOptionalDate = (value: IMongoDate | undefined): Date | undefined => {
return value ? convertDate(value) : undefined;
};
const convertEquipment = (client: IEquipmentClient): IEquipmentDatabase => {
const { ItemId, ...rest } = client;
return {
...rest,
_id: new Types.ObjectId(ItemId.$oid),
InfestationDate: convertOptionalDate(client.InfestationDate),
Expiry: convertOptionalDate(client.Expiry),
UpgradesExpiry: convertOptionalDate(client.UpgradesExpiry)
};
};
const convertWeaponSkin = (client: IWeaponSkinClient): IWeaponSkinDatabase => {
const { ItemId, ...rest } = client;
return {
...rest,
_id: new Types.ObjectId(ItemId.$oid)
};
};
const convertUpgrade = (client: IUpgradeClient): IUpgradeDatabase => {
const { ItemId, ...rest } = client;
return {
...rest,
_id: new Types.ObjectId(ItemId.$oid)
};
};
const convertOperatorConfig = (client: IOperatorConfigClient): IOperatorConfigDatabase => {
const { ItemId, ...rest } = client;
return {
...rest,
_id: new Types.ObjectId(ItemId.$oid)
};
};
const replaceArray = <T>(arr: T[], replacement: T[]): void => {
arr.splice(0, arr.length);
replacement.forEach(x => {
arr.push(x);
});
};
const replaceSlots = (db: ISlots, client: ISlots): void => {
db.Extra = client.Extra;
db.Slots = client.Slots;
};
const convertCrewShipMembers = (client: ICrewShipMembersClient): ICrewShipMembersDatabase => {
return {
SLOT_A: client.SLOT_A ? new Types.ObjectId(client.SLOT_A.ItemId.$oid) : undefined,
SLOT_B: client.SLOT_B ? new Types.ObjectId(client.SLOT_B.ItemId.$oid) : undefined,
SLOT_C: client.SLOT_C ? new Types.ObjectId(client.SLOT_C.ItemId.$oid) : undefined
};
};
const convertCrewShip = (client: ICrewShipClient): ICrewShipDatabase => {
const { ItemId, ...rest } = client;
return {
...rest,
_id: new Types.ObjectId(ItemId.$oid),
CrewMembers: client.CrewMembers ? convertCrewShipMembers(client.CrewMembers) : undefined
};
};
const convertInfestedFoundry = (client: IInfestedFoundryClient): IInfestedFoundryDatabase => {
return {
...client,
LastConsumedSuit: client.LastConsumedSuit ? convertEquipment(client.LastConsumedSuit) : undefined,
AbilityOverrideUnlockCooldown: convertOptionalDate(client.AbilityOverrideUnlockCooldown)
};
};
const convertDialogue = (client: IDialogueClient): IDialogueDatabase => {
return {
...client,
AvailableDate: convertDate(client.AvailableDate),
AvailableGiftDate: convertDate(client.AvailableGiftDate),
RankUpExpiry: convertDate(client.RankUpExpiry),
BountyChemExpiry: convertDate(client.BountyChemExpiry)
};
};
const convertDialogueHistory = (client: IDialogueHistoryClient): IDialogueHistoryDatabase => {
return {
YearIteration: client.YearIteration,
Dialogues: client.Dialogues ? client.Dialogues.map(convertDialogue) : undefined
};
};
export const importInventory = (db: TInventoryDatabaseDocument, client: Partial<IInventoryClient>): void => {
for (const key of equipmentKeys) {
if (client[key]) {
replaceArray<IEquipmentDatabase>(db[key], client[key].map(convertEquipment));
}
}
if (client.WeaponSkins) {
replaceArray<IWeaponSkinDatabase>(db.WeaponSkins, client.WeaponSkins.map(convertWeaponSkin));
}
if (client.Upgrades) {
replaceArray<IUpgradeDatabase>(db.Upgrades, client.Upgrades.map(convertUpgrade));
}
for (const key of ["RawUpgrades", "MiscItems"] as const) {
if (client[key]) {
db[key].splice(0, db[key].length);
client[key].forEach(x => {
db[key].push({
ItemType: x.ItemType,
ItemCount: x.ItemCount
});
});
}
}
for (const key of ["OperatorLoadOuts", "AdultOperatorLoadOuts"] as const) {
if (client[key]) {
replaceArray<IOperatorConfigDatabase>(db[key], client[key].map(convertOperatorConfig));
}
}
for (const key of [
"SuitBin",
"WeaponBin",
"SentinelBin",
"SpaceSuitBin",
"SpaceWeaponBin",
"PvpBonusLoadoutBin",
"PveBonusLoadoutBin",
"RandomModBin",
"MechBin",
"CrewMemberBin",
"OperatorAmpBin",
"CrewShipSalvageBin"
] as const) {
if (client[key]) {
replaceSlots(db[key], client[key]);
}
}
if (client.UseAdultOperatorLoadout) {
db.UseAdultOperatorLoadout = client.UseAdultOperatorLoadout;
}
for (const key of [
"PlayerLevel",
"RegularCredits",
"PremiumCredits",
"PremiumCreditsFree",
"FusionPoints",
"PrimeTokens"
] as const) {
if (client[key]) {
db[key] = client[key];
}
}
for (const key of ["ThemeStyle", "ThemeBackground", "ThemeSounds", "EquippedInstrument", "FocusAbility"] as const) {
if (client[key]) {
db[key] = client[key];
}
}
for (const key of ["EquippedGear", "EquippedEmotes", "NodeIntrosCompleted"] as const) {
if (client[key]) {
db[key] = client[key];
}
}
if (client.XPInfo) {
db.XPInfo = client.XPInfo;
}
if (client.CurrentLoadOutIds) {
db.CurrentLoadOutIds = client.CurrentLoadOutIds;
}
if (client.Affiliations) {
db.Affiliations = client.Affiliations;
}
if (client.FusionTreasures) {
db.FusionTreasures = client.FusionTreasures;
}
if (client.FocusUpgrades) {
db.FocusUpgrades = client.FocusUpgrades;
}
if (client.CrewShips) {
replaceArray<ICrewShipDatabase>(db.CrewShips, client.CrewShips.map(convertCrewShip));
}
if (client.InfestedFoundry) {
db.InfestedFoundry = convertInfestedFoundry(client.InfestedFoundry);
}
if (client.DialogueHistory) {
db.DialogueHistory = convertDialogueHistory(client.DialogueHistory);
}
};
const convertLoadOutConfig = (client: ILoadoutConfigClient): ILoadoutConfigDatabase => {
const { ItemId, ...rest } = client;
return {
...rest,
_id: new Types.ObjectId(ItemId.$oid)
};
};
export const importLoadOutPresets = (db: ILoadoutDatabase, client: ILoadOutPresets): void => {
db.NORMAL = client.NORMAL.map(convertLoadOutConfig);
db.SENTINEL = client.SENTINEL.map(convertLoadOutConfig);
db.ARCHWING = client.ARCHWING.map(convertLoadOutConfig);
db.NORMAL_PVP = client.NORMAL_PVP.map(convertLoadOutConfig);
db.LUNARO = client.LUNARO.map(convertLoadOutConfig);
db.OPERATOR = client.OPERATOR.map(convertLoadOutConfig);
db.KDRIVE = client.KDRIVE.map(convertLoadOutConfig);
db.DATAKNIFE = client.DATAKNIFE.map(convertLoadOutConfig);
db.MECH = client.MECH.map(convertLoadOutConfig);
db.OPERATOR_ADULT = client.OPERATOR_ADULT.map(convertLoadOutConfig);
db.DRIFTER = client.DRIFTER.map(convertLoadOutConfig);
};

View File

@ -78,8 +78,11 @@ export interface IEquipmentSelection {
hide?: boolean;
}
export interface IEquipmentClient extends Omit<IEquipmentDatabase, "_id" | "UpgradesExpiry"> {
export interface IEquipmentClient
extends Omit<IEquipmentDatabase, "_id" | "InfestationDate" | "Expiry" | "UpgradesExpiry"> {
ItemId: IOid;
InfestationDate?: IMongoDate;
Expiry?: IMongoDate;
UpgradesExpiry?: IMongoDate;
}
@ -106,12 +109,12 @@ export interface IEquipmentDatabase {
CustomizationSlotPurchases?: number;
UpgradeType?: string;
UpgradeFingerprint?: string;
InfestationDate?: IMongoDate;
InfestationDate?: Date;
InfestationDays?: number;
InfestationType?: string;
ModularParts?: string[];
UnlockLevel?: number;
Expiry?: IMongoDate;
Expiry?: Date;
SkillTree?: string;
OffensiveUpgrade?: string;
DefensiveUpgrade?: string;

View File

@ -7,12 +7,14 @@ import {
IItemConfig,
IOperatorConfigClient,
IEquipmentSelection,
IEquipmentDatabase
IEquipmentDatabase,
IEquipmentClient,
IOperatorConfigDatabase
} from "@/src/types/inventoryTypes/commonInventoryTypes";
export interface IInventoryDatabase
extends Omit<
IInventoryResponse,
IInventoryClient,
| "TrainingDate"
| "LoadOutPresets"
| "Mailbox"
@ -23,6 +25,15 @@ export interface IInventoryDatabase
| "BlessingCooldown"
| "Ships"
| "WeaponSkins"
| "Upgrades"
| "CrewShipSalvagedWeaponSkins"
| "CrewShipWeaponSkins"
| "OperatorLoadOuts"
| "AdultOperatorLoadOuts"
| "CrewShips"
| "InfestedFoundry"
| "DialogueHistory"
| TEquipmentKey
> {
accountOwnerId: Types.ObjectId;
Created: Date;
@ -35,6 +46,28 @@ export interface IInventoryDatabase
BlessingCooldown: Date;
Ships: Types.ObjectId[];
WeaponSkins: IWeaponSkinDatabase[];
Upgrades: IUpgradeDatabase[];
CrewShipSalvagedWeaponSkins: IUpgradeDatabase[];
CrewShipWeaponSkins: IUpgradeDatabase[];
OperatorLoadOuts: IOperatorConfigDatabase[];
AdultOperatorLoadOuts: IOperatorConfigDatabase[];
CrewShips: ICrewShipDatabase[];
InfestedFoundry?: IInfestedFoundryDatabase;
DialogueHistory?: IDialogueHistoryDatabase;
Suits: IEquipmentDatabase[];
LongGuns: IEquipmentDatabase[];
Pistols: IEquipmentDatabase[];
Melee: IEquipmentDatabase[];
SpecialItems: IEquipmentDatabase[];
Sentinels: IEquipmentDatabase[];
SentinelWeapons: IEquipmentDatabase[];
SpaceSuits: IEquipmentDatabase[];
SpaceGuns: IEquipmentDatabase[];
SpaceMelee: IEquipmentDatabase[];
Hoverboards: IEquipmentDatabase[];
OperatorAmps: IEquipmentDatabase[];
MoaPets: IEquipmentDatabase[];
}
export interface IQuestKeyDatabase {
@ -46,12 +79,6 @@ export interface IQuestKeyDatabase {
CompletionDate?: Date;
}
export interface IFocusUpgrades {
ItemType: string;
Level: number;
IsUniversal: boolean;
}
export interface ITypeCount {
ItemType: string;
ItemCount: number;
@ -126,7 +153,21 @@ export interface IDailyAffiliations {
DailyAffiliationHex: number;
}
export interface IInventoryResponse extends IDailyAffiliations {
export interface IInventoryClient extends IDailyAffiliations {
Suits: IEquipmentClient[];
LongGuns: IEquipmentClient[];
Pistols: IEquipmentClient[];
Melee: IEquipmentClient[];
SpecialItems: IEquipmentClient[];
Sentinels: IEquipmentClient[];
SentinelWeapons: IEquipmentClient[];
SpaceSuits: IEquipmentClient[];
SpaceGuns: IEquipmentClient[];
SpaceMelee: IEquipmentClient[];
Hoverboards: IEquipmentClient[];
OperatorAmps: IEquipmentClient[];
MoaPets: IEquipmentClient[];
Horses: IEquipmentDatabase[];
DrifterMelee: IEquipmentDatabase[];
DrifterGuns: IEquipmentDatabase[];
@ -163,17 +204,13 @@ export interface IInventoryResponse extends IDailyAffiliations {
ChallengeProgress: IChallengeProgress[];
RawUpgrades: IRawUpgrade[];
ReceivedStartingGear: boolean;
Suits: IEquipmentDatabase[];
LongGuns: IEquipmentDatabase[];
Pistols: IEquipmentDatabase[];
Melee: IEquipmentDatabase[];
Ships: IShipInventory[];
QuestKeys: IQuestKeyResponse[];
FlavourItems: IFlavourItem[];
Scoops: IEquipmentDatabase[];
TrainingRetriesLeft: number;
LoadOutPresets: ILoadOutPresets;
CurrentLoadOutIds: Array<any[] | IOid>;
CurrentLoadOutIds: IOid[]; // we store it in the database using this representation as well :/
Missions: IMission[];
RandomUpgradesIdentified?: number;
LastRegionPlayed: TSolarMapRegion;
@ -191,7 +228,7 @@ export interface IInventoryResponse extends IDailyAffiliations {
Accolades?: {
Heirloom?: boolean;
};
Upgrades: ICrewShipSalvagedWeaponSkin[];
Upgrades: IUpgradeClient[];
EquippedGear: string[];
DeathMarks: string[];
FusionTreasures: IFusionTreasure[];
@ -213,14 +250,9 @@ export interface IInventoryResponse extends IDailyAffiliations {
Affiliations: IAffiliation[];
QualifyingInvasions: any[];
FactionScores: number[];
SpaceSuits: IEquipmentDatabase[];
SpaceMelee: IEquipmentDatabase[];
SpaceGuns: IEquipmentDatabase[];
ArchwingEnabled: boolean;
PendingSpectreLoadouts?: ISpectreLoadout[];
SpectreLoadouts?: ISpectreLoadout[];
SentinelWeapons: IEquipmentDatabase[];
Sentinels: IEquipmentDatabase[];
EmailItems: ITypeCount[];
CompletedSyndicates: string[];
FocusXP: IFocusXP;
@ -237,13 +269,11 @@ export interface IInventoryResponse extends IDailyAffiliations {
CompletedJobs: ICompletedJob[];
FocusAbility: string;
FocusUpgrades: IFocusUpgrade[];
OperatorAmps: IEquipmentDatabase[];
HasContributedToDojo?: boolean;
HWIDProtectEnabled?: boolean;
KubrowPetPrints: IKubrowPetPrint[];
AlignmentReplay: IAlignment;
PersonalGoalProgress: IPersonalGoalProgress[];
SpecialItems: IEquipmentDatabase[];
ThemeStyle: string;
ThemeBackground: string;
ThemeSounds: string;
@ -252,12 +282,10 @@ export interface IInventoryResponse extends IDailyAffiliations {
LoginMilestoneRewards: string[];
OperatorLoadOuts: IOperatorConfigClient[];
RecentVendorPurchases: Array<number | string>;
Hoverboards: IEquipmentDatabase[];
NodeIntrosCompleted: string[];
GuildId?: IOid;
CompletedJobChains: ICompletedJobChain[];
SeasonChallengeHistory: ISeasonChallenge[];
MoaPets: IEquipmentDatabase[];
EquippedInstrument?: string;
InvasionChainProgress: IInvasionChainProgress[];
DataKnives: IEquipmentDatabase[];
@ -266,18 +294,18 @@ export interface IInventoryResponse extends IDailyAffiliations {
LastNemesisAllySpawnTime?: IMongoDate;
Settings: ISettings;
PersonalTechProjects: IPersonalTechProject[];
CrewShips: ICrewShip[];
CrewShips: ICrewShipClient[];
PlayerSkills: IPlayerSkills;
CrewShipAmmo: IConsumable[];
CrewShipSalvagedWeaponSkins: ICrewShipSalvagedWeaponSkin[];
CrewShipSalvagedWeaponSkins: IUpgradeClient[];
CrewShipWeapons: ICrewShipWeapon[];
CrewShipSalvagedWeapons: ICrewShipWeapon[];
CrewShipWeaponSkins: ICrewShipSalvagedWeaponSkin[];
CrewShipWeaponSkins: IUpgradeClient[];
TradeBannedUntil?: IMongoDate;
PlayedParkourTutorial: boolean;
SubscribedToEmailsPersonalized: number;
MechSuits: IEquipmentDatabase[];
InfestedFoundry?: IInfestedFoundry;
InfestedFoundry?: IInfestedFoundryClient;
BlessingCooldown: IMongoDate;
CrewShipHarnesses: IEquipmentDatabase[];
CrewShipRawSalvage: IConsumable[];
@ -304,7 +332,7 @@ export interface IInventoryResponse extends IDailyAffiliations {
Harvestable: boolean;
DeathSquadable: boolean;
EndlessXP?: IEndlessXpProgress[];
DialogueHistory?: IDialogueHistoryDatabase;
DialogueHistory?: IDialogueHistoryClient;
}
export interface IAffiliation {
@ -415,15 +443,18 @@ export interface ISlots {
Slots: number;
}
export interface ICrewShipSalvagedWeaponSkin {
export interface IUpgradeClient {
ItemType: string;
UpgradeFingerprint?: string;
PendingRerollFingerprint?: string;
ItemId?: IOid;
_id?: Types.ObjectId;
ItemId: IOid;
}
export interface ICrewShip {
export interface IUpgradeDatabase extends Omit<IUpgradeClient, "ItemId"> {
_id: Types.ObjectId;
}
export interface ICrewShipClient {
ItemType: string;
Configs: IItemConfig[];
Weapon?: ICrewShipWeapon;
@ -432,6 +463,10 @@ export interface ICrewShip {
RailjackImage?: IFlavourItem;
CrewMembers?: ICrewShipMembersClient;
ItemId: IOid;
}
export interface ICrewShipDatabase extends Omit<ICrewShipClient, "CrewMembers" | "ItemId"> {
CrewMembers?: ICrewShipMembersDatabase;
_id: Types.ObjectId;
}
@ -535,7 +570,7 @@ export interface IHelminthResource {
RecentlyConvertedResources?: IHelminthFoodRecord[];
}
export interface IInfestedFoundry {
export interface IInfestedFoundryClient {
Name?: string;
Resources?: IHelminthResource[];
Slots?: number;
@ -544,6 +579,12 @@ export interface IInfestedFoundry {
InvigorationIndex?: number;
InvigorationSuitOfferings?: string[];
InvigorationsApplied?: number;
LastConsumedSuit?: IEquipmentClient;
AbilityOverrideUnlockCooldown?: IMongoDate;
}
export interface IInfestedFoundryDatabase
extends Omit<IInfestedFoundryClient, "LastConsumedSuit" | "AbilityOverrideUnlockCooldown"> {
LastConsumedSuit?: IEquipmentDatabase;
AbilityOverrideUnlockCooldown?: Date;
}
@ -636,7 +677,7 @@ export interface ILibraryPersonalProgress {
Completed: boolean;
}
//this needs to be checked against ILoadoutDatabase
// keep in sync with ILoadoutDatabase
export interface ILoadOutPresets {
NORMAL: ILoadoutConfigClient[];
NORMAL_PVP: ILoadoutConfigClient[];
@ -649,6 +690,7 @@ export interface ILoadOutPresets {
DATAKNIFE: ILoadoutConfigClient[];
MECH: ILoadoutConfigClient[];
OPERATOR_ADULT: ILoadoutConfigClient[];
DRIFTER: ILoadoutConfigClient[];
}
export enum FocusSchool {
@ -913,9 +955,10 @@ export interface ITaunt {
export interface IWeaponSkinDatabase {
ItemType: string;
_id: Types.ObjectId;
}
export interface IWeaponSkinClient extends IWeaponSkinDatabase {
export interface IWeaponSkinClient extends Omit<IWeaponSkinDatabase, "_id"> {
ItemId: IOid;
}

View File

@ -1,4 +1,4 @@
import { IInfestedFoundry } from "./inventoryTypes/inventoryTypes";
import { IInfestedFoundryClient } from "./inventoryTypes/inventoryTypes";
export interface IPurchaseRequest {
PurchaseParams: IPurchaseParams;
@ -29,9 +29,9 @@ export interface ICurrencyChanges {
export type IInventoryChanges = {
[_ in SlotNames]?: IBinChanges;
} & ICurrencyChanges & { InfestedFoundry?: IInfestedFoundry } & Record<
} & ICurrencyChanges & { InfestedFoundry?: IInfestedFoundryClient } & Record<
string,
IBinChanges | number | object[] | IInfestedFoundry
IBinChanges | number | object[] | IInfestedFoundryClient
>;
export interface IPurchaseResponse {

View File

@ -54,18 +54,19 @@ export interface IConfigEntry {
export interface ILoadoutClient extends Omit<ILoadoutDatabase, "_id" | "loadoutOwnerId"> {}
// keep in sync with ILoadOutPresets
export interface ILoadoutDatabase {
NORMAL: ILoadoutEntry;
SENTINEL: ILoadoutEntry;
ARCHWING: ILoadoutEntry;
NORMAL_PVP: ILoadoutEntry;
LUNARO: ILoadoutEntry;
OPERATOR: ILoadoutEntry;
KDRIVE: ILoadoutEntry;
DATAKNIFE: ILoadoutEntry;
MECH: ILoadoutEntry;
OPERATOR_ADULT: ILoadoutEntry;
DRIFTER: ILoadoutEntry;
NORMAL: ILoadoutConfigDatabase[];
SENTINEL: ILoadoutConfigDatabase[];
ARCHWING: ILoadoutConfigDatabase[];
NORMAL_PVP: ILoadoutConfigDatabase[];
LUNARO: ILoadoutConfigDatabase[];
OPERATOR: ILoadoutConfigDatabase[];
KDRIVE: ILoadoutConfigDatabase[];
DATAKNIFE: ILoadoutConfigDatabase[];
MECH: ILoadoutConfigDatabase[];
OPERATOR_ADULT: ILoadoutConfigDatabase[];
DRIFTER: ILoadoutConfigDatabase[];
_id: Types.ObjectId;
loadoutOwnerId: Types.ObjectId;
}

View File

@ -64,6 +64,9 @@
<li class="nav-item">
<a class="nav-link" href="/webui/cheats" data-bs-dismiss="offcanvas" data-bs-target="#sidebar">Cheats</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/webui/import" data-bs-dismiss="offcanvas" data-bs-target="#sidebar">Import</a>
</li>
</ul>
</div>
</div>
@ -493,6 +496,11 @@
</div>
</div>
</div>
<div data-route="/webui/import" data-title="Import | OpenWF WebUI">
<p>You can provide a full or partial inventory response (client respresentation) here. All fields that are supported by the importer <b>will be overwritten</b> in your account.</p>
<textarea class="form-control" id="import-inventory"></textarea>
<button class="btn btn-primary mt-3" onclick="doImport();">Submit</button>
</div>
</div>
</div>
<datalist id="datalist-Suits"></datalist>

View File

@ -215,7 +215,12 @@ function updateInventory() {
const td = document.createElement("td");
td.textContent = itemMap[item.ItemType]?.name ?? item.ItemType;
if (item.ItemName) {
td.textContent = item.ItemName + " (" + td.textContent + ")";
const pipeIndex = item.ItemName.indexOf("|");
if (pipeIndex != -1) {
td.textContent = item.ItemName.substr(1 + pipeIndex) + " " + td.textContent;
} else {
td.textContent = item.ItemName + " (" + td.textContent + ")";
}
}
if (item.ModularParts && item.ModularParts.length) {
td.textContent += " [";
@ -1083,3 +1088,18 @@ function doPopArchonCrystalUpgrade(type) {
});
});
}
function doImport() {
revalidateAuthz(() => {
$.post({
url: "/custom/import?" + window.authz,
contentType: "text/plain",
data: JSON.stringify({
inventory: JSON.parse($("#import-inventory").val())
})
}).then(function () {
alert("Successfully imported.");
updateInventory();
});
});
}