您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Automates clicks at various locations on the screen with customizable intervals
当前为
// ==UserScript== // @name YAD Multiple Auto Clicker // @namespace https://greasyfork.org/en/users/781396 // @version 2.6 // @description Automates clicks at various locations on the screen with customizable intervals // @author YAD // @license MIT // @match *://*/* // @grant none // ==/UserScript== (function () { 'use strict'; let buttons = []; let buttonId = 1; let isRunning = false; // Load button positions and settings from localStorage const loadButtonData = () => JSON.parse(localStorage.getItem('buttonData') || '[]'); // Save button positions and settings to localStorage const saveButtonData = () => { const buttonData = buttons.map(button => ({ id: button.id, top: button.style.top, left: button.style.left, interval: button.dataset.interval, clicks: button.dataset.clicks })); localStorage.setItem('buttonData', JSON.stringify(buttonData)); }; // Save the current running state in localStorage const saveRunningState = () => { localStorage.setItem('isRunning', JSON.stringify(isRunning)); }; // Load the running state from localStorage on page reload const loadRunningState = () => { return JSON.parse(localStorage.getItem('isRunning') || 'false'); }; // Create the main interface const mainInterface = document.createElement('div'); mainInterface.style.position = 'fixed'; mainInterface.style.right = '10px'; mainInterface.style.top = '50%'; mainInterface.style.transform = 'translateY(-50%)'; mainInterface.style.zIndex = '9999'; // Plus button to add new auto-click buttons const plusButton = document.createElement('button'); plusButton.textContent = '➕'; plusButton.style.display = 'block'; plusButton.style.padding = '10px'; plusButton.style.marginBottom = '5px'; plusButton.style.fontSize = '16px'; plusButton.style.cursor = 'pointer'; plusButton.style.backgroundColor = '#28a745'; // Green background plusButton.style.border = 'none'; plusButton.style.color = 'transparent'; plusButton.style.textShadow = '0 0 0 white'; plusButton.style.borderRadius = '5px'; mainInterface.appendChild(plusButton); // Start/Stop button const startStopButton = document.createElement('button'); startStopButton.textContent = '👆'; startStopButton.style.display = 'block'; startStopButton.style.padding = '10px'; startStopButton.style.marginBottom = '5px'; startStopButton.style.fontSize = '16px'; startStopButton.style.cursor = 'pointer'; startStopButton.style.backgroundColor = '#007bff'; // Blue background startStopButton.style.border = 'none'; startStopButton.style.color = 'white'; startStopButton.style.borderRadius = '5px'; mainInterface.appendChild(startStopButton); // Reset button const resetButton = document.createElement('button'); resetButton.textContent = '♻️'; resetButton.style.display = 'block'; resetButton.style.padding = '10px'; resetButton.style.fontSize = '16px'; resetButton.style.cursor = 'pointer'; resetButton.style.backgroundColor = '#dc3545'; // Red background resetButton.style.border = 'none'; resetButton.style.color = 'transparent'; resetButton.style.textShadow = '0 0 0 white'; resetButton.style.borderRadius = '5px'; mainInterface.appendChild(resetButton); document.body.appendChild(mainInterface); // Plus button functionality plusButton.addEventListener('click', () => { createAutoClickButton(); }); // Start/Stop button functionality startStopButton.addEventListener('click', () => { isRunning = !isRunning; saveRunningState(); if (isRunning) { startStopButton.textContent = '🛑'; startAutoClick(); } else { startStopButton.textContent = '👆'; stopAutoClick(); } }); // Reset button functionality resetButton.addEventListener('click', () => { buttons.forEach(button => button.remove()); buttons = []; localStorage.removeItem('buttonData'); buttonId = 1; stopAutoClick(); startStopButton.textContent = '👆'; saveRunningState(); }); // Function to create a new auto-click button function createAutoClickButton(buttonData = null) { const autoButton = document.createElement('div'); autoButton.id = buttonId++; autoButton.textContent = autoButton.id; autoButton.style.width = '50px'; autoButton.style.height = '50px'; autoButton.style.borderRadius = '50%'; autoButton.style.backgroundColor = '#0061ffcc'; autoButton.style.position = 'absolute'; autoButton.style.top = buttonData?.top || '50%'; autoButton.style.left = buttonData?.left || '50%'; autoButton.style.display = 'flex'; autoButton.style.alignItems = 'center'; autoButton.style.justifyContent = 'center'; autoButton.style.cursor = 'pointer'; autoButton.style.zIndex = '9999'; autoButton.style.color = 'white'; // Ensure text is visible autoButton.dataset.interval = buttonData?.interval || 1000; // Default interval autoButton.dataset.clicks = buttonData?.clicks || 1; // Default number of clicks document.body.appendChild(autoButton); makeDraggable(autoButton); buttons.push(autoButton); saveButtonData(); // Open settings modal on right-click autoButton.addEventListener('contextmenu', (e) => { e.preventDefault(); openSettingsModal(autoButton); }); } // Function to make the buttons draggable function makeDraggable(element) { let posX = 0, posY = 0, mouseX = 0, mouseY = 0; element.onmousedown = function (e) { e.preventDefault(); mouseX = e.clientX; mouseY = e.clientY; document.onmousemove = moveElement; document.onmouseup = stopMovingElement; }; function moveElement(e) { posX = mouseX - e.clientX; posY = mouseY - e.clientY; mouseX = e.clientX; mouseY = e.clientY; element.style.top = (element.offsetTop - posY) + 'px'; element.style.left = (element.offsetLeft - posX) + 'px'; } function stopMovingElement() { document.onmouseup = null; document.onmousemove = null; saveButtonData(); } } // Function to open settings modal function openSettingsModal(button) { const modal = document.createElement('div'); modal.style.position = 'fixed'; modal.style.top = '50%'; modal.style.left = '50%'; modal.style.transform = 'translate(-50%, -50%)'; modal.style.zIndex = '10000'; modal.style.padding = '15px'; modal.style.backgroundColor = '#6f42c1'; modal.style.borderRadius = '8px'; modal.style.boxShadow = '0px 4px 12px rgba(0, 0, 0, 0.1)'; modal.style.width = '300px'; // Make it more compact modal.style.fontFamily = 'Arial, sans-serif'; const title = document.createElement('h3'); title.textContent = 'Settings'; title.style.marginTop = '0'; title.style.marginBottom = '15px'; title.style.color = '#fff'; title.style.textAlign = 'center'; title.style.fontSize = '18px'; modal.appendChild(title); const form = document.createElement('form'); form.style.display = 'flex'; form.style.flexDirection = 'column'; form.style.gap = '10px'; modal.appendChild(form); const createInputField = (labelText, inputType, inputValue) => { const fieldWrapper = document.createElement('div'); fieldWrapper.style.display = 'flex'; fieldWrapper.style.flexDirection = 'column'; const label = document.createElement('label'); label.textContent = labelText; label.style.fontSize = '14px'; label.style.color = '#fff'; label.style.marginBottom = '5px'; fieldWrapper.appendChild(label); const input = document.createElement('input'); input.type = inputType; input.value = inputValue; input.style.padding = '5px'; input.style.borderRadius = '4px'; input.style.border = '1px solid #ccc'; input.style.fontSize = '14px'; fieldWrapper.appendChild(input); form.appendChild(fieldWrapper); return input; }; const intervalInput = createInputField('Interval (ms):', 'number', button.dataset.interval); const clicksInput = createInputField('Clicks per Interval:', 'number', button.dataset.clicks); const saveButton = document.createElement('button'); saveButton.textContent = 'Save'; saveButton.style.padding = '10px'; saveButton.style.borderRadius = '5px'; saveButton.style.border = 'none'; saveButton.style.backgroundColor = '#28a745'; saveButton.style.color = 'white'; saveButton.style.cursor = 'pointer'; form.appendChild(saveButton); saveButton.addEventListener('click', (e) => { e.preventDefault(); button.dataset.interval = intervalInput.value; button.dataset.clicks = clicksInput.value; saveButtonData(); document.body.removeChild(modal); }); const cancelButton = document.createElement('button'); cancelButton.textContent = 'Cancel'; cancelButton.style.padding = '10px'; cancelButton.style.borderRadius = '5px'; cancelButton.style.border = 'none'; cancelButton.style.backgroundColor = '#dc3545'; cancelButton.style.color = 'white'; cancelButton.style.cursor = 'pointer'; form.appendChild(cancelButton); cancelButton.addEventListener('click', (e) => { e.preventDefault(); document.body.removeChild(modal); }); document.body.appendChild(modal); } // Function to simulate real auto-clicks on elements function autoClick(button) { const rect = button.getBoundingClientRect(); button.style.visibility = 'hidden'; const elemUnderButton = document.elementFromPoint( rect.left + rect.width / 2, rect.top + rect.height / 2 ); button.style.visibility = 'visible'; if (elemUnderButton) { const interval = button.dataset.interval ? parseInt(button.dataset.interval) : 1000; const clicks = button.dataset.clicks ? parseInt(button.dataset.clicks) : 1; // Reduce opacity to indicate clicking button.style.opacity = '0.6'; // Delay before the first click set return new Promise(resolve => { setTimeout(() => { for (let i = 0; i < clicks; i++) { simulateClick(elemUnderButton); } // Restore opacity after the clicks button.style.opacity = '1'; // Continue after clicks resolve(); }, interval); // Wait for the interval before the first click }); } } // Function to simulate clicks, including handling iframes and shadow DOMs function simulateClick(target) { const eventNames = ['mousedown', 'mouseup', 'click']; eventNames.forEach(eventName => { const event = new MouseEvent(eventName, { bubbles: true, cancelable: true, view: window }); target.dispatchEvent(event); }); // Handle iframes if (target.tagName === 'IFRAME') { const iframeDoc = target.contentDocument || target.contentWindow.document; const clickableElement = iframeDoc.querySelector('selector'); // Update this selector for specific iframe content clickableElement?.click(); } // Handle Shadow DOM if (target.shadowRoot) { const clickableElement = target.shadowRoot.querySelector('selector'); // Update this selector for Shadow DOM clickableElement?.click(); } } // Function to start auto-clicking in sequence async function startAutoClick() { if (buttons.length === 0) return; while (isRunning) { for (let button of buttons) { await autoClick(button); } } } // Function to stop auto-clicking function stopAutoClick() { buttons.forEach((button) => { clearInterval(button.autoClickInterval); }); } // Restore buttons and state on page reload window.onload = function () { const buttonData = loadButtonData(); if (buttonData.length) { buttonData.forEach(data => createAutoClickButton(data)); } isRunning = loadRunningState(); if (isRunning) { startStopButton.textContent = '🛑'; startAutoClick(); } }; })();