chore: avoid using client oid representation in database (#2685)
All checks were successful
Build / build (push) Successful in 1m45s
Build Docker image / docker-amd64 (push) Successful in 1m5s
Build Docker image / docker-arm64 (push) Successful in 1m6s

Reviewed-on: #2685
Co-authored-by: Sainan <63328889+Sainan@users.noreply.github.com>
Co-committed-by: Sainan <63328889+Sainan@users.noreply.github.com>
This commit is contained in:
Sainan 2025-08-23 12:56:41 -07:00 committed by Sainan
parent 2c43d897c0
commit dfd1fb834b
12 changed files with 191 additions and 106 deletions

View File

@ -1,4 +1,4 @@
import { version_compare } from "@/src/helpers/inventoryHelpers"; import { fromDbOid, version_compare } from "@/src/helpers/inventoryHelpers";
import { import {
antivirusMods, antivirusMods,
decodeNemesisGuess, decodeNemesisGuess,
@ -130,7 +130,9 @@ export const nemesisController: RequestHandler = async (req, res) => {
if (result1 == GUESS_CORRECT || result2 == GUESS_CORRECT || result3 == GUESS_CORRECT) { if (result1 == GUESS_CORRECT || result2 == GUESS_CORRECT || result3 == GUESS_CORRECT) {
let antivirusGain = 5; let antivirusGain = 5;
const loadout = (await Loadout.findById(inventory.LoadOutPresets, "DATAKNIFE"))!; const loadout = (await Loadout.findById(inventory.LoadOutPresets, "DATAKNIFE"))!;
const dataknifeLoadout = loadout.DATAKNIFE.id(inventory.CurrentLoadOutIds[LoadoutIndex.DATAKNIFE].$oid); const dataknifeLoadout = loadout.DATAKNIFE.id(
fromDbOid(inventory.CurrentLoadOutIds[LoadoutIndex.DATAKNIFE])
);
const dataknifeConfigIndex = dataknifeLoadout?.s?.mod ?? 0; const dataknifeConfigIndex = dataknifeLoadout?.s?.mod ?? 0;
const dataknifeUpgrades = inventory.DataKnives[0].Configs[dataknifeConfigIndex].Upgrades!; const dataknifeUpgrades = inventory.DataKnives[0].Configs[dataknifeConfigIndex].Upgrades!;
for (const upgrade of body.knife!.AttachedUpgrades) { for (const upgrade of body.knife!.AttachedUpgrades) {
@ -219,7 +221,7 @@ export const nemesisController: RequestHandler = async (req, res) => {
// Subtract a charge from all requiem mods installed on parazon // Subtract a charge from all requiem mods installed on parazon
const loadout = (await Loadout.findById(inventory.LoadOutPresets, "DATAKNIFE"))!; const loadout = (await Loadout.findById(inventory.LoadOutPresets, "DATAKNIFE"))!;
const dataknifeLoadout = loadout.DATAKNIFE.id( const dataknifeLoadout = loadout.DATAKNIFE.id(
inventory.CurrentLoadOutIds[LoadoutIndex.DATAKNIFE].$oid fromDbOid(inventory.CurrentLoadOutIds[LoadoutIndex.DATAKNIFE])
); );
const dataknifeConfigIndex = dataknifeLoadout?.s?.mod ?? 0; const dataknifeConfigIndex = dataknifeLoadout?.s?.mod ?? 0;
const dataknifeUpgrades = inventory.DataKnives[0].Configs[dataknifeConfigIndex].Upgrades!; const dataknifeUpgrades = inventory.DataKnives[0].Configs[dataknifeConfigIndex].Upgrades!;

View File

@ -1,4 +1,4 @@
import { toMongoDate, toOid } from "@/src/helpers/inventoryHelpers"; import { fromDbOid, toMongoDate, toOid } from "@/src/helpers/inventoryHelpers";
import { Guild, GuildMember, TGuildDatabaseDocument } from "@/src/models/guildModel"; import { Guild, GuildMember, TGuildDatabaseDocument } from "@/src/models/guildModel";
import { Inventory, TInventoryDatabaseDocument } from "@/src/models/inventoryModels/inventoryModel"; import { Inventory, TInventoryDatabaseDocument } from "@/src/models/inventoryModels/inventoryModel";
import { Loadout } from "@/src/models/inventoryModels/loadoutModel"; import { Loadout } from "@/src/models/inventoryModels/loadoutModel";
@ -13,7 +13,8 @@ import {
IDailyAffiliations, IDailyAffiliations,
IMission, IMission,
IPlayerSkills, IPlayerSkills,
ITypeXPItem ITypeXPItem,
LoadoutIndex
} from "@/src/types/inventoryTypes/inventoryTypes"; } from "@/src/types/inventoryTypes/inventoryTypes";
import { RequestHandler } from "express"; import { RequestHandler } from "express";
import { catBreadHash, getJSONfromString } from "@/src/helpers/stringHelpers"; import { catBreadHash, getJSONfromString } from "@/src/helpers/stringHelpers";
@ -298,30 +299,32 @@ const populateLoadout = async (
): Promise<void> => { ): Promise<void> => {
if (inventory.CurrentLoadOutIds.length) { if (inventory.CurrentLoadOutIds.length) {
const loadout = (await Loadout.findById(inventory.LoadOutPresets, "NORMAL"))!; const loadout = (await Loadout.findById(inventory.LoadOutPresets, "NORMAL"))!;
result.LoadOutPreset = loadout.NORMAL.id(inventory.CurrentLoadOutIds[0].$oid)!.toJSON<ILoadoutConfigClient>(); result.LoadOutPreset = loadout.NORMAL.id(
fromDbOid(inventory.CurrentLoadOutIds[LoadoutIndex.NORMAL])
)!.toJSON<ILoadoutConfigClient>();
result.LoadOutPreset.ItemId = undefined; result.LoadOutPreset.ItemId = undefined;
const skins = new Set<string>(); const skins = new Set<string>();
if (result.LoadOutPreset.s) { if (result.LoadOutPreset.s?.ItemId) {
result.LoadOutInventory.Suits = [ result.LoadOutInventory.Suits = [
inventory.Suits.id(result.LoadOutPreset.s.ItemId.$oid)!.toJSON<IEquipmentClient>() inventory.Suits.id(fromDbOid(result.LoadOutPreset.s.ItemId))!.toJSON<IEquipmentClient>()
]; ];
resolveAndCollectSkins(inventory, skins, result.LoadOutInventory.Suits[0]); resolveAndCollectSkins(inventory, skins, result.LoadOutInventory.Suits[0]);
} }
if (result.LoadOutPreset.p) { if (result.LoadOutPreset.p?.ItemId) {
result.LoadOutInventory.Pistols = [ result.LoadOutInventory.Pistols = [
inventory.Pistols.id(result.LoadOutPreset.p.ItemId.$oid)!.toJSON<IEquipmentClient>() inventory.Pistols.id(fromDbOid(result.LoadOutPreset.p.ItemId))!.toJSON<IEquipmentClient>()
]; ];
resolveAndCollectSkins(inventory, skins, result.LoadOutInventory.Pistols[0]); resolveAndCollectSkins(inventory, skins, result.LoadOutInventory.Pistols[0]);
} }
if (result.LoadOutPreset.l) { if (result.LoadOutPreset.l?.ItemId) {
result.LoadOutInventory.LongGuns = [ result.LoadOutInventory.LongGuns = [
inventory.LongGuns.id(result.LoadOutPreset.l.ItemId.$oid)!.toJSON<IEquipmentClient>() inventory.LongGuns.id(fromDbOid(result.LoadOutPreset.l.ItemId))!.toJSON<IEquipmentClient>()
]; ];
resolveAndCollectSkins(inventory, skins, result.LoadOutInventory.LongGuns[0]); resolveAndCollectSkins(inventory, skins, result.LoadOutInventory.LongGuns[0]);
} }
if (result.LoadOutPreset.m) { if (result.LoadOutPreset.m?.ItemId) {
result.LoadOutInventory.Melee = [ result.LoadOutInventory.Melee = [
inventory.Melee.id(result.LoadOutPreset.m.ItemId.$oid)!.toJSON<IEquipmentClient>() inventory.Melee.id(fromDbOid(result.LoadOutPreset.m.ItemId))!.toJSON<IEquipmentClient>()
]; ];
resolveAndCollectSkins(inventory, skins, result.LoadOutInventory.Melee[0]); resolveAndCollectSkins(inventory, skins, result.LoadOutInventory.Melee[0]);
} }

View File

@ -44,6 +44,11 @@ export const fromOid = (oid: IOidWithLegacySupport): string => {
return (oid.$oid ?? oid.$id)!; return (oid.$oid ?? oid.$id)!;
}; };
// For oids that may have been stored incorrectly
export const fromDbOid = (x: Types.ObjectId | IOid): Types.ObjectId => {
return "$oid" in x ? new Types.ObjectId(x.$oid) : x;
};
export const toMongoDate = (date: Date): IMongoDate => { export const toMongoDate = (date: Date): IMongoDate => {
return { $date: { $numberLong: date.getTime().toString() } }; return { $date: { $numberLong: date.getTime().toString() } };
}; };

View File

@ -100,8 +100,8 @@ import {
IOperatorConfigDatabase, IOperatorConfigDatabase,
IPolarity IPolarity
} from "@/src/types/inventoryTypes/commonInventoryTypes"; } from "@/src/types/inventoryTypes/commonInventoryTypes";
import { toMongoDate, toOid } from "@/src/helpers/inventoryHelpers"; import { fromDbOid, toMongoDate, toOid } from "@/src/helpers/inventoryHelpers";
import { EquipmentSelectionSchema, oidSchema } from "@/src/models/inventoryModels/loadoutModel"; import { EquipmentSelectionSchema } from "@/src/models/inventoryModels/loadoutModel";
import { ICountedStoreItem } from "warframe-public-export-plus"; import { ICountedStoreItem } from "warframe-public-export-plus";
import { colorSchema, shipCustomizationSchema } from "@/src/models/commonModel"; import { colorSchema, shipCustomizationSchema } from "@/src/models/commonModel";
import { import {
@ -109,8 +109,8 @@ import {
ICrewShipMemberClient, ICrewShipMemberClient,
ICrewShipMemberDatabase, ICrewShipMemberDatabase,
ICrewShipMembersDatabase, ICrewShipMembersDatabase,
ICrewShipWeapon, ICrewShipWeaponDatabase,
ICrewShipWeaponEmplacements, ICrewShipWeaponEmplacementsDatabase,
IEquipmentClient, IEquipmentClient,
IEquipmentDatabase, IEquipmentDatabase,
IKubrowPetDetailsClient, IKubrowPetDetailsClient,
@ -847,7 +847,6 @@ const endlessXpProgressSchema = new Schema<IEndlessXpProgressDatabase>(
}, },
{ _id: false } { _id: false }
); );
endlessXpProgressSchema.set("toJSON", { endlessXpProgressSchema.set("toJSON", {
transform(_doc, ret: Record<string, any>) { transform(_doc, ret: Record<string, any>) {
const db = ret as IEndlessXpProgressDatabase; const db = ret as IEndlessXpProgressDatabase;
@ -861,7 +860,8 @@ endlessXpProgressSchema.set("toJSON", {
} }
} }
}); });
const crewShipWeaponEmplacementsSchema = new Schema<ICrewShipWeaponEmplacements>(
const crewShipWeaponEmplacementsSchema = new Schema<ICrewShipWeaponEmplacementsDatabase>(
{ {
PRIMARY_A: EquipmentSelectionSchema, PRIMARY_A: EquipmentSelectionSchema,
PRIMARY_B: EquipmentSelectionSchema, PRIMARY_B: EquipmentSelectionSchema,
@ -871,7 +871,7 @@ const crewShipWeaponEmplacementsSchema = new Schema<ICrewShipWeaponEmplacements>
{ _id: false } { _id: false }
); );
const crewShipWeaponSchema = new Schema<ICrewShipWeapon>( const crewShipWeaponSchema = new Schema<ICrewShipWeaponDatabase>(
{ {
PILOT: crewShipWeaponEmplacementsSchema, PILOT: crewShipWeaponEmplacementsSchema,
PORT_GUNS: crewShipWeaponEmplacementsSchema, PORT_GUNS: crewShipWeaponEmplacementsSchema,
@ -1748,7 +1748,7 @@ const inventorySchema = new Schema<IInventoryDatabase, InventoryDocumentProps>(
HasContributedToDojo: Boolean, HasContributedToDojo: Boolean,
HWIDProtectEnabled: Boolean, HWIDProtectEnabled: Boolean,
LoadOutPresets: { type: Schema.Types.ObjectId, ref: "Loadout" }, LoadOutPresets: { type: Schema.Types.ObjectId, ref: "Loadout" },
CurrentLoadOutIds: [oidSchema], CurrentLoadOutIds: [Schema.Types.Mixed], // should be Types.ObjectId[] but might be IOid[] because of old commits
RandomUpgradesIdentified: Number, RandomUpgradesIdentified: Number,
BountyScore: Number, BountyScore: Number,
//ChallengeInstanceStates: [Schema.Types.Mixed], //ChallengeInstanceStates: [Schema.Types.Mixed],
@ -1808,12 +1808,15 @@ inventorySchema.set("toJSON", {
const inventoryDatabase = returnedObject as Partial<IInventoryDatabase>; const inventoryDatabase = returnedObject as Partial<IInventoryDatabase>;
const inventoryResponse = returnedObject as IInventoryClient; const inventoryResponse = returnedObject as IInventoryClient;
if (inventoryDatabase.TrainingDate) {
inventoryResponse.TrainingDate = toMongoDate(inventoryDatabase.TrainingDate);
}
if (inventoryDatabase.Created) { if (inventoryDatabase.Created) {
inventoryResponse.Created = toMongoDate(inventoryDatabase.Created); inventoryResponse.Created = toMongoDate(inventoryDatabase.Created);
} }
if (inventoryDatabase.CurrentLoadOutIds) {
inventoryResponse.CurrentLoadOutIds = inventoryDatabase.CurrentLoadOutIds.map(x => toOid(fromDbOid(x)));
}
if (inventoryDatabase.TrainingDate) {
inventoryResponse.TrainingDate = toMongoDate(inventoryDatabase.TrainingDate);
}
if (inventoryDatabase.GuildId) { if (inventoryDatabase.GuildId) {
inventoryResponse.GuildId = toOid(inventoryDatabase.GuildId); inventoryResponse.GuildId = toOid(inventoryDatabase.GuildId);
} }

View File

@ -1,21 +1,13 @@
import { fromDbOid, toOid } from "@/src/helpers/inventoryHelpers";
import { IOid } from "@/src/types/commonTypes"; import { IOid } from "@/src/types/commonTypes";
import { IEquipmentSelection } from "@/src/types/equipmentTypes"; import { IEquipmentSelectionClient, IEquipmentSelectionDatabase } from "@/src/types/equipmentTypes";
import { ILoadoutConfigDatabase, ILoadoutDatabase } from "@/src/types/saveLoadoutTypes"; import { ILoadoutConfigDatabase, ILoadoutDatabase } from "@/src/types/saveLoadoutTypes";
import { Document, Model, Schema, Types, model } from "mongoose"; import { Document, Model, Schema, Types, model } from "mongoose";
export const oidSchema = new Schema<IOid>(
{
$oid: String
},
{
_id: false
}
);
//create a mongoose schema based on interface M //create a mongoose schema based on interface M
export const EquipmentSelectionSchema = new Schema<IEquipmentSelection>( export const EquipmentSelectionSchema = new Schema<IEquipmentSelectionDatabase>(
{ {
ItemId: oidSchema, ItemId: Schema.Types.Mixed, // should be Types.ObjectId but might be IOid because of old commits
mod: Number, mod: Number,
cus: Number, cus: Number,
hide: Boolean hide: Boolean
@ -24,6 +16,17 @@ export const EquipmentSelectionSchema = new Schema<IEquipmentSelection>(
_id: false _id: false
} }
); );
EquipmentSelectionSchema.set("toJSON", {
virtuals: true,
transform(_doc, ret: Record<string, any>) {
const db = ret as IEquipmentSelectionDatabase;
const client = ret as IEquipmentSelectionClient;
if (db.ItemId) {
client.ItemId = toOid(fromDbOid(db.ItemId));
}
}
});
export const loadoutConfigSchema = new Schema<ILoadoutConfigDatabase>( export const loadoutConfigSchema = new Schema<ILoadoutConfigDatabase>(
{ {

View File

@ -39,8 +39,14 @@ import {
ICrewShipMemberDatabase, ICrewShipMemberDatabase,
ICrewShipMembersClient, ICrewShipMembersClient,
ICrewShipMembersDatabase, ICrewShipMembersDatabase,
ICrewShipWeaponClient,
ICrewShipWeaponDatabase,
ICrewShipWeaponEmplacementsClient,
ICrewShipWeaponEmplacementsDatabase,
IEquipmentClient, IEquipmentClient,
IEquipmentDatabase, IEquipmentDatabase,
IEquipmentSelectionClient,
IEquipmentSelectionDatabase,
IKubrowPetDetailsClient, IKubrowPetDetailsClient,
IKubrowPetDetailsDatabase IKubrowPetDetailsDatabase
} from "@/src/types/equipmentTypes"; } from "@/src/types/equipmentTypes";
@ -84,7 +90,8 @@ const convertEquipment = (client: IEquipmentClient): IEquipmentDatabase => {
Expiry: convertOptionalDate(client.Expiry), Expiry: convertOptionalDate(client.Expiry),
UpgradesExpiry: convertOptionalDate(client.UpgradesExpiry), UpgradesExpiry: convertOptionalDate(client.UpgradesExpiry),
UmbraDate: convertOptionalDate(client.UmbraDate), UmbraDate: convertOptionalDate(client.UmbraDate),
CrewMembers: client.CrewMembers ? convertCrewShipMembers(client.CrewMembers) : undefined, Weapon: client.Weapon ? importCrewShipWeapon(client.Weapon) : undefined,
CrewMembers: client.CrewMembers ? importCrewShipMembers(client.CrewMembers) : undefined,
Details: client.Details ? convertKubrowDetails(client.Details) : undefined, Details: client.Details ? convertKubrowDetails(client.Details) : undefined,
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
Configs: client.Configs Configs: client.Configs
@ -133,14 +140,43 @@ const replaceSlots = (db: ISlots, client: ISlots): void => {
db.Slots = client.Slots; db.Slots = client.Slots;
}; };
export const importCrewMemberId = (crewMemberId: ICrewShipMemberClient): ICrewShipMemberDatabase => { const convertEquipmentSelection = (es: IEquipmentSelectionClient): IEquipmentSelectionDatabase => {
const { ItemId, ...rest } = es;
return {
...rest,
ItemId: ItemId ? new Types.ObjectId(ItemId.$oid) : undefined
};
};
const convertCrewShipWeaponEmplacements = (
obj: ICrewShipWeaponEmplacementsClient
): ICrewShipWeaponEmplacementsDatabase => {
return {
PRIMARY_A: obj.PRIMARY_A ? convertEquipmentSelection(obj.PRIMARY_A) : undefined,
PRIMARY_B: obj.PRIMARY_B ? convertEquipmentSelection(obj.PRIMARY_B) : undefined,
SECONDARY_A: obj.SECONDARY_A ? convertEquipmentSelection(obj.SECONDARY_A) : undefined,
SECONDARY_B: obj.SECONDARY_B ? convertEquipmentSelection(obj.SECONDARY_B) : undefined
};
};
export const importCrewShipWeapon = (weapon: ICrewShipWeaponClient): ICrewShipWeaponDatabase => {
return {
PILOT: weapon.PILOT ? convertCrewShipWeaponEmplacements(weapon.PILOT) : undefined,
PORT_GUNS: weapon.PORT_GUNS ? convertCrewShipWeaponEmplacements(weapon.PORT_GUNS) : undefined,
STARBOARD_GUNS: weapon.STARBOARD_GUNS ? convertCrewShipWeaponEmplacements(weapon.STARBOARD_GUNS) : undefined,
ARTILLERY: weapon.ARTILLERY ? convertCrewShipWeaponEmplacements(weapon.ARTILLERY) : undefined,
SCANNER: weapon.SCANNER ? convertCrewShipWeaponEmplacements(weapon.SCANNER) : undefined
};
};
const importCrewMemberId = (crewMemberId: ICrewShipMemberClient): ICrewShipMemberDatabase => {
if (crewMemberId.ItemId) { if (crewMemberId.ItemId) {
return { ItemId: new Types.ObjectId(crewMemberId.ItemId.$oid) }; return { ItemId: new Types.ObjectId(crewMemberId.ItemId.$oid) };
} }
return { NemesisFingerprint: BigInt(crewMemberId.NemesisFingerprint ?? 0) }; return { NemesisFingerprint: BigInt(crewMemberId.NemesisFingerprint ?? 0) };
}; };
const convertCrewShipMembers = (client: ICrewShipMembersClient): ICrewShipMembersDatabase => { export const importCrewShipMembers = (client: ICrewShipMembersClient): ICrewShipMembersDatabase => {
return { return {
SLOT_A: client.SLOT_A ? importCrewMemberId(client.SLOT_A) : undefined, SLOT_A: client.SLOT_A ? importCrewMemberId(client.SLOT_A) : undefined,
SLOT_B: client.SLOT_B ? importCrewMemberId(client.SLOT_B) : undefined, SLOT_B: client.SLOT_B ? importCrewMemberId(client.SLOT_B) : undefined,
@ -429,34 +465,40 @@ export const importInventory = (db: TInventoryDatabaseDocument, client: Partial<
} }
}; };
const convertLoadOutConfig = (client: ILoadoutConfigClient): ILoadoutConfigDatabase => { export const importLoadOutConfig = (client: ILoadoutConfigClient): ILoadoutConfigDatabase => {
const { ItemId, ...rest } = client; const { ItemId, ...rest } = client;
return { return {
...rest, ...rest,
_id: new Types.ObjectId(ItemId.$oid) _id: new Types.ObjectId(ItemId.$oid),
s: client.s ? convertEquipmentSelection(client.s) : undefined,
p: client.p ? convertEquipmentSelection(client.p) : undefined,
l: client.l ? convertEquipmentSelection(client.l) : undefined,
m: client.m ? convertEquipmentSelection(client.m) : undefined,
h: client.h ? convertEquipmentSelection(client.h) : undefined,
a: client.a ? convertEquipmentSelection(client.a) : undefined
}; };
}; };
export const importLoadOutPresets = (db: ILoadoutDatabase, client: ILoadOutPresets): void => { export const importLoadOutPresets = (db: ILoadoutDatabase, client: ILoadOutPresets): void => {
db.NORMAL = client.NORMAL.map(convertLoadOutConfig); db.NORMAL = client.NORMAL.map(importLoadOutConfig);
db.SENTINEL = client.SENTINEL.map(convertLoadOutConfig); db.SENTINEL = client.SENTINEL.map(importLoadOutConfig);
db.ARCHWING = client.ARCHWING.map(convertLoadOutConfig); db.ARCHWING = client.ARCHWING.map(importLoadOutConfig);
db.NORMAL_PVP = client.NORMAL_PVP.map(convertLoadOutConfig); db.NORMAL_PVP = client.NORMAL_PVP.map(importLoadOutConfig);
db.LUNARO = client.LUNARO.map(convertLoadOutConfig); db.LUNARO = client.LUNARO.map(importLoadOutConfig);
db.OPERATOR = client.OPERATOR.map(convertLoadOutConfig); db.OPERATOR = client.OPERATOR.map(importLoadOutConfig);
db.GEAR = client.GEAR?.map(convertLoadOutConfig); db.GEAR = client.GEAR?.map(importLoadOutConfig);
db.KDRIVE = client.KDRIVE.map(convertLoadOutConfig); db.KDRIVE = client.KDRIVE.map(importLoadOutConfig);
db.DATAKNIFE = client.DATAKNIFE.map(convertLoadOutConfig); db.DATAKNIFE = client.DATAKNIFE.map(importLoadOutConfig);
db.MECH = client.MECH.map(convertLoadOutConfig); db.MECH = client.MECH.map(importLoadOutConfig);
db.OPERATOR_ADULT = client.OPERATOR_ADULT.map(convertLoadOutConfig); db.OPERATOR_ADULT = client.OPERATOR_ADULT.map(importLoadOutConfig);
db.DRIFTER = client.DRIFTER.map(convertLoadOutConfig); db.DRIFTER = client.DRIFTER.map(importLoadOutConfig);
}; };
export const convertCustomizationInfo = (client: ICustomizationInfoClient): ICustomizationInfoDatabase => { export const convertCustomizationInfo = (client: ICustomizationInfoClient): ICustomizationInfoDatabase => {
return { return {
...client, ...client,
LoadOutPreset: client.LoadOutPreset ? convertLoadOutConfig(client.LoadOutPreset) : undefined, LoadOutPreset: client.LoadOutPreset ? importLoadOutConfig(client.LoadOutPreset) : undefined,
VehiclePreset: client.VehiclePreset ? convertLoadOutConfig(client.VehiclePreset) : undefined VehiclePreset: client.VehiclePreset ? importLoadOutConfig(client.VehiclePreset) : undefined
}; };
}; };

View File

@ -63,6 +63,7 @@ import {
import { createShip } from "@/src/services/shipService"; import { createShip } from "@/src/services/shipService";
import { import {
catbrowDetails, catbrowDetails,
fromDbOid,
fromMongoDate, fromMongoDate,
fromOid, fromOid,
kubrowDetails, kubrowDetails,
@ -2232,6 +2233,8 @@ export const setupKahlSyndicate = (inventory: TInventoryDatabaseDocument): void
}; };
export const cleanupInventory = (inventory: TInventoryDatabaseDocument): void => { export const cleanupInventory = (inventory: TInventoryDatabaseDocument): void => {
inventory.CurrentLoadOutIds = inventory.CurrentLoadOutIds.map(fromDbOid);
let index = inventory.MiscItems.findIndex(x => x.ItemType == ""); let index = inventory.MiscItems.findIndex(x => x.ItemType == "");
if (index != -1) { if (index != -1) {
inventory.MiscItems.splice(index, 1); inventory.MiscItems.splice(index, 1);

View File

@ -65,7 +65,6 @@ import {
getNemesisPasscode getNemesisPasscode
} from "@/src/helpers/nemesisHelpers"; } from "@/src/helpers/nemesisHelpers";
import { Loadout } from "@/src/models/inventoryModels/loadoutModel"; import { Loadout } from "@/src/models/inventoryModels/loadoutModel";
import { ILoadoutConfigDatabase } from "@/src/types/saveLoadoutTypes";
import { import {
getLiteSortie, getLiteSortie,
getSortie, getSortie,
@ -84,6 +83,7 @@ import { ITypeCount } from "@/src/types/commonTypes";
import { IEquipmentClient } from "@/src/types/equipmentTypes"; import { IEquipmentClient } from "@/src/types/equipmentTypes";
import { Guild } from "@/src/models/guildModel"; import { Guild } from "@/src/models/guildModel";
import { handleGuildGoalProgress } from "@/src/services/guildService"; import { handleGuildGoalProgress } from "@/src/services/guildService";
import { importLoadOutConfig } from "@/src/services/importService";
const getRotations = (rewardInfo: IRewardInfo, tierOverride?: number): number[] => { const getRotations = (rewardInfo: IRewardInfo, tierOverride?: number): number[] => {
// Disruption missions just tell us (https://onlyg.it/OpenWF/SpaceNinjaServer/issues/2599) // Disruption missions just tell us (https://onlyg.it/OpenWF/SpaceNinjaServer/issues/2599)
@ -602,11 +602,7 @@ export const addMissionInventoryUpdates = async (
const loadout = await Loadout.findOne({ loadoutOwnerId: inventory.accountOwnerId }); const loadout = await Loadout.findOne({ loadoutOwnerId: inventory.accountOwnerId });
if (loadout) { if (loadout) {
for (const [loadoutId, loadoutConfig] of Object.entries(value.LoadOuts.NORMAL)) { for (const [loadoutId, loadoutConfig] of Object.entries(value.LoadOuts.NORMAL)) {
const { ItemId, ...loadoutConfigItemIdRemoved } = loadoutConfig; const loadoutConfigDatabase = importLoadOutConfig(loadoutConfig);
const loadoutConfigDatabase: ILoadoutConfigDatabase = {
_id: new Types.ObjectId(ItemId.$oid),
...loadoutConfigItemIdRemoved
};
const dbConfig = loadout.NORMAL.id(loadoutId); const dbConfig = loadout.NORMAL.id(loadoutId);
if (dbConfig) { if (dbConfig) {
dbConfig.overwrite(loadoutConfigDatabase); dbConfig.overwrite(loadoutConfigDatabase);

View File

@ -2,7 +2,6 @@ import {
IItemEntry, IItemEntry,
ILoadoutClient, ILoadoutClient,
ILoadoutEntry, ILoadoutEntry,
ILoadoutConfigDatabase,
IOperatorConfigEntry, IOperatorConfigEntry,
ISaveLoadoutRequestNoUpgradeVer ISaveLoadoutRequestNoUpgradeVer
} from "@/src/types/saveLoadoutTypes"; } from "@/src/types/saveLoadoutTypes";
@ -14,7 +13,7 @@ import { isEmptyObject } from "@/src/helpers/general";
import { logger } from "@/src/utils/logger"; import { logger } from "@/src/utils/logger";
import { equipmentKeys, TEquipmentKey } from "@/src/types/inventoryTypes/inventoryTypes"; import { equipmentKeys, TEquipmentKey } from "@/src/types/inventoryTypes/inventoryTypes";
import { IItemConfig } from "@/src/types/inventoryTypes/commonInventoryTypes"; import { IItemConfig } from "@/src/types/inventoryTypes/commonInventoryTypes";
import { importCrewMemberId } from "@/src/services/importService"; import { importCrewShipMembers, importCrewShipWeapon, importLoadOutConfig } from "@/src/services/importService";
//TODO: setup default items on account creation or like originally in giveStartingItems.php //TODO: setup default items on account creation or like originally in giveStartingItems.php
@ -88,20 +87,17 @@ export const handleInventoryItemConfigChange = async (
const oldLoadoutConfig = loadout[loadoutSlot].id(loadoutId); const oldLoadoutConfig = loadout[loadoutSlot].id(loadoutId);
const { ItemId, ...loadoutConfigItemIdRemoved } = loadoutConfig; const loadoutConfigDatabase = importLoadOutConfig(loadoutConfig);
const loadoutConfigDatabase: ILoadoutConfigDatabase = {
_id: new Types.ObjectId(ItemId.$oid),
...loadoutConfigItemIdRemoved
};
// if no config with this id exists, create a new one // if no config with this id exists, create a new one
if (!oldLoadoutConfig) { if (!oldLoadoutConfig) {
//save the new object id and assign it for every ffff return at the end //save the new object id and assign it for every ffff return at the end
if (ItemId.$oid === "ffffffffffffffffffffffff") { if (loadoutConfigDatabase._id.toString() === "ffffffffffffffffffffffff") {
if (!newLoadoutId) { if (!newLoadoutId) {
newLoadoutId = new Types.ObjectId(); newLoadoutId = new Types.ObjectId();
} }
loadout[loadoutSlot].push({ _id: newLoadoutId, ...loadoutConfigItemIdRemoved }); loadoutConfigDatabase._id = newLoadoutId;
loadout[loadoutSlot].push(loadoutConfigDatabase);
continue; continue;
} }
@ -218,15 +214,11 @@ export const handleInventoryItemConfigChange = async (
if ("Customization" in itemConfigEntries) { if ("Customization" in itemConfigEntries) {
inventoryItem.Customization = itemConfigEntries.Customization; inventoryItem.Customization = itemConfigEntries.Customization;
} }
if ("Weapon" in itemConfigEntries) { if (itemConfigEntries.Weapon) {
inventoryItem.Weapon = itemConfigEntries.Weapon; inventoryItem.Weapon = importCrewShipWeapon(itemConfigEntries.Weapon);
} }
if (itemConfigEntries.CrewMembers) { if (itemConfigEntries.CrewMembers) {
inventoryItem.CrewMembers = { inventoryItem.CrewMembers = importCrewShipMembers(itemConfigEntries.CrewMembers);
SLOT_A: importCrewMemberId(itemConfigEntries.CrewMembers.SLOT_A ?? {}),
SLOT_B: importCrewMemberId(itemConfigEntries.CrewMembers.SLOT_B ?? {}),
SLOT_C: importCrewMemberId(itemConfigEntries.CrewMembers.SLOT_C ?? {})
};
} }
} }
break; break;

View File

@ -7,14 +7,18 @@ import {
IPolarity IPolarity
} from "@/src/types/inventoryTypes/commonInventoryTypes"; } from "@/src/types/inventoryTypes/commonInventoryTypes";
export interface IEquipmentSelection { export interface IEquipmentSelectionClient {
ItemId: IOid; ItemId?: IOid;
mod?: number; mod?: number;
cus?: number; cus?: number;
ItemType?: string; ItemType?: string;
hide?: boolean; hide?: boolean;
} }
export interface IEquipmentSelectionDatabase extends Omit<IEquipmentSelectionClient, "ItemId"> {
ItemId?: Types.ObjectId | IOid; // should be Types.ObjectId but might be IOid because of old commits
}
export enum EquipmentFeatures { export enum EquipmentFeatures {
DOUBLE_CAPACITY = 1, DOUBLE_CAPACITY = 1,
UTILITY_SLOT = 2, UTILITY_SLOT = 2,
@ -51,7 +55,7 @@ export interface IEquipmentDatabase {
UpgradesExpiry?: Date; UpgradesExpiry?: Date;
UmbraDate?: Date; // related to scrapped "echoes of umbra" feature UmbraDate?: Date; // related to scrapped "echoes of umbra" feature
ArchonCrystalUpgrades?: IArchonCrystalUpgrade[]; ArchonCrystalUpgrades?: IArchonCrystalUpgrade[];
Weapon?: ICrewShipWeapon; Weapon?: ICrewShipWeaponDatabase;
Customization?: ICrewShipCustomization; Customization?: ICrewShipCustomization;
RailjackImage?: IFlavourItem; RailjackImage?: IFlavourItem;
CrewMembers?: ICrewShipMembersDatabase; CrewMembers?: ICrewShipMembersDatabase;
@ -64,13 +68,14 @@ export interface IEquipmentDatabase {
export interface IEquipmentClient export interface IEquipmentClient
extends Omit< extends Omit<
IEquipmentDatabase, IEquipmentDatabase,
"_id" | "InfestationDate" | "Expiry" | "UpgradesExpiry" | "UmbraDate" | "CrewMembers" | "Details" "_id" | "InfestationDate" | "Expiry" | "UpgradesExpiry" | "UmbraDate" | "Weapon" | "CrewMembers" | "Details"
> { > {
ItemId: IOidWithLegacySupport; ItemId: IOidWithLegacySupport;
InfestationDate?: IMongoDate; InfestationDate?: IMongoDate;
Expiry?: IMongoDate; Expiry?: IMongoDate;
UpgradesExpiry?: IMongoDate; UpgradesExpiry?: IMongoDate;
UmbraDate?: IMongoDate; UmbraDate?: IMongoDate;
Weapon?: ICrewShipWeaponClient;
CrewMembers?: ICrewShipMembersClient; CrewMembers?: ICrewShipMembersClient;
Details?: IKubrowPetDetailsClient; Details?: IKubrowPetDetailsClient;
} }
@ -117,19 +122,34 @@ export enum Status {
} }
// inventory.CrewShips[0].Weapon // inventory.CrewShips[0].Weapon
export interface ICrewShipWeapon { export interface ICrewShipWeaponClient {
PILOT?: ICrewShipWeaponEmplacements; PILOT?: ICrewShipWeaponEmplacementsClient;
PORT_GUNS?: ICrewShipWeaponEmplacements; PORT_GUNS?: ICrewShipWeaponEmplacementsClient;
STARBOARD_GUNS?: ICrewShipWeaponEmplacements; STARBOARD_GUNS?: ICrewShipWeaponEmplacementsClient;
ARTILLERY?: ICrewShipWeaponEmplacements; ARTILLERY?: ICrewShipWeaponEmplacementsClient;
SCANNER?: ICrewShipWeaponEmplacements; SCANNER?: ICrewShipWeaponEmplacementsClient;
} }
export interface ICrewShipWeaponEmplacements { export interface ICrewShipWeaponDatabase {
PRIMARY_A?: IEquipmentSelection; PILOT?: ICrewShipWeaponEmplacementsDatabase;
PRIMARY_B?: IEquipmentSelection; PORT_GUNS?: ICrewShipWeaponEmplacementsDatabase;
SECONDARY_A?: IEquipmentSelection; STARBOARD_GUNS?: ICrewShipWeaponEmplacementsDatabase;
SECONDARY_B?: IEquipmentSelection; ARTILLERY?: ICrewShipWeaponEmplacementsDatabase;
SCANNER?: ICrewShipWeaponEmplacementsDatabase;
}
export interface ICrewShipWeaponEmplacementsClient {
PRIMARY_A?: IEquipmentSelectionClient;
PRIMARY_B?: IEquipmentSelectionClient;
SECONDARY_A?: IEquipmentSelectionClient;
SECONDARY_B?: IEquipmentSelectionClient;
}
export interface ICrewShipWeaponEmplacementsDatabase {
PRIMARY_A?: IEquipmentSelectionDatabase;
PRIMARY_B?: IEquipmentSelectionDatabase;
SECONDARY_A?: IEquipmentSelectionDatabase;
SECONDARY_B?: IEquipmentSelectionDatabase;
} }
export interface ICrewShipMembersClient { export interface ICrewShipMembersClient {

View File

@ -68,12 +68,14 @@ export interface IInventoryDatabase
| "LastInventorySync" | "LastInventorySync"
| "EndlessXP" | "EndlessXP"
| "PersonalGoalProgress" | "PersonalGoalProgress"
| "CurrentLoadOutIds"
| TEquipmentKey | TEquipmentKey
>, >,
InventoryDatabaseEquipment, InventoryDatabaseEquipment,
IAccountCheats { IAccountCheats {
accountOwnerId: Types.ObjectId; accountOwnerId: Types.ObjectId;
Created: Date; Created: Date;
CurrentLoadOutIds: Types.ObjectId[] | IOid[]; // should be Types.ObjectId[] but might be IOid[] because of old commits
TrainingDate: Date; TrainingDate: Date;
LoadOutPresets: Types.ObjectId; // LoadOutPresets changed from ILoadOutPresets to Types.ObjectId for population LoadOutPresets: Types.ObjectId; // LoadOutPresets changed from ILoadOutPresets to Types.ObjectId for population
//Mailbox?: IMailboxDatabase; //Mailbox?: IMailboxDatabase;
@ -254,7 +256,7 @@ export interface IInventoryClient extends IDailyAffiliations, InventoryClientEqu
ActiveQuest: string; ActiveQuest: string;
FlavourItems: IFlavourItem[]; FlavourItems: IFlavourItem[];
LoadOutPresets: ILoadOutPresets; LoadOutPresets: ILoadOutPresets;
CurrentLoadOutIds: IOid[]; // we store it in the database using this representation as well :/ CurrentLoadOutIds: IOid[];
Missions: IMission[]; Missions: IMission[];
RandomUpgradesIdentified?: number; RandomUpgradesIdentified?: number;
LastRegionPlayed: TSolarMapRegion; LastRegionPlayed: TSolarMapRegion;

View File

@ -7,7 +7,12 @@ import {
IOperatorConfigClient IOperatorConfigClient
} from "@/src/types/inventoryTypes/commonInventoryTypes"; } from "@/src/types/inventoryTypes/commonInventoryTypes";
import { Types } from "mongoose"; import { Types } from "mongoose";
import { ICrewShipMembersClient, ICrewShipWeapon, IEquipmentSelection } from "@/src/types/equipmentTypes"; import {
ICrewShipMembersClient,
ICrewShipWeaponClient,
IEquipmentSelectionClient,
IEquipmentSelectionDatabase
} from "@/src/types/equipmentTypes";
export interface ISaveLoadoutRequest { export interface ISaveLoadoutRequest {
LoadOuts: ILoadoutClient; LoadOuts: ILoadoutClient;
@ -53,10 +58,12 @@ export interface IOperatorConfigEntry {
[configId: string]: IOperatorConfigClient; [configId: string]: IOperatorConfigClient;
} }
// client
export interface IItemEntry { export interface IItemEntry {
[itemId: string]: IConfigEntry; [itemId: string]: IConfigEntry;
} }
// client
export type IConfigEntry = { export type IConfigEntry = {
[configId in "0" | "1" | "2" | "3" | "4" | "5"]: IItemConfig; [configId in "0" | "1" | "2" | "3" | "4" | "5"]: IItemConfig;
} & { } & {
@ -66,7 +73,7 @@ export type IConfigEntry = {
ItemName?: string; ItemName?: string;
RailjackImage?: IFlavourItem; RailjackImage?: IFlavourItem;
Customization?: ICrewShipCustomization; Customization?: ICrewShipCustomization;
Weapon?: ICrewShipWeapon; Weapon?: ICrewShipWeaponClient;
CrewMembers?: ICrewShipMembersClient; CrewMembers?: ICrewShipMembersClient;
}; };
@ -108,10 +115,6 @@ export interface ILoadoutEntry {
[key: string]: ILoadoutConfigClient; [key: string]: ILoadoutConfigClient;
} }
export interface ILoadoutConfigDatabase extends Omit<ILoadoutConfigClient, "ItemId"> {
_id: Types.ObjectId;
}
export enum FocusSchool { export enum FocusSchool {
Attack = "AP_ATTACK", Attack = "AP_ATTACK",
Defense = "AP_DEFENSE", Defense = "AP_DEFENSE",
@ -125,12 +128,23 @@ export interface ILoadoutConfigClient {
PresetIcon?: string; PresetIcon?: string;
Favorite?: boolean; Favorite?: boolean;
n?: string; // Loadout name n?: string; // Loadout name
s?: IEquipmentSelection; // Suit s?: IEquipmentSelectionClient; // Suit
p?: IEquipmentSelection; // Secondary weapon p?: IEquipmentSelectionClient; // Secondary weapon
l?: IEquipmentSelection; // Primary weapon l?: IEquipmentSelectionClient; // Primary weapon
m?: IEquipmentSelection; // Melee weapon m?: IEquipmentSelectionClient; // Melee weapon
h?: IEquipmentSelection; // Gravimag weapon h?: IEquipmentSelectionClient; // Gravimag weapon
a?: IEquipmentSelection; // Necromech exalted weapon a?: IEquipmentSelectionClient; // Necromech exalted weapon
ItemId: IOid; ItemId: IOid;
Remove?: boolean; // when client wants to remove a config, it only includes ItemId & Remove. Remove?: boolean; // when client wants to remove a config, it only includes ItemId & Remove.
} }
export interface ILoadoutConfigDatabase
extends Omit<ILoadoutConfigClient, "ItemId" | "s" | "p" | "l" | "m" | "h" | "a"> {
_id: Types.ObjectId;
s?: IEquipmentSelectionDatabase;
p?: IEquipmentSelectionDatabase;
l?: IEquipmentSelectionDatabase;
m?: IEquipmentSelectionDatabase;
h?: IEquipmentSelectionDatabase;
a?: IEquipmentSelectionDatabase;
}