Moomoo.io - 1.8.0 Holder Macro & Interactive Menu

This functions as a key rebinder. Press Keycode 186 to toggle hold macros. Use 'Esc' to toggle the menu and adjust hold intervals. Holds: Spike, Trap, Mill, Turret, Spawnpad, Wall

  1. // ==UserScript==
  2. // @name Moomoo.io - 1.8.0 Holder Macro & Interactive Menu
  3. // @author Seryo
  4. // @description This functions as a key rebinder. Press Keycode 186 to toggle hold macros. Use 'Esc' to toggle the menu and adjust hold intervals. Holds: Spike, Trap, Mill, Turret, Spawnpad, Wall
  5. // @version 2.0
  6. // @match *://*.moomoo.io/*
  7. // @namespace https://gf.qytechs.cn/users/1190411
  8. // @icon https://cdn.glitch.com/82ae8945-dcc6-4276-98a9-665381b4cd2b/cursor12.png
  9. // @require https://cdnjs.cloudflare.com/ajax/libs/msgpack-lite/0.1.26/msgpack.min.js
  10. // @require https://gf.qytechs.cn/scripts/478839-moomoo-io-packet-code/code/MooMooio%20Packet%20Code.js?version=1274028
  11. // @run-at document-start
  12. // @grant unsafeWindow
  13. // @license MIT
  14. // ==/UserScript==
  15.  
  16. function iso() {
  17. return document.activeElement.id.toLowerCase() === 'chatbox';
  18. }
  19.  
  20. function iaia() {
  21. return document.activeElement.id.toLowerCase() === 'allianceinput';
  22. }
  23.  
  24. function shhk() {
  25. return !iso() && !iaia();
  26. }
  27.  
  28. function saveInputValue() {
  29. const inputValue = document.getElementById("speed").value;
  30. localStorage.setItem("speedValue", inputValue);
  31. }
  32.  
  33. function loadInputValue() {
  34. const savedValue = localStorage.getItem("speedValue");
  35. if (savedValue) {
  36. document.getElementById("speed").value = savedValue;
  37. }
  38.  
  39. const speedInput = document.getElementById("speed");
  40. speedInput.addEventListener("blur", handleBlur);
  41. speedInput.addEventListener("input", handleInput);
  42. }
  43.  
  44. function handleBlur() {
  45. const speedInput = document.getElementById("speed");
  46. const inputValue = speedInput.value;
  47.  
  48. if (inputValue === "" || inputValue === "110") {
  49. speedInput.value = "110";
  50. speedInput.style.color = "gray";
  51. }
  52. }
  53.  
  54. function handleInput() {
  55. const speedInput = document.getElementById("speed");
  56. const inputValue = speedInput.value;
  57.  
  58. if (inputValue !== "110") {
  59. speedInput.style.color = "black";
  60. }
  61. }
  62.  
  63. let menuVisible = false;
  64. let initialInterval = true;
  65. let multipleTimes = false;
  66.  
  67. const mnu = document.createElement("div");
  68. mnu.id = "mnu";
  69. mnu.style.display = "none";
  70. mnu.style.background = "rgba(0, 0, 0, 0.8)";
  71. mnu.style.fontFamily = "'Hammersmith One, sans-serif'";
  72. mnu.style.position = "fixed";
  73. mnu.style.top = "50%";
  74. mnu.style.left = "50%";
  75. mnu.style.border = "1px solid #000";
  76. mnu.style.borderRadius = "8px";
  77. mnu.style.boxShadow = "0px 0px 10px rgba(0, 0, 0, 0.25), 5px 5px 10px rgba(0, 0, 0, 0.4)";
  78. mnu.style.width = "200px";
  79. mnu.style.color = "#fff";
  80. mnu.style.fontSize = "17px";
  81. mnu.style.zIndex = "1000";
  82. mnu.style.overflowY = "auto";
  83. mnu.style.padding = "10px";
  84. mnu.style.textAlign = "center";
  85.  
  86. mnu.innerHTML = `
  87. <h2 style="font-size: 28px; color: white; margin-bottom: 8px;">Holder</h2>
  88. <hr style="border-color: white; margin: 5px 0;">
  89. <p style="font-size: 22px; color: gray; margin: 8px 0; display: inline-block; vertical-align: middle;"><span id="onOffIndicator">${multipleTimes ? 'On' : 'Off'}</span></p>
  90. <label for="speed" style="display: inline-block; margin-bottom: 5px; margin-left: 10px;"></label>
  91. <input type="number" id="speed" value="110" min="0" maxlength="5" style="width: 50px; margin: 0; display: inline-block; border-radius: 8px; border: 1px solid white; padding: 5px; vertical-align: middle;">
  92. <span style="margin-left: 5px; color: white;">ms</span>
  93.  
  94. <div id="controls" style="margin-top: 10px; position: relative; color: white; opacity: 0; transition: opacity 0.3s ease-in-out;">
  95. <span id="controlsHeader" style="cursor: pointer; border: 1px solid white; padding: 8px; border-radius: 8px; background-color: #000; display: block;">Controls</span>
  96. <div id="controlsOptions" style="display: none; position: absolute; top: 100%; left: 50%; transform: translateX(-50%); background-color: #000; border: 1px solid white; border-radius: 8px; padding: 8px; width: 100px;">
  97. <p class="fade" style="font-size: 22px; color: gray; margin: 8px 0;">Spike = V</p>
  98. <p class="fade" style="font-size: 22px; color: gray; margin: 8px 0;">Trap = F</p>
  99. <p class="fade" style="font-size: 22px; color: gray; margin: 8px 0;">Mill = N</p>
  100. <p class="fade" style="font-size: 22px; color: gray; margin: 8px 0;">Food = M</p>
  101. </div>
  102. </div>
  103. `;
  104.  
  105. document.body.appendChild(mnu);
  106.  
  107. const controlsElement = document.getElementById('controls');
  108. const controlsOptionsElement = document.getElementById('controlsOptions');
  109. const fadeElements = document.querySelectorAll('.fade');
  110.  
  111. document.getElementById('controlsHeader').addEventListener('click', () => {
  112. controlsOptionsElement.style.display = controlsOptionsElement.style.display === 'none' ? 'block' : 'none';
  113.  
  114. fadeElements.forEach(element => {
  115. element.style.opacity = controlsOptionsElement.style.display === 'none' ? 0 : 1;
  116. });
  117.  
  118. controlsElement.style.opacity = controlsOptionsElement.style.display === 'none' ? 0 : 1;
  119. });
  120.  
  121. // Main script logic
  122. (async () => {
  123. unsafeWindow.keyRebinder = true;
  124.  
  125. let items = [],
  126. weapons = [],
  127. inGame = false,
  128. keys = {},
  129. intervalIds = {},
  130. ws;
  131.  
  132. try {
  133. // Establish WebSocket connection
  134. ws = await new Promise((resolve, reject) => {
  135. let { send } = WebSocket.prototype;
  136.  
  137. WebSocket.prototype.send = function (...x) {
  138. send.apply(this, x);
  139. this.send = send;
  140. this.iosend = function (...datas) {
  141. const [packet, data] = datas;
  142. this.send(msgpack.encode([packet, data]));
  143. };
  144. this.addEventListener("message", (e) => {
  145. if (!e.origin.includes("moomoo.io") && unsafeWindow.privateServer) return;
  146. const [packet, data] = msgpack.decode(new Uint8Array(e.data));
  147. switch (packet) {
  148. case OLDPACKETCODE.RECEIVE["1"]:
  149. inGame = true;
  150. items = [0, 3, 6, 10];
  151. weapons = [0];
  152. break;
  153. case OLDPACKETCODE.RECEIVE["11"]:
  154. inGame = false;
  155. break;
  156. case OLDPACKETCODE.RECEIVE["17"]:
  157. if (data[0]) {
  158. if (data[1]) weapons = data[0];
  159. else items = data[0];
  160. }
  161. break;
  162. }
  163. });
  164. resolve(this);
  165. };
  166. this.addEventListener("error", (err) => reject(err));
  167. });
  168. } catch (error) {
  169. // Handle WebSocket connection error if any
  170. }
  171.  
  172. if (ws) {
  173. loadInputValue();
  174. document.getElementById("speed").addEventListener("input", saveInputValue);
  175. document.addEventListener("keydown", handleKeydown);
  176.  
  177. document.addEventListener("keyup", (event) => {
  178. if (inGame && keys[event.code] && shhk()) {
  179. keys[event.code] = false;
  180. clearInterval(intervalIds[event.code]);
  181. }
  182. });
  183.  
  184. function handleKeydown(event) {
  185. if (event.keyCode === 27 && !shhk() && storeMenu.style.display !== 'block') {
  186. return;
  187. }
  188.  
  189. if (event.keyCode === 27) {
  190. menuVisible = !menuVisible;
  191. mnu.style.display = menuVisible ? "block" : "none";
  192. }
  193.  
  194. const speed = parseInt(document.getElementById("speed").value) || 110;
  195.  
  196. if (event.keyCode === 186 && shhk()) {
  197. multipleTimes = !multipleTimes;
  198. document.getElementById('onOffIndicator').textContent = multipleTimes ? 'On' : 'Off';
  199. document.title = `𝙷𝚘𝚕𝚍 𝙼𝚊𝚌𝚛𝚘 ${multipleTimes ? '𝙾𝙽' : '𝙾𝙵𝙵'}`;
  200. console.log("Multiple Times: " + multipleTimes);
  201. }
  202.  
  203. // Handle key presses for macro functionality when in-game and not in chat or alliance input
  204. if (inGame && shhk() && !keys[event.code]) {
  205. keys[event.code] = true;
  206. if (event.keyCode === 70) {
  207. ws.iosend(OLDPACKETCODE.SEND["5"], [items[4], null]); // Spike (V)
  208. } else if (event.keyCode === 86) {
  209. ws.iosend(OLDPACKETCODE.SEND["5"], [items[2], null]); // Trap (F)
  210. } else if (event.keyCode === 78) {
  211. ws.iosend(OLDPACKETCODE.SEND["5"], [items[3], null]); // Mill (N)
  212. } else if (event.keyCode === 77) {
  213. ws.iosend(OLDPACKETCODE.SEND["5"], [items[0], null]); // Food (M)
  214. }
  215.  
  216. // Handle multipleTimes functionality
  217. if (multipleTimes) {
  218. intervalIds[event.code] = setInterval(() => {
  219. // Repeat the corresponding action based on the key pressed
  220. if (event.keyCode === 70) {
  221. ws.iosend(OLDPACKETCODE.SEND["5"], [items[4], null]);
  222. } else if (event.keyCode === 86) {
  223. ws.iosend(OLDPACKETCODE.SEND["5"], [items[2], null]);
  224. } else if (event.keyCode === 78) {
  225. ws.iosend(OLDPACKETCODE.SEND["5"], [items[3], null]);
  226. } else if (event.keyCode === 77) {
  227. ws.iosend(OLDPACKETCODE.SEND["5"], [items[0], null]);
  228. }
  229. }, speed);
  230. }
  231. }
  232. }
  233. }
  234. })();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址