ESP + Aimlock
// ==UserScript==
// @name Evowars Xit - AIM + ESP
// @version 2.3.2
// @description ESP + Aimlock
// @author NlongCodedao
// @match *://evowars.io/*
// @run-at document-start
// @grant none
// @namespace https://greasyfork.org/users/1573841
// ==/UserScript==
(function() {
'use strict';
const config = {
CIRCLE_SIZE_FACTOR: 1.7,
CIRCLE_FILL: "rgba(255, 255, 0, 0.3)",
CIRCLE_BORDER: "#ffff00",
TRACER: "#ffffff",
FONT: "#ffffff",
SHOW_CIRCLE: true,
SHOW_TRACER: true,
SHOW_NAMES: true,
SHOW_SCORES: true,
SHOW_FOV: true,
FOV_FILL: "rgba(0, 255, 0, 0.08)",
FOV_BORDER: "#00ff00",
FOV_LINE_WIDTH: 4,
SWORD_LENGTH_FACTOR: 2.1,
FOV_EXTRA_OFFSET: 0.4,
SHOW_FOV_COUNT: true,
};
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
let rt, pType, gameCanvas;
let mouseOverlay = null;
let holdingG = false;
let lockedTarget = null;
let fixedTiltDx = 0;
let fixedTiltDy = 0;
let hasFixedTilt = false;
let lastMouseX = window.innerWidth / 2;
let lastMouseY = window.innerHeight / 2;
let aimLockEnabled = true; // Mặc định bật
const TILT_DISTANCE = 400;
// GUI Variables
let guiVisible = true;
let guiDiv = null;
let isDragging = false;
let offsetX, offsetY;
// Tạo GUI
function createGUI() {
if (guiDiv) return;
guiDiv = document.createElement('div');
guiDiv.id = 'evowars-xit-gui';
guiDiv.style.cssText = `
position: fixed; top: 20px; right: 20px; width: 220px; padding: 10px;
background: rgba(0,0,0,0.7); color: #0f0; border: 2px solid #0f0;
border-radius: 8px; font-family: Arial; font-size: 13px; z-index: 999998;
cursor: move; user-select: none; box-shadow: 0 0 10px #0f0;
`;
guiDiv.innerHTML = `
<div style="font-weight:bold; text-align:center; margin-bottom:8px;">Evowars Xit</div>
<label style="display:flex; align-items:center; margin:6px 0;">
<input type="checkbox" id="aimlock-checkbox" checked style="margin-right:8px;">
Aim Lock
</label>
<div id="status-box" style="height:30px; background:#111; border:1px solid #0f0; margin:8px 0; text-align:center; line-height:30px; font-weight:bold;">
HOLD G: OFF
</div>
<div style="text-align:center; font-size:11px; color:#0f0; margin-top:8px;">
Cre: NlongCodedao
</div>
`;
document.body.appendChild(guiDiv);
// Checkbox control
const checkbox = guiDiv.querySelector('#aimlock-checkbox');
checkbox.addEventListener('change', (e) => {
aimLockEnabled = e.target.checked;
if (!aimLockEnabled && holdingG) {
// Nếu tắt khi đang hold G → reset ngay
holdingG = false;
lockedTarget = null;
hasFixedTilt = false;
fixedTiltDx = 0;
fixedTiltDy = 0;
aimLoop.stop();
cleanupMouse();
updateGUIStatus();
}
});
// Draggable GUI
guiDiv.addEventListener('mousedown', (e) => {
if (e.target.tagName === 'INPUT') return;
isDragging = true;
offsetX = e.clientX - guiDiv.getBoundingClientRect().left;
offsetY = e.clientY - guiDiv.getBoundingClientRect().top;
guiDiv.style.cursor = 'grabbing';
});
document.addEventListener('mousemove', (e) => {
if (!isDragging) return;
guiDiv.style.left = (e.clientX - offsetX) + 'px';
guiDiv.style.top = (e.clientY - offsetY) + 'px';
guiDiv.style.right = 'auto';
});
document.addEventListener('mouseup', () => {
isDragging = false;
guiDiv.style.cursor = 'move';
});
// Bật/tắt GUI bằng Insert
document.addEventListener('keydown', (e) => {
if (e.key === 'Insert') {
guiVisible = !guiVisible;
guiDiv.style.display = guiVisible ? 'block' : 'none';
}
});
}
function updateGUIStatus() {
if (!guiDiv) return;
const statusBox = guiDiv.querySelector('#status-box');
if (holdingG && aimLockEnabled) {
statusBox.textContent = 'HOLD G: ON';
statusBox.style.background = 'rgba(0,255,0,0.3)';
statusBox.style.color = '#000';
} else {
statusBox.textContent = 'HOLD G: OFF';
statusBox.style.background = '#111';
statusBox.style.color = '#0f0';
}
}
document.addEventListener('mousemove', (e) => {
lastMouseX = e.clientX;
lastMouseY = e.clientY;
});
document.addEventListener('keydown', (e) => {
if (e.key.toLowerCase() === 'g' && aimLockEnabled) {
if (!holdingG) {
const self = getSelf();
if (self) {
lockedTarget = getClosestToMouse(self);
if (lockedTarget) fixTiltDirection(self);
}
holdingG = true;
createMouseOverlay();
aimLoop.start();
updateGUIStatus();
}
}
});
document.addEventListener('keyup', (e) => {
if (e.key.toLowerCase() === 'g') {
holdingG = false;
lockedTarget = null;
hasFixedTilt = false;
fixedTiltDx = 0;
fixedTiltDy = 0;
aimLoop.stop();
cleanupMouse();
updateGUIStatus();
}
});
const aimLoop = {
interval: null,
start: function() { if (!this.interval) this.interval = setInterval(aimUpdate, 16); },
stop: function() { if (this.interval) { clearInterval(this.interval); this.interval = null; } }
};
const aimUpdate = () => {
if (!holdingG || !lockedTarget) return;
const self = getSelf();
if (!self || !lockedTarget.layer) return;
const rect = gameCanvas.getBoundingClientRect();
const viewX = rect.left + rect.width / 2;
const viewY = rect.top + rect.height / 2;
const targetMouseX = viewX + fixedTiltDx * TILT_DISTANCE;
const targetMouseY = viewY + fixedTiltDy * TILT_DISTANCE;
const event = new MouseEvent('mousemove', {
clientX: targetMouseX, clientY: targetMouseY,
bubbles: true, cancelable: true, view: window
});
[document, gameCanvas].forEach(el => el.dispatchEvent(event));
};
const createMouseOverlay = () => {
if (mouseOverlay) return;
mouseOverlay = document.createElement('div');
mouseOverlay.style.cssText = 'position:fixed;top:0;left:0;width:100vw;height:100vh;background:transparent;z-index:999999;pointer-events:auto;cursor:none;';
document.body.appendChild(mouseOverlay);
mouseOverlay.addEventListener('mousemove', (e) => {
e.preventDefault();
e.stopImmediatePropagation();
return false;
}, { capture: true, passive: false });
updateOverlaySize();
window.addEventListener('resize', updateOverlaySize);
};
const removeMouseOverlay = () => {
if (mouseOverlay) {
document.body.removeChild(mouseOverlay);
mouseOverlay = null;
window.removeEventListener('resize', updateOverlaySize);
}
};
const updateOverlaySize = () => {
if (mouseOverlay) {
mouseOverlay.style.width = window.innerWidth + 'px';
mouseOverlay.style.height = window.innerHeight + 'px';
}
};
const cleanupMouse = () => {
removeMouseOverlay();
document.body.offsetHeight;
const fakeEvent = new MouseEvent('mousemove', {
clientX: lastMouseX,
clientY: lastMouseY,
bubbles: true,
cancelable: true,
view: window
});
document.dispatchEvent(fakeEvent);
if (gameCanvas) gameCanvas.dispatchEvent(fakeEvent);
requestAnimationFrame(() => {
document.dispatchEvent(fakeEvent);
});
};
const fixTiltDirection = (self) => {
if (!self || !lockedTarget) return;
let dx = lockedTarget.x - self.x;
let dy = lockedTarget.y - self.y;
const len = Math.hypot(dx, dy) || 1;
dx /= len; dy /= len;
const angle = 135 * Math.PI / 180;
const cos = Math.cos(angle);
const sin = Math.sin(angle);
fixedTiltDx = dx * cos - dy * sin;
fixedTiltDy = dx * sin + dy * cos;
hasFixedTilt = true;
};
const getSelf = () => {
if (!rt || !rt.running_layout || !pType) return null;
let self = null;
let min_d = Infinity;
for (const p of pType.instances) {
const d = Math.hypot(p.x - rt.running_layout.scrollX, p.y - rt.running_layout.scrollY);
if (d < min_d) { min_d = d; self = p; }
}
return self;
};
const getClosestToMouse = (self) => {
if (!self) return null;
let target = null;
let minDist = Infinity;
const rect = gameCanvas.getBoundingClientRect();
const viewX = rect.left + rect.width / 2;
const viewY = rect.top + rect.height / 2;
const scale = self.layer.getScale();
for (const p of pType.instances) {
if (p.uid === self.uid) continue;
const screenX = viewX + (p.x - self.x) * scale;
const screenY = viewY + (p.y - self.y) * scale;
const distToMouse = Math.hypot(screenX - lastMouseX, screenY - lastMouseY);
if (distToMouse < minDist) { minDist = distToMouse; target = p; }
}
return target;
};
const setup = () => {
document.body.appendChild(canvas);
canvas.style.cssText = 'position:fixed;top:0;left:0;width:100%;height:100%;pointer-events:none;z-index:1000;';
window.addEventListener('resize', () => {
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
});
window.dispatchEvent(new Event('resize'));
createGUI();
};
const draw = () => {
if (!rt || !rt.running_layout || !pType) return;
const self = getSelf();
if (!self) return;
ctx.clearRect(0, 0, canvas.width, canvas.height);
const rect = gameCanvas.getBoundingClientRect();
const viewX = rect.left + rect.width / 2;
const viewY = rect.top + rect.height / 2;
const scale = self.layer.getScale();
if (config.SHOW_FOV) {
const baseRadius = (self.width / 2) * scale * config.SWORD_LENGTH_FACTOR;
const fovRadius = baseRadius * (1 + config.FOV_EXTRA_OFFSET);
ctx.beginPath();
ctx.arc(viewX, viewY, fovRadius, 0, 2 * Math.PI);
ctx.fillStyle = config.FOV_FILL;
ctx.fill();
ctx.strokeStyle = config.FOV_BORDER;
ctx.lineWidth = config.FOV_LINE_WIDTH;
ctx.stroke();
if (config.SHOW_FOV_COUNT) {
let count = 0;
for (const p of pType.instances) {
if (p.uid === self.uid) continue;
const pX = viewX + (p.x - self.x) * scale;
const pY = viewY + (p.y - self.y) * scale;
if (Math.hypot(pX - viewX, pY - viewY) <= fovRadius) count++;
}
ctx.font = "bold 22px Arial";
ctx.textAlign = 'center';
ctx.fillStyle = config.FOV_BORDER;
ctx.fillText(`${count}`, viewX, viewY + 8);
}
}
for (const p of pType.instances) {
if (p.uid === self.uid) continue;
const pX = viewX + (p.x - self.x) * scale;
const pY = viewY + (p.y - self.y) * scale;
const isLocked = lockedTarget && p.uid === lockedTarget.uid;
if (config.SHOW_CIRCLE) {
const radius = (p.width / 2) * scale * config.CIRCLE_SIZE_FACTOR;
ctx.beginPath();
ctx.arc(pX, pY, radius, 0, 2 * Math.PI);
ctx.fillStyle = isLocked ? "rgba(128, 0, 128, 0.4)" : config.CIRCLE_FILL;
ctx.fill();
ctx.strokeStyle = isLocked ? "#9932cc" : config.CIRCLE_BORDER;
ctx.lineWidth = isLocked ? 4 : 1;
ctx.stroke();
}
if (config.SHOW_TRACER) {
ctx.beginPath();
ctx.moveTo(viewX, viewY);
ctx.lineTo(pX, pY);
ctx.strokeStyle = isLocked ? "#9932cc" : config.TRACER;
ctx.lineWidth = isLocked ? 5 : 2;
ctx.stroke();
}
const name = p.instance_vars[18] || '';
const score = p.instance_vars[20] || 0;
const text = `${config.SHOW_NAMES ? name : ''} ${config.SHOW_SCORES ? '[' + score + ']' : ''}`.trim();
if (text) {
ctx.font = isLocked ? "bold 15px Arial" : "bold 12px Arial";
ctx.textAlign = 'center';
ctx.fillStyle = isLocked ? "#9932cc" : config.FONT;
const textY = pY - ((p.width / 2) * scale * config.CIRCLE_SIZE_FACTOR) - 5;
ctx.fillText(text, pX, textY);
if (isLocked) ctx.fillText("TILT 135°", pX, textY + 18);
}
}
};
const mainLoop = () => {
try { if (rt && rt.running_layout) draw(); } catch (e) {}
requestAnimationFrame(mainLoop);
};
const init = setInterval(() => {
if (window.cr_getC2Runtime && (rt = window.cr_getC2Runtime())) {
clearInterval(init);
gameCanvas = rt.canvas;
for (const type of rt.types_by_index) {
if (type && type.instvar_sids && type.instvar_sids.length === 72) {
pType = type;
break;
}
}
setup();
mainLoop();
console.log("Evowars Xit activated! (Aim Lock checkbox in GUI)");
}
}, 100);
})();