// ==UserScript==
// @name Auto Click Enabled Button
// @name:zh-CN 自动点击启用按钮
// @name:en Auto Click Enabled Button
// @name:hi ऑटो क्लिक सक्षम बटन
// @name:fr Bouton de clic automatique activé
// @name:ar زر النقر التلقائي عند التمكين
// @name:bg Автоматично кликване на активиран бутон
// @name:ru Автоматическое нажатие на активированные кнопки
// @name:pt-BR Botão de Clique Automático Habilitado
// @name:id Tombol Klik Otomatis yang Diaktifkan
// @name:zh-TW 自動點擊啟用按鈕
// @namespace http://tampermonkey.net/
// @version 2.6
// @description This script detects and automatically clicks buttons that become enabled
// @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.
// @description:zh-CN 这个脚本可以探测并自动点击变为可用状态的按钮。该脚本于 https://app.runwayml.com/* 页面测试正常运行。
// @description:hi यह स्क्रिप्ट बटन को पहचानती है और स्वचालित रूप से क्लिक करती है जो सक्षम हो जाते हैं। इसका परीक्षण https://app.runwayml.com/* पृष्ठ पर किया गया है और यह सही ढंग से काम करता है।
// @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/*.
// @description:ar يكتشف هذا البرنامج النصي الأزرار التي تصبح ممكّنة وينقر عليها تلقائيًا. تم اختباره ويعمل بشكل صحيح على صفحة https://app.runwayml.com/*.
// @description:bg Този скрипт открива и автоматично кликва върху бутони, които стават активни. Тестван е и работи правилно на страницата https://app.runwayml.com/*.
// @description:ru Этот скрипт обнаруживает и автоматически нажимает кнопки, которые становятся активными. Он был протестирован и работает правильно на странице https://app.runwayml.com/*.
// @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/*.
// @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/*.
// @description:zh-TW 此腳本可以檢測並自動點擊變為可用狀態的按鈕。經測試,該腳本在 https://app.runwayml.com/* 頁面上正常運行。
// @author HDR10
// @match https://*/*
// @match https://app.runwayml.com/*
// @grant none
// @license Apache License 2.0
// ==/UserScript==
(function() {
'use strict';
// 多语言支持的按钮文本
const texts = {
en: {
title: "Auto Click Enabled Button",
statusStopped: "Auto-clicking stopped",
statusStarted: "Auto-clicking enabled",
start: "Enable",
stop: "Stop",
clickLimit: "Stop after clicking:",
clearLog: "Clear log",
minimize: "Minimize"
},
"zh-CN": {
title: "自动点击启用按钮",
statusStopped: "自动点击已停止",
statusStarted: "自动点击已启用",
start: "启用",
stop: "停止",
clickLimit: "点击几次后停止:",
clearLog: "清除log",
minimize: "最小化"
},
hi: {
title: "ऑटो क्लिक सक्षम बटन",
statusStopped: "स्वचालित क्लिक बंद हो गया",
statusStarted: "स्वचालित क्लिक सक्षम",
start: "सक्षम करें",
stop: "रोकें",
clickLimit: "क्लिक करने के बाद रोकें:",
clearLog: "लॉग साफ़ करें",
minimize: "छोटा करें"
},
fr: {
title: "Bouton de clic automatique activé",
statusStopped: "Clic automatique arrêté",
statusStarted: "Clic automatique activé",
start: "Activer",
stop: "Arrêter",
clickLimit: "Arrêter après avoir cliqué:",
clearLog: "Effacer le journal",
minimize: "Minimiser"
},
ar: {
title: "زر النقر التلقائي عند التمكين",
statusStopped: "توقف النقر التلقائي",
statusStarted: "تمكين النقر التلقائي",
start: "تمكين",
stop: "إيقاف",
clickLimit: "توقف بعد النقر:",
clearLog: "مسح السجل",
minimize: "تصغير"
},
bg: {
title: "Автоматично кликване на активиран бутон",
statusStopped: "Автоматичното кликване е спряно",
statusStarted: "Автоматичното кликване е активирано",
start: "Активирай",
stop: "Спри",
clickLimit: "Спри след кликване:",
clearLog: "Изчисти дневника",
minimize: "Минимизирай"
},
ru: {
title: "Автоматическое нажатие на активированные кнопки",
statusStopped: "Автоклик остановлен",
statusStarted: "Автоклик активирован",
start: "Активировать",
stop: "Остановить",
clickLimit: "Остановить после кликов:",
clearLog: "Очистить журнал",
minimize: "Свернуть"
},
"pt-BR": {
title: "Botão de Clique Automático Habilitado",
statusStopped: "Clique automático parado",
statusStarted: "Clique automático habilitado",
start: "Habilitar",
stop: "Parar",
clickLimit: "Parar após clicar:",
clearLog: "Limpar log",
minimize: "Minimizar"
},
id: {
title: "Tombol Klik Otomatis yang Diaktifkan",
statusStopped: "Klik otomatis dihentikan",
statusStarted: "Klik otomatis diaktifkan",
start: "Aktifkan",
stop: "Hentikan",
clickLimit: "Berhenti setelah mengklik:",
clearLog: "Hapus log",
minimize: "Minimalkan"
},
"zh-TW": {
title: "自動點擊啟用按鈕",
statusStopped: "自動點擊已停止",
statusStarted: "自動點擊已啟用",
start: "啟用",
stop: "停止",
clickLimit: "點擊幾次後停止:",
clearLog: "清除log",
minimize: "最小化"
}
};
// 获取浏览器语言,默认为英文
const lang = navigator.language || navigator.userLanguage;
const userLang = lang.startsWith('zh') ? (lang === 'zh-TW' ? 'zh-TW' : 'zh-CN') : (texts[lang] ? lang : 'en');
const t = texts[userLang];
// 创建浮窗
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.style.display = 'none'; // 初始状态为最小化
floatWindow.innerHTML = `
<div>
<div id="dragHandle" style="width: 20px; height: 20px; background-color: gray; position: absolute; top: 5px; right: 5px; cursor: move;"></div>
<h3>${t.title}</h3>
<p id="statusLabel">${t.statusStopped}</p>
<button id="startBtn">${t.start}</button>
<button id="stopBtn">${t.stop}</button>
<label for="clickLimit">${t.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">${t.clearLog}</button>
<button id="minimizeBtn">${t.minimize}</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>`;
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 = t.statusStarted;
document.getElementById('statusLabel').style.color = 'green';
minimizeIcon.style.backgroundColor = 'green';
startObserving();
});
document.getElementById('stopBtn').addEventListener('click', function() {
autoClickEnabled = false;
document.getElementById('statusLabel').textContent = t.statusStopped;
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 = t.statusStopped;
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);
}
})();