返回提交历史
Modified
src/controllers/api/getVoidProjectionRewardsController.ts
+8
-2
Modified
src/helpers/relicHelper.ts
+39
-7
Modified
src/services/missionInventoryUpdateService.ts
+8
-3
Modified
src/types/requestTypes.ts
+7
-5
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
代码差异
4 个文件
+62
-17
@@ -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;
@@ -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
};
@@ -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,
@@ -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;