Questify: Send terminal on last heartbeat. (#965)

This commit is contained in:
Etorix 2026-04-10 13:42:53 -07:00 • committed by GitHub
parent 9aa13ca0ca
commit 3a5bd94de0
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 31 additions and 5 deletions

View file

@ -282,6 +282,14 @@ function QuestTileContextMenu(children: React.ReactNode[], props: { quest: any;
clearInterval(interval.progressTimeout); clearInterval(interval.progressTimeout);
clearTimeout(interval.rerenderTimeout); clearTimeout(interval.rerenderTimeout);
activeQuestIntervals.delete(props.quest.id); activeQuestIntervals.delete(props.quest.id);
if (interval.type === "play") {
void reportPlayGameQuestProgress(refreshQuest(props.quest), true, QuestifyLogger, {
attempts: 3,
delay: 2500,
});
}
resetQuestsToResume(props.quest); resetQuestsToResume(props.quest);
rerenderQuests(); rerenderQuests();
} }
@ -820,9 +828,18 @@ async function startPlayGameProgressTracking(quest: Quest, target: { raw: number
} }
} }
function handleQuestComplete(): void { async function sendTerminalHeartbeat(): Promise<void> {
await reportPlayGameQuestProgress(refreshQuest(quest), true, QuestifyLogger, {
attempts: 3,
delay: 2500,
});
}
async function handleQuestComplete(): Promise<void> {
clearTrackingTimers(); clearTrackingTimers();
activeQuestIntervals.delete(quest.id); activeQuestIntervals.delete(quest.id);
await sendTerminalHeartbeat();
QuestifyLogger.info(`[${getFormattedNow()}] Quest ${questName} completed.`); QuestifyLogger.info(`[${getFormattedNow()}] Quest ${questName} completed.`);
if (settings.store.notifyOnQuestComplete) { if (settings.store.notifyOnQuestComplete) {
@ -855,7 +872,7 @@ async function startPlayGameProgressTracking(quest: Quest, target: { raw: number
} }
if (result.completed || result.progress >= questTarget) { if (result.completed || result.progress >= questTarget) {
handleQuestComplete(); await handleQuestComplete();
return; return;
} }
@ -899,7 +916,7 @@ async function startPlayGameProgressTracking(quest: Quest, target: { raw: number
} }
if (initial.completed || initial.progress >= questTarget) { if (initial.completed || initial.progress >= questTarget) {
handleQuestComplete(); await handleQuestComplete();
return; return;
} }
@ -1988,6 +2005,15 @@ export default definePlugin({
} }
activeQuestIntervals.forEach((intervalData, questId) => { activeQuestIntervals.forEach((intervalData, questId) => {
const quest = QuestsStore.getQuest(questId);
if (intervalData.type === "play" && quest) {
void reportPlayGameQuestProgress(refreshQuest(quest), true, QuestifyLogger, {
attempts: 3,
delay: 2500,
});
}
clearInterval(intervalData.progressTimeout); clearInterval(intervalData.progressTimeout);
clearTimeout(intervalData.rerenderTimeout); clearTimeout(intervalData.rerenderTimeout);
activeQuestIntervals.delete(questId); activeQuestIntervals.delete(questId);

View file

@ -346,14 +346,14 @@ export async function reportPlayGameQuestProgress(quest: Quest, terminal: boolea
if (!quest.userStatus?.enrolledAt) { if (!quest.userStatus?.enrolledAt) {
logger?.warn(`[${getFormattedNow()}] Cannot send heartbeat for unenrolled Quest ${questName}.`); logger?.warn(`[${getFormattedNow()}] Cannot send heartbeat for unenrolled Quest ${questName}.`);
return { progress: null, completed: false }; return { progress: null, completed: false };
} else if (quest.userStatus?.completedAt) { } else if (quest.userStatus?.completedAt && !terminal) {
return { progress: null, completed: true }; return { progress: null, completed: true };
} }
const maxAttempts = options?.attempts ?? 1; const maxAttempts = options?.attempts ?? 1;
const delay = options?.delay ?? 2500; const delay = options?.delay ?? 2500;
const timeout = options?.timeout ?? 10000; const timeout = options?.timeout ?? 10000;
const streamKey = options?.streamKey ?? `call:${quest.id}:1`; const streamKey = options?.streamKey;
const applicationId = options?.applicationId ?? quest.config.application.id; const applicationId = options?.applicationId ?? quest.config.application.id;
const questPlayType = quest.config.taskConfigV2?.tasks.PLAY_ON_DESKTOP || quest.config.taskConfigV2?.tasks.PLAY_ON_XBOX || quest.config.taskConfigV2?.tasks.PLAY_ON_PLAYSTATION || quest.config.taskConfigV2?.tasks.PLAY_ACTIVITY; const questPlayType = quest.config.taskConfigV2?.tasks.PLAY_ON_DESKTOP || quest.config.taskConfigV2?.tasks.PLAY_ON_XBOX || quest.config.taskConfigV2?.tasks.PLAY_ON_PLAYSTATION || quest.config.taskConfigV2?.tasks.PLAY_ACTIVITY;