EarnBitMoon Auto Claim

Auto faucet claim and bonus with smart click.

您需要先安装一个扩展,例如 篡改猴Greasemonkey暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴Userscripts ,之后才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。

您需要先安装用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         EarnBitMoon Auto Claim
// @namespace    http://tampermonkey.net/
// @version      2.1
// @description  Auto faucet claim and bonus with smart click.
// @author       Rubystance
// @license      MIT
// @match        https://earnbitmoon.club/*
// @grant        none
// ==/UserScript==

(function () {
    'use strict';

    const MIN_DELAY = 1000;
    const MAX_DELAY = 3000;
    const CAPTCHA_TIMEOUT = 60000;
    const RESULT_TIMEOUT = 20000;
    const HARD_RELOAD_INTERVAL = 5 * 60 * 1000;

    let alreadyClicked = false;

    const sleep = ms => new Promise(resolve => setTimeout(resolve, ms));
    const randomDelay = () => sleep(Math.floor(Math.random() * (MAX_DELAY - MIN_DELAY + 1)) + MIN_DELAY);

    const smartClick = async (el, label = 'button') => {
        if (!el) return;
        try {
            const eventResult = el.dispatchEvent(new MouseEvent('click', {
                bubbles: true,
                cancelable: true,
                view: window
            }));
            if (!eventResult) throw new Error('dispatchEvent blocked');
            console.log(`[EarnBitMoon] Smart click (dispatch) on ${label}`);
        } catch (err) {
            console.warn(`[EarnBitMoon] dispatchEvent failed on ${label}, falling back to .click()`);
            try {
                el.click();
                console.log(`[EarnBitMoon] Fallback click() successful on ${label}`);
            } catch (e2) {
                console.error(`[EarnBitMoon] Both click methods failed on ${label}`, e2);
            }
        }
    };

    const isCaptchaSolved = () => {
        const turnstile = document.querySelector('input[name="cf-turnstile-response"]');
        const recaptcha = document.querySelector('#g-recaptcha-response');
        const hcaptcha = document.querySelector('textarea[name="h-captcha-response"]');
        const icon = document.querySelector('.iconcaptcha-wrap.solved, .iconcaptcha-done');
        return (
            (turnstile && turnstile.value.length > 10) ||
            (recaptcha && recaptcha.value.length > 10) ||
            (hcaptcha && hcaptcha.value.length > 10) ||
            icon
        );
    };

    const isButtonClickable = btn => {
        if (!btn) return false;
        const style = window.getComputedStyle(btn);
        return (
            style.display !== 'none' &&
            style.visibility !== 'hidden' &&
            style.opacity !== '0' &&
            !btn.disabled &&
            btn.offsetParent !== null
        );
    };

    async function waitForCaptchaAndPress() {
        console.log('[EarnBitMoon] Waiting for CAPTCHA and "Press & Win"...');
        const startTime = Date.now();

        while (Date.now() - startTime < CAPTCHA_TIMEOUT) {
            const pressBtn = document.querySelector('button.zxz');

            if (isCaptchaSolved() && isButtonClickable(pressBtn) && !alreadyClicked) {
                console.log('[EarnBitMoon] CAPTCHA solved. Claiming reward...');
                alreadyClicked = true;
                await randomDelay();
                await smartClick(pressBtn, '"Press & Win"');
                waitForResultOrReload();
                return;
            }

            await sleep(5000);
        }

        console.warn('[EarnBitMoon] CAPTCHA timeout. Reloading...');
        location.reload();
    }

    async function waitForResultOrReload() {
        console.log('[EarnBitMoon] Waiting for claim result...');
        const start = Date.now();

        while (Date.now() - start < RESULT_TIMEOUT) {
            const restartBtn = document.querySelector('.fa-rotate-right');
            const closeBtn = document.querySelector('.fa-xmark');

            if (restartBtn) {
                console.log('[EarnBitMoon] Claim successful.');
                return;
            }

            if (closeBtn && !restartBtn) {
                console.warn('[EarnBitMoon] Only close button visible. Reloading...');
                location.reload();
                return;
            }

            await sleep(2000);
        }

        console.warn('[EarnBitMoon] No result after timeout. Reloading...');
        location.reload();
    }

    async function clickRollNow() {
        await randomDelay();
        const rollBtn = [...document.querySelectorAll('button')].find(btn =>
            btn.innerText.includes('ROLL NOW') && btn.dataset.toggle === "modal"
        );
        if (rollBtn) {
            console.log('[EarnBitMoon] Clicking "ROLL NOW"...');
            await smartClick(rollBtn, '"ROLL NOW"');
        } else {
            console.warn('[EarnBitMoon] "ROLL NOW" button not found.');
        }
    }

    async function checkAndGoToBonus() {
        const bonusLink = [...document.querySelectorAll('a.btn')].find(a =>
            a.innerText.includes('Daily Bonus') && a.innerText.includes('1')
        );

        if (bonusLink) {
            console.log('[EarnBitMoon] Daily Bonus available. Going to bonus page...');
            bonusLink.click();
            return true;
        }

        return false;
    }

    async function handleBonusPage() {
        console.log('[EarnBitMoon] On bonus page...');
        const start = Date.now();

        while (Date.now() - start < 15000) {
            const claimBtn = [...document.querySelectorAll('button')].find(btn =>
                btn.innerText.includes('CLAIM DAILY BONUS')
            );

            if (claimBtn) {
                console.log('[EarnBitMoon] Clicking "CLAIM DAILY BONUS"...');
                await randomDelay();
                await smartClick(claimBtn, '"CLAIM DAILY BONUS"');

                const modalStart = Date.now();
                while (Date.now() - modalStart < 10000) {
                    const innerClaim = document.querySelector('#dailyBonus');
                    if (innerClaim) {
                        console.log('[EarnBitMoon] Clicking "Claim Coins"...');
                        await randomDelay();
                        await smartClick(innerClaim, '"Claim Coins"');
                        await sleep(4000);
                        location.href = '/faucet.html';
                        return;
                    }
                    await sleep(1000);
                }

                console.warn('[EarnBitMoon] "Claim Coins" button not found. Reloading...');
                location.reload();
                return;
            }

            await sleep(1000);
        }

        console.warn('[EarnBitMoon] Bonus claim button not detected. Returning to faucet...');
        location.href = '/faucet.html';
    }

    function hardReloadTimer() {
        setTimeout(() => {
            console.log('[EarnBitMoon] Hard reload triggered after 5 minutes.');
            location.reload();
        }, HARD_RELOAD_INTERVAL);
    }

    async function main() {
        console.log(`[EarnBitMoon] Current page: ${location.pathname}`);

        if (location.pathname === '/bonus.html') {
            await handleBonusPage();
            return;
        }

        const wentToBonus = await checkAndGoToBonus();
        if (wentToBonus) return;

        await sleep(2000);
        await clickRollNow();
        await waitForCaptchaAndPress();
        hardReloadTimer();
    }

    window.addEventListener('load', main);
})();