WIP: fix: avoid pushing to quest progress in updateQuestStage #2847

Closed
Sainan wants to merge 7 commits from quest-fix into main
4 changed files with 40 additions and 30 deletions

View File

@ -5,6 +5,7 @@ import type { IUpdateQuestRequest } from "../../services/questService.ts";
import { updateQuestKey } from "../../services/questService.ts";
import { getInventory } from "../../services/inventoryService.ts";
import type { IInventoryChanges } from "../../types/purchaseTypes.ts";
import { sendWsBroadcastTo } from "../../services/wsService.ts";
export const updateQuestController: RequestHandler = async (req, res) => {
const accountId = parseString(req.query.accountId);
@ -29,4 +30,5 @@ export const updateQuestController: RequestHandler = async (req, res) => {
await inventory.save();
res.send(updateQuestResponse);
sendWsBroadcastTo(accountId, { update_inventory: true });
};

View File

@ -115,7 +115,7 @@ export const manageQuestsController: RequestHandler = async (req, res) => {
if (stage > 0) {
await giveKeyChainStageTriggered(inventory, {
KeyChain: questKey.ItemType,
ChainStage: stage - 1
ChainStage: stage
});
}
}

View File

@ -210,7 +210,7 @@ export const getKeyChainItems = ({ KeyChain, ChainStage }: IKeyChainRequest): st
throw new Error(`KeyChain ${KeyChain} does not contain chain stages`);
}
const keyChainStage = chainStages[ChainStage];
const keyChainStage = chainStages[ChainStage - 1];
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
if (!keyChainStage) {
throw new Error(`KeyChainStage ${ChainStage} not found`);

View File

@ -68,26 +68,32 @@ export const updateQuestStage = (
throw new Error(`Progress should always exist when giving keychain triggered items or messages`);
}
const questStage = quest.Progress[ChainStage];
ChainStage -= 1; // They are 1-indexed in the client, but we need 0-indexing
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
if (!questStage) {
const questStageIndex =
if (ChainStage == quest.Progress.length) {
logger.debug(`pushing to quest progress in updateQuestStage`);
quest.Progress.push({
c: questStageUpdate.c ?? 0,
i: questStageUpdate.i ?? false,
m: questStageUpdate.m ?? false,
b: questStageUpdate.b ?? []
}) - 1;
if (questStageIndex !== ChainStage) {
throw new Error(`Quest stage index mismatch: ${questStageIndex} !== ${ChainStage}`);
}
return;
c: 0,
i: false,
m: false,
b: []
});
} else if (ChainStage >= quest.Progress.length) {
throw new Error(
`Quest stage index mismatch: stage is ${ChainStage} but array size is ${quest.Progress.length}`
);
}
// Note that the client may use index 0 as well, e.g. for rising tide's initial inbox message. 'm' is not tracked for it.
if (ChainStage >= 0) {
const questStage = quest.Progress[ChainStage]; // guaranteed in-bounds now
for (const [key, value] of Object.entries(questStageUpdate) as [keyof IQuestStage, number | boolean | any[]][]) {
for (const [key, value] of Object.entries(questStageUpdate) as [
keyof IQuestStage,
number | boolean | any[]
][]) {
(questStage[key] as any) = value;
}
}
};
export const addQuestKey = (
@ -157,7 +163,7 @@ export const completeQuest = async (inventory: TInventoryDatabaseDocument, quest
existingQuestKey.Progress.push(...missingProgress);
}
for (let i = 0; i < chainStageTotal; i++) {
for (let i = 1; i < chainStageTotal; i++) {
const stage = existingQuestKey.Progress[i];
if (stage.c <= run) {
stage.c = run;
@ -302,7 +308,7 @@ export const giveKeyChainItem = async (
): Promise<IInventoryChanges> => {
let inventoryChanges: IInventoryChanges = {};
if (!questKey.Progress?.[keyChainInfo.ChainStage]?.i) {
if (!questKey.Progress?.[keyChainInfo.ChainStage - 1]?.i) {
inventoryChanges = await addKeyChainItems(inventory, keyChainInfo);
if (isEmptyObject(inventoryChanges)) {
@ -329,6 +335,7 @@ export const giveKeyChainMessage = async (
keyChainInfo: IKeyChainRequest,
questKey: IQuestKeyDatabase
): Promise<void> => {
if (!questKey.Progress?.[keyChainInfo.ChainStage - 1]?.m) {
const keyChainMessage = getKeyChainMessage(keyChainInfo);
if ((questKey.Progress?.[0]?.c ?? 0) > 0) {
@ -339,6 +346,7 @@ export const giveKeyChainMessage = async (
await createMessage(inventory.accountOwnerId, [keyChainMessage]);
updateQuestStage(inventory, keyChainInfo, { m: true });
}
};
export const giveKeyChainMissionReward = async (
@ -391,11 +399,11 @@ export const giveKeyChainStageTriggered = async (
const questKey = inventory.QuestKeys.find(qk => qk.ItemType === keyChainInfo.KeyChain);
if (chainStages && questKey) {
if (chainStages[keyChainInfo.ChainStage].itemsToGiveWhenTriggered.length > 0) {
if (chainStages[keyChainInfo.ChainStage - 1].itemsToGiveWhenTriggered.length > 0) {
await giveKeyChainItem(inventory, keyChainInfo, questKey);
}
if (chainStages[keyChainInfo.ChainStage].messageToSendWhenTriggered) {
if (chainStages[keyChainInfo.ChainStage - 1].messageToSendWhenTriggered) {
await giveKeyChainMessage(inventory, keyChainInfo, questKey);
}
}