Bouton de clic automatique activé

Ce script détecte et clique automatiquement sur les boutons qui deviennent activés. Il a été testé et fonctionne correctement sur la page https://app.runwayml.com/*.

Version au 07/06/2024. Voir la dernière version.

Vous devrez installer une extension telle que Tampermonkey, Greasemonkey ou Violentmonkey pour installer ce script.

Vous devrez installer une extension telle que Tampermonkey ou Violentmonkey pour installer ce script.

Vous devrez installer une extension telle que Tampermonkey ou Violentmonkey pour installer ce script.

Vous devrez installer une extension telle que Tampermonkey ou Userscripts pour installer ce script.

Vous devrez installer une extension telle que Tampermonkey pour installer ce script.

Vous devrez installer une extension de gestionnaire de script utilisateur pour installer ce script.

(J'ai déjà un gestionnaire de scripts utilisateur, laissez-moi l'installer !)

Vous devrez installer une extension telle que Stylus pour installer ce style.

Vous devrez installer une extension telle que Stylus pour installer ce style.

Vous devrez installer une extension telle que Stylus pour installer ce style.

Vous devrez installer une extension du gestionnaire de style pour utilisateur pour installer ce style.

Vous devrez installer une extension du gestionnaire de style pour utilisateur pour installer ce style.

Vous devrez installer une extension du gestionnaire de style pour utilisateur pour installer ce style.

(J'ai déjà un gestionnaire de style utilisateur, laissez-moi l'installer!)

// ==UserScript==
// @name         Auto Click Enabled Button
// @namespace    http://tampermonkey.net/
// @version      2.5
// @description  探测并自动点击变为可用状态的按钮
// @author       HDR10
// @match        https://*/*
// @grant        none
// @license      Apache License 2.0
// @license-link https://www.apache.org/licenses/LICENSE-2.0

// @name:en      Auto Click Enabled Button
// @description:en This script detects and automatically clicks buttons that become enabled. It has been tested and works correctly on the https://app.runwayml.com/* page.

// @name:zh-CN   自动点击启用按钮
// @description:zh-CN 这个脚本可以探测并自动点击变为可用状态的按钮。该脚本于 https://app.runwayml.com/* 页面测试正常运行。

// @name:hi      ऑटो क्लिक सक्षम बटन
// @description:hi यह स्क्रिप्ट बटन को पहचानती है और स्वचालित रूप से क्लिक करती है जो सक्षम हो जाते हैं। इसका परीक्षण https://app.runwayml.com/* पृष्ठ पर किया गया है और यह सही ढंग से काम करता है।

// @name:fr      Bouton de clic automatique activé
// @description:fr Ce script détecte et clique automatiquement sur les boutons qui deviennent activés. Il a été testé et fonctionne correctement sur la page https://app.runwayml.com/*.

// @name:ar      زر النقر التلقائي عند التمكين
// @description:ar يكتشف هذا البرنامج النصي الأزرار التي تصبح ممكّنة وينقر عليها تلقائيًا. تم اختباره ويعمل بشكل صحيح على صفحة https://app.runwayml.com/*.

// @name:bg      Автоматично кликване на активиран бутон
// @description:bg Този скрипт открива и автоматично кликва върху бутони, които стават активни. Тестван е и работи правилно на страницата https://app.runwayml.com/*.

// @name:ru      Автоматическое нажатие на активированные кнопки
// @description:ru Этот скрипт обнаруживает и автоматически нажимает кнопки, которые становятся активными. Он был протестирован и работает правильно на странице https://app.runwayml.com/*.

// @name:pt-BR   Botão de Clique Automático Habilitado
// @description:pt-BR Este script detecta e clica automaticamente em botões que se tornam habilitados. Ele foi testado e funciona corretamente na página https://app.runwayml.com/*.

// @name:id      Tombol Klik Otomatis yang Diaktifkan
// @description:id Skrip ini mendeteksi dan mengklik tombol yang menjadi aktif secara otomatis. Skrip ini telah diuji dan berfungsi dengan baik di halaman https://app.runwayml.com/*.

// @name:zh-TW   自動點擊啟用按鈕
// @description:zh-TW 此腳本可以檢測並自動點擊變為可用狀態的按鈕。經測試,該腳本在 https://app.runwayml.com/* 頁面上正常運行。
// ==/UserScript==
// ==/UserScript==

(function() {
    'use strict';

    // 创建浮窗
    const floatWindow = document.createElement('div');
    floatWindow.style.position = 'fixed';
    floatWindow.style.bottom = '10px';
    floatWindow.style.right = '10px';
    floatWindow.style.width = '400px';
    floatWindow.style.height = '250px';
    floatWindow.style.backgroundColor = 'white';
    floatWindow.style.border = '1px solid black';
    floatWindow.style.color = 'black';
    floatWindow.style.padding = '10px';
    floatWindow.style.overflowY = 'auto';
    floatWindow.style.zIndex = '10000';
    floatWindow.innerHTML = `
        <div>
            <div id="dragHandle" style="width: 20px; height: 20px; background-color: gray; position: absolute; top: 5px; right: 5px; cursor: move;"></div>
            <h3>自动点击变为可用的button</h3>
            <p id="statusLabel">自动点击已停止</p>
            <button id="startBtn">启用</button>
            <button id="stopBtn">停止</button>
            <label for="clickLimit">点击几次后停止:</label>
            <input type="number" id="clickLimit" value="0" min="0" style="width: 50px;">
            <div id="logContainer" style="height: 100px; background-color: white; border: 1px solid black; overflow-y: auto;"></div>
            <button id="clearLogBtn">清除log</button>
            <button id="minimizeBtn">最小化</button>
        </div>
    `;
    document.body.appendChild(floatWindow);

    // 创建最小化图标
    const minimizeIcon = document.createElement('div');
    minimizeIcon.style.position = 'fixed';
    minimizeIcon.style.bottom = '10px';
    minimizeIcon.style.right = '10px';
    minimizeIcon.style.width = '40px';
    minimizeIcon.style.height = '40px';
    minimizeIcon.style.backgroundColor = 'white';
    minimizeIcon.style.border = '1px solid black';
    minimizeIcon.style.borderRadius = '50%';
    minimizeIcon.style.display = 'flex';
    minimizeIcon.style.alignItems = 'center';
    minimizeIcon.style.justifyContent = 'center';
    minimizeIcon.style.cursor = 'pointer';
    minimizeIcon.style.zIndex = '10000';
    minimizeIcon.innerHTML = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8 0-4.41 3.59-8 8-8 4.41 0 8 3.59 8 8 0 4.41-3.59 8-8 8zm-1-13h2v6h-2zm0 8h2v2h-2z"/></svg>`;
    minimizeIcon.style.display = 'none';
    document.body.appendChild(minimizeIcon);

    let observer;
    let autoClickEnabled = false;
    let clickCount = 0;
    let clickLimit = 0;

    document.getElementById('startBtn').addEventListener('click', function() {
        autoClickEnabled = true;
        clickCount = 0;
        clickLimit = parseInt(document.getElementById('clickLimit').value, 10);
        document.getElementById('statusLabel').textContent = '自动点击已启用';
        document.getElementById('statusLabel').style.color = 'green';
        minimizeIcon.style.backgroundColor = 'green';
        startObserving();
    });

    document.getElementById('stopBtn').addEventListener('click', function() {
        autoClickEnabled = false;
        document.getElementById('statusLabel').textContent = '自动点击已停止';
        document.getElementById('statusLabel').style.color = 'black';
        minimizeIcon.style.backgroundColor = 'white';
        stopObserving();
    });

    document.getElementById('clearLogBtn').addEventListener('click', function() {
        document.getElementById('logContainer').innerHTML = '';
    });

    document.getElementById('minimizeBtn').addEventListener('click', function() {
        floatWindow.style.display = 'none';
        minimizeIcon.style.display = 'flex';
    });

    minimizeIcon.addEventListener('click', function() {
        floatWindow.style.display = 'block';
        minimizeIcon.style.display = 'none';
    });

    function startObserving() {
        const config = { attributes: true, childList: true, subtree: true };
        observer = new MutationObserver(mutationsList => {
            for (let mutation of mutationsList) {
                if (mutation.type === 'attributes' && mutation.attributeName === 'disabled') {
                    const target = mutation.target;
                    if (target.tagName.toLowerCase() === 'button' && !target.disabled && autoClickEnabled) {
                        target.click();
                        clickCount++;
                        logClick(target);
                        if (clickLimit > 0 && clickCount >= clickLimit) {
                            autoClickEnabled = false;
                            document.getElementById('statusLabel').textContent = '自动点击已停止';
                            document.getElementById('statusLabel').style.color = 'black';
                            minimizeIcon.style.backgroundColor = 'white';
                            stopObserving();
                        }
                    }
                }
            }
        });

        observer.observe(document.body, config);
    }

    function stopObserving() {
        if (observer) {
            observer.disconnect();
            observer = null;
        }
    }

    function logClick(target) {
        const logContainer = document.getElementById('logContainer');
        const timestamp = new Date().toLocaleTimeString();
        const logEntry = document.createElement('div');
        logEntry.textContent = `${timestamp} - 点击了按钮: ${target.innerText || target.id || 'Unknown'}`;
        logContainer.appendChild(logEntry);

        // 保持日志最多显示10行
        while (logContainer.children.length > 10) {
            logContainer.removeChild(logContainer.firstChild);
        }

        // 自动滚动到最新日志
        logContainer.scrollTop = logContainer.scrollHeight;
    }

    // 拖动浮窗功能
    const dragHandle = document.getElementById('dragHandle');
    let isDragging = false;
    let startX, startY, initialX, initialY;

    dragHandle.addEventListener('mousedown', function(e) {
        isDragging = true;
        startX = e.clientX;
        startY = e.clientY;
        initialX = floatWindow.offsetLeft;
        initialY = floatWindow.offsetTop;
        document.addEventListener('mousemove', onMouseMove);
        document.addEventListener('mouseup', onMouseUp);
    });

    function onMouseMove(e) {
        if (isDragging) {
            const dx = e.clientX - startX;
            const dy = e.clientY - startY;
            floatWindow.style.left = initialX + dx + 'px';
            floatWindow.style.top = initialY + dy + 'px';
        }
    }

    function onMouseUp() {
        isDragging = false;
        document.removeEventListener('mousemove', onMouseMove);
        document.removeEventListener('mouseup', onMouseUp);
    }
})();