Advertisement
Guest User

Untitled

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