diff --git a/src/controllers/api/getNewRewardSeedController.ts b/src/controllers/api/getNewRewardSeedController.ts index 4ff82405..cb9e1f82 100644 --- a/src/controllers/api/getNewRewardSeedController.ts +++ b/src/controllers/api/getNewRewardSeedController.ts @@ -1,14 +1,12 @@ import { Inventory } from "@/src/models/inventoryModels/inventoryModel"; import { generateRewardSeed } from "@/src/services/inventoryService"; import { getAccountIdForRequest } from "@/src/services/loginService"; -import { logger } from "@/src/utils/logger"; import { RequestHandler } from "express"; export const getNewRewardSeedController: RequestHandler = async (req, res) => { const accountId = await getAccountIdForRequest(req); const rewardSeed = generateRewardSeed(); - logger.debug(`generated new reward seed: ${rewardSeed}`); await Inventory.updateOne( { accountOwnerId: accountId diff --git a/src/models/inventoryModels/inventoryModel.ts b/src/models/inventoryModels/inventoryModel.ts index a0eddb10..9c737d24 100644 --- a/src/models/inventoryModels/inventoryModel.ts +++ b/src/models/inventoryModels/inventoryModel.ts @@ -1213,7 +1213,7 @@ const inventorySchema = new Schema( accountOwnerId: Schema.Types.ObjectId, SubscribedToEmails: { type: Number, default: 0 }, SubscribedToEmailsPersonalized: { type: Number, default: 0 }, - RewardSeed: Number, + RewardSeed: BigInt, //Credit RegularCredits: { type: Number, default: 0 }, diff --git a/src/services/missionInventoryUpdateService.ts b/src/services/missionInventoryUpdateService.ts index b74c1ddf..f75fa2f4 100644 --- a/src/services/missionInventoryUpdateService.ts +++ b/src/services/missionInventoryUpdateService.ts @@ -9,7 +9,7 @@ import { } from "warframe-public-export-plus"; import { IMissionInventoryUpdateRequest, IRewardInfo } from "../types/requestTypes"; import { logger } from "@/src/utils/logger"; -import { IRngResult, getRandomElement, getRandomReward } from "@/src/services/rngService"; +import { IRngResult, SRng, getRandomElement, getRandomReward } from "@/src/services/rngService"; import { equipmentKeys, TEquipmentKey } from "@/src/types/inventoryTypes/inventoryTypes"; import { addBooster, @@ -31,6 +31,7 @@ import { addShipDecorations, addStanding, combineInventoryChanges, + generateRewardSeed, updateCurrency, updateSyndicate } from "@/src/services/inventoryService"; @@ -70,7 +71,12 @@ const getRotations = (rotationCount: number, tierOverride: number | undefined): return rotatedValues; }; -const getRandomRewardByChance = (pool: IReward[]): IRngResult | undefined => { +const getRandomRewardByChance = (pool: IReward[], rng?: SRng): IRngResult | undefined => { + if (rng) { + const res = rng.randomReward(pool as IRngResult[]); + rng.randomFloat(); // something related to rewards multiplier + return res; + } return getRandomReward(pool as IRngResult[]); }; @@ -548,6 +554,11 @@ export const addMissionRewards = async ( return { MissionRewards: [] }; } + if (rewardInfo.rewardSeed) { + // We're using a reward seed, so give the client a new one in the response. + inventory.RewardSeed = generateRewardSeed(); + } + //TODO: check double reward merging const MissionRewards: IMissionReward[] = getRandomMissionDrops(rewardInfo, wagerTier); logger.debug("random mission drops:", MissionRewards); @@ -1062,6 +1073,7 @@ function getRandomMissionDrops(RewardInfo: IRewardInfo, tierOverride: number | u if (rewardManifests.length != 0) { logger.debug(`generating random mission rewards`, { rewardManifests, rotations }); } + const rng = new SRng(BigInt(RewardInfo.rewardSeed ?? generateRewardSeed()) ^ 0xffffffffffffffffn); rewardManifests.forEach(name => { const table = ExportRewards[name]; if (!table) { @@ -1070,7 +1082,7 @@ function getRandomMissionDrops(RewardInfo: IRewardInfo, tierOverride: number | u } for (const rotation of rotations) { const rotationRewards = table[rotation]; - const drop = getRandomRewardByChance(rotationRewards); + const drop = getRandomRewardByChance(rotationRewards, rng); if (drop) { drops.push({ StoreItem: drop.type, ItemCount: drop.itemCount }); } diff --git a/src/services/rngService.ts b/src/services/rngService.ts index 983977ce..f88b23c0 100644 --- a/src/services/rngService.ts +++ b/src/services/rngService.ts @@ -31,7 +31,7 @@ const getRewardAtPercentage = (pool: T[], per return item; } } - throw new Error("What the fuck?"); + return pool[pool.length - 1]; }; export const getRandomReward = (pool: T[]): T | undefined => { @@ -142,4 +142,8 @@ export class SRng { this.state = (0x5851f42d4c957f2dn * this.state + 0x14057b7ef767814fn) & 0xffffffffffffffffn; return (Number(this.state >> 38n) & 0xffffff) * 0.000000059604645; } + + randomReward(pool: T[]): T | undefined { + return getRewardAtPercentage(pool, this.randomFloat()); + } } diff --git a/src/types/inventoryTypes/inventoryTypes.ts b/src/types/inventoryTypes/inventoryTypes.ts index 1146bef6..63207ef0 100644 --- a/src/types/inventoryTypes/inventoryTypes.ts +++ b/src/types/inventoryTypes/inventoryTypes.ts @@ -194,7 +194,7 @@ export interface IInventoryClient extends IDailyAffiliations, InventoryClientEqu Mailbox?: IMailboxClient; SubscribedToEmails: number; Created: IMongoDate; - RewardSeed: number; + RewardSeed: number | bigint; RegularCredits: number; PremiumCredits: number; PremiumCreditsFree: number; diff --git a/src/types/requestTypes.ts b/src/types/requestTypes.ts index 494e23f4..fff164a8 100644 --- a/src/types/requestTypes.ts +++ b/src/types/requestTypes.ts @@ -141,7 +141,7 @@ export interface IRewardInfo { EOM_AFK?: number; rewardQualifications?: string; // did a Survival for 5 minutes and this was "1" PurgatoryRewardQualifications?: string; - rewardSeed?: number; + rewardSeed?: number | bigint; periodicMissionTag?: string; // for bounties, only EOM_AFK and node are given from above, plus: