Work.ink Auto Clicker Human-Like

Auto clicks Work.ink buttons with human-like mouse events, random delays

您需要先安裝使用者腳本管理器擴展,如 TampermonkeyGreasemonkeyViolentmonkey 之後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyUserscripts 後才能安裝該腳本。

你需要先安裝一款使用者腳本管理器擴展,比如 Tampermonkey,才能安裝此腳本

您需要先安裝使用者腳本管理器擴充功能後才能安裝該腳本。

(我已經安裝了使用者腳本管理器,讓我安裝!)

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

(我已經安裝了使用者樣式管理器,讓我安裝!)

// ==UserScript==
// @name         Work.ink Auto Clicker Human-Like
// @namespace    http://tampermonkey.net/
// @version      1.6
// @description  Auto clicks Work.ink buttons with human-like mouse events, random delays
// @author       Shiva
// @match        *://*.work.ink/*
// @grant        none
// @license      MIT
// ==/UserScript==

(function() {
    'use strict';

    // 🔹 Helper: random wait (1–3s by default)
    function wait(min = 1000, max = 3000) {
        const delay = Math.floor(Math.random() * (max - min + 1)) + min;
        return new Promise(resolve => setTimeout(resolve, delay));
    }

    // 🔹 Human-like click for normal steps
    function simulateMouseClick(element) {
        if (!element) return false;

        element.scrollIntoView({ behavior: "smooth", block: "center" });
        element.focus();

        const rect = element.getBoundingClientRect();
        const clientX = rect.left + rect.width / 2 + (Math.random() * 4 - 2); // jitter
        const clientY = rect.top + rect.height / 2 + (Math.random() * 4 - 2);

        const opts = {
            bubbles: true,
            cancelable: true,
            view: window,
            clientX,
            clientY,
            screenX: window.screenX + clientX,
            screenY: window.screenY + clientY,
            buttons: 1
        };

        const events = [
            "pointerover", "pointerenter", "mouseover", "mouseenter",
            "pointerdown", "mousedown",
            "pointerup", "mouseup", "click"
        ];

        events.forEach((type, i) => {
            setTimeout(() => {
                element.dispatchEvent(new PointerEvent(type, opts));
            }, i * (10 + Math.random() * 30));
        });

        return true;
    }

    // 🔹 Helper: wait for element
    function waitForElement(selector, timeout = 60000) {
        return new Promise((resolve, reject) => {
            const start = Date.now();
            const interval = setInterval(() => {
                const el = document.querySelector(selector);
                if (el) {
                    clearInterval(interval);
                    resolve(el);
                } else if (Date.now() - start > timeout) {
                    clearInterval(interval);
                    reject(`Timeout waiting for element: ${selector}`);
                }
            }, 500);
        });
    }

    // 🔹 YOUR ORIGINAL final button logic (unchanged)
    function waitAndClickFinalButton(selector, delay = 1000) {
        const interval = setInterval(() => {
            const el = document.querySelector(selector);
            if (el && !el.disabled && el.offsetParent !== null) {
                console.log("✅ Final button is now enabled. Clicking...");

                el.scrollIntoView({ behavior: "smooth", block: "center" });
                el.focus();

                ['pointerdown', 'mousedown', 'mouseup', 'click'].forEach(type => {
                    el.dispatchEvent(new MouseEvent(type, {
                        bubbles: true,
                        cancelable: true,
                        view: window,
                        buttons: 1
                    }));
                });

                console.log("✅ Final button clicked. Stopping retries.");
                clearInterval(interval);
            } else {
                console.log("⏳ Final button still disabled. Waiting...");
            }
        }, delay);
    }

    // 🔹 Step sequence
    (async function runSteps() {
        try {
            const el1 = await waitForElement('div.button.large.accessBtn');
            console.log("Step 1: Go To Destination");
            await wait();
            simulateMouseClick(el1);

            const adsBtn = await waitForElement('button:contains("Continue With Ads")');
            console.log("Step 2: Continue With Ads");
            await wait();
            simulateMouseClick(adsBtn);

            const el2 = await waitForElement('div.button.large.accessBtn');
            console.log("Step 3: Go To Destination Again");
            await wait();
            simulateMouseClick(el2);

            const finalBtn = await waitForElement('button span:contains("Proceed to Safe Destination")');
            console.log("Step 4: Proceed to Safe Destination");
            await wait();
            simulateMouseClick(finalBtn.closest("button"));

            console.log("⏳ Waiting for final access button...");
            waitAndClickFinalButton('#access-offers', 5000);

        } catch (err) {
            console.error("⚠️ Script error:", err);
        }
    })();

    // 🔹 Add :contains() pseudo support
    (function() {
        const contains = (selector) => {
            const regex = /:contains\(["']?(.+?)["']?\)/;
            if (!regex.test(selector)) return null;
            const text = selector.match(regex)[1];
            const baseSelector = selector.replace(regex, '');
            return [...document.querySelectorAll(baseSelector)]
                .find(el => el.textContent.trim().includes(text));
        };

        document.querySelector = new Proxy(document.querySelector, {
            apply(target, thisArg, args) {
                if (args[0].includes(':contains')) {
                    return contains(args[0]);
                }
                return Reflect.apply(target, thisArg, args);
            }
        });
    })();

    // 🔹 Remove "done" banners
    const observer = new MutationObserver(() => {
        const banner = document.querySelector('.done-banner-container');
        if (banner) banner.remove();
    });
    observer.observe(document.body, { childList: true, subtree: true });

})();