XFE Git
XFE Studio Git
Git 首页 全局搜索
XFE 主站 文档 NuGet

XFESpaceNinjaServer

A simple server for a small space ninja game

公开
关注 0 Fork 0 Star 0
返回提交历史

XFEstudio/XFESpaceNinjaServer

feat: syndicates (#269)

Co-authored-by: janisslsm <janisslsm@users.noreply.github.com>

2a1a4e77
Jānis <97699850+janisslsm@users.noreply.github.com>
提交于

代码差异

7 个文件 +141 -12
Added src/controllers/api/syndicateSacrificeController.ts +25 -0
@@ -0,0 +1,25 @@
1 import { getJSONfromString } from "@/src/helpers/stringHelpers";
2 import { syndicateSacrifice } from "@/src/services/inventoryService";
3 import { ISyndicateSacrifice } from "@/src/types/syndicateTypes";
4 import { RequestHandler } from "express";
5 import { getAccountIdForRequest } from "@/src/services/loginService";
6 // eslint-disable-next-line @typescript-eslint/no-misused-promises
7 const syndicateSacrificeController: RequestHandler = async (request, response) => {
8 const accountId = await getAccountIdForRequest(request);
9 const body = getJSONfromString(request.body);
10 let reply = {};
11 try {
12 const update = JSON.parse(body) as ISyndicateSacrifice;
13 if (typeof update !== "object") {
14 throw new Error("Invalid data format");
15 }
16
17 reply = await syndicateSacrifice(update, accountId);
18 } catch (err) {
19 console.error("Error parsing JSON data:", err);
20 }
21
22 response.json(reply);
23 };
24
25 export { syndicateSacrificeController };
Modified src/controllers/api/updateChallengeProgressController.ts +6 -10
@@ -1,19 +1,15 @@
1 1 import { RequestHandler } from "express";
2 import { IChallengeProgress } from "@/src/types/inventoryTypes/inventoryTypes";
3 2 import { getJSONfromString } from "@/src/helpers/stringHelpers";
4 3 import { getAccountIdForRequest } from "@/src/services/loginService";
5 import { getInventory, addChallenges } from "@/src/services/inventoryService";
6
7 interface IUpdateChallengeProgessRequest {
8 ChallengeProgress: IChallengeProgress[];
9 }
4 import { updateChallengeProgress } from "@/src/services/inventoryService";
5 import { IUpdateChallengeProgressRequest } from "@/src/types/requestTypes";
10 6
11 7 const updateChallengeProgressController: RequestHandler = async (req, res) => {
12 const payload: IUpdateChallengeProgessRequest = getJSONfromString(req.body.toString());
8 const payload: IUpdateChallengeProgressRequest = getJSONfromString(req.body.toString());
13 9 const accountId = await getAccountIdForRequest(req);
14 const inventory = await getInventory(accountId);
15 addChallenges(inventory, payload.ChallengeProgress);
16 await inventory.save();
10
11 await updateChallengeProgress(payload, accountId);
12
17 13 res.status(200).end();
18 14 };
19 15
Modified src/routes/api.ts +2 -0
@@ -52,6 +52,7 @@ import { getGuildLogController } from "../controllers/api/getGuildLogController"
52 52 import { guildTechController } from "../controllers/api/guildTechController";
53 53 import { dojoController } from "@/src/controllers/api/dojoController";
54 54 import { getGuildDojoController } from "@/src/controllers/api/getGuildDojoController";
55 import { syndicateSacrificeController } from "../controllers/api/syndicateSacrificeController";
55 56
56 57 const apiRouter = express.Router();
57 58
@@ -114,5 +115,6 @@ apiRouter.post("/createGuild.php", createGuildController);
114 115 apiRouter.post("/sell.php", sellController);
115 116 apiRouter.post("/upgrades.php", upgradesController);
116 117 apiRouter.post("/guildTech.php", guildTechController);
118 apiRouter.post("/syndicateSacrifice.php", syndicateSacrificeController);
117 119
118 120 export { apiRouter };
Modified src/services/inventoryService.ts +74 -1
@@ -13,12 +13,19 @@ import {
13 13 IMiscItem,
14 14 IMission,
15 15 IRawUpgrade,
16 ISeasonChallengeHistory,
16 17 ITypeCount
17 18 } from "@/src/types/inventoryTypes/inventoryTypes";
18 19 import { IGenericUpdate } from "../types/genericUpdate";
19 import { IArtifactsRequest, IMissionInventoryUpdateRequest, IThemeUpdateRequest } from "../types/requestTypes";
20 import {
21 IArtifactsRequest,
22 IMissionInventoryUpdateRequest,
23 IThemeUpdateRequest,
24 IUpdateChallengeProgressRequest
25 } from "../types/requestTypes";
20 26 import { logger } from "@/src/utils/logger";
21 27 import { WeaponTypeInternal } from "@/src/services/itemDataService";
28 import { ISyndicateSacrifice, ISyndicateSacrificeResponse } from "../types/syndicateTypes";
22 29
23 30 export const createInventory = async (
24 31 accountOwnerId: Types.ObjectId,
@@ -164,6 +171,28 @@ export const updateTheme = async (data: IThemeUpdateRequest, accountId: string)
164 171 await inventory.save();
165 172 };
166 173
174 export const syndicateSacrifice = async (
175 data: ISyndicateSacrifice,
176 accountId: string
177 ): Promise<ISyndicateSacrificeResponse> => {
178 const inventory = await getInventory(accountId);
179 const syndicate = inventory.Affiliations.find(x => x.Tag == data.AffiliationTag);
180 const level = data.SacrificeLevel - (syndicate?.Title ?? 0);
181 const res: ISyndicateSacrificeResponse = {
182 AffiliationTag: data.AffiliationTag,
183 InventoryChanges: [],
184 Level: data.SacrificeLevel,
185 LevelIncrease: level <= 0 ? 1 : level,
186 NewEpisodeReward: syndicate?.Tag == "RadioLegionIntermission9Syndicate"
187 };
188
189 if (syndicate?.Title !== undefined) syndicate.Title += 1;
190
191 await inventory.save();
192
193 return res;
194 };
195
167 196 export const addWeapon = async (
168 197 weaponType: WeaponTypeInternal,
169 198 weaponName: string,
@@ -290,6 +319,32 @@ export const addMods = (inventory: IInventoryDatabaseDocument, itemsArray: IRawU
290 319 });
291 320 };
292 321
322 export const updateChallengeProgress = async (challenges: IUpdateChallengeProgressRequest, accountId: string) => {
323 const inventory = await getInventory(accountId);
324
325 addChallenges(inventory, challenges.ChallengeProgress);
326 addSeasonalChallengeHistory(inventory, challenges.SeasonChallengeHistory);
327
328 await inventory.save();
329 };
330
331 export const addSeasonalChallengeHistory = (
332 inventory: IInventoryDatabaseDocument,
333 itemsArray: ISeasonChallengeHistory[] | undefined
334 ) => {
335 const category = inventory.SeasonChallengeHistory;
336
337 itemsArray?.forEach(({ challenge, id }) => {
338 const itemIndex = category.findIndex(i => i.challenge === challenge);
339
340 if (itemIndex !== -1) {
341 category[itemIndex].id = id;
342 } else {
343 category.push({ challenge, id });
344 }
345 });
346 };
347
293 348 export const addChallenges = (inventory: IInventoryDatabaseDocument, itemsArray: IChallengeProgress[] | undefined) => {
294 349 const category = inventory.ChallengeProgress;
295 350
@@ -330,6 +385,24 @@ export const missionInventoryUpdate = async (data: IMissionInventoryUpdateReques
330 385 // endo
331 386 inventory.FusionPoints += FusionPoints || 0;
332 387
388 // syndicate
389 data.AffiliationChanges?.forEach(affiliation => {
390 const syndicate = inventory.Affiliations.find(x => x.Tag == affiliation.Tag);
391 if (syndicate !== undefined) {
392 syndicate.Standing =
393 syndicate.Standing === undefined ? affiliation.Standing : syndicate.Standing + affiliation.Standing;
394 syndicate.Title = syndicate.Title === undefined ? affiliation.Title : syndicate.Title + affiliation.Title;
395 } else {
396 inventory.Affiliations.push({
397 Standing: affiliation.Standing,
398 Title: affiliation.Title,
399 Tag: affiliation.Tag,
400 FreeFavorsEarned: [],
401 FreeFavorsUsed: []
402 });
403 }
404 });
405
333 406 // Gear XP
334 407 gearKeys.forEach(key => addGearExpByCategory(inventory, data[key], key));
335 408
Modified src/types/inventoryTypes/inventoryTypes.ts +5 -0
@@ -1028,6 +1028,11 @@ export interface ISeasonChallengeHistory {
1028 1028 id: string;
1029 1029 }
1030 1030
1031 export interface ISeasonChallengeCompletions {
1032 challenge: string;
1033 id: string;
1034 }
1035
1031 1036 export interface ISentientSpawnChanceBoosters {
1032 1037 numOceanMissionsCompleted: number;
1033 1038 }
Modified src/types/requestTypes.ts +16 -1
@@ -7,7 +7,9 @@ import {
7 7 ICrewShipSalvagedWeaponSkin,
8 8 IMiscItem,
9 9 IMission,
10 IRawUpgrade
10 IRawUpgrade,
11 ISeasonChallengeCompletions,
12 ISeasonChallengeHistory
11 13 } from "./inventoryTypes/inventoryTypes";
12 14 import { IWeaponClient } from "./inventoryTypes/weaponTypes";
13 15 import { ISuitClient } from "./inventoryTypes/SuitTypes";
@@ -25,9 +27,22 @@ export interface IThemeUpdateRequest {
25 27 Sounds?: string;
26 28 }
27 29
30 export interface IAffiliationChange {
31 Tag: string;
32 Standing: number;
33 Title: number;
34 }
35
36 export interface IUpdateChallengeProgressRequest {
37 ChallengeProgress: IChallengeProgress[];
38 SeasonChallengeHistory: ISeasonChallengeHistory[];
39 SeasonChallengeCompletions: ISeasonChallengeCompletions[];
40 }
41
28 42 export interface IMissionInventoryUpdateRequest {
29 43 rewardsMultiplier?: number;
30 44 ActiveBoosters?: IBooster[];
45 AffiliationChanges?: IAffiliationChange[];
31 46 LongGuns?: IWeaponClient[];
32 47 Pistols?: IWeaponClient[];
33 48 Suits?: ISuitClient[];
Added src/types/syndicateTypes.ts +13 -0
@@ -0,0 +1,13 @@
1 export interface ISyndicateSacrifice {
2 AffiliationTag: string;
3 SacrificeLevel: number;
4 AllowMultiple: boolean;
5 }
6
7 export interface ISyndicateSacrificeResponse {
8 AffiliationTag: string;
9 Level: number;
10 LevelIncrease: number;
11 InventoryChanges: any[];
12 NewEpisodeReward: boolean;
13 }