// ==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);
};