2ch-CAPTCHA-MATH

Автоматическое решение математической CAPTCHA на 2ch.hk

Bu betiği kurabilmeniz için Tampermonkey, Greasemonkey ya da Violentmonkey gibi bir kullanıcı betiği eklentisini kurmanız gerekmektedir.

Bu betiği kurabilmeniz için Tampermonkey ya da Violentmonkey gibi bir kullanıcı betiği eklentisini kurmanız gerekmektedir.

Bu betiği kurabilmeniz için Tampermonkey ya da Violentmonkey gibi bir kullanıcı betiği eklentisini kurmanız gerekmektedir.

Bu betiği kurabilmeniz için Tampermonkey ya da Userscripts gibi bir kullanıcı betiği eklentisini kurmanız gerekmektedir.

You will need to install an extension such as Tampermonkey to install this script.

Bu komut dosyasını yüklemek için bir kullanıcı komut dosyası yöneticisi uzantısı yüklemeniz gerekecek.

(Zaten bir kullanıcı komut dosyası yöneticim var, kurmama izin verin!)

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

(Zateb bir user-style yöneticim var, yükleyeyim!)

// ==UserScript==
// @name         2ch-CAPTCHA-MATH
// @license      MIT
// @version      0.2
// @author       Master2ch
// @description  Автоматическое решение математической CAPTCHA на 2ch.hk
// @homepageURL  https://t.me/Master2ch
// @match        *://2ch.hk/*
// @namespace    https://greasyfork.org/ru/users/1120123
// @grant        none
// ==/UserScript==

(function() {
    'use strict';

    /**
     * Логгер для отладки и вывода сообщений в консоль.
     */
    const logger = {
        info: (message) => {
            console.log(`[2ch-CAPTCHA-MATH] ${message}`);
        },
        warn: (message) => {
            console.warn(`[2ch-CAPTCHA-MATH] ${message}`);
        },
        error: (message, err) => {
            console.error(`[2ch-CAPTCHA-MATH] ${message}`, err);
        }
    };

    /**
     * Решает математическое уравнение, в котором один из операндов или результат неизвестен.
     * @param {string} equation Строка уравнения, например "2 + ? = 5" или "? * 3 = 6".
     * @returns {number|null} Результат уравнения или null, если решить не удалось.
     */
    function solveEquation(equation) {
        // Улучшенное регулярное выражение для более точного парсинга,
        // учитывая возможные пробелы и гарантируя захват оператора и '='
        const match = equation.match(/\s*(\d+|\?)\s*([-+*/\\])\s*(\d+|\?)\s*=\s*(\d+|\?)\s*/);

        if (!match) {
            logger.warn(`Не удалось разобрать уравнение: "${equation}"`);
            return null;
        }

        // Извлекаем части: match[1] - первый операнд, match[2] - оператор,
        // match[3] - второй операнд, match[4] - результат.
        let operand1Str = match[1];
        let operator = match[2];
        let operand2Str = match[3];
        let resultStr = match[4];

        // Преобразуем строки в числа, если это не "?"
        const operand1 = operand1Str === "?" ? null : parseFloat(operand1Str);
        const operand2 = operand2Str === "?" ? null : parseFloat(operand2Str);
        const result = resultStr === "?" ? null : parseFloat(resultStr);

        // Обрабатываем оператор деления, где 2ch может использовать как / так и \
        if (operator === '\\') {
            operator = '/';
        }

        // Логика решения
        if (operand1 === null) {
            switch (operator) {
                case "/": return (operand2 !== 0) ? result * operand2 : null; // Деление на ноль
                case "*": return (operand2 !== 0) ? result / operand2 : null;
                case "+": return result - operand2;
                case "-": return result + operand2;
            }
        } else if (operand2 === null) {
            switch (operator) {
                case "/": return (result !== 0) ? operand1 / result : null; // Деление на ноль
                case "*": return (operand1 !== 0) ? result / operand1 : null;
                case "+": return result - operand1;
                case "-": return operand1 - result;
            }
        } else if (result === null) {
            switch (operator) {
                case "/": return (operand2 !== 0) ? operand1 / operand2 : null; // Деление на ноль
                case "*": return operand1 * operand2;
                case "+": return operand1 + operand2;
                case "-": return operand1 - operand2;
            }
        }
        logger.warn(`Неподдерживаемый сценарий для уравнения: "${equation}"`);
        return null; // Возвращаем null, если ни одно условие не подошло
    }

    /**
     * Обрабатывает изменение значения в поле ввода CAPTCHA.
     * @param {Event} event Событие ввода.
     */
    function handleCaptchaInput(event) {
        const inputElement = event.target;
        const enteredText = inputElement.value;

        // Регулярное выражение для проверки, похоже ли введенное значение на уравнение CAPTCHA.
        // Оно ищет [число или ?] [оператор] [число или ?] = [число или ?]
        const captchaPattern = /^\s*(\d+|\?)\s*[-+*/\\]\s*(\d+|\?)\s*=\s*(\d+|\?)\s*$/;

        if (captchaPattern.test(enteredText)) {
            const solution = solveEquation(enteredText);
            if (solution !== null && !isNaN(solution)) { // Проверяем, что решение не null и является числом
                logger.info(`Найдено уравнение "${enteredText}", решение: ${solution}`);
                inputElement.value = Math.round(solution); // Округляем до целого числа, т.к. CAPTCHA обычно требует целые
                inputElement.dispatchEvent(new Event('change', { bubbles: true })); // Имитируем событие 'change'
                inputElement.dispatchEvent(new Event('input', { bubbles: true })); // Имитируем событие 'input' на всякий случай
            } else {
                logger.warn(`Не удалось решить "${enteredText}" или получен некорректный результат.`);
            }
        }
    }

    // --- Инициализация скрипта ---
    function initialize() {
        // Ищем все элементы CAPTCHA. Используем MutationObserver для динамически загружаемых CAPTCHA.
        const observer = new MutationObserver((mutations) => {
            mutations.forEach((mutation) => {
                if (mutation.addedNodes && mutation.addedNodes.length > 0) {
                    mutation.addedNodes.forEach((node) => {
                        // Проверяем, является ли добавленный узел элементом или содержит нужные элементы
                        if (node.nodeType === 1) { // ELEMENT_NODE
                            const inputElements = node.querySelectorAll('.captcha__val.input');
                            inputElements.forEach(inputElement => {
                                // Добавляем флаг, чтобы не добавлять обработчик несколько раз
                                if (!inputElement.dataset.captchaMathProcessed) {
                                    inputElement.dataset.captchaMathProcessed = 'true';
                                    inputElement.maxLength = 20; // Устанавливаем maxlength
                                    inputElement.addEventListener('input', handleCaptchaInput);
                                    logger.info(`Добавлен обработчик к элементу CAPTCHA: ${inputElement.outerHTML}`);
                                }
                            });
                        }
                    });
                }
            });
        });

        // Начинаем наблюдение за изменениями в теле документа
        observer.observe(document.body, { childList: true, subtree: true });

        // Также сразу ищем существующие элементы CAPTCHA на момент загрузки страницы
        document.querySelectorAll('.captcha__val.input').forEach(inputElement => {
            if (!inputElement.dataset.captchaMathProcessed) {
                inputElement.dataset.captchaMathProcessed = 'true';
                inputElement.maxLength = 20;
                inputElement.addEventListener('input', handleCaptchaInput);
                logger.info(`Добавлен обработчик к существующему элементу CAPTCHA: ${inputElement.outerHTML}`);
            }
        });

        logger.info("2ch-CAPTCHA-MATH скрипт загружен и готов.");
    }

    // Запускаем инициализацию после загрузки DOM
    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', initialize);
    } else {
        initialize();
    }
})();