返回提交历史
Modified
package-lock.json
+4
-4
Modified
package.json
+1
-1
Modified
src/controllers/api/guildTechController.ts
+34
-5
Modified
src/controllers/custom/getItemListsController.ts
+7
-0
Modified
src/models/inventoryModels/inventoryModel.ts
+23
-2
Modified
src/services/inventoryService.ts
+28
-1
Modified
src/types/inventoryTypes/inventoryTypes.ts
+18
-3
XFEstudio/SpaceNinjaServer
feat: fabricate research (#1150)
Closes #910 Reviewed-on: https://onlyg.it/OpenWF/SpaceNinjaServer/pulls/1150
38dfe147
代码差异
7 个文件
+115
-16
@@ -17,7 +17,7 @@
17
17
"mongoose": "^8.11.0",
18
18
"morgan": "^1.10.0",
19
19
"typescript": ">=4.7.4 <5.6.0",
20
"warframe-public-export-plus": "^0.5.42",
20
"warframe-public-export-plus": "^0.5.43",
21
21
"warframe-riven-info": "^0.1.2",
22
22
"winston": "^3.17.0",
23
23
"winston-daily-rotate-file": "^5.0.0"
@@ -4073,9 +4073,9 @@
4073
4073
}
4074
4074
},
4075
4075
"node_modules/warframe-public-export-plus": {
4076
"version": "0.5.42",
4077
"resolved": "https://registry.npmjs.org/warframe-public-export-plus/-/warframe-public-export-plus-0.5.42.tgz",
4078
"integrity": "sha512-up3P5bLKD42Xkr3o7TX9WUwvpJzK88aQTLZ2bB6QWUHdsJxl/Z3TBn+HSd3eouIDTMVUzbTDeDPosSw7TcLegA=="
4076
"version": "0.5.43",
4077
"resolved": "https://registry.npmjs.org/warframe-public-export-plus/-/warframe-public-export-plus-0.5.43.tgz",
4078
"integrity": "sha512-LeF7HmsjOPsJDtgr66x3iMEIAQgcxKNM54VG895FTemgHLLo34UGDyeS1yIfY67WxxbTUgW3MkHQLlCEJXD14w=="
4079
4079
},
4080
4080
"node_modules/warframe-riven-info": {
4081
4081
"version": "0.1.2",
@@ -22,7 +22,7 @@
22
22
"mongoose": "^8.11.0",
23
23
"morgan": "^1.10.0",
24
24
"typescript": ">=4.7.4 <5.6.0",
25
"warframe-public-export-plus": "^0.5.42",
25
"warframe-public-export-plus": "^0.5.43",
26
26
"warframe-riven-info": "^0.1.2",
27
27
"winston": "^3.17.0",
28
28
"winston-daily-rotate-file": "^5.0.0"
@@ -2,7 +2,14 @@ import { RequestHandler } from "express";
2
2
import { getGuildForRequestEx, getGuildVault, scaleRequiredCount } from "@/src/services/guildService";
3
3
import { ExportDojoRecipes, IDojoResearch } from "warframe-public-export-plus";
4
4
import { getAccountIdForRequest } from "@/src/services/loginService";
5
import { addMiscItems, addRecipes, getInventory, updateCurrency } from "@/src/services/inventoryService";
5
import {
6
addItem,
7
addMiscItems,
8
addRecipes,
9
combineInventoryChanges,
10
getInventory,
11
updateCurrency
12
} from "@/src/services/inventoryService";
6
13
import { IMiscItem } from "@/src/types/inventoryTypes/inventoryTypes";
7
14
import { IInventoryChanges } from "@/src/types/purchaseTypes";
8
15
import { config } from "@/src/services/configService";
@@ -127,6 +134,20 @@ export const guildTechController: RequestHandler = async (req, res) => {
127
134
Recipes: recipeChanges
128
135
}
129
136
});
137
} else if (action == "Fabricate") {
138
const payload = data as IGuildTechFabricateRequest;
139
const recipe = ExportDojoRecipes.fabrications[payload.RecipeType];
140
const inventory = await getInventory(accountId);
141
const inventoryChanges: IInventoryChanges = updateCurrency(inventory, recipe.price, false);
142
inventoryChanges.MiscItems = recipe.ingredients.map(x => ({
143
ItemType: x.ItemType,
144
ItemCount: x.ItemCount * -1
145
}));
146
addMiscItems(inventory, inventoryChanges.MiscItems);
147
combineInventoryChanges(inventoryChanges, (await addItem(inventory, recipe.resultType)).InventoryChanges);
148
await inventory.save();
149
// Not a mistake: This response uses `inventoryChanges` instead of `InventoryChanges`.
150
res.json({ inventoryChanges: inventoryChanges });
130
151
} else {
131
152
throw new Error(`unknown guildTech action: ${data.Action}`);
132
153
}
@@ -144,10 +165,12 @@ const processFundedProject = (
144
165
}
145
166
};
146
167
147
type TGuildTechRequest = {
148
Action: string;
149
} & Partial<IGuildTechStartFields> &
150
Partial<IGuildTechContributeFields>;
168
type TGuildTechRequest =
169
| ({
170
Action: string;
171
} & Partial<IGuildTechStartFields> &
172
Partial<IGuildTechContributeFields>)
173
| IGuildTechFabricateRequest;
151
174
152
175
interface IGuildTechStartFields {
153
176
Mode: "Guild";
@@ -164,3 +187,9 @@ interface IGuildTechContributeFields {
164
187
VaultCredits: number;
165
188
VaultMiscItems: IMiscItem[];
166
189
}
190
191
interface IGuildTechFabricateRequest {
192
Action: "Fabricate";
193
Mode: "Guild";
194
RecipeType: string;
195
}
@@ -6,6 +6,7 @@ import {
6
6
ExportDrones,
7
7
ExportGear,
8
8
ExportMisc,
9
ExportRailjackWeapons,
9
10
ExportRecipes,
10
11
ExportRelics,
11
12
ExportResources,
@@ -160,6 +161,12 @@ const getItemListsController: RequestHandler = (req, response) => {
160
161
name: getString(item.name, lang)
161
162
});
162
163
}
164
for (const [uniqueName, item] of Object.entries(ExportRailjackWeapons)) {
165
res.miscitems.push({
166
uniqueName: uniqueName,
167
name: getString(item.name, lang)
168
});
169
}
163
170
164
171
res.mods = [];
165
172
for (const [uniqueName, upgrade] of Object.entries(ExportUpgrades)) {
@@ -75,7 +75,8 @@ import {
75
75
ICollectibleEntry,
76
76
IIncentiveState,
77
77
ISongChallenge,
78
ILibraryPersonalProgress
78
ILibraryPersonalProgress,
79
ICrewShipWeaponDatabase
79
80
} from "../../types/inventoryTypes/inventoryTypes";
80
81
import { IOid } from "../../types/commonTypes";
81
82
import {
@@ -1037,6 +1038,25 @@ const alignmentSchema = new Schema<IAlignment>(
1037
1038
{ _id: false }
1038
1039
);
1039
1040
1041
const crewShipWeaponSchema2 = new Schema<ICrewShipWeaponDatabase>(
1042
{
1043
ItemType: String
1044
},
1045
{ id: false }
1046
);
1047
1048
crewShipWeaponSchema2.virtual("ItemId").get(function () {
1049
return { $oid: this._id.toString() } satisfies IOid;
1050
});
1051
1052
crewShipWeaponSchema2.set("toJSON", {
1053
virtuals: true,
1054
transform(_document, returnedObject) {
1055
delete returnedObject._id;
1056
delete returnedObject.__v;
1057
}
1058
});
1059
1040
1060
const inventorySchema = new Schema<IInventoryDatabase, InventoryDocumentProps>(
1041
1061
{
1042
1062
accountOwnerId: Schema.Types.ObjectId,
@@ -1157,7 +1177,7 @@ const inventorySchema = new Schema<IInventoryDatabase, InventoryDocumentProps>(
1157
1177
1158
1178
//Default RailJack
1159
1179
CrewShipAmmo: [typeCountSchema],
1160
CrewShipWeapons: [Schema.Types.Mixed],
1180
CrewShipWeapons: [crewShipWeaponSchema2],
1161
1181
CrewShipWeaponSkins: [upgradeSchema],
1162
1182
1163
1183
//NPC Crew and weapon
@@ -1404,6 +1424,7 @@ export type InventoryDocumentProps = {
1404
1424
WeaponSkins: Types.DocumentArray<IWeaponSkinDatabase>;
1405
1425
QuestKeys: Types.DocumentArray<IQuestKeyDatabase>;
1406
1426
Drones: Types.DocumentArray<IDroneDatabase>;
1427
CrewShipWeapons: Types.DocumentArray<ICrewShipWeaponDatabase>;
1407
1428
CrewShipWeaponSkins: Types.DocumentArray<IUpgradeDatabase>;
1408
1429
} & { [K in TEquipmentKey]: Types.DocumentArray<IEquipmentDatabase> };
1409
1430
@@ -26,7 +26,8 @@ import {
26
26
ILibraryDailyTaskInfo,
27
27
ICalendarProgress,
28
28
IDroneClient,
29
IUpgradeClient
29
IUpgradeClient,
30
ICrewShipWeaponClient
30
31
} from "@/src/types/inventoryTypes/inventoryTypes";
31
32
import { IGenericUpdate } from "../types/genericUpdate";
32
33
import {
@@ -54,6 +55,7 @@ import {
54
55
ExportGear,
55
56
ExportKeys,
56
57
ExportMisc,
58
ExportRailjackWeapons,
57
59
ExportRecipes,
58
60
ExportResources,
59
61
ExportSentinels,
@@ -386,6 +388,14 @@ export const addItem = async (
386
388
};
387
389
}
388
390
}
391
if (typeName in ExportRailjackWeapons) {
392
return {
393
InventoryChanges: {
394
...addCrewShipWeapon(inventory, typeName),
395
...occupySlot(inventory, InventorySlot.RJ_COMPONENT_AND_ARMAMENTS, premiumPurchase)
396
}
397
};
398
}
389
399
if (typeName in ExportMisc.creditBundles) {
390
400
const creditsTotal = ExportMisc.creditBundles[typeName] * quantity;
391
401
inventory.RegularCredits += creditsTotal;
@@ -859,6 +869,7 @@ export const addCustomization = (
859
869
inventoryChanges: IInventoryChanges = {}
860
870
): IInventoryChanges => {
861
871
const flavourItemIndex = inventory.FlavourItems.push({ ItemType: customizationName }) - 1;
872
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
862
873
inventoryChanges.FlavourItems ??= [];
863
874
(inventoryChanges.FlavourItems as IFlavourItem[]).push(
864
875
inventory.FlavourItems[flavourItemIndex].toJSON<IFlavourItem>()
@@ -872,6 +883,7 @@ export const addSkin = (
872
883
inventoryChanges: IInventoryChanges = {}
873
884
): IInventoryChanges => {
874
885
const index = inventory.WeaponSkins.push({ ItemType: typeName }) - 1;
886
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
875
887
inventoryChanges.WeaponSkins ??= [];
876
888
(inventoryChanges.WeaponSkins as IWeaponSkinClient[]).push(
877
889
inventory.WeaponSkins[index].toJSON<IWeaponSkinClient>()
@@ -879,12 +891,27 @@ export const addSkin = (
879
891
return inventoryChanges;
880
892
};
881
893
894
const addCrewShipWeapon = (
895
inventory: TInventoryDatabaseDocument,
896
typeName: string,
897
inventoryChanges: IInventoryChanges = {}
898
): IInventoryChanges => {
899
const index = inventory.CrewShipWeapons.push({ ItemType: typeName, _id: new Types.ObjectId() }) - 1;
900
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
901
inventoryChanges.CrewShipWeapons ??= [];
902
(inventoryChanges.CrewShipWeapons as ICrewShipWeaponClient[]).push(
903
inventory.CrewShipWeapons[index].toJSON<ICrewShipWeaponClient>()
904
);
905
return inventoryChanges;
906
};
907
882
908
const addCrewShipWeaponSkin = (
883
909
inventory: TInventoryDatabaseDocument,
884
910
typeName: string,
885
911
inventoryChanges: IInventoryChanges = {}
886
912
): IInventoryChanges => {
887
913
const index = inventory.CrewShipWeaponSkins.push({ ItemType: typeName }) - 1;
914
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
888
915
inventoryChanges.CrewShipWeaponSkins ??= [];
889
916
(inventoryChanges.CrewShipWeaponSkins as IUpgradeClient[]).push(
890
917
inventory.CrewShipWeaponSkins[index].toJSON<IUpgradeClient>()
@@ -31,6 +31,7 @@ export interface IInventoryDatabase
31
31
| "WeaponSkins"
32
32
| "Upgrades"
33
33
| "CrewShipSalvagedWeaponSkins"
34
| "CrewShipWeapons"
34
35
| "CrewShipWeaponSkins"
35
36
| "AdultOperatorLoadOuts"
36
37
| "OperatorLoadOuts"
@@ -56,6 +57,7 @@ export interface IInventoryDatabase
56
57
WeaponSkins: IWeaponSkinDatabase[];
57
58
Upgrades: IUpgradeDatabase[];
58
59
CrewShipSalvagedWeaponSkins: IUpgradeDatabase[];
60
CrewShipWeapons: ICrewShipWeaponDatabase[];
59
61
CrewShipWeaponSkins: IUpgradeDatabase[];
60
62
AdultOperatorLoadOuts: IOperatorConfigDatabase[];
61
63
OperatorLoadOuts: IOperatorConfigDatabase[];
@@ -289,8 +291,8 @@ export interface IInventoryClient extends IDailyAffiliations, InventoryClientEqu
289
291
PlayerSkills: IPlayerSkills;
290
292
CrewShipAmmo: IConsumable[];
291
293
CrewShipSalvagedWeaponSkins: IUpgradeClient[];
292
CrewShipWeapons: ICrewShipWeapon[];
293
CrewShipSalvagedWeapons: ICrewShipWeapon[];
294
CrewShipWeapons: ICrewShipWeaponClient[];
295
CrewShipSalvagedWeapons: IEquipmentClient[];
294
296
CrewShipWeaponSkins: IUpgradeClient[];
295
297
TradeBannedUntil?: IMongoDate;
296
298
PlayedParkourTutorial: boolean;
@@ -428,7 +430,8 @@ export enum InventorySlot {
428
430
SPACESUITS = "SpaceSuitBin",
429
431
MECHSUITS = "MechBin",
430
432
PVE_LOADOUTS = "PveBonusLoadoutBin",
431
SENTINELS = "SentinelBin"
433
SENTINELS = "SentinelBin",
434
RJ_COMPONENT_AND_ARMAMENTS = "CrewShipSalvageBin"
432
435
}
433
436
434
437
export interface ISlots {
@@ -489,11 +492,23 @@ export interface IFlavourItem {
489
492
490
493
export type IMiscItem = ITypeCount;
491
494
495
// inventory.CrewShips[0].Weapon
492
496
export interface ICrewShipWeapon {
493
497
PILOT: ICrewShipPilotWeapon;
494
498
PORT_GUNS: ICrewShipPortGuns;
495
499
}
496
500
501
// inventory.CrewShipWeapons
502
export interface ICrewShipWeaponClient {
503
ItemType: string;
504
ItemId: IOid;
505
}
506
507
export interface ICrewShipWeaponDatabase {
508
ItemType: string;
509
_id: Types.ObjectId;
510
}
511
497
512
export interface ICrewShipPilotWeapon {
498
513
PRIMARY_A: IEquipmentSelection;
499
514
SECONDARY_A: IEquipmentSelection;