forked from OpenWF/SpaceNinjaServer
fix: generate rewards based on RewardSeed to match what's show in client (#1628)
Reviewed-on: OpenWF/SpaceNinjaServer#1628 Co-authored-by: Sainan <63328889+Sainan@users.noreply.github.com> Co-committed-by: Sainan <63328889+Sainan@users.noreply.github.com>
This commit is contained in:
parent
d28437b658
commit
3f0a2bec48
@ -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
|
||||
|
@ -1213,7 +1213,7 @@ const inventorySchema = new Schema<IInventoryDatabase, InventoryDocumentProps>(
|
||||
accountOwnerId: Schema.Types.ObjectId,
|
||||
SubscribedToEmails: { type: Number, default: 0 },
|
||||
SubscribedToEmailsPersonalized: { type: Number, default: 0 },
|
||||
RewardSeed: Number,
|
||||
RewardSeed: BigInt,
|
||||
|
||||
//Credit
|
||||
RegularCredits: { type: Number, default: 0 },
|
||||
|
@ -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. On live, missionInventoryUpdate seems to always provide a fresh 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 });
|
||||
}
|
||||
|
@ -31,7 +31,7 @@ const getRewardAtPercentage = <T extends { probability: number }>(pool: T[], per
|
||||
return item;
|
||||
}
|
||||
}
|
||||
throw new Error("What the fuck?");
|
||||
return pool[pool.length - 1];
|
||||
};
|
||||
|
||||
export const getRandomReward = <T extends { probability: number }>(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<T extends { probability: number }>(pool: T[]): T | undefined {
|
||||
return getRewardAtPercentage(pool, this.randomFloat());
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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:
|
||||
|
Loading…
x
Reference in New Issue
Block a user