Neopets Quest Log Helper

Links quest descriptions + auto claim rewards one-by-one.

当前为 2025-06-08 提交的版本,查看 最新版本

// ==UserScript==
// @name         Neopets Quest Log Helper
// @namespace    http://tampermonkey.net/
// @version      6.5
// @description  Links quest descriptions + auto claim rewards one-by-one.
// @match        https://www.neopets.com/questlog/
// @grant        none
// ==/UserScript==

(function () {
    'use strict';

    const LINKS = {
        customise: "/customise.phtml",
        fashionFever: "/games/game.phtml?game_id=805&size=regular&quality=high&play=true",
        inventory: "/inventory.phtml",
        homePage: "/home/index.phtml",
        generalStore: "/generalstore.phtml",
        healingSprings: "/faerieland/springs.phtml",
        wheelOfMisfortune: "/halloween/wheel/index.phtml",
        wheelOfKnowledge: "/medieval/knowledge.phtml",
        wheelOfExcitement: "/faerieland/wheel.phtml",
        wheelOfMediocrity: "/prehistoric/mediocrity.phtml"
    };

    function injectLinks() {
        document.querySelectorAll('.ql-task-description').forEach(task => {
            const text = task.textContent.toLowerCase();

            if (text.includes("customise")) {
                task.innerHTML = `<a href="${LINKS.customise}" target="_blank">Customise</a> your Neopet`;
            } else if (text.includes("play a game")) {
                task.innerHTML = `Play a game like <a href="${LINKS.fashionFever}" target="_blank">Fashion Fever</a>`;
            } else if (text.includes("groom")) {
                task.innerHTML = `Groom your Neopet using the <a href="${LINKS.inventory}" target="_blank">Inventory</a> or <a href="${LINKS.homePage}" target="_blank">Home Page</a>`;
            } else if (text.includes("feed")) {
                task.innerHTML = `Feed your Neopet using the <a href="${LINKS.inventory}" target="_blank">Inventory</a> or <a href="${LINKS.homePage}" target="_blank">Home Page</a>`;
            } else if (text.includes("purchase item")) {
                task.innerHTML = `Purchase item(s) from the <a href="${LINKS.generalStore}" target="_blank">General Store</a> or <a href="${LINKS.healingSprings}" target="_blank">Healing Springs</a>`;
            } else if (text.includes("wheel of misfortune")) {
                task.innerHTML = `Spin the <a href="${LINKS.wheelOfMisfortune}" target="_blank">Wheel of Misfortune</a>`;
            } else if (text.includes("wheel of knowledge")) {
                task.innerHTML = `Spin the <a href="${LINKS.wheelOfKnowledge}" target="_blank">Wheel of Knowledge</a>`;
            } else if (text.includes("wheel of excitement")) {
                task.innerHTML = `Spin the <a href="${LINKS.wheelOfExcitement}" target="_blank">Wheel of Excitement</a>`;
            } else if (text.includes("wheel of mediocrity")) {
                task.innerHTML = `Spin the <a href="${LINKS.wheelOfMediocrity}" target="_blank">Wheel of Mediocrity</a>`;
            }
        });
    }

    function autoClaimRewardsSequentially() {
        const buttons = Array.from(document.querySelectorAll('.ql-claim'))
            .filter(btn =>
                btn.offsetParent !== null &&
                !btn.disabled &&
                btn.textContent.toLowerCase().includes("claim")
            );

        if (!buttons.length) {
            console.log("✅ No claimable rewards.");
            claimFinalBonusReward(() => {
                console.log("🏁 All rewards including bonus claimed.");
            });
            return;
        }

        let index = 0;

        function claimNext() {
            if (index >= buttons.length) {
                claimFinalBonusReward(() => {
                    console.log("🏁 All rewards including bonus claimed.");
                });
                return;
            }

            const btn = buttons[index];
            console.log(`🎯 Clicking Claim Reward for quest ${btn.dataset.quest}`);
            btn.click();

            waitForPopupToClose(() => {
                index++;
                claimNext();
            });
        }

        claimNext();
    }

    function claimFinalBonusReward(callback = () => {}) {
    const bonusClaim = document.querySelector('#QuestLogBonusAlert');
    const bonusContainer = document.querySelector('#QuestLogBonus.ql-claim-bonus');

    if (bonusClaim && bonusContainer && getComputedStyle(bonusClaim).display !== 'none') {
        console.log("💰 Clicking visible 20,000 NP Claim bonus button...");

        // Usa .click() tradicional — mais confiável em DOM visível
        bonusClaim.click();

        waitForPopupToClose(() => {
            console.log("🎉 Bonus reward claimed.");
            callback();
        });
    } else {
        console.log("🔕 Bonus claim button not found or not visible.");
        callback();
    }
}

    function waitForPopupToClose(callback) {
        const closePopup = () => {
            const backBtn = [...document.querySelectorAll('.button-yellow__2020')]
                .find(btn => btn.textContent?.trim().toLowerCase().includes("back to quests"));
            const closeBtn = document.querySelector('.modal-close');
            const overlay = document.querySelector('.modal-overlay');

            if (backBtn) {
                console.log("🟡 Clicking Back to Quests");
                backBtn.click();
                return;
            }

            if (closeBtn) {
                console.log("❌ Clicking close (X)");
                closeBtn.click();
                return;
            }

            if (overlay) {
                console.log("🖱 Clicking outside overlay");
                overlay.click();
            }
        };

        const interval = setInterval(() => {
            const visible = document.querySelector('.neopets-modal, .modal-overlay');
            if (visible) {
                closePopup();
            } else {
                clearInterval(interval);
                setTimeout(callback, 600);
            }
        }, 400);
    }

    function waitForQuestsToLoad(ready) {
        const check = setInterval(() => {
            const loading = document.querySelector('#QuestLogLoader')?.offsetParent !== null;
            const loaded = document.querySelectorAll('.ql-task-description').length >= 1;

            if (!loading && loaded) {
                clearInterval(check);
                console.log("🚀 Quest Log ready!");
                ready();
            }
        }, 500);
    }

    waitForQuestsToLoad(() => {
        injectLinks();
        autoClaimRewardsSequentially();
    });
})();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址