diff --git a/src/equicordplugins/questCompleter/index.tsx b/src/equicordplugins/questCompleter/index.tsx
index d474646b..24f08ba2 100644
--- a/src/equicordplugins/questCompleter/index.tsx
+++ b/src/equicordplugins/questCompleter/index.tsx
@@ -17,12 +17,195 @@
*/
import { showNotification } from "@api/Notifications";
+import ErrorBoundary from "@components/ErrorBoundary";
import { Devs, EquicordDevs } from "@utils/constants";
import { getTheme, Theme } from "@utils/discord";
+import { classes } from "@utils/misc";
import definePlugin from "@utils/types";
-import { findByCode, findByProps } from "@webpack";
+import { findByCode, findByProps, findExportedComponentLazy } from "@webpack";
import { FluxDispatcher, Forms, RestAPI, Text, UserStore } from "@webpack/common";
+const HeaderBarIcon = findExportedComponentLazy("Icon", "Divider");
+const isApp = navigator.userAgent.includes("Electron/");
+
+const QuestsIcon = () => props => (
+
+);
+
+function ToolBarQuestsIcon() {
+ return (
+
+ );
+}
+
+function ToolBarHeader() {
+ return (
+
+
+
+
+ );
+}
+
+async function openCompleteQuestUI() {
+ // check if user is sharing screen and there is someone that is watching the stream
+ const ApplicationStreamingStore = findByProps("getStreamerActiveStreamMetadata");
+ const RunningGameStore = findByProps("getRunningGames");
+ const ExperimentStore = findByProps("getGuildExperiments");
+ const QuestsStore = findByProps("getQuest");
+ const quest = [...QuestsStore.quests.values()].find(x => x.id !== "1248385850622869556" && x.userStatus?.enrolledAt && !x.userStatus?.completedAt && new Date(x.config.expiresAt).getTime() > Date.now());
+
+ if (!isApp) {
+ showNotification({
+ title: "Quests Completer",
+ body: "This no longer works in browser. Use the desktop app!",
+ });
+ } else if (!quest) {
+ showNotification({
+ title: "Quests Completer",
+ body: "No Quests To Complete",
+ });
+ } else {
+ const pid = Math.floor(Math.random() * 30000) + 1000;
+ const theme = getTheme() === Theme.Light
+ ? "light"
+ : "dark";
+
+ let applicationId, applicationName, secondsNeeded, secondsDone, canPlay, icon, questId;
+ if (quest.config.configVersion === 1) {
+ questId = quest.id;
+ applicationId = quest.config.applicationId;
+ applicationName = quest.config.applicationName;
+ secondsNeeded = quest.config.streamDurationRequirementMinutes * 60;
+ secondsDone = quest.userStatus?.streamProgressSeconds ?? 0;
+ icon = `https://cdn.discordapp.com/assets/quests/${questId}/${theme}/${quest.config.assets.gameTile}`;
+ canPlay = quest.config.variants.includes(2);
+ } else if (quest.config.configVersion === 2) {
+ questId = quest.id;
+ applicationId = quest.config.application.id;
+ applicationName = quest.config.application.name;
+ icon = `https://cdn.discordapp.com/assets/quests/${questId}/${theme}/${quest.config.assets.gameTile}`;
+ canPlay = ExperimentStore.getUserExperimentBucket("2024-04_quest_playtime_task") > 0 && quest.config.taskConfig.tasks.PLAY_ON_DESKTOP;
+ const taskName = canPlay ? "PLAY_ON_DESKTOP" : "STREAM_ON_DESKTOP";
+ secondsNeeded = quest.config.taskConfig.tasks[taskName]?.target;
+ secondsDone = quest.userStatus?.progress?.[taskName]?.value ?? 0;
+ }
+ if (canPlay) {
+ await RestAPI.get({ url: `/applications/public?application_ids=${applicationId}` }).then(res => {
+ const appData = res.body[0];
+ const exeName = appData.executables.find(x => x.os === "win32").name.replace(">", "");
+
+ const games = RunningGameStore.getRunningGames();
+ const fakeGame = {
+ cmdLine: `C:\\Program Files\\${appData.name}\\${exeName}`,
+ exeName,
+ exePath: `c:/program files/${appData.name.toLowerCase()}/${exeName}`,
+ hidden: false,
+ isLauncher: false,
+ id: applicationId,
+ name: appData.name,
+ pid: pid,
+ pidPath: [pid],
+ processName: appData.name,
+ start: Date.now(),
+ };
+ games.push(fakeGame);
+ FluxDispatcher.dispatch({ type: "RUNNING_GAMES_CHANGE", removed: [], added: [fakeGame], games: games });
+
+ const fn = data => {
+ const progress = quest.config.configVersion === 1 ? data.userStatus.streamProgressSeconds : Math.floor(data.userStatus.progress.PLAY_ON_DESKTOP.value);
+ showNotification({
+ title: `${applicationName} - Quests Completer`,
+ body: `Current progress: ${progress}/${secondsNeeded} seconds.`,
+ icon: icon,
+ });
+
+ if (progress >= secondsNeeded) {
+ showNotification({
+ title: `${applicationName} - Quests Completer`,
+ body: "Quest Completed.",
+ icon: icon,
+ });
+
+ const idx = games.indexOf(fakeGame);
+ if (idx > -1) {
+ games.splice(idx, 1);
+ FluxDispatcher.dispatch({ type: "RUNNING_GAMES_CHANGE", removed: [fakeGame], added: [], games: [] });
+ }
+ FluxDispatcher.unsubscribe("QUESTS_SEND_HEARTBEAT_SUCCESS", fn);
+ }
+ };
+ FluxDispatcher.subscribe("QUESTS_SEND_HEARTBEAT_SUCCESS", fn);
+ });
+ } else {
+ const stream = ApplicationStreamingStore.getAnyStreamForUser(UserStore.getCurrentUser()?.id);
+ if (!stream) {
+ showNotification({
+ title: "You're not streaming - Quests Completer",
+ body: `${applicationName} requires you to be streaming.`,
+ icon: icon,
+ });
+ }
+ const realFunc = ApplicationStreamingStore.getStreamerActiveStreamMetadata;
+ ApplicationStreamingStore.getStreamerActiveStreamMetadata = () => ({
+ id: applicationId,
+ pid,
+ sourceName: null
+ });
+
+ const fn = data => {
+ const progress = quest.config.configVersion === 1 ? data.userStatus.streamProgressSeconds : Math.floor(data.userStatus.progress.STREAM_ON_DESKTOP.value);
+ showNotification({
+ title: `${applicationName} - Quests Completer`,
+ body: `Current progress: ${progress}/${secondsNeeded} seconds.`,
+ icon: icon,
+ });
+
+ if (progress >= secondsNeeded) {
+ showNotification({
+ title: `${applicationName} - Quests Completer`,
+ body: "Quest Completed.",
+ icon: icon,
+ });
+
+ ApplicationStreamingStore.getStreamerActiveStreamMetadata = realFunc;
+ FluxDispatcher.unsubscribe("QUESTS_SEND_HEARTBEAT_SUCCESS", fn);
+ }
+ };
+ FluxDispatcher.subscribe("QUESTS_SEND_HEARTBEAT_SUCCESS", fn);
+ }
+ return;
+ }
+}
+
export default definePlugin({
name: "QuestCompleter",
description: "A plugin to complete quests without having the game installed.",
@@ -34,14 +217,50 @@ export default definePlugin({
match: /(function .+?\(.+?\){let{inPopout:.+allowIdle.+?}=.+?\.\i\)\("popup"\),(.+?)=\[\];if\(.+?\){.+"chat-spacer"\)\)\),\(\d,.+?\.jsx\)\(.+?,{children:).+?}}/,
replace: "$1[$self.renderQuestButton(),...$2]})}}"
}
+ },
+ {
+ find: "toolbar:function",
+ replacement: {
+ match: /(function \i\(\i\){)(.{1,200}toolbar.{1,200}mobileToolbar)/,
+ replace: "$1$self.toolbarAction(arguments[0]);$2"
+ }
}
],
- settingsAboutComponent() {
- const isDesktop = navigator.userAgent.includes("discord/");
+ renderQuestButton() {
+ const ToolTipButton = findByCode("}),color:\"currentColor\"})})}}");
+ return (
+ <>
+
+
+
+ >
+ );
+ },
+ toolbarAction(e) {
+ if (Array.isArray(e.toolbar))
+ return e.toolbar.push(
+
+
+
+ );
+
+ e.toolbar = [
+
+
+ ,
+ e.toolbar,
+ ];
+ },
+ settingsAboutComponent() {
return (<>
{
- isDesktop ?
+ isApp ?
The plugin should work properly because you are on the Desktop Client.
@@ -51,164 +270,5 @@ export default definePlugin({
}
>);
- },
- start() {
- const currentUserId: string = UserStore.getCurrentUser().id;
- window.currentUserId = currentUserId; // this is here because discord will lag if we get the current user id every time
- },
- renderQuestButton() {
- const ToolTipButton = findByCode("}),color:\"currentColor\"})})}}");
- const QuestsIcon = () => props => (
-
-
- );
-
- return (
- <>
-
-
-
-
- >
- );
- },
- async openCompleteQuestUI() {
- // check if user is sharing screen and there is someone that is watching the stream
- const ApplicationStreamingStore = findByProps("getStreamerActiveStreamMetadata");
- const RunningGameStore = findByProps("getRunningGames");
- const ExperimentStore = findByProps("getGuildExperiments");
- const QuestsStore = findByProps("getQuest");
- const quest = [...QuestsStore.quests.values()].find(quest => quest.userStatus?.enrolledAt && !quest?.userStatus?.completedAt && new Date(quest?.config?.expiresAt) >= new Date());
-
- const isApp = navigator.userAgent.includes("Electron/");
- if (!isApp) {
- showNotification({
- title: "Quests Completer",
- body: "This no longer works in browser. Use the desktop app!",
- });
- } else if (!quest) {
- showNotification({
- title: "Quests Completer",
- body: "No Quests To Complete",
- });
- } else {
- const pid = Math.floor(Math.random() * 30000) + 1000;
- const theme = getTheme() === Theme.Light
- ? "light"
- : "dark";
-
- let applicationId, applicationName, secondsNeeded, secondsDone, canPlay, icon, questId;
- if (quest.config.configVersion === 1) {
- questId = quest.id;
- applicationId = quest.config.applicationId;
- applicationName = quest.config.applicationName;
- secondsNeeded = quest.config.streamDurationRequirementMinutes * 60;
- secondsDone = quest.userStatus?.streamProgressSeconds ?? 0;
- icon = `https://cdn.discordapp.com/assets/quests/${questId}/${theme}/${quest.config.assets.gameTile}`;
- canPlay = quest.config.variants.includes(2);
- } else if (quest.config.configVersion === 2) {
- questId = quest.id;
- applicationId = quest.config.application.id;
- applicationName = quest.config.application.name;
- icon = `https://cdn.discordapp.com/assets/quests/${questId}/${theme}/${quest.config.assets.gameTile}`;
- canPlay = ExperimentStore.getUserExperimentBucket("2024-04_quest_playtime_task") > 0 && quest.config.taskConfig.tasks.PLAY_ON_DESKTOP;
- const taskName = canPlay ? "PLAY_ON_DESKTOP" : "STREAM_ON_DESKTOP";
- secondsNeeded = quest.config.taskConfig.tasks[taskName]?.target;
- secondsDone = quest.userStatus?.progress?.[taskName]?.value ?? 0;
- }
- if (canPlay) {
- await RestAPI.get({ url: `/applications/public?application_ids=${applicationId}` }).then(res => {
- const appData = res.body[0];
- const exeName = appData.executables.find(x => x.os === "win32").name.replace(">", "");
-
- const games = RunningGameStore.getRunningGames();
- const fakeGame = {
- cmdLine: `C:\\Program Files\\${appData.name}\\${exeName}`,
- exeName,
- exePath: `c:/program files/${appData.name.toLowerCase()}/${exeName}`,
- hidden: false,
- isLauncher: false,
- id: applicationId,
- name: appData.name,
- pid: pid,
- pidPath: [pid],
- processName: appData.name,
- start: Date.now(),
- };
- games.push(fakeGame);
- FluxDispatcher.dispatch({ type: "RUNNING_GAMES_CHANGE", removed: [], added: [fakeGame], games: games });
-
- const fn = data => {
- const progress = quest.config.configVersion === 1 ? data.userStatus.streamProgressSeconds : Math.floor(data.userStatus.progress.PLAY_ON_DESKTOP.value);
- showNotification({
- title: `${applicationName} - Quests Completer`,
- body: `Current progress: ${progress}/${secondsNeeded} seconds.`,
- icon: icon,
- });
-
- if (progress >= secondsNeeded) {
- showNotification({
- title: `${applicationName} - Quests Completer`,
- body: "Quest Completed",
- icon: icon,
- });
-
- const idx = games.indexOf(fakeGame);
- if (idx > -1) {
- games.splice(idx, 1);
- FluxDispatcher.dispatch({ type: "RUNNING_GAMES_CHANGE", removed: [fakeGame], added: [], games: [] });
- }
- FluxDispatcher.unsubscribe("QUESTS_SEND_HEARTBEAT_SUCCESS", fn);
- }
- };
- FluxDispatcher.subscribe("QUESTS_SEND_HEARTBEAT_SUCCESS", fn);
- });
- } else {
- const realFunc = ApplicationStreamingStore.getStreamerActiveStreamMetadata;
- ApplicationStreamingStore.getStreamerActiveStreamMetadata = () => ({
- id: applicationId,
- pid,
- sourceName: null
- });
-
- const fn = data => {
- const progress = quest.config.configVersion === 1 ? data.userStatus.streamProgressSeconds : Math.floor(data.userStatus.progress.STREAM_ON_DESKTOP.value);
- showNotification({
- title: `${applicationName} - Quests Completer`,
- body: `Current progress: ${progress}/${secondsNeeded} seconds.`,
- icon: icon,
- });
-
- if (progress >= secondsNeeded) {
- showNotification({
- title: `${applicationName} - Quests Completer`,
- body: "Quest Completed",
- icon: icon,
- });
-
- ApplicationStreamingStore.getStreamerActiveStreamMetadata = realFunc;
- FluxDispatcher.unsubscribe("QUESTS_SEND_HEARTBEAT_SUCCESS", fn);
- }
- };
- FluxDispatcher.subscribe("QUESTS_SEND_HEARTBEAT_SUCCESS", fn);
- }
- return;
- }
}
});