Krunker.IO Aimbot & ESP

Locks aim to the nearest player in krunker.io and shows players behind walls. Also shows a line between you and them.

  1. // ==UserScript==
  2. // @name Krunker.IO Aimbot & ESP
  3. // @namespace http://tampermonkey.net/
  4. // @version 0.3.0
  5. // @description Locks aim to the nearest player in krunker.io and shows players behind walls. Also shows a line between you and them.
  6. // @author Zertalious (Zert)
  7. // @match *://krunker.io/*
  8. // @match *://browserfps.com/*
  9. // @exclude *://krunker.io/social*
  10. // @exclude *://krunker.io/editor*
  11. // @icon https://www.google.com/s2/favicons?domain=krunker.io
  12. // @grant none
  13. // @run-at document-start
  14. // @require https://unpkg.com/three@0.150.0/build/three.min.js
  15. // @antifeature ads
  16. // ==/UserScript==
  17.  
  18. const THREE = window.THREE;
  19. delete window.THREE;
  20.  
  21. const settings = {
  22. aimbotEnabled: true,
  23. aimbotOnRightMouse: false,
  24. espEnabled: true,
  25. espLines: true,
  26. wireframe: false
  27. };
  28.  
  29. const keyToSetting = {
  30. KeyB: 'aimbotEnabled',
  31. KeyL: 'aimbotOnRightMouse',
  32. KeyM: 'espEnabled',
  33. KeyN: 'espLines',
  34. KeyK: 'wireframe'
  35. };
  36.  
  37. const gui = createGUI();
  38.  
  39. let scene;
  40.  
  41. const x = {
  42. window: window,
  43. document: document,
  44. querySelector: document.querySelector,
  45. consoleLog: console.log,
  46. ReflectApply: Reflect.apply,
  47. ArrayPrototype: Array.prototype,
  48. ArrayPush: Array.prototype.push,
  49. ObjectPrototype: Object.prototype,
  50. clearInterval: window.clearInterval,
  51. setTimeout: window.setTimeout,
  52. reToString: RegExp.prototype.toString,
  53. indexOf: String.prototype.indexOf,
  54. requestAnimationFrame: window.requestAnimationFrame
  55. };
  56.  
  57. x.consoleLog( 'Waiting to inject...' );
  58.  
  59. const proxied = function ( object ) {
  60.  
  61. // [native code]
  62.  
  63. try {
  64.  
  65. if ( typeof object === 'object' &&
  66. typeof object.parent === 'object' &&
  67. object.parent.type === 'Scene' &&
  68. object.parent.name === 'Main' ) {
  69.  
  70. x.consoleLog( 'Found Scene!' )
  71. scene = object.parent;
  72. x.ArrayPrototype.push = x.ArrayPush;
  73.  
  74. }
  75.  
  76. } catch ( error ) {}
  77.  
  78. return x.ArrayPush.apply( this, arguments );
  79.  
  80. }
  81.  
  82. const tempVector = new THREE.Vector3();
  83.  
  84. const tempObject = new THREE.Object3D();
  85. tempObject.rotation.order = 'YXZ';
  86.  
  87. const geometry = new THREE.EdgesGeometry( new THREE.BoxGeometry( 5, 15, 5 ).translate( 0, 7.5, 0 ) );
  88.  
  89. const material = new THREE.RawShaderMaterial( {
  90. vertexShader: `
  91.  
  92. attribute vec3 position;
  93.  
  94. uniform mat4 projectionMatrix;
  95. uniform mat4 modelViewMatrix;
  96.  
  97. void main() {
  98.  
  99. gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
  100. gl_Position.z = 1.0;
  101.  
  102. }
  103.  
  104. `,
  105. fragmentShader: `
  106.  
  107. void main() {
  108.  
  109. gl_FragColor = vec4( 1.0, 0.0, 0.0, 1.0 );
  110.  
  111. }
  112.  
  113. `
  114. } );
  115.  
  116. const line = new THREE.LineSegments( new THREE.BufferGeometry(), material );
  117.  
  118. line.frustumCulled = false;
  119.  
  120. const linePositions = new THREE.BufferAttribute( new Float32Array( 100 * 2 * 3 ), 3 );
  121. line.geometry.setAttribute( 'position', linePositions );
  122.  
  123. let injectTimer = null;
  124.  
  125. function animate() {
  126.  
  127. x.requestAnimationFrame.call( x.window, animate );
  128.  
  129. if ( ! scene && ! injectTimer ) {
  130.  
  131. const el = x.querySelector.call( x.document, '#loadingBg' );
  132.  
  133. if ( el && el.style.display === 'none' ) {
  134.  
  135. x.consoleLog( 'Inject timer started!' );
  136.  
  137. injectTimer = x.setTimeout.call( x.window, () => {
  138.  
  139. x.consoleLog( 'Injected!' );
  140. x.ArrayPrototype.push = proxied;
  141.  
  142. }, 2e3 );
  143.  
  144. }
  145.  
  146. }
  147.  
  148. if ( typeof shouldShowAd === 'undefined' || shouldShowAd === true || scene === undefined || ! scene.children || isNaN( value ) ) {
  149.  
  150. return;
  151.  
  152. }
  153.  
  154. const players = [];
  155.  
  156. let myPlayer;
  157.  
  158. for ( let i = 0; i < scene.children.length; i ++ ) {
  159.  
  160. const child = scene.children[ i ];
  161.  
  162. if ( child.type === 'Object3D' ) {
  163.  
  164. try {
  165.  
  166. if ( child.children[ 0 ].children[ 0 ].type === 'PerspectiveCamera' ) {
  167.  
  168. myPlayer = child;
  169.  
  170. } else {
  171.  
  172. players.push( child );
  173.  
  174. }
  175.  
  176. } catch ( err ) {}
  177.  
  178. } else if ( child.material ) {
  179.  
  180. child.material.wireframe = settings.wireframe;
  181.  
  182. }
  183.  
  184. }
  185.  
  186. if ( ! myPlayer ) {
  187.  
  188. x.consoleLog( 'Player not found, finding new scene.' );
  189. x.ArrayPrototype.push = proxied;
  190. return;
  191.  
  192. }
  193.  
  194. let counter = 0;
  195.  
  196. let targetPlayer;
  197. let minDistance = Infinity;
  198.  
  199. tempObject.matrix.copy( myPlayer.matrix ).invert()
  200.  
  201. for ( let i = 0; i < players.length; i ++ ) {
  202.  
  203. const player = players[ i ];
  204.  
  205. if ( ! player.box ) {
  206.  
  207. const box = new THREE.LineSegments( geometry, material );
  208. box.frustumCulled = false;
  209.  
  210. player.add( box );
  211.  
  212. player.box = box;
  213.  
  214. }
  215.  
  216. if ( player.position.x === myPlayer.position.x && player.position.z === myPlayer.position.z ) {
  217.  
  218. player.box.visible = false;
  219.  
  220. if ( line.parent !== player ) {
  221.  
  222. player.add( line );
  223.  
  224. }
  225.  
  226. continue;
  227.  
  228. }
  229.  
  230. linePositions.setXYZ( counter ++, 0, 10, - 5 );
  231.  
  232. tempVector.copy( player.position );
  233. tempVector.y += 9;
  234. tempVector.applyMatrix4( tempObject.matrix );
  235.  
  236. linePositions.setXYZ(
  237. counter ++,
  238. tempVector.x,
  239. tempVector.y,
  240. tempVector.z
  241. );
  242.  
  243. player.visible = settings.espEnabled || player.visible;
  244. player.box.visible = settings.espEnabled;
  245.  
  246. const distance = player.position.distanceTo( myPlayer.position );
  247.  
  248. if ( distance < minDistance ) {
  249.  
  250. targetPlayer = player;
  251. minDistance = distance;
  252.  
  253. }
  254.  
  255. }
  256.  
  257. linePositions.needsUpdate = true;
  258. line.geometry.setDrawRange( 0, counter );
  259.  
  260. line.visible = settings.espLines;
  261.  
  262. if ( settings.aimbotEnabled === false || ( settings.aimbotOnRightMouse && ! rightMouseDown ) || targetPlayer === undefined ) {
  263.  
  264. return;
  265.  
  266. }
  267.  
  268. tempVector.setScalar( 0 );
  269.  
  270. targetPlayer.children[ 0 ].children[ 0 ].localToWorld( tempVector );
  271.  
  272. tempObject.position.copy( myPlayer.position );
  273.  
  274. tempObject.lookAt( tempVector );
  275.  
  276. myPlayer.children[ 0 ].rotation.x = - tempObject.rotation.x;
  277. myPlayer.rotation.y = tempObject.rotation.y + Math.PI;
  278.  
  279. }
  280.  
  281. const value = parseInt( new URLSearchParams( window.location.search ).get( 'showAd' ), 16 );
  282. const shouldShowAd = isNaN( value ) || Date.now() - value < 0 || Date.now() - value > 10 * 60 * 1000;
  283.  
  284. const el = document.createElement( 'div' );
  285.  
  286. el.innerHTML = `<style>
  287.  
  288. .dialog {
  289. position: absolute;
  290. left: 50%;
  291. top: 50%;
  292. padding: 20px;
  293. background: rgba(0, 0, 0, 0.8);
  294. border: 6px solid rgba(0, 0, 0, 0.2);
  295. color: #fff;
  296. transform: translate(-50%, -50%);
  297. text-align: center;
  298. z-index: 999999;
  299. }
  300.  
  301. .dialog * {
  302. color: #fff;
  303. }
  304.  
  305. .close {
  306. position: absolute;
  307. right: 5px;
  308. top: 5px;
  309. width: 20px;
  310. height: 20px;
  311. opacity: 0.5;
  312. cursor: pointer;
  313. }
  314.  
  315. .close:before, .close:after {
  316. content: ' ';
  317. position: absolute;
  318. left: 50%;
  319. top: 50%;
  320. width: 100%;
  321. height: 20%;
  322. transform: translate(-50%, -50%) rotate(-45deg);
  323. background: #fff;
  324. }
  325.  
  326. .close:after {
  327. transform: translate(-50%, -50%) rotate(45deg);
  328. }
  329.  
  330. .close:hover {
  331. opacity: 1;
  332. }
  333.  
  334. .btn {
  335. cursor: pointer;
  336. padding: 0.5em;
  337. background: red;
  338. border: 3px solid rgba(0, 0, 0, 0.2);
  339. }
  340.  
  341. .btn:active {
  342. transform: scale(0.8);
  343. }
  344.  
  345. .msg {
  346. position: absolute;
  347. left: 10px;
  348. bottom: 10px;
  349. color: #fff;
  350. background: rgba(0, 0, 0, 0.6);
  351. font-weight: bolder;
  352. padding: 15px;
  353. animation: msg 0.5s forwards, msg 0.5s reverse forwards 3s;
  354. z-index: 999999;
  355. pointer-events: none;
  356. }
  357.  
  358. @keyframes msg {
  359. from {
  360. transform: translate(-120%, 0);
  361. }
  362.  
  363. to {
  364. transform: none;
  365. }
  366. }
  367.  
  368. .zui {
  369. position: fixed;
  370. right: 10px;
  371. top: 0;
  372. z-index: 999;
  373. display: flex;
  374. flex-direction: column;
  375. font-family: monospace;
  376. font-size: 14px;
  377. color: #fff;
  378. width: 250px;
  379. user-select: none;
  380. border: 2px solid #000;
  381. }
  382.  
  383. .zui-item {
  384. padding: 5px 8px;
  385. display: flex;
  386. justify-content: space-between;
  387. align-items: center;
  388. background: #222;
  389. cursor: pointer;
  390. }
  391.  
  392. .zui-item.text {
  393. justify-content: center;
  394. cursor: unset;
  395. text-align: center;
  396. background: #333;
  397. }
  398.  
  399. .zui-item:hover {
  400. background: #333;
  401. }
  402.  
  403. .zui-item span {
  404. color: #fff;
  405. font-family: monospace;
  406. font-size: 14px;
  407. }
  408.  
  409. .zui-header {
  410. background: #000;
  411. }
  412.  
  413. .zui-header span {
  414. font-size: 16px;
  415. }
  416.  
  417. .zui-header:hover {
  418. background: #000;
  419. }
  420.  
  421. .zui-on {
  422. color: green;
  423. }
  424.  
  425. .zui-item-value {
  426. font-size: 0.8em;
  427. }
  428.  
  429. .zui-content .zui-item-value {
  430. font-weight: bolder;
  431. }
  432.  
  433. </style>
  434. <div class="msg" style="display: none;"></div>
  435. <div class="dialog">${shouldShowAd ? `<big>Loading ad...</big>` : `<div class="close" onclick="this.parentNode.style.display='none';"></div>
  436. <big>== Aimbot & ESP ==</big>
  437. <br>
  438. <br>
  439. [B] to toggle aimbot
  440. <br>
  441. [V] to toggle ESP
  442. <br>
  443. [N] to toggle ESP Lines
  444. <br>
  445. [L] to toggle aimbot on <br>right mouse hold
  446. <br>
  447. [H] to show/hide help
  448. <br>
  449. <br>
  450. By Zertalious
  451. <br>
  452. <br>
  453. <div style="display: grid; grid-template-columns: 1fr 1fr; grid-gap: 5px;">
  454. <div class="btn" onclick="window.open('https://discord.gg/K24Zxy88VM', '_blank')">Discord</div>
  455. <div class="btn" onclick="window.open('https://www.instagram.com/zertalious/', '_blank')">Instagram</div>
  456. <div class="btn" onclick="window.open('https://twitter.com/Zertalious', '_blank')">Twitter</div>
  457. <div class="btn" onclick="window.open('https://greasyfork.org/en/users/662330-zertalious', '_blank')">More scripts</div>
  458. </div>
  459. ` }
  460. </div>`;
  461.  
  462. const msgEl = el.querySelector( '.msg' );
  463. const dialogEl = el.querySelector( '.dialog' );
  464.  
  465. window.addEventListener( 'DOMContentLoaded', function () {
  466.  
  467. while ( el.children.length > 0 ) {
  468.  
  469. document.body.appendChild( el.children[ 0 ] );
  470.  
  471. }
  472.  
  473. document.body.appendChild( gui );
  474.  
  475. } );
  476.  
  477. if ( shouldShowAd ) {
  478.  
  479. const url = new URL( window.location.href );
  480.  
  481. url.searchParams.set( 'showAd', Date.now().toString( 16 ) );
  482. url.searchParams.set( 'scriptVersion', GM.info.script.version );
  483.  
  484. window.location.href = 'https://zertalious.xyz?ref=' + new TextEncoder().encode( url.href ).toString();
  485.  
  486. } else {
  487.  
  488. removeQueries();
  489.  
  490. }
  491.  
  492. function removeQueries() {
  493.  
  494. const url = new URL( window.location.href );
  495. url.searchParams.delete( 'showAd' );
  496. url.searchParams.delete( 'scriptVersion' );
  497.  
  498. window.history.pushState( null, '', url.href );
  499.  
  500. }
  501.  
  502. let rightMouseDown = false;
  503.  
  504. function handleMouse( event ) {
  505.  
  506. if ( event.button === 2 ) {
  507.  
  508. rightMouseDown = event.type === 'pointerdown' ? true : false;
  509.  
  510. }
  511.  
  512. }
  513.  
  514. window.addEventListener( 'pointerdown', handleMouse );
  515. window.addEventListener( 'pointerup', handleMouse );
  516.  
  517. window.addEventListener( 'keyup', function ( event ) {
  518.  
  519. if ( x.document.activeElement && x.document.activeElement.value !== undefined ) return;
  520.  
  521. if ( keyToSetting[ event.code ] ) {
  522.  
  523. toggleSetting( keyToSetting[ event.code ] );
  524.  
  525. }
  526.  
  527. switch ( event.code ) {
  528.  
  529. case 'Slash' :
  530. toggleElementVisibility( gui );
  531. break;
  532.  
  533. case 'KeyH' :
  534. toggleElementVisibility( dialogEl );
  535. break;
  536.  
  537. }
  538.  
  539. } );
  540.  
  541. function toggleElementVisibility( el ) {
  542.  
  543. el.style.display = el.style.display === '' ? 'none' : '';
  544.  
  545. }
  546.  
  547. function showMsg( name, bool ) {
  548.  
  549. msgEl.innerText = name + ': ' + ( bool ? 'ON' : 'OFF' );
  550.  
  551. msgEl.style.display = 'none';
  552. void msgEl.offsetWidth;
  553. msgEl.style.display = '';
  554.  
  555. }
  556.  
  557. animate();
  558.  
  559. function createGUI() {
  560.  
  561. const guiEl = fromHtml( `<div class="zui">
  562. <div class="zui-item zui-header">
  563. <span>[/] Controls</span>
  564. <span class="zui-item-value">[close]</span>
  565. </div>
  566. <div class="zui-content"></div>
  567. </div>` );
  568.  
  569. const headerEl = guiEl.querySelector( '.zui-header' );
  570. const contentEl = guiEl.querySelector( '.zui-content' );
  571. const headerStatusEl = guiEl.querySelector( '.zui-item-value' );
  572.  
  573. headerEl.onclick = function () {
  574.  
  575. const isHidden = contentEl.style.display === 'none';
  576.  
  577. contentEl.style.display = isHidden ? '' : 'none';
  578. headerStatusEl.innerText = isHidden ? '[close]' : '[open]';
  579.  
  580. }
  581.  
  582. const settingToKey = {};
  583. for ( const key in keyToSetting ) {
  584.  
  585. settingToKey[ keyToSetting[ key ] ] = key;
  586.  
  587. }
  588.  
  589. for ( const prop in settings ) {
  590.  
  591. let name = fromCamel( prop );
  592. let shortKey = settingToKey[ prop ];
  593.  
  594. if ( shortKey ) {
  595.  
  596. if ( shortKey.startsWith( 'Key' ) ) shortKey = shortKey.slice( 3 );
  597. name = `[${shortKey}] ${name}`;
  598.  
  599. }
  600.  
  601. const itemEl = fromHtml( `<div class="zui-item">
  602. <span>${name}</span>
  603. <span class="zui-item-value"></span>
  604. </div>` );
  605. const valueEl = itemEl.querySelector( '.zui-item-value' );
  606.  
  607. function updateValueEl() {
  608.  
  609. const value = settings[ prop ];
  610. valueEl.innerText = value ? 'ON' : 'OFF';
  611. valueEl.style.color = value ? 'green' : 'red';
  612.  
  613. }
  614. itemEl.onclick = function() {
  615.  
  616. settings[ prop ] = ! settings[ prop ];
  617.  
  618. }
  619. updateValueEl();
  620.  
  621. contentEl.appendChild( itemEl );
  622.  
  623. const p = `__${prop}`;
  624. settings[ p ] = settings[ prop ];
  625. Object.defineProperty( settings, prop, {
  626. get() {
  627.  
  628. return this[ p ];
  629.  
  630. },
  631. set( value ) {
  632.  
  633. this[ p ] = value;
  634. updateValueEl();
  635.  
  636. }
  637. } );
  638.  
  639. }
  640.  
  641. contentEl.appendChild( fromHtml( `<div class="zui-item text">
  642. <span>Created by Zertalious!</span>
  643. </div>` ) );
  644.  
  645. return guiEl;
  646.  
  647. }
  648.  
  649. function fromCamel( text ) {
  650.  
  651. const result = text.replace( /([A-Z])/g, ' $1' );
  652. return result.charAt( 0 ).toUpperCase() + result.slice( 1 );
  653.  
  654. }
  655.  
  656. function fromHtml( html ) {
  657.  
  658. const div = document.createElement( 'div' );
  659. div.innerHTML = html;
  660. return div.children[ 0 ];
  661.  
  662. }
  663.  
  664. function toggleSetting( key ) {
  665.  
  666. settings[ key ] = ! settings[ key ];
  667. showMsg( fromCamel( key ), settings[ key ] );
  668.  
  669. }