返回提交历史
Modified
src/controllers/api/syndicateStandingBonusController.ts
+14
-10
Modified
src/services/inventoryService.ts
+41
-2
Modified
src/types/inventoryTypes/inventoryTypes.ts
+19
-15
XFEstudio/SpaceNinjaServer
feat: apply & track daily standing limit when trading in medallions (#788)
d8845bc4
代码差异
3 个文件
+74
-27
@@ -1,19 +1,19 @@
1
1
import { RequestHandler } from "express";
2
2
import { getAccountIdForRequest } from "@/src/services/loginService";
3
import { addMiscItems, getInventory } from "@/src/services/inventoryService";
3
import { addMiscItems, getInventory, getStandingLimit, updateStandingLimit } from "@/src/services/inventoryService";
4
4
import { IMiscItem } from "@/src/types/inventoryTypes/inventoryTypes";
5
5
import { IOid } from "@/src/types/commonTypes";
6
import { ExportSyndicates } from "warframe-public-export-plus";
6
import { ExportSyndicates, ISyndicate } from "warframe-public-export-plus";
7
7
8
8
export const syndicateStandingBonusController: RequestHandler = async (req, res) => {
9
9
const accountId = await getAccountIdForRequest(req);
10
10
const request = JSON.parse(String(req.body)) as ISyndicateStandingBonusRequest;
11
11
12
const syndicateMeta = ExportSyndicates[request.Operation.AffiliationTag];
13
12
14
let gainedStanding = 0;
13
15
request.Operation.Items.forEach(item => {
14
const medallion = (ExportSyndicates[request.Operation.AffiliationTag].medallions ?? []).find(
15
medallion => medallion.itemType == item.ItemType
16
);
16
const medallion = (syndicateMeta.medallions ?? []).find(medallion => medallion.itemType == item.ItemType);
17
17
if (medallion) {
18
18
gainedStanding += medallion.standing * item.ItemCount;
19
19
}
@@ -27,17 +27,22 @@ export const syndicateStandingBonusController: RequestHandler = async (req, res)
27
27
let syndicate = inventory.Affiliations.find(x => x.Tag == request.Operation.AffiliationTag);
28
28
if (!syndicate) {
29
29
syndicate =
30
inventory.Affiliations[inventory.Affiliations.push({ Tag: request.Operation.AffiliationTag, Standing: 0 })];
30
inventory.Affiliations[
31
inventory.Affiliations.push({ Tag: request.Operation.AffiliationTag, Standing: 0 }) - 1
32
];
31
33
}
32
34
33
const max = getMaxStanding(request.Operation.AffiliationTag, syndicate.Title ?? 0);
35
const max = getMaxStanding(syndicateMeta, syndicate.Title ?? 0);
34
36
if (syndicate.Standing + gainedStanding > max) {
35
37
gainedStanding = max - syndicate.Standing;
36
38
}
39
if (gainedStanding > getStandingLimit(inventory, syndicateMeta.dailyLimitBin)) {
40
gainedStanding = getStandingLimit(inventory, syndicateMeta.dailyLimitBin);
41
}
37
42
38
43
syndicate.Standing += gainedStanding;
39
44
40
// TODO: Subtract from daily limit bin; maybe also a cheat to skip that.
45
updateStandingLimit(inventory, syndicateMeta.dailyLimitBin, gainedStanding);
41
46
42
47
await inventory.save();
43
48
@@ -63,8 +68,7 @@ interface ISyndicateStandingBonusRequest {
63
68
ModularWeaponId: IOid; // Seems to just be "000000000000000000000000", also note there's a "Category" query field
64
69
}
65
70
66
const getMaxStanding = (affiliationTag: string, title: number): number => {
67
const syndicate = ExportSyndicates[affiliationTag];
71
const getMaxStanding = (syndicate: ISyndicate, title: number): number => {
68
72
if (!syndicate.titles) {
69
73
// LibrarySyndicate
70
74
return 125000;
@@ -16,7 +16,8 @@ import {
16
16
IWeaponSkinClient,
17
17
TEquipmentKey,
18
18
equipmentKeys,
19
IFusionTreasure
19
IFusionTreasure,
20
IDailyAffiliations
20
21
} from "@/src/types/inventoryTypes/inventoryTypes";
21
22
import { IGenericUpdate } from "../types/genericUpdate";
22
23
import {
@@ -36,7 +37,8 @@ import {
36
37
ExportRecipes,
37
38
ExportResources,
38
39
ExportSentinels,
39
ExportUpgrades
40
ExportUpgrades,
41
TStandingLimitBin
40
42
} from "warframe-public-export-plus";
41
43
import { createShip } from "./shipService";
42
44
@@ -492,6 +494,43 @@ export const updateCurrencyByAccountId = async (
492
494
return currencyChanges;
493
495
};
494
496
497
const standingLimitBinToInventoryKey: Record<
498
Exclude<TStandingLimitBin, "STANDING_LIMIT_BIN_NONE">,
499
keyof IDailyAffiliations
500
> = {
501
STANDING_LIMIT_BIN_NORMAL: "DailyAffiliation",
502
STANDING_LIMIT_BIN_PVP: "DailyAffiliationPvp",
503
STANDING_LIMIT_BIN_LIBRARY: "DailyAffiliationLibrary",
504
STANDING_LIMIT_BIN_CETUS: "DailyAffiliationCetus",
505
STANDING_LIMIT_BIN_QUILLS: "DailyAffiliationQuills",
506
STANDING_LIMIT_BIN_SOLARIS: "DailyAffiliationSolaris",
507
STANDING_LIMIT_BIN_VENTKIDS: "DailyAffiliationVentkids",
508
STANDING_LIMIT_BIN_VOX: "DailyAffiliationVox",
509
STANDING_LIMIT_BIN_ENTRATI: "DailyAffiliationEntrati",
510
STANDING_LIMIT_BIN_NECRALOID: "DailyAffiliationNecraloid",
511
STANDING_LIMIT_BIN_ZARIMAN: "DailyAffiliationZariman",
512
STANDING_LIMIT_BIN_KAHL: "DailyAffiliationKahl",
513
STANDING_LIMIT_BIN_CAVIA: "DailyAffiliationCavia",
514
STANDING_LIMIT_BIN_HEX: "DailyAffiliationHex"
515
};
516
517
export const getStandingLimit = (inventory: IDailyAffiliations, bin: TStandingLimitBin): number => {
518
if (bin == "STANDING_LIMIT_BIN_NONE") {
519
return Number.MAX_SAFE_INTEGER;
520
}
521
return inventory[standingLimitBinToInventoryKey[bin]];
522
};
523
524
export const updateStandingLimit = (
525
inventory: IDailyAffiliations,
526
bin: TStandingLimitBin,
527
subtrahend: number
528
): void => {
529
if (bin != "STANDING_LIMIT_BIN_NONE") {
530
inventory[standingLimitBinToInventoryKey[bin]] -= subtrahend;
531
}
532
};
533
495
534
// TODO: AffiliationMods support (Nightwave).
496
535
export const updateGeneric = async (data: IGenericUpdate, accountId: string): Promise<void> => {
497
536
const inventory = await getInventory(accountId);
@@ -110,7 +110,25 @@ export type TSolarMapRegion =
110
110
export interface IPendingRecipeResponse extends Omit<IPendingRecipe, "CompletionDate"> {
111
111
CompletionDate: IMongoDate;
112
112
}
113
export interface IInventoryResponse {
113
114
export interface IDailyAffiliations {
115
DailyAffiliation: number;
116
DailyAffiliationPvp: number;
117
DailyAffiliationLibrary: number;
118
DailyAffiliationCetus: number;
119
DailyAffiliationQuills: number;
120
DailyAffiliationSolaris: number;
121
DailyAffiliationVentkids: number;
122
DailyAffiliationVox: number;
123
DailyAffiliationEntrati: number;
124
DailyAffiliationNecraloid: number;
125
DailyAffiliationZariman: number;
126
DailyAffiliationKahl: number;
127
DailyAffiliationCavia: number;
128
DailyAffiliationHex: number;
129
}
130
131
export interface IInventoryResponse extends IDailyAffiliations {
114
132
Horses: IEquipmentDatabase[];
115
133
DrifterMelee: IEquipmentDatabase[];
116
134
DrifterGuns: IEquipmentDatabase[];
@@ -138,9 +156,6 @@ export interface IInventoryResponse {
138
156
OperatorAmpBin: ISlots;
139
157
CrewShipSalvageBin: ISlots;
140
158
TradesRemaining: number;
141
DailyAffiliation: number;
142
DailyAffiliationPvp: number;
143
DailyAffiliationLibrary: number;
144
159
DailyFocus: number;
145
160
GiftsRemaining: number;
146
161
HandlerPoints: number;
@@ -220,8 +235,6 @@ export interface IInventoryResponse {
220
235
ActiveAvatarImageType: string;
221
236
KubrowPets: IEquipmentDatabase[];
222
237
ShipDecorations: IConsumable[];
223
DailyAffiliationCetus: number;
224
DailyAffiliationQuills: number;
225
238
DiscoveredMarkers: IDiscoveredMarker[];
226
239
CompletedJobs: ICompletedJob[];
227
240
FocusAbility: string;
@@ -232,7 +245,6 @@ export interface IInventoryResponse {
232
245
KubrowPetPrints: IKubrowPetPrint[];
233
246
AlignmentReplay: IAlignment;
234
247
PersonalGoalProgress: IPersonalGoalProgress[];
235
DailyAffiliationSolaris: number;
236
248
SpecialItems: IEquipmentDatabase[];
237
249
ThemeStyle: string;
238
250
ThemeBackground: string;
@@ -241,8 +253,6 @@ export interface IInventoryResponse {
241
253
ChallengeInstanceStates: IChallengeInstanceState[];
242
254
LoginMilestoneRewards: string[];
243
255
OperatorLoadOuts: IOperatorConfigClient[];
244
DailyAffiliationVentkids: number;
245
DailyAffiliationVox: number;
246
256
RecentVendorPurchases: Array<number | string>;
247
257
Hoverboards: IEquipmentDatabase[];
248
258
NodeIntrosCompleted: string[];
@@ -268,8 +278,6 @@ export interface IInventoryResponse {
268
278
TradeBannedUntil?: IMongoDate;
269
279
PlayedParkourTutorial: boolean;
270
280
SubscribedToEmailsPersonalized: number;
271
DailyAffiliationEntrati: number;
272
DailyAffiliationNecraloid: number;
273
281
MechSuits: IEquipmentDatabase[];
274
282
InfestedFoundry?: IInfestedFoundry;
275
283
BlessingCooldown: IMongoDate;
@@ -279,11 +287,7 @@ export interface IInventoryResponse {
279
287
AdultOperatorLoadOuts: IOperatorConfigClient[];
280
288
LotusCustomization: ILotusCustomization;
281
289
UseAdultOperatorLoadout?: boolean;
282
DailyAffiliationZariman: number;
283
290
NemesisAbandonedRewards: string[];
284
DailyAffiliationKahl: number;
285
DailyAffiliationCavia: number;
286
DailyAffiliationHex: number;
287
291
LastInventorySync: IOid;
288
292
NextRefill: IMongoDate; // Next time argon crystals will have a decay tick
289
293
FoundToday?: IMiscItem[]; // for Argon Crystals