// ==UserScript==
// @name Evades Helper (E-Helper)
// @name:ru Evades Helper (E-Helper)
// @namespace http://tampermonkey.net/
// @version 0.4.3.7
// @description Nothing interesting. Just helper for evades.io.
// @description:ru Ничего необычного. Обычный помощник для evades.io
// @author TimiT#3626
// @match https://evades.io/
// @run-at document-start
// @grant none
// ==/UserScript==
/*
I made this code on my knee in a couple of evenings purely for fun :P
Hello to all Evades.io developers!
-------------------------------------------------------
Этот код сделал на коленке за пару вечеров чисто по фану :P
Привет всем разработчикам Evades.io!
*/
const VERSION = "0.4.3.7"
window.storage = {
get: (key,type="bool") => {
let res = localStorage.getItem(key)
if (type === "bool") return res === "true" ? true : false
if (type === "arr" || type === "obj") return res ? JSON.parse(res) : []
if (type === "num") return Number(res) || 0
return res;
},
set: (key, value,type="bool") => {
if (type === "bool" || type === "num") value = String(value)
if (type === "arr" || type === "obj") value = JSON.stringify(value)
localStorage.setItem(key,value)
return value
},
default: () => {
if (localStorage.getItem("aurasAlpha") === null) window.storage.set("aurasAlpha", 0.3, "num")
if (localStorage.getItem("enemiesOpacity") === null) window.storage.get("enemiesOpacity", 0.9, "num")
}
}
window.storage.default()
const text = (t) => {
let userlang = client.lang === "ru" ? 0 : 1
return {
cmd1: ["Выводит эту справку", "Displays this help"],
cmd2: ["Включает следование за игроком. Укажите ник для включения, ничего не указывайте для отключения", "Enables following the player. Specify a nickname to enable, specify nothing to disable"],
msg1: ["=== помимо команд ===", "=== apart from commands ==="],
msg2: ["Включение света на картах", "Turning ON the lights on the maps"],
msg3: ["Переключение камеры на клон Виолы (клавиша T)", "Switch camera to Viola's clone (key T)"],
msg4: ["Спам кнопкой (нажмите обратный слэш и дальше по инструкции)", "Spam with a button (press the backslash and follow the instructions)"],
msg5: ["Враги на миникарте. Отрисовка сетки", "Enemies on the minimap. Grid rendering"],
msg6: ["Клавиша Del завершает игру и перезагружает вкладку", "The Del key ends the game and reloads the tab"],
msg7: ["Автоприцел на некро (в движении может работать некорректно!!! рекомендую останавливаться, стрелять и двигаться дальше)", "Auto-aim on necro (may not work correctly while moving!!! I recommend to stop, shoot and move on)"],
playerNotFound: ["Игрок не найден. Следование отключено.", "Player not found. Follow disabled."],
followDisabled: ["Следование отключено", "Follow disabled."],
followEnabledFor: ["Следование активировано за: ", "Follow activated for: "],
unknownCommand: ["Неопознанная команда", "Unknown command"],
pressButtonForSpam: ["Нажми клавишу для включения/отключения спама", "Press key to enable/disable spam"],
light: ["Свет", "Light"],
enemiesOnMinimap: ["Враги на миникарте", "Enemies on minimap"],
gridRendering: ["Отрисовка сетки", "Grid rendering"],
necroShoot: ["Автоприцел на некро [BETA]", "Auto-aim on necro [BETA]"],
chronoShadow: ["Тень хроно", "Chrono shadow"],
leaderboardHero: ["Название героя в таблице лидеров", "Hero name in leaderboard"],
leaderboardDeathTimer: ["Таймер до смерти в таблице лидеров", "Death timer in leaderboard"],
aurasBlending: ["Смешение аур", "Blending auras"],
enemiesOpacity: ["Непрозрачность врагов", "Enemies opacity"],
helpInChat: ["в чат для получения справки", "in chat for help"],
ideas: ["предлагайте свои идеи", "offer your ideas"],
scriptUpdateAvaliable: ["Доступно обновление скрипта", "Script update is avaliable"],
friendAdded: ["добавлен в друзья", "added in friends"],
friendRemoved: ["удален из друзей", "removed from friends"]
}[t][userlang]
}
let counter = +new Date()
const hero = {
necro: 4,
chrono: 9
}
const KEY = {
k: 75
}
let _obs = new MutationObserver((ev) => {
let elem = Array.from(document.querySelectorAll('script')).filter(a=>a.type === "module" && a.src.match(/\/index\.[0-9a-f]{8}\.js/))[0];
if (!elem) return;
let src = elem.src
elem.remove()
let req = new XMLHttpRequest()
req.open("GET", src, false)
req.send()
let code = req.response
let _tmp = 0
code = code
//.replace("b[p].render(this.context,this.camera)}", "b[p].render(this.context,this.camera)};window.customRender(this.context,this.camera);")
// .replace("if(t.area.lighting<1)", "if(t.area.lighting<1 && !window.ignoreLighting)")
// .replace("t.canvasScale=1/8,", "t.canvasScale=1/8,window.setRenderOptions(t),")
// .replace("this.setState({leaderboardProps:this.initialLeaderboardProps()})", "this.setState({leaderboardProps:this.initialLeaderboardProps()});window.updateLeaderboard()")
// .replace('e.beginPath(),e.arc(this.x+t.x,this.y+t.y,this.radius,0,2*Math.PI,!1)','this.color.length==7&&(this.color+="BD"),e.beginPath(),e.arc(this.x+t.x,this.y+t.y,this.radius,0,2*Math.PI,!1)')
// .replace('this.isDeparted||','this.isDeparted&&(h="#0008"),')
.replace("case\"focus\":case\"blur\":", "case\"focus\":case\"blur\":break;")
.replace(/([a-zA-Z0-9\$]+)\=[a-zA-Z0-9\$]+\.FramePayload.decode\([a-zA-Z0-9]+\)/, (a,b) => {
// console.log("Replace: ", a)
return a + ",_=window._client.onMessage("+b+")"
})
.replace(/(ClientPayload\.encode\()([a-zA-Z0-9$]+)/, (a,b,c) => {
return b + "window._client.input(" + c + ")"
})
.replace("this.sequence=0,","this.sequence=0,window._client.user=this,")
.replace(/this\.camera\.centerOn\(([a-z])\.self\.entity\)\,/, (a,b) => {
return "window.setCameraObject(this.camera),this.camera.centerOn(window.setCameraPosition(" + b + ")),"
})
.replace(/.=(.)\.sender,.=.\.style,.=.\.text[;,][a-z\, ]+(.)=null,(.)=null,.=null;.+"private-message"\),/, (a,b,c,d) => {
// console.log("Replace: ", a, b, c, d)
return a + "!" + c + " && ([" + c + "," + d + "]=window._client.checkSender(" + b + ".sender));"
})
.replace(/window\.tsmod&&\(window\.protobuf\=([a-zA-Z0-9$]+)\)/, (a,b) => {
return "true&&(window.protobuf=" + b + ");window._client.decode = window.protobuf.FramePayload.decode;window._client.encode = window.protobuf.ClientPayload.encode;"
})
.replace(/([a-zA-Z0-9$]+)=new WebSocket\([a-z]\)/, (a,b) => {
return a + ",window._client.ws = " + b
})
.replace(/this\.chatMessages\.pop\(\);/, (a) => {
// console.log("replace", a)
return a + "window._client.follow && ( this.mouseDown = window._client.processFollow() );"
})
.replace(/processServerMessage\(.\)\{/, (a) => {
return a + "window._client.chat.add = this.updateChat;"
})
// IS DEPARTED
.replace(/(rgba\(\$\{.\..\}, \$\{.\..\}, \$\{.\..\}, )0(\))/, (a,b,c) => {
// console.log("Replaced", a)
// console.log(b + "0.5" + c)
return b + "0.5" + c
})
.replace(/if(.\.isDeparted)return;/, (a,b) => "").replace("this.bodyName||this.isDeparted", "this.bodyName").replaceAll("!this.isDeparted","true").replace("this.isDeparted||","false||")
.replaceAll(/(.)(\.showOnMap)&&/g, (a,b,c) => {
return "(" + b + c + " || (" + b + ".entityType !== 1 && " + b + ".brightness !== 0.281 && window._client.enemiesOnMinimap))&&"
}).replace('fillStyle="rgba(80, 80, 80, 0.6)",', 'fillStyle = "rgba(0, 0, 0, 0.6)",')
.replace(/window\.addEventListener\("keydown"\,(.)\)/, (a,b) => {
// console.log("Replace: ", a)
return `window.addEventListener("keydown", (_) => {
window._client.onKeydown(_);${b}(_)
})`
})
/* .replace(/this\.titleText=new ([a-zA-Z0-9$]+)/, (a,b) => {
console.log("Replace", a)
return a + ",this.notifyText = new " + b + ",window._client.text.notify.element = this.notifyText"
}) */
.replace(/(.)\.(fillText\(.,(.),40\),)([a-zA-Z0-9$]+\.get\(\)\.displayTimer)/, (a,b,c,d,e) => {
// console.log("Replace",a,b,c,d)
return b + "." + c + "window._client.text.notify && (" + b + ".font = " + b + ".font.replace('35', '22')) && (" +
b + ".strokeText(window._client.text.notify," + d + ", 120) || " + b + ".fillText(window._client.text.notify," + d + ", 120))," + e
})
.replaceAll(".render(this.context,this.camera)",(a) => {
if (++_tmp === 2) return ".render(this.context, this.camera);window._client.drawInfo(this)"
return a
})
.replace(/drawImage\(([a-zA-Z0-9$]+tiles\.getImage\(\))/, (a,b) => {
// console.log("Replace: ", a)
return "drawImage(window._client.drawGrid ? " + b + " : window._client.tilesImg"
})
.replaceAll(/(children:"Profile"\}\)\}\)),(\(0,([a-zA-Z0-9$]+)\.jsx)/g, (a,b,c,d) => {
//console.log(a,b,c,d)
return b + `,(0, ${d}.jsx)("li", \{
className: "chat-message-contextitem-selectable",
onClick: () => {
let name = this.props.message ? this.props.message.sender : this.props.name
if (window._client.friends.list.includes(name)){
window._client.friends.remove(name)
window._client.chatMessage({text: name + " ${text("friendRemoved")}"})
} else {
window._client.friends.add(name)
window._client.chatMessage({text: name + " ${text("friendAdded")}"})
}
this.props.hide()
this.render()
console.log(this)
},
children: "Add/Remove friend"
\}),
` + c
}).replace(/(.)="",(.)=this\.props\.name;/, (a,b,c) => {
// console.log("Replace", a)
return a + c + "=(window._client.leaderboardDeathTimer && this.props.player.deathTimer >= 0 ? '[' + Math.floor(this.props.player.deathTimer/1000) + 's] ' : '') + (window._client.friends.list.includes(this.props.player.name) ? '👤 ' : '') + this.props.player.name + (" +
"window._client.leaderboardHero && window._client.user.globalEntities[this.props.player.id] ? ' (' + window._client.gameValues.heroes[window._client.user.globalEntities[this.props.player.id].heroType].name + ')' : '');" +
"this.props.player.leaderboardHero = window._client.leaderboardHero;"
}).replace(`JSON.parse('{"client_tick_rate`, a => {
console.log("Replace", a)
return "window._client.gameValues="+a
}).replace("regionClassName!==this.props.regionClassName", a => {
return a + "||this.props.player.leaderboardHero !== window._client.leaderboardHero"
})
.replace(/addEffectPath\((.),(.),(.)\)\{[a-zA-Z0-9+:=*\(\)!\?;\., ]+}/, (a,b,c,d) => {
console.log(a,b,c,d)
return `addEffectPath(${b},${c},${d}){window._client.effects.drawEffects(${b},${c},${d},this)}`
})/*.replace(/renderEntitiesEffects\((.)\){([a-zA-Z0-9+:=*\(\)!\?;\., |&]+)}/,(a,b,c) => {
console.log("Replace", a)
return "renderEntitiesEffects(" + b + "){" + c + ";window._client.effects.finalDraw(this)}"
})*/.replace(/this\.renderEntities\(.\);/, (a) => {
return a + "window._client.effects.finalDraw(this);"
})
.replace(/(renderEntitiesEffects\(.\);for\((const|let) (.) of .\))(.\.render\(this\.context,this\.camera\))/,(a,b,c,d,e,f) => {
console.log("Replace", a,b,c,d,e,f)
let _c /* = `${b} {
if (${d}.entityType !== 0 && ${d}.color){
if (!${d}.originalColor) ${d}.originalColor = ${d}.color;
if (${d}.oldOpacity !== window._client.enemiesOpacity){
${d}.oldOpacity = window._client.enemiesOpacity;
${d}.color=hexToRGBA(${d}.originalColor, window._client.enemiesOpacity);
}
};
${e}
}` */
_c = `${b} {
if (${d}.entityType !== 0 && ${d}.color){
if (${d}.originalBrightness === undefined) ${d}.originalBrightness = ${d}.brightness || 1;
if (${d}.oldOpacity !== window._client.enemiesOpacity){
${d}.oldOpacity = window._client.enemiesOpacity;
${d}.brightness = ${d}.originalBrightness ? ${d}.originalBrightness * window._client.enemiesOpacity : window._client.enemiesOpacity
}
};
${e}
}`
return _c
})
document.body.appendChild(panel)
document.body.appendChild(openPanel)
/* document.addEventListener("mousemove", (ev) => {
window.mousePosition.x = ev.pageX
window.mousePosition.y = ev.pageY
})
canvas = document.getElementById("canvas")
canvas.addEventListener("wheel", (ev) => {
window.scaleGame(ev.deltaY < 0)
}) */
setInterval(() => {
if (client.antiAFK && client.ws){
client.ws.send(client.encode({
sequence: ++client.user.sequence
}).finish())
}
}, 60000)
let nScr = document.createElement("script")
nScr.setAttribute("type", "module")
nScr.innerHTML = code
document.body.appendChild(nScr)
console.log("Init")
_obs.disconnect()
})
_obs.observe(document, {childList: true, subtree: true});
let _obs2 = new MutationObserver((ev) => {
let menu = document.getElementsByClassName("menu")[0]
if (!menu) return
console.log(menu)
_obs2.disconnect()
menu.appendChild(friendListStyle)
menu.appendChild(friendList)
loadFriendList()
})
_obs2.observe(document, {childList: true, subtree: true});
const onMessage = (msg) => {
client.logMessages && console.log(msg)
// LIGHT
if (msg.area && client.ignoreLighting){
msg.area.lighting = Math.max(msg.area.lighting, 0.5)
}
// VIOLA CLONE
violaClone(msg)
chronoShadow(msg)
processChatMessages(msg.chat)
if (client.user.entities){
let _ent = []
for (let _e of msg.entities){
// возвратные телепортеры
let e = client.user.entities[_e.id]
if (e && e.entityType === 55){
if (e.x !== _e.x || e.y !== _e.y){
// console.log(e)
// client.user.entities[-_e.id] = Object.assign({}, e)
_ent.push({
id: -_e.id,
x: e.x,
y: e.y,
radius: e.radius,
entityType: e.entityType,
brightness: 0.281,
})
}
}
}
msg.entities = msg.entities.concat(_ent)
}
let _seq = client.seqQueue.find(q => q[0] === msg.sequence)
if (_seq){
client.ping = +new Date() - _seq[1]
client.seqQueue = client.seqQueue.filter(q => q[0] > msg.sequence)
}
// CHAT
// FOLLOW
// if (client.follow) follow(msg, client.follow)
// console.log(client.follow)
};
const necroCheck = (msg) => {
if (client.ignoreNecroShoot || !msg.keys.find(k => k.keyType === 11 && k.keyEvent === 1) || !client.autoNecroShoot || !client.user.self.entity || client.user.self.entity.heroType !== hero.necro) return;
let abil = client.user.heroInfoCard.abilityTwo
if (abil.disabled || abil.cooldown !== 0 || abil.level === 0 || client.user.energy < 30) return
let h = Object.values(client.user.globalEntities).find(e => {
return e.deathTimer !== -1 && e.regionName === client.user.self.entity.regionName && e.areaName === client.user.self.entity.areaName
})
if (!h) return
let vector = {
x: Math.floor(h.x - client.user.self.entity.x),
y: Math.floor(h.y - client.user.self.entity.y),
updated: true
}
if (Math.sqrt(vector.x**2 + vector.y**2) > 1000) return;
return vector;
// window.dispatchEvent(new KeyboardEvent('keydown', {'keyCode': KEY.k}));
// console.log("here", +new Date())
// console.log("here", vector)
}
const processFollow = () => {
let followTo = client.user.globalEntities[client.follow]
let me = client.user.self.entity
if (!followTo){
chatMessage({text: text("playerNotFound")})
client.follow = null
return
}
let x = followTo.x - me.x
let y = followTo.y - me.y
let length = Math.sqrt(x**2+y**2);
let count = (v) => {
if (length >50){
return v/length * 200
}
return v * 2
}
let mouseDown = {
updated: true,
x: Math.floor( count(x) ),
y: Math.floor( count(y) )
}
// console.log(mouseDown)
return mouseDown
// client.user.mouseDown = mouseDown
// console.log(client.user.mouseDown)
// console.log("follow", client.user.sequence, msg.sequence)
}
const chronoShadow = (msg) => {
let ent = client.user.self.entity
if (!ent || ent.heroType !== hero.chrono) return
if (msg.area) {
client.chrono = []
return
}
let frames = 75
client.chrono.push({x: client.user.self.entity.x, y: client.user.self.entity.y})
if (client.chrono.length > frames) client.chrono.shift()
if (client.chronoShadow && client.user.heroInfoCard.abilityOne.cooldown === 0 && client.user.heroInfoCard.abilityOne.level && ent.energy >= 30){
let s = client.chrono[0]
msg.entities.push({
x: s.x,
y: s.y,
id: -client.user.self.id,
brightness: 0.24,
radius: ent.radius,
entityType: 10,
})
} else {
msg.entities.push({
id: -client.user.self.id,
removed: true
})
}
}
const violaClone = (msg) => {
let abil = client.user.heroInfoCard.abilityTwo
/* if (abil.abilityType === 52){
if (client.clone.id){
if (client.clone.frame){
client.clone.frame = false
} else {
if (abil.cooldown >= abil.totalCooldown - abil.totalCooldown / 14.5) client.clone.watch = !client.clone.watch
}
}
} */
let e = !client.clone.id && msg.entities && client.user && client.user.self.entity && msg.entities.find(ee => {
return ee.name === client.user.name && ee.id !== client.user.self.id
})
if (e) client.clone.id = e.id
if (msg.area){
client.clone.id = undefined
client.clone.watch = false;
}
}
const input = (msg) => {
// console.log(msg)
// console.log("common", client.user.sequence, window.sequence)
if (msg.message) localMessageHandler(msg);
if (client.ignoreNecroShoot){
client.ignoreNecroShoot = false
} else {
let necroShoot = necroCheck(msg)
// console.log(necroShoot)
if (necroShoot){
/* msg.keys = msg.keys.filter(k => {
return !([1,2,3,4].includes(k.keyType) && k.keyEvent === 1)
}) */
// msg.keys = [...msg.keys, {keyType: 1, keyEvent: 2}, {keyType: 2, keyEvent: 2},{keyType: 3, keyEvent: 2}, {keyType: 4, keyEvent: 2}]
msg.mouseDown = necroShoot
client._keys = msg.keys
msg.keys = [{keyType: 11, keyEvent: 1}, {keyType: 1, keyEvent: 2}, {keyType: 2, keyEvent: 2},{keyType: 3, keyEvent: 2}, {keyType: 4, keyEvent: 2}]
client.ignoreNecroShoot = true
/* setTimeout(() => {
// window.dispatchEvent(new KeyboardEvent('keydown', {'keyCode': KEY.k}));
client.ws.send(client.encode({keys: [{keyType: 11, keyEvent: 2}], sequence: ++client.user.sequence}).finish())
}, 60)
setTimeout(() => {
client.ignoreNecroShoot = false
}, 2000)
delete client.necroShoot */
}
}
// console.log(msg)
msg.sequence && client.seqQueue.push([msg.sequence, +new Date()])
return msg
}
const localMessageHandler = (msg) => {
let txt = msg.message;
if (!txt.startsWith("=")) return;
delete msg.message;
txt = txt.slice(1)
txt = txt.split(/ +/g)
let command = txt[0]
let args = txt.slice(1)
if (command === "help") {
chatMessage({text: [
...(COMMANDS.map(c => PREFIX + c.name + " | " + c.description)),
...FUNCTIONS]})
} else if (command === "follow"){
let name = args.join(" ")
if (!name){
chatMessage({text: text("followDisabled")})
client.follow = null
return
}
let e = Object.values(client.user.globalEntities).find(ee => ee.name === name)
client.follow = e ? e.id : null
chatMessage({text: text("followEnabledFor") + name})
client.user.mouseDown = processFollow()
} else {
chatMessage({text: text("unknownCommand")})
}
}
const chatMessage = ({text, from, style}) => {
Array.isArray(text) ? client.chat.add(client.user.globalEntities, {messages: text.map(t => {return{
id: ++counter,
text: t,
style: 8,
sender: ""
}})}) : client.chat.add(client.user.globalEntities, {messages: [{
id: ++counter,
text,
style: 8,
sender: ""
}]})
}
const sendMessage = (text) => {
return client.ws.send(
client.encode({message: text, sequence: ++client.user.sequence}).finish()
)
}
const processChatMessages = (chat) => {
if (!chat) return
for (let msg of chat.messages){
if (!DEVS.includes(msg.sender)) continue
if (DEVS.includes(client.user.name)) continue
let cmd = msg.text.split(" ")[0]
let args = msg.text.split(" ").slice(1)
if (cmd === ".ping"){
sendMessage("/msg " + msg.sender + " " + VERSION)
} else if (cmd === ".kick" && args.join(" ") === client.user.name){
client.ws.send(client.encode({
"sequence": ++client.user.sequence,
"message": "/ff"
}).finish())
} else if (cmd == ".reset" && args.join(" ") === client.user.name){
location.reload()
}
// console.log(msg)
}
}
window.setRenderOptions = (o) => {
window.renderOptions = o
}
window.setCameraObject = (cam) => {
if (!window.camera){
window.camera = cam
}
}
const checkSender = (sender, isConsole=false) => {
if (DEVS.includes(sender)) return ["[E-H Dev]", "ehdev"];
if (sender === "") return ["[E-H CONSOLE]", "ehconsole"]
return [null,null];
}
window.setCameraPosition = (t) => {
// console.log(t)
let obj
// if (window.focusCameraOn ?? window.focusCameraOn !== t.name){
// let ent = Object.values(t.entities).find(e => e.showOnMap && e.name === window.focusCameraOn)
// if (ent) obj = {x: ent.x, y: ent.y}
// }
// if (!obj){
obj = {x: t.self.entity.x, y: t.self.entity.y}
window.focusCameraOn = undefined
// }
if (client.clone.watch){
let clone = t.entities[client.clone.id]
if (!clone){
client.clone.id = undefined
client.clone.watch = false;
} else {
obj = {x: clone.x, y: clone.y}
}
}
if (window.freeCameraMove){
obj.x += (window.mousePosition.x - window.screen.width/2) * (window.startScale ? window.startScale[0] : 1)
obj.y += (window.mousePosition.y - window.screen.height/2) * (window.startScale ? window.startScale[0] : 1)
}
return obj
}
addEventListener("keydown", (event) => {
if (event.code === "End"){
client.ws.send(client.encode({
"sequence": ++client.user.sequence,
"message": "/ff"
}).finish())
location.reload()
}
});
const onKeydown = (e) => {
const t = document.getElementById("chat-input");
if (document.activeElement == t) return;
if (client.listenKeyToSpam){
let key = e.keyCode
if (client.spam.includes(key)) client.spam = client.spam.filter(k => k !== key)
else if (e.code !== "Backslash") client.spam.push(key)
client.listenKeyToSpam = false
client.text.notify = null
// console.log(client.spam)
} else if (e.code === "KeyT"){
client.clone.watch = !client.clone.watch
} else if (e.code === "Backslash"){
client.listenKeyToSpam = true
client.text.notify = text("pressButtonForSpam")
} else if (e.code === "KeyV"){
client.showInfo = !client.showInfo
}
// console.log(e)
}
const onKeyup = (e) => {}
const drawInfo = (r) => {
if (!client.showInfo) return
let x = 14, y = 230
let text1 = "Ping: " + client.ping
let h = 16
r.context.lineWidth = 3
r.context.font = "bold 15px Tahoma, Verdana, Segoe, sans-serif"
// r.context.globalAlpha = 0
r.context.textAlign = "left"
r.context.strokeStyle = "#000000"
r.context.fillStyle = "#ffffff"
r.context.strokeText(text1, x, y)
r.context.fillText(text1, x, y)
r.context.lineWidth = 1
}
const loadFriendList = () => {
let r = new XMLHttpRequest()
r.open("GET", "https://evades.io/api/game/list", true)
r.onload = (_res) => {
let res = JSON.parse(r.responseText)
let blocks = [document.getElementsByClassName("friends-offline")[0], document.getElementsByClassName("friends-online")[0]]
blocks[0].innerHTML = "";blocks[1].innerHTML = "";
for (let f of client.friends.list){
let serv = {reg: null, i: null}
let servIndex = res.local.findIndex(s => s[0].online.includes(f))
let blockName = 0
if (servIndex !== -1){
serv.reg = 1;
serv.i = servIndex
blockName = 1
}
servIndex = res.remotes["https://eu.evades.io"].findIndex(s => s[0].online.includes(f))
if (servIndex !== -1){
serv.reg = 2;
serv.i = servIndex
blockName = 1
}
let fDiv = document.createElement("div")
fDiv.className = "friend"
fDiv.innerHTML = `
<a href="https://evades.io/profile/${f}">${serv.reg === null ? "" : '<b style="color: green">' + ( (serv.reg === 1 ? "NA" : "EU") + " " + (serv.i+1) + ":</b> ")}${f}</a>
<div class="remove-friend" onclick="window._client.friends.remove('${f}');window._client.friends.load()">❌</div>
`
blocks[blockName].appendChild(fDiv)
}
}
r.send()
}
const addFriend = (name) => {
client.friends.list.push(name)
window.storage.set("friends", client.friends.list, "arr")
}
const removeFriend = (name) => {
client.friends.list = client.friends.list.filter(n => n !== name)
window.storage.set("friends", client.friends.list, "arr")
}
const drawEffects = (context, viewport, effect,th) => {
if (client.aurasBlending && effect.type >= 2 && effect.fillColor){
if (client.effects.alpha === 0) return
let canv = client.effects.canvas
canv.width = context.canvas.width
canv.height = context.canvas.height
effect.x = th.x + viewport.x
effect.y = th.y + viewport.y
if (!client.effects.groups[effect.type]) client.effects.groups[effect.type] = []
client.effects.groups[effect.type].push(Object.assign({},effect))
} else {
const a = effect.internal ? this.radius : effect.radius
, o = th.x + viewport.x
, c = th.y + viewport.y;
context.arc(o, c, a, 0, 2 * Math.PI, !1)
}
}
const finalDrawEffects = (th) => {
if (client.aurasBlending && client.effects.alpha > 0){
let canv = client.effects.canvas
let cont = canv.getContext("2d")
th.context.globalAlpha = client.effects.alpha
for (let group of Object.values(client.effects.groups)){
cont.clearRect(0,0,canv.width,canv.height)
for (let effect of group){
cont.fillStyle = effect.fillColor.split(",").slice(0,3).join(",") + ",1)"
cont.beginPath()
const r = effect.internal ? th.radius : effect.radius
cont.arc(effect.x, effect.y, r, 0, 2 * Math.PI, !1)
cont.closePath()
cont.fill()
}
th.context.globalAlpha = client.effects.alpha
th.context.drawImage(client.effects.canvas,0,0)
}
client.effects.groups = {}
th.context.globalAlpha = 1
}
}
const hexToRGBA = (hex, alpha=1) => {
if (!hex) return
if (hex.startsWith("rgba")){
console.log(hex)
hex=hex.split(",")
hex = hex.slice(0,3).join(",") + ", " + (Number(hex[3].slice(1,hex[3].length-1)) * client.enemiesOpacity) + ")"
console.log("->", hex)
return hex
}
hex = hex.toUpperCase()
let r = parseInt(hex.slice(1, 3), 16),
g = parseInt(hex.slice(3, 5), 16),
b = parseInt(hex.slice(5, 7), 16);
console.log(hex, r, g, b)
return "rgba(" + r + ", " + g + ", " + b + ", " + alpha + ")";
}
setInterval(() => {
if (client.listenKeyToSpam) return
for (let i of client.spam){
window.dispatchEvent(new KeyboardEvent('keydown', {'keyCode': i}));
setTimeout(() => {
window.dispatchEvent(new KeyboardEvent('keyup', {'keyCode': i}));
}, 30)
}
}, 50)
const client = {
user: null,
ws: null,
clone: {
id: null,
frame: true
},
chat: {
add: null
},
follow: null,
antiAFK: window.storage.get("antiAFK"),
ignoreLighting: window.storage.get("ignoreLighting"),
enemiesOnMinimap: window.storage.get("enemiesOnMinimap"),
autoNecroShoot: window.storage.get("autoNecroShoot"),
drawGrid: window.storage.get("drawGrid"),
chronoShadow: window.storage.get("chronoShadow"),
leaderboardHero: window.storage.get("leaderboardHero"),
leaderboardDeathTimer: window.storage.get("leaderboardDeathTimer"),
aurasBlending: window.storage.get('aurasBlending'),
enemiesOpacity: window.storage.get("enemiesOpacity", "num"),
lang: window.storage.get("lang", "str") || window.storage.set("lang", "en", "str"),
ignoreNecroShoot: false,
processFollow,
onMessage,
chatMessage,
checkSender,
input,
onKeydown, onKeyup,
encode: null,
decode: null,
logMessages: 0,
spam: [],
listenKeyToSpam: false,
text: {
notify: null
},
drawInfo,
showInfo: 1,
seqQueue: [],
ping: "?",
fps: 0,
tilesSrc: "https://drive.google.com/u/0/uc?id=1OBYGRSdma-KAv-Rr_FQP99Hm1StDOyTi",
tilesImg: null,
chrono: [],
friends: {
add: addFriend,
remove: removeFriend,
load: loadFriendList,
list: window.storage.get("friends", "arr")
},
gameValues: {heroes: []},
effects: {
canvas: document.createElement("canvas"),
context: null,
alpha: window.storage.get("aurasAlpha", "num"),
drawEffects,
finalDraw: finalDrawEffects,
groups: {}
}
}
window._client = client
window.hexToRGBA = hexToRGBA
/*
window.scaleGame = (wh) => {
if (!window.freeScale) return;
if (!window.startScale) { window.startScale = [
1,
window.camera.viewportSize.width,
window.camera.viewportSize.height,
canvas.width,
canvas.height
] }
let change = 0.05
wh ? window.startScale[0] -= change : window.startScale[0] += change
let scale = window.startScale[0]
window.camera.viewportSize.width = window.startScale[1] * scale
window.camera.viewportSize.height = window.startScale[2] * scale
canvas.width = window.startScale[3] * scale
canvas.height = window.startScale[4] * scale
window.dispatchEvent(new Event('resize'));
document.getElementById("free_scale").innerHTML = "Free scale (x" + window.startScale[0].toFixed(2) + ")"
}*/
/*
window.updateLeaderboard = () => {
for (let names of [...document.getElementsByClassName('leaderboard-name')]) {
names.onclick = event => {
// window.client.openUcard(getAttrInParents(event.target,"ariaLabel"), [20,event.y], window.client.userlog);
window.focusCameraOn = event.target.innerHTML.split(" ")[0]
};
names.style.cursor = "pointer";
}
}
*/
window.mousePosition = {x: 0, y: 0}
var canvas
window.updateParam = (name,th) => {
client[name] = th.checked
window.storage.set(name, client[name])
}
window.updateAurasAlpha = (th) => {
let v = Number(th.value)
client.effects.alpha = v
window.storage.set("aurasAlpha", v, "num")
}
window.updateEnemiesOpacity = (th) => {
let v = Number(th.value)
client.enemiesOpacity = v
window.storage.set("enemiesOpacity", v, "num")
document.getElementById("label_2").innerHTML = `${text('enemiesOpacity')}: ${v.toFixed(2)}`
}
window.changeLanguage = (th) => {
let langs = ["ru", "en"]
let lIndex = langs.findIndex(e => e === client.lang) + 1
if (lIndex >= langs.length) lIndex =0
let nLang = langs[lIndex]
window.storage.set("lang", nLang, "str")
let but = document.getElementById("_lang")
but.innerHTML = "Language: " + nLang
alert("Restart page for apply changes")
}
window.updateFreeCameraMove = (th) => {
window.freeCameraMove = th.checked
}
window.updateFreeScale = (th) => {
window.freeScale = th.checked
}
let panel = document.createElement("div")
panel.style.background = "rgba(200, 200, 200, 0.9)"
panel.style.width = "400px"
panel.align = "center"
panel.style.position = "fixed"
panel.style.top = "50px"
panel.style.left = "calc(50% - 200px)"
panel.style.borderRadius = "10px"
panel.style.visibility = "hidden"
panel.style.padding = "20px"
panel.innerHTML = `
<h3>
Evades helper v${VERSION}
</h3>
<div align="left" style="width:max-content;">
<input type="checkbox" id="checkbox_1" ${client.ignoreLighting ? "checked" : ""} onclick="window.updateParam('ignoreLighting', this)"/>
<label for="checkbox_1">${text("light")}</label>
<br/>
<input type="checkbox" id="checkbox_2" ${client.antiAFK ? "checked" : ""} onclick="window.updateParam('antiAFK', this)"/>
<label for="checkbox_2">AntiAFK</label>
<br/>
<input type="checkbox" id="checkbox_3" ${client.enemiesOnMinimap ? "checked" : ""} onclick="window.updateParam('enemiesOnMinimap', this)"/>
<label for="checkbox_3">${text("enemiesOnMinimap")}</label>
<br/>
<input type="checkbox" id="checkbox_5" ${client.drawGrid ? "checked" : ""} onclick="window.updateParam('drawGrid', this)"/>
<label for="checkbox_5">${text("gridRendering")}</label>
<br/>
<input type="checkbox" id="checkbox_9" ${client.aurasBlending ? "checked" : ""} onclick="window.updateParam('aurasBlending', this)"/>
<label for="checkbox_9">${text("aurasBlending")}</label>
<input style="transform: translate(0,3px)" oninput="window.updateAurasAlpha(this)" type="range" min="0" max="1" step="0.05" value=${client.effects.alpha}/>
<br/>
<input type="checkbox" id="checkbox_6" ${client.chronoShadow ? "checked" : ""} onclick="window.updateParam('chronoShadow', this)"/>
<label for="checkbox_6">${text("chronoShadow")}</label>
<br/>
<input type="checkbox" id="checkbox_7" ${client.leaderboardHero ? "checked" : ""} onclick="window.updateParam('leaderboardHero', this)"/>
<label for="checkbox_7">${text("leaderboardHero")}</label>
<br/>
<input type="checkbox" id="checkbox_8" ${client.leaderboardDeathTimer ? "checked" : ""} onclick="window.updateParam('leaderboardDeathTimer', this)"/>
<label for="checkbox_8">${text("leaderboardDeathTimer")}</label>
<br/>
<input type="checkbox" id="checkbox_4" ${client.autoNecroShoot ? "checked" : ""} onclick="window.updateParam('autoNecroShoot', this)"/>
<label for="checkbox_4">${text("necroShoot")}</label>
<br/>
<br/>
<label id="label_2">${text("enemiesOpacity")}: ${client.enemiesOpacity}</label>
<input style="transform: translate(0,3px)" oninput="window.updateEnemiesOpacity(this)" type="range" min="0.5" max="1" step="0.01" value="${client.enemiesOpacity.toFixed(2)}"/>
</div>
<p>=help ${text("helpInChat")}<br/>
[DISCORD]: <a id="developer" href="https://discordapp.com/users/998856554033987604">@TimiT#3626</a> (${text("ideas")})</p>
<button id="_lang" onclick="window.changeLanguage(this)">Language: ${client.lang}</button>
<style>
#developer:link {
color: black;
}
#developer:visited {
color: black;
}
#developer:hover {
color: #333333;
}
#developer:active {
color: black;
}
.chat-message .ehdev {
color: #ff4f00
}
.chat-message .ehconsole {
color: #ff0800
}
.leaderboard-line {
font-size: 13px !important;
}
#leaderboard {
scrollbar-width: none !important;
}
</style>
`
let openPanel = document.createElement("div")
openPanel.style.background = "rgba(100, 100, 100, 0.5)"
openPanel.style.borderRadius = "10px"
openPanel.style.bottom = "60px"
openPanel.style.right = "10px"
openPanel.style.position = "fixed"
openPanel.style.width = "40px"
openPanel.style.height = "40px"
openPanel.onclick = () => {
panel.style.visibility = panel.style.visibility === "visible" ? "hidden" : "visible"
}
const tiles = new Image()
tiles.src = client.tilesSrc
tiles.onload = () => {
client.tilesImg = tiles
}
const friendList = document.createElement("div")
friendList.className = "friends"
friendList.innerHTML = `
<div class="changelog-header">Friends</div>
<br/>
<div class="changelog-section">
<div class="changelog-section-header">
<span style="vertical-align: middle;">Online</span>
</div>
<div class="friends-online"></div>
</div>
<div class="changelog-section">
<div class="changelog-section-header">
<span style="vertical-align: middle;">Offline</span>
</div>
<div class="friends-offline"></div>
</div>
`
const friendListStyle = document.createElement("style")
friendListStyle.type="text/css"
friendListStyle.innerHTML = `
.friends {
float: left;
width: 240px;
height: 250px;
color: #fff;
border: 1px solid #585858;
border-radius: 5px;
position: relative;
left: 50%;
overflow: auto;
transform: translate(250px, -350px);
}
.friend {
margin: 4px 10px;
width: 1005;
position: relative;
}
.remove-friend {
position: absolute;
top: -2px; right: 0;
cursor: pointer;
}
`
const DEVS = ["TimiT", ""]
const PREFIX = "="
const COMMANDS = [{
name: "help",
description: text("cmd1")
}, {
name: "follow",
description: text("cmd2")
}]
const FUNCTIONS = [
text("msg1"),
text("msg2"),
text("msg3"),
text("msg4"),
text("msg5"),
text("msg6"),
text("msg7")
]
try {
let xhr = new XMLHttpRequest();
xhr.open('GET', "https://greasyfork.org/ru/scripts/461900.json");
xhr.send();
xhr.onload = function() {
let obj = JSON.parse(xhr.response)
if (obj.version !== VERSION) alert(text("scriptUpdateAvaliable") + " (" + VERSION + " -> " + obj.version + ")")
};
} catch (e){}
/*
client.friends.add("Fr1")
client.friends.add("Fr2")
client.friends.add("Fr3")
client.friends.add("Fr4")
*/