返回提交历史
Modified
src/controllers/api/guildTechController.ts
+17
-10
Modified
src/services/guildService.ts
+9
-5
XFEstudio/XFESpaceNinjaServer
feat: U8 clan research (#3712)
Closes #3570 Reviewed-on: https://onlyg.it/OpenWF/SpaceNinjaServer/pulls/3712 Co-authored-by: Sainan <63328889+Sainan@users.noreply.github.com> Co-committed-by: Sainan <63328889+Sainan@users.noreply.github.com>
fd873949
代码差异
2 个文件
+26
-15
@@ -40,6 +40,7 @@ export const guildTechController: RequestHandler = async (req, res) => {
40
40
const accountId = account._id.toString();
41
41
const inventory = await getInventory(accountId);
42
42
const data = JSON.parse(String(req.body)) as TGuildTechRequest;
43
//logger.debug(`guildTech:`, data);
43
44
if (data.Action == "Sync") {
44
45
let needSave = false;
45
46
const techProjects: ITechProjectClient[] = [];
@@ -76,7 +77,9 @@ export const guildTechController: RequestHandler = async (req, res) => {
76
77
res.status(400).send("-1").end();
77
78
return;
78
79
}
79
const recipeType: string = (data.RecipeType || data.ResearchId)!;
80
const recipeType: string = (data.RecipeType ??
81
data.ResearchId ??
82
(req.query.researchId as string | undefined))!;
80
83
const recipe = ExportDojoRecipes.research[recipeType];
81
84
guild.TechProjects ??= [];
82
85
if (!guild.TechProjects.find(x => x.ItemType == recipeType)) {
@@ -137,8 +140,8 @@ export const guildTechController: RequestHandler = async (req, res) => {
137
140
});
138
141
}
139
142
} else if (data.Action == "Contribute") {
140
if ((req.query.guildId as string) == "000000000000000000000000") {
141
const techProject = inventory.PersonalTechProjects.id(data.ResearchId)!;
143
if ("guildId" in req.query && (req.query.guildId as string) == "000000000000000000000000") {
144
const techProject = inventory.PersonalTechProjects.id(data.ResearchId!)!;
142
145
143
146
techProject.ReqCredits -= data.RegularCredits;
144
147
const inventoryChanges: IInventoryChanges = updateCurrency(inventory, data.RegularCredits, false);
@@ -185,7 +188,9 @@ export const guildTechController: RequestHandler = async (req, res) => {
185
188
{ accountId, guildId: guild._id },
186
189
"RegularCreditsContributed MiscItemsContributed"
187
190
))!;
188
const recipeType = data.RecipeType || data.ResearchId;
191
const recipeType: string = (data.RecipeType ??
192
data.ResearchId ??
193
(req.query.researchId as string | undefined))!;
189
194
const techProject = guild.TechProjects!.find(x => x.ItemType == recipeType)!;
190
195
191
196
if (data.VaultCredits) {
@@ -204,7 +209,7 @@ export const guildTechController: RequestHandler = async (req, res) => {
204
209
guildMember.RegularCreditsContributed ??= 0;
205
210
guildMember.RegularCreditsContributed += data.RegularCredits;
206
211
207
if (data.VaultMiscItems.length) {
212
if (data.VaultMiscItems?.length) {
208
213
for (const miscItem of data.VaultMiscItems) {
209
214
const reqItem = techProject.ReqItems.find(x => x.ItemType == miscItem.ItemType);
210
215
if (reqItem) {
@@ -251,7 +256,9 @@ export const guildTechController: RequestHandler = async (req, res) => {
251
256
} else if (data.Action.split(",")[0] == "Buy") {
252
257
const purchase = data as IGuildTechBuyRequest;
253
258
if (purchase.Mode != "Personal") {
254
const recipeType: string = (purchase.RecipeType || purchase.ResearchId)!;
259
const recipeType: string = (purchase.RecipeType ??
260
purchase.ResearchId ??
261
(req.query.researchId as string | undefined))!;
255
262
const guild = await getGuildForRequestEx(req, inventory);
256
263
if (
257
264
!hasAccessToDojo(inventory) ||
@@ -398,7 +405,7 @@ type TGuildTechRequest =
398
405
399
406
interface IGuildTechBasicRequest {
400
407
Action: "Start" | "Fabricate" | "Pause" | "Unpause" | "Cancel" | "Rush" | "InstantFinish";
401
Mode: "Guild" | "Personal";
408
Mode?: "Guild" | "Personal";
402
409
ResearchId?: string; // U18.0.6 uses that instead RecipeType
403
410
RecipeType?: string;
404
411
TechProductCategory?: string;
@@ -411,12 +418,12 @@ interface IGuildTechBuyRequest extends Omit<IGuildTechBasicRequest, "Action"> {
411
418
412
419
interface IGuildTechContributeRequest {
413
420
Action: "Contribute";
414
ResearchId: string;
421
ResearchId?: string;
415
422
RecipeType?: string;
416
423
RegularCredits: number;
417
424
MiscItems: IMiscItem[];
418
VaultCredits: number;
419
VaultMiscItems: IMiscItem[];
425
VaultCredits?: number;
426
VaultMiscItems?: IMiscItem[];
420
427
}
421
428
422
429
const getSalvageCategory = (
@@ -50,13 +50,17 @@ export const getGuildForRequestEx = async (
50
50
req: Request,
51
51
inventory: TInventoryDatabaseDocument
52
52
): Promise<TGuildDatabaseDocument> => {
53
const guildId = req.query.guildId as string;
54
if (!inventory.GuildId || inventory.GuildId.toString() != guildId) {
55
throw new Error("Account is not in the guild that it has sent a request for");
53
// guildTech requests from U8 don't have the guildId query param
54
if ("guildId" in req.query) {
55
const guildId = req.query.guildId as string;
56
if (!inventory.GuildId || inventory.GuildId.toString() != guildId) {
57
throw new Error("Account is not in the guild that it has sent a request for");
58
}
56
59
}
57
const guild = await Guild.findById(guildId);
60
61
const guild = await Guild.findById(inventory.GuildId);
58
62
if (!guild) {
59
throw new Error("Account thinks it is in a guild that doesn't exist");
63
throw new Error("Account is in a guild that doesn't exist (anymore)");
60
64
}
61
65
return guild;
62
66
};