Premium external overlay for Deadshot.io — Aimbot, ESP, Prediction, TriggerBot
// ==UserScript==
// @name Destiny V2
// @namespace http://tampermonkey.net/
// @version 2.5
// @description Premium external overlay for Deadshot.io — Aimbot, ESP, Prediction, TriggerBot
// @match *://*deadshot.io/*
// @grant none
// @run-at document-start
// @license MIT
// ==/UserScript==
(function() {
'use strict';
const defaultConfig = {
aimbotEnabled: true,
aimSmooth: 1.5,
lockDist: 40,
hitbox: 0,
priority: 1,
randomize: false,
espEnabled: true,
fov: 100,
showFov: false,
showCrosshair: false,
menuKey: "Insert",
accentColor: "#a855f7",
menuVisible: true,
x: 100,
y: 100,
predictionEnabled: true,
predictionStrength: 2.0,
velocityTracking: true,
showDistance: true,
showTracers: false,
espThickness: 2,
triggerBot: false,
triggerDelay: 100,
fovGradient: true,
performanceMode: false,
showFPS: true,
showStats: true,
antiAFK: false,
aimKey: "RightClick",
smoothCurve: "ease",
targetLock: false,
lockTime: 2000,
visibilityCheck: true,
blockFullscreen: false
};
let config = { ...defaultConfig };
const saved = localStorage.getItem("destiny_v1_config");
if (saved) {
try { config = { ...config, ...JSON.parse(saved) }; } catch (e) {}
}
let _saveTimer = null;
function save() {
if (_saveTimer) clearTimeout(_saveTimer);
_saveTimer = setTimeout(() => {
localStorage.setItem("destiny_v1_config", JSON.stringify(config));
}, 200);
}
function saveImmediate() {
if (_saveTimer) clearTimeout(_saveTimer);
localStorage.setItem("destiny_v1_config", JSON.stringify(config));
}
function setupFullscreenBlocker() {
if (!config.blockFullscreen) return;
const block = () => Promise.resolve();
['requestFullscreen','webkitRequestFullscreen','mozRequestFullScreen','msRequestFullscreen'].forEach(fn => {
if (Element.prototype[fn]) Element.prototype[fn] = block;
});
}
setupFullscreenBlocker();
// =================================================================
// TRACKING STATE
// =================================================================
const state = {
targetID: -1,
programCounter: 0,
modelMatrices: [],
vpMatrices: [],
input: {left:false, right:false},
accX: 0, accY: 0,
lastPositions: new Map(),
deadPositions: new Map(),
velocities: new Map(),
lockedTarget: null,
lockStartTime: 0,
fps: 0,
frameCount: 0,
lastFPSUpdate: Date.now(),
totalTargets: 0,
hitCount: 0,
missCount: 0,
recoilPattern: [],
currentRecoilIndex: 0,
lastMouseMove: Date.now(),
lastTriggerFire: 0,
overlayCtx: null
};
// =================================================================
// GUI
// =================================================================
let currentTab = 'aimbot';
const CSS = `
#d-ui *{box-sizing:border-box;margin:0;padding:0}
#d-ui{position:fixed;width:280px;background:#0c0c0f;border:1px solid #1e1e24;border-radius:10px;font-family:'Segoe UI',system-ui,sans-serif;color:#c8c8d0;z-index:2147483646;user-select:none;box-shadow:0 8px 32px rgba(0,0,0,.6);overflow:hidden}
#d-ui .d-head{padding:10px 14px;cursor:move;display:flex;justify-content:space-between;align-items:center;border-bottom:1px solid #1e1e24;background:#0e0e12}
#d-ui .d-brand{font-size:13px;font-weight:700;letter-spacing:1.5px;background:linear-gradient(135deg,${config.accentColor},${config.accentColor}99);-webkit-background-clip:text;-webkit-text-fill-color:transparent}
#d-ui .d-ver{font-size:9px;color:#555;font-family:monospace}
#d-ui .d-tabs{display:flex;gap:2px;padding:6px 10px;background:#0a0a0d;border-bottom:1px solid #1e1e24}
#d-ui .d-tab{flex:1;text-align:center;padding:5px 0;font-size:10px;font-weight:600;letter-spacing:.5px;color:#555;cursor:pointer;border-radius:6px;transition:all .15s}
#d-ui .d-tab:hover{color:#888;background:#151518}
#d-ui .d-tab.active{color:${config.accentColor};background:#1a1a20}
#d-ui .d-body{padding:10px 12px;max-height:380px;overflow-y:auto;scrollbar-width:thin;scrollbar-color:#222 transparent}
#d-ui .d-body::-webkit-scrollbar{width:3px}
#d-ui .d-body::-webkit-scrollbar-thumb{background:#333;border-radius:3px}
#d-ui .d-section{font-size:9px;font-weight:600;letter-spacing:1px;color:#444;text-transform:uppercase;margin:10px 0 6px;padding-bottom:4px;border-bottom:1px solid #1a1a1e}
#d-ui .d-section:first-child{margin-top:2px}
#d-ui .d-row{display:flex;align-items:center;justify-content:space-between;padding:5px 0}
#d-ui .d-row span{font-size:11px;color:#aaa}
#d-ui .d-toggle{position:relative;width:32px;height:16px;cursor:pointer;display:inline-block;flex-shrink:0}
#d-ui .d-toggle input{opacity:0;width:0;height:0;position:absolute}
#d-ui .d-toggle .slider{position:absolute;inset:0;background:#222;border-radius:10px;transition:all .2s}
#d-ui .d-toggle .slider:before{content:'';position:absolute;width:12px;height:12px;left:2px;top:2px;background:#555;border-radius:50%;transition:all .2s}
#d-ui .d-toggle input:checked+.slider{background:${config.accentColor}30}
#d-ui .d-toggle input:checked+.slider:before{transform:translateX(16px);background:${config.accentColor}}
#d-ui .d-slider-row{padding:4px 0}
#d-ui .d-slider-label{display:flex;justify-content:space-between;font-size:10px;color:#666;margin-bottom:3px}
#d-ui .d-slider-label span:last-child{color:#aaa;font-family:monospace;font-size:10px}
#d-ui input[type=range]{-webkit-appearance:none;width:100%;height:3px;background:#1e1e24;border-radius:3px;outline:none}
#d-ui input[type=range]::-webkit-slider-thumb{-webkit-appearance:none;width:10px;height:10px;background:${config.accentColor};border-radius:50%;cursor:pointer;border:none}
#d-ui select{width:100%;background:#141418;color:#aaa;border:1px solid #1e1e24;padding:5px 8px;border-radius:6px;font-size:10px;outline:none;cursor:pointer}
#d-ui select:focus{border-color:${config.accentColor}40}
#d-ui .d-select-row{padding:4px 0}
#d-ui .d-select-label{font-size:10px;color:#666;margin-bottom:3px}
#d-ui .d-btn{width:100%;padding:7px;background:#141418;color:${config.accentColor};border:1px solid #1e1e24;border-radius:6px;cursor:pointer;font-size:10px;font-weight:600;letter-spacing:.5px;transition:all .15s}
#d-ui .d-btn:hover{background:#1a1a20;border-color:${config.accentColor}40}
#d-ui .d-stat-grid{display:grid;grid-template-columns:1fr 1fr 1fr;gap:6px;margin-top:4px}
#d-ui .d-stat{background:#111114;border-radius:6px;padding:8px;text-align:center;border:1px solid #1a1a1e}
#d-ui .d-stat-val{font-size:16px;font-weight:700;color:${config.accentColor};font-family:monospace}
#d-ui .d-stat-lbl{font-size:8px;color:#555;text-transform:uppercase;letter-spacing:.5px;margin-top:2px}
#d-ui .d-footer{padding:6px 12px;border-top:1px solid #1e1e24;display:flex;justify-content:space-between;align-items:center;background:#0a0a0d}
#d-ui .d-footer span{font-size:9px;color:#333;font-family:monospace}
#d-ui .d-id-bar{display:flex;align-items:center;gap:6px;background:#111114;border-radius:6px;padding:6px 10px;margin-top:6px;border:1px solid #1a1a1e}
#d-ui .d-id-bar .lbl{font-size:9px;color:#555;text-transform:uppercase;letter-spacing:.5px}
#d-ui .d-id-bar .val{font-size:14px;font-weight:700;color:${config.accentColor};font-family:monospace;min-width:24px;text-align:center}
#d-ui .d-id-bar .hint{font-size:8px;color:#333;margin-left:auto;font-family:monospace}
`;
function toggle(id, label, checked) {
return `<div class="d-row"><span>${label}</span><label class="d-toggle"><input type="checkbox" id="${id}" ${checked?'checked':''}><span class="slider"></span></label></div>`;
}
function slider(id, label, valId, val, min, max, step) {
return `<div class="d-slider-row"><div class="d-slider-label"><span>${label}</span><span id="${valId}">${val}</span></div><input type="range" id="${id}" min="${min}" max="${max}" step="${step}" value="${val}"></div>`;
}
function selectBox(id, label, options, current) {
const opts = options.map(o => `<option value="${o.v}" ${current===o.v?'selected':''}>${o.l}</option>`).join('');
return `<div class="d-select-row"><div class="d-select-label">${label}</div><select id="${id}">${opts}</select></div>`;
}
function getTabContent() {
if (currentTab === 'aimbot') {
return `
<div class="d-section">Targeting</div>
${toggle('chk-aim','Aimbot',config.aimbotEnabled)}
${slider('sld-smooth','Smoothing','val-smooth',config.aimSmooth,1,10,0.1)}
${toggle('chk-pred','Prediction',config.predictionEnabled)}
${slider('sld-pred','Pred. Strength','val-pred',config.predictionStrength,0.5,3,0.1)}
<div style="display:flex;gap:6px;padding:4px 0">
<div style="flex:1">${selectBox('sel-bone','Hitbox',[{v:0,l:'Head'},{v:1,l:'Neck'},{v:2,l:'Body'}],config.hitbox)}</div>
<div style="flex:1">${selectBox('sel-prio','Priority',[{v:1,l:'Crosshair'},{v:0,l:'Distance'}],config.priority)}</div>
</div>
<div class="d-section">Automation</div>
${toggle('chk-trigger','TriggerBot',config.triggerBot)}
${toggle('chk-lock','Target Lock',config.targetLock)}
<div class="d-id-bar">
<span class="lbl">Target ID</span>
<span class="val" id="id-disp">${state.targetID}</span>
<span class="hint">Arrow Keys</span>
</div>
`;
} else if (currentTab === 'visuals') {
return `
<div class="d-section">ESP</div>
${toggle('chk-esp','Box ESP',config.espEnabled)}
${toggle('chk-dist','Distance',config.showDistance)}
${toggle('chk-tracers','Tracers',config.showTracers)}
${slider('sld-thick','Box Thickness','val-thick',config.espThickness,1,5,0.5)}
<div class="d-section">Overlay</div>
${toggle('chk-fov','FOV Circle',config.showFov)}
${toggle('chk-gradient','FOV Gradient',config.fovGradient)}
${slider('sld-fov','FOV Radius','val-fov',config.fov,50,600,10)}
${toggle('chk-crosshair','Crosshair',config.showCrosshair)}
${toggle('chk-fps','Show FPS',config.showFPS)}
`;
} else if (currentTab === 'config') {
return `
<div class="d-section">Engine</div>
${toggle('chk-velocity','Velocity Tracking',config.velocityTracking)}
${toggle('chk-visibility','Visibility Check',config.visibilityCheck)}
${toggle('chk-perfmode','Performance Mode',config.performanceMode)}
${selectBox('sel-curve','Smooth Curve',[{v:'linear',l:'Linear'},{v:'ease',l:'Ease'},{v:'exponential',l:'Exponential'}],config.smoothCurve)}
<div class="d-section">Misc</div>
${toggle('chk-afk','Anti-AFK',config.antiAFK)}
${toggle('chk-blockfs','Block Fullscreen',config.blockFullscreen)}
<div class="d-section">Stats</div>
<div class="d-stat-grid">
<div class="d-stat"><div class="d-stat-val" id="stat-fps">${state.fps}</div><div class="d-stat-lbl">FPS</div></div>
<div class="d-stat"><div class="d-stat-val" id="stat-targets">${state.totalTargets}</div><div class="d-stat-lbl">Targets</div></div>
<div class="d-stat"><div class="d-stat-val" id="stat-accuracy">${state.hitCount+state.missCount>0?Math.round(state.hitCount/(state.hitCount+state.missCount)*100):0}%</div><div class="d-stat-lbl">Accuracy</div></div>
</div>
<div style="margin-top:10px"><button class="d-btn" id="btn-reset">Reset All Settings</button></div>
`;
}
return '';
}
function createGUI() {
if (document.getElementById('d-ui')) return;
const style = document.createElement('style');
style.textContent = CSS;
document.head.appendChild(style);
const div = document.createElement('div');
div.id = 'd-ui';
div.style.top = config.y + 'px';
div.style.left = config.x + 'px';
div.style.display = config.menuVisible ? 'block' : 'none';
div.innerHTML = `
<div class="d-head" id="d-header">
<span class="d-brand">DESTINY</span>
<span class="d-ver">v2.3</span>
</div>
<div class="d-tabs">
<div class="d-tab${currentTab==='aimbot'?' active':''}" data-tab="aimbot">AIMBOT</div>
<div class="d-tab${currentTab==='visuals'?' active':''}" data-tab="visuals">VISUALS</div>
<div class="d-tab${currentTab==='config'?' active':''}" data-tab="config">CONFIG</div>
</div>
<div class="d-body" id="tab-content">${getTabContent()}</div>
<div class="d-footer"><span>INS to toggle</span><span>deadshot.io</span></div>
`;
document.body.appendChild(div);
// Drag
const header = document.getElementById('d-header');
let dragging = false, ox, oy;
header.onmousedown = e => { dragging=true; ox=e.clientX-div.offsetLeft; oy=e.clientY-div.offsetTop; e.preventDefault(); };
window.addEventListener('mousemove', e => { if(dragging){const x=e.clientX-ox,y=e.clientY-oy;div.style.left=x+'px';div.style.top=y+'px';config.x=x;config.y=y;} });
window.addEventListener('mouseup', () => { if(dragging) save(); dragging=false; });
// Tabs
div.querySelectorAll('.d-tab').forEach(btn => {
btn.onclick = () => { currentTab = btn.dataset.tab; refreshGUI(); };
});
attachEventHandlers();
}
function refreshGUI() {
const content = document.getElementById('tab-content');
if (content) content.innerHTML = getTabContent();
const ui = document.getElementById('d-ui');
if (ui) {
ui.querySelectorAll('.d-tab').forEach(btn => {
btn.classList.toggle('active', btn.dataset.tab === currentTab);
btn.onclick = () => { currentTab = btn.dataset.tab; refreshGUI(); };
});
}
attachEventHandlers();
}
function attachEventHandlers() {
const handlers = {
'chk-aim': e => { config.aimbotEnabled = e.target.checked; save(); },
'chk-esp': e => { config.espEnabled = e.target.checked; save(); },
'chk-fov': e => { config.showFov = e.target.checked; save(); },
'chk-crosshair': e => { config.showCrosshair = e.target.checked; save(); },
'chk-pred': e => { config.predictionEnabled = e.target.checked; save(); },
'chk-trigger': e => { config.triggerBot = e.target.checked; save(); },
'chk-lock': e => { config.targetLock = e.target.checked; save(); },
'chk-dist': e => { config.showDistance = e.target.checked; save(); },
'chk-tracers': e => { config.showTracers = e.target.checked; save(); },
'chk-gradient': e => { config.fovGradient = e.target.checked; save(); },
'chk-velocity': e => { config.velocityTracking = e.target.checked; save(); },
'chk-visibility': e => { config.visibilityCheck = e.target.checked; save(); },
'chk-afk': e => { config.antiAFK = e.target.checked; save(); },
'chk-blockfs': e => {
config.blockFullscreen = e.target.checked;
saveImmediate();
if(confirm('Reload to apply fullscreen setting?')) location.reload();
},
'chk-fps': e => { config.showFPS = e.target.checked; save(); },
'chk-perfmode': e => { config.performanceMode = e.target.checked; save(); },
'sld-smooth': e => { config.aimSmooth = parseFloat(e.target.value); const el = document.getElementById('val-smooth'); if(el) el.innerText = config.aimSmooth; save(); },
'sld-fov': e => { config.fov = parseInt(e.target.value); const el = document.getElementById('val-fov'); if(el) el.innerText = config.fov; save(); },
'sld-pred': e => { config.predictionStrength = parseFloat(e.target.value); const el = document.getElementById('val-pred'); if(el) el.innerText = config.predictionStrength; save(); },
'sld-thick': e => { config.espThickness = parseFloat(e.target.value); const el = document.getElementById('val-thick'); if(el) el.innerText = config.espThickness; save(); },
'sel-prio': e => { config.priority = parseInt(e.target.value); save(); },
'sel-bone': e => { config.hitbox = parseInt(e.target.value); save(); },
'sel-curve': e => { config.smoothCurve = e.target.value; save(); },
'btn-reset': () => {
if(confirm('Reset all settings?')) {
config = {...defaultConfig};
saveImmediate();
refreshGUI();
}
}
};
Object.keys(handlers).forEach(id => {
const el = document.getElementById(id);
if (el) {
if (el.tagName === 'INPUT' && el.type === 'range') el.oninput = handlers[id];
else if (el.tagName === 'BUTTON') el.onclick = handlers[id];
else if (el.tagName === 'INPUT' && el.type === 'checkbox') el.onclick = handlers[id];
else el.onchange = handlers[id];
}
});
}
// =================================================================
// KEYBOARD
// =================================================================
document.addEventListener('keydown', (e) => {
if (e.code === 'Insert' || e.code === 'Delete') {
config.menuVisible = !config.menuVisible;
const el = document.getElementById('d-ui');
if (el) el.style.display = config.menuVisible ? 'block' : 'none';
saveImmediate();
e.preventDefault();
e.stopImmediatePropagation();
}
if (e.code === 'ArrowRight') {
state.targetID++;
updateID();
e.preventDefault();
e.stopImmediatePropagation();
}
if (e.code === 'ArrowLeft') {
state.targetID--;
updateID();
e.preventDefault();
e.stopImmediatePropagation();
}
}, true);
function updateID() {
state.modelMatrices = [];
const el = document.getElementById('id-disp');
if (el) el.innerText = state.targetID;
}
window.addEventListener('mousedown', e => { if(e.button===0) state.input.left=true; if(e.button===2) state.input.right=true; });
window.addEventListener('mouseup', e => { if(e.button===0) state.input.left=false; if(e.button===2) state.input.right=false; });
// =================================================================
// WEBGL HOOK
// =================================================================
const originalGetContext = HTMLCanvasElement.prototype.getContext;
const proxyCache = new WeakMap();
const programMap = new WeakMap();
function spoof(fake, real) {
Object.defineProperty(fake, 'name', { value: real.name, configurable: true });
Object.defineProperty(fake, 'toString', { value: () => real.toString(), configurable: true });
return fake;
}
HTMLCanvasElement.prototype.getContext = spoof(function(type, options) {
const ctx = originalGetContext.call(this, type, options);
if (!ctx || (type !== 'webgl' && type !== 'webgl2')) return ctx;
if (proxyCache.has(ctx)) return proxyCache.get(ctx);
const handler = {
get(target, prop) {
const val = target[prop];
if (typeof val === 'function') {
if (prop === 'uniformMatrix4fv') {
return function(location, transpose, value) {
if (value && value.length === 16) {
if (Math.abs(value[11] + 1) < 0.1 && Math.abs(value[15]) < 0.1) {
if (state.vpMatrices.length > 3) state.vpMatrices.shift();
state.vpMatrices.push(new Float32Array(value));
}
const gl = target;
const pid = programMap.get(gl.getParameter(gl.CURRENT_PROGRAM));
if (pid === state.targetID) {
if (Math.abs(value[3]) < 1e-6 &&
Math.abs(value[7]) < 1e-6 &&
Math.abs(value[15] - 1) < 1e-6 &&
state.modelMatrices.length < 100) {
state.modelMatrices.push(new Float32Array(value));
}
}
}
return val.apply(target, arguments);
}
}
if (prop === 'useProgram') {
return function(program) {
if (program && !programMap.has(program)) programMap.set(program, state.programCounter++);
return val.apply(target, arguments);
}
}
if (prop === 'drawElements') {
return function(mode, count, type, offset) {
const gl = target;
const pid = programMap.get(gl.getParameter(gl.CURRENT_PROGRAM));
if (config.aimbotEnabled && config.espEnabled && pid === state.targetID) gl.disable(gl.DEPTH_TEST);
const res = val.apply(target, arguments);
if (config.aimbotEnabled && config.espEnabled && pid === state.targetID) gl.enable(gl.DEPTH_TEST);
return res;
}
}
return val.bind(target);
}
return val;
}
};
const proxied = new Proxy(ctx, handler);
proxyCache.set(ctx, proxied);
return proxied;
}, originalGetContext);
function setupCanvas() {
const canvas = document.createElement('canvas');
canvas.id = 'destiny-overlay-canvas';
canvas.style.cssText = "position:fixed;top:0;left:0;width:100vw;height:100vh;z-index:2147483646;pointer-events:none;";
document.body.appendChild(canvas);
function updateCanvasSize() {
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
}
window.addEventListener('resize', updateCanvasSize);
document.addEventListener('fullscreenchange', () => { setTimeout(updateCanvasSize, 100); });
document.addEventListener('webkitfullscreenchange', () => { setTimeout(updateCanvasSize, 100); });
updateCanvasSize();
function loop() {
render(canvas);
requestAnimationFrame(loop);
}
loop();
setInterval(createGUI, 2000);
}
function getBoneOffset() {
let y = (config.hitbox === 0) ? 2.15 : (config.hitbox === 1) ? 1.5 : 0.8;
if (config.randomize) y += (Math.random() - 0.5) * 0.15;
return y;
}
function applySmoothCurve(value, curve) {
if (curve === 'ease') {
return value < 0.5
? 4 * value * value * value
: 1 - Math.pow(-2 * value + 2, 3) / 2;
} else if (curve === 'exponential') {
return 1 - Math.pow(1 - value, 3);
}
return value;
}
function easeOutQuart(x) {
return 1 - Math.pow(1 - x, 4);
}
function easeInOutCubic(x) {
return x < 0.5 ? 4 * x * x * x : 1 - Math.pow(-2 * x + 2, 3) / 2;
}
function calculateVelocity(posKey, currentPos) {
const last = state.lastPositions.get(posKey);
const now = Date.now();
if (last) {
const dt = (now - last.time) / 1000;
if (dt > 0.001 && dt < 0.5) {
const vx = (currentPos.x - last.x) / dt;
const vy = (currentPos.y - last.y) / dt;
const vz = (currentPos.z - last.z) / dt;
const prev = state.velocities.get(posKey);
if (prev) {
const blend = 0.6;
state.velocities.set(posKey, {
vx: vx * blend + prev.vx * (1 - blend),
vy: vy * blend + prev.vy * (1 - blend),
vz: vz * blend + prev.vz * (1 - blend),
time: now
});
} else {
state.velocities.set(posKey, {vx, vy, vz, time: now});
}
}
}
state.lastPositions.set(posKey, {x: currentPos.x, y: currentPos.y, z: currentPos.z, time: now});
}
function render(canvas) {
if (!state.overlayCtx) state.overlayCtx = canvas.getContext('2d');
const ctx = state.overlayCtx;
const w = canvas.width;
const h = canvas.height;
const cx = w / 2;
const cy = h / 2;
ctx.clearRect(0, 0, w, h);
state.frameCount++;
const now = Date.now();
const shouldUpdateStats = now - state.lastFPSUpdate > 1000;
if (shouldUpdateStats) {
state.fps = state.frameCount;
state.frameCount = 0;
state.lastFPSUpdate = now;
if (config.menuVisible && currentTab === 'config') {
const fpsEl = document.getElementById('stat-fps');
const targetsEl = document.getElementById('stat-targets');
const accuracyEl = document.getElementById('stat-accuracy');
if (fpsEl) fpsEl.innerText = state.fps;
if (targetsEl) targetsEl.innerText = state.totalTargets;
if (accuracyEl) {
const total = state.hitCount + state.missCount;
accuracyEl.innerText = total > 0 ? Math.round(state.hitCount/total*100) + '%' : '0%';
}
}
}
if (config.showFPS) {
ctx.font = 'bold 16px monospace';
ctx.fillStyle = config.accentColor;
ctx.fillText(`FPS: ${state.fps}`, 10, 30);
}
if (config.showCrosshair) {
const s = 10, g = 4;
ctx.strokeStyle = config.accentColor;
ctx.lineWidth = 2;
ctx.beginPath();
ctx.moveTo(cx, cy - g - s); ctx.lineTo(cx, cy - g);
ctx.moveTo(cx, cy + g); ctx.lineTo(cx, cy + g + s);
ctx.moveTo(cx - g - s, cy); ctx.lineTo(cx - g, cy);
ctx.moveTo(cx + g, cy); ctx.lineTo(cx + g + s, cy);
ctx.stroke();
ctx.fillStyle = config.accentColor;
ctx.fillRect(cx - 1, cy - 1, 2, 2);
}
if (config.showFov) {
ctx.beginPath();
ctx.arc(cx, cy, config.fov, 0, Math.PI * 2);
if (config.fovGradient && !config.performanceMode) {
const gradient = ctx.createRadialGradient(cx, cy, 0, cx, cy, config.fov);
gradient.addColorStop(0, 'transparent');
gradient.addColorStop(0.8, 'transparent');
gradient.addColorStop(1, config.accentColor + '40');
ctx.fillStyle = gradient;
ctx.fill();
}
ctx.strokeStyle = config.accentColor;
ctx.lineWidth = 1.5;
ctx.stroke();
}
if(state.modelMatrices.length > 50) state.modelMatrices.length = 0;
if (state.vpMatrices.length === 0) return;
const vp = state.vpMatrices[state.vpMatrices.length - 1];
let bestTarget = null;
let bestScore = Infinity;
let bestLockData = null;
state.totalTargets = 0;
const processedPositions = [];
const MIN_DISTANCE = 0.5;
for (let i = 0; i < state.modelMatrices.length; i++) {
const mat = state.modelMatrices[i];
const wx = mat[12], wy = mat[13], wz = mat[14];
let isDuplicate = false;
for (const pos of processedPositions) {
const dx = wx - pos.x;
const dy = wy - pos.y;
const dz = wz - pos.z;
const distSq = dx*dx + dy*dy + dz*dz;
if (distSq < MIN_DISTANCE * MIN_DISTANCE) {
isDuplicate = true;
break;
}
}
if (isDuplicate) continue;
if (processedPositions.length < 20) {
processedPositions.push({x: wx, y: wy, z: wz});
}
const posKey = `${Math.round(wx*10)}_${Math.round(wy*10)}_${Math.round(wz*10)}`;
if (config.velocityTracking && config.predictionEnabled) {
calculateVelocity(posKey, {x: wx, y: wy, z: wz});
}
const boneY = getBoneOffset();
const head = project(vp, wx, wy + boneY, wz, w, h);
const foot = project(vp, wx, wy, wz, w, h);
let targetX = wx, targetY = wy + boneY, targetZ = wz;
if (config.predictionEnabled && config.velocityTracking) {
const vel = state.velocities.get(posKey);
if (vel && now - vel.time < 200) {
const predTime = config.predictionStrength * 0.016;
targetX += vel.vx * predTime;
targetY += vel.vy * predTime;
targetZ += vel.vz * predTime;
}
}
if (!head || !foot) continue;
const boxH = foot.y - head.y;
const boxW = boxH * 0.6;
if (boxH < 30 || boxH > 400 || boxW < 15 || boxW > 250) continue;
const aspectRatio = boxW / boxH;
if (aspectRatio < 0.3 || aspectRatio > 1.0) continue;
if (head.x < -100 || head.x > w + 100 || head.y < -100 || head.y > h + 100) continue;
const prevDeadTime = state.deadPositions.get(posKey);
if (!prevDeadTime) {
state.deadPositions.set(posKey, now);
}
state.totalTargets++;
const dist3D = Math.sqrt(wx*wx + wy*wy + wz*wz);
const dist2D = Math.hypot(head.x - cx, head.y - cy);
if (config.espEnabled) {
const skipAdvancedESP = config.performanceMode;
const inFov = dist2D <= config.fov;
const espColor = inFov ? config.accentColor : config.accentColor + '80';
ctx.strokeStyle = espColor;
ctx.lineWidth = config.espThickness;
ctx.strokeRect(head.x - boxW / 2, head.y, boxW, boxH);
if (!skipAdvancedESP) {
ctx.fillStyle = '#00ff00';
ctx.fillRect(head.x - boxW / 2 - 5, head.y, 2, boxH);
}
if (config.showDistance && !skipAdvancedESP) {
ctx.font = '11px monospace';
ctx.fillStyle = config.accentColor;
ctx.fillText(`${Math.round(dist3D)}m`, head.x, head.y - 5);
}
if (config.showTracers && !skipAdvancedESP) {
ctx.beginPath();
ctx.moveTo(cx, h);
ctx.lineTo(foot.x, foot.y);
ctx.strokeStyle = config.accentColor + '60';
ctx.lineWidth = 1;
ctx.stroke();
}
}
if (dist2D > config.fov) continue;
const isDead = prevDeadTime && now - prevDeadTime > 2000;
if (isDead) continue;
if (config.visibilityCheck) {
if (head.w < 0.01 || head.w > 100) continue;
const screenToWorldRatio = dist3D / (dist2D + 1);
if (screenToWorldRatio > 50) continue;
if (boxH < 20 || boxH > 500) continue;
}
let score = (config.priority === 1) ? dist2D : head.w;
if (score < bestScore) {
bestScore = score;
const predictedHead = project(vp, targetX, targetY, targetZ, w, h);
bestTarget = predictedHead || head;
bestLockData = {wx, wy, wz, boneY, posKey};
}
}
if (config.targetLock && bestLockData) {
if (!state.lockedTarget) {
state.lockedTarget = bestLockData;
state.lockStartTime = now;
} else if (now - state.lockStartTime > config.lockTime) {
state.lockedTarget = null;
}
} else if (!config.targetLock) {
state.lockedTarget = null;
}
let activeTarget = bestTarget;
if (state.lockedTarget) {
const lt = state.lockedTarget;
let lx = lt.wx, ly = lt.wy + lt.boneY, lz = lt.wz;
if (config.predictionEnabled && config.velocityTracking) {
const vel = state.velocities.get(lt.posKey);
if (vel && now - vel.time < 200) {
const predTime = config.predictionStrength * 0.016;
lx += vel.vx * predTime;
ly += vel.vy * predTime;
lz += vel.vz * predTime;
}
}
const locked = project(vp, lx, ly, lz, w, h);
if (locked) activeTarget = locked;
}
if (config.triggerBot && activeTarget) {
const trigDx = activeTarget.x - cx;
const trigDy = activeTarget.y - cy;
const trigDist = Math.hypot(trigDx, trigDy);
if (trigDist < 15 && now - state.lastTriggerFire > config.triggerDelay) {
window.dispatchEvent(new MouseEvent('mousedown', { button: 0, bubbles: true }));
setTimeout(() => {
window.dispatchEvent(new MouseEvent('mouseup', { button: 0, bubbles: true }));
}, 50);
state.lastTriggerFire = now;
}
}
if (config.aimbotEnabled && activeTarget && (state.input.right || state.input.left)) {
const dx = activeTarget.x - cx;
const dy = activeTarget.y - cy;
const dist = Math.hypot(dx, dy);
const DEADZONE = 3;
if (dist < DEADZONE) {
state.accX *= 0.7;
state.accY *= 0.7;
return;
}
let smooth = config.aimSmooth;
const distRatio = Math.min(1, dist / config.fov);
if (dist < config.lockDist * 0.5) {
smooth *= 2.5;
} else if (dist < config.lockDist) {
const closeRatio = (dist - config.lockDist * 0.5) / (config.lockDist * 0.5);
smooth *= 1.5 + easeOutQuart(closeRatio);
} else if (dist < config.lockDist * 2) {
const midRatio = (dist - config.lockDist) / config.lockDist;
smooth *= 1.0 + (0.5 * easeInOutCubic(midRatio));
}
const easedProgress = applySmoothCurve(distRatio, config.smoothCurve);
smooth = smooth * (0.8 + easedProgress * 0.4);
let tx = dx / smooth;
let ty = dy / smooth;
tx += state.accX * 0.85;
ty += state.accY * 0.85;
let mx = Math.round(tx);
let my = Math.round(ty);
state.accX = (tx - mx) * 0.9;
state.accY = (ty - my) * 0.9;
const moveAmount = Math.hypot(mx, my);
if (moveAmount >= 1) {
const speedFactor = Math.min(1, moveAmount / 20);
const smoothFactor = 0.92 + (speedFactor * 0.06);
const smoothedMx = Math.round(mx * smoothFactor);
const smoothedMy = Math.round(my * smoothFactor);
if (smoothedMx !== 0 || smoothedMy !== 0) {
window.dispatchEvent(new MouseEvent('mousemove', {
movementX: smoothedMx,
movementY: smoothedMy,
bubbles: true
}));
state.lastMouseMove = now;
}
}
} else {
state.accX *= 0.5;
state.accY *= 0.5;
}
if (config.antiAFK && now - state.lastMouseMove > 60000) {
window.dispatchEvent(new MouseEvent('mousemove', {movementX: 1, movementY: 0, bubbles: true}));
state.lastMouseMove = now;
}
if (now % 5000 < 16) {
const cutoffTime = now - 5000;
for (const [key, pos] of state.lastPositions.entries()) {
if (pos && pos.time < cutoffTime) {
state.lastPositions.delete(key);
}
}
for (const [key, vel] of state.velocities.entries()) {
if (vel.time < cutoffTime) {
state.velocities.delete(key);
}
}
for (const [key, time] of state.deadPositions.entries()) {
if (time < cutoffTime) {
state.deadPositions.delete(key);
}
}
}
state.modelMatrices.length = 0;
}
function project(vp, x, y, z, w, h) {
const X = x*vp[0] + y*vp[4] + z*vp[8] + vp[12];
const Y = x*vp[1] + y*vp[5] + z*vp[9] + vp[13];
const W = x*vp[3] + y*vp[7] + z*vp[11] + vp[15];
if (W < 0.1) return null;
return { x: (X/W + 1) * w * 0.5, y: (-Y/W + 1) * h * 0.5, w: W };
}
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', () => { setupCanvas(); });
} else {
setupCanvas();
}
})();