0% found this document useful (0 votes)
5K views

Message

The document contains a user script for the game MooMoo.io. It defines metadata for the script such as the name, author, and required libraries. It then defines functions for serializing and deserializing data to send and receive messages between the game client and server in a compact binary format.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
5K views

Message

The document contains a user script for the game MooMoo.io. It defines metadata for the script such as the name, author, and required libraries. It then defines functions for serializing and deserializing data to send and receive messages between the game client and server in a compact binary format.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
You are on page 1/ 13

// ==UserScript==

// @name Syuza
// @namespace Macro top :o
// @version none
// @description N: Windmill, V: Spike, H: Turret, F: Trap/Boost, Q: Food.
// @author 𝙒𝙚𝙖𝙡𝙩𝙝𝙮#9994
// @match *://moomoo.io/*
// @match *://dev.moomoo.io/*
// @match *://*sandbox.moomoo.io/*
// @require https://greasyfork.org/scripts/368273-msgpack/code/msgpack.js?
version=598723
// @require http://code.jquery.com/jquery-3.3.1.min.js
// @require https://code.jquery.com/ui/1.12.0/jquery-ui.min.js
// @require https://cdnjs.cloudflare.com/ajax/libs/jquery-confirm/3.3.0/jquery-
confirm.min.js
// ==/UserScript==
// CPS Could Lag With Bad Ping.

window.onbeforeunload = null;
(function() {
'use strict';

function serialize(data) {
const pow32 = 0x100000000;
let floatBuffer, floatView;
let array = new Uint8Array(128);
let length = 0;
append(data);
return array.subarray(0, length);

function append(data) {
switch (typeof data) {
case "undefined":
appendNull(data);
break;
case "boolean":
appendBoolean(data);
break;
case "number":
appendNumber(data);
break;
case "string":
appendString(data);
break;
case "object":
if (data === null) {
appendNull(data);
} else if (data instanceof Date) {
appendDate(data);
} else if (Array.isArray(data)) {
appendArray(data);
} else if (data instanceof Uint8Array || data instanceof
Uint8ClampedArray) {
appendBinArray(data);
} else if (data instanceof Int8Array || data instanceof
Int16Array || data instanceof Uint16Array ||
data instanceof Int32Array || data instanceof
Uint32Array ||
data instanceof Float32Array || data instanceof
Float64Array) {
appendArray(data);
} else {
appendObject(data);
}
break;
}
}

function appendNull(data) {
appendByte(0xc0);
}

function appendBoolean(data) {
appendByte(data ? 0xc3 : 0xc2);
}

function appendNumber(data) {
if (isFinite(data) && Math.floor(data) === data) {
if (data >= 0 && data <= 0x7f) {
appendByte(data);
} else if (data < 0 && data >= -0x20) {
appendByte(data);
} else if (data > 0 && data <= 0xff) { // uint8
appendBytes([0xcc, data]);
} else if (data >= -0x80 && data <= 0x7f) { // int8
appendBytes([0xd0, data]);
} else if (data > 0 && data <= 0xffff) { // uint16
appendBytes([0xcd, data >>> 8, data]);
} else if (data >= -0x8000 && data <= 0x7fff) { // int16
appendBytes([0xd1, data >>> 8, data]);
} else if (data > 0 && data <= 0xffffffff) { // uint32
appendBytes([0xce, data >>> 24, data >>> 16, data >>> 8,
data]);
} else if (data >= -0x80000000 && data <= 0x7fffffff) { // int32
appendBytes([0xd2, data >>> 24, data >>> 16, data >>> 8,
data]);
} else if (data > 0 && data <= 0xffffffffffffffff) { // uint64
let hi = data / pow32;
let lo = data % pow32;
appendBytes([0xd3, hi >>> 24, hi >>> 16, hi >>> 8, hi, lo >>>
24, lo >>> 16, lo >>> 8, lo]);
} else if (data >= -0x8000000000000000 && data <=
0x7fffffffffffffff) { // int64
appendByte(0xd3);
appendInt64(data);
} else if (data < 0) { // below int64
appendBytes([0xd3, 0x80, 0, 0, 0, 0, 0, 0, 0]);
} else { // above uint64
appendBytes([0xcf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff]);
}
} else {
if (!floatView) {
floatBuffer = new ArrayBuffer(8);
floatView = new DataView(floatBuffer);
}
floatView.setFloat64(0, data);
appendByte(0xcb);
appendBytes(new Uint8Array(floatBuffer));
}
}

function appendString(data) {
let bytes = encodeUtf8(data);
let length = bytes.length;

if (length <= 0x1f) {


appendByte(0xa0 + length);
} else if (length <= 0xff) {
appendBytes([0xd9, length]);
} else if (length <= 0xffff) {
appendBytes([0xda, length >>> 8, length]);
} else {
appendBytes([0xdb, length >>> 24, length >>> 16, length >>> 8,
length]);
}

appendBytes(bytes);
}

function appendArray(data) {
let length = data.length;

if (length <= 0xf) {


appendByte(0x90 + length);
} else if (length <= 0xffff) {
appendBytes([0xdc, length >>> 8, length]);
} else {
appendBytes([0xdd, length >>> 24, length >>> 16, length >>> 8,
length]);
}

for (let index = 0; index < length; index++) {


append(data[index]);
}
}

function appendBinArray(data) {
let length = data.length;

if (length <= 0xf) {


appendBytes([0xc4, length]);
} else if (length <= 0xffff) {
appendBytes([0xc5, length >>> 8, length]);
} else {
appendBytes([0xc6, length >>> 24, length >>> 16, length >>> 8,
length]);
}

appendBytes(data);
}

function appendObject(data) {
let length = 0;
for (let key in data) length++;

if (length <= 0xf) {


appendByte(0x80 + length);
} else if (length <= 0xffff) {
appendBytes([0xde, length >>> 8, length]);
} else {
appendBytes([0xdf, length >>> 24, length >>> 16, length >>> 8,
length]);
}

for (let key in data) {


append(key);
append(data[key]);
}
}

function appendDate(data) {
let sec = data.getTime() / 1000;
if (data.getMilliseconds() === 0 && sec >= 0 && sec < 0x100000000) { //
32 bit seconds
appendBytes([0xd6, 0xff, sec >>> 24, sec >>> 16, sec >>> 8, sec]);
}
else if (sec >= 0 && sec < 0x400000000) { // 30 bit nanoseconds, 34 bit
seconds
let ns = data.getMilliseconds() * 1000000;
appendBytes([0xd7, 0xff, ns >>> 22, ns >>> 14, ns >>> 6, ((ns << 2)
>>> 0) | (sec / pow32), sec >>> 24, sec >>> 16, sec >>> 8, sec]);
}
else { // 32 bit nanoseconds, 64 bit seconds, negative values allowed
let ns = data.getMilliseconds() * 1000000;
appendBytes([0xc7, 12, 0xff, ns >>> 24, ns >>> 16, ns >>> 8, ns]);
appendInt64(sec);
}
}

function appendByte(byte) {
if (array.length < length + 1) {
let newLength = array.length * 2;
while (newLength < length + 1)
newLength *= 2;
let newArray = new Uint8Array(newLength);
newArray.set(array);
array = newArray;
}
array[length] = byte;
length++;
}

function appendBytes(bytes) {
if (array.length < length + bytes.length) {
let newLength = array.length * 2;
while (newLength < length + bytes.length)
newLength *= 2;
let newArray = new Uint8Array(newLength);
newArray.set(array);
array = newArray;
}
array.set(bytes, length);
length += bytes.length;
}
function appendInt64(value) {
let hi, lo;
if (value >= 0) {
hi = value / pow32;
lo = value % pow32;
}
else {
value++;
hi = Math.abs(value) / pow32;
lo = Math.abs(value) % pow32;
hi = ~hi;
lo = ~lo;
}
appendBytes([hi >>> 24, hi >>> 16, hi >>> 8, hi, lo >>> 24, lo >>> 16,
lo >>> 8, lo]);
}
}

function deserialize(array) {
const pow32 = 0x100000000; // 2^32
let pos = 0;
if (array instanceof ArrayBuffer) {
array = new Uint8Array(array);
}
if (typeof array !== "object" || typeof array.length === "undefined") {
throw new Error("Invalid argument type: Expected a byte array (Array or
Uint8Array) to deserialize.");
}
if (!array.length) {
throw new Error("Invalid argument: The byte array to deserialize is
empty.");
}
if (!(array instanceof Uint8Array)) {
array = new Uint8Array(array);
}
let data = read();
if (pos < array.length) {
}
return data;

function read() {
const byte = array[pos++];
if (byte >= 0x00 && byte <= 0x7f) return byte; // positive fixint
if (byte >= 0x80 && byte <= 0x8f) return readMap(byte - 0x80); //
fixmap
if (byte >= 0x90 && byte <= 0x9f) return readArray(byte - 0x90); //
fixarray
if (byte >= 0xa0 && byte <= 0xbf) return readStr(byte - 0xa0); //
fixstr
if (byte === 0xc0) return null; // nil
if (byte === 0xc1) throw new Error("Invalid byte code 0xc1 found."); //
never used
if (byte === 0xc2) return false // false
if (byte === 0xc3) return true; // true
if (byte === 0xc4) return readBin(-1, 1); // bin 8
if (byte === 0xc5) return readBin(-1, 2); // bin 16
if (byte === 0xc6) return readBin(-1, 4); // bin 32
if (byte === 0xc7) return readExt(-1, 1); // ext 8
if (byte === 0xc8) return readExt(-1, 2); // ext 16
if (byte === 0xc9) return readExt(-1, 4) // ext 32
if (byte === 0xca) return readFloat(4); // float 32
if (byte === 0xcb) return readFloat(8); // float 64
if (byte === 0xcc) return readUInt(1); // uint 8
if (byte === 0xcd) return readUInt(2); // uint 16
if (byte === 0xce) return readUInt(4); // uint 32
if (byte === 0xcf) return readUInt(8) // uint 64
if (byte === 0xd0) return readInt(1); // int 8
if (byte === 0xd1) return readInt(2); // int 16
if (byte === 0xd2) return readInt(4); // int 32
if (byte === 0xd3) return readInt(8); // int 64
if (byte === 0xd4) return readExt(1); // fixext 1
if (byte === 0xd5) return readExt(2); // fixext 2
if (byte === 0xd6) return readExt(4); // fixext 4
if (byte === 0xd7) return readExt(8); // fixext 8
if (byte === 0xd8) return readExt(16); // fixext 16
if (byte === 0xd9) return readStr(-1, 1); // str 8
if (byte === 0xda) return readStr(-1, 2); // str 16
if (byte === 0xdb) return readStr(-1, 4); // str 32
if (byte === 0xdc) return readArray(-1, 2); // array 16
if (byte === 0xdd) return readArray(-1, 4); // array 32
if (byte === 0xde) return readMap(-1, 2); // map 16
if (byte === 0xdf) return readMap(-1, 4); // map 32
if (byte >= 0xe0 && byte <= 0xff) return byte - 256; // negative fixint
console.debug("msgpack array:", array);
throw new Error("Invalid byte value '" + byte + "' at index " + (pos -
1) + " in the MessagePack binary data (length " + array.length + "): Expecting a
range of 0 to 255. This is not a byte array.");
}

function readInt(size) {
let value = 0;
let first = true;
while (size-- > 0) {
if (first) {
let byte = array[pos++];
value += byte & 0x7f;
if (byte & 0x80) {
value -= 0x80;
}
first = false;
}
else {
value *= 256;
value += array[pos++];
}
}
return value;
}

function readUInt(size) {
let value = 0;
while (size-- > 0) {
value *= 256;
value += array[pos++];
}
return value;
}
function readFloat(size) {
let view = new DataView(array.buffer, pos, size);
pos += size;
if (size === 4) {
return view.getFloat32(0, false);
}
if (size === 8) {
return view.getFloat64(0, false);
}
}

function readBin(size, lengthSize) {


if (size < 0) size = readUInt(lengthSize);
let data = array.subarray(pos, pos + size);
pos += size;
return data;
}

function readMap(size, lengthSize) {


if (size < 0) size = readUInt(lengthSize);
let data = {};
while (size-- > 0) {
let key = read();
data[key] = read();
}
return data;
}

function readArray(size, lengthSize) {


if (size < 0) size = readUInt(lengthSize);
let data = [];
while (size-- > 0) {
data.push(read());
}
return data;
}

function readStr(size, lengthSize) {


if (size < 0) size = readUInt(lengthSize);
let start = pos;
pos += size;
return decodeUtf8(array, start, size);
}

function readExt(size, lengthSize) {


if (size < 0) size = readUInt(lengthSize);
let type = readUInt(1);
let data = readBin(size);
switch (type) {
case 255:
return readExtDate(data);
}
return { type: type, data: data };
}

function readExtDate(data) {
if (data.length === 4) {
let sec = ((data[0] << 24) >>> 0) +
((data[1] << 16) >>> 0) +
((data[2] << 8) >>> 0) +
data[3];
return new Date(sec * 1000);
}
if (data.length === 8) {
let ns = ((data[0] << 22) >>> 0) +
((data[1] << 14) >>> 0) +
((data[2] << 6) >>> 0) +
(data[3] >>> 2);
let sec = ((data[3] & 0x3) * pow32) +
((data[4] << 24) >>> 0) +
((data[5] << 16) >>> 0) +
((data[6] << 8) >>> 0) +
data[7];
return new Date(sec * 1000 + ns / 1000000);
}
if (data.length === 12) {
let ns = ((data[0] << 24) >>> 0) +
((data[1] << 16) >>> 0) +
((data[2] << 8) >>> 0) +
data[3];
pos -= 8;
let sec = readInt(8);
return new Date(sec * 1000 + ns / 1000000);
}
throw new Error("Invalid data length for a date value.");
}
}

function encodeUtf8(str) {
let ascii = true, length = str.length;
for (let x = 0; x < length; x++) {
if (str.charCodeAt(x) > 127) {
ascii = false;
break;
}
}

let i = 0, bytes = new Uint8Array(str.length * (ascii ? 1 : 4));


for (let ci = 0; ci !== length; ci++) {
let c = str.charCodeAt(ci);
if (c < 128) {
bytes[i++] = c;
continue;
}
if (c < 2048) {
bytes[i++] = c >> 6 | 192;
}
else {
if (c > 0xd7ff && c < 0xdc00) {
if (++ci >= length)
throw new Error("UTF-8 encode: incomplete surrogate pair");
let c2 = str.charCodeAt(ci);
if (c2 < 0xdc00 || c2 > 0xdfff)
throw new Error("UTF-8 encode: second surrogate character
0x" + c2.toString(16) + " at index " + ci + " out of range");
c = 0x10000 + ((c & 0x03ff) << 10) + (c2 & 0x03ff);
bytes[i++] = c >> 18 | 240;
bytes[i++] = c >> 12 & 63 | 128;
}
else bytes[i++] = c >> 12 | 224;
bytes[i++] = c >> 6 & 63 | 128;
}
bytes[i++] = c & 63 | 128;
}
return ascii ? bytes : bytes.subarray(0, i);
}

function decodeUtf8(bytes, start, length) {


let i = start, str = "";
length += start;
while (i < length) {
let c = bytes[i++];
if (c > 127) {
if (c > 191 && c < 224) {
if (i >= length)
throw new Error("UTF-8 decode: incomplete 2-byte
sequence");
c = (c & 31) << 6 | bytes[i++] & 63;
}
else if (c > 223 && c < 240) {
if (i + 1 >= length)
throw new Error("UTF-8 decode: incomplete 3-byte
sequence");
c = (c & 15) << 12 | (bytes[i++] & 63) << 6 | bytes[i++] & 63;
}
else if (c > 239 && c < 248) {
if (i + 2 >= length)
throw new Error("UTF-8 decode: incomplete 4-byte
sequence");
c = (c & 7) << 18 | (bytes[i++] & 63) << 12 | (bytes[i++] & 63)
<< 6 | bytes[i++] & 63;
}
else throw new Error("UTF-8 decode: unknown multibyte start 0x" +
c.toString(16) + " at index " + (i - 1));
}
if (c <= 0xffff) str += String.fromCharCode(c);
else if (c <= 0x10ffff) {
c -= 0x10000;
str += String.fromCharCode(c >> 10 | 0xd800)
str += String.fromCharCode(c & 0x3FF | 0xdc00)
}
else throw new Error("UTF-8 decode: code point 0x" + c.toString(16) + "
exceeds UTF-16 reach");
}
return str;
}

let msgpack = {
serialize: serialize,
deserialize: deserialize,

encode: serialize,
decode: deserialize
};

if (typeof module === "object" && module && typeof module.exports === "object")
{
module.exports = msgpack;
}
else {
window[window.msgpackJsName || "msgpack"] = msgpack;
}

})();
let mouseX;
let mouseY;
let width;
let height;
function aim(x, y){
var cvs = document.getElementById("gameCanvas");
cvs.dispatchEvent(new MouseEvent("mousemove", {
clientX: x,
clientY: y
}));
}
var foodType;
var spikeType;
var millType;
var boostType;
var turretType;
var ws;
var msgpack5 = msgpack;
let myPlayer = {id: null, weapon: null};
document.msgpack = msgpack;
function n(){
this.buffer = new Uint8Array([0]);
this.buffer.__proto__ = new Uint8Array;
this.type = 0;
}
WebSocket.prototype.oldSend = WebSocket.prototype.send;
WebSocket.prototype.send = function(m){
if (!ws){
document.ws = this;
ws = this;
socketFound(this);
}
this.oldSend(m);
};
function socketFound(socket){
socket.addEventListener('message', function(message){
handleMessage(message);
});
}
function handleMessage(m){
let temp = msgpack5.decode(new Uint8Array(m.data));
let data;
if(temp.length > 1) {
data = [temp[0], ...temp[1]];
if (data[1] instanceof Array){
data = data;
}
} else {
data = temp;
}
let item = data[0];
if(!data) {return};
if(item === "io-init") {
let cvs = document.getElementById("gameCanvas");
width = cvs.clientWidth;
height = cvs.clientHeight;
$(window).resize(function() {
width = cvs.clientWidth;
height = cvs.clientHeight;
});
cvs.addEventListener("mousemove", e => {
mouseX = e.clientX;
mouseY = e.clientY;
});
}
if (item == "1" && myPlayer.id == null){
myPlayer.id = data[1];
}
if (item == "33") {
for(let i = 0; i < data[1].length / 13; i++) {
let playerInfo = data[1].slice(13*i, 13*i+13);
if(playerInfo[0] == myPlayer.id) {
myPlayer.weapon = playerInfo[5];
}
}
}
update();
}
function doNewSend(sender){
ws.send(new Uint8Array(Array.from(msgpack5.encode(sender))));
}
function place(id, angle = Math.atan2(mouseY - height / 2, mouseX - width / 2)) {
doNewSend(["5", [id, null]]);
doNewSend(["c", [1, angle]]);
doNewSend(["c", [0, angle]]);
doNewSend(["5", [myPlayer.weapon, true]]);
}
var repeater = function(key, action, interval) {
let _isKeyDown = false;
let _intervalId = undefined;
return {
start(keycode) {
if(keycode == key && document.activeElement.id.toLowerCase() !==
'chatbox') {
_isKeyDown = true;
if(_intervalId === undefined) {
_intervalId = setInterval(() => {
action();
action();
action();
action();
if(!_isKeyDown){
clearInterval(_intervalId);
_intervalId = undefined;
}
}, interval);
}
}
}, stop(keycode) {
if(keycode == key && document.activeElement.id.toLowerCase() !== 'chatbox')
{
_isKeyDown = false;
}
}
};
}
const healer = repeater(81, () => {
place(foodType)
}, 5);
const boostPlacer = repeater(70, () => {
place(boostType)
}, 0);
const spikePlacer = repeater(86, () => {
place(spikeType)
}, 0);
const millPlacer = repeater(78, () => {
place(millType)
}, 0);
const turretPlacer = repeater(72, () => {
place(turretType)
}, 0);
document.addEventListener('keydown', (e)=>{
spikePlacer.start(e.keyCode);
healer.start(e.keyCode);
boostPlacer.start(e.keyCode);
millPlacer.start(e.keyCode);
turretPlacer.start(e.keyCode);
})
document.addEventListener('keyup', (e)=>{
spikePlacer.stop(e.keyCode);
boostPlacer.stop(e.keyCode);
millPlacer.stop(e.keyCode);
turretPlacer.stop(e.keyCode);
healer.stop(e.keyCode);
})
function isElementVisible(e) {
return (e.offsetParent !== null);
}
function toRad(angle) {
return angle * 0.01745329251;
}
function dist(a, b){
return Math.sqrt( Math.pow((b.y-a[2]), 2) + Math.pow((b.x-a[1]), 2) );
}
function update() {
for (let i=16;i<19;i++){
if (isElementVisible(document.getElementById("actionBarItem" +
i.toString()))){
foodType = i - 16;
}
}
for (let i=22;i<26;i++){
if (isElementVisible(document.getElementById("actionBarItem" +
i.toString()))){
spikeType = i - 16;
}
}
for (let i=26;i<29;i++){
if (isElementVisible(document.getElementById("actionBarItem" +
i.toString()))){
millType = i - 16;
}
}
for (let i=31;i<33;i++){
if (isElementVisible(document.getElementById("actionBarItem" +
i.toString()))){
boostType = i - 16;
}
}
for (let i=33;i<39;i++){
if (isElementVisible(document.getElementById("actionBarItem" +
i.toString())) && i != 36){
turretType = i - 16;
}
}
}

You might also like