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

SpaceNinjaServer

A simple server for a small space ninja game

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

XFEstudio/SpaceNinjaServer

feat: calendar progress (#1830)

Closes #1775 Reviewed-on: https://onlyg.it/OpenWF/SpaceNinjaServer/pulls/1830 Co-authored-by: Sainan <63328889+Sainan@users.noreply.github.com> Co-committed-by: Sainan <63328889+Sainan@users.noreply.github.com>

fd7f4c9e
Sainan <63328889+Sainan@users.noreply.github.com>
提交于

代码差异

9 个文件 +104 -29
Added src/controllers/api/completeCalendarEventController.ts +41 -0
@@ -0,0 +1,41 @@
1 import { getCalendarProgress, getInventory } from "@/src/services/inventoryService";
2 import { getAccountIdForRequest } from "@/src/services/loginService";
3 import { handleStoreItemAcquisition } from "@/src/services/purchaseService";
4 import { getWorldState } from "@/src/services/worldStateService";
5 import { IInventoryChanges } from "@/src/types/purchaseTypes";
6 import { RequestHandler } from "express";
7
8 // GET request; query parameters: CompletedEventIdx=0&Iteration=4&Version=19&Season=CST_SUMMER
9 export const completeCalendarEventController: RequestHandler = async (req, res) => {
10 const accountId = await getAccountIdForRequest(req);
11 const inventory = await getInventory(accountId);
12 const calendarProgress = getCalendarProgress(inventory);
13 const currentSeason = getWorldState().KnownCalendarSeasons[0];
14 let inventoryChanges: IInventoryChanges = {};
15 let dayIndex = 0;
16 for (const day of currentSeason.Days) {
17 if (day.events.length == 0 || day.events[0].type != "CET_CHALLENGE") {
18 if (dayIndex == calendarProgress.SeasonProgress.LastCompletedDayIdx) {
19 if (day.events.length != 0) {
20 const selection = day.events[parseInt(req.query.CompletedEventIdx as string)];
21 if (selection.type == "CET_REWARD") {
22 inventoryChanges = (await handleStoreItemAcquisition(selection.reward!, inventory))
23 .InventoryChanges;
24 } else if (selection.type == "CET_UPGRADE") {
25 calendarProgress.YearProgress.Upgrades.push(selection.upgrade!);
26 } else if (selection.type != "CET_PLOT") {
27 throw new Error(`unexpected selection type: ${selection.type}`);
28 }
29 }
30 break;
31 }
32 ++dayIndex;
33 }
34 }
35 calendarProgress.SeasonProgress.LastCompletedDayIdx++;
36 await inventory.save();
37 res.json({
38 InventoryChanges: inventoryChanges,
39 CalendarProgress: inventory.CalendarProgress
40 });
41 };
Modified src/models/inventoryModels/inventoryModel.ts +6 -6
@@ -1125,15 +1125,15 @@ const CustomMarkersSchema = new Schema<ICustomMarkers>(
1125 1125 const calenderProgressSchema = new Schema<ICalendarProgress>(
1126 1126 {
1127 1127 Version: { type: Number, default: 19 },
1128 Iteration: { type: Number, default: 2 },
1128 Iteration: { type: Number, required: true },
1129 1129 YearProgress: {
1130 Upgrades: { type: [] }
1130 Upgrades: { type: [String], default: [] }
1131 1131 },
1132 1132 SeasonProgress: {
1133 SeasonType: String,
1134 LastCompletedDayIdx: { type: Number, default: -1 },
1135 LastCompletedChallengeDayIdx: { type: Number, default: -1 },
1136 ActivatedChallenges: []
1133 SeasonType: { type: String, required: true },
1134 LastCompletedDayIdx: { type: Number, default: 0 },
1135 LastCompletedChallengeDayIdx: { type: Number, default: 0 },
1136 ActivatedChallenges: { type: [String], default: [] }
1137 1137 }
1138 1138 },
1139 1139 { _id: false }
Modified src/routes/api.ts +2 -0
@@ -19,6 +19,7 @@ import { claimCompletedRecipeController } from "@/src/controllers/api/claimCompl
19 19 import { claimLibraryDailyTaskRewardController } from "@/src/controllers/api/claimLibraryDailyTaskRewardController";
20 20 import { clearDialogueHistoryController } from "@/src/controllers/api/clearDialogueHistoryController";
21 21 import { clearNewEpisodeRewardController } from "@/src/controllers/api/clearNewEpisodeRewardController";
22 import { completeCalendarEventController } from "@/src/controllers/api/completeCalendarEventController";
22 23 import { completeRandomModChallengeController } from "@/src/controllers/api/completeRandomModChallengeController";
23 24 import { confirmAllianceInvitationController } from "@/src/controllers/api/confirmAllianceInvitationController";
24 25 import { confirmGuildInvitationGetController, confirmGuildInvitationPostController } from "@/src/controllers/api/confirmGuildInvitationController";
@@ -158,6 +159,7 @@ apiRouter.get("/changeDojoRoot.php", changeDojoRootController);
158 159 apiRouter.get("/changeGuildRank.php", changeGuildRankController);
159 160 apiRouter.get("/checkDailyMissionBonus.php", checkDailyMissionBonusController);
160 161 apiRouter.get("/claimLibraryDailyTaskReward.php", claimLibraryDailyTaskRewardController);
162 apiRouter.get("/completeCalendarEvent.php", completeCalendarEventController);
161 163 apiRouter.get("/confirmAllianceInvitation.php", confirmAllianceInvitationController);
162 164 apiRouter.get("/confirmGuildInvitation.php", confirmGuildInvitationGetController);
163 165 apiRouter.get("/credits.php", creditsController);
Modified src/services/inventoryService.ts +37 -17
@@ -18,7 +18,6 @@ import {
18 18 IKubrowPetEggDatabase,
19 19 IKubrowPetEggClient,
20 20 ILibraryDailyTaskInfo,
21 ICalendarProgress,
22 21 IDroneClient,
23 22 IUpgradeClient,
24 23 TPartialStartingGear,
@@ -26,7 +25,8 @@ import {
26 25 ICrewMemberClient,
27 26 Status,
28 27 IKubrowPetDetailsDatabase,
29 ITraits
28 ITraits,
29 ICalendarProgress
30 30 } from "@/src/types/inventoryTypes/inventoryTypes";
31 31 import { IGenericUpdate, IUpdateNodeIntrosResponse } from "../types/genericUpdate";
32 32 import { IKeyChainRequest, IMissionInventoryUpdateRequest } from "../types/requestTypes";
@@ -78,6 +78,7 @@ import libraryDailyTasks from "@/static/fixed_responses/libraryDailyTasks.json";
78 78 import { getRandomElement, getRandomInt, getRandomWeightedReward, SRng } from "./rngService";
79 79 import { createMessage } from "./inboxService";
80 80 import { getMaxStanding } from "@/src/helpers/syndicateStandingHelper";
81 import { getWorldState } from "./worldStateService";
81 82
82 83 export const createInventory = async (
83 84 accountOwnerId: Types.ObjectId,
@@ -91,7 +92,6 @@ export const createInventory = async (
91 92 });
92 93
93 94 inventory.LibraryAvailableDailyTaskInfo = createLibraryDailyTask();
94 inventory.CalendarProgress = createCalendar();
95 95 inventory.RewardSeed = generateRewardSeed();
96 96 inventory.DuviriInfo = {
97 97 Seed: generateRewardSeed(),
@@ -1756,20 +1756,6 @@ export const createLibraryDailyTask = (): ILibraryDailyTaskInfo => {
1756 1756 };
1757 1757 };
1758 1758
1759 const createCalendar = (): ICalendarProgress => {
1760 return {
1761 Version: 19,
1762 Iteration: 2,
1763 YearProgress: { Upgrades: [] },
1764 SeasonProgress: {
1765 SeasonType: "CST_SPRING",
1766 LastCompletedDayIdx: -1,
1767 LastCompletedChallengeDayIdx: -1,
1768 ActivatedChallenges: []
1769 }
1770 };
1771 };
1772
1773 1759 export const setupKahlSyndicate = (inventory: TInventoryDatabaseDocument): void => {
1774 1760 inventory.Affiliations.push({
1775 1761 Title: 1,
@@ -1806,3 +1792,37 @@ export const cleanupInventory = (inventory: TInventoryDatabaseDocument): void =>
1806 1792 LibrarySyndicate.FreeFavorsEarned = undefined;
1807 1793 }
1808 1794 };
1795
1796 export const getCalendarProgress = (inventory: TInventoryDatabaseDocument): ICalendarProgress => {
1797 const currentSeason = getWorldState().KnownCalendarSeasons[0];
1798
1799 if (!inventory.CalendarProgress) {
1800 inventory.CalendarProgress = {
1801 Version: 19,
1802 Iteration: currentSeason.YearIteration,
1803 YearProgress: {
1804 Upgrades: []
1805 },
1806 SeasonProgress: {
1807 SeasonType: currentSeason.Season,
1808 LastCompletedDayIdx: 0,
1809 LastCompletedChallengeDayIdx: 0,
1810 ActivatedChallenges: []
1811 }
1812 };
1813 }
1814
1815 const yearRolledOver = inventory.CalendarProgress.Iteration != currentSeason.YearIteration;
1816 if (yearRolledOver) {
1817 inventory.CalendarProgress.Iteration = currentSeason.YearIteration;
1818 inventory.CalendarProgress.YearProgress.Upgrades = [];
1819 }
1820 if (yearRolledOver || inventory.CalendarProgress.SeasonProgress.SeasonType != currentSeason.Season) {
1821 inventory.CalendarProgress.SeasonProgress.SeasonType = currentSeason.Season;
1822 inventory.CalendarProgress.SeasonProgress.LastCompletedDayIdx = -1;
1823 inventory.CalendarProgress.SeasonProgress.LastCompletedChallengeDayIdx = -1;
1824 inventory.CalendarProgress.SeasonProgress.ActivatedChallenges = [];
1825 }
1826
1827 return inventory.CalendarProgress;
1828 };
Modified src/services/missionInventoryUpdateService.ts +10 -0
@@ -33,6 +33,7 @@ import {
33 33 addStanding,
34 34 combineInventoryChanges,
35 35 generateRewardSeed,
36 getCalendarProgress,
36 37 updateCurrency,
37 38 updateSyndicate
38 39 } from "@/src/services/inventoryService";
@@ -560,6 +561,15 @@ export const addMissionInventoryUpdates = async (
560 561 }
561 562 break;
562 563 }
564 case "CalendarProgress": {
565 const calendarProgress = getCalendarProgress(inventory);
566 for (const progress of value) {
567 const challengeName = progress.challenge.substring(progress.challenge.lastIndexOf("/") + 1);
568 calendarProgress.SeasonProgress.LastCompletedChallengeDayIdx++;
569 calendarProgress.SeasonProgress.ActivatedChallenges.push(challengeName);
570 }
571 break;
572 }
563 573 default:
564 574 // Equipment XP updates
565 575 if (equipmentKeys.includes(key as TEquipmentKey)) {
Modified src/services/worldStateService.ts +1 -1
@@ -683,7 +683,7 @@ const getCalendarSeason = (week: number): ICalendarSeason => {
683 683 Activation: { $date: { $numberLong: weekStart.toString() } },
684 684 Expiry: { $date: { $numberLong: weekEnd.toString() } },
685 685 Days: eventDays,
686 Season: ["CST_WINTER", "CST_SPRING", "CST_SUMMER", "CST_FALL"][seasonIndex],
686 Season: (["CST_WINTER", "CST_SPRING", "CST_SUMMER", "CST_FALL"] as const)[seasonIndex],
687 687 YearIteration: Math.trunc(week / 4),
688 688 Version: 19,
689 689 UpgradeAvaliabilityRequirements: ["/Lotus/Upgrades/Calendar/1999UpgradeApplicationRequirement"]
Modified src/types/inventoryTypes/inventoryTypes.ts +5 -4
@@ -353,7 +353,7 @@ export interface IInventoryClient extends IDailyAffiliations, InventoryClientEqu
353 353 DeathSquadable: boolean;
354 354 EndlessXP?: IEndlessXpProgress[];
355 355 DialogueHistory?: IDialogueHistoryClient;
356 CalendarProgress: ICalendarProgress;
356 CalendarProgress?: ICalendarProgress;
357 357 SongChallenges?: ISongChallenge[];
358 358 EntratiVaultCountLastPeriod?: number;
359 359 EntratiVaultCountResetDate?: IMongoDate;
@@ -1193,17 +1193,18 @@ export interface IMarker {
1193 1193 z: number;
1194 1194 showInHud: boolean;
1195 1195 }
1196
1196 1197 export interface ISeasonProgress {
1197 SeasonType: "CST_UNDEFINED" | "CST_WINTER" | "CST_SPRING" | "CST_SUMMER" | "CST_FALL";
1198 SeasonType: "CST_WINTER" | "CST_SPRING" | "CST_SUMMER" | "CST_FALL";
1198 1199 LastCompletedDayIdx: number;
1199 1200 LastCompletedChallengeDayIdx: number;
1200 ActivatedChallenges: unknown[];
1201 ActivatedChallenges: string[];
1201 1202 }
1202 1203
1203 1204 export interface ICalendarProgress {
1204 1205 Version: number;
1205 1206 Iteration: number;
1206 YearProgress: { Upgrades: unknown[] };
1207 YearProgress: { Upgrades: string[] };
1207 1208 SeasonProgress: ISeasonProgress;
1208 1209 }
1209 1210
Modified src/types/requestTypes.ts +1 -0
@@ -44,6 +44,7 @@ export type IMissionInventoryUpdateRequest = {
44 44
45 45 SyndicateId?: string;
46 46 SortieId?: string;
47 CalendarProgress?: { challenge: string }[];
47 48 SeasonChallengeCompletions?: ISeasonChallenge[];
48 49 AffiliationChanges?: IAffiliationChange[];
49 50 crossPlaySetting?: string;
Modified src/types/worldStateTypes.ts +1 -1
@@ -133,7 +133,7 @@ export interface ISeasonChallenge {
133 133 export interface ICalendarSeason {
134 134 Activation: IMongoDate;
135 135 Expiry: IMongoDate;
136 Season: string; // "CST_UNDEFINED" | "CST_WINTER" | "CST_SPRING" | "CST_SUMMER" | "CST_FALL"
136 Season: "CST_WINTER" | "CST_SPRING" | "CST_SUMMER" | "CST_FALL";
137 137 Days: ICalendarDay[];
138 138 YearIteration: number;
139 139 Version: number;