// ==UserScript==
// @name 元梦之星农场辅助(最终修复版)QQ群121234447
// @namespace https://your-namespace.com
// @match *://gamer.qq.com/v2/game/*
// @grant none
// @version 1.1
// @author QQ1277745546
// @description 修复拖拽和点击问题的最终版
// @require https://code.jquery.com/jquery-3.6.0.min.js
// ==/UserScript==
(function() {
'use strict';
// ===== 配置 =====
const config = {
loopInterval: 30000,
uiMinimized: false,
buttonsToClick: [
{ selector: ".cancel-btn", desc: "取消按钮", customPos: false, x: 879, y: 650 },
{ selector: ".reject-btn", desc: "拒绝按钮", customPos: false, x: 0, y: 0 }
],
keySequence: [
{ key: "r", delayAfter: 1500 },
{ key: "Shift", times: 10, interval: 800, delayAfter: 1500 },
{ key: "a", duration: 800, delayAfter: 0 },
{ key: "q" }
],
isCapturingPos: false,
currentCaptureFor: null,
shouldStop: false,
qqGroupLink: "https://qm.qq.com/q/esXtDSP2WA",
qqGroupNumber: "121234447"
};
// ===== 状态变量 =====
let isRunning = false;
let timer = null;
let cycleCount = 0;
let isDragging = false;
let offsetX = 0, offsetY = 0;
// ===== 核心功能 =====
async function executeSequence() {
if (config.shouldStop) return;
cycleCount++;
log(`\n🔄 开始第 ${cycleCount} 次循环`);
updateStatus();
// 1. 点击界面按钮
for (const btn of config.buttonsToClick) {
if (config.shouldStop) break;
if (btn.customPos) {
if (!await clickAtPosition(btn.x, btn.y)) {
log(`⚠️ 坐标点击失败: [${btn.x}, ${btn.y}]`);
} else {
log(`🖱️ 点击坐标: [${btn.x}, ${btn.y}] (${btn.desc})`);
}
} else {
const element = document.querySelector(btn.selector);
if (element) {
simulateRealClick(element);
log(`🖱️ 点击: ${btn.desc}`);
} else {
log(`⚠️ 未找到: ${btn.desc}`);
}
}
await delay(500);
}
// 2. 执行按键序列
for (const step of config.keySequence) {
if (config.shouldStop) break;
if (step.times) {
for (let i = 1; i <= step.times; i++) {
if (config.shouldStop) break;
await pressKey(step.key);
log(`⇧ ${step.key} 第 ${i} 次`);
if (i < step.times) await delay(step.interval);
}
} else if (step.duration) {
await holdKey(step.key, step.duration);
} else {
await pressKey(step.key);
}
if (step.delayAfter && !config.shouldStop) await delay(step.delayAfter);
}
if (!config.shouldStop) {
log(`⏱ 下次执行在 ${config.loopInterval/1000} 秒后`);
timer = setTimeout(executeSequence, config.loopInterval);
}
}
// ===== 控制函数 =====
function startAuto() {
if (isRunning) return;
config.shouldStop = false;
isRunning = true;
updateStatus();
log("🚀 启动自动化任务");
executeSequence();
}
async function stopAuto() {
if (!isRunning) return;
config.shouldStop = true;
isRunning = false;
if (timer) clearTimeout(timer);
updateStatus();
log("🛑 正在停止任务...");
// 停止后1秒按R键
await delay(1000);
if (!isRunning) { // 确保在停止状态才发送R键
const key = "r";
const code = `Key${key.toUpperCase()}`;
const keyCode = key.toUpperCase().charCodeAt(0);
// 确保发送完整的按键事件
document.dispatchEvent(new KeyboardEvent("keydown", {
key, code, keyCode, bubbles: true, cancelable: true
}));
await delay(50);
document.dispatchEvent(new KeyboardEvent("keyup", {
key, code, keyCode, bubbles: true, cancelable: true
}));
log("⌨ 已发送停止信号(R键)");
}
}
// ===== 修复后的拖拽功能 =====
function setupDrag() {
const ui = document.getElementById("auto-ui");
const header = ui.querySelector("div:first-child");
header.addEventListener("mousedown", function(e) {
if (e.target.id === "minimize-btn" || e.target.classList.contains("capture-btn")) return;
isDragging = true;
offsetX = e.clientX - ui.getBoundingClientRect().left;
offsetY = e.clientY - ui.getBoundingClientRect().top;
e.preventDefault();
});
document.addEventListener("mousemove", function(e) {
if (!isDragging) return;
ui.style.left = (e.clientX - offsetX) + "px";
ui.style.top = (e.clientY - offsetY) + "px";
});
document.addEventListener("mouseup", function() {
isDragging = false;
});
}
// ===== 修复后的坐标捕捉功能 =====
function setupPositionCapture() {
document.querySelectorAll(".capture-btn").forEach(btn => {
btn.addEventListener("click", function(e) {
e.stopPropagation();
const index = parseInt(this.getAttribute("data-index"));
startPositionCapture(index);
});
});
}
// ===== UI界面 =====
function createUI() {
if (document.getElementById("auto-ui")) return;
const positionControls = config.buttonsToClick.map((btn, index) => `
`).join('');
const uiHtml = `
按键控制面板QQ群121234447
🔴 已停止
`;
document.body.insertAdjacentHTML("beforeend", uiHtml);
// 初始化拖拽功能
setupDrag();
// 初始化坐标捕捉功能
setupPositionCapture();
// 循环间隔最小值限制
document.getElementById("loop-interval").addEventListener("change", function() {
let value = parseInt(this.value);
if (value < 15) {
value = 15;
this.value = 15;
}
config.loopInterval = value * 1000;
});
// 使用坐标复选框
config.buttonsToClick.forEach((btn, index) => {
document.getElementById(`use-custom-${index}`).addEventListener("change", function() {
btn.customPos = this.checked;
log(`${btn.desc} ${btn.customPos ? "使用" : "不使用"}自定义坐标`);
});
document.getElementById(`pos-x-${index}`).addEventListener("change", function() {
btn.x = parseInt(this.value) || 0;
if (btn.x > 0 && btn.y > 0) {
btn.customPos = true;
document.getElementById(`use-custom-${index}`).checked = true;
}
});
document.getElementById(`pos-y-${index}`).addEventListener("change", function() {
btn.y = parseInt(this.value) || 0;
if (btn.x > 0 && btn.y > 0) {
btn.customPos = true;
document.getElementById(`use-custom-${index}`).checked = true;
}
});
});
// 控制按钮事件
document.getElementById("start-btn").addEventListener("click", startAuto);
document.getElementById("stop-btn").addEventListener("click", stopAuto);
document.getElementById("minimize-btn").addEventListener("click", function() {
toggleMinimize();
});
}
// ===== 其他辅助函数 =====
function updateStatus() {
const statusText = isRunning ? "🟢 运行中" : "🔴 已停止";
document.getElementById("status-indicator").textContent = statusText;
}
function toggleMinimize() {
const ui = document.getElementById("auto-ui");
const content = document.getElementById("ui-content");
const btn = document.getElementById("minimize-btn");
config.uiMinimized = !config.uiMinimized;
if (config.uiMinimized) {
ui.style.width = "150px";
ui.style.height = "80px";
content.style.display = "none";
btn.textContent = "↗";
} else {
ui.style.width = "420px";
ui.style.height = "auto";
content.style.display = "block";
btn.textContent = "−";
}
}
function startPositionCapture(buttonIndex) {
config.isCapturingPos = true;
config.currentCaptureFor = buttonIndex;
log(`🎯 开始捕捉坐标 (${config.buttonsToClick[buttonIndex].desc})`);
log("👉 请点击目标位置...");
document.body.style.cursor = "crosshair";
document.getElementById("auto-ui").style.cursor = "default";
}
function handlePositionCapture(e) {
if (!config.isCapturingPos) return;
e.preventDefault();
e.stopPropagation();
const x = e.clientX;
const y = e.clientY;
const buttonIndex = config.currentCaptureFor;
config.buttonsToClick[buttonIndex].x = x;
config.buttonsToClick[buttonIndex].y = y;
config.buttonsToClick[buttonIndex].customPos = true;
document.getElementById(`pos-x-${buttonIndex}`).value = x;
document.getElementById(`pos-y-${buttonIndex}`).value = y;
document.getElementById(`use-custom-${buttonIndex}`).checked = true;
log(`✔ 已记录坐标: [${x}, ${y}] (${config.buttonsToClick[buttonIndex].desc})`);
endPositionCapture();
}
function endPositionCapture() {
config.isCapturingPos = false;
config.currentCaptureFor = null;
document.body.style.cursor = "";
document.getElementById("auto-ui").style.cursor = "";
}
function simulateRealClick(element) {
const rect = element.getBoundingClientRect();
const x = rect.left + rect.width/2;
const y = rect.top + rect.height/2;
const mouseOver = new MouseEvent('mouseover', { bubbles: true, clientX: x, clientY: y });
const mouseDown = new MouseEvent('mousedown', { bubbles: true, clientX: x, clientY: y });
const mouseUp = new MouseEvent('mouseup', { bubbles: true, clientX: x, clientY: y });
const click = new MouseEvent('click', { bubbles: true, clientX: x, clientY: y });
element.dispatchEvent(mouseOver);
element.dispatchEvent(mouseDown);
element.dispatchEvent(mouseUp);
element.dispatchEvent(click);
}
async function clickAtPosition(x, y) {
return new Promise(resolve => {
const element = document.elementFromPoint(x, y);
if (element) {
const mouseDown = new MouseEvent('mousedown', {
bubbles: true,
cancelable: true,
view: window,
clientX: x,
clientY: y,
screenX: x + window.screenX,
screenY: y + window.screenY
});
const mouseUp = new MouseEvent('mouseup', {
bubbles: true,
cancelable: true,
view: window,
clientX: x,
clientY: y,
screenX: x + window.screenX,
screenY: y + window.screenY
});
const click = new MouseEvent('click', {
bubbles: true,
cancelable: true,
view: window,
clientX: x,
clientY: y
});
element.dispatchEvent(mouseDown);
setTimeout(() => {
element.dispatchEvent(mouseUp);
element.dispatchEvent(click);
resolve(true);
}, 50);
} else {
resolve(false);
}
});
}
function pressKey(key) {
return new Promise(resolve => {
if (config.shouldStop) return resolve();
const code = key === "Shift" ? "ShiftLeft" : `Key${key.toUpperCase()}`;
const keyCode = key === "Shift" ? 16 : key.toUpperCase().charCodeAt(0);
const downEvent = new KeyboardEvent("keydown", {
key, code, keyCode,
bubbles: true,
cancelable: true,
composed: true
});
document.dispatchEvent(downEvent);
setTimeout(() => {
const upEvent = new KeyboardEvent("keyup", {
key, code, keyCode,
bubbles: true,
cancelable: true,
composed: true
});
document.dispatchEvent(upEvent);
log(`⌨ 按键: ${key}`);
resolve();
}, 50);
});
}
function holdKey(key, duration) {
return new Promise(resolve => {
if (config.shouldStop) return resolve();
const code = key === "Shift" ? "ShiftLeft" : `Key${key.toUpperCase()}`;
const keyCode = key === "Shift" ? 16 : key.toUpperCase().charCodeAt(0);
const downEvent = new KeyboardEvent("keydown", {
key, code, keyCode,
bubbles: true,
cancelable: true,
composed: true
});
document.dispatchEvent(downEvent);
log(`🔼 长按: ${key}`);
const interval = setInterval(() => {
if (config.shouldStop) {
clearInterval(interval);
document.dispatchEvent(new KeyboardEvent("keyup", {
key, code, keyCode,
bubbles: true,
cancelable: true,
composed: true
}));
resolve();
}
}, 100);
setTimeout(() => {
if (!config.shouldStop) {
clearInterval(interval);
document.dispatchEvent(new KeyboardEvent("keyup", {
key, code, keyCode,
bubbles: true,
cancelable: true,
composed: true
}));
log(`🔽 松开: ${key}`);
}
resolve();
}, duration);
});
}
function delay(ms) {
return new Promise(resolve => {
if (config.shouldStop) return resolve();
setTimeout(resolve, ms);
});
}
function log(message) {
const time = new Date().toLocaleTimeString();
const logText = `[${time}] ${message}\n`;
console.log(logText);
const logArea = document.getElementById("log-area");
logArea.value += logText;
logArea.scrollTop = logArea.scrollHeight;
}
// ===== 初始化 =====
window.addEventListener('load', function() {
createUI();
createWatermark();
createBlinkingGroupLink();
log("✅ 脚本已加载");
log(`💬 交流群: ${config.qqGroupNumber}`);
log("🔍 正在检测按钮...");
config.buttonsToClick.forEach(btn => {
if (!document.querySelector(btn.selector)) {
log(`⚠️ 未找到: ${btn.desc} (${btn.selector})`);
}
});
// 全局点击事件用于坐标捕捉
document.addEventListener("click", function(e) {
if (config.isCapturingPos) {
handlePositionCapture(e);
}
});
});
function createWatermark() {
const watermark = document.createElement('div');
watermark.innerHTML = `
脚本辅助QQ群:${config.qqGroupNumber}
${document.title}
`;
document.body.appendChild(watermark);
}
function createBlinkingGroupLink() {
const link = document.createElement('a');
link.href = config.qqGroupLink;
link.target = '_blank';
link.textContent = '元梦之星农场交流群1';
link.style.cssText = `
position: fixed;
bottom: 20px;
right: 20px;
padding: 10px 15px;
background: #ff0000;
color: white;
font-weight: bold;
border-radius: 5px;
text-decoration: none;
z-index: 99999;
animation: blink 1s infinite alternate;
box-shadow: 0 0 10px rgba(0,0,0,0.5);
`;
const style = document.createElement('style');
style.textContent = `
@keyframes blink {
0% { background: #ff0000; }
100% { background: #0000ff; }
}
`;
document.head.appendChild(style);
document.body.appendChild(link);
}
})();