您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Automates clicks at various locations on the screen with customizable intervals
// ==UserScript== // @name YAD Multi Auto Clicker // @namespace https://greasyfork.org/en/users/781396 // @version 2.9 // @description Automates clicks at various locations on the screen with customizable intervals // @author YAD // @license MIT // @icon https://i.ibb.co/z7JVjSp/image.png // @match *://*/* // @grant none // ==/UserScript== (function () { 'use strict'; let buttons = []; let buttonId = 1; let isRunning = false; let clickIntervals = []; // 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', () => { stopAutoClick(); // Ensure all running intervals are stopped buttons.forEach(button => button.remove()); buttons = []; localStorage.removeItem('buttonData'); buttonId = 1; 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 auto-clicking on buttons with a specified interval and number of clicks async function autoClick(button) { const rect = button.getBoundingClientRect(); const interval = parseInt(button.dataset.interval) || 1000; const clicks = parseInt(button.dataset.clicks) || 1; button.style.visibility = 'hidden'; const elemUnderButton = document.elementFromPoint( rect.left + rect.width / 2, rect.top + rect.height / 2 ); button.style.visibility = 'visible'; if (elemUnderButton && isRunning) { button.style.opacity = '0.6'; // Perform clicks at the specified interval for (let i = 0; i < clicks; i++) { if (!isRunning) break; // Stop the clicks if not running anymore simulateClick(elemUnderButton); await new Promise(resolve => setTimeout(resolve, interval)); // Wait for the interval between clicks } button.style.opacity = '1'; } } // Function to simulate clicks anywhere, including on HTML5 game canvas elements function simulateClick(target, x = null, y = null) { const eventNames = ['mousedown', 'mouseup', 'click']; // If specific coordinates are provided, simulate the click there if (x !== null && y !== null) { const elementAtPoint = document.elementFromPoint(x, y); // If the element at the coordinates is a canvas, simulate a click on it if (elementAtPoint.tagName === 'CANVAS') { eventNames.forEach(eventName => { const event = new MouseEvent(eventName, { bubbles: true, cancelable: true, view: window, clientX: x, clientY: y }); elementAtPoint.dispatchEvent(event); }); } else { // Simulate click at the provided coordinates for non-canvas elements eventNames.forEach(eventName => { const event = new MouseEvent(eventName, { bubbles: true, cancelable: true, view: window, clientX: x, clientY: y }); elementAtPoint?.dispatchEvent(event); }); } return; } // If no coordinates, click on the target element eventNames.forEach(eventName => { const event = new MouseEvent(eventName, { bubbles: true, cancelable: true, view: window }); target.dispatchEvent(event); }); // Handle specific cases like canvas, iframes, and shadow DOM // HTML5 Canvas if (target.tagName === 'CANVAS') { const rect = target.getBoundingClientRect(); const canvasClickEvent = new MouseEvent('click', { bubbles: true, cancelable: true, view: window, clientX: rect.left + rect.width / 2, // Click at center clientY: rect.top + rect.height / 2 }); target.dispatchEvent(canvasClickEvent); } // Handle IFRAMEs if (target.tagName === 'IFRAME') { const iframeDoc = target.contentDocument || target.contentWindow.document; const clickableElement = iframeDoc?.body || iframeDoc?.querySelector('canvas'); clickableElement?.dispatchEvent(new MouseEvent('click', { bubbles: true, cancelable: true, view: window })); } // Handle Shadow DOM if (target.shadowRoot) { const clickableElement = target.shadowRoot.querySelector('canvas, [clickable], button, a'); clickableElement?.dispatchEvent(new MouseEvent('click', { bubbles: true, cancelable: true, view: window })); } // Handle Flash or Java embedded objects (legacy games) if (target.tagName === 'OBJECT' || target.tagName === 'EMBED') { try { target.focus(); const objectClickEvent = new MouseEvent('click', { bubbles: true, cancelable: true, view: window }); target.dispatchEvent(objectClickEvent); } catch (e) { console.warn("Flash or Java interaction failed:", e); } } } // Start auto-clicking in sequence async function startAutoClick() { for (const button of buttons) { const interval = parseInt(button.dataset.interval); await autoClick(button); // Wait for the current button to finish before starting the next } if (isRunning) { setTimeout(startAutoClick, 0); // Immediately restart the clicking sequence if still running } } // Stop auto-clicking function stopAutoClick() { isRunning = false; } // Load buttons and state on page load window.addEventListener('load', () => { loadButtonData().forEach(buttonData => createAutoClickButton(buttonData)); if (loadRunningState()) { isRunning = true; startStopButton.textContent = '🛑'; startAutoClick(); } }); })();