您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Автоматическое решение математической CAPTCHA на 2ch.hk
// ==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(); } })();