Greasy Fork

[Premium] Faucetpay ReCaptcha/Antibot Rotator

Automates form filling and button clicking on Faucetpay Faucet websites, with ReCaptcha/Antibot handling.

目前为 2024-01-21 提交的版本。查看 最新版本

// ==UserScript==
// @name         [Premium] Faucetpay ReCaptcha/Antibot Rotator
// @namespace    https://greasyfork.org/users/1162863
// @version      1.3
// @description  Automates form filling and button clicking on Faucetpay Faucet websites, with ReCaptcha/Antibot handling.
// @author       Andrewblood
// @match        https://sollcrypto.com/home/page/*
// @match        https://cryptoclaps.com/earn/*
// @match        https://baltoniearn.com/claim/*
// @match        https://vptron.online/TRX/*
// @match        https://claimcoins.site/reward/*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=faucetpay.io
// @grant        GM_setValue
// @grant        GM_getValue
// @grant        GM_deleteValue
// @antifeature  referral-code
// @license      Andrewblood
// ==/UserScript==
/*

Automates form filling and button clicking on Faucetpay Faucet websites, with ReCaptcha/Antibot handling.

Features:
- Automatically fills and clicks buttons on supported Faucetpay Faucet websites.
- If the claim is done, it redirects to the next supported Faucet URL.
- Saves empty pages with timestamps to prevent revisiting within 6 hours.
- Provides an overlay for managing saved pages, clearing stored pages, displaying them, and saving Faucetpay email.

*/
(function() {
    'use strict';

    // Function to click a button
    function clickButton(selector) {
        var button = document.querySelector(selector);
        if (button) {
            button.click();
        }
    }

    // Function to check if an element is visible
    function isElementVisible(selector) {
        var element = document.querySelector(selector);
        return element && element.offsetWidth > 0 && element.offsetHeight > 0;
    }

    // Email overlay creation
    var overlay = document.createElement('div');
    overlay.id = 'emailInputOverlay';
    overlay.style.position = 'fixed';
    overlay.style.bottom = '10px';
    overlay.style.right = '10px';
    overlay.style.zIndex = '10000';

    // Create a button to clear stored URLs
    var clearStoredUrlsButton = document.createElement('button');
    clearStoredUrlsButton.id = 'clearStoredUrlsButton';
    clearStoredUrlsButton.style.padding = '5px';
    clearStoredUrlsButton.style.marginLeft = '5px';
    clearStoredUrlsButton.textContent = 'Clear Stored Pages';

    // Add an event listener for the new button
    clearStoredUrlsButton.addEventListener('click', function() {
        // Clear stored pages
        GM_deleteValue('storedUrls');
        console.log('Stored pages have been cleared.');
    });

    // Create a button to show stored URLs
    var showStoredUrlsButton = document.createElement('button');
    showStoredUrlsButton.id = 'showStoredUrlsButton';
    showStoredUrlsButton.style.padding = '5px';
    showStoredUrlsButton.style.marginLeft = '5px';
    showStoredUrlsButton.textContent = 'Show Stored Pages';

    // Add an event listener for the showStoredUrlsButton
    showStoredUrlsButton.addEventListener('click', function() {
        // Display stored pages in an overlay
        var storedUrls = GM_getValue('storedUrls', []);

        // Check if there are stored URLs
        if (storedUrls.length > 0) {
            // Create an overlay for the table
            var overlayTable = document.createElement('div');
            overlayTable.style.position = 'fixed';
            overlayTable.style.top = '50%';
            overlayTable.style.left = '50%';
            overlayTable.style.transform = 'translate(-50%, -50%)';
            overlayTable.style.zIndex = '10001';
            overlayTable.style.backgroundColor = '#fff';
            overlayTable.style.border = '1px solid #ddd';
            overlayTable.style.padding = '20px';
            overlayTable.style.maxHeight = '80%';
            overlayTable.style.overflowY = 'auto';

            // Create a close button for the overlay
            var closeButton = document.createElement('button');
            closeButton.textContent = 'Close';
            closeButton.style.padding = '8px';
            closeButton.style.marginTop = '10px';
            closeButton.addEventListener('click', function() {
                // Close the overlay when the close button is clicked
                document.body.removeChild(overlayTable);
            });

            // Create a table element
            var table = document.createElement('table');
            table.style.borderCollapse = 'collapse';
            table.style.width = '100%';

            // Create table headers
            var headers = ['URL', 'Time'];
            var headerRow = table.insertRow();
            for (var i = 0; i < headers.length; i++) {
                var headerCell = headerRow.insertCell(i);
                headerCell.style.border = '1px solid #ddd';
                headerCell.style.padding = '8px';
                headerCell.style.textAlign = 'left';
                headerCell.textContent = headers[i];

                // Add click event for sorting
                headerCell.addEventListener('click', function() {
                    sortTable(table, this.cellIndex);
                });
            }

            // Populate table with stored URLs and timestamps
            for (var j = 0; j < storedUrls.length; j++) {
                var storedUrl = storedUrls[j];
                var row = table.insertRow();

                var urlCell = row.insertCell(0);
                urlCell.style.border = '1px solid #ddd';
                urlCell.style.padding = '8px';
                urlCell.textContent = storedUrl.url;

                var timestampCell = row.insertCell(1);
                timestampCell.style.border = '1px solid #ddd';
                timestampCell.style.padding = '8px';
                timestampCell.textContent = storedUrl.timestamp;
            }

            // Append the table and close button to the overlay
            overlayTable.appendChild(table);
            overlayTable.appendChild(closeButton);

            // Add the overlay to the body
            document.body.appendChild(overlayTable);
        } else {
            // Display a message if there are no stored URLs
            alert('No stored pages found.');
        }
    });

    // Function to sort the table by column index
    function sortTable(table, columnIndex) {
        var rows = Array.from(table.rows).slice(1); // Exclude header row
        var sortOrder = 1;

        // Determine sorting order based on the current order of the column
        if (table.rows[0].cells[columnIndex].classList.contains('ascending')) {
            sortOrder = -1;
        }

        // Remove sorting classes from all columns
        for (var i = 0; i < table.rows[0].cells.length; i++) {
            table.rows[0].cells[i].classList.remove('ascending', 'descending');
        }

        // Sort the rows based on the content of the selected column
        rows.sort(function(a, b) {
            var textA = a.cells[columnIndex].textContent.trim().toUpperCase();
            var textB = b.cells[columnIndex].textContent.trim().toUpperCase();

            if (textA < textB) {
                return -1 * sortOrder;
            } else if (textA > textB) {
                return 1 * sortOrder;
            } else {
                return 0;
            }
        });

        // Clear and rebuild the table with the sorted rows
        while (table.rows.length > 1) {
            table.deleteRow(1);
        }

        for (var j = 0; j < rows.length; j++) {
            table.appendChild(rows[j]);
        }

        // Add sorting class to the header cell
        if (sortOrder === 1) {
            table.rows[0].cells[columnIndex].classList.add('ascending');
        } else {
            table.rows[0].cells[columnIndex].classList.add('descending');
        }
    }

    // Create an email input field
    var emailInput = document.createElement('input');
    emailInput.type = 'text';
    emailInput.id = 'emailInput';
    emailInput.placeholder = 'Faucetpay Email';
    emailInput.style.padding = '5px';

    // Create a save email button
    var saveEmailButton = document.createElement('button');
    saveEmailButton.id = 'saveEmailButton';
    saveEmailButton.style.padding = '5px';
    saveEmailButton.style.marginLeft = '5px';
    saveEmailButton.textContent = 'Save';

    // Add elements to the overlay
    overlay.appendChild(clearStoredUrlsButton);
    overlay.appendChild(showStoredUrlsButton);
    overlay.appendChild(emailInput);
    overlay.appendChild(saveEmailButton);

    // Add overlay to the body
    document.body.appendChild(overlay);

    // Get email value from Tampermonkey storage
    var storedEmail = GM_getValue('storedEmail', '');

    // Populate saved email address into the input field
    emailInput.value = storedEmail;

    // Add event listener for save email button
    saveEmailButton.addEventListener('click', function() {
        // Save entered email address
        var newEmail = emailInput.value;
        GM_setValue('storedEmail', newEmail);

        // Success notification (can be customized)
        alert('Email address saved successfully!');
    });

    if (
        (isElementVisible("body > div.container.flex-grow.my-4 > div.row.my-2 > div.col-12.col-md-8.col-lg-8.order-md-2.mb-4.text-center > center > div.form > div.alert.alert-danger.fade.show") &&
         document.querySelector("body > div.container.flex-grow.my-4 > div.row.my-2 > div.col-12.col-md-8.col-lg-8.order-md-2.mb-4.text-center > center > div.form > div.alert.alert-danger.fade.show")?.innerText === ' The faucet does not have sufficient funds for this transaction.') ||
        (isElementVisible("body > div.container.flex-grow.my-4 > div.row.my-2 > div.col-12.col-md-8.col-lg-8.order-md-2.mb-4.text-center > center > div.alert.alert-danger.fade.show") &&
         document.querySelector("body > div.container.flex-grow.my-4 > div.row.my-2 > div.col-12.col-md-8.col-lg-8.order-md-2.mb-4.text-center > center > div.alert.alert-danger.fade.show").innerText === ' Your daily claim limit has been reached. Please come back in tomorrow.')
    ) {
        // Element is visible, so save the URL with a timestamp in a list
        var currentPageUrl = window.location.href;

        // Check if "?r=" exists in the URL
        var indexOfRParameter = currentPageUrl.indexOf("?r=");
        if (indexOfRParameter !== -1) {
            // Take only the part of the URL before "?r="
            currentPageUrl = currentPageUrl.substring(0, indexOfRParameter);
        }

        var currentTimeStamp = new Date().toISOString().slice(0, 19).replace('T', ' '); // ISO-8601 format without milliseconds
        var urlWithTimestamp = { url: currentPageUrl, timestamp: currentTimeStamp };

        // Retrieve stored URLs with fallback to an empty array if not present
        var storedUrls = GM_getValue('storedUrls', []) || [];

        // Check if the page is already in the stored URLs
        var existingUrlIndex = storedUrls.findIndex(function (storedUrl) {
            return storedUrl.url === currentPageUrl;
        });

        if (existingUrlIndex !== -1) {
            // Page is already present, update the timestamp if more than 24 hours have passed
            var storedTimestamp = new Date(storedUrls[existingUrlIndex].timestamp).getTime();
            var currentTimestamp = new Date().getTime();

            if (currentTimestamp - storedTimestamp > 6 * 60 * 60 * 1000) {
                storedUrls[existingUrlIndex].timestamp = currentTimeStamp;
                GM_setValue('storedUrls', storedUrls);
            }
        } else {
            // Page is not present, add it to the list
            storedUrls.push(urlWithTimestamp);
            GM_setValue('storedUrls', storedUrls);
        }
    }

    // Check if the element with the text "satoshi" or specific error messages is visible
    if ((isElementVisible("body > div.container.flex-grow.my-4 > div.row.my-2 > div.col-12.col-md-8.col-lg-8.order-md-2.mb-4.text-center > center > div.form > div.alert.alert-success.fade.show") &&
         document.querySelector("body > div.container.flex-grow.my-4 > div.row.my-2 > div.col-12.col-md-8.col-lg-8.order-md-2.mb-4.text-center > center > div.form > div.alert.alert-success.fade.show").innerText.includes('satoshi')) ||
        (isElementVisible("body > div.container.flex-grow.my-4 > div.row.my-2 > div.col-12.col-md-8.col-lg-8.order-md-2.mb-4.text-center > center > div.form > div.alert.alert-danger.fade.show") &&
         document.querySelector("body > div.container.flex-grow.my-4 > div.row.my-2 > div.col-12.col-md-8.col-lg-8.order-md-2.mb-4.text-center > center > div.form > div.alert.alert-danger.fade.show").innerText === ' The faucet does not have sufficient funds for this transaction.') ||
        (isElementVisible("body > div.container.flex-grow.my-4 > div.row.my-2 > div.col-12.col-md-8.col-lg-8.order-md-2.mb-4.text-center > center > div.alert.alert-danger.fade.show") &&
         document.querySelector("body > div.container.flex-grow.my-4 > div.row.my-2 > div.col-12.col-md-8.col-lg-8.order-md-2.mb-4.text-center > center > div.alert.alert-danger.fade.show").innerText === ' Your daily claim limit has been reached. Please come back in tomorrow.')) {
        var currentURL = window.location.href;

        // Check if "?" exists in the URL
        var indexOfQuestionMark = currentURL.indexOf("?");
        if (indexOfQuestionMark !== -1) {
            // Take only the part of the URL before "?"
            currentURL = currentURL.substring(0, indexOfQuestionMark);
        }
        var urlIndex = 0;
        var urls = [
            "https://sollcrypto.com/home/page/bitcoin/",
            "https://sollcrypto.com/home/page/doge/",
            "https://sollcrypto.com/home/page/tron/",
            "https://sollcrypto.com/home/page/digibyte/",
            "https://sollcrypto.com/home/page/litecoin/",
            "https://sollcrypto.com/home/page/binance/",
            "https://sollcrypto.com/home/page/solana/",
            "https://sollcrypto.com/home/page/ethereum/",
            "https://sollcrypto.com/home/page/bch/",
            "https://sollcrypto.com/home/page/xrp/",
            "https://sollcrypto.com/home/page/dash/",
            "https://sollcrypto.com/home/page/zcash/",
            "https://cryptoclaps.com/earn/dogecoin/",
            "https://cryptoclaps.com/earn/tron/",
            "https://cryptoclaps.com/earn/digibyte/",
            "https://cryptoclaps.com/earn/litecoin/",
            "https://cryptoclaps.com/earn/binance/",
            "https://cryptoclaps.com/earn/solana/",
            "https://cryptoclaps.com/earn/ethereum/",
            "https://cryptoclaps.com/earn/bch/",
            "https://cryptoclaps.com/earn/xrp/",
            "https://cryptoclaps.com/earn/dash/",
            "https://cryptoclaps.com/earn/polygon/",
            "https://cryptoclaps.com/earn/usdt/",
            "https://cryptoclaps.com/earn/feyorra/",
            "https://cryptoclaps.com/earn/zcash/",
        ];

        // Find the index of the current URL in the list
        for (var i = 0; i < urls.length; i++) {
            if (currentURL === urls[i]) {
                urlIndex = i;
                break;
            }
        }

        // Debugging: Output stored URLs before the loop
        var storedUrlsBefore = GM_getValue('storedUrls', []);
        console.log('Stored URLs before the loop:\n', JSON.stringify(storedUrlsBefore, null, 2));

        // Redirect to the next URL only if a valid URL is found
        var foundValidUrl = false;
        do {
            if (urlIndex < urls.length - 1) {
                urlIndex++;
            } else {
                // If the last URL is reached, start again from the beginning
                urlIndex = 0;
            }

            // Check if the next URL is in the stored URLs with a timestamp and the timestamp is within 6 hours
            var nextUrl = urls[urlIndex];
            var storedUrls = GM_getValue('storedUrls', []);

            var isUrlInStoredList = Array.isArray(storedUrls) && storedUrls.some(function (storedUrl) {
                return storedUrl.url === nextUrl && (new Date().getTime() - new Date(storedUrl.timestamp).getTime()) < 6 * 60 * 60 * 1000; // 6 hours in milliseconds
            });

            if (!isUrlInStoredList) {
                foundValidUrl = true;
                console.log('Valid URL found:', nextUrl);

                // Redirect to the next URL
                window.location.href = nextUrl;
            } else {
                console.log('Invalid URL, skipping:', nextUrl);
            }
        } while (!foundValidUrl);
        // Console logs for completion
        console.log('Redirecting to the next URL:', nextUrl);

        // Debugging: Output updated stored URLs after the loop
        var storedUrlsAfter = GM_getValue('storedUrls', []);
        console.log('Stored URLs after the loop:\n', JSON.stringify(storedUrlsAfter, null, 2));

        // Redirect to the next URL
        window.location.href = nextUrl;

        // Debugging alert
        console.log('Debugging: Redirecting to the next URL.\n\nValid URL found: ' + nextUrl);
    } else {
        // Element is not visible, so proceed with the actions
        // Check if the Referral Code is in the URL, if not, add it
        var currentURL = window.location.href;
        var referralCode = '[email protected]';

        if (!currentURL.includes(referralCode)) {
            currentURL += referralCode;
            window.location.href = currentURL; // Redirect with the updated URL
        } else {
            // Continue with actions as the Referral Code is already present
            // If the Faucetpay email field is found, fill it with the saved email address
            var faucetpayEmailInput = document.querySelector("#address");
            if (faucetpayEmailInput) {
                faucetpayEmailInput.value = storedEmail;

                // Click the button after inserting the email address
                clickButton("body > div.container.flex-grow.my-4 > div.row.my-2 > div.col-12.col-md-8.col-lg-8.order-md-2.mb-4.text-center > center > form > div:nth-child(4) > button");

                // Check if the pop-up/overlay appears and click the login button if conditions are met
                var intervalId = setInterval(function() {
                    var antibotLinksValue = document.querySelector("#antibotlinks").value.length;
                    var recaptchaResponseValue = document.querySelector("#g-recaptcha-response").value.length;

                    if (antibotLinksValue > 1 && recaptchaResponseValue > 1) {
                        clearInterval(intervalId);

                        // Click the login button
                        clickButton("#login");
                    }
                }, 1000);
            }
        }
    }
})();