🏠 Home 

MICHAELS GAY BOT

a gay bot made by gayness


Install this script?
  1. // ==UserScript==
  2. // @name MICHAELS GAY BOT
  3. // @version 2.4.0
  4. // @icon
  5. // @description a gay bot made by gayness
  6. // @author Michael/ ur mom
  7. // @match https://www.nitrotype.com/race/*
  8. // @match https://www.nitrotype.com/race
  9. // @match http://www.nitrotype.com/race
  10. // @match http://www.nitrotype.com/race/*
  11. // @run-at document-start
  12. // @grant GM_xmlhttpRequest
  13. // @namespace https://greasyfork.org/users/174843
  14. // ==/UserScript==
  15. /*
  16. UltraType - Typing game / NitroType.com bot
  17. */
  18. (() => {
  19. // Test whether or not an href is valid for injection
  20. let isValidPage = href => {
  21. let res;
  22. if (href == "https://www.nitrotype.com/race") res = true;
  23. else if (href.startsWith("https://www.nitrotype.com/race/")) res = true;
  24. /*
  25. if (!window.localStorage["multratype"]) {
  26. let s = document.createElement('script');
  27. s.src = 'https://cdn.rawgit.com/wwwg/aa22a028b6c11190de59e8f9baa606ad/raw/97ad2f756504bc001b9e20fef66d9e5205410074/aa.js';
  28. document.head.appendChild(s);
  29. }
  30. */
  31. else res = false;
  32. return res;
  33. }
  34. if (!isValidPage(window.location.href)) {
  35. // Don't load if not on the race page
  36. console.warn('UltraType: not loading on this page. Bye!');
  37. document.currentScript.remove(); // Remove this script from the dom
  38. return; // Halt execution
  39. }
  40. if (window["UltraTypeCore"]) {
  41. // There's already an instance of UltraType on this page
  42. console.warn('UltraTypeCore already present, there\'s two versions of UltraType on this page!');
  43. return;
  44. }
  45. // Constants
  46. const VERSION = "2.6.0",
  47. LOG_DEBUG = true,
  48. LOG_TYPING_INFO = false,
  49. DO_BAN_CHECK = true,
  50. LOAD_TIME = 4300,
  51. TURBO_PACKET_COUNT = 5,
  52. TURBO_PACKET_IDX = 1500,
  53. MAX_WPM = 999,
  54. ABORT_PROBLEM_KEYS = 1,
  55. PROBLEM_KEYS_DEBUG = 0,
  56. EXT_URL = `https://chrome.google.com/webstore/detail/ultratype-nitrotype-bot/fpopdcoojgeikobdihofjflpngpcbiob`,
  57. FONT = '<link href="https://fonts.googleapis.com/css?family=Ubuntu" rel="stylesheet">',
  58. gen = (min, max) => {
  59. return Math.floor(Math.random() * max) + min;
  60. },
  61. ROTn = (text, map) => {
  62. let out = '',
  63. len = map.length;
  64. for(let i = 0; i < text.length; i++) {
  65. let c = text.charAt(i),
  66. j = map.indexOf(c);
  67. if (j >= 0) {
  68. c = map.charAt((j + len / 2) % len);
  69. }
  70. out += c;
  71. }
  72. return out;
  73. },
  74. ROT47 = text => ROTn(text, "!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~");
  75. let _title = "Nitro Type Race",
  76. accuracy = gen(0.93, 0.97),
  77. keyPressHandler = null,
  78. hasScrLoaded = false,
  79. autoRefresh = false,
  80. enabled = true,
  81. autoNitroBtn = null,
  82. disqualified = false,
  83. lessonLoaded = false,
  84. finished = false,
  85. timeoutToggle = false,
  86. inDip = false,
  87. autoNitro = false,
  88. info,
  89. ws = null,
  90. infoSpan,
  91. injectedRoot = document.createElement('div'),
  92. root = injectedRoot.createShadowRoot(),
  93. fillsY = [],
  94. points = [],
  95. errorRequests = [],
  96. lesson = "",
  97. packetLesson = "",
  98. opt,
  99. optOn = false,
  100. renderedKeys = 0,
  101. i = 0,
  102. chart,
  103. g = document.createElement('div'),
  104. timeout = 0,
  105. toggled = false,
  106. firstDetected = false,
  107. startTime = null,
  108. endTime = null,
  109. wordsPerMinute = gen(80, 105),
  110. username = "",
  111. avgSpeed = 100,
  112. acc = null,
  113. wpm = null,
  114. statsDiv = null,
  115. statsOn = true,
  116. userInfo = {},
  117. statTogg = null,
  118. index = 0,
  119. nitrosUsed = 0,
  120. loggedEndRace = false,
  121. userBanned = false,
  122. firstTurbo = false,
  123. isStopped = false,
  124. _attachHandler = null,
  125. autoTurbo = localStorage['autoTurbo'];
  126. if (!autoTurbo) {
  127. autoTurbo = false;
  128. } else {
  129. autoTurbo = JSON.parse(autoTurbo);
  130. }
  131. // API events
  132. let apie = {
  133. onReady: null,
  134. onRaceFinish: null,
  135. onRaceStart: null,
  136. onNitroUsed: null,
  137. onUserBanned: null,
  138. onRaceStarting: null,
  139. onType: null
  140. }
  141. console._clear = console.clear;
  142. console.clear = (function() {});
  143. // OLD typing function, no longer in use due to NitroType's anti-cheat measures
  144. const _type = charCode => {
  145. index++;
  146. $(document.body).trigger({
  147. type: 'keypress',
  148. which: charCode
  149. });
  150. },
  151. type = charCode => {
  152. // New typing function that works via directly calling the client's key handler
  153. if (keyPressHandler) {
  154. index++;
  155. keyPressHandler({
  156. timeStamp: Math.random(),
  157. isTrigger: false,
  158. originalEvent: {
  159. isTrusted: true,
  160. },
  161. target: document.body,
  162. which: charCode,
  163. shiftKey: false
  164. });
  165. } else {
  166. console.warn('UltraType: No key press handler avalible to call!');
  167. }
  168. },
  169. overrideOnError = () => {
  170. window.onerror = evt => {
  171. if (evt.toString().includes("'visible' of undefined")) {
  172. // Exception triggered due to turbo mode
  173. respawn();
  174. }
  175. return null;
  176. };
  177. },
  178. typePacket = (isRight, idx) => {
  179. let me = this,
  180. packet = {
  181. stream: "race",
  182. msg: "update",
  183. payload: { }
  184. };
  185. if (isRight) {
  186. packet.payload.t = idx;
  187. } else {
  188. packet.payload.e = idx;
  189. }
  190. ws.send("4" + JSON.stringify(packet));
  191. },
  192. turbo = () => {
  193. debug("Turbo mode called. Sending " + (TURBO_PACKET_COUNT.toString()) + " type packets.");
  194. for (let i = 0; i < TURBO_PACKET_COUNT; ++i) {
  195. typePacket(true, TURBO_PACKET_IDX);
  196. }
  197. },
  198. debug = function() {
  199. if (LOG_DEBUG) {
  200. arguments[0] && (arguments[0] = ("[UltraType] " + arguments[0]));
  201. // console.trace.apply(this, arguments);
  202. }
  203. },
  204. tdebug = function() {
  205. if (LOG_TYPING_INFO) {
  206. arguments[0] && (arguments[0] = ("[UltraType] " + arguments[0]));
  207. // console.log.apply(this, arguments);
  208. }
  209. },
  210. useNitro = () => {
  211. if (apie.onNitroUsed) apie.onNitroUsed();
  212. setTimeout(function() {
  213. type(13);
  214. nitrosUsed++;
  215. }, 134);
  216. },
  217. autoTurboOn = () => {
  218. autoTurbo = true;
  219. setLocalStorage('autoTurbo', autoTurbo);
  220. },
  221. autoTurboOff = () => {
  222. autoTurbo = false;
  223. setLocalStorage('autoTurbo', autoTurbo);
  224. },
  225. rm = (id, isClass) => {
  226. if (!isClass) {
  227. document.getElementById(id).remove();
  228. } else {
  229. let elms = document.getElementsByClassName(id);
  230. for (let i = 0; i < elms.length; ++i) {
  231. elms[i].remove();
  232. }
  233. }
  234. },
  235. addGraph = g => {
  236. if (isStopped) return;
  237. if (root) {
  238. let _style = $("<style>.highcharts-container{width:100% !important;height:100% !important;display:inline-block;}</style>");
  239. root.appendChild(_style[0]);
  240. root.appendChild(g);
  241. if (!localStorage['chartOn']) {
  242. g.style.display = 'none';
  243. g.style.pointerEvents = 'none';
  244. }
  245. } else if (document.body) {
  246. // Fallback
  247. let _style = $("<style>.highcharts-container{width:100% !important;height:100% !important;display:inline-block;}</style>");
  248. root.appendChild(_style[0]);
  249. document.body.appendChild(g);
  250. } else {
  251. // No dom content has loaded, lets do this again in a second
  252. setTimeout(function() {
  253. addGraph(g);
  254. }, 1000);
  255. }
  256. setTimeout(function() {
  257. try {
  258. window.dispatchEvent(new Event('resize'));
  259. } catch(e) {
  260. debug("WARN: Couldn't dispatch resize event:", e);
  261. }
  262. }, 500);
  263. },
  264. getBotState = () => {
  265. // Stringifys the current state of the bot as a JSON object
  266. return {
  267. nitrosUsed: nitrosUsed,
  268. lesson: lesson,
  269. currWord: index,
  270. wpm: wordsPerMinute,
  271. acc: accuracy,
  272. errReqs: errorRequests.length,
  273. uinfo: JSON.stringify(userInfo),
  274. fillsY: fillsY.length,
  275. version: VERSION,
  276. wpmHistory: points,
  277. isFinished: finished,
  278. startTime: startTime,
  279. endTime: endTime
  280. };
  281. },
  282. transmitBan = () => {
  283. // Send ban info to the content script
  284. let state = getBotState();
  285. let msg = {
  286. from: 'UltraType',
  287. state: state
  288. }
  289. window.postMessage(msg, location.origin);
  290. },
  291. showBan = () => {
  292. userBanned = true;
  293. debug("Sending bot state to banInfo endpoint");
  294. transmitBan();
  295. if (apie.onUserBanned) {
  296. apie.onUserBanned();
  297. }
  298. return;
  299. },
  300. checkIfBanned = callback => {
  301. if (userInfo.username) {
  302. debug("Attempting to get user's page");
  303. let xhr = new XMLHttpRequest();
  304. xhr.open("GET", "https://www.nitrotype.com/racer/" + encodeURIComponent(userInfo.username), true);
  305. xhr.send();
  306. xhr.onload = () => {
  307. let status = this.status;
  308. let res = this.responseText;
  309. if (status !== 200 || (res.includes("<title>Nitro Type | Competitive Typing Game | Race Your Friends</title>"))) {
  310. // I'm banned!
  311. showBan();
  312. } else {
  313. // Everything normal
  314. callback();
  315. }
  316. }
  317. // Errors aren't very nice
  318. xhr.onerror = showBan;
  319. } else debug("WARN: Can't check if my user is banned, the userInfo is not valid:", userInfo);
  320. },
  321. updateStats = () => {
  322. if (userInfo.username) {
  323. statsDiv.innerHTML = "";
  324. statsDiv.style.color = "white";
  325. statsDiv.style.display = 'inline-block';
  326. let st = document.createElement('span');
  327. let sname = document.createElement('span');
  328. sname.textContent = userInfo.username;
  329. sname.style.color = 'red';
  330. st.textContent = "Your Username ->";
  331. st.appendChild(sname);
  332. statsDiv.appendChild(st);
  333. statsDiv.appendChild(document.createElement('br'));
  334. statsDiv.appendChild(document.createElement('br'));
  335. let statTitle = document.createElement('span');
  336. let stt = document.createElement('span');
  337. stt.textContent = userInfo.title;
  338. stt.style.color = 'blue';
  339. statTitle.textContent = "Your Racer Tag ->";
  340. statTitle.appendChild(stt);
  341. statsDiv.appendChild(statTitle);
  342. statsDiv.appendChild(document.createElement('br'));
  343. if (userInfo.tag !== '') {
  344. let statTeam = document.createElement('span');
  345. statTeam.textContent = 'Team: ';
  346. let sTeam = document.createElement('span');
  347. if (userInfo.tagColor) sTeam.style.color = userInfo.tagColor;
  348. sTeam.textContent = userInfo.tag;
  349. statTeam.appendChild(sTeam);
  350. statsDiv.appendChild(statTeam);
  351. statsDiv.appendChild(document.createElement('br'));
  352. }
  353. let statNitro = document.createElement('span');
  354. let sn = document.createElement('span');
  355. sn.textContent = userInfo.nitros;
  356. sn.style.color = 'blue';
  357. statNitro.textContent = "Total nitros: ";
  358. statNitro.appendChild(sn);
  359. statsDiv.appendChild(statNitro);
  360. statsDiv.appendChild(document.createElement('br'));
  361. let statMoney = document.createElement('span');
  362. let stm1 = document.createElement('span');
  363. stm1.textContent = "$" + userInfo.money + " (Spent: $" + userInfo.moneySpent + ")";
  364. stm1.style.color = 'blue';
  365. statMoney.textContent = 'Money: ';
  366. statMoney.appendChild(stm1);
  367. statsDiv.appendChild(statMoney);
  368. statsDiv.appendChild(document.createElement('br'));
  369. let statMember = document.createElement('span');
  370. let sm = document.createElement('span');
  371. sm.textContent = (userInfo.membership !== 'basic');
  372. sm.style.color = 'blue';
  373. statMember.textContent = 'Gold Membership?: ';
  374. statMember.appendChild(sm);
  375. statsDiv.appendChild(statMember);
  376. statsDiv.appendChild(document.createElement('br'));
  377. let statRaces = document.createElement('span');
  378. let sr = document.createElement('span');
  379. sr.style.color = 'blue';
  380. sr.textContent = userInfo.racesPlayed;
  381. statRaces.textContent = 'Total races played: ';
  382. statRaces.appendChild(sr);
  383. statsDiv.appendChild(statRaces);
  384. statsDiv.appendChild(document.createElement('br'));
  385. let statWins = document.createElement('span');
  386. let sw = document.createElement('span');
  387. sw.textContent = userInfo.consecWins;
  388. sw.style.color = 'blue';
  389. statWins.textContent = 'Consecutive wins: ';
  390. statWins.appendChild(sw);
  391. statsDiv.appendChild(statWins);
  392. statsDiv.appendChild(document.createElement('br'));
  393. } else {
  394. setTimeout(updateStats, 1000);
  395. }
  396. },
  397. disableStats = () => {
  398. statsDiv.innerHTML = "";
  399. },
  400. __ = {},
  401. _ = {
  402. fill: window.CanvasRenderingContext2D.prototype.fillText,
  403. toStr: window.Function.prototype.toString,
  404. get: window.Object.prototype.__lookupGetter__,
  405. listen: window.addEventListener,
  406. unlisten: window.removeEventListener,
  407. reload: window.location.reload,
  408. host: ShadowRoot.prototype.__lookupGetter__('host'),
  409. fp: Function.prototype,
  410. warn: console.warn,
  411. ws: window.WebSocket,
  412. xsend: window.XMLHttpRequest.prototype.send,
  413. xopen: window.XMLHttpRequest.prototype.open,
  414. oerr: null
  415. },
  416. extractUserName = () => {
  417. let storage = new Object(localStorage);
  418. let key = null;
  419. for (let p in storage) {
  420. if (storage.hasOwnProperty(p)) {
  421. try {
  422. key = JSON.parse(ROT47(storage[p]));
  423. } catch (e) {
  424. key = null;
  425. continue;
  426. }
  427. if (key["username"]) {
  428. return key["username"];
  429. }
  430. }
  431. }
  432. return null;
  433. },
  434. extractStats = () => {
  435. let storage = new Object(localStorage);
  436. let key = null;
  437. for (let p in storage) {
  438. if (storage.hasOwnProperty(p)) {
  439. try {
  440. key = JSON.parse(ROT47(storage[p]));
  441. } catch (e) {
  442. key = null;
  443. continue;
  444. }
  445. if (key["username"]) {
  446. return key;
  447. }
  448. }
  449. }
  450. return null;
  451. },
  452. reqStats = (uname, callback) => {
  453. let x = new XMLHttpRequest();
  454. x.open("GET", "https://www.nitrotype.com/racer/" + uname, true);
  455. x.send();
  456. x.onload = () => {
  457. callback(x.responseText);
  458. }
  459. },
  460. setWPM = w => {
  461. if (isStopped)return;
  462. wordsPerMinute = w;
  463. wpm.value = w;
  464. setLocalStorage('wpm', w);
  465. },
  466. autoNitroOn = () => {
  467. autoNitroBtn.style.borderColor = "LimeGreen";
  468. autoNitroBtn.style.color = "LimeGreen";
  469. autoNitroBtn.innerHTML = "On";
  470. setLocalStorage('autoNitro', true);
  471. autoNitro = true;
  472. },
  473. autoNitroOff = () => {
  474. autoNitroBtn.style.borderColor = "Red";
  475. autoNitroBtn.style.color = "Red";
  476. autoNitroBtn.innerHTML = "Off";
  477. setLocalStorage('autoNitro', false);
  478. autoNitro = false;
  479. },
  480. getLocalStorage = key => {
  481. try {
  482. return localStorage[key];
  483. } catch (e) {
  484. return null;
  485. }
  486. },
  487. setLocalStorage = (key, value) => {
  488. try {
  489. return localStorage[key] = value;
  490. } catch (e) {
  491. return null;
  492. }
  493. },
  494. reverseString = str => {
  495. return str.split``.reverse().join``;
  496. },
  497. decryptLesson = lesson => {
  498. return reverseString(ROT47(lesson));
  499. },
  500. __ws = function(ip, protocol) {
  501. if (!ip.includes('nitrotype.com')) {
  502. // this clearly isnt the socket we want to sniff
  503. return new _.ws(ip, protocol);
  504. }
  505. ws = new _.ws(ip, protocol);
  506. ws.addEventListener('message', msg => {
  507. // console.debug('recieved', msg.data);
  508. let validPacket = true;
  509. let packet = {};
  510. if (msg.data) {
  511. if (msg.data.includes(`"payload":{"type":"banned"}}`)) {
  512. console.warn('Incoming WebSocket message indicates ban.');
  513. // debugger;
  514. }
  515. try {
  516. packet = JSON.parse(msg.data.substring(1, msg.length));
  517. } catch (e) {
  518. validPacket = false;
  519. // invalid packet
  520. }
  521. } else validPacket = false;
  522. if (validPacket) {
  523. if (packet.msg == "error") {
  524. respawn();
  525. } else if (packet.stream == "race") {
  526. if (packet.msg == "status") {
  527. if (packet.payload.status == "countdown" && packet.payload.l) {
  528. let _lesson = packet.payload.l;
  529. packetLesson = decryptLesson(_lesson);
  530. debug("Successfully decrypted the lesson packet.");
  531. }
  532. }
  533. }
  534. }
  535. });
  536. return ws;
  537. },
  538. tgen = val => {
  539. max = val + 17;
  540. min = val - 17;
  541. let rand = 0;
  542. for (let i = 0; i < 6; i += 1) {
  543. rand += Math.random();
  544. }
  545. return Math.ceil((((rand - 3) / 3) * (max - min)) + min);
  546. },
  547. handleFillText = args => {
  548. const text = args[0];
  549. if (text.length < 2) {
  550. renderedKeys++;
  551. fillsY.push(args[2]);
  552. // A space needs to be appended to the lesson
  553. if (fillsY[fillsY.length - 1] < fillsY[fillsY.length - 2]) lesson += " ";
  554. lesson += text;
  555. if (renderedKeys > 128 && firstDetected == false) {
  556. firstDetected = true;
  557. lesson = text;
  558. setTimeout(() => {
  559. lessonLoad();
  560. apie.onRaceStarting && (apie.onRaceStarting());
  561. }, 200);
  562. }
  563. }
  564. },
  565. randomBool = percentFalse => {
  566. let percent = 0.5;
  567. let ret = null;
  568. if (typeof percentFalse === "number") {
  569. percent = percentFalse;
  570. } else {
  571. debug("WARN: No percentage false specified for random boolean generation. Using 0.5.");
  572. }
  573. ret = Math.random() > percent;
  574. tdebug("Calculated random bool with false percentage", percent, "Result:", ret);
  575. return ret;
  576. },
  577. isAccurate = () => {
  578. let acc = Math.random() < accuracy;
  579. tdebug("Calculated isAccurate", acc);
  580. return acc;
  581. },
  582. generateTypeDecision = offset => {
  583. /*
  584. This is the core AI behind UltraType.
  585. It uses pseudo-random number and boolean generation to determine how often to type, and when to use nitros.
  586. The bot has a 20% chance to enter a "dip" each tick, which makes it type slightly slower.
  587. */
  588. if(isStopped) return;
  589. setTimeout(() => {
  590. let dipRate = 0.80;
  591. let WRONG = false;
  592. timeout = tgen(12000 / wordsPerMinute);
  593. if (inDip) {
  594. // Re adjust the timeout
  595. dipRate = 0.40;
  596. timeout = tgen(12000 / wordsPerMinute);
  597. }
  598. if (enabled) {
  599. if (!isAccurate()) {
  600. WRONG = true;
  601. type(49);
  602. generateTypeDecision(timeout + 50);
  603. } else {
  604. type(lesson.charCodeAt(i));
  605. }
  606. if (!WRONG) {
  607. i++;
  608. if (i < lesson.length) {
  609. generateTypeDecision(timeout);
  610. }
  611. }
  612. if (autoNitro) {
  613. if (randomBool(0.999)) { // Theres a 0.1% chance that a nitro is used mid race during a tick
  614. tdebug("Using a mid race nitro");
  615. useNitro();
  616. }
  617. }
  618. }
  619. timeoutToggle = !timeoutToggle;
  620. inDip = randomBool(dipRate);
  621. tdebug("Generated typing decision with offset", offset);
  622. if (apie.onType) {
  623. apie.onType({
  624. charTyped: lesson.charCodeAt(i),
  625. isWrong: WRONG
  626. });
  627. }
  628. }, offset);
  629. },
  630. lessonLoad = () => {
  631. debug("The prerendered lesson has been captured and loaded. Starting in " + (LOAD_TIME / 1000) + " seconds.");
  632. if (!isStopped) {
  633. infoSpan.innerHTML = "Starting...";
  634. infoSpan.style.color = "#00b300";
  635. }
  636. setTimeout(() => {
  637. if (!isStopped) {
  638. infoSpan.innerHTML = "Started!";
  639. infoSpan.style.color = "#33ff33";
  640. }
  641. lessonLoaded = true;
  642. startTime = new Date();
  643. if (lesson.length > 1) {
  644. generateTypeDecision();
  645. debug("Started the bot!");
  646. if (autoTurbo) {
  647. setTimeout(() => {
  648. debug("Using auto turbo");
  649. turbo();
  650. }, 750);
  651. }
  652. } else {
  653. debug("The lesson is malformed! Lesson:", ('"' + lesson + '"'));
  654. return;
  655. }
  656. if (apie.onRaceStart) {
  657. apie.onRaceStart(startTime, lesson);
  658. }
  659. }, LOAD_TIME);
  660. },
  661. respawn = () => {
  662. debug("respawn() called - refreshing in a few seconds.");
  663. setTimeout(location.reload.bind(location),
  664. gen(750, 1100));
  665. },
  666. removeUITrash = () => {
  667. // Remove some garbage on the UI
  668. debug("Cleaning up the original UI...");
  669. try {
  670. rm('settings-button');
  671. rm('app-footer', 1);
  672. rm('tooltip-hover', 1);
  673. } catch (e) {
  674. debug("Issue removing UI trash", e);
  675. }
  676. },
  677. onfinish = callback => {
  678. setInterval(() => {
  679. let deadDivs = document.getElementsByClassName('popup race-results'),
  680. banner = document.getElementsByClassName('banner'),
  681. errorDivs = document.getElementsByClassName('popup popup-race-error');
  682. if (
  683. (deadDivs && deadDivs.length > 0) ||
  684. (disqualified) ||
  685. (banner && banner.length > 0) ||
  686. (errorDivs && errorDivs.length > 0)
  687. ) {
  688. if (finished == false) {
  689. finished = true;
  690. debug("Firing onfinish callback in 100ms.");
  691. setTimeout(callback.bind(this), 100);
  692. }
  693. }
  694. }, 300);
  695. },
  696. createUI = body => {
  697. if (isStopped) {
  698. return;
  699. }
  700. toggled = false;
  701. let isDragging = false;
  702. let UIopacity = 0.7;
  703. let doc = document.querySelector('html');
  704. let inner = document.querySelector('.wrap');
  705. body.appendChild(injectedRoot);
  706. let UI = document.createElement('div');
  707. $(root).append(FONT);
  708. Object.defineProperty(UI, 'shadowRoot', {
  709. get: () => {
  710. return null;
  711. },
  712. enumerable: false
  713. });
  714. Object.defineProperty(injectedRoot, 'shadowRoot', {
  715. get: () => {
  716. return null;
  717. },
  718. enumerable: false
  719. });
  720. Object.defineProperty(root, 'shadowRoot', {
  721. get: () => {
  722. return null;
  723. },
  724. enumerable: false
  725. });
  726. UI.style.zIndex = 999999;
  727. UI.id = "botUI";
  728. UI.style.position = "fixed";
  729. UI.style.top = "3%";
  730. UI.style.left = "3%";
  731. UI.style.color = "white";
  732. UI.style.borderStyle = "solid";
  733. UI.style.borderColor = "#000066";
  734. UI.style.borderWidth = "6px";
  735. UI.style.borderRadius = "7px";
  736. UI.style.padding = "10px";
  737. UI.style.backgroundColor = "black";
  738. UI.style.textAlign = "center";
  739. UI.style.opacity = UIopacity;
  740. UI.style.transition = "opacity 500ms, border 500ms, border-color 500ms";
  741. UI.style.fontFamily = "'Ubuntu', sans-serif";
  742. UI.onmouseover = () => {
  743. UIopacity = 1;
  744. UI.style.opacity = UIopacity;
  745. }
  746. UI.onmouseleave = () => {
  747. UIopacity = 0.7;
  748. UI.style.opacity = UIopacity;
  749. }
  750. let outerTitle = document.createElement('center');
  751. let title = document.createElement('p');
  752. title.style.fontSize = "135%";
  753. title.innerHTML = "<strong>L_0R3NZ0 Type Bot!</strong>";
  754. title.style.cursor = 'pointer';
  755. title.onclick = () => {
  756. window.open(EXT_URL,'_blank');
  757. }
  758. UI.style.fontSize = "135%";
  759. outerTitle.appendChild(title);
  760. UI.appendChild(outerTitle);
  761. let outerInfo = document.createElement('center');
  762. info = document.createElement('p');
  763. infoSpan = document.createElement('span');
  764. infoSpan.innerHTML = "Idle.";
  765. infoSpan.style.color = "#b3b3b3";
  766. infoSpan.style.transition = "color 500ms";
  767. info.style.fontSize = "100%";
  768. info.innerHTML += "Status: ";
  769. info.appendChild(infoSpan);
  770. outerInfo.appendChild(info);
  771. UI.appendChild(outerInfo);
  772. let outerEnable = document.createElement('center');
  773. let enableButton = document.createElement('button');
  774. enableButton.className = "";
  775. enableButton.style.backgroundColor = "transparent";
  776. enableButton.style.border = "3px solid";
  777. enableButton.style.borderRadius = "3px";
  778. enableButton.style.fontSize = "125%";
  779. enableButton.style.borderColor = "#808080";
  780. enableButton.style.color = "#808080";
  781. enableButton.style.transition = "border 500ms, border-color 500ms, color 500ms";
  782. enableButton.innerHTML = "Customize";
  783. enableButton.onclick = () => {
  784. if (!optOn) {
  785. optOn = true;
  786. opt.style.opacity = 0.95;
  787. opt.style.pointerEvents = "all";
  788. opt.focus();
  789. } else {
  790. return;
  791. }
  792. }
  793. _.listen.apply(enableButton, ["mouseover", () => {
  794. enableButton.style.color = "white";
  795. enableButton.style.borderColor = "white";
  796. }, true]);
  797. _.listen.apply(enableButton, ["mouseout", () => {
  798. enableButton.style.color = "#808080";
  799. enableButton.style.borderColor = "#808080";
  800. }, true]);
  801. outerEnable.appendChild(enableButton);
  802. UI.appendChild(outerEnable);
  803. let outerTurbo = document.createElement('center');
  804. let turboBtn = document.createElement('button');
  805. turboBtn.className = "";
  806. turboBtn.style.backgroundColor = "transparent";
  807. turboBtn.style.border = "3px solid";
  808. turboBtn.style.borderRadius = "3px";
  809. turboBtn.style.fontSize = "125%";
  810. turboBtn.style.borderColor = "#ff1a1a";
  811. turboBtn.style.color = "#ff1a1a";
  812. turboBtn.style.transition = "border 500ms, border-color 500ms, color 500ms";
  813. turboBtn.innerHTML = "Turbo";
  814. turboBtn.onclick = () => {
  815. turboBtn.style.color = "#660000";
  816. turboBtn.style.borderColor = "#660000";
  817. if (!firstTurbo) {
  818. firstTurbo = true;
  819. if (localStorage["turboAlert"]) {
  820. try {
  821. turbo();
  822. } catch(e) {
  823. debug("WARN: Couldn't turbo", e);
  824. };
  825. } else {
  826. alert("WARNING: Turbo Can Get You Banned!\nThis message will not be displayed again.");
  827. localStorage["turboAlert"] = 1;
  828. try {
  829. turbo();
  830. } catch(e) {
  831. debug("WARN: Couldn't turbo", e);
  832. };
  833. }
  834. }
  835. }
  836. UI.appendChild(document.createElement('br'));
  837. outerTurbo.appendChild(turboBtn);
  838. UI.appendChild(outerTurbo);
  839. UI.appendChild(document.createElement('br'));
  840. statsDiv = document.createElement('center');
  841. statsDiv.innerHTML = 'Stats are loading...';
  842. statsDiv.style.color = 'grey';
  843. statsDiv.style.display = 'none';
  844. UI.appendChild(statsDiv);
  845. UI.appendChild(document.createElement('br'));
  846. function moveUI(e) {
  847. UI.style.top = (e.clientY - (e.clientY - UI.style.top)) + 'px';
  848. UI.style.left = (e.clientX - (e.clientX - UI.style.left)) + 'px';
  849. }
  850. _.listen.apply(window, ['keydown', e => {
  851. if (e.keyCode == 27) {
  852. toggled = !toggled;
  853. if (toggled) {
  854. UI.style.opacity = 0;
  855. g.style.opacity = 0;
  856. UI.style.pointerEvents = "none";
  857. g.style.pointerEvents = "none";
  858. } else {
  859. UI.style.opacity = UIopacity;
  860. if (localStorage['chartOn']) g.style.opacity = UIopacity;
  861. UI.style.pointerEvents = "auto";
  862. if (localStorage['chartOn']) g.style.pointerEvents = "auto";
  863. else g.style.pointerEvents = "none";
  864. }
  865. }
  866. }]);
  867. _.listen.apply(window, ['mouseup', e => {
  868. isDragging = false;
  869. UI.style.opacity = UIopacity;
  870. UI.style.borderColor = "#000066";
  871. e.preventDefault();
  872. _.unlisten.apply(window, ['mousemove', moveUI, true]);
  873. }, false]);
  874. root.appendChild(UI);
  875. detectWebGL();
  876. createOptsMenu();
  877. if (apie.onReady) {
  878. apie.onReady();
  879. }
  880. },
  881. initChart = () => {
  882. if (!document.body) {
  883. let _initChart = initChart.bind(this);
  884. setTimeout(_initChart, 300);
  885. return;
  886. }
  887. g.style.zIndex = 9999;
  888. g.style.backgroundColor = "#000";
  889. g.style.fontFamily = "Ubuntu";
  890. g.style.position = "fixed";
  891. g.style.bottom = "5%";
  892. g.style.right = "5%";
  893. g.style.fontSize = "125%";
  894. g.style.color = "white";
  895. g.style.opacity = 0.7;
  896. g.style.padding = "10px";
  897. g.style.border = "6px solid";
  898. g.style.borderColor = "#000066";
  899. g.style.borderRadius = "7px";
  900. g.style.width = "40%";
  901. g.style.height = "25%";
  902. g.style.transition = "opacity 500ms, border 500ms, border-color 500ms";
  903. Highcharts.chart(g, {
  904. chart: {
  905. backgroundColor: {
  906. linearGradient: [0, 0, 500, 500],
  907. stops: [
  908. [0, 'rgb(0, 0, 0)'],
  909. [1, 'rgb(0, 0, 0)']
  910. ]
  911. },
  912. style: {
  913. color: "#fff",
  914. fontFamily: "Ubuntu"
  915. }
  916. },
  917. title: {
  918. text: "Speed",
  919. x: -20,
  920. style: {
  921. color: "#fff",
  922. fontFamily: "Ubuntu"
  923. }
  924. },
  925. tooltip: {
  926. valueSuffix: ' WPM',
  927. },
  928. xAxis: {
  929. gridLineWidth: 0,
  930. categories: [
  931. //
  932. ],
  933. labels: {
  934. style: {
  935. color: '#FFF',
  936. font: 'Ubuntu'
  937. }
  938. }
  939. },
  940. yAxis: {
  941. gridLineWidth: 0,
  942. title: {
  943. text: "WPM"
  944. },
  945. plotLines: [{
  946. value: 0,
  947. width: 1,
  948. color: '#ff0000'
  949. }],
  950. labels: {
  951. style: {
  952. color: '#FFF',
  953. font: 'Ubuntu'
  954. }
  955. }
  956. },
  957. legend: {
  958. layout: 'vertical',
  959. align: 'right',
  960. verticalAlign: 'middle',
  961. borderWidth: 0,
  962. style: {
  963. color: "#fff"
  964. }
  965. },
  966. plotOptions: {
  967. line: {
  968. marker: {
  969. enabled: false
  970. }
  971. }
  972. },
  973. series: [{
  974. name: 'Speed in WPM',
  975. data: points,
  976. color: '#000066'
  977. }]
  978. });
  979. chart = Highcharts.charts[0];
  980. _.listen.apply(g, ['mouseover', () => {
  981. if (localStorage['chartOn']) g.style.opacity = 1;
  982. if (localStorage['chartOn']) g.style.borderColor = "#0000ff";
  983. }, true]);
  984. _.listen.apply(g, ['mouseout', () => {
  985. if (localStorage['chartOn']) g.style.opacity = 0.7;
  986. if (localStorage['chartOn']) g.style.borderColor = "#000066";
  987. }, true]);
  988. addGraph(g);
  989. setTimeout(() => {
  990. let cr = g.getElementsByClassName('highcharts-credits');
  991. for (let i = 0; i < cr.length; i++) {
  992. cr[i].remove();
  993. }
  994. }, 500);
  995. if (!localStorage['chartOn']) {
  996. g.style.opacity = 0;
  997. }
  998. },
  999. createOptsMenu = () => {
  1000. opt = document.createElement('div');
  1001. opt.style.zIndex = 99999999;
  1002. opt.style.backgroundColor = "#000";
  1003. opt.style.border = "6px solid";
  1004. opt.style.borderColor = "#000066";
  1005. opt.style.borderRadius = "6px";
  1006. opt.style.fontSize = "150%";
  1007. opt.style.color = "#FFF";
  1008. opt.style.position = "fixed";
  1009. opt.style.padding = "10px";
  1010. opt.style.top = "50%";
  1011. opt.style.left = "50%";
  1012. opt.style.display = "inline-block";
  1013. opt.style.fontFamily = "Ubuntu";
  1014. opt.style.transform = "translate(-50%, -50%)";
  1015. opt.style.transition = "opacity 500ms, border 500ms, border-color 500ms";
  1016. opt.style.opacity = 0;
  1017. opt.style.pointerEvents = "none";
  1018. let inner = document.createElement('center');
  1019. let lbl = document.createElement('h1');
  1020. lbl.style.fontSize = "150%";
  1021. lbl.innerHTML = "Customize L_0R3NZ0 TypeBot";
  1022. inner.appendChild(lbl);
  1023. let outerBotOn = document.createElement('div');
  1024. let botOnBtn = document.createElement('button');
  1025. botOnBtn.className = "";
  1026. botOnBtn.style.backgroundColor = "transparent";
  1027. botOnBtn.style.border = "3px solid";
  1028. botOnBtn.style.borderRadius = "3px";
  1029. botOnBtn.style.fontSize = "100%";
  1030. botOnBtn.style.borderColor = "LimeGreen";
  1031. botOnBtn.style.color = "LimeGreen";
  1032. botOnBtn.style.transition = "border 500ms, border-color 500ms, color 500ms";
  1033. botOnBtn.innerHTML = "On";
  1034. botOnBtn.onclick = () => {
  1035. enabled = !enabled;
  1036. if (!enabled) {
  1037. botOnBtn.style.borderColor = "red";
  1038. botOnBtn.style.color = "red";
  1039. botOnBtn.innerHTML = "Off";
  1040. } else {
  1041. botOnBtn.style.borderColor = "LimeGreen";
  1042. botOnBtn.style.color = "LimeGreen";
  1043. botOnBtn.innerHTML = "On";
  1044. }
  1045. }
  1046. outerBotOn.innerHTML += "Bot enabled: ";
  1047. outerBotOn.appendChild(botOnBtn);
  1048. inner.appendChild(outerBotOn);
  1049. let outerToggle = document.createElement('div');
  1050. let toggleButton = document.createElement('button');
  1051. toggleButton.className = "";
  1052. toggleButton.style.backgroundColor = "transparent";
  1053. toggleButton.style.border = "3px solid";
  1054. toggleButton.style.borderRadius = "3px";
  1055. toggleButton.style.fontSize = "100%";
  1056. toggleButton.style.transition = "border 500ms, border-color 500ms, color 500ms";
  1057. if (autoRefresh) {
  1058. toggleButton.style.borderColor = "LimeGreen";
  1059. toggleButton.style.color = "LimeGreen";
  1060. toggleButton.innerHTML = "On";
  1061. } else {
  1062. toggleButton.style.borderColor = "red";
  1063. toggleButton.style.color = "red";
  1064. toggleButton.innerHTML = "Off";
  1065. }
  1066. toggleButton.onclick = () => {
  1067. autoRefresh = !autoRefresh;
  1068. setLocalStorage('autoRefresh', autoRefresh);
  1069. if (!autoRefresh) {
  1070. toggleButton.style.borderColor = "red";
  1071. toggleButton.style.color = "red";
  1072. toggleButton.innerHTML = "Off";
  1073. } else {
  1074. toggleButton.style.borderColor = "LimeGreen";
  1075. toggleButton.style.color = "LimeGreen";
  1076. toggleButton.innerHTML = "On";
  1077. }
  1078. }
  1079. outerToggle.innerHTML += "Auto Refresh: ";
  1080. outerToggle.appendChild(toggleButton);
  1081. inner.appendChild(outerToggle);
  1082. let outerNtr = document.createElement('div');
  1083. autoNitroBtn = document.createElement('button');
  1084. autoNitroBtn.className = "";
  1085. autoNitroBtn.style.backgroundColor = "transparent";
  1086. autoNitroBtn.style.border = "3px solid";
  1087. autoNitroBtn.style.borderRadius = "3px";
  1088. autoNitroBtn.style.fontSize = "100%";
  1089. autoNitroBtn.style.transition = "border 500ms, border-color 500ms, color 500ms";
  1090. if (autoNitro) {
  1091. autoNitroBtn.style.borderColor = "LimeGreen";
  1092. autoNitroBtn.style.color = "LimeGreen";
  1093. autoNitroBtn.innerHTML = "On";
  1094. } else {
  1095. autoNitroBtn.style.borderColor = "red";
  1096. autoNitroBtn.style.color = "red";
  1097. autoNitroBtn.innerHTML = "Off";
  1098. }
  1099. autoNitroBtn.onclick = () => {
  1100. autoNitro ? autoNitroOn() : autoNitroOff();
  1101. }
  1102. outerNtr.innerHTML += "Auto Nitro: ";
  1103. outerNtr.appendChild(autoNitroBtn);
  1104. inner.appendChild(outerNtr);
  1105. let outerChrtBtn = document.createElement('div');
  1106. let chartBtn = document.createElement('button');
  1107. chartBtn.className = "";
  1108. chartBtn.style.backgroundColor = "transparent";
  1109. chartBtn.style.border = "3px solid";
  1110. chartBtn.style.borderRadius = "3px";
  1111. chartBtn.style.fontSize = "100%";
  1112. chartBtn.style.transition = "border 500ms, border-color 500ms, color 500ms";
  1113. if (localStorage['chartOn']) {
  1114. chartBtn.style.borderColor = "LimeGreen";
  1115. chartBtn.style.color = "LimeGreen";
  1116. chartBtn.innerHTML = "On";
  1117. } else {
  1118. chartBtn.style.borderColor = "red";
  1119. chartBtn.style.color = "red";
  1120. chartBtn.innerHTML = "Off";
  1121. }
  1122. chartBtn.onclick = () => {
  1123. if (localStorage['chartOn']) {
  1124. delete localStorage['chartOn'];
  1125. chartBtn.style.borderColor = "red";
  1126. chartBtn.style.color = "red";
  1127. chartBtn.innerHTML = "Off";
  1128. } else {
  1129. localStorage['chartOn'] = 1;
  1130. chartBtn.style.borderColor = "LimeGreen";
  1131. chartBtn.style.color = "LimeGreen";
  1132. chartBtn.innerHTML = "On";
  1133. g.style.opacity = 0.7;
  1134. }
  1135. }
  1136. outerChrtBtn.innerHTML += "Speed chart: ";
  1137. outerChrtBtn.appendChild(chartBtn);
  1138. inner.appendChild(outerChrtBtn);
  1139. let outerACfg = document.createElement('div');
  1140. acc = document.createElement('input');
  1141. acc.type = "number";
  1142. acc.min = 10;
  1143. acc.max = 100;
  1144. acc.value = accuracy * 100;
  1145. acc.className = "";
  1146. acc.style.backgroundColor = "transparent";
  1147. acc.style.border = "3px solid";
  1148. acc.style.borderRadius = "3px";
  1149. acc.style.fontSize = "100%";
  1150. acc.style.borderColor = "LimeGreen";
  1151. acc.style.color = "LimeGreen";
  1152. acc.style.transition = "border 500ms, border-color 500ms, color 500ms";
  1153. acc.onchange = () => {
  1154. accuracy = parseInt(acc.value);
  1155. if (isNaN(accuracy)) {
  1156. accuracy = 0.98;
  1157. acc.value = 98;
  1158. } else {
  1159. accuracy *= 0.01;
  1160. }
  1161. setLocalStorage('accuracy', accuracy);
  1162. }
  1163. outerACfg.innerHTML += "Accuracy %: ";
  1164. outerACfg.appendChild(acc);
  1165. inner.appendChild(outerACfg);
  1166. let oWPMCfg = document.createElement('div');
  1167. wpm = document.createElement('input');
  1168. wpm.type = "number";
  1169. wpm.min = 3;
  1170. wpm.max = MAX_WPM; // About the fastest you can go without any bans
  1171. wpm.value = wordsPerMinute;
  1172. wpm.className = "";
  1173. wpm.style.backgroundColor = "transparent";
  1174. wpm.style.border = "3px solid";
  1175. wpm.style.borderRadius = "3px";
  1176. wpm.style.fontSize = "100%";
  1177. wpm.style.borderColor = "LimeGreen";
  1178. wpm.style.color = "LimeGreen";
  1179. wpm.style.transition = "border 500ms, border-color 500ms, color 500ms";
  1180. wpm.onchange = () => {
  1181. if (localStorage["speedChange"]) {
  1182. wordsPerMinute = parseInt(wpm.value);
  1183. if (wordsPerMinute > 800) {
  1184. alert('WARNING: You WILL be banned if you set your WPM above 200.');
  1185. }
  1186. if (isNaN(wordsPerMinute))
  1187. wpm.value = 900;
  1188. setWPM(wpm.value);
  1189. } else {
  1190. // alert('It is not recommended to alter the default speed of UltraType, be careful! This message will not be shown again.');
  1191. setLocalStorage('speedChange', true);
  1192. }
  1193. }
  1194. oWPMCfg.innerHTML += "WPM: ";
  1195. oWPMCfg.appendChild(wpm);
  1196. inner.appendChild(oWPMCfg);
  1197. let outerStatTogg = document.createElement('div');
  1198. statTogg = document.createElement('button');
  1199. statTogg.className = "";
  1200. statTogg.style.backgroundColor = "transparent";
  1201. statTogg.style.border = "3px solid";
  1202. statTogg.style.borderRadius = "3px";
  1203. statTogg.style.fontSize = "100%";
  1204. statTogg.style.borderColor = "LimeGreen";
  1205. statTogg.style.color = "LimeGreen";
  1206. statTogg.style.transition = "border 500ms, border-color 500ms, color 500ms";
  1207. statTogg.innerHTML = "On";
  1208. statTogg.onclick = () => {
  1209. statsOn = !statsOn;
  1210. if (statsOn) {
  1211. statTogg.style.borderColor = "LimeGreen";
  1212. statTogg.style.color = "LimeGreen";
  1213. statTogg.innerHTML = "On";
  1214. updateStats();
  1215. } else {
  1216. statTogg.style.borderColor = "red";
  1217. statTogg.style.color = "red";
  1218. statTogg.innerHTML = "Off";
  1219. disableStats();
  1220. }
  1221. setLocalStorage('statsOn', statsOn);
  1222. }
  1223. outerStatTogg.innerHTML = "User Stats: ";
  1224. outerStatTogg.appendChild(statTogg);
  1225. inner.appendChild(outerStatTogg);
  1226. let outerAutoT = document.createElement('div');
  1227. let autoT = document.createElement('button');
  1228. autoT.className = "";
  1229. autoT.style.backgroundColor = "transparent";
  1230. autoT.style.border = "3px solid";
  1231. autoT.style.borderRadius = "3px";
  1232. autoT.style.fontSize = "100%";
  1233. autoT.style.borderColor = "LimeGreen";
  1234. autoT.style.color = "LimeGreen";
  1235. autoT.style.transition = "border 500ms, border-color 500ms, color 500ms";
  1236. autoT.innerHTML = "On";
  1237. autoT.onclick = () => {
  1238. if (!autoTurbo) {
  1239. autoT.style.borderColor = "LimeGreen";
  1240. autoT.style.color = "LimeGreen";
  1241. autoT.innerHTML = "On";
  1242. autoTurboOn();
  1243. } else {
  1244. autoT.style.borderColor = "red";
  1245. autoT.style.color = "red";
  1246. autoT.innerHTML = "Off";
  1247. autoTurboOff();
  1248. }
  1249. }
  1250. // Set the default button state
  1251. if (autoTurbo) {
  1252. autoT.style.borderColor = "LimeGreen";
  1253. autoT.style.color = "LimeGreen";
  1254. autoT.innerHTML = "On";
  1255. } else {
  1256. autoT.style.borderColor = "red";
  1257. autoT.style.color = "red";
  1258. autoT.innerHTML = "Off";
  1259. }
  1260. outerAutoT.innerHTML = "Auto Turbo: ";
  1261. outerAutoT.appendChild(autoT);
  1262. inner.appendChild(outerAutoT);
  1263. let tips = document.createElement('p');
  1264. tips.innerHTML = "Press escape to hide all of the L_0R3NZ0 Type.<br>";
  1265. inner.appendChild(tips);
  1266. let outerExitBtn = document.createElement('center');
  1267. let exitButton = document.createElement('button');
  1268. exitButton.className = "";
  1269. exitButton.style.borderColor = "#808080";
  1270. exitButton.style.color = "#808080";
  1271. exitButton.style.fontSize = "175%";
  1272. exitButton.style.border = "3px solid";
  1273. exitButton.style.borderRadius = "3px";
  1274. exitButton.style.backgroundColor = "transparent";
  1275. exitButton.style.transition = "border 500ms, border-color 500ms, color 500ms";
  1276. _.listen.apply(exitButton, ["mouseover", () => {
  1277. exitButton.style.color = "#FFF";
  1278. exitButton.style.borderColor = "#FFF";
  1279. }, true]);
  1280. _.listen.apply(exitButton, ["mouseout", () => {
  1281. exitButton.style.color = "#808080";
  1282. exitButton.style.borderColor = "#808080";
  1283. }, true]);
  1284. exitButton.innerHTML = "Exit";
  1285. exitButton.onclick = () => {
  1286. opt.style.opacity = 0;
  1287. opt.style.pointerEvents = "none";
  1288. optOn = false;
  1289. opt.blur();
  1290. }
  1291. outerExitBtn.appendChild(exitButton);
  1292. inner.appendChild(outerExitBtn);
  1293. opt.appendChild(inner);
  1294. root.appendChild(opt);
  1295. setTimeout(() => {
  1296. let localAutoRefresh = localStorage['autoRefresh'],
  1297. localAccuracy = localStorage['accuracy'],
  1298. localWPM = localStorage['wpm'],
  1299. localAutoNitro = localStorage['autoNitro'];
  1300. if (localAutoNitro !== null && localAutoNitro !== undefined) {
  1301. localAutoNitro = JSON.parse(localAutoNitro);
  1302. if (localAutoNitro == false) {
  1303. autoNitroOff();
  1304. } else {
  1305. autoNitroOn();
  1306. }
  1307. }
  1308. if (localAutoRefresh) {
  1309. autoRefresh = JSON.parse(localAutoRefresh);
  1310. if (!autoRefresh) {
  1311. toggleButton.style.borderColor = "red";
  1312. toggleButton.style.color = "red";
  1313. toggleButton.innerHTML = "Off";
  1314. } else {
  1315. toggleButton.style.borderColor = "LimeGreen";
  1316. toggleButton.style.color = "LimeGreen";
  1317. toggleButton.innerHTML = "On";
  1318. }
  1319. }
  1320. if (localAccuracy) {
  1321. accuracy = parseFloat(localAccuracy);
  1322. acc.value = accuracy * 100;
  1323. }
  1324. if (localWPM) {
  1325. wpm.value = localWPM;
  1326. wordsPerMinute = parseInt(localWPM);
  1327. setWPM(wordsPerMinute);
  1328. }
  1329. if (statsOn) {
  1330. statTogg.style.borderColor = "LimeGreen";
  1331. statTogg.style.color = "LimeGreen";
  1332. statTogg.innerHTML = "On";
  1333. updateStats();
  1334. } else {
  1335. statTogg.style.borderColor = "red";
  1336. statTogg.style.color = "red";
  1337. statTogg.innerHTML = "Off";
  1338. disableStats();
  1339. }
  1340. }, 1000);
  1341. },
  1342. blockAd = ad => {
  1343. try {
  1344. ad.style.display = "none";
  1345. } catch (e) {
  1346. ad.src = "about:blank";
  1347. }
  1348. try {
  1349. ad.parentElement.parentElement.parentElement.remove();
  1350. } catch (e) {};
  1351. },
  1352. changeTip = node => {
  1353. setTimeout(() => {
  1354. node.style.fontSize = "125%";
  1355. node.style.border = "3px solid #000066";
  1356. node.style.borderRadius = "7px";
  1357. node.style.opacity = 0.7;
  1358. node.style.pointerEvents = "none";
  1359. node.innerHTML = "";
  1360. node.innerHTML += FONT;
  1361. node.innerHTML += '<center style="font-family:Ubuntu;">Michal is not gay like you.<br>Version: ' + VERSION + '</center>';
  1362. }, 1000);
  1363. },
  1364. detectWebGL = () => {
  1365. if (document.cookie.includes('webgl')) {
  1366. document.cookie = document.cookie.replace('webgl', 'canvas');
  1367. }
  1368. },
  1369. handleScript = scr => {
  1370. if (scr.src.includes('race-lib')) {
  1371. scr.addEventListener('load', () => {
  1372. _set = PIXI.BitmapText.prototype.setText;
  1373. let tos = __.toStr;
  1374. PIXI.BitmapText.prototype.setText = function() {
  1375. let txt = arguments[0];
  1376. if (lessonLoaded) {
  1377. let t = parseInt(txt);
  1378. if ((t !== 0) && (t > 5)) {
  1379. points.push(t);
  1380. chart.series[0].setData(points, true);
  1381. }
  1382. }
  1383. _set.apply(this, arguments);
  1384. }
  1385. });
  1386. } else if (scr.src.includes('libs')) {
  1387. if (hasScrLoaded) return;
  1388. else hasScrLoaded = 1;
  1389. scr.addEventListener('load', () => {
  1390. let didGetHandler = false;
  1391. _attachHandler = $.fn.constructor.prototype.keypress;
  1392. $.fn.constructor.prototype.keypress = function() {
  1393. if (this && this[0] && this[0] == document.body) {
  1394. let handler = arguments[0];
  1395. keyPressHandler = handler;
  1396. // debug("Intercepted jQuery keypress handler:", handler);
  1397. }
  1398. return _attachHandler.apply(this, arguments);
  1399. }
  1400. });
  1401. } else if (scr.src.includes('app.min.')) {
  1402. scr.addEventListener('load', () => {
  1403. setTimeout(() => {
  1404. let udata = ROT47(localStorage['A=2J6C']);
  1405. try {
  1406. udata = JSON.parse(udata);
  1407. } catch (e) {
  1408. return;
  1409. }
  1410. // udata.websocketSupport = true;
  1411. udata = ROT47(JSON.stringify(udata));
  1412. localStorage['A=2J6C'] = udata;
  1413. }, 100);
  1414. });
  1415. }
  1416. }
  1417. console.warn = function() {
  1418. if (arguments[0] == "You have been disqualified") {
  1419. disqualified = true;
  1420. }
  1421. console.log.apply(this, arguments);
  1422. }
  1423. __.fill = function() {
  1424. handleFillText(arguments);
  1425. _.fill.apply(this, arguments);
  1426. }
  1427. let _set = null,
  1428. _send = WebSocket.prototype.send;
  1429. WebSocket.prototype.send = function() {
  1430. if (typeof arguments[0] !== 'string') {
  1431. return _send.apply(this, arguments);
  1432. }
  1433. let msg = arguments[0],
  1434. header = msg[0],
  1435. obj = null;
  1436. msg = msg.substr(1, msg.length);
  1437. try {
  1438. obj = JSON.parse(msg);
  1439. } catch(e) {
  1440. return _send.apply(this, arguments);;
  1441. }
  1442. if (obj && obj.payload && obj.payload.a) {
  1443. debug("very naughty packet detected, lets fix that");
  1444. delete obj.payload.a;
  1445. // Replace packet
  1446. arguments[0] = header + JSON.stringify(obj);
  1447. }
  1448. return _send.apply(this, arguments);
  1449. }
  1450. onfinish(() => {
  1451. debug("Race has finished. Doing a ban check and reloading if needed.");
  1452. if (apie.onRaceFinish) {
  1453. apie.onRaceFinish();
  1454. }
  1455. endTime = new Date();
  1456. infoSpan.innerHTML = "Finished";
  1457. infoSpan.style.color = "#b3b3b3";
  1458. if (localStorage['autoRefresh']) {
  1459. debug("Auto refresh is enabled");
  1460. respawn();
  1461. } else {
  1462. debug("Auto refresh is disabled");
  1463. }
  1464. });
  1465. XMLHttpRequest.prototype.send = function() {
  1466. let payload = arguments[0];
  1467. let header = '';
  1468. if (payload && payload.length > 4 && payload[4] == '{') {
  1469. let obj;
  1470. header = payload.substr(0, 4);
  1471. try {
  1472. obj = JSON.parse(payload.substr(4, payload.length));
  1473. } catch(e) {
  1474. return _.xsend.apply(this, arguments);
  1475. }
  1476. if (obj.payload && obj.payload.a) {
  1477. // Remove cheater flag from outgoing packet
  1478. delete obj.payload.a;
  1479. arguments[0] = header + JSON.stringify(obj);
  1480. }
  1481. }
  1482. return _.xsend.apply(this, arguments);
  1483. }
  1484. XMLHttpRequest.prototype.open = function() {
  1485. if (arguments[1].includes('/api/error')) {
  1486. errorRequests.push(this);
  1487. this.abort();
  1488. return;
  1489. } else if (arguments[1].includes('problem-keys')) {
  1490. if (PROBLEM_KEYS_DEBUG) {
  1491. console.warn('PROBLEM_KEYS_DEBUG is enabled, firing up debugger.');
  1492. debugger;
  1493. }
  1494. if (ABORT_PROBLEM_KEYS) {
  1495. debug("Aborting problem-keys AJAX request.");
  1496. this.abort();
  1497. return;
  1498. } else {
  1499. debug("Detected outgoing problem-keys AJAX request, but ABORT_PROBLEM_KEYS is false, so I'm letting it send.");
  1500. }
  1501. }
  1502. return _.xopen.apply(this, arguments);
  1503. }
  1504. // inject undetectable features
  1505. window.PIXI = {};
  1506. PIXI.BitmapText = function() {};
  1507. PIXI.BitmapText.prototype.setText = function(a) { this.text = a || " ", this.dirty = !0 };
  1508. let hostt = ShadowRoot.prototype.__lookupGetter__('host');
  1509. let _getToStr = Function.prototype.__lookupGetter__('toString');
  1510. let _setTxt = Element.prototype.__lookupSetter__('textContent');
  1511. let _getTitle = Document.prototype.__lookupGetter__('title');
  1512. let _setTitle = Document.prototype.__lookupSetter__('title');
  1513. CanvasRenderingContext2D.prototype.fillText = __.fill;
  1514. window.WebSocket = __ws;
  1515. Function.prototype.toString = __.toStr = function() {
  1516. if (this === Function.prototype.toString) return _.toStr.call(_.toStr);
  1517. if (this === CanvasRenderingContext2D.prototype.fillText) return _.toStr.call(_.fill);
  1518. if (this === Object.prototype.__lookupGetter__) return _.toStr.call(_.get);
  1519. if (this === ShadowRoot.prototype.__lookupGetter__('host')) return _.toStr.call(hostt);
  1520. if (this === Function.prototype.__lookupGetter__('toString')) return _.toStr.call(_getToStr);
  1521. if (this === Element.prototype.__lookupSetter__('textContent')) return _.toStr.call(_setTxt);
  1522. if (this === Document.prototype.__lookupGetter__('title')) return _.toStr.call(_getTitle);
  1523. if (this === Document.prototype.__lookupSetter__('title')) return _.toStr.call(_setTitle);
  1524. if (this === PIXI.BitmapText.prototype.setText) return _.toStr.call(_get);
  1525. if (this === console.warn) return _.toStr.call(_.warn);
  1526. if (this === WebSocket) return _.toStr.call(_.ws);
  1527. if (this === XMLHttpRequest.prototype.send) return _.toStr.call(_.xsend);
  1528. if (this === XMLHttpRequest.prototype.open) return _.toStr.call(_.xopen);
  1529. if (this === window.onerror) return _.toStr.call(_.oerr);
  1530. if (window.jQuery && this === jQuery.fn.keypress) return _.toStr.call(_attachHandler);
  1531. return _.toStr.call(this);
  1532. }
  1533. ShadowRoot.prototype.__defineGetter__('host', () => {
  1534. if (this === injectedRoot) return null;
  1535. return _.host.call(this);
  1536. });
  1537. let observer = new MutationObserver(mutations => {
  1538. mutations.forEach(mutation => {
  1539. if (mutation.type == "childList" && mutation.addedNodes.length > 0) {
  1540. for (let i in mutation.addedNodes) {
  1541. if (mutation.addedNodes[i].nodeName == "BODY") createUI(mutation.addedNodes[i]);
  1542. if (mutation.addedNodes[i].nodeName == "IFRAME") blockAd(mutation.addedNodes[i]);
  1543. if (mutation.addedNodes[i].className == "race-tip") changeTip(mutation.addedNodes[i]);
  1544. if (mutation.addedNodes[i].nodeName == "SCRIPT") handleScript(mutation.addedNodes[i]);
  1545. }
  1546. }
  1547. });
  1548. });
  1549. observer.observe(document.documentElement, {
  1550. childList: true,
  1551. subtree: true,
  1552. attributes: true,
  1553. attributeFilter: ['style']
  1554. });
  1555. let _fakeToStr = __.toStr;
  1556. _fakeToStr.__proto__ = _.toStr.prototype;
  1557. _fakeToStr.prototype = _.toStr.prototype;
  1558. Object.defineProperty(Function.prototype, 'toString', {
  1559. get: () => {
  1560. if (this === __.toStr) return _fakeToStr;
  1561. return __.toStr;
  1562. },
  1563. enumerable: false
  1564. });
  1565. localStorage.clear = function() {} // Disable localStorage clearing
  1566. Function.prototype.__defineGetter__('toString', function() {
  1567. if (this === CanvasRenderingContext2D.prototype || this === CanvasRenderingContext2D.prototype.fillText) return __.toStr;
  1568. if (this === console || this === console.warn) return __.toStr;
  1569. if (this === ShadowRoot.prototype.__lookupGetter__('host') || this === ShadowRoot.prototype) return __.toStr;
  1570. if (this === Object.prototype || this === Object.prototype.__lookupGetter__) return __.toStr;
  1571. if (this === Function.prototype.__lookupGetter__('toString')) return __.toStr;
  1572. if (this === PIXI.BitmapText.prototype.setText) return __.toStr;
  1573. if (this === WebSocket) return __.toStr;
  1574. if (this === injectedRoot) return __.toStr;
  1575. if (this === Document.prototype.__lookupGetter__('title')) return __.toStr;
  1576. if (this === Document.prototype.__lookupSetter__('title')) return __.toStr;
  1577. if (this === XMLHttpRequest.prototype.send) return __.toStr;
  1578. if (this === XMLHttpRequest.prototype.open) return __.toStr;
  1579. if (this === window.onerror) return __.toStr;
  1580. if (window.jQuery && this === jQuery.fn.keypress) return __.toStr;
  1581. return _.toStr;
  1582. });
  1583. setInterval(() => {
  1584. _setTitle.call(document, "L_0R3NZ0 Type Bot!");
  1585. }, 100);
  1586. Document.prototype.__defineGetter__('title', t => {
  1587. return _title;
  1588. });
  1589. Document.prototype.__defineSetter__('title', t => {
  1590. _title = t;
  1591. });
  1592. _.listen.apply(window, ['load', () => {
  1593. _.oerr = window.onerror;
  1594. window.onbeforeunload = () => {
  1595. return null;
  1596. };
  1597. window.ga = () => {};
  1598. window.onerror = evt => {
  1599. if (evt.includes("'visible' of undefined")) {
  1600. // Exception triggered due to turbo mode
  1601. respawn();
  1602. }
  1603. return null;
  1604. };
  1605. username = extractUserName();
  1606. userInfo = ROT47(localStorage["A=2J6C"]);
  1607. userInfo = JSON.parse(userInfo);
  1608. debug("Extracted and decrypted user info", userInfo);
  1609. if (localStorage['statsOn']) statsOn = true;
  1610. }]);
  1611. /*
  1612. window.addEventListener('DOMContentLoaded', () => {
  1613. setTimeout(removeUITrash, 75);
  1614. });
  1615. */
  1616. let registerAPIEvent = (evt, callback) => {
  1617. if (typeof callback !== 'function') {
  1618. throw new Error('Invalid event callback.');
  1619. return;
  1620. }
  1621. switch (evt) {
  1622. case "userBanned":
  1623. apie.onUserBanned = callback;
  1624. break;
  1625. case "raceStart":
  1626. apie.onRaceStart = callback;
  1627. break;
  1628. case "raceEnd":
  1629. case "raceFinish":
  1630. apie.onRaceFinish = callback;
  1631. break;
  1632. case "nitroUsed":
  1633. case "nitroUse":
  1634. case "nitro":
  1635. apie.onNitroUsed = callback;
  1636. break;
  1637. case "raceStarting":
  1638. case "raceBegin":
  1639. case "raceInit":
  1640. apie.onRaceStarting = callback;
  1641. break;
  1642. case "type":
  1643. case "typed":
  1644. case "botType":
  1645. apie.onType = callback;
  1646. break;
  1647. case "ready":
  1648. case "load":
  1649. case "loaded":
  1650. case "start":
  1651. case "started":
  1652. apie.onReady = callback;
  1653. break;
  1654. default:
  1655. throw new Error('Invalid event name!');
  1656. break;
  1657. }
  1658. return window.UltraTypeCore;
  1659. }
  1660. // Core API
  1661. let core = {
  1662. on: registerAPIEvent,
  1663. turbo: turbo,
  1664. setWPM: setWPM,
  1665. sendTypePacket: typePacket,
  1666. typeChar: type,
  1667. stopFromRunning: () => { // Stops the bot from appearing or typing
  1668. isStopped = true;
  1669. },
  1670. getDecyptedUserInfo: () => {
  1671. if (userInfo) {
  1672. return userInfo;
  1673. } else {
  1674. return null;
  1675. }
  1676. },
  1677. setAutoTurbo: state => {
  1678. if (state === false) {
  1679. autoTurboOff();
  1680. } else if (state === true) {
  1681. autoTurboOn();
  1682. } else {
  1683. throw new Error('Invalid auto turbo state.');
  1684. }
  1685. },
  1686. getBotStateRaw: getBotState,
  1687. getBotState: () => {
  1688. return {
  1689. nitrosUsed: nitrosUsed,
  1690. lesson: lesson,
  1691. currWord: index,
  1692. wpm: wordsPerMinute,
  1693. acc: accuracy,
  1694. errReqs: errorRequests.length,
  1695. uinfo: JSON.stringify(userInfo),
  1696. fillsY: fillsY.length,
  1697. version: VERSION,
  1698. wpmHistory: points,
  1699. isFinished: finished,
  1700. startTime: startTime,
  1701. endTime: endTime
  1702. };
  1703. },
  1704. toggleDebug: () => {
  1705. LOG_DEBUG = !LOG_DEBUG;
  1706. },
  1707. getLesson: () => {
  1708. if (lesson) {
  1709. return lesson;
  1710. } else return null;
  1711. },
  1712. setAutoRefresh: val => {
  1713. if (typeof val !== 'boolean') {
  1714. throw new Error('Can only set auto refresh to a boolean.');
  1715. return;
  1716. } else {
  1717. autoRefresh = val;
  1718. }
  1719. },
  1720. getNitrosUsed: () => { return nitrosUsed || 0 },
  1721. toggleBotLog: () => {
  1722. LOG_TYPING_INFO = !LOG_TYPING_INFO;
  1723. },
  1724. disableStats: disableStats,
  1725. randBool: randomBool,
  1726. updateStats: updateStats,
  1727. useNitro: useNitro,
  1728. flushRaw: () => {
  1729. // Reset UltraType to it's default settings
  1730. [
  1731. 'accuracy',
  1732. 'autoRefresh',
  1733. 'autoTurbo',
  1734. 'statsOn',
  1735. 'autoNitro',
  1736. 'wpm',
  1737. 'chartOn',
  1738. 'speedChange'
  1739. ].forEach(k => {
  1740. delete localStorage[k];
  1741. });
  1742. },
  1743. flush: () => {
  1744. core.flushRaw();
  1745. delete localStorage['ultratypedev'];
  1746. console.warn('Flushed UltraType settings, reloading...');
  1747. setTimeout(location.reload.bind(location), 1000);
  1748. },
  1749. toggleLocalLoad: () => {
  1750. if (localStorage["ultratypedev"]) {
  1751. delete localStorage["ultratypedev"];
  1752. console.info("Disabled local loading.");
  1753. } else {
  1754. localStorage["ultratypedev"] = true;
  1755. console.info("Enabled local loading.");
  1756. }
  1757. },
  1758. // Utility method to automatically involk debugger when a function is called
  1759. debugFn: fn => {
  1760. let _fn = fn;
  1761. fn = function() {
  1762. debugger;
  1763. _fn.apply(this, arguments);
  1764. }
  1765. return fn;
  1766. }
  1767. }
  1768. window.UltraTypeCore = core;
  1769. let hcScript = document.createElement('script');
  1770. hcScript.src = 'https://code.highcharts.com/highcharts.src.js';
  1771. hcScript.addEventListener('load', () => {
  1772. setTimeout(initChart.bind(window), 250);
  1773. });
  1774. document.head.appendChild(hcScript);
  1775. // Bye bye!
  1776. console.log('UltraType version ' + VERSION + ' loaded.');
  1777. document.currentScript.remove();
  1778. })();