Keran Auto Faucet

Automates keran.co: redirects to "Home" after claim, refreshes captcha if not solved in 15s, waits up to 60s for solution, and reloads page if

目前為 2025-08-03 提交的版本,檢視 最新版本

// ==UserScript==
// @name         Keran Auto Faucet
// @namespace    https://tampermonkey.net/
// @version      1.0
// @description  Automates keran.co: redirects to "Home" after claim, refreshes captcha if not solved in 15s, waits up to 60s for solution, and reloads page if
//               stuck on waiting.
// @author       Rubystance
// @license      MIT
// @match        https://keran.co/*
// @grant        none
// ==/UserScript==

(function () {
    'use strict';

    if (window.hasRunKeranAutoClaim) return;
    window.hasRunKeranAutoClaim = true;

    const wait = (ms) => new Promise(resolve => setTimeout(resolve, ms));
    const randomDelay = (min = 4000, max = 7000) =>
        wait(Math.floor(Math.random() * (max - min + 1)) + min);

    async function clickIfExists(selector) {
        const el = document.querySelector(selector);
        if (el) {
            el.click();
            console.log("✅ Clicked:", selector);
            return true;
        }
        console.log("❌ Element not found:", selector);
        return false;
    }

    async function waitForElement(selector, timeout = 60000) {
        const interval = 1000;
        let waited = 0;
        while (!document.querySelector(selector) && waited < timeout) {
            await wait(interval);
            waited += interval;
        }
        return document.querySelector(selector);
    }

    function isCaptchaSolved() {
        const gRecaptcha = document.querySelector('.g-recaptcha-response');
        const hCaptcha = document.querySelector('input[name="h-captcha-response"]');
        const turnstile = document.querySelector('input[name="cf-turnstile-response"]');

        return (
            (gRecaptcha && gRecaptcha.value.trim().length > 0) ||
            (hCaptcha && hCaptcha.value.trim().length > 0) ||
            (turnstile && turnstile.value.trim().length > 0)
        );
    }

    async function waitForCaptchaSolved(timeout = 60000) {
        const interval = 2000;
        let waited = 0;

        let refreshTried = false;

        while (waited < timeout) {
            if (isCaptchaSolved()) return true;

            if (!refreshTried && waited >= 15000) {
                console.log("🔁 Captcha not solved after 15s, trying to click the refresh captcha button...");
                const svgBtn = document.querySelector('svg[width="25"][height="25"]');
                if (svgBtn) {
                    svgBtn.click();
                    console.log("🔄 Refresh captcha button clicked.");
                } else {
                    console.log("❌ Refresh SVG button not found.");
                }
                refreshTried = true;
            }

            await wait(interval);
            waited += interval;
        }
        return false;
    }

    async function handlePage() {
        const path = window.location.pathname;
        console.log("🔄 Current path:", path);

        if (path === "/dashboard.php") {
            await randomDelay();
            await clickIfExists('a.button.is-normal.is-info[href="/faucet.php"]');
        }

        else if (path === "/faucet.php") {
            await randomDelay();
            await clickIfExists('button.button.is-link[type="submit"]');
        }

        else if (path === "/captha.php") {
            console.log("🔍 Checking captcha button...");
            await randomDelay();

            const captchaBtn = document.querySelector('#submitBtn');

            if (captchaBtn && captchaBtn.disabled && captchaBtn.textContent.includes("Waiting")) {
                console.warn("🕒 Captcha button is disabled (Waiting...), waiting 20 seconds...");
                await wait(20000);

                const stillWaiting = captchaBtn.disabled && captchaBtn.textContent.includes("Waiting");
                if (stillWaiting) {
                    console.warn("🔄 Still 'Waiting...' after 20s. Reloading the page.");
                    location.reload();
                    return;
                } else {
                    console.log("✅ Button is now enabled! Continuing...");
                }
            }

            if (captchaBtn && !captchaBtn.disabled) {
                captchaBtn.click();
                console.log("✅ Clicked: Solve Captcha");
            }

            console.log("⏳ Waiting for captcha to be solved (max 60s)...");
            const solved = await waitForCaptchaSolved(60000);

            if (solved) {
                console.log("✅ Captcha solved! Waiting for final claim button...");
                await randomDelay();
                const claimFinal = await waitForElement('button.button.is-success[type="submit"]');
                if (claimFinal) {
                    await wait(3000);
                    claimFinal.click();
                    console.log("🎯 Final claim button clicked.");
                }
            } else {
                console.warn("⚠️ Captcha not solved after 60s.");
            }
        }

        else if (path === "/") {
            await randomDelay();
            const homeLink = document.querySelector('a[href="/"]');
            if (homeLink) {
                homeLink.click();
                console.log("🏠 Redirected to Home.");
            } else {
                console.log("🔍 Home link not found.");
            }
        }
    }

    handlePage();

    setInterval(() => {
        console.log("🔁 Automatic loop...");
        handlePage();
    }, 60000);
})();