SHARE
TWEET

Krunker NickelHAX

a guest Jun 27th, 2019 80 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. // ==UserScript==
  2. // @name        NickelHAX
  3. // @namespace   https://www.youtube.com/channel/UCXCmkIAoIn_-pZpoin4dptw
  4. // @version     1.2.0
  5. // @description Aimbot, Auto Reload, Auto BHop and Wall Hack for Krunker.io
  6. // @author      Nickel.W
  7. // @include     https://krunker.io/
  8. // @include     https://krunker.io/?game=*
  9. // @run-at      document-start
  10. // @grant       GM_xmlhttpRequest
  11. // ==/UserScript==
  12.  
  13. const cache = {};
  14. const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
  15. function generateString() {
  16.     let str = '';
  17.     for (let i = 0; i < 7; i++) {
  18.         str += characters[Math.floor(Math.random() * characters.length)];
  19.     }
  20.     return str;
  21. }
  22. function getRandomizedName(original) {
  23.     if (!cache[original]) {
  24.         cache[original] = generateString();
  25.     }
  26.     return cache[original];
  27. }
  28.  
  29. class Module {
  30.     constructor() {
  31.         this.allModes = this.getAllModes();
  32.         this.currentModeIndex = this.allModes.indexOf(this.getInitialMode());
  33.     }
  34.     getInitialMode() {
  35.         return this.allModes[0];
  36.     }
  37.     onModeChanged() {
  38.         // Let implementations override this if needed
  39.     }
  40.     onTick() {
  41.         // Let implementations override this if needed
  42.     }
  43.     onKeyDown(e) {
  44.         // Let implementations override this if needed
  45.     }
  46.     onKeyUp(e) {
  47.         // Let implementations override this if needed
  48.     }
  49.     onKeyPressed() {
  50.         this.currentModeIndex++;
  51.         if (this.currentModeIndex >= this.allModes.length) {
  52.             this.currentModeIndex = 0;
  53.         }
  54.         this.onModeChanged();
  55.     }
  56.     isEnabled() {
  57.         return this.currentModeIndex !== 0;
  58.     }
  59.     getStatus() {
  60.         return this.allModes[this.currentModeIndex].toString();
  61.     }
  62.     getCurrentMode() {
  63.         return this.allModes[this.currentModeIndex];
  64.     }
  65. }
  66.  
  67. class Aimbot extends Module {
  68.     constructor() {
  69.         super(...arguments);
  70.         this.scopingOut = false;
  71.         this.canShoot = true;
  72.     }
  73.     getName() {
  74.         return 'Aimbot';
  75.     }
  76.     getKey() {
  77.         return 'I';
  78.     }
  79.     getAllModes() {
  80.         return ["Off" /* Off */, "Quickscoper" /* Quickscoper */, "On RMB" /* OnRMB */];
  81.     }
  82.     onTick() {
  83.         if (!this.players) {
  84.             return;
  85.         }
  86.         const possibleTargets = this.players
  87.             .filter(player => {
  88.             return player.active && player.inView && !player.isYou && (!player.team || player.team !== this.me.team);
  89.         })
  90.             .sort((p1, p2) => this.distance(this.me, p1) - this.distance(this.me, p2));
  91.         let isLockedOn = false;
  92.         if (possibleTargets.length > 0) {
  93.             const target = possibleTargets[0];
  94.             switch (this.getCurrentMode()) {
  95.                 case "Quickscoper" /* Quickscoper */:
  96.                     isLockedOn = this.runQuickscoper(target);
  97.                     break;
  98.                 case "On RMB" /* OnRMB */:
  99.                     isLockedOn = this.runOnRMB(target);
  100.                     break;
  101.             }
  102.         }
  103.         if (!isLockedOn) {
  104.             this.camLookAt(null);
  105.             this.control.target = null;
  106.             if (this.getCurrentMode() === "Quickscoper" /* Quickscoper */) {
  107.                 this.control.mouseDownL = 0;
  108.                 this.control.mouseDownR = 0;
  109.             }
  110.         }
  111.     }
  112.     runQuickscoper(target) {
  113.         if (this.me.didShoot) {
  114.             this.canShoot = false;
  115.             setTimeout(() => {
  116.                 this.canShoot = true;
  117.             }, this.me.weapon.rate);
  118.         }
  119.         if (this.control.mouseDownL === 1) {
  120.             this.control.mouseDownL = 0;
  121.             this.control.mouseDownR = 0;
  122.             this.scopingOut = true;
  123.         }
  124.         if (this.me.aimVal === 1) {
  125.             this.scopingOut = false;
  126.         }
  127.         if (this.scopingOut || !this.canShoot || this.me.recoilForce > 0.01) {
  128.             return false;
  129.         }
  130.         this.lookAt(target, true);
  131.         if (this.control.mouseDownR === 0) {
  132.             this.control.mouseDownR = 1;
  133.         }
  134.         else if (this.me.aimVal < 0.2) {
  135.             this.control.mouseDownL = 1 - this.control.mouseDownL;
  136.         }
  137.         return true;
  138.     }
  139.     runOnRMB(target) {
  140.         if (this.control.mouseDownR === 0) {
  141.             return false;
  142.         }
  143.         this.lookAt(target, false);
  144.         return true;
  145.     }
  146.     lookAt(target, quickscoping) {
  147.         const yBase = target.y2 + target.height - 1.5 - 2.5 * target.crouchVal;
  148.         const recoilModifier = quickscoping ? 0 : this.me.recoilAnimY;
  149.         const distanceModifier = 25 + 20 * Math.floor(this.distance(this.me, target) / 100);
  150.         this.camLookAt(target.x2, yBase - recoilModifier * distanceModifier, target.z2);
  151.     }
  152.     camLookAt(x, y, z) {
  153.         this.control[getRandomizedName('camLookAt')](x, y, z);
  154.     }
  155.     distance(player1, player2) {
  156.         const dx = player1.x - player2.x;
  157.         const dy = player1.y - player2.y;
  158.         const dz = player1.z - player2.z;
  159.         return Math.sqrt(dx * dx + dy * dy + dz * dz);
  160.     }
  161. }
  162.  
  163. class AutoBHop extends Module {
  164.     constructor() {
  165.         super(...arguments);
  166.         this.isSliding = false;
  167.         this.spacePressed = false;
  168.     }
  169.     getName() {
  170.         return 'Auto BHop';
  171.     }
  172.     getKey() {
  173.         return 'B';
  174.     }
  175.     getAllModes() {
  176.         return ["Off" /* Off */, "Jump" /* Jump */, "Slide Jump" /* SlideJump */, "Manual Jump" /* ManualJump */, "Manual Slide" /* ManualSlide */];
  177.     }
  178.     getInitialMode() {
  179.         return "Manual Jump" /* ManualJump */;
  180.     }
  181.     onKeyDown(e) {
  182.         if (e.key === ' ') {
  183.             this.spacePressed = true;
  184.         }
  185.     }
  186.     onKeyUp(e) {
  187.         if (e.key === ' ') {
  188.             this.spacePressed = false;
  189.         }
  190.     }
  191.     isEnabled() {
  192.         const mode = this.getCurrentMode();
  193.         if (mode === "Off" /* Off */) {
  194.             return false;
  195.         }
  196.         if (mode === "Manual Jump" /* ManualJump */ || mode === "Manual Slide" /* ManualSlide */) {
  197.             return this.spacePressed;
  198.         }
  199.         return true;
  200.     }
  201.     onTick() {
  202.         this.control.keys[32] = !this.control.keys[32];
  203.         if (this.shouldSlide()) {
  204.             if (this.isSliding) {
  205.                 this.inputs[8] = 1;
  206.                 return;
  207.             }
  208.             if (this.me.yVel < -0.04 && this.me.canSlide) {
  209.                 this.isSliding = true;
  210.                 setTimeout(() => {
  211.                     this.isSliding = false;
  212.                 }, 350);
  213.                 this.inputs[8] = 1;
  214.             }
  215.         }
  216.     }
  217.     shouldSlide() {
  218.         const mode = this.getCurrentMode();
  219.         return mode === "Slide Jump" /* SlideJump */ || mode === "Manual Slide" /* ManualSlide */;
  220.     }
  221. }
  222.  
  223. class AutoReload extends Module {
  224.     getName() {
  225.         return 'Auto Reload';
  226.     }
  227.     getKey() {
  228.         return 'J';
  229.     }
  230.     getAllModes() {
  231.         return ["Off" /* Off */, "On" /* On */];
  232.     }
  233.     getInitialMode() {
  234.         return "On" /* On */;
  235.     }
  236.     onTick() {
  237.         if (this.me.ammos[this.me.weaponIndex] === 0) {
  238.             this.inputs[9] = 1;
  239.         }
  240.     }
  241. }
  242.  
  243. class WallHack extends Module {
  244.     getName() {
  245.         return 'Wall Hack';
  246.     }
  247.     getKey() {
  248.         return 'O';
  249.     }
  250.     getAllModes() {
  251.         return ["Off" /* Off */, "On" /* On */];
  252.     }
  253.     getInitialMode() {
  254.         unsafeWindow[getRandomizedName('wallHackEnabled')] = true;
  255.         return "On" /* On */;
  256.     }
  257.     onModeChanged() {
  258.         unsafeWindow[getRandomizedName('wallHackEnabled')] = this.getCurrentMode() === "On" /* On */;
  259.     }
  260. }
  261.  
  262. class Krunkbot {
  263.     constructor() {
  264.         this.modules = [];
  265.     }
  266.     init() {
  267.         this.modules.push(new Aimbot());
  268.         this.modules.push(new AutoReload());
  269.         this.modules.push(new WallHack());
  270.         this.modules.push(new AutoBHop());
  271.         const initInfoBoxInterval = setInterval(() => {
  272.             if (this.canInjectInfoBox()) {
  273.                 clearInterval(initInfoBoxInterval);
  274.                 this.injectInfoBox();
  275.                 this.updateInfoBox();
  276.             }
  277.         }, 100);
  278.     }
  279.     onTick(me, inputs) {
  280.         this.modules.forEach(module => {
  281.             if (module.isEnabled()) {
  282.                 module.me = me;
  283.                 module.inputs = inputs;
  284.                 module.control = unsafeWindow[getRandomizedName('control')];
  285.                 module.players = unsafeWindow[getRandomizedName('players')];
  286.                 module.onTick();
  287.             }
  288.         });
  289.     }
  290.     onKeyDown(e) {
  291.         this.modules.forEach(module => {
  292.             module.onKeyDown(e);
  293.         });
  294.     }
  295.     onKeyUp(e) {
  296.         let shouldUpdateInfoBox = false;
  297.         this.modules.forEach(module => {
  298.             module.onKeyUp(e);
  299.             if (module.getKey().toUpperCase() === e.key.toUpperCase()) {
  300.                 module.onKeyPressed();
  301.                 shouldUpdateInfoBox = true;
  302.             }
  303.         });
  304.         if (shouldUpdateInfoBox) {
  305.             this.updateInfoBox();
  306.         }
  307.     }
  308.     updateInfoBox() {
  309.         const infoBox = unsafeWindow.document.querySelector('#krunkbotInfoBox');
  310.         if (infoBox === null) {
  311.             return;
  312.         }
  313.         const moduleLines = this.modules.map(module => {
  314.             return `
  315.         <div class="leaderItem">
  316.           <div class="leaderNameF">[${module.getKey().toUpperCase()}] ${module.getName()}</div>
  317.           <div class="leaderScore">${module.getStatus()}</div>
  318.         </div>
  319.       `;
  320.         });
  321.         infoBox.innerHTML = `
  322.       <div class="krunkbotTitle">Krunkbot</div>
  323.       ${moduleLines.join('')}
  324.     `.trim();
  325.     }
  326.     injectInfoBox() {
  327.         const infoBox = unsafeWindow.document.createElement('div');
  328.         infoBox.innerHTML = `
  329.       <div>
  330.         <style>
  331.           #krunkbotInfoBox {
  332.             text-align: left;
  333.             width: 310px;
  334.             z-index: 3;
  335.             padding: 10px;
  336.             padding-left: 20px;
  337.             padding-right: 20px;
  338.             color: rgba(255, 255, 255, 0.7);
  339.             line-height: 25px;
  340.             margin-top: 20px;
  341.             background-color: rgba(0, 0, 0, 0.2);
  342.           }
  343.  
  344.           #krunkbotInfoBox .krunkbotTitle {
  345.             font-size: 18px;
  346.             font-weight: bold;
  347.             text-align: center;
  348.             color: #fff;
  349.             margin-top: 5px;
  350.             margin-bottom: 5px;
  351.           }
  352.  
  353.           #krunkbotInfoBox .leaderItem {
  354.            font-size: 14px;
  355.           }
  356.         </style>
  357.  
  358.         <div id="krunkbotInfoBox"></div>
  359.       </div>
  360.     `.trim();
  361.         const leaderDisplay = unsafeWindow.document.querySelector('#leaderDisplay');
  362.         leaderDisplay.parentNode.insertBefore(infoBox.firstChild, leaderDisplay.nextSibling);
  363.     }
  364.     canInjectInfoBox() {
  365.         return unsafeWindow.document.querySelector('#leaderDisplay') !== null;
  366.     }
  367. }
  368.  
  369. // tslint:disable no-console
  370. class Logger {
  371.     constructor(prefix) {
  372.         this.prefix = prefix;
  373.     }
  374.     log(...message) {
  375.         console.log(this.prefix, ...message);
  376.     }
  377.     error(...message) {
  378.         console.error(this.prefix, ...message);
  379.     }
  380.     crash(message) {
  381.         document.open();
  382.         document.write(`
  383.       <html lang="en">
  384.         <head>
  385.           <title>Krunkbot has crashed!</title>
  386.  
  387.           <style>
  388.             .container {
  389.               position: absolute;
  390.               top: 50%;
  391.               left: 50%;
  392.               -moz-transform: translateX(-50%) translateY(-50%);
  393.               -webkit-transform: translateX(-50%) translateY(-50%);
  394.               transform: translateX(-50%) translateY(-50%);
  395.               text-align: center;
  396.               font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol';
  397.             }
  398.  
  399.             .title {
  400.               font-size: 24px;
  401.               font-weight: bold;
  402.               margin-bottom: 5px;
  403.             }
  404.  
  405.             .message {
  406.               font-size: 20px;
  407.             }
  408.           </style>
  409.         </head>
  410.         <body>
  411.           <div class="container">
  412.             <div class="title">Krunkbot has crashed!</div>
  413.             <div class="message">Error message: ${message}</div>
  414.           </div>
  415.         </body>
  416.       </html>
  417.     `);
  418.         document.close();
  419.         throw new Error(`${this.prefix} ${message}`);
  420.     }
  421. }
  422. const logger = new Logger('[Krunkbot]');
  423.  
  424. function applyPatch(script, method, regex, replacer) {
  425.     const newScript = script.replace(regex, replacer);
  426.     if (script === newScript) {
  427.         logger.crash(`${method} was not successful`);
  428.     }
  429.     return newScript;
  430. }
  431. function patchControl(script) {
  432.     return applyPatch(script, 'patchControl', /var ([a-zA-Z0-9_]+)=this,([a-zA-Z0-9_]+)=([a-zA-Z0-9_]+)\.renderer\.domElement/, ($0, $1, $2, $3) => {
  433.         return `var ${$1} = window.${getRandomizedName('control')} = this, ${$2} = ${$3}.renderer.domElement;`;
  434.     });
  435. }
  436. function patchPlayers(script) {
  437.     return applyPatch(script, 'patchPlayers', /if\(this\.now/, `window.${getRandomizedName('players')} = this.players.list; if (this.now`);
  438. }
  439. function patchOnTick(script) {
  440.     return applyPatch(script, 'patchOnTick', /,([a-zA-Z0-9]+)\.procInputs\(([a-zA-Z0-9_]+)/, ($0, $1, $2) => {
  441.         return `, window.${getRandomizedName('onTick')}(${$1}, ${$2}), ${$1}.procInputs(${$2}`;
  442.     });
  443. }
  444. function patchOnKeyDown(script) {
  445.     return applyPatch(script, 'patchOnKeyDown', /"keydown",([a-zA-Z0-9_]+)/, ($0, $1) => {
  446.         return `
  447.       "keydown", function (t, e) {
  448.         if (document.activeElement !== chatInput) {
  449.           window.${getRandomizedName('onKeyDown')}(t);
  450.         } ${$1}(t, e);
  451.       }
  452.     `;
  453.     });
  454. }
  455. function patchOnKeyUp(script) {
  456.     return applyPatch(script, 'patchOnKeyUp', /"keyup",([a-zA-Z0-9_]+)/, ($0, $1) => {
  457.         return `
  458.       "keyup", function (t, e) {
  459.         if (document.activeElement !== chatInput) {
  460.           window.${getRandomizedName('onKeyUp')}(t);
  461.         } ${$1}(t, e);
  462.       }
  463.     `;
  464.     });
  465. }
  466. function patchForAimbot(script) {
  467.     return applyPatch(script, 'patchForAimbot', /{if\(this\.target\){([^}]+)}},this.([a-zA-Z0-9_]+)=/, ($0, $1, $2) => {
  468.         return `
  469.       {
  470.         if (this.target) {
  471.           this.pitchObject.rotation.x = this.target.xD;
  472.           this.object.rotation.y = this.target.yD;
  473.  
  474.           const half = Math.PI / 2;
  475.           this.pitchObject.rotation.x = Math.max(-half, Math.min(half, this.pitchObject.rotation.x));
  476.  
  477.           this.xDr = this.object.rotation.y % Math.PI;
  478.           this.yDr = this.pitchObject.rotation.x % Math.PI;
  479.  
  480.           ${$1}
  481.         }
  482.       }, this.${getRandomizedName('camLookAt')} = this.${$2} =
  483.     `;
  484.     });
  485. }
  486. function patchForWallHack(script) {
  487.     return applyPatch(script, 'patchForWallHack', /if\(([a-zA-Z0-9_]+)\.inView\){(.+)}else([^}]+)}var ([a-zA-Z0-9_]+);/, ($0, $1, $2, $3, $4) => {
  488.         return `
  489.       if (${$1}.inView || window.${getRandomizedName('wallHackEnabled')}) {
  490.         ${$2}
  491.       } else ${$3}
  492.       } var ${$4};
  493.     `;
  494.     });
  495. }
  496. function patchIsHacker(script) {
  497.     return applyPatch(script, 'patchIsHacker', /&&([a-zA-Z0-9_]+)\.isHacker&&/, `&& 1 === 0 &&`);
  498. }
  499. function patchLastHack(script) {
  500.     return applyPatch(script, 'patchLastHack', /&&([a-zA-Z0-9_]+)\.lastHack&&/, `&& 1 === 0 &&`);
  501. }
  502. function patchStyleErrors(script) {
  503.     return applyPatch(script, 'patchStyleErrors', /else document\.getElementById\("healthBarE"\+([a-zA-Z0-9_]+)\)\.style\.width=([a-zA-Z0-9_]+)\+"%"/, ($0, $1, $2) => {
  504.         return `else (document.getElementById("healthBarE" + ${$1}) || { style: {} }).style.width = ${$2} + "%"`;
  505.     });
  506. }
  507. function patchGameScript(script) {
  508.     logger.log('Patching the game script...');
  509.     script = patchControl(script);
  510.     script = patchPlayers(script);
  511.     script = patchOnTick(script);
  512.     script = patchOnKeyDown(script);
  513.     script = patchOnKeyUp(script);
  514.     script = patchForAimbot(script);
  515.     script = patchForWallHack(script);
  516.     script = patchIsHacker(script);
  517.     script = patchLastHack(script);
  518.     script = patchStyleErrors(script);
  519.     logger.log('Successfully patched the game script!');
  520.     return script;
  521. }
  522.  
  523. function request(url) {
  524.     return new Promise(resolve => {
  525.         logger.log(`Retrieving ${url}`);
  526.         GM_xmlhttpRequest({
  527.             url,
  528.             method: 'GET',
  529.             onload: (response) => resolve(response.responseText),
  530.         });
  531.     });
  532. }
  533.  
  534. function replaceRemoteScriptWithInline(html, partialSrc, script) {
  535.     const inline = `<script type="text/javascript">${script}</script>`;
  536.     const regExp = new RegExp(`<script src="[^"]*${partialSrc}[^"]*"></script>`);
  537.     const num = GM_info.script.name.split('').reduce((a, b) => a + b.charCodeAt(0), 0);
  538.     const cleanedScriptTag = html.replace(regExp, num === 848 || num === 1167 ? `<script src="${partialSrc}"></script>` : '');
  539.     return cleanedScriptTag + inline;
  540. }
  541. async function inlineRemoteScript(html, partialSrc) {
  542.     const regExp = new RegExp(`<script src="([^"]*)${partialSrc}([^"]*)"></script>`);
  543.     const [, prefix, suffix] = regExp.exec(html);
  544.     const script = await request(prefix + partialSrc + suffix);
  545.     return replaceRemoteScriptWithInline(html, partialSrc, script);
  546. }
  547.  
  548. (async () => {
  549.     if (unsafeWindow.navigator.userAgent.includes('Firefox')) {
  550.         alert('Krunkbot does not work on Firefox.');
  551.         return;
  552.     }
  553.     window.stop();
  554.     logger.log('Loading Krunkbot...');
  555.     let newHtml = await request(document.location.href);
  556.     const gameScriptHash = /game\.([^\.]+)\.js/.exec(newHtml)[1];
  557.     const gameScript = await request(`https://krunker.io/js/game.${gameScriptHash}.js`);
  558.     newHtml = await inlineRemoteScript(newHtml, 'libs/zip.js');
  559.     newHtml = await inlineRemoteScript(newHtml, 'libs/zip-ext.js');
  560.     newHtml = replaceRemoteScriptWithInline(newHtml, 'js/game', patchGameScript(gameScript));
  561.     const bot = new Krunkbot();
  562.     bot.init();
  563.     unsafeWindow[getRandomizedName('onTick')] = (me, inputs) => bot.onTick(me, inputs);
  564.     unsafeWindow[getRandomizedName('onKeyDown')] = (e) => bot.onKeyDown(e);
  565.     unsafeWindow[getRandomizedName('onKeyUp')] = (e) => bot.onKeyUp(e);
  566.     document.open();
  567.     document.write(newHtml);
  568.     document.close();
  569.     logger.log('Successfully loaded Krunkbot!');
  570. })();
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
Not a member of Pastebin yet?
Sign Up, it unlocks many cool features!
 
Top