// ==UserScript==
// @name MooMoo.io Auto Heal
// @namespace https://gf.qytechs.cn/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://gf.qytechs.cn/scripts/423602-msgpack/code/msgpack.js
// @grant none
// @icon https://moomoo.io/img/favicon.png?v=1
// @license MIT
// ==/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 e = [{
category: 'primary',
start: 0,
end: 9
}, {
category: 'secondary',
start: 9,
end: 16
}, {
category: 'food',
start: 16,
end: 19
}, {
category: 'wall',
start: 19,
end: 22
}, {
category: 'spike',
start: 22,
end: 26
}, {
category: 'mill',
start: 26,
end: 29
}, {
category: 'mine',
start: 29,
end: 31
}, {
category: 'boostPad',
start: 31,
end: 33
}, {
category: 'trap',
start: 31,
end: 33
}, {
category: 'turret',
start: 29,
end: 31
}, {
category: 'spawnpad',
start: 36,
end: 37
}];
e.forEach(category => {
for (let i = category.start; i < category.end; i++) {
const elementId = `actionBarItem${i}`;
const element = document.getElementById(elementId);
if (element && element.offsetParent !== null) {
inventory[category.category] = i - category.start;
}
}
});
};
// 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);
};
})();