Aimbot, triggerbot, chams, no-recoil, High Visibility NameTags (No Ores) with sound
// ==UserScript== // @name Kobitz VOXHACK Menu // @namespace http://tampermonkey.net/ // @match https://voxiom.io/* // @run-at document-start // @grant none // @version 3.0 // @author Log & Modified // @description Aimbot, triggerbot, chams, no-recoil, High Visibility NameTags (No Ores) with sound // @license GPL // @require https://cdn.jsdelivr.net/npm/[email protected]/dist/lil-gui.umd.min.js // @require https://unpkg.com/[email protected]/build/three.min.js // @icon https://www.google.com/s2/favicons?sz=64&domain=voxiom.io // ==/UserScript== if (!document.getElementById('side-player-list')) { const listUI = document.createElement('div'); listUI.id = 'side-player-list'; listUI.style = ` position: fixed; top: 230px; left: 0px; width: 280px; background: rgba(0, 0, 0, 0.85); border-left: 5px solid #00ff00; color: white; font-family: 'Segoe UI', sans-serif; font-size: 16px; z-index: 10001; padding: 15px; border-radius: 0 10px 10px 0; pointer-events: none; box-shadow: 8px 8px 20px rgba(0,0,0,0.6); `; // Thêm style cho mục được chọn bằng phím tắt và làm rõ số mét const styleSheet = document.createElement("style"); styleSheet.innerText = ` .player-row { display: flex; align-items: center; margin-bottom: 8px; transition: all 0.2s; padding: 2px 5px; border-radius: 4px; } .player-row.selected { background: rgba(255, 255, 0, 0.3) !important; border: 1px solid yellow; } .dist-text { margin-left: auto; color: #00ffff !important; font-size: 13px; font-weight: bold; opacity: 1 !important; text-shadow: 1px 1px 2px #000; } `; document.head.appendChild(styleSheet); listUI.innerHTML = ` <div style="color:#00ff00; font-weight:bold; margin-bottom:10px; border-bottom:1px solid #444; font-size:12px; letter-spacing:1px; text-transform: uppercase;"> 📡 Player Radar (<span id="radar-count" style="color: #00ff00;">0</span>) </div> <div id="list-content"></div> `; document.body.appendChild(listUI); }// --- TẠO BẢNG THÔNG BÁO CÓ HIỆU ỨNG TRƯỢT --- const statusNotify = document.createElement('div'); statusNotify.id = 'status-notify'; statusNotify.style = ` position: fixed; bottom: 50px; left: -300px; /* Bắt đầu ở ngoài màn hình bên trái */ padding: 10px 20px; background: rgba(0, 0, 0, 0.9); color: #00ff00; border-left: 5px solid #00ff00; font-family: 'Segoe UI', sans-serif; font-size: 13px; font-weight: bold; z-index: 10005; pointer-events: none; border-radius: 0 4px 4px 0; /* Bo góc bên phải */ box-shadow: 5px 0 15px rgba(0,0,0,0.5); text-transform: uppercase; transition: left 0.3s ease-out; /* Hiệu ứng trượt trong 0.3 giây */ `; document.body.appendChild(statusNotify); let statusTimer; function notifyStatus(label, value) { statusNotify.innerHTML = `${label}: <span style="color:white">${value}</span>`; // Hiệu ứng: Chạy từ trái vào (sát lề 0px) statusNotify.style.left = '0px'; clearTimeout(statusTimer); statusTimer = setTimeout(() => { // Hiệu ứng: Chạy ngược ra ngoài màn hình statusNotify.style.left = '-300px'; }, 2000); } // CHÈN VÀO ĐÂY: window.handlePlayerAction = function(name) { console.log("Đang tương tác với người chơi: " + name); // Ví dụ: Thông báo tên người chơi vừa nhấn alert("Bạn đã chọn: " + name); }; // Khởi tạo Map toàn cục window.playerMap = new Map(); window.lastPositions = new Map(); // Cực kỳ quan trọng: Không có cái này máy không nhớ được vị trí cũ để tính hướng di chuyển window.ignoredPlayers = new Set(); // Danh sách lưu tên người chơi bị né // Hàm tạo tiếng "Ping" thanh mảnh khi nhấn window.playClickSound = function() { try { const oscillator = audioCtx.createOscillator(); const gainNode = audioCtx.createGain(); oscillator.connect(gainNode); gainNode.connect(audioCtx.destination); oscillator.type = 'sine'; oscillator.frequency.setValueAtTime(1500, audioCtx.currentTime); // Tần số cao nghe rất thanh gainNode.gain.setValueAtTime(0.1, audioCtx.currentTime); gainNode.gain.exponentialRampToValueAtTime(0.01, audioCtx.currentTime + 0.2); oscillator.start(); oscillator.stop(audioCtx.currentTime + 0.2); } catch (e) { console.log("Audio error"); } }; window.handlePlayerAction = function(name) { window.playClickSound(); // Kêu Ping! if (window.ignoredPlayers.has(name)) { window.ignoredPlayers.delete(name); } else { window.ignoredPlayers.add(name); } }; // Hàm tạo tiếng "tích" nhỏ khi nhấn window.playClickSound = function() { try { if (!window.sharedAudioCtx) window.sharedAudioCtx = new (window.AudioContext || window.webkitAudioContext)(); const audioCtx = window.sharedAudioCtx; const oscillator = audioCtx.createOscillator(); const gainNode = audioCtx.createGain(); oscillator.connect(gainNode); gainNode.connect(audioCtx.destination); oscillator.type = 'sine'; oscillator.frequency.setValueAtTime(1200, audioCtx.currentTime); // Tần số cao cho tiếng "tích" gainNode.gain.setValueAtTime(0.05, audioCtx.currentTime); // Âm lượng nhỏ gainNode.gain.exponentialRampToValueAtTime(0.01, audioCtx.currentTime + 0.1); oscillator.start(); oscillator.stop(audioCtx.currentTime + 0.1); } catch (e) {} }; window.handlePlayerAction = function(name) { window.playClickSound(); // Phát âm thanh ngay lập tức if (window.ignoredPlayers.has(name)) { window.ignoredPlayers.delete(name); } else { window.ignoredPlayers.add(name); } }; window.handlePlayerAction = function(name) { if (window.ignoredPlayers.has(name)) { window.ignoredPlayers.delete(name); console.log("Đã cho phép bắn: " + name); } else { window.ignoredPlayers.add(name); console.log("Aimbot sẽ né: " + name); } }; // avoid detection const matchDetection = /^function\(\){\w+\['\w+'\]\(\);}$/; const setIntervalHandler = { apply: function(target, thisArg, argumentsList) { const callback = argumentsList[0]; const delay = argumentsList[1]; if (delay === 1000 && callback && callback.toString().match(matchDetection)) { console.log('Blocked detection'); return null; } return Reflect.apply(...arguments); } }; window.setInterval = new Proxy(window.setInterval, setIntervalHandler); // add #lil-gui container const lilGuiContainer = document.createElement('div'); lilGuiContainer.id = 'lil-gui'; document.body.appendChild(lilGuiContainer); const style = document.createElement('style'); const guiStyle = document.createElement('style'); const GUI = lil.GUI; const gui = new GUI({ container: lilGuiContainer, title: 'Kobitz Menu' }); // THÊM ĐOẠN NÀY NGAY PHÍA DƯỚI: gui.onFinishChange(() => { const configToSave = gui.save(); localStorage.setItem('espConfig', JSON.stringify(configToSave)); console.log('Đã lưu cấu hình mới!'); }); let espConfig = { heightLine: 1.16, zoomLevel: 20, // Độ phóng (càng nhỏ càng phóng xa) zoomKey: 'z', // Phím Zoom là Z isZooming: false, // Trạng thái Zoom fZoomEnabled: false, sneakHeight: 0.4, ennemyDistance: 50, maxAngleInRadians: 0.5, unlimitedAngle: false, // THÊM DÒNG NÀY: Trạng thái không giới hạn góc noRecoil: true, showBox: 0, showOutline: 0, showPlayer: 2, nameScaling: true, // Bật/tắt tự động phóng to theo khoảng cách showPlayerNames: true, showRadar: true, // Mặc định bảng sẽ hiện khi vào game showLine: 1, wireframe: false, allEnnemies: false, isSniper: false, aimbot: 2, triggerBot: 2, aimbotIgnoreWall: false, aimbotIgnoreWallKey: '\\', // Thêm dòng này để gán phím \ mapZoom: 100, mapOffsetZ: 0, autoClaimAds: false, antiAFK: false, antiAFKKey: 'k', // Thêm phím tắt cho Anti-AFK showRadar: true, // THÊM DÒNG NÀY: Mặc định hiện bảng Radar sit: false, sit: false, // Lưu trạng thái cho nút trên Menu rainbow: false, rainbowKey: '=', // Gán phím = showAimRadius: false, lockAimbotTriggerBot: false, aimbotKey: 'b', triggerBotKey: 't', toggleUIKey: '.', // NEW: Sound features triggerSound: false, triggerSoundType: 'beep', triggerSoundVolume: 0.5, // NEW: Item ESP showItems: false, showItemNames: false, // NEW: Key bindings showItemsKey: 'i', showItemNamesKey: 'n', }; const aimbotFolder = gui.addFolder('Aimbot'); aimbotFolder.add(espConfig, 'aimbot').name(`aimbot (${espConfig.aimbotKey})`).options({Off: 0, LeftClick: 1, RightClick: 2, Always: 3}).listen(); aimbotFolder.add(espConfig, 'triggerBot').name(`triggerBot (${espConfig.triggerBotKey})`).options({Off: 0, LeftClick: 1, RightClick: 2, Always: 3}).listen(); aimbotFolder.add(espConfig, 'noRecoil'); aimbotFolder.add(espConfig, 'allEnnemies').name("All Enemies (L)").listen(); aimbotFolder.add(espConfig, 'isSniper'); const advancedAimbotFolder = aimbotFolder.addFolder('Advanced'); advancedAimbotFolder.close(); advancedAimbotFolder.add(espConfig, 'aimbotIgnoreWall'); advancedAimbotFolder.add(espConfig, 'showAimRadius'); advancedAimbotFolder.add(espConfig, 'maxAngleInRadians', 0.01, 0.5, 0.01); advancedAimbotFolder.add(espConfig, 'unlimitedAngle').name('Không giới hạn góc (Unlimited)'); advancedAimbotFolder.add(espConfig, 'heightLine', .5, 1.25, 0.01); advancedAimbotFolder.add(espConfig, 'sneakHeight', 0, 1, 0.01); const chamsFolder = gui.addFolder('Chams'); chamsFolder.close(); chamsFolder.add(espConfig, 'showPlayer').options({Off: 0, Ennemies: 1, All: 2}); chamsFolder.add(espConfig, 'nameScaling').name('Auto Scale Names'); chamsFolder.add(espConfig, 'showPlayerNames').name('Show Names'); chamsFolder.add(espConfig, 'showRadar').name("Show Radar ( ' )").listen(); chamsFolder.add(espConfig, 'showRadar').name("Hiện Bảng Radar ( ' )").listen(); // Lệnh .listen() cực kỳ quan trọng để dấu tích tự nhảy khi bạn nhấn phím ' chamsFolder.add(espConfig, 'showLine').options({Off: 0, Ennemies: 1, All: 2}); chamsFolder.add(espConfig, 'showOutline').options({Off: 0, Ennemies: 1, All: 2}); chamsFolder.add(espConfig, 'showBox').options({Off: 0, Ennemies: 1, All: 2}); chamsFolder.add(espConfig, 'ennemyDistance', 10, 100, 1); chamsFolder.add(espConfig, 'wireframe'); chamsFolder.add(espConfig, 'rainbow').name("rainbow ( = )").listen(); chamsFolder.add(espConfig, 'mapZoom', 20, 100, 1); chamsFolder.add(espConfig, 'mapOffsetZ', -50, 50, 1); // NEW: Item ESP settings chamsFolder.add(espConfig, 'showItems').name(`Show Items (${espConfig.showItemsKey})`); chamsFolder.add(espConfig, 'showItemNames').name(`Show Item Names (${espConfig.showItemNamesKey})`); // NEW: Sound folder const soundFolder = gui.addFolder('Sound'); soundFolder.close(); soundFolder.add(espConfig, 'triggerSound').name('Triggerbot Sound'); // ĐÃ THÊM DANH SÁCH 11 ÂM THANH soundFolder.add(espConfig, 'triggerSoundType', [ 'beep', 'click', 'ping', 'laser', 'retro', 'heavy', 'digital', 'sharp', 'ufo', 'electric', 'dubstep' ]).name('Sound Type'); soundFolder.add(espConfig, 'triggerSoundVolume', 0.1, 1, 0.1).name('Volume'); const zoomFolder = gui.addFolder('Tính năng Zoom'); zoomFolder.add(espConfig, 'isZooming').name('Đang Zoom (Z)').listen(); zoomFolder.add(espConfig, 'zoomLevel', 1, 175, 1).name('Độ Zoom (FOV)').listen(); zoomFolder.add(espConfig, 'fZoomEnabled').name('Bật Zoom phím F').listen(); // Nút mới ở đây zoomFolder.add(espConfig, 'zoomKey').name('Phím Zoom'); const toolsFolder = gui.addFolder('Tools'); toolsFolder.close(); toolsFolder.add(espConfig, 'autoClaimAds'); toolsFolder.add(espConfig, 'antiAFK').name(`antiAFK (${espConfig.antiAFKKey})`).listen(); toolsFolder.add(espConfig, 'sit').name('Sit Mode (V)'); // Nút bấm trên Menu toolsFolder.add(espConfig, 'lockAimbotTriggerBot'); // load/save config const configFolder = gui.addFolder('Config'); configFolder.add(espConfig, 'toggleUIKey').name('Toggle UI key'); configFolder.add(espConfig, 'aimbotKey').name('Aimbot key'); configFolder.add(espConfig, 'triggerBotKey').name('Triggerbot key'); configFolder.add(espConfig, 'showItemsKey').name('Show Items key'); // NEW configFolder.add(espConfig, 'showItemNamesKey').name('Show Item Names key'); // NEW configFolder.close(); const defaultConfig = gui.save(); let config = { configName: 'espConfig' }; configFolder.add(config, 'configName').name('Config name'); configFolder.add({ export: () => { const currentConfig = JSON.stringify(gui.save(), null, 2); const element = document.createElement('a'); element.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(currentConfig)); element.setAttribute('download', config.configName + '.json'); element.style.display = 'none'; document.body.appendChild(element); element.click(); document.body.removeChild(element); }}, 'export').name('Export config'); configFolder.add({ import: () => { const input = document.createElement('input'); input.type = 'file'; input.accept = '.json'; input.onchange = (e) => { const file = e.target.files[0]; const reader = new FileReader(); reader.onload = (e) => { gui.load(JSON.parse(e.target.result)); }; reader.readAsText(file); }; input.click(); }}, 'import').name('Import config'); configFolder.add({ reset: () => { gui.load(defaultConfig); localStorage.removeItem('espConfig'); }}, 'reset').name('Reset config'); // auto load/save config const savedConfig = localStorage.getItem('espConfig'); if (savedConfig) { console.log('Loaded config', savedConfig); gui.load(JSON.parse(savedConfig)); } // --- TỐI ƯU ÂM THANH: Tạo 1 đối tượng duy nhất để dùng lại --- const clickSound = new Audio('https://commondatastorage.googleapis.com/codeskulptor-assets/week7-brads79-brio.ogg'); clickSound.volume = 0.5; // --- ĐOẠN MÃ TỐI ƯU: CHỈ DÙNG 1 LISTENER DUY NHẤT --- document.addEventListener('keydown', (e) => { // 1. Kiểm tra nếu đang gõ văn bản thì không kích hoạt hack const isInputField = e.target && (e.target.isContentEditable || e.target instanceof HTMLInputElement || e.target instanceof HTMLTextAreaElement); if (isInputField) return; const key = e.key; const keyL = e.key.toLowerCase(); const modes = ["OFF", "LeftClick", "RightClick", "Always"]; // 2. Xử lý các phím chức năng switch (keyL) { case espConfig.rainbowKey: // Phím '=' espConfig.rainbow = !espConfig.rainbow; notifyStatus("Rainbow", espConfig.rainbow ? "ON" : "OFF"); break; case espConfig.aimbotIgnoreWallKey: // Phím '\' case 'n': // Sửa điều kiện: thêm phím '\' vào để nó nhận diện đúng if (e.shiftKey || key === 'N' || key === '\\') { espConfig.aimbotIgnoreWall = !espConfig.aimbotIgnoreWall; notifyStatus("aimbotIgnoreWall", espConfig.aimbotIgnoreWall ? "ON" : "OFF"); } else { espConfig.showItemNames = !espConfig.showItemNames; notifyStatus("showItemName", espConfig.showItemNames ? "ON" : "OFF"); } break; case 'k': espConfig.antiAFK = !espConfig.antiAFK; notifyStatus("Anti-AFK", espConfig.antiAFK ? "ON" : "OFF"); break; case 'i': espConfig.showItems = !espConfig.showItems; notifyStatus("Show Items", espConfig.showItems ? "ON" : "OFF"); break; case 'b': if (!espConfig.lockAimbotTriggerBot) { espConfig.aimbot = (espConfig.aimbot + 1) % 4; notifyStatus("Aimbot", modes[espConfig.aimbot]); } break; case espConfig.zoomKey.toLowerCase(): espConfig.isZooming = true; break; case 't': if (!espConfig.lockAimbotTriggerBot) { espConfig.triggerBot = (espConfig.triggerBot + 1) % 4; notifyStatus("TriggerBot", modes[espConfig.triggerBot]); } break; case 'l': espConfig.allEnnemies = !espConfig.allEnnemies; notifyStatus("All Enemies", espConfig.allEnnemies ? "ON" : "OFF"); break; case 'f': // Thêm xử lý cho phím F if (espConfig.fZoomEnabled) { espConfig.isZooming = true; } break; case ';': espConfig.wireframe = !espConfig.wireframe; notifyStatus("Wireframe", espConfig.wireframe ? "ON" : "OFF"); break; case 'v': espConfig.sit = !espConfig.sit; // Lệnh đảo trạng thái Bật/Tắt notifyStatus("Sit Mode", espConfig.sit ? "ON" : "OFF"); break; case "'": espConfig.showRadar = !espConfig.showRadar; notifyStatus("Radar", espConfig.showRadar ? "ON" : "OFF"); const radar = document.getElementById('side-player-list'); if (radar) radar.style.display = espConfig.showRadar ? 'block' : 'none'; break; case espConfig.toggleUIKey: // Phím '.' lilGuiContainer.style.display = lilGuiContainer.style.display === 'none' ? 'block' : 'none'; break; case 'e': if (espConfig.autoClaimAds) setTimeout(claimAds, 100); break; } // Cập nhật lại Menu lil-gui để đồng bộ dấu tích if (typeof gui !== 'undefined') { gui.controllersRecursive().forEach(c => c.updateDisplay()); } }); // NEW: Sound functions let audioContext = null; let lastSoundTime = 0; const soundCooldown = 100; // ms between sounds function createTriggerSound(type, volume) { if (!audioContext) { audioContext = new (window.AudioContext || window.webkitAudioContext)(); } const now = Date.now(); if (now - lastSoundTime < soundCooldown) return; lastSoundTime = now; const gainNode = audioContext.createGain(); gainNode.gain.value = volume; gainNode.connect(audioContext.destination); const oscillator = audioContext.createOscillator(); oscillator.connect(gainNode); switch(type) { case 'beep': oscillator.frequency.value = 800; oscillator.type = 'sine'; oscillator.start(); oscillator.stop(audioContext.currentTime + 0.05); break; case 'click': oscillator.frequency.value = 1200; oscillator.type = 'sine'; oscillator.start(); oscillator.stop(audioContext.currentTime + 0.03); break; case 'ping': oscillator.frequency.value = 1000; oscillator.type = 'triangle'; oscillator.start(); oscillator.frequency.exponentialRampToValueAtTime(2000, audioContext.currentTime + 0.1); oscillator.stop(audioContext.currentTime + 0.1); break; case 'laser': oscillator.frequency.value = 1500; oscillator.type = 'sawtooth'; oscillator.start(); oscillator.frequency.exponentialRampToValueAtTime(200, audioContext.currentTime + 0.2); oscillator.stop(audioContext.currentTime + 0.2); break; case 'retro': oscillator.frequency.value = 600; oscillator.type = 'square'; oscillator.start(); oscillator.frequency.exponentialRampToValueAtTime(100, audioContext.currentTime + 0.1); oscillator.stop(audioContext.currentTime + 0.1); break; // --- CÁC ÂM THANH MỚI --- case 'heavy': oscillator.frequency.value = 150; oscillator.type = 'sawtooth'; oscillator.start(); oscillator.frequency.exponentialRampToValueAtTime(50, audioContext.currentTime + 0.15); oscillator.stop(audioContext.currentTime + 0.15); break; case 'digital': oscillator.frequency.value = 2000; oscillator.type = 'square'; oscillator.start(); oscillator.frequency.setValueAtTime(1500, audioContext.currentTime + 0.05); oscillator.stop(audioContext.currentTime + 0.1); break; case 'sharp': oscillator.frequency.value = 3000; oscillator.type = 'sine'; oscillator.start(); oscillator.stop(audioContext.currentTime + 0.02); break; case 'ufo': oscillator.frequency.value = 1000; oscillator.type = 'sine'; oscillator.start(); oscillator.frequency.linearRampToValueAtTime(200, audioContext.currentTime + 0.2); oscillator.frequency.linearRampToValueAtTime(1000, audioContext.currentTime + 0.4); oscillator.stop(audioContext.currentTime + 0.2); break; case 'electric': oscillator.frequency.value = 400; oscillator.type = 'sawtooth'; gainNode.gain.setTargetAtTime(0, audioContext.currentTime, 0.05); oscillator.start(); oscillator.stop(audioContext.currentTime + 0.1); break; case 'dubstep': oscillator.frequency.value = 100; oscillator.type = 'square'; oscillator.start(); oscillator.frequency.exponentialRampToValueAtTime(800, audioContext.currentTime + 0.05); oscillator.frequency.exponentialRampToValueAtTime(100, audioContext.currentTime + 0.1); oscillator.stop(audioContext.currentTime + 0.15); break; } } function playTriggerSound() { if (espConfig.triggerSound) { createTriggerSound(espConfig.triggerSoundType, espConfig.triggerSoundVolume); } } // no-recoil let foundRecoil = false; const arrayPushHandler = { apply: function(target, thisArg, argumentsList) { if (!foundRecoil && argumentsList.length === 1) { const item = argumentsList[0]; if (item && typeof item === 'object') { const keys = Object.keys(item); if (keys.length === 44) { for (const key in item) { if (item[key] === 0.3) { console.log('Recoil key found', key); foundRecoil = true; Object.defineProperty(Object.prototype, key, { get: () => { return espConfig.noRecoil ? 0 : item[key]; }, set: (baseRecoil) => { _baseRecoil = baseRecoil; } }); break; } } } } } return Reflect.apply(...arguments); } }; Array.prototype.push = new Proxy(Array.prototype.push, arrayPushHandler); // listen for mouse click let isLeftClick = false; let isRightClick = false; document.addEventListener('mousedown', (e) => { if (e.button === 0) { isLeftClick = true; } if (e.button === 2) { if (espConfig.isSniper) { setTimeout(() => { isRightClick = true; }, 400); } else { isRightClick = true; } } }); document.addEventListener('mouseup', (e) => { if (e.button === 0) { isLeftClick = false; } if (e.button === 2) { isRightClick = false; } }); // obfuscaed keys let worldScene = null; let childrenKey = null; let worldCamera = null; let projectionMatrixKey = null; let matrixWorldKey = null; let matrixElKey = null; // three.js setup const scene = new THREE.Scene(); const camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 0.1, 1000); camera.rotation.order = 'YXZ'; let saveViewport = new THREE.Vector4(); let saveScissor = new THREE.Vector4(); let minimapViewport = new THREE.Vector4(20, window.innerHeight - 250 - 20, 250, 250); const minimapCamera = new THREE.OrthographicCamera(-espConfig.mapZoom, espConfig.mapZoom, espConfig.mapZoom, -espConfig.mapZoom, 0.1, 1000); minimapCamera.rotation.order = 'YXZ'; minimapCamera.position.set(0, 50, 0); minimapCamera.lookAt(0, 0, 0); const renderer = new THREE.WebGLRenderer( { alpha: true, antialias: true }); renderer.setSize(window.innerWidth, window.innerHeight); renderer.setPixelRatio(window.devicePixelRatio); renderer.domElement.id = 'overlayCanvas'; document.body.appendChild(renderer.domElement); function setTransform(target, transform, isMatrix = true) { const matrix = new THREE.Matrix4().fromArray(isMatrix ? transform : transform[matrixWorldKey][matrixElKey]); matrix.decompose(target.position, target.quaternion, target.scale); } doOnce = (fn) => { let done = false; return (...args) => { if (!done) { done = true; return fn(...args); } }; }; function checkWorldCamera(object) { if (worldCamera && object.uuid === worldCamera.uuid) return; let hasProjectionMatrix = false; for (const key in object) { const element = object[key]; if (!element) continue; if (typeof element == 'object') { if (hasProjectionMatrix) continue; const valueKey = Object.keys(element)[0]; const value = element[valueKey]; if (Array.isArray(value) && value[11] === -1) { hasProjectionMatrix = true; matrixElKey = valueKey; projectionMatrixKey = key; } } else if (typeof element === 'function') { const code = element.toString(); const match = /verse'\]\(this\['([^']+)'\]\);/.exec(code); if (match) { matrixWorldKey = match[1]; } } if (hasProjectionMatrix && matrixWorldKey) { console.log('Found camera', {object}, object); worldCamera = object; object[projectionMatrixKey] = new Proxy(object[projectionMatrixKey], { get: function(target, prop, receiver) { // 1. Update overlay camera (camera) based on game's worldCamera state setTransform(camera, worldCamera, false); camera.near = worldCamera.near; camera.far = worldCamera.far; camera.aspect = worldCamera.aspect; camera.fov = worldCamera.fov; camera.updateProjectionMatrix(); worldCamera = object; window.worldCamera = object; return Reflect.get(...arguments); } }); break; } } } function checkWorldScene(object) { if (worldScene || object instanceof THREE.Scene) return; for (const key in object) { const element = object[key]; if (!element) continue; if (Array.isArray(element) && element.length === 9) { const value = element[0]; if (value && typeof value === 'object' && value.hasOwnProperty('uuid')) { childrenKey = key; } } if (childrenKey) { console.log('Found scene', {childrenKey}, object); worldScene = object; window.worldScene = object; renderer.setAnimationLoop(animate); break; } } } Object.defineProperty( Object.prototype, 'overrideMaterial', { get: function() { checkWorldScene(this); return this._overrideMaterial; }, set: function(value) { this._overrideMaterial = value; } }); Object.defineProperty( Object.prototype, 'far', { get: function() { checkWorldCamera(this); return this._far; }, set: function(value) { this._far = value; } }); function isPlayer(entity) { try { return entity[childrenKey].length > 2 || !entity[childrenKey][1].geometry; } catch { return false; } } // NEW: Function to check if entity is an item (from the first script) function isItem(entity) { try { // Items typically have simpler geometry than players const mesh = entity[childrenKey][0]; if (mesh && mesh.geometry) { // Check if it's not a player and has geometry (could be item or block) return !isPlayer(entity) && mesh.geometry; } return false; } catch { return false; } } // NEW: Function to create item sprite with name function createItemSprite(text, colorStr) { const fontface = "Arial"; const fontsize = 40; const padding = 8; const canvas = document.createElement('canvas'); const context = canvas.getContext('2d'); context.font = "Bold " + fontsize + "px " + fontface; const metrics = context.measureText(text); const textWidth = metrics.width; canvas.width = textWidth + padding * 2; canvas.height = fontsize * 1.2; context.font = "Bold " + fontsize + "px " + fontface; context.textBaseline = "middle"; context.textAlign = "center"; context.fillStyle = "rgba(0, 0, 0, 0.6)"; context.fillRect(0, 0, canvas.width, canvas.height); context.fillStyle = colorStr; context.fillText(text, canvas.width / 2, canvas.height / 2); const texture = new THREE.CanvasTexture(canvas); texture.minFilter = THREE.LinearFilter; const spriteMaterial = new THREE.SpriteMaterial({ map: texture, depthTest: false, depthWrite: false }); const sprite = new THREE.Sprite(spriteMaterial); sprite.initialRatio = (canvas.width / canvas.height); sprite.baseScale = 1.0; sprite.scale.set(0.3 * sprite.initialRatio, 0.3, 1); sprite.scale.multiplyScalar(sprite.baseScale); return sprite; } // claim ads function claimAds() { document.querySelectorAll('svg').forEach(svg => { if (svg.getAttribute('data-icon') === 'play-circle') { svg.closest('div').click(); console.log('Claimed ads'); } }); } const context2DFillTextHandler = { apply: function(target, thisArg, argumentsList) { thisArg.canvas.lastText = argumentsList[0]; return Reflect.apply(...arguments); } }; CanvasRenderingContext2D.prototype.fillText = new Proxy(CanvasRenderingContext2D.prototype.fillText, context2DFillTextHandler); function isEnnemy(entity) { for (const child of entity[childrenKey]) { try { const matImage = child.material.map.image; if (matImage instanceof HTMLCanvasElement && matImage.hasOwnProperty('lastText')) { entity.playerName = matImage.lastText; return false; } } catch {} } return true; } let lastFiringState = false; function setFiring(shouldFire) { if (setFiring.firing === shouldFire) return; setFiring.firing = shouldFire; // NEW: Play sound when starting to fire if (shouldFire && !lastFiringState) { playTriggerSound(); } lastFiringState = shouldFire; if (shouldFire) { if (espConfig.isSniper) { // need improvement setTimeout(() => { document.dispatchEvent(new MouseEvent('mousedown', { buttons: 3 })); setTimeout(() => { document.dispatchEvent(new MouseEvent('mouseup', { buttons: 0 })); }, 200); // setFiring.firing = false; }, 300); } else { document.dispatchEvent(new MouseEvent('mousedown', { buttons: 3 })); } } else { document.dispatchEvent(new MouseEvent('mouseup', { buttons: 0 })); } } const colors = { ennemy: new THREE.Color(0xff0000), player: new THREE.Color(0x00ff00), blue: new THREE.Color(0x0000ff), item: new THREE.Color(0xD4AF37) // NEW: Gold color for items (from first script) }; const outlineMats = { ennemy: new THREE.LineBasicMaterial({ color: colors.ennemy }), player: new THREE.LineBasicMaterial({ color: colors.player }) }; const meshMats = { ennemy: new THREE.MeshBasicMaterial({ color: colors.ennemy, transparent: true, opacity: 0.5 }), player: new THREE.MeshBasicMaterial({ color: colors.player, transparent: true, opacity: 0.5 }), item: new THREE.MeshBasicMaterial({ color: colors.item, transparent: true, opacity: 0.7 }) // NEW: Item material }; const raycaster = new THREE.Raycaster(); const edgesGeometry = new THREE.EdgesGeometry(new THREE.BoxGeometry(1, 1, 1).translate(0, 0.5, 0)); // NEW: Item box geometry (smaller than player boxes) const itemBoxGeometry = new THREE.BoxGeometry(0.25, 0.25, 0.25); const lineGeometry = new THREE.BufferGeometry(); const lineMaterial = new THREE.LineBasicMaterial({ vertexColors: true, transparent: true }); const line = new THREE.LineSegments(lineGeometry, lineMaterial); line.frustumCulled = false; scene.add(line); const dummyLookAt = new THREE.PerspectiveCamera(); const color = new THREE.Color(); const chunkMaterial = new THREE.MeshNormalMaterial(); const boxPlayerGeometry = new THREE.BoxGeometry(.25, 1.25, 0.25); // crosshair circle const crosshairGeometry = new THREE.CircleGeometry(.5, 32); const crosshairMaterial = new THREE.LineBasicMaterial({ color: 0xffffff, transparent: true, opacity: 0.2 }); const crosshair = new THREE.LineLoop(crosshairGeometry, crosshairMaterial); camera.add(crosshair); scene.add(camera); function calculateValue(maxAngleInRadians) { const a = -79.83; const b = -30.06; const c = -0.90; return a * Math.exp(b * maxAngleInRadians) + c; } // Hàm tạo Text Sprite: RÕ RÀNG HƠN với nền đen và chữ to function makeTextSprite(message, colorStr) { const fontface = "Arial"; const fontsize = 60; const padding = 10; const canvas = document.createElement('canvas'); const context = canvas.getContext('2d'); context.font = "Bold " + fontsize + "px " + fontface; const metrics = context.measureText(message); const textWidth = metrics.width; canvas.width = textWidth + padding * 2; canvas.height = fontsize * 1.4; context.font = "Bold " + fontsize + "px " + fontface; context.textBaseline = "middle"; context.textAlign = "center"; context.fillStyle = "rgba(0, 0, 0, 0.6)"; context.fillRect(0, 0, canvas.width, canvas.height); context.fillStyle = colorStr; context.fillText(message, canvas.width / 2, canvas.height / 2); const texture = new THREE.CanvasTexture(canvas); texture.minFilter = THREE.LinearFilter; const spriteMaterial = new THREE.SpriteMaterial({ map: texture, depthTest: false, depthWrite: false }); const sprite = new THREE.Sprite(spriteMaterial); // Đặt tỷ lệ cơ bản (nhỏ hơn 2.0 ban đầu) và lưu ratio/baseScale sprite.initialRatio = (canvas.width / canvas.height); sprite.baseScale = 1.5; // Kích thước cơ bản sprite.scale.set(0.5 * sprite.initialRatio, 0.5, 1); sprite.scale.multiplyScalar(sprite.baseScale); return sprite; } function animate(time) { const now = Date.now(); const entities = childrenKey ? worldScene[childrenKey][5][childrenKey] : []; const lineOrigin = camera.localToWorld(new THREE.Vector3(0, 0, -10)); const linePositions = []; crosshair.position.z = calculateValue(espConfig.maxAngleInRadians); crosshair.visible = espConfig.showAimRadius && !espConfig.unlimitedAngle; const colorArray = []; const aimbotTarget = { angleDifference: Infinity}; const chunks = []; const gameChunks = childrenKey ? worldScene[childrenKey][4][childrenKey] : []; for (const chunk of gameChunks) { if (!chunk || !chunk.geometry) continue; const chunkPositions = chunk.geometry.attributes.position.array; if (!chunkPositions || !chunkPositions.length) continue; if (!chunk.myChunk) { const geometry = new THREE.BufferGeometry(); geometry.setAttribute( 'position', new THREE.Float32BufferAttribute(chunkPositions, 3) ); geometry.setIndex( new THREE.BufferAttribute(chunk.geometry.index.array, 1) ); geometry.computeVertexNormals(); geometry.computeBoundingBox(); chunk.myChunk = new THREE.Mesh(geometry, chunkMaterial); chunk.myChunk.box = new THREE.Box3(); } const myChunk = chunk.myChunk; if (chunk.material) chunk.material.wireframe = espConfig.wireframe; setTransform(myChunk, chunk, false); myChunk.updateMatrixWorld(); myChunk.box.copy(myChunk.geometry.boundingBox).applyMatrix4(myChunk.matrixWorld); chunks.push(myChunk); } chunks.sort((a, b) => { const distanceA = a.position.distanceTo(camera.position); const distanceB = b.position.distanceTo(camera.position); return distanceB - distanceA; }); const shouldAimbot = espConfig.aimbot === 3 || (espConfig.aimbot === 1 && isLeftClick) || (espConfig.aimbot === 2 && isRightClick); entities.forEach(entity => { if (!entity || !entity.parent) return; if (!entity.myObject3D) { entity.myObject3D = new THREE.Object3D(); entity.myObject3D.frustumCulled = false; entity.discovered = now; entity.loaded = false; entity.logged = false; entity.ennemy = null; return; } if (typeof entity.visible === 'boolean' && !entity.visible) { entity.myObject3D.visible = false; return; } if (!entity.loaded && now - entity.discovered < 500) return; entity.loaded = true; // --- TÍNH VẬN TỐC CHO TẤT CẢ MỌI NGƯỜI (DÙ CÓ TÊN HAY KHÔNG) --- if (entity.myObject3D) { // Sử dụng entity.id thay cho entity.playerName để quét tất cả vật thể const entityKey = entity.id || entity.playerName || "unknown"; const currentPos = entity.myObject3D.position.clone(); if (window.lastPositions.has(entityKey)) { const lastPos = window.lastPositions.get(entityKey); const instantVel = new THREE.Vector3().subVectors(currentPos, lastPos); if (!entity.velocity) entity.velocity = new THREE.Vector3(0, 0, 0); // Giữ nguyên độ nhạy 0.4 entity.velocity.lerp(instantVel, 0.4); } window.lastPositions.set(entityKey, currentPos.clone()); } // Check if it's a player if (isPlayer(entity)) { if (!entity.logged) { const skinnedMesh = entity[childrenKey][1][childrenKey][3]; entity.isPlayer = true; entity.logged = true; entity.ennemy = isEnnemy(entity); const playerMesh = new THREE.Mesh(skinnedMesh.geometry, entity.ennemy ? meshMats.ennemy : meshMats.player); entity.myObject3D.add(playerMesh); entity.myObject3D.playerMesh = playerMesh; const playerMiniMap = new THREE.Mesh(skinnedMesh.geometry, entity.ennemy ? meshMats.ennemy : meshMats.player); playerMiniMap.visible = false; entity.myObject3D.add(playerMiniMap); entity.myObject3D.playerMiniMap = playerMiniMap; const outline = new THREE.LineSegments(edgesGeometry, entity.ennemy ? outlineMats.ennemy : outlineMats.player); outline.scale.set(0.5, 1.25, 0.5); outline.frustumCulled = false; entity.myObject3D.add(outline); entity.myObject3D.outline = outline; const boxMesh = new THREE.Mesh(boxPlayerGeometry, entity.ennemy ? meshMats.ennemy : meshMats.player); boxMesh.position.y = 0.625; entity.myObject3D.add(boxMesh); entity.myObject3D.boxMesh = boxMesh; const dir = new THREE.Vector3(0, 0, -1); const origin = new THREE.Vector3(0, 1, 0); const arrowLookingAt = new THREE.ArrowHelper(dir, origin, 1, entity.ennemy ? colors.ennemy : colors.player, 0.5, .4); playerMiniMap.add(arrowLookingAt); setTransform(entity.myObject3D, entity, false); scene.add(entity.myObject3D); }if (isPlayer(entity)) { // ... (các đoạn code cũ của bạn) ... if (entity.playerName) { const dist = entity.myObject3D.position.distanceTo(camera.position); // Mặc định: Đỏ cho địch (#ff4444), Xanh cho bạn (#44ff44) let playerColor = entity.ennemy ? "#ff4444" : "#44ff44"; // TÍNH NĂNG MỚI: Nếu tên chứa "soldier" (không phân biệt hoa thường), hiện màu đỏ rực if (entity.playerName.toLowerCase().includes("soldier#")) { playerColor = "#ff0000"; } // Cập nhật dữ liệu vào Radar // --- ĐOẠN MÃ MŨI TÊN AN TOÀN --- let playerArrow = "•"; try { // Lấy vị trí người chơi và camera const pPos = entity.myObject3D.position; const cPos = camera.position; // Tính hướng từ mình đến địch (chỉ tính mặt phẳng X-Z) const toP = new THREE.Vector3(pPos.x - cPos.x, 0, pPos.z - cPos.z).normalize(); const cDir = new THREE.Vector3(); camera.getWorldDirection(cDir); const forward = new THREE.Vector3(cDir.x, 0, cDir.z).normalize(); // Tính góc xoay const angle = Math.atan2(toP.z, toP.x) - Math.atan2(forward.z, forward.x); let deg = angle * (180 / Math.PI); if (deg < 0) deg += 360; // Xác định mũi tên theo độ if (deg > 337.5 || deg <= 22.5) playerArrow = "↑"; else if (deg > 22.5 && deg <= 67.5) playerArrow = "↗"; else if (deg > 67.5 && deg <= 112.5) playerArrow = "→"; else if (deg > 112.5 && deg <= 157.5) playerArrow = "↘"; else if (deg > 157.5 && deg <= 202.5) playerArrow = "↓"; else if (deg > 202.5 && deg <= 247.5) playerArrow = "↙"; else if (deg > 247.5 && deg <= 292.5) playerArrow = "←"; else if (deg > 292.5 && deg <= 337.5) playerArrow = "↖"; } catch(err) { /* Nếu lỗi thì hiện dấu chấm để không hỏng ESP */ playerArrow = "•"; } // Lưu vào bộ nhớ Radar window.playerMap.set(entity.playerName, { dist: Math.round(camera.position.distanceTo(entity.myObject3D.position)), color: playerColor, arrow: playerArrow }); // --- HẾT ĐOẠN MÃ MŨI TÊN --- } } entity.myObject3D.playerMesh.rotation.y = -entity[childrenKey][1].rotation._y; entity.myObject3D.playerMiniMap.rotation.y = -entity[childrenKey][1].rotation._y; const skinnedMesh = entity[childrenKey][1][childrenKey][3]; const isSneak = skinnedMesh.skeleton.bones[4].rotation._x > 0.1; entity.myObject3D.boxMesh.scale.set(1, isSneak ? .4 : 1, 1); entity.myObject3D.outline.scale.set(0.5, isSneak ? .9 : 1.25, 0.5); entity.myObject3D.playerMesh.scale.set(1, isSneak ? .7 : 1, 1); entity.myObject3D.visible = true; entity.myObject3D.playerMesh.visible = espConfig.showPlayer === 2 || (espConfig.showPlayer === 1 && !entity.ennemy); entity.myObject3D.boxMesh.visible = espConfig.showBox === 2 || (espConfig.showBox === 1 && entity.ennemy); entity.myObject3D.outline.visible = espConfig.showOutline === 2 || (espConfig.showOutline === 1 && entity.ennemy); setTransform(entity.myObject3D, entity, false); if (espConfig.showPlayerNames && entity.playerName) { // 1. Khởi tạo Sprite nếu chưa có (Phần này giữ nguyên như bạn nói) if (!entity.myObject3D.nameSprite) { const spriteColor = entity.ennemy ? "#ff0000" : "#00ff00"; const sprite = makeTextSprite(entity.playerName, spriteColor); entity.myObject3D.add(sprite); entity.myObject3D.nameSprite = sprite; } const nameSprite = entity.myObject3D.nameSprite; nameSprite.visible = true; nameSprite.position.y = isSneak ? 1.8 : 2.3; // --- BẮT ĐẦU PHẦN THÊM MỚI: LOGIC PHÓNG TO/THU NHỎ --- // Bước 1: Tính khoảng cách từ bạn đến đối thủ const distance = entity.myObject3D.position.distanceTo(camera.position); // Bước 2: Tính toán tỷ lệ (Multiplier) - ĐÃ ĐIỀU CHỈNH ĐỂ TO HƠN let scaleMultiplier = 1.0; if (espConfig.nameScaling) { // Giải thích các con số: // 10: Khoảng cách bắt đầu tính (mét) // 150: Khoảng cách tối đa để đạt độ phóng to lớn nhất (tăng từ 80 lên 150) // 0.5: Độ nhỏ khi ở gần // 6.0: Độ to cực đại khi ở xa (tăng từ 2.5 lên 6.0 - bạn có thể chỉnh số này to hơn nữa) const t = Math.max(0, Math.min(1, (distance - 10) / (150 - 10))); scaleMultiplier = 0.5 + (8.0 - 0.5) * t; // Thay 6.0 bằng 12.0 để to gấp đôi khi ở xa } // Bước 3: Áp dụng kích thước mới vào Sprite // Lưu ý: baseScale thường là 1.5 trong hàm makeTextSprite của bạn const finalScale = (nameSprite.baseScale || 1.5) * scaleMultiplier; nameSprite.scale.set(0.5 * nameSprite.initialRatio * finalScale, 0.5 * finalScale, 1); // --- KẾT THÚC PHẦN THÊM MỚI --- } // aimbot and line const pos = entity.myObject3D.position.clone(); pos.y -= isSneak ? espConfig.sneakHeight : 0; // line if (espConfig.showLine === 2 || (espConfig.showLine === 1 && entity.ennemy)) { if (espConfig.rainbow) { color.setHSL(time % 2000 / 2000, 1, 0.5); } else if (entity.ennemy) { color.lerpColors(colors.ennemy, colors.player, pos.distanceTo(camera.position) / espConfig.ennemyDistance); color.a = .8; } else { color.set(colors.blue); color.a = .3; } linePositions.push(lineOrigin.x, lineOrigin.y, lineOrigin.z); pos.y += 1.25; linePositions.push(pos.x, pos.y, pos.z); pos.y -= 1.25; colorArray.push(color.r, color.g, color.b, color.a); colorArray.push(color.r, color.g, color.b, color.a); } pos.y += espConfig.heightLine; // aimbot if (shouldAimbot && (entity.ennemy || espConfig.allEnnemies)) { if (entity.playerName && window.ignoredPlayers.has(entity.playerName)) return; const distance = pos.distanceTo(camera.position); // Nếu tên người này nằm trong danh sách né, thì bỏ qua không nhắm if (entity.playerName && window.ignoredPlayers.has(entity.playerName)) return; // Lấy vị trí hiện tại let target = pos.clone(); if (entity.velocity) { // Tăng số này nếu muốn đón đầu xa hơn (Trái/Phải) const leadFactor = 1.5; // 1. Lệch ngang (Trái/Phải/Tới/Lui) const horizontalLead = new THREE.Vector3(entity.velocity.x, 0, entity.velocity.z).multiplyScalar(leadFactor); target.add(horizontalLead); // 2. Ghì tâm khi nhảy (Lên/Xuống) if (entity.velocity.y > 0.01) { const pullDownStrength = 0.02; // THAY ĐỔI SỐ NÀY target.y -= pullDownStrength; } } const dummy = new THREE.PerspectiveCamera(); setTransform(dummy, worldCamera, false); dummy.lookAt(target); const cameraVector = new THREE.Vector3(0, 0, -1).applyQuaternion(camera.quaternion); const targetVector = new THREE.Vector3(0, 0, -1).applyQuaternion(dummy.quaternion); const angleDifference = cameraVector.angleTo(targetVector); const currentMaxAngle = espConfig.unlimitedAngle ? Math.PI : espConfig.maxAngleInRadians; if (angleDifference < currentMaxAngle && angleDifference < aimbotTarget.angleDifference) { const directionV3 = new THREE.Vector3(); directionV3.subVectors(target, camera.position).normalize(); raycaster.set(camera.position, directionV3); let behindBlock = false; if (espConfig.aimbotIgnoreWall) { aimbotTarget.angleDifference = angleDifference; aimbotTarget.target = target; } else { for (const chunk of chunks) { if (raycaster.ray.intersectsBox(chunk.box)) { const hit = raycaster.intersectObject(chunk)[0]; if (hit && hit.distance < distance) { behindBlock = true; break; } } } if (!behindBlock) { aimbotTarget.angleDifference = angleDifference; aimbotTarget.target = target; color.setHSL(time % 2000 / 2000, 1, 0.5); } } } } } // NEW: Handle items (non-player entities) else if (isItem(entity) && espConfig.showItems) { if (!entity.itemBox) { entity.itemBox = new THREE.Mesh(itemBoxGeometry, meshMats.item); entity.itemBox.frustumCulled = false; scene.add(entity.itemBox); // Create item name sprite if showItemNames is enabled if (espConfig.showItemNames) { // Try to get item name from canvas text let itemName = "Item"; for (const child of entity[childrenKey]) { try { const matImage = child.material?.map?.image; if (matImage instanceof HTMLCanvasElement && matImage.hasOwnProperty('lastText')) { itemName = matImage.lastText || "Item"; break; } } catch {} } entity.itemName = itemName; const itemSprite = createItemSprite(itemName, "#D4AF37"); itemSprite.position.y = 0.5; entity.itemBox.add(itemSprite); entity.itemNameSprite = itemSprite; } } setTransform(entity.itemBox, entity, false); entity.itemBox.visible = true; // Update item name sprite visibility if (entity.itemNameSprite) { entity.itemNameSprite.visible = espConfig.showItemNames; } } // Hide item if showItems is false else if (entity.itemBox) { entity.itemBox.visible = false; if (entity.itemNameSprite) { entity.itemNameSprite.visible = false; } } }); // aim at target if (espConfig.aimbot && shouldAimbot && aimbotTarget.target) { setTransform(dummyLookAt, worldCamera, false); dummyLookAt.lookAt(aimbotTarget.target); worldCamera.rotation.set( dummyLookAt.rotation.x, dummyLookAt.rotation.y, dummyLookAt.rotation.z ); } // triggerbot const shouldTrigger = espConfig.triggerBot === 3 || (espConfig.triggerBot === 1 && isLeftClick) || (espConfig.triggerBot === 2 && isRightClick); if (shouldTrigger) { raycaster.set(camera.position, camera.getWorldDirection(new THREE.Vector3())); let hasHit = false; for (const entity of entities) { if (!entity.myObject3D?.visible) continue; if (entity.isPlayer && (entity.ennemy || espConfig.allEnnemies)) { const hit = raycaster.intersectObject(entity.myObject3D.playerMesh); if (hit.length) { hasHit = true; const distance = hit[0].distance; for (const chunk of chunks) { if (raycaster.ray.intersectsBox(chunk.box)) { const hitBlock = raycaster.intersectObject(chunk)[0]; if (hitBlock && hitBlock.distance < distance) { hasHit = false; break; } } } if (hasHit) { break; } } } } setFiring(hasHit); } else { setFiring(false); } line.geometry.setAttribute('color', new THREE.Float32BufferAttribute(colorArray, 4)); line.geometry.setAttribute('position', new THREE.Float32BufferAttribute(linePositions, 3)); line.visible = espConfig.showLine; renderer.render(scene, camera); // minimap // make entities larger for minimap const scale = espConfig.mapZoom / 3; entities.forEach(entity => { if (entity.isPlayer) { entity.myObject3D.playerMesh.visible = false; entity.myObject3D.boxMesh.visible = false; entity.myObject3D.outline.visible = false; if (entity.myObject3D.nameSprite) entity.myObject3D.nameSprite.visible = false; // Ẩn tên trên minimap entity.myObject3D.playerMiniMap.visible = true; entity.myObject3D.playerMiniMap.scale.set(scale, 1, scale); } // Hide items on minimap if (entity.itemBox) { entity.itemBox.visible = false; } }); if (worldCamera) { line.visible = false; crosshair.visible = false; // update orthographic camera based on espConfig.mapZoom minimapCamera.left = -espConfig.mapZoom; minimapCamera.right = espConfig.mapZoom; minimapCamera.top = espConfig.mapZoom; minimapCamera.bottom = -espConfig.mapZoom; // update position with camera position minimapCamera.position.copy(camera.position); minimapCamera.position.y += 50; minimapCamera.position.z += espConfig.mapOffsetZ; minimapCamera.rotation.y = camera.rotation.y; minimapCamera.updateProjectionMatrix(); renderer.getViewport(saveViewport); renderer.getScissor(saveScissor); let saveScissorTest = renderer.getScissorTest(); renderer.setViewport(minimapViewport); renderer.setScissor(minimapViewport); renderer.setScissorTest(true); renderer.render(scene, minimapCamera); renderer.setViewport(saveViewport); renderer.setScissor(saveScissor); renderer.setScissorTest(saveScissorTest); } entities.forEach(entity => { if (entity.isPlayer) { entity.myObject3D.playerMiniMap.visible = false; } }); scene.children.forEach(child => { if (child.type === 'Object3D') { child.visible = false; } }); } window.addEventListener('resize', () => { renderer.setSize( window.innerWidth, window.innerHeight ); }); // add style to header style.innerHTML = ` #overlayCanvas { position: absolute; top: 0; left: 0; width: 100%; height: 100%; pointer-events: none; z-index: 1000; } #lil-gui { position: absolute; top: 50%; right: 0; z-index: 1001; transform: translateY(-50%); } .lil-gui { --background-color: rgba(0, 0, 0, 0.5); } `; guiStyle.innerHTML = ` .lil-gui { --title-background-color: #ff0019; --number-color: #00ff33; } `; document.head.appendChild(style); document.head.appendChild(guiStyle); setInterval(() => { if (espConfig.antiAFK) { // Gửi sự kiện đè phím (keydown) cho cả 4 hướng cùng lúc // Không gửi sự kiện nhả phím (keyup) để mô phỏng việc giữ chặt document.dispatchEvent(new KeyboardEvent('keydown', { keyCode: 87 })); // W document.dispatchEvent(new KeyboardEvent('keydown', { keyCode: 67 })); // A document.dispatchEvent(new KeyboardEvent('keydown', { keyCode: 70 })); // S } }, 20); // Lặp lại mỗi 20ms (cực nhanh, không có độ trễ) // wait for load window.addEventListener('load', () => { console.log('Loaded'); if (espConfig.autoClaimAds) { setTimeout(() => { claimAds(); }, 500); } }); // Logic điều khiển Sit Mode setInterval(() => { if (espConfig.sit) { // Nhấn phím C (keyCode 67) document.dispatchEvent(new KeyboardEvent('keydown', { keyCode: 67 })); // Nhả phím C sau 1ms để tạo vòng lặp nhấp nhả cực nhanh setTimeout(() => { document.dispatchEvent(new KeyboardEvent('keyup', { keyCode: 67 })); }, 5); } }, 0); // Lặp lại toàn bộ quá trình sau 2ms setInterval(() => { const radarContainer = document.getElementById('side-player-list'); if (!radarContainer) return; // Cập nhật số lượng người chơi vào tiêu đề const countElement = document.getElementById('radar-count'); if (countElement && window.playerMap) { countElement.innerText = window.playerMap.size; } // KIỂM TRA LỆNH TỪ MENU/PHÍM TẮT if (!espConfig.showRadar) { radarContainer.style.display = 'none'; // Tắt bảng return; } else { radarContainer.style.display = 'block'; // Mở bảng } const content = document.getElementById('list-content'); if (!content) return; if (!window.playerMap || window.playerMap.size === 0) { content.innerHTML = '<div style="color:#ffcc00; font-size:12px; font-weight:bold; text-align:center;">🔍 ĐANG QUÉT...</div>'; } else { const sortedPlayers = Array.from(window.playerMap.entries()) .map(([name, data]) => ({ name, ...data })) .sort((a, b) => a.dist - b.dist); let html = ''; sortedPlayers.forEach((p, index) => { const isSoldier = p.color === "#ff0000"; const shadow = isSoldier ? "1px 1px 0px #000, -1px -1px 0px #000, 1px -1px 0px #000, -1px 1px 0px #000, 0px 0px 3px #ffffff" : "1px 1px 1px #000"; const isIgnored = window.ignoredPlayers && window.ignoredPlayers.has(p.name); const btnColor = isIgnored ? "#00ff00" : "#555"; const btnText = isIgnored ? "✔" : "+"; // Đổi thành window.selectedPlayerIndex để phím tắt điều khiển được const isSelected = (index === window.selectedPlayerIndex); html += ` <div class="player-row ${isSelected ? 'selected' : ''}" style="color:${p.color}; text-shadow: ${shadow};"> <span style="width:25px; text-align:center; font-size:18px; margin-right:5px; flex-shrink:0;">${p.arrow || "•"}</span> <button onmousedown="window.handlePlayerAction('${p.name}')" style="pointer-events: auto; margin-right: 10px; background: ${btnColor}; color: white; border: 1px solid rgba(255,255,255,0.3); border-radius: 4px; width: 26px; height: 26px; cursor: pointer; font-size: 16px; font-weight: bold; flex-shrink: 0; display: flex; align-items: center; justify-content: center;">${btnText}</button> <span style="flex-grow:1; overflow:hidden; text-overflow:ellipsis; font-weight:900;">${p.name}</span> <span class="dist-text" style="margin-left:auto; color:#00ffff; font-weight:bold; font-size:12px;">${p.dist}m</span> </div> `; }); content.innerHTML = html; } if (window.playerMap) window.playerMap.clear(); }, 250); // --- Tính năng Phím tắt Điều khiển --- let selectedPlayerIndex = 0; window.addEventListener('keydown', (e) => { // Lấy danh sách người chơi hiện tại từ giao diện (các button handlePlayerAction) const playerRows = document.querySelectorAll('#side-player-list div[style*="margin-bottom:6px"]'); if (playerRows.length === 0) return; // Phím '[' : Di chuyển lên if (e.key === '[') { selectedPlayerIndex = (selectedPlayerIndex <= 0) ? playerRows.length - 1 : selectedPlayerIndex - 1; updateSelectionHighlight(playerRows); } // Phím ']' : Di chuyển xuống if (e.key === ']') { selectedPlayerIndex = (selectedPlayerIndex >= playerRows.length - 1) ? 0 : selectedPlayerIndex + 1; updateSelectionHighlight(playerRows); } // Phím '/' : Kích hoạt né/hủy né cho người chơi đang chọn if (e.key === '/') { const selectedRow = playerRows[selectedPlayerIndex]; if (selectedRow) { const btn = selectedRow.querySelector('button'); if (btn) btn.onmousedown(); // Kích hoạt sự kiện nhấn nút } } }); // Khởi tạo biến toàn cục window.selectedPlayerIndex = -1; let hideTimer = null; // Thêm CSS cho class "selected" và hiệu ứng nháy khi nhấn "/" if (!document.getElementById('selection-style')) { const s = document.createElement('style'); s.id = 'selection-style'; s.innerHTML = ` .player-row { border: 1.5px solid transparent; transition: all 0.1s; padding: 2px 5px; border-radius: 5px; } .player-row.selected { background: rgba(0, 255, 0, 0.2) !important; border-color: #00ff00 !important; box-shadow: 0 0 10px #00ff00; } .player-row.clicked { background: rgba(255, 255, 0, 0.5) !important; border-color: yellow !important; } `; document.head.appendChild(s); } window.onkeydown = function(e) { if (document.activeElement.tagName === 'INPUT' || document.activeElement.tagName === 'TEXTAREA') return; const rows = document.querySelectorAll('.player-row'); if (rows.length === 0) return; if (e.key === '[') { // Lên window.selectedPlayerIndex = (window.selectedPlayerIndex <= 0) ? rows.length - 1 : window.selectedPlayerIndex - 1; e.preventDefault(); } else if (e.key === ']') { // Xuống window.selectedPlayerIndex = (window.selectedPlayerIndex >= rows.length - 1) ? 0 : window.selectedPlayerIndex + 1; e.preventDefault(); } else if (e.key === '/') { // Chọn if (window.selectedPlayerIndex >= 0 && rows[window.selectedPlayerIndex]) { const row = rows[window.selectedPlayerIndex]; const btn = row.querySelector('button'); if (btn) btn.onmousedown(); // Hiệu ứng nháy vàng khi nhấn / (để không bị chọn ngầm) row.classList.add('clicked'); setTimeout(() => row.classList.remove('clicked'), 200); } e.preventDefault(); } else { return; } // Tự động ẩn viền sau 1 giây clearTimeout(hideTimer); hideTimer = setTimeout(() => { window.selectedPlayerIndex = -1; }, 3000); };// 1. Xử lý thả phím Z để ngừng Zoom window.addEventListener('keyup', (e) => { const keyL = e.key.toLowerCase(); // Kiểm tra: Nếu nhả phím zoom mặc định (Z) // HOẶC nhả phím F (khi tính năng Zoom phím F đang được bật trong menu) if (keyL === espConfig.zoomKey.toLowerCase() || (keyL === 'f' && espConfig.fZoomEnabled)) { espConfig.isZooming = false; // Cập nhật lại giao diện Menu (để nút "Đang Zoom" tự tắt đi) if (typeof gui !== 'undefined') { gui.controllersRecursive().forEach(c => c.updateDisplay()); } } }); // 2. KHẮC PHỤC LỖI: Chặn đổi vũ khí khi đang cuộn chuột để Zoom window.addEventListener('wheel', (e) => { if (espConfig.isZooming) { // e.preventDefault() ở đây giúp chặn sự kiện mặc định (đổi vũ khí) của game e.preventDefault(); if (e.deltaY < 0) { // Cuộn lên: Giảm FOV = Phóng to hơn espConfig.zoomLevel = Math.max(1, espConfig.zoomLevel - 3); } else { // Cuộn xuống: Tăng FOV = Nhìn rộng hơn espConfig.zoomLevel = Math.min(175, espConfig.zoomLevel + 3); } // Cập nhật con số trên Menu khi đang lăn chuột if (typeof gui !== 'undefined') { gui.controllersRecursive().forEach(c => { if (c.property === 'zoomLevel') c.updateDisplay(); }); } } }, { passive: false }); // Cần passive: false để preventDefault hoạt động // 3. Ghi đè FOV của Camera game Object.defineProperty(Object.prototype, 'fov', { get: function() { // Nếu là Camera và người dùng đang giữ phím Z if (this.isPerspectiveCamera && espConfig.isZooming) { return espConfig.zoomLevel; } return this._fov; }, set: function(v) { this._fov = v; }, configurable: true });