forked from OpenWF/SpaceNinjaServer
feat: calendar progress (#1830)
Closes #1775 Reviewed-on: OpenWF/SpaceNinjaServer#1830 Co-authored-by: Sainan <63328889+Sainan@users.noreply.github.com> Co-committed-by: Sainan <63328889+Sainan@users.noreply.github.com>
This commit is contained in:
parent
fa6fac494b
commit
fd7f4c9e92
41
src/controllers/api/completeCalendarEventController.ts
Normal file
41
src/controllers/api/completeCalendarEventController.ts
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
import { getCalendarProgress, getInventory } from "@/src/services/inventoryService";
|
||||||
|
import { getAccountIdForRequest } from "@/src/services/loginService";
|
||||||
|
import { handleStoreItemAcquisition } from "@/src/services/purchaseService";
|
||||||
|
import { getWorldState } from "@/src/services/worldStateService";
|
||||||
|
import { IInventoryChanges } from "@/src/types/purchaseTypes";
|
||||||
|
import { RequestHandler } from "express";
|
||||||
|
|
||||||
|
// GET request; query parameters: CompletedEventIdx=0&Iteration=4&Version=19&Season=CST_SUMMER
|
||||||
|
export const completeCalendarEventController: RequestHandler = async (req, res) => {
|
||||||
|
const accountId = await getAccountIdForRequest(req);
|
||||||
|
const inventory = await getInventory(accountId);
|
||||||
|
const calendarProgress = getCalendarProgress(inventory);
|
||||||
|
const currentSeason = getWorldState().KnownCalendarSeasons[0];
|
||||||
|
let inventoryChanges: IInventoryChanges = {};
|
||||||
|
let dayIndex = 0;
|
||||||
|
for (const day of currentSeason.Days) {
|
||||||
|
if (day.events.length == 0 || day.events[0].type != "CET_CHALLENGE") {
|
||||||
|
if (dayIndex == calendarProgress.SeasonProgress.LastCompletedDayIdx) {
|
||||||
|
if (day.events.length != 0) {
|
||||||
|
const selection = day.events[parseInt(req.query.CompletedEventIdx as string)];
|
||||||
|
if (selection.type == "CET_REWARD") {
|
||||||
|
inventoryChanges = (await handleStoreItemAcquisition(selection.reward!, inventory))
|
||||||
|
.InventoryChanges;
|
||||||
|
} else if (selection.type == "CET_UPGRADE") {
|
||||||
|
calendarProgress.YearProgress.Upgrades.push(selection.upgrade!);
|
||||||
|
} else if (selection.type != "CET_PLOT") {
|
||||||
|
throw new Error(`unexpected selection type: ${selection.type}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
++dayIndex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
calendarProgress.SeasonProgress.LastCompletedDayIdx++;
|
||||||
|
await inventory.save();
|
||||||
|
res.json({
|
||||||
|
InventoryChanges: inventoryChanges,
|
||||||
|
CalendarProgress: inventory.CalendarProgress
|
||||||
|
});
|
||||||
|
};
|
@ -1125,15 +1125,15 @@ const CustomMarkersSchema = new Schema<ICustomMarkers>(
|
|||||||
const calenderProgressSchema = new Schema<ICalendarProgress>(
|
const calenderProgressSchema = new Schema<ICalendarProgress>(
|
||||||
{
|
{
|
||||||
Version: { type: Number, default: 19 },
|
Version: { type: Number, default: 19 },
|
||||||
Iteration: { type: Number, default: 2 },
|
Iteration: { type: Number, required: true },
|
||||||
YearProgress: {
|
YearProgress: {
|
||||||
Upgrades: { type: [] }
|
Upgrades: { type: [String], default: [] }
|
||||||
},
|
},
|
||||||
SeasonProgress: {
|
SeasonProgress: {
|
||||||
SeasonType: String,
|
SeasonType: { type: String, required: true },
|
||||||
LastCompletedDayIdx: { type: Number, default: -1 },
|
LastCompletedDayIdx: { type: Number, default: 0 },
|
||||||
LastCompletedChallengeDayIdx: { type: Number, default: -1 },
|
LastCompletedChallengeDayIdx: { type: Number, default: 0 },
|
||||||
ActivatedChallenges: []
|
ActivatedChallenges: { type: [String], default: [] }
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{ _id: false }
|
{ _id: false }
|
||||||
|
@ -19,6 +19,7 @@ import { claimCompletedRecipeController } from "@/src/controllers/api/claimCompl
|
|||||||
import { claimLibraryDailyTaskRewardController } from "@/src/controllers/api/claimLibraryDailyTaskRewardController";
|
import { claimLibraryDailyTaskRewardController } from "@/src/controllers/api/claimLibraryDailyTaskRewardController";
|
||||||
import { clearDialogueHistoryController } from "@/src/controllers/api/clearDialogueHistoryController";
|
import { clearDialogueHistoryController } from "@/src/controllers/api/clearDialogueHistoryController";
|
||||||
import { clearNewEpisodeRewardController } from "@/src/controllers/api/clearNewEpisodeRewardController";
|
import { clearNewEpisodeRewardController } from "@/src/controllers/api/clearNewEpisodeRewardController";
|
||||||
|
import { completeCalendarEventController } from "@/src/controllers/api/completeCalendarEventController";
|
||||||
import { completeRandomModChallengeController } from "@/src/controllers/api/completeRandomModChallengeController";
|
import { completeRandomModChallengeController } from "@/src/controllers/api/completeRandomModChallengeController";
|
||||||
import { confirmAllianceInvitationController } from "@/src/controllers/api/confirmAllianceInvitationController";
|
import { confirmAllianceInvitationController } from "@/src/controllers/api/confirmAllianceInvitationController";
|
||||||
import { confirmGuildInvitationGetController, confirmGuildInvitationPostController } from "@/src/controllers/api/confirmGuildInvitationController";
|
import { confirmGuildInvitationGetController, confirmGuildInvitationPostController } from "@/src/controllers/api/confirmGuildInvitationController";
|
||||||
@ -158,6 +159,7 @@ apiRouter.get("/changeDojoRoot.php", changeDojoRootController);
|
|||||||
apiRouter.get("/changeGuildRank.php", changeGuildRankController);
|
apiRouter.get("/changeGuildRank.php", changeGuildRankController);
|
||||||
apiRouter.get("/checkDailyMissionBonus.php", checkDailyMissionBonusController);
|
apiRouter.get("/checkDailyMissionBonus.php", checkDailyMissionBonusController);
|
||||||
apiRouter.get("/claimLibraryDailyTaskReward.php", claimLibraryDailyTaskRewardController);
|
apiRouter.get("/claimLibraryDailyTaskReward.php", claimLibraryDailyTaskRewardController);
|
||||||
|
apiRouter.get("/completeCalendarEvent.php", completeCalendarEventController);
|
||||||
apiRouter.get("/confirmAllianceInvitation.php", confirmAllianceInvitationController);
|
apiRouter.get("/confirmAllianceInvitation.php", confirmAllianceInvitationController);
|
||||||
apiRouter.get("/confirmGuildInvitation.php", confirmGuildInvitationGetController);
|
apiRouter.get("/confirmGuildInvitation.php", confirmGuildInvitationGetController);
|
||||||
apiRouter.get("/credits.php", creditsController);
|
apiRouter.get("/credits.php", creditsController);
|
||||||
|
@ -18,7 +18,6 @@ import {
|
|||||||
IKubrowPetEggDatabase,
|
IKubrowPetEggDatabase,
|
||||||
IKubrowPetEggClient,
|
IKubrowPetEggClient,
|
||||||
ILibraryDailyTaskInfo,
|
ILibraryDailyTaskInfo,
|
||||||
ICalendarProgress,
|
|
||||||
IDroneClient,
|
IDroneClient,
|
||||||
IUpgradeClient,
|
IUpgradeClient,
|
||||||
TPartialStartingGear,
|
TPartialStartingGear,
|
||||||
@ -26,7 +25,8 @@ import {
|
|||||||
ICrewMemberClient,
|
ICrewMemberClient,
|
||||||
Status,
|
Status,
|
||||||
IKubrowPetDetailsDatabase,
|
IKubrowPetDetailsDatabase,
|
||||||
ITraits
|
ITraits,
|
||||||
|
ICalendarProgress
|
||||||
} from "@/src/types/inventoryTypes/inventoryTypes";
|
} from "@/src/types/inventoryTypes/inventoryTypes";
|
||||||
import { IGenericUpdate, IUpdateNodeIntrosResponse } from "../types/genericUpdate";
|
import { IGenericUpdate, IUpdateNodeIntrosResponse } from "../types/genericUpdate";
|
||||||
import { IKeyChainRequest, IMissionInventoryUpdateRequest } from "../types/requestTypes";
|
import { IKeyChainRequest, IMissionInventoryUpdateRequest } from "../types/requestTypes";
|
||||||
@ -78,6 +78,7 @@ import libraryDailyTasks from "@/static/fixed_responses/libraryDailyTasks.json";
|
|||||||
import { getRandomElement, getRandomInt, getRandomWeightedReward, SRng } from "./rngService";
|
import { getRandomElement, getRandomInt, getRandomWeightedReward, SRng } from "./rngService";
|
||||||
import { createMessage } from "./inboxService";
|
import { createMessage } from "./inboxService";
|
||||||
import { getMaxStanding } from "@/src/helpers/syndicateStandingHelper";
|
import { getMaxStanding } from "@/src/helpers/syndicateStandingHelper";
|
||||||
|
import { getWorldState } from "./worldStateService";
|
||||||
|
|
||||||
export const createInventory = async (
|
export const createInventory = async (
|
||||||
accountOwnerId: Types.ObjectId,
|
accountOwnerId: Types.ObjectId,
|
||||||
@ -91,7 +92,6 @@ export const createInventory = async (
|
|||||||
});
|
});
|
||||||
|
|
||||||
inventory.LibraryAvailableDailyTaskInfo = createLibraryDailyTask();
|
inventory.LibraryAvailableDailyTaskInfo = createLibraryDailyTask();
|
||||||
inventory.CalendarProgress = createCalendar();
|
|
||||||
inventory.RewardSeed = generateRewardSeed();
|
inventory.RewardSeed = generateRewardSeed();
|
||||||
inventory.DuviriInfo = {
|
inventory.DuviriInfo = {
|
||||||
Seed: generateRewardSeed(),
|
Seed: generateRewardSeed(),
|
||||||
@ -1756,20 +1756,6 @@ export const createLibraryDailyTask = (): ILibraryDailyTaskInfo => {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const createCalendar = (): ICalendarProgress => {
|
|
||||||
return {
|
|
||||||
Version: 19,
|
|
||||||
Iteration: 2,
|
|
||||||
YearProgress: { Upgrades: [] },
|
|
||||||
SeasonProgress: {
|
|
||||||
SeasonType: "CST_SPRING",
|
|
||||||
LastCompletedDayIdx: -1,
|
|
||||||
LastCompletedChallengeDayIdx: -1,
|
|
||||||
ActivatedChallenges: []
|
|
||||||
}
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
export const setupKahlSyndicate = (inventory: TInventoryDatabaseDocument): void => {
|
export const setupKahlSyndicate = (inventory: TInventoryDatabaseDocument): void => {
|
||||||
inventory.Affiliations.push({
|
inventory.Affiliations.push({
|
||||||
Title: 1,
|
Title: 1,
|
||||||
@ -1806,3 +1792,37 @@ export const cleanupInventory = (inventory: TInventoryDatabaseDocument): void =>
|
|||||||
LibrarySyndicate.FreeFavorsEarned = undefined;
|
LibrarySyndicate.FreeFavorsEarned = undefined;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const getCalendarProgress = (inventory: TInventoryDatabaseDocument): ICalendarProgress => {
|
||||||
|
const currentSeason = getWorldState().KnownCalendarSeasons[0];
|
||||||
|
|
||||||
|
if (!inventory.CalendarProgress) {
|
||||||
|
inventory.CalendarProgress = {
|
||||||
|
Version: 19,
|
||||||
|
Iteration: currentSeason.YearIteration,
|
||||||
|
YearProgress: {
|
||||||
|
Upgrades: []
|
||||||
|
},
|
||||||
|
SeasonProgress: {
|
||||||
|
SeasonType: currentSeason.Season,
|
||||||
|
LastCompletedDayIdx: 0,
|
||||||
|
LastCompletedChallengeDayIdx: 0,
|
||||||
|
ActivatedChallenges: []
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const yearRolledOver = inventory.CalendarProgress.Iteration != currentSeason.YearIteration;
|
||||||
|
if (yearRolledOver) {
|
||||||
|
inventory.CalendarProgress.Iteration = currentSeason.YearIteration;
|
||||||
|
inventory.CalendarProgress.YearProgress.Upgrades = [];
|
||||||
|
}
|
||||||
|
if (yearRolledOver || inventory.CalendarProgress.SeasonProgress.SeasonType != currentSeason.Season) {
|
||||||
|
inventory.CalendarProgress.SeasonProgress.SeasonType = currentSeason.Season;
|
||||||
|
inventory.CalendarProgress.SeasonProgress.LastCompletedDayIdx = -1;
|
||||||
|
inventory.CalendarProgress.SeasonProgress.LastCompletedChallengeDayIdx = -1;
|
||||||
|
inventory.CalendarProgress.SeasonProgress.ActivatedChallenges = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
return inventory.CalendarProgress;
|
||||||
|
};
|
||||||
|
@ -33,6 +33,7 @@ import {
|
|||||||
addStanding,
|
addStanding,
|
||||||
combineInventoryChanges,
|
combineInventoryChanges,
|
||||||
generateRewardSeed,
|
generateRewardSeed,
|
||||||
|
getCalendarProgress,
|
||||||
updateCurrency,
|
updateCurrency,
|
||||||
updateSyndicate
|
updateSyndicate
|
||||||
} from "@/src/services/inventoryService";
|
} from "@/src/services/inventoryService";
|
||||||
@ -560,6 +561,15 @@ export const addMissionInventoryUpdates = async (
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case "CalendarProgress": {
|
||||||
|
const calendarProgress = getCalendarProgress(inventory);
|
||||||
|
for (const progress of value) {
|
||||||
|
const challengeName = progress.challenge.substring(progress.challenge.lastIndexOf("/") + 1);
|
||||||
|
calendarProgress.SeasonProgress.LastCompletedChallengeDayIdx++;
|
||||||
|
calendarProgress.SeasonProgress.ActivatedChallenges.push(challengeName);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
// Equipment XP updates
|
// Equipment XP updates
|
||||||
if (equipmentKeys.includes(key as TEquipmentKey)) {
|
if (equipmentKeys.includes(key as TEquipmentKey)) {
|
||||||
|
@ -683,7 +683,7 @@ const getCalendarSeason = (week: number): ICalendarSeason => {
|
|||||||
Activation: { $date: { $numberLong: weekStart.toString() } },
|
Activation: { $date: { $numberLong: weekStart.toString() } },
|
||||||
Expiry: { $date: { $numberLong: weekEnd.toString() } },
|
Expiry: { $date: { $numberLong: weekEnd.toString() } },
|
||||||
Days: eventDays,
|
Days: eventDays,
|
||||||
Season: ["CST_WINTER", "CST_SPRING", "CST_SUMMER", "CST_FALL"][seasonIndex],
|
Season: (["CST_WINTER", "CST_SPRING", "CST_SUMMER", "CST_FALL"] as const)[seasonIndex],
|
||||||
YearIteration: Math.trunc(week / 4),
|
YearIteration: Math.trunc(week / 4),
|
||||||
Version: 19,
|
Version: 19,
|
||||||
UpgradeAvaliabilityRequirements: ["/Lotus/Upgrades/Calendar/1999UpgradeApplicationRequirement"]
|
UpgradeAvaliabilityRequirements: ["/Lotus/Upgrades/Calendar/1999UpgradeApplicationRequirement"]
|
||||||
|
@ -353,7 +353,7 @@ export interface IInventoryClient extends IDailyAffiliations, InventoryClientEqu
|
|||||||
DeathSquadable: boolean;
|
DeathSquadable: boolean;
|
||||||
EndlessXP?: IEndlessXpProgress[];
|
EndlessXP?: IEndlessXpProgress[];
|
||||||
DialogueHistory?: IDialogueHistoryClient;
|
DialogueHistory?: IDialogueHistoryClient;
|
||||||
CalendarProgress: ICalendarProgress;
|
CalendarProgress?: ICalendarProgress;
|
||||||
SongChallenges?: ISongChallenge[];
|
SongChallenges?: ISongChallenge[];
|
||||||
EntratiVaultCountLastPeriod?: number;
|
EntratiVaultCountLastPeriod?: number;
|
||||||
EntratiVaultCountResetDate?: IMongoDate;
|
EntratiVaultCountResetDate?: IMongoDate;
|
||||||
@ -1193,17 +1193,18 @@ export interface IMarker {
|
|||||||
z: number;
|
z: number;
|
||||||
showInHud: boolean;
|
showInHud: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ISeasonProgress {
|
export interface ISeasonProgress {
|
||||||
SeasonType: "CST_UNDEFINED" | "CST_WINTER" | "CST_SPRING" | "CST_SUMMER" | "CST_FALL";
|
SeasonType: "CST_WINTER" | "CST_SPRING" | "CST_SUMMER" | "CST_FALL";
|
||||||
LastCompletedDayIdx: number;
|
LastCompletedDayIdx: number;
|
||||||
LastCompletedChallengeDayIdx: number;
|
LastCompletedChallengeDayIdx: number;
|
||||||
ActivatedChallenges: unknown[];
|
ActivatedChallenges: string[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ICalendarProgress {
|
export interface ICalendarProgress {
|
||||||
Version: number;
|
Version: number;
|
||||||
Iteration: number;
|
Iteration: number;
|
||||||
YearProgress: { Upgrades: unknown[] };
|
YearProgress: { Upgrades: string[] };
|
||||||
SeasonProgress: ISeasonProgress;
|
SeasonProgress: ISeasonProgress;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,6 +44,7 @@ export type IMissionInventoryUpdateRequest = {
|
|||||||
|
|
||||||
SyndicateId?: string;
|
SyndicateId?: string;
|
||||||
SortieId?: string;
|
SortieId?: string;
|
||||||
|
CalendarProgress?: { challenge: string }[];
|
||||||
SeasonChallengeCompletions?: ISeasonChallenge[];
|
SeasonChallengeCompletions?: ISeasonChallenge[];
|
||||||
AffiliationChanges?: IAffiliationChange[];
|
AffiliationChanges?: IAffiliationChange[];
|
||||||
crossPlaySetting?: string;
|
crossPlaySetting?: string;
|
||||||
|
@ -133,7 +133,7 @@ export interface ISeasonChallenge {
|
|||||||
export interface ICalendarSeason {
|
export interface ICalendarSeason {
|
||||||
Activation: IMongoDate;
|
Activation: IMongoDate;
|
||||||
Expiry: IMongoDate;
|
Expiry: IMongoDate;
|
||||||
Season: string; // "CST_UNDEFINED" | "CST_WINTER" | "CST_SPRING" | "CST_SUMMER" | "CST_FALL"
|
Season: "CST_WINTER" | "CST_SPRING" | "CST_SUMMER" | "CST_FALL";
|
||||||
Days: ICalendarDay[];
|
Days: ICalendarDay[];
|
||||||
YearIteration: number;
|
YearIteration: number;
|
||||||
Version: number;
|
Version: number;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user