From 3c79f910a28c1a555ed323bde98f17d3ff385fc7 Mon Sep 17 00:00:00 2001 From: Sainan <63328889+Sainan@users.noreply.github.com> Date: Sun, 6 Apr 2025 06:03:55 -0700 Subject: [PATCH] feat: coda weapon vendor rotation (#1471) Reviewed-on: https://onlyg.it/OpenWF/SpaceNinjaServer/pulls/1471 Co-authored-by: Sainan <63328889+Sainan@users.noreply.github.com> Co-committed-by: Sainan <63328889+Sainan@users.noreply.github.com> --- src/services/serversideVendorsService.ts | 49 +++++- src/types/vendorTypes.ts | 6 +- .../InfestedLichWeaponVendorManifest.json | 157 ------------------ 3 files changed, 52 insertions(+), 160 deletions(-) delete mode 100644 static/fixed_responses/getVendorInfo/InfestedLichWeaponVendorManifest.json diff --git a/src/services/serversideVendorsService.ts b/src/services/serversideVendorsService.ts index 23b382d8..961b5faa 100644 --- a/src/services/serversideVendorsService.ts +++ b/src/services/serversideVendorsService.ts @@ -3,8 +3,9 @@ import path from "path"; import { repoDir } from "@/src/helpers/pathHelper"; import { CRng, mixSeeds } from "@/src/services/rngService"; import { IMongoDate } from "@/src/types/commonTypes"; -import { IRawVendorManifest, IVendorManifestPreprocessed } from "@/src/types/vendorTypes"; +import { IItemManifestPreprocessed, IRawVendorManifest, IVendorManifestPreprocessed } from "@/src/types/vendorTypes"; import { JSONParse } from "json-with-bigint"; +import { ExportVendors } from "warframe-public-export-plus"; const getVendorManifestJson = (name: string): IRawVendorManifest => { return JSONParse(fs.readFileSync(path.join(repoDir, `static/fixed_responses/getVendorInfo/${name}.json`), "utf-8")); @@ -29,7 +30,6 @@ const rawVendorManifests: IRawVendorManifest[] = [ getVendorManifestJson("HubsIronwakeDondaVendorManifest"), // uses preprocessing getVendorManifestJson("HubsPerrinSequenceWeaponVendorManifest"), getVendorManifestJson("HubsRailjackCrewMemberVendorManifest"), - getVendorManifestJson("InfestedLichWeaponVendorManifest"), getVendorManifestJson("MaskSalesmanManifest"), getVendorManifestJson("Nova1999ConquestShopManifest"), getVendorManifestJson("OstronFishmongerVendorManifest"), @@ -50,6 +50,9 @@ export const getVendorManifestByTypeName = (typeName: string): IVendorManifestPr return preprocessVendorManifest(vendorManifest); } } + if (typeName == "/Lotus/Types/Game/VendorManifests/TheHex/InfestedLichWeaponVendorManifest") { + return generateCodaWeaponVendorManifest(); + } return undefined; }; @@ -59,6 +62,9 @@ export const getVendorManifestByOid = (oid: string): IVendorManifestPreprocessed return preprocessVendorManifest(vendorManifest); } } + if (oid == "67dadc30e4b6e0e5979c8d84") { + return generateCodaWeaponVendorManifest(); + } return undefined; }; @@ -96,3 +102,42 @@ const refreshExpiry = (expiry: IMongoDate): number => { } return 0; }; + +const generateCodaWeaponVendorManifest = (): IVendorManifestPreprocessed => { + const EPOCH = 1740960000 * 1000; + const DUR = 4 * 86400 * 1000; + const cycle = Math.trunc((Date.now() - EPOCH) / DUR); + const cycleStart = EPOCH + cycle * DUR; + const cycleEnd = cycleStart + DUR; + const binThisCycle = cycle % 2; // isOneBinPerCycle + const items: IItemManifestPreprocessed[] = []; + const manifest = ExportVendors["/Lotus/Types/Game/VendorManifests/TheHex/InfestedLichWeaponVendorManifest"]; + const rng = new CRng(cycle); + for (const rawItem of manifest.items) { + if (rawItem.bin != binThisCycle) { + continue; + } + items.push({ + StoreItem: rawItem.storeItem, + ItemPrices: rawItem.itemPrices!.map(item => ({ ...item, ProductCategory: "MiscItems" })), + Bin: "BIN_" + rawItem.bin, + QuantityMultiplier: 1, + Expiry: { $date: { $numberLong: cycleEnd.toString() } }, + AllowMultipurchase: false, + LocTagRandSeed: (BigInt(rng.randomInt(0, 0xffffffff)) << 32n) | BigInt(rng.randomInt(0, 0xffffffff)), + Id: { $oid: "67e9da12793a120d" + rng.randomInt(0, 0xffffffff).toString(16).padStart(8, "0") } + }); + } + return { + VendorInfo: { + _id: { $oid: "67dadc30e4b6e0e5979c8d84" }, + TypeName: "/Lotus/Types/Game/VendorManifests/TheHex/InfestedLichWeaponVendorManifest", + ItemManifest: items, + PropertyTextHash: "77093DD05A8561A022DEC9A4B9BB4A56", + RandomSeedType: "VRST_WEAPON", + RequiredGoalTag: "", + WeaponUpgradeValueAttenuationExponent: 2.25, + Expiry: { $date: { $numberLong: cycleEnd.toString() } } + } + }; +}; diff --git a/src/types/vendorTypes.ts b/src/types/vendorTypes.ts index e5c7cdfc..f962a494 100644 --- a/src/types/vendorTypes.ts +++ b/src/types/vendorTypes.ts @@ -23,7 +23,7 @@ interface IItemManifest { Id: IOid; } -interface IItemManifestPreprocessed extends Omit { +export interface IItemManifestPreprocessed extends Omit { ItemPrices?: IItemPricePreprocessed[]; } @@ -31,6 +31,10 @@ interface IVendorInfo { _id: IOid; TypeName: string; ItemManifest: IItemManifest[]; + PropertyTextHash?: string; + RandomSeedType?: "VRST_WEAPON"; + RequiredGoalTag?: string; + WeaponUpgradeValueAttenuationExponent?: number; Expiry: IMongoDate; // Either a date in the distant future or a period in milliseconds for preprocessing. } diff --git a/static/fixed_responses/getVendorInfo/InfestedLichWeaponVendorManifest.json b/static/fixed_responses/getVendorInfo/InfestedLichWeaponVendorManifest.json deleted file mode 100644 index 04a0392d..00000000 --- a/static/fixed_responses/getVendorInfo/InfestedLichWeaponVendorManifest.json +++ /dev/null @@ -1,157 +0,0 @@ -{ - "VendorInfo": { - "_id": { - "$oid": "67dadc30e4b6e0e5979c8d84" - }, - "TypeName": "/Lotus/Types/Game/VendorManifests/TheHex/InfestedLichWeaponVendorManifest", - "ItemManifest": [ - { - "StoreItem": "/Lotus/StoreItems/Weapons/Infested/InfestedLich/LongGuns/1999InfShotgun/1999InfShotgunWeapon", - "ItemPrices": [ - { - "ItemCount": 10, - "ItemType": "/Lotus/Types/Items/MiscItems/CodaWeaponBucks", - "ProductCategory": "MiscItems" - } - ], - "Bin": "BIN_1", - "QuantityMultiplier": 1, - "Expiry": { - "$date": { - "$numberLong": "9999999999999" - } - }, - "PurchaseQuantityLimit": 1, - "AllowMultipurchase": false, - "LocTagRandSeed": 65079176837546984, - "Id": { - "$oid": "67e9da12793a120dbbc1c193" - } - }, - { - "StoreItem": "/Lotus/StoreItems/Weapons/Infested/InfestedLich/Melee/CodaCaustacyst/CodaCaustacyst", - "ItemPrices": [ - { - "ItemCount": 10, - "ItemType": "/Lotus/Types/Items/MiscItems/CodaWeaponBucks", - "ProductCategory": "MiscItems" - } - ], - "Bin": "BIN_1", - "QuantityMultiplier": 1, - "Expiry": { - "$date": { - "$numberLong": "9999999999999" - } - }, - "PurchaseQuantityLimit": 1, - "AllowMultipurchase": false, - "LocTagRandSeed": 5687904240491804000, - "Id": { - "$oid": "67e9da12793a120dbbc1c194" - } - }, - { - "StoreItem": "/Lotus/StoreItems/Weapons/Infested/InfestedLich/Melee/CodaPathocyst/CodaPathocyst", - "ItemPrices": [ - { - "ItemCount": 10, - "ItemType": "/Lotus/Types/Items/MiscItems/CodaWeaponBucks", - "ProductCategory": "MiscItems" - } - ], - "Bin": "BIN_1", - "QuantityMultiplier": 1, - "Expiry": { - "$date": { - "$numberLong": "9999999999999" - } - }, - "PurchaseQuantityLimit": 1, - "AllowMultipurchase": false, - "LocTagRandSeed": 6177144662234093000, - "Id": { - "$oid": "67e9da12793a120dbbc1c195" - } - }, - { - "StoreItem": "/Lotus/StoreItems/Weapons/Infested/InfestedLich/Pistols/CodaTysis", - "ItemPrices": [ - { - "ItemCount": 10, - "ItemType": "/Lotus/Types/Items/MiscItems/CodaWeaponBucks", - "ProductCategory": "MiscItems" - } - ], - "Bin": "BIN_1", - "QuantityMultiplier": 1, - "Expiry": { - "$date": { - "$numberLong": "9999999999999" - } - }, - "PurchaseQuantityLimit": 1, - "AllowMultipurchase": false, - "LocTagRandSeed": 1988275604378227700, - "Id": { - "$oid": "67e9da12793a120dbbc1c196" - } - }, - { - "StoreItem": "/Lotus/StoreItems/Weapons/Infested/InfestedLich/LongGuns/CodaSynapse", - "ItemPrices": [ - { - "ItemCount": 10, - "ItemType": "/Lotus/Types/Items/MiscItems/CodaWeaponBucks", - "ProductCategory": "MiscItems" - } - ], - "Bin": "BIN_1", - "QuantityMultiplier": 1, - "Expiry": { - "$date": { - "$numberLong": "9999999999999" - } - }, - "PurchaseQuantityLimit": 1, - "AllowMultipurchase": false, - "LocTagRandSeed": 8607452585593957000, - "Id": { - "$oid": "67e9da12793a120dbbc1c197" - } - }, - { - "StoreItem": "/Lotus/StoreItems/Weapons/Infested/InfestedLich/Melee/CodaHirudo", - "ItemPrices": [ - { - "ItemCount": 10, - "ItemType": "/Lotus/Types/Items/MiscItems/CodaWeaponBucks", - "ProductCategory": "MiscItems" - } - ], - "Bin": "BIN_1", - "QuantityMultiplier": 1, - "Expiry": { - "$date": { - "$numberLong": "9999999999999" - } - }, - "PurchaseQuantityLimit": 1, - "AllowMultipurchase": false, - "LocTagRandSeed": 8385013066220909000, - "Id": { - "$oid": "67e9da12793a120dbbc1c198" - } - } - ], - "PropertyTextHash": "77093DD05A8561A022DEC9A4B9BB4A56", - "RandomSeedType": "VRST_WEAPON", - "RequiredGoalTag": "", - "WeaponUpgradeValueAttenuationExponent": 2.25, - "Expiry": { - "$date": { - "$numberLong": "9999999999999" - } - } - } -}