Memesense V2

Advanced Krunker.io cheat - Aimbot, ESP, Chams, FOV Changer, Keystrokes

You will need to install an extension such as Tampermonkey, Greasemonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Userscripts to install this script.

You will need to install an extension such as Tampermonkey to install this script.

You will need to install a user script manager extension to install this script.

(У мене вже є менеджер скриптів, дайте мені встановити його!)

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

(I already have a user style manager, let me install it!)

// ==UserScript==
// @name         Memesense V2
// @namespace    http://tampermonkey.net/
// @version      2.9.4
// @description  Advanced Krunker.io cheat - Aimbot, ESP, Chams, FOV Changer, Keystrokes
// @license      N1ko
// @author       N1ko
// @match        *://krunker.io/*
// @match        *://browserfps.com/*
// @exclude      *://krunker.io/social*
// @exclude      *://krunker.io/editor*
// @icon         https://www.google.com/s2/favicons?domain=krunker.io
// @run-at       document-start
// @require      https://unpkg.com/[email protected]/build/three.min.js
// @grant        none
// ==/UserScript==

const THREE = window.THREE;
delete window.THREE;

const CheatSettings = {
    aimbotEnabled: false,
    aimbotFOV: 180,
    aimSmooth: 50,
    hitbox: 'head',          // 'head', 'torso', 'legs'
    teamCheck: false,
    wallCheck: true,
    espEnabled: false,
    espBox: true,
    espName: true,
    espClass: true,
    espDistance: true,
    espTracers: true,
    espChams: false,
    keystrokesEnabled: false,
    fovChanger: 0,
    wireframe: false
};

const keyToSetting = {
    KeyV: 'aimbotEnabled',
    KeyN: 'espEnabled',
    KeyT: 'teamCheck',
    KeyC: 'espChams',
    KeyK: 'keystrokesEnabled',
    KeyL: 'wireframe'
};

let scene, myPlayerObject = null, rainbowHue = 0;
let playerInputs = null;
let listeningForKey = null, listeningKeyEl = null;
let frameCount = 0, wallCache = null;

// Speedometer
let lastSpeedPos = null, lastSpeedTime = null, lastPlayerObject = null;
let speedDisplayEl = null, speedValueEl = null;

// Chams
const originalMaterials = new Map();
const chamsMaterial = new THREE.MeshBasicMaterial({
    color: 0xff0000,
    depthTest: false,
    depthWrite: false,
    transparent: true,
    opacity: 0.8
});

// Preallocated vectors
const _v1 = new THREE.Vector3();
const _v2 = new THREE.Vector3();
const _v3 = new THREE.Vector3();
const _proj = new THREE.Vector3();
const _aimPos = new THREE.Vector3();
const _myHead = new THREE.Vector3();

// Keystrokes UI
let keystrokesContainer = null;
const pressedKeys = new Set();
let isDraggingKeystrokes = false;
let dragOffsetX = 0, dragOffsetY = 0;

const x = {
    window, document, querySelector: document.querySelector, consoleLog: console.log,
    ArrayPrototype: Array.prototype, ArrayPush: Array.prototype.push,
    setTimeout: window.setTimeout, requestAnimationFrame: window.requestAnimationFrame
};
x.consoleLog('Memesense V2 - Waiting for access...');

const proxied = function (object) {
    try {
        if (typeof object === 'object' && typeof object.parent === 'object' &&
            object.parent.type === 'Scene' && object.parent.name === 'Main') {
            x.consoleLog('Found Scene!');
            scene = object.parent;
            x.ArrayPrototype.push = x.ArrayPush;
        }
    } catch (error) {}
    return x.ArrayPush.apply(this, arguments);
};

const tempVector = new THREE.Vector3();
const tempVector2 = new THREE.Vector3();
const tempObject = new THREE.Object3D();
tempObject.rotation.order = 'YXZ';
const raycaster = new THREE.Raycaster();

const geometry = new THREE.EdgesGeometry(new THREE.BoxGeometry(5, 15, 5).translate(0, 7.5, 0));
const rainbowMaterial = new THREE.RawShaderMaterial({
    vertexShader: `
        attribute vec3 position;
        uniform mat4 projectionMatrix;
        uniform mat4 modelViewMatrix;
        uniform vec3 uColor;
        void main() {
            gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
            gl_Position.z = 1.0;
        }`,
    fragmentShader: `
        precision mediump float;
        uniform vec3 uColor;
        void main() { gl_FragColor = vec4(uColor, 1.0); }`,
    uniforms: { uColor: { value: new THREE.Vector3(1, 0, 0) } }
});

let injectTimer = null, canvas2d = null, ctx2d = null;

function hslToRgb(h, s, l) {
    let r, g, b;
    if (s === 0) { r = g = b = l; } else {
        const hue2rgb = (p, q, t) => {
            if (t < 0) t += 1; if (t > 1) t -= 1;
            if (t < 1/6) return p + (q - p) * 6 * t;
            if (t < 1/2) return q;
            if (t < 2/3) return p + (q - p) * (2/3 - t) * 6;
            return p;
        };
        const q = l < 0.5 ? l * (1 + s) : l + s - l * s, p = 2 * l - q;
        r = hue2rgb(p, q, h + 1/3); g = hue2rgb(p, q, h); b = hue2rgb(p, q, h - 1/3);
    }
    return [r, g, b];
}

function isCrouched(player) {
    try { return player.children?.[0]?.position?.y < 0; } catch(e) { return false; }
}

function isInFOV(targetPos, myPlayer, fov) {
    tempVector2.copy(targetPos).sub(myPlayer.position);
    const angle = myPlayer.children[0].rotation.x;
    const targetAngle = Math.atan2(tempVector2.y, tempVector2.length());
    return Math.abs(targetAngle - angle) < (fov / 2) * (Math.PI / 180);
}

function buildWallCache() {
    if (wallCache) return;
    wallCache = [];
    const stack = [scene];
    while (stack.length > 0) {
        const obj = stack.pop();
        if (obj.type === 'Mesh' && obj.material && !obj.material.transparent) wallCache.push(obj);
        if (obj.children) {
            for (let i = 0; i < obj.children.length; i++) {
                const c = obj.children[i];
                if (c.type !== 'Object3D' || !c.children?.[0]?.children?.[0]?.type?.includes('Camera')) stack.push(c);
            }
        }
    }
}

function isWallBetween(from, to) {
    if (!wallCache || wallCache.length === 0) return false;
    tempVector2.copy(to).sub(from);
    const dist = tempVector2.length();
    if (dist < 0.5) return false;
    tempVector2.normalize();
    raycaster.set(from, tempVector2);
    raycaster.far = dist;
    return raycaster.intersectObjects(wallCache, false).length > 0;
}

function getClassName(player) {
    try {
        const n = (player.children?.[0]?.children?.[2]?.name || '').toLowerCase();
        const m = { weapon:'Triggerman', smg:'Run N Gun', sniper:'Hunter', shotgun:'Vince',
            pistol:'Detective', revolver:'Detective', rocket:'Rocketeer', crossbow:'Archer',
            knife:'Knifeman', sword:'Knifeman', bat:'Knifeman', hammer:'Knifeman' };
        for (const [k, v] of Object.entries(m)) { if (n.includes(k)) return v; }
    } catch(e) {}
    return 'Unknown';
}

function getPlayerName(player) {
    try { if (player.name && player.name.length > 0) return player.name; } catch(e) {}
    return 'Enemy';
}

function isTeammate(myPlayer, target) {
    const myTeam = myPlayer?.userData?.team ?? myPlayer?.team ?? myPlayer?.children?.[0]?.userData?.team ?? myPlayer?.children?.[0]?.children?.[0]?.userData?.team;
    const tTeam = target?.userData?.team ?? target?.team ?? target?.children?.[0]?.userData?.team ?? target?.children?.[0]?.children?.[0]?.userData?.team;
    if (myTeam !== undefined && tTeam !== undefined) return myTeam === tTeam;
    if (target?.isYou) return true;
    return false;
}

function findInputs() {
    if (playerInputs) return true;
    if (!myPlayerObject) return false;
    try {
        const cam = myPlayerObject.children?.[0]?.children?.[0];
        if (cam?.userData?.inputs) { playerInputs = cam.userData.inputs; return true; }
        if (cam?.userData?.world?.inputs) { playerInputs = cam.userData.world.inputs; return true; }
        const ctrl = myPlayerObject.children?.[0];
        if (ctrl?.userData?.inputs) { playerInputs = ctrl.userData.inputs; return true; }
    } catch(e) {}
    return false;
}

// Robust getAimPos with try-catch
function getAimPos(player, out) {
    const hitbox = CheatSettings.hitbox;
    try {
        if (hitbox === 'head') {
            if (player.children?.[0]?.children?.[0]) {
                out.setScalar(0);
                player.children[0].children[0].localToWorld(out);
                return out;
            }
            out.set(player.position.x, player.position.y + (isCrouched(player) ? 8 : 13), player.position.z);
            return out;
        } else if (hitbox === 'torso') {
            out.set(player.position.x, player.position.y + (isCrouched(player) ? 5 : 10), player.position.z);
            return out;
        } else { // legs
            out.set(player.position.x, player.position.y + (isCrouched(player) ? 2 : 5), player.position.z);
            return out;
        }
    } catch(e) {
        // Fallback to feet position
        out.set(player.position.x, player.position.y, player.position.z);
        return out;
    }
}

function setup2DCanvas() {
    if (canvas2d) return;
    canvas2d = document.createElement('canvas');
    canvas2d.style.cssText = 'position:fixed;top:0;left:0;width:100%;height:100%;pointer-events:none;z-index:9998;';
    canvas2d.width = window.innerWidth;
    canvas2d.height = window.innerHeight;
    document.body.appendChild(canvas2d);
    ctx2d = canvas2d.getContext('2d');
    window.addEventListener('resize', () => {
        canvas2d.width = window.innerWidth;
        canvas2d.height = window.innerHeight;
    });
}

function worldToScreen(pos, camera, target) {
    target = target || new THREE.Vector3();
    target.copy(pos).project(camera);
    return {
        x: (target.x * 0.5 + 0.5) * canvas2d.width,
        y: (-target.y * 0.5 + 0.5) * canvas2d.height,
        z: target.z
    };
}

function drawESP2D(players, myPlayer, camera) {
    if (!ctx2d || !CheatSettings.espEnabled) return;
    ctx2d.clearRect(0, 0, canvas2d.width, canvas2d.height);
    const screenCenterX = canvas2d.width / 2;
    const screenCenterY = canvas2d.height / 2;

    for (let i = 0; i < players.length; i++) {
        const p = players[i];
        if (p.position.x === myPlayer.position.x && p.position.z === myPlayer.position.z) continue;
        const h = isCrouched(p) ? 8 : 15;
        _v1.set(p.position.x, p.position.y + h, p.position.z);
        _v2.set(p.position.x, p.position.y, p.position.z);
        const top = worldToScreen(_v1, camera, _v3);
        const bot = worldToScreen(_v2, camera, null);
        if (top.z > 1 || bot.z > 1) continue;
        const sH = Math.abs(top.y - bot.y), sW = sH * 0.5;
        const [r, g, b] = hslToRgb((rainbowHue + i * 0.15) % 1, 1, 0.5);
        const clr = `rgb(${Math.floor(r*255)},${Math.floor(g*255)},${Math.floor(b*255)})`;

        if (CheatSettings.espBox) {
            ctx2d.strokeStyle = clr;
            ctx2d.lineWidth = 2;
            ctx2d.strokeRect(top.x - sW/2, top.y, sW, sH);
        }
        let ty = top.y - 5;
        if (CheatSettings.espName) {
            ctx2d.fillStyle = clr;
            ctx2d.font = 'bold 12px "Orbitron", sans-serif';
            ctx2d.textAlign = 'center';
            ctx2d.fillText(getPlayerName(p), top.x, ty);
            ty -= 14;
        }
        if (CheatSettings.espClass) {
            ctx2d.fillStyle = 'rgba(255,255,255,0.8)';
            ctx2d.font = '10px "Orbitron", sans-serif';
            ctx2d.textAlign = 'center';
            ctx2d.fillText(getClassName(p), top.x, ty);
            ty -= 12;
        }
        if (CheatSettings.espDistance) {
            const dx = p.position.x - myPlayer.position.x, dz = p.position.z - myPlayer.position.z;
            const dy = p.position.y - myPlayer.position.y;
            const dist = Math.sqrt(dx*dx + dy*dy + dz*dz);
            ctx2d.fillStyle = 'rgba(255,255,255,0.6)';
            ctx2d.font = '10px "Orbitron", sans-serif';
            ctx2d.fillText(Math.floor(dist) + 'm', top.x, bot.y + 26);
        }
        if (CheatSettings.espTracers) {
            ctx2d.beginPath();
            ctx2d.moveTo(screenCenterX, screenCenterY);
            ctx2d.lineTo(top.x, top.y);
            ctx2d.strokeStyle = clr;
            ctx2d.lineWidth = 1;
            ctx2d.stroke();
        }
        if (CheatSettings.teamCheck && isTeammate(myPlayer, p)) {
            ctx2d.strokeStyle = 'rgba(0,255,0,0.5)';
            ctx2d.lineWidth = 1;
            ctx2d.strokeRect(top.x - sW/2 - 2, top.y - 2, sW + 4, sH + 4);
        }
    }

    // Watermark (dark red, only when ESP is fully on)
    ctx2d.fillStyle = '#8B0000';
    ctx2d.font = 'bold 16px "Orbitron", sans-serif';
    ctx2d.textAlign = 'left';
    ctx2d.fillText('MemesenseV2', 10, canvas2d.height - 10);
}

function applyChams(players, myPlayer) {
    if (!CheatSettings.espChams) {
        for (const [player, mats] of originalMaterials.entries()) {
            for (const { mesh, material } of mats) {
                mesh.material = material;
            }
        }
        originalMaterials.clear();
        return;
    }
    for (const p of players) {
        if (p.position.x === myPlayer.position.x && p.position.z === myPlayer.position.z) continue;
        if (CheatSettings.teamCheck && isTeammate(myPlayer, p)) continue;
        if (!originalMaterials.has(p)) {
            const mats = [];
            p.traverse(obj => {
                if (obj.isMesh && obj.material) {
                    mats.push({ mesh: obj, material: obj.material });
                    obj.material = chamsMaterial;
                }
            });
            originalMaterials.set(p, mats);
        }
    }
    for (const [player, mats] of originalMaterials.entries()) {
        if (!players.includes(player) || (CheatSettings.teamCheck && isTeammate(myPlayer, player))) {
            for (const { mesh, material } of mats) {
                mesh.material = material;
            }
            originalMaterials.delete(player);
        }
    }
}

function createSpeedometer() {
    if (speedDisplayEl) return;
    speedDisplayEl = document.createElement('div');
    speedDisplayEl.style.cssText = 'position:fixed;top:10px;left:10px;z-index:9999;font-family:"Orbitron",sans-serif;font-size:14px;color:#fff;background:rgba(0,0,0,0.7);padding:8px 12px;border-radius:6px;border:1px solid #ff0000;pointer-events:none;';
    speedDisplayEl.innerHTML = 'Speed: <span style="font-weight:bold;color:#00ff00;">0.00</span> m/s';
    speedValueEl = speedDisplayEl.querySelector('span');
    document.body.appendChild(speedDisplayEl);
}

function createWatermark() {
    const wm = document.createElement('div');
    wm.style.cssText = 'position:fixed;bottom:10px;left:10px;z-index:10000;font-family:"Orbitron",sans-serif;font-size:16px;color:#8B0000;background:rgba(0,0,0,0.5);padding:8px 16px;border-radius:6px;border:1px solid #ff0000;pointer-events:none;';
    wm.textContent = 'MemesenseV2';
    wm.classList.add('memesense-watermark');
    document.body.appendChild(wm);
}

function createKeystrokes() {
    if (keystrokesContainer) return;
    keystrokesContainer = document.createElement('div');
    keystrokesContainer.style.cssText = 'position:fixed;bottom:10px;right:10px;z-index:9999;display:flex;flex-direction:column;align-items:center;gap:5px;font-family:"Orbitron",sans-serif;cursor:grab;user-select:none;';

    const row1 = document.createElement('div');
    row1.style.cssText = 'display:flex;gap:5px;';
    row1.appendChild(createKeyElement('W', 'KeyW'));
    keystrokesContainer.appendChild(row1);

    const row2 = document.createElement('div');
    row2.style.cssText = 'display:flex;gap:5px;';
    row2.appendChild(createKeyElement('A', 'KeyA'));
    row2.appendChild(createKeyElement('S', 'KeyS'));
    row2.appendChild(createKeyElement('D', 'KeyD'));
    keystrokesContainer.appendChild(row2);

    const row3 = document.createElement('div');
    row3.style.cssText = 'display:flex;justify-content:center;gap:5px;';
    const keySpace = createKeyElement('Space', 'Space');
    keySpace.style.width = '70px';
    row3.appendChild(keySpace);
    keystrokesContainer.appendChild(row3);

    keystrokesContainer.addEventListener('mousedown', (e) => {
        isDraggingKeystrokes = true;
        const rect = keystrokesContainer.getBoundingClientRect();
        dragOffsetX = e.clientX - rect.left;
        dragOffsetY = e.clientY - rect.top;
        keystrokesContainer.style.cursor = 'grabbing';
        e.preventDefault();
    });

    document.addEventListener('mousemove', (e) => {
        if (isDraggingKeystrokes) {
            keystrokesContainer.style.left = (e.clientX - dragOffsetX) + 'px';
            keystrokesContainer.style.top = (e.clientY - dragOffsetY) + 'px';
            keystrokesContainer.style.bottom = 'auto';
            keystrokesContainer.style.right = 'auto';
        }
    });

    document.addEventListener('mouseup', () => {
        isDraggingKeystrokes = false;
        keystrokesContainer.style.cursor = 'grab';
    });

    document.body.appendChild(keystrokesContainer);
}

function createKeyElement(label, code) {
    const el = document.createElement('div');
    el.className = 'key-' + code.toLowerCase();
    el.textContent = label;
    el.style.cssText = 'width:40px;height:40px;display:flex;align-items:center;justify-content:center;background:rgba(0,0,0,0.5);border:1px solid #fff;border-radius:5px;font-size:14px;font-weight:bold;color:#fff;transition:background 0.1s;';
    return el;
}

function updateKeystrokes() {
    if (!keystrokesContainer) return;
    const keyMap = {
        'KeyW': '.key-keyw',
        'KeyA': '.key-keya',
        'KeyS': '.key-keys',
        'KeyD': '.key-keyd',
        'Space': '.key-space'
    };
    for (const [code, selector] of Object.entries(keyMap)) {
        const el = keystrokesContainer.querySelector(selector);
        if (el) {
            if (pressedKeys.has(code)) {
                el.style.background = 'rgba(255,0,0,0.8)';
            } else {
                el.style.background = 'rgba(0,0,0,0.5)';
            }
        }
    }
}

function applyFOV(camera) {
    if (CheatSettings.fovChanger > 0 && camera) {
        camera.fov = CheatSettings.fovChanger;
        camera.updateProjectionMatrix();
    }
}

function animate() {
    x.requestAnimationFrame.call(x.window, animate);
    frameCount++;

    if (document.body) {
        if (!speedDisplayEl) createSpeedometer();
        if (!document.querySelector('.memesense-watermark')) createWatermark();
        if (CheatSettings.keystrokesEnabled && !keystrokesContainer) createKeystrokes();
        if (!CheatSettings.keystrokesEnabled && keystrokesContainer) {
            keystrokesContainer.remove();
            keystrokesContainer = null;
        }
    }

    if (frameCount % 3 === 0) {
        rainbowHue = (rainbowHue + 0.005) % 1;
        const [r, g, b] = hslToRgb(rainbowHue, 1, 0.5);
        rainbowMaterial.uniforms.uColor.value.set(r, g, b);
    }

    if (!scene && !injectTimer) {
        const el = x.querySelector.call(x.document, '#loadingBg');
        if (el && el.style.display === 'none') {
            injectTimer = x.setTimeout.call(x.window, () => {
                x.consoleLog('Memesense V2 Injected!');
                x.ArrayPrototype.push = proxied;
            }, 2e3);
        }
    }

    const players = [];
    let myPlayer, camera;
    if (!scene) return;

    const children = scene.children;
    for (let i = 0, len = children.length; i < len; i++) {
        const child = children[i];
        if (child.type === 'Object3D') {
            try {
                if (child.children[0].children[0].type === 'PerspectiveCamera') {
                    myPlayer = child;
                    camera = child.children[0].children[0];
                    myPlayerObject = child;
                } else {
                    players.push(child);
                }
            } catch (err) {}
        } else if (child.material) {
            child.material.wireframe = CheatSettings.wireframe;
        }
    }

    if (!myPlayer) {
        playerInputs = null;
        wallCache = null;
        lastSpeedPos = null;
        lastSpeedTime = null;
        lastPlayerObject = null;
        x.ArrayPrototype.push = proxied;
        return;
    }

    // Speed
    const now = performance.now();
    if (lastSpeedPos && lastSpeedTime && lastPlayerObject === myPlayer) {
        const dx = myPlayer.position.x - lastSpeedPos.x;
        const dz = myPlayer.position.z - lastSpeedPos.z;
        const dist = Math.sqrt(dx*dx + dz*dz);
        const dt = (now - lastSpeedTime) / 1000;
        const speed = dt > 0 ? dist / dt : 0;
        if (speedValueEl) speedValueEl.textContent = speed.toFixed(2);
    }
    if (!lastSpeedPos) lastSpeedPos = new THREE.Vector3();
    lastSpeedPos.copy(myPlayer.position);
    lastSpeedTime = now;
    lastPlayerObject = myPlayer;

    // FOV
    applyFOV(camera);

    // ESP / Chams
    if (CheatSettings.espEnabled || CheatSettings.espChams) {
        for (const p of players) {
            if (!p.box) {
                const box = new THREE.LineSegments(geometry, rainbowMaterial);
                box.frustumCulled = false;
                p.add(box);
                p.box = box;
            }
            if (p.position.x === myPlayer.position.x && p.position.z === myPlayer.position.z) {
                p.box.visible = false;
                continue;
            }
            p.box.visible = CheatSettings.espEnabled;
            if (CheatSettings.espEnabled) {
                if (isCrouched(p)) {
                    p.box.scale.y = 0.5;
                    p.box.position.y = -3;
                } else {
                    p.box.scale.y = 1;
                    p.box.position.y = 0;
                }
            }
        }
        if (CheatSettings.espEnabled && camera) {
            if (!canvas2d) setup2DCanvas();
            drawESP2D(players, myPlayer, camera);
        }
        applyChams(players, myPlayer);
    } else {
        for (const p of players) {
            if (p.box) p.box.visible = false;
        }
        if (ctx2d) ctx2d.clearRect(0, 0, canvas2d.width, canvas2d.height);
        applyChams([], myPlayer);
    }

    // Keystrokes
    if (CheatSettings.keystrokesEnabled) {
        updateKeystrokes();
    }

    // ===== AIMBOT (v1 logic, robust) =====
    if (!CheatSettings.aimbotEnabled) return;

    if (CheatSettings.wallCheck && !wallCache && frameCount % 60 === 0) buildWallCache();

    let targetPlayer = null;
    let minCrossDist = Infinity;

    for (let i = 0; i < players.length; i++) {
        const p = players[i];
        if (p.position.x === myPlayer.position.x && p.position.z === myPlayer.position.z) continue;
        if (CheatSettings.teamCheck && isTeammate(myPlayer, p)) continue;

        getAimPos(p, _aimPos);
        if (CheatSettings.aimbotFOV < 180 && !isInFOV(_aimPos, myPlayer, CheatSettings.aimbotFOV)) continue;

        _proj.copy(_aimPos).project(camera);
        if (_proj.z > 1) continue;
        const crossDist = _proj.x * _proj.x + _proj.y * _proj.y;
        if (crossDist < minCrossDist) {
            targetPlayer = p;
            minCrossDist = crossDist;
        }
    }

    if (!targetPlayer) return;

    if (CheatSettings.wallCheck && wallCache) {
        getAimPos(targetPlayer, _aimPos);
        _myHead.set(myPlayer.position.x, myPlayer.position.y + 13, myPlayer.position.z);
        if (isWallBetween(_myHead, _aimPos)) return;
    }

    getAimPos(targetPlayer, _aimPos);
    if (!myPlayer?.position) return;

    tempObject.position.copy(myPlayer.position);
    tempObject.lookAt(_aimPos);

    if (CheatSettings.aimSmooth > 0) {
        const s = CheatSettings.aimSmooth / 100;
        if (myPlayer.children?.[0]?.rotation) {
            const tPitch = -tempObject.rotation.x;
            const tYaw = tempObject.rotation.y + Math.PI;
            myPlayer.children[0].rotation.x += (tPitch - myPlayer.children[0].rotation.x) * s;
            myPlayer.rotation.y += (tYaw - myPlayer.rotation.y) * s;
        }
    } else {
        if (myPlayer.children?.[0]?.rotation) {
            myPlayer.children[0].rotation.x = -tempObject.rotation.x;
            myPlayer.rotation.y = tempObject.rotation.y + Math.PI;
        }
    }

    if (findInputs() && playerInputs?.keys) {
        playerInputs.keys[0] = true;
    }
    // ===== END AIMBOT =====
}

// --- UI Setup ---
const style = document.createElement('style');
style.textContent = `
@import url('https://fonts.googleapis.com/css2?family=Orbitron:wght@400;700&display=swap');

:root { --on-color: #00ff00; --off-color: #ff4757; --bg-dark: rgba(0,0,0,0.9); --bg-item: rgba(0,0,0,0.4); }
.msg { position:absolute;left:10px;bottom:10px;color:#fff;background:rgba(0,0,0,0.85);font-weight:500;padding:12px 20px;border-radius:6px;box-shadow:0 4px 15px rgba(0,0,0,0.7);animation:msg-in .3s forwards,msg-out .3s forwards 3s;z-index:999999;pointer-events:none;font-family:'Orbitron',sans-serif;border:2px solid #ff0000; }
@keyframes msg-in { from{transform:translateX(-120%);opacity:0} to{transform:translateX(0);opacity:1} }
@keyframes msg-out { from{transform:translateX(0);opacity:1} to{transform:translateX(-120%);opacity:0} }

/* Centered vertical menu with tabs */
.zui {
    position: fixed;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    z-index: 9999;
    display: flex;
    flex-direction: column;
    font-family: 'Orbitron', sans-serif;
    font-size: 14px;
    color: #fff;
    width: 320px;
    max-height: 80vh;
    overflow: hidden;
    user-select: none;
    border-radius: 12px;
    background: var(--bg-dark);
    backdrop-filter: blur(8px);
    box-shadow: 0 8px 32px rgba(0,0,0,0.4);
    border: 2px solid #ff0000;
}
.zui-tabs {
    display: flex;
    justify-content: space-around;
    background: linear-gradient(180deg, #ff0000, #000000);
    border-bottom: 2px solid #ff0000;
    padding: 0;
}
.zui-tab {
    padding: 10px 0;
    cursor: pointer;
    font-weight: 700;
    font-size: 12px;
    letter-spacing: 1px;
    color: #fff;
    text-align: center;
    flex: 1;
    transition: background 0.2s;
}
.zui-tab:hover {
    background: rgba(255,0,0,0.2);
}
.zui-tab.active {
    background: rgba(255,0,0,0.3);
    border-bottom: 2px solid #ff0000;
}
.zui-content {
    overflow-y: auto;
    max-height: calc(80vh - 60px);
}
.zui::-webkit-scrollbar { width: 4px; }
.zui::-webkit-scrollbar-thumb { background: #ff0000; border-radius: 2px; }
.zui-section { padding: 6px 15px; font-weight: 700; font-size: 11px; text-transform: uppercase; letter-spacing: 1px; color: #ff0000; background: rgba(255,0,0,0.1); border-bottom: 1px solid rgba(255,0,0,0.3); }
.zui-item { padding: 10px 15px; display: flex; justify-content: space-between; align-items: center; background: var(--bg-item); border-bottom: 1px solid rgba(255,255,255,0.1); transition: background .2s; cursor: pointer; color: #fff; }
.zui-item:hover { background: rgba(255,0,0,0.15); }
.zui-item-value { font-weight: bold; transition: color .2s; }
.zui-keybind { font-size: 11px; padding: 2px 6px; border-radius: 3px; background: rgba(255,255,255,0.15); color: #ff0000; cursor: pointer; margin-left: 6px; border: 1px solid rgba(255,0,0,0.3); transition: all .2s; }
.zui-keybind:hover { background: rgba(255,0,0,0.3); }
.zui-keybind.listening { background: rgba(255,0,0,0.4); color: #fff; border-color: #ff0000; animation: pulse .5s ease infinite alternate; }
@keyframes pulse { from{opacity:0.6} to{opacity:1} }
.zui-footer { padding: 8px; text-align: center; font-size: 11px; color: rgba(255,255,255,0.4); border-top: 1px solid rgba(255,0,0,0.3); background: rgba(0,0,0,0.5); }
`;
document.head.appendChild(style);

const msgEl = document.createElement('div');
msgEl.className = 'msg';
msgEl.style.display = 'none';

const gui = createGUI();

window.addEventListener('DOMContentLoaded', function () {
    document.body.appendChild(msgEl);
    document.body.appendChild(gui);
});

window.addEventListener('keydown', function (event) {
    if (CheatSettings.keystrokesEnabled) {
        pressedKeys.add(event.code);
        updateKeystrokes();
    }
    if (listeningForKey && listeningKeyEl) {
        event.preventDefault(); event.stopPropagation();
        const newCode = event.code;
        const oldCode = listeningForKey;
        const settingName = keyToSetting[oldCode];
        delete keyToSetting[oldCode];
        keyToSetting[newCode] = settingName;
        listeningKeyEl.textContent = formatKey(newCode);
        listeningKeyEl.classList.remove('listening');
        listeningForKey = null; listeningKeyEl = null;
        return;
    }
    if (document.activeElement && document.activeElement.value !== undefined) return;
    if (keyToSetting[event.code]) { event.preventDefault(); toggleSetting(keyToSetting[event.code]); }
    if (event.code === 'Slash') gui.style.display = gui.style.display === 'none' ? '' : 'none';
}, true);

window.addEventListener('keyup', function (event) {
    if (CheatSettings.keystrokesEnabled) {
        pressedKeys.delete(event.code);
        updateKeystrokes();
    }
    if (listeningForKey) { event.preventDefault(); return; }
}, true);

function formatKey(code) {
    if (code.startsWith('Key')) return code.slice(3);
    if (code.startsWith('Digit')) return code.slice(5);
    if (code === 'Space') return 'Space';
    if (code.startsWith('Shift')) return 'Shift';
    if (code.startsWith('Control')) return 'Ctrl';
    if (code.startsWith('Alt')) return 'Alt';
    if (code === 'Tab') return 'Tab';
    if (code === 'Enter') return 'Enter';
    if (code === 'Backspace') return 'Bksp';
    if (code.startsWith('Arrow')) return code.slice(5);
    return code;
}

function showMsg(name, bool) {
    msgEl.innerText = name + ': ' + (bool ? 'ON' : 'OFF');
    msgEl.style.display = 'none';
    void msgEl.offsetWidth;
    msgEl.style.display = '';
}

animate();

function createGUI() {
    const guiEl = fromHtml(`<div class="zui">
        <div class="zui-tabs" id="zui-tabs">
            <div class="zui-tab active" data-tab="Aimbot">Aimbot</div>
            <div class="zui-tab" data-tab="ESP">ESP</div>
            <div class="zui-tab" data-tab="Visual">Visual</div>
        </div>
        <div class="zui-content" id="zui-content"></div>
        <div class="zui-footer">Made By N1ko</div>
    </div>`);
    const contentEl = guiEl.querySelector('#zui-content');
    const tabsContainer = guiEl.querySelector('#zui-tabs');

    const sections = {
        Aimbot: ['aimbotEnabled', 'aimbotFOV', 'aimSmooth', 'hitbox', 'teamCheck', 'wallCheck'],
        ESP: ['espEnabled', 'espBox', 'espName', 'espClass', 'espDistance', 'espTracers', 'espChams'],
        Visual: ['fovChanger', 'keystrokesEnabled', 'wireframe']
    };

    const settingToKey = {};
    for (const k in keyToSetting) settingToKey[keyToSetting[k]] = k;

    // Create content for each tab
    const tabContents = {};
    for (const [tabName, props] of Object.entries(sections)) {
        const tabDiv = document.createElement('div');
        tabDiv.className = 'tab-content';
        tabDiv.dataset.tab = tabName;
        tabDiv.style.display = tabName === 'Aimbot' ? 'block' : 'none';
        for (const prop of props) {
            let name = fromCamel(prop);
            const hasBind = settingToKey[prop] !== undefined;
            const currentKey = settingToKey[prop] || '';

            if (prop === 'aimbotFOV') {
                const itemEl = fromHtml(`<div class="zui-item"><span>${name}</span><span class="zui-item-value"></span></div>`);
                const valEl = itemEl.querySelector('.zui-item-value');
                const upd = () => { valEl.innerText = CheatSettings[prop] + '\u00B0'; valEl.style.color = '#fff'; };
                itemEl.onclick = () => { CheatSettings[prop] = (CheatSettings[prop] + 15) % 195; if (!CheatSettings[prop]) CheatSettings[prop] = 15; };
                upd(); tabDiv.appendChild(itemEl); watchProp(prop, upd);
            } else if (prop === 'aimSmooth') {
                const itemEl = fromHtml(`<div class="zui-item"><span>${name}</span><span class="zui-item-value"></span></div>`);
                const valEl = itemEl.querySelector('.zui-item-value');
                const upd = () => { valEl.innerText = CheatSettings[prop] + '%'; valEl.style.color = CheatSettings[prop] > 0 ? '#ffff00' : '#fff'; };
                itemEl.onclick = () => { CheatSettings[prop] = (CheatSettings[prop] + 10) % 110; };
                upd(); tabDiv.appendChild(itemEl); watchProp(prop, upd);
            } else if (prop === 'hitbox') {
                const itemEl = fromHtml(`<div class="zui-item"><span>${name}</span><span class="zui-item-value"></span></div>`);
                const valEl = itemEl.querySelector('.zui-item-value');
                const options = ['head', 'torso', 'legs'];
                let idx = options.indexOf(CheatSettings.hitbox);
                const upd = () => { valEl.innerText = CheatSettings.hitbox.charAt(0).toUpperCase() + CheatSettings.hitbox.slice(1); valEl.style.color = '#fff'; };
                itemEl.onclick = () => { idx = (idx + 1) % options.length; CheatSettings.hitbox = options[idx]; };
                upd(); tabDiv.appendChild(itemEl); watchProp(prop, upd);
            } else if (prop === 'fovChanger') {
                const itemEl = fromHtml(`<div class="zui-item"><span>${name}</span><span class="zui-item-value"></span></div>`);
                const valEl = itemEl.querySelector('.zui-item-value');
                const upd = () => { valEl.innerText = CheatSettings.fovChanger > 0 ? CheatSettings.fovChanger + '\u00B0' : 'Off'; valEl.style.color = CheatSettings.fovChanger > 0 ? '#00ff00' : '#fff'; };
                itemEl.onclick = () => { CheatSettings.fovChanger = (CheatSettings.fovChanger + 10) % 170; if (CheatSettings.fovChanger === 0) CheatSettings.fovChanger = 30; };
                upd(); tabDiv.appendChild(itemEl); watchProp(prop, upd);
            } else {
                const keyLabel = hasBind ? `<span class="zui-keybind" data-setting="${prop}">${formatKey(currentKey)}</span>` : '';
                const itemEl = fromHtml(`<div class="zui-item"><span>${name}${keyLabel}</span><span class="zui-item-value"></span></div>`);
                const valEl = itemEl.querySelector('.zui-item-value');
                const keybindEl = itemEl.querySelector('.zui-keybind');
                if (keybindEl) {
                    keybindEl.addEventListener('click', function(e) {
                        e.stopPropagation();
                        if (listeningForKey) listeningKeyEl.classList.remove('listening');
                        const currentBind = Object.entries(keyToSetting).find(([k, v]) => v === prop);
                        if (currentBind) {
                            listeningForKey = currentBind[0]; listeningKeyEl = keybindEl;
                            keybindEl.textContent = '...'; keybindEl.classList.add('listening');
                        }
                    });
                }
                const upd = () => {
                    const v = CheatSettings[prop];
                    valEl.innerText = v ? 'ON' : 'OFF';
                    valEl.style.color = v ? 'var(--on-color)' : 'var(--off-color)';
                };
                itemEl.onclick = () => { CheatSettings[prop] = !CheatSettings[prop]; };
                upd(); tabDiv.appendChild(itemEl); watchProp(prop, upd);
            }
        }
        tabContents[tabName] = tabDiv;
        contentEl.appendChild(tabDiv);
    }

    // Tab switching
    tabsContainer.addEventListener('click', (e) => {
        const tab = e.target.closest('.zui-tab');
        if (!tab) return;
        const target = tab.dataset.tab;
        tabsContainer.querySelectorAll('.zui-tab').forEach(t => t.classList.remove('active'));
        tab.classList.add('active');
        for (const [tabName, div] of Object.entries(tabContents)) {
            div.style.display = tabName === target ? 'block' : 'none';
        }
    });

    return guiEl;
}

function watchProp(prop, updateFn) {
    const p = `__${prop}`;
    CheatSettings[p] = CheatSettings[prop];
    Object.defineProperty(CheatSettings, prop, {
        get() { return this[p]; },
        set(v) { this[p] = v; updateFn(); }
    });
}

function fromCamel(text) {
    const r = text.replace(/([A-Z])/g, ' $1');
    return r.charAt(0).toUpperCase() + r.slice(1);
}

function fromHtml(html) {
    const div = document.createElement('div');
    div.innerHTML = html;
    return div.children[0];
}

function toggleSetting(key) {
    CheatSettings[key] = !CheatSettings[key];
    showMsg(fromCamel(key), CheatSettings[key]);
}