// ==UserScript== // @name Splo Mod // @description Autobreak-trap, Autoheal, Hat macros, Anti-trap, AutoPush & more! // @version 2.8 // @author Wealthy#8266 & Nuro#9999 // @match *://sploop.io/* // @run-at document-start // @require http://code.jquery.com/jquery-3.3.1.min.js // @require https://code.jquery.com/ui/1.12.0/jquery-ui.min.js // @grant none // @namespace https://greasyfork.org/users/761829 // @downloadURL none // ==/UserScript== let version = "2.8" let addHealMS = 0 let Game; let Entity = new Array(); let Canvas; let ctx; let keyDown = []; let user = {}; let tribe = []; let enemy; let encoder = new TextEncoder(); let decoder = new TextDecoder(); let server; let Config = { update: (type) => { Config[type] += 1; setTimeout(() => (Config[type] -= 1), 1e3); }, serverUpdate: 1e3 / 9, breaking: false, pushing: false, rate: 1e3, pps: 0, weapon: 0, cps: 0, tps: 0, fps: 0, ping: 0, freeze: { send: true, pps: true, message: false, setup: false }, angle: 0, move: 0, messages: new Array([], []), counter: 0, resolver: function(){}, last: Date.now(), isJson: (data) => { try { JSON.parse(data); } catch (e) { return false; } return true; }, WS: null }; Config.tick = () => { return new Promise((e) => (Config.resolver = e)) }; let Toggle = { UI: false, autoBreak: true, autoPush: true, autoPlace: true, autoSync: true } class Macro { constructor(advanced, spike, trap, mill, food){ this.advanced = advanced; this.spike = spike; this.trap = trap; this.mill = mill; this.food = food; }; update(){ if(keyDown[this.spike]) Sploop.newPlace(4); if(keyDown[this.trap]) Sploop.newPlace(7); if(keyDown[this.mill]) Sploop.newPlace(5); if(keyDown[this.food]) Sploop.newPlace(2); }; }; let Placer = new Macro(true, 86, 70, 78, 81); class Sploop { static place(id, angle = Config.angle){ Config.update('cps'); Sploop.take(id); Sploop.hit(angle); Sploop.take(Config.weapon); } static newPlace(id, angle = Config.angle){ let increasor = Math.PI / 8; // 22.25 radians let offset = Math.PI / 4; // 45 radians this.place(id, angle, true) for(let newAngle = 0; newAngle < offset; newAngle += increasor){ Sploop.place(id, angle - newAngle); Sploop.place(id, angle + newAngle); } Sploop.take(Config.weapon); } static quad(id, angle = 0){ for(let newAngle = 0; newAngle < Math.PI * 2; newAngle += Math.PI / 8){ let time = (Config.serverUpdate / 4) * (newAngle / (Math.PI / 8)) setTimeout(() => Sploop.place(7, angle + newAngle), time); } } static heal(amount) { for(let count = 0; count <= amount; count++) Sploop.place(2); } static equip(id) { if(user.skin != id) Game.send(new Uint8Array([9, id])); } static walk(angle = Config.move) { if(typeof angle !== 'number') return Game.send(new Uint8Array([1, 0])); angle = (65535 * (angle + Math.PI)) / (2 * Math.PI); Game.send(new Uint8Array([15, 255 & angle, (angle >> 8) & 255])); } static take(id) { Game.send(new Uint8Array([8, id])); } static chat(text){ text = encoder.encode(text); Game.send(new Uint8Array([10, ...text])) } static hit(angle) { angle = (65535 * (angle + Math.PI)) / (2 * Math.PI); Game.send(new Uint8Array([4, 255 & angle, (angle >> 8) & 255])); Game.send(new Uint8Array([5])); } static watch(angle){ angle = (65535 * (angle + Math.PI)) / (2 * Math.PI); Game.send(new Uint8Array([2, 255 & angle, (angle >> 8) & 255])); } static offensive(){ let offensive = () => { let distance = enemy ? Math.dist(enemy, user) : 0; if(user.y <= 9e3 && user.y >= 8e3) return 9; if(enemy && distance <= 300) return false && distance <= 150 ? 6 : 5; return 7; } Sploop.equip(offensive()); } static healthChange(health, oldHealth){ if(oldHealth > health){ user.hitDate = Config.counter; }; user.health = health; } static mine(build){ if(user.id2 == build.id2) return true; if(user.team){ let length = tribe.length; for(let index = 0; index < length; index++) { let teammate = tribe[index]; if(build.id2 == teammate.id2) return true; } } return false; } static update(){ Config.counter += 1; Config.resolver(); Config.last = Date.now(); if(user.alive){ if(user.health < 100){ setTimeout(() => { let amount = 3; Sploop.heal(amount); }, (Config.serverUpdate - 20 - Config.ping) + addHealMS); }; let trap = Entity.find(c => c && Math.dist(c, user) <= 50 && c.type == 6 && !Sploop.mine(c)); let wasBreaking = Config.breaking; Config.breaking = false; if(trap && Toggle.autoBreak){ console.log(trap, user) let angle = Math.angle(trap, user); Config.breaking = true; Sploop.hit(angle); Sploop.equip(6); if(!wasBreaking) Sploop.quad(7, angle); } else if(wasBreaking){ Sploop.offensive(); } let wasPushing = Config.pushing; Config.pushing = false; if(enemy && !trap && user.alive){ let distance = Math.dist(enemy, user); if(Toggle.autoPush && distance <= 250){ let trap = Entity.find(c => c && Math.dist(c, enemy) <= 50 && c.type == 6 && Sploop.mine(c)); if(trap){ let spikes = Entity.filter(c => c && [2, 7, 17].includes(c.type) && Sploop.mine(c) && Math.dist(c, trap) <= 130); if(spikes.length){ let spike = spikes.sort((a, b) => Math.dist(a, trap) - Math.dist(b, trap))[0]; let angle = Math.angle(enemy, spike); distance = Math.dist(enemy, spike) + 70; let position = { x: spike.x + (distance * Math.cos(angle)), y: spike.y + (distance * Math.sin(angle)) }; distance = Math.dist(position, user); angle = () => { if(distance > 40){ return Math.angle(position, user) } else { let angleDifference = Math.abs(Math.angle(spike, position) - Math.angle(spike, user)) let message = `diffence [${angleDifference / (Math.PI / 180)}]` // Sploop.chat(message); return Math.angle(enemy, user) } } Config.pushing = true; Sploop.walk(angle()) } } } distance = Math.dist(enemy, user) if(Toggle.autoPlace && distance <= 200){ let trap = Entity.find(c => c && c.type == 6 && Sploop.mine(c) && Math.dist(c, enemy) <= 50); let enemyPos = { x: enemy.x + enemy.xVel, y: enemy.y + enemy.yVel } let userPos = { x: user.x + user.xVel, y: user.y + user.yVel } distance = Math.dist(enemyPos, userPos); let angle = Math.angle(enemyPos, userPos) let range = 28 * 2 + 50; if(trap){ angle = Math.angle(trap, userPos); for(let newAngle = 0; newAngle < Math.PI / 2; newAngle += Math.PI / 9){ Sploop.place(4, angle + newAngle); Sploop.place(4, angle - newAngle); } } else { if(Toggle.autoSync && distance < 250){ let spike = Entity.find(c => c && [2, 7, 17].includes(c.type) && Sploop.mine(c) && Math.dist(c, enemyPos) <= 60); if(spike){ Sploop.equip(2); Sploop.take(0); Sploop.hit(angle); setTimeout(() => Sploop.offensive(), 2e3); } if(enemy.health <= (enemy.skin == 2 ? 78 : 85) && user.skin == 5 && user.health <= 70){ Sploop.equip(2); Sploop.take(0); Sploop.hit(angle); setTimeout(() => Sploop.offensive(), 2e3); } } if(range >= distance){ Sploop.place(7, angle); } } } } if(wasPushing && !Config.pushing) Sploop.walk('Stop'); } Placer.update(); } } class Script { setup(){ this.run(); }; override(ws, data){ !Config.freeze.send && this.log(`WebSocket`, `⬈`, data[0], '#8ecc51'); ws.classic(data, true); let string = Config.isJson(data); data = string ? JSON.parse(data) : new Uint8Array(data); let item = data[0]; switch(item) { case 6: user.name = data[1]; break; } Config.update('pps'); } send(data){ this.ws && 1 === this.ws.readyState && (typeof data !== "string" && window.encoder.encode(data), this.ws.classic(data, true)) Config.update('pps'); } message(event){ let data = event.data; let string = typeof data === 'string'; let decoded = string ? JSON.parse(data) : new Uint8Array(data); let length = decoded.length; let id = Number(decoded[0]); let found = Config.messages[Number(string)].find(item => item && item.id == id); if(!found) return !Config.freeze.message && Game.log(`WebSocket`, `⬉`, `${decoded} | ${string}`, '#c7cc51'); switch(found.name){ case 'Player update': enemy = null; tribe = []; for(let index = 0; index < Entity.length; index++){ let player = Entity[index]; if(player) player.visible = false; } for (let int = 1; int < length; int += 18) { let type = decoded[int], owner = decoded[int + 1], index = decoded[int + 2] | decoded[int + 3] << 8, x = decoded[int + 4] | decoded[int + 5] << 8, y = decoded[int + 6] | decoded[int + 7] << 8, broken = decoded[int + 8], skin = decoded[int + 11], team = decoded[int + 12], health = decoded[int + 13] / 255 * 100, clown = decoded[int + 8]; let Default = {fd: 2, active: true, health: 100, x: 0, y: 0, xVel: 0, yVel: 0}; let temp = Entity[index] || Default; temp.visible = true; if (broken & 2) { Entity[index] = null; } else { if (temp.fd & 2) { temp.type = type; temp.id = index; temp.health = health; temp.id3 = broken; temp.xVel = temp.x - x; temp.yVel = temp.y - y; temp.speed = Math.hypot(y - temp.y, x - temp.x); temp.move = Math.atan2(y - temp.y, x - temp.x); temp.x = x; temp.y = y; temp.id2 = owner; temp.skin = skin; temp.team = team; temp.clown = Boolean(clown); } Entity[index] = temp; if(temp.id === user.id) { Sploop.healthChange(temp.health, user.health); Object.assign(user, temp) } else if(!temp.type && (user.team && user.team == temp.team)){ tribe.push(temp); } else if(!temp.type && (!user.team || temp.team != user.team)){ let distance = Math.hypot(user.y - temp.y, user.x - temp.x); let distance2 = enemy ? Math.hypot(user.y - enemy.y, user.x - enemy.x) : null; if(enemy){ if(distance < distance2) enemy = temp; } else { enemy = temp; } } } } Config.update('tps'); Sploop.update(); break; case 'Spawn': user.id = decoded[1]; user.alive = true; user.spawnDate = Date.now(); user.health = 100; Config.weapon = 0; break; case 'Death': user.health = 0; user.speed = 0; user.alive = false; break; case 'Ping update': Config.ping = decoded[1] | (decoded[2] << 8); break; } Placer.update(); } log(group, symbol, result, color){ return console.log(`%c[${group}] %c${symbol}`, `color:${color};font-weight:bold`, `color:${color}`, result); } run(ws){ !Config.freeze.setup && Game.log(`Hijacked Iframe`, `✔`, ws.url, '#0f0'); let notifications = `
` $("body").append(notifications) this.ws = ws; let infoPanel = '\n