fix quest system

This commit is contained in:
Master 2024-07-06 01:29:08 +08:00
parent a4ec3833bf
commit 1148ef8de4
8 changed files with 319 additions and 6 deletions

View File

@ -0,0 +1,17 @@
import { RequestHandler } from "express";
import { getJSONfromString } from "@/src/helpers/stringHelpers";
import { getAccountIdForRequest } from "@/src/services/loginService";
import { giveKeyChainTriggeredItems } from "@/src/services/questService";
import { IGiveKeyChainTriggeredItemsRequest } from "@/src/types/questTypes";
// eslint-disable-next-line @typescript-eslint/no-misused-promises
const giveKeyChainTriggeredItemsController: RequestHandler = async (req, res) => {
const accountId = await getAccountIdForRequest(req);
const payload = getJSONfromString(req.body as string) as IGiveKeyChainTriggeredItemsRequest;
if (payload) {
const result = await giveKeyChainTriggeredItems(accountId, payload);
if (result) res.json(result);
} else res.json({});
};
export { giveKeyChainTriggeredItemsController };

View File

@ -0,0 +1,28 @@
import { RequestHandler } from "express";
import { getJSONfromString } from "@/src/helpers/stringHelpers";
import { getAccountIdForRequest } from "@/src/services/loginService";
import { giveKeyChainTriggeredMessage } from "@/src/services/questService";
export interface IGiveKeyChainTriggeredMessageGroup {
experiment: string;
experimentGroup: string;
}
export interface IGiveKeyChainTriggeredMessageRequest {
KeyChain: string;
ChainStage: number;
Groups: IGiveKeyChainTriggeredMessageGroup[];
}
// eslint-disable-next-line @typescript-eslint/no-misused-promises
const giveKeyChainTriggeredMessageController: RequestHandler = async (req, res) => {
const accountId = await getAccountIdForRequest(req);
const payload = getJSONfromString(req.body as string) as IGiveKeyChainTriggeredMessageRequest;
const result = giveKeyChainTriggeredMessage(accountId, payload.KeyChain, payload.ChainStage);
if (result) res.json(result);
else res.status(200).end();
};
export { giveKeyChainTriggeredMessageController };

View File

@ -1,7 +1,13 @@
import { getAccountIdForRequest } from "@/src/services/loginService";
import { setActiveQuest } from "@/src/services/questService";
import { RequestHandler } from "express";
const setActiveQuestController: RequestHandler = (_req, res) => {
res.sendStatus(200);
// eslint-disable-next-line @typescript-eslint/no-misused-promises
const setActiveQuestController: RequestHandler = async (req, res) => {
const accountId = await getAccountIdForRequest(req);
const quest = req.query.quest as string;
const result = await setActiveQuest(accountId, quest);
res.json(result);
};
export { setActiveQuestController };

View File

@ -0,0 +1,16 @@
import { RequestHandler } from "express";
import { getJSONfromString } from "@/src/helpers/stringHelpers";
import { getAccountIdForRequest } from "@/src/services/loginService";
import { IUpdateQuestRequest } from "@/src/types/questTypes";
import { updateQuest } from "@/src/services/questService";
// eslint-disable-next-line @typescript-eslint/no-misused-promises
const updateQuestController: RequestHandler = async (req, res) => {
const accountId = await getAccountIdForRequest(req);
const payload = getJSONfromString(req.body as string) as IUpdateQuestRequest;
const result = await updateQuest(accountId, payload);
res.json(result);
};
export { updateQuestController };

View File

@ -19,18 +19,18 @@ import {
equipmentKeys,
IFusionTreasure
} from "@/src/types/inventoryTypes/inventoryTypes";
import { IGenericUpdate } from "../types/genericUpdate";
import { IGenericUpdate } from "@/src/types/genericUpdate";
import {
IArtifactsRequest,
IMissionInventoryUpdateRequest,
IThemeUpdateRequest,
IUpdateChallengeProgressRequest
} from "../types/requestTypes";
} from "@/src/types/requestTypes";
import { logger } from "@/src/utils/logger";
import { getWeaponType, getExalted } from "@/src/services/itemDataService";
import { getRandomWeightedReward } from "@/src/services/rngService";
import { ISyndicateSacrifice, ISyndicateSacrificeResponse } from "../types/syndicateTypes";
import { IEquipmentClient } from "../types/inventoryTypes/commonInventoryTypes";
import { ISyndicateSacrifice, ISyndicateSacrificeResponse } from "@/src/types/syndicateTypes";
import { IEquipmentClient, IEquipmentDatabase } from "@/src/types/inventoryTypes/commonInventoryTypes";
import {
ExportBoosterPacks,
ExportCustoms,
@ -870,3 +870,10 @@ export const upgradeMod = async (artifactsData: IArtifactsRequest, accountId: st
throw error;
}
};
export const addHerse = async (ItemType: string, accountId: string): Promise<IEquipmentDatabase> => {
const inventory = await getInventory(accountId);
const herseIndex = inventory.Horses.push({ ItemType: ItemType, Configs: [], UpgradeVer: 101 });
const changedInventory = await inventory.save();
return changedInventory.Horses[herseIndex - 1].toJSON();
};

View File

@ -0,0 +1,193 @@
import { ExportKeys, ExportRecipes, ExportResources, IKey } from "warframe-public-export-plus";
import { addHerse, addItem, getInventory } from "./inventoryService";
import { logger } from "@/src/utils/logger";
import {
IGiveKeyChainTriggeredItemsRequest,
IGiveKeyChainTriggeredItemsResponse,
ISetActiveQuestResponse,
IUpdateQuestRequest,
IUpdateQuestResponse
} from "@/src/types/questTypes";
import { IInventoryDatabaseDocument, IQuestKeyDatabase } from "@/src/types/inventoryTypes/inventoryTypes";
import { toOid } from "@/src/helpers/inventoryHelpers";
const getQuest = (quest: string): IKey | undefined => {
for (const [k, v] of Object.entries(ExportKeys)) {
if (k == quest) {
return v;
}
}
return undefined;
};
export const setActiveQuest = async (accountId: string, quest: string): Promise<ISetActiveQuestResponse> => {
const inventory = await getInventory(accountId);
const questKey = inventory.QuestKeys.find(q => q.ItemType == quest);
if (questKey == null) inventory.QuestKeys.push({ ItemType: quest });
inventory.ActiveQuest = quest;
await inventory.save();
const questData = getQuest(quest);
if (questData) {
console.log(questData);
}
const result: ISetActiveQuestResponse = {
inventoryChanges: {
QuestKey: [],
Herses: [],
PremiumCreditsFree: 0,
PremiumCredits: 0,
RegularCredits: 0
}
};
switch (quest) {
case "/Lotus/Types/Keys/DuviriQuest/DuviriQuestKeyChain":
// eslint-disable-next-line no-case-declarations
const inventory = await getInventory(accountId);
// eslint-disable-next-line no-case-declarations
const questKey = inventory.QuestKeys.find(q => q.ItemType == quest);
if (questKey == null) inventory.QuestKeys.push({ ItemType: quest });
inventory.ActiveQuest = quest;
await inventory.save();
// eslint-disable-next-line no-case-declarations
const herse = await addHerse("/Lotus/Types/NeutralCreatures/ErsatzHorse/ErsatzHorsePowerSuit", accountId);
result.inventoryChanges.QuestKey.push({ ItemType: quest });
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
result.inventoryChanges.Herses.push({ ItemType: herse.ItemType, ItemId: toOid(herse._id) });
result.inventoryChanges.PremiumCreditsFree = 50;
result.inventoryChanges.PremiumCredits = 50;
result.inventoryChanges.RegularCredits = 3000;
break;
default:
result.inventoryChanges.QuestKey.push({ ItemType: quest });
break;
}
return result;
};
export const updateQuestKeys = async (
inventory: IInventoryDatabaseDocument,
questKeys: IQuestKeyDatabase[]
): Promise<void> => {
logger.debug("quest: " + questKeys[0].ItemType);
const questKeyIndex = inventory.QuestKeys.findIndex(questKey => questKey.ItemType === questKeys[0].ItemType);
inventory.QuestKeys[questKeyIndex] = questKeys[0];
if (questKeys[0].Completed) {
inventory.QuestKeys[questKeyIndex].CompletionDate = new Date();
}
await inventory.save();
};
export const updateQuest = async (
accountId: string,
updateQuest: IUpdateQuestRequest
): Promise<IUpdateQuestResponse> => {
const inventory = await getInventory(accountId);
await updateQuestKeys(inventory, updateQuest.QuestKeys);
const result: IUpdateQuestResponse = {
MissionRewards: []
};
if (updateQuest.QuestKeys[0].Completed) {
const quest = ExportKeys[updateQuest.QuestKeys[0].ItemType];
if (quest.rewards != null) {
for (const reward of quest.rewards) {
switch (reward.rewardType) {
case "RT_STORE_ITEM":
await addItem(accountId, reward.itemType.replace("/Lotus/StoreItems/", "/Lotus/"), 1);
break;
case "RT_RECIPE":
await addItem(accountId, reward.itemType, 1);
break;
case "RT_CREDITS":
inventory.RegularCredits += reward.amount;
await inventory.save();
break;
}
// push MissionRewards
// result.MissionRewards.push({});
}
}
}
return result;
};
export const giveKeyChainTriggeredItems = async (
accountId: string,
payload: IGiveKeyChainTriggeredItemsRequest
): Promise<IGiveKeyChainTriggeredItemsResponse> => {
logger.debug("keyChain: " + payload.KeyChain + " chainStage: " + payload.ChainStage);
const inventory = await getInventory(accountId);
const quest = ExportKeys[payload.KeyChain];
const result: IGiveKeyChainTriggeredItemsResponse = {};
if (quest.chainStages) {
const stage = quest.chainStages[payload.ChainStage];
if (stage.key && stage.key in ExportKeys) {
const stageQuest = ExportKeys[stage.key];
if (stageQuest.rewards) {
for (const item of stageQuest.rewards) {
switch (item.rewardType) {
case "RT_STORE_ITEM":
await addItem(accountId, item.itemType.replace("/Lotus/StoreItems/", "/Lotus/"), 1);
break;
case "RT_CREDITS":
inventory.RegularCredits += item.amount;
await inventory.save();
break;
}
}
}
}
if (stage.itemsToGiveWhenTriggered.length > 0) {
let itemType = stage.itemsToGiveWhenTriggered[0];
if (itemType.indexOf("") > 0) {
itemType = itemType.replace("/Lotus/StoreItems/", "/Lotus/");
}
await addItem(accountId, itemType, 1);
if (itemType in ExportRecipes) {
result.Recipes = [
{
ItemType: itemType,
ItemCount: 1
}
];
}
if (itemType in ExportResources) {
result.WishlistChanges = [itemType];
result.MiscItems = [
{
ItemType: itemType,
ItemCount: 1
}
];
}
// more
} else {
result.MissionRewards = [];
}
}
return result;
};
export const giveKeyChainTriggeredMessage = (accountId: string, keyChain: string, chainStage: number): null => {
logger.debug("accountId:" + accountId + "keyChain: " + keyChain + " chainStage: " + chainStage);
// TODO:message
return null;
};

View File

@ -290,6 +290,7 @@ export interface IInventoryResponse {
PendingCoupon: IPendingCoupon;
Harvestable: boolean;
DeathSquadable: boolean;
ActiveQuest: string;
}
export interface IAffiliation {

45
src/types/questTypes.ts Normal file
View File

@ -0,0 +1,45 @@
import { IOid } from "./commonTypes";
import { IQuestKeyDatabase } from "./inventoryTypes/inventoryTypes";
export interface ISetActiveQuestKey {
ItemType: string;
}
export interface ISetActiveQuestHerse extends ISetActiveQuestKey {
ItemId: IOid;
}
export interface ISetActiveQuestResponse {
inventoryChanges: {
QuestKey: ISetActiveQuestKey[];
Herses: ISetActiveQuestHerse[];
PremiumCreditsFree: number;
PremiumCredits: number;
RegularCredits: number;
};
}
export interface IUpdateQuestRequest {
QuestKeys: IQuestKeyDatabase[];
PS: string;
questCompletion: boolean;
PlayerShipEvents: [];
crossPlaySetting: string;
}
export interface IUpdateQuestResponse {
CustomData?: string;
MissionRewards: [];
}
export interface IGiveKeyChainTriggeredItemsRequest {
KeyChain: string;
ChainStage: number;
}
export interface IGiveKeyChainTriggeredItemsResponse {
WishlistChanges?: [string];
MiscItems?: [{ ItemType: string; ItemCount: number }];
Recipes?: [{ ItemType: string; ItemCount: number }];
MissionRewards?: [];
}