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.

  1. // ==UserScript==
  2. // @name Idle MMO Battle Automation with GUI and Logs
  3. // @namespace https://web.idle-mmo.com/
  4. // @version 1.3
  5. // @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.
  6. // @author Unknown Monkey
  7. // @match https://web.idle-mmo.com/battle
  8. // @match https://web.idle-mmo.com/battle?same_window=true
  9. // @grant GM_addStyle
  10. // ==/UserScript==
  11.  
  12. (function() {
  13. 'use strict';
  14.  
  15. // Settings
  16. let autoBattleEnabled = true;
  17. let cooldownMin = 2000; // Minimum cooldown (milliseconds)
  18. let cooldownMax = 5000; // Maximum cooldown (milliseconds)
  19. let randomizeCooldown = true;
  20.  
  21. // Function to log messages to the GUI
  22. function logMessage(message) {
  23. const logArea = document.getElementById('logArea');
  24. const timestamp = new Date().toLocaleTimeString();
  25. logArea.value += `[${timestamp}] ${message}\n`;
  26. logArea.scrollTop = logArea.scrollHeight; // Auto-scroll to the bottom
  27. }
  28.  
  29. // Function to click buttons by CSS selector with improved timing
  30. function clickButtonBySelector(selector) {
  31. const waitForButton = setInterval(() => {
  32. const button = document.querySelector(selector);
  33. if (button) {
  34. const isButtonDisabled = button.hasAttribute('disabled') || button.classList.contains('opacity-40');
  35. logMessage(`Button found with selector: ${selector}`);
  36. logMessage(`Button disabled state: ${isButtonDisabled}`);
  37. if (!isButtonDisabled) {
  38. try {
  39. clearInterval(waitForButton);
  40.  
  41. // Introduce a small random delay before clicking to simulate more human-like behavior
  42. setTimeout(() => {
  43. button.click();
  44. logMessage(`Clicked button with selector: ${selector}`);
  45. // Log button action
  46. logMessage(`Button ${selector} action triggered.`);
  47. }, getRandomCooldown()); // Use a small random delay
  48.  
  49. } catch (error) {
  50. logMessage(`Error clicking button with selector: ${selector} - ${error.message}`);
  51. }
  52. } else {
  53. logMessage(`Button with selector: ${selector} is disabled`);
  54. }
  55. } else {
  56. logMessage(`Button with selector: ${selector} not found`);
  57. }
  58. }, 1000); // Check every 1000ms
  59. }
  60.  
  61. // Function to get the value of an element by CSS selector
  62. function getValueBySelector(selector) {
  63. const element = document.querySelector(selector);
  64. return element ? parseInt(element.textContent.trim(), 10) : null;
  65. }
  66.  
  67. // Function to get a random cooldown value within the specified range
  68. function getRandomCooldown() {
  69. return Math.floor(Math.random() * (cooldownMax - cooldownMin + 1)) + cooldownMin;
  70. }
  71.  
  72. // Automation logic (focuses on "Start Hunt", "Battle Max" and "Battle Max" button)
  73. function automateBattle() {
  74. if (!autoBattleEnabled) return;
  75.  
  76. const battleMaxValueSelector = 'div.w-5'; // Adjust selector if necessary
  77. const startHuntSelector = 'button.bg-white\\/10:nth-child(1)';
  78. const battleMaxButtonSelector = 'button.battle-max'; // Placeholder selector for "Battle Max" button
  79.  
  80. setTimeout(() => {
  81. const battleMaxValue = getValueBySelector(battleMaxValueSelector);
  82. logMessage(`Battle Max Value: ${battleMaxValue}`);
  83.  
  84. if (document.querySelector(startHuntSelector)) {
  85. logMessage(`Attempting to click "Start Hunt"`);
  86. clickButtonBySelector(startHuntSelector);
  87. } else if (battleMaxValue > 0 && document.querySelector(battleMaxButtonSelector)) {
  88. logMessage(`Attempting to click "Battle Max" button`);
  89. clickButtonBySelector(battleMaxButtonSelector);
  90. } else {
  91. logMessage(`"Start Hunt" button not found or Battle Max value is not greater than 0, or "Battle Max" button not found.`);
  92. }
  93. }, randomizeCooldown ? getRandomCooldown() : cooldownMin);
  94. }
  95.  
  96. // Set up an interval for automation
  97. setInterval(automateBattle, randomizeCooldown ? getRandomCooldown() : cooldownMin);
  98.  
  99. // GUI creation with a toggle button
  100. function createGUI() {
  101. // Create GUI container
  102. const gui = document.createElement('div');
  103. gui.id = 'battle-automation-gui';
  104. gui.innerHTML = `
  105. <div>
  106. <h3>Battle Automation</h3>
  107. <label><input type="checkbox" id="toggleAutoBattle" checked> Auto Battle</label><br>
  108. <label for="cooldownMin">Cooldown Min (ms):</label>
  109. <input type="number" id="cooldownMin" value="${cooldownMin}" min="0"><br>
  110. <label for="cooldownMax">Cooldown Max (ms):</label>
  111. <input type="number" id="cooldownMax" value="${cooldownMax}" min="0"><br>
  112. <label><input type="checkbox" id="toggleRandomizeCooldown" checked> Randomize Cooldown</label><br>
  113. <textarea id="logArea" rows="10" cols="40" readonly></textarea><br>
  114. <button id="copyLogButton">Copy Log</button><br>
  115. </div>
  116. `;
  117. document.body.appendChild(gui);
  118.  
  119. // Create Show/Hide GUI button
  120. const toggleGUIButton = document.createElement('button');
  121. toggleGUIButton.id = 'toggleGUIButton';
  122. toggleGUIButton.textContent = 'Hide GUI';
  123. toggleGUIButton.style.position = 'fixed';
  124. toggleGUIButton.style.top = '10px';
  125. toggleGUIButton.style.right = '10px';
  126. toggleGUIButton.style.zIndex = '1001'; // Above GUI
  127. document.body.appendChild(toggleGUIButton);
  128.  
  129. // Event listeners for toggling settings
  130. document.getElementById('toggleAutoBattle').addEventListener('change', (e) => {
  131. autoBattleEnabled = e.target.checked;
  132. logMessage(`Auto Battle: ${autoBattleEnabled}`);
  133. });
  134.  
  135. // Event listeners for cooldown settings
  136. document.getElementById('cooldownMin').addEventListener('change', (e) => {
  137. cooldownMin = parseInt(e.target.value, 10);
  138. logMessage(`Cooldown Min set to: ${cooldownMin}`);
  139. });
  140. document.getElementById('cooldownMax').addEventListener('change', (e) => {
  141. cooldownMax = parseInt(e.target.value, 10);
  142. logMessage(`Cooldown Max set to: ${cooldownMax}`);
  143. });
  144.  
  145. // Event listeners for randomizing cooldown
  146. document.getElementById('toggleRandomizeCooldown').addEventListener('change', (e) => {
  147. randomizeCooldown = e.target.checked;
  148. logMessage(`Randomize Cooldown: ${randomizeCooldown}`);
  149. });
  150.  
  151. // Event listener for copying logs
  152. document.getElementById('copyLogButton').addEventListener('click', () => {
  153. const logArea = document.getElementById('logArea');
  154. logArea.select();
  155. document.execCommand('copy');
  156. logMessage('Log copied to clipboard.');
  157. });
  158.  
  159. // Event listener for hiding/showing GUI
  160. document.getElementById('toggleGUIButton').addEventListener('click', () => {
  161. const gui = document.getElementById('battle-automation-gui');
  162. if (gui.style.opacity === '0') {
  163. gui.style.opacity = '1';
  164. document.getElementById('toggleGUIButton').textContent = 'Hide GUI';
  165. } else {
  166. gui.style.opacity = '0';
  167. document.getElementById('toggleGUIButton').textContent = 'Show GUI';
  168. }
  169. });
  170.  
  171. // Inject CSS for GUI
  172. GM_addStyle(`
  173. #battle-automation-gui {
  174. position: fixed;
  175. top: 10px;
  176. right: 10px;
  177. background: #ffffff;
  178. border: 1px solid #cccccc;
  179. padding: 10px;
  180. border-radius: 5px;
  181. box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.1);
  182. z-index: 1000;
  183. opacity: 1; /* Ensure GUI is initially visible */
  184. transition: opacity 0.3s; /* Smooth transition for hiding/showing */
  185. }
  186. #battle-automation-gui h3 {
  187. margin: 0;
  188. font-size: 16px;
  189. color: black;
  190. }
  191. #battle-automation-gui label,
  192. #battle-automation-gui input,
  193. #battle-automation-gui button,
  194. #battle-automation-gui textarea {
  195. font-size: 14px;
  196. color: black;
  197. }
  198. #battle-automation-gui textarea {
  199. width: 100%;
  200. font-family: monospace;
  201. }
  202. #toggleGUIButton {
  203. background: #f39c12;
  204. color: white;
  205. border: none;
  206. padding: 8px 16px;
  207. cursor: pointer;
  208. z-index: 1001;
  209. }
  210. `);
  211. }
  212.  
  213. // Initialize GUI
  214. createGUI();
  215. })();
  216.