diff --git a/src/controllers/api/inventoryController.ts b/src/controllers/api/inventoryController.ts index c3ad296a..f2bf0408 100644 --- a/src/controllers/api/inventoryController.ts +++ b/src/controllers/api/inventoryController.ts @@ -5,6 +5,7 @@ import { Request, RequestHandler, Response } from "express"; import config from "@/config.json"; import testMissions from "@/static/fixed_responses/testMissions.json"; import testQuestKeys from "@/static/fixed_responses/testQuestKeys.json"; +import testInventory from "../../../static/testInventory.json"; const inventoryController: RequestHandler = async (request: Request, response: Response) => { const accountId = request.query.accountId; @@ -23,12 +24,16 @@ const inventoryController: RequestHandler = async (request: Request, response: R const inventoryJSON = inventory.toJSON(); - const inventoreResponse = toInventoryResponse(inventoryJSON); + const inventoryResponse = toInventoryResponse(inventoryJSON); - if (config.testMission) inventoreResponse.Missions = testMissions; - if (config.testQuestKey) inventoreResponse.QuestKeys = testQuestKeys; + if (config.testMission) inventoryResponse.Missions = testMissions; + if (config.testQuestKey) inventoryResponse.QuestKeys = testQuestKeys; - response.json(inventoreResponse); + const now = Math.floor(Date.now()) - 129600; + const date: string = (now + 24 * 60 * 60 * 1000).toString(); + inventoryResponse.TrainingDate = { $date: { $numberLong: "1693769173000" } }; + console.log(inventoryResponse.TrainingDate); + response.json(inventoryResponse); }; export { inventoryController }; diff --git a/src/controllers/api/trainingResultController.ts b/src/controllers/api/trainingResultController.ts new file mode 100644 index 00000000..88f8e42d --- /dev/null +++ b/src/controllers/api/trainingResultController.ts @@ -0,0 +1,51 @@ +import { parseString } from "@/src/helpers/general"; +import { getJSONfromString } from "@/src/helpers/stringHelpers"; +import { Inventory } from "@/src/models/inventoryModel"; +import { getInventory } from "@/src/services/inventoryService"; +import { RequestHandler } from "express"; + +interface ITrainingResultsRequest { + numLevelsGained: number; +} + +const epochDay = 86400 * 1000; // in ms +const timeNow = Date.now() + epochDay; + +// eslint-disable-next-line @typescript-eslint/no-misused-promises +const trainingResultController: RequestHandler = async (req, res): Promise => { + console.log(req.body.toString()); + const accountId = parseString(req.query.accountId); + + const trainingResults = getJSONfromString(req.body.toString()) as ITrainingResultsRequest; + + const nextTrainingDate = Date.now().toString; + + if (trainingResults.numLevelsGained == 0) { + res.json({ + NewTrainingDate: { + $date: { $numberLong: nextTrainingDate } + }, + NewLevel: 0, + InventoryChanges: [] + }); + } + + const inventory = await getInventory(accountId); + + console.log("inventory", inventory.TrainingDate); + inventory.TrainingDate = new Date(Date.now() + epochDay * 500); + console.log("inventory after", inventory.TrainingDate); + await inventory.save(); + + if (trainingResults.numLevelsGained == 1) { + res.json({ + NewTrainingDate: { + $date: { $numberLong: nextTrainingDate } + }, + NewLevel: 1, + InventoryChanges: [] + }); + } +}; + +export { trainingResultController }; diff --git a/src/controllers/stats/uploadController.ts b/src/controllers/stats/uploadController.ts index 575ebf9f..2763354a 100644 --- a/src/controllers/stats/uploadController.ts +++ b/src/controllers/stats/uploadController.ts @@ -1,7 +1,7 @@ import { RequestHandler } from "express"; const uploadController: RequestHandler = (_req, res) => { - res.json({}); + res.status(200).end(); }; export { uploadController }; diff --git a/src/helpers/inventoryHelpers.ts b/src/helpers/inventoryHelpers.ts index 7ecb6f92..45b6ff14 100644 --- a/src/helpers/inventoryHelpers.ts +++ b/src/helpers/inventoryHelpers.ts @@ -1,9 +1,10 @@ import { IInventoryDatabase, IInventoryResponse } from "@/src/types/inventoryTypes/inventoryTypes"; +// a schema's toJSON is responsible for changing Oid and Date to their corresponding Response versions __id to "ItemId":{"$oid":"6450f720bc562ebf030222d4"}, and a Date to "date":{"$date":{"$numberLong":"unix timestamp"}) const toInventoryResponse = (inventoryDatabase: IInventoryDatabase): IInventoryResponse => { // eslint-disable-next-line @typescript-eslint/no-unused-vars - const { accountOwnerId, ...inventoreResponse } = inventoryDatabase; - return inventoreResponse; + const { accountOwnerId, ...inventoryResponse } = inventoryDatabase; + return inventoryResponse as unknown as IInventoryResponse; }; export { toInventoryResponse }; diff --git a/src/helpers/stringHelpers.ts b/src/helpers/stringHelpers.ts index 67995382..8cf21e80 100644 --- a/src/helpers/stringHelpers.ts +++ b/src/helpers/stringHelpers.ts @@ -1,4 +1,4 @@ -const getJSONfromString = (str: string): any => { +export const getJSONfromString = (str: string): any => { const jsonSubstring = str.substring(0, str.lastIndexOf("}") + 1); return JSON.parse(jsonSubstring); }; diff --git a/src/models/inventoryModel.ts b/src/models/inventoryModel.ts index f73dd1fb..b13b6791 100644 --- a/src/models/inventoryModel.ts +++ b/src/models/inventoryModel.ts @@ -1,5 +1,14 @@ import { Model, Schema, Types, model } from "mongoose"; -import { FlavourItem, RawUpgrade, MiscItem, IInventoryDatabase, Booster } from "../types/inventoryTypes/inventoryTypes"; +import { + FlavourItem, + RawUpgrade, + MiscItem, + IInventoryDatabase, + Booster, + IInventoryResponse, + IInventoryDatabaseDocument, + IInventoryResponseDocument +} from "../types/inventoryTypes/inventoryTypes"; import { Oid } from "../types/commonTypes"; import { ISuitDatabase, ISuitDocument } from "@/src/types/inventoryTypes/SuitTypes"; import { IWeaponDatabase } from "@/src/types/inventoryTypes/weaponTypes"; @@ -19,7 +28,7 @@ const colorSchema = new Schema({ m1: Number }); -const longGunConfigSchema = new Schema({ +const weaponConfigSchema = new Schema({ Skins: [String], pricol: colorSchema, attcol: colorSchema, @@ -51,7 +60,7 @@ const longGunConfigSchema = new Schema({ const WeaponSchema = new Schema({ ItemType: String, - Configs: [longGunConfigSchema], + Configs: [weaponConfigSchema], UpgradeVer: Number, XP: Number, Features: Number, @@ -201,7 +210,7 @@ const inventorySchema = new Schema({ Recipes: [Schema.Types.Mixed], WeaponSkins: [Schema.Types.Mixed], PendingRecipes: [Schema.Types.Mixed], - TrainingDate: Schema.Types.Mixed, + TrainingDate: Date, PlayerLevel: Number, Upgrades: [Schema.Types.Mixed], EquippedGear: [String], @@ -327,9 +336,17 @@ const inventorySchema = new Schema({ }); inventorySchema.set("toJSON", { - transform(_document, returnedObject) { + transform(_document, returnedObject: IInventoryDatabaseDocument) { delete returnedObject._id; delete returnedObject.__v; + + const trainingDate = returnedObject.TrainingDate; + + (returnedObject as unknown as IInventoryResponse).TrainingDate = { + $date: { + $numberLong: trainingDate.getTime().toString() + } + }; } }); diff --git a/src/routes/api.ts b/src/routes/api.ts index c52a8056..ca0fdea0 100644 --- a/src/routes/api.ts +++ b/src/routes/api.ts @@ -29,6 +29,7 @@ import { updateSessionGetController, updateSessionPostController } from "@/src/c import { viewController } from "@/src/controllers/api/viewController"; import { joinSessionController } from "@/src/controllers/api/joinSessionController"; import { saveLoadoutController } from "@/src/controllers/api/saveLoadout"; +import { trainingResultController } from "@/src/controllers/api/trainingResultController"; import express from "express"; @@ -71,4 +72,6 @@ apiRouter.post("/genericUpdate.php", genericUpdateController); apiRouter.post("/rerollRandomMod.php", rerollRandomModController); apiRouter.post("/joinSession.php", joinSessionController); apiRouter.post("/saveLoadout.php", saveLoadoutController); +apiRouter.post("/trainingResult.php", trainingResultController); + export { apiRouter }; diff --git a/src/services/inventoryService.ts b/src/services/inventoryService.ts index 19900497..8bf83fa3 100644 --- a/src/services/inventoryService.ts +++ b/src/services/inventoryService.ts @@ -34,7 +34,7 @@ const createInventory = async (accountOwnerId: Types.ObjectId) => { //const updateInventory = async (accountOwnerId: Types.ObjectId, inventoryChanges: any) => {}; -const getInventory = async (accountOwnerId: string) => { +export const getInventory = async (accountOwnerId: string) => { const inventory = await Inventory.findOne({ accountOwnerId: accountOwnerId }); if (!inventory) { diff --git a/src/types/commonTypes.ts b/src/types/commonTypes.ts index 4c1a7bf7..b69c1a3d 100644 --- a/src/types/commonTypes.ts +++ b/src/types/commonTypes.ts @@ -1,3 +1,9 @@ export interface Oid { $oid: string; } + +export interface BSONDate { + $date: { + $numberLong: string; + }; +} diff --git a/src/types/inventoryTypes/inventoryTypes.ts b/src/types/inventoryTypes/inventoryTypes.ts index b175dc64..8d632cc8 100644 --- a/src/types/inventoryTypes/inventoryTypes.ts +++ b/src/types/inventoryTypes/inventoryTypes.ts @@ -1,20 +1,21 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ import { Document, Types } from "mongoose"; -import { Oid } from "../commonTypes"; +import { Oid, BSONDate } from "../commonTypes"; import { AbilityOverride, Color, FocusSchool, Polarity } from "@/src/types/inventoryTypes/commonInventoryTypes"; import { ISuitDatabase } from "@/src/types/inventoryTypes/SuitTypes"; import { OperatorLoadOutSigcol, IWeaponDatabase } from "@/src/types/inventoryTypes/weaponTypes"; -export interface IInventoryDatabase extends IInventoryResponse { +export interface IInventoryDatabaseDocument extends IInventoryDatabase, Document {} +export interface IInventoryDatabase extends Omit { accountOwnerId: Types.ObjectId; + TrainingDate: Date; } -export interface IInventoryDatabaseDocument extends IInventoryDatabase, Document {} - +export interface IInventoryResponseDocument extends IInventoryResponse, Document {} export interface IInventoryResponse { SubscribedToEmails: number; - Created: Date; + Created: BSONDate; RewardSeed: number; RegularCredits: number; PremiumCredits: number; @@ -58,7 +59,7 @@ export interface IInventoryResponse { Recipes: Consumable[]; WeaponSkins: WeaponSkin[]; PendingRecipes: PendingRecipe[]; - TrainingDate: Date; + TrainingDate: BSONDate; PlayerLevel: number; Upgrades: CrewShipSalvagedWeaponSkin[]; EquippedGear: string[]; @@ -135,7 +136,7 @@ export interface IInventoryResponse { InvasionChainProgress: InvasionChainProgress[]; DataKnives: DataKnife[]; NemesisHistory: NemesisHistory[]; - LastNemesisAllySpawnTime: Date; + LastNemesisAllySpawnTime: BSONDate; Settings: Settings; PersonalTechProjects: PersonalTechProject[]; CrewShips: CrewShip[]; @@ -146,7 +147,7 @@ export interface IInventoryResponse { CrewShipWeapons: CrewShipWeapon[]; CrewShipSalvagedWeapons: CrewShipWeapon[]; CrewShipWeaponSkins: CrewShipSalvagedWeaponSkin[]; - TradeBannedUntil: Date; + TradeBannedUntil: BSONDate; PlayedParkourTutorial: boolean; SubscribedToEmailsPersonalized: number; MechBin: CrewMemberBinClass; @@ -154,7 +155,7 @@ export interface IInventoryResponse { DailyAffiliationNecraloid: number; MechSuits: MechSuit[]; InfestedFoundry: InfestedFoundry; - BlessingCooldown: Date; + BlessingCooldown: BSONDate; CrewMemberBin: CrewMemberBinClass; CrewShipHarnesses: CrewShipHarness[]; CrewShipRawSalvage: Consumable[]; @@ -166,7 +167,7 @@ export interface IInventoryResponse { NemesisAbandonedRewards: string[]; DailyAffiliationKahl: number; LastInventorySync: Oid; - NextRefill: Date; + NextRefill: BSONDate; ActiveLandscapeTraps: any[]; EvolutionProgress: any[]; RepVotes: any[]; @@ -207,10 +208,6 @@ export interface Alignment { Alignment: number; } -export interface Date { - $date: { $numberLong: string }; -} - export interface Booster { ExpiryDate: number; ItemType: string; @@ -271,7 +268,7 @@ export interface CrewMember { ItemType: string; NemesisFingerprint: number; Seed: number; - HireDate: Date; + HireDate: BSONDate; AssignedRole: number; SkillEfficiency: SkillEfficiency; WeaponConfigIdx: number; @@ -434,7 +431,7 @@ export interface Drone { ItemType: string; CurrentHP: number; ItemId: Oid; - RepairStart?: Date; + RepairStart?: BSONDate; } export interface EmailItem { @@ -522,7 +519,7 @@ export interface InvasionChainProgress { export interface KubrowPetEgg { ItemType: KubrowPetEggItemType; - ExpirationDate: Date; + ExpirationDate: BSONDate; ItemId: Oid; } @@ -575,7 +572,7 @@ export interface KubrowPet { Polarized?: number; Polarity?: Polarity[]; Features?: number; - InfestationDate?: Date; + InfestationDate?: BSONDate; InfestationDays?: number; InfestationType?: string; ItemId: Oid; @@ -595,7 +592,7 @@ export interface Details { HasCollar: boolean; PrintsRemaining: number; Status: Status; - HatchDate: Date; + HatchDate: BSONDate; DominantTraits: Traits; RecessiveTraits: Traits; IsMale: boolean; @@ -738,7 +735,7 @@ export interface Mission { Completes: number; Tier?: number; Tag: string; - RewardsCooldownTime?: Date; + RewardsCooldownTime?: BSONDate; } export interface MoaPet { @@ -763,7 +760,7 @@ export interface NemesisHistory { BirthNode: BirthNode; Rank: number; k: boolean; - d: Date; + d: BSONDate; GuessHistory?: number[]; currentGuess?: number; Traded?: boolean; @@ -812,13 +809,13 @@ export interface OperatorLoadOut { } export interface PendingCoupon { - Expiry: Date; + Expiry: BSONDate; Discount: number; } export interface PendingRecipe { ItemType: string; - CompletionDate: Date; + CompletionDate: BSONDate; ItemId: Oid; } @@ -877,7 +874,7 @@ export enum GivingSlotOrderInfo { } export interface PeriodicMissionCompletion { - date: Date; + date: BSONDate; tag: string; count?: number; } @@ -896,7 +893,7 @@ export interface PersonalTechProject { ReqCredits: number; ItemType: string; ReqItems: Consumable[]; - CompletionDate?: Date; + CompletionDate?: BSONDate; ItemId: Oid; ProductCategory?: string; CategoryItemId?: Oid; @@ -917,7 +914,7 @@ export interface QuestKey { unlock?: boolean; Completed?: boolean; ItemType: string; - CompletionDate?: Date; + CompletionDate?: BSONDate; } export interface Progress { @@ -1094,15 +1091,15 @@ export interface WebFlags { activeBuyPlat: number; noShow2FA: boolean; Tennocon2018Digital: boolean; - VisitPrimeAccess: Date; - VisitTennocon2019: Date; - enteredSC2019: Date; - VisitPrimeVault: Date; - VisitBuyPlatinum: Date; - ClickedSku_640_Page__en_buyplatinum: Date; - ClickedSku_640_Page__buyplatinum: Date; - VisitStarterPack: Date; + VisitPrimeAccess: BSONDate; + VisitTennocon2019: BSONDate; + enteredSC2019: BSONDate; + VisitPrimeVault: BSONDate; + VisitBuyPlatinum: BSONDate; + ClickedSku_640_Page__en_buyplatinum: BSONDate; + ClickedSku_640_Page__buyplatinum: BSONDate; + VisitStarterPack: BSONDate; Tennocon2020Digital: boolean; Anniversary2021: boolean; - HitDownloadBtn: Date; + HitDownloadBtn: BSONDate; } diff --git a/static/fixed_responses/postTutorialInventory.json b/static/fixed_responses/postTutorialInventory.json index 1c2d8721..31d9a61f 100644 --- a/static/fixed_responses/postTutorialInventory.json +++ b/static/fixed_responses/postTutorialInventory.json @@ -96,6 +96,8 @@ "AdultOperatorLoadOuts": [], "KahlLoadOuts": [], "PendingRecipes": [], + "TrainingDate": 0, + "PlayerLevel": 0, "PersonalGoalProgress": [], "PersonalTechProjects": [], "QualifyingInvasions": [],