Greasy Fork is available in English.

auto push

self explanatory

// ==UserScript==
// @name        auto push
// @namespace   https://discord.gg/AFYkkKTZq4
// @version     1
// @description self explanatory
// @author      no one important
// @match       *://moomoo.io/*
// @match       *://sandbox.moomoo.io/*
// @require     https://greasyfork.org/scripts/423602-msgpack/code/msgpack.js
// @license     MIT
// @grant       none
// ==/UserScript==
/*
hold p to auto push enemy into spike
*/
function websocket(ws, actions) {
    window.WEBSOCKET = ws;
    ws.addEventListener("message", (message) => {
        let data = window.msgpack.decode(message.data);
        if(actions[data[0]]) {
            actions[data[0]].apply(null, data[1]);
        }
    });
}
var client = null;
class Player {
    constructor(id, sid) {
        this.id = id;
        this.sid = sid;
        this.tmpScore = 0;
        this.team = null;
        this.skinIndex = 0;
        this.tailIndex = 0;
        this.hitTime = 0;
        this.tails = {};
        this.skins = {};
        this.points = 0;
        this.dt = 0;
        this.hidden = false;
        this.itemCounts = {};
        this.isPlayer = true;
        this.pps = 0;
        this.moveDir = undefined;
        this.skinRot = 0;
        this.lastPing = 0;
        this.iconIndex = 0;
        this.skinColor = 0;
        this.spawn = function() {
            this.active = true;
            this.alive = true;
            this.lockMove = false;
            this.lockDir = false;
            this.minimapCounter = 0;
            this.chatCountdown = 0;
            this.shameCount = 0;
            this.shameTimer = 0;
            this.buildIndex = -1;
            this.weaponIndex = 0;
            this.maxXP = 300;
            this.XP = 0;
            this.age = 1;
            this.kills = 0;
            this.upgrAge = 2;
            this.upgradePoints = 0;
            this.zIndex = 0;
            this.slowMult = 1;
            this.dir = 0;
            this.maxHealth = 100;
            this.health = this.maxHealth;
            this.scale = 35;
            this.speed = 0.0016;
            this.items = [0, 3, 6, 10];
            this.weapons = [0];
        };
    }
}
function send(type) {
    var data = Array.prototype.slice.call(arguments, 1);
    var binary = window.msgpack.encode([type, data]);
    window.WEBSOCKET.send(binary);
}
var mySid = null;
var players = [], player = {};
function findPlayer(sid) {
    for(let i = 0; i < players.length; i++) {
        if(players[i].sid == sid) {
            return players[i];
        }
    }
    return null;
}
var enemies = {
    all: [],
    nearest: [],
    canHit: [],
    angle: function() {
        return Math.atan2(this.nearest.y2 - player.y2, this.nearest.x2 - player.x2);
    }
};
function dist(a, b) {
    return Math.hypot((a.y2 || a.y) - (b.y2 || b.y), (a.x2 || a.x) - (b.x2 || b.x));
}
var groups = [{
    id: 0,
    name: "food",
    layer: 0
}, {
    id: 1,
    name: "walls",
    place: true,
    limit: 30,
    layer: 0
}, {
    id: 2,
    name: "spikes",
    place: true,
    limit: 15,
    layer: 0
}, {
    id: 3,
    name: "mill",
    place: true,
    limit: 7,
    layer: 1
}, {
    id: 4,
    name: "mine",
    place: true,
    limit: 1,
    layer: 0
}, {
    id: 5,
    name: "trap",
    place: true,
    limit: 6,
    layer: -1
}, {
    id: 6,
    name: "booster",
    place: true,
    limit: 12,
    layer: -1
}, {
    id: 7,
    name: "turret",
    place: true,
    limit: 2,
    layer: 1
}, {
    id: 8,
    name: "watchtower",
    place: true,
    limit: 12,
    layer: 1
}, {
    id: 9,
    name: "buff",
    place: true,
    limit: 4,
    layer: -1
}, {
    id: 10,
    name: "spawn",
    place: true,
    limit: 1,
    layer: -1
}, {
    id: 11,
    name: "sapling",
    place: true,
    limit: 2,
    layer: 0
}, {
    id: 12,
    name: "blocker",
    place: true,
    limit: 3,
    layer: -1
}, {
    id: 13,
    name: "teleporter",
    place: true,
    limit: 2,
    layer: -1
}];
var list = [{
    group: groups[0],
    name: "apple",
    desc: "restores 20 health when consumed",
    req: ["food", 10],
    consume: function(doer) {
        return doer.changeHealth(20, doer);
    },
    scale: 22,
    holdOffset: 15
}, {
    age: 3,
    group: groups[0],
    name: "cookie",
    desc: "restores 40 health when consumed",
    req: ["food", 15],
    consume: function(doer) {
        return doer.changeHealth(40, doer);
    },
    scale: 27,
    holdOffset: 15
}, {
    age: 7,
    group: groups[0],
    name: "cheese",
    desc: "restores 30 health and another 50 over 5 seconds",
    req: ["food", 25],
    consume: function(doer) {
        if(doer.changeHealth(30, doer) || doer.health < 100) {
            doer.dmgOverTime.dmg = -10;
            doer.dmgOverTime.doer = doer;
            doer.dmgOverTime.time = 5;
            return true;
        }
        return false;
    },
    scale: 27,
    holdOffset: 15
}, {
    group: groups[1],
    name: "wood wall",
    desc: "provides protection for your village",
    req: ["wood", 10],
    projDmg: true,
    health: 380,
    scale: 50,
    holdOffset: 20,
    placeOffset: -5
}, {
    age: 3,
    group: groups[1],
    name: "stone wall",
    desc: "provides improved protection for your village",
    req: ["stone", 25],
    health: 900,
    scale: 50,
    holdOffset: 20,
    placeOffset: -5
}, {
    age: 7,
    pre: 1,
    group: groups[1],
    name: "castle wall",
    desc: "provides powerful protection for your village",
    req: ["stone", 35],
    health: 1500,
    scale: 52,
    holdOffset: 20,
    placeOffset: -5
}, {
    group: groups[2],
    name: "spikes",
    desc: "damages enemies when they touch them",
    req: ["wood", 20, "stone", 5],
    health: 400,
    dmg: 20,
    scale: 49,
    spritePadding: -23,
    holdOffset: 8,
    placeOffset: -5
}, {
    age: 5,
    group: groups[2],
    name: "greater spikes",
    desc: "damages enemies when they touch them",
    req: ["wood", 30, "stone", 10],
    health: 500,
    dmg: 35,
    scale: 52,
    spritePadding: -23,
    holdOffset: 8,
    placeOffset: -5
}, {
    age: 9,
    pre: 1,
    group: groups[2],
    name: "poison spikes",
    desc: "poisons enemies when they touch them",
    req: ["wood", 35, "stone", 15],
    health: 600,
    dmg: 30,
    pDmg: 5,
    scale: 52,
    spritePadding: -23,
    holdOffset: 8,
    placeOffset: -5
}, {
    age: 9,
    pre: 2,
    group: groups[2],
    name: "spinning spikes",
    desc: "damages enemies when they touch them",
    req: ["wood", 30, "stone", 20],
    health: 500,
    dmg: 45,
    turnSpeed: 0.003,
    scale: 52,
    spritePadding: -23,
    holdOffset: 8,
    placeOffset: -5
}, {
    group: groups[3],
    name: "windmill",
    desc: "generates gold over time",
    req: ["wood", 50, "stone", 10],
    health: 400,
    pps: 1,
    turnSpeed: 0,
    spritePadding: 25,
    iconLineMult: 12,
    scale: 45,
    holdOffset: 20,
    placeOffset: 5
}, {
    age: 5,
    pre: 1,
    group: groups[3],
    name: "faster windmill",
    desc: "generates more gold over time",
    req: ["wood", 60, "stone", 20],
    health: 500,
    pps: 1.5,
    turnSpeed: 0,
    spritePadding: 25,
    iconLineMult: 12,
    scale: 47,
    holdOffset: 20,
    placeOffset: 5
}, {
    age: 8,
    pre: 1,
    group: groups[3],
    name: "power mill",
    desc: "generates more gold over time",
    req: ["wood", 100, "stone", 50],
    health: 800,
    pps: 2,
    turnSpeed: 0,
    spritePadding: 25,
    iconLineMult: 12,
    scale: 47,
    holdOffset: 20,
    placeOffset: 5
}, {
    age: 5,
    group: groups[4],
    type: 2,
    name: "mine",
    desc: "allows you to mine stone",
    req: ["wood", 20, "stone", 100],
    iconLineMult: 12,
    scale: 65,
    holdOffset: 20,
    placeOffset: 0
}, {
    age: 5,
    group: groups[11],
    type: 0,
    name: "sapling",
    desc: "allows you to farm wood",
    req: ["wood", 150],
    iconLineMult: 12,
    colDiv: 0.5,
    scale: 110,
    holdOffset: 50,
    placeOffset: -15
}, {
    age: 4,
    group: groups[5],
    name: "pit trap",
    desc: "pit that traps enemies if they walk over it",
    req: ["wood", 30, "stone", 30],
    trap: true,
    ignoreCollision: true,
    hideFromEnemy: true,
    health: 500,
    colDiv: 0.2,
    scale: 50,
    holdOffset: 20,
    placeOffset: -5
}, {
    age: 4,
    group: groups[6],
    name: "boost pad",
    desc: "provides boost when stepped on",
    req: ["stone", 20, "wood", 5],
    ignoreCollision: true,
    boostSpeed: 1.5,
    health: 150,
    colDiv: 0.7,
    scale: 45,
    holdOffset: 20,
    placeOffset: -5
}, {
    age: 7,
    group: groups[7],
    doUpdate: true,
    name: "turret",
    desc: "defensive structure that shoots at enemies",
    req: ["wood", 200, "stone", 150],
    health: 800,
    projectile: 1,
    shootRange: 700,
    shootRate: 2200,
    scale: 43,
    holdOffset: 20,
    placeOffset: -5
}, {
    age: 7,
    group: groups[8],
    name: "platform",
    desc: "platform to shoot over walls and cross over water",
    req: ["wood", 20],
    ignoreCollision: true,
    zIndex: 1,
    health: 300,
    scale: 43,
    holdOffset: 20,
    placeOffset: -5
}, {
    age: 7,
    group: groups[9],
    name: "healing pad",
    desc: "standing on it will slowly heal you",
    req: ["wood", 30, "food", 10],
    ignoreCollision: true,
    healCol: 15,
    health: 400,
    colDiv: 0.7,
    scale: 45,
    holdOffset: 20,
    placeOffset: -5
}, {
    age: 9,
    group: groups[10],
    name: "spawn pad",
    desc: "you will spawn here when you die but it will dissapear",
    req: ["wood", 100, "stone", 100],
    health: 400,
    ignoreCollision: true,
    spawnPoint: true,
    scale: 45,
    holdOffset: 20,
    placeOffset: -5
}, {
    age: 7,
    group: groups[12],
    name: "blocker",
    desc: "blocks building in radius",
    req: ["wood", 30, "stone", 25],
    ignoreCollision: true,
    blocker: 300,
    health: 400,
    colDiv: 0.7,
    scale: 45,
    holdOffset: 20,
    placeOffset: -5
}, {
    age: 7,
    group: groups[13],
    name: "teleporter",
    desc: "teleports you to a random point on the map",
    req: ["wood", 60, "stone", 60],
    ignoreCollision: true,
    teleport: true,
    health: 200,
    colDiv: 0.7,
    scale: 45,
    holdOffset: 20,
    placeOffset: -5
}];
var buildings = [];
class Building {
    constructor(sid, x, y, dir, scale, type, data = {}, setSID, owner) {
        this.sentTo = {};
		this.gridLocations = [];
		this.active = true;
		this.doUpdate = data.doUpdate;
		this.x = x;
		this.y = y;
		this.dir = dir;
		this.xWiggle = 0;
		this.yWiggle = 0;
		this.scale = scale;
		this.type = type;
		this.id = data.id;
		this.owner = owner;
		this.name = data.name;
		this.isItem = (this.id!=undefined);
		this.group = data.group;
		this.health = data.health;
		this.layer = 2;
		if (this.group != undefined) {
			this.layer = this.group.layer;
		} else if (this.type == 0) {
			this.layer = 3;
		} else if (this.type == 2) {
			this.layer = 0;
		} else if (this.type == 4) {
			this.layer = -1;
		}
		this.colDiv = data.colDiv||1;
		this.blocker = data.blocker;
		this.ignoreCollision = data.ignoreCollision;
		this.dontGather = data.dontGather;
		this.hideFromEnemy = data.hideFromEnemy;
		this.friction = data.friction;
		this.projDmg = data.projDmg;
		this.dmg = data.dmg;
		this.pDmg = data.pDmg;
		this.pps = data.pps;
		this.zIndex = data.zIndex||0;
		this.turnSpeed = data.turnSpeed;
		this.req = data.req;
		this.trap = data.trap;
		this.healCol = data.healCol;
		this.teleport = data.teleport;
		this.boostSpeed = data.boostSpeed;
		this.projectile = data.projectile;
		this.shootRange = data.shootRange;
		this.shootRate = data.shootRate;
		this.shootCount = this.shootRate;
		this.spawnPoint = data.spawnPoint;
    }
}
var autopush = false;
window.addEventListener("keydown", (e) => {
    if(e.key == "p") {
        autopush = true;
    }
});
window.addEventListener("keyup", (e) => {
    if(e.key == "p") {
        autopush = false;
    }
});
WebSocket.prototype.oldSend = WebSocket.prototype.send;
WebSocket.prototype.send = function (m) {
    if (!client) {
        client = new websocket(this, {
            "1": function(sid) {
                mySid = sid;
                player.sid = sid;
            },
            "11": function() {
                player.spawn(1);
                player.isAlive = false;
            },
            "6": function(data) {
                for (var i = 0; i < data.length;) {
                    buildings.push(new Building(
                        data[i],
                        data[i + 1],
                        data[i + 2],
                        data[i + 3],
                        data[i + 4],
                        data[i + 5],
                        list[data[i + 6]],
                        true,
                        (data[i + 7] >= 0 ? {
                            sid:data[i + 7]
                        } : null),
                    ));
                    i+=8;
                }
            },
            "12": function(sid) {
                for(let i = 0; i < buildings.length; i++) {
                    let building = buildings[i];
                    if(building.sid == sid) {
                        building.active = false;
                        break;
                    }
                }
            },
            "13": function(sid) {
                for(let i = 0; i < buildings.length; i++) {
                    let building = buildings[i];
                    if(building.owner && building.owner.sid == sid) {
                        building.active = false;
                    }
                }
            },
            "4": function(bob_the_mail_man) {
                for(let i = 0; i < players.length; i++) {
                    if(players[i].id == bob_the_mail_man) {
                        players.splice(i, 1);
                    }
                }
            },
            "2": function(data, you) {
                let tmpPlayer = findPlayer(data[0]);
                if(!tmpPlayer) {
                    tmpPlayer = new Player(data[0], data[1]);
                    players.push(tmpPlayer);
                }
                tmpPlayer.spawn(you ? 1 : null);
                tmpPlayer.visible = false;
                tmpPlayer.x2 = undefined;
                tmpPlayer.y2 = undefined;
                tmpPlayer.id = data[0];
                tmpPlayer.sid = data[1];
                tmpPlayer.name = data[2];
                tmpPlayer.x = data[3];
                tmpPlayer.y = data[4];
                tmpPlayer.dir = data[5];
                tmpPlayer.health = data[6];
                tmpPlayer.maxHealth = data[7];
                tmpPlayer.scale = data[8];
                tmpPlayer.skinColor = data[9];
                if(you) {
                    player = tmpPlayer;
                    player.isAlive = true;
                }
            },
            "33": function(data) {
                enemies.all = [];
                enemies.nearest = {};
                for (let i = 0; i < players.length; ++i) {
                    players[i].visible = false;
                }
                for (let i = 0; i < data.length;) {
                    let Player = findPlayer(data[i]);
                    if (Player) {
                        Player.x2 = data[i + 1];
                        Player.y2 = data[i + 2];
                        Player.d2 = data[i + 3];
                        Player.buildIndex = data[i + 4];
                        Player.weaponIndex = data[i + 5];
                        Player.weaponVariant = data[i + 6];
                        Player.team = data[i + 7];
                        Player.isLeader = data[i + 8];
                        Player.skinIndex = data[i + 9];
                        Player.tailIndex = data[i + 10];
                        Player.iconIndex = data[i + 11];
                        Player.zIndex = data[i + 12];
                        Player.visible = true;
                        if((!player.team && Player.sid != player.sid) || (player.team && player.team != Player.team)) {
                            enemies.all.push(Player);
                        }
                    }
                    i+=13;
                }
                if(enemies.all.length) {
                    enemies.all = enemies.all.sort((a, b) => dist(a, player) - dist(b, player));
                    enemies.nearest = enemies.all[0];
                }
                let trap = buildings.find(e => e.active && e.trap && e.owner.sid == player.sid && dist(e, enemies.nearest) <= 50);
                if(trap) {
                    let spike = buildings.filter(e => e.active && e.dmg && e.owner.sid == player.sid && dist(e, enemies.nearest) <= 130);
                    spike = spike.sort((a, b) => dist(a, player) - dist(b, player))[0];
                    if(dist(enemies.nearest, player) <= 200 && spike && autopush) {
                        let angle = Math.atan2(enemies.nearest.y2 - spike.y, enemies.nearest.x2 - spike.x);
                        let location = {
                            x: spike.x + Math.cos(angle) * (dist(spike, enemies.nearest) + 50),
                            y: spike.y + Math.sin(angle) * (dist(spike, enemies.nearest) + 50)
                        };
                        if(dist(spike, enemies.nearest) <= 35 + spike.scale) {
                            return;
                        }
                        if(Math.hypot(location.x - player.x2, location.y - player.y2) <= 20) {
                            send("33", Math.atan2(spike.y - player.y2, spike.x - player.x2));
                        }else {
                            send("33", Math.atan2(location.y - player.y2, location.x - player.x2));
                        }
                    }
                }
            }
        });
    }
    this.oldSend(m);
};