// ==UserScript== // @name MooMoo.io Auto Heal // @namespace https://greasyfork.org/users/1064285-vcrazy-gaming // @version 0.1 // @description A simple MooMoo.io Auto Heal script for in-game auto-healing. // @match *://moomoo.io/* // @match *://*.moomoo.io/* // @author _VcrazY_ // @require https://greasyfork.org/scripts/423602-msgpack/code/msgpack.js // @grant none // @icon https://moomoo.io/img/favicon.png?v=1 // @license MIT // @downloadURL none // ==/UserScript== (() => { // Constants and Variables window.onbeforeunload = null; let mouseX, mouseY, weapons = [], width, height; let coreURL = new URL(window.location.href); window.sessionStorage.force = coreURL.searchParams.get("fc"); let ws, msgpack5 = window.msgpack, tmpHealth = 100, sCount = 0, sTime = 0; const inventory = { primary: null, secondary: null, food: null, wall: null, spike: null, mill: null, mine: null, boostPad: null, trap: null, turret: null, spawnpad: null }; const myPlayer = { sid: null, x: null, y: null, dir: null, buildIndex: null, weaponIndex: null, weaponVariant: null, team: null, isLeader: null, skinIndex: null, tailIndex: null, iconIndex: null }; // Helper Functions /** * Utility function to join arrays * @param {Array} message - The array to join * @returns {Array} - Joined array */ const join = message => Array.isArray(message) ? [...message] : [...message]; /** * Hook function for WebSocket * @param {object} data - WebSocket message */ const hookWS = data => { // PARSE MESSAGE: let tmpData = msgpack5.decode(new Uint8Array(data.data)); if ((data = undefined) || (tmpData = (data = tmpData.length > 1 ? [tmpData[0], ...join(tmpData[1])] : tmpData)[0]) || data) { let health = data[2]; let addEventListener = { "setupGame": "C", "updateHealth": "O" }; // CALL EVENT: if ("io-init" == tmpData) { let gameCanvas = document.getElementById("gameCanvas"); width = gameCanvas.clientWidth; height = gameCanvas.clientHeight; document.getElementById(window).resize(function () { width = gameCanvas.clientWidth; height = gameCanvas.clientHeight; }); gameCanvas.addEventListener("mousemove", f => { mouseX = f.clientX; mouseY = f.clientY; }); } // SETUP GAME: if (addEventListener.setupGame == tmpData && null === myPlayer.sid) { myPlayer.sid = data[1]; weapons = [0]; } // UPDATE HEALTH/AUTO HEAL CODES: if (addEventListener.updateHealth == tmpData && data[1] == myPlayer.sid) { if (health > 0 && tmpHealth !== health) { setTimeout(() => { place(inventory.food); place(inventory.food); }, Math.max(0, 175 - window.pingTime)); } if (tmpHealth - health < 0) { if (sTime) { let timeHit = Date.now() - sTime; sTime = 0; if (timeHit <= 120) sCount++;else sCount = Math.max(0, sCount - 2); } } else { sTime = Date.now(); } tmpHealth = health; } cacheItems(); } }; /** * Function to send a packet * @param {string} event - Event type * @param {*} e - Parameter e */ function sendPacket(e) { // EXTRACT DATA ARRAY: let t = Array.prototype.slice.call(arguments, 1); // SEND MESSAGE: ws.send(window.msgpack.encode([e, t])); } // PLACE: /** * Function to place an item * @param {number} event - Event type * @param {number} ang - Angle */ const place = (id, ang) => { sendPacket("G", id, false); sendPacket("d", 1, ang); sendPacket("d", 0, ang); sendPacket("G", 0, true); }; // ITEM GROUPS/WEAPONS: /** * Cache the player's items */ const cacheItems = () => { const categories = [{ category: 'primary', start: 0, end: 8 }, { category: 'secondary', start: 9, end: 15 }, { category: 'food', start: 16, end: 18 }, { category: 'wall', start: 19, end: 21 }, { category: 'spike', start: 22, end: 25 }, { category: 'mill', start: 26, end: 28 }, { category: 'mine', start: 29, end: 30 }, { category: 'boostPad', start: 31, end: 32 }, { category: 'trap', start: 31, end: 32 }, { category: 'turret', start: 29, end: 30 }, { category: 'spawnpad', start: 36, end: 36 }]; categories.forEach(category => { for (let i = category.start; i <= category.end; i++) { const element = document.getElementById(`actionBarItem${i}`); if (element !== null && element.offsetParent !== null) { inventory[category.category] = i - 16; } } }); }; // Override WebSocket's send method document.msgpack = window.msgpack; WebSocket.prototype.oldSend = WebSocket.prototype.send; WebSocket.prototype.send = function (event) { ws || (document.ws = this, ws = this, document.ws.addEventListener("message", hookWS)); this.oldSend(event); }; })();