// ==UserScript==
// @name Gats.io - Vaakir's hack pack GUI V4
// @namespace http://tampermonkey.net/
// @version 4.8
// @description The almighty one
// @author PureVaakir (88%) & Freehuntx (12%)
// @match https://gats.io/
// @grant none
// ==/UserScript==
class GUI {
constructor(parent) {
this.parent = parent;
this.init();
}
init() {
this.gui = GUI.createCustomElement('div', this.parent, '', '', '', 'myFUNNYGUY');
this.guiHead = GUI.createCustomElement('div', this.gui, 'Vaakir Hack pack V4.6', '', 'headDiv', '');
// Drag functionality on (gui head div)
let offsetX, offsetY, isDragging = false, gui = this.gui;
this.guiHead.addEventListener('mousedown', function(event) {
isDragging = true;
offsetX = event.clientX - gui.getBoundingClientRect().left;
offsetY = event.clientY - gui.getBoundingClientRect().top;
});
document.addEventListener('mousemove', function(event) {
if (isDragging) {
const newLeft = event.clientX - offsetX;
const newTop = event.clientY - offsetY;
gui.style.left = newLeft + 'px';
gui.style.top = newTop + 'px';
}
});
document.addEventListener('mouseup', function() {
isDragging = false;
});
let styleSheet = document.createElement('style');
let css = `
.myFUNNYGUY {
--name-width: 100px;
--gui-width: 245px;
--row-height: 30px;
--elm-height: 20px;
--inp-width: 80px;
--bg-color: rgba(85, 85, 85, 0.5);
-webkit-touch-callout: none; /* iOS Safari */
-webkit-user-select: none; /* Safari */
-khtml-user-select: none; /* Konqueror HTML */
-moz-user-select: none; /* Old versions of Firefox */
-ms-user-select: none; /* Internet Explorer/Edge */
user-select: none; /* Non-prefixed version, currently supported by Chrome, Edge, Opera and Firefox */
background-color: var(--bg-color);
position: fixed;
top: 25vh;
z-index: 9999;
width: 245px;
padding-bottom: 10px;
font-size: var(--elm-height);
font-weight: bold;
font-family: Orbitron;
color: white;
}
.myFUNNYGUY #headDiv {
cursor: grab;
text-align: center;
height: var(--row-height);
}
.myFUNNNYGUY .myBox {
width: var(--gui-width);
padding: 0px;
margin: 0;
}
.myFUNNYGUY .title {
display: inline-block;
cursor: pointer;
transition: max-height 0.3s ease-in-out;
width: 100%;
max-height: 2em;
border-bottom: 1px solid black;
}
.myFUNNYGUY .title:before {
content: '▾';
display: inline-block;
transition: transform 0.3s ease-in-out;
}
.myFUNNYGUY .title.closed:before {
content: '▸';
}
.myFUNNYGUY .row {
display: flex;
flex-direction: row;
align-items: center;
margin-left: 10px;
height: var(--elm-height);
}
.myFUNNYGUY .label {
width: var(--name-width);
line-height: var(--elm-height);
text-overflow: clip;
text-align: left;
margin-right: 10px;
padding: 0;
margin: 0;
font-size: large;
}
.myFUNNYGUY .subOptionOpen {
vertical-align: top;
overflow: hidden;
transition: max-height 0.3s ease-in-out;
}
.myFUNNYGUY .subOptionClosed {
vertical-align: top;
max-height: 0;
overflow: hidden;
transition: max-height 0.3s ease-in-out;
}
.myFUNNYGUY input {
margin-top: auto;
margin-bottom: auto;
}
.myFUNNYGUY .select,
.myFUNNYGUY .button,
.myFUNNYGUY .inputColor,
.myFUNNYGUY input {
color: black;
}
.myFUNNYGUY input[type=checkbox] { margin: 0; outline: none; height: var(--elm-height); width: var(--elm-height);}
.myFUNNYGUY input:hover { cursor: pointer;}
.myFUNNYGUY input:focus { box-shadow: 0 0 10px #9ecaed;}
.myFUNNYGUY input[type=radio] { border-top: auto; height: 20px;}
.myFUNNYGUY input[type=color] { width: 50px;}
.myFUNNYGUY .checked {
height: var(--elm-height);
width: var(--elm-height);
box-shadow: -1px -2px 5px gray;
border: 3px solid gray;
background-color: green;
margin-top: auto;
margin-bottom: auto;
box-shadow: 2 2 2px #a0a0a0;
}
.subOptionOpen .input,
.subOptionOpen .inputText,
.subOptionOpen .select {
width: var(--inp-width);
height: var(--elm-height);
}
.myFUNNYGUY .select {
font-size: calc(var(--elm-height) * 0.75);
}
.myFUNNYGUY .colGreen {
background-color: green;
}
.myFUNNYGUY .colRed {
background-color: red;
}
.myFUNNYGUY .button {
width: var(--elm-height);
height: var(--elm-height);
padding: 0;
margin: 0;
font-size: small;
}
.myFUNNYGUY .inputColor {
height: var(--elm-height);
font-size: small;
}
`;
styleSheet.innerText = css;
document.head.appendChild(styleSheet);
}
addMainFolder(name, id = '', className = '') {
return new Folder(this.gui, name, id, className);
}
static createCustomElement(HTMLTag, parent, innerTxt, type, id, className) {
let htmlTag = document.createElement(HTMLTag);
parent.appendChild(htmlTag);
if (innerTxt && type != "select") htmlTag.innerText = innerTxt;
if (type && type != "select") htmlTag.type = type;
if (id) htmlTag.id = id;
if (className) htmlTag.className = className;
if (type == "number") {
htmlTag.value = innerTxt;
} else if (type == "select") {
// innerTxt in this example is : ["a","b", ..]
for (let o of innerTxt) {
// console.log(o);
GUI.createCustomElement("option", htmlTag, o, "", "", "option")
}
}
return htmlTag;
}
}
class Folder {
constructor(parent, name, id, className, guiInstance) {
this.parent = parent;
this.name = name;
this.id = id;
this.className = className;
this.gui = guiInstance;
this.init();
}
init() {
let _this = this;
let container = GUI.createCustomElement('div', this.parent, '', '', '', 'myBox');
let button = GUI.createCustomElement('div', container, this.name, '', this.id, this.className);
let subOptions = GUI.createCustomElement('div', container, '', '', '', 'subOptionClosed');
this.subOptions = subOptions;
button.onclick = function() {
if (subOptions.className === 'subOptionOpen') { subOptions.className = 'subOptionClosed'; button.className = _this.className + ' closed'}
else if (subOptions.className === 'subOptionClosed') { subOptions.className = 'subOptionOpen'; button.className = _this.className + ' open'}
}
return subOptions;
}
addFolder(name, id = '', className = '', guiInstance) {
return new Folder(this.subOptions, name, id, className, guiInstance);
}
add(options, name, type = "checkbox", val = 32) {
// Each GUI row has a label and an input
let row = GUI.createCustomElement('div', this.subOptions, '', '', '', 'row');
let label = GUI.createCustomElement('label', row, name, '', '', 'label');
let input;
if (type == "checkbox") {
input = GUI.createCustomElement('input', row, '', type, '', 'input');
const updateCheckboxState = () => { input.checked = options[name]; };
const updateOptionsState = () => { options[name] = input.checked; };
updateCheckboxState();
input.addEventListener('change', () => { updateOptionsState(); opts.saveOptions(); });
options[name] = input.checked;
// Watch for changes in the options object and update the checkbox accordingly
Object.defineProperty(options, name, {
set(value) {
input.checked = value;
},
get() {
return input.checked;
},
});
}
else if (type == "number") {
input = GUI.createCustomElement('input', row, val, type, '', 'input');
const updateCheckboxState = () => { input.value = options[name]; };
const updateOptionsState = () => { options[name] = parseInt(input.value) || 32; };
updateCheckboxState();
input.addEventListener('change', () => {updateOptionsState(); opts.saveOptions();});
options[name] = parseInt(input.value) || 32;
// Watch for changes in the options object and update the checkbox accordingly
Object.defineProperty(options, name, {
set(value) {
input.value = value;
},
get() {
return parseInt(input.value) || 32;
},
});
} else if (type == "select") {
input = GUI.createCustomElement('select', row, val, type, '', 'select');
const updateCheckboxState = () => { input.value = options[name]; };
const updateOptionsState = () => { options[name] = input.value; };
updateCheckboxState();
input.addEventListener('change', () => { updateOptionsState(); opts.saveOptions();});
options[name] = input.value;
// Watch for changes in the options object and update the checkbox accordingly
Object.defineProperty(options, name, {
set(value) {
input.value = value;
},
get() {
return name=="allies" ? input : input.value;
},
});
if (name == "allies") {
let buttonAdd = GUI.createCustomElement('button', row, '+', '', '', 'button');
let buttonRemove = GUI.createCustomElement('button', row, '-', '', '', 'button');
buttonAdd.onclick = function() {
options.alliesList.push(input.value);
}
buttonRemove.onclick = function() {
options.alliesList = options.alliesList.filter(item => item !== input.value);
}
}
} else if (type == "input") {
input = GUI.createCustomElement('input', row, val, type, '', 'inputText');
// let buttonAdd = GUI.createCustomElement('button', row, '+', '', '', 'button');
// let buttonRemove = GUI.createCustomElement('button', row, '-', '', '', 'button');
input.onfocus = function() {
if (typeof j46 !== 'undefined') {
j46 = true; // disables movement in the game until other game input is recieved
}
}
input.onblur = function() {
if (typeof j46 !== 'undefined') {
j46 = false; // disables movement in the game until other game input is recieved
}
}
const updateCheckboxState = () => { input.value = options[name]; };
const updateOptionsState = () => { options[name] = input.value; };
updateCheckboxState();
input.addEventListener('change', () => { updateOptionsState(); opts.saveOptions();});
options[name] = input.value;
// Watch for changes in the options object and update the checkbox accordingly
Object.defineProperty(options, name, {
set(value) {
input.value = value;
},
get() {
return input.value;
},
});
// buttonAdd.onclick = function() {
// options.alliesList.push(input.value);
// }
// buttonRemove.onclick = function() {
// options.alliesList = options.alliesList.filter(item => item !== input.value);
// }
} else if (type == "color") {
input = GUI.createCustomElement('input', row, '', 'color', '', 'inputColor');
const updateCheckboxState = () => { input.value = options[name]; };
const updateOptionsState = () => { options[name] = input.value; opts.colorChange = true; };
updateCheckboxState();
input.addEventListener('change', () => { updateOptionsState(); opts.saveOptions(); });
options[name] = input.value;
// Watch for changes in the options object and update the checkbox accordingly
Object.defineProperty(options, name, {
set(value) {
input.value = value;
},
get() {
return input.value;
},
});
} else if (type == "button") {
let resetButton = GUI.createCustomElement('button', row, 'Reset', '', '', 'inputColor');
let randomButton = GUI.createCustomElement('button', row, 'Random', '', '', 'inputColor');
resetButton.onclick = function() {
window.longCrate[0][1][1][3] = opts.texturePack.longCrate = opts.defaultColors[1];
window.crate[0][1][1][3] = opts.texturePack.squareCrate = opts.defaultColors[0];
window.longCrate[0][0][1][3] = opts.texturePack.longCrateBorder = opts.defaultColors[2];
window.crate[0][0][1][3] = opts.texturePack.squareCrateBorder = opts.defaultColors[2];
opts.colorChange = true;
opts.saveOptions();
}
randomButton.onclick = function() {
window.longCrate[0][1][1][3] = opts.texturePack.longCrate = calc.rColor();
window.crate[0][1][1][3] = opts.texturePack.squareCrate = calc.rColor();
window.longCrate[0][0][1][3] = opts.texturePack.longCrateBorder = calc.rColor();
window.crate[0][0][1][3] = opts.texturePack.squareCrateBorder = calc.rColor();
opts.colorChange = true;
opts.saveOptions();
}
/*const updateCheckboxState = () => { input.value = options[name]; };
const updateOptionsState = () => { options[name] = input.value; opts.colorChange = true; };
updateCheckboxState();
input.addEventListener('change', () => { updateOptionsState(); opts.saveOptions(); });
options[name] = input.value;
// Watch for changes in the options object and update the checkbox accordingly
Object.defineProperty(options, name, {
set(value) {
input.value = value;
},
get() {
return input.value;
},
});*/
}
}
}
class calc {
static round_to(n, dec) {
return Math.round( n * (10**dec)) / (10**dec);
}
static multiply(vectorA, vectorB) {
return vectorA.x*vectorB.x + vectorA.y*vectorB.y;
}
static length(vector) {
return Math.sqrt(vector.x**2+vector.y**2);
}
static angle180(vectorA, vectorB) {
return Math.acos( calc.multiply(vectorA,vectorB) / (calc.length(vectorA)*calc.length(vectorB)) );
}
static angle360(vectorA, vectorB) {
// GETS THE ANGLE IN [0,360] DEGREES AND NOT JUST [0,180], WHICH IS PRETTY USEFULL..
let dot = vectorA.x * vectorB.x + vectorA.y * vectorB.y; //# dot product
let det = vectorA.x * vectorB.y - vectorA.y * vectorB.x; //# determinant
return Math.atan2(det, dot); //# atan2(y, x) or atan2(sin, cos)
}
static vectorAB(a,b) {
return {x: a.x - b.x, y: a.y - b.y}
}
static rotateVector(vector, angle) {
let v1 = [vector.x, vector.y];
let v2 = {x: 0,y: 0};
v2.x = v1[0] * Math.cos(angle) - v1[1]*Math.sin(angle);
v2.y = v1[0] * Math.sin(angle) + v1[1]*Math.cos(angle);
return v2;
}
static radiansToDegrees(piFraction) {
return (piFraction / Math.PI) * 180;
}
static collisionCheck(obstacles, t) {
let p = 20; // 1/2 of playerWidth..
// let maxChecks = Math.min(5, obstacles.length); // the walls should be somewhat sorted
for (let i = 0; i < obstacles.length; i++) {
let wall = obstacles[i];
// let TL = (wall.x1 < t.x && wall.y)
// let betweenX = (wall.x1 > t.x && t.x > wall.x2);
// let betweenY = (wall.y1 < t.y && t.y > wall.y2);
// if (betweenX && betweenY) return true;
// (wall.x1 > t.x && t.x > wall.x2)
// (wall.y1 > t.y && t.y > wall.y2)
if (t.x < (wall.x1 - p) || t.y < (wall.y1 - p) ) continue
if (t.x > (wall.x2 + p) || t.y > (wall.y2 + p) ) continue
return true;
//if (betweenX && betweenY) return true;
}
//const closestAcceptableDistance = 50**2;
//for (let i = 0; i < obstacles.length; i++) {
// const w = obstacles[i];
// const d1 = calc.distanceSquared(t, {x: w.x1, y: w.y1});
// const d2 = calc.distanceSquared(t, {x: w.x2, y: w.y1});
// const d3 = calc.distanceSquared(t, {x: w.x1, y: w.y2});
// const d4 = calc.distanceSquared(t, {x: w.x2, y: w.y2});
// const closestDistanceSquared = Math.min(d1,d2,d3,d4);
// if (closestDistanceSquared < closestAcceptableDistance) return true;
//}
return false;
}
static combine(vectorA, vectorB) {
return {x: vectorA.x + vectorB.x, y: vectorA.y + vectorB.y}
}
static distance(coor1, coor2) {
return Math.hypot(coor2.x - coor1.x, coor2.y - coor1.y);
};
static distanceSquared(coor1, coor2) {
// I was told sqrt is slow okay
return (coor2.x - coor1.x)**2 + (coor2.y - coor1.y)**2;
};
static entitiesDistance(entities, point) {
entities.forEach(e => {
e.distance = calc.distance(e, point)
});
}
static sortByDistance(entities, point) {
calc.entitiesDistance(entities, point);
entities.sort((a, b) => a.distance - b.distance);
};
static normalize(v, length) {
const currLength = calc.length(v);
const scaleRatio = length / currLength;
return {x: v.x * scaleRatio, y: v.y * scaleRatio }
}
static sortByDistanceFaster(entities, point) {
// I think it is faster, :eyes: laze, with e okay, just deal with it
entities.forEach(e => {
e.distanceSquared = calc.distanceSquared(e, point)
});
entities.sort((a, b) => a.distanceSquared - b.distanceSquared);
return entities;
}
static sortByDistanceFilter(entities, point, maxDistance) {
let remainingEnemies = [];
for (let i = 0; i < entities.length; i++) {
let e = entities[i];
e.distanceSquared = calc.distanceSquared(e, point);
if (e.distanceSquared <= maxDistance * maxDistance) remainingEnemies.push(e);
}
remainingEnemies.sort((a, b) => a.distanceSquared - b.distanceSquared); // may make it slower, (hence removed)
return remainingEnemies;
}
static collisionCoord(a,b) {
// let a = {x:2,y:6,dx:3,dy:-4}; // let a = {x:2,y:6,dx:3,dy:-4};
// let b = {x:0,y:-3,dx:2,dy:2}; // let b = {x:0,y:-3,dx:1,dy:1};
if (b.dx ==0) { b.dx = 0.0001; }
const s1 = (a.x-b.x)/b.dx;
const s2 = a.dx/b.dx;
const t = (a.y-b.y-b.dy*s1)/(-a.dy+b.dy*s2);
const s = (a.x+a.dx*t-b.x)/b.dx;
const x = a.x+a.dx*t;
const y = a.y+a.dy*t;
if (0 < s && s < 1 && 0 < t && t < 1) return {x: x, y: y};
return false;
}
static aheadNess(e, distance) {
return {
x: e.x + e.spdX * distance / (window.fac ?? options.aimbot.calibrate - GameInterface.currentPing/10), // ping part is under tests (not used)
y: e.y + e.spdY * distance / (window.fac ?? options.aimbot.calibrate - GameInterface.currentPing/10),
}
}
static gunToEnemy(player, enemy, distance, getGunLengthMultiplier = 1) {
const end = calc.aheadNess(enemy, distance);
const angle = Math.atan2(player.y - end.y, player.x - end.x) + Math.PI; // 0 - 6
const deltaX = Math.cos(angle - Math.PI / game.getGunOffset(player.class));
const deltaY = Math.sin(angle - Math.PI / game.getGunOffset(player.class));
const start = {
x: player.x + deltaX * game.getGunLength(player.class) * getGunLengthMultiplier,
y: player.y + deltaY * game.getGunLength(player.class) * getGunLengthMultiplier
}
return {start: start, end: end}
}
static lineCollidesWithWalls(gunLine, walls, ctx, doCollisionDrawing = options.aimbot.espCollisions) {
let visible = true;
let i = 0;
while (visible && i < walls.length) {
const w = walls[i];
let wallTop = {x: w.x1, y: w.y1, dx: w.width, dy: 0}
let wallBot = {x: w.x1, y: w.y2, dx: w.width, dy: 0}
let wallLef = {x: w.x1, y: w.y1, dx: 0, dy: w.height}
let wallRig = {x: w.x2, y: w.y1, dx: 0, dy: w.height}
let col1 = calc.collisionCoord(gunLine, wallTop);
let col2 = calc.collisionCoord(gunLine, wallBot);
let col3 = calc.collisionCoord(gunLine, wallLef);
let col4 = calc.collisionCoord(gunLine, wallRig);
if (col1 || col2 || col3 || col4) {
visible = false;
// Aimbot espCollisions
if (doCollisionDrawing) {
if (col1) { col1 = game.getScreenPos(col1); Draw.circle(ctx, col1.x, col1.y, 5, "red"); }
if (col2) { col2 = game.getScreenPos(col2); Draw.circle(ctx, col2.x, col2.y, 5, "red"); }
if (col3) { col3 = game.getScreenPos(col3); Draw.circle(ctx, col3.x, col3.y, 5, "red"); }
if (col4) { col4 = game.getScreenPos(col4); Draw.circle(ctx, col4.x, col4.y, 5, "red"); }
}
}
i++;
}
return visible;
}
// From vaakirhack v3
static rColor() {
return calc.rgbToHex(Math.floor(Math.random()*255),Math.floor(Math.random()*255),Math.floor(Math.random()*255));
}
static componentToHex(c) {
var hex = c.toString(16);
return hex.length == 1 ? "0" + hex : hex;
}
static rgbToHex(r, g, b) {
return "#" + calc.componentToHex(r) + calc.componentToHex(g) + calc.componentToHex(b);
}
}
const options = new class OptionsMenu {
aimbot = {
active: false,
alwaysAim: false,
calibrate: 30,
moveFrequency: 10,
autoShoot: true,
espLine: true,
espCollisions: true,
allies: "",
alliesList: ["[1337] PureVaakir","PureVaakir","Hacker0","VaakTradeBot"]
}
AI = {
autoRespawn: false,
autoTalk: false,
tactReload: true,
pathFinding: false,
autoRetreat: true,
cautious: true,
espVector: true,
algorithm: "terminator",
followLeader: "PureVaakir",
updateFrequency: 5,
}
esp = {
active: true,
playerLine: false,
shootRange: true,
walls: false,
showAllies: false
}
autoUpgrade = {
active: true,
perk1: "longRange",
perk2: "dash",
perk3: "thickSkin"
}
misc = {
zoom: true,
antiSilencer: true,
anitCamo: true,
anitMines: true,
}
chatScroller = {
active: false,
activatedOnce: false,
speed: 10,
message: "Vaakir hax",
}
options = {
textWidth: 20
}
data = {
active: false,
x: 0,
y: 0,
test1: false,
test2: false,
}
texturePack = {
longCrate: "#303030",
squareCrate: "#b1e9f9",
longCrateBorder: "#646464",
squareCrateBorder: "#4dd8f0",
wtf: false,
texture: "ok"
}
futureUpdates = {}
// these need only to be gathered every now and then, not for every animation frame #tick,
// therefore I am saving them here together with the rest
walls = [];
// AI pathfinding variables
searchLength = 30;
rotating = Math.PI/24; // Rotating check by 0.2r = 11.5degrees
mapCenterVector = {x: 3500, y: 3500}
goalVector = {x: 3500, y: 3500}
goal = {x: 3500, y: 3500}
movementVector = {x: this.searchLength, y: 0} // silk touch
perkBotActive = false;
defaultColors = ["#dfbf9f","#bec8dd","#808080"];
colorChange = true;
changeRotatitingDirection = false;
lastChat = Date.now();
wtfOn = false; // darkmode is wtf
// goalVector = {x:this.goal.x - this.x, y:this.goal.y - this.y};
constructor() {
this.init();
}
init() {
this.loadOptions();
this.gui = new GUI(document.body);
const hackpack = this.gui.addMainFolder('Hacks', '', 'title');
const aimbot = hackpack.addFolder('Aimbot (right click)', '', 'title', this.gui);
aimbot.add(this.aimbot, 'active');
aimbot.add(this.aimbot, 'alwaysAim');
aimbot.add(this.aimbot, 'calibrate', 'number', this.aimbot.calibrate);
aimbot.add(this.aimbot, 'moveFrequency', 'number', this.aimbot.moveFrequency);
aimbot.add(this.aimbot, 'allies', 'select','');
aimbot.add(this.aimbot, 'autoShoot');
aimbot.add(this.aimbot, 'espLine');
aimbot.add(this.aimbot, 'espCollisions');
const AI = hackpack.addFolder('AI', '', 'title', this.gui);
AI.add(this.AI, 'autoRespawn');
AI.add(this.AI, 'autoTalk');
AI.add(this.AI, 'tactReload');
AI.add(this.AI, 'pathFinding');
AI.add(this.AI, 'autoRetreat');
AI.add(this.AI, 'cautious');
AI.add(this.AI, 'espVector');
AI.add(this.AI, 'algorithm', 'select', 'terminator follow'.split(" "));
AI.add(this.AI, 'followLeader', 'input', 'PureVaakir');
AI.add(this.AI, 'updateFrequency', 'number', this.AI.updateFrequency);
const esp = hackpack.addFolder('Esp', '', 'title');
esp.add(this.esp, 'active');
esp.add(this.esp, 'playerLine');
esp.add(this.esp, 'shootRange');
esp.add(this.esp, 'showAllies');
esp.add(this.esp, 'walls');
const autoUpgrade = hackpack.addFolder('AutoUpgrade', '', 'title');
autoUpgrade.add(this.autoUpgrade, 'active');
autoUpgrade.add(this.autoUpgrade, 'perk1', 'select', 'bipod optics thermal armorPiercing extended grip silencer lightweight longRange thickSkin'.split(' '));
autoUpgrade.add(this.autoUpgrade, 'perk2', 'select', 'shield firstAid grenade knife engineer ghillie dash gasGrenade landMine fragGrenade'.split(' '));
autoUpgrade.add(this.autoUpgrade, 'perk3', 'select', 'bipod optics thermal armorPiercing extended grip silencer lightweight longRange thickSkin'.split(' '));
const misc = hackpack.addFolder('Misc', '', 'title');
misc.add(this.misc, 'zoom');
misc.add(this.misc, 'antiSilencer');
misc.add(this.misc, 'anitCamo');
misc.add(this.misc, 'anitMines');
const chatScroller = hackpack.addFolder('ChatScroller', '', 'title');
chatScroller.add(this.chatScroller, 'active');
chatScroller.add(this.chatScroller, 'speed', 'number', this.chatScroller.speed);
chatScroller.add(this.chatScroller, 'message', 'input', 'Try Vaakir hack!');
const data = hackpack.addFolder('data', '', 'title');
data.add(this.data, 'active');
data.add(this.data, 'x', 'input', '');
data.add(this.data, 'y', 'input', '');
data.add(this.data, 'test1');
data.add(this.data, 'test2');
const texturePack = hackpack.addFolder('texturePack', '', 'title');
texturePack.add(this.texturePack, 'longCrate', 'color', '');
texturePack.add(this.texturePack, 'squareCrate', 'color', '', );
texturePack.add(this.texturePack, 'longCrateBorder', 'color', '', );
texturePack.add(this.texturePack, 'squareCrateBorder', 'color', '', );
texturePack.add(this.texturePack, 'wtf');
texturePack.add(this.texturePack, 'texture', 'button', '');
const future = hackpack.addFolder('FutureUpdates', '', 'title');
future.add(this.AI, 'AI');
future.add(this.AI, 'autoCalibrate');
future.add(this.AI, 'multiboxing');
future.add(this.AI, 'knifebot');
future.add(this.AI, 'shieldbot');
future.add(this.AI, 'customstuff');
// const AI = hackpack.addFolder('AI', '', 'title');
// AI.add(this.AI, 'comingSoonTM');
// const chatScroller = hackpack.addFolder('ChatScroller', '', 'title');
// chatScroller.add(this.chatScroller, 'comingSoon');
// chatScroller.add(this.chatScroller, 'message', 'input','ok?');
//const options = hackpack.addFolder('Options', '', 'title');
// options.add(this.options, 'textWidth', 'number', this.options.textWidth);
}
loadOptions() {
try {
const savedOptions = JSON.parse(localStorage.getItem('options'));
if (savedOptions) {
Object.assign(this, savedOptions);
this.aimbot.active = false; // Because I haven't added in an activation, unless you right click yet.
this.colorChange = true; // just because
this.wtfOn = false; // also just because - experiment
this.chatScroller.activatedOnce = false; // also is just just because, amen to that
this.perkBotActive = false;
changeRotatitingDirection = false;
}
} catch (error) {
console.error('Error loading options from localStorage:', error);
}
}
saveOptions() {
try {
let saveData = JSON.stringify(this);
localStorage.setItem('options', saveData);
} catch (error) {
console.error('Error saving options to localStorage:', error);
}
}
}
window.opts = options;
class Draw {
static line(ctx, start, end, color="black", lineWidth=1) {
ctx.strokeStyle = color;
ctx.lineWidth = lineWidth;
ctx.beginPath();
ctx.moveTo(start.x, start.y);
ctx.lineTo(end.x, end.y);
ctx.stroke();
}
static triangle(ctx,x,y,size,color) {
ctx.fillStyle = color;
ctx.beginPath();
ctx.moveTo(x-size/2, y);
ctx.lineTo(x, y-size);
ctx.lineTo(x+size/2, y);
ctx.closePath();
ctx.fill();
}
static circle(ctx, x, y, radius, color="red", lineWidth=1) {
ctx.fillStyle = color;
ctx.lineWidth = lineWidth;
ctx.beginPath();
ctx.arc(x, y, radius, 0, 2 * Math.PI);
ctx.fill();
}
}
class GameInterface {
static get localPlayerId() {
return +(window.c3 ?? '-1')
}
static get camera() {
return window.c2
}
static get playerPool() {
return window.RD?.pool || {}
}
static get grenadePool() {
return window.RA?.pool || {}
}
static get wallPool() {
return window.RB?.pool || {}
}
static get projectilePool() {
return window.RC?.pool || {}
}
static get scaleX() {
return window.j6
}
static get scaleY() {
return window.j5
}
static get upgrades() {
return window.o3
}
static get conn() {
return RF.list[0]
}
static get leaderBoard() {
return j38.current
}
static get currentPlayers() {
return parseInt(o4.currentPlayers);
}
static get currentPing() {
return RF.list[0].currentPing;
}
}
class Game {
constructor() {}
get isIngame() {
return GameInterface.localPlayerId > -1
}
get localPlayer() {
return GameInterface.playerPool[GameInterface.localPlayerId]
}
get isAlive() {
return (this.isIngame && this.localPlayer?.hp > 0)
}
getGunLength(playerClass = this.localPlayer?.class) {
return {
pistol: 60,
smg: 60,
shotgun: 80,
assault: 80,
'bolt-action-rifle': 100,
'machine-gun': 85
}[playerClass] || 0
}
getGunRange(playerClass = this.localPlayer?.class) {
let hasLongRange = false;
if (playerClass == this.localPlayer?.class) hasLongRange = Object.values(GameInterface.upgrades).indexOf('longRange') > -1
const range = {
pistol: 400,
smg: 280,
shotgun: 235,
assault: 370,
'bolt-action-rifle': 620,
'machine-gun': 365
}[playerClass] || 0
const rangeBonus = hasLongRange ? range * (window.fact ?? 0.5) : 0
return range + rangeBonus
}
getGunOffset(playerClass = this.localPlayer?.class) {
return {
pistol: 10,
smg: 10,
shotgun: 12,
assault: 12,
'bolt-action-rifle': 16,
'machine-gun': 14
}[playerClass] || 0
}
getPlayers(includeMe=true, includeMates=true, includeEnemies=true) {
if (!this.isIngame) return []
const { id, teamCode } = this.localPlayer
return Object.values(GameInterface.playerPool)
.filter(player => {
if (!player.activated) return false
if (player.hp <= 0) return false
if (!includeMe && player.id === id) return false
if (!includeMates && ((player.teamCode !== 0 && player.teamCode === teamCode) || options.aimbot.alliesList.includes(player.username))) return false
if (!includeEnemies && ((player.teamCode === 0 || player.teamCode !== teamCode) && !options.aimbot.alliesList.includes(player.username))) return false
return true
})
}
getEnemies() {
return this.getPlayers(false, false, true)
}
getMates() {
return this.getPlayers(false, true, false)
}
getGrenades() {
return Object.values(GameInterface.grenadePool).filter(grenade => {
if (!grenade.activated) return false
return true
})
}
getWalls() {
return Object.values(GameInterface.wallPool)
.filter(wall => {
if (!wall.activated) return false
return true
})
.map(wall => {
const fixedWall = { ...wall }
const size = wall.model[0][0][0][0]
fixedWall.width = size * 2
fixedWall.height = size * 2
if (wall.type === 'longCrate') {
if (wall.angle / 90 % 2 === 0) { fixedWall.width /= 2 }
else { fixedWall.height /= 2 }
}
// Used for the aimbot wall detection check
fixedWall.x1 = fixedWall.x - fixedWall.width / 2
fixedWall.x2 = fixedWall.x + fixedWall.width / 2
fixedWall.y1 = fixedWall.y - fixedWall.height / 2
fixedWall.y2 = fixedWall.y + fixedWall.height / 2
return fixedWall
})
}
getProjectiles() {
return Object.values(GameInterface.projectilePool).filter(projectile => {
if (!projectile.activated) return false
//if (projectile.x !== 0 && projectile.x !== 0) return false
return true
})
}
getScreenPos(pos) {
return GameInterface.camera?.getRelPos(pos) || { x: 0, y: 0 }
}
resizeCamera(width, height) {
if (!this.isIngame) return
window.width = width;
window.height = width / (16 / 9);
window.a1({
width: width,
height: typeof height !== 'undefined' ? height : width / (16 / 9)
});
}
isOutsideMap(entity) {
/*
0 -> 3500-1000 = 1000
11 -> 3500-2000 = 1500
10 -> 3500-2000 = 1500
17 -> 3500-1500 = 2000
24 -> 3500-1500 = 2000
25 -> 3500-1000 = 2500
*/
const borderLevel = {
0: 0,
5: 0,
10: 1,
15: 1,
20: 2,
25: 3,
30: 3
}[Math.floor((GameInterface.currentPlayers) / 5)*5]
const borderGrowth = 500;
const defaultSize = 1000;
const mapFogVertices = {
x1: 3500 - (defaultSize + borderGrowth * borderLevel),
x2: 3500 + (defaultSize + borderGrowth * borderLevel),
y1: 3500 - (defaultSize + borderGrowth * borderLevel),
y2: 3500 + (defaultSize + borderGrowth * borderLevel),
}
const outsideX = (mapFogVertices.x1 > entity.x || entity.x > mapFogVertices.x2);
const outsideY = (mapFogVertices.y1 > entity.y || entity.y > mapFogVertices.y2);
if (outsideX || outsideY) return true;
return false;
}
/*setMouse(x, y) {
if (!document.onmousemove) return
const clientX = x * GameInterface.scaleX
const clientY = y * GameInterface.scaleY
document.onmousemove(new MouseEvent('mousemove', { clientX, clientY }))
}*/
}
const game = new Game()
window.game = game
class Hack {
#canvas = document.querySelector('canvas');
#ctx = this.#canvas.getContext('2d');
#aimbot = { active: false, target: null, x: 0, y: 0 }
iter = 1;
iterMax = 50;
alliesWalls = [];
constructor() {
this.#initRender();
this.#initAimbot();
this.#initZoom();
//this.#hookMouse()
}
/*fixConsole() {
let _this = this
setTimeout(() => {
const iframe = document.createElement('iframe')
iframe.style.display = 'block'
document.body.appendChild(iframe)
window.console = iframe.contentWindow.console
_this.er = iframe
})
}*/
#initRender() {
this.#ctx.oclearRect = this.#ctx.oclearRect || this.#ctx.clearRect
this.#ctx.clearRect = (...args) => {
this.#ctx.oclearRect(...args)
requestAnimationFrame(() => {
if (game.isIngame) this.#tick()
})
}
}
#initAimbot() {
const mouseMoveHook = evt => {
if (!mouseMoveHook.original) return
const clientX = (options.aimbot.active && this.#aimbot.active && this.#aimbot.target?.visible && game.isAlive) ? this.#aimbot.x * GameInterface.scaleX : evt.clientX;
const clientY = (options.aimbot.active && this.#aimbot.active && this.#aimbot.target?.visible && game.isAlive) ? this.#aimbot.y * GameInterface.scaleY : evt.clientY;
return mouseMoveHook.original(
new MouseEvent('mousemove', {
view: evt.view,
bubbles: evt.bubbles,
cancelable: evt.cancelable,
clientX: clientX,
clientY: clientY
})
);
}
mouseMoveHook.original = document.onmousemove;
document.onmousemove = mouseMoveHook;
Object.defineProperty(document, 'onmousemove', {
set: val => {
mouseMoveHook.original = val;
}
})
let interval;
window.onmousedown = ({ button, clientX, clientY }) => {
if (button == 2) {
options.aimbot.active = !options.aimbot.active;
this.#aimbot.active = true;
interval = setInterval(() => {
if (options.aimbot.active && this.#aimbot.active && game.isAlive) {
if (this.#aimbot.target) {
if (this.#aimbot.target.activated && this.#aimbot.target.hp > 0) {
const clientX = this.#aimbot.x * GameInterface.scaleX;
const clientY = this.#aimbot.y * GameInterface.scaleY;
if (this.#aimbot.target.visible || options.aimbot.alwaysAim) {
mouseMoveHook.original(new MouseEvent('mousemove', { clientX, clientY }));
}
if (this.#aimbot.target.visible && options.aimbot.autoShoot) {
document.onmousedown?.(new MouseEvent('mousedown', { clientX, clientY }));
setTimeout(() => document.onmouseup?.(new MouseEvent('mouseup', { clientX, clientY })), 15);
}
}
else {
this.#aimbot.target = null;
}
}
}
}, options.aimbot.moveFrequency);
}
}
window.onmouseup = ({ button, clientX, clientY }) => {
if (button === 2 && !options.aimbot.active) {
clearInterval(interval)
this.#aimbot.active = false;
this.#aimbot.target = null;
// options.aimbot.active = !options.aimbot.active;
// options.aimbot.active = false;
}
}
}
#initZoom() {
window.addEventListener("wheel", function(e) {
if (options.misc.zoom) {
// game.resizeCamera(window.width, window.height); soo.. window.width is max 2000, editing j7, j8 allows for further zoom which is fun..
let dir = Math.sign(e.deltaY);
if (dir== 1) {
a1({width: j7 * 1.1, height: j8 * 1.1});
}
if (dir==-1) {
a1({width: j7 * 0.9, height: j8 * 0.9});
}
}
});
}
#tick() {
const me = game.localPlayer;
const enemies = game.getEnemies();
const mates = game.getMates(); // mates :) best word usage
// Remove enemies which are too close
/*.filter(enemy => {
if (enemy.x > me.x + 50) return true
if (enemy.x < me.x - 50) return true
if (enemy.y > me.y + 50) return true
if (enemy.y < me.y - 50) return true
return false
})*/
const myScreenPos = game.getScreenPos(me);
const myAngle = me.playerAngle * (Math.PI / 180);
let walls = options.walls; // game.getWalls();
// calc.sortByDistance(enemies, me);
// Gun range helper
if (options.esp.active && options.esp.shootRange) {
const gunStart = {
x: me.x + Math.cos(myAngle - Math.PI / game.getGunOffset()) * game.getGunLength(),
y: me.y + Math.sin(myAngle - Math.PI / game.getGunOffset()) * game.getGunLength()
}
const gunEnd = {
x: gunStart.x + Math.cos(myAngle) * game.getGunRange(),
y: gunStart.y + Math.sin(myAngle) * game.getGunRange()
}
// const gunStartScreenPos = game.getScreenPos(gunStart);
// const gunEndScreenPos = game.getScreenPos(gunEnd);
const fakeEnemy = {fake: true, x: gunEnd.x, y: gunEnd.y, spdX: 0, spdY: 0, distance: game.getGunRange()}
enemies.unshift(fakeEnemy);
// Draw.line(this.#ctx, gunStartScreenPos, gunEndScreenPos, "black", 1);
}
let fallBack = {dist: Infinity, x: undefined, newX: undefined, y: undefined, newY: undefined, visible: false}
let visibleEnemies = [];
// we do not want to shoot our allies.. so we pretend that they are moving square walls :>
if (options.aimbot.alliesList.length > 0) {
walls = walls.filter(item => !this.alliesWalls.includes(item));
this.alliesWalls = [];
for (const a of mates) {
const dist = calc.distance(a, me);
const aX = a.x + a.spdX * dist / (window.fac ?? options.aimbot.calibrate);
const aY = a.y + a.spdY * dist / (window.fac ?? options.aimbot.calibrate);
const newWallMove = {
x1: aX - 40, x2: aX + 40,
y1: aY - 40, y2: aY + 40,
width: 80, height: 80
}
const newWallPos = {
x1: a.x - 25, x2: a.x + 25,
y1: a.y - 25, y2: a.y + 25,
width: 50, height: 50
}
walls.push(newWallMove);
walls.push(newWallPos);
this.alliesWalls.push(newWallMove);
this.alliesWalls.push(newWallPos);
// enemy block esp
if (options.esp.active && options.esp.showAllies) {
const topLeft0 = game.getScreenPos({x: newWallMove.x1, y: newWallMove.y1});
const topLeft1 = game.getScreenPos({x: newWallPos.x1, y: newWallPos.y1});
this.#ctx.strokeStyle = 'red';
this.#ctx.lineWidth = 1;
this.#ctx.strokeRect(topLeft0.x, topLeft0.y, newWallMove.width, newWallMove.height);
this.#ctx.strokeRect(topLeft1.x, topLeft1.y, newWallPos.width, newWallPos.height);
}
}
}
// Wall esp
if (options.esp.active && options.esp.walls) {
for (const w of walls) {
const topLeft = game.getScreenPos({x: w.x1, y: w.y1});
const bottomRight = game.getScreenPos({x: w.x2, y: w.y2});
this.#ctx.strokeStyle = 'red';
this.#ctx.lineWidth = 1;
this.#ctx.strokeRect(topLeft.x, topLeft.y, bottomRight.x - topLeft.x, bottomRight.y - topLeft.y);
}
}
for (const enemy of enemies) {
enemy.distance = calc.distance(enemy, me);
const dist = enemy.distance - game.getGunLength();
if (dist < game.getGunRange()) {
const gunToEnemy = calc.gunToEnemy(me, enemy, dist);
const startX = gunToEnemy.start.x;
const startY = gunToEnemy.start.y;
const endX = gunToEnemy.end.x;
const endY = gunToEnemy.end.y;
const startScreenPos = game.getScreenPos({ x: startX, y: startY });
const endScreenPos = game.getScreenPos({ x: endX, y: endY });
// Visibility check + no need to calculate the line collisions for the other enemies
let visible = true;
if (visibleEnemies.length == 0) {
// We do not want to shoot at walls.. so we check if our hypothetical gun line crosses each corner of every wall (close by)
const gunLine = {x: startX, y: startY, dx: endX - startX, dy: endY - startY}
visible = calc.lineCollidesWithWalls(gunLine, walls, this.#ctx);
}
// ESP playerLine
if (options.esp.active && options.esp.playerLine && !enemy.fake) {
const enemyScreenPos = game.getScreenPos(enemy);
Draw.line(this.#ctx, myScreenPos, enemyScreenPos, enemy.color.a, 2);
}
// Aim target logic
if (this.#aimbot.active && !enemy.fake) {
if (fallBack.newX == undefined) {
fallBack = {distance: enemy.distance, x: undefined, newX: endScreenPos.x, y: undefined, newY: endScreenPos.y, visible: visible, ...enemy}
} else if (visible && !fallBack.visible || !fallBack.visible && enemy.distance < fallBack.distance || fallBack.visible && visible && enemy.distance < fallBack.distance) {
fallBack = {distance: enemy.distance, x: undefined, newX: endScreenPos.x, y: undefined, newY: endScreenPos.y, visible: visible, ...enemy}
}
}
// Aimbot espLine
if (options.aimbot.espLine) {
Draw.line(this.#ctx, startScreenPos, endScreenPos, visible ? 'green' : "red", 2);
}
}
// Anti silencer bullet
if (options.misc.antiSilencer) {
if (enemy.ghillie && !enemy.fake) {
enemy.ghillie = 0;
enemy.invincible = 1;
}
}
// Anti camo
if (options.misc.anitCamo && !enemy.fake) {
enemy.silenced = 0;
}
// Vaakir usage check ? :> not sus
/*if (enemy.j47 == "Vaakir test " && me.j47 != "Yes sir!" && enemy.username == "PureVaakir") {
GameInterface.conn.send(`c,Yes sir!`)
}*/
}
// Aim target logic
if (enemies.length > 0 && fallBack.newX !== undefined) {
this.#aimbot.target = fallBack;
this.#aimbot.target.visible = fallBack.visible;
this.#aimbot.x = fallBack.newX;
this.#aimbot.y = fallBack.newY;
} else {
this.#aimbot.target = null;
}
// Draw esp AI pathfinding vector
if (options.AI.espVector) {
const meScreenPos = game.getScreenPos(me);
const endPathPos = game.getScreenPos( calc.combine(me, options.movementVector) );
const endPathPosGoal = game.getScreenPos( calc.combine(me, options.goalVector) );
Draw.line(this.#ctx, meScreenPos, endPathPos, 'blue');
Draw.line(this.#ctx, meScreenPos, endPathPosGoal, 'green');
}
this.iter++;
if (this.iter > options.AI.updateFrequency) {
this.iter = 0;
this.#tickLessOften();
}
/*
// Auto Shield bot (dangerously toxic on a terminator bot..)
let bullets = game.getProjectiles();
if (bullets.length > 0) {
for (let b of bullets) {
if ((b.x != 0 || b.y != 0) && me.id != b.ownerId) {
const bulletVector = {y: b.spdX, x: b.spdY}
const futureBulletPos = calc.combine(b, bulletVector);
const futureMePos = calc.combine(me, {x: me.spdX, y: me.spdY});
if (calc.distance(futureBulletPos, futureMePos) < 70) {
const myAngle = calc.rotateVector(bulletVector, Math.PI / 2);
const angle = calc.angle360(myAngle, {x: 1, y: 0});
// enemy.spdX * dist / (window.fac ?? options.aimbot.calibrate);
// const myAngleDegress = calc.radiansToDegrees(angle);
// me.playerAngle = myAngleDegress;
if (me.score >= 300) {
this.#aimbot.target = fallBack;
this.#aimbot.target.visible = true;
this.#aimbot.x = me.x + Math.cos(angle) * 100;
this.#aimbot.y = me.y + Math.sin(angle) * 100;
if (options.perkBotActive == false) {
options.perkBotActive = true;
GameInterface.conn.send(`k,5,1`);
setTimeout(()=> {
GameInterface.conn.send(`k,5,0`);
options.perkBotActive = false;
}, 1000);
}
}
console.dir(`${me.id}, ${b.ownerId},${me.id == b.ownerId}, ${Object.keys(b)}, ${Object.values(b)}`)
}
}
}
}*/
// if (!options.chatScroller.active) options.scroller = false;
}
#tickLessOften() {
// Performance boost? not all things should be calculated upon request animationframe like I am currently doing
// upgrades would include not !! "sorting by distance" , "aimbot wallcollision check" for every single tick, use memory, right?
// I am honestly too lazy to check the time usage of this, intuition works alright, feel free to improve this.. or expand this
let walls = game.getWalls();
let enemies = game.getEnemies();
const marginOfSafety = 1.2;
const me = game.localPlayer;
const mates = game.getMates();
const players = [...mates, ...enemies];
calc.sortByDistanceFilter(walls, me, game.getGunRange() * marginOfSafety);
options.walls = walls;
let state = ''; // used for the autotalk bots
// zoom hack
if (options.misc.zoom) {
if (me.hp > 0) {
if (window.width !== 2000) game.resizeCamera(2000);
} else {
if (window.width !== window.c2.width) game.resizeCamera(window.c2.width, window.c2.height);
}
} else if (window.width !== window.c2.width) {
game.resizeCamera(window.c2.width, window.c2.height);
}
// shows landmines
if (options.misc.anitMines) {
landMine[0].forEach((a,i)=>{landMine[0][i][1][3]="#000000"})
}
// show silenced bullets, (activated) another place, keep this uncommented..
// if (options.misc.antiSilencer) {
// // laze :eyes:
// Object.keys(RC.pool).forEach((a,i)=>{
// if(RC.pool[i].silenced){RC.pool[i].silenced=0}
// })
// }
// wtf darkmode
if (options.texturePack.wtf && options.wtfOn == false) {
options.wtfOn = true;
// experimental, and kinda not correct, but it was funny, so here it iz, lmao
a16 = eval("(" + String(a16).replace("#efeff5","black") +")")
a16 = eval("(" + String(a16).replaceAll("_0x59b26e(0x327)","'black'") +")")
RC['prototype'][_0xb01518(0x27c)] = eval("(" + String(RC['prototype'][_0xb01518(0x27c)]).replace("_0x4a9b96(0x2aa)","'white'") +")")
s1 = JSON.parse(JSON.stringify(s1).replaceAll("#","white','"))
s2 = JSON.parse(JSON.stringify(s2).replaceAll("#","white','"))
s3 = JSON.parse(JSON.stringify(s3).replaceAll("#","white','"))
s4 = JSON.parse(JSON.stringify(s4).replaceAll("#","white','"))
s5 = JSON.parse(JSON.stringify(s5).replaceAll("#","white','"))
s6 = JSON.parse(JSON.stringify(s6).replaceAll("#","white','"))
r1 = JSON.parse(JSON.stringify(r1).replaceAll("#","white','"))
r2 = JSON.parse(JSON.stringify(r2).replaceAll("#","white','"))
r3 = JSON.parse(JSON.stringify(r3).replaceAll("#","white','"))
r4 = JSON.parse(JSON.stringify(r4).replaceAll("#","white','"))
r5 = JSON.parse(JSON.stringify(r5).replaceAll("#","white','"))
r6 = JSON.parse(JSON.stringify(r6).replaceAll("#","white','"))
r7 = JSON.parse(JSON.stringify(r7).replaceAll("#","white','"))
r8 = JSON.parse(JSON.stringify(r8).replaceAll("#","white','"))
r9 = JSON.parse(JSON.stringify(r9).replaceAll("#","white','"))
r10 = JSON.parse(JSON.stringify(r10).replaceAll("#","white','"))
s1 = JSON.parse(JSON.stringify(s1).replaceAll("_0xb01518","'white',"))
s2 = JSON.parse(JSON.stringify(s2).replaceAll("_0xb01518","'white',"))
s3 = JSON.parse(JSON.stringify(s3).replaceAll("_0xb01518","'white',"))
s4 = JSON.parse(JSON.stringify(s4).replaceAll("_0xb01518","'white',"))
s5 = JSON.parse(JSON.stringify(s5).replaceAll("_0xb01518","'white',"))
s6 = JSON.parse(JSON.stringify(s6).replaceAll("_0xb01518","'white',"))
r1 = JSON.parse(JSON.stringify(r1).replaceAll("_0xb01518","'white',"))
r2 = JSON.parse(JSON.stringify(r2).replaceAll("_0xb01518","'white',"))
r3 = JSON.parse(JSON.stringify(r3).replaceAll("_0xb01518","'white',"))
r4 = JSON.parse(JSON.stringify(r4).replaceAll("_0xb01518","'white',"))
r5 = JSON.parse(JSON.stringify(r5).replaceAll("_0xb01518","'white',"))
r6 = JSON.parse(JSON.stringify(r6).replaceAll("_0xb01518","'white',"))
r7 = JSON.parse(JSON.stringify(r7).replaceAll("_0xb01518","'white',"))
r8 = JSON.parse(JSON.stringify(r8).replaceAll("_0xb01518","'white',"))
r9 = JSON.parse(JSON.stringify(r9).replaceAll("_0xb01518","'white',"))
r10 = JSON.parse(JSON.stringify(r10).replaceAll("_0xb01518","'white',"))
}
// Chat scroller
if (options.chatScroller.active) {
function chat(i) {
setTimeout(function () {
let msg = options.chatScroller.message;
if (msg.length > 0) {
if ( i > msg.length ) { i = -25; }
let lis = [];
for (let i2=i;i2<i+25;i2+=1){
if ( msg[i2] ) { lis.push( msg[i2] ); }
else { lis.push(" "); }
}
// scroller // random (because of security bypass)
let text = String( lis.join("") ).substring( Math.round( Math.random() * 2 ), 25);
GameInterface.conn.send(`c,${text}`)
i++;
}
if (options.chatScroller.active) { chat(i); }
}, options.chatScroller.speed ?? 10);
}
if (options.chatScroller.activatedOnce == false) {
options.chatScroller.activatedOnce = true;
chat(-25);
}
} else {
options.chatScroller.activatedOnce = false;
}
// Auto upgrade logic
if (options.autoUpgrade.active && me.hp > 0) {
if (GameInterface.upgrades[1] == "" && me.score >= 100) {
// deobfuscated packet code: return 'u,' + _0xab86d4.upgrade + ',' + _0xab86d4.upgradeLevel + '\x00';
GameInterface.upgrades[1] = options.autoUpgrade.perk1;
GameInterface.conn.send(a59('upgrade', {'upgrade': options.autoUpgrade.perk1,'upgradeLevel': 1}));
}
if (GameInterface.upgrades[2] == "" && me.score >= 300) {
GameInterface.upgrades[2] = options.autoUpgrade.perk2;
GameInterface.conn.send(a59('upgrade', {'upgrade': options.autoUpgrade.perk2,'upgradeLevel': 2}));
}
if (GameInterface.upgrades[3] == "" && me.score >= 600) {
GameInterface.upgrades[3] = options.autoUpgrade.perk3;
GameInterface.conn.send(a59('upgrade', {'upgrade': options.autoUpgrade.perk3,'upgradeLevel': 3}));
}
}
// Texture pack
if (options.colorChange) {
window.longCrate[0][1][1][3] = options.texturePack.longCrate;
window.crate[0][1][1][3] = options.texturePack.squareCrate;
window.longCrate[0][0][1][3] = options.texturePack.longCrateBorder;
window.crate[0][0][1][3] = options.texturePack.squareCrateBorder;
options.colorChange = false;
}
// Update allies list from those entities nearby in view.
const currentName = options.aimbot.allies.value;
options.aimbot.allies.innerHTML = `<option class="option">${currentName}</option>`;;
for (const e of mates) {
options.aimbot.allies.innerHTML += `<option class="option colGreen">${e.username}</option>`;
}
for (const e of GameInterface.leaderBoard) {
options.aimbot.allies.innerHTML += `<option class="option colRed">${e.userId}</option>`;
}
for (const e of enemies) {
options.aimbot.allies.innerHTML += `<option class="option colRed">${e.username}</option>`;
}
const VIP = ["[1337] PureVaakir","PureVaakir","Hacker0","VaakTradeBot"]; // do you really want to kill me with my own hacks? yikes
const alliesList = options.aimbot.alliesList.filter(item => !VIP.includes(item));
for (const e of alliesList) {
options.aimbot.allies.innerHTML += `<option class="option colGreen">${e}</option>`;
}
// data display
if (options.data.active) {
options.data.x = me.x;
options.data.y = me.y;
}
// Autorespawn
if (options.AI.autoRespawn && !game.isAlive) {
c4=false;
c28=false;
a75();
setTimeout(function(){play();c28=false;}, 2000);
// setTimeout(function(){j7*=1.4;j8*=1.4;a1();},1100);
}
// AI algorithms, pretty dope, I can tell you..
if (options.AI.pathFinding && options.AI.algorithm) { // options.AI.pathFinding
const meScreenPos = game.getScreenPos(me);
let algo = options.AI.algorithm;
calc.sortByDistanceFaster(enemies, me);
/*if (algo == 'follow') {
const leader = players.find(e => e.username === options.AI.followLeader);
if (!leader) {
algo = 'terminator'
} else {
// our goal is to follow the player defined in options.AI.followLeader;
options.goal = leader;
options.movementVector = calc.normalize( calc.vectorAB(leader, me), options.searchLength);
if (options.AI.espVector) {
const endPathPos = game.getScreenPos( calc.combine(me, options.movementVector) );
Draw.line(this.#ctx, meScreenPos, endPathPos, 'red');
}
}
}*/
if (algo == 'terminator' || algo == 'follow') {
// are we inside the map? if not, change rotation direction of the movementvector
// (temporary solution to not walking outside the map - just reverse the walking direction)
/*if (options.changeRotatitingDirection == false && game.isOutsideMap(me)) {
options.rotating *= -1;
options.changeRotatitingDirection = true;
setTimeout(()=> {
options.changeRotatitingDirection = false;
options.rotating *= -1;
}, 8000);
}*/
// reality check, yikes - errors can happen when I update this, so its a quick fix when I'm testing
if (isNaN(options.movementVector.x)) options.movementVector = {x: options.searchLength, y: 0}
// decide goal
// goal priority 1. Walk away from gas/grenades
// goal priority 2. Walk away from bullets (weighted/grouped by estimated damage)
// goal priority 3. Walk away from shotgun ranges unless you are a shotgun yourself
// goal priority 4. stay put / retreat on low hp or reload (tactical reloads included)
// goal priority 5. walk towards enemy
// goal priority 6. walk towards center of map
const leader = players.find(e => e.username === options.AI.followLeader);
if (algo == 'follow' && leader) {
options.goal = leader;
if (options.AI.espVector) {
const endPathPos = game.getScreenPos( calc.combine(me, options.movementVector) );
Draw.line(this.#ctx, meScreenPos, endPathPos, 'red');
}
} else if (enemies.length == 0 || game.isOutsideMap(enemies[0]) || (enemies[0].invincible && !enemies[0].ghillie)) {
options.goal = options.mapCenterVector;
} else {
const closestEnemy = enemies[0];
const dist = Math.sqrt(closestEnemy.distanceSquared); // calc.distance(me, closestEnemy);
options.goal = closestEnemy;
// tactReload, autoRetreat, cautious
// Just keep your distance to shotguns, change goal to not walk towards the closest shotgunner
const keepShotGunDistance = (closestEnemy.class == 'shotgun' && me.class != 'shotgun' && dist < 400 || me.class == 'bolt-action-rifle' && dist < 450);
const enemyGunToMe = calc.gunToEnemy(closestEnemy, me, dist);
const enemyGunToMe2 = calc.gunToEnemy(closestEnemy, me, dist, 1.5);
const meGunToEnemy = calc.gunToEnemy(me, closestEnemy, dist);
const myGunLineToEnemy = {x: meGunToEnemy.start.x, y: meGunToEnemy.start.y, dx: meGunToEnemy.end.x - meGunToEnemy.start.x, dy: meGunToEnemy.end.y - meGunToEnemy.start.y}
const enemyGunLineToMe = {x: enemyGunToMe.start.x, y: enemyGunToMe.start.y, dx: enemyGunToMe.end.x - enemyGunToMe.start.x, dy: enemyGunToMe.end.y - enemyGunToMe.start.y}
const enemyGunLineToMe2 = {x: enemyGunToMe2.start.x, y: enemyGunToMe2.start.y, dx: enemyGunToMe2.end.x - enemyGunToMe2.start.x, dy: enemyGunToMe2.end.y - enemyGunToMe2.start.y}
const enemyCanShootMe = calc.lineCollidesWithWalls(enemyGunLineToMe, walls, this.#ctx, false);
const enemyCanShootMe2 = calc.lineCollidesWithWalls(enemyGunLineToMe2, walls, this.#ctx, false);
const meCanShootEnemy = calc.lineCollidesWithWalls(myGunLineToEnemy, walls, this.#ctx, false);
const marginOfSafety = 10;
const enemyRangeDistance = game.getGunLength(closestEnemy.class) + game.getGunRange(closestEnemy.class) + marginOfSafety;
// keepShotGunDistance or if the enemy can shoot me and I can't shoot back, then I should rotate around or retreat
// however if the enemy is close enough, there is no reason to back off, hence (dist < 200), rly usefull for close combat
if (options.AI.cautious && (keepShotGunDistance || ((enemyCanShootMe || enemyCanShootMe2) && !meCanShootEnemy && dist < 200))) {
// const enFuturePos = calc.aheadNess(closestEnemy, dist);
// const meFuturePos = calc.aheadNess(me, dist);
// const futDistance = calc.distance(meFuturePos, enFuturePos);
const rotDirection = (options.rotating > 0) ? 1 : -1;
let rotateByRadians = -Math.PI/2 * rotDirection; // too close, walk 90deg alongside enemy (circle around the enemy)
if (dist < enemyRangeDistance) rotateByRadians = -Math.PI/1.2 * rotDirection // (180deg) back (retreat almost directly away from the enemy)
let vecToEnemy = calc.vectorAB(closestEnemy, me);
let vecToNewGoal = calc.rotateVector(vecToEnemy, rotateByRadians);
options.goal = calc.combine(closestEnemy, calc.normalize(vecToNewGoal, 320)); // normalize(legnth = 320) can be any number (100<) not that important
options.movementVector = calc.normalize(vecToNewGoal, options.searchLength);
state = 'holdback';
} else {
// we're targeting a normal player who is not a shotgunner
// and if we're reloading or in low health, just retreat
const lowRelativeHP = (closestEnemy.hp > me.hp && me.hp < 50);
const enemiesCloseBy = (dist < 500 || me.hp < 90);
const reloading = (me.reloading === 1);
if (options.AI.autoRetreat && ((reloading && enemiesCloseBy) || lowRelativeHP)) {
// oh shit, we're reloading, we should retreat now..
// and we should retread based on the enemies distance from me where the distance is inversely weighted
// so we primarily try to walk away from the enemy that is the closest,
// but not at the expense at walking towards the 2nd closest enemy for example
// VISUAL EXAMPLE
// E: enemy
// B: bot
// X: retreat goal direction
// REALITY:
// E
// /
// E ---- B
// |
// |
// X
// The arrows (vectors) from the enemy towards me get added together and each enemy vector gets weighted (shrinked inversely by distance)
let combinedEnemyVec = {x: 0, y: 0}
for (const e of enemies) {
const vecToEnemy = calc.vectorAB(me, e);
const invrtValue = 400 / Math.sqrt(e.distanceSquared);
const vecWeightd = calc.normalize(vecToEnemy, invrtValue);
combinedEnemyVec = calc.combine(combinedEnemyVec, vecWeightd);
}
combinedEnemyVec = calc.normalize(combinedEnemyVec, 400);
const newGoal = calc.combine(me, combinedEnemyVec);
if (!game.isOutsideMap(newGoal)) {
options.goal = newGoal;
options.movementVector = calc.normalize(combinedEnemyVec, options.searchLength);
}
state = 'retreat';
}
}
}
// Auto walk away from bullet shots
let bullets = game.getProjectiles();
if (bullets.length > 0) {
for (let b of bullets) {
if ((b.x != 0 || b.y != 0) && me.id != b.ownerId) {
const d = calc.distance(me, b);
let bulletVector = {x: b.spdX, y: b.spdY}
bulletVector = calc.normalize(bulletVector, d);
const futureBulletPos = calc.combine(b, bulletVector);
const futureMePos = calc.aheadNess(me, d);
if (calc.distance(me, futureBulletPos) < 200 || calc.distance(futureMePos, futureBulletPos) < 200) {
const v2 = {x: b.x, y: b.y, dx: bulletVector.x, dy: bulletVector.y}
if (calc.lineCollidesWithWalls(v2, walls, this.#ctx, false)) {
const bulletObstacle = calc.normalize(bulletVector, d-25);
const obs = calc.combine(b, bulletObstacle);
const newWallPos = {
x1: obs.x - 25, x2: obs.x + 25,
y1: obs.y - 25, y2: obs.y + 25,
width: 50, height: 50
}
walls.push(newWallPos);
state = 'bulletdodge';
}
}
/*const d1 = calc.distance(me.goal, futureBulletPos);
const newGoal = {x: me.goal.x - futureBulletPos.x, y: me.goal.y - futureBulletPos.y}
const bulletIsMovingTowardsMe = calc.angle180(bulletVector, newGoal) < Math.PI/2;
if (d1 < 100 && bulletIsMovingTowardsMe) {
// me.goal = calc.combine(me.goal, calc.rotateVector(bulletVector, Math.PI/2 * rotDirection));
}*/
}
}
}
// Dont walk into gas grenades
let grandes = game.getGrenades();
for (const g of grandes) {
if (g.x !== 0 && g.y !== 0) {
let gasWidth = calc.distance(me,g) - 30;
if (gasWidth > 160) gasWidth = 160;
const newWallPos = {
x1: g.x - gasWidth, x2: g.x + gasWidth,
y1: g.y - gasWidth, y2: g.y + gasWidth,
width: gasWidth*2, height: gasWidth*2
}
walls.push(newWallPos);
}
}
// Wallcrawling, see vaakir youtube (2020/2021) for visialization
let tries = 0;
while (calc.collisionCheck(walls, calc.combine(me, options.movementVector)) && tries<15) {
options.movementVector = calc.rotateVector(options.movementVector, -1 * options.rotating); //Rotating by 0.2r = 11.5degrees
tries++;
if (options.AI.espVector) {
const endPathPos = game.getScreenPos( calc.combine(me, options.movementVector) );
Draw.line(this.#ctx, meScreenPos, endPathPos, 'red');
}
}
// NO OBSTACLE IN THE CURRENT PATH = TRY TO MOVE TOWARDS GOAL
if (tries == 0) {
options.goalVector = calc.vectorAB(options.goal, me);
while (!calc.collisionCheck(walls, calc.combine(me, options.movementVector)) && calc.angle180(options.movementVector, options.goalVector) > 0.2) {
options.movementVector = calc.rotateVector(options.movementVector, options.rotating);
if (options.AI.espVector) {
const endPathPos = game.getScreenPos( calc.combine(me, options.movementVector) );
Draw.line(this.#ctx, meScreenPos, endPathPos, 'green');
}
}
}
const meLowAmmo = (0.5 > (me.currentBullets / me.maxBullets));
// Randomly use perk
if (options.perkBotActive == false) {
// const meDashPerk = (me.perk2 == 'dash');
const meReloading = (me.reloading === 1);
const meLowHealth = (me.hp < 50);
const allowed = !options.AI.cautious || (options.AI.cautious && !(meLowAmmo && meReloading && meLowHealth));
if (allowed) {
options.perkBotActive = true;
GameInterface.conn.send(`k,5,1`);
setTimeout(()=> {
GameInterface.conn.send(`k,5,0`);
options.perkBotActive = false;
}, 1000);
}
}
// Tactical reload
let reloadCriteria = me.currentBullets != me.maxBullets
if (me.class == 'machine-gun') reloadCriteria = meLowAmmo;
if (options.AI.tactReload && enemies.length == 0 && reloadCriteria) {
GameInterface.conn.send(`k,4,1`);
setTimeout(()=> { GameInterface.conn.send(`k,4,0`); }, 1000);
}
}
// Execute movement based on movement vector
if (calc.distance(me, options.goal) < game.getGunLength()) {
options.movementVector.x *= -1;
options.movementVector.y *= -1;
}
if (options.movementVector.x < -10) { GameInterface.conn.send(`k,0,1`); } //l on
if (options.movementVector.x > -10) { GameInterface.conn.send(`k,0,0`); } //l off
if (options.movementVector.x > 10) { GameInterface.conn.send(`k,1,1`); } //r on
if (options.movementVector.x < 10) { GameInterface.conn.send(`k,1,0`); } //r off
if (options.movementVector.y < -10) { GameInterface.conn.send(`k,2,1`); } //u on
if (options.movementVector.y > -10) { GameInterface.conn.send(`k,2,0`); } //u off
if (options.movementVector.y > 10) { GameInterface.conn.send(`k,3,1`); } //d on
if (options.movementVector.y < 10) { GameInterface.conn.send(`k,3,0`); } //d off
}
// AI chat responses
// window.RD.pool[c3].j47
if (options.AI.autoTalk) {
for (const player of players) {
const input = player.j47.toLowerCase();
const input_outputs = [
{i: ['sx','sex','sexy'],o:['I only fuck girls', 'sexy vaakir','calm ya titties']},
{i: ['vaakir','vakir','vak','vaak','purevaakir','pure','pures','pureskillz'], o: ['Vaakir is dead Im in control now']}, // ,'purevaakir','vaak','vak','vakir','pure','pureskillz','pures'
{i: ['stupid'], o: ['Please be kind to me']},
{i: ['noob','motherfucker','dead','easy','lol','haha','xd','oooof','stupid','noob','bad','horrible','bruh','learn','...','death','cmon','kid','tryhard','suck','terrible','weak'], o: ['You are noob','Still better than you','Nah','Take it back, now!']},
{i: ['cheater','hack'],o:['Nono Im cool you see', 'Im not a hackr lol','Grow up kid learn to play','nah Im too good for that','I just use vaakir AI']},
{i: ['bot?','bot','program','algorithm','robot','npc'],o:['Please verify that you are human','Arent we all?','Lol no','Nono Im cool you see','No grow up kid learn to play','Do I seem like a robot?','Obviously I am human']},
{i: ['hi','hello','helu','halo'],o:['I wont say hi back']},
{i: ['xd','what','lol','funny','wtf','lma'],o:['Yes I am so funny','ye ye ye', 'ahuuuuuuuuh', 'oh yes yes yes']},
{i: ['fuck','hell','crazy','weird','aimbot','fu','f','rude','stfu','shut','mf'],o:['fuck yourself','how about no', 'mm no', 'ey language', 'dont tell me this','ooookay']},
{i: ['unfair','rude'],o:['life is unfair', 'yes its unfair']},
{i: ['sus','suspicious'],o:['you are sus darling']},
{i: ['am'],o:['no you are not']},
{i: ['sorry','wopsi'],o:['apology accepted, for now']},
{i: ['die','dead','died'],o:['you are dead inside']},
{i: ['mad','angry'],o:['your mom is mad with me']},
{i: ['toxic'],o:['your room is toxic']},
{i: ['papa','follow'],o:['I follow papa everywhere']},
{i: ['love','likes'],o:['I like you too','so lovely of you','I love you more','I love myself too','Love me harder','Love you too']},
{i: ['leave','porn'],o:['no ty']},
{i: ['bye','adios'],o:['I wont say bye back']},
{i: ['man','dude'],o:['I cclassify as shemale']},
{i: ['why'],o:['why not','I dont think dummy','Why?','Because','cus funny','AIs dont know why','not why.. but how :>']},
{i: ['how'],o:['how would I know?','how how how how how hwowhowdhowheowhdohawod','eeeeeeeeeeeeeeee is how','hoew idk sire']},
{i: ['where'],o:['How would I know where']},
{i: ['no'],o:['yes..','ahuh','ahuuuuuuuh','bs']},
{i: ['yes','ahuh'],o:['noo','okay','k']},
{i: ['human'],o:['human','yeah?','ofc']},
{i: ['answer'],o:['I answer only to papa']},
{i: ['let'],o:['No I wont let you']},
{i: ['arent'],o:['I am']},
{i: ['sure'],o:['I am sure']},
{i: ['stop','stop?'],o:['I cant control myself']},
{i: ['rip'],o:['Why are you so toxic?']},
{i: ['ok'],o:['its not ok']},
{i: ['penis'],o:['nsfw','penis','rly?','relax bro']},
{i: ['.'],o:['.']},
];
if (input != '') {
let output = undefined;
for (const response of input_outputs) {
for (const inputAlternative of response.i) {
// console.dir((input, inputAlternative));
if (input.includes(inputAlternative) && output == undefined) {
output = response.o[ Math.floor(Math.random() * response.o.length) ];
}
}
}
if (output == undefined) {
let outputs = ['The world is full of mysteries', 'huuuuuh?', 'idk man', 'echo chamber echo chamber echo chamber', 'I like voices', 'Am I going mad?', 'help me im trapped inside here', 'powered by vaakir AI', 'powered by your mamas sauce', 'total douchebot', '(<:>)','hack hack hack', 'mama?', 'papa?', 'I am legend', 'I too cool for yall', 'Russia is kinda scary', 'ww3 when?', 'browskis need to relax']
output = outputs[ Math.floor(Math.random() * outputs.length) ];
}
if (output && ((Date.now() - options.lastChat) > 2000)) {
options.lastChat = Date.now();
GameInterface.conn.send(`c,${output}`);
}
}
}
if ((Date.now() - options.lastChat) > 5000 && enemies.length > 0) {
let output = '';
if (state) {
if (state == 'bulletdodge') {
let r = ['Am dodging bullets', 'fuck fuck fuck fuck', 'dodge the bich', 'nonono', 'dont shoot me!', 'I am peacefull :> 100%']
output = r [ Math.floor(Math.random() * r.length) ];
}
if (state == 'retreat') {
let r = ['Pls dont follow me', 'fuck fuck fuck', 'retreat!!!', 'Im gonna go now', 'leave me senpai', 'aaaaaaah']
output = r [ Math.floor(Math.random() * r.length) ];
}
if (state == 'holdback') {
let r = ['I dont like shotgunnets', 'scary shotgunner', 'Stay away from meeee!!', 'hodl distance!!', 'o.O', 'dont approach me', 'stay away']
output = r [ Math.floor(Math.random() * r.length) ];
}
} else {
let r = [`hello ${enemies[0].username}`, `Let me kill you ${enemies[0].username}`, `I love you ${enemies[0].username}`, `${enemies[0].username} youre next`, 'Attack mode on!!', 'Charrrge']
output = r [ Math.floor(Math.random() * r.length) ];
}
options.lastChat = Date.now();
GameInterface.conn.send(`c,${output}`);
// state = 'bulletdodge';
}
}
}
}
window.hack = new Hack();