forked from OpenWF/SpaceNinjaServer
		
	init
This commit is contained in:
		
							parent
							
								
									372dde7d88
								
							
						
					
					
						commit
						58b1cfc30f
					
				
							
								
								
									
										20
									
								
								src/app.ts
									
									
									
									
									
								
							
							
						
						
									
										20
									
								
								src/app.ts
									
									
									
									
									
								
							@ -15,12 +15,32 @@ import { statsRouter } from "@/src/routes/stats";
 | 
				
			|||||||
import { webuiRouter } from "@/src/routes/webui";
 | 
					import { webuiRouter } from "@/src/routes/webui";
 | 
				
			||||||
import { connectDatabase } from "@/src/services/mongoService";
 | 
					import { connectDatabase } from "@/src/services/mongoService";
 | 
				
			||||||
import { registerLogFileCreationListener } from "@/src/utils/logger";
 | 
					import { registerLogFileCreationListener } from "@/src/utils/logger";
 | 
				
			||||||
 | 
					import * as zlib from 'zlib';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void registerLogFileCreationListener();
 | 
					void registerLogFileCreationListener();
 | 
				
			||||||
void connectDatabase();
 | 
					void connectDatabase();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const app = express();
 | 
					const app = express();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					app.use(function (req, _res, next) {
 | 
				
			||||||
 | 
					    var buffer: Buffer[] = []
 | 
				
			||||||
 | 
					    req.on('data', function (chunk: Buffer) {
 | 
				
			||||||
 | 
					        if (chunk !== undefined && chunk.length > 2 && chunk[0] == 0x1f && chunk[1] == 0x8b) {
 | 
				
			||||||
 | 
					            buffer.push(Buffer.from(chunk));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    req.on('end', function () {
 | 
				
			||||||
 | 
					        zlib.gunzip(Buffer.concat(buffer), function (_err, dezipped) {
 | 
				
			||||||
 | 
					            if (typeof dezipped != 'undefined') {
 | 
				
			||||||
 | 
					                req.body = dezipped.toString('utf-8');
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            next();
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
app.use(bodyParser.raw());
 | 
					app.use(bodyParser.raw());
 | 
				
			||||||
app.use(express.json());
 | 
					app.use(express.json());
 | 
				
			||||||
app.use(bodyParser.text());
 | 
					app.use(bodyParser.text());
 | 
				
			||||||
 | 
				
			|||||||
@ -4,70 +4,7 @@ import { Guild } from "@/src/models/guildModel";
 | 
				
			|||||||
import { getAccountIdForRequest } from "@/src/services/loginService";
 | 
					import { getAccountIdForRequest } from "@/src/services/loginService";
 | 
				
			||||||
import { toOid } from "@/src/helpers/inventoryHelpers";
 | 
					import { toOid } from "@/src/helpers/inventoryHelpers";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// eslint-disable-next-line @typescript-eslint/no-misused-promises
 | 
					const getGuildController: RequestHandler = async (_, res) => {
 | 
				
			||||||
const getGuildController: RequestHandler = async (req, res) => {
 | 
					 | 
				
			||||||
    const accountId = await getAccountIdForRequest(req);
 | 
					 | 
				
			||||||
    const inventory = await Inventory.findOne({ accountOwnerId: accountId });
 | 
					 | 
				
			||||||
    if (!inventory) {
 | 
					 | 
				
			||||||
        res.status(400).json({ error: "inventory was undefined" });
 | 
					 | 
				
			||||||
        return;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    if (inventory.GuildId) {
 | 
					 | 
				
			||||||
        const guild = await Guild.findOne({ _id: inventory.GuildId });
 | 
					 | 
				
			||||||
        if (guild) {
 | 
					 | 
				
			||||||
            res.json({
 | 
					 | 
				
			||||||
                _id: toOid(guild._id),
 | 
					 | 
				
			||||||
                Name: guild.Name,
 | 
					 | 
				
			||||||
                Members: [
 | 
					 | 
				
			||||||
                    {
 | 
					 | 
				
			||||||
                        _id: { $oid: req.query.accountId },
 | 
					 | 
				
			||||||
                        Rank: 0,
 | 
					 | 
				
			||||||
                        Status: 0
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                ],
 | 
					 | 
				
			||||||
                Ranks: [
 | 
					 | 
				
			||||||
                    {
 | 
					 | 
				
			||||||
                        Name: "/Lotus/Language/Game/Rank_Creator",
 | 
					 | 
				
			||||||
                        Permissions: 16351
 | 
					 | 
				
			||||||
                    },
 | 
					 | 
				
			||||||
                    {
 | 
					 | 
				
			||||||
                        Name: "/Lotus/Language/Game/Rank_Warlord",
 | 
					 | 
				
			||||||
                        Permissions: 14303
 | 
					 | 
				
			||||||
                    },
 | 
					 | 
				
			||||||
                    {
 | 
					 | 
				
			||||||
                        Name: "/Lotus/Language/Game/Rank_General",
 | 
					 | 
				
			||||||
                        Permissions: 4318
 | 
					 | 
				
			||||||
                    },
 | 
					 | 
				
			||||||
                    {
 | 
					 | 
				
			||||||
                        Name: "/Lotus/Language/Game/Rank_Officer",
 | 
					 | 
				
			||||||
                        Permissions: 4314
 | 
					 | 
				
			||||||
                    },
 | 
					 | 
				
			||||||
                    {
 | 
					 | 
				
			||||||
                        Name: "/Lotus/Language/Game/Rank_Leader",
 | 
					 | 
				
			||||||
                        Permissions: 4106
 | 
					 | 
				
			||||||
                    },
 | 
					 | 
				
			||||||
                    {
 | 
					 | 
				
			||||||
                        Name: "/Lotus/Language/Game/Rank_Sage",
 | 
					 | 
				
			||||||
                        Permissions: 4304
 | 
					 | 
				
			||||||
                    },
 | 
					 | 
				
			||||||
                    {
 | 
					 | 
				
			||||||
                        Name: "/Lotus/Language/Game/Rank_Soldier",
 | 
					 | 
				
			||||||
                        Permissions: 4098
 | 
					 | 
				
			||||||
                    },
 | 
					 | 
				
			||||||
                    {
 | 
					 | 
				
			||||||
                        Name: "/Lotus/Language/Game/Rank_Initiate",
 | 
					 | 
				
			||||||
                        Permissions: 4096
 | 
					 | 
				
			||||||
                    },
 | 
					 | 
				
			||||||
                    {
 | 
					 | 
				
			||||||
                        Name: "/Lotus/Language/Game/Rank_Utility",
 | 
					 | 
				
			||||||
                        Permissions: 4096
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                ],
 | 
					 | 
				
			||||||
                Tier: 1
 | 
					 | 
				
			||||||
            });
 | 
					 | 
				
			||||||
            return;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    res.json({});
 | 
					    res.json({});
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -9,6 +9,7 @@ import { ILoadoutDatabase } from "@/src/types/saveLoadoutTypes";
 | 
				
			|||||||
import { IInventoryDatabase, IShipInventory, equipmentKeys } from "@/src/types/inventoryTypes/inventoryTypes";
 | 
					import { IInventoryDatabase, IShipInventory, equipmentKeys } from "@/src/types/inventoryTypes/inventoryTypes";
 | 
				
			||||||
import { IPolarity, ArtifactPolarity } from "@/src/types/inventoryTypes/commonInventoryTypes";
 | 
					import { IPolarity, ArtifactPolarity } from "@/src/types/inventoryTypes/commonInventoryTypes";
 | 
				
			||||||
import { ExportCustoms, ExportFlavour, ExportKeys, ExportResources } from "warframe-public-export-plus";
 | 
					import { ExportCustoms, ExportFlavour, ExportKeys, ExportResources } from "warframe-public-export-plus";
 | 
				
			||||||
 | 
					import { IFlavourItem } from "@/src/types/inventoryTypes/inventoryTypes";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// eslint-disable-next-line @typescript-eslint/no-misused-promises
 | 
					// eslint-disable-next-line @typescript-eslint/no-misused-promises
 | 
				
			||||||
const inventoryController: RequestHandler = async (request, response) => {
 | 
					const inventoryController: RequestHandler = async (request, response) => {
 | 
				
			||||||
@ -20,9 +21,7 @@ const inventoryController: RequestHandler = async (request, response) => {
 | 
				
			|||||||
        return;
 | 
					        return;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const inventory = await Inventory.findOne({ accountOwnerId: accountId })
 | 
					    const inventory = await Inventory.findOne({ accountOwnerId: accountId });
 | 
				
			||||||
        .populate<{ LoadOutPresets: ILoadoutDatabase }>("LoadOutPresets")
 | 
					 | 
				
			||||||
        .populate<{ Ships: IShipInventory }>("Ships", "-ShipInteriorColors");
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (!inventory) {
 | 
					    if (!inventory) {
 | 
				
			||||||
        response.status(400).json({ error: "inventory was undefined" });
 | 
					        response.status(400).json({ error: "inventory was undefined" });
 | 
				
			||||||
@ -38,62 +37,17 @@ const inventoryController: RequestHandler = async (request, response) => {
 | 
				
			|||||||
    if (config.infiniteResources) {
 | 
					    if (config.infiniteResources) {
 | 
				
			||||||
        inventoryResponse.RegularCredits = 999999999;
 | 
					        inventoryResponse.RegularCredits = 999999999;
 | 
				
			||||||
        inventoryResponse.TradesRemaining = 999999999;
 | 
					        inventoryResponse.TradesRemaining = 999999999;
 | 
				
			||||||
        inventoryResponse.PremiumCreditsFree = 999999999;
 | 
					 | 
				
			||||||
        inventoryResponse.PremiumCredits = 999999999;
 | 
					        inventoryResponse.PremiumCredits = 999999999;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (config.skipAllDialogue) {
 | 
					    if (config.unlockAllMissions) {
 | 
				
			||||||
        inventoryResponse.TauntHistory = [
 | 
					        //inventoryResponse.Missions = allMissions;
 | 
				
			||||||
            {
 | 
					        //inventoryResponse.NodeIntrosCompleted.push("TeshinHardModeUnlocked");
 | 
				
			||||||
                node: "TreasureTutorial",
 | 
					 | 
				
			||||||
                state: "TS_COMPLETED"
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        ];
 | 
					 | 
				
			||||||
        for (const str of allDialogue) {
 | 
					 | 
				
			||||||
            addString(inventoryResponse.NodeIntrosCompleted, str);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (config.unlockAllMissions) {
 | 
					    if (config.unlockAllMissions) {
 | 
				
			||||||
        inventoryResponse.Missions = allMissions;
 | 
					        //inventoryResponse.Missions = allMissions;
 | 
				
			||||||
        addString(inventoryResponse.NodeIntrosCompleted, "TeshinHardModeUnlocked");
 | 
					        //addString(inventoryResponse.NodeIntrosCompleted, "TeshinHardModeUnlocked");
 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (config.unlockAllQuests) {
 | 
					 | 
				
			||||||
        for (const [k, v] of Object.entries(ExportKeys)) {
 | 
					 | 
				
			||||||
            if ("chainStages" in v) {
 | 
					 | 
				
			||||||
                if (!inventoryResponse.QuestKeys.find(quest => quest.ItemType == k)) {
 | 
					 | 
				
			||||||
                    inventoryResponse.QuestKeys.push({ ItemType: k });
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    if (config.completeAllQuests) {
 | 
					 | 
				
			||||||
        for (const quest of inventoryResponse.QuestKeys) {
 | 
					 | 
				
			||||||
            quest.Completed = true;
 | 
					 | 
				
			||||||
            quest.Progress = [
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    c: 0,
 | 
					 | 
				
			||||||
                    i: false,
 | 
					 | 
				
			||||||
                    m: false,
 | 
					 | 
				
			||||||
                    b: []
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            ];
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        inventoryResponse.ArchwingEnabled = true;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // Skip "Watch The Maker"
 | 
					 | 
				
			||||||
        addString(inventoryResponse.NodeIntrosCompleted, "/Lotus/Levels/Cinematics/NewWarIntro/NewWarStageTwo.level");
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (config.unlockAllShipDecorations) {
 | 
					 | 
				
			||||||
        inventoryResponse.ShipDecorations = [];
 | 
					 | 
				
			||||||
        for (const [uniqueName, item] of Object.entries(ExportResources)) {
 | 
					 | 
				
			||||||
            if (item.productCategory == "ShipDecorations") {
 | 
					 | 
				
			||||||
                inventoryResponse.ShipDecorations.push({ ItemType: uniqueName, ItemCount: 1 });
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (config.unlockAllFlavourItems) {
 | 
					    if (config.unlockAllFlavourItems) {
 | 
				
			||||||
@ -130,23 +84,6 @@ const inventoryController: RequestHandler = async (request, response) => {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (config.universalPolarityEverywhere) {
 | 
					 | 
				
			||||||
        const Polarity: IPolarity[] = [];
 | 
					 | 
				
			||||||
        for (let i = 0; i != 10; ++i) {
 | 
					 | 
				
			||||||
            Polarity.push({
 | 
					 | 
				
			||||||
                Slot: i,
 | 
					 | 
				
			||||||
                Value: ArtifactPolarity.Any
 | 
					 | 
				
			||||||
            });
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        for (const key of equipmentKeys) {
 | 
					 | 
				
			||||||
            if (key in inventoryResponse) {
 | 
					 | 
				
			||||||
                for (const equipment of inventoryResponse[key]) {
 | 
					 | 
				
			||||||
                    equipment.Polarity = Polarity;
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // Fix for #380
 | 
					    // Fix for #380
 | 
				
			||||||
    inventoryResponse.NextRefill = { $date: { $numberLong: "9999999999999" } };
 | 
					    inventoryResponse.NextRefill = { $date: { $numberLong: "9999999999999" } };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -8,7 +8,6 @@ import { toLoginRequest } from "@/src/helpers/loginHelpers";
 | 
				
			|||||||
import { Account } from "@/src/models/loginModel";
 | 
					import { Account } from "@/src/models/loginModel";
 | 
				
			||||||
import { createAccount, isCorrectPassword } from "@/src/services/loginService";
 | 
					import { createAccount, isCorrectPassword } from "@/src/services/loginService";
 | 
				
			||||||
import { ILoginResponse } from "@/src/types/loginTypes";
 | 
					import { ILoginResponse } from "@/src/types/loginTypes";
 | 
				
			||||||
import { DTLS, groups, HUB, platformCDNs } from "@/static/fixed_responses/login_static";
 | 
					 | 
				
			||||||
import { logger } from "@/src/utils/logger";
 | 
					import { logger } from "@/src/utils/logger";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// eslint-disable-next-line @typescript-eslint/no-misused-promises
 | 
					// eslint-disable-next-line @typescript-eslint/no-misused-promises
 | 
				
			||||||
@ -17,7 +16,7 @@ const loginController: RequestHandler = async (request, response) => {
 | 
				
			|||||||
    const body = JSON.parse(request.body); // parse octet stream of json data to json object
 | 
					    const body = JSON.parse(request.body); // parse octet stream of json data to json object
 | 
				
			||||||
    const loginRequest = toLoginRequest(body);
 | 
					    const loginRequest = toLoginRequest(body);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const account = await Account.findOne({ email: loginRequest.email }); //{ _id: 0, __v: 0 }
 | 
					    const account = await Account.findOne({ email: loginRequest.email });
 | 
				
			||||||
    const nonce = Math.round(Math.random() * Number.MAX_SAFE_INTEGER);
 | 
					    const nonce = Math.round(Math.random() * Number.MAX_SAFE_INTEGER);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (!account && config.autoCreateAccount && loginRequest.ClientType != "webui") {
 | 
					    if (!account && config.autoCreateAccount && loginRequest.ClientType != "webui") {
 | 
				
			||||||
@ -26,27 +25,16 @@ const loginController: RequestHandler = async (request, response) => {
 | 
				
			|||||||
                email: loginRequest.email,
 | 
					                email: loginRequest.email,
 | 
				
			||||||
                password: loginRequest.password,
 | 
					                password: loginRequest.password,
 | 
				
			||||||
                DisplayName: loginRequest.email.substring(0, loginRequest.email.indexOf("@")),
 | 
					                DisplayName: loginRequest.email.substring(0, loginRequest.email.indexOf("@")),
 | 
				
			||||||
                CountryCode: loginRequest.lang.toUpperCase(),
 | 
					                Nonce: nonce,
 | 
				
			||||||
                ClientType: loginRequest.ClientType,
 | 
					 | 
				
			||||||
                CrossPlatformAllowed: true,
 | 
					 | 
				
			||||||
                ForceLogoutVersion: 0,
 | 
					 | 
				
			||||||
                ConsentNeeded: false,
 | 
					 | 
				
			||||||
                TrackedSettings: [],
 | 
					 | 
				
			||||||
                Nonce: nonce
 | 
					 | 
				
			||||||
            });
 | 
					            });
 | 
				
			||||||
            logger.debug("created new account");
 | 
					            logger.debug("created new account");
 | 
				
			||||||
            // eslint-disable-next-line @typescript-eslint/no-unused-vars
 | 
					            // eslint-disable-next-line @typescript-eslint/no-unused-vars
 | 
				
			||||||
            const { email, password, ...databaseAccount } = newAccount;
 | 
					            const { email, password, ...databaseAccount } = newAccount;
 | 
				
			||||||
            const newLoginResponse: ILoginResponse = {
 | 
					            const newLoginResponse: ILoginResponse = {
 | 
				
			||||||
                ...databaseAccount,
 | 
					                ...databaseAccount,
 | 
				
			||||||
                Groups: groups,
 | 
					 | 
				
			||||||
                platformCDNs: platformCDNs,
 | 
					 | 
				
			||||||
                NRS: [config.myAddress],
 | 
					 | 
				
			||||||
                DTLS: DTLS,
 | 
					 | 
				
			||||||
                IRC: config.myIrcAddresses ?? [config.myAddress],
 | 
					 | 
				
			||||||
                HUB: HUB,
 | 
					 | 
				
			||||||
                BuildLabel: buildConfig.buildLabel,
 | 
					                BuildLabel: buildConfig.buildLabel,
 | 
				
			||||||
                MatchmakingBuildId: buildConfig.matchmakingBuildId
 | 
					                NatHash: "0",
 | 
				
			||||||
 | 
					                SteamId: "0"
 | 
				
			||||||
            };
 | 
					            };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            response.json(newLoginResponse);
 | 
					            response.json(newLoginResponse);
 | 
				
			||||||
@ -67,22 +55,15 @@ const loginController: RequestHandler = async (request, response) => {
 | 
				
			|||||||
    if (account.Nonce == 0 || loginRequest.ClientType != "webui") {
 | 
					    if (account.Nonce == 0 || loginRequest.ClientType != "webui") {
 | 
				
			||||||
        account.Nonce = nonce;
 | 
					        account.Nonce = nonce;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    if (loginRequest.ClientType != "webui") {
 | 
					    
 | 
				
			||||||
        account.CountryCode = loginRequest.lang.toUpperCase();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    await account.save();
 | 
					    await account.save();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const { email, password, ...databaseAccount } = account.toJSON();
 | 
					    const { email, password, ...databaseAccount } = account.toJSON();
 | 
				
			||||||
    const newLoginResponse: ILoginResponse = {
 | 
					    const newLoginResponse: ILoginResponse = {
 | 
				
			||||||
        ...databaseAccount,
 | 
					        ...databaseAccount,
 | 
				
			||||||
        Groups: groups,
 | 
					 | 
				
			||||||
        platformCDNs: platformCDNs,
 | 
					 | 
				
			||||||
        NRS: [config.myAddress],
 | 
					 | 
				
			||||||
        DTLS: DTLS,
 | 
					 | 
				
			||||||
        IRC: config.myIrcAddresses ?? [config.myAddress],
 | 
					 | 
				
			||||||
        HUB: HUB,
 | 
					 | 
				
			||||||
        BuildLabel: buildConfig.buildLabel,
 | 
					        BuildLabel: buildConfig.buildLabel,
 | 
				
			||||||
        MatchmakingBuildId: buildConfig.matchmakingBuildId
 | 
					        NatHash: "0",
 | 
				
			||||||
 | 
					        SteamId: "0"
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    response.json(newLoginResponse);
 | 
					    response.json(newLoginResponse);
 | 
				
			||||||
 | 
				
			|||||||
@ -8,15 +8,21 @@ import { logger } from "@/src/utils/logger";
 | 
				
			|||||||
export const tauntHistoryController: RequestHandler = async (req, res) => {
 | 
					export const tauntHistoryController: RequestHandler = async (req, res) => {
 | 
				
			||||||
    const accountId = await getAccountIdForRequest(req);
 | 
					    const accountId = await getAccountIdForRequest(req);
 | 
				
			||||||
    const inventory = await getInventory(accountId);
 | 
					    const inventory = await getInventory(accountId);
 | 
				
			||||||
    const clientTaunt = JSON.parse(String(req.body)) as ITaunt;
 | 
					    if(req.body !== undefined)
 | 
				
			||||||
    logger.debug(`updating taunt ${clientTaunt.node} to state ${clientTaunt.state}`);
 | 
					    {
 | 
				
			||||||
    inventory.TauntHistory ??= [];
 | 
					        const clientTaunt = JSON.parse(String(req.body)) as ITaunt;
 | 
				
			||||||
    const taunt = inventory.TauntHistory.find(x => x.node == clientTaunt.node);
 | 
					        logger.debug(`updating taunt ${clientTaunt.node} to state ${clientTaunt.state}`);
 | 
				
			||||||
    if (taunt) {
 | 
					        inventory.TauntHistory ??= [];
 | 
				
			||||||
        taunt.state = clientTaunt.state;
 | 
					        const taunt = inventory.TauntHistory.find(x => x.node == clientTaunt.node);
 | 
				
			||||||
    } else {
 | 
					        if (taunt) {
 | 
				
			||||||
        inventory.TauntHistory.push(clientTaunt);
 | 
					            taunt.state = clientTaunt.state;
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            inventory.TauntHistory.push(clientTaunt);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        await inventory.save();
 | 
				
			||||||
 | 
					        res.end();
 | 
				
			||||||
 | 
					    }else
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        res.json({});
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    await inventory.save();
 | 
					 | 
				
			||||||
    res.end();
 | 
					 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										151
									
								
								src/controllers/api/updateInventoryController.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										151
									
								
								src/controllers/api/updateInventoryController.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,151 @@
 | 
				
			|||||||
 | 
					import { getAccountIdForRequest } from "@/src/services/loginService";
 | 
				
			||||||
 | 
					import { getJSONfromString } from "@/src/helpers/stringHelpers";
 | 
				
			||||||
 | 
					import { startRecipe } from "@/src/services/recipeService";
 | 
				
			||||||
 | 
					import { logger } from "@/src/utils/logger";
 | 
				
			||||||
 | 
					import { RequestHandler } from "express";
 | 
				
			||||||
 | 
					import { getInventory } from "@/src/services/inventoryService";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// eslint-disable-next-line @typescript-eslint/no-misused-promises
 | 
				
			||||||
 | 
					export const updateInventoryController: RequestHandler = async (req, res) => {
 | 
				
			||||||
 | 
					    const accountId = await getAccountIdForRequest(req);
 | 
				
			||||||
 | 
					    const body = JSON.parse(req.body);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const inventory = await getInventory(accountId);
 | 
				
			||||||
 | 
					    inventory.Missions.push({Tag: body.Missions.Tag, Completes: body.Missions.Completes, BestRating: 0.2 })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    await inventory.save();
 | 
				
			||||||
 | 
					    console.log(body);
 | 
				
			||||||
 | 
					    res.json({})
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    "LongGuns" : [
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            "ItemType" : "",
 | 
				
			||||||
 | 
					            "ItemId" : {
 | 
				
			||||||
 | 
					                "$id" : ""
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            "XP" : 882,
 | 
				
			||||||
 | 
					            "UpgradeVer" : 0,
 | 
				
			||||||
 | 
					            "UnlockLevel" : 0,
 | 
				
			||||||
 | 
					            "ExtraCapacity" : 4,
 | 
				
			||||||
 | 
					            "ExtraRemaining" : 4
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					    "Pistols" : [
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            "ItemType" : "",
 | 
				
			||||||
 | 
					            "ItemId" : {
 | 
				
			||||||
 | 
					                "$id" : ""
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            "XP" : 0,
 | 
				
			||||||
 | 
					            "UpgradeVer" : 0,
 | 
				
			||||||
 | 
					            "UnlockLevel" : 0,
 | 
				
			||||||
 | 
					            "ExtraCapacity" : 4,
 | 
				
			||||||
 | 
					            "ExtraRemaining" : 4
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					    "Suits" : [
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            "ItemType" : "",
 | 
				
			||||||
 | 
					            "ItemId" : {
 | 
				
			||||||
 | 
					                "$id" : ""
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            "XP" : 982,
 | 
				
			||||||
 | 
					            "UpgradeVer" : 101,
 | 
				
			||||||
 | 
					            "UnlockLevel" : 0,
 | 
				
			||||||
 | 
					            "ExtraCapacity" : 4,
 | 
				
			||||||
 | 
					            "ExtraRemaining" : 4
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					    "Melee" : [
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            "ItemType" : "",
 | 
				
			||||||
 | 
					            "ItemId" : {
 | 
				
			||||||
 | 
					                "$id" : ""
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            "XP" : 0,
 | 
				
			||||||
 | 
					            "UpgradeVer" : 0,
 | 
				
			||||||
 | 
					            "UnlockLevel" : 0,
 | 
				
			||||||
 | 
					            "ExtraCapacity" : 4,
 | 
				
			||||||
 | 
					            "ExtraRemaining" : 4
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					    "WeaponSkins" : [],
 | 
				
			||||||
 | 
					    "Upgrades" : [],
 | 
				
			||||||
 | 
					    "Boosters" : [],
 | 
				
			||||||
 | 
					    "Robotics" : [],
 | 
				
			||||||
 | 
					    "Consumables" : [],
 | 
				
			||||||
 | 
					    "FlavourItems" : [],
 | 
				
			||||||
 | 
					    "MiscItems" : [],
 | 
				
			||||||
 | 
					    "Cards" : [],
 | 
				
			||||||
 | 
					    "Recipes" : [],
 | 
				
			||||||
 | 
					    "XPInfo" : [],
 | 
				
			||||||
 | 
					    "Sentinels" : [],
 | 
				
			||||||
 | 
					    "SentinelWeapons" : [],
 | 
				
			||||||
 | 
					    "SuitBin" : {
 | 
				
			||||||
 | 
					        "Slots" : 0,
 | 
				
			||||||
 | 
					        "Extra" : 0
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "WeaponBin" : {
 | 
				
			||||||
 | 
					        "Slots" : 0,
 | 
				
			||||||
 | 
					        "Extra" : 0
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "MiscBin" : {
 | 
				
			||||||
 | 
					        "Slots" : 0,
 | 
				
			||||||
 | 
					        "Extra" : 0
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "SentinelBin" : {
 | 
				
			||||||
 | 
					        "Slots" : 0,
 | 
				
			||||||
 | 
					        "Extra" : 0
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "RegularCredits" : 1304,
 | 
				
			||||||
 | 
					    "PremiumCredits" : 0,
 | 
				
			||||||
 | 
					    "PlayerXP" : 784,
 | 
				
			||||||
 | 
					    "AdditionalPlayerXP" : 0,
 | 
				
			||||||
 | 
					    "Rating" : 15,
 | 
				
			||||||
 | 
					    "PlayerLevel" : 0,
 | 
				
			||||||
 | 
					    "TrainingDate" : {
 | 
				
			||||||
 | 
					        "sec" : "",
 | 
				
			||||||
 | 
					        "usec" : ""
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "AliveTime" : 193.78572,
 | 
				
			||||||
 | 
					    "Missions" : {
 | 
				
			||||||
 | 
					        "Tag" : "SolNode103",
 | 
				
			||||||
 | 
					        "Completes" : 1,
 | 
				
			||||||
 | 
					        "BestRating" : 0.2
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "AssignedMissions" : [],
 | 
				
			||||||
 | 
					    "CompletedAlerts" : [],
 | 
				
			||||||
 | 
					    "DeathMarks" : [],
 | 
				
			||||||
 | 
					    "MissionReport" : {
 | 
				
			||||||
 | 
					        "HostId" : "",
 | 
				
			||||||
 | 
					        "MishStartTime" : "1725359860",
 | 
				
			||||||
 | 
					        "MishName" : "SolNode103",
 | 
				
			||||||
 | 
					        "PlayerReport" : {
 | 
				
			||||||
 | 
					            "ReporterId" : "",
 | 
				
			||||||
 | 
					            "FullReport" : true,
 | 
				
			||||||
 | 
					            "PlayerMishInfos" : [
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    "Pid" : "",
 | 
				
			||||||
 | 
					                    "Creds" : 304,
 | 
				
			||||||
 | 
					                    "CredBonus" : 1000,
 | 
				
			||||||
 | 
					                    "Xp" : 784,
 | 
				
			||||||
 | 
					                    "XpBonus" : 0,
 | 
				
			||||||
 | 
					                    "SuitXpBonus" : 590,
 | 
				
			||||||
 | 
					                    "PistolXpBonus" : 0,
 | 
				
			||||||
 | 
					                    "RfileXpBonus" : 490,
 | 
				
			||||||
 | 
					                    "MeleeXpBonus" : 0,
 | 
				
			||||||
 | 
					                    "SentnlXPBonus" : 0,
 | 
				
			||||||
 | 
					                    "SentnlWepXpBonus" : 0,
 | 
				
			||||||
 | 
					                    "Rating" : 0.2,
 | 
				
			||||||
 | 
					                    "Upgrades" : []
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            ]
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
@ -43,11 +43,6 @@ const toAccountCreation = (accountCreation: unknown): IAccountCreation => {
 | 
				
			|||||||
const toDatabaseAccount = (createAccount: IAccountCreation): IDatabaseAccount => {
 | 
					const toDatabaseAccount = (createAccount: IAccountCreation): IDatabaseAccount => {
 | 
				
			||||||
    return {
 | 
					    return {
 | 
				
			||||||
        ...createAccount,
 | 
					        ...createAccount,
 | 
				
			||||||
        ClientType: "",
 | 
					 | 
				
			||||||
        ConsentNeeded: false,
 | 
					 | 
				
			||||||
        CrossPlatformAllowed: true,
 | 
					 | 
				
			||||||
        ForceLogoutVersion: 0,
 | 
					 | 
				
			||||||
        TrackedSettings: [],
 | 
					 | 
				
			||||||
        Nonce: 0
 | 
					        Nonce: 0
 | 
				
			||||||
    } satisfies IDatabaseAccount;
 | 
					    } satisfies IDatabaseAccount;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
				
			|||||||
@ -9,23 +9,11 @@ const toLoginRequest = (loginRequest: unknown): ILoginRequest => {
 | 
				
			|||||||
    // TODO: function that checks whether every field of interface is in object
 | 
					    // TODO: function that checks whether every field of interface is in object
 | 
				
			||||||
    if (
 | 
					    if (
 | 
				
			||||||
        "email" in loginRequest &&
 | 
					        "email" in loginRequest &&
 | 
				
			||||||
        "password" in loginRequest &&
 | 
					        "password" in loginRequest
 | 
				
			||||||
        "time" in loginRequest &&
 | 
					 | 
				
			||||||
        "s" in loginRequest &&
 | 
					 | 
				
			||||||
        "lang" in loginRequest &&
 | 
					 | 
				
			||||||
        "date" in loginRequest &&
 | 
					 | 
				
			||||||
        "ClientType" in loginRequest &&
 | 
					 | 
				
			||||||
        "PS" in loginRequest
 | 
					 | 
				
			||||||
    ) {
 | 
					    ) {
 | 
				
			||||||
        return {
 | 
					        return {
 | 
				
			||||||
            email: parseEmail(loginRequest.email),
 | 
					            email: parseEmail(loginRequest.email),
 | 
				
			||||||
            password: parseString(loginRequest.password),
 | 
					            password: parseString(loginRequest.password)
 | 
				
			||||||
            time: parseNumber(loginRequest.time),
 | 
					 | 
				
			||||||
            s: parseString(loginRequest.s),
 | 
					 | 
				
			||||||
            lang: parseString(loginRequest.lang),
 | 
					 | 
				
			||||||
            date: parseNumber(loginRequest.date),
 | 
					 | 
				
			||||||
            ClientType: parseString(loginRequest.ClientType),
 | 
					 | 
				
			||||||
            PS: parseString(loginRequest.PS)
 | 
					 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -589,61 +589,13 @@ const inventorySchema = new Schema<IInventoryDatabase, InventoryDocumentProps>(
 | 
				
			|||||||
        RegularCredits: Number,
 | 
					        RegularCredits: Number,
 | 
				
			||||||
        //Platinum
 | 
					        //Platinum
 | 
				
			||||||
        PremiumCredits: Number,
 | 
					        PremiumCredits: Number,
 | 
				
			||||||
        //Gift Platinum(Non trade)
 | 
					 | 
				
			||||||
        PremiumCreditsFree: Number,
 | 
					 | 
				
			||||||
        //Endo
 | 
					 | 
				
			||||||
        FusionPoints: Number,
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        //Slots
 | 
					        //Slots
 | 
				
			||||||
        SuitBin: slotsBinSchema,
 | 
					        SuitBin: slotsBinSchema,
 | 
				
			||||||
        WeaponBin: slotsBinSchema,
 | 
					        WeaponBin: slotsBinSchema,
 | 
				
			||||||
        SentinelBin: slotsBinSchema,
 | 
					        SentinelBin: slotsBinSchema,
 | 
				
			||||||
        SpaceSuitBin: slotsBinSchema,
 | 
					 | 
				
			||||||
        SpaceWeaponBin: slotsBinSchema,
 | 
					 | 
				
			||||||
        PvpBonusLoadoutBin: slotsBinSchema,
 | 
					 | 
				
			||||||
        PveBonusLoadoutBin: slotsBinSchema,
 | 
					 | 
				
			||||||
        RandomModBin: slotsBinSchema,
 | 
					        RandomModBin: slotsBinSchema,
 | 
				
			||||||
        OperatorAmpBin: slotsBinSchema,
 | 
					 | 
				
			||||||
        CrewShipSalvageBin: slotsBinSchema,
 | 
					 | 
				
			||||||
        MechBin: slotsBinSchema,
 | 
					        MechBin: slotsBinSchema,
 | 
				
			||||||
        CrewMemberBin: slotsBinSchema,
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        //How many trades do you have left
 | 
					 | 
				
			||||||
        TradesRemaining: Number,
 | 
					 | 
				
			||||||
        //How many Gift do you have left*(gift spends the trade)
 | 
					 | 
				
			||||||
        GiftsRemaining: Number,
 | 
					 | 
				
			||||||
        //Curent trade info Giving or Getting items
 | 
					 | 
				
			||||||
        PendingTrades: [Schema.Types.Mixed],
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        //Syndicate currently being pledged to.
 | 
					 | 
				
			||||||
        SupportedSyndicate: String,
 | 
					 | 
				
			||||||
        //Curent Syndicates rank\exp
 | 
					 | 
				
			||||||
        Affiliations: [affiliationsSchema],
 | 
					 | 
				
			||||||
        //Syndicates Missions complate(Navigation->Syndicate)
 | 
					 | 
				
			||||||
        CompletedSyndicates: [String],
 | 
					 | 
				
			||||||
        //Daily Syndicates Exp
 | 
					 | 
				
			||||||
        DailyAffiliation: Number,
 | 
					 | 
				
			||||||
        DailyAffiliationPvp: Number,
 | 
					 | 
				
			||||||
        DailyAffiliationLibrary: Number,
 | 
					 | 
				
			||||||
        DailyAffiliationCetus: Number,
 | 
					 | 
				
			||||||
        DailyAffiliationQuills: Number,
 | 
					 | 
				
			||||||
        DailyAffiliationSolaris: Number,
 | 
					 | 
				
			||||||
        DailyAffiliationVentkids: Number,
 | 
					 | 
				
			||||||
        DailyAffiliationVox: Number,
 | 
					 | 
				
			||||||
        DailyAffiliationEntrati: Number,
 | 
					 | 
				
			||||||
        DailyAffiliationNecraloid: Number,
 | 
					 | 
				
			||||||
        DailyAffiliationZariman: Number,
 | 
					 | 
				
			||||||
        DailyAffiliationKahl: Number,
 | 
					 | 
				
			||||||
        DailyAffiliationCavia: Number,
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        //Daily Focus limit
 | 
					 | 
				
			||||||
        DailyFocus: Number,
 | 
					 | 
				
			||||||
        //Focus XP per School
 | 
					 | 
				
			||||||
        FocusXP: focusXPSchema,
 | 
					 | 
				
			||||||
        //Curent active like Active school focuses is = "Zenurik"
 | 
					 | 
				
			||||||
        FocusAbility: String,
 | 
					 | 
				
			||||||
        //The treeways of the Focus school.(Active and passive Ability)
 | 
					 | 
				
			||||||
        FocusUpgrades: [focusUpgradesSchema],
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        //Achievement
 | 
					        //Achievement
 | 
				
			||||||
        ChallengeProgress: [challengeProgressSchema],
 | 
					        ChallengeProgress: [challengeProgressSchema],
 | 
				
			||||||
@ -651,8 +603,6 @@ const inventorySchema = new Schema<IInventoryDatabase, InventoryDocumentProps>(
 | 
				
			|||||||
        //Account Item like Ferrite,Form,Kuva etc
 | 
					        //Account Item like Ferrite,Form,Kuva etc
 | 
				
			||||||
        MiscItems: [typeCountSchema],
 | 
					        MiscItems: [typeCountSchema],
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        //Non Upgrade Mods Example:I have 999 item WeaponElectricityDamageMod (only "ItemCount"+"ItemType")
 | 
					 | 
				
			||||||
        RawUpgrades: [RawUpgrades],
 | 
					 | 
				
			||||||
        //Upgrade Mods\Riven\Arcane Example:"UpgradeFingerprint"+"ItemType"+""
 | 
					        //Upgrade Mods\Riven\Arcane Example:"UpgradeFingerprint"+"ItemType"+""
 | 
				
			||||||
        Upgrades: [upgradesSchema],
 | 
					        Upgrades: [upgradesSchema],
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -672,95 +622,26 @@ const inventorySchema = new Schema<IInventoryDatabase, InventoryDocumentProps>(
 | 
				
			|||||||
        //Sentinel(like Helios or modular)
 | 
					        //Sentinel(like Helios or modular)
 | 
				
			||||||
        Sentinels: [EquipmentSchema],
 | 
					        Sentinels: [EquipmentSchema],
 | 
				
			||||||
        //Any /Sentinels/SentinelWeapons/ (like warframe weapon)
 | 
					        //Any /Sentinels/SentinelWeapons/ (like warframe weapon)
 | 
				
			||||||
        SentinelWeapons: [EquipmentSchema],
 | 
					        SentinelWeapons: [Schema.Types.Mixed],
 | 
				
			||||||
        //Modular Pets
 | 
					 | 
				
			||||||
        MoaPets: [EquipmentSchema],
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        KubrowPetEggs: [Schema.Types.Mixed],
 | 
					 | 
				
			||||||
        //Like PowerSuit Cat\Kubrow or etc Pets
 | 
					 | 
				
			||||||
        KubrowPets: [EquipmentSchema],
 | 
					 | 
				
			||||||
        //Prints   Cat(3 Prints)\Kubrow(2 Prints) Pets
 | 
					 | 
				
			||||||
        KubrowPetPrints: [Schema.Types.Mixed],
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        //Item for EquippedGear example:Scaner,LoadoutTechSummon etc
 | 
					        //Item for EquippedGear example:Scaner,LoadoutTechSummon etc
 | 
				
			||||||
        Consumables: [typeCountSchema],
 | 
					        Consumables: [typeCountSchema],
 | 
				
			||||||
        //Weel Emotes+Gear
 | 
					        //Weel Emotes+Gear
 | 
				
			||||||
        EquippedEmotes: [String],
 | 
					 | 
				
			||||||
        EquippedGear: [String],
 | 
					 | 
				
			||||||
        //Equipped Shawzin
 | 
					        //Equipped Shawzin
 | 
				
			||||||
        EquippedInstrument: String,
 | 
					 | 
				
			||||||
        ReceivedStartingGear: Boolean,
 | 
					        ReceivedStartingGear: Boolean,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        //to use add SummonItem to Consumables+EquippedGear
 | 
					        //Complete Mission
 | 
				
			||||||
        //Archwing need Suits+Melee+Guns
 | 
					 | 
				
			||||||
        SpaceSuits: [EquipmentSchema],
 | 
					 | 
				
			||||||
        SpaceMelee: [EquipmentSchema],
 | 
					 | 
				
			||||||
        SpaceGuns: [EquipmentSchema],
 | 
					 | 
				
			||||||
        ArchwingEnabled: Boolean,
 | 
					 | 
				
			||||||
        //Mech need Suits+SpaceGuns+SpecialItem
 | 
					 | 
				
			||||||
        MechSuits: [EquipmentSchema],
 | 
					 | 
				
			||||||
        ///Restoratives/HoverboardSummon (like Suit)
 | 
					 | 
				
			||||||
        Hoverboards: [EquipmentSchema],
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        //Use Operator\Drifter
 | 
					 | 
				
			||||||
        UseAdultOperatorLoadout: Boolean,
 | 
					 | 
				
			||||||
        //Operator\Drifter Weapon
 | 
					 | 
				
			||||||
        OperatorAmps: [EquipmentSchema],
 | 
					 | 
				
			||||||
        //Operator
 | 
					 | 
				
			||||||
        OperatorLoadOuts: [operatorConfigSchema],
 | 
					 | 
				
			||||||
        //Drifter
 | 
					 | 
				
			||||||
        AdultOperatorLoadOuts: [operatorConfigSchema],
 | 
					 | 
				
			||||||
        DrifterMelee: [EquipmentSchema],
 | 
					 | 
				
			||||||
        DrifterGuns: [EquipmentSchema],
 | 
					 | 
				
			||||||
        //ErsatzHorsePowerSuit
 | 
					 | 
				
			||||||
        Horses: [EquipmentSchema],
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        //LandingCraft like Liset
 | 
					 | 
				
			||||||
        Ships: { type: [Schema.Types.ObjectId], ref: "Ships" },
 | 
					 | 
				
			||||||
        // /Lotus/Types/Items/ShipDecos/
 | 
					 | 
				
			||||||
        ShipDecorations: [typeCountSchema],
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        //RailJack Setting(Mods,Skin,Weapon,etc)
 | 
					 | 
				
			||||||
        CrewShipHarnesses: [EquipmentSchema],
 | 
					 | 
				
			||||||
        //Railjack/Components(https://warframe.fandom.com/wiki/Railjack/Components)
 | 
					 | 
				
			||||||
        CrewShipRawSalvage: [Schema.Types.Mixed],
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        //Default RailJack
 | 
					 | 
				
			||||||
        CrewShips: [Schema.Types.Mixed],
 | 
					 | 
				
			||||||
        CrewShipAmmo: [typeCountSchema],
 | 
					 | 
				
			||||||
        CrewShipWeapons: [Schema.Types.Mixed],
 | 
					 | 
				
			||||||
        CrewShipWeaponSkins: [Schema.Types.Mixed],
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        //NPC Crew and weapon
 | 
					 | 
				
			||||||
        CrewMembers: [Schema.Types.Mixed],
 | 
					 | 
				
			||||||
        CrewShipSalvagedWeaponSkins: [Schema.Types.Mixed],
 | 
					 | 
				
			||||||
        CrewShipSalvagedWeapons: [Schema.Types.Mixed],
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        //Complete Mission\Quests
 | 
					 | 
				
			||||||
        Missions: [Schema.Types.Mixed],
 | 
					        Missions: [Schema.Types.Mixed],
 | 
				
			||||||
        QuestKeys: [questKeysSchema],
 | 
					 | 
				
			||||||
        //item like DojoKey or Boss missions key
 | 
					 | 
				
			||||||
        LevelKeys: [Schema.Types.Mixed],
 | 
					 | 
				
			||||||
        //Active quests
 | 
					 | 
				
			||||||
        Quests: [Schema.Types.Mixed],
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        //Cosmetics like profile glyphs\Kavasa Prime Kubrow Collar\Game Theme etc
 | 
					        //Cosmetics like profile glyphs\Kavasa Prime Kubrow Collar\Game Theme etc
 | 
				
			||||||
        FlavourItems: [FlavourItemSchema],
 | 
					        FlavourItems: [FlavourItemSchema],
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        //Lunaro Weapon
 | 
					 | 
				
			||||||
        Scoops: [EquipmentSchema],
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        //Mastery Rank*(Need item XPInfo to rank up)
 | 
					        //Mastery Rank*(Need item XPInfo to rank up)
 | 
				
			||||||
        PlayerLevel: Number,
 | 
					        PlayerLevel: Number,
 | 
				
			||||||
        //Item Mastery Rank exp
 | 
					        //Item Mastery Rank exp
 | 
				
			||||||
        XPInfo: [TypeXPItemSchema],
 | 
					        XPInfo: [TypeXPItemSchema],
 | 
				
			||||||
        //Mastery Rank next availability
 | 
					        //Mastery Rank next availability
 | 
				
			||||||
        TrainingDate: Date,
 | 
					        TrainingDate: Date,
 | 
				
			||||||
        //Retries rank up(3 time)
 | 
					 | 
				
			||||||
        TrainingRetriesLeft: Number,
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        //you saw last played Region when you opened the star map
 | 
					 | 
				
			||||||
        LastRegionPlayed: String,
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        //Blueprints for Foundry
 | 
					        //Blueprints for Foundry
 | 
				
			||||||
        Recipes: [typeCountSchema],
 | 
					        Recipes: [typeCountSchema],
 | 
				
			||||||
@ -770,116 +651,35 @@ const inventorySchema = new Schema<IInventoryDatabase, InventoryDocumentProps>(
 | 
				
			|||||||
        //Skins for Suits, Weapons etc.
 | 
					        //Skins for Suits, Weapons etc.
 | 
				
			||||||
        WeaponSkins: [weaponSkinsSchema],
 | 
					        WeaponSkins: [weaponSkinsSchema],
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        //Ayatan Item
 | 
					 | 
				
			||||||
        FusionTreasures: [fusionTreasuresSchema],
 | 
					 | 
				
			||||||
        //only used for Maroo apparently - { "node": "TreasureTutorial", "state": "TS_COMPLETED" }
 | 
					 | 
				
			||||||
        TauntHistory: { type: [tauntSchema], default: undefined },
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        //noShow2FA,VisitPrimeVault etc
 | 
					        //noShow2FA,VisitPrimeVault etc
 | 
				
			||||||
        WebFlags: Schema.Types.Mixed,
 | 
					        WebFlags: Schema.Types.Mixed,
 | 
				
			||||||
        //Id CompletedAlerts
 | 
					        //Id CompletedAlerts
 | 
				
			||||||
        CompletedAlerts: [String],
 | 
					        CompletedAlerts: [String],
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        //Warframe\Duviri
 | 
					 | 
				
			||||||
        StoryModeChoice: String,
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        //Alert->Kuva Siphon
 | 
					 | 
				
			||||||
        PeriodicMissionCompletions: [periodicMissionCompletionsSchema],
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        //Codex->LoreFragment
 | 
					 | 
				
			||||||
        LoreFragmentScans: [loreFragmentScansSchema],
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        //Resource,Credit,Affinity etc or Bless any boosters
 | 
					        //Resource,Credit,Affinity etc or Bless any boosters
 | 
				
			||||||
        Boosters: [boosterSchema],
 | 
					        Boosters: [boosterSchema],
 | 
				
			||||||
        BlessingCooldown: Date, // Date convert to IMongoDate
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        //the color your clan requests like Items/Research/DojoColors/DojoColorPlainsB
 | 
					 | 
				
			||||||
        ActiveDojoColorResearch: String,
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        SentientSpawnChanceBoosters: Schema.Types.Mixed,
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        QualifyingInvasions: [Schema.Types.Mixed],
 | 
					 | 
				
			||||||
        FactionScores: [Number],
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        //Have only Suit+Pistols+LongGuns+Melee+ItemType(BronzeSpectre,GoldSpectre,PlatinumSpectreArmy,SilverSpectreArmy)
 | 
					 | 
				
			||||||
        //"/Lotus/Types/Game/SpectreArmies/BronzeSpectreArmy": "Vapor Specter Regiment",
 | 
					 | 
				
			||||||
        SpectreLoadouts: [spectreLoadoutsSchema],
 | 
					 | 
				
			||||||
        //If you want change Spectre Gear id
 | 
					 | 
				
			||||||
        PendingSpectreLoadouts: [Schema.Types.Mixed],
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        //New Quest Email
 | 
					        //New Quest Email
 | 
				
			||||||
        EmailItems: [TypeXPItemSchema],
 | 
					        EmailItems: [TypeXPItemSchema],
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        //Profile->Wishlist
 | 
					 | 
				
			||||||
        Wishlist: [String],
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        //https://warframe.fandom.com/wiki/Alignment
 | 
					        //https://warframe.fandom.com/wiki/Alignment
 | 
				
			||||||
        //like "Alignment": { "Wisdom": 9, "Alignment": 1 },
 | 
					        //like "Alignment": { "Wisdom": 9, "Alignment": 1 },
 | 
				
			||||||
        Alignment: Schema.Types.Mixed,
 | 
					        Alignment: Schema.Types.Mixed,
 | 
				
			||||||
        AlignmentReplay: Schema.Types.Mixed,
 | 
					        AlignmentReplay: Schema.Types.Mixed,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        //https://warframe.fandom.com/wiki/Sortie
 | 
					 | 
				
			||||||
        CompletedSorties: [String],
 | 
					 | 
				
			||||||
        LastSortieReward: [Schema.Types.Mixed],
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        //Resource_Drone[Uselees stuff]
 | 
					 | 
				
			||||||
        Drones: [Schema.Types.Mixed],
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        //Active profile ico
 | 
					        //Active profile ico
 | 
				
			||||||
        ActiveAvatarImageType: String,
 | 
					        ActiveAvatarImageType: String,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // open location store like EidolonPlainsDiscoverable or OrbVallisCaveDiscoverable
 | 
					 | 
				
			||||||
        DiscoveredMarkers: [Schema.Types.Mixed],
 | 
					 | 
				
			||||||
        //Open location mission like "JobId" + "StageCompletions"
 | 
					 | 
				
			||||||
        CompletedJobs: [Schema.Types.Mixed],
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        //Game mission\ivent score example  "Tag": "WaterFight", "Best": 170, "Count": 1258,
 | 
					 | 
				
			||||||
        PersonalGoalProgress: [Schema.Types.Mixed],
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        //Setting interface Style
 | 
					 | 
				
			||||||
        ThemeStyle: String,
 | 
					 | 
				
			||||||
        ThemeBackground: String,
 | 
					 | 
				
			||||||
        ThemeSounds: String,
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        //Daily LoginRewards
 | 
					 | 
				
			||||||
        LoginMilestoneRewards: [String],
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        //You first Dialog with NPC or use new Item
 | 
					        //You first Dialog with NPC or use new Item
 | 
				
			||||||
        NodeIntrosCompleted: [String],
 | 
					        NodeIntrosCompleted: [String],
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        //Current guild id, if applicable.
 | 
					        //Current guild id, if applicable.
 | 
				
			||||||
        GuildId: { type: Schema.Types.ObjectId, ref: "Guild" },
 | 
					        GuildId: { type: Schema.Types.ObjectId, ref: "Guild" },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        //https://warframe.fandom.com/wiki/Heist
 | 
					 | 
				
			||||||
        //ProfitTaker(1-4) Example:"LocationTag": "EudicoHeists", "Jobs":Mission name
 | 
					 | 
				
			||||||
        CompletedJobChains: [completedJobChainsSchema],
 | 
					 | 
				
			||||||
        //Night Wave Challenge
 | 
					 | 
				
			||||||
        SeasonChallengeHistory: [seasonChallengeHistorySchema],
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        //Cephalon Simaris Entries Example:"TargetType"+"Scans"(1-10)+"Completed": true|false
 | 
					 | 
				
			||||||
        LibraryPersonalProgress: [Schema.Types.Mixed],
 | 
					 | 
				
			||||||
        //Cephalon Simaris Daily Task
 | 
					 | 
				
			||||||
        LibraryAvailableDailyTaskInfo: Schema.Types.Mixed,
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        //https://warframe.fandom.com/wiki/Invasion
 | 
					 | 
				
			||||||
        InvasionChainProgress: [Schema.Types.Mixed],
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        //https://warframe.fandom.com/wiki/Parazon
 | 
					 | 
				
			||||||
        DataKnives: [EquipmentSchema],
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        //CorpusLich or GrineerLich
 | 
					 | 
				
			||||||
        NemesisAbandonedRewards: [String],
 | 
					 | 
				
			||||||
        //CorpusLich\KuvaLich
 | 
					 | 
				
			||||||
        NemesisHistory: [Schema.Types.Mixed],
 | 
					 | 
				
			||||||
        LastNemesisAllySpawnTime: Schema.Types.Mixed,
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        //TradingRulesConfirmed,ShowFriendInvNotifications(Option->Social)
 | 
					        //TradingRulesConfirmed,ShowFriendInvNotifications(Option->Social)
 | 
				
			||||||
        Settings: settingsSchema,
 | 
					        Settings: settingsSchema,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        //Railjack craft
 | 
					 | 
				
			||||||
        //https://warframe.fandom.com/wiki/Rising_Tide
 | 
					 | 
				
			||||||
        PersonalTechProjects: [Schema.Types.Mixed],
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        //Modulars lvl and exp(Railjack|Duviri)
 | 
					        //Modulars lvl and exp(Railjack|Duviri)
 | 
				
			||||||
        //https://warframe.fandom.com/wiki/Intrinsics
 | 
					        //https://warframe.fandom.com/wiki/Intrinsics
 | 
				
			||||||
        PlayerSkills: playerSkillsSchema,
 | 
					        PlayerSkills: playerSkillsSchema,
 | 
				
			||||||
@ -887,42 +687,15 @@ const inventorySchema = new Schema<IInventoryDatabase, InventoryDocumentProps>(
 | 
				
			|||||||
        //TradeBannedUntil data
 | 
					        //TradeBannedUntil data
 | 
				
			||||||
        TradeBannedUntil: Schema.Types.Mixed,
 | 
					        TradeBannedUntil: Schema.Types.Mixed,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        //https://warframe.fandom.com/wiki/Helminth
 | 
					 | 
				
			||||||
        InfestedFoundry: infestedFoundrySchema,
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        NextRefill: Schema.Types.Mixed, // Date, convert to IMongoDate
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        //Purchase this new permanent skin from the Lotus customization options in Personal Quarters located in your Orbiter.
 | 
					 | 
				
			||||||
        //https://warframe.fandom.com/wiki/Lotus#The_New_War
 | 
					 | 
				
			||||||
        LotusCustomization: Schema.Types.Mixed,
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        //Progress+Rank+ItemType(ZarimanPumpShotgun)
 | 
					 | 
				
			||||||
        //https://warframe.fandom.com/wiki/Incarnon
 | 
					 | 
				
			||||||
        EvolutionProgress: { type: [evolutionProgressSchema], default: undefined },
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        //Unknown and system
 | 
					        //Unknown and system
 | 
				
			||||||
        DuviriInfo: DuviriInfoSchema,
 | 
					 | 
				
			||||||
        Mailbox: MailboxSchema,
 | 
					        Mailbox: MailboxSchema,
 | 
				
			||||||
        KahlLoadOuts: [Schema.Types.Mixed],
 | 
					 | 
				
			||||||
        HandlerPoints: Number,
 | 
					        HandlerPoints: Number,
 | 
				
			||||||
        ChallengesFixVersion: Number,
 | 
					        ChallengesFixVersion: Number,
 | 
				
			||||||
        PlayedParkourTutorial: Boolean,
 | 
					        PlayedParkourTutorial: Boolean,
 | 
				
			||||||
        SubscribedToEmailsPersonalized: Number,
 | 
					        SubscribedToEmailsPersonalized: Number,
 | 
				
			||||||
        LastInventorySync: Schema.Types.Mixed, // this should be Schema.Types.ObjectId, but older inventories may break with that.
 | 
					        LastInventorySync: Schema.Types.Mixed,
 | 
				
			||||||
        ActiveLandscapeTraps: [Schema.Types.Mixed],
 | 
					 | 
				
			||||||
        RepVotes: [Schema.Types.Mixed],
 | 
					 | 
				
			||||||
        LeagueTickets: [Schema.Types.Mixed],
 | 
					 | 
				
			||||||
        HasContributedToDojo: Boolean,
 | 
					 | 
				
			||||||
        HWIDProtectEnabled: Boolean,
 | 
					 | 
				
			||||||
        LoadOutPresets: { type: Schema.Types.ObjectId, ref: "Loadout" },
 | 
					 | 
				
			||||||
        CurrentLoadOutIds: [Schema.Types.Mixed],
 | 
					 | 
				
			||||||
        RandomUpgradesIdentified: Number,
 | 
					 | 
				
			||||||
        BountyScore: Number,
 | 
					 | 
				
			||||||
        ChallengeInstanceStates: [Schema.Types.Mixed],
 | 
					 | 
				
			||||||
        RecentVendorPurchases: [Schema.Types.Mixed],
 | 
					 | 
				
			||||||
        Robotics: [Schema.Types.Mixed],
 | 
					        Robotics: [Schema.Types.Mixed],
 | 
				
			||||||
        UsedDailyDeals: [Schema.Types.Mixed],
 | 
					 | 
				
			||||||
        CollectibleSeries: [Schema.Types.Mixed],
 | 
					 | 
				
			||||||
        HasResetAccount: Boolean,
 | 
					        HasResetAccount: Boolean,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        //Discount Coupon
 | 
					        //Discount Coupon
 | 
				
			||||||
 | 
				
			|||||||
@ -25,15 +25,7 @@ const databaseAccountSchema = new Schema<IDatabaseAccountDocument>(
 | 
				
			|||||||
        email: { type: String, required: true, unique: true },
 | 
					        email: { type: String, required: true, unique: true },
 | 
				
			||||||
        password: { type: String, required: true },
 | 
					        password: { type: String, required: true },
 | 
				
			||||||
        DisplayName: { type: String, required: true },
 | 
					        DisplayName: { type: String, required: true },
 | 
				
			||||||
        CountryCode: { type: String, required: true },
 | 
					        Nonce: { type: Number, required: true }
 | 
				
			||||||
        ClientType: { type: String },
 | 
					 | 
				
			||||||
        CrossPlatformAllowed: { type: Boolean, required: true },
 | 
					 | 
				
			||||||
        ForceLogoutVersion: { type: Number, required: true },
 | 
					 | 
				
			||||||
        AmazonAuthToken: { type: String },
 | 
					 | 
				
			||||||
        AmazonRefreshToken: { type: String },
 | 
					 | 
				
			||||||
        ConsentNeeded: { type: Boolean, required: true },
 | 
					 | 
				
			||||||
        TrackedSettings: { type: [String], default: [] },
 | 
					 | 
				
			||||||
        Nonce: { type: Number, default: 0 }
 | 
					 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    opts
 | 
					    opts
 | 
				
			||||||
);
 | 
					);
 | 
				
			||||||
 | 
				
			|||||||
@ -64,6 +64,8 @@ import { updateChallengeProgressController } from "@/src/controllers/api/updateC
 | 
				
			|||||||
import { updateSessionGetController, updateSessionPostController } from "@/src/controllers/api/updateSessionController";
 | 
					import { updateSessionGetController, updateSessionPostController } from "@/src/controllers/api/updateSessionController";
 | 
				
			||||||
import { updateThemeController } from "../controllers/api/updateThemeController";
 | 
					import { updateThemeController } from "../controllers/api/updateThemeController";
 | 
				
			||||||
import { upgradesController } from "@/src/controllers/api/upgradesController";
 | 
					import { upgradesController } from "@/src/controllers/api/upgradesController";
 | 
				
			||||||
 | 
					import { worldStateController } from "../controllers/dynamic/worldStateController";
 | 
				
			||||||
 | 
					import { updateInventoryController } from "../controllers/api/updateInventoryController";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const apiRouter = express.Router();
 | 
					const apiRouter = express.Router();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -99,6 +101,16 @@ apiRouter.get("/setSupportedSyndicate.php", setSupportedSyndicateController);
 | 
				
			|||||||
apiRouter.get("/surveys.php", surveysController);
 | 
					apiRouter.get("/surveys.php", surveysController);
 | 
				
			||||||
apiRouter.get("/updateSession.php", updateSessionGetController);
 | 
					apiRouter.get("/updateSession.php", updateSessionGetController);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					apiRouter.get('/getMessages.php', (_, response) => {
 | 
				
			||||||
 | 
					    response.json({});
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
 | 
					apiRouter.get('/trainingResult.php', (_, response) => {
 | 
				
			||||||
 | 
					    response.status(200);
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
 | 
					apiRouter.get('/giveStartingGear.php', (_, response) => {
 | 
				
			||||||
 | 
					    response.status(200);
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
 | 
					apiRouter.get('/worldState.php', worldStateController);
 | 
				
			||||||
// post
 | 
					// post
 | 
				
			||||||
apiRouter.post("/addFriendImage.php", addFriendImageController);
 | 
					apiRouter.post("/addFriendImage.php", addFriendImageController);
 | 
				
			||||||
apiRouter.post("/artifacts.php", artifactsController);
 | 
					apiRouter.post("/artifacts.php", artifactsController);
 | 
				
			||||||
@ -138,5 +150,6 @@ apiRouter.post("/updateNodeIntros.php", genericUpdateController);
 | 
				
			|||||||
apiRouter.post("/updateSession.php", updateSessionPostController);
 | 
					apiRouter.post("/updateSession.php", updateSessionPostController);
 | 
				
			||||||
apiRouter.post("/updateTheme.php", updateThemeController);
 | 
					apiRouter.post("/updateTheme.php", updateThemeController);
 | 
				
			||||||
apiRouter.post("/upgrades.php", upgradesController);
 | 
					apiRouter.post("/upgrades.php", upgradesController);
 | 
				
			||||||
 | 
					apiRouter.post("/updateInventory.php", updateInventoryController);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export { apiRouter };
 | 
					export { apiRouter };
 | 
				
			||||||
 | 
				
			|||||||
@ -12,6 +12,11 @@ cacheRouter.get("/B.Cache.Windows_en.bin*", (_req, res) => {
 | 
				
			|||||||
    res.sendFile("static/data/B.Cache.Windows_en_33.0.10.bin", { root: "./" });
 | 
					    res.sendFile("static/data/B.Cache.Windows_en_33.0.10.bin", { root: "./" });
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					cacheRouter.get("/H.Cache.bin!03_---------------------w", (_req, res) => {
 | 
				
			||||||
 | 
					    res.sendFile(`static/data/H.Cache.bin`, { root: "./" });
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
cacheRouter.get(/^\/origin\/[a-zA-Z0-9]+\/[0-9]+\/H\.Cache\.bin.*$/, (_req, res) => {
 | 
					cacheRouter.get(/^\/origin\/[a-zA-Z0-9]+\/[0-9]+\/H\.Cache\.bin.*$/, (_req, res) => {
 | 
				
			||||||
    res.sendFile(`static/data/H.Cache_${buildConfig.version}.bin`, { root: "./" });
 | 
					    res.sendFile(`static/data/H.Cache_${buildConfig.version}.bin`, { root: "./" });
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
				
			|||||||
@ -666,9 +666,8 @@ export interface ILotusCustomization extends IItemConfig {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
export interface IMission {
 | 
					export interface IMission {
 | 
				
			||||||
    Completes: number;
 | 
					    Completes: number;
 | 
				
			||||||
    Tier?: number;
 | 
					 | 
				
			||||||
    Tag: string;
 | 
					    Tag: string;
 | 
				
			||||||
    RewardsCooldownTime?: IMongoDate;
 | 
					    BestRating?: number;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export interface INemesisHistory {
 | 
					export interface INemesisHistory {
 | 
				
			||||||
 | 
				
			|||||||
@ -1,12 +1,7 @@
 | 
				
			|||||||
export interface ILoginResponse extends Omit<IDatabaseAccountDocument, "email" | "password"> {
 | 
					export interface ILoginResponse extends Omit<IDatabaseAccountDocument, "email" | "password"> {
 | 
				
			||||||
    Groups: IGroup[];
 | 
					    BuildLabel?: string;
 | 
				
			||||||
    BuildLabel: string;
 | 
					    NatHash?: string;
 | 
				
			||||||
    MatchmakingBuildId: string;
 | 
					    SteamId?: string;
 | 
				
			||||||
    platformCDNs: string[];
 | 
					 | 
				
			||||||
    NRS: string[];
 | 
					 | 
				
			||||||
    DTLS: number;
 | 
					 | 
				
			||||||
    IRC: string[];
 | 
					 | 
				
			||||||
    HUB: string;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Includes virtual ID
 | 
					// Includes virtual ID
 | 
				
			||||||
@ -20,27 +15,14 @@ export interface IGroup {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export interface IDatabaseAccount {
 | 
					export interface IDatabaseAccount {
 | 
				
			||||||
    email: string;
 | 
					    email?: string;
 | 
				
			||||||
    password: string;
 | 
					    password: string;
 | 
				
			||||||
    DisplayName: string;
 | 
					    DisplayName?: string;
 | 
				
			||||||
    CountryCode: string;
 | 
					    Nonce?: number;
 | 
				
			||||||
    ClientType: string;
 | 
					 | 
				
			||||||
    CrossPlatformAllowed: boolean;
 | 
					 | 
				
			||||||
    ForceLogoutVersion: number;
 | 
					 | 
				
			||||||
    AmazonAuthToken?: string;
 | 
					 | 
				
			||||||
    AmazonRefreshToken?: string;
 | 
					 | 
				
			||||||
    ConsentNeeded: boolean;
 | 
					 | 
				
			||||||
    TrackedSettings: string[];
 | 
					 | 
				
			||||||
    Nonce: number;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export interface ILoginRequest {
 | 
					export interface ILoginRequest {
 | 
				
			||||||
    email: string;
 | 
					    email: string;
 | 
				
			||||||
    password: string;
 | 
					    password: string;
 | 
				
			||||||
    time: number;
 | 
					    ClientType?: string;
 | 
				
			||||||
    s: string;
 | 
					 | 
				
			||||||
    lang: string;
 | 
					 | 
				
			||||||
    date: number;
 | 
					 | 
				
			||||||
    ClientType: string;
 | 
					 | 
				
			||||||
    PS: string;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -2,163 +2,47 @@
 | 
				
			|||||||
  "SubscribedToEmails": 0,
 | 
					  "SubscribedToEmails": 0,
 | 
				
			||||||
  "SubscribedToEmailsPersonalized": 0,
 | 
					  "SubscribedToEmailsPersonalized": 0,
 | 
				
			||||||
  "RewardSeed": -5604904486637265640,
 | 
					  "RewardSeed": -5604904486637265640,
 | 
				
			||||||
  "CrewMemberBin": { "Slots": 3 },
 | 
					 | 
				
			||||||
  "CrewShipSalvageBin": { "Slots": 8 },
 | 
					 | 
				
			||||||
  "DrifterMelee": [{ "ItemType": "/Lotus/Types/Friendly/PlayerControllable/Weapons/DuviriDualSwords", "ItemId": { "$oid": "647bd27cf856530b4f3bf343" } }],
 | 
					 | 
				
			||||||
  "FusionPoints": 0,
 | 
					 | 
				
			||||||
  "MechBin": { "Slots": 4 },
 | 
					 | 
				
			||||||
  "OperatorAmpBin": { "Slots": 8 },
 | 
					 | 
				
			||||||
  "PveBonusLoadoutBin": { "Slots": 0 },
 | 
					 | 
				
			||||||
  "PvpBonusLoadoutBin": { "Slots": 0 },
 | 
					 | 
				
			||||||
  "RandomModBin": { "Slots": 15 },
 | 
					 | 
				
			||||||
  "RegularCredits": 3000,
 | 
					  "RegularCredits": 3000,
 | 
				
			||||||
  "SentinelBin": { "Slots": 10 },
 | 
					  "SentinelBin": { "Slots": 10 },
 | 
				
			||||||
  "SpaceSuitBin": { "Slots": 4 },
 | 
					  "SpaceSuitBin": { "Slots": 4 },
 | 
				
			||||||
  "SpaceWeaponBin": { "Slots": 4 },
 | 
					  "SpaceWeaponBin": { "Slots": 4 },
 | 
				
			||||||
  "SuitBin": { "Slots": 1 },
 | 
					  "SuitBin": { "Slots": 1 },
 | 
				
			||||||
  "WeaponBin": { "Slots": 5 },
 | 
					  "WeaponBin": { "Slots": 5 },
 | 
				
			||||||
  "DailyAffiliation": 16000,
 | 
					 | 
				
			||||||
  "DailyAffiliationCetus": 16000,
 | 
					 | 
				
			||||||
  "DailyAffiliationEntrati": 16000,
 | 
					 | 
				
			||||||
  "DailyAffiliationKahl": 16000,
 | 
					 | 
				
			||||||
  "DailyAffiliationLibrary": 16000,
 | 
					 | 
				
			||||||
  "DailyAffiliationNecraloid": 16000,
 | 
					 | 
				
			||||||
  "DailyAffiliationPvp": 16000,
 | 
					 | 
				
			||||||
  "DailyAffiliationQuills": 16000,
 | 
					 | 
				
			||||||
  "DailyAffiliationSolaris": 16000,
 | 
					 | 
				
			||||||
  "DailyAffiliationVentkids": 16000,
 | 
					 | 
				
			||||||
  "DailyAffiliationVox": 16000,
 | 
					 | 
				
			||||||
  "DailyAffiliationZariman": 16000,
 | 
					 | 
				
			||||||
  "DailyAffiliationCavia": 16000,
 | 
					 | 
				
			||||||
  "DailyFocus": 250000,
 | 
					 | 
				
			||||||
  "DuviriInfo": { "Seed": 5898912197983600352, "NumCompletions": 0 },
 | 
					 | 
				
			||||||
  "GiftsRemaining": 8,
 | 
					 | 
				
			||||||
  "TradesRemaining": 0,
 | 
					 | 
				
			||||||
  "Recipes": [{ "ItemCount": 1, "ItemType": "/Lotus/Types/Recipes/Weapons/BoltonfaBlueprint" }],
 | 
					  "Recipes": [{ "ItemCount": 1, "ItemType": "/Lotus/Types/Recipes/Weapons/BoltonfaBlueprint" }],
 | 
				
			||||||
  "SeasonChallengeHistory": [
 | 
					 | 
				
			||||||
    { "challenge": "SeasonDailySolveCiphers", "id": "001000220000000000000308" },
 | 
					 | 
				
			||||||
    { "challenge": "SeasonDailyVisitFeaturedDojo", "id": "001000230000000000000316" },
 | 
					 | 
				
			||||||
    { "challenge": "SeasonDailyKillEnemiesWithRadiation", "id": "001000230000000000000317" },
 | 
					 | 
				
			||||||
    { "challenge": "SeasonWeeklyCompleteSortie", "id": "001000230000000000000309" },
 | 
					 | 
				
			||||||
    { "challenge": "SeasonWeeklyVenusBounties", "id": "001000230000000000000310" },
 | 
					 | 
				
			||||||
    { "challenge": "SeasonWeeklyZarimanBountyHunter", "id": "001000230000000000000311" },
 | 
					 | 
				
			||||||
    { "challenge": "SeasonWeeklyCatchRarePlainsFish", "id": "001000230000000000000312" },
 | 
					 | 
				
			||||||
    { "challenge": "SeasonWeeklyKillArchgunEnemies", "id": "001000230000000000000313" },
 | 
					 | 
				
			||||||
    { "challenge": "SeasonWeeklyHardKillSilverGroveSpecters", "id": "001000230000000000000314" },
 | 
					 | 
				
			||||||
    { "challenge": "SeasonWeeklyHardKillRopalolyst", "id": "001000230000000000000315" }
 | 
					 | 
				
			||||||
  ],
 | 
					 | 
				
			||||||
  "StoryModeChoice": "WARFRAME",
 | 
					 | 
				
			||||||
  "ChallengeProgress": [{ "Progress": 2, "Name": "EMGetKills" }],
 | 
					  "ChallengeProgress": [{ "Progress": 2, "Name": "EMGetKills" }],
 | 
				
			||||||
  "ChallengesFixVersion": 6,
 | 
					 | 
				
			||||||
  "ActiveQuest": "/Lotus/Types/Keys/VorsPrize/VorsPrizeQuestKeyChain",
 | 
					 | 
				
			||||||
  "Consumables": [{ "ItemCount": 1, "ItemType": "/Lotus/Types/Restoratives/LisetAutoHack" }],
 | 
					  "Consumables": [{ "ItemCount": 1, "ItemType": "/Lotus/Types/Restoratives/LisetAutoHack" }],
 | 
				
			||||||
  "DataKnives": [{ "ItemType": "/Lotus/Weapons/Tenno/HackingDevices/TnHackingDevice/TnHackingDeviceWeapon", "XP": 450000, "ItemId": { "$oid": "647bd274f22fc794a2cd3d33" } }],
 | 
					 | 
				
			||||||
  "FlavourItems": [
 | 
					  "FlavourItems": [
 | 
				
			||||||
    { "ItemType": "/Lotus/Types/StoreItems/AvatarImages/AvatarImageItem1" },
 | 
					    { "ItemType": "/Lotus/Types/StoreItems/AvatarImages/AvatarImageItem1" },
 | 
				
			||||||
    { "ItemType": "/Lotus/Types/StoreItems/AvatarImages/AvatarImageItem2" },
 | 
					    { "ItemType": "/Lotus/Types/StoreItems/AvatarImages/AvatarImageItem2" },
 | 
				
			||||||
    { "ItemType": "/Lotus/Types/StoreItems/AvatarImages/AvatarImageItem3" },
 | 
					    { "ItemType": "/Lotus/Types/StoreItems/AvatarImages/AvatarImageItem3" },
 | 
				
			||||||
    { "ItemType": "/Lotus/Types/StoreItems/AvatarImages/AvatarImageItem4" }
 | 
					    { "ItemType": "/Lotus/Types/StoreItems/AvatarImages/AvatarImageItem4" }
 | 
				
			||||||
  ],
 | 
					  ],
 | 
				
			||||||
  "LongGuns": [{ "ItemType": "/Lotus/Weapons/MK1Series/MK1Paris", "XP": 0, "Configs": [{}, {}, {}], "ItemId": { "$oid": "647bd27cf856530b4f3bf343" } }],
 | 
					  "LongGuns": [{ "ItemType": "/Lotus/Weapons/Tenno/Bows/HuntingBow", "XP": 0, "Configs": [{}, {}, {}], "ItemId": { "$oid": "647bd27cf856530b4f3bf343" } }],
 | 
				
			||||||
  "Melee": [{ "ItemType": "/Lotus/Weapons/Tenno/Melee/LongSword/LongSword", "XP": 0, "Configs": [{}, {}, {}], "ItemId": { "$oid": "647bd27cf856530b4f3bf343" } }],
 | 
					  "Melee": [{ "ItemType": "/Lotus/Weapons/Tenno/Melee/LongSword/LongSword", "XP": 0, "Configs": [{}, {}, {}], "ItemId": { "$oid": "647bd27cf856530b4f3bf343" } }],
 | 
				
			||||||
  "Pistols": [{ "ItemType": "/Lotus/Weapons/MK1Series/MK1Kunai", "XP": 0, "Configs": [{}, {}, {}], "ItemId": { "$oid": "647bd27cf856530b4f3bf343" } }],
 | 
					  "Pistols": [{ "ItemType": "/Lotus/Weapons/Tenno/Pistol/TutorialPistol", "XP": 0, "Configs": [{}, {}, {}], "ItemId": { "$oid": "647bd27cf856530b4f3bf343" } }],
 | 
				
			||||||
  "PlayedParkourTutorial": true,
 | 
					 | 
				
			||||||
  "PremiumCreditsFree": 50,
 | 
					 | 
				
			||||||
  "QuestKeys": [{ "ItemType": "/Lotus/Types/Keys/VorsPrize/VorsPrizeQuestKeyChain" }],
 | 
					 | 
				
			||||||
  "RawUpgrades": [{ "ItemCount": 1, "LastAdded": { "$oid": "6450f9bfe0714a4d6703f05f" }, "ItemType": "/Lotus/Upgrades/Mods/Warframe/AvatarShieldMaxMod" }],
 | 
					  "RawUpgrades": [{ "ItemCount": 1, "LastAdded": { "$oid": "6450f9bfe0714a4d6703f05f" }, "ItemType": "/Lotus/Upgrades/Mods/Warframe/AvatarShieldMaxMod" }],
 | 
				
			||||||
  "ReceivedStartingGear": true,
 | 
					  "ReceivedStartingGear": true,
 | 
				
			||||||
  "Scoops": [{ "ItemType": "/Lotus/Weapons/Tenno/Speedball/SpeedballWeaponTest", "ItemId": { "$oid": "647bd27cf856530b4f3bf343" } }],
 | 
					 | 
				
			||||||
  "Ships": [{ "ItemType": "/Lotus/Types/Items/Ships/DefaultShip", "ItemId": { "$oid": "647bd27cf856530b4f3bf343" } }],
 | 
					 | 
				
			||||||
  "Suits": [{ "ItemType": "/Lotus/Powersuits/Volt/Volt", "XP": 0, "Configs": [{}, {}, {}], "UpgradeVer": 101, "ItemId": { "$oid": "647bd27cf856530b4f3bf343" } }],
 | 
					  "Suits": [{ "ItemType": "/Lotus/Powersuits/Volt/Volt", "XP": 0, "Configs": [{}, {}, {}], "UpgradeVer": 101, "ItemId": { "$oid": "647bd27cf856530b4f3bf343" } }],
 | 
				
			||||||
  "TrainingRetriesLeft": 0,
 | 
					 | 
				
			||||||
  "WeaponSkins": [{ "ItemType": "/Lotus/Upgrades/Skins/Volt/VoltHelmet", "ItemId": { "$oid": "647bd27cf856530b4f3bf343" } }],
 | 
					  "WeaponSkins": [{ "ItemType": "/Lotus/Upgrades/Skins/Volt/VoltHelmet", "ItemId": { "$oid": "647bd27cf856530b4f3bf343" } }],
 | 
				
			||||||
  "LastInventorySync": { "$oid": "647bd27cf856530b4f3bf343" },
 | 
					 | 
				
			||||||
  "NextRefill": { "$date": { "$numberLong": "1685829131" } },
 | 
					 | 
				
			||||||
  "ActiveLandscapeTraps": [],
 | 
					 | 
				
			||||||
  "CrewMembers": [],
 | 
					 | 
				
			||||||
  "CrewShips": [],
 | 
					 | 
				
			||||||
  "CrewShipHarnesses": [],
 | 
					 | 
				
			||||||
  "CrewShipSalvagedWeapons": [],
 | 
					 | 
				
			||||||
  "CrewShipSalvagedWeaponSkins": [],
 | 
					 | 
				
			||||||
  "CrewShipWeapons": [],
 | 
					 | 
				
			||||||
  "CrewShipWeaponSkins": [],
 | 
					 | 
				
			||||||
  "DrifterGuns": [],
 | 
					 | 
				
			||||||
  "Drones": [],
 | 
					 | 
				
			||||||
  "Horses": [
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
      "ItemType": "/Lotus/Types/NeutralCreatures/ErsatzHorse/ErsatzHorsePowerSuit",
 | 
					 | 
				
			||||||
      "Configs": [
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
          "Skins": ["", "", "/Lotus/Upgrades/Skins/Horse/ErsatzHorseTailDefault"]
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
          "Skins": ["", "", "/Lotus/Upgrades/Skins/Horse/ErsatzHorseTailDefault"]
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
          "Skins": ["", "", "/Lotus/Upgrades/Skins/Horse/ErsatzHorseTailDefault"]
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      ],
 | 
					 | 
				
			||||||
      "UpgradeVer": 101,
 | 
					 | 
				
			||||||
      "ItemId": { "$oid": "647bd27cf856530b4f3bf343" }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  ],
 | 
					 | 
				
			||||||
  "Hoverboards": [],
 | 
					 | 
				
			||||||
  "KubrowPets": [],
 | 
					 | 
				
			||||||
  "KubrowPetEggs": [],
 | 
					 | 
				
			||||||
  "KubrowPetPrints": [],
 | 
					 | 
				
			||||||
  "MechSuits": [],
 | 
					 | 
				
			||||||
  "MoaPets": [],
 | 
					 | 
				
			||||||
  "OperatorAmps": [],
 | 
					 | 
				
			||||||
  "OperatorLoadOuts": [],
 | 
					 | 
				
			||||||
  "AdultOperatorLoadOuts": [],
 | 
					 | 
				
			||||||
  "KahlLoadOuts": [],
 | 
					 | 
				
			||||||
  "PendingRecipes": [],
 | 
					  "PendingRecipes": [],
 | 
				
			||||||
  "TrainingDate": 0,
 | 
					  "TrainingDate": 0,
 | 
				
			||||||
  "PlayerLevel": 0,
 | 
					  "PlayerLevel": 0,
 | 
				
			||||||
  "PersonalGoalProgress": [],
 | 
					  "CompletedAlerts": [],
 | 
				
			||||||
  "PersonalTechProjects": [],
 | 
					 | 
				
			||||||
  "QualifyingInvasions": [],
 | 
					 | 
				
			||||||
  "RepVotes": [],
 | 
					 | 
				
			||||||
  "Sentinels": [],
 | 
					  "Sentinels": [],
 | 
				
			||||||
  "SentinelWeapons": [],
 | 
					  "SentinelWeapons": [],
 | 
				
			||||||
  "SpaceGuns": [],
 | 
					 | 
				
			||||||
  "SpaceMelee": [],
 | 
					 | 
				
			||||||
  "SpaceSuits": [],
 | 
					 | 
				
			||||||
  "SpecialItems": [],
 | 
					  "SpecialItems": [],
 | 
				
			||||||
  "StepSequencers": [],
 | 
					  "StepSequencers": [],
 | 
				
			||||||
  "Upgrades": [],
 | 
					  "Upgrades": [],
 | 
				
			||||||
  "Boosters": [],
 | 
					  "Boosters": [],
 | 
				
			||||||
  "EmailItems": [],
 | 
					  "EmailItems": [],
 | 
				
			||||||
  "FocusUpgrades": [],
 | 
					 | 
				
			||||||
  "FusionTreasures": [],
 | 
					 | 
				
			||||||
  "LeagueTickets": [],
 | 
					  "LeagueTickets": [],
 | 
				
			||||||
  "LevelKeys": [],
 | 
					 | 
				
			||||||
  "LoreFragmentScans": [],
 | 
					 | 
				
			||||||
  "MiscItems": [],
 | 
					  "MiscItems": [],
 | 
				
			||||||
  "PendingSpectreLoadouts": [],
 | 
					 | 
				
			||||||
  "Quests": [],
 | 
					 | 
				
			||||||
  "Robotics": [],
 | 
					  "Robotics": [],
 | 
				
			||||||
  "ShipDecorations": [],
 | 
					 | 
				
			||||||
  "SpectreLoadouts": [],
 | 
					 | 
				
			||||||
  "XPInfo": [],
 | 
					  "XPInfo": [],
 | 
				
			||||||
  "CrewShipAmmo": [],
 | 
					  "Missions": [ {
 | 
				
			||||||
  "CrewShipRawSalvage": [],
 | 
					    "Tag" : "SolNode103",
 | 
				
			||||||
  "EvolutionProgress": [],
 | 
					    "Completes" : 1,
 | 
				
			||||||
  "Missions": [],
 | 
					    "BestRating" : 0.2
 | 
				
			||||||
  "TauntHistory": [],
 | 
					  }],
 | 
				
			||||||
  "CompletedSyndicates": [],
 | 
					 | 
				
			||||||
  "UsedDailyDeals": [],
 | 
					 | 
				
			||||||
  "LibraryAvailableDailyTaskInfo": {
 | 
					 | 
				
			||||||
    "EnemyTypes": ["/Lotus/Types/Enemies/Orokin/OrokinBladeSawmanAvatar"],
 | 
					 | 
				
			||||||
    "EnemyLocTag": "/Lotus/Language/Game/OrokinBladeSawman",
 | 
					 | 
				
			||||||
    "EnemyIcon": "/Lotus/Interface/Icons/Npcs/Orokin/OrokinBladeSawman.png",
 | 
					 | 
				
			||||||
    "ScansRequired": 4,
 | 
					 | 
				
			||||||
    "RewardStoreItem": "/Lotus/StoreItems/Upgrades/Mods/FusionBundles/UncommonFusionBundle",
 | 
					 | 
				
			||||||
    "RewardQuantity": 10,
 | 
					 | 
				
			||||||
    "RewardStanding": 10000
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
  "HasContributedToDojo": false,
 | 
					 | 
				
			||||||
  "HasResetAccount": false,
 | 
					 | 
				
			||||||
  "PendingCoupon": { "Expiry": { "$date": { "$numberLong": "0" } }, "Discount": 0 },
 | 
					 | 
				
			||||||
  "PremiumCredits": 50
 | 
					  "PremiumCredits": 50
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user