New visuals elements [Tracers, HitBoxes, HP indicator, Setting menu]
// ==UserScript== // @name Sploop.io [Visual Extension] // @name:ru Sploop.io [Визуальное расширение] // @description New visuals elements [Tracers, HitBoxes, HP indicator, Setting menu] // @description:ru Новые визуальные элементы [Tracers, HitBoxes, HP indicator, Setting menu] // @namespace https://greasyfork.org/ru/users/759782-nudo // @version 2.1 // @author Nudo#3310 // @match *://sploop.io/* // @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 // ==/UserScript== class Visuals { constructor() { this.text = { color: { all: "#fff", rainbow: false }, visible: 1 } this.tracers = { active: true, disttag: true, dashline: false, color: { entity: "#cc5151", ally: "#a4cc4f", rainbow: false }, size: 1, visible: 1 } this.hitboxes = { active: false, dashline: false, color: { all: "#5174cd", rainbow: false }, size: 1, visible: 1 } this.rainbow = { old: Date.now(), hue: 0, power: 3, time: 10 } this.offset = [0, Date.now()] } rainbowColor() { if (!this.rainbow.old || Date.now() - this.rainbow.old >= this.rainbow.time) { this.rainbow.hue += this.rainbow.power * Math.random() this.rainbow.old = Date.now() } visuals.rb = `hsl(${this.rainbow.hue}, 100%, 50%)` } drawText(text, x, y) { Context.save() Context.font = '18px "Baloo Paaji"' Context.lineWidth = 8 Context.strokeStyle = "#3d3f42" Context.globalAlpha = this.text.visible Context.textAlign = 'center' Context.fillStyle = this.text.color.rainbow ? visuals.rb : this.text.color.all Context.strokeText(text, x, y) Context.fillText(text, x, y) Context.restore() } updateOffset() { if (!this.offset[1] || Date.now() - this.offset[1] >= 10) { this.offset[0]++ this.offset[1] = Date.now() } } dashLine() { Context.setLineDash([18, 6, 6, 6]) Context.lineDashOffset = -visuals.offset[0] } } let visuals = new Visuals() class Tracers { constructor() { this.allAlly = [] this.allEntity = [] this.localPlayer = { active: false, x: 0, y: 0 } } drawDistTag(x, y, dist) { if (!visuals.tracers.disttag) return Context.save() Context.font = '18px "Baloo Paaji"' Context.lineWidth = 8 Context.strokeStyle = "#3d3f42" Context.globalAlpha = visuals.text.visible Context.fillStyle = visuals.text.color.rainbow ? visuals.rb : visuals.text.color.all Context.strokeText(dist, x, y) Context.fillText(dist, x, y) Context.restore() } draw(x, y, x2, y2, color) { if (!visuals.tracers.active) return Context.save() Context.lineCap = "round" Context.lineWidth = visuals.tracers.size Context.globalAlpha = visuals.tracers.visible Context.beginPath() if (visuals.tracers.dashline) visuals.dashLine() Context.strokeStyle = color Context.moveTo(x, y) Context.lineTo(x2, y2) Context.stroke() Context.restore() } } let tracers = new Tracers() class HitBoxes { static draw(x, y, width, height) { if (!visuals.hitboxes.active) return Context.save() Context.lineWidth = visuals.hitboxes.size Context.globalAlpha = visuals.hitboxes.visible if (visuals.hitboxes.dashline) visuals.dashLine() Context.strokeStyle = visuals.hitboxes.color.rainbow ? visuals.rb : visuals.hitboxes.color.all Context.strokeRect(x, y, width, height) Context.restore() } } let Context; let { clearRect, fillRect, fillText, drawImage } = CanvasRenderingContext2D.prototype CanvasRenderingContext2D.prototype.clearRect = function(x, y, width, height) { if (this.canvas.id === "game-canvas") { Context = this.canvas.getContext("2d") visuals.rainbowColor() tracers.allEntity = [] tracers.allAlly = [] } return clearRect.apply(this, arguments); } CanvasRenderingContext2D.prototype.drawImage = function(image, x, y, width, height, dx, dy, dwidth, dheight) { if (tracers.localPlayer.active && typeof image.src == 'string') { let ff = image.src.split("/") if (ff[4] == "skins" || ff[4] == "entity" && !ff[5].includes("inv_") && !ff[5].includes("map") && !ff[5].includes("resource") && !ff[5].includes("health") && !ff[5].includes("button") && !ff[5].includes("skull")) { HitBoxes.draw(x, y, width, height) } } return drawImage.apply(this, arguments); } CanvasRenderingContext2D.prototype.fillRect = function(x, y, width, height) { if (document.getElementById("homepage").style.display == "none") { visuals.updateOffset() if (this.fillStyle == "#a4cc4f") { tracers.allAlly.push({ x: x + 45, y: y - 70 }) tracers.localPlayer.active = true tracers.localPlayer.x = tracers.allAlly[0].x tracers.localPlayer.y = tracers.allAlly[0].y visuals.drawText(`HP: ${~~(width / 95 * 100)}%`, x + 45, y + 40) visuals.drawText(`VisualExtension`, tracers.localPlayer.x, tracers.localPlayer.y + 125) if (tracers.allAlly[1]) { tracers.allAlly.forEach(ally => { if (ally.x != tracers.localPlayer.x) { let color = (visuals.tracers.color.rainbow ? visuals.rb : visuals.tracers.color.ally) tracers.draw(tracers.localPlayer.x, tracers.localPlayer.y, ally.x, ally.y, color) tracers.drawDistTag((tracers.localPlayer.x + ally.x) / 2, (tracers.localPlayer.y + ally.y) / 2, ~~(Math.hypot(tracers.localPlayer.y - ally.y, tracers.localPlayer.x - ally.x))) } }) } } if (this.fillStyle == "#cc5151" && tracers.localPlayer.active) { visuals.drawText(`HP: ${~~(width / 95 * 100)}%`, x + 45, y + 40) tracers.allEntity.push({ x: x + 45, y: y - 70 }) tracers.allEntity.forEach(enemy => { let color = (visuals.tracers.color.rainbow ? visuals.rb : visuals.tracers.color.entity) tracers.draw(tracers.localPlayer.x, tracers.localPlayer.y, enemy.x, enemy.y, color) tracers.drawDistTag((tracers.localPlayer.x + enemy.x) / 2, (tracers.localPlayer.y + enemy.y) / 2, ~~(Math.hypot(tracers.localPlayer.y - enemy.y, tracers.localPlayer.x - enemy.x))) }) } } else { tracers.localPlayer.active = false } return fillRect.apply(this, arguments) } let Menu = ` <div class="menu-holder flex-c"> <div class="menu-wrapper"> <div class="menu-container"> <div class="menu-title flex-c text-shadowed-4"> <span>VisualExtension</span> </div> <div class="menu-content scrollbar text-shadowed-3"> <ul class="tracers-content"> <li class="subcontent-subtitle" style="font-size: 18px;">Tracer</li> <li class="setting-box"> <div class="name-box">Active</div> <div class="action-box"><div class="control-group"><label class="control control-checkbox" style="display:unset;padding-top:4px;"><input type="checkbox" id="tracer-active" checked><div class="control_indicator"></div></label></div></div> </li> <li class="setting-box"> <div class="name-box">RainbowColor</div> <div class="action-box"><div class="control-group"><label class="control control-checkbox" style="display:unset;padding-top:4px;"><input type="checkbox" id="tracer-rainbow"><div class="control_indicator"></div></label></div></div> </li> <li class="setting-box" title="When there are a lot of tracers, it's a lower your FPS!"> <div class="name-box">DashLine</div> <div class="action-box"><div class="control-group"><label class="control control-checkbox" style="display:unset;padding-top:4px;"><input type="checkbox" id="tracer-dashline"><div class="control_indicator"></div></label></div></div> </li> <li class="setting-box"> <div class="name-box">DistTag</div> <div class="action-box"><div class="control-group"><label class="control control-checkbox" style="display:unset;padding-top:4px;"><input type="checkbox" id="tracer-disttag" checked><div class="control_indicator"></div></label></div></div> </li> <li class="setting-box"> <div class="name-box">AllyColor</div> <div class="action-box"><input type="color" id="tracers-ally-color" value="#a4cc4f"></div> </li> <li class="setting-box"> <div class="name-box">EntityColor</div> <div class="action-box"><input type="color" id="tracers-entity-color" value="#cc5151"></div> </li> <li class="setting-box"> <div class="name-box">Size</div> <div class="action-box"> <div class="range-wrapper"><input type="range" class="pointer" id="tracers-size" value="1" min="1" step="any" max="10"><div class="range-value flex-c text-shadowed-3" id="tracers-size-value">1</div></div> </div> </li> <li class="setting-box"> <div class="name-box">Visible</div> <div class="action-box"> <div class="range-wrapper"><input type="range" class="pointer" id="tracers-visible" value="1" min="0" step="any" max="1"><div class="range-value flex-c text-shadowed-3" id="tracers-visible-value">1</div></div> </div> </li> </ul> <ul class="text-content"> <li class="subcontent-subtitle" style="font-size: 18px;">Text</li> <li class="setting-box"> <div class="name-box">RainbowColor</div> <div class="action-box"><div class="control-group"><label class="control control-checkbox" style="display:unset;padding-top:4px;"><input type="checkbox" id="text-rainbow"><div class="control_indicator"></div></label></div></div> </li> <li class="setting-box"> <div class="name-box">Color</div> <div class="action-box"><input type="color" id="text-all-color" value="#ffffff"></div> </li> <li class="setting-box"> <div class="name-box">Visible</div> <div class="action-box"> <div class="range-wrapper"><input type="range" class="pointer" id="text-visible" value="1" min="0" step="any" max="1"><div class="range-value flex-c text-shadowed-3" id="text-visible-value">1</div></div> </div> </li> </ul> <ul class="hitboxes-content"> <li class="subcontent-subtitle" style="font-size: 18px;">HitBox</li> <li class="setting-box"> <div class="name-box">Active</div> <div class="action-box"><div class="control-group"><label class="control control-checkbox" style="display:unset;padding-top:4px;"><input type="checkbox" id="hitbox-active"><div class="control_indicator"></div></label></div></div> </li> <li class="setting-box"> <div class="name-box">RainbowColor</div> <div class="action-box"><div class="control-group"><label class="control control-checkbox" style="display:unset;padding-top:4px;"><input type="checkbox" id="hitbox-rainbow"><div class="control_indicator"></div></label></div></div> </li> <li class="setting-box" title="When there are a lot of hitboxes, it's a lower your FPS!"> <div class="name-box">DashLine</div> <div class="action-box"><div class="control-group"><label class="control control-checkbox" style="display:unset;padding-top:4px;"><input type="checkbox" id="hitbox-dashline"><div class="control_indicator"></div></label></div></div> </li> <li class="setting-box"> <div class="name-box">Color</div> <div class="action-box"><input type="color" id="hitbox-all-color" value="#5174cd"></div> </li> <li class="setting-box"> <div class="name-box">Size</div> <div class="action-box"> <div class="range-wrapper"><input type="range" class="pointer" id="hitbox-size" value="1" min="1" step="any" max="10"><div class="range-value flex-c text-shadowed-3" id="hitbox-size-value">1</div></div> </div> </li> <li class="setting-box"> <div class="name-box">Visible</div> <div class="action-box"> <div class="range-wrapper"><input type="range" class="pointer" id="hitbox-visible" value="1" min="0" step="any" max="1"><div class="range-value flex-c text-shadowed-3" id="hitbox-visible-value">1</div></div> </div> </li> </ul> </div> </div> </div> </div> <style> .range-value { width: 26px; margin-left: 5px; margin-right: -5px; } .range-wrapper { display: flex; margin-right: 5px; align-items: center; } .name-box { dont-size: 16px; } .setting-box { margin-bottom: 8px; display: flex; justify-content: space-between; width: 100%; padding-left: 3px; padding-right: 3px; } .tracers-content, .text-content, .hitboxes-content { margin-left: 5px; } .menu-content { display: flex; flex-direction: column; width: 214px; height: 265px; background: rgb(20 20 20 / 30%); border-radius: 10px; overflow-y: scroll; overflow-x: hidden; border: 3px solid #141414; box-shadow: inset 0 5px 0 rgb(20 20 20 / 40%); margin-left: 3px; } .menu-title span { font-size: 20px; color: #f0ece0; } .menu-title { width: 100%; height: 40px; } .menu-container { position: relative; left: -215px; display: flex; flex-direction: column; } .menu-wrapper { width: 40px; height: 325px; background: rgba(40, 45, 34, 0.6); border-radius: 0 15px 15px 0; border: 5px solid #141414; border-left: none; box-shadow: none; opacity: .5; transition: .5s all; } .menu-wrapper:hover { box-shadow: inset 0 4px 0 #4e5645, inset 0 -4px 0 #384825, 0px 2px 0 5px rgb(20 20 20 / 30%), 0px 0px 0 15px rgb(20 20 20 / 10%); } .menu-holder { position: absolute; top: 0; height: 100%; } .flex-c { display: flex; justify-content: center; align-items: center; } .flex-sb-c { display: flex; justify-content: space-between; align-items: center; } input[type="color"] { -webkit-appearance: none; border: none; background: none; width: 20px; height: 20px; border: 4px solid #141414; border-radius: 50%; } input[type="color"]::-webkit-color-swatch-wrapper { padding: 0; } input[type="color"]::-webkit-color-swatch { border: none; border-radius: 50%; } input[type=color]::-moz-focus-inner { border: none; padding: 0; border-radius: 50%; } input[type=color]::-moz-color-swatch { border: none; border-radius: 50%; } input[type="range"] { -webkit-appearance: none; width: 80px; height: 12px; background: rgba(40, 45, 34, 0.6);; border: 3px solid #141414; outline: none; } input[type="range"]::-webkit-slider-thumb { cursor: url(img/ui/cursor-pointer.png) 6 0, pointer; -webkit-appearance: none; width: 20px; border-radius: 4px; height: 20px; background: #f0ece0; border: 4px solid #141414; position: relative; z-index: 3; } </style> ` $("body").append(Menu) $(".menu-wrapper").mouseenter(() => { $(".menu-container").animate({left: "0px"}, 750) $(".menu-wrapper").animate({ width: "225px", opacity: "1" }, 250) }).mouseleave(() => { $(".menu-container").animate({left: "-215px"}, 750) $(".menu-wrapper").animate({ width: "40px", opacity: ".5" }, 250) }) $("#tracers-visible").on("input", () => { visuals.tracers.visible = $("#tracers-visible").val() let fn = String((parseInt(visuals.tracers.visible * 100)) / 100) $("#tracers-visible-value").text(fn.includes("0.0") ? "." + fn.split("0.")[1] : fn.includes("0.") ? fn.split("0")[1] : fn) }) $("#text-visible").on("input", () => { visuals.text.visible = $("#text-visible").val() let fn = String((parseInt(visuals.text.visible * 100)) / 100) $("#text-visible-value").text(fn.includes("0.0") ? "." + fn.split("0.")[1] : fn.includes("0.") ? fn.split("0")[1] : fn) }) $("#hitbox-visible").on("input", () => { visuals.hitboxes.visible = $("#hitbox-visible").val() let fn = String((parseInt(visuals.hitboxes.visible * 100)) / 100) $("#hitbox-visible-value").text(fn.includes("0.0") ? "." + fn.split("0.")[1] : fn.includes("0.") ? fn.split("0")[1] : fn) }) $("#hitbox-size").on("input", () => { visuals.hitboxes.size = $("#hitbox-size").val() let fn = String((parseInt(visuals.hitboxes.size * 100)) / 100) $("#hitbox-size-value").text(fn.includes("0.0") ? "." + fn.split("0.")[1] : fn.includes("0.") ? fn.split("0")[1] : fn) }) $("#tracers-size").on("input", () => { visuals.tracers.size = $("#tracers-size").val() let fn = String((parseInt(visuals.tracers.size * 100)) / 100) $("#tracers-size-value").text(fn.includes("0.0") ? "." + fn.split("0.")[1] : fn.includes("0.") ? fn.split("0")[1] : fn) }) $("#tracers-ally-color").on("input", () => visuals.tracers.color.ally = $("#tracers-ally-color").val()) $("#tracers-entity-color").on("input", () => visuals.tracers.color.entity = $("#tracers-entity-color").val()) $("#tracer-rainbow").on("input", () => visuals.tracers.color.rainbow = !visuals.tracers.color.rainbow) $("#tracer-disttag").on("input", () => visuals.tracers.disttag = !visuals.tracers.disttag, ) $("#tracer-dashline").on("input", () => visuals.tracers.dashline = !visuals.tracers.dashline) $("#text-all-color").on("input", () => visuals.text.color.all = $("#text-all-color").val()) $("#text-rainbow").on("input", () => visuals.text.color.rainbow = !visuals.text.color.rainbow) $("#hitbox-all-color").on("input", () => visuals.hitboxes.color.all = $("#hitbox-all-color").val()) $("#hitbox-rainbow").on("input", () => visuals.hitboxes.color.rainbow = !visuals.hitboxes.color.rainbow) $("#hitbox-dashline").on("input", () => visuals.hitboxes.dashline = !visuals.hitboxes.dashline) $("#hitbox-active").on("input", () => visuals.hitboxes.active = !visuals.hitboxes.active) $("#tracer-active").on("input", () => visuals.tracers.active = !visuals.tracers.active)