在5-10秒随机时间内(用于测试),挪动鼠标至随机位置,右侧贴边有启动/关闭开关、记录移动次数和下次移动倒计时。
// ==UserScript==
// @name 随机鼠标移动器 (调试版-修复view属性)
// @namespace http://tampermonkey.net/
// @version 1.2.2
// @description 在5-10秒随机时间内(用于测试),挪动鼠标至随机位置,右侧贴边有启动/关闭开关、记录移动次数和下次移动倒计时。
// @author Your Name (替换成你的名字)
// @match *://*/*
// @grant GM_setValue
// @grant GM_getValue
// @grant GM_addStyle
// @grant unsafeWindow
// @license MPL-2.0 License
// ==/UserScript==
(function() {
'use strict';
let moveTimeoutId; // 用于 setTimeout 的 ID
let countdownIntervalId; // 用于 setInterval 更新倒计时的 ID
let isRunning = false;
let moveCount = GM_getValue('mouseMoveCount', 0) || 0;
let nextMoveTime = 0; // 下次移动的精确时间戳
// --- 样式 ---
GM_addStyle(`
#mouseMoverControlPanel {
position: fixed;
top: 50%;
right: 0;
transform: translateY(-50%);
background-color: rgba(0, 0, 0, 0.75);
color: white;
padding: 15px;
border-top-left-radius: 8px;
border-bottom-left-radius: 8px;
z-index: 99999999; /* 确保非常高 */
font-family: Arial, sans-serif;
font-size: 14px;
box-shadow: -2px 0px 5px rgba(0,0,0,0.5);
display: flex;
flex-direction: column;
gap: 10px;
}
#mouseMoverControlPanel button {
background-color: #4CAF50;
color: white;
border: none;
padding: 10px;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 14px;
cursor: pointer;
border-radius: 4px;
transition: background-color 0.3s ease;
}
#mouseMoverControlPanel button:hover {
background-color: #45a049;
}
#mouseMoverControlPanel button.stop {
background-color: #f44336;
}
#mouseMoverControlPanel button.stop:hover {
background-color: #da190b;
}
#mouseMoverControlPanel div[id$="Text"] {
font-weight: normal;
text-align: center;
padding: 3px 0;
}
#mouseMoverControlPanel #statusText {
font-weight: bold;
}
#mouseMoverControlPanel #countdownText {
font-style: italic;
color: #c8ff00;
}
`);
// --- 创建控制面板 ---
const controlPanel = document.createElement('div');
controlPanel.id = 'mouseMoverControlPanel';
document.body.appendChild(controlPanel);
const statusText = document.createElement('div');
statusText.id = 'statusText';
statusText.textContent = '状态: 已停止';
controlPanel.appendChild(statusText);
const toggleButton = document.createElement('button');
toggleButton.id = 'toggleButton';
toggleButton.textContent = '启动';
controlPanel.appendChild(toggleButton);
const countText = document.createElement('div');
countText.id = 'countText';
countText.textContent = `移动次数: ${moveCount}`;
controlPanel.appendChild(countText);
const countdownTextElement = document.createElement('div');
countdownTextElement.id = 'countdownText';
countdownTextElement.textContent = '下次移动: --:--';
controlPanel.appendChild(countdownTextElement);
const resetButton = document.createElement('button');
resetButton.textContent = '重置计数';
resetButton.style.backgroundColor = '#ff9800';
resetButton.addEventListener('mouseover', () => resetButton.style.backgroundColor = '#e68a00');
resetButton.addEventListener('mouseout', () => resetButton.style.backgroundColor = '#ff9800');
controlPanel.appendChild(resetButton);
// --- 功能函数 ---
function moveMouse(x, y) {
console.log(`[调试] moveMouse: 准备移动到 (${x}, ${y})`);
const event = new MouseEvent('mousemove', {
bubbles: true,
cancelable: true,
clientX: x,
clientY: y,
view: unsafeWindow // 修改: 使用 unsafeWindow 代替 window
});
try {
let dispatchedOn = null;
if (document.activeElement && document.activeElement !== document.body) {
// 尝试派发到当前活动元素,如果它不是 body
document.activeElement.dispatchEvent(event);
dispatchedOn = "document.activeElement";
} else if (document.documentElement) {
document.documentElement.dispatchEvent(event);
dispatchedOn = "document.documentElement";
} else if (document.body) { // 如果 documentElement 不存在,则尝试 body
document.body.dispatchEvent(event);
dispatchedOn = "document.body";
}
if (dispatchedOn) {
console.log(`[调试] moveMouse: 鼠标移动事件已派发到 ${dispatchedOn} 到: (${x}, ${y})`);
// 为了更明显地看到效果,可以临时添加一个视觉反馈,比如闪烁背景色
// document.body.style.transition = 'background-color 0.1s ease-out';
// const originalBg = document.body.style.backgroundColor;
// document.body.style.backgroundColor = 'rgba(255,0,0,0.2)';
// setTimeout(() => { document.body.style.backgroundColor = originalBg; }, 100);
} else {
console.warn("[调试] moveMouse: 未找到合适的元素来派发鼠标事件。");
}
} catch (e) {
console.error("[调试] moveMouse: 派发鼠标移动事件时出错:", e);
}
}
function getRandomPosition() {
const x = Math.floor(Math.random() * window.innerWidth);
const y = Math.floor(Math.random() * window.innerHeight);
return { x, y };
}
// 获取随机时间 (修改为5-10秒用于测试)
function getRandomTime() {
// 原来的: 5-10分钟 (300000 - 600000毫秒)
// return Math.floor(Math.random() * (600000 - 300000 + 1)) + 300000;
// 测试用: 5-10秒 (5000 - 10000毫秒)
const randomShortTime = Math.floor(Math.random() * (10000 - 5000 + 1)) + 5000;
console.log(`[调试] getRandomTime: 生成的随机延时为 ${randomShortTime} ms`);
return randomShortTime;
}
function updateCountdownDisplay() {
if (!isRunning || nextMoveTime <= 0) {
countdownTextElement.textContent = '下次移动: --:--';
return;
}
const now = Date.now();
const timeLeftMs = nextMoveTime - now;
if (timeLeftMs <= 0) {
countdownTextElement.textContent = '下次移动: 即将...';
return;
}
const totalSeconds = Math.max(0, Math.floor(timeLeftMs / 1000));
const minutes = Math.floor(totalSeconds / 60);
const seconds = totalSeconds % 60;
countdownTextElement.textContent = `下次移动: ${String(minutes).padStart(2, '0')}:${String(seconds).padStart(2, '0')}`;
}
function startMoving() {
if (isRunning) {
console.log('[调试] startMoving: 已在运行,无需再次启动。');
return;
}
isRunning = true;
statusText.textContent = '状态: 运行中';
toggleButton.textContent = '停止';
toggleButton.classList.add('stop');
console.log('[调试] startMoving: 随机鼠标移动已启动');
scheduleMove(); // 直接开始调度
}
function scheduleMove() {
if (!isRunning) {
console.log('[调试] scheduleMove: isRunning 为 false, 停止调度。');
return;
}
const randomTimeDelay = getRandomTime();
nextMoveTime = Date.now() + randomTimeDelay;
console.log(`[调试] scheduleMove: 下一次移动操作将在 ${randomTimeDelay} ms (即 ${(randomTimeDelay / 1000).toFixed(1)} 秒) 后执行。`);
if (countdownIntervalId) clearInterval(countdownIntervalId);
countdownIntervalId = setInterval(updateCountdownDisplay, 1000);
updateCountdownDisplay(); // 立即更新一次
moveTimeoutId = setTimeout(() => {
console.log('[调试] setTimeout 回调: 准备执行移动。');
if (!isRunning) {
console.log('[调试] setTimeout 回调: isRunning 为 false, 取消本次移动。');
clearInterval(countdownIntervalId); // 确保倒计时也停止
nextMoveTime = 0;
updateCountdownDisplay();
return;
}
const position = getRandomPosition();
console.log(`[调试] setTimeout 回调: 获取到随机位置 (${position.x}, ${position.y})。`);
moveMouse(position.x, position.y);
moveCount++;
GM_setValue('mouseMoveCount', moveCount);
countText.textContent = `移动次数: ${moveCount}`;
console.log(`[调试] setTimeout 回调: 移动次数更新为 ${moveCount}。`);
if (isRunning) {
console.log('[调试] setTimeout 回调: 准备调度下一次移动。');
scheduleMove();
} else {
console.log('[调试] setTimeout 回调: isRunning 变为 false, 停止后续调度。');
clearInterval(countdownIntervalId);
nextMoveTime = 0;
updateCountdownDisplay();
}
}, randomTimeDelay);
console.log(`[调试] scheduleMove: setTimeout 已设置,ID: ${moveTimeoutId}`);
}
function stopMoving() {
if (!isRunning) {
console.log('[调试] stopMoving: 已停止,无需再次操作。');
return;
}
isRunning = false;
console.log(`[调试] stopMoving: 准备清除 setTimeout (ID: ${moveTimeoutId}) 和 setInterval (ID: ${countdownIntervalId})。`);
clearTimeout(moveTimeoutId);
clearInterval(countdownIntervalId);
nextMoveTime = 0;
statusText.textContent = '状态: 已停止';
toggleButton.textContent = '启动';
toggleButton.classList.remove('stop');
updateCountdownDisplay();
console.log('[调试] stopMoving: 随机鼠标移动已停止。');
}
function resetCounter() {
if (confirm('确定要重置移动次数吗?')) {
moveCount = 0;
GM_setValue('mouseMoveCount', moveCount);
countText.textContent = `移动次数: ${moveCount}`;
console.log('[调试] resetCounter: 移动次数已重置。');
}
}
// --- 事件监听 ---
toggleButton.addEventListener('click', () => {
if (isRunning) {
stopMoving();
} else {
startMoving();
}
});
resetButton.addEventListener('click', resetCounter);
// 脚本加载时,默认是停止状态
console.log('[调试] 脚本已加载并初始化。');
})();