XFE Git
XFE Studio Git
Git 首页 全局搜索
XFE 主站 文档 NuGet

XFESpaceNinjaServer

A simple server for a small space ninja game

公开
关注 0 Fork 0 Star 0
返回提交历史

XFEstudio/XFESpaceNinjaServer

feat: picking relic rewards from other players (#3523)

Reviewed-on: https://onlyg.it/OpenWF/SpaceNinjaServer/pulls/3523 Co-authored-by: Sainan <63328889+Sainan@users.noreply.github.com> Co-committed-by: Sainan <63328889+Sainan@users.noreply.github.com>

19333e62
Sainan <63328889+Sainan@users.noreply.github.com>
提交于

代码差异

4 个文件 +62 -17
Modified src/controllers/api/getVoidProjectionRewardsController.ts +8 -2
@@ -1,13 +1,15 @@
1 1 import { getJSONfromString } from "../../helpers/stringHelpers.ts";
2 import { crackRelic } from "../../helpers/relicHelper.ts";
2 import { crackRelic, ensureRelicRewardIsCorrect } from "../../helpers/relicHelper.ts";
3 3 import { getInventory } from "../../services/inventoryService.ts";
4 4 import { getAccountIdForRequest } from "../../services/loginService.ts";
5 import type { IVoidTearParticipantInfo } from "../../types/requestTypes.ts";
5 import type { IVoidTearParticipantInfo, IVoidTearWaveInfo } from "../../types/requestTypes.ts";
6 6 import type { RequestHandler } from "express";
7 import { logger } from "../../utils/logger.ts";
7 8
8 9 export const getVoidProjectionRewardsController: RequestHandler = async (req, res) => {
9 10 const accountId = await getAccountIdForRequest(req);
10 11 const data = getJSONfromString<IVoidProjectionRewardRequest>(String(req.body));
12 logger.debug(`getVoidProjectionRewards request:`, data);
11 13
12 14 if (data.ParticipantInfo.QualifiesForReward && !data.ParticipantInfo.HaveRewardResponse) {
13 15 const inventory = await getInventory(accountId);
@@ -16,6 +18,9 @@ export const getVoidProjectionRewardsController: RequestHandler = async (req, re
16 18 inventory.MissionRelicRewards = [];
17 19 }
18 20 inventory.MissionRelicRewards.push({ ItemType: reward.type, ItemCount: reward.itemCount });
21 if (data.VoidTearParticipantsPrevWave) {
22 await ensureRelicRewardIsCorrect(inventory, data.VoidTearParticipantsPrevWave);
23 }
19 24 await inventory.save();
20 25 }
21 26
@@ -30,6 +35,7 @@ export const getVoidProjectionRewardsController: RequestHandler = async (req, re
30 35 interface IVoidProjectionRewardRequest {
31 36 CurrentWave: number;
32 37 ParticipantInfo: IVoidTearParticipantInfo;
38 VoidTearParticipantsPrevWave?: IVoidTearWaveInfo;
33 39 VoidTier: string;
34 40 DifficultyTier: number;
35 41 VoidProjectionRemovalHash: string;
Modified src/helpers/relicHelper.ts +39 -7
@@ -1,13 +1,14 @@
1 1 import type { TInventoryDatabaseDocument } from "../models/inventoryModels/inventoryModel.ts";
2 import type { IVoidTearParticipantInfo } from "../types/requestTypes.ts";
2 import type { IVoidTearParticipantInfo, IVoidTearWaveInfo } from "../types/requestTypes.ts";
3 3 import type { TRarity } from "warframe-public-export-plus";
4 4 import { ExportRelics, ExportRewards } from "warframe-public-export-plus";
5 5 import type { IRngResult } from "../services/rngService.ts";
6 6 import { getRandomWeightedReward } from "../services/rngService.ts";
7 7 import { logger } from "../utils/logger.ts";
8 import { addMiscItems, combineInventoryChanges } from "../services/inventoryService.ts";
9 import { handleStoreItemAcquisition } from "../services/purchaseService.ts";
8 import { addItem, addMiscItems, combineInventoryChanges } from "../services/inventoryService.ts";
10 9 import type { IInventoryChanges } from "../types/purchaseTypes.ts";
10 import type { ITypeCount } from "../types/commonTypes.ts";
11 import { fromStoreItem } from "../services/itemDataService.ts";
11 12
12 13 export const crackRelic = async (
13 14 inventory: TInventoryDatabaseDocument,
@@ -48,10 +49,7 @@ export const crackRelic = async (
48 49 combineInventoryChanges(inventoryChanges, { MiscItems: miscItemChanges });
49 50
50 51 // Give reward
51 combineInventoryChanges(
52 inventoryChanges,
53 (await handleStoreItemAcquisition(reward.type, inventory, reward.itemCount)).InventoryChanges
54 );
52 combineInventoryChanges(inventoryChanges, await addItem(inventory, fromStoreItem(reward.type), reward.itemCount));
55 53
56 54 // Client has picked its own reward (for lack of choice)
57 55 participant.ChosenRewardOwner = participant.AccountId;
@@ -85,3 +83,37 @@ const refinementToWeights = {
85 83 LEGENDARY: 0
86 84 }
87 85 };
86
87 const getTypeCountForParticiantReward = (participant: IVoidTearParticipantInfo): ITypeCount => {
88 const relic = ExportRelics[participant.VoidProjection];
89 const reward = ExportRewards[relic.rewardManifest][0].find(x => x.type == participant.Reward)!;
90 return {
91 ItemType: reward.type,
92 ItemCount: reward.itemCount
93 };
94 };
95
96 export const ensureRelicRewardIsCorrect = async (
97 inventory: TInventoryDatabaseDocument,
98 wi: IVoidTearWaveInfo
99 ): Promise<void> => {
100 if (inventory.MissionRelicRewards && inventory.MissionRelicRewards.length >= wi.Wave) {
101 const userParticipantInfo = wi.Participants.find(x => inventory.accountOwnerId.equals(x.AccountId))!;
102 const userReward = inventory.MissionRelicRewards[wi.Wave - 1];
103 if (userParticipantInfo.ChosenRewardOwner) {
104 const chosenParticipantInfo = wi.Participants.find(
105 x => x.AccountId == userParticipantInfo.ChosenRewardOwner
106 )!;
107 const chosenReward = getTypeCountForParticiantReward(chosenParticipantInfo);
108 if (chosenReward.ItemType != userReward.ItemType || chosenReward.ItemCount != userReward.ItemCount) {
109 logger.debug(`fixing up wave ${wi.Wave} reward for ${inventory.accountOwnerId.toString()}`, {
110 toRemove: userReward,
111 toAdd: chosenReward
112 });
113 await addItem(inventory, fromStoreItem(userReward.ItemType), userReward.ItemCount * -1);
114 await addItem(inventory, fromStoreItem(chosenReward.ItemType), chosenReward.ItemCount);
115 inventory.MissionRelicRewards[wi.Wave - 1] = chosenReward;
116 }
117 }
118 }
119 };
Modified src/services/missionInventoryUpdateService.ts +8 -3
@@ -66,7 +66,7 @@ import type { TInventoryDatabaseDocument } from "../models/inventoryModels/inven
66 66 import { getEntriesUnsafe } from "../utils/ts-utils.ts";
67 67 import { handleStoreItemAcquisition } from "./purchaseService.ts";
68 68 import type { IMissionCredits, IMissionReward, INemesisTaxInfo, IRecoveredItemInfo } from "../types/missionTypes.ts";
69 import { crackRelic } from "../helpers/relicHelper.ts";
69 import { crackRelic, ensureRelicRewardIsCorrect } from "../helpers/relicHelper.ts";
70 70 import type { IMessageCreationTemplate } from "./inboxService.ts";
71 71 import { createMessage } from "./inboxService.ts";
72 72 import kuriaMessage50 from "../../static/fixed_responses/kuriaMessages/fiftyPercent.json" with { type: "json" };
@@ -1675,11 +1675,16 @@ export const addMissionRewards = async (
1675 1675
1676 1676 if (voidTearWave && voidTearWave.Participants[0].QualifiesForReward) {
1677 1677 if (!voidTearWave.Participants[0].HaveRewardResponse) {
1678 // non-endless fissure; giving reward now
1678 // non-endless fissure in solo mode; giving reward now
1679 1679 const reward = await crackRelic(inventory, voidTearWave.Participants[0], inventoryChanges);
1680 1680 MissionRewards.push({ StoreItem: reward.type, ItemCount: reward.itemCount });
1681 1681 } else if (inventory.MissionRelicRewards) {
1682 // endless fissure; already gave reward(s) but should still show in EOM screen
1682 // endless fissure or non-endless fissure in multiplayer
1683
1684 await ensureRelicRewardIsCorrect(inventory, voidTearWave);
1685 await inventory.save(); // needed to avoid conflict on MissionRelicRewards
1686
1687 // already gave reward(s) but should still show in EOM screen
1683 1688 for (const reward of inventory.MissionRelicRewards) {
1684 1689 MissionRewards.push({
1685 1690 StoreItem: reward.ItemType,
Modified src/types/requestTypes.ts +7 -5
@@ -114,11 +114,7 @@ export type IMissionInventoryUpdateRequest = {
114 114 PlayerSkillGains: Partial<IPlayerSkills>;
115 115 CustomMarkers?: ICustomMarkers[];
116 116 LoreFragmentScans?: ILoreFragmentScan[];
117 VoidTearParticipantsCurrWave?: {
118 Wave: number;
119 IsFinalWave: boolean;
120 Participants: IVoidTearParticipantInfo[];
121 };
117 VoidTearParticipantsCurrWave?: IVoidTearWaveInfo;
122 118 LibraryScans?: {
123 119 EnemyType: string;
124 120 Count: number;
@@ -274,6 +270,12 @@ export interface IUpgradeOperation {
274 270 PolarityRemap: IPolarity[];
275 271 }
276 272
273 export interface IVoidTearWaveInfo {
274 Wave: number;
275 IsFinalWave: boolean;
276 Participants: IVoidTearParticipantInfo[];
277 }
278
277 279 export interface IVoidTearParticipantInfo {
278 280 AccountId: string;
279 281 Name: string;