Moomoo.io 1.8.0 JS-AutoHeal & Interactive Menu

Toggle Autoheal using "P", open the menu with "Esc" to adjust speed, multiplier, or HP Umbral.

  1. // ==UserScript==
  2. // @name Moomoo.io 1.8.0 JS-AutoHeal & Interactive Menu
  3. // @version 2
  4. // @description Toggle Autoheal using "P", open the menu with "Esc" to adjust speed, multiplier, or HP Umbral.
  5. // @author Seryo
  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. // @grant none
  10. // @license MIT
  11. // @require https://gf.qytechs.cn/scripts/440839-moomoo-items/code/MooMoo%20Items.js?version=1023778
  12. // @require https://gf.qytechs.cn/scripts/423602-msgpack/code/msgpack.js?version=1005014
  13. // ==/UserScript==
  14.  
  15. let autoHealEnabled = true;
  16. let menuVisible = false;
  17. let speed = { hotKey: "" };
  18. let hp = { hotKey: "" };
  19. let multiplier = { hotKey: "" };
  20.  
  21. function restoreMenuValues() {
  22. document.getElementById('hpInput').value = this.hotkeys.settings.heal.hp !== undefined ? this.hotkeys.settings.heal.hp : '86';
  23. document.getElementById('speedInput').value = this.hotkeys.settings.heal.speed !== undefined ? this.hotkeys.settings.heal.speed : '125';
  24. document.getElementById('multiplierInput').value = this.hotkeys.settings.heal.multiplier !== undefined ? this.hotkeys.settings.heal.multiplier : '2';
  25. }
  26.  
  27. function hideElements() {
  28. const leaderboard = document.getElementById('leaderboard');
  29. const killCounter = document.getElementById('killCounter');
  30.  
  31. if (leaderboard) {
  32. leaderboard.style.display = 'none';
  33. }
  34. if (killCounter) {
  35. killCounter.style.display = 'none';
  36. }
  37. }
  38.  
  39. document.addEventListener('DOMContentLoaded', () => {
  40. hideElements();
  41. MooMoo.appendMenu();
  42. MooMoo.restoreMenuValues();
  43. });
  44.  
  45. function isChatOpen() {
  46. return document.activeElement.id.toLowerCase() === 'chatbox';
  47. }
  48.  
  49. function isAllianceInputActive() {
  50. return document.activeElement.id.toLowerCase() === 'allianceinput';
  51. }
  52.  
  53. function shouldHandleHotkeys() {
  54. return !isChatOpen() && !isAllianceInputActive();
  55. }
  56.  
  57. function updateAutoHealStateText() {
  58. const stateText = document.getElementById('autoHealState');
  59. if (stateText) {
  60. stateText.textContent = autoHealEnabled ? 'On' : 'Off';
  61. }
  62. }
  63.  
  64. class MooMoo {
  65. static updateSettings() {
  66. const hp = parseInt(document.getElementById('hpInput').value);
  67. const speed = parseInt(document.getElementById('speedInput').value);
  68. const multiplier = parseInt(document.getElementById('multiplierInput').value);
  69.  
  70. this.hotkeys.settings.heal.hp = hp;
  71. this.hotkeys.settings.heal.speed = speed;
  72. this.hotkeys.settings.heal.multiplier = multiplier;
  73.  
  74. localStorage.setItem('moomoo_settings', JSON.stringify(this.hotkeys.settings));
  75.  
  76. document.getElementById('hpValue').textContent = `${hp}`;
  77. document.getElementById('speedValue').textContent = `${speed}`;
  78. document.getElementById('multiplierValue').textContent = `${multiplier}`;
  79. }
  80.  
  81. static loadSettings() {
  82. const savedSettings = localStorage.getItem('moomoo_settings');
  83. if (savedSettings) {
  84. this.hotkeys.settings = JSON.parse(savedSettings);
  85. this.restoreMenuValues();
  86. }
  87.  
  88. document.getElementById('hpInput').value = this.hotkeys.settings.heal.hp !== undefined ? this.hotkeys.settings.heal.hp : 'none';
  89. document.getElementById('speedInput').value = this.hotkeys.settings.heal.speed !== undefined ? this.hotkeys.settings.heal.speed : 'none';
  90. document.getElementById('multiplierInput').value = this.hotkeys.settings.heal.multiplier !== undefined ? this.hotkeys.settings.heal.multiplier : 'none';
  91. }
  92.  
  93.  
  94. static appendMenu() {
  95. const menuDiv = document.createElement('div');
  96. menuDiv.id = 'moomooMenu';
  97. menuDiv.innerHTML = `
  98. <h2 style="text-align: center; font-size: 28px;">Autoheal <span id="autoHealState">On</span></h2>
  99. <hr>
  100. <label for="hpInput">HP Umbral</label>
  101. <input type="number" id="hpInput" oninput="this.value = this.value.slice(0, 3)" value="86">
  102. <span id="hpValue"></span>
  103. <hr>
  104. <label for="speedInput">Speed</label>
  105. <input type="number" id="speedInput" oninput="this.value = this.value.slice(0, 4)" value="125">
  106. <span id="speedValue"></span>
  107. <hr>
  108. <label for="multiplierInput">Multiplier</label>
  109. <input type="number" id="multiplierInput" oninput="this.value = this.value.slice(0, 2)" value="2">
  110. <span id="multiplierValue"></span>
  111. `;
  112.  
  113. menuDiv.style.display = 'none';
  114. menuDiv.style.background = 'rgba(0, 0, 0, 0.8';
  115. menuDiv.style.fontFamily = 'Hammersmith One, sans-serif';
  116. menuDiv.style.position = 'fixed';
  117. menuDiv.style.top = '20px';
  118. menuDiv.style.right = '20px';
  119. menuDiv.style.border = '1px solid #000';
  120. menuDiv.style.borderRadius = '8px';
  121. menuDiv.style.boxShadow = '0px 0px 10px rgba(0, 0, 0, 0.25)';
  122. menuDiv.style.boxShadow = '5px 5px 10px rgba(0, 0, 0, 0.4)';
  123. menuDiv.style.width = '216px';
  124. menuDiv.style.color = '#fff';
  125. menuDiv.style.fontSize = '17px';
  126. menuDiv.style.zIndex = '1000';
  127. menuDiv.style.overflowY = 'auto';
  128. menuDiv.style.padding = '10px';
  129.  
  130. document.body.appendChild(menuDiv);
  131. document.getElementById('hpInput').classList.add('menu-input');
  132. document.getElementById('speedInput').classList.add('menu-input');
  133. document.getElementById('multiplierInput').classList.add('menu-input');
  134.  
  135. document.querySelectorAll('.menu-input').forEach((input) => {
  136. input.addEventListener('focus', () => {
  137. input.addEventListener('input', handleNumericInput);
  138. });
  139. input.addEventListener('blur', () => {
  140. input.removeEventListener('input', handleNumericInput);
  141. });
  142. });
  143. document.getElementById('hpInput').style.width = "41px";
  144. document.getElementById('speedInput').style.width = "49px";
  145. document.getElementById('multiplierInput').style.width = "33px";
  146. }
  147.  
  148. static saveSettings() {
  149. this.updateSettings();
  150.  
  151. // Hide the menu after saving settings
  152. const menu = document.getElementById('moomooMenu');
  153. if (menu) {
  154. menu.style.display = 'none';
  155. }
  156.  
  157. // Show the hidden elements
  158. const leaderboard = document.getElementById('leaderboard');
  159. const killCounter = document.getElementById('killCounter');
  160. if (leaderboard) {
  161. leaderboard.style.display = 'block';
  162. }
  163. if (killCounter) {
  164. killCounter.style.display = 'block';
  165. }
  166. }
  167.  
  168. static get hotkeys() {
  169. return {
  170. settings: {
  171. heal: {
  172. speed: speed.hotKey,
  173. hp: hp.hotKey,
  174. multiplier: multiplier.hotKey
  175. }
  176. }
  177. };
  178. }
  179. static set forcedisablecps(arg) {
  180. this.forcedisable = arg
  181. }
  182. static fixweaponswap() {
  183. let keys = ['1', '2']
  184. let local = this;
  185. let items = window.items
  186. let spammers = this.spammers
  187. for(let i in keys) {
  188. document.addEventListener('keydown', e => {
  189. if(document.activeElement.type == "text") return;
  190. if(e.key == keys[i]) {
  191. switch(keys[i]) {
  192. case '1':
  193. for(let i = 0; i < 10; i++) {
  194. setTimeout(() => {
  195. local.sendws(["G", [items.primary, true]])
  196. }, i*2)
  197. }
  198. break;
  199. case '2':
  200. for(let i = 0; i < 10; i++) {
  201. setTimeout(() => {
  202. local.sendws(["G", [items.secondary, true]])
  203. }, i*2)
  204. }
  205. }
  206. }
  207. })
  208. }
  209. }
  210. static init(arg) {
  211. this.fixweaponswap()
  212. this.antiinvis();
  213. this.canvas = document.getElementById("gameCanvas");
  214. this.initplayer();
  215. this.getkeys();
  216. this.setmouse()
  217. this.initspammer();
  218. this.spammers = {};
  219. this.result = "";
  220. this.initcps();
  221. this.cps = 0;
  222. this.doc = document;
  223. this.initlisteners;
  224. this.id = `#${arg.match(/d="?g(.*)?I/g)[0].match(/(?=g).*(?=)/)[0]}`
  225. window.addEventListener("load", function(event) {
  226. MooMoo.initHTML;
  227. })
  228. }
  229. static get getalpha() {
  230. this.alpha = Array.from(Array(26)).map((e, i) => i + 65).map((x) => String.fromCharCode(x));
  231. for(let i in this.alpha) {
  232. this.result += this.alpha[i]
  233. }
  234. return this.result.toLocaleLowerCase();
  235. }
  236. static getkeys() {
  237. this.lts = new Array();
  238. this.lts.push(this.getalpha.match(/v([\s\S]*)w/g)[0].split("v")[1])
  239. this.lts.push(this.getalpha.match(/(.+(?=[b])|(?<=str).+)/g)[0].split('d')[2].split('a')[0])
  240. this.lts.push(this.getalpha.match(/\m(.*?)\o/))[0]
  241. this.lts.push(this.getalpha.match(/(?=d).*(?=e)/g)[0].split("c")[1].split('')[0])
  242. }
  243. static get initlisteners() {
  244. this.doc.onkeydown = function(e) {
  245. if(document.activeElement.type == "text") return;
  246. MooMoo.handleKeyDown(e)
  247. };
  248. this.doc.onkeyup = function(e) {
  249. if(document.activeElement.type == "text") return;
  250. MooMoo.handleKeyUp(e)
  251. }
  252. }
  253. static antiinvis() {
  254. CanvasRenderingContext2D.prototype.rotatef = CanvasRenderingContext2D.prototype.rotate
  255. CanvasRenderingContext2D.prototype.rotate = function(e){
  256. if(Math.abs(e) > 1e300){
  257. e = Math.atan2(Math.cos(e), Math.sin(e));
  258. this.globalAlpha = 0.5;
  259. this.rotatef(e);
  260. }else{
  261. this.rotatef(e);
  262. }
  263. };
  264. }
  265. static get() {
  266. return new Promise(resolve => {
  267. fetch(arguments[0]).then(res => res.text()).then(res => {
  268. return resolve(res);
  269. });
  270. });
  271. }
  272. static ioinit() {
  273. this.width = this.canvas.clientWidth;
  274. this.height = this.canvas.clientHeight;
  275. this.canvas.addEventListener("mousemove", e => {
  276. this.mouse.x = e.clientX;
  277. this.mouse.y = e.clientY;
  278. });
  279. }
  280. static setws (args) {
  281. this.ws = args
  282. }
  283. static get initHTML() {
  284. this.appendMenu();
  285.  
  286. }
  287. static initplayer() {
  288. this.player = {
  289. id: null,
  290. weapon: null
  291. }
  292. }
  293. static setmouse() {
  294. this.mouse = {
  295. x: null,
  296. y: null
  297. }
  298. }
  299. static checkelement(e) {
  300. return (e.offsetParent !== null);
  301. }
  302. static handleHit(arg) {
  303. switch(this.decode(arg)[1][0]) {
  304. case 1:
  305. this.handleCPS()
  306. }
  307. }
  308. static handleCPS() {
  309. this.initcps();
  310. this.cps++
  311. setTimeout(() => {
  312. this.initcps();
  313. this.cps--
  314. }, 1000)
  315. }
  316. static sendws(sender) {
  317. this.ws.send(new Uint8Array(Array.from(msgpack.encode(sender))));
  318. }
  319. static getnormalangle() {
  320. return Math.atan2(this.mouse.y - this.height / 2, this.mouse.x - this.width / 2)
  321. }
  322. static hit(angle) {
  323. this.sendws(["d", [1, angle]]);
  324. this.sendws(["d", [0, angle]]);
  325. }
  326. static placeitem(id, angle = this.getnormalangle()) {
  327. this.sendws(["G", [id, null]]);
  328. this.hit(angle)
  329. this.createfakeclick()
  330. this.sendws(["G", [this.player.weapon, true]]);
  331.  
  332. }
  333. static placefood(id) {
  334. this.sendws(["G", [id, null]]);
  335. this.hit(this.getnormalangle())
  336. this.createfoodpress();
  337. this.sendws(["G", [this.player.weapon, true]]);
  338. }
  339. static item1 (data) {
  340. if(!this.player.id) {
  341. this.player.id = data[1];
  342. console.log(this.player)
  343. }
  344. }
  345. static updateplayer(data) {
  346. this.rndata = data
  347. for (let i = 0; i < this.rndata[1].length / 13; i++) {
  348. this.playerInfo = this.rndata[1].slice(13 * i, 13 * i + 13);
  349. if (this.playerInfo[0] == this.player.id) {
  350. this.player.weapon = this.playerInfo[5];
  351. }
  352. }
  353. }
  354. static doautoheal(data) {
  355. let items = window.items;
  356. if (autoHealEnabled) {
  357. if (data[2] < 60) {
  358. return;
  359. } else if (data[2] >= 60 && data[2] <= 85) {
  360. setTimeout(() => {
  361. for (let i = 0; i < 1; i++) {
  362. this.placefood(items.food);
  363. }
  364. }, 350);
  365. } else if (data[2] > 85) {
  366. return;
  367. }
  368. }
  369. }
  370. static getwsmessage(message) {
  371. let temp = this.decode(new Uint8Array(message.data));
  372. let data;
  373. if (temp.length > 1) {
  374. data = [temp[0], ...temp[1]];
  375. if (data[1] instanceof Array) {
  376. data = data;
  377. }
  378. } else {
  379. data = temp;
  380. }
  381. let item = data[0];
  382. if (!data) {
  383. return;
  384. }
  385. if (item === "io-init") {
  386. this.ioinit();
  387. }
  388. if (item == "C") {
  389. this.item1(data);
  390. }
  391. if (item == "a") {
  392. this.updateplayer(data);
  393. }
  394. switch (item) {
  395. case '8':
  396. console.log(data);
  397. break;
  398. case 'O':
  399. if (data[1] == this.player.id) {
  400. if (data[2] === 'autoheal: on') {
  401. autoHealEnabled = true;
  402. console.log("AutoHeal is now ON");
  403. } else if (data[2] === 'autoheal: off') {
  404. autoHealEnabled = false;
  405. console.log("AutoHeal is now OFF");
  406. } else {
  407. this.doautoheal(data);
  408. }
  409. }
  410. break;
  411. }
  412. }
  413.  
  414. static doautoheal(data) {
  415. let items = window.items;
  416. if (autoHealEnabled) {
  417. const hpThreshold = parseInt(document.getElementById('hpInput').value);
  418. const healSpeed = parseInt(document.getElementById('speedInput').value);
  419. const healMultiplier = parseInt(document.getElementById('multiplierInput').value);
  420.  
  421. if (data[2] < hpThreshold) {
  422. setTimeout(() => {
  423. for (let i = 0; i < healMultiplier; i++) {
  424. this.placefood(items.food);
  425. }
  426. }, healSpeed);
  427. }
  428. }
  429. }
  430. static decode(arg) {
  431. return msgpack.decode(arg)
  432. }
  433. static initspammer() {
  434. this.spammers = {};
  435. let spammers = this.spammers;
  436.  
  437. document.addEventListener('keydown', (e) => {
  438. if (document.activeElement.id.toLocaleLowerCase() !== 'chatbox' && document.activeElement.id.toLocaleLowerCase() !== 'mainMenu') {
  439. spammers.food.start(e.key);
  440. }
  441. });
  442.  
  443. document.addEventListener('keyup', (e) => {
  444. if(document.activeElement.type == "text") return;
  445. spammers.food.stop(e.key);
  446. });
  447. }
  448. static append() {
  449. $(this.id).append(arguments[0])
  450. }
  451. static getelement() {
  452. return document.getElementById(arguments[0])
  453. }
  454. static initcps() {
  455. if(!this.getelement("cpsdisplay")) return;
  456. this.getelement("cpsdisplay").textContent = "CPS: " + this.cps
  457. }
  458. static createfakeclick() {
  459. setTimeout(() => {
  460. MooMoo.addAttribute("kdisp-RButton")
  461. setTimeout(() => {
  462. MooMoo.deleteAttribute("kdisp-RButton")
  463. }, 50)
  464. }, 50)
  465. }
  466. static createfakeclick() {
  467. setTimeout(() => {
  468. MooMoo.addAttribute("kdisp-RButton")
  469. setTimeout(() => {
  470. MooMoo.deleteAttribute("kdisp-RButton")
  471. }, 50)
  472. }, 50)
  473. }
  474. static createfoodpress() {
  475. setTimeout(() => {
  476. this.addAttribute("kdisp-food")
  477. setTimeout(() => {
  478. this.deleteAttribute("kdisp-food")
  479. }, 50)
  480. }, 50)
  481. setTimeout(() => {
  482. this.addAttribute("kdisp-RButton")
  483. setTimeout(() => {
  484. this.deleteAttribute("kdisp-RButton")
  485. }, 50)
  486. }, 50)
  487. }
  488. }
  489.  
  490. document.addEventListener('keydown', (e) => {
  491. if (e.keyCode === 80 && shouldHandleHotkeys()) {
  492. autoHealEnabled = !autoHealEnabled;
  493. document.title = autoHealEnabled ? "𝙷𝚎𝚊𝚕 𝙾𝙽" : "𝙷𝚎𝚊𝚕 𝙾𝙵𝙵";
  494. console.log("AutoHeal is now " + (autoHealEnabled ? "ON" : "OFF"));
  495.  
  496. updateAutoHealStateText();
  497. }
  498. });
  499.  
  500. function toggleMenu() {
  501. const menu = document.getElementById('moomooMenu');
  502. if (menu) {
  503. if (menu.style.display === 'none') {
  504. menu.style.display = 'block';
  505. menuVisible = true;
  506. hideElements();
  507. } else {
  508. menu.style.display = 'none';
  509. menuVisible = false;
  510. const leaderboard = document.getElementById('leaderboard');
  511. const killCounter = document.getElementById('killCounter');
  512. if (leaderboard) {
  513. leaderboard.style.display = 'block';
  514. }
  515. if (killCounter) {
  516. killCounter.style.display = 'block';
  517. }
  518. }
  519.  
  520. if (menuVisible) {
  521. MooMoo.restoreMenuValues();
  522. }
  523.  
  524. updateAutoHealStateText();
  525. }
  526. }
  527.  
  528. document.addEventListener('keydown', (e) => {
  529. if (e.keyCode === 27 && shouldHandleHotkeys() && storeMenu.style.display !== 'block') {
  530. toggleMenu();
  531. }
  532. });
  533.  
  534. (async () => {
  535. const game = await MooMoo.get(document.location.href);
  536. MooMoo.init(game);
  537. var ws;
  538. WebSocket.prototype._send = WebSocket.prototype.send;
  539. WebSocket.prototype.send = function (m) {
  540. if (MooMoo.decode(m)[0] == "d") {
  541. MooMoo.handleHit(m);
  542. }
  543. if (!ws) {
  544. document.ws = this;
  545. ws = this;
  546. this.addEventListener('message', function (message) {
  547. MooMoo.setws(this);
  548. MooMoo.getwsmessage(message);
  549. });
  550. }
  551. this._send(m);
  552. };
  553. })();

QingJ © 2025

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