Idle MMO Battle Automation with GUI and Logs

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.

您需要先安装一个扩展,例如 篡改猴Greasemonkey暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴Userscripts ,之后才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。

您需要先安装用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         Idle MMO Battle Automation with GUI and Logs
// @namespace    https://web.idle-mmo.com/
// @version      1.3
// @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
// @match        https://web.idle-mmo.com/battle?same_window=true
// @grant        GM_addStyle
// ==/UserScript==

(function() {
    'use strict';

    // Settings
    let autoBattleEnabled = true;
    let cooldownMin = 2000; // Minimum cooldown (milliseconds)
    let cooldownMax = 5000; // Maximum cooldown (milliseconds)
    let randomizeCooldown = true;

    // Function to log messages to the GUI
    function logMessage(message) {
        const logArea = document.getElementById('logArea');
        const timestamp = new Date().toLocaleTimeString();
        logArea.value += `[${timestamp}] ${message}\n`;
        logArea.scrollTop = logArea.scrollHeight; // Auto-scroll to the bottom
    }

    // Function to click buttons by CSS selector with improved timing
    function clickButtonBySelector(selector) {
        const waitForButton = setInterval(() => {
            const button = document.querySelector(selector);
            if (button) {
                const isButtonDisabled = button.hasAttribute('disabled') || button.classList.contains('opacity-40');
                logMessage(`Button found with selector: ${selector}`);
                logMessage(`Button disabled state: ${isButtonDisabled}`);
                if (!isButtonDisabled) {
                    try {
                        clearInterval(waitForButton);

                        // Introduce a small random delay before clicking to simulate more human-like behavior
                        setTimeout(() => {
                            button.click();
                            logMessage(`Clicked button with selector: ${selector}`);
                            // Log button action
                            logMessage(`Button ${selector} action triggered.`);
                        }, getRandomCooldown()); // Use a small random delay

                    } catch (error) {
                        logMessage(`Error clicking button with selector: ${selector} - ${error.message}`);
                    }
                } else {
                    logMessage(`Button with selector: ${selector} is disabled`);
                }
            } else {
                logMessage(`Button with selector: ${selector} not found`);
            }
        }, 1000); // Check every 1000ms
    }

    // Function to get the value of an element by CSS selector
    function getValueBySelector(selector) {
        const element = document.querySelector(selector);
        return element ? parseInt(element.textContent.trim(), 10) : null;
    }

    // Function to get a random cooldown value within the specified range
    function getRandomCooldown() {
        return Math.floor(Math.random() * (cooldownMax - cooldownMin + 1)) + cooldownMin;
    }

    // Automation logic (focuses on "Start Hunt", "Battle Max" and "Battle Max" button)
    function automateBattle() {
        if (!autoBattleEnabled) return;

        const battleMaxValueSelector = 'div.w-5'; // Adjust selector if necessary
        const startHuntSelector = 'button.bg-white\\/10:nth-child(1)';
        const battleMaxButtonSelector = 'button.battle-max'; // Placeholder selector for "Battle Max" button

        setTimeout(() => {
            const battleMaxValue = getValueBySelector(battleMaxValueSelector);
            logMessage(`Battle Max Value: ${battleMaxValue}`);

            if (document.querySelector(startHuntSelector)) {
                logMessage(`Attempting to click "Start Hunt"`);
                clickButtonBySelector(startHuntSelector);
            } else if (battleMaxValue > 0 && document.querySelector(battleMaxButtonSelector)) {
                logMessage(`Attempting to click "Battle Max" button`);
                clickButtonBySelector(battleMaxButtonSelector);
            } else {
                logMessage(`"Start Hunt" button not found or Battle Max value is not greater than 0, or "Battle Max" button not found.`);
            }
        }, randomizeCooldown ? getRandomCooldown() : cooldownMin);
    }

    // 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: #ffffff;
                border: 1px solid #cccccc;
                padding: 10px;
                border-radius: 5px;
                box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.1);
                z-index: 1000;
                opacity: 1; /* Ensure GUI is initially visible */
                transition: opacity 0.3s; /* 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 button,
            #battle-automation-gui textarea {
                font-size: 14px;
                color: black;
            }
            #battle-automation-gui textarea {
                width: 100%;
                font-family: monospace;
            }
            #toggleGUIButton {
                background: #f39c12;
                color: white;
                border: none;
                padding: 8px 16px;
                cursor: pointer;
                z-index: 1001;
            }
        `);
    }

    // Initialize GUI
    createGUI();
})();