返回提交历史
Modified
src/controllers/api/genericUpdateController.ts
+1
-2
Modified
src/services/inventoryService.ts
+54
-3
Modified
src/services/purchaseService.ts
+30
-15
Modified
src/services/serversideVendorsService.ts
+2
-0
Modified
src/types/genericUpdate.ts
+7
-0
Added
static/fixed_responses/getVendorInfo/Nova1999ConquestShopManifest.json
+188
-0
XFEstudio/SpaceNinjaServer
feat: acquisition of peely pix + free pack for first visit (#1292)
Reviewed-on: https://onlyg.it/OpenWF/SpaceNinjaServer/pulls/1292
b5a0a229
代码差异
6 个文件
+282
-20
@@ -10,8 +10,7 @@ import { IGenericUpdate } from "@/src/types/genericUpdate";
10
10
const genericUpdateController: RequestHandler = async (request, response) => {
11
11
const accountId = await getAccountIdForRequest(request);
12
12
const update = getJSONfromString<IGenericUpdate>(String(request.body));
13
await updateGeneric(update, accountId);
14
response.json(update);
13
response.json(await updateGeneric(update, accountId));
15
14
};
16
15
17
16
export { genericUpdateController };
@@ -28,7 +28,7 @@ import {
28
28
IUpgradeClient,
29
29
ICrewShipWeaponClient
30
30
} from "@/src/types/inventoryTypes/inventoryTypes";
31
import { IGenericUpdate } from "../types/genericUpdate";
31
import { IGenericUpdate, IUpdateNodeIntrosResponse } from "../types/genericUpdate";
32
32
import {
33
33
IMissionInventoryUpdateRequest,
34
34
IThemeUpdateRequest,
@@ -574,6 +574,39 @@ export const addItem = async (
574
574
};
575
575
}
576
576
break;
577
578
case "Stickers":
579
{
580
const entry = inventory.RawUpgrades.find(x => x.ItemType == typeName);
581
if (entry && entry.ItemCount >= 10) {
582
const miscItemChanges = [
583
{
584
ItemType: "/Lotus/Types/Items/MiscItems/1999ConquestBucks",
585
ItemCount: 1
586
}
587
];
588
addMiscItems(inventory, miscItemChanges);
589
return {
590
InventoryChanges: {
591
MiscItems: miscItemChanges
592
}
593
};
594
} else {
595
const changes = [
596
{
597
ItemType: typeName,
598
ItemCount: quantity
599
}
600
];
601
addMods(inventory, changes);
602
return {
603
InventoryChanges: {
604
RawUpgrades: changes
605
}
606
};
607
}
608
}
609
break;
577
610
}
578
611
break;
579
612
}
@@ -876,14 +909,27 @@ export const updateStandingLimit = (
876
909
};
877
910
878
911
// TODO: AffiliationMods support (Nightwave).
879
export const updateGeneric = async (data: IGenericUpdate, accountId: string): Promise<void> => {
880
const inventory = await getInventory(accountId);
912
export const updateGeneric = async (data: IGenericUpdate, accountId: string): Promise<IUpdateNodeIntrosResponse> => {
913
const inventory = await getInventory(accountId, "NodeIntrosCompleted MiscItems");
881
914
882
915
// Make it an array for easier parsing.
883
916
if (typeof data.NodeIntrosCompleted === "string") {
884
917
data.NodeIntrosCompleted = [data.NodeIntrosCompleted];
885
918
}
886
919
920
const inventoryChanges: IInventoryChanges = {};
921
for (const node of data.NodeIntrosCompleted) {
922
if (node == "KayaFirstVisitPack") {
923
inventoryChanges.MiscItems = [
924
{
925
ItemType: "/Lotus/Types/Items/MiscItems/1999FixedStickersPack",
926
ItemCount: 1
927
}
928
];
929
addMiscItems(inventory, inventoryChanges.MiscItems);
930
}
931
}
932
887
933
// Combine the two arrays into one.
888
934
data.NodeIntrosCompleted = inventory.NodeIntrosCompleted.concat(data.NodeIntrosCompleted);
889
935
@@ -892,6 +938,11 @@ export const updateGeneric = async (data: IGenericUpdate, accountId: string): Pr
892
938
893
939
inventory.NodeIntrosCompleted = nodes;
894
940
await inventory.save();
941
942
return {
943
MissionRewards: [],
944
InventoryChanges: inventoryChanges
945
};
895
946
};
896
947
897
948
export const updateTheme = async (data: IThemeUpdateRequest, accountId: string): Promise<void> => {
@@ -54,11 +54,16 @@ export const handlePurchase = async (
54
54
if (purchaseRequest.PurchaseParams.Source == 7) {
55
55
const manifest = getVendorManifestByOid(purchaseRequest.PurchaseParams.SourceId!);
56
56
if (manifest) {
57
const ItemId = (JSON.parse(purchaseRequest.PurchaseParams.ExtraPurchaseInfoJson!) as { ItemId: string })
58
.ItemId;
59
const offer = manifest.VendorInfo.ItemManifest.find(x => x.Id.$oid == ItemId);
57
let ItemId: string | undefined;
58
if (purchaseRequest.PurchaseParams.ExtraPurchaseInfoJson) {
59
ItemId = (JSON.parse(purchaseRequest.PurchaseParams.ExtraPurchaseInfoJson) as { ItemId: string })
60
.ItemId;
61
}
62
const offer = ItemId
63
? manifest.VendorInfo.ItemManifest.find(x => x.Id.$oid == ItemId)
64
: manifest.VendorInfo.ItemManifest.find(x => x.StoreItem == purchaseRequest.PurchaseParams.StoreItem);
60
65
if (!offer) {
61
throw new Error(`unknown vendor offer: ${ItemId}`);
66
throw new Error(`unknown vendor offer: ${ItemId ? ItemId : purchaseRequest.PurchaseParams.StoreItem}`);
62
67
}
63
68
if (offer.ItemPrices) {
64
69
handleItemPrices(
@@ -68,7 +73,7 @@ export const handlePurchase = async (
68
73
prePurchaseInventoryChanges
69
74
);
70
75
}
71
if (!config.noVendorPurchaseLimits) {
76
if (!config.noVendorPurchaseLimits && ItemId) {
72
77
inventory.RecentVendorPurchases ??= [];
73
78
let vendorPurchases = inventory.RecentVendorPurchases.find(
74
79
x => x.VendorType == manifest.VendorInfo.TypeName
@@ -410,16 +415,26 @@ const handleBoosterPackPurchase = async (
410
415
"attempt to roll over 100 booster packs in a single go. possible but unlikely to be desirable for the user or the server."
411
416
);
412
417
}
413
for (let i = 0; i != quantity; ++i) {
414
for (const weights of pack.rarityWeightsPerRoll) {
415
const result = getRandomWeightedRewardUc(pack.components, weights);
416
if (result) {
417
logger.debug(`booster pack rolled`, result);
418
purchaseResponse.BoosterPackItems += toStoreItem(result.Item) + ',{"lvl":0};';
419
combineInventoryChanges(
420
purchaseResponse.InventoryChanges,
421
(await addItem(inventory, result.Item, 1)).InventoryChanges
422
);
418
if (typeName == "/Lotus/Types/BoosterPacks/1999StickersPackEchoesArchimedeaFixed") {
419
for (const result of pack.components) {
420
purchaseResponse.BoosterPackItems += toStoreItem(result.Item) + ',{"lvl":0};';
421
combineInventoryChanges(
422
purchaseResponse.InventoryChanges,
423
(await addItem(inventory, result.Item, 1)).InventoryChanges
424
);
425
}
426
} else {
427
for (let i = 0; i != quantity; ++i) {
428
for (const weights of pack.rarityWeightsPerRoll) {
429
const result = getRandomWeightedRewardUc(pack.components, weights);
430
if (result) {
431
logger.debug(`booster pack rolled`, result);
432
purchaseResponse.BoosterPackItems += toStoreItem(result.Item) + ',{"lvl":0};';
433
combineInventoryChanges(
434
purchaseResponse.InventoryChanges,
435
(await addItem(inventory, result.Item, 1)).InventoryChanges
436
);
437
}
423
438
}
424
439
}
425
440
}
@@ -19,6 +19,7 @@ import HubsIronwakeDondaVendorManifest from "@/static/fixed_responses/getVendorI
19
19
import HubsPerrinSequenceWeaponVendorManifest from "@/static/fixed_responses/getVendorInfo/HubsPerrinSequenceWeaponVendorManifest.json";
20
20
import HubsRailjackCrewMemberVendorManifest from "@/static/fixed_responses/getVendorInfo/HubsRailjackCrewMemberVendorManifest.json";
21
21
import MaskSalesmanManifest from "@/static/fixed_responses/getVendorInfo/MaskSalesmanManifest.json";
22
import Nova1999ConquestShopManifest from "@/static/fixed_responses/getVendorInfo/Nova1999ConquestShopManifest.json";
22
23
import OstronFishmongerVendorManifest from "@/static/fixed_responses/getVendorInfo/OstronFishmongerVendorManifest.json";
23
24
import OstronPetVendorManifest from "@/static/fixed_responses/getVendorInfo/OstronPetVendorManifest.json";
24
25
import OstronProspectorVendorManifest from "@/static/fixed_responses/getVendorInfo/OstronProspectorVendorManifest.json";
@@ -69,6 +70,7 @@ const vendorManifests: IVendorManifest[] = [
69
70
HubsPerrinSequenceWeaponVendorManifest,
70
71
HubsRailjackCrewMemberVendorManifest,
71
72
MaskSalesmanManifest,
73
Nova1999ConquestShopManifest,
72
74
OstronFishmongerVendorManifest,
73
75
OstronPetVendorManifest,
74
76
OstronProspectorVendorManifest,
@@ -1,4 +1,11 @@
1
import { IInventoryChanges } from "./purchaseTypes";
2
1
3
export interface IGenericUpdate {
2
4
NodeIntrosCompleted: string | string[];
3
5
// AffiliationMods: any[];
4
6
}
7
8
export interface IUpdateNodeIntrosResponse {
9
MissionRewards: [];
10
InventoryChanges: IInventoryChanges;
11
}
@@ -0,0 +1,188 @@
1
{
2
"VendorInfo": {
3
"_id": {
4
"$oid": "67dadc30e4b6e0e5979c8d6a"
5
},
6
"TypeName": "/Lotus/Types/Game/VendorManifests/TheHex/Nova1999ConquestShopManifest",
7
"ItemManifest": [
8
{
9
"StoreItem": "/Lotus/StoreItems/Types/BoosterPacks/1999StickersPackEchoesArchimedea",
10
"ItemPrices": [
11
{
12
"ItemCount": 10,
13
"ItemType": "/Lotus/Types/Items/MiscItems/1999ConquestBucks",
14
"ProductCategory": "MiscItems"
15
}
16
],
17
"Bin": "BIN_0",
18
"QuantityMultiplier": 1,
19
"Expiry": {
20
"$date": {
21
"$numberLong": "2051240400000"
22
}
23
},
24
"AllowMultipurchase": true,
25
"Id": {
26
"$oid": "67db32b983b2ad79a9c1c18c"
27
}
28
},
29
{
30
"StoreItem": "/Lotus/StoreItems/Types/BoosterPacks/1999StickersPackEchoesArchimedeaFree",
31
"ItemPrices": [
32
{
33
"ItemCount": 1,
34
"ItemType": "/Lotus/Types/Items/MiscItems/1999FreeStickersPack",
35
"ProductCategory": "MiscItems"
36
}
37
],
38
"Bin": "BIN_0",
39
"QuantityMultiplier": 1,
40
"Expiry": {
41
"$date": {
42
"$numberLong": "2051240400000"
43
}
44
},
45
"AllowMultipurchase": true,
46
"Id": {
47
"$oid": "67db32b983b2ad79a9c1c18d"
48
}
49
},
50
{
51
"StoreItem": "/Lotus/StoreItems/Types/BoosterPacks/1999StickersPackEchoesArchimedeaFixed",
52
"ItemPrices": [
53
{
54
"ItemCount": 1,
55
"ItemType": "/Lotus/Types/Items/MiscItems/1999FixedStickersPack",
56
"ProductCategory": "MiscItems"
57
}
58
],
59
"Bin": "BIN_0",
60
"QuantityMultiplier": 1,
61
"Expiry": {
62
"$date": {
63
"$numberLong": "2051240400000"
64
}
65
},
66
"AllowMultipurchase": true,
67
"Id": {
68
"$oid": "67db32b983b2ad79a9c1c18e"
69
}
70
},
71
{
72
"StoreItem": "/Lotus/Types/StoreItems/Packages/SyndicateVosforPack",
73
"ItemPrices": [
74
{
75
"ItemCount": 6,
76
"ItemType": "/Lotus/Types/Items/MiscItems/1999ConquestBucks",
77
"ProductCategory": "MiscItems"
78
}
79
],
80
"Bin": "BIN_0",
81
"QuantityMultiplier": 1,
82
"Expiry": {
83
"$date": {
84
"$numberLong": "2051240400000"
85
}
86
},
87
"AllowMultipurchase": true,
88
"Id": {
89
"$oid": "67db32b983b2ad79a9c1c18f"
90
}
91
},
92
{
93
"StoreItem": "/Lotus/StoreItems/Types/Items/ShipDecos/StickerPictureFrame",
94
"ItemPrices": [
95
{
96
"ItemCount": 10,
97
"ItemType": "/Lotus/Types/Items/MiscItems/1999ConquestBucks",
98
"ProductCategory": "MiscItems"
99
}
100
],
101
"Bin": "BIN_0",
102
"QuantityMultiplier": 1,
103
"Expiry": {
104
"$date": {
105
"$numberLong": "2051240400000"
106
}
107
},
108
"AllowMultipurchase": true,
109
"Id": {
110
"$oid": "67db32b983b2ad79a9c1c190"
111
}
112
},
113
{
114
"StoreItem": "/Lotus/StoreItems/Upgrades/CosmeticEnhancers/Utility/AbilityRadiationProcsCreateUniversalOrbsOnKill",
115
"ItemPrices": [
116
{
117
"ItemCount": 5,
118
"ItemType": "/Lotus/Types/Items/MiscItems/1999ConquestBucks",
119
"ProductCategory": "MiscItems"
120
}
121
],
122
"Bin": "BIN_1",
123
"QuantityMultiplier": 1,
124
"Expiry": {
125
"$date": {
126
"$numberLong": "2051240400000"
127
}
128
},
129
"PurchaseQuantityLimit": 1,
130
"AllowMultipurchase": false,
131
"Id": {
132
"$oid": "67db32b983b2ad79a9c1c191"
133
}
134
},
135
{
136
"StoreItem": "/Lotus/StoreItems/Upgrades/CosmeticEnhancers/Offensive/AbilityHeatProcsGiveCritChance",
137
"ItemPrices": [
138
{
139
"ItemCount": 5,
140
"ItemType": "/Lotus/Types/Items/MiscItems/1999ConquestBucks",
141
"ProductCategory": "MiscItems"
142
}
143
],
144
"Bin": "BIN_1",
145
"QuantityMultiplier": 1,
146
"Expiry": {
147
"$date": {
148
"$numberLong": "2051240400000"
149
}
150
},
151
"PurchaseQuantityLimit": 1,
152
"AllowMultipurchase": false,
153
"Id": {
154
"$oid": "67db32b983b2ad79a9c1c192"
155
}
156
},
157
{
158
"StoreItem": "/Lotus/StoreItems/Upgrades/CosmeticEnhancers/Defensive/InvulnerabilityOnDeathOnMercyKill",
159
"ItemPrices": [
160
{
161
"ItemCount": 5,
162
"ItemType": "/Lotus/Types/Items/MiscItems/1999ConquestBucks",
163
"ProductCategory": "MiscItems"
164
}
165
],
166
"Bin": "BIN_1",
167
"QuantityMultiplier": 1,
168
"Expiry": {
169
"$date": {
170
"$numberLong": "2051240400000"
171
}
172
},
173
"PurchaseQuantityLimit": 1,
174
"AllowMultipurchase": false,
175
"Id": {
176
"$oid": "67db32b983b2ad79a9c1c193"
177
}
178
}
179
],
180
"PropertyTextHash": "CB7D0E807FD5E2BCD059195201D963B9",
181
"RequiredGoalTag": "",
182
"Expiry": {
183
"$date": {
184
"$numberLong": "2051240400000"
185
}
186
}
187
}
188
}