// ==UserScript==
// @name Dsync Client [Sploop.io]
// @author Murka
// @description The most advanced hack for sploop.io
// @icon https://sploop.io/img/ui/favicon.png
// @version 1.0.11
// @match *://sploop.io/*
// @run-at document-start
// @grant none
// @license MIT
// @namespace https://greasyfork.org/users/919633
// @downloadURL none
// ==/UserScript==
/* jshint esversion:6 */
/*
Author: Murka
Github: https://github.com/Murka007/Dsync-client
Discord: https://discord.gg/sG9cyfGPj5
Greasyfork: https://greasyfork.org/en/users/919633
PLEASE, I NEED YOUR SUPPORT ON GITHUB (GIVE ME A STAR ON MY REPOSITORY),
ALSO SUPPORT THIS SCRIPT ON GREASYFORK (register and write a comment: "this script works, thank you so much"),
FOR MORE UPDATES JOIN MY DISCORD SERVER!!!
*/
Function("(" + (() => {
"use strict";
var __webpack_modules__ = {
147: module => {
module.exports = {
i8: "1.0.11"
};
}
};
var __webpack_module_cache__ = {};
function __webpack_require__(moduleId) {
var cachedModule = __webpack_module_cache__[moduleId];
if (cachedModule !== undefined) {
return cachedModule.exports;
}
var module = __webpack_module_cache__[moduleId] = {
exports: {}
};
__webpack_modules__[moduleId](module, module.exports, __webpack_require__);
return module.exports;
}
(() => {
__webpack_require__.d = (exports, definition) => {
for (var key in definition) {
if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
Object.defineProperty(exports, key, {
enumerable: true,
get: definition[key]
});
}
}
};
})();
(() => {
__webpack_require__.o = (obj, prop) => Object.prototype.hasOwnProperty.call(obj, prop);
})();
var __webpack_exports__ = {};
(() => {
__webpack_require__.d(__webpack_exports__, {
s: () => Dsync,
c: () => log
});
var WebsocketString;
(function(WebsocketString) {
WebsocketString[WebsocketString["CONNECT"] = 12] = "CONNECT";
WebsocketString[WebsocketString["DEFAULTDATA"] = 33] = "DEFAULTDATA";
WebsocketString[WebsocketString["DIED"] = 19] = "DIED";
WebsocketString[WebsocketString["KILLUPDATE"] = 22] = "KILLUPDATE";
WebsocketString[WebsocketString["KILLED"] = 28] = "KILLED";
WebsocketString[WebsocketString["SPAWN"] = 35] = "SPAWN";
})(WebsocketString || (WebsocketString = {}));
var EItems;
(function(EItems) {
EItems[EItems["PRIMARY"] = 0] = "PRIMARY";
EItems[EItems["SECONDARY"] = 1] = "SECONDARY";
EItems[EItems["HEAL"] = 2] = "HEAL";
EItems[EItems["WALL"] = 3] = "WALL";
EItems[EItems["SPIKE"] = 4] = "SPIKE";
EItems[EItems["WINDMILL"] = 5] = "WINDMILL";
EItems[EItems["TREE"] = 6] = "TREE";
EItems[EItems["TRAP"] = 7] = "TRAP";
EItems[EItems["PLATFORM"] = 8] = "PLATFORM";
EItems[EItems["SPAWN"] = 9] = "SPAWN";
EItems[EItems["TURRET"] = 10] = "TURRET";
})(EItems || (EItems = {}));
var ELayer;
(function(ELayer) {
ELayer[ELayer["PLAYER"] = 0] = "PLAYER";
ELayer[ELayer["STONE"] = 1] = "STONE";
ELayer[ELayer["HARDSPIKE"] = 2] = "HARDSPIKE";
ELayer[ELayer["TREE"] = 3] = "TREE";
ELayer[ELayer["GOLD"] = 4] = "GOLD";
ELayer[ELayer["BUSH"] = 5] = "BUSH";
ELayer[ELayer["TRAP"] = 6] = "TRAP";
ELayer[ELayer["SPIKE"] = 7] = "SPIKE";
ELayer[ELayer["WOODWALL"] = 8] = "WOODWALL";
ELayer[ELayer["PLATFORM"] = 9] = "PLATFORM";
ELayer[ELayer["BOOST"] = 10] = "BOOST";
ELayer[ELayer["LOOTBOX"] = 11] = "LOOTBOX";
ELayer[ELayer["PROJECTILE"] = 12] = "PROJECTILE";
ELayer[ELayer["WINDMILL"] = 13] = "WINDMILL";
ELayer[ELayer["COW"] = 14] = "COW";
ELayer[ELayer["SPAWN"] = 15] = "SPAWN";
ELayer[ELayer["POWERMILL"] = 16] = "POWERMILL";
ELayer[ELayer["CASTLESPIKE"] = 17] = "CASTLESPIKE";
ELayer[ELayer["TURRET"] = 18] = "TURRET";
ELayer[ELayer["WOODFARM"] = 19] = "WOODFARM";
ELayer[ELayer["CHERRYWOODFARM"] = 20] = "CHERRYWOODFARM";
ELayer[ELayer["STONEWARM"] = 21] = "STONEWARM";
ELayer[ELayer["CASTLEWALL"] = 22] = "CASTLEWALL";
ELayer[ELayer["SHARK"] = 23] = "SHARK";
ELayer[ELayer["WOLF"] = 24] = "WOLF";
ELayer[ELayer["GOLDENCOW"] = 25] = "GOLDENCOW";
ELayer[ELayer["ROOF"] = 26] = "ROOF";
ELayer[ELayer["DRAGON"] = 27] = "DRAGON";
ELayer[ELayer["MAMMOTH"] = 28] = "MAMMOTH";
ELayer[ELayer["FIREBALL"] = 29] = "FIREBALL";
ELayer[ELayer["CHEST"] = 30] = "CHEST";
ELayer[ELayer["DRAGONWALLBIG"] = 31] = "DRAGONWALLBIG";
ELayer[ELayer["DRAGONWALLMEDIUM"] = 32] = "DRAGONWALLMEDIUM";
ELayer[ELayer["DRAGONWALLSMALL"] = 33] = "DRAGONWALLSMALL";
ELayer[ELayer["MAMMOTHWALL"] = 34] = "MAMMOTHWALL";
ELayer[ELayer["MAMMOTHWALLSMALL"] = 35] = "MAMMOTHWALLSMALL";
ELayer[ELayer["DUCK"] = 36] = "DUCK";
ELayer[ELayer["TELEPORT"] = 37] = "TELEPORT";
ELayer[ELayer["CACTUS"] = 38] = "CACTUS";
ELayer[ELayer["TORNADO"] = 39] = "TORNADO";
})(ELayer || (ELayer = {}));
const LayerObjects = [ ELayer.STONE, ELayer.HARDSPIKE, ELayer.TREE, ELayer.GOLD, ELayer.BUSH, ELayer.SPIKE, ELayer.WOODWALL, ELayer.WINDMILL, ELayer.SPAWN, ELayer.POWERMILL, ELayer.CASTLESPIKE, ELayer.TURRET, ELayer.WOODFARM, ELayer.CHERRYWOODFARM, ELayer.STONEWARM, ELayer.CASTLEWALL, ELayer.CHEST, ELayer.DRAGONWALLBIG, ELayer.DRAGONWALLMEDIUM, ELayer.DRAGONWALLSMALL, ELayer.MAMMOTHWALL, ELayer.MAMMOTHWALLSMALL, ELayer.TELEPORT, ELayer.CACTUS ];
const LayerExclude = [ ELayer.TREE, ELayer.WOODFARM, ELayer.CHERRYWOODFARM ];
var EObjects;
(function(EObjects) {
EObjects[EObjects["BOOST"] = 6] = "BOOST";
EObjects[EObjects["PLATFORM"] = 8] = "PLATFORM";
EObjects[EObjects["TRAP"] = 9] = "TRAP";
EObjects[EObjects["ROOF"] = 48] = "ROOF";
})(EObjects || (EObjects = {}));
var EHats;
(function(EHats) {
EHats[EHats["BUSH"] = 1] = "BUSH";
EHats[EHats["BERSERKER"] = 2] = "BERSERKER";
EHats[EHats["JUNGLE"] = 3] = "JUNGLE";
EHats[EHats["CRYSTAL"] = 4] = "CRYSTAL";
EHats[EHats["SPIKEGEAR"] = 5] = "SPIKEGEAR";
EHats[EHats["IMMUNITY"] = 6] = "IMMUNITY";
EHats[EHats["BOOST"] = 7] = "BOOST";
EHats[EHats["APPLEHAT"] = 8] = "APPLEHAT";
EHats[EHats["SCUBA"] = 9] = "SCUBA";
EHats[EHats["HOOD"] = 10] = "HOOD";
EHats[EHats["DEMOLIST"] = 11] = "DEMOLIST";
})(EHats || (EHats = {}));
var EWeapons;
(function(EWeapons) {
EWeapons[EWeapons["SHIELD"] = 11] = "SHIELD";
EWeapons[EWeapons["STICK"] = 13] = "STICK";
EWeapons[EWeapons["HAMMER"] = 15] = "HAMMER";
})(EWeapons || (EWeapons = {}));
var EItemTypes;
(function(EItemTypes) {
EItemTypes[EItemTypes["ATTACKING"] = 0] = "ATTACKING";
EItemTypes[EItemTypes["SHOOTING"] = 1] = "SHOOTING";
EItemTypes[EItemTypes["PLACEABLE"] = 2] = "PLACEABLE";
EItemTypes[EItemTypes["FOOD"] = 3] = "FOOD";
})(EItemTypes || (EItemTypes = {}));
var EAnimals;
(function(EAnimals) {
EAnimals[EAnimals["COW"] = 14] = "COW";
EAnimals[EAnimals["SHARK"] = 23] = "SHARK";
EAnimals[EAnimals["WOLF"] = 24] = "WOLF";
EAnimals[EAnimals["GOLDENCOW"] = 25] = "GOLDENCOW";
EAnimals[EAnimals["DRAGON"] = 27] = "DRAGON";
EAnimals[EAnimals["MAMMOTH"] = 28] = "MAMMOTH";
EAnimals[EAnimals["DUCK"] = 36] = "DUCK";
})(EAnimals || (EAnimals = {}));
var PlacementType;
(function(PlacementType) {
PlacementType[PlacementType["DEFAULT"] = 0] = "DEFAULT";
PlacementType[PlacementType["INVISIBLE"] = 1] = "INVISIBLE";
PlacementType[PlacementType["HOLDING"] = 2] = "HOLDING";
})(PlacementType || (PlacementType = {}));
const selectData = {
placementType: PlacementType
};
let teammates = [];
const UpdateClanList = userList => {
teammates = userList;
};
const DeleteClan = () => {
teammates = [];
};
const storage = {
get(key) {
return JSON.parse(localStorage.getItem(key));
},
set(key, value) {
localStorage.setItem(key, JSON.stringify(value));
},
delete(key) {
localStorage.removeItem(key);
}
};
const defaultSettings = {
primary: "Digit1",
secondary: "Digit2",
heal: "KeyQ",
wall: "Digit4",
spike: "KeyV",
windmill: "KeyN",
trap: "KeyF",
turret: "KeyH",
tree: "KeyU",
platform: "KeyT",
spawn: "KeyJ",
up: "KeyW",
left: "KeyA",
down: "KeyS",
right: "KeyD",
attack: 0,
autoattack: "KeyE",
lockRotation: "KeyX",
openChat: "Enter",
invisibleHit: 2,
spikeInsta: "KeyR",
toggleMenu: "Escape",
fastBreak: "KeyZ",
upgradeScythe: "...",
unequip: "...",
bush: "...",
berserker: "...",
jungle: "...",
crystal: "...",
spikegear: "...",
immunity: 4,
boost: 3,
applehat: "...",
scuba: "...",
hood: "...",
demolist: "...",
placementType: PlacementType.INVISIBLE,
placementSpeed: 1,
autoheal: true,
autohealDelay: 80,
jungleOnClown: true,
lastHat: true,
autoScuba: true,
meleeAim: true,
bowAim: true,
spikeInstaAim: true,
enemyTracers: true,
teammateTracers: true,
animalTracers: true,
enemyColor: "#cc5151",
teammateColor: "#8ecc51",
animalColor: "#518ccc",
arrows: true,
rainbow: false,
drawHP: true,
showHoods: true,
itemCounter: true,
drawID: false,
visualAim: true,
hideNicknames: false,
itemMarkers: true,
teammateMarkers: true,
enemyMarkers: true,
trapActivated: true,
itemMarkersColor: "#8ecc51",
teammateMarkersColor: "#cfbc5f",
enemyMarkersColor: "#cc5151",
trapActivatedColor: "#48b2b8",
markersBottom: true,
hatReloadBar: true,
hatReloadBarColor: "#5155cc",
fireballReloadBar: true,
fireballReloadBarColor: "#cf7748",
turretReloadBar: true,
turretReloadBarColor: "#51cc80",
windmillRotation: false,
possibleShots: true,
autochat: true,
autochatMessages: [ "Dsync Client", "What is it?", "The most advanced hack for sploop!", "Download on greasyfork!" ],
kill: true,
killMessage: "{NAME}, you suck! {KILL}x",
autospawn: false,
smoothZoom: true,
skipUpgrades: true,
invisHitToggle: false,
reverseZoom: false,
autoScythe: true,
menuTransparency: false
};
const settings = {
...defaultSettings,
...storage.get("Dsync-settings")
};
for (const key in settings) {
if (!defaultSettings.hasOwnProperty(key)) {
delete settings[key];
}
}
storage.set("Dsync-settings", settings);
const Settings = settings;
const itemBar = index => Dsync.defaultData[Dsync.props.itemBar][index];
const hasSecondary = () => {
const item = Dsync.itemData[itemBar(1)];
return item[Dsync.props.itemType] === EItems.SECONDARY;
};
const canShoot = () => {
const item = Dsync.itemData[itemBar(1)];
return item[Dsync.props.itemDataType] === EItemTypes.SHOOTING;
};
const hasItemByType = type => {
const items = Dsync.defaultData[Dsync.props.itemBar];
return items.some((id => Dsync.itemData[id][Dsync.props.itemType] === type));
};
const isStoneGold = () => {
const item = Dsync.itemData[itemBar(0)];
return [ 1, 2 ].includes(item[Dsync.props.weaponType]);
};
const upgradeScythe = () => {
const goldenCowID = Dsync.goldenCowID();
if (goldenCowID) {
Dsync.upgradeScythe(goldenCowID);
}
};
const getAnimals = () => {
const list = Dsync.entityList();
return [ ...list[EAnimals.COW], ...list[EAnimals.SHARK], ...list[EAnimals.WOLF], ...list[EAnimals.GOLDENCOW], ...list[EAnimals.DRAGON], ...list[EAnimals.MAMMOTH], ...list[EAnimals.DUCK] ].map((entity => formatEntity(entity)));
};
const getEnemies = () => {
const players = Dsync.entityList()[0];
return players.map((player => formatEntity(player))).filter((({id, ownerID}) => {
const isMyPlayer = id === Dsync.myPlayerID();
const isTeammate = teammates.includes(ownerID);
return !isMyPlayer && !isTeammate;
}));
};
const getEntities = () => [ ...getEnemies(), ...getAnimals() ];
const lineSegmentIntersectsCircle = (x1, y1, x2, y2, cx, cy, r) => {
const xL = x2 - x1;
const xC = x1 - cx;
const yL = y2 - y1;
const yC = y1 - cy;
const a = xL * xL + yL * yL;
const hB = xL * xC + yL * yC;
const c = xC * xC + yC * yC - r * r;
return hB * hB >= a * c && (-hB <= a || c + hB + hB + a <= 0) && (hB <= 0 || c <= 0);
};
const getNearestEntities = shoot => {
const enemies = getEnemies().map((enemy => ({
...enemy,
dir: getAngle(enemy, Dsync.myPlayer).angle,
distance: distance(enemy, Dsync.myPlayer).dist
}))).sort(((a, b) => a.distance - b.distance));
if (shoot) {
enemies.sort(((a, b) => {
const hasShield1 = a.target[Dsync.props.currentItem] === EWeapons.SHIELD;
const hasShield2 = b.target[Dsync.props.currentItem] === EWeapons.SHIELD;
return hasShield1 ? 1 : hasShield2 ? -1 : 0;
}));
}
const animals = getAnimals().map((enemy => ({
...enemy,
dir: getAngle(enemy, Dsync.myPlayer).angle,
distance: distance(enemy, Dsync.myPlayer).dist
}))).sort(((a, b) => a.distance - b.distance));
return [ ...enemies, ...animals ];
};
const entityIn = (entity, layer) => Dsync.entityList()[layer].some((target => {
const object = formatObject(target);
return distance(entity, object).dist < entity.radius + object.radius;
}));
const projectileCanHitEntity = entity => {
if (!canShoot()) return false;
const range = Dsync.itemData[itemBar(EItems.SECONDARY)].range;
const enemy = {
...entity,
dir: getAngle(entity, Dsync.myPlayer).angle,
distance: distance(entity, Dsync.myPlayer).dist
};
const x1 = Dsync.myPlayer.x2;
const y1 = Dsync.myPlayer.y2;
const x2 = x1 + range * Math.cos(enemy.dir);
const y2 = y1 + range * Math.sin(enemy.dir);
const myPlayerOnPlatform = entityIn(Dsync.myPlayer, ELayer.PLATFORM);
const entityInRoof = entityIn(entity, ELayer.ROOF);
if (myPlayerOnPlatform && entityInRoof) return false;
const layers = Dsync.entityList();
for (const layer of LayerObjects) {
if (myPlayerOnPlatform && !LayerExclude.includes(layer)) continue;
for (const entity of layers[layer]) {
const object = formatObject(entity);
const dist = distance(object, Dsync.myPlayer).dist;
if (dist > enemy.distance) continue;
if (lineSegmentIntersectsCircle(x1, y1, x2, y2, object.x2, object.y2, object.radius)) {
const objectData = Dsync.entityData[object.type];
const maxHealth = objectData[Dsync.props.maxHealth];
if (maxHealth === undefined) return false;
return {
canHit: true,
needDestroy: true
};
}
}
}
return {
canHit: true,
needDestroy: false
};
};
const getNearestPossibleEnemy = index => {
const range = Dsync.itemData[itemBar(index)].range;
const shoot = canShoot() && index === 1;
const enemies = getNearestEntities(shoot).filter((enemy => {
const inDistance = enemy.distance < range + enemy.radius;
if (shoot) {
const entityHit = projectileCanHitEntity(enemy);
return inDistance && typeof entityHit === "object" && entityHit.canHit;
}
return inDistance;
}));
if (shoot) {
enemies.sort(((a, b) => {
const canHitA = projectileCanHitEntity(a);
const canHitB = projectileCanHitEntity(b);
return canHitA.needDestroy ? 1 : canHitB.needDestroy ? -1 : 0;
}));
}
return enemies.length ? enemies[0] : null;
};
const createImage = src => {
const img = new Image;
img.src = src;
img.loaded = false;
img.onload = () => {
img.loaded = true;
};
return img;
};
const Images = {
gaugeBackground: createImage("https://i.imgur.com/xincrX4.png"),
gaugeFront: createImage("https://i.imgur.com/6AkHQM4.png")
};
const utils_Images = Images;
const TYPEOF = value => Object.prototype.toString.call(value).slice(8, -1).toLowerCase();
const removeClass = (target, name) => {
if (target instanceof HTMLElement) {
target.classList.remove(name);
return;
}
for (const element of target) {
element.classList.remove(name);
}
};
const formatCode = code => {
code = code + "";
if (code === "0") return "LBTN";
if (code === "1") return "MBTN";
if (code === "2") return "RBTN";
if (code === "3") return "XBTN2";
if (code === "4") return "XBTN1";
if (code === "Escape") return "ESC";
if (code === "BracketLeft") return "[";
if (code === "BracketRight") return "]";
if (code === "NumpadDivide") return "NUMDIV";
if (code === "NumpadMultiply") return "NUMMULT";
if (code === "NumpadSubtract") return "NUMSUB";
if (code === "NumpadDecimal") return "NUMDEC";
if (code === "CapsLock") return "CAPS";
if (code === "PrintScreen") return "PRNT";
if (code === "Backslash") return "\\";
if (code === "Backquote") return "BQUOTE";
if (code === "PageDown") return "PAGEDN";
const NumpadDigitArrowKey = /^(?:Numpad|Digit|Arrow|Key)(\w+)$/;
if (NumpadDigitArrowKey.test(code)) {
code = code.replace(NumpadDigitArrowKey, "$1").replace(/Numpad/, "NUM");
}
const ExtraKeysRegex = /^(Control|Shift|Alt)(.).*/;
if (ExtraKeysRegex.test(code)) {
code = code.replace(ExtraKeysRegex, "$2$1").replace(/Control/, "CTRL");
}
return code.toUpperCase();
};
const contains = (target, name) => target.classList.contains(name);
const isInput = target => {
const element = target || document.activeElement;
return [ "TEXTAREA", "INPUT" ].includes(element.tagName);
};
const inGame = () => {
const homepage = document.querySelector("#homepage");
return homepage && homepage.style.display === "none";
};
const formatData = object => ({
id: object[Dsync.props.id],
type: object.type,
x: object[Dsync.props.x],
y: object[Dsync.props.y],
x1: object[Dsync.props.x1],
y1: object[Dsync.props.y1],
x2: object[Dsync.props.x2],
y2: object[Dsync.props.y2],
angle: object[Dsync.props.angle],
angle1: object[Dsync.props.angle1],
angle2: object[Dsync.props.angle2],
ownerID: object[Dsync.props.itemOwner],
target: object
});
const formatProjectile = object => {
const data = formatData(object);
return {
...data,
range: object.range
};
};
const formatObject = object => {
const data = formatData(object);
const entityData = Dsync.entityData[object.type];
return {
...data,
radius: entityData[Dsync.props.radius]
};
};
const formatEntity = entity => {
const object = formatObject(entity);
const entityData = Dsync.entityData[entity.type];
const healthValue = entity[Dsync.props.health];
const maxHealth = entityData[Dsync.props.maxHealth];
return {
...object,
healthValue,
health: Math.ceil(entity[Dsync.props.health] / 255 * maxHealth),
maxHealth,
playerValue: entity[Dsync.props.playerValue]
};
};
const formatPlayer = entity => {
const player = formatEntity(entity);
return {
...player,
hat: entity[Dsync.props.hat],
isClown: player.playerValue === 128
};
};
const getTracerColor = (entity, isTeammate) => {
if (entity.id === Dsync.myPlayerID() || isTeammate) return Settings.teammateColor;
if (entity.type === 0) return Settings.enemyColor;
return Settings.animalColor;
};
const trapActive = object => {
const trap = formatObject(object);
return getEntities().some((entity => distance(entity, trap).dist < trap.radius + entity.radius - 25));
};
const getMarkerColor = (target, ownerID) => {
let color = null;
const isMyPlayers = (Dsync.myPlayer || {}).ownerID === ownerID;
const isTeammates = teammates.includes(ownerID);
const isTeammateTrap = target.type === 6 && (isMyPlayers || isTeammates);
if (Settings.itemMarkers && isMyPlayers) {
color = Settings.itemMarkersColor;
} else if (Settings.teammateMarkers && isTeammates) {
color = Settings.teammateMarkersColor;
} else if (Settings.enemyMarkers && !isMyPlayers && !isTeammates) {
color = Settings.enemyMarkersColor;
}
if (Settings.trapActivated && isTeammateTrap) {
const id = target[Dsync.props.id];
if (!target.active && trapActive(target)) {
target.active = id;
}
if (target.active === id) return Settings.trapActivatedColor;
target.active = null;
}
return color;
};
const marker = (ctx, color) => {
ctx.strokeStyle = "#303030";
ctx.lineWidth = 3;
ctx.fillStyle = color;
ctx.beginPath();
ctx.arc(0, 0, 9, 0, 2 * Math.PI);
ctx.fill();
ctx.stroke();
ctx.closePath();
};
const arrow = (ctx, len, x, y, angle, color) => {
ctx.save();
ctx.translate(x, y);
ctx.rotate(Math.PI / 4);
ctx.rotate(angle);
ctx.globalAlpha = .75;
ctx.strokeStyle = color;
ctx.lineCap = "round";
ctx.lineWidth = 8;
ctx.beginPath();
ctx.moveTo(-len, -len);
ctx.lineTo(len, -len);
ctx.lineTo(len, len);
ctx.stroke();
ctx.closePath();
ctx.restore();
};
const lines = (ctx, x1, y1, x2, y2, color) => {
ctx.save();
ctx.globalAlpha = .75;
ctx.strokeStyle = color;
ctx.lineCap = "round";
ctx.lineWidth = 5;
ctx.beginPath();
ctx.moveTo(x1, y1);
ctx.lineTo(x2, y2);
ctx.stroke();
ctx.restore();
};
const Common_images = {};
const crosshair = (ctx, x, y, angle, color, radius, width, height) => {
const canvas = Common_images[color] || function() {
const canvas = document.createElement("canvas");
canvas.width = 256;
canvas.height = 256;
const ctx = canvas.getContext("2d");
ctx.translate(canvas.width / 2, canvas.height / 2);
ctx.strokeStyle = color;
ctx.fillStyle = color;
ctx.lineWidth = width / 1.5;
ctx.beginPath();
ctx.arc(0, 0, radius, 0, 2 * Math.PI);
ctx.stroke();
ctx.closePath();
for (let i = 0; i < 4; i++) {
ctx.beginPath();
ctx.rect(-width / 2, radius - height / 2, width, height);
ctx.fill();
ctx.rotate(Math.PI / 2);
ctx.closePath();
}
Common_images[color] = canvas;
return canvas;
}();
ctx.save();
ctx.translate(x, y);
ctx.rotate(angle);
ctx.globalAlpha = .75;
ctx.drawImage(canvas, -canvas.width / 2, -canvas.height / 2);
ctx.restore();
};
const drawImage = (ctx, image) => {
ctx.drawImage(image, -.5 * image.width / 2, -.5 * image.height, image.width * .5, image.height * .5);
};
const drawBar = (ctx, entity, value, maxValue, color) => {
const {x, y, radius} = entity;
const background = utils_Images.gaugeBackground;
const front = utils_Images.gaugeFront;
const scale = .5;
const width = front.width * scale;
const fill = value / maxValue * (width - 10);
const h = entity.type === ELayer.TURRET ? 25 : 50;
ctx.save();
if (Settings.markersBottom && entity.type === ELayer.TURRET) {
ctx.rotate(Math.PI - entity.angle);
ctx.rotate(Math.PI);
}
ctx.translate(x, y + radius + h + front.height * scale);
drawImage(ctx, background);
ctx.fillStyle = color;
ctx.fillRect(-width / 2 + 5, -scale * front.height + 5, fill, scale * front.height - 10);
drawImage(ctx, front);
ctx.restore();
};
const drawHealth = (ctx, entity) => {
if (!Settings.drawHP) return;
const {x, y, health, maxHealth, radius} = entity;
const front = utils_Images.gaugeFront;
let h = 0;
if (Settings.hatReloadBar && entity.type === 0 || Settings.fireballReloadBar && entity.type === ELayer.DRAGON) {
h = front.height * .5;
}
renderText(ctx, `HP ${health}/${maxHealth}`, ((width, height) => [ x - width / 2, y + radius + h + 55 ]));
};
const dist = (x1, y1, x2, y2) => Math.sqrt(Math.pow(x1 - x2, 2) + Math.pow(y1 - y2, 2));
const distance = (entity1, entity2) => {
const entity1Has = "x" in entity1 && "y" in entity1;
const entity2Has = "x" in entity2 && "y" in entity2;
return {
lerpDist: entity1Has && entity2Has ? dist(entity1.x, entity1.y, entity2.x, entity2.y) : null,
dist: dist(entity1.x2, entity1.y2, entity2.x2, entity2.y2)
};
};
const getAngle = (entity1, entity2) => {
const entity1Has = "x" in entity1 && "y" in entity1;
const entity2Has = "x" in entity2 && "y" in entity2;
return {
lerpAngle: entity1Has && entity2Has ? Math.atan2(entity1.y - entity2.y, entity1.x - entity2.x) : null,
angle: Math.atan2(entity1.y2 - entity2.y2, entity1.x2 - entity2.x2)
};
};
const lerp = (start, stop, amt) => amt * (stop - start) + start;
const drawTracers = (ctx, entity, isTeammate) => {
const player = formatPlayer(Dsync.target);
const {x: x1, y: y1} = player;
const {x: x2, y: y2} = entity;
const color = Settings.rainbow ? `hsl(${Dsync.hsl}, 100%, 50%)` : getTracerColor(entity, isTeammate);
if (Settings.arrows) {
const arrowWidth = 8;
const angle = getAngle(entity, player).lerpAngle;
const dist = Math.min(100 + arrowWidth * 2, distance(entity, player).lerpDist - arrowWidth * 2);
const x = x1 + dist * Math.cos(angle);
const y = y1 + dist * Math.sin(angle);
arrow(ctx, arrowWidth, x, y, angle, color);
} else {
lines(ctx, x1, y1, x2, y2, color);
}
};
const TextOptions = {
font: "bold 15px Montserrat",
textBaseline: "top"
};
const renderText = (ctx, text, callback, options) => {
ctx.save();
ctx.fillStyle = "#fff";
ctx.strokeStyle = "#303030";
ctx.lineWidth = 8;
ctx.lineJoin = "round";
Object.assign(ctx, TextOptions, options);
const width = ctx.measureText(text).width;
const height = parseInt(ctx.font.match(/\d+/)[0]) || 1;
const data = callback(width, height);
ctx.strokeText(text, ...data);
ctx.fillText(text, ...data);
ctx.restore();
};
const windmillRotation = target => {
if (target.type !== ELayer.WINDMILL && target.type !== ELayer.POWERMILL) return;
if (!target.rotSpeed) {
target.rotSpeed = target[Dsync.props.rotSpeed];
}
const rot = Settings.windmillRotation ? target.rotSpeed : 0;
if (target[Dsync.props.rotSpeed] !== rot) {
target[Dsync.props.rotSpeed] = rot;
}
};
const sleep = ms => new Promise((resolve => setTimeout(resolve, ms)));
const linker = value => {
const hook = {
0: value,
toString: radix => hook[0].toString(radix),
valueOf: () => hook[0].valueOf()
};
return hook;
};
const download = (data, filename) => {
const blob = new Blob([ JSON.stringify(data, null, 4) ], {
type: "application/json "
});
const url = URL.createObjectURL(blob);
const a = document.createElement("a");
a.href = url;
a.download = (filename || "settings") + ".txt";
a.click();
a.remove();
URL.revokeObjectURL(url);
};
const capitalize = word => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase();
let move = 0;
let attacking = false;
let autoattack = false;
let weapon = false;
let isHealing = false;
let attackingInvis = false;
let toggleInvis = false;
let currentItem = null;
const hotkeys = new Map;
const spawn = async () => {
await sleep(100);
const play = document.querySelector("#play");
if (play) play.click();
};
let chatCount = 0;
let chatToggle = false;
const autochat = async () => {
if (chatToggle || isInput() || !inGame()) return;
chatToggle = true;
const messages = Settings.autochatMessages.filter((msg => msg.length));
if (!messages.length) return;
Dsync.chat(messages[chatCount++]);
chatCount %= messages.length;
await sleep(2e3);
chatToggle = false;
};
const Controller_reset = () => {
move = 0;
attacking = false;
autoattack = false;
weapon = false;
isHealing = false;
attackingInvis = false;
toggleInvis = false;
currentItem = null;
for (const [key] of hotkeys) {
hotkeys.delete(key);
}
};
const equipHat = (id, ignore = false, actual = true) => {
const hat = (Dsync.myPlayer || {}).hat || 0;
if (id === 0) {
id = hat;
} else if (hat === id && !ignore) return;
if (actual) {
Dsync.actualHat = id;
}
Dsync.equipHat(id);
Dsync.equipHat(id);
};
const whichWeapon = type => {
if (type !== undefined) {
weapon = type;
}
Dsync.selectByID(itemBar(Number(weapon)));
};
const attack = (angle = null) => {
Dsync.attack(angle !== null ? angle : Dsync.getAngle());
};
const place = (id, angle = null) => {
whichWeapon();
if (attacking || autoattack) attack(angle);
Dsync.selectItem(id);
attack(angle);
Dsync.stopAttack();
if (Settings.placementType !== PlacementType.HOLDING) whichWeapon();
};
let count = 0;
const placement = () => {
if (currentItem === null) return;
place(currentItem);
count++;
if ((count %= Settings.placementSpeed) === 0) {
setTimeout(placement);
} else {
queueMicrotask(placement);
}
};
const placementHandler = (type, code) => {
if (!hasItemByType(type)) return;
if (Settings.placementType === PlacementType.DEFAULT) {
Dsync.selectItem(type);
return;
}
hotkeys.set(code, type);
currentItem = type;
if (hotkeys.size === 1) {
placement();
}
};
const heal = () => {
Dsync.selectItem(EItems.HEAL);
attack();
Dsync.stopAttack();
whichWeapon();
if (attacking) {
attack();
}
};
const healing = () => {
if (!isHealing) return;
heal();
setTimeout(healing, 0);
};
const invisibleHit = () => {
Dsync.mousemove = true;
Dsync.aimTarget = null;
if (Settings.invisHitToggle && !toggleInvis || !Settings.invisHitToggle && !attackingInvis) {
toggleInvis = false;
attackingInvis = false;
return;
}
let angle = null;
const enemy = getNearestPossibleEnemy(+!weapon);
const shoot = canShoot() && !weapon;
if (enemy && (Settings.meleeAim && !shoot || Settings.bowAim && shoot)) {
angle = enemy.dir;
Dsync.mousemove = false;
Dsync.aimTarget = enemy.target;
}
if (enemy && shoot || !shoot) {
whichWeapon(!weapon);
attack(angle);
Dsync.stopAttack();
whichWeapon(!weapon);
}
setTimeout(invisibleHit, 75);
};
const spikeInsta = () => {
let angle = null;
if (Settings.spikeInstaAim) {
const enemy = getNearestPossibleEnemy(0);
if (enemy) {
angle = enemy.dir;
}
}
const oldWeapon = weapon;
equipHat(EHats.BERSERKER);
whichWeapon(false);
place(EItems.SPIKE, angle);
attack(angle);
Dsync.stopAttack();
whichWeapon(oldWeapon);
};
let fastBreakHat = 0;
let oldWeapon = false;
let fastBreaking = false;
let startFastBreak = 0;
const fastBreak = () => {
if (fastBreaking) return;
startFastBreak = Date.now();
const primary = itemBar(0);
const secondary = itemBar(1);
const pickWeapon = hasSecondary() && !canShoot() && (secondary === EWeapons.HAMMER || primary === EWeapons.STICK);
oldWeapon = weapon;
fastBreaking = true;
fastBreakHat = Dsync.myPlayer.hat;
whichWeapon(pickWeapon);
equipHat(EHats.DEMOLIST);
attacking = true;
attack();
};
const fastBreakStop = async () => {
if (!fastBreaking) return;
Dsync.stopAttack();
attacking = false;
whichWeapon(oldWeapon);
const step = Date.now() - startFastBreak;
if (step < 1300) await sleep(1300 - step);
if (!Dsync.myPlayer.isClown) equipHat(fastBreakHat);
fastBreaking = false;
};
const handleKeydown = (event, code) => {
if (code === 1) event.preventDefault();
if (event instanceof KeyboardEvent && event.repeat) return;
if (Dsync.active) return;
if (code === Settings.toggleMenu && !isInput(event.target)) {
Dsync.toggleMenu();
}
if (!inGame()) return;
if (code === Settings.openChat) {
if (!isInput()) event.preventDefault();
Dsync.toggleChat();
}
if (isInput(event.target)) return;
if (code === Settings.primary) whichWeapon(false);
if (code === Settings.secondary && hasSecondary()) whichWeapon(true);
if (code === Settings.heal) {
isHealing = true;
healing();
}
if (code === Settings.wall) placementHandler(EItems.WALL, code);
if (code === Settings.spike) placementHandler(EItems.SPIKE, code);
if (code === Settings.windmill) placementHandler(EItems.WINDMILL, code);
if (code === Settings.trap) placementHandler(EItems.TRAP, code);
if (code === Settings.turret) placementHandler(EItems.TURRET, code);
if (code === Settings.tree) placementHandler(EItems.TREE, code);
if (code === Settings.platform) placementHandler(EItems.PLATFORM, code);
if (code === Settings.spawn) placementHandler(EItems.SPAWN, code);
if (code === Settings.unequip) equipHat(Dsync.myPlayer.hat, true);
if (code === Settings.bush) equipHat(EHats.BUSH);
if (code === Settings.berserker) equipHat(EHats.BERSERKER);
if (code === Settings.jungle) equipHat(EHats.JUNGLE);
if (code === Settings.crystal) equipHat(EHats.CRYSTAL);
if (code === Settings.spikegear) equipHat(EHats.SPIKEGEAR);
if (code === Settings.immunity) equipHat(EHats.IMMUNITY);
if (code === Settings.boost) equipHat(EHats.BOOST);
if (code === Settings.applehat) equipHat(EHats.APPLEHAT);
if (code === Settings.scuba) equipHat(EHats.SCUBA);
if (code === Settings.hood) equipHat(EHats.HOOD);
if (code === Settings.demolist) equipHat(EHats.DEMOLIST);
if (code === Settings.invisibleHit && hasSecondary()) {
if (Settings.invisHitToggle) {
toggleInvis = !toggleInvis;
} else {
attackingInvis = true;
}
if (toggleInvis || attackingInvis) invisibleHit();
}
if (code === Settings.spikeInsta) spikeInsta();
if (code === Settings.fastBreak) fastBreak();
const copyMove = move;
if (code === Settings.up) move |= 1;
if (code === Settings.left) move |= 4;
if (code === Settings.down) move |= 2;
if (code === Settings.right) move |= 8;
if (copyMove !== move) Dsync.move(move);
if (event instanceof MouseEvent && code === Settings.attack) {
const canAttack = !Dsync.mousedown(event);
if (canAttack && Dsync.mousemove) {
attacking = true;
Dsync.attack(Dsync.getAngle());
}
}
if (code === Settings.autoattack) {
autoattack = !autoattack;
Dsync.autoattack(autoattack);
}
if (code === Settings.lockRotation) Dsync.toggleRotation();
if (code === Settings.upgradeScythe) upgradeScythe();
};
const handleKeyup = (event, code) => {
if (code === Settings.heal && isHealing) {
isHealing = false;
}
if (code === Settings.invisibleHit && attackingInvis) {
attackingInvis = false;
}
if (code === Settings.fastBreak) fastBreakStop();
const copyMove = move;
if (code === Settings.up) move &= -2;
if (code === Settings.left) move &= -5;
if (code === Settings.down) move &= -3;
if (code === Settings.right) move &= -9;
if (copyMove !== move) Dsync.move(move);
if (event instanceof MouseEvent && code === Settings.attack) {
Dsync.mouseup(event);
attacking = false;
}
if (currentItem !== null && hotkeys.delete(code)) {
const entries = [ ...hotkeys ];
currentItem = entries.length ? entries[entries.length - 1][1] : null;
if (currentItem === null) {
whichWeapon();
}
}
};
var code = '