// ==UserScript== // @name 鼠标坐标记录器 // @namespace https://www.0755tt.com/ // @version 9.0 // @description 在屏幕右上角输入坐标,实时解析为 clickX 和 clickY,带确认按钮,默认921,409 // @author reese // @match https://www.0755tt.com/* // @grant none // ==/UserScript== (function() { //输入框(预填默认值) const DEFAULT_X = 921; const DEFAULT_Y = 409; // 创建容器 const container = document.createElement('div'); container.id = 'coord-recorder'; container.style.cssText = ` position: fixed; top: 10px; right: 10px; z-index: 999999; background: rgba(30, 30, 30, 0.9); border: 1px solid #555; border-radius: 6px; padding: 10px 14px; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; font-size: 13px; color: #fff; box-shadow: 0 4px 12px rgba(0,0,0,0.3); display: flex; flex-direction: column; gap: 6px; min-width: 180px; `; // 标题 const title = document.createElement('div'); title.textContent = '坐标输入'; title.style.cssText = ` font-weight: 600; color: #4fc3f7; margin-bottom: 2px; font-size: 12px; text-transform: uppercase; letter-spacing: 0.5px; `; // 输入框(预填默认值) const input = document.createElement('input'); input.type = 'text'; input.value = `${DEFAULT_X}, ${DEFAULT_Y}`; input.style.cssText = ` background: #2a2a2a; border: 1px solid #81c784; border-radius: 4px; padding: 6px 8px; color: #fff; font-size: 13px; outline: none; width: 100%; box-sizing: border-box; `; input.addEventListener('focus', () => { if (input.style.borderColor !== '#e57373') { input.style.borderColor = '#4fc3f7'; } }); input.addEventListener('blur', () => { if (input.style.borderColor !== '#e57373') { input.style.borderColor = '#81c784'; } }); // 显示区域 const display = document.createElement('div'); display.style.cssText = ` font-size: 12px; color: #aaa; margin-top: 2px; line-height: 1.5; min-height: 36px; `; // 按钮区域 const btnRow = document.createElement('div'); btnRow.style.cssText = ` display: flex; justify-content: flex-end; margin-top: 2px; `; // 确认按钮 const confirmBtn = document.createElement('button'); confirmBtn.textContent = '确认'; confirmBtn.style.cssText = ` background: #4fc3f7; border: none; border-radius: 4px; padding: 5px 14px; color: #1a1a1a; font-size: 12px; font-weight: 600; cursor: pointer; transition: background 0.2s, transform 0.1s; `; confirmBtn.addEventListener('mouseenter', () => { confirmBtn.style.background = '#29b6f6'; }); confirmBtn.addEventListener('mouseleave', () => { confirmBtn.style.background = '#4fc3f7'; }); confirmBtn.addEventListener('mousedown', () => { confirmBtn.style.transform = 'scale(0.96)'; }); confirmBtn.addEventListener('mouseup', () => { confirmBtn.style.transform = 'scale(1)'; }); function updateDisplay() { if (typeof window.clickX === 'number' && typeof window.clickY === 'number') { display.innerHTML = ` clickX: ${window.clickX}
clickY: ${window.clickY} `; } else { display.innerHTML = '等待输入...'; } } function parseCoords(value) { const cleaned = value.replace(/[xyXY]:/g, '').replace(/[^\d\s,.-]/g, ''); const parts = cleaned.split(/[,\s]+/).filter(p => p.trim() !== ''); if (parts.length >= 2) { const x = parseInt(parts[0], 10); const y = parseInt(parts[1], 10); if (!isNaN(x) && !isNaN(y)) { return { x, y }; } } return null; } function applyCoords() { const coords = parseCoords(input.value); if (coords) { window.clickX = coords.x; window.clickY = coords.y; input.style.borderColor = '#81c784'; updateDisplay(); console.log(`[坐标] 已更新。 ${window.clickX}, ${window.clickY}`); return true; } else { input.style.borderColor = '#e57373'; if (input.value.trim() === '') { window.clickX = undefined; window.clickY = undefined; } updateDisplay(); console.log(`[坐标] 更新失败。`); return false; } } // 实时输入 input.addEventListener('input', applyCoords); // 回车确认 input.addEventListener('keydown', (e) => { if (e.key === 'Enter') { if (applyCoords()) { input.style.background = '#1b3a1b'; setTimeout(() => input.style.background = '#2a2a2a', 300); } } }); // 按钮确认 confirmBtn.addEventListener('click', () => { if (applyCoords()) { input.style.background = '#1b3a1b'; setTimeout(() => input.style.background = '#2a2a2a', 300); } }); // 组装 btnRow.appendChild(confirmBtn); container.appendChild(title); container.appendChild(input); container.appendChild(display); container.appendChild(btnRow); document.body.appendChild(container); // 初始化默认值 window.clickX = DEFAULT_X; window.clickY = DEFAULT_Y; updateDisplay(); console.log(`[坐标记录器] 已加载。默认坐标: ${DEFAULT_X}, ${DEFAULT_Y}`); // ==UserScript== const tooltip = document.createElement('div'); tooltip.id = 'mouse-screen-coord-tooltip'; tooltip.style.cssText = ` position: fixed; pointer-events: none; z-index: 999999; background: rgba(0, 0, 0, 0.75); color: #00ff88; font-family: 'Courier New', monospace; font-size: 12px; padding: 4px 8px; border-radius: 4px; white-space: nowrap; box-shadow: 0 2px 8px rgba(0,0,0,0.3); border: 1px solid rgba(0, 255, 136, 0.3); user-select: none; transition: opacity 0.15s; opacity: 0; `; document.body.appendChild(tooltip); let mouseX = 0, mouseY = 0; let ticking = false; document.addEventListener('mousemove', (e) => { // tooltip 定位仍用 clientX/clientY(基于视口) mouseX = e.clientX; mouseY = e.clientY; if (!ticking) { window.requestAnimationFrame(() => { // 屏幕坐标:相对于整个显示器屏幕左上角 const sx = e.clientX; const sy = e.clientY; tooltip.textContent = `${sx},${sy}`; tooltip.style.opacity = '1'; const offset = 15; let left = mouseX + offset; let top = mouseY + offset; const rect = tooltip.getBoundingClientRect(); if (left + rect.width > window.innerWidth) { left = mouseX - rect.width - offset; } if (top + rect.height > window.innerHeight) { top = mouseY - rect.height - offset; } tooltip.style.left = left + 'px'; tooltip.style.top = top + 'px'; ticking = false; }); ticking = true; } }); document.addEventListener('mouseleave', () => { tooltip.style.opacity = '0'; }); console.log('[鼠标屏幕坐标] 脚本已加载'); //输入框结尾 let isProcessing = false; let lastDialogCloseTime = 0; // 记录上次弹窗关闭时间,避免残留误判 function isDialogVisible() { // 检查选项是否存在且可见 const radios = document.querySelectorAll('.el-radio'); if (radios.length < 2) return false; // 检查第一个 radio 是否在视觉上可见(宽高大于0且未被隐藏) const firstRadio = radios[0]; if (firstRadio.offsetParent === null) return false; // 额外检查弹窗容器是否可见 const dialog = document.querySelector('.el-dialog'); return dialog !== null; } function selectRadio(index) { const radios = document.querySelectorAll('.el-radio'); if (!radios.length) return false; const target = radios[index]; target.click(); const input = target.querySelector('input[type="radio"]'); if (input) { input.checked = true; input.dispatchEvent(new Event('input', { bubbles: true })); input.dispatchEvent(new Event('change', { bubbles: true })); } console.log(`✅ 已选择选项 ${index + 1}: ${target.textContent.trim()}`); return true; } function simulateClick(x, y) { console.log(`🖱️ 在坐标 (${x}, ${y}) 模拟鼠标点击`); // 获取该坐标下的顶层元素 const target = document.elementFromPoint(x, y); if (!target) { console.warn('坐标处无元素'); return false; } console.log(` 目标元素: ${target.tagName}.${target.className}`); // 派发完整鼠标事件序列 const events = [ new PointerEvent('pointerdown', { bubbles: true, cancelable: true, clientX: x, clientY: y }), new MouseEvent('mousedown', { bubbles: true, cancelable: true, clientX: x, clientY: y }), new PointerEvent('pointerup', { bubbles: true, cancelable: true, clientX: x, clientY: y }), new MouseEvent('mouseup', { bubbles: true, cancelable: true, clientX: x, clientY: y }), new MouseEvent('click', { bubbles: true, cancelable: true, clientX: x, clientY: y }) ]; const element = document.elementFromPoint(x, y); if (element) { const clickEvent = new MouseEvent('click', {view: window,bubbles: true,cancelable: true,clientX: x,clientY: y}); element.dispatchEvent(clickEvent); } else { console.log("未找到对应坐标的元素"); } events.forEach(event => target.dispatchEvent(event)); return true; } function doSequence() { if (isProcessing) return; isProcessing = true; // 第一步:选正确并确认 selectRadio(0); setTimeout(() => simulateClick(window.clickX, window.clickY), 100); // 1秒后第二步 setTimeout(() => { // 重新检查弹窗是否还在(可能已关闭) if (!isDialogVisible()) { console.warn('弹窗已提前关闭,跳过第二步'); isProcessing = false; return; } selectRadio(1); setTimeout(() => simulateClick(window.clickX, window.clickY), 100); // 完成标记 setTimeout(() => { isProcessing = false; lastDialogCloseTime = Date.now(); console.log('✅ 流程完成,等待下一次弹窗'); }, 2000); }, 1000); } // 主循环:每 500ms 检查一次弹窗 setInterval(() => { if (isProcessing) return; // 弹窗关闭后 3 秒内不触发(防止弹窗关闭动画导致的误判) if (Date.now() - lastDialogCloseTime < 3000) return; if (isDialogVisible()) { console.log('🔔 检测到弹窗'); doSequence(); } }, 500); // 同时保留 MutationObserver 作为补充(处理弹窗通过插入新节点出现的情况) const observer = new MutationObserver(mutations => { for (const m of mutations) { if (!m.addedNodes.length) continue; for (const node of m.addedNodes) { if (node.nodeType !== 1) continue; if (node.querySelectorAll('.el-radio').length >= 2) { if (!isProcessing && Date.now() - lastDialogCloseTime >= 3000) { console.log('🔔 DOM 新增弹窗'); doSequence(); } return; } } } }); const tooltip1 = document.createElement('div'); tooltip1.id = 'mouse-screen-coord-tooltip1'; tooltip1.style.cssText = ` position: fixed; pointer-events: none; z-index: 999999; background: rgba(0, 0, 0, 0.75); color: #00ff88; font-family: 'Courier New', monospace; font-size: 12px; padding: 4px 8px; border-radius: 4px; white-space: nowrap; box-shadow: 0 2px 8px rgba(0,0,0,0.3); border: 1px solid rgba(0, 255, 136, 0.3); user-select: none; transition: opacity 0.15s; opacity: 0; `; document.body.appendChild(tooltip1); document.addEventListener('mousemove', (e) => { // tooltip 定位仍用 clientX/clientY(基于视口) mouseX = e.clientX; mouseY = e.clientY; if (!ticking) { window.requestAnimationFrame(() => { // 屏幕坐标:相对于整个显示器屏幕左上角 const sx = e.clientX; const sy = e.clientY; tooltip.textContent = `${sx},${sy}`; tooltip.style.opacity = '1'; const offset = 15; let left = mouseX + offset; let top = mouseY + offset; const rect = tooltip.getBoundingClientRect(); if (left + rect.width > window.innerWidth) { left = mouseX - rect.width - offset; } if (top + rect.height > window.innerHeight) { top = mouseY - rect.height - offset; } tooltip.style.left = left + 'px'; tooltip.style.top = top + 'px'; ticking = false; }); ticking = true; } }); document.addEventListener('mouseleave', () => { tooltip1.style.opacity = '0'; }); console.log('[鼠标屏幕坐标] 脚本已加载'); })();