Advanced Sploop.io script v2.1

-

  1. // ==UserScript==
  2. // @name Advanced Sploop.io script v2.1
  3. // @version 2.1
  4. // @description -
  5. // @namespace Auto-push auto place
  6. // @author renato and i COPYED the whole script LMAO
  7. // @match https://sploop.io/
  8. // @icon https://www.google.com/s2/favicons?sz=64&domain=sploop.io
  9. // @run-at document-start
  10. // @grant none
  11. // @license MIT
  12. // ==/UserScript==
  13.  
  14.  
  15. const getElem = (id) => {
  16. return document.getElementById(id);
  17. }
  18.  
  19. const getValue = (id) => {
  20. return document.getElementById(id).value;
  21. }
  22.  
  23. const localResources = {
  24. arrow: "https://i.imgur.com/jFZXJlt.png",
  25. }
  26.  
  27. const HTML = {
  28. menuname: function (name, version) {
  29. return `
  30. <div style="display: flex">
  31. <span class="menu-header">
  32. <h1> ${name} </h1>
  33. </span>
  34. <span class="version-header">
  35. <h1> ${version} </h1>
  36. </span>
  37. </div>
  38. `
  39. },
  40. newline: function (amount) {
  41. let result = '';
  42. for (let i = 0; i < amount; i += 1) {
  43. result += '<br>';
  44. }
  45. return result;
  46. },
  47. title: function (name, id, id2) {
  48. return `
  49. <div class="option-title">
  50. <div class="holder-title">${name}</div>
  51. <button id="${id}" class="title-button">
  52. <img src=${localResources.arrow} id="${id2}" style="width: 25px; height: 25px; transform: rotate(0deg); transition: transform 0.3s ease-in-out;"/>
  53. </button>
  54. </div>`;
  55. },
  56. color: function (id, name, color, id2, state) {
  57. return `
  58. <div class="option-color">
  59. <h1>${name}</h1>
  60. <div style="display: flex; align-items: center; justify-content: space-between;">
  61. <input type="color" id="${id}" value="${color}" class="color-style" style="margin-right: 5px;" />
  62. <input type="checkbox" id="${id2}" style = "margin-bottom: 12.5px;" ${state} />
  63. </div>
  64. </div>
  65. `
  66. },
  67. noarrowtitle: function (name) {
  68. return `
  69. <div class="option-title">
  70. <div class="holder-title">${name}</div>
  71. </div>`;
  72. },
  73. checkbox: function (name, id, state) {
  74. return `
  75. <div class="new-checkbox-section">
  76. <h1> ${name} </h1> <input type="checkbox" id="${id}" style = "margin-bottom: 12.5px;" ${state}/>
  77. </div>`;
  78. },
  79. text: function (name, id, value, id2, state) {
  80. return `
  81. <div class="option-text-text">
  82. <h1> ${name} </h1>
  83. <div style="display: flex; align-items: center; justify-content: space-between;">
  84. <input type="text" id="${id}" class="chats-input" style="width: 225px" value="${value}"/>
  85. <input type="checkbox" id="${id2}" style = "margin-bottom: 12.5px;" ${state} />
  86. </div>
  87. </div>
  88. `
  89. },
  90. }
  91.  
  92. const menu = document.createElement("div");
  93. menu.id = "menu";
  94. menu.style = ' position: absolute; padding: 5px; border-radius: 4px; color: #000; background-color: #2B2B2C; top: 0; left: 0; bottom: 0; right: 0; margin: auto; width: 625px; height: 325px; display: block; ';
  95.  
  96. const display = document.createElement("div");
  97. display.id = "display";
  98. display.style = ' position: absolute; top: 20px; left: 20px; color: #fff; display: block; font-size: 16.5px; font-family: Cursive; ';
  99.  
  100. const watermarkD = document.createElement("div");
  101. watermarkD.id = "watermarkD";
  102. watermarkD.style = ' position: absolute; display: none; top: 20px; left: 45%; border-radius: 12px; width: 180px; height: 50px; font-size: 18px; font-family: "Montserrat", sans-serif; font-weight: 900; background-color: rgba(0, 0, 0, 0); color: #fff; border: 5px solid black; align-items: center; text-align: center; padding: 10px; ';
  103.  
  104. window.addEventListener("DOMContentLoaded", () => {
  105.  
  106. display.innerHTML = `
  107. <div id = "pinginner"> </div> <br>
  108. <div id = "fpsinner"> </div>
  109. `;
  110.  
  111. document.body.appendChild(display);
  112.  
  113. watermarkD.innerHTML = `RXT v1`
  114. document.body.appendChild(watermarkD);
  115.  
  116.  
  117.  
  118. menu.innerHTML = `
  119. <div class="tabs">
  120. <ul>
  121. ${HTML.menuname("RXT ", " version 1")} ${HTML.newline(1)}
  122. <div class="option-text"><li><a id="#tab1">Combat</a></li></div>
  123. <div class="option-text"><li><a id="#tab2">Misc</a></li></div>
  124. <div class="option-text"><li><a id="#tab3">Visual</a></li></div>
  125. <div class="option-text"><li><a id="#tab4">Chats</a></li></div>
  126. </ul>
  127. </div>
  128. <div class="menu-content">
  129.  
  130. <div id="tab1" class="tab-content active">
  131. <div style = "overflow-y: scroll; height: 305px;">
  132. <div class="add-holder">
  133. ${HTML.title("Heal", "heal-arrow", "heal-arrow-rotation")}
  134. <div id="heal-content" style="display: none;">
  135. ${HTML.checkbox("Auto heal", "autoheal", "checked")}
  136. </div> </div> ${HTML.newline(1)}
  137. <div class="add-holder">
  138. ${HTML.title("Placing", "placing-arrow", "placing-arrow-rotation")}
  139. <div id="placing-content" style="display: none;">
  140. ${HTML.checkbox("Auto place", "autoplace", "checked")}
  141. ${HTML.checkbox("Placing macro", "placingmacro", "checked")}
  142. </div> </div> ${HTML.newline(1)}
  143. <div class="add-holder">
  144. ${HTML.title("Movement", "movement-arrow", "movement-arrow-rotation")}
  145. <div id="movement-content" style="display: none;">
  146. ${HTML.checkbox("Auto push", "autopush", "")}
  147. ${HTML.checkbox("Path finder", "pathfinder", "")}
  148. ${HTML.checkbox("Scaffold", "scaffold", "")}
  149. </div> </div> ${HTML.newline(1)}
  150. <div class="add-holder">
  151. ${HTML.title("Hats", "hats-arrow", "hats-arrow-rotation")}
  152. <div id="hats-content" style="display: none;">
  153. ${HTML.checkbox("Auto jungle", "autojungle", "checked")}
  154. ${HTML.checkbox("Auto scuba", "autoscuba", "checked")}
  155. ${HTML.checkbox("Auto demolist", "autodemolist", "")}
  156. ${HTML.checkbox("Auto prev hat", "autoprevhat", "")}
  157. ${HTML.checkbox("Hats macro", "hatsmacro", "checked")}
  158. </div> </div> ${HTML.newline(1)}
  159. <div class="add-holder">
  160. ${HTML.title("Other", "other-arrow", "other-arrow-rotation")}
  161. <div id="other-content" style="display: none;">
  162. ${HTML.checkbox("Auto insta", "autoinsta", "checked")}
  163. ${HTML.checkbox("Auto break trap", "autobreak", "checked")}
  164. </div> </div>
  165. </div>
  166. </div>
  167.  
  168. <div id="tab2" class="tab-content">
  169. <div style = "overflow-y: scroll; height: 305px;">
  170. <div class="add-holder">
  171. ${HTML.noarrowtitle("Select")}
  172. ${HTML.checkbox("Auto pick", "autopick", "")}
  173. </div> ${HTML.newline(1)}
  174. <div class="add-holder">
  175. ${HTML.noarrowtitle("Display")}
  176. ${HTML.checkbox("Show ping", "showping", "")}
  177. ${HTML.checkbox("Show fps", "showfps", "")}
  178. </div>
  179. </div>
  180. </div>
  181.  
  182. <div id="tab3" class="tab-content">
  183. <div style = "overflow-y: scroll; height: 305px;">
  184. <div class="add-holder">
  185. ${HTML.title("Tracers", "tracers-arrow", "tracers-arrow-rotation")}
  186. <div id="tracers-content" style="display: none;">
  187. ${HTML.color("animal-tracer-color", "Animal color", "#518CCC", "animal-tracers", "checked")}
  188. ${HTML.color("team-tracer-color", "Teammates color", "#8ECC51", "team-tracers", "checked")}
  189. ${HTML.color("enemy-tracer-color", "Enemies color", "#CC5151", "enemy-tracers", "checked")}
  190. ${HTML.checkbox("Use lines", "use-lines", "")}
  191. ${HTML.checkbox("Use rainbow", "use-rainbow", "")} ${HTML.newline(1)}
  192. ${HTML.color("autopush-tracer-color", "Auto push line", "#6b78c1", "autopushline", "state")}
  193. </div> </div> ${HTML.newline(1)}
  194. <div class="add-holder">
  195. ${HTML.title("Markers", "markers-arrow", "markers-arrow-rotation")}
  196. <div id="markers-content" style="display: none;">
  197. ${HTML.color("team-marker-color", "Teammates color", "#518CCC", "team-markers", "checked")}
  198. ${HTML.color("mine-marker-color", "Mine color", "#8ECC51", "mine-markers", "checked")}
  199. ${HTML.color("enemy-marker-color", "Enemies color", "#CC5151", "enemy-markers", "checked")}
  200. </div> </div> ${HTML.newline(1)}
  201. <div class="add-holder">
  202. ${HTML.title("Watermark", "watermark-arrow", "watermark-arrow-rotation")}
  203. <div id="watermark-content" style="display: none;">
  204. ${HTML.color("fill-mark-color", "Fill color", "#CC5151", "fill-color", "checked")}
  205. ${HTML.color("stroke-mark-color", "Stroke color", "#FF0000", "stroke-color", "checked")}
  206. ${HTML.checkbox("Use rainbow", "use-rainbow-mark", "")}
  207. ${HTML.checkbox("Watermark", "watermark-display", "")}
  208. </div> </div>
  209. </div>
  210. </div>
  211.  
  212. <div id="tab4" class="tab-content">
  213. <div style = "overflow-y: scroll; height: 305px;">
  214. <div class="add-holder">
  215. ${HTML.title("Chats", "chats-arrow", "chats-arrow-rotation")}
  216. <div id="chats-content" style="display: none;">
  217. ${HTML.text("Kill chat", "kill-chat", "gg you're no match", "killchat", "checked")}
  218. ${HTML.text("Auto break chat", "auto-break-chat", "", "autobreakchat", "")}
  219. ${HTML.text("Auto push chat", "auto-push-chat", "", "autopushchat", "checked")}
  220. </div> </div>
  221. </div>
  222. </div>
  223.  
  224. </div>
  225. `;
  226.  
  227. document.body.appendChild(menu);
  228.  
  229. setInterval(() => {
  230. if (getElem("watermark-display").checked) {
  231. getElem("watermarkD").style.display = "block";
  232. } else {
  233. getElem("watermarkD").style.display = "none";
  234. }
  235. getElem("watermarkD").style.backgroundColor = (getElem("use-rainbow-mark").checked ? `hsl(${hue}, 100%, 50%)` : (getElem("fill-color").checked ? getValue("fill-mark-color") : 'rgba(0, 0, 0, 0)'));
  236. getElem("watermarkD").style.borderColor = (getElem("use-rainbow-mark").checked ? `hsl(${hue}, 100%, 80%)` : (getElem("stroke-color").checked ? getValue("stroke-mark-color") : 'rgba(0, 0, 0, 0)'));
  237. }, 0);
  238.  
  239. document.addEventListener("keydown", (e) => {
  240. if (e.keyCode == 27) {
  241. if (getElem("menu").style.display == "none") {
  242. getElem("menu").style.display = "block"
  243. } else {
  244. getElem("menu").style.display = "none"
  245. }
  246. }
  247. });
  248.  
  249. let classesAndStyles = `
  250. ::-webkit-scrollbar {
  251. display: none;
  252. border-radius: 4px;
  253. outline: none;
  254. }
  255. .option-title, .title-button:hover {
  256. cursor: url(img/ui/cursor-pointer.png) 6 0, pointer;
  257. }
  258.  
  259. .option-color, .option-text-text {
  260. display: flex;
  261. justify-content: space-between;
  262. align-items: center;
  263. margin-top: 10px;
  264. }
  265.  
  266. .chats-input {
  267. padding: 5px;
  268. border: none;
  269. outline: none;
  270. text-align: center;
  271. border-radius: 4px;
  272. background-color: #3f3f4b;
  273. color: #fff;
  274. }
  275.  
  276. .title-button {
  277. color: #6b78c1;
  278. border: none;
  279. outline: none;
  280. border-radius: 4px;
  281. width: 100%;
  282. height: 22.5px;
  283. background-color: rgba(0,0,0,0);
  284. text-align: right;
  285. }
  286.  
  287. .holder-title {
  288. color: #646fab;
  289. font-size: 22.5px;
  290. }
  291.  
  292. .option-title {
  293. display: flex;
  294. justify-content: space-between;
  295. align-items: center;
  296. }
  297.  
  298. .menu-header h1 {
  299. font-size: 20px;
  300. color: #fff;
  301. }
  302.  
  303. .version-header h1 {
  304. color: #646fab;
  305. font-size: 20px;
  306. margin-left: 5px;
  307. }
  308.  
  309. .new-checkbox-section {
  310. display: flex;
  311. justify-content: space-between;
  312. align-items: center;
  313. margin-top: 10px;
  314. }
  315.  
  316. .color-style {
  317. outline: none;
  318. border: none;
  319. padding: 0 1px;
  320. margin: 0;
  321. height: 24px;
  322. background-color: #515a88;
  323. border-radius: 5px;
  324. cursor: pointer
  325. }
  326.  
  327. .tab-content h1 {
  328. color: #515a88;
  329. font-size: 20px;
  330. }
  331.  
  332. .tabs {
  333. position: absolute;
  334. border-radius: 4px;
  335. float: left;
  336. width: 150px;
  337. height: 315px;
  338. background-color: #2F2F31;
  339. padding: 10px;
  340. margin-right: 5px;
  341. }
  342.  
  343. .tabs ul {
  344. list-style: none;
  345. margin: 0;
  346. padding: 0;
  347. }
  348.  
  349. .tabs li {
  350. width: 100%;
  351. margin-bottom: 10px;
  352. padding: 10px;
  353. background-color: #36363d;
  354. border-radius: 4px;
  355. transition: background-color 0.3s ease-in-out;
  356. }
  357.  
  358. .tabs a {
  359. text-decoration: none;
  360. color: #fff;
  361. padding: 5px 10px;
  362. transition: color 0.3s ease-in-out;
  363. }
  364.  
  365. .tabs li:hover a {
  366. color: #646fab;
  367. cursor: url(img/ui/cursor-pointer.png) 6 0, pointer;
  368. }
  369.  
  370. .tabs li:hover {
  371. background-color: #28282f;
  372. color: #646fab;
  373. cursor: url(img/ui/cursor-pointer.png) 6 0, pointer;
  374. }
  375.  
  376. .tabs a:hover {
  377. color: #646fab;
  378. cursor: url(img/ui/cursor-pointer.png) 6 0, pointer;
  379. }
  380.  
  381. .menu-content {
  382. border-radius: 4px;
  383. float: right;
  384. width: calc(100% - 150px - 5px);
  385. padding: 5px;
  386. background-color: #2F2F31;
  387. }
  388.  
  389. .tab-content {
  390. display: none;
  391. }
  392.  
  393. .tab-content.active {
  394. display: block;
  395. }
  396.  
  397. .add-holder {
  398. width: 100%;
  399. padding: 5px;
  400. color: #fff;
  401. border-radius: 4px;
  402. background-color: #36363d;
  403. }
  404.  
  405. input:checked[type="checkbox"] {
  406. background: #6b78c1;
  407. }
  408.  
  409. input[type="checkbox" i] {
  410. background-color: initial;
  411. cursor: default;
  412. appearance: auto;
  413. box-sizing: border-box;
  414. margin: 3px 3px 3px 4px;
  415. padding: initial;
  416. border: initial;
  417. }
  418.  
  419. input:checked[type="checkbox"]::after {
  420. left: 55%;
  421. }
  422.  
  423. input[type="checkbox"]::after {
  424. position: absolute;
  425. content: "";
  426. width: 15px;
  427. height: 15px;
  428. top: 0;
  429. left: 0;
  430. background: #fff;
  431. border-radius: 50%;
  432. box-shadow: 0 0 5px rgba(0, 0, 0, 0.2);
  433. transition: 0.4s;
  434. }
  435.  
  436. input[type="checkbox"] {
  437. position: relative;
  438. appearance: none;
  439. width: 30px;
  440. height: 15px;
  441. background: #3f454d;
  442. border-radius: 8px;
  443. box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.2);
  444. cursor: url(img/ui/cursor-pointer.png) 6 0, pointer;
  445. top: 4px;
  446. transition: 0.4s;
  447. }
  448.  
  449. #cross-promo,
  450. #bottom-wrap,
  451. #google_play,
  452. #game-left-content-main,
  453. #game-bottom-content,
  454. #game-right-content-main,
  455. #right-content,
  456. #left-content,
  457. #settings {
  458. display: none !important;
  459. }
  460. #main-content {
  461. background: rgb(54 54 61 / 20%)
  462. }
  463. #homepage {
  464. background: rgb(65 65 165 / 65%);
  465. }
  466. .nav-button-active {
  467. color: #6b78c1;
  468. }
  469. .nav-button-text:hover {
  470. color: #57619a;
  471. }
  472. .dark-blue-button,
  473. .blue-button,
  474. .green-button {
  475. background-color: #6b78c1;
  476. box-shadow: inset 0 -5px 0 #57619a;
  477. }
  478. .green-button:hover,
  479. .dark-blue-button:hover,
  480. .blue-button:hover,
  481. #play:hover {
  482. background-color: #7c8bdd;
  483. box-shadow: inset 0 -5px 0 #6974b6;
  484. }
  485. .login-button-active,
  486. .dark-blue-button-3-active {
  487. background-color: #7c8bdd;
  488. box-shadow: inset 0 5px 0 #6974b6;
  489. }
  490. #server-select {
  491. background-color: #6b78c1;
  492. box-shadow: inset 0 -5px 0 #57619a;
  493. }
  494. #server-select:hover {
  495. background-color: #7c8bdd;
  496. box-shadow: inset 0 -5px 0 #6974b6;
  497. }
  498. .background-img-play {
  499. filter: blur(2.5px);
  500. background: none;
  501. display: none !important;
  502. }
  503. #play {
  504. background-color: #6b78c1;
  505. box-shadow: inset 0 -9px 0 #57619a;
  506. }
  507. #play-text {
  508. text-align: center;
  509. position: absolute;
  510. top: 11px;
  511. left: 0;
  512. items-align: center;
  513. bottom: 0;
  514. right: 0;
  515. margin: auto;
  516. }
  517.  
  518. #logo {
  519. height: 150px;
  520. }
  521. `;
  522. const menuStylesUpdate = document.createElement("style");
  523. menuStylesUpdate.type = "text/css";
  524. menuStylesUpdate.innerText = classesAndStyles;
  525. document.head.appendChild(menuStylesUpdate);
  526.  
  527. getElem('ranking-middle-main').style.height = '380px';
  528. getElem('ranking-ranks-container').style.height = '295px';
  529. getElem('ranking2-middle-main').style.height = '380px';
  530. getElem('ranking-rank-container').style.height = '295px';
  531. getElem('profile-left-main').style.width = '650px';
  532. getElem('change-username').style.width = '200px';
  533. document.querySelector('#game-content').style.justifyContent = 'center';
  534. document.querySelector('#main-content').style.width = 'auto';
  535.  
  536. let isArrowRotated = [false, false, false, false, false, false, false, false, false];
  537.  
  538. const toggleContent = (index) => {
  539. const contentEl = getElem(`${["heal", "placing", "hats", "tracers", "markers", "other", "movement", "chats", "watermark"][index]}-content`);
  540. const arrowEl = getElem(`${["heal", "placing", "hats", "tracers", "markers", "other", "movement", "chats", "watermark"][index]}-arrow-rotation`);
  541.  
  542. if (contentEl.style.display === "none") {
  543. contentEl.style.display = "block";
  544. contentEl.style.height = "0";
  545. contentEl.style.overflow = "hidden";
  546. contentEl.style.transition = "height 0.3s ease-in-out";
  547. setTimeout(() => {
  548. contentEl.style.height = contentEl.scrollHeight + "px";
  549. }, 10);
  550. } else {
  551. contentEl.style.height = contentEl.scrollHeight + "px";
  552. contentEl.style.transition = "height 0.3s ease-in-out";
  553. setTimeout(() => {
  554. contentEl.style.height = "0";
  555. setTimeout(() => {
  556. contentEl.style.display = "none";
  557. }, 300);
  558. }, 10);
  559. }
  560.  
  561. arrowEl.style.transform = isArrowRotated[index] ? 'rotate(0deg)' : 'rotate(90deg)';
  562. isArrowRotated[index] = !isArrowRotated[index];
  563. };
  564.  
  565. getElem("heal-arrow").onclick = () => toggleContent(0);
  566. getElem("placing-arrow").onclick = () => toggleContent(1);
  567. getElem("hats-arrow").onclick = () => toggleContent(2);
  568. getElem("tracers-arrow").onclick = () => toggleContent(3);
  569. getElem("markers-arrow").onclick = () => toggleContent(4);
  570. getElem("other-arrow").onclick = () => toggleContent(5);
  571. getElem("movement-arrow").onclick = () => toggleContent(6);
  572. getElem("chats-arrow").onclick = () => toggleContent(7);
  573. getElem("watermark-arrow").onclick = () => toggleContent(8);
  574.  
  575. const tabs = document.querySelectorAll('.tabs li');
  576. const tabContents = document.querySelectorAll('.tab-content');
  577.  
  578. tabs.forEach((tab, index) => {
  579. tab.addEventListener('click', () => {
  580. tabContents.forEach((content) => {
  581. content.classList.remove('active');
  582. });
  583. tabContents[index].classList.add('active');
  584. });
  585. });
  586.  
  587. setInterval(() => {
  588. defaultToggles.autoBreak = getElem("autobreak").checked ? true : false;
  589. defaultToggles.autoHeal = getElem("autoheal").checked ? true : false;
  590. defaultToggles.autoPlace = getElem("autoplace").checked ? true : false;
  591. defaultToggles.autoPush = getElem("autopush").checked ? true : false;
  592. defaultToggles.autoJungle = getElem("autojungle").checked ? true : false;
  593. defaultToggles.autoScuba = getElem("autoscuba").checked ? true : false;
  594. defaultToggles.autoDemolist = getElem("autodemolist").checked ? true : false;
  595. defaultToggles.autoPrevHat = getElem("autoprevhat").checked ? true : false;
  596. defaultToggles.autoPick = getElem("autopick").checked ? true : false;
  597. defaultToggles.autoInsta = getElem("autoinsta").checked ? true : false;
  598. defaultToggles.teamTracers = getElem("team-tracers").checked ? true : false;
  599. defaultToggles.animalTracers = getElem("animal-tracers").checked ? true : false;
  600. defaultToggles.enemyTracers = getElem("enemy-tracers").checked ? true : false;
  601. defaultToggles.useRainbow = getElem("use-rainbow").checked ? true : false;
  602. defaultToggles.useLines = getElem("use-lines").checked ? true : false;
  603. defaultToggles.killChat = getElem("killchat").checked ? true : false;
  604. defaultToggles.killChatValue = getValue("kill-chat");
  605. defaultToggles.autoPushChat = getElem("autopushchat").checked ? true : false;
  606. defaultToggles.autoPushChatValue = getValue("auto-push-chat");
  607. defaultToggles.autoBreakChat = getElem("autobreakchat").checked ? true : true;
  608. defaultToggles.autoBreakChatValue = getValue("auto-break-chat");
  609. defaultToggles.teamMarkers = getElem("team-markers").checked ? true : false;
  610. defaultToggles.enemyMarkers = getElem("enemy-markers").checked ? true : false;
  611. defaultToggles.mineMarkers = getElem("mine-markers").checked ? true : false;
  612. defaultToggles.autoPushLine = getElem("autopushline").checked ? true : false;
  613. defaultToggles.placingMacro = getElem("placingmacro").checked ? true : false;
  614. defaultToggles.hatsMacro = getElem("hatsmacro").checked ? true : false;
  615. defaultToggles.showPing = getElem("showping").checked ? true : false;
  616. defaultToggles.showFps = getElem("showfps").checked ? true : false;
  617. defaultToggles.scaffold = getElem("scaffold").checked ? true : false;
  618. }, []);
  619. });
  620.  
  621. let frames = 0,
  622. lastTime,
  623. lastUpdate = 0,
  624. frameCount = 0;
  625. window.updateFPSCounter = (currentTime) => {
  626. const elapsedSeconds = (currentTime - (lastTime || (lastTime = currentTime))) / 1000;
  627. frameCount++;
  628.  
  629. // Define colors for the gradient (lightest to darkest purples)
  630. const purpleColors = [
  631. "#d8a9ff", // Lightest purple
  632. "#bb80ff", // Light purple
  633. "#9f55ff", // Medium light purple
  634. "#8a2aff", // Medium purple
  635. "#7c00cc", // Darker purple
  636. "#6200b3", // Dark purple
  637. "#48007a", // Very dark purple
  638. "#2e0044" // Deepest purple
  639. ];
  640.  
  641. if (elapsedSeconds >= 1) {
  642. if (defaultToggles.showFps) {
  643. // Create the purple gradient string from lightest to darkest
  644. const gradient = `linear-gradient(to right, ${purpleColors.join(', ')})`;
  645.  
  646. // Apply the gradient to the text
  647. getElem("fpsinner").innerHTML = `Fps: ${Math.round(frameCount / elapsedSeconds)}`;
  648. getElem("fpsinner").style.background = gradient;
  649. getElem("fpsinner").style.webkitBackgroundClip = 'text'; // Required for Webkit browsers
  650. getElem("fpsinner").style.backgroundClip = 'text'; // Required for other browsers
  651. getElem("fpsinner").style.color = 'transparent'; // Make the text color transparent so the gradient shows
  652.  
  653. // Apply a dark glowing effect to the text
  654. getElem("fpsinner").style.textShadow = "0 0 10px rgba(0, 0, 0, 0.7), 0 0 20px rgba(0, 0, 0, 0.7), 0 0 30px rgba(0, 0, 0, 0.7)";
  655. } else {
  656. getElem("fpsinner").innerHTML = '';
  657. }
  658. frameCount = 0;
  659. lastTime = currentTime;
  660. };
  661. }
  662. let alive = {}
  663. const defaultToggles = {
  664. autoBreak: true,
  665. autoHeal: true,
  666. autoPlace: true,
  667. autoPush: true,
  668. autoJungle: true,
  669. autoScuba: true,
  670. autoDemolist: true,
  671. autoPrevHat: false,
  672. autoInsta: false,
  673. autoPick: true,
  674. showPing: true,
  675. showFps: true,
  676. teamTracers: false,
  677. enemyTracers: false,
  678. animalTracers: false,
  679. useRainbow: false,
  680. useLines: false,
  681. killChatValue: "",
  682. killChat: false,
  683. autoBreakChatValue: "",
  684. autoBreakChat: false,
  685. autoPushChatValue: "",
  686. autoPushChat: false,
  687. teamMarkers: false,
  688. enemyMarkers: false,
  689. mineMarkers: false,
  690. autoPushLine: false,
  691. placingMacro: false,
  692. hatsMacro: true,
  693. scaffold: false,
  694. }
  695.  
  696. const binds = {
  697. trap: "KeyF",
  698. spike: "KeyV",
  699. wall: "Digit4",
  700. mill: "Digit6",
  701. food: "KeyQ",
  702. platform: "...",
  703. turret: "...",
  704.  
  705. bushHat: "...",
  706. berserkerHat: "KeyB",
  707. jungleGear: "...",
  708. crystalGear: "KeyY",
  709. spikeGear: "KeyH",
  710. immunityGear: "KeyI",
  711. boostHat: "KeyN",
  712. appleHat: "...",
  713. scubaGear: "...",
  714. hood: "KeyT",
  715. demolist: "KeyC",
  716. }
  717.  
  718. let color
  719. , colors = {
  720. stroke: "#303030",
  721. nobody: "rgba(0, 0, 0, 0)",
  722. nobodystroke: "rgba(0, 0, 0, 0)",
  723. }
  724.  
  725. const hats = {
  726. bushHat: 1,
  727. berserkerHat: 2,
  728. jungleGear: 3,
  729. crystalGear: 4,
  730. spikeGear: 5,
  731. immunityGear: 6,
  732. boostHat: 7,
  733. appleHat: 8,
  734. scubaGear: 9,
  735. hood: 10,
  736. demolist: 11
  737. }
  738.  
  739. const packets = {
  740. item: 0,
  741. move: 1,
  742. itemByID: 2,
  743. hat: 5,
  744. chat: 7,
  745. place: 8,
  746. joinGame: 11,
  747. angle: 13,
  748. upgrade: 14,
  749. stopMove: 15,
  750. clanAcc: 17,
  751. stopAttack: 18,
  752. hit: 19,
  753. joinClan: 21,
  754. clan: 22,
  755. EAttack: 23,
  756. clanLeave: 24
  757. }
  758.  
  759. const serverPackets = {
  760. pingServer: 0,
  761. updateLeaderBoard: 3,
  762. age_barWmats: 8,
  763. chooseItem: 14,
  764. pingUpdate: 15,
  765. updateClan: 16,
  766. clanRequest: 17,
  767. death: 19,
  768. getKill: 22,
  769. createClan: 24,
  770. clanRemove: 27,
  771. killText: 28,
  772. attackAnimation: 29,
  773. updateEntities: 20,
  774. playerSpawn: 32,
  775. getMyID: 33,
  776. spawn: 35,
  777. itemCount: 36,
  778. }
  779.  
  780.  
  781.  
  782. // Save the original fillRect function
  783. const originalFillRect = CanvasRenderingContext2D.prototype.fillRect;
  784.  
  785. // Define colors for the gradient (lightest to darkest purples)
  786. const purpleColors = [
  787. "#d8a9ff", // Lightest purple
  788. "#bb80ff", // Light purple
  789. "#9f55ff", // Medium light purple
  790. "#8a2aff", // Medium purple
  791. "#7c00cc", // Darker purple
  792. "#6200b3", // Dark purple
  793. "#48007a", // Very dark purple
  794. "#2e0044" // Deepest purple
  795. ];
  796.  
  797. // Override fillRect
  798. CanvasRenderingContext2D.prototype.fillRect = function (x, y, width, height) {
  799. // Check if fillStyle is the specific color
  800. if (this.fillStyle === "#a4cc4f") {
  801. // Create a gradient from lightest to darkest purple for the health bar
  802. const gradient = this.createLinearGradient(x, y, x + width, y + height);
  803.  
  804. // Add each color stop for the purple gradient (starting from lightest to darkest)
  805. gradient.addColorStop(0, purpleColors[0]); // Lightest purple
  806. gradient.addColorStop(0.14, purpleColors[1]); // Lighter purple
  807. gradient.addColorStop(0.28, purpleColors[2]); // Medium light purple
  808. gradient.addColorStop(0.42, purpleColors[3]); // Medium purple
  809. gradient.addColorStop(0.57, purpleColors[4]); // Darker purple
  810. gradient.addColorStop(0.71, purpleColors[5]); // Dark purple
  811. gradient.addColorStop(0.85, purpleColors[6]); // Very dark purple
  812. gradient.addColorStop(1, purpleColors[7]); // Deepest purple
  813.  
  814. // Set the fillStyle to the gradient for the health bar
  815. this.fillStyle = gradient;
  816.  
  817. // Call the original fillRect function (to draw the health bar)
  818. originalFillRect.call(this, x, y, width, height);
  819.  
  820. // Calculate the health percentage
  821. const healthPercentage = Math.floor((myPlayer.health / myPlayer.maxHealth) * 100);
  822.  
  823. // Apply futuristic, aesthetic styling to the health text
  824. this.font = "18px 'Orbitron', sans-serif"; // Smaller font size for a more subtle effect
  825. this.textAlign = "center"; // Center the text horizontally
  826. this.textBaseline = "middle"; // Center the text vertically
  827.  
  828. // Create a gradient for the text with the same colors as the health bar
  829. const textGradient = this.createLinearGradient(x, y, x + width, y + height);
  830. textGradient.addColorStop(0, purpleColors[0]); // Lightest purple
  831. textGradient.addColorStop(0.14, purpleColors[1]); // Lighter purple
  832. textGradient.addColorStop(0.28, purpleColors[2]); // Medium light purple
  833. textGradient.addColorStop(0.42, purpleColors[3]); // Medium purple
  834. textGradient.addColorStop(0.57, purpleColors[4]); // Darker purple
  835. textGradient.addColorStop(0.71, purpleColors[5]); // Dark purple
  836. textGradient.addColorStop(0.85, purpleColors[6]); // Very dark purple
  837. textGradient.addColorStop(1, purpleColors[7]); // Deepest purple
  838.  
  839. // Set the fillStyle to the text gradient
  840. this.fillStyle = textGradient;
  841.  
  842. // Draw the text "HP: X%" (replace X with the calculated health percentage)
  843. this.shadowColor = "rgba(255, 255, 255, 0.7)"; // Light white glow
  844. this.shadowBlur = 10; // Blur the shadow for glow effect
  845. this.shadowOffsetX = 0;
  846. this.shadowOffsetY = 0;
  847.  
  848. // Draw the health percentage text 20px below the health bar
  849. this.fillText("health: " + myPlayer.health + "%", x + width / 2, y + height + 20);
  850. } else {
  851. // If fillStyle is not the specific color, call the original fillRect function
  852. originalFillRect.call(this, x, y, width, height);
  853. }
  854. };
  855.  
  856.  
  857.  
  858. let kh = [1, 12, 9, 19, 20, 15, 8, 17, 16];
  859.  
  860. let traps = [];
  861. let teammates = [];
  862. let drawpinginner = "game is loading";
  863.  
  864. let doingInsta = false;
  865. let Entity = new Array();
  866. let drawSyncHit = false;
  867. let genderPing = NaN;
  868. let autoPushing = false;
  869. let myWS,
  870. weaponInHands = 0,
  871. ping = 100,
  872. PI = 3.141592653589793,
  873. PI2 = 6.283185307179586,
  874. mouseAngle,
  875. mouseX,
  876. mouseY,
  877. inRiver = false,
  878. buyed = false,
  879. myPlayer = { id: null, clown: false, inRiver: false },
  880. hatReloaded = true;
  881. let drawHitSyncCircle = false;
  882. window.getWS = (websocket) => {
  883. myWS = websocket;
  884. websocket.onclose = () => {
  885. myWS = undefined;
  886. buyed = false;
  887. };
  888. };
  889.  
  890. const toRad = (angle) => {
  891. while (angle < 0) {
  892. angle += 360;
  893. };
  894. while (angle >= 360) {
  895. angle -= 360;
  896. };
  897. return (angle * Math.PI) / 180;
  898. };
  899. const toDegree = (angle) => {
  900. return ((angle * 180) / Math.PI);
  901. };
  902. const sleep = (ms) => new Promise(resolve => setTimeout(resolve, ms));
  903. const formatAge = age => Math.floor(Math.log(1 + Math.max(0, age)) ** 2.4 / 13);
  904.  
  905. window.receiveMsg = async ({ data }) => {
  906. const decoded = typeof data === "string" ? JSON.parse(data) : new Uint8Array(data);
  907. switch (decoded[0]) {
  908. case serverPackets.attackAnimation:
  909. for (let i = 1; i < decoded.length; i += 5) {
  910. const type = decoded[i]
  911. , id = decoded[i + 1] | decoded[i + 2] << 8
  912. , weapon = decoded[i + 3];
  913. let isObject = decoded[i + 4];
  914. }
  915. break;
  916. case serverPackets.playerSpawn:
  917. break
  918. case serverPackets.chooseItem:
  919. if (defaultToggles.autoPick) kh.forEach(id => sendPacket(packets.upgrade, decoded[1].find(id2 => id === id2)));
  920. break;
  921. case serverPackets.getMyID:
  922. myPlayer.id = decoded[1];
  923. break;
  924. case serverPackets.pingUpdate:
  925. ping = decoded[1];
  926. if (defaultToggles.showPing) {
  927. // Create a gradient from lightest to darkest purple for the "Ping" text
  928. var purpleColors = [
  929. "#d8a9ff", // Lightest purple
  930. "#bb80ff", // Light purple
  931. "#9f55ff", // Medium light purple
  932. "#8a2aff", // Medium purple
  933. "#7c00cc", // Darker purple
  934. "#6200b3", // Dark purple
  935. "#48007a", // Very dark purple
  936. "#2e0044" // Deepest purple
  937. ];
  938.  
  939. // Join the colors into a CSS gradient string
  940. var gradient = 'linear-gradient(to right, ' + purpleColors.join(', ') + ')';
  941.  
  942. // Set the inner HTML for the ping value
  943. getElem("pinginner").innerHTML = "Ping: " + ping + "ms";
  944.  
  945. // Apply the gradient to the background and clip it to text
  946. getElem("pinginner").style.background = gradient;
  947. getElem("pinginner").style.webkitBackgroundClip = 'text'; // For Chrome/Safari
  948. getElem("pinginner").style.backgroundClip = 'text'; // For Firefox/Other browsers
  949. getElem("pinginner").style.color = 'transparent'; // Make the text color transparent
  950.  
  951. // Apply the dark glowing text effect
  952. getElem("pinginner").style.textShadow = "0 0 10px rgba(0, 0, 0, 0.7), 0 0 20px rgba(0, 0, 0, 0.7), 0 0 30px rgba(0, 0, 0, 0.7)";
  953. } else {
  954. getElem("pinginner").innerHTML = "";
  955. }
  956.  
  957. break;
  958. case serverPackets.spawn:
  959. alive = true
  960. if (!buyed) {
  961. for (let i = 0; i < 12; i++) sendPacket(packets.hat, i);
  962. buyed = true;
  963. };
  964. break;
  965. case serverPackets.death:
  966. alive = false
  967. break;
  968. case serverPackets.getKill:
  969. if (defaultToggles.killChat) {
  970. let kills = decoded[1][0];
  971. let killChatValue = defaultToggles.killChatValue;
  972. let updatedValue = killChatValue.replace('{kills}', kills);
  973. sendMsg(updatedValue);
  974. }
  975. break
  976. case serverPackets.updateClan: {
  977. const array_with_ID = [...decoded.slice(2, decoded.length)];
  978. array_with_ID.splice(array_with_ID.indexOf(myPlayer.id), 1);
  979. teammates = array_with_ID;
  980. return;
  981. }
  982. case serverPackets.createClan: {
  983. const array_with_ID = [...decoded.slice(3, decoded.length)];
  984. array_with_ID.splice(array_with_ID.indexOf(myPlayer.id), 1);
  985. teammates = array_with_ID;
  986. break;
  987. }
  988. case serverPackets.clanRemove:
  989. teammates = [];
  990. break;
  991. case serverPackets.updateEntities: {
  992. for (let i = 1; i < decoded.length; i += 19) {
  993. const newEnemy = {
  994. type: decoded[i],
  995. id: decoded[i + 1],
  996. hat: decoded[i + 11],
  997. teamID: decoded[i + 12],
  998. x: decoded[i + 4] | decoded[i + 5] << 8,
  999. y: decoded[i + 6] | decoded[i + 7] << 8,
  1000. index: decoded[i + 2] | decoded[i + 3] << 8,
  1001. health: Math.ceil(decoded[i + 13] / 2.55),
  1002. angle: decoded[i + 9] * 0.02454369260617026 - PI,
  1003. broken: decoded[i + 8]
  1004. }
  1005. newEnemy.id === myPlayer.id && Object.assign(myPlayer, newEnemy);
  1006. window.myPlayer = newEnemy;
  1007. if (newEnemy.broken & 2) {
  1008. if (myPlayer.inTrap && myPlayer.inTrap.index === newEnemy.index) {
  1009. myPlayer.inTrap = false;
  1010. clearInterval(hatInterval);
  1011. hatInterval = setInterval(() => {
  1012. if (hatReloaded) {
  1013. clearInterval(hatInterval);
  1014. equipHat(hats.crystalGear);//puaal
  1015. };
  1016. }, 10)
  1017. };
  1018. traps = traps.filter(trap => trap.index !== newEnemy.index);
  1019. } else {
  1020. if (newEnemy.type === 6) {
  1021. traps.push(newEnemy); // Add enemy trap to the traps array
  1022. } else if (defaultToggles.autoBreak && newEnemy.id === myPlayer.id && newEnemy.broken !== 16) {
  1023. // Find a nearby trap to break
  1024. const trap = traps.find(trap => Math.hypot(myPlayer.x - trap.x, myPlayer.y - trap.y) <= 70 && trap.id !== myPlayer.id && !teammates.includes(trap.id));
  1025.  
  1026. if (trap && myPlayer.inTrap && trap.index !== myPlayer.inTrap.index) {
  1027. // If the player is already in a trap but it's not the current trap, update the trap
  1028. myPlayer.inTrap = trap;
  1029. }
  1030.  
  1031. if (!myPlayer.inTrap && trap) {
  1032. // If the player is not in a trap, assign the trap
  1033. myPlayer.inTrap = trap;
  1034. const angle = Math.atan2(trap.y - myPlayer.y, trap.x - myPlayer.x);
  1035. const prevWeapon = window.stats[Sploop.itemsID][weaponInHands];
  1036. sendPacket(packets.item, 1);
  1037. hit(angle);
  1038. sendPacket(packets.itemByID, prevWeapon);
  1039. sendPacket(packets.stopAttack);
  1040.  
  1041. // Function to place the traps with a 25ms delay between each
  1042. const placeTrapsWithDelay = async (angle) => {
  1043. const item = 4;
  1044. const item2 = 7;
  1045.  
  1046. // Place `7` trap first
  1047. singlePlace(item2, toRad(toDegree(angle) - 98));
  1048. await sleep(90); // 25ms delay
  1049. // Place another `7` trap opposite direction
  1050. singlePlace(item2, toRad(toDegree(angle) + 98));
  1051. await sleep(90); // 25ms delay
  1052. // Place `4` trap after `7`
  1053. singlePlace(item, toRad(toDegree(angle) + 180));
  1054. };
  1055.  
  1056. // Place traps with delay
  1057. placeTrapsWithDelay(angle);
  1058. }
  1059.  
  1060. if (myPlayer.inTrap && trap) {
  1061. const angle = Math.atan2(trap.y - myPlayer.y, trap.x - myPlayer.x);
  1062.  
  1063. // If autoDemolist toggle is enabled, equip the appropriate hat
  1064. if (defaultToggles.autoDemolist) {
  1065. equipHat(hats.demolist);
  1066. } else {
  1067. // Only equip the hat if crystalGear is not already equipped
  1068. if (myPlayer.hat !== hats.crystalGear) {
  1069. equipHat(hats.crystalGear); // Equip crystalGear if it's not already equipped
  1070. }
  1071. }
  1072.  
  1073. const prevWeapon = window.stats[Sploop.itemsID][weaponInHands];
  1074. sendPacket(packets.item, 1);
  1075. hit(angle);
  1076. sendPacket(packets.itemByID, prevWeapon);
  1077. sendPacket(packets.stopAttack);
  1078.  
  1079.  
  1080. const item = 4;
  1081. const item2 = 7;
  1082. setTimeout(()=>{
  1083. singlePlace(item, toRad(toDegree(angle) - 98));
  1084. },90);
  1085. setTimeout(()=>{
  1086. singlePlace(item, toRad(toDegree(angle) + 98));
  1087. },90);
  1088. setTimeout(()=>{
  1089. singlePlace(item, toRad(toDegree(angle) + 180));
  1090. },90);
  1091. }
  1092.  
  1093. // If the player is in a trap and there are no nearby traps (within 52 distance)
  1094. if (myPlayer.inTrap && !traps.find(trap => Math.hypot(myPlayer.x - trap.x, myPlayer.y - trap.y) <= 70)) {
  1095. // Place a `7` trap when leaving or destroying a trap
  1096. singlePlace(7, newEnemy);
  1097. myPlayer.inTrap = false;
  1098. clearInterval(hatInterval); // Clear the previous hat interval
  1099.  
  1100. // Re-apply the hat logic after the trap is placed
  1101. hatInterval = setInterval(() => {
  1102. if (hatReloaded) {
  1103. clearInterval(hatInterval);
  1104. if (defaultToggles.autoPrevHat) {
  1105. // Only re-equip the crystalGear if it's not currently equipped
  1106. if (myPlayer.hat !== hats.crystalGear) {
  1107. equipHat(hats.crystalGear); // Re-equip the previous hat if the setting is enabled
  1108. }
  1109. }
  1110. };
  1111. }, 10); // Check every 10ms if hat reload is finished
  1112. }
  1113. }
  1114. }
  1115. window.inTrap = myPlayer.inTrap;
  1116. }
  1117.  
  1118. if (myPlayer.y <= 9000 && myPlayer.y >= 8000) {
  1119. if (defaultToggles.scaffold) {
  1120. const angle = Math.atan2(myPlayer.y - myPlayer.y2, myPlayer.x - myPlayer.x2);
  1121. place(8, angle);
  1122. }
  1123. }
  1124.  
  1125.  
  1126.  
  1127.  
  1128.  
  1129. if (defaultToggles.autoScuba) {
  1130. if (myPlayer.y <= 9000 && myPlayer.y >= 8000 && !myPlayer.inRiver) {
  1131. myPlayer.inRiver = true;
  1132. if (hatReloaded) {
  1133. equipHat(hats.scubaGear);
  1134. } else {
  1135. clearInterval(hatInterval);
  1136. hatInterval = setInterval(() => {
  1137. if (hatReloaded) {
  1138. clearInterval(hatInterval);
  1139. equipHat(hats.scubaGear);
  1140. };
  1141. }, 10)
  1142. };
  1143. };
  1144. if ((myPlayer.y >= 9000 || myPlayer.y <= 8000) && myPlayer.inRiver) {
  1145. myPlayer.inRiver = false;
  1146. if (hatReloaded) {
  1147. equipHat(hats.boostHat);
  1148. } else {
  1149. clearInterval(hatInterval);
  1150. hatInterval = setInterval(() => {
  1151. if (hatReloaded) {
  1152. clearInterval(hatInterval);
  1153. equipHat(hats.boostHat);
  1154. };
  1155. }, 10)
  1156. };
  1157. };
  1158. } else {
  1159. myPlayer.inRiver = false;
  1160. };
  1161.  
  1162.  
  1163.  
  1164.  
  1165.  
  1166. if (myPlayer.broken === 128 && !myPlayer.clowned && defaultToggles.autoJungle) {
  1167. myPlayer.clowned = true;
  1168. equipHat(hats.jungleGear);
  1169. setTimeout(() => {
  1170. myPlayer.clowned = false;
  1171. equipHat(hats.crystalGear);
  1172. }, 3000)
  1173. };
  1174.  
  1175. let damageCount = 0; // Counter for damage hits between 9 and 14
  1176. let healingSlow = false; // Flag to indicate if healing should be slowed down
  1177. let slowHealingTimer = 0; // Timer for resetting slow healing after 1000ms
  1178. let lastDamage = 0; // Store last damage value
  1179. let doubleHealDisabled = false; // Flag to indicate if double heal is disabled
  1180. let doubleHealFor35Active = false; // Flag for double heal at 35 HP
  1181. let noDelayActive = false; // Flag to track if no-delay healing is active for 62-65 HP range
  1182. let noDelayTimer = null; // Timer to manage the no-delay window for healing
  1183. if(alive){
  1184. // Function to detect damage in the range of 9 to 14
  1185. function handleDamage(damage) {
  1186. // Check if the damage is between 9 and 14
  1187. if (damage >= 10 && damage <= 14) {
  1188. damageCount++;
  1189. }
  1190.  
  1191. // If damageCount exceeds 4, slow down healing
  1192. if (damageCount > 4 && !healingSlow) {
  1193. healingSlow = true; // Set flag to slow healing
  1194. slowHealingTimer = Date.now() + 1000; // Set timer for 1000ms to reset healing
  1195. }
  1196.  
  1197. // Special check for 65 exact damage to trigger double heal
  1198. if (damage === 65 && !doubleHealDisabled) {
  1199. healPlayer(true); // Trigger double heal
  1200. doubleHealDisabled = true; // Disable special heal
  1201. setTimeout(() => {
  1202. doubleHealDisabled = false; // Re-enable special heal after 3000ms
  1203. }, 3000);
  1204. }
  1205. }
  1206.  
  1207. let specialHealActive = false; // Flag to track if special healing is active
  1208.  
  1209. // Function to handle healing logic
  1210. function healPlayer(isDoubleHeal = false) {
  1211. let delay;
  1212.  
  1213. // Check if health is exactly 35 and the special heal is not disabled
  1214. if (myPlayer.health === 35 && !doubleHealFor35Active) {
  1215. doubleHealFor35Active = true; // Activate double heal for 35 HP
  1216. healPlayer(true); // Trigger double heal immediately with no delay
  1217.  
  1218. // Disable double heal for 2000ms
  1219. setTimeout(() => {
  1220. doubleHealFor35Active = false; // Re-enable double heal for 35 HP after 2000ms
  1221. }, 2000);
  1222.  
  1223. return; // Prevent further healing logic from executing
  1224. }
  1225.  
  1226. // Special heal for under 40 health
  1227. if (myPlayer.health < 40 && !specialHealActive) {
  1228. specialHealActive = true; // Activate special healing
  1229.  
  1230. // Initialize the delay counter for each tick
  1231. let healTickDelay = 10; // Start with 15ms delay
  1232. let healTickCount = 0; // Track the number of healing ticks
  1233.  
  1234. // Function to apply the special healing gradually
  1235. let healInterval = setInterval(() => {
  1236. // Heal with the current delay
  1237. placeFood(); // Heal the player
  1238.  
  1239. // Increase the delay after each heal
  1240. healTickCount++;
  1241. healTickDelay += 5; // Increase by 10ms per heal tick
  1242.  
  1243. // If delay exceeds a certain limit (e.g., 100ms), stop the special healing
  1244. if (healTickDelay >= 100 || healTickCount > 10) {
  1245. clearInterval(healInterval); // Stop healing when the delay gets too high
  1246. specialHealActive = false; // Deactivate special healing
  1247. }
  1248. }, healTickDelay); // Apply healing at the current delay
  1249.  
  1250. return; // Prevent further healing logic from executing
  1251. }
  1252.  
  1253. // If we are in the 62-65 range, and no-delay healing is active, check if myPlayer.hat !== 4
  1254. if (myPlayer.health >= 62 && myPlayer.health <= 65 && !noDelayActive && myPlayer.hat !== 4) {
  1255. noDelayActive = true; // Activate no delay healing
  1256. healPlayer(true); // Trigger double heal immediately with no delay
  1257.  
  1258. // Set a timer to disable the no-delay healing for 1 second
  1259. setTimeout(() => {
  1260. noDelayActive = false; // Disable no-delay healing after 1 second
  1261. }, 1000);
  1262.  
  1263. // Set a timer to re-enable no-delay healing every 2 seconds (changed from 3 seconds to 2 seconds)
  1264. setTimeout(() => {
  1265. noDelayActive = true; // Re-enable no-delay healing after 2 seconds
  1266. }, 1000);
  1267.  
  1268. return; // Prevent further healing logic from executing
  1269. }
  1270.  
  1271. // If healing should be slowed down due to constant damage
  1272. if (healingSlow) {
  1273. delay = 250; // Slow healing with 170ms delay
  1274. } else {
  1275. // Determine the delay based on health ranges
  1276. if (myPlayer.health >= 62 && myPlayer.health <= 65 && noDelayActive) {
  1277. delay = -1; // Heal immediately with no delay if in the range 62-65 and no-delay active
  1278. } else if (myPlayer.health >= 22 && myPlayer.health <= 34) {
  1279. delay = 40; // Heal with 40ms delay
  1280. } else {
  1281. delay = window.pingTime > 100 ? 55 : 80; // Default healing delay based on pingTime
  1282. }
  1283. }
  1284.  
  1285. // If it's been more than 1000ms since we started slow healing, reset the healing speed
  1286. if (healingSlow && Date.now() > slowHealingTimer) {
  1287. healingSlow = false; // Reset the slow healing flag
  1288. damageCount = 0; // Reset the damage counter
  1289. }
  1290.  
  1291. // If this is a double heal, trigger twice with no delay
  1292. if (isDoubleHeal) {
  1293. // Heal the player twice with no delay
  1294. setTimeout(() => {
  1295. placeFood(); // Heal the player
  1296. }, 0); // Heal immediately
  1297.  
  1298. setTimeout(() => {
  1299. placeFood(); // Heal again
  1300. }, 0); // Heal immediately again
  1301. } else {
  1302. // Heal the player with normal delay
  1303. setTimeout(() => {
  1304. placeFood(); // Heal the player
  1305. }, delay);
  1306. }
  1307. }
  1308. // Logic to trigger the healing process and track damage (this would be triggered where damage is detected in your game loop)
  1309. if (myPlayer.health < 100 && defaultToggles.autoHeal) {
  1310. let delay;
  1311.  
  1312. // Determine the delay based on health ranges
  1313. if (myPlayer.health < 40 && !specialHealActive) {
  1314. delay = 15; // Start the special heal with 15ms delay when health is below 40
  1315. } else if (myPlayer.health >= 62 && myPlayer.health <= 65 && !noDelayActive && myPlayer.hat === 4) {
  1316. delay = 25; // Heal with 35ms delay when no-delay is off and hat is 4
  1317. } else if (myPlayer.health >= 62 && myPlayer.health <= 65 && noDelayActive) {
  1318. delay = -1; // Heal immediately with no delay when in the range 62-65 and no-delay is active
  1319. } else if (myPlayer.health >= 22 && myPlayer.health <= 34) {
  1320. delay = 25; // Heal with 40ms delay
  1321. } else {
  1322. delay = window.pingTime > 100 ? 55 : 80; // Default healing delay based on pingTime
  1323. }
  1324.  
  1325. setTimeout(() => {
  1326. healPlayer(); // Trigger the healing function
  1327. }, delay);
  1328. }
  1329. }
  1330.  
  1331. break;
  1332. }
  1333. }
  1334. }
  1335.  
  1336. const encoder = new TextEncoder();
  1337. const sendMsg = (text) => {
  1338. return sendPacket(packets.chat, ...encoder.encode(text));
  1339. };
  1340. const hit = (angle) => {
  1341. const transformedAngle = 65535 * (angle + Math.PI) / (2 * Math.PI);
  1342. sendPacket(packets.hit, 255 & transformedAngle, transformedAngle >> 8 & 255);
  1343. };
  1344.  
  1345. let placingObject = 0;
  1346. let pushingCounts = 0;
  1347. let pushingChatCount = 0;
  1348.  
  1349. window.getEntityData = (entity, ctx, isTeammate) => {
  1350. const isMe = entity[Sploop.id] === myPlayer.id;
  1351. const entityX = entity[Sploop.x], entityY = entity[Sploop.y], entityAngle = entity[Sploop.angle];
  1352.  
  1353. if (isMe) myPlayer.currentItem = window.weapons[entity[Sploop.currentWeapon]];
  1354.  
  1355. const tracerAngle = (Math.atan2(myPlayer.y2 - entity[Sploop.y], myPlayer.x2 - entity[Sploop.x]) + Math.PI) % (2 * Math.PI);
  1356. const tracerDistance = Math.max(Math.hypot(entity[Sploop.y] - myPlayer.y2, entity[Sploop.x] - myPlayer.x2) / 2, 30);
  1357. const tracerx = myPlayer.x2 + tracerDistance * Math.cos(tracerAngle);
  1358. const tracery = myPlayer.y2 + tracerDistance * Math.sin(tracerAngle);
  1359. let tracerColor;
  1360. if (myPlayer.id != entity[Sploop.id]) {
  1361. if (defaultToggles.useRainbow) {
  1362. if (defaultToggles.teamTracers || defaultToggles.enemyTracers || defaultToggles.animalTracers) {
  1363. tracerColor = `hsl(${hue}, 100%, 50%)`;
  1364. }
  1365. } else {
  1366. if (entity.type != 0) {
  1367. (defaultToggles.animalTracers) ? tracerColor = getValue("animal-tracer-color") : tracerColor = "rgba(0, 0, 0, 0)"
  1368. } else if (entity.type == 0 && !teammates.includes(entity[Sploop.id])) {
  1369. (defaultToggles.enemyTracers) ? tracerColor = getValue("enemy-tracer-color") : tracerColor = "rgba(0, 0, 0, 0)"
  1370. } else {
  1371. (defaultToggles.teamTracers) ? tracerColor = getValue("team-tracer-color") : tracerColor = "rgba(0, 0, 0, 0)"
  1372. }
  1373. }
  1374. } else {
  1375. tracerColor = "rgba(0, 0, 0, 0)";
  1376. }
  1377. if (defaultToggles.useLines) {
  1378. canvas.local.save();
  1379. canvas.local.beginPath();
  1380. canvas.local.globalAlpha = 1;
  1381. canvas.local.lineCap = "round"
  1382. canvas.local.strokeStyle = tracerColor;
  1383. canvas.local.lineWidth = 5;
  1384. canvas.local.moveTo(myPlayer.x2, myPlayer.y2);
  1385. canvas.local.lineTo(entity[Sploop.x], entity[Sploop.y])
  1386. canvas.local.stroke();
  1387. canvas.local.closePath();
  1388. canvas.local.restore();
  1389. } else {
  1390. canvas.local.save();
  1391. canvas.local.beginPath();
  1392. canvas.local.translate(tracerx, tracery);
  1393. canvas.local.rotate(Math.PI / 4);
  1394. canvas.local.rotate(tracerAngle);
  1395. canvas.local.globalAlpha = 1;
  1396. canvas.local.fillStyle = tracerColor;
  1397. canvas.local.moveTo(-12, -12);
  1398. canvas.local.lineTo(12, 12);
  1399. canvas.local.lineTo(25, -25);
  1400. canvas.local.fill();
  1401. canvas.local.closePath();
  1402. canvas.local.restore();
  1403. }
  1404.  
  1405. if (isMe) {
  1406. myPlayer.x2 = entityX;
  1407. myPlayer.y2 = entityY;
  1408. myPlayer.angle2 = entityAngle;
  1409. myPlayer.currentWeapon = entity[Sploop.currentWeapon];
  1410. } else if (!isMe && entity.type === 0 && !teammates.includes(entity[Sploop.id])) {
  1411. const distance = Math.hypot(entityX - myPlayer.x2, entityY - myPlayer.y2);
  1412. const angle = Math.atan2(entityY - myPlayer.y2, entityX - myPlayer.x2); // Angle to enemy (not used for placement)
  1413.  
  1414. let lastPlacedObject = -1; // Track the last object placed to prevent repeated packets
  1415. if (alive) {
  1416. if (distance <= 130) {
  1417. const enemyTrapped = myTraps.find(c => Math.hypot(c[Sploop.y] - entity[Sploop.y], c[Sploop.x] - entity[Sploop.x]) <= 70);
  1418.  
  1419. if (enemyTrapped) {
  1420. const x = enemyTrapped[Sploop.x] - myPlayer.x;
  1421. const y = enemyTrapped[Sploop.y] - myPlayer.y;
  1422. placingObject++;
  1423.  
  1424. if (placingObject == 15) {
  1425. // Place traps around the enemy when trapped
  1426. singlePlace(4, Math.atan2(y, x) + 1.3);
  1427. singlePlace(4, Math.atan2(y, x) - 1.3);
  1428. placingObject = 0;
  1429. } else if (placingObject == 7.5) {
  1430. singlePlace(4, Math.atan2(y, x) + 2.6);
  1431. singlePlace(4, Math.atan2(y, x) - 2.6);
  1432. placingObject = 0;
  1433. }
  1434. } else {
  1435. placingObject = 0; // Reset placingObject when no traps are found
  1436.  
  1437. // Calculate the angle in the enemy's direction
  1438. const enemyAngle = Math.atan2(entity[Sploop.y] - myPlayer.y, entity[Sploop.x] - myPlayer.x);
  1439.  
  1440. // Calculate the 50° angle in radians
  1441. const angle50 = 50 * Math.PI / 180;
  1442.  
  1443. // Place the main traps
  1444. singlePlace(7, enemyAngle);
  1445. setTimeout(() => {
  1446. singlePlace(7, enemyAngle + angle50); // Place one to the right (+50°)
  1447. }, 50);
  1448. setTimeout(() => {
  1449. singlePlace(7, enemyAngle - angle50); // Place one to the left (-50°)
  1450. }, 50);
  1451. const angleBehind = Math.PI; // 180° to reverse direction
  1452. }
  1453. }
  1454. }
  1455. const dsd = myTraps.find(c => myPlayer.id == c[Sploop.id] && Math.hypot(c[Sploop.y] - entity[Sploop.y], c[Sploop.x] - entity[Sploop.x]) <= 70);
  1456. // Ensure lastEquippedHat is defined and stored correctly
  1457. if (typeof lastEquippedHat === "undefined") {
  1458. var lastEquippedHat = myPlayer.hat;
  1459. }
  1460.  
  1461.  
  1462. if (defaultToggles.autoPush && distance <= 170) {
  1463. const enemyTrapped = myTraps.find(c => myPlayer.id == c[Sploop.id] && Math.hypot(c[Sploop.y] - entity[Sploop.y], c[Sploop.x] - entity[Sploop.x]) <= 75);
  1464. if (enemyTrapped && Math.hypot(enemyTrapped[Sploop.y] - myPlayer.y, enemyTrapped[Sploop.x] - myPlayer.x) <= 250) {
  1465. // Ensure the spike belongs to your player
  1466. const nearestSpike = mySpikes.find(c => c[Sploop.id] == myPlayer.id && Math.hypot(c[Sploop.y] - enemyTrapped[Sploop.y], c[Sploop.x] - enemyTrapped[Sploop.x]) <= 140);
  1467. const angle = Math.atan2(entityY - myPlayer.y2, entityX - myPlayer.x2); // Angle to enemy (not used for placement)
  1468. if (nearestSpike) {
  1469. pushingCounts++;
  1470. autoPushing = true;
  1471. nearestSpike.x = nearestSpike[Sploop.x];
  1472. nearestSpike.y = nearestSpike[Sploop.y];
  1473. const angleToEnemy = Math.atan2(entity[Sploop.y] - nearestSpike.y, entity[Sploop.x] - nearestSpike.x)
  1474. let distance = Math.hypot(nearestSpike.x - entity[Sploop.x], nearestSpike.y - entity[Sploop.y]) + 45;
  1475. const pushPos = {
  1476. x: nearestSpike.x + (distance * Math.cos(angleToEnemy)),
  1477. y: nearestSpike.y + (distance * Math.sin(angleToEnemy))
  1478. };
  1479. const pushingCount = Math.hypot(myPlayer.x - pushPos.x, myPlayer.y - pushPos.y);
  1480. let pushingAngle;
  1481. if (pushingCount > 15) {
  1482. pushingAngle = Math.atan2(pushPos.y - myPlayer.y, pushPos.x - myPlayer.x);
  1483. } else {
  1484. pushingAngle = Math.atan2(entity[Sploop.y] - myPlayer.y, entity[Sploop.x] - myPlayer.x);
  1485. }
  1486. const pushAngle = 65535 * (pushingAngle + Math.PI) / (2 * Math.PI);
  1487.  
  1488. if (entity[Sploop.health] < 95 && distance <= 155) {//nu merge
  1489. const instaKillAngle = Math.atan2(entity[Sploop.y] - myPlayer.y2, entity[Sploop.x] - myPlayer.x2);
  1490. const hitAngle = 65535 * (instaKillAngle + PI) / PI2;
  1491. equipHat(hats.berserkerHat);
  1492. sendPacket(packets.item, 0);
  1493.  
  1494. // Adjust the delay based on ping
  1495. let delayTime = 25;
  1496. if (ping > 100) {
  1497. delayTime = 25; // Halve the delay if ping is over 100
  1498. }
  1499.  
  1500. setTimeout(() => {
  1501. sendPacket(packets.hit, 255 & hitAngle, hitAngle >> 8 & 255);
  1502. }, delayTime);
  1503.  
  1504. setTimeout(() => {
  1505. sendPacket(packets.stopAttack);
  1506. }, delayTime);
  1507.  
  1508. setTimeout(() => {
  1509. if (myPlayer.hat !== 4) {
  1510. equipHat(hats.crystalGear);
  1511. }
  1512. }, 1600);
  1513. }
  1514.  
  1515. // Draw purple stroke and fill
  1516. ctx.save();
  1517. ctx.beginPath();
  1518. ctx.lineWidth = 5;
  1519. ctx.lineCap = "round";
  1520. ctx.strokeStyle = "#800080"; // Purple stroke color
  1521. ctx.fillStyle = "#800080"; // Purple fill color
  1522. ctx.moveTo(myPlayer.x, myPlayer.y);
  1523. ctx.bezierCurveTo(entity[Sploop.x], entity[Sploop.y], pushPos.x, pushPos.y, nearestSpike.x, nearestSpike.y);
  1524. ctx.globalAlpha = 0.5;
  1525. ctx.arc(nearestSpike.x, nearestSpike.y, 8, 0, Math.PI * 2);
  1526. ctx.fill(); // Fill the circle
  1527. ctx.stroke(); // Stroke the path
  1528. ctx.closePath();
  1529. ctx.restore();
  1530.  
  1531. if (distance < 41) {
  1532. sendPacket(packets.stopMove);
  1533. } else {
  1534. if (pushingCounts > 6) {
  1535. sendPacket(packets.move, 255 & pushAngle, pushAngle >> 8 & 255);
  1536. pushingCounts = 0;
  1537. }
  1538. }
  1539. } else {
  1540. // No nearby spike found, stop pushing
  1541. autoPushing = false;
  1542. pushingCounts = 0; // Reset pushing count
  1543. }
  1544. } else {
  1545. // No enemy trapped or distance too far, stop pushing
  1546. autoPushing = false;
  1547. pushingCounts = 0; // Reset pushing count
  1548. }
  1549. }
  1550. }}
  1551. window.render = (ctx, shit) => {
  1552. };
  1553.  
  1554. let mySpikes = [];
  1555. let myTraps = [];
  1556. let myScaffs = [];
  1557. window.drawMarkers = (target, id, ctx, step) => {
  1558. const objectID = target[Sploop.id]
  1559. const isSpike = [2, 7, 17].includes(target.type);
  1560.  
  1561. if (isSpike) {
  1562. let isMySpike = myPlayer.id == objectID;
  1563. if (isMySpike && !mySpikes.find(c => c[Sploop.id2] == target[Sploop.id2])) {
  1564. mySpikes.push(target);
  1565. }
  1566. }
  1567.  
  1568. if (myTraps && target.type == 6) {
  1569. let isMyTrap = myPlayer.id == objectID;
  1570. if (isMyTrap && !myTraps.find(c => c[Sploop.id2] == target[Sploop.id2])) {
  1571. myTraps.push(target);
  1572. }
  1573. };
  1574.  
  1575. if (myScaffs && target.type == 9) {
  1576. let isMyScaff = myPlayer.id == objectID;
  1577. if (isMyScaff && !myScaffs.find(c => c[Sploop.id2] == target[Sploop.id2])) {
  1578. myScaffs.push(target);
  1579. }
  1580. };
  1581.  
  1582. let color, strokeColor;
  1583. if (teammates.includes(target[Sploop.id])) {
  1584. if (defaultToggles.teamMarkers) {
  1585. color = getValue("team-marker-color");
  1586. strokeColor = colors.stroke;
  1587. } else {
  1588. color = colors.nobody;
  1589. strokeColor = colors.nobodystroke;
  1590. }
  1591. } else if (objectID === myPlayer.id) {
  1592. if (defaultToggles.mineMarkers) {
  1593. color = getValue("mine-marker-color");
  1594. strokeColor = colors.stroke;
  1595. } else {
  1596. color = colors.nobody;
  1597. strokeColor = colors.nobodystroke;
  1598. }
  1599. } else {
  1600. if (defaultToggles.enemyMarkers) {
  1601. color = getValue("enemy-marker-color");
  1602. strokeColor = colors.stroke;
  1603. } else {
  1604. color = colors.nobody;
  1605. strokeColor = colors.nobodystroke;
  1606. }
  1607. }
  1608.  
  1609. if (![21, 30, 40, 31, 32, 33, 34, 35, 38, 39, 1, 3, 4, 5, 9].includes(target.type)) {
  1610. ctx.save();
  1611. ctx.beginPath();
  1612. ctx.strokeStyle = strokeColor;
  1613. ctx.lineWidth = 10;
  1614. ctx.arc(0, 0, 5, 0, 2 * Math.PI);
  1615. ctx.stroke();
  1616. ctx.fillStyle = color;
  1617. ctx.arc(0, 0, 5, 0, 2 * Math.PI);
  1618. ctx.fill();
  1619. ctx.closePath();
  1620. ctx.restore();
  1621. }
  1622.  
  1623. };
  1624.  
  1625. let weaponReloading = false;
  1626. window.attackAnimation = (type, id, weapon, isObject, entity) => {
  1627. try {
  1628. const entityID = entity[Sploop.id];
  1629. entityID == myPlayer.id && (weaponReloading = true);
  1630. setTimeout(function () {
  1631. entityID == myPlayer.id && (weaponReloading = false);
  1632. }, window.weapons[window.stats[Sploop.itemsID][weaponInHands]].reload)
  1633. } catch (err) { }
  1634. };
  1635.  
  1636. const checkChanges = (obj1, obj2) => {
  1637. const keys1 = Object.keys(obj1);
  1638. const keys2 = Object.keys(obj2);
  1639. return keys2.some(key => !keys1.includes(key)) || keys1.some(key => !keys2.includes(key));
  1640. };
  1641.  
  1642. const changeSettings = (key, value) => {
  1643. let newSettings = JSON.parse(localStorage.settings);
  1644. newSettings[key] = value;
  1645. localStorage.setItem("settings", JSON.stringify(newSettings));
  1646. };
  1647.  
  1648. const sendPacket = (packetID, ...values) => {
  1649. return myWS.send(new Uint8Array([packetID, ...values]));
  1650. }
  1651.  
  1652. let mouseAngle2;
  1653. window.addEventListener("mousemove", ({ pageX, pageY }) => {
  1654. mouseX = pageX;
  1655. mouseY = pageY;
  1656. mouseAngle = 65535 * (Math.atan2(mouseY - innerHeight / 2, mouseX - innerWidth / 2) + PI) / PI2;
  1657. mouseAngle2 = Math.atan2(mouseY - innerHeight / 2, mouseX - innerWidth / 2);
  1658. });
  1659.  
  1660. let hatInterval;
  1661. const equipHat = (id) => {
  1662. if (hatReloaded) {
  1663. hatReloaded = false;
  1664. setTimeout(() => {
  1665. hatReloaded = true;
  1666. }, 1300);
  1667. if (myPlayer.hat !== id) {
  1668. myPlayer.prevHat = myPlayer.inRiver && myPlayer.hat === hats.scubaGear ? id : myPlayer.hat;
  1669. sendPacket(packets.hat, id);
  1670. };
  1671. };
  1672. };
  1673.  
  1674. let _isKeyDown = false, _intervalId;
  1675.  
  1676. const checkChat = () => !getElem("chat-wrapper").style.display || getElem("chat-wrapper").style.display === "none";
  1677.  
  1678. let repeater = (key, action) => ({
  1679. start(keycode) {
  1680. if (keycode === key && !_isKeyDown) {
  1681. _isKeyDown = true;
  1682. placingItem = true;
  1683. _intervalId = setInterval(() => {
  1684. action();
  1685. !_isKeyDown && (clearInterval(_intervalId), _intervalId = undefined);
  1686. }, 25);
  1687. }
  1688. },
  1689. stop(keycode) {
  1690. if (keycode === key) {
  1691. _isKeyDown = false;
  1692. placingItem = false;
  1693. };
  1694. }
  1695. });
  1696.  
  1697. const changeAngle = (angle, isTransformed = false) => {
  1698. if (isTransformed) {
  1699. sendPacket(packets.angle, 255 & angle, angle >> 8 & 255);
  1700. return;
  1701. } else {
  1702. const angle2 = 65535 * (angle + Math.PI) / (2 * Math.PI);
  1703. sendPacket(packets.angle, 255 & angle2, angle2 >> 8 & 255);
  1704. }
  1705. };
  1706.  
  1707. let placingItem = false;
  1708. const canvas = {
  1709. local: undefined,
  1710. }
  1711.  
  1712. window.addEventListener("DOMContentLoaded", event => {
  1713. canvas.local = getElem("game-canvas").getContext("2d");
  1714. });
  1715.  
  1716. const prevRect = CanvasRenderingContext2D.prototype.clearRect;
  1717. CanvasRenderingContext2D.prototype.clearRect = function (x, y, width, height) {
  1718. if (this.canvas.id === "game-canvas") {
  1719. canvas.local = this.canvas.getContext("2d");
  1720. }
  1721. return prevRect.apply(this, arguments);
  1722. }
  1723.  
  1724. const { fillRect } = CanvasRenderingContext2D.prototype;
  1725. CanvasRenderingContext2D.prototype.fillRect = function (x, y, width, height) {
  1726. if (placingItem && this.fillStyle === "#a4cc4f") {
  1727. //drawPredict('place');
  1728. };
  1729. return fillRect.apply(this, arguments);
  1730. }
  1731.  
  1732. const place = (itemID) => {
  1733. sendPacket(packets.item, weaponInHands);
  1734. sendPacket(packets.item, itemID);
  1735. sendPacket(packets.hit, 255 & mouseAngle, mouseAngle >> 8 & 255);
  1736. sendPacket(packets.stopAttack);
  1737. sendPacket(packets.item, weaponInHands);
  1738. };
  1739.  
  1740. const singlePlace = (itemID, preAngle) => {
  1741. const back = mouseAngle;
  1742. const angle = 65535 * (preAngle + Math.PI) / (2 * Math.PI);
  1743. sendPacket(packets.item, weaponInHands);
  1744. sendPacket(packets.item, itemID);
  1745. sendPacket(packets.hit, 255 & angle, angle >> 8 & 255);
  1746. changeAngle(back, true);
  1747. sendPacket(packets.stopAttack);
  1748. sendPacket(packets.item, weaponInHands);
  1749. };
  1750.  
  1751. const placeFood = () => {
  1752. sendPacket(packets.item, weaponInHands);
  1753. sendPacket(packets.item, 2);
  1754. const healAngle = 65535 * (myPlayer.angle + PI) / PI2;
  1755. sendPacket(packets.hit, 255 & healAngle, healAngle >> 8 & 255);
  1756. sendPacket(packets.stopAttack);
  1757. sendPacket(packets.item, weaponInHands);
  1758. };
  1759.  
  1760. const placeByKey = (key, itemID) => repeater(binds[key], () => place(itemID), itemID);
  1761. const placement = {
  1762. trap: placeByKey("trap", 7),
  1763. spike: placeByKey("spike", 4),
  1764. wall: placeByKey("wall", 3),
  1765. mill: placeByKey("mill", 5),
  1766. QHold: placeByKey("QHeal", 2),
  1767. platform: placeByKey("platform", 8),
  1768. turret: placeByKey("turret", 10)
  1769. };
  1770.  
  1771. let copyMove = 0;
  1772. document.addEventListener("keydown", event => {
  1773. if (event.repeat || !checkChat()) return;
  1774. const pressedKey = event.code;
  1775. if (defaultToggles.placingMacro) {
  1776. if (Object.values(binds).includes(pressedKey)) Object.values(placement).forEach(action => action.start(pressedKey));
  1777. }
  1778. if (["KeyW", "KeyA", "KeyS", "KeyD"].includes(pressedKey)) {
  1779. if (pressedKey === "KeyW") copyMove |= 1;
  1780. if (pressedKey === "KeyA") copyMove |= 4;
  1781. if (pressedKey === "KeyS") copyMove |= 2;
  1782. if (pressedKey === "KeyD") copyMove |= 8;
  1783. }
  1784.  
  1785. switch (pressedKey) {
  1786. case "Digit1": weaponInHands = 0; break;
  1787. case "Digit2": weaponInHands = 1; break;
  1788. case binds.bushHat: if (defaultToggles.hatsMacro) equipHat(hats.bushHat); break;
  1789. case binds.berserkerHat: if (defaultToggles.hatsMacro) equipHat(hats.berserkerHat); break;
  1790. case binds.jungleGear: if (defaultToggles.hatsMacro) equipHat(hats.jungleGear); break;
  1791. case binds.crystalGear: if (defaultToggles.hatsMacro) equipHat(hats.crystalGear); break;
  1792. case binds.spikeGear: if (defaultToggles.hatsMacro) equipHat(hats.spikeGear); break;
  1793. case binds.immunityGear: if (defaultToggles.hatsMacro) equipHat(hats.immunityGear); break;
  1794. case binds.boostHat: if (defaultToggles.hatsMacro) equipHat(hats.boostHat); break;
  1795. case binds.appleHat: if (defaultToggles.hatsMacro) equipHat(hats.appleHat); break;
  1796. case binds.scubaGear: if (defaultToggles.hatsMacro) equipHat(hats.scubaGear); break;
  1797. case binds.hood: if (defaultToggles.hatsMacro) equipHat(hats.hood); break;
  1798. case binds.demolist: if (defaultToggles.hatsMacro) equipHat(hats.demolist); break;
  1799. };
  1800. });
  1801.  
  1802. document.addEventListener("keyup", event => {
  1803. if (!checkChat()) return;
  1804. const pressedKey = event.code;
  1805. if (["KeyW", "KeyA", "KeyS", "KeyD"].includes(pressedKey)) {
  1806. if (pressedKey === "KeyW") copyMove &= -2;
  1807. if (pressedKey === "KeyA") copyMove &= -5;
  1808. if (pressedKey === "KeyS") copyMove &= -3;
  1809. if (pressedKey === "KeyD") copyMove &= -9;
  1810. };
  1811. if (Object.values(binds).includes(pressedKey)) Object.values(placement).forEach(action => action.stop(pressedKey));
  1812. });
  1813.  
  1814. let objectsCounts = {
  1815. limit: 0,
  1816. count: 0,
  1817. }
  1818.  
  1819. const hasCount = (type) => {
  1820. return objectsCounts.count < objectsCounts.limit;
  1821. }
  1822.  
  1823. const maxObjCount = [0, 0, 0, 100, 30, 8, 2, 12, 32, 1, 2];
  1824. window.drawItemBar = (ctx, imageData, index) => {
  1825. const limit = maxObjCount[window.weapons[window.stats[Sploop.itemsID][index]][Sploop.weaponID2]];
  1826. const crntCount = window.stats[Sploop.objCount][window.weapons[window.stats[Sploop.itemsID][index]][Sploop.weaponID2]];
  1827. objectsCounts.limit = limit;
  1828. objectsCounts.count = crntCount;
  1829. if (limit == 0) return;
  1830. const text = `${crntCount}/${limit}`;
  1831. ctx.save();
  1832. ctx.font = "900 20px Montserrat";
  1833. ctx.fillStyle = "#fff";
  1834. ctx.fillText(text, imageData[Sploop.x] + imageData.width - ctx.measureText(text).width - 10, imageData[Sploop.y] + 25);
  1835. ctx.strokeStyle = "#000";
  1836. ctx.strokeText(text, imageData[Sploop.x] + imageData.width - ctx.measureText(text).width - 10, imageData[Sploop.y] + 25);
  1837. ctx.restore();
  1838. };
  1839.  
  1840. const TYPEOF = value => Object.prototype.toString.call(value).slice(8, -1).toLowerCase();
  1841. const NumberSystem = [
  1842. { radix: 2, prefix: "0b0*" },
  1843. { radix: 8, prefix: "0+" },
  1844. { radix: 10, prefix: "" },
  1845. { radix: 16, prefix: "0x0*" }
  1846. ];
  1847. class Regex {
  1848. constructor(code, unicode) {
  1849. this.code = this.COPY_CODE = code;
  1850. this.unicode = unicode || false;
  1851. this.hooks = {};
  1852. }
  1853.  
  1854. static parseValue = value => {
  1855. try { return Function(`return (${value})`)(); }
  1856. catch (err) { return null; }
  1857. };
  1858.  
  1859. isRegexp = value => TYPEOF(value) === "regexp";
  1860.  
  1861. generateNumberSystem = int => `(?:${NumberSystem.map(({ prefix, radix }) => prefix + int.toString(radix)).join("|")})`;
  1862.  
  1863. parseVariables = regex => regex.replace(/\{VAR\}/g, "(?:let|var|const)")
  1864. .replace(/\{QUOTE\}/g, "['\"`]")
  1865. .replace(/ARGS\{(\d+)\}/g, (_, count) => (Array(Number(count)).fill("\\w+")).join("\\s*,\\s*"))
  1866. .replace(/NUMBER\{(\d+)\}/g, (_, int) => this.generateNumberSystem(Number(int)));
  1867.  
  1868. format = (name, inputRegex, flags) => {
  1869. const regex = Array.isArray(inputRegex) ? inputRegex.map(exp => this.isRegexp(exp) ? exp.source : exp).join("\\s*") : this.isRegexp(inputRegex) ? inputRegex.source : "";
  1870. let parsedRegex = this.parseVariables(regex);
  1871.  
  1872. if (this.unicode) {
  1873. parsedRegex = parsedRegex.replace(/\\w/g, "(?:[^\\x00-\\x7F-]|\\$|\\w)");
  1874. }
  1875.  
  1876. const expression = new RegExp(parsedRegex.replace(/\{INSERT\}/, ""), flags);
  1877. return parsedRegex.includes("{INSERT}") ? new RegExp(parsedRegex, flags) : expression;
  1878. };
  1879.  
  1880. template = (type, name, regex, substr) => {
  1881. const expression = new RegExp(`(${this.format(name, regex).source})`);
  1882. const match = this.code.match(expression) || [];
  1883. this.code = this.code.replace(expression, type === 0 ? "$1" + substr : substr + "$1");
  1884. return match;
  1885. };
  1886.  
  1887. match = (name, regex, flags, debug = false) => {
  1888. const expression = this.format(name, regex, flags);
  1889. const match = this.code.match(expression) || [];
  1890. this.hooks[name] = { expression, match };
  1891. return match;
  1892. };
  1893.  
  1894. matchAll = (name, regex, debug = false) => {
  1895. const expression = this.format(name, regex, "g");
  1896. const matches = [...this.code.matchAll(expression)];
  1897. this.hooks[name] = { expression, match: matches };
  1898. return matches;
  1899. };
  1900.  
  1901. replace = (name, regex, substr, flags) => {
  1902. const expression = this.format(name, regex, flags);
  1903. this.code = this.code.replace(expression, substr);
  1904. return this.code.match(expression) || [];
  1905. };
  1906.  
  1907. replaceAll = (name, regex, substr, flags) => {
  1908. const expression = this.format(name, regex, "g");
  1909. this.code = this.code.replaceAll(expression, substr);
  1910. return this.code.match(expression) || [];
  1911. };
  1912.  
  1913. append = (name, regex, substr) => this.template(0, name, regex, substr);
  1914.  
  1915. prepend = (name, regex, substr) => this.template(1, name, regex, substr);
  1916.  
  1917. insert = (name, regex, substr) => {
  1918. const { source } = this.format(name, regex);
  1919. if (!source.includes("{INSERT}")) throw new Error("Your regexp must contain {INSERT} keyword");
  1920. const findExpression = new RegExp(source.replace(/^(.*)\{INSERT\}(.*)$/, "($1)($2)"));
  1921. this.code = this.code.replace(findExpression, `$1${substr}$2`);
  1922. return this.code.match(findExpression);
  1923. };
  1924. };
  1925.  
  1926. let Sploop;
  1927. const applyHooks = code => {
  1928. const Hook = new Regex(code, true);
  1929. window.COPY_CODE = (Hook.COPY_CODE.match(/^(\(function \w+\(\w+\)\{.+)\(.+?\);$/) || [])[1];
  1930. Hook.append("EXTERNAL fix", /\(function (\w+)\(\w+\)\{/, "let $2 = eval(`(() => ${COPY_CODE})()`);delete window.COPY_CODE;console.log(1);");
  1931. const myData = Hook.match('myPlayer', /=(\w.get\(\w{2}\));\w&&\w\(\)/)[1];
  1932. const X = Hook.match('playerX', /\{this\.(\w{2})=\w\|\|0/)[1];
  1933. const Y = Hook.match('playerY', /,this\.(\w{2})=\w\|\|0\}/)[1];
  1934. const ID = Hook.match('ID', /&&\w{2}===\w\.(\w{2})\){/)[1];
  1935. const ID2 = Hook.match('ID2', /-1!==\w+\.(\w+)&&/)[1];
  1936. const currentWeapon = Hook.match("crntWeapon", /,\w.(\w{2})===/)[1];
  1937. const angle = Hook.match("angle", /;\w.(\w{2})=\w\(\)/)[1];
  1938. const weaponName = Hook.match("wpnName", /(\w{2}):"XX/)[1];
  1939. const health = Hook.match("health", /(\w{2})<<8;/)[1];
  1940. const weaponDamage = Hook.match("wpnDamage", /(\w{2}):32,reload:300/)[1];
  1941. const teamID = Hook.match('test', /,\w=\w.(\w{2})\|.+?\<\<8/)[1];
  1942. const radius = Hook.match("radius", /(\w{2}):220/)[1];
  1943. const [, currentItem, hat] = Hook.match("hat", /\(\w+\.(\w+)\|\w+\.(\w+)<<NUMBER{8}\)/);
  1944. const inWhichObject = Hook.match("iwo", /110\).+?,1===\w.(\w{2})&&!\w{2}/)[1];
  1945. const weaponID = Hook.match('el', /(\w{2}):0,\w{2}:22,reload:150/)[1];
  1946. const itemsID = Hook.match("IDs", />1\){.{3}(\w{2})/)[1];
  1947. const weaponID2 = Hook.matchAll('el', /,(\w+):9,\w+:2/)[1][1];
  1948. const objCount = Hook.match("objCount", /\),this.(\w{2})=\w\):/)[1];
  1949. const size = Hook.match("size", /\.(\w{2})\+50/)[1];
  1950. const objQuantity = Hook.match("Quantity", /\),this.(\w{2})=\w\):/)[1];
  1951. const itemBar = Hook.match("defaultData", /(\W\w+>NUMBER{1}\W.+?(\w+)\.(\w+).+?)function/)[3];
  1952. Sploop = {
  1953. myPlayer: {
  1954. myData: myData,
  1955. x: `${myData}.${X}`,
  1956. y: `${myData}.${Y}`,
  1957. id: `${myData}.${ID}`,
  1958. teamID: `${myData}.${teamID}`,
  1959. angle: `${myData}.${angle}`
  1960. },
  1961. x: X,
  1962. y: Y,
  1963. id: ID,
  1964. id2: ID2,
  1965. hat: hat,
  1966. type: 'type',
  1967. angle: angle,
  1968. health: health,
  1969. radius: radius,
  1970. teamID: teamID,
  1971. itemsID: itemsID,
  1972. temBar: itemBar,
  1973. objCount: objCount,
  1974. weaponID: weaponID,
  1975. weaponID2: weaponID2,
  1976. weaponName: weaponName,
  1977. objQuantity: objQuantity,
  1978. weaponDamage: weaponDamage,
  1979. currentWeapon: currentWeapon,
  1980. inWhichObject: inWhichObject
  1981. };
  1982. Hook.append("itemCounter", /AGE 0.+?\[(\w+)\][,;](\w+)\.\w+\((\w+)\)([,;])/, `window.drawItemBar($4,$3,$2)$5`);
  1983. Hook.replace("blockMouse", /\|\|(\w+\(\w+\(\)\)\))/, `||!window.inTrap && $1;`);
  1984. Hook.append("renderer", /1}function \w+\((\w),(\w)\){/, `window.render($2, $3);`);
  1985. Hook.replace("grid", /1,(\w{2})=!0/, `1, $1=window.grid`);
  1986. Hook.replace("grid", /,\w{2}(&&\w+\(\w,)/, `,window.grid$1`);
  1987. Hook.append("updateFPS", /const (\w)=\+new Date,.+?3;/, `window.updateFPSCounter($2);`);
  1988. Hook.replace("renderItems", /(\(\w+\.\w+\+\w+,\w+\.\w+\+\w+\).+?\w+\(\).+?\w+\.\w+\.\w+\)([,;]))/, `$1window.drawMarkers(...arguments)$2`);
  1989. const args = Hook.match("drawEntityInfo", /-NUMBER{50},.+?function \w+\((ARGS{3})\)\{/)[1];
  1990. Hook.append('drawEntityInfo', /=.5;/, `try {window.getEntityData(${args});} catch(err) {};`)
  1991. Hook.append("getMsg", /0;fu.{10}(\w).{2}/, `window.receiveMsg($2);`);
  1992. Hook.append("getWS", /(\w{2})=new \w{2}\("".{31}/, `,window.getWS($2)`);
  1993. const weaponList = Hook.match("weaponList", /\?Math\.PI\/2.+?(\w\(\))/)[1];
  1994. Hook.replace("defaultData", /(\W\w+>NUMBER{1}\W.+?(\w+)\.(\w+).+?)function/, `$1window.stats=$2;window.weapons = ${weaponList};window.sprites = tt();function`);
  1995. Hook.append('attackReload', /\+=NUMBER{5}.+?(\w+)=.+?(\w+)=.+?(\w+)=.+?(\w+)=.+?(\w+)=.+?;/, `window.attackAnimation($2, $3, $4, $5, $6);`)
  1996. return Hook.code;
  1997. };
  1998.  
  1999. window.eval = new Proxy(window.eval, {
  2000. apply(target, _this, args) {
  2001. const code = args[0];
  2002. if (code.length > 100000) {
  2003. args[0] = applyHooks(code);
  2004. window.eval = target;
  2005. }
  2006. return target.apply(_this, args);
  2007. }
  2008. });