Compare commits

..

8 Commits

Author SHA1 Message Date
564aa06762 fix: correctly apply riven cipher (#2554)
The completeRandomModChallenge endpoint is only supposed to complete the challenge, what a shocker. Because we directly set a unveiled fingerprint, the game was not showing the expected UI.

Reviewed-on: OpenWF/SpaceNinjaServer#2554
Co-authored-by: Sainan <63328889+Sainan@users.noreply.github.com>
Co-committed-by: Sainan <63328889+Sainan@users.noreply.github.com>
2025-07-27 06:29:12 -07:00
2e84f71af8 chore: faithful handling when ki'teer signa was rolled (#2553)
Reviewed-on: OpenWF/SpaceNinjaServer#2553
Co-authored-by: Sainan <63328889+Sainan@users.noreply.github.com>
Co-committed-by: Sainan <63328889+Sainan@users.noreply.github.com>
2025-07-27 06:29:02 -07:00
ddfa98e0b2 chore: update baro.json (#2550)
Co-authored-by: BanLanGen <banlangen@noreply.localhost>
Reviewed-on: OpenWF/SpaceNinjaServer#2550
Co-authored-by: Sainan <63328889+Sainan@users.noreply.github.com>
Co-committed-by: Sainan <63328889+Sainan@users.noreply.github.com>
2025-07-27 06:28:51 -07:00
bb3c3e01b0 chore: add GEAR loadout slot (#2545)
added missing GEAR loadout slot (was causing issues with saving loadout in U29)

Reviewed-on: OpenWF/SpaceNinjaServer#2545
Reviewed-by: Sainan <63328889+sainan@users.noreply.github.com>
Co-authored-by: azdful <mischzaripov@yandex.ru>
Co-committed-by: azdful <mischzaripov@yandex.ru>
2025-07-25 01:51:13 -07:00
695dcf98e0 chore: handle sale of fusion treasures (#2542)
Closes #2541

Reviewed-on: OpenWF/SpaceNinjaServer#2542
Co-authored-by: Sainan <63328889+Sainan@users.noreply.github.com>
Co-committed-by: Sainan <63328889+Sainan@users.noreply.github.com>
2025-07-24 05:30:55 -07:00
509f7f0d9b feat: selling for Dirac (CrewShipFusionPoints) (#2540)
Co-authored-by: Sainan <63328889+Sainan@users.noreply.github.com>
Reviewed-on: OpenWF/SpaceNinjaServer#2540
Reviewed-by: Sainan <63328889+sainan@users.noreply.github.com>
Co-authored-by: azdful <mischzaripov@yandex.ru>
Co-committed-by: azdful <mischzaripov@yandex.ru>
2025-07-23 11:09:44 -07:00
aada031a80 chore: update mongoose (#2539)
The transform hook signature was changed in the typings, so I just updated them to be explicit about what we expect.

Reviewed-on: OpenWF/SpaceNinjaServer#2539
Co-authored-by: Sainan <63328889+Sainan@users.noreply.github.com>
Co-committed-by: Sainan <63328889+Sainan@users.noreply.github.com>
2025-07-23 07:51:51 -07:00
a2a441ecb0 fix: getUsernameFromEmail returning wrong value (#2538)
Closes #2537

Reviewed-on: OpenWF/SpaceNinjaServer#2538
Co-authored-by: Sainan <63328889+Sainan@users.noreply.github.com>
Co-committed-by: Sainan <63328889+Sainan@users.noreply.github.com>
2025-07-23 07:51:22 -07:00
25 changed files with 142 additions and 90 deletions

View File

@ -21,7 +21,7 @@
"@typescript-eslint/no-unsafe-argument": "error", "@typescript-eslint/no-unsafe-argument": "error",
"@typescript-eslint/no-unsafe-call": "error", "@typescript-eslint/no-unsafe-call": "error",
"@typescript-eslint/no-unsafe-assignment": "error", "@typescript-eslint/no-unsafe-assignment": "error",
"@typescript-eslint/no-explicit-any": "error", "@typescript-eslint/no-explicit-any": "off",
"no-loss-of-precision": "error", "no-loss-of-precision": "error",
"@typescript-eslint/no-unnecessary-condition": "error", "@typescript-eslint/no-unnecessary-condition": "error",
"@typescript-eslint/no-base-to-string": "off", "@typescript-eslint/no-base-to-string": "off",

8
package-lock.json generated
View File

@ -18,7 +18,7 @@
"crc-32": "^1.2.2", "crc-32": "^1.2.2",
"express": "^5", "express": "^5",
"json-with-bigint": "^3.4.4", "json-with-bigint": "^3.4.4",
"mongoose": ">=8.11.0 <8.16.2", "mongoose": "^8.11.0",
"morgan": "^1.10.0", "morgan": "^1.10.0",
"ncp": "^2.0.0", "ncp": "^2.0.0",
"typescript": "^5.5", "typescript": "^5.5",
@ -3889,9 +3889,9 @@
} }
}, },
"node_modules/mongoose": { "node_modules/mongoose": {
"version": "8.16.1", "version": "8.16.4",
"resolved": "https://registry.npmjs.org/mongoose/-/mongoose-8.16.1.tgz", "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-8.16.4.tgz",
"integrity": "sha512-Q+0TC+KLdY4SYE+u9gk9pdW1tWu/pl0jusyEkMGTgBoAbvwQdfy4f9IM8dmvCwb/blSfp7IfLkob7v76x6ZGpQ==", "integrity": "sha512-jslgdQ8pY2vcNSKPv3Dbi5ogo/NT8zcvf6kPDyD8Sdsjsa1at3AFAF0F5PT+jySPGSPbvlNaQ49nT9h+Kx2UDA==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"bson": "^6.10.4", "bson": "^6.10.4",

View File

@ -35,7 +35,7 @@
"crc-32": "^1.2.2", "crc-32": "^1.2.2",
"express": "^5", "express": "^5",
"json-with-bigint": "^3.4.4", "json-with-bigint": "^3.4.4",
"mongoose": ">=8.11.0 <8.16.2", "mongoose": "^8.11.0",
"morgan": "^1.10.0", "morgan": "^1.10.0",
"ncp": "^2.0.0", "ncp": "^2.0.0",
"typescript": "^5.5", "typescript": "^5.5",

View File

@ -4,8 +4,7 @@ import { addMiscItems, getInventory, updateCurrency } from "@/src/services/inven
import { IInventoryChanges } from "@/src/types/purchaseTypes"; import { IInventoryChanges } from "@/src/types/purchaseTypes";
import { IMiscItem } from "@/src/types/inventoryTypes/inventoryTypes"; import { IMiscItem } from "@/src/types/inventoryTypes/inventoryTypes";
import { getJSONfromString } from "@/src/helpers/stringHelpers"; import { getJSONfromString } from "@/src/helpers/stringHelpers";
import { createUnveiledRivenFingerprint } from "@/src/helpers/rivenHelper"; import { IVeiledRivenFingerprint } from "@/src/helpers/rivenHelper";
import { ExportUpgrades } from "warframe-public-export-plus";
export const completeRandomModChallengeController: RequestHandler = async (req, res) => { export const completeRandomModChallengeController: RequestHandler = async (req, res) => {
const accountId = await getAccountIdForRequest(req); const accountId = await getAccountIdForRequest(req);
@ -27,10 +26,11 @@ export const completeRandomModChallengeController: RequestHandler = async (req,
inventoryChanges.MiscItems = miscItemChanges; inventoryChanges.MiscItems = miscItemChanges;
} }
// Update riven fingerprint to a randomised unveiled state // Complete the riven challenge
const upgrade = inventory.Upgrades.id(request.ItemId)!; const upgrade = inventory.Upgrades.id(request.ItemId)!;
const meta = ExportUpgrades[upgrade.ItemType]; const fp = JSON.parse(upgrade.UpgradeFingerprint!) as IVeiledRivenFingerprint;
upgrade.UpgradeFingerprint = JSON.stringify(createUnveiledRivenFingerprint(meta)); fp.challenge.Progress = fp.challenge.Required;
upgrade.UpgradeFingerprint = JSON.stringify(fp);
await inventory.save(); await inventory.save();

View File

@ -88,7 +88,6 @@ export const crewShipFusionController: RequestHandler = async (req, res) => {
} }
} }
superiorItem.UpgradeFingerprint = JSON.stringify(fingerprint); superiorItem.UpgradeFingerprint = JSON.stringify(fingerprint);
// eslint-disable-next-line @typescript-eslint/no-explicit-any
inventoryChanges[category] = [superiorItem.toJSON() as any]; inventoryChanges[category] = [superiorItem.toJSON() as any];
await inventory.save(); await inventory.save();

View File

@ -2,22 +2,14 @@ import { RequestHandler } from "express";
import { ExportResources } from "warframe-public-export-plus"; import { ExportResources } from "warframe-public-export-plus";
import { getAccountIdForRequest } from "@/src/services/loginService"; import { getAccountIdForRequest } from "@/src/services/loginService";
import { addFusionTreasures, addMiscItems, getInventory } from "@/src/services/inventoryService"; import { addFusionTreasures, addMiscItems, getInventory } from "@/src/services/inventoryService";
import { IFusionTreasure, IMiscItem } from "@/src/types/inventoryTypes/inventoryTypes"; import { IMiscItem } from "@/src/types/inventoryTypes/inventoryTypes";
import { parseFusionTreasure } from "@/src/helpers/inventoryHelpers";
interface IFusionTreasureRequest { interface IFusionTreasureRequest {
oldTreasureName: string; oldTreasureName: string;
newTreasureName: string; newTreasureName: string;
} }
const parseFusionTreasure = (name: string, count: number): IFusionTreasure => {
const arr = name.split("_");
return {
ItemType: arr[0],
Sockets: parseInt(arr[1], 16),
ItemCount: count
};
};
export const fusionTreasuresController: RequestHandler = async (req, res) => { export const fusionTreasuresController: RequestHandler = async (req, res) => {
const accountId = await getAccountIdForRequest(req); const accountId = await getAccountIdForRequest(req);
const inventory = await getInventory(accountId); const inventory = await getInventory(accountId);

View File

@ -9,13 +9,16 @@ import {
freeUpSlot, freeUpSlot,
combineInventoryChanges, combineInventoryChanges,
addCrewShipRawSalvage, addCrewShipRawSalvage,
addFusionPoints addFusionPoints,
addCrewShipFusionPoints,
addFusionTreasures
} from "@/src/services/inventoryService"; } from "@/src/services/inventoryService";
import { InventorySlot } from "@/src/types/inventoryTypes/inventoryTypes"; import { InventorySlot } from "@/src/types/inventoryTypes/inventoryTypes";
import { ExportDojoRecipes } from "warframe-public-export-plus"; import { ExportDojoRecipes } from "warframe-public-export-plus";
import { IInventoryChanges } from "@/src/types/purchaseTypes"; import { IInventoryChanges } from "@/src/types/purchaseTypes";
import { TInventoryDatabaseDocument } from "@/src/models/inventoryModels/inventoryModel"; import { TInventoryDatabaseDocument } from "@/src/models/inventoryModels/inventoryModel";
import { sendWsBroadcastEx } from "@/src/services/wsService"; import { sendWsBroadcastEx } from "@/src/services/wsService";
import { parseFusionTreasure } from "@/src/helpers/inventoryHelpers";
export const sellController: RequestHandler = async (req, res) => { export const sellController: RequestHandler = async (req, res) => {
const payload = JSON.parse(String(req.body)) as ISellRequest; const payload = JSON.parse(String(req.body)) as ISellRequest;
@ -26,6 +29,8 @@ export const sellController: RequestHandler = async (req, res) => {
requiredFields.add("RegularCredits"); requiredFields.add("RegularCredits");
} else if (payload.SellCurrency == "SC_FusionPoints") { } else if (payload.SellCurrency == "SC_FusionPoints") {
requiredFields.add("FusionPoints"); requiredFields.add("FusionPoints");
} else if (payload.SellCurrency == "SC_CrewShipFusionPoints") {
requiredFields.add("CrewShipFusionPoints");
} else { } else {
requiredFields.add("MiscItems"); requiredFields.add("MiscItems");
} }
@ -79,6 +84,8 @@ export const sellController: RequestHandler = async (req, res) => {
inventory.RegularCredits += payload.SellPrice; inventory.RegularCredits += payload.SellPrice;
} else if (payload.SellCurrency == "SC_FusionPoints") { } else if (payload.SellCurrency == "SC_FusionPoints") {
addFusionPoints(inventory, payload.SellPrice); addFusionPoints(inventory, payload.SellPrice);
} else if (payload.SellCurrency == "SC_CrewShipFusionPoints") {
addCrewShipFusionPoints(inventory, payload.SellPrice);
} else if (payload.SellCurrency == "SC_PrimeBucks") { } else if (payload.SellCurrency == "SC_PrimeBucks") {
addMiscItems(inventory, [ addMiscItems(inventory, [
{ {
@ -290,6 +297,11 @@ export const sellController: RequestHandler = async (req, res) => {
]); ]);
}); });
} }
if (payload.Items.FusionTreasures) {
payload.Items.FusionTreasures.forEach(sellItem => {
addFusionTreasures(inventory, [parseFusionTreasure(sellItem.String, sellItem.Count * -1)]);
});
}
await inventory.save(); await inventory.save();
res.json({ res.json({
@ -322,6 +334,7 @@ interface ISellRequest {
CrewMembers?: ISellItem[]; CrewMembers?: ISellItem[];
CrewShipWeapons?: ISellItem[]; CrewShipWeapons?: ISellItem[];
CrewShipWeaponSkins?: ISellItem[]; CrewShipWeaponSkins?: ISellItem[];
FusionTreasures?: ISellItem[];
}; };
SellPrice: number; SellPrice: number;
SellCurrency: SellCurrency:
@ -330,7 +343,8 @@ interface ISellRequest {
| "SC_FusionPoints" | "SC_FusionPoints"
| "SC_DistillPoints" | "SC_DistillPoints"
| "SC_CrewShipFusionPoints" | "SC_CrewShipFusionPoints"
| "SC_Resources"; | "SC_Resources"
| "somethingelsewemightnotknowabout";
buildLabel: string; buildLabel: string;
} }

View File

@ -141,7 +141,7 @@ export const getProfileViewingDataGetController: RequestHandler = async (req, re
} }
} }
} else { } else {
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-explicit-any // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
combinedStats[arrayName].push(entry as any); combinedStats[arrayName].push(entry as any);
} }
} }

View File

@ -1,6 +1,7 @@
import { IMongoDate, IOid, IOidWithLegacySupport } from "@/src/types/commonTypes"; import { IMongoDate, IOid, IOidWithLegacySupport } from "@/src/types/commonTypes";
import { Types } from "mongoose"; import { Types } from "mongoose";
import { TRarity } from "warframe-public-export-plus"; import { TRarity } from "warframe-public-export-plus";
import { IFusionTreasure } from "@/src/types/inventoryTypes/inventoryTypes";
export const version_compare = (a: string, b: string): number => { export const version_compare = (a: string, b: string): number => {
const a_digits = a const a_digits = a
@ -51,6 +52,15 @@ export const fromMongoDate = (date: IMongoDate): Date => {
return new Date(parseInt(date.$date.$numberLong)); return new Date(parseInt(date.$date.$numberLong));
}; };
export const parseFusionTreasure = (name: string, count: number): IFusionTreasure => {
const arr = name.split("_");
return {
ItemType: arr[0],
Sockets: parseInt(arr[1], 16),
ItemCount: count
};
};
export type TTraitsPool = Record< export type TTraitsPool = Record<
"Colors" | "EyeColors" | "FurPatterns" | "BodyTypes" | "Heads" | "Tails", "Colors" | "EyeColors" | "FurPatterns" | "BodyTypes" | "Heads" | "Tails",
{ type: string; rarity: TRarity }[] { type: string; rarity: TRarity }[]

View File

@ -150,7 +150,7 @@ messageSchema.virtual("messageId").get(function (this: IMessageDatabase) {
messageSchema.set("toJSON", { messageSchema.set("toJSON", {
virtuals: true, virtuals: true,
transform(_document, returnedObject) { transform(_document, returnedObject: Record<string, any>) {
const messageDatabase = returnedObject as IMessageDatabase; const messageDatabase = returnedObject as IMessageDatabase;
const messageClient = returnedObject as IMessageClient; const messageClient = returnedObject as IMessageClient;

View File

@ -121,7 +121,7 @@ import {
export const typeCountSchema = new Schema<ITypeCount>({ ItemType: String, ItemCount: Number }, { _id: false }); export const typeCountSchema = new Schema<ITypeCount>({ ItemType: String, ItemCount: Number }, { _id: false });
typeCountSchema.set("toJSON", { typeCountSchema.set("toJSON", {
transform(_doc, obj) { transform(_doc, obj: Record<string, any>) {
if (obj.ItemCount > 2147483647) { if (obj.ItemCount > 2147483647) {
obj.ItemCount = 2147483647; obj.ItemCount = 2147483647;
} else if (obj.ItemCount < -2147483648) { } else if (obj.ItemCount < -2147483648) {
@ -189,7 +189,7 @@ operatorConfigSchema.virtual("ItemId").get(function () {
operatorConfigSchema.set("toJSON", { operatorConfigSchema.set("toJSON", {
virtuals: true, virtuals: true,
transform(_document, returnedObject) { transform(_document, returnedObject: Record<string, any>) {
delete returnedObject._id; delete returnedObject._id;
delete returnedObject.__v; delete returnedObject.__v;
} }
@ -226,7 +226,7 @@ const ItemConfigSchema = new Schema<IItemConfig>(
); );
ItemConfigSchema.set("toJSON", { ItemConfigSchema.set("toJSON", {
transform(_document, returnedObject) { transform(_document, returnedObject: Record<string, any>) {
delete returnedObject.__v; delete returnedObject.__v;
} }
}); });
@ -261,7 +261,7 @@ RawUpgrades.virtual("LastAdded").get(function () {
RawUpgrades.set("toJSON", { RawUpgrades.set("toJSON", {
virtuals: true, virtuals: true,
transform(_document, returnedObject) { transform(_document, returnedObject: Record<string, any>) {
delete returnedObject._id; delete returnedObject._id;
delete returnedObject.__v; delete returnedObject.__v;
} }
@ -282,7 +282,7 @@ upgradeSchema.virtual("ItemId").get(function () {
upgradeSchema.set("toJSON", { upgradeSchema.set("toJSON", {
virtuals: true, virtuals: true,
transform(_document, returnedObject) { transform(_document, returnedObject: Record<string, any>) {
delete returnedObject._id; delete returnedObject._id;
delete returnedObject.__v; delete returnedObject.__v;
} }
@ -325,7 +325,7 @@ const crewMemberSchema = new Schema<ICrewMemberDatabase>(
crewMemberSchema.set("toJSON", { crewMemberSchema.set("toJSON", {
virtuals: true, virtuals: true,
transform(_doc, obj) { transform(_doc, obj: Record<string, any>) {
const db = obj as ICrewMemberDatabase; const db = obj as ICrewMemberDatabase;
const client = obj as ICrewMemberClient; const client = obj as ICrewMemberClient;
@ -353,7 +353,7 @@ const FlavourItemSchema = new Schema(
); );
FlavourItemSchema.set("toJSON", { FlavourItemSchema.set("toJSON", {
transform(_document, returnedObject) { transform(_document, returnedObject: Record<string, any>) {
delete returnedObject._id; delete returnedObject._id;
delete returnedObject.__v; delete returnedObject.__v;
} }
@ -367,7 +367,7 @@ FlavourItemSchema.set("toJSON", {
); );
MailboxSchema.set("toJSON", { MailboxSchema.set("toJSON", {
transform(_document, returnedObject) { transform(_document, returnedObject: Record<string, any>) {
const mailboxDatabase = returnedObject as HydratedDocument<IMailboxDatabase, { __v?: number }>; const mailboxDatabase = returnedObject as HydratedDocument<IMailboxDatabase, { __v?: number }>;
delete mailboxDatabase.__v; delete mailboxDatabase.__v;
(returnedObject as IMailboxClient).LastInboxId = toOid(mailboxDatabase.LastInboxId); (returnedObject as IMailboxClient).LastInboxId = toOid(mailboxDatabase.LastInboxId);
@ -386,7 +386,7 @@ const DuviriInfoSchema = new Schema<IDuviriInfo>(
); );
DuviriInfoSchema.set("toJSON", { DuviriInfoSchema.set("toJSON", {
transform(_document, returnedObject) { transform(_document, returnedObject: Record<string, any>) {
delete returnedObject.__v; delete returnedObject.__v;
} }
}); });
@ -416,7 +416,7 @@ const droneSchema = new Schema<IDroneDatabase>(
); );
droneSchema.set("toJSON", { droneSchema.set("toJSON", {
virtuals: true, virtuals: true,
transform(_document, obj) { transform(_document, obj: Record<string, any>) {
const client = obj as IDroneClient; const client = obj as IDroneClient;
const db = obj as IDroneDatabase; const db = obj as IDroneDatabase;
@ -457,7 +457,7 @@ const personalGoalProgressSchema = new Schema<IPersonalGoalProgressDatabase>(
personalGoalProgressSchema.set("toJSON", { personalGoalProgressSchema.set("toJSON", {
virtuals: true, virtuals: true,
transform(_doc, obj) { transform(_doc, obj: Record<string, any>) {
const db = obj as IPersonalGoalProgressDatabase; const db = obj as IPersonalGoalProgressDatabase;
const client = obj as IPersonalGoalProgressClient; const client = obj as IPersonalGoalProgressClient;
@ -502,7 +502,7 @@ StepSequencersSchema.virtual("ItemId").get(function () {
StepSequencersSchema.set("toJSON", { StepSequencersSchema.set("toJSON", {
virtuals: true, virtuals: true,
transform(_document, returnedObject) { transform(_document, returnedObject: Record<string, any>) {
delete returnedObject._id; delete returnedObject._id;
delete returnedObject.__v; delete returnedObject.__v;
} }
@ -516,7 +516,7 @@ const kubrowPetEggSchema = new Schema<IKubrowPetEggDatabase>(
); );
kubrowPetEggSchema.set("toJSON", { kubrowPetEggSchema.set("toJSON", {
virtuals: true, virtuals: true,
transform(_document, obj) { transform(_document, obj: Record<string, any>) {
const client = obj as IKubrowPetEggClient; const client = obj as IKubrowPetEggClient;
const db = obj as IKubrowPetEggDatabase; const db = obj as IKubrowPetEggDatabase;
@ -586,7 +586,7 @@ personalTechProjectSchema.virtual("ItemId").get(function () {
personalTechProjectSchema.set("toJSON", { personalTechProjectSchema.set("toJSON", {
virtuals: true, virtuals: true,
transform(_doc, ret, _options) { transform(_doc, ret: Record<string, any>) {
delete ret._id; delete ret._id;
delete ret.__v; delete ret.__v;
@ -687,7 +687,7 @@ const questKeysSchema = new Schema<IQuestKeyDatabase>(
); );
questKeysSchema.set("toJSON", { questKeysSchema.set("toJSON", {
transform(_doc, ret, _options) { transform(_doc, ret: Record<string, any>) {
const questKeysDatabase = ret as IQuestKeyDatabase; const questKeysDatabase = ret as IQuestKeyDatabase;
if (questKeysDatabase.CompletionDate) { if (questKeysDatabase.CompletionDate) {
@ -709,7 +709,7 @@ const invasionProgressSchema = new Schema<IInvasionProgressDatabase>(
); );
invasionProgressSchema.set("toJSON", { invasionProgressSchema.set("toJSON", {
transform(_doc, obj) { transform(_doc, obj: Record<string, any>) {
const db = obj as IInvasionProgressDatabase; const db = obj as IInvasionProgressDatabase;
const client = obj as IInvasionProgressClient; const client = obj as IInvasionProgressClient;
@ -748,7 +748,7 @@ weaponSkinsSchema.virtual("ItemId").get(function () {
weaponSkinsSchema.set("toJSON", { weaponSkinsSchema.set("toJSON", {
virtuals: true, virtuals: true,
transform(_doc, ret, _options) { transform(_doc, ret: Record<string, any>) {
delete ret._id; delete ret._id;
delete ret.__v; delete ret.__v;
} }
@ -772,7 +772,7 @@ const periodicMissionCompletionsSchema = new Schema<IPeriodicMissionCompletionDa
); );
periodicMissionCompletionsSchema.set("toJSON", { periodicMissionCompletionsSchema.set("toJSON", {
transform(_doc, ret, _options) { transform(_doc, ret: Record<string, any>) {
const periodicMissionCompletionDatabase = ret as IPeriodicMissionCompletionDatabase; const periodicMissionCompletionDatabase = ret as IPeriodicMissionCompletionDatabase;
(periodicMissionCompletionDatabase as unknown as IPeriodicMissionCompletionResponse).date = toMongoDate( (periodicMissionCompletionDatabase as unknown as IPeriodicMissionCompletionResponse).date = toMongoDate(
@ -849,7 +849,7 @@ const endlessXpProgressSchema = new Schema<IEndlessXpProgressDatabase>(
); );
endlessXpProgressSchema.set("toJSON", { endlessXpProgressSchema.set("toJSON", {
transform(_doc, ret) { transform(_doc, ret: Record<string, any>) {
const db = ret as IEndlessXpProgressDatabase; const db = ret as IEndlessXpProgressDatabase;
const client = ret as IEndlessXpProgressClient; const client = ret as IEndlessXpProgressClient;
@ -898,7 +898,7 @@ const crewShipMemberSchema = new Schema<ICrewShipMemberDatabase>(
); );
crewShipMemberSchema.set("toJSON", { crewShipMemberSchema.set("toJSON", {
virtuals: true, virtuals: true,
transform(_doc, obj) { transform(_doc, obj: Record<string, any>) {
const db = obj as ICrewShipMemberDatabase; const db = obj as ICrewShipMemberDatabase;
const client = obj as ICrewShipMemberClient; const client = obj as ICrewShipMemberClient;
if (db.ItemId) { if (db.ItemId) {
@ -951,7 +951,7 @@ const dialogueSchema = new Schema<IDialogueDatabase>(
); );
dialogueSchema.set("toJSON", { dialogueSchema.set("toJSON", {
virtuals: true, virtuals: true,
transform(_doc, ret) { transform(_doc, ret: Record<string, any>) {
const db = ret as IDialogueDatabase; const db = ret as IDialogueDatabase;
const client = ret as IDialogueClient; const client = ret as IDialogueClient;
@ -997,7 +997,7 @@ const kubrowPetPrintSchema = new Schema<IKubrowPetPrintDatabase>({
}); });
kubrowPetPrintSchema.set("toJSON", { kubrowPetPrintSchema.set("toJSON", {
virtuals: true, virtuals: true,
transform(_doc, obj) { transform(_doc, obj: Record<string, any>) {
const db = obj as IKubrowPetPrintDatabase; const db = obj as IKubrowPetPrintDatabase;
const client = obj as IKubrowPetPrintClient; const client = obj as IKubrowPetPrintClient;
@ -1025,7 +1025,7 @@ const detailsSchema = new Schema<IKubrowPetDetailsDatabase>(
); );
detailsSchema.set("toJSON", { detailsSchema.set("toJSON", {
transform(_doc, returnedObject) { transform(_doc, returnedObject: Record<string, any>) {
delete returnedObject.__v; delete returnedObject.__v;
const db = returnedObject as IKubrowPetDetailsDatabase; const db = returnedObject as IKubrowPetDetailsDatabase;
@ -1081,7 +1081,7 @@ EquipmentSchema.virtual("ItemId").get(function () {
EquipmentSchema.set("toJSON", { EquipmentSchema.set("toJSON", {
virtuals: true, virtuals: true,
transform(_document, returnedObject) { transform(_document, returnedObject: Record<string, any>) {
delete returnedObject._id; delete returnedObject._id;
delete returnedObject.__v; delete returnedObject.__v;
@ -1132,7 +1132,7 @@ pendingRecipeSchema.virtual("ItemId").get(function () {
pendingRecipeSchema.set("toJSON", { pendingRecipeSchema.set("toJSON", {
virtuals: true, virtuals: true,
transform(_document, returnedObject) { transform(_document, returnedObject: Record<string, any>) {
delete returnedObject._id; delete returnedObject._id;
delete returnedObject.__v; delete returnedObject.__v;
delete returnedObject.LongGuns; delete returnedObject.LongGuns;
@ -1170,7 +1170,7 @@ const infestedFoundrySchema = new Schema<IInfestedFoundryDatabase>(
); );
infestedFoundrySchema.set("toJSON", { infestedFoundrySchema.set("toJSON", {
transform(_doc, ret, _options) { transform(_doc, ret: Record<string, any>) {
if (ret.AbilityOverrideUnlockCooldown) { if (ret.AbilityOverrideUnlockCooldown) {
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
ret.AbilityOverrideUnlockCooldown = toMongoDate(ret.AbilityOverrideUnlockCooldown); ret.AbilityOverrideUnlockCooldown = toMongoDate(ret.AbilityOverrideUnlockCooldown);
@ -1243,7 +1243,7 @@ const vendorPurchaseHistoryEntrySchema = new Schema<IVendorPurchaseHistoryEntryD
); );
vendorPurchaseHistoryEntrySchema.set("toJSON", { vendorPurchaseHistoryEntrySchema.set("toJSON", {
transform(_doc, obj) { transform(_doc, obj: Record<string, any>) {
const db = obj as IVendorPurchaseHistoryEntryDatabase; const db = obj as IVendorPurchaseHistoryEntryDatabase;
const client = obj as IVendorPurchaseHistoryEntryClient; const client = obj as IVendorPurchaseHistoryEntryClient;
client.Expiry = toMongoDate(db.Expiry); client.Expiry = toMongoDate(db.Expiry);
@ -1286,7 +1286,7 @@ const pendingCouponSchema = new Schema<IPendingCouponDatabase>(
); );
pendingCouponSchema.set("toJSON", { pendingCouponSchema.set("toJSON", {
transform(_doc, ret, _options) { transform(_doc, ret: Record<string, any>) {
(ret as IPendingCouponClient).Expiry = toMongoDate((ret as IPendingCouponDatabase).Expiry); (ret as IPendingCouponClient).Expiry = toMongoDate((ret as IPendingCouponDatabase).Expiry);
} }
}); });
@ -1353,7 +1353,7 @@ const nemesisSchema = new Schema<INemesisDatabase>(
nemesisSchema.set("toJSON", { nemesisSchema.set("toJSON", {
virtuals: true, virtuals: true,
transform(_doc, obj) { transform(_doc, obj: Record<string, any>) {
const db = obj as INemesisDatabase; const db = obj as INemesisDatabase;
const client = obj as INemesisClient; const client = obj as INemesisClient;
@ -1383,7 +1383,7 @@ const lastSortieRewardSchema = new Schema<ILastSortieRewardDatabase>(
lastSortieRewardSchema.set("toJSON", { lastSortieRewardSchema.set("toJSON", {
virtuals: true, virtuals: true,
transform(_doc, obj) { transform(_doc, obj: Record<string, any>) {
const db = obj as ILastSortieRewardDatabase; const db = obj as ILastSortieRewardDatabase;
const client = obj as ILastSortieRewardClient; const client = obj as ILastSortieRewardClient;
@ -1437,6 +1437,8 @@ const inventorySchema = new Schema<IInventoryDatabase, InventoryDocumentProps>(
PremiumCreditsFree: { type: Number, default: 0 }, PremiumCreditsFree: { type: Number, default: 0 },
//Endo //Endo
FusionPoints: { type: Number, default: 0 }, FusionPoints: { type: Number, default: 0 },
//Dirac
CrewShipFusionPoints: { type: Number, default: 0 },
//Regal Aya //Regal Aya
PrimeTokens: { type: Number, default: 0 }, PrimeTokens: { type: Number, default: 0 },
@ -1790,7 +1792,7 @@ const inventorySchema = new Schema<IInventoryDatabase, InventoryDocumentProps>(
); );
inventorySchema.set("toJSON", { inventorySchema.set("toJSON", {
transform(_document, returnedObject) { transform(_document, returnedObject: Record<string, any>) {
delete returnedObject._id; delete returnedObject._id;
delete returnedObject.__v; delete returnedObject.__v;
delete returnedObject.accountOwnerId; delete returnedObject.accountOwnerId;

View File

@ -49,7 +49,7 @@ loadoutConfigSchema.virtual("ItemId").get(function () {
loadoutConfigSchema.set("toJSON", { loadoutConfigSchema.set("toJSON", {
virtuals: true, virtuals: true,
transform(_doc, ret, _options) { transform(_doc, ret: Record<string, any>) {
delete ret._id; delete ret._id;
delete ret.__v; delete ret.__v;
} }
@ -62,6 +62,7 @@ export const loadoutSchema = new Schema<ILoadoutDatabase, loadoutModelType>({
NORMAL_PVP: [loadoutConfigSchema], NORMAL_PVP: [loadoutConfigSchema],
LUNARO: [loadoutConfigSchema], LUNARO: [loadoutConfigSchema],
OPERATOR: [loadoutConfigSchema], OPERATOR: [loadoutConfigSchema],
GEAR: [loadoutConfigSchema],
KDRIVE: [loadoutConfigSchema], KDRIVE: [loadoutConfigSchema],
DATAKNIFE: [loadoutConfigSchema], DATAKNIFE: [loadoutConfigSchema],
MECH: [loadoutConfigSchema], MECH: [loadoutConfigSchema],
@ -71,7 +72,7 @@ export const loadoutSchema = new Schema<ILoadoutDatabase, loadoutModelType>({
}); });
loadoutSchema.set("toJSON", { loadoutSchema.set("toJSON", {
transform(_doc, ret, _options) { transform(_doc, ret: Record<string, any>) {
delete ret._id; delete ret._id;
delete ret.__v; delete ret.__v;
delete ret.loadoutOwnerId; delete ret.loadoutOwnerId;
@ -88,6 +89,7 @@ type loadoutDocumentProps = {
NORMAL_PVP: Types.DocumentArray<ILoadoutConfigDatabase>; NORMAL_PVP: Types.DocumentArray<ILoadoutConfigDatabase>;
LUNARO: Types.DocumentArray<ILoadoutConfigDatabase>; LUNARO: Types.DocumentArray<ILoadoutConfigDatabase>;
OPERATOR: Types.DocumentArray<ILoadoutConfigDatabase>; OPERATOR: Types.DocumentArray<ILoadoutConfigDatabase>;
GEAR: Types.DocumentArray<ILoadoutConfigDatabase>;
KDRIVE: Types.DocumentArray<ILoadoutConfigDatabase>; KDRIVE: Types.DocumentArray<ILoadoutConfigDatabase>;
DATAKNIFE: Types.DocumentArray<ILoadoutConfigDatabase>; DATAKNIFE: Types.DocumentArray<ILoadoutConfigDatabase>;
MECH: Types.DocumentArray<ILoadoutConfigDatabase>; MECH: Types.DocumentArray<ILoadoutConfigDatabase>;

View File

@ -32,7 +32,7 @@ const databaseAccountSchema = new Schema<IDatabaseAccountJson>(
); );
databaseAccountSchema.set("toJSON", { databaseAccountSchema.set("toJSON", {
transform(_document, returnedObject) { transform(_document, returnedObject: Record<string, any>) {
delete returnedObject._id; delete returnedObject._id;
delete returnedObject.__v; delete returnedObject.__v;
}, },

View File

@ -55,7 +55,7 @@ placedDecosSchema.virtual("id").get(function (this: IPlacedDecosDatabase) {
placedDecosSchema.set("toJSON", { placedDecosSchema.set("toJSON", {
virtuals: true, virtuals: true,
transform(_document, returnedObject) { transform(_document, returnedObject: Record<string, any>) {
delete returnedObject._id; delete returnedObject._id;
} }
}); });
@ -78,7 +78,7 @@ const favouriteLoadoutSchema = new Schema<IFavouriteLoadoutDatabase>(
); );
favouriteLoadoutSchema.set("toJSON", { favouriteLoadoutSchema.set("toJSON", {
virtuals: true, virtuals: true,
transform(_document, returnedObject) { transform(_document, returnedObject: Record<string, any>) {
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
returnedObject.LoadoutId = toOid(returnedObject.LoadoutId); returnedObject.LoadoutId = toOid(returnedObject.LoadoutId);
} }
@ -95,7 +95,7 @@ const plantSchema = new Schema<IPlantDatabase>(
plantSchema.set("toJSON", { plantSchema.set("toJSON", {
virtuals: true, virtuals: true,
transform(_doc, obj) { transform(_doc, obj: Record<string, any>) {
const client = obj as IPlantClient; const client = obj as IPlantClient;
const db = obj as IPlantDatabase; const db = obj as IPlantDatabase;
@ -158,7 +158,7 @@ const orbiterSchema = new Schema<IOrbiterDatabase>(
); );
orbiterSchema.set("toJSON", { orbiterSchema.set("toJSON", {
virtuals: true, virtuals: true,
transform(_doc, obj) { transform(_doc, obj: Record<string, any>) {
const db = obj as IOrbiterDatabase; const db = obj as IOrbiterDatabase;
const client = obj as IOrbiterClient; const client = obj as IOrbiterClient;

View File

@ -22,7 +22,7 @@ shipSchema.virtual("ItemId").get(function () {
shipSchema.set("toJSON", { shipSchema.set("toJSON", {
virtuals: true, virtuals: true,
transform(_document, returnedObject) { transform(_document, returnedObject: Record<string, any>) {
const shipResponse = returnedObject as IShipInventory; const shipResponse = returnedObject as IShipInventory;
const shipDatabase = returnedObject as IShipDatabase; const shipDatabase = returnedObject as IShipDatabase;
delete returnedObject._id; delete returnedObject._id;

View File

@ -101,7 +101,7 @@ const statsSchema = new Schema<IStatsDatabase>({
}); });
statsSchema.set("toJSON", { statsSchema.set("toJSON", {
transform(_document, returnedObject) { transform(_document, returnedObject: Record<string, any>) {
delete returnedObject._id; delete returnedObject._id;
delete returnedObject.__v; delete returnedObject.__v;
delete returnedObject.accountOwnerId; delete returnedObject.accountOwnerId;

View File

@ -114,7 +114,7 @@ export const loadConfig = (): void => {
// Set all values to undefined now so if the new config.json omits some fields that were previously present, it's correct in-memory. // Set all values to undefined now so if the new config.json omits some fields that were previously present, it's correct in-memory.
for (const key of Object.keys(config)) { for (const key of Object.keys(config)) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
(config as any)[key] = undefined; (config as any)[key] = undefined;
} }

View File

@ -422,6 +422,7 @@ export const importLoadOutPresets = (db: ILoadoutDatabase, client: ILoadOutPrese
db.NORMAL_PVP = client.NORMAL_PVP.map(convertLoadOutConfig); db.NORMAL_PVP = client.NORMAL_PVP.map(convertLoadOutConfig);
db.LUNARO = client.LUNARO.map(convertLoadOutConfig); db.LUNARO = client.LUNARO.map(convertLoadOutConfig);
db.OPERATOR = client.OPERATOR.map(convertLoadOutConfig); db.OPERATOR = client.OPERATOR.map(convertLoadOutConfig);
db.GEAR = client.GEAR.map(convertLoadOutConfig);
db.KDRIVE = client.KDRIVE.map(convertLoadOutConfig); db.KDRIVE = client.KDRIVE.map(convertLoadOutConfig);
db.DATAKNIFE = client.DATAKNIFE.map(convertLoadOutConfig); db.DATAKNIFE = client.DATAKNIFE.map(convertLoadOutConfig);
db.MECH = client.MECH.map(convertLoadOutConfig); db.MECH = client.MECH.map(convertLoadOutConfig);

View File

@ -1241,6 +1241,15 @@ export const addFusionPoints = (inventory: TInventoryDatabaseDocument, add: numb
return add; return add;
}; };
export const addCrewShipFusionPoints = (inventory: TInventoryDatabaseDocument, add: number): number => {
if (inventory.CrewShipFusionPoints + add > 2147483647) {
logger.warn(`capping CrewShipFusionPoints balance at 2147483647`);
add = 2147483647 - inventory.CrewShipFusionPoints;
}
inventory.CrewShipFusionPoints += add;
return add;
};
const standingLimitBinToInventoryKey: Record< const standingLimitBinToInventoryKey: Record<
Exclude<TStandingLimitBin, "STANDING_LIMIT_BIN_NONE">, Exclude<TStandingLimitBin, "STANDING_LIMIT_BIN_NONE">,
keyof IDailyAffiliations keyof IDailyAffiliations

View File

@ -32,7 +32,7 @@ export const getUsernameFromEmail = async (email: string): Promise<string> => {
name = nameFromEmail + suffix; name = nameFromEmail + suffix;
} while (await isNameTaken(name)); } while (await isNameTaken(name));
} }
return nameFromEmail; return name;
}; };
export const createAccount = async (accountData: IDatabaseAccountRequiredFields): Promise<IDatabaseAccountJson> => { export const createAccount = async (accountData: IDatabaseAccountRequiredFields): Promise<IDatabaseAccountJson> => {

View File

@ -581,7 +581,7 @@ const handleBoosterPackPurchase = async (
purchaseResponse.InventoryChanges, purchaseResponse.InventoryChanges,
await addItem(inventory, specialItemReward.Item) await addItem(inventory, specialItemReward.Item)
); );
// TOVERIFY: Is the SpecialItemRewardAttenuation entry removed now? atten.Atten = 0;
} else { } else {
atten.Atten += specialItemReward.PityIncreaseRate!; atten.Atten += specialItemReward.PityIncreaseRate!;
} }

View File

@ -2,13 +2,7 @@ import http from "http";
import https from "https"; import https from "https";
import ws from "ws"; import ws from "ws";
import { Account } from "@/src/models/loginModel"; import { Account } from "@/src/models/loginModel";
import { import { createAccount, createNonce, getUsernameFromEmail, isCorrectPassword } from "@/src/services/loginService";
createAccount,
createNonce,
getUsernameFromEmail,
isCorrectPassword,
isNameTaken
} from "@/src/services/loginService";
import { IDatabaseAccountJson } from "@/src/types/loginTypes"; import { IDatabaseAccountJson } from "@/src/types/loginTypes";
import { HydratedDocument } from "mongoose"; import { HydratedDocument } from "mongoose";
import { logError } from "@/src/utils/logger"; import { logError } from "@/src/utils/logger";
@ -111,16 +105,14 @@ const wsOnConnect = (ws: ws, req: http.IncomingMessage): void => {
} }
} else if (data.auth.isRegister) { } else if (data.auth.isRegister) {
const name = await getUsernameFromEmail(data.auth.email); const name = await getUsernameFromEmail(data.auth.email);
if (!(await isNameTaken(name))) { account = await createAccount({
account = await createAccount({ email: data.auth.email,
email: data.auth.email, password: data.auth.password,
password: data.auth.password, ClientType: "webui",
ClientType: "webui", LastLogin: new Date(),
LastLogin: new Date(), DisplayName: name,
DisplayName: name, Nonce: createNonce()
Nonce: createNonce() });
});
}
} }
if (account) { if (account) {
(ws as IWsCustomData).accountId = account.id; (ws as IWsCustomData).accountId = account.id;

View File

@ -1,4 +1,3 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import { Types } from "mongoose"; import { Types } from "mongoose";
import { IOid, IMongoDate, IOidWithLegacySupport, ITypeCount } from "@/src/types/commonTypes"; import { IOid, IMongoDate, IOidWithLegacySupport, ITypeCount } from "@/src/types/commonTypes";
import { import {
@ -216,6 +215,7 @@ export interface IInventoryClient extends IDailyAffiliations, InventoryClientEqu
PremiumCredits: number; PremiumCredits: number;
PremiumCreditsFree: number; PremiumCreditsFree: number;
FusionPoints: number; FusionPoints: number;
CrewShipFusionPoints: number; //Dirac (pre-rework Railjack)
PrimeTokens: number; PrimeTokens: number;
SuitBin: ISlots; SuitBin: ISlots;
WeaponBin: ISlots; WeaponBin: ISlots;

View File

@ -79,6 +79,7 @@ export interface ILoadoutDatabase {
NORMAL_PVP: ILoadoutConfigDatabase[]; NORMAL_PVP: ILoadoutConfigDatabase[];
LUNARO: ILoadoutConfigDatabase[]; LUNARO: ILoadoutConfigDatabase[];
OPERATOR: ILoadoutConfigDatabase[]; OPERATOR: ILoadoutConfigDatabase[];
GEAR: ILoadoutConfigDatabase[];
KDRIVE: ILoadoutConfigDatabase[]; KDRIVE: ILoadoutConfigDatabase[];
DATAKNIFE: ILoadoutConfigDatabase[]; DATAKNIFE: ILoadoutConfigDatabase[];
MECH: ILoadoutConfigDatabase[]; MECH: ILoadoutConfigDatabase[];

View File

@ -304,7 +304,6 @@
{ "ItemType": "/Lotus/StoreItems/Types/StoreItems/AvatarImages/Seasonal/AvatarImageGlyphCookieKubrow", "PrimePrice": 80, "RegularPrice": 50000 }, { "ItemType": "/Lotus/StoreItems/Types/StoreItems/AvatarImages/Seasonal/AvatarImageGlyphCookieKubrow", "PrimePrice": 80, "RegularPrice": 50000 },
{ "ItemType": "/Lotus/StoreItems/Upgrades/Skins/Scarves/LisetScarf", "PrimePrice": 600, "RegularPrice": 400000 }, { "ItemType": "/Lotus/StoreItems/Upgrades/Skins/Scarves/LisetScarf", "PrimePrice": 600, "RegularPrice": 400000 },
{ "ItemType": "/Lotus/StoreItems/Types/StoreItems/SuitCustomizations/ColourPickerTwitchBItemA", "PrimePrice": 220, "RegularPrice": 220000 }, { "ItemType": "/Lotus/StoreItems/Types/StoreItems/SuitCustomizations/ColourPickerTwitchBItemA", "PrimePrice": 220, "RegularPrice": 220000 },
{ "ItemType": "/Lotus/StoreItems/Upgrades/Skins/Effects/FootstepsMaple", "PrimePrice": 15, "RegularPrice": 1000 },
{ "ItemType": "/Lotus/StoreItems/Upgrades/Skins/Clan/BaroKavatBadgeItem", "PrimePrice": 50, "RegularPrice": 50000 }, { "ItemType": "/Lotus/StoreItems/Upgrades/Skins/Clan/BaroKavatBadgeItem", "PrimePrice": 50, "RegularPrice": 50000 },
{ "ItemType": "/Lotus/StoreItems/Upgrades/Skins/Sigils/BaroKavatSigil", "PrimePrice": 55, "RegularPrice": 45000 }, { "ItemType": "/Lotus/StoreItems/Upgrades/Skins/Sigils/BaroKavatSigil", "PrimePrice": 55, "RegularPrice": 45000 },
{ "ItemType": "/Lotus/StoreItems/Upgrades/Skins/Scarves/WraithTurbinesScarf", "PrimePrice": 400, "RegularPrice": 500000 }, { "ItemType": "/Lotus/StoreItems/Upgrades/Skins/Scarves/WraithTurbinesScarf", "PrimePrice": 400, "RegularPrice": 500000 },
@ -363,7 +362,6 @@
{ "ItemType": "/Lotus/StoreItems/Types/Items/MiscItems/PhotoboothTileInarosTomb", "PrimePrice": 325, "RegularPrice": 175000 }, { "ItemType": "/Lotus/StoreItems/Types/Items/MiscItems/PhotoboothTileInarosTomb", "PrimePrice": 325, "RegularPrice": 175000 },
{ "ItemType": "/Lotus/StoreItems/Types/Restoratives/Consumable/BaroFireWorksCrate", "PrimePrice": 50, "RegularPrice": 100000 }, { "ItemType": "/Lotus/StoreItems/Types/Restoratives/Consumable/BaroFireWorksCrate", "PrimePrice": 50, "RegularPrice": 100000 },
{ "ItemType": "/Lotus/StoreItems/Types/Items/MiscItems/PhotoboothTileOrokinExtraction", "PrimePrice": 325, "RegularPrice": 175000 }, { "ItemType": "/Lotus/StoreItems/Types/Items/MiscItems/PhotoboothTileOrokinExtraction", "PrimePrice": 325, "RegularPrice": 175000 },
{ "ItemType": "/Lotus/StoreItems/Types/Keys/MummyQuestKeyBlueprint", "PrimePrice": 100, "RegularPrice": 25000 },
{ "ItemType": "/Lotus/StoreItems/Types/Restoratives/Consumable/AssassinBait", "PrimePrice": 200, "RegularPrice": 125000 }, { "ItemType": "/Lotus/StoreItems/Types/Restoratives/Consumable/AssassinBait", "PrimePrice": 200, "RegularPrice": 125000 },
{ "ItemType": "/Lotus/StoreItems/Types/Restoratives/Consumable/AssassinBaitB", "PrimePrice": 200, "RegularPrice": 125000 }, { "ItemType": "/Lotus/StoreItems/Types/Restoratives/Consumable/AssassinBaitB", "PrimePrice": 200, "RegularPrice": 125000 },
{ "ItemType": "/Lotus/StoreItems/Types/Items/ShipDecos/BaroKiTeerDecorationB", "PrimePrice": 100, "RegularPrice": 100000 }, { "ItemType": "/Lotus/StoreItems/Types/Items/ShipDecos/BaroKiTeerDecorationB", "PrimePrice": 100, "RegularPrice": 100000 },
@ -401,7 +399,39 @@
{ "ItemType": "/Lotus/StoreItems/Types/Items/ShipDecos/BaroKiTeerDecorationC", "PrimePrice": 100, "RegularPrice": 100000 }, { "ItemType": "/Lotus/StoreItems/Types/Items/ShipDecos/BaroKiTeerDecorationC", "PrimePrice": 100, "RegularPrice": 100000 },
{ "ItemType": "/Lotus/StoreItems/Types/Items/ShipDecos/PedistalPrime", "PrimePrice": 0, "RegularPrice": 1000000 }, { "ItemType": "/Lotus/StoreItems/Types/Items/ShipDecos/PedistalPrime", "PrimePrice": 0, "RegularPrice": 1000000 },
{ "ItemType": "/Lotus/StoreItems/Types/Items/Emotes/BaroEmote", "PrimePrice": 0, "RegularPrice": 1000000 }, { "ItemType": "/Lotus/StoreItems/Types/Items/Emotes/BaroEmote", "PrimePrice": 0, "RegularPrice": 1000000 },
{ "ItemType": "/Lotus/StoreItems/Upgrades/Mods/Rifle/EventSniperReloadDamageMod", "PrimePrice": 2995, "RegularPrice": 1000000 } { "ItemType": "/Lotus/StoreItems/Upgrades/Mods/Rifle/EventSniperReloadDamageMod", "PrimePrice": 2995, "RegularPrice": 1000000 },
{ "ItemType": "/Lotus/StoreItems/Types/StoreItems/AvatarImages/AvatarImageAvaClemCommunityGlyph", "PrimePrice": 20, "RegularPrice": 33333 },
{ "ItemType": "/Lotus/StoreItems/Types/Items/ShipDecos/TennoconConcert2025Display", "PrimePrice": 90, "RegularPrice": 125000 },
{ "ItemType": "/Lotus/StoreItems/Types/Items/ShipDecos/SummerGameFestPoster", "PrimePrice": 90, "RegularPrice": 125000 },
{ "ItemType": "/Lotus/StoreItems/Types/Items/ShipDecos/RathuumEventPoster", "PrimePrice": 90, "RegularPrice": 125000 },
{ "ItemType": "/Lotus/StoreItems/Types/StoreItems/AvatarImages/Factions/GlyphFactionCorpus", "PrimePrice": 70, "RegularPrice": 55000 },
{ "ItemType": "/Lotus/StoreItems/Types/StoreItems/AvatarImages/Factions/GlyphFactionEntrati", "PrimePrice": 99, "RegularPrice": 1900 },
{ "ItemType": "/Lotus/StoreItems/Types/StoreItems/AvatarImages/Factions/GlyphFactionScaldra", "PrimePrice": 93, "RegularPrice": 1906 },
{ "ItemType": "/Lotus/StoreItems/Types/StoreItems/AvatarImages/Factions/GlyphFactionTechrot", "PrimePrice": 98, "RegularPrice": 1901 },
{ "ItemType": "/Lotus/StoreItems/Types/StoreItems/AvatarImages/Warframes/VorunaActionGlyph", "PrimePrice": 75, "RegularPrice": 60000 },
{ "ItemType": "/Lotus/StoreItems/Types/StoreItems/AvatarImages/AvatarImageVoidAngelBaro", "PrimePrice": 80, "RegularPrice": 50000 },
{ "ItemType": "/Lotus/StoreItems/Upgrades/Skins/Sigils/1999DrippySigil", "PrimePrice": 50, "RegularPrice": 45000 },
{ "ItemType": "/Lotus/StoreItems/Upgrades/Skins/Weapons/Rapier/CrpRapierSkin", "PrimePrice": 375, "RegularPrice": 400000 },
{ "ItemType": "/Lotus/StoreItems/Upgrades/Skins/Events/OgrisOldSchool", "PrimePrice": 350, "RegularPrice": 325000 },
{ "ItemType": "/Lotus/StoreItems/Upgrades/Skins/Sigils/PrismaLotusFlamesSigil", "PrimePrice": 55, "RegularPrice": 60000 },
{ "ItemType": "/Lotus/StoreItems/Upgrades/Mods/Melee/Expert/WeaponMeleeFactionDamageMurmursExpert", "PrimePrice": 375, "RegularPrice": 130000 },
{ "ItemType": "/Lotus/StoreItems/Upgrades/Mods/Pistol/Expert/WeaponRecoilReductionModExpert", "PrimePrice": 300, "RegularPrice": 220000 },
{ "ItemType": "/Lotus/StoreItems/Upgrades/Mods/Rifle/Expert/WeaponRecoilReductionModExpert", "PrimePrice": 300, "RegularPrice": 220000 },
{ "ItemType": "/Lotus/StoreItems/Upgrades/Mods/Shotgun/Expert/WeaponRecoilReductionModExpert", "PrimePrice": 300, "RegularPrice": 220000 },
{ "ItemType": "/Lotus/StoreItems/Types/Items/SongItems/TenthAnniversaryLoginSongItem", "PrimePrice": 145, "RegularPrice": 165000 },
{ "ItemType": "/Lotus/StoreItems/Types/Items/SongItems/AbyssofDagathSongItem", "PrimePrice": 150, "RegularPrice": 155000 },
{ "ItemType": "/Lotus/StoreItems/Types/Items/SongItems/ZarimanLoginSongItem", "PrimePrice": 160, "RegularPrice": 180000 },
{ "ItemType": "/Lotus/StoreItems/Types/Items/SongItems/DanteUnboundLoginSongItem", "PrimePrice": 150, "RegularPrice": 150000 },
{ "ItemType": "/Lotus/StoreItems/Types/Items/SongItems/EmpyreanSongItem", "PrimePrice": 160, "RegularPrice": 155000 },
{ "ItemType": "/Lotus/StoreItems/Types/Items/SongItems/DeimosLoginSongItem", "PrimePrice": 155, "RegularPrice": 160000 },
{ "ItemType": "/Lotus/StoreItems/Types/Items/SongItems/JadeShadowsLoginSongItem", "PrimePrice": 150, "RegularPrice": 170000 },
{ "ItemType": "/Lotus/StoreItems/Types/Items/SongItems/WhispersInTheWallLoginSongItem", "PrimePrice": 165, "RegularPrice": 170000 },
{ "ItemType": "/Lotus/StoreItems/Types/Items/SongItems/CorpusRailjackLoginSongItem", "PrimePrice": 150, "RegularPrice": 165000 },
{ "ItemType": "/Lotus/StoreItems/Types/Items/SongItems/LotusEatersSongItem", "PrimePrice": 165, "RegularPrice": 150000 },
{ "ItemType": "/Lotus/StoreItems/Types/Items/SongItems/KuvaLichLoginSongItem", "PrimePrice": 140, "RegularPrice": 170000 },
{ "ItemType": "/Lotus/StoreItems/Types/Items/ShipDecos/Plushies/PlushyBaro", "PrimePrice": 100, "RegularPrice": 125000 },
{ "ItemType": "/Lotus/StoreItems/Types/Items/ShipDecos/Plushies/PlushyInaros", "PrimePrice": 120, "RegularPrice": 90000 },
{ "ItemType": "/Lotus/Upgrades/Mods/Pistol/Expert/WeaponPistolFactionDamageMurmursExpert", "PrimePrice": 375, "RegularPrice": 130000 }
], ],
"allIfAny": [ "allIfAny": [
[ [