diff --git a/package-lock.json b/package-lock.json index ec52be41..a43d45a2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4093,9 +4093,9 @@ } }, "node_modules/warframe-public-export-plus": { - "version": "0.5.30", - "resolved": "https://registry.npmjs.org/warframe-public-export-plus/-/warframe-public-export-plus-0.5.30.tgz", - "integrity": "sha512-vzs+naEqp3iFZTbgIky4jiNbjNIovuR4oSimrFiuyIbrnfTlfXFzDfzT0hG2rgS8yEXBAbOcv2Zfm3fmWuZ0Kg==" + "version": "0.5.32", + "resolved": "https://registry.npmjs.org/warframe-public-export-plus/-/warframe-public-export-plus-0.5.32.tgz", + "integrity": "sha512-jO9i2Gzz9DWibiHlEO17D975ajs6KrTay8cS5I0GkUUe1XWVU8mML4b+IYCHzM4FWq1t6p2YPCGznQfknqvorg==" }, "node_modules/warframe-riven-info": { "version": "0.1.2", diff --git a/src/controllers/api/getNewRewardSeedController.ts b/src/controllers/api/getNewRewardSeedController.ts index 163e3c6e..bbb3f71b 100644 --- a/src/controllers/api/getNewRewardSeedController.ts +++ b/src/controllers/api/getNewRewardSeedController.ts @@ -1,13 +1,11 @@ import { RequestHandler } from "express"; -const getNewRewardSeedController: RequestHandler = (_req, res) => { +export const getNewRewardSeedController: RequestHandler = (_req, res) => { res.json({ rewardSeed: generateRewardSeed() }); }; -function generateRewardSeed(): number { +export function generateRewardSeed(): number { const min = -Number.MAX_SAFE_INTEGER; const max = Number.MAX_SAFE_INTEGER; return Math.floor(Math.random() * (max - min + 1)) + min; } - -export { getNewRewardSeedController }; diff --git a/src/controllers/api/giveStartingGearController.ts b/src/controllers/api/giveStartingGearController.ts new file mode 100644 index 00000000..ef9be78f --- /dev/null +++ b/src/controllers/api/giveStartingGearController.ts @@ -0,0 +1,96 @@ +import { getJSONfromString } from "@/src/helpers/stringHelpers"; +import { InventoryDocumentProps } from "@/src/models/inventoryModels/inventoryModel"; +import { + addEquipment, + addItem, + combineInventoryChanges, + getInventory, + updateSlots +} from "@/src/services/inventoryService"; +import { getAccountIdForRequest } from "@/src/services/loginService"; +import { IInventoryClient, IInventoryDatabase, InventorySlot } from "@/src/types/inventoryTypes/inventoryTypes"; +import { IInventoryChanges } from "@/src/types/purchaseTypes"; +import { RequestHandler } from "express"; +import { HydratedDocument } from "mongoose"; + +type TPartialStartingGear = Pick; + +export const giveStartingGearController: RequestHandler = async (req, res) => { + const accountId = await getAccountIdForRequest(req); + const startingGear = getJSONfromString(String(req.body)); + const inventory = await getInventory(accountId); + + const inventoryChanges = await addStartingGear(inventory, startingGear); + await inventory.save(); + + res.send(inventoryChanges); +}; + +//TODO: RawUpgrades might need to return a LastAdded +const awakeningRewards = [ + "/Lotus/Types/StoreItems/AvatarImages/AvatarImageItem1", + "/Lotus/Types/StoreItems/AvatarImages/AvatarImageItem2", + "/Lotus/Types/StoreItems/AvatarImages/AvatarImageItem3", + "/Lotus/Types/StoreItems/AvatarImages/AvatarImageItem4", + "/Lotus/Types/Restoratives/LisetAutoHack", + "/Lotus/Upgrades/Mods/Warframe/AvatarShieldMaxMod" +]; + +export const addStartingGear = async ( + inventory: HydratedDocument, + startingGear: TPartialStartingGear | undefined = undefined +) => { + const { LongGuns, Pistols, Suits, Melee } = startingGear || { + LongGuns: [{ ItemType: "/Lotus/Weapons/Tenno/Rifle/Rifle" }], + Pistols: [{ ItemType: "/Lotus/Weapons/Tenno/Pistol/Pistol" }], + Suits: [{ ItemType: "/Lotus/Powersuits/Excalibur/Excalibur" }], + Melee: [{ ItemType: "/Lotus/Weapons/Tenno/Melee/LongSword/LongSword" }] + }; + + //TODO: properly merge weapon bin changes it is currently static here + const inventoryChanges: IInventoryChanges = {}; + addEquipment(inventory, "LongGuns", LongGuns[0].ItemType, undefined, inventoryChanges); + addEquipment(inventory, "Pistols", Pistols[0].ItemType, undefined, inventoryChanges); + addEquipment(inventory, "Melee", Melee[0].ItemType, undefined, inventoryChanges); + addEquipment(inventory, "Suits", Suits[0].ItemType, undefined, inventoryChanges, { Configs: Suits[0].Configs }); + addEquipment( + inventory, + "DataKnives", + "/Lotus/Weapons/Tenno/HackingDevices/TnHackingDevice/TnHackingDeviceWeapon", + undefined, + inventoryChanges, + { XP: 450_000 } + ); + addEquipment( + inventory, + "Scoops", + "/Lotus/Weapons/Tenno/Speedball/SpeedballWeaponTest", + undefined, + inventoryChanges + ); + + updateSlots(inventory, InventorySlot.SUITS, 0, 1); + updateSlots(inventory, InventorySlot.WEAPONS, 0, 3); + inventoryChanges.SuitBin = { count: 1, platinum: 0, Slots: -1 }; + inventoryChanges.WeaponBin = { count: 3, platinum: 0, Slots: -3 }; + + await addItem(inventory, "/Lotus/Types/Keys/VorsPrize/VorsPrizeQuestKeyChain"); + inventory.ActiveQuest = "/Lotus/Types/Keys/VorsPrize/VorsPrizeQuestKeyChain"; + + inventory.PremiumCredits = 50; + inventory.PremiumCreditsFree = 50; + inventoryChanges.PremiumCredits = 50; + inventoryChanges.PremiumCreditsFree = 50; + inventory.RegularCredits = 3000; + inventoryChanges.RegularCredits = 3000; + + for (const item of awakeningRewards) { + const inventoryDelta = await addItem(inventory, item); + combineInventoryChanges(inventoryChanges, inventoryDelta.InventoryChanges); + } + + inventory.PlayedParkourTutorial = true; + inventory.ReceivedStartingGear = true; + + return inventoryChanges; +}; diff --git a/src/controllers/custom/manageQuestsController.ts b/src/controllers/custom/manageQuestsController.ts index edf1feae..6899b76d 100644 --- a/src/controllers/custom/manageQuestsController.ts +++ b/src/controllers/custom/manageQuestsController.ts @@ -63,8 +63,6 @@ export const manageQuestsController: RequestHandler = async (req, res) => { inventory.ArchwingEnabled = true; } } - - inventory.ActiveQuest = ""; break; } case "ResetAll": { @@ -103,7 +101,6 @@ export const manageQuestsController: RequestHandler = async (req, res) => { inventory.ArchwingEnabled = true; } } - inventory.ActiveQuest = ""; break; } case "giveAll": { diff --git a/src/models/inventoryModels/inventoryModel.ts b/src/models/inventoryModels/inventoryModel.ts index fe651349..3ec3c363 100644 --- a/src/models/inventoryModels/inventoryModel.ts +++ b/src/models/inventoryModels/inventoryModel.ts @@ -64,7 +64,11 @@ import { IKubrowPetEggClient, ICustomMarkers, IMarkerInfo, - IMarker + IMarker, + ICalendarProgress, + IPendingCouponDatabase, + IPendingCouponClient, + ILibraryAvailableDailyTaskInfo } from "../../types/inventoryTypes/inventoryTypes"; import { IOid } from "../../types/commonTypes"; import { @@ -323,7 +327,7 @@ MailboxSchema.set("toJSON", { const DuviriInfoSchema = new Schema( { Seed: Number, - NumCompletions: Number + NumCompletions: { type: Number, default: 0 } }, { _id: false, @@ -435,6 +439,7 @@ const seasonChallengeHistorySchema = new Schema( //TODO: check whether this is complete const playerSkillsSchema = new Schema( { + LPP_NONE: { type: Number, default: 0 }, LPP_SPACE: { type: Number, default: 0 }, LPS_PILOTING: { type: Number, default: 0 }, LPS_GUNNERY: { type: Number, default: 0 }, @@ -891,19 +896,63 @@ const CustomMarkersSchema = new Schema( { _id: false } ); +const calenderProgressSchema = new Schema( + { + Version: { type: Number, default: 19 }, + Iteration: { type: Number, default: 2 }, + YearProgress: { + Upgrades: { type: [] } + }, + SeasonProgress: { + SeasonType: String, + LastCompletedDayIdx: { type: Number, default: -1 }, + LastCompletedChallengeDayIdx: { type: Number, default: -1 }, + ActivatedChallenges: [] + } + }, + { _id: false } +); + +const pendingCouponSchema = new Schema( + { + Expiry: { type: Date, default: new Date(0) }, + Discount: { type: Number, default: 0 } + }, + { _id: false } +); + +pendingCouponSchema.set("toJSON", { + transform(_doc, ret, _options) { + (ret as IPendingCouponClient).Expiry = toMongoDate((ret as IPendingCouponDatabase).Expiry); + } +}); + +const libraryAvailableDailyTaskInfoSchema = new Schema( + { + EnemyTypes: [String], + EnemyLocTag: String, + EnemyIcon: String, + ScansRequired: Number, + RewardStoreItem: String, + RewardQuantity: Number, + RewardStanding: Number + }, + { _id: false } +); + const inventorySchema = new Schema( { accountOwnerId: Schema.Types.ObjectId, - SubscribedToEmails: Number, - Created: Date, + SubscribedToEmails: { type: Number, default: 0 }, + SubscribedToEmailsPersonalized: { type: Number, default: 0 }, RewardSeed: Number, //Credit RegularCredits: { type: Number, default: 0 }, //Platinum - PremiumCredits: { type: Number, default: 50 }, + PremiumCredits: { type: Number, default: 0 }, //Gift Platinum(Non trade) - PremiumCreditsFree: { type: Number, default: 50 }, + PremiumCreditsFree: { type: Number, default: 0 }, //Endo FusionPoints: { type: Number, default: 0 }, //Regal Aya @@ -911,7 +960,7 @@ const inventorySchema = new Schema( //Slots SuitBin: { type: slotsBinSchema, default: { Slots: 3 } }, - WeaponBin: { type: slotsBinSchema, default: { Slots: 10 } }, + WeaponBin: { type: slotsBinSchema, default: { Slots: 11 } }, SentinelBin: { type: slotsBinSchema, default: { Slots: 10 } }, SpaceSuitBin: { type: slotsBinSchema, default: { Slots: 4 } }, SpaceWeaponBin: { type: slotsBinSchema, default: { Slots: 4 } }, @@ -1022,7 +1071,7 @@ const inventorySchema = new Schema( //Complete Mission\Quests Missions: [missionSchema], QuestKeys: [questKeysSchema], - ActiveQuest: { type: String, default: "/Lotus/Types/Keys/VorsPrize/VorsPrizeQuestKeyChain" }, //TODO: check after mission starting gear + ActiveQuest: { type: String, default: "" }, //item like DojoKey or Boss missions key LevelKeys: [Schema.Types.Mixed], //Active quests @@ -1137,7 +1186,7 @@ const inventorySchema = new Schema( //Cephalon Simaris Entries Example:"TargetType"+"Scans"(1-10)+"Completed": true|false LibraryPersonalProgress: [Schema.Types.Mixed], //Cephalon Simaris Daily Task - LibraryAvailableDailyTaskInfo: Schema.Types.Mixed, + LibraryAvailableDailyTaskInfo: libraryAvailableDailyTaskInfoSchema, //https://warframe.fandom.com/wiki/Invasion InvasionChainProgress: [Schema.Types.Mixed], @@ -1184,7 +1233,6 @@ const inventorySchema = new Schema( HandlerPoints: Number, ChallengesFixVersion: Number, PlayedParkourTutorial: Boolean, - SubscribedToEmailsPersonalized: Number, ActiveLandscapeTraps: [Schema.Types.Mixed], RepVotes: [Schema.Types.Mixed], LeagueTickets: [Schema.Types.Mixed], @@ -1202,7 +1250,7 @@ const inventorySchema = new Schema( HasResetAccount: { type: Boolean, default: false }, //Discount Coupon - PendingCoupon: Schema.Types.Mixed, + PendingCoupon: pendingCouponSchema, //Like BossAladV,BossCaptainVor come for you on missions % chance DeathMarks: [String], //Zanuka @@ -1212,7 +1260,8 @@ const inventorySchema = new Schema( EndlessXP: { type: [endlessXpProgressSchema], default: undefined }, - DialogueHistory: dialogueHistorySchema + DialogueHistory: dialogueHistorySchema, + CalendarProgress: calenderProgressSchema }, { timestamps: { createdAt: "Created", updatedAt: false } } ); diff --git a/src/routes/api.ts b/src/routes/api.ts index 7ad9e5a6..41c5f460 100644 --- a/src/routes/api.ts +++ b/src/routes/api.ts @@ -87,6 +87,7 @@ import { updateSessionGetController, updateSessionPostController } from "@/src/c import { updateThemeController } from "../controllers/api/updateThemeController"; import { upgradesController } from "@/src/controllers/api/upgradesController"; import { saveSettingsController } from "../controllers/api/saveSettingsController"; +import { giveStartingGearController } from "@/src/controllers/api/giveStartingGearController"; const apiRouter = express.Router(); @@ -146,6 +147,7 @@ apiRouter.post("/gildWeapon.php", gildWeaponController); apiRouter.post("/giveKeyChainTriggeredItems.php", giveKeyChainTriggeredItemsController); apiRouter.post("/giveKeyChainTriggeredMessage.php", giveKeyChainTriggeredMessageController); apiRouter.post("/giveQuestKeyReward.php", giveQuestKeyRewardController); +apiRouter.post("/giveStartingGear.php", giveStartingGearController); apiRouter.post("/guildTech.php", guildTechController); apiRouter.post("/hostSession.php", hostSessionController); apiRouter.post("/infestedFoundry.php", infestedFoundryController); diff --git a/src/services/inboxService.ts b/src/services/inboxService.ts index 11768054..895699f1 100644 --- a/src/services/inboxService.ts +++ b/src/services/inboxService.ts @@ -2,7 +2,7 @@ import { IMessageDatabase, Inbox } from "@/src/models/inboxModel"; import { getAccountForRequest } from "@/src/services/loginService"; import { HydratedDocument } from "mongoose"; import { Request } from "express"; -import messages from "@/static/fixed_responses/messages.json"; +import eventMessages from "@/static/fixed_responses/eventMessages.json"; import { logger } from "@/src/utils/logger"; export const getAllMessagesSorted = async (accountId: string): Promise[]> => { @@ -32,7 +32,7 @@ export const createNewEventMessages = async (req: Request) => { const latestEventMessageDate = account.LatestEventMessageDate; //TODO: is baroo there? create these kind of messages too (periodical messages) - const newEventMessages = messages.Messages.filter(m => new Date(m.eventMessageDate) > latestEventMessageDate); + const newEventMessages = eventMessages.Messages.filter(m => new Date(m.eventMessageDate) > latestEventMessageDate); if (newEventMessages.length === 0) { logger.debug(`No new event messages. Latest event message date: ${latestEventMessageDate.toISOString()}`); diff --git a/src/services/inventoryService.ts b/src/services/inventoryService.ts index c43e1d1c..2ab822e6 100644 --- a/src/services/inventoryService.ts +++ b/src/services/inventoryService.ts @@ -22,7 +22,9 @@ import { IDailyAffiliations, IInventoryDatabase, IKubrowPetEggDatabase, - IKubrowPetEggClient + IKubrowPetEggClient, + ILibraryAvailableDailyTaskInfo, + ICalendarProgress } from "@/src/types/inventoryTypes/inventoryTypes"; import { IGenericUpdate } from "../types/genericUpdate"; import { @@ -32,7 +34,7 @@ import { } from "../types/requestTypes"; import { logger } from "@/src/utils/logger"; import { getExalted, getKeyChainItems } from "@/src/services/itemDataService"; -import { IEquipmentClient, IItemConfig } from "../types/inventoryTypes/commonInventoryTypes"; +import { IEquipmentClient, IEquipmentDatabase, IItemConfig } from "../types/inventoryTypes/commonInventoryTypes"; import { ExportArcanes, ExportCustoms, @@ -51,6 +53,9 @@ import { createShip } from "./shipService"; import { creditBundles, fusionBundles } from "@/src/services/missionInventoryUpdateService"; import { IKeyChainRequest } from "@/src/controllers/api/giveKeyChainTriggeredItemsController"; import { toOid } from "../helpers/inventoryHelpers"; +import { generateRewardSeed } from "@/src/controllers/api/getNewRewardSeedController"; +import { addStartingGear } from "@/src/controllers/api/giveStartingGearController"; +import { completeQuest } from "@/src/services/questService"; export const createInventory = async ( accountOwnerId: Types.ObjectId, @@ -65,65 +70,18 @@ export const createInventory = async ( ReceivedStartingGear: config.skipTutorial }); + inventory.LibraryAvailableDailyTaskInfo = createLibraryAvailableDailyTaskInfo(); + inventory.CalendarProgress = createCalendar(); + inventory.RewardSeed = generateRewardSeed(); + inventory.DuviriInfo = { + Seed: generateRewardSeed(), + NumCompletions: 0 + }; + await addItem(inventory, "/Lotus/Types/Friendly/PlayerControllable/Weapons/DuviriDualSwords"); + if (config.skipTutorial) { - const defaultEquipment = [ - // Awakening rewards - { ItemCount: 1, ItemType: "/Lotus/Powersuits/Excalibur/Excalibur" }, - { ItemCount: 1, ItemType: "/Lotus/Weapons/Tenno/Melee/LongSword/LongSword" }, - { ItemCount: 1, ItemType: "/Lotus/Weapons/Tenno/Pistol/Pistol" }, - { ItemCount: 1, ItemType: "/Lotus/Weapons/Tenno/Rifle/Rifle" }, - { ItemCount: 1, ItemType: "/Lotus/Types/StoreItems/AvatarImages/AvatarImageItem1" }, - { ItemCount: 1, ItemType: "/Lotus/Types/StoreItems/AvatarImages/AvatarImageItem2" }, - { ItemCount: 1, ItemType: "/Lotus/Types/StoreItems/AvatarImages/AvatarImageItem3" }, - { ItemCount: 1, ItemType: "/Lotus/Types/StoreItems/AvatarImages/AvatarImageItem4" }, - { ItemCount: 1, ItemType: "/Lotus/Types/Restoratives/LisetAutoHack" } - ]; - - // const vorsPrizeRewards = [ - // // Vor's Prize rewards - // { ItemCount: 1, ItemType: "/Lotus/Upgrades/Mods/Warframe/AvatarHealthMaxMod" }, - // { ItemCount: 1, ItemType: "/Lotus/Upgrades/Mods/Warframe/AvatarShieldMaxMod" }, - // { ItemCount: 1, ItemType: "/Lotus/Upgrades/Mods/Warframe/AvatarAbilityRangeMod" }, - // { ItemCount: 1, ItemType: "/Lotus/Upgrades/Mods/Warframe/AvatarAbilityStrengthMod" }, - // { ItemCount: 1, ItemType: "/Lotus/Upgrades/Mods/Warframe/AvatarAbilityDurationMod" }, - // { ItemCount: 1, ItemType: "/Lotus/Upgrades/Mods/Warframe/AvatarPickupBonusMod" }, - // { ItemCount: 1, ItemType: "/Lotus/Upgrades/Mods/Warframe/AvatarPowerMaxMod" }, - // { ItemCount: 1, ItemType: "/Lotus/Upgrades/Mods/Warframe/AvatarEnemyRadarMod" }, - // { ItemCount: 1, ItemType: "/Lotus/Upgrades/Mods/Melee/WeaponFireRateMod" }, - // { ItemCount: 1, ItemType: "/Lotus/Upgrades/Mods/Melee/WeaponMeleeDamageMod" }, - // { ItemCount: 1, ItemType: "/Lotus/Upgrades/Mods/Rifle/WeaponFactionDamageCorpus" }, - // { ItemCount: 1, ItemType: "/Lotus/Upgrades/Mods/Rifle/WeaponFactionDamageGrineer" }, - // { ItemCount: 1, ItemType: "/Lotus/Upgrades/Mods/Rifle/WeaponDamageAmountMod" }, - // { ItemCount: 1, ItemType: "/Lotus/Upgrades/Mods/Pistol/WeaponFireDamageMod" }, - // { ItemCount: 1, ItemType: "/Lotus/Upgrades/Mods/Pistol/WeaponElectricityDamageMod" }, - // { ItemCount: 1, ItemType: "/Lotus/Upgrades/Mods/Pistol/WeaponDamageAmountMod" }, - // { ItemCount: 1, ItemType: "/Lotus/Types/Recipes/Weapons/BurstonRifleBlueprint" }, - // { ItemCount: 1, ItemType: "/Lotus/Types/Items/MiscItems/Morphic" }, - // { ItemCount: 400, ItemType: "/Lotus/Types/Items/MiscItems/PolymerBundle" }, - // { ItemCount: 150, ItemType: "/Lotus/Types/Items/MiscItems/AlloyPlate" } - // ]; - for (const equipment of defaultEquipment) { - await addItem(inventory, equipment.ItemType, equipment.ItemCount); - } - - // Missing in Public Export - inventory.Horses.push({ - ItemType: "/Lotus/Types/NeutralCreatures/ErsatzHorse/ErsatzHorsePowerSuit" - }); - inventory.DataKnives.push({ - ItemType: "/Lotus/Weapons/Tenno/HackingDevices/TnHackingDevice/TnHackingDeviceWeapon", - XP: 450000 - }); - inventory.Scoops.push({ - ItemType: "/Lotus/Weapons/Tenno/Speedball/SpeedballWeaponTest" - }); - inventory.DrifterMelee.push({ - ItemType: "/Lotus/Types/Friendly/PlayerControllable/Weapons/DuviriDualSwords" - }); - - inventory.QuestKeys.push({ - ItemType: "/Lotus/Types/Keys/VorsPrize/VorsPrizeQuestKeyChain" - }); + await addStartingGear(inventory); + await completeQuest(inventory, "/Lotus/Types/Keys/VorsPrize/VorsPrizeQuestKeyChain"); const completedMissions = ["SolNode27", "SolNode89", "SolNode63", "SolNode85", "SolNode15", "SolNode79"]; @@ -133,14 +91,11 @@ export const createInventory = async ( Tag: tag })) ); - - inventory.RegularCredits = 25000; - inventory.FusionPoints = 180; } await inventory.save(); } catch (error) { - throw new Error(`Error creating inventory: ${error instanceof Error ? error.message : "Unknown error"}`); + throw new Error(`Error creating inventory: ${error instanceof Error ? error.message : "Unknown error type"}`); } }; @@ -150,6 +105,7 @@ export const createInventory = async ( * @param InventoryChanges - will hold the combined changes * @param delta - inventory changes to be added */ +//TODO: this fails silently when providing an incorrect object to delta export const combineInventoryChanges = (InventoryChanges: IInventoryChanges, delta: IInventoryChanges): void => { for (const key in delta) { if (!(key in InventoryChanges)) { @@ -779,15 +735,19 @@ export const addEquipment = ( category: TEquipmentKey, type: string, modularParts: string[] | undefined = undefined, - inventoryChanges: IInventoryChanges = {} + inventoryChanges: IInventoryChanges = {}, + defaultOverwrites: Partial | undefined = undefined ): IInventoryChanges => { - const index = - inventory[category].push({ + const equipment = Object.assign( + { ItemType: type, Configs: [], XP: 0, ModularParts: modularParts - }) - 1; + }, + defaultOverwrites + ); + const index = inventory[category].push(equipment) - 1; inventoryChanges[category] ??= []; inventoryChanges[category].push(inventory[category][index].toJSON()); @@ -1173,3 +1133,28 @@ export const addKeyChainItems = async ( return inventoryChanges; }; +const createLibraryAvailableDailyTaskInfo = (): ILibraryAvailableDailyTaskInfo => { + return { + EnemyTypes: ["/Lotus/Types/Enemies/Orokin/RifleLancerAvatar"], + EnemyLocTag: "/Lotus/Language/Game/CorruptedLancer", + EnemyIcon: "/Lotus/Interface/Icons/Npcs/OrokinRifleLancerAvatar.png", + ScansRequired: 3, + RewardStoreItem: "/Lotus/StoreItems/Upgrades/Mods/FusionBundles/UncommonFusionBundle", + RewardQuantity: 7, + RewardStanding: 7500 + }; +}; + +const createCalendar = (): ICalendarProgress => { + return { + Version: 19, + Iteration: 2, + YearProgress: { Upgrades: [] }, + SeasonProgress: { + SeasonType: "CST_SPRING", + LastCompletedDayIdx: -1, + LastCompletedChallengeDayIdx: -1, + ActivatedChallenges: [] + } + }; +}; diff --git a/src/services/questService.ts b/src/services/questService.ts index 0446e273..630ca60a 100644 --- a/src/services/questService.ts +++ b/src/services/questService.ts @@ -126,7 +126,8 @@ export const completeQuest = async (inventory: TInventoryDatabaseDocument, quest }); } } - //TODO: handle quest completions + inventory.ActiveQuest = ""; + //TODO: handle quest completion items }; export const giveKeyChainItem = async (inventory: TInventoryDatabaseDocument, keyChainInfo: IKeyChainRequest) => { diff --git a/src/types/inventoryTypes/inventoryTypes.ts b/src/types/inventoryTypes/inventoryTypes.ts index fab41e4e..e9375863 100644 --- a/src/types/inventoryTypes/inventoryTypes.ts +++ b/src/types/inventoryTypes/inventoryTypes.ts @@ -38,6 +38,7 @@ export interface IInventoryDatabase | "InfestedFoundry" | "DialogueHistory" | "KubrowPetEggs" + | "PendingCoupon" | TEquipmentKey >, InventoryDatabaseEquipment { @@ -61,6 +62,7 @@ export interface IInventoryDatabase InfestedFoundry?: IInfestedFoundryDatabase; DialogueHistory?: IDialogueHistoryDatabase; KubrowPetEggs?: IKubrowPetEggDatabase[]; + PendingCoupon: IPendingCouponDatabase; } export interface IQuestKeyDatabase { @@ -318,11 +320,12 @@ export interface IInventoryClient extends IDailyAffiliations, InventoryClientEqu CollectibleSeries: ICollectibleSery[]; LibraryAvailableDailyTaskInfo: ILibraryAvailableDailyTaskInfo; HasResetAccount: boolean; - PendingCoupon: IPendingCoupon; + PendingCoupon: IPendingCouponClient; Harvestable: boolean; DeathSquadable: boolean; EndlessXP?: IEndlessXpProgress[]; DialogueHistory?: IDialogueHistoryClient; + CalendarProgress: ICalendarProgress; } export interface IAffiliation { @@ -759,7 +762,12 @@ export enum Manifest { LotusTypesGameNemesisKuvaLichKuvaLichManifestVersionTwo = "/Lotus/Types/Game/Nemesis/KuvaLich/KuvaLichManifestVersionTwo" } -export interface IPendingCoupon { +export interface IPendingCouponDatabase { + Expiry: Date; + Discount: number; +} + +export interface IPendingCouponClient { Expiry: IMongoDate; Discount: number; } @@ -858,6 +866,7 @@ export interface IPersonalTechProject { } export interface IPlayerSkills { + LPP_NONE: number; LPP_SPACE: number; LPS_PILOTING: number; LPS_GUNNERY: number; @@ -1042,3 +1051,16 @@ export interface IMarker { z: number; showInHud: boolean; } +export interface ISeasonProgress { + SeasonType: "CST_UNDEFINED" | "CST_WINTER" | "CST_SPRING" | "CST_SUMMER" | "CST_FALL"; + LastCompletedDayIdx: number; + LastCompletedChallengeDayIdx: number; + ActivatedChallenges: unknown[]; +} + +export interface ICalendarProgress { + Version: number; + Iteration: number; + YearProgress: { Upgrades: unknown[] }; + SeasonProgress: ISeasonProgress; +} diff --git a/static/fixed_responses/eventMessages.json b/static/fixed_responses/eventMessages.json new file mode 100644 index 00000000..6ecf6d44 --- /dev/null +++ b/static/fixed_responses/eventMessages.json @@ -0,0 +1,12 @@ +{ + "Messages": [ + { + "sub": "Welcome to Space Ninja Server", + "sndr": "/Lotus/Language/Bosses/Ordis", + "msg": "Enjoy your Space Ninja Experience", + "icon": "/Lotus/Interface/Icons/Npcs/Darvo.png", + "eventMessageDate": "2025-01-30T13:00:00.000Z", + "r": false + } + ] +} diff --git a/static/fixed_responses/messages.json b/static/fixed_responses/messages.json deleted file mode 100644 index a67069c7..00000000 --- a/static/fixed_responses/messages.json +++ /dev/null @@ -1,49 +0,0 @@ -{ - "Messages": [ - { - "sub": "Welcome to Space Ninja Server", - "sndr": "/Lotus/Language/Bosses/Ordis", - "msg": "Enjoy your Space Ninja Experience", - "icon": "/Lotus/Interface/Icons/Npcs/Darvo.png", - "eventMessageDate": "2025-01-30T13:00:00.000Z", - "r": false - }, - { - "sub": "/Lotus/Language/Inbox/DarvoWeaponCraftingMessageBTitle", - "sndr": "/Lotus/Language/Bosses/Darvo", - "msg": "/Lotus/Language/Inbox/DarvoWeaponCraftingMessageBDesc", - "icon": "/Lotus/Interface/Icons/Npcs/Darvo.png", - "countedAtt": [ - { - "ItemCount": 1, - "ItemType": "/Lotus/Types/Recipes/Weapons/BurstonRifleBlueprint" - }, - { - "ItemCount": 1, - "ItemType": "/Lotus/Types/Items/MiscItems/Morphic" - }, - { - "ItemCount": 400, - "ItemType": "/Lotus/Types/Items/MiscItems/PolymerBundle" - }, - { - "ItemCount": 150, - "ItemType": "/Lotus/Types/Items/MiscItems/AlloyPlate" - } - ], - "highPriority": true, - "eventMessageDate": "2023-10-01T17:00:00.000Z", - "r": false - }, - { - "sub": "/Lotus/Language/G1Quests/Beginner_Growth_Inbox_Title", - "sndr": "/Lotus/Language/Menu/Mailbox_WarframeSender", - "msg": "/Lotus/Language/G1Quests/Beginner_Growth_Inbox_Desc", - "icon": "/Lotus/Interface/Icons/Npcs/Lotus_d.png", - "transmission": "/Lotus/Sounds/Dialog/VorsPrize/DLisetPostAssassinate110Lotus", - "highPriority": true, - "eventMessageDate": "2023-09-01T17:00:00.000Z", - "r": false - } - ] -}