您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Automatically clicks "Start Hunt" and "Battle Max" based on game conditions. Includes a GUI for toggling settings, viewing logs, and copying the log, with customizable cooldown and randomization to prevent bans.
当前为
// ==UserScript== // @name Idle MMO Battle Automation with GUI and Logs // @namespace https://web.idle-mmo.com/ // @version 1.1 // @description Automatically clicks "Start Hunt" and "Battle Max" based on game conditions. Includes a GUI for toggling settings, viewing logs, and copying the log, with customizable cooldown and randomization to prevent bans. // @author Unknown Monkey // @match https://web.idle-mmo.com/battle // @grant GM_addStyle // ==/UserScript== (function() { 'use strict'; // Settings let autoBattleEnabled = true; let autoHuntEnabled = true; let cooldownMin = 2000; // Minimum cooldown (milliseconds) let cooldownMax = 5000; // Maximum cooldown (milliseconds) let randomizeCooldown = true; // Function to click buttons by XPath (enhanced with direct click method) function clickButtonByXPath(xpath) { setTimeout(() => { const button = document.evaluate(xpath, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue; if (button) { // Check button state before clicking const isButtonDisabled = button.hasAttribute('disabled') || button.classList.contains('disabled'); logMessage(`Button found with XPath: ${xpath}`); logMessage(`Button disabled state: ${isButtonDisabled}`); if (!isButtonDisabled) { try { button.click(); // Use click() directly logMessage(`Clicked button with XPath: ${xpath}`); } catch (error) { logMessage(`Error clicking button with XPath: ${xpath} - ${error.message}`); } } else { logMessage(`Button with XPath: ${xpath} is disabled`); } } else { logMessage(`Button with XPath: ${xpath} not found`); } }, randomizeCooldown ? getRandomCooldown() : cooldownMin); } // Function to get the value of an element by CSS selector function getValueBySelector(selector) { const element = document.querySelector(selector); return element ? element.textContent.trim() : null; } // Function to get a random cooldown value within the specified range function getRandomCooldown() { return Math.floor(Math.random() * (cooldownMax - cooldownMin + 1)) + cooldownMin; } // Function to check if an element exists by XPath function elementExistsByXPath(xpath) { const element = document.evaluate(xpath, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue; return element !== null; } // Function to check for the "Start Hunt" button function checkForStartHunt() { const startHuntXPath = '/html/body/div[1]/main/div[1]/div/div[2]/div[2]/div/div[2]/div[1]/div[1]/div[2]/div/div/div/div[1]/button'; return elementExistsByXPath(startHuntXPath); } // Logging function function logMessage(message) { const logArea = document.getElementById('logArea'); const timestamp = new Date().toLocaleTimeString(); logArea.value += `[${timestamp}] ${message}\n`; logArea.scrollTop = logArea.scrollHeight; } // Automation logic (removed "Hunt Again" and only focuses on "Start Hunt" and "Battle Max") function automateBattle() { if (!autoBattleEnabled) return; // Updated XPaths and CSS selectors const battleMaxXPath = '/html/body/div[1]/main/div[1]/div/div[2]/div[2]/div/div[2]/div[1]/div[1]/div[2]/div/div[2]/div[1]/button'; const battleMaxValueSelector = 'div.w-5'; // CSS selector for Battle Max Value const startHuntXPath = '/html/body/div[1]/main/div[1]/div/div[2]/div[2]/div/div[2]/div[1]/div[1]/div[2]/div/div/div/div[1]/button'; const enemiesXPath = '/html/body/div[1]/main/div[1]/div/div[2]/div[2]/div/div[2]/div[1]/div[1]/div[2]/div'; setTimeout(() => { // Re-evaluate the XPath to handle potential stale element reference const battleMaxButton = document.evaluate(battleMaxXPath, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue; const battleMaxValue = getValueBySelector(battleMaxValueSelector); const startHuntButton = document.evaluate(startHuntXPath, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue; // Check if there are any enemy buttons within the enemiesXPath container const enemiesContainer = document.evaluate(enemiesXPath, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue; const enemyButtons = enemiesContainer ? enemiesContainer.querySelectorAll('button') : []; const enemiesExist = enemyButtons.length > 0; // Enhanced logging for debugging console.log("autoBattleEnabled:", autoBattleEnabled); console.log("battleMaxButton:", battleMaxButton); console.log("battleMaxButton.disabled:", battleMaxButton ? battleMaxButton.disabled : "null"); console.log("battleMaxValue:", battleMaxValue); console.log("parseInt(battleMaxValue) > 0:", parseInt(battleMaxValue) > 0); console.log("startHuntButton:", startHuntButton); logMessage(`Enemies Exist: ${enemiesExist}`); logMessage(`Battle Max Value: ${battleMaxValue}`); // Prioritize "Start Hunt", then "Battle Max" if (autoBattleEnabled && startHuntButton) { logMessage(`Attempting to click "Start Hunt"`); clickButtonByXPath(startHuntXPath); } else if (autoBattleEnabled && battleMaxButton && !battleMaxButton.disabled && battleMaxValue !== null && parseInt(battleMaxValue) > 0) { logMessage(`Attempting to click "Battle Max"`); clickButtonByXPath(battleMaxXPath); } else { // Log specific reasons for not clicking if (!autoBattleEnabled) logMessage("Auto Battle is disabled."); if (!battleMaxButton) logMessage("Battle Max button not found."); if (battleMaxButton && battleMaxButton.disabled) logMessage("Battle Max button is disabled."); if (battleMaxValue === null) logMessage("Battle Max value is null."); if (!(parseInt(battleMaxValue) > 0)) logMessage("Battle Max value is not greater than 0."); if (!startHuntButton) logMessage("Start Hunt button not found."); } }, 500); } // Set up an interval for automation setInterval(automateBattle, randomizeCooldown ? getRandomCooldown() : cooldownMin); // GUI creation with a toggle button function createGUI() { // Create GUI container const gui = document.createElement('div'); gui.id = 'battle-automation-gui'; gui.innerHTML = ` <div> <h3>Battle Automation</h3> <label><input type="checkbox" id="toggleAutoBattle" checked> Auto Battle</label><br> <label for="cooldownMin">Cooldown Min (ms):</label> <input type="number" id="cooldownMin" value="${cooldownMin}" min="0"><br> <label for="cooldownMax">Cooldown Max (ms):</label> <input type="number" id="cooldownMax" value="${cooldownMax}" min="0"><br> <label><input type="checkbox" id="toggleRandomizeCooldown" checked> Randomize Cooldown</label><br> <textarea id="logArea" rows="10" cols="40" readonly></textarea><br> <button id="copyLogButton">Copy Log</button><br> </div> `; document.body.appendChild(gui); // Create Show/Hide GUI button const toggleGUIButton = document.createElement('button'); toggleGUIButton.id = 'toggleGUIButton'; toggleGUIButton.textContent = 'Hide GUI'; toggleGUIButton.style.position = 'fixed'; toggleGUIButton.style.top = '10px'; toggleGUIButton.style.right = '10px'; toggleGUIButton.style.zIndex = '1001'; // Above GUI document.body.appendChild(toggleGUIButton); // Event listeners for toggling settings document.getElementById('toggleAutoBattle').addEventListener('change', (e) => { autoBattleEnabled = e.target.checked; logMessage(`Auto Battle: ${autoBattleEnabled}`); }); // Event listeners for cooldown settings document.getElementById('cooldownMin').addEventListener('change', (e) => { cooldownMin = parseInt(e.target.value, 10); logMessage(`Cooldown Min set to: ${cooldownMin}`); }); document.getElementById('cooldownMax').addEventListener('change', (e) => { cooldownMax = parseInt(e.target.value, 10); logMessage(`Cooldown Max set to: ${cooldownMax}`); }); // Event listeners for randomizing cooldown document.getElementById('toggleRandomizeCooldown').addEventListener('change', (e) => { randomizeCooldown = e.target.checked; logMessage(`Randomize Cooldown: ${randomizeCooldown}`); }); // Event listener for copying logs document.getElementById('copyLogButton').addEventListener('click', () => { const logArea = document.getElementById('logArea'); logArea.select(); document.execCommand('copy'); logMessage('Log copied to clipboard.'); }); // Event listener for hiding/showing GUI document.getElementById('toggleGUIButton').addEventListener('click', () => { const gui = document.getElementById('battle-automation-gui'); if (gui.style.opacity === '0') { gui.style.opacity = '1'; document.getElementById('toggleGUIButton').textContent = 'Hide GUI'; } else { gui.style.opacity = '0'; document.getElementById('toggleGUIButton').textContent = 'Show GUI'; } }); // Inject CSS for GUI GM_addStyle(` #battle-automation-gui { position: fixed; top: 10px; right: 10px; background: rgba(255, 255, 255, 0.5); /* Semi-transparent background */ border: 1px solid #ccc; padding: 10px; z-index: 1000; font-family: Arial, sans-serif; opacity: 1; /* Start with GUI visible */ transition: opacity 0.3s ease; /* Smooth transition for hiding/showing */ } #battle-automation-gui h3 { margin: 0; font-size: 16px; color: black; } #battle-automation-gui label, #battle-automation-gui input, #battle-automation-gui textarea, #battle-automation-gui button { font-size: 14px; color: black; } #logArea { color: red; /* Red text for the log area */ } `); } // Create GUI on page load window.addEventListener('load', createGUI); })();