Josiahiscool73

Mobile support added and simplified

Aug 22nd, 2025
52
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 17.94 KB | None | 0 0
  1. (function() {
  2. // --- DEPENDENCY LOADER ---
  3. function loadScript(url) {
  4. return new Promise((resolve, reject) => {
  5. const script = document.createElement('script');
  6. script.src = url;
  7. script.onload = resolve;
  8. script.onerror = () => reject(new Error(`Failed to load script: ${url}`));
  9. document.head.appendChild(script);
  10. });
  11. }
  12.  
  13. loadScript('https://cdn.jsdelivr.net/npm/@tensorflow/[email protected]/dist/tf.min.js')
  14. .then(() => loadScript('https://cdn.jsdelivr.net/npm/@tensorflow/[email protected]/dist/tf-backend-webgpu.min.js'))
  15. .then(() => loadScript('https://cdn.jsdelivr.net/npm/@tensorflow-models/[email protected]/dist/pose-detection.min.js'))
  16. .then(() => runAimbot())
  17. .catch(error => {
  18. console.error("Aimbot initialization failed: A required dependency could not be loaded.", error);
  19. alert("Aimbot could not start. Check the developer console for errors.");
  20. });
  21.  
  22.  
  23. // --- MAIN AIMBOT LOGIC ---
  24. function runAimbot() {
  25. const config = {
  26. confidence: 0.25,
  27. enableEsp: true,
  28. fovRadius: 136,
  29. keyboard: {
  30. enabled: true,
  31. // Binds: 'MouseRight', 'q', 'e', 'Shift', etc. (Not case-sensitive)
  32. aimKey: 'MouseRight'
  33. },
  34. controller: {
  35. enabled: true,
  36. aimButton: 'LT' // Binds: 'LT', 'RT', 'LB', 'RB', 'A', 'B', 'X', 'Y'
  37. },
  38. mobile: {
  39. enabled: true
  40. },
  41. fov: {
  42. showCircle: true,
  43. },
  44. mask: {
  45. enabled: true,
  46. showMask: true, // Shows a transparent overlay of the masked area
  47. // Hard-coded optimal values
  48. x: 0.0, y: 0.27, width: 0.43, height: 0.74
  49. }
  50. };
  51.  
  52. // --- State Variables ---
  53. let gameVideo = null, detectionModel = null, overlayCanvas = null, overlayCtx = null;
  54. let mobileToggleButton = null, mobileSettingsButton = null, settingsGui = null;
  55. let isAiming = false, offscreenCanvas = null, offscreenCtx = null;
  56. let lastMouseX = window.innerWidth / 2, lastMouseY = window.innerHeight / 2;
  57. let gamepadIndex = null, lastAimButtonState = false;
  58. const buttonMap = { 'A': 0, 'B': 1, 'X': 2, 'Y': 3, 'LB': 4, 'RB': 5, 'LT': 6, 'RT': 7 };
  59.  
  60. async function setupAndLoadModel() { try { await tf.setBackend('webgpu'); await tf.ready(); } catch (e) { console.error("Fatal: Could not initialize WebGPU backend.", e); return false; } try { detectionModel = await poseDetection.createDetector( poseDetection.SupportedModels.MoveNet, { modelType: poseDetection.movenet.modelType.SINGLEPOSE_LIGHTNING, enableSmoothing: true, minPoseScore: config.confidence }); const warmUpTensor = tf.zeros([192, 192, 3], 'int32'); await detectionModel.estimatePoses(warmUpTensor); tf.dispose(warmUpTensor); return true; } catch (e) { console.error("Failed to load AI model:", e); return false; } }
  61. function createOverlayCanvas() { if (overlayCanvas) return; overlayCanvas = document.createElement('canvas'); overlayCanvas.style.cssText = 'position:fixed;top:0;left:0;width:100vw;height:100vh;pointer-events:none;z-index:99998;'; document.body.appendChild(overlayCanvas); overlayCtx = overlayCanvas.getContext('2d'); const resizeObserver = new ResizeObserver(() => { overlayCanvas.width = window.innerWidth; overlayCanvas.height = window.innerHeight; }); resizeObserver.observe(document.body); overlayCanvas.width = window.innerWidth; overlayCanvas.height = window.innerHeight; }
  62. function setIsAiming(newState) { isAiming = newState; if (config.mobile.enabled && mobileToggleButton) { mobileToggleButton.style.backgroundColor = isAiming ? 'rgba(255, 0, 0, 0.6)' : 'rgba(128, 128, 128, 0.5)'; } }
  63. function pollGamepad() { if (!config.controller.enabled || gamepadIndex === null) return; const gamepad = navigator.getGamepads()[gamepadIndex]; if (!gamepad) return; const aimButtonIndex = buttonMap[config.controller.aimButton] ?? 6; const isPressed = gamepad.buttons[aimButtonIndex]?.pressed; if (isPressed && !lastAimButtonState) { setIsAiming(!isAiming); } lastAimButtonState = isPressed; }
  64. function calculateBoundingBox(keypoints) { let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity, validKeypoints = 0; keypoints.forEach(kp => { if (kp.score && kp.score >= config.confidence) { minX = Math.min(minX, kp.x); minY = Math.min(minY, kp.y); maxX = Math.max(maxX, kp.x); maxY = Math.max(maxY, kp.y); validKeypoints++; } }); if (validKeypoints < 5) return null; return { x: minX, y: minY, width: maxX - minX, height: maxY - minY }; }
  65. function findBestTarget(poses) { if (!poses || !gameVideo) return null; const videoRect = gameVideo.getBoundingClientRect(); if (videoRect.width === 0) return null; const centerX = videoRect.left + videoRect.width / 2, centerY = videoRect.top + videoRect.height / 2; let bestTarget = null, minDistance = Infinity; poses.forEach(pose => { if (!pose.bbox) return; const { x: vX, y: vY, width: vW, height: vH } = pose.bbox; const sX = videoRect.left + (vX / gameVideo.videoWidth) * videoRect.width, sY = videoRect.top + (vY / gameVideo.videoHeight) * videoRect.height; const sW = (vW / gameVideo.videoWidth) * videoRect.width, sH = (vH / gameVideo.videoHeight) * videoRect.height; const tX = sX + sW / 2, tY = sY + sH / 2; const distance = Math.hypot(tX - centerX, tY - centerY); if (distance < config.fovRadius && distance < minDistance) { minDistance = distance; bestTarget = { x: tX, y: tY, box: { x: sX, y: sY, width: sW, height: sH } }; } }); return bestTarget; }
  66. function moveMouseTo(targetX, targetY) { const videoRect = gameVideo.getBoundingClientRect(); if (!videoRect || videoRect.width === 0) return; const gameCenterX = videoRect.left + videoRect.width / 2, gameCenterY = videoRect.top + videoRect.height / 2; const movementX = targetX - gameCenterX, movementY = targetY - gameCenterY; const gameContainer = document.querySelector('#game-stream') || gameVideo; gameContainer.dispatchEvent(new PointerEvent('pointermove', { bubbles: true, cancelable: true, view: window, clientX: Math.round(lastMouseX + movementX), clientY: Math.round(lastMouseY + movementY), movementX: Math.round(movementX), movementY: Math.round(movementY), pointerType: 'mouse', isPrimary: true })); lastMouseX += movementX; lastMouseY += movementY; }
  67.  
  68. // --- MOBILE GUI & BUTTONS ---
  69. function makeDraggable(element) {
  70. let pos1 = 0, pos2 = 0, pos3 = 0, pos4 = 0;
  71. const dragMouseDown = (e) => {
  72. e = e || window.event; e.preventDefault();
  73. pos3 = e.clientX || e.touches[0].clientX; pos4 = e.clientY || e.touches[0].clientY;
  74. document.onmouseup = closeDragElement; document.onmousemove = elementDrag;
  75. document.ontouchend = closeDragElement; document.ontouchmove = elementDrag;
  76. };
  77. element.onmousedown = dragMouseDown; element.ontouchstart = dragMouseDown;
  78.  
  79. const elementDrag = (e) => {
  80. e = e || window.event; e.preventDefault();
  81. const clientX = e.clientX || e.touches[0].clientX; const clientY = e.clientY || e.touches[0].clientY;
  82. pos1 = pos3 - clientX; pos2 = pos4 - clientY;
  83. pos3 = clientX; pos4 = clientY;
  84. element.style.top = (element.offsetTop - pos2) + "px"; element.style.left = (element.offsetLeft - pos1) + "px";
  85. };
  86.  
  87. const closeDragElement = () => { document.onmouseup = null; document.onmousemove = null; document.ontouchend = null; document.ontouchmove = null; };
  88. }
  89.  
  90. function createMobileControls() {
  91. const gameContainer = document.querySelector('#game-stream') || document.body;
  92.  
  93. // --- AIM TOGGLE BUTTON ---
  94. mobileToggleButton = document.createElement('div');
  95. const robotIcon = `url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3e%3crect x='15' y='20' width='70' height='60' rx='10' ry='10' fill='none' stroke='rgba(255,255,255,0.8)' stroke-width='6'/%3e%3ccircle cx='35' cy='45' r='6' fill='rgba(255,255,255,0.8)'/%3e%3ccircle cx='65' cy='45' r='6' fill='rgba(255,255,255,0.8)'/%3e%3cline x1='30' y1='65' x2='70' y2='65' stroke='rgba(255,255,255,0.8)' stroke-width='6' stroke-linecap='round'/%3e%3c/svg%3e")`;
  96. mobileToggleButton.style.cssText = `position: absolute; top: 20px; right: 20px; width: 60px; height: 60px; background-color: rgba(128, 128, 128, 0.5); border-radius: 50%; z-index: 100000; pointer-events: auto; cursor: pointer; background-image: ${robotIcon}; background-size: 60%; background-position: center; background-repeat: no-repeat;`;
  97. gameContainer.appendChild(mobileToggleButton);
  98. const toggleAction = (e) => { e.preventDefault(); e.stopPropagation(); setIsAiming(!isAiming); };
  99. mobileToggleButton.addEventListener('touchstart', toggleAction); mobileToggleButton.addEventListener('click', toggleAction);
  100.  
  101. // --- SETTINGS BUTTON ---
  102. if (localStorage.getItem('hideMobileSettings') === 'true') return;
  103. mobileSettingsButton = document.createElement('div');
  104. const gearIcon = `url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='rgba(255,255,255,0.8)'%3e%3cpath d='M19.14,12.94c0.04-0.3,0.06-0.61,0.06-0.94c0-0.32-0.02-0.64-0.07-0.94l2.03-1.58c0.18-0.14,0.23-0.41,0.12-0.61 l-1.92-3.32c-0.12-0.22-0.37-0.29-0.59-0.22l-2.39,0.96c-0.5-0.38-1.03-0.7-1.62-0.94L14.4,2.81c-0.04-0.24-0.24-0.41-0.48-0.41h-3.84c-0.24,0-0.44,0.17-0.48,0.41L9.22,5.25C8.63,5.49,8.1,5.81,7.6,6.19L5.21,5.23C4.99,5.16,4.74,5.22,4.62,5.44L2.7,8.76c-0.12,0.2,0,0.47,0.18,0.61l2.03,1.58C4.88,11.36,4.86,11.68,4.86,12s0.02,0.64,0.07,0.94l-2.03,1.58c-0.18,0.14-0.23,0.41-0.12,0.61l1.92,3.32c0.12,0.22,0.37,0.29,0.59,0.22l2.39-0.96c0.5,0.38,1.03,0.7,1.62,0.94l0.38,2.44c0.04,0.24,0.24,0.41,0.48,0.41h3.84c0.24,0,0.44-0.17,0.48-0.41l0.38-2.44c0.59-0.24,1.12-0.56,1.62-0.94l2.39,0.96c0.22,0.08,0.47,0,0.59-0.22l1.92-3.32c0.12-0.2-0.01-0.47-0.18-0.61L19.14,12.94z M12,15.6c-1.98,0-3.6-1.62-3.6-3.6s1.62-3.6,3.6-3.6s3.6,1.62,3.6,3.6S13.98,15.6,12,15.6z'/%3e%3c/svg%3e")`;
  105. mobileSettingsButton.style.cssText = `position: absolute; top: 90px; right: 20px; width: 45px; height: 45px; background-color: rgba(128, 128, 128, 0.5); border-radius: 50%; z-index: 100000; pointer-events: auto; cursor: pointer; background-image: ${gearIcon}; background-size: 60%; background-position: center; background-repeat: no-repeat;`;
  106. gameContainer.appendChild(mobileSettingsButton);
  107. mobileSettingsButton.addEventListener('click', (e) => { e.preventDefault(); e.stopPropagation(); settingsGui.style.display = 'block'; });
  108.  
  109. // --- SETTINGS GUI ---
  110. settingsGui = document.createElement('div');
  111. settingsGui.style.cssText = 'position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); background: rgba(0,0,0,0.8); padding: 20px; border-radius: 10px; color: white; z-index: 100001; font-family: sans-serif; display: none; text-align: center;';
  112. settingsGui.innerHTML = `
  113. <h3 style="margin: 0 0 15px 0;">Settings</h3>
  114. <div style="margin-bottom: 15px;">
  115. <input type="checkbox" id="drag-toggle">
  116. <label for="drag-toggle">Enable Button Dragging</label>
  117. </div>
  118. <button id="hide-settings-btn" style="padding: 8px 12px; border: none; border-radius: 5px; background: #555; color: white; cursor: pointer; margin-right: 10px;">Permanently Hide Settings</button>
  119. <button id="close-settings-btn" style="padding: 8px 12px; border: none; border-radius: 5px; background: #800; color: white; cursor: pointer;">Close</button>
  120. `;
  121. document.body.appendChild(settingsGui);
  122.  
  123. const dragToggle = settingsGui.querySelector('#drag-toggle');
  124. dragToggle.addEventListener('change', () => {
  125. if (dragToggle.checked) { makeDraggable(mobileToggleButton); makeDraggable(mobileSettingsButton); }
  126. else { mobileToggleButton.onmousedown = null; mobileToggleButton.ontouchstart = null; mobileSettingsButton.onmousedown = null; mobileSettingsButton.ontouchstart = null; }
  127. });
  128.  
  129. settingsGui.querySelector('#hide-settings-btn').addEventListener('click', () => {
  130. if (confirm('Are you sure you want to permanently hide the settings button?')) {
  131. localStorage.setItem('hideMobileSettings', 'true');
  132. mobileSettingsButton.style.display = 'none';
  133. settingsGui.style.display = 'none';
  134. }
  135. });
  136. settingsGui.querySelector('#close-settings-btn').addEventListener('click', () => { settingsGui.style.display = 'none'; });
  137. }
  138.  
  139. async function getPoses() { if (!isAiming || !detectionModel || !gameVideo || gameVideo.paused || gameVideo.ended || gameVideo.videoWidth === 0) return []; let videoSource = gameVideo; if (config.mask.enabled) { if (!offscreenCanvas) { offscreenCanvas = document.createElement('canvas'); offscreenCtx = offscreenCanvas.getContext('2d'); } if (offscreenCanvas.width !== gameVideo.videoWidth || offscreenCanvas.height !== gameVideo.videoHeight) { offscreenCanvas.width = gameVideo.videoWidth; offscreenCanvas.height = gameVideo.videoHeight; } offscreenCtx.drawImage(gameVideo, 0, 0); offscreenCtx.fillStyle = 'black'; offscreenCtx.fillRect(gameVideo.videoWidth * config.mask.x, gameVideo.videoHeight * config.mask.y, gameVideo.videoWidth * config.mask.width, gameVideo.videoHeight * config.mask.height); videoSource = offscreenCanvas; } try { const poses = await detectionModel.estimatePoses(videoSource, { flipHorizontal: false }); return poses.filter(p => p.score && p.score >= config.confidence).map(p => ({ ...p, bbox: calculateBoundingBox(p.keypoints) })).filter(p => p.bbox); } catch (err) { return []; } }
  140.  
  141. function drawVisuals(target) {
  142. overlayCtx.clearRect(0, 0, overlayCanvas.width, overlayCanvas.height); const videoRect = gameVideo.getBoundingClientRect(); if (!videoRect || videoRect.width === 0) return;
  143. const settingsGuiVisible = settingsGui && settingsGui.style.display === 'block';
  144. if (!isAiming && !settingsGuiVisible) return;
  145.  
  146. if (config.fov.showCircle) { const centerX = videoRect.left + videoRect.width / 2, centerY = videoRect.top + videoRect.height / 2; overlayCtx.strokeStyle = 'rgba(255, 255, 255, 0.4)'; overlayCtx.lineWidth = 2; overlayCtx.beginPath(); overlayCtx.arc(centerX, centerY, config.fovRadius, 0, 2 * Math.PI); overlayCtx.stroke(); }
  147. if (config.mask.enabled && config.mask.showMask) { overlayCtx.fillStyle = 'rgba(255, 255, 255, 0.15)'; overlayCtx.fillRect(videoRect.left + videoRect.width * config.mask.x, videoRect.top + videoRect.height * config.mask.y, videoRect.width * config.mask.width, videoRect.height * config.mask.height); }
  148. if (config.enableEsp && isAiming && target) { const { x, y, width, height } = target.box; overlayCtx.strokeStyle = '#FF0000'; overlayCtx.lineWidth = 2; overlayCtx.strokeRect(x, y, width, height); overlayCtx.fillStyle = '#FF0000'; overlayCtx.font = '16px Arial'; overlayCtx.textAlign = 'center'; overlayCtx.textBaseline = 'bottom'; overlayCtx.fillText('target', x + width / 2, y - 5); }
  149. }
  150.  
  151. async function mainLoop() { pollGamepad(); let currentTarget = null; if (isAiming) { const poses = await getPoses(); currentTarget = findBestTarget(poses); if (currentTarget) { moveMouseTo(currentTarget.x, currentTarget.y); } } drawVisuals(currentTarget); requestAnimationFrame(mainLoop); }
  152.  
  153. function initialize() {
  154. gameVideo = document.querySelector('#game-stream video'); if (!gameVideo) { console.error("Game video element not found. Retrying in 3 seconds..."); setTimeout(initialize, 3000); return; }
  155. console.log(`Aimbot locked onto game stream: "${gameVideo.getAttribute('aria-label') || 'Name not available'}"`);
  156. createOverlayCanvas();
  157. if (config.mobile.enabled) createMobileControls();
  158.  
  159. document.addEventListener('mousemove', e => { lastMouseX = e.clientX; lastMouseY = e.clientY; });
  160.  
  161. if (config.keyboard.enabled) {
  162. const aimKey = config.keyboard.aimKey.toLowerCase();
  163. if (aimKey === 'mouseright') { document.addEventListener('mousedown', e => { if (e.button === 2) setIsAiming(true); }); document.addEventListener('mouseup', e => { if (e.button === 2) setIsAiming(false); }); }
  164. else { document.addEventListener('keydown', e => { if (e.key.toLowerCase() === aimKey) setIsAiming(true); }); document.addEventListener('keyup', e => { if (e.key.toLowerCase() === aimKey) setIsAiming(false); }); }
  165. }
  166.  
  167. if (config.controller.enabled) { window.addEventListener('gamepadconnected', (e) => { gamepadIndex = e.gamepad.index; console.log(`Gamepad connected: ${e.gamepad.id}`); }); window.addEventListener('gamepaddisconnected', () => { gamepadIndex = null; console.log("Gamepad disconnected."); }); }
  168.  
  169. setupAndLoadModel().then(success => {
  170. if (success) {
  171. mainLoop(); let methods = [];
  172. if (config.keyboard.enabled) methods.push(`Hold ${config.keyboard.aimKey}`);
  173. if (config.controller.enabled) methods.push("press controller aim button");
  174. if (config.mobile.enabled) methods.push("tap the on-screen button");
  175. console.log(`Aimbot is active. ${methods.join(' or ')} to activate.`);
  176. } else { console.error("Aimbot could not start due to model initialization failures."); }
  177. });
  178. }
  179.  
  180. initialize();
  181. }
  182. })();
  183.  
Advertisement
Add Comment
Please, Sign In to add comment