Questify: Fix patches & improve Auto Complete warning. (#956)

* Fix patches.

* Make warning more clear and verbose.

* Fix button.

* Fix a button and resuming.
This commit is contained in:
Etorix 2026-04-08 06:38:58 -07:00 • committed by GitHub
parent a8c1023b4c
commit 6005a02c24
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 52 additions and 13 deletions

View file

@ -276,6 +276,8 @@ function QuestTileContextMenu(children: React.ReactNode[], props: { quest: any;
const interval = activeQuestIntervals.get(props.quest.id);
if (interval) {
QuestifyLogger.info(`[${getFormattedNow()}] Auto-Complete for Quest ${normalizeQuestName(props.quest.config.messages.questName)} stopped via context menu.`);
resetQuestsToResume(props.quest);
clearInterval(interval.progressTimeout);
clearTimeout(interval.rerenderTimeout);
activeQuestIntervals.delete(props.quest.id);
@ -968,12 +970,10 @@ function getQuestUnacceptedButtonText(quest: Quest): string | null {
const isPlay = task?.type === QuestTaskType.PLAY_ON_DESKTOP || task?.type === QuestTaskType.PLAY_ON_XBOX || task?.type === QuestTaskType.PLAY_ON_PLAYSTATION || task?.type === QuestTaskType.PLAY_ACTIVITY;
const isAchievement = task?.type === QuestTaskType.ACHIEVEMENT_IN_ACTIVITY;
if (target > 0) {
if ((isPlay && completeGameQuestsInBackground && IS_DISCORD_DESKTOP) || (isWatch && completeVideoQuestsInBackground)) {
return `Complete (${targetFormatted})`;
} else if (isAchievement && completeAchievementQuestsInBackground) {
return "Complete (Immediate)";
}
if ((isPlay && completeGameQuestsInBackground && IS_DISCORD_DESKTOP) || (isWatch && completeVideoQuestsInBackground && target > 0)) {
return `Complete (${targetFormatted})`;
} else if ((isAchievement && completeAchievementQuestsInBackground) || (isWatch && completeVideoQuestsInBackground && target === 0)) {
return "Complete (Immediate)";
}
return null;
@ -1192,6 +1192,16 @@ function getQuestAcceptedButtonProps(quest: Quest, text: string, disabled: boole
};
}
function resetQuestsToResume(quest?: Quest): void {
if (quest) {
settings.store.resumeQuestIDs.play = settings.store.resumeQuestIDs.play.filter(id => id !== quest.id);
settings.store.resumeQuestIDs.watch = settings.store.resumeQuestIDs.watch.filter(id => id !== quest.id);
settings.store.resumeQuestIDs.achievement = settings.store.resumeQuestIDs.achievement.filter(id => id !== quest.id);
} else {
settings.store.resumeQuestIDs = settings.def.resumeQuestIDs.default;
}
}
// Drop support for QuestCompleter and migrate to Questify settings.
migratePluginToSettings(true, "Questify", "QuestCompleter", "completeVideoQuestsInBackground", "completeGameQuestsInBackground", "completeAchievementQuestsInBackground");
@ -1586,7 +1596,7 @@ export default definePlugin({
// Whether preloading assets is enabled or not, the placeholders loading
// before the assets causes a lot of element shifting, whereas if
// the elements load immediately instead, it doesn't.
find: ".LEARN_MORE_CTA_AND_EXPRESSIVE_BUTTON_TREATMENT_FOUR_OPEN_GAME_LINK,sourceQuestContent:",
find: ".QUEST_HOME_TILE_HEADER_WATCH_VIDEO})},",
replacement: {
match: /showPlaceholder:!\i/,
replace: "showPlaceholder:false"
@ -1635,7 +1645,7 @@ export default definePlugin({
},
{
// Adds support for dev://experiment/2025-12-quest-cta-refactor-rollout
find: '"primary",preClickCallback:',
find: "WATCH_VIDEO?async()=>{await",
replacement: [
{
match: /(?=let{quest:)/,
@ -1651,9 +1661,27 @@ export default definePlugin({
}
]
},
{
// Same thing as above, maybe? Different location though.
find: ".ACCEPT_QUEST),",
replacement: [
{
match: /(?=let{quest:)/,
replace: "const questifyText=$self.getQuestUnacceptedButtonText(arguments[0].quest);"
},
{
match: /(?<=,text:)(\i)/g,
replace: "questifyText??$1"
},
{
match: /(?<="primary",onClick:)(\i)/,
replace: "!$self.processQuestForAutoComplete(arguments[0].quest)&&$1"
}
]
},
{
// Sets intervals to progress Video Quests in the background.
find: "CAPTCHA_FAILED:",
find: "questContentRowIndex});",
replacement: {
match: /(?<=SUCCESS:)(\i\({)/,
replace: "!$self.processQuestForAutoComplete(arguments[0])&&$1"
@ -1783,7 +1811,7 @@ export default definePlugin({
const maybeResumable = !(settings.store.disableQuestsEverything || settings.store.disableQuestsFetchingQuests);
if (!wasReload || !maybeResumable) {
settings.store.resumeQuestIDs = settings.def.resumeQuestIDs.default;
resetQuestsToResume();
return;
}
@ -1821,7 +1849,7 @@ export default definePlugin({
stopAutoFetchingQuests();
if (!Settings.plugins.Questify.enabled) {
settings.store.resumeQuestIDs = settings.def.resumeQuestIDs.default;
resetQuestsToResume();
}
activeQuestIntervals.forEach((intervalData, questId) => {

View file

@ -828,8 +828,11 @@ function DisableQuestsSetting(): JSX.Element {
For Video Quests, subsequent clicks will open the video modal as normal. For Activity Quests, subsequent clicks
will open the activity as normal. To abort the Quests, you can open the context menu on the Quest tile and
select <span className={q("inline-code-block")}>Stop Auto-Complete</span>.
<br /><br />
Using any of the Auto-Complete options is against Discord's TOS. Use at your own risk.
</Paragraph>
<Paragraph className={q("form-warning")}>
Using any of the Auto-Complete options is against <a href="https://discord.com/safety/platform-manipulation-policy-explainer" target="_blank" rel="noreferrer">Discord's TOS</a>. Discord has been known to warn users
that automate Quest completion with threat of loss of access to Quests. There has been no reports of account
limitations or bans, but Discord may change their stance at any time. Use at your own risk.
</Paragraph>
<DynamicDropdown
placeholder="Select which Quest features to modify."

View file

@ -50,6 +50,14 @@
font-size: 14px;
}
.questify-form-warning {
margin: 12px 0 8px;
padding: 10px 12px;
border-left: 3px solid var(--status-danger);
border-radius: 4px;
background-color: color-mix(in srgb, var(--status-danger) 12%, transparent);
}
.questify-select > div {
border-radius: 3px;
min-height: 43px;