Automates clicks at various locations on the screen with customizable intervals
当前为
// ==UserScript==
// @name YAD Multiple Auto Clicker
// @namespace http://tampermonkey.net/
// @version 2.0
// @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;
const loadButtonData = () => JSON.parse(localStorage.getItem('buttonData') || '[]');
const saveButtonData = () => {
const buttonData = buttons.map(button => ({
id: button.id,
top: button.style.top,
left: button.style.left,
interval: button.dataset.interval || 1000,
clicks: button.dataset.clicks || 1
}));
localStorage.setItem('buttonData', JSON.stringify(buttonData));
};
const saveRunningState = () => {
localStorage.setItem('isRunning', JSON.stringify(isRunning));
};
const loadRunningState = () => {
return JSON.parse(localStorage.getItem('isRunning') || 'false');
};
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';
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';
plusButton.style.border = 'none';
plusButton.style.color = 'transparent';
plusButton.style.textShadow = '0 0 0 white';
plusButton.style.borderRadius = '5px';
mainInterface.appendChild(plusButton);
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';
startStopButton.style.border = 'none';
startStopButton.style.color = 'white';
startStopButton.style.borderRadius = '5px';
mainInterface.appendChild(startStopButton);
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';
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);
plusButton.addEventListener('click', () => {
createAutoClickButton();
});
startStopButton.addEventListener('click', () => {
isRunning = !isRunning;
saveRunningState();
if (isRunning) {
startStopButton.textContent = '🛑';
startAutoClick();
} else {
startStopButton.textContent = '👆';
stopAutoClick();
}
});
resetButton.addEventListener('click', () => {
buttons.forEach(button => button.remove());
buttons = [];
localStorage.removeItem('buttonData');
buttonId = 1;
stopAutoClick();
startStopButton.textContent = '👆';
});
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 = '#ff0000cc';
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';
document.body.appendChild(autoButton);
makeDraggable(autoButton);
autoButton.dataset.interval = buttonData?.interval || 1000;
autoButton.dataset.clicks = buttonData?.clicks || 1;
buttons.push(autoButton);
autoButton.addEventListener('contextmenu', (e) => {
e.preventDefault();
openSettingsModal(autoButton);
});
autoButton.addEventListener('click', (e) => {
e.stopPropagation();
});
}
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 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 = '#fff';
modal.style.borderRadius = '8px';
modal.style.boxShadow = '0px 4px 12px rgba(0, 0, 0, 0.1)';
modal.style.width = '300px';
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 = '#333';
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 = '#555';
label.style.marginBottom = '5px';
fieldWrapper.appendChild(label);
const input = document.createElement('input');
input.type = inputType;
input.value = inputValue;
input.style.padding = '8px';
input.style.border = '1px solid #ccc';
input.style.borderRadius = '4px';
input.style.fontSize = '14px';
fieldWrapper.appendChild(input);
return { fieldWrapper, input };
};
const intervalField = createInputField('Interval (ms):', 'number', button.dataset.interval);
const clicksField = createInputField('Number of clicks:', 'number', button.dataset.clicks);
form.appendChild(intervalField.fieldWrapper);
form.appendChild(clicksField.fieldWrapper);
const buttonWrapper = document.createElement('div');
buttonWrapper.style.display = 'flex';
buttonWrapper.style.justifyContent = 'center';
buttonWrapper.style.marginTop = '15px';
modal.appendChild(buttonWrapper);
const saveButton = document.createElement('button');
saveButton.textContent = 'Save';
saveButton.style.padding = '8px 16px';
saveButton.style.border = 'none';
saveButton.style.borderRadius = '4px';
saveButton.style.backgroundColor = '#007bff';
saveButton.style.color = 'white';
saveButton.style.fontSize = '14px';
saveButton.style.cursor = 'pointer';
buttonWrapper.appendChild(saveButton);
saveButton.addEventListener('click', (e) => {
e.preventDefault();
button.dataset.interval = intervalField.input.value;
button.dataset.clicks = clicksField.input.value;
saveButtonData();
modal.remove();
});
document.body.appendChild(modal);
}
let intervalId;
let currentButtonIndex = 0;
const startAutoClick = () => {
if (buttons.length === 0) return;
intervalId = setInterval(() => {
if (currentButtonIndex >= buttons.length) {
currentButtonIndex = 0;
}
const button = buttons[currentButtonIndex];
const interval = parseInt(button.dataset.interval, 10);
const clicks = parseInt(button.dataset.clicks, 10);
performClick(button, clicks);
currentButtonIndex++;
}, buttons[currentButtonIndex].dataset.interval);
};
const stopAutoClick = () => {
clearInterval(intervalId);
};
const performClick = (button, clicks) => {
const targetElement = document.querySelector(`[data-button-id="${button.id}"]`);
if (targetElement) {
for (let i = 0; i < clicks; i++) {
targetElement.click();
}
}
};
window.addEventListener('load', () => {
buttons = loadButtonData().map(createAutoClickButton);
isRunning = loadRunningState();
if (isRunning) {
startStopButton.textContent = '🛑';
startAutoClick();
}
});
})();