Advertisement
Guest User

Krunker NickelHAX

a guest
Jun 27th, 2019
191
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 18.29 KB | None | 0 0
  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. })();
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement