Turbo.cr Auto-Captcha Solver

Robust, CPU-efficient, and bot-safe Altcha solver for turbo.cr

이 스크립트를 설치하려면 Tampermonkey, Greasemonkey 또는 Violentmonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey와 같은 확장 프로그램을 설치해야 합니다.

이 스크립트를 설치하려면 Tampermonkey 또는 Violentmonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey 또는 Userscripts와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 유저 스크립트 관리자 확장 프로그램이 필요합니다.

(이미 유저 스크립트 관리자가 설치되어 있습니다. 설치를 진행합니다!)

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

(이미 유저 스타일 관리자가 설치되어 있습니다. 설치를 진행합니다!)

// ==UserScript==
// @name         Turbo.cr Auto-Captcha Solver
// @namespace    http://tampermonkey.net/
// @icon data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMzYiIGhlaWdodD0iMzYiIHZpZXdCb3g9IjAgMCAzNiAzNiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cmVjdCB4PSIyIiB5PSIyIiB3aWR0aD0iMzIiIGhlaWdodD0iMzIiIHJ4PSIxMiIgZmlsbD0iYmxhY2siIGZpbGwtb3BhY2l0eT0iMC4wNSIgZmlsdGVyPSJibHVyKDNweCkiLz48ZGVmcz48bGluZWFyR3JhZGllbnQgaWQ9ImciIHgxPSIwIiB5MT0iMzYiIHgyPSIzNiIgeTI9IjAiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIj48c3RvcCBvZmZzZXQ9IjAlIiBzdG9wLWNvbG9yPSIjRjQzRjVFIi8+PHN0b3Agb2Zmc2V0PSI1MCUiIHN0b3AtY29sb3I9IiNFRjQ0NDQiLz48c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiNGQkJGMjQiLz48L2xpbmVhckdyYWRpZW50PjwvZGVmcz48cmVjdCB3aWR0aD0iMzYiIGhlaWdodD0iMzYiIHJ4PSIxMiIgZmlsbD0idXJsKCNnKSIvPjwvc3ZnPg==
// @version      2.0
// @description  Robust, CPU-efficient, and bot-safe Altcha solver for turbo.cr
// @author       lol_nocode
// @match        https://turbo.cr/*
// @grant        none
// @run-at       document-start
// @license      MIT
// ==/UserScript==

(function() {
    'use strict';

    // Configuration
    const CONFIG = {
        debounceMs: 50,           // Wait 50ms after DOM changes settle before checking
        lockoutMs: 3000,          // Wait 3 seconds before allowing a retry on the same captcha
        lockAttr: 'data-gm-lock'  // Custom attribute to prevent duplicate clicks
    };

    /**
     * Safely triggers the captcha by simulating a human interacting with the label.
     * @param {HTMLElement} container - The main altcha container
     * @param {HTMLElement} checkbox - The hidden or styled input element
     */
    function interactWithCaptcha(container, checkbox) {
        // Find the label associated with the checkbox (most framework-safe way to click)
        const label = container.querySelector(`label[for="${checkbox.id}"]`);
        const targetElement = label || checkbox;

        // Apply a temporary lock to prevent spam-clicking while Altcha processes
        checkbox.setAttribute(CONFIG.lockAttr, 'true');

        console.log('[Auto-Captcha] Solving Altcha...');

        // 1. Focus the element natively
        targetElement.focus();

        // 2. Dispatch a native-like click sequence
        ['pointerdown', 'mousedown', 'pointerup', 'mouseup', 'click'].forEach(eventType => {
            targetElement.dispatchEvent(new MouseEvent(eventType, {
                view: window,
                bubbles: true,
                cancelable: true,
                buttons: 1
            }));
        });

        // 3. Fallback: Ensure the state changes if the native click failed
        if (!checkbox.checked) {
            checkbox.checked = true;
            checkbox.dispatchEvent(new Event('input', { bubbles: true }));
            checkbox.dispatchEvent(new Event('change', { bubbles: true }));
        }

        // Release the lock after a few seconds in case the captcha failed and reset
        setTimeout(() => {
            if (checkbox.hasAttribute(CONFIG.lockAttr)) {
                checkbox.removeAttribute(CONFIG.lockAttr);
            }
        }, CONFIG.lockoutMs);
    }

    /**
     * Scans the DOM for unverified, unlocked captchas.
     */
    function scanAndSolve() {
        try {
            const containers = document.querySelectorAll('.altcha[data-state="unverified"]');

            containers.forEach(container => {
                const checkbox = container.querySelector('.altcha-checkbox input[type="checkbox"]');

                // Only interact if we found the checkbox and it isn't currently locked by our script
                if (checkbox && !checkbox.hasAttribute(CONFIG.lockAttr)) {
                    interactWithCaptcha(container, checkbox);
                }
            });
        } catch (error) {
            console.error('[Auto-Captcha] Error during scan:', error);
        }
    }

    // --- Debounced Mutation Observer ---
    let debounceTimer;

    const observer = new MutationObserver(() => {
        clearTimeout(debounceTimer);
        debounceTimer = setTimeout(scanAndSolve, CONFIG.debounceMs);
    });

    // Start observing as soon as the body or documentElement is available
    const targetNode = document.body || document.documentElement;
    if (targetNode) {
        observer.observe(targetNode, {
            childList: true,
            subtree: true,
            attributes: true,
            attributeFilter: ['data-state'] // Only trigger on relevant state changes
        });
    }

    // Initial check on load
    scanAndSolve();

})();