Greasy Fork is available in English.

Dsync Client [Sploop.io]

The most advanced hack for sploop.io

  1. // ==UserScript==
  2. // @name Dsync Client [Sploop.io]
  3. // @author Murka
  4. // @description The most advanced hack for sploop.io
  5. // @icon https://sploop.io/img/ui/favicon.png
  6. // @version 1.0.21
  7. // @match *://sploop.io/*
  8. // @run-at document-start
  9. // @grant none
  10. // @license MIT
  11. // @namespace https://greasyfork.org/users/919633
  12. // ==/UserScript==
  13. /* jshint esversion:6 */
  14.  
  15. /*
  16. Author: Murka
  17. Github: https://github.com/Murka007/Dsync-client
  18. Discord: https://discord.gg/sG9cyfGPj5
  19. Greasyfork: https://greasyfork.org/en/scripts/449995-dsync-client-sploop-io
  20.  
  21. I need your support, please follow these steps:
  22. 1. Join my DISCORD server
  23. 2. Write a feedback about this script on GREASYFORK "script works, thank you so much"
  24. 3. Star my repository on GITHUB
  25. */
  26.  
  27. Function("(" + ((GM_info) => {
  28. "use strict";
  29. var __webpack_modules__ = {
  30. 147: module => {
  31. module.exports = {
  32. i8: "1.0.21"
  33. };
  34. }
  35. };
  36. var __webpack_module_cache__ = {};
  37. function __webpack_require__(moduleId) {
  38. var cachedModule = __webpack_module_cache__[moduleId];
  39. if (cachedModule !== undefined) {
  40. return cachedModule.exports;
  41. }
  42. var module = __webpack_module_cache__[moduleId] = {
  43. exports: {}
  44. };
  45. __webpack_modules__[moduleId](module, module.exports, __webpack_require__);
  46. return module.exports;
  47. }
  48. (() => {
  49. __webpack_require__.d = (exports, definition) => {
  50. for (var key in definition) {
  51. if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
  52. Object.defineProperty(exports, key, {
  53. enumerable: true,
  54. get: definition[key]
  55. });
  56. }
  57. }
  58. };
  59. })();
  60. (() => {
  61. __webpack_require__.o = (obj, prop) => Object.prototype.hasOwnProperty.call(obj, prop);
  62. })();
  63. var __webpack_exports__ = {};
  64. (() => {
  65. __webpack_require__.d(__webpack_exports__, {
  66. sv: () => Dsync,
  67. Ih: () => controller,
  68. vU: () => error,
  69. cM: () => log,
  70. lZ: () => pingCount,
  71. fA: () => target
  72. });
  73. var code = '<header> <span>Dsync Client</span> <div id="version"> <svg width="15" height="15" viewBox="0 0 16 16" version="1.1"> <path d="M11.75 2.5a.75.75 0 100 1.5.75.75 0 000-1.5zm-2.25.75a2.25 2.25 0 113 2.122V6A2.5 2.5 0 0110 8.5H6a1 1 0 00-1 1v1.128a2.251 2.251 0 11-1.5 0V5.372a2.25 2.25 0 111.5 0v1.836A2.492 2.492 0 016 7h4a1 1 0 001-1v-.628A2.25 2.25 0 019.5 3.25zM4.25 12a.75.75 0 100 1.5.75.75 0 000-1.5zM3.5 3.25a.75.75 0 111.5 0 .75.75 0 01-1.5 0z"></path> </svg> <span></span> </div> <svg id="close-menu" class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 30 30" width="30px" height="30px"> <path d="M 7 4 C 6.744125 4 6.4879687 4.0974687 6.2929688 4.2929688 L 4.2929688 6.2929688 C 3.9019687 6.6839688 3.9019687 7.3170313 4.2929688 7.7070312 L 11.585938 15 L 4.2929688 22.292969 C 3.9019687 22.683969 3.9019687 23.317031 4.2929688 23.707031 L 6.2929688 25.707031 C 6.6839688 26.098031 7.3170313 26.098031 7.7070312 25.707031 L 15 18.414062 L 22.292969 25.707031 C 22.682969 26.098031 23.317031 26.098031 23.707031 25.707031 L 25.707031 23.707031 C 26.098031 23.316031 26.098031 22.682969 25.707031 22.292969 L 18.414062 15 L 25.707031 7.7070312 C 26.098031 7.3170312 26.098031 6.6829688 25.707031 6.2929688 L 23.707031 4.2929688 C 23.316031 3.9019687 22.682969 3.9019687 22.292969 4.2929688 L 15 11.585938 L 7.7070312 4.2929688 C 7.5115312 4.0974687 7.255875 4 7 4 z"/> </svg> </header>';
  74. const Header = code;
  75. var Navbar_code = '<aside id="navbar-container"> <button class="open-menu active">Keybinds</button> <button class="open-menu">Combat</button> <button class="open-menu">Visuals</button> <button class="open-menu">Misc</button> <button class="open-menu bottom-align">Credits</button> </aside>';
  76. const Navbar = Navbar_code;
  77. var Keybinds_code = '<div class="menu-page opened"> <h1>Keybinds</h1> <p>Setup keybinds for items, weapons and hats</p> <div class="section"> <div class="section-title"> <h2>Items & Weapons</h2> <svg class="icon" version="1.0" xmlns="http://www.w3.org/2000/svg" width="64.000000pt" height="64.000000pt" viewBox="0 0 64.000000 64.000000" preserveAspectRatio="xMidYMid meet"> <g transform="translate(0.000000,64.000000) scale(0.100000,-0.100000)" stroke="none"> <path d="M160 575 l-54 -55 99 -100 100 -100 -100 -100 -100 -100 58 -57 57 -58 157 158 158 157 -155 155 c-85 85 -157 155 -160 155 -3 0 -30 -25 -60 -55z"/> </g> </svg> </div> <div class="section-content"> <div class="split-section"> <div class="section-option"> <span class="section-option-title">Primary</span> <button id="primary" class="section-option-hotkeyInput"></button> </div> <div class="section-option"> <span class="section-option-title">Secondary</span> <button id="secondary" class="section-option-hotkeyInput"></button> </div> <div class="section-option"> <span class="section-option-title">Heal</span> <button id="heal" class="section-option-hotkeyInput"></button> </div> <div class="section-option"> <span class="section-option-title">Wall</span> <button id="wall" class="section-option-hotkeyInput"></button> </div> <div class="section-option"> <span class="section-option-title">Spike</span> <button id="spike" class="section-option-hotkeyInput"></button> </div> <div class="section-option"> <span class="section-option-title">Windmill</span> <button id="windmill" class="section-option-hotkeyInput"></button> </div> </div> <div class="split-section"> <div class="section-option"> <span class="section-option-title">Trap/Boost</span> <button id="trap" class="section-option-hotkeyInput"></button> </div> <div class="section-option"> <span class="section-option-title">Turret</span> <button id="turret" class="section-option-hotkeyInput"></button> </div> <div class="section-option"> <span class="section-option-title">Tree/Stone</span> <button id="tree" class="section-option-hotkeyInput"></button> </div> <div class="section-option"> <span class="section-option-title">Platform</span> <button id="platform" class="section-option-hotkeyInput"></button> </div> <div class="section-option"> <span class="section-option-title">Cosy bed</span> <button id="spawn" class="section-option-hotkeyInput"></button> </div> </div> </div> </div> <div class="section"> <div class="section-title"> <h2>Combat & Functions</h2> <svg class="icon" version="1.0" xmlns="http://www.w3.org/2000/svg" width="64.000000pt" height="64.000000pt" viewBox="0 0 64.000000 64.000000" preserveAspectRatio="xMidYMid meet"> <g transform="translate(0.000000,64.000000) scale(0.100000,-0.100000)" stroke="none"> <path d="M160 575 l-54 -55 99 -100 100 -100 -100 -100 -100 -100 58 -57 57 -58 157 158 158 157 -155 155 c-85 85 -157 155 -160 155 -3 0 -30 -25 -60 -55z"/> </g> </svg> </div> <div class="section-content"> <div class="section-option"> <span class="section-option-title">Invisible hit</span> <button id="invisibleHit" class="section-option-hotkeyInput"></button> </div> <div class="section-option"> <span class="section-option-title">Spike insta</span> <button id="spikeInsta" class="section-option-hotkeyInput"></button> </div> <div class="section-option"> <span class="section-option-title"> Fast break <span class="tooltip"> * <span class="tooltip-text">When you press a key, it equips a demolist and starts attacking</span> </span> </span> <button id="fastBreak" class="section-option-hotkeyInput"></button> </div> <div class="section-option"> <span class="section-option-title">Zoom In</span> <button class="section-option-hotkeyInput smaller">WHEEL DN</button> </div> <div class="section-option"> <span class="section-option-title">Toggle Dsync Menu</span> <button id="toggleMenu" class="section-option-hotkeyInput"></button> </div> <div class="section-option"> <span class="section-option-title">Zoom Out</span> <button class="section-option-hotkeyInput smaller">WHEEL UP</button> </div> </div> </div> <div class="section"> <div class="section-title"> <h2>Hats</h2> <svg class="icon" version="1.0" xmlns="http://www.w3.org/2000/svg" width="64.000000pt" height="64.000000pt" viewBox="0 0 64.000000 64.000000" preserveAspectRatio="xMidYMid meet"> <g transform="translate(0.000000,64.000000) scale(0.100000,-0.100000)" stroke="none"> <path d="M160 575 l-54 -55 99 -100 100 -100 -100 -100 -100 -100 58 -57 57 -58 157 158 158 157 -155 155 c-85 85 -157 155 -160 155 -3 0 -30 -25 -60 -55z"/> </g> </svg> </div> <div class="section-content"> <div class="section-option"> <span class="section-option-title">Unequip hat</span> <button id="unequip" class="section-option-hotkeyInput"></button> </div> <div class="section-option"> <span class="section-option-title">Bush hat</span> <button id="bush" class="section-option-hotkeyInput"></button> </div> <div class="section-option"> <span class="section-option-title">Berserker</span> <button id="berserker" class="section-option-hotkeyInput"></button> </div> <div class="section-option"> <span class="section-option-title">Jungle gear</span> <button id="jungle" class="section-option-hotkeyInput"></button> </div> <div class="section-option"> <span class="section-option-title">Crystal gear</span> <button id="crystal" class="section-option-hotkeyInput"></button> </div> <div class="section-option"> <span class="section-option-title">Spike gear</span> <button id="spikegear" class="section-option-hotkeyInput"></button> </div> <div class="section-option"> <span class="section-option-title">Immunity gear</span> <button id="immunity" class="section-option-hotkeyInput"></button> </div> <div class="section-option"> <span class="section-option-title">Boost hat</span> <button id="boost" class="section-option-hotkeyInput"></button> </div> <div class="section-option"> <span class="section-option-title">Apple hat</span> <button id="applehat" class="section-option-hotkeyInput"></button> </div> <div class="section-option"> <span class="section-option-title">Scuba gear</span> <button id="scuba" class="section-option-hotkeyInput"></button> </div> <div class="section-option"> <span class="section-option-title">Hood</span> <button id="hood" class="section-option-hotkeyInput"></button> </div> <div class="section-option"> <span class="section-option-title">Demolist</span> <button id="demolist" class="section-option-hotkeyInput"></button> </div> </div> </div> <div class="section"> <div class="section-title"> <h2>Controls & Movement</h2> <svg class="icon" version="1.0" xmlns="http://www.w3.org/2000/svg" width="64.000000pt" height="64.000000pt" viewBox="0 0 64.000000 64.000000" preserveAspectRatio="xMidYMid meet"> <g transform="translate(0.000000,64.000000) scale(0.100000,-0.100000)" stroke="none"> <path d="M160 575 l-54 -55 99 -100 100 -100 -100 -100 -100 -100 58 -57 57 -58 157 158 158 157 -155 155 c-85 85 -157 155 -160 155 -3 0 -30 -25 -60 -55z"/> </g> </svg> </div> <div class="section-content"> <div class="section-option"> <span class="section-option-title">Up</span> <button id="up" class="section-option-hotkeyInput"></button> </div> <div class="section-option"> <span class="section-option-title">Left</span> <button id="left" class="section-option-hotkeyInput"></button> </div> <div class="section-option"> <span class="section-option-title">Down</span> <button id="down" class="section-option-hotkeyInput"></button> </div> <div class="section-option"> <span class="section-option-title">Right</span> <button id="right" class="section-option-hotkeyInput"></button> </div> <div class="split"></div> <div class="section-option"> <span class="section-option-title">Auto attack</span> <button id="autoattack" class="section-option-hotkeyInput"></button> </div> <div class="section-option"> <span class="section-option-title">Lock rotation</span> <button id="lockRotation" class="section-option-hotkeyInput"></button> </div> <div class="section-option"> <span class="section-option-title">Open chat</span> <button id="openChat" class="section-option-hotkeyInput"></button> </div> <div class="section-option"> <span class="section-option-title">Upgrade scythe</span> <button id="upgradeScythe" class="section-option-hotkeyInput"></button> </div> </div> </div> </div>';
  78. const Keybinds = Keybinds_code;
  79. var Combat_code = '<div class="menu-page"> <h1>Combat</h1> <p>Modify combat settings, change pvp behavior</p> <div class="section opened"> <div class="section-title"> <h2>Placement</h2> </div> <div class="section-content one-row"> <div class="section-option"> <span class="section-option-title"> Placement speed <span class="tooltip"> * <span class="tooltip-text">The higher value, the faster you place</span> </span> </span> <label class="slider"> <input id="placementSpeed" min="1" max="30" type="range"> <span class="slider-value">30</span> </label> </div> <div class="section-option"> <span class="section-option-title">Placement type</span> <select id="placementType"></select> </div> <div class="section-option"> <span class="section-option-title">Autobed</span> <label class="switch-checkbox"> <input id="autobed" type="checkbox"> <span></span> </label> </div> <div class="section-option"> <span class="section-option-title">Automill</span> <label class="switch-checkbox"> <input id="automill" type="checkbox"> <span></span> </label> </div> <div class="section-option"> <span class="section-option-title"> Anti fireball <span class="tooltip"> * <span class="tooltip-text">When you collide a fireball, place platform</span> </span> </span> <label class="switch-checkbox"> <input id="antiFireball" type="checkbox"> <span></span> </label> </div> </div> </div> <div class="section opened"> <div class="section-title"> <h2>Healing</h2> </div> <div class="section-content"> <div class="split-section"> <div class="section-option"> <span class="section-option-title">Autoheal</span> <label class="switch-checkbox"> <input id="autoheal" type="checkbox"> <span></span> </label> </div> </div> </div> </div> <div class="section opened"> <div class="section-title"> <h2>Hats</h2> </div> <div class="section-content"> <div class="split-section"> <div class="section-option"> <span class="section-option-title">Jungle On Clown</span> <label class="switch-checkbox"> <input id="jungleOnClown" type="checkbox"> <span></span> </label> </div> <div class="section-option"> <span class="section-option-title"> Equip last hat <span class="tooltip"> * <span class="tooltip-text">On spawn, the last hat you had will be equipped</span> </span> </span> <label class="switch-checkbox"> <input id="lastHat" type="checkbox"> <span></span> </label> </div> <div class="section-option"> <span class="section-option-title">Auto scuba</span> <label class="switch-checkbox"> <input id="autoScuba" type="checkbox"> <span></span> </label> </div> </div> </div> </div> <div class="section opened"> <div class="section-title"> <h2>Autoaim</h2> </div> <div class="section-content"> <div class="split-section"> <div class="section-option"> <span class="section-option-title">Melee</span> <label class="switch-checkbox"> <input id="meleeAim" type="checkbox"> <span></span> </label> </div> <div class="section-option"> <span class="section-option-title">Bow</span> <label class="switch-checkbox"> <input id="bowAim" type="checkbox"> <span></span> </label> </div> <div class="section-option"> <span class="section-option-title">Spike insta</span> <label class="switch-checkbox"> <input id="spikeInstaAim" type="checkbox"> <span></span> </label> </div> <div class="section-option"> <span class="section-option-title">Autosync</span> <label class="switch-checkbox"> <input id="autosync" type="checkbox"> <span></span> </label> </div> <div class="section-option"> <span class="section-option-title">Autoboost follow</span> <label class="switch-checkbox"> <input id="autoboostFollow" type="checkbox"> <span></span> </label> </div> </div> </div> </div> </div>';
  80. const Combat = Combat_code;
  81. var Visuals_code = '<div class="menu-page"> <h1>Visuals</h1> <p>Customize your visuals, or you can disable it for performance</p> <div class="section opened"> <div class="section-title"> <h2>Tracers</h2> </div> <div class="section-content"> <div class="section-option"> <span class="section-option-title">Enemies</span> <div class="content"> <button class="default-color" title="Reset Color"></button> <input id="enemyColor" type="color"> <label class="switch-checkbox"> <input id="enemyTracers" type="checkbox"> <span></span> </label> </div> </div> <div class="section-option"> <span class="section-option-title">Arrows</span> <label class="switch-checkbox"> <input id="arrows" type="checkbox"> <span></span> </label> </div> <div class="section-option"> <span class="section-option-title">Teammates</span> <div class="content"> <button class="default-color" title="Reset Color"></button> <input id="teammateColor" type="color"> <label class="switch-checkbox"> <input id="teammateTracers" type="checkbox"> <span></span> </label> </div> </div> <div class="section-option"> <span class="section-option-title">Rainbow colors</span> <label class="switch-checkbox"> <input id="rainbow" type="checkbox"> <span></span> </label> </div> <div class="section-option"> <span class="section-option-title">Animals</span> <div class="content"> <button class="default-color" title="Reset Color"></button> <input id="animalColor" type="color"> <label class="switch-checkbox"> <input id="animalTracers" type="checkbox"> <span></span> </label> </div> </div> </div> </div> <div class="section opened"> <div class="section-title"> <h2>Markers</h2> </div> <div class="section-content"> <div class="section-option"> <span class="section-option-title">Your markers</span> <div class="content"> <button class="default-color" title="Reset Color"></button> <input id="itemMarkersColor" type="color"> <label class="switch-checkbox"> <input id="itemMarkers" type="checkbox"> <span></span> </label> </div> </div> <div class="section-option"> <span class="section-option-title">Teammates</span> <div class="content"> <button class="default-color" title="Reset Color"></button> <input id="teammateMarkersColor" type="color"> <label class="switch-checkbox"> <input id="teammateMarkers" type="checkbox"> <span></span> </label> </div> </div> <div class="section-option"> <span class="section-option-title">Enemies</span> <div class="content"> <button class="default-color" title="Reset Color"></button> <input id="enemyMarkersColor" type="color"> <label class="switch-checkbox"> <input id="enemyMarkers" type="checkbox"> <span></span> </label> </div> </div> <div class="section-option"> <span class="section-option-title"> Trap activated <span class="tooltip"> * <span class="tooltip-text">When the player or animal will be trapped, marker will change color</span> </span> </span> <div class="content"> <button class="default-color" title="Reset Color"></button> <input id="trapActivatedColor" type="color"> <label class="switch-checkbox"> <input id="trapActivated" type="checkbox"> <span></span> </label> </div> </div> </div> </div> <div class="section opened"> <div class="section-title"> <h2>Reload bars</h2> </div> <div class="section-content"> <div class="section-option"> <span class="section-option-title">Hat reload bar</span> <div class="content"> <button class="default-color" title="Reset Color"></button> <input id="hatReloadBarColor" type="color"> <label class="switch-checkbox"> <input id="hatReloadBar" type="checkbox"> <span></span> </label> </div> </div> <div class="section-option"> <span class="section-option-title">Fireball reload bar</span> <div class="content"> <button class="default-color" title="Reset Color"></button> <input id="fireballReloadBarColor" type="color"> <label class="switch-checkbox"> <input id="fireballReloadBar" type="checkbox"> <span></span> </label> </div> </div> <div class="section-option"> <span class="section-option-title">Turret reload bar</span> <div class="content"> <button class="default-color" title="Reset Color"></button> <input id="turretReloadBarColor" type="color"> <label class="switch-checkbox"> <input id="turretReloadBar" type="checkbox"> <span></span> </label> </div> </div> <div class="section-option"> <span class="section-option-title">Weapon reload bar</span> <div class="content"> <button class="default-color" title="Reset Color"></button> <input id="weaponReloadBarColor" type="color"> <label class="switch-checkbox"> <input id="weaponReloadBar" type="checkbox"> <span></span> </label> </div> </div> <div class="section-option"> <span class="section-option-title">Smooth reload bar</span> <label class="switch-checkbox"> <input id="smoothReloadBar" type="checkbox"> <span></span> </label> </div> </div> </div> <div class="section opened"> <div class="section-title"> <h2>Player</h2> </div> <div class="section-content"> <div class="section-option"> <span class="section-option-title">Anti hood</span> <label class="switch-checkbox"> <input id="showHoods" type="checkbox"> <span></span> </label> </div> <div class="section-option"> <span class="section-option-title">Render HP</span> <label class="switch-checkbox"> <input id="drawHP" type="checkbox"> <span></span> </label> </div> <div class="section-option"> <span class="section-option-title">Item counter</span> <label class="switch-checkbox"> <input id="itemCounter" type="checkbox"> <span></span> </label> </div> <div class="section-option"> <span class="section-option-title"> Visual aim <span class="tooltip"> * <span class="tooltip-text">It will show where are you aiming</span> </span> </span> <label class="switch-checkbox"> <input id="visualAim" type="checkbox"> <span></span> </label> </div> <div class="section-option"> <span class="section-option-title">Hide chat messages</span> <label class="switch-checkbox"> <input id="hideMessages" type="checkbox"> <span></span> </label> </div> </div> </div> <div class="section opened"> <div class="section-title"> <h2>Appearance</h2> </div> <div class="section-content"> <div class="split-section"> <div class="section-option"> <span class="section-option-title">Custom skins</span> <label class="switch-checkbox"> <input id="customSkins" type="checkbox"> <span></span> </label> </div> <div class="section-option"> <span class="section-option-title">Skin</span> <div class="content"> <img> <button data-type="popup" data-id="skin" class="button">Select skin</button> </div> </div> <div class="section-option"> <span class="section-option-title">Accessory</span> <div class="content"> <img> <button data-type="popup" data-id="accessory" class="button">Select accessory</button> </div> </div> <div class="section-option"> <span class="section-option-title">Back</span> <div class="content"> <img> <button data-type="popup" data-id="back" class="button">Select back</button> </div> </div> </div> </div> </div> <div class="section opened"> <div class="section-title"> <h2>Other</h2> </div> <div class="section-content"> <div class="section-option"> <span class="section-option-title">Windmill rotation</span> <label class="switch-checkbox"> <input id="windmillRotation" type="checkbox"> <span></span> </label> </div> <div class="section-option"> <span class="section-option-title"> Possible shots <span class="tooltip"> * <span class="tooltip-text">Draws a crosshair on entities that can be hit by a projectile</span> </span> </span> <label class="switch-checkbox"> <input id="possibleShots" type="checkbox"> <span></span> </label> </div> </div> </div> </div>';
  82. const Visuals = Visuals_code;
  83. var Misc_code = '<div class="menu-page"> <h1>Misc</h1> <p>Customize misc settings, add autochat messages, reset settings</p> <div class="section opened"> <div class="section-title"> <h2>Chat</h2> </div> <div class="section-content one-row"> <div class="section-option"> <span class="section-option-title">Auto chat</span> <div class="content"> <input class="input autochat" type="text" maxlength="35"> <input class="input autochat" type="text" maxlength="35"> <input class="input autochat" type="text" maxlength="35"> <input class="input autochat" type="text" maxlength="35"> <label class="switch-checkbox"> <input id="autochat" type="checkbox"> <span></span> </label> </div> </div> <div class="section-option"> <span class="section-option-title"> Kill message <span class="tooltip"> * <span class="tooltip-text left"> <div>Variables:</div> <div><span class="highlight">{KILL}</span> - amount of kills</div> <div><span class="highlight">{NAME}</span> - name of the player you killed</div> </span> </span> </span> <div class="content"> <input id="killMessage" class="input" type="text" maxlength="35"> <label class="switch-checkbox"> <input id="kill" type="checkbox"> <span></span> </label> </div> </div> </div> </div> <div class="section opened"> <div class="section-title"> <h2>Other</h2> </div> <div class="section-content"> <div class="section-option"> <span class="section-option-title">Auto spawn</span> <label class="switch-checkbox"> <input id="autospawn" type="checkbox"> <span></span> </label> </div> <div class="section-option"> <span class="section-option-title"> Smooth zoom <span class="tooltip"> * <span class="tooltip-text">Disable for performance</span> </span> </span> <label class="switch-checkbox"> <input id="smoothZoom" type="checkbox"> <span></span> </label> </div> <div class="section-option"> <span class="section-option-title"> Skip upgrades <span class="tooltip"> * <span class="tooltip-text">When you have only 1 item in the upgradebar, it will automatically select it</span> </span> </span> <label class="switch-checkbox"> <input id="skipUpgrades" type="checkbox"> <span></span> </label> </div> <div class="section-option"> <span class="section-option-title"> Invis hit toggle <span class="tooltip"> * <span class="tooltip-text">If enabled, invisible hit hotkey will work in toggle mode. Useful when you don\'t want to hold this button permanently</span> </span> </span> <label class="switch-checkbox"> <input id="invisHitToggle" type="checkbox"> <span></span> </label> </div> <div class="section-option"> <span class="section-option-title">Reverse zoom</span> <label class="switch-checkbox"> <input id="reverseZoom" type="checkbox"> <span></span> </label> </div> <div class="section-option"> <span class="section-option-title">Auto accept</span> <label class="switch-checkbox"> <input id="autoAccept" type="checkbox"> <span></span> </label> </div> <div class="section-option"> <span class="section-option-title">Always connect to</span> <select id="connectTo" class="smaller"></select> </div> </div> </div> <div class="section opened"> <div class="section-title"> <h2>Menu</h2> </div> <div class="section-content one-row"> <div class="section-option"> <span class="section-option-title">Menu transparency</span> <label class="switch-checkbox"> <input id="menuTransparency" type="checkbox"> <span></span> </label> </div> <div class="section-option"> <div class="content-double"> <button id="reset-settings" class="button red">Reset settings</button> <button id="download-settings" class="button">Download settings</button> <div class="form-upload"> <input id="upload-settings" type="file" accept=".txt"> <span class="light">DRAG SETTINGS FILE HERE OR <span class="light-extra">BROWSE</span></span> </div> </div> </div> </div> </div> </div>';
  84. const Misc = Misc_code;
  85. var Credits_code = '<div class="menu-page"> <h1>Credits</h1> <P>Some details about the script and links to my socials</P> <div class="section opened"> <div class="section-content" style="max-height:100%"> <div class="split-section"> <div class="section-option text"> <span class="section-option-title">Author</span> <span class="text-value">Murka</span> </div> <div class="section-option text"> <svg class="icon" version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"> <path d="M512 12.672c-282.88 0-512 229.248-512 512 0 226.261 146.688 418.133 350.080 485.76 25.6 4.821 34.987-11.008 34.987-24.619 0-12.16-0.427-44.373-0.64-87.040-142.421 30.891-172.459-68.693-172.459-68.693-23.296-59.093-56.96-74.88-56.96-74.88-46.379-31.744 3.584-31.104 3.584-31.104 51.413 3.584 78.421 52.736 78.421 52.736 45.653 78.293 119.851 55.68 149.12 42.581 4.608-33.109 17.792-55.68 32.427-68.48-113.707-12.8-233.216-56.832-233.216-253.013 0-55.893 19.84-101.547 52.693-137.387-5.76-12.928-23.040-64.981 4.48-135.509 0 0 42.88-13.739 140.8 52.48 40.96-11.392 84.48-17.024 128-17.28 43.52 0.256 87.040 5.888 128 17.28 97.28-66.219 140.16-52.48 140.16-52.48 27.52 70.528 10.24 122.581 5.12 135.509 32.64 35.84 52.48 81.493 52.48 137.387 0 196.693-119.68 240-233.6 252.587 17.92 15.36 34.56 46.763 34.56 94.72 0 68.523-0.64 123.563-0.64 140.203 0 13.44 8.96 29.44 35.2 24.32 204.843-67.157 351.403-259.157 351.403-485.077 0-282.752-229.248-512-512-512z"></path> </svg> <a href="https://github.com/Murka007/Dsync-client" class="text-value" target="_blank" title="Give a star please :)">Dsync client</a> </div> <div class="section-option text"> <svg class="icon" version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32"> <path d="M26.963 0c1.875 0 3.387 1.516 3.476 3.3v28.7l-3.569-3.031-1.96-1.784-2.139-1.864 0.893 2.94h-18.717c-1.869 0-3.387-1.42-3.387-3.301v-21.653c0-1.784 1.52-3.303 3.393-3.303h22zM18.805 7.577h-0.040l-0.269 0.267c2.764 0.8 4.101 2.049 4.101 2.049-1.781-0.891-3.387-1.336-4.992-1.516-1.16-0.18-2.32-0.085-3.3 0h-0.267c-0.627 0-1.96 0.267-3.747 0.98-0.623 0.271-0.98 0.448-0.98 0.448s1.336-1.336 4.28-2.049l-0.18-0.18c0 0-2.229-0.085-4.636 1.693 0 0-2.407 4.192-2.407 9.36 0 0 1.333 2.32 4.991 2.408 0 0 0.533-0.711 1.073-1.336-2.053-0.624-2.853-1.872-2.853-1.872s0.179 0.088 0.447 0.267h0.080c0.040 0 0.059 0.020 0.080 0.040v0.008c0.021 0.021 0.040 0.040 0.080 0.040 0.44 0.181 0.88 0.36 1.24 0.533 0.621 0.269 1.42 0.537 2.4 0.715 1.24 0.18 2.661 0.267 4.28 0 0.8-0.18 1.6-0.356 2.4-0.713 0.52-0.267 1.16-0.533 1.863-0.983 0 0-0.8 1.248-2.94 1.872 0.44 0.621 1.060 1.333 1.060 1.333 3.659-0.080 5.080-2.4 5.16-2.301 0-5.16-2.42-9.36-2.42-9.36-2.18-1.619-4.22-1.68-4.58-1.68zM19.029 13.461c0.937 0 1.693 0.8 1.693 1.78 0 0.987-0.76 1.787-1.693 1.787s-1.693-0.8-1.693-1.779c0.003-0.987 0.764-1.784 1.693-1.788zM12.972 13.461c0.933 0 1.688 0.8 1.688 1.78 0 0.987-0.76 1.787-1.693 1.787s-1.693-0.8-1.693-1.779c0-0.987 0.76-1.784 1.699-1.788z"></path> </svg> <a href="https://discord.gg/sG9cyfGPj5" class="text-value" target="_blank" title="Join my discord server">Coding paradise</a> </div> <div class="section-option text"> <svg class="icon" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" viewBox="0 0 96 96"> <circle fill="#36363d" stroke="#6a6a81" stroke-width="2" r="48" cy="48" cx="48"/> <clipPath id="GreasyForkCircleClip" clipPathUnits="userSpaceOnUse"> <circle fill="#000" r="47" cy="48" cx="48"/> </clipPath> <text fill="#9494b8" clip-path="url(#GreasyForkCircleClip)" text-anchor="middle" font-size="18" font-family="\'DejaVu Sans\', Verdana, Arial, \'Liberation Sans\', sans-serif" letter-spacing="-0.75" pointer-events="none" style="-moz-user-select:none;-ms-user-select:none;-webkit-user-select:none;user-select:none"> <tspan x="51" y="13" textLength="57">= null;</tspan> <tspan x="56" y="35" textLength="98">function init</tspan> <tspan x="49" y="57" textLength="113">for (var i = 0;</tspan> <tspan x="50" y="79" textLength="105">XmlHttpReq</tspan> <tspan x="48" y="101" textLength="80">appendCh</tspan> </text> <path fill="#36363d" stroke="#36363d" stroke-width="4" d="M 44,29\r\n a6.36396,6.36396 0,0,1 0,9\r\n l36,36\r\n a3.25,3.25 0,0,1 -6.5,6.5\r\n l-36,-36\r\n a6.36396,6.36396 0,0,1 -9,0\r\n l-19,-19\r\n a1.76777,1.76777 0,0,1 0,-2.5\r\n l13.0,-13\r\n a1.76777,1.76777 0,0,1 2.5,0\r\n z"/> <path fill="#9494b8" d="M 44,29\r\n a6.36396,6.36396 0,0,1 0,9\r\n l36,36\r\n a3.25,3.25 0,0,1 -6.5,6.5\r\n l-36,-36\r\n a6.36396,6.36396 0,0,1 -9,0\r\n l-19,-19\r\n a1.76777,1.76777 0,0,1 2.5,-2.5\r\n l14,14 4,-4 -14,-14\r\n a1.76777,1.76777 0,0,1 2.5,-2.5\r\n l14,14 4,-4 -14,-14\r\n a1.76777,1.76777 0,0,1 2.5,-2.5\r\n z"/> </svg> <a href="https://greasyfork.org/en/users/919633" class="text-value" target="_blank" title="Please support this script on greasyfork">Dsync client</a> </div> </div> </div> </div> </div>';
  86. const Credits = Credits_code;
  87. const styles = '@import"https://fonts.googleapis.com/css2?family=Lato:wght@400;700;900&display=swap";header{background:#2f2f31;color:#76689a;padding:5px 10px;display:flex;justify-content:flex-start;align-items:center}header #version{align-self:flex-end;color:#9787bd;font-size:.5em;font-weight:600;margin-left:10px}header #version svg{fill:#9787bd}header .icon{margin-left:auto;width:35px;height:35px;fill:#cebcb4;transition:fill 100ms;cursor:pointer}header .icon:hover{fill:#ffe7dc}#navbar-container{display:flex;flex-direction:column;padding:10px;margin-right:10px;background:#2f2f31}#navbar-container .open-menu{outline:none;border:none;cursor:pointer;font-weight:900;font-size:1.4rem;padding:10px;background:#313135;color:#ffe7dc;border-right:1px solid;border-right-color:rgba(0,0,0,0);transition:background 100ms,color 100ms,border-right-color 100ms}#navbar-container .open-menu:hover{background:#313135}#navbar-container .open-menu:active{background:#ffe7dc;color:#313135}#navbar-container .open-menu.active{pointer-events:none;background:#313135;border-right-color:#ffe7dc}#navbar-container .bottom-align{margin-bottom:0px;margin-top:auto !important}@-webkit-keyframes appear{from{opacity:0}to{opacity:1}}@-webkit-keyframes disappear{from{opacity:1}to{opacity:0}}@-webkit-keyframes failedTransition{0%{transform:translate(0px, 0px)}10%{transform:translate(-35px, -10px)}30%{transform:translate(25px, 8px)}50%{transform:translate(-15px, -6px)}70%{transform:translate(5px, 4px)}100%{transform:translate(0px, 0px)}}@keyframes appear{from{opacity:0}to{opacity:1}}@keyframes disappear{from{opacity:1}to{opacity:0}}@keyframes failedTransition{0%{transform:translate(0px, 0px)}10%{transform:translate(-35px, -10px)}30%{transform:translate(25px, 8px)}50%{transform:translate(-15px, -6px)}70%{transform:translate(5px, 4px)}100%{transform:translate(0px, 0px)}}.menu-page{display:none;background:#2f2f31;padding:10px;padding-top:0px}.menu-page.opened{display:block;animation:appear 300ms forwards}.menu-page h1{color:#76689a;font-size:1.5em;font-weight:900}.menu-page h2{color:#9494b8;font-size:1em;font-weight:900}.menu-page p{color:#675a86;font-size:.5em;font-weight:700}.menu-page .content{display:flex;justify-content:space-between;align-items:center;gap:10px}.menu-page .content>img{width:40px;height:40px}.menu-page .content-double{display:flex;flex-wrap:wrap;justify-content:space-between;gap:10px;width:250px}.menu-page .content-double button{width:48%}.menu-page .content-double:nth-child(3){width:100%}.menu-page #killMessage{width:270px}.menu-page .highlight{font-weight:700;color:#ffe7dc;background:#6a6a81;padding:0 1px}.menu-page .section{background:#36363d;border-radius:5px;margin:20px 0}.menu-page .section:last-child{margin-bottom:0px}.menu-page .section .section-title{display:flex;justify-content:space-between;align-items:center;padding:10px}.menu-page .section .section-title .icon{width:25px;height:25px;margin-right:10px;fill:#cebcb4;transition:fill 100ms,transform 100ms}.menu-page .section .section-title .icon.rotate{transform:rotate(90deg);fill:#ffe7dc}.menu-page .section .section-title:hover .icon{fill:#ffe7dc}.menu-page .section:not(.opened) .section-title{cursor:pointer}.menu-page .section:not(.opened) .section-content{overflow:hidden}.menu-page .section .section-content{padding:10px;padding-top:0px;display:grid;grid-template-columns:1fr 1fr;transition:max-height 250ms cubic-bezier(0, 1, 0, 1);max-height:0px}.menu-page .section .section-content.one-row{grid-template-columns:1fr}.menu-page .section .section-content.opened{transition:max-height 250ms ease-out;max-height:100%}.menu-page .section .section-content .split{grid-column:1/3;margin-top:10px;background:#40404a;height:2px}.menu-page .section .section-content .section-option{display:flex;justify-content:space-between;align-items:center;margin-top:10px;padding-right:25px}.menu-page .section .section-content .section-option .icon{width:35px;height:35px;fill:#6a6a81}.menu-page .section .section-content .section-option.centered{justify-content:center}.menu-page .section .section-content .section-option.text{justify-content:flex-start;gap:10px}.menu-page .section .section-content .section-option.text .text-value{font-size:.7em;color:#9494b8}.menu-page .section .section-content .section-option .section-option-title{color:#6a6a81;font-size:.8em}.menu-page .section .section-content .section-option .section-option-hotkeyInput{cursor:pointer;font-weight:900;font-size:.6em;padding-bottom:8px;outline:none;border:none;text-align:center;width:80px;height:35px;border-radius:7.5px;background:#7d7d9b;color:#adbcd8;box-shadow:0px -6px 0px 0px #68687c inset}.menu-page .section .section-content .section-option .section-option-hotkeyInput.red{background:#9e5454;color:#d8adad;box-shadow:0px -6px 0px 0px #783d3d inset}.menu-page .section .section-content .section-option .section-option-hotkeyInput:not([id]){cursor:not-allowed}.menu-page .section .section-content .section-option .section-option-hotkeyInput.smaller{font-size:.41em}.menu-page .section .section-content .section-option .switch-checkbox{position:relative;width:70px;height:25px}.menu-page .section .section-content .section-option .switch-checkbox input{width:0;height:0;opacity:0}.menu-page .section .section-content .section-option .switch-checkbox input:checked+span{background:#7d7d9b;box-shadow:0px 5px 0px 0px #68687c inset}.menu-page .section .section-content .section-option .switch-checkbox input:checked+span:before{background:#ffe7dc;transform:translateX(42px)}.menu-page .section .section-content .section-option .switch-checkbox span{position:absolute;cursor:pointer;top:0;left:0;bottom:0;right:0;width:100%;height:100%;display:flex;align-items:center;background:#5f5f79;box-shadow:0px 5px 0px 0px #4d4d5f inset;border-radius:10px;transition:all 100ms ease-in-out}.menu-page .section .section-content .section-option .switch-checkbox span:before{position:absolute;content:"";width:28px;height:28px;border-radius:50%;background:#f0dcd3;box-shadow:0px -5px 0px 0px #cebcb4 inset;border:2px solid #adbcd8;transition:all 100ms ease-in-out}.menu-page .section .section-content .section-option .slider{position:relative;margin-right:45px}.menu-page .section .section-content .section-option .slider input{-webkit-appearance:none;outline:none;cursor:pointer;width:154px;height:20.8333333333px;border-radius:10px;background:#7d7d9b;box-shadow:0px 5px 0px 0px #68687c inset}.menu-page .section .section-content .section-option .slider input::-webkit-slider-thumb{-webkit-appearance:none;width:28px;height:28px;border-radius:50%;background:#ffe7dc;box-shadow:0px -5px 0px 0px #cebcb4 inset;border:2px solid #adbcd8}.menu-page .section .section-content .section-option .slider .slider-value{position:absolute;margin-left:5px;color:#6a6a81;font-size:.65em}.menu-page .section .section-content .section-option .input{outline:none;border:none;font-weight:900;text-align:center;width:130px;height:35px;padding-bottom:6px;border-radius:7.5px;background:#7d7d9b;color:#adbcd8;box-shadow:0px -6px 0px 0px #68687c inset}.menu-page .section .section-content .section-option .input:focus{border:3px solid #f0dcd3}.menu-page .section .section-content .section-option .button{outline:none;border:none;font-weight:900;cursor:pointer;height:40px;padding-bottom:6px;border-radius:7.5px;background:#7d7d9b;color:#adbcd8;box-shadow:0px -6px 0px 0px #68687c inset}.menu-page .section .section-content .section-option .button[data-type]{width:135px;font-size:.45em}.menu-page .section .section-content .section-option .button:active{padding-bottom:0px;padding-top:3px;box-shadow:0px 3px 0px 0px #68687c inset}.menu-page .section .section-content .section-option .button.red{background:#9e5454;color:#d8adad;box-shadow:0px -6px 0px 0px #783d3d inset}.menu-page .section .section-content .section-option .button.red:active{box-shadow:0px 3px 0px 0px #783d3d inset}.menu-page .section .section-content .section-option .button.width{width:9em;font-size:.6em}.menu-page .section .section-content .section-option .form-upload{position:relative;font-size:.55em;font-weight:400;letter-spacing:1.5px;text-align:center;width:100%;border-radius:5px;border:2px dashed;border-color:rgba(173,188,216,.5411764706);padding:15px 10px;transition:border-color 100ms}.menu-page .section .section-content .section-option .form-upload:hover{border-color:#adbcd8}.menu-page .section .section-content .section-option .form-upload.red{border-color:#9e5454;animation:failedTransition 400ms}.menu-page .section .section-content .section-option .form-upload.red .light{color:#d8adad}.menu-page .section .section-content .section-option .form-upload.green{border-color:#77c468}.menu-page .section .section-content .section-option .form-upload.green .light{color:#a1dda1}.menu-page .section .section-content .section-option .form-upload input{position:absolute;opacity:0;top:0;left:0;bottom:0;right:0;width:100%;height:100%;cursor:pointer}.menu-page .section .section-content .section-option .form-upload .light{color:#adbcd8}.menu-page .section .section-content .section-option .form-upload .light-extra{color:#f0dcd3}.menu-page .section .section-content .section-option .tooltip{position:relative;margin-left:5px;color:#8181a0}.menu-page .section .section-content .section-option .tooltip:hover{cursor:pointer}.menu-page .section .section-content .section-option .tooltip:hover .tooltip-text{visibility:visible}.menu-page .section .section-content .section-option .tooltip .tooltip-text{position:absolute;visibility:hidden;text-align:center;overflow:visible;bottom:calc(100% - 5px);left:50%;transform:translateX(-50%);background-color:#7d7d9b;color:#ffe7dc;width:225px;font-size:13px;font-weight:600;padding:5px;border-radius:5px;border:3px solid #5f5f79}.menu-page .section .section-content .section-option .tooltip .tooltip-text.left{text-align:left}.menu-page .section .section-content .section-option select[id]{outline:none;border:none;font-weight:900;width:195px;font-size:.6em;border-radius:7.5px;padding:2.5px;background:#7d7d9b;color:#adbcd8;box-shadow:0px 4px 0px 0px #68687c inset}.menu-page .section .section-content .section-option select[id].smaller{width:130px}@-webkit-keyframes appear{from{opacity:0}to{opacity:1}}@-webkit-keyframes disappear{from{opacity:1}to{opacity:0}}@-webkit-keyframes failedTransition{0%{transform:translate(0px, 0px)}10%{transform:translate(-35px, -10px)}30%{transform:translate(25px, 8px)}50%{transform:translate(-15px, -6px)}70%{transform:translate(5px, 4px)}100%{transform:translate(0px, 0px)}}@keyframes appear{from{opacity:0}to{opacity:1}}@keyframes disappear{from{opacity:1}to{opacity:0}}@keyframes failedTransition{0%{transform:translate(0px, 0px)}10%{transform:translate(-35px, -10px)}30%{transform:translate(25px, 8px)}50%{transform:translate(-15px, -6px)}70%{transform:translate(5px, 4px)}100%{transform:translate(0px, 0px)}}@-webkit-keyframes appear{from{opacity:0}to{opacity:1}}@-webkit-keyframes disappear{from{opacity:1}to{opacity:0}}@-webkit-keyframes failedTransition{0%{transform:translate(0px, 0px)}10%{transform:translate(-35px, -10px)}30%{transform:translate(25px, 8px)}50%{transform:translate(-15px, -6px)}70%{transform:translate(5px, 4px)}100%{transform:translate(0px, 0px)}}@keyframes appear{from{opacity:0}to{opacity:1}}@keyframes disappear{from{opacity:1}to{opacity:0}}@keyframes failedTransition{0%{transform:translate(0px, 0px)}10%{transform:translate(-35px, -10px)}30%{transform:translate(25px, 8px)}50%{transform:translate(-15px, -6px)}70%{transform:translate(5px, 4px)}100%{transform:translate(0px, 0px)}}html,body{margin:0;padding:0;background:rgba(0,0,0,0) !important;scrollbar-width:10px;scrollbar-track-color:#36363d;scrollbar-face-color:#494955}*{font-family:"Lato",sans-serif}h1,h2,h3,h4,p{margin:0}#menu-container{font-weight:900;font-size:2rem;position:absolute;top:50%;left:50%;transform:translate(-50%, -50%);width:1024px;height:700px;display:flex;justify-content:center;align-items:center;user-select:none}#menu-container.open{animation:appear 100ms forwards}#menu-container.close{animation:disappear 100ms forwards}#menu-container.transparent #menu-wrapper{background:rgba(43,43,44,.4666666667)}#menu-container.transparent #navbar-container{background:rgba(47,47,49,.6431372549)}#menu-container.transparent .menu-page{background:rgba(47,47,49,.6431372549)}#menu-container.transparent .section{background:rgba(54,54,61,.6509803922)}#menu-wrapper{position:relative;display:flex;flex-direction:column;width:100%;height:80%;background:#2b2b2c;border-radius:5px;padding:10px}main{display:flex;justify-content:space-between;margin-top:10px;height:100%}main #menu-page-container{width:100%;height:500px;overflow-y:scroll}.default-color{outline:none;border:none;width:10px;height:10px;border-radius:100%;cursor:pointer}input[id][type=color]{outline:none;border:none;padding:0 1px;margin:0;height:24px;background-color:#7d7d9b;border-radius:5px;cursor:pointer}::-webkit-scrollbar{width:10px}::-webkit-scrollbar-track{background:#36363d;border-radius:10px}::-webkit-scrollbar-thumb{background:#494955;border-radius:10px}#popup-menu{position:absolute;top:0;left:0;bottom:0;right:0;width:100%;height:100%;display:flex;justify-content:center;align-items:center;background:rgba(25,25,35,.5)}#popup-menu #popup-container{position:relative;width:70%;height:50%;background:#2f2f31;border-radius:10px;border:6px solid #36363d;padding:10px;display:flex;justify-content:space-between}#popup-menu #popup-container #close-popup{position:absolute;z-index:5;right:0;top:0;fill:#cebcb4;transition:fill 100ms;cursor:pointer}#popup-menu #popup-container #close-popup:hover{fill:#ffe7dc}#popup-menu #popup-container #popup-wrapper{position:absolute;z-index:1;top:10px;left:10px;bottom:10px;right:10px;padding:10px;display:flex;justify-content:space-between}#popup-menu #popup-container #popup-wrapper #popup-data{width:50%;height:100%;display:flex;flex-direction:column}#popup-menu #popup-container #popup-wrapper #popup-content{display:grid;width:100%;grid-template-columns:repeat(auto-fill, minmax(125px, 1fr));grid-gap:10px;overflow-y:auto}#popup-menu #popup-container #popup-wrapper #popup-content .img-prev{padding-bottom:6px;border-radius:7.5px;background:#7d7d9b;color:#adbcd8;box-shadow:0px -6px 0px 0px #68687c inset;cursor:pointer}#popup-menu #popup-container #popup-wrapper #popup-content .img-prev:active{padding-bottom:0px;padding-top:6px;box-shadow:0px 6px 0px 0px #68687c inset}#popup-menu #popup-container #popup-wrapper #popup-content .img-prev img{pointer-events:none;width:100%;height:100%}#popup-menu #popup-container #popup-title{font-size:2em;color:#ffe7dc;text-shadow:#3d3937 4px 0px 0px,#3d3937 3.87565px .989616px 0px,#3d3937 3.51033px 1.9177px 0px,#3d3937 2.92676px 2.72655px 0px,#3d3937 2.16121px 3.36588px 0px,#3d3937 1.26129px 3.79594px 0px,#3d3937 .282949px 3.98998px 0px,#3d3937 -0.712984px 3.93594px 0px,#3d3937 -1.66459px 3.63719px 0px,#3d3937 -2.51269px 3.11229px 0px,#3d3937 -3.20457px 2.39389px 0px,#3d3937 -3.69721px 1.52664px 0px,#3d3937 -3.95997px .56448px 0px,#3d3937 -3.97652px -0.432781px 0px,#3d3937 -3.74583px -1.40313px 0px,#3d3937 -3.28224px -2.28625px 0px,#3d3937 -2.61457px -3.02721px 0px,#3d3937 -1.78435px -3.57996px 0px,#3d3937 -0.843183px -3.91012px 0px,#3d3937 .150409px -3.99717px 0px,#3d3937 1.13465px -3.8357px 0px,#3d3937 2.04834px -3.43574px 0px,#3d3937 2.83468px -2.82216px 0px,#3d3937 3.44477px -2.03312px 0px,#3d3937 3.84068px -1.11766px 0px,#3d3937 3.9978px -0.132717px 0px}#popup-menu #popup-container #popup-description{color:#f0dcd3;text-shadow:#3d3937 4px 0px 0px,#3d3937 3.87565px .989616px 0px,#3d3937 3.51033px 1.9177px 0px,#3d3937 2.92676px 2.72655px 0px,#3d3937 2.16121px 3.36588px 0px,#3d3937 1.26129px 3.79594px 0px,#3d3937 .282949px 3.98998px 0px,#3d3937 -0.712984px 3.93594px 0px,#3d3937 -1.66459px 3.63719px 0px,#3d3937 -2.51269px 3.11229px 0px,#3d3937 -3.20457px 2.39389px 0px,#3d3937 -3.69721px 1.52664px 0px,#3d3937 -3.95997px .56448px 0px,#3d3937 -3.97652px -0.432781px 0px,#3d3937 -3.74583px -1.40313px 0px,#3d3937 -3.28224px -2.28625px 0px,#3d3937 -2.61457px -3.02721px 0px,#3d3937 -1.78435px -3.57996px 0px,#3d3937 -0.843183px -3.91012px 0px,#3d3937 .150409px -3.99717px 0px,#3d3937 1.13465px -3.8357px 0px,#3d3937 2.04834px -3.43574px 0px,#3d3937 2.83468px -2.82216px 0px,#3d3937 3.44477px -2.03312px 0px,#3d3937 3.84068px -1.11766px 0px,#3d3937 3.9978px -0.132717px 0px;margin-left:30px;margin-top:30px}#popup-menu #popup-container #popup-bottom{display:flex;justify-content:space-between;align-items:center;margin-top:auto}#popup-menu #popup-container #popup-bottom .popup-button{border:none;outline:none;display:inline-block;font-family:"Lato",sans-serif;text-align:center;cursor:pointer;max-width:160px;width:100%;font-size:.8em;font-weight:900;padding:5px 10px 10px;border-radius:5px;color:#ffe7dc;text-decoration:none;text-shadow:#3d3937 4px 0px 0px,#3d3937 3.87565px .989616px 0px,#3d3937 3.51033px 1.9177px 0px,#3d3937 2.92676px 2.72655px 0px,#3d3937 2.16121px 3.36588px 0px,#3d3937 1.26129px 3.79594px 0px,#3d3937 .282949px 3.98998px 0px,#3d3937 -0.712984px 3.93594px 0px,#3d3937 -1.66459px 3.63719px 0px,#3d3937 -2.51269px 3.11229px 0px,#3d3937 -3.20457px 2.39389px 0px,#3d3937 -3.69721px 1.52664px 0px,#3d3937 -3.95997px .56448px 0px,#3d3937 -3.97652px -0.432781px 0px,#3d3937 -3.74583px -1.40313px 0px,#3d3937 -3.28224px -2.28625px 0px,#3d3937 -2.61457px -3.02721px 0px,#3d3937 -1.78435px -3.57996px 0px,#3d3937 -0.843183px -3.91012px 0px,#3d3937 .150409px -3.99717px 0px,#3d3937 1.13465px -3.8357px 0px,#3d3937 2.04834px -3.43574px 0px,#3d3937 2.83468px -2.82216px 0px,#3d3937 3.44477px -2.03312px 0px,#3d3937 3.84068px -1.11766px 0px,#3d3937 3.9978px -0.132717px 0px}#popup-menu #popup-container #popup-bottom .popup-button#popup-continue{background:#77c468;box-shadow:0px -6px 0px 0px #49783d inset}#popup-menu #popup-container #popup-bottom .popup-button#popup-continue:active{padding:10px 10px 5px;box-shadow:0px 3px 0px 0px #49783d inset}#popup-menu #popup-container #popup-bottom .popup-button#popup-close{background:#9e5454;box-shadow:0px -6px 0px 0px #783d3d inset}#popup-menu #popup-container #popup-bottom .popup-button#popup-close:active{padding:10px 10px 5px;box-shadow:0px 3px 0px 0px #783d3d inset}#popup-menu #popup-container #popup-prev{width:50%;height:100%;display:flex;justify-content:right;align-items:center}#popup-menu #popup-container #popup-prev img{width:auto;height:auto;max-width:100%;max-height:100%}#image-background{position:absolute;animation:moving 60s infinite linear;padding:10px;top:0;left:0;bottom:0;right:0;filter:opacity(0.4)}.discord-bg{background:url(https://i.imgur.com/RcTl09i.png) 0 0/8% repeat;background-clip:content-box}.github-bg{background:url(https://i.imgur.com/q0z20jB.png) 0 0/8% repeat;background-clip:content-box}.greasyfork-bg{background:url(https://i.imgur.com/y6OYX0D.png) 0 0/8% repeat;background-clip:content-box}@keyframes moving{0%{background-position:0 0}100%{background-position:-500px 500px}}';
  88. var ELayer;
  89. (function(ELayer) {
  90. ELayer[ELayer["PLAYER"] = 0] = "PLAYER";
  91. ELayer[ELayer["STONE"] = 1] = "STONE";
  92. ELayer[ELayer["HARDSPIKE"] = 2] = "HARDSPIKE";
  93. ELayer[ELayer["TREE"] = 3] = "TREE";
  94. ELayer[ELayer["GOLD"] = 4] = "GOLD";
  95. ELayer[ELayer["BUSH"] = 5] = "BUSH";
  96. ELayer[ELayer["TRAP"] = 6] = "TRAP";
  97. ELayer[ELayer["SPIKE"] = 7] = "SPIKE";
  98. ELayer[ELayer["WOODWALL"] = 8] = "WOODWALL";
  99. ELayer[ELayer["PLATFORM"] = 9] = "PLATFORM";
  100. ELayer[ELayer["BOOST"] = 10] = "BOOST";
  101. ELayer[ELayer["LOOTBOX"] = 11] = "LOOTBOX";
  102. ELayer[ELayer["PROJECTILE"] = 12] = "PROJECTILE";
  103. ELayer[ELayer["WINDMILL"] = 13] = "WINDMILL";
  104. ELayer[ELayer["COW"] = 14] = "COW";
  105. ELayer[ELayer["SPAWN"] = 15] = "SPAWN";
  106. ELayer[ELayer["POWERMILL"] = 16] = "POWERMILL";
  107. ELayer[ELayer["CASTLESPIKE"] = 17] = "CASTLESPIKE";
  108. ELayer[ELayer["TURRET"] = 18] = "TURRET";
  109. ELayer[ELayer["WOODFARM"] = 19] = "WOODFARM";
  110. ELayer[ELayer["CHERRYWOODFARM"] = 20] = "CHERRYWOODFARM";
  111. ELayer[ELayer["STONEWARM"] = 21] = "STONEWARM";
  112. ELayer[ELayer["CASTLEWALL"] = 22] = "CASTLEWALL";
  113. ELayer[ELayer["SHARK"] = 23] = "SHARK";
  114. ELayer[ELayer["WOLF"] = 24] = "WOLF";
  115. ELayer[ELayer["GOLDENCOW"] = 25] = "GOLDENCOW";
  116. ELayer[ELayer["ROOF"] = 26] = "ROOF";
  117. ELayer[ELayer["DRAGON"] = 27] = "DRAGON";
  118. ELayer[ELayer["MAMMOTH"] = 28] = "MAMMOTH";
  119. ELayer[ELayer["FIREBALL"] = 29] = "FIREBALL";
  120. ELayer[ELayer["CHEST"] = 30] = "CHEST";
  121. ELayer[ELayer["DRAGONWALLBIG"] = 31] = "DRAGONWALLBIG";
  122. ELayer[ELayer["DRAGONWALLMEDIUM"] = 32] = "DRAGONWALLMEDIUM";
  123. ELayer[ELayer["DRAGONWALLSMALL"] = 33] = "DRAGONWALLSMALL";
  124. ELayer[ELayer["MAMMOTHWALL"] = 34] = "MAMMOTHWALL";
  125. ELayer[ELayer["MAMMOTHWALLSMALL"] = 35] = "MAMMOTHWALLSMALL";
  126. ELayer[ELayer["DUCK"] = 36] = "DUCK";
  127. ELayer[ELayer["TELEPORT"] = 37] = "TELEPORT";
  128. ELayer[ELayer["CACTUS"] = 38] = "CACTUS";
  129. ELayer[ELayer["TORNADO"] = 39] = "TORNADO";
  130. })(ELayer || (ELayer = {}));
  131. const LayerDataArray = [ {
  132. id: ELayer.PLAYER,
  133. radius: 35,
  134. maxHealth: 100,
  135. Qa: 1
  136. }, {
  137. id: ELayer.STONE,
  138. shoot: true,
  139. radius: 75,
  140. Qa: 1,
  141. Pa: 1
  142. }, {
  143. id: ELayer.HARDSPIKE,
  144. shoot: true,
  145. qa: 35,
  146. radius: 45,
  147. maxHealth: 500,
  148. Qa: 1
  149. }, {
  150. id: ELayer.TREE,
  151. shoot: true,
  152. cannotShoot: true,
  153. radius: 90,
  154. Qa: 1,
  155. Ka: 1
  156. }, {
  157. id: ELayer.GOLD,
  158. shoot: true,
  159. radius: 76,
  160. Qa: 1,
  161. Xa: 5
  162. }, {
  163. id: ELayer.BUSH,
  164. shoot: true,
  165. radius: 50,
  166. Qa: 1,
  167. Na: 1
  168. }, {
  169. id: ELayer.TRAP,
  170. radius: 40,
  171. maxHealth: 500,
  172. Qa: 1
  173. }, {
  174. id: ELayer.SPIKE,
  175. shoot: true,
  176. qa: 20,
  177. radius: 45,
  178. maxHealth: 375,
  179. Ia: 20,
  180. Qa: 1
  181. }, {
  182. id: ELayer.WOODWALL,
  183. shoot: true,
  184. radius: 45,
  185. maxHealth: 380,
  186. Qa: 1
  187. }, {
  188. id: ELayer.PLATFORM,
  189. radius: 60,
  190. maxHealth: 300,
  191. Qa: 1
  192. }, {
  193. id: ELayer.BOOST,
  194. radius: 40,
  195. maxHealth: 300,
  196. Qa: 1
  197. }, {
  198. id: ELayer.LOOTBOX,
  199. radius: 40,
  200. maxHealth: 4,
  201. Qa: 1
  202. }, {
  203. id: ELayer.PROJECTILE,
  204. radius: 0,
  205. maxHealth: 0
  206. }, {
  207. id: ELayer.WINDMILL,
  208. shoot: true,
  209. radius: 45,
  210. maxHealth: 400,
  211. rotateSpeed: Math.PI / 4,
  212. Qa: 1
  213. }, {
  214. id: ELayer.COW,
  215. radius: 90,
  216. maxHealth: 380,
  217. animal: true,
  218. Qa: 1,
  219. Ja: 1.6,
  220. $a: 9,
  221. ts: 0
  222. }, {
  223. id: ELayer.SPAWN,
  224. shoot: true,
  225. radius: 50,
  226. maxHealth: 380,
  227. Qa: 1
  228. }, {
  229. id: ELayer.POWERMILL,
  230. shoot: true,
  231. radius: 54,
  232. maxHealth: 400,
  233. rotateSpeed: Math.PI / 2,
  234. Qa: 1
  235. }, {
  236. id: ELayer.CASTLESPIKE,
  237. shoot: true,
  238. qa: 5,
  239. radius: 42,
  240. maxHealth: 1200,
  241. Ia: 24,
  242. Qa: 1
  243. }, {
  244. id: ELayer.TURRET,
  245. shoot: true,
  246. radius: 45,
  247. maxHealth: 800,
  248. Qa: 1
  249. }, {
  250. id: ELayer.WOODFARM,
  251. shoot: true,
  252. cannotShoot: true,
  253. radius: 80,
  254. Qa: 1,
  255. Ka: 1
  256. }, {
  257. id: ELayer.CHERRYWOODFARM,
  258. shoot: true,
  259. cannotShoot: true,
  260. radius: 80,
  261. Qa: 1,
  262. Ka: 1
  263. }, {
  264. id: ELayer.STONEWARM,
  265. shoot: true,
  266. radius: 60,
  267. Qa: 1,
  268. Pa: 1
  269. }, {
  270. id: ELayer.CASTLEWALL,
  271. shoot: true,
  272. radius: 59,
  273. maxHealth: 1750,
  274. Qa: 1
  275. }, {
  276. id: ELayer.SHARK,
  277. radius: 90,
  278. maxHealth: 380,
  279. animal: true,
  280. Qa: 1,
  281. Ja: 1.2,
  282. $a: 49,
  283. qa: 14,
  284. ts: 3
  285. }, {
  286. id: ELayer.WOLF,
  287. radius: 50,
  288. maxHealth: 380,
  289. animal: true,
  290. Qa: 1,
  291. Ja: 1.6,
  292. $a: 17,
  293. qa: 14,
  294. ts: 0
  295. }, {
  296. id: ELayer.GOLDENCOW,
  297. radius: 90,
  298. maxHealth: 1e3,
  299. animal: true,
  300. Qa: 1,
  301. Ja: 1.6,
  302. $a: 17,
  303. qa: 19
  304. }, {
  305. id: ELayer.ROOF,
  306. radius: 50,
  307. maxHealth: 300,
  308. Qa: 1
  309. }, {
  310. id: ELayer.DRAGON,
  311. radius: 100,
  312. maxHealth: 5e3,
  313. animal: true,
  314. Qa: 1,
  315. Ja: 1.15,
  316. $a: 17,
  317. qa: 30,
  318. ts: 0
  319. }, {
  320. id: ELayer.MAMMOTH,
  321. radius: 90,
  322. maxHealth: 5e3,
  323. animal: true,
  324. Qa: 1,
  325. Ja: 1.6,
  326. $a: 17,
  327. qa: 30,
  328. ts: 1
  329. }, {
  330. id: ELayer.FIREBALL,
  331. radius: 100,
  332. maxHealth: 380,
  333. Qa: 1,
  334. Ja: .4,
  335. $a: 1,
  336. qa: 15,
  337. ts: 0
  338. }, {
  339. id: ELayer.CHEST,
  340. shoot: true,
  341. radius: 45,
  342. maxHealth: 380,
  343. Qa: 1,
  344. Xa: 50,
  345. Lr: 20
  346. }, {
  347. id: ELayer.DRAGONWALLBIG,
  348. shoot: true,
  349. radius: 92,
  350. Qa: 1,
  351. Pa: 1
  352. }, {
  353. id: ELayer.DRAGONWALLMEDIUM,
  354. shoot: true,
  355. radius: 92,
  356. Qa: 1,
  357. Pa: 1
  358. }, {
  359. id: ELayer.DRAGONWALLSMALL,
  360. shoot: true,
  361. radius: 58,
  362. Qa: 1,
  363. Pa: 1
  364. }, {
  365. id: ELayer.MAMMOTHWALL,
  366. shoot: true,
  367. radius: 92,
  368. Qa: 1,
  369. Pa: 0
  370. }, {
  371. id: ELayer.MAMMOTHWALLSMALL,
  372. shoot: true,
  373. radius: 20,
  374. Qa: 1,
  375. Pa: 0
  376. }, {
  377. id: ELayer.DUCK,
  378. radius: 20,
  379. maxHealth: 380,
  380. animal: true,
  381. Qa: 1,
  382. Ja: 1.6,
  383. $a: 9,
  384. ts: 0
  385. }, {
  386. id: ELayer.TELEPORT,
  387. shoot: true,
  388. radius: 35,
  389. maxHealth: 150,
  390. Qa: 1
  391. }, {
  392. id: ELayer.CACTUS,
  393. shoot: true,
  394. radius: 50,
  395. Qa: 1,
  396. Na: 5,
  397. qa: 20
  398. }, {
  399. id: ELayer.TORNADO,
  400. radius: 220,
  401. rotateSpeed: Math.PI / 4,
  402. Qa: 0,
  403. Na: 5,
  404. qa: 1
  405. } ];
  406. const LayerData = LayerDataArray;
  407. const LayerObjects = LayerData.filter((layer => layer.shoot));
  408. const Animals = LayerData.filter((layer => layer.animal));
  409. var EObjects;
  410. (function(EObjects) {
  411. EObjects[EObjects["BOOST"] = 6] = "BOOST";
  412. EObjects[EObjects["PLATFORM"] = 8] = "PLATFORM";
  413. EObjects[EObjects["TRAP"] = 9] = "TRAP";
  414. EObjects[EObjects["WINDMILL"] = 14] = "WINDMILL";
  415. EObjects[EObjects["SPAWN"] = 16] = "SPAWN";
  416. EObjects[EObjects["POWERMILL"] = 19] = "POWERMILL";
  417. EObjects[EObjects["ROOF"] = 48] = "ROOF";
  418. })(EObjects || (EObjects = {}));
  419. var PlacementType;
  420. (function(PlacementType) {
  421. PlacementType[PlacementType["DEFAULT"] = 0] = "DEFAULT";
  422. PlacementType[PlacementType["INVISIBLE"] = 1] = "INVISIBLE";
  423. PlacementType[PlacementType["HOLDING"] = 2] = "HOLDING";
  424. })(PlacementType || (PlacementType = {}));
  425. var EServers;
  426. (function(EServers) {
  427. EServers["SAND_EU1"] = "SFRA";
  428. EServers["SAND_EU2"] = "SFRA2BIS";
  429. EServers["SAND_USA1"] = "SCA";
  430. EServers["SAND_USA2"] = "SCA2";
  431. EServers["SAND_AS1"] = "SGP";
  432. EServers["SAND_AS2"] = "SGP2";
  433. EServers["SAND_AS3"] = "SGP3BIS";
  434. EServers["NORM_EU1"] = "FRA1FFA";
  435. EServers["NORM_USA1"] = "CA1FFA";
  436. EServers["NORM_AS1"] = "SGP1FFA";
  437. EServers["BATTLE_USA1"] = "BRSCA";
  438. })(EServers || (EServers = {}));
  439. const selectData = {
  440. placementType: PlacementType,
  441. connectTo: EServers
  442. };
  443. var TargetReload;
  444. (function(TargetReload) {
  445. TargetReload[TargetReload["TURRET"] = 3e3] = "TURRET";
  446. TargetReload[TargetReload["HAT"] = 1300] = "HAT";
  447. TargetReload[TargetReload["DRAGON"] = 3e3] = "DRAGON";
  448. })(TargetReload || (TargetReload = {}));
  449. var Hit;
  450. (function(Hit) {
  451. Hit[Hit["CANNOT"] = 0] = "CANNOT";
  452. Hit[Hit["CAN"] = 1] = "CAN";
  453. Hit[Hit["NEEDDESTROY"] = 2] = "NEEDDESTROY";
  454. })(Hit || (Hit = {}));
  455. const Reload = {
  456. hat: {
  457. current: TargetReload.HAT,
  458. lerp: TargetReload.HAT,
  459. max: TargetReload.HAT,
  460. color: () => Settings.hatReloadBarColor
  461. },
  462. weapon: {
  463. current: 0,
  464. lerp: 0,
  465. max: 0,
  466. color: () => Settings.weaponReloadBarColor
  467. },
  468. turret: {
  469. current: TargetReload.TURRET,
  470. lerp: TargetReload.TURRET,
  471. max: TargetReload.TURRET,
  472. color: () => Settings.turretReloadBarColor
  473. },
  474. fireball: {
  475. current: TargetReload.DRAGON,
  476. lerp: TargetReload.DRAGON,
  477. max: TargetReload.DRAGON,
  478. color: () => Settings.fireballReloadBarColor
  479. }
  480. };
  481. class Storage {
  482. static get(key) {
  483. const item = localStorage.getItem(key);
  484. return item !== null ? JSON.parse(item) : null;
  485. }
  486. static set(key, value) {
  487. localStorage.setItem(key, JSON.stringify(value));
  488. }
  489. static delete(key) {
  490. const has = localStorage.hasOwnProperty(key) && key in localStorage;
  491. localStorage.removeItem(key);
  492. return has;
  493. }
  494. }
  495. const defaultSettings = {
  496. primary: "Digit1",
  497. secondary: "Digit2",
  498. heal: "KeyQ",
  499. wall: "Digit4",
  500. spike: "KeyV",
  501. windmill: "KeyN",
  502. trap: "KeyF",
  503. turret: "KeyH",
  504. tree: "KeyU",
  505. platform: "KeyT",
  506. spawn: "KeyJ",
  507. up: "KeyW",
  508. left: "KeyA",
  509. down: "KeyS",
  510. right: "KeyD",
  511. autoattack: "KeyE",
  512. lockRotation: "KeyX",
  513. openChat: "Enter",
  514. invisibleHit: 2,
  515. spikeInsta: "KeyR",
  516. toggleMenu: "Escape",
  517. fastBreak: "KeyZ",
  518. upgradeScythe: "...",
  519. unequip: "...",
  520. bush: "...",
  521. berserker: "...",
  522. jungle: "...",
  523. crystal: "...",
  524. spikegear: "...",
  525. immunity: 4,
  526. boost: 3,
  527. applehat: "...",
  528. scuba: "...",
  529. hood: "...",
  530. demolist: "...",
  531. placementType: PlacementType.INVISIBLE,
  532. placementSpeed: 1,
  533. autobed: true,
  534. automill: true,
  535. antiFireball: true,
  536. autoheal: true,
  537. jungleOnClown: true,
  538. lastHat: true,
  539. autoScuba: true,
  540. meleeAim: true,
  541. bowAim: true,
  542. spikeInstaAim: true,
  543. autosync: true,
  544. autoboostFollow: true,
  545. enemyTracers: true,
  546. teammateTracers: true,
  547. animalTracers: true,
  548. enemyColor: "#cc5151",
  549. teammateColor: "#8ecc51",
  550. animalColor: "#518ccc",
  551. arrows: true,
  552. rainbow: false,
  553. drawHP: true,
  554. showHoods: true,
  555. itemCounter: true,
  556. visualAim: true,
  557. hideMessages: false,
  558. customSkins: false,
  559. skin: Storage.get("skin") || 27,
  560. accessory: Storage.get("accessory") || 30,
  561. back: Storage.get("back") || 2,
  562. itemMarkers: true,
  563. teammateMarkers: true,
  564. enemyMarkers: true,
  565. trapActivated: true,
  566. itemMarkersColor: "#8ecc51",
  567. teammateMarkersColor: "#cfbc5f",
  568. enemyMarkersColor: "#cc5151",
  569. trapActivatedColor: "#48b2b8",
  570. hatReloadBar: true,
  571. hatReloadBarColor: "#5155cc",
  572. fireballReloadBar: true,
  573. fireballReloadBarColor: "#cf7148",
  574. turretReloadBar: true,
  575. turretReloadBarColor: "#51cc80",
  576. weaponReloadBar: true,
  577. weaponReloadBarColor: "#cc8251",
  578. smoothReloadBar: true,
  579. windmillRotation: false,
  580. possibleShots: true,
  581. autochat: true,
  582. autochatMessages: [ "Dsync Client", "What is it?", "The most advanced hack for sploop!", "Download on greasyfork!" ],
  583. kill: true,
  584. killMessage: "{NAME}, you suck! {KILL}x",
  585. autospawn: false,
  586. smoothZoom: true,
  587. skipUpgrades: true,
  588. invisHitToggle: false,
  589. reverseZoom: false,
  590. autoAccept: false,
  591. connectTo: "SFRA",
  592. menuTransparency: false,
  593. blindUsers: [ 0, 0, 0 ]
  594. };
  595. const settings = {
  596. ...defaultSettings,
  597. ...Storage.get("Dsync-settings")
  598. };
  599. for (const key in settings) {
  600. if (!defaultSettings.hasOwnProperty(key)) {
  601. delete settings[key];
  602. }
  603. }
  604. Storage.set("Dsync-settings", settings);
  605. const Settings = settings;
  606. class Formatter {
  607. static object(target) {
  608. const layer = LayerData[target.type];
  609. return {
  610. id: target[Dsync.props.id],
  611. type: target.type,
  612. x: target[Dsync.props.x],
  613. y: target[Dsync.props.y],
  614. x1: target[Dsync.props.x1],
  615. y1: target[Dsync.props.y1],
  616. x2: target[Dsync.props.x2],
  617. y2: target[Dsync.props.y2],
  618. angle: target[Dsync.props.angle],
  619. angle1: target[Dsync.props.angle1],
  620. angle2: target[Dsync.props.angle2],
  621. ownerID: target[Dsync.props.ownerID],
  622. radius: layer.radius,
  623. layerData: layer,
  624. target
  625. };
  626. }
  627. static projectile(target) {
  628. const object = this.object(target);
  629. return {
  630. ...object,
  631. range: target.range,
  632. projectileType: target[Dsync.props.projectileType]
  633. };
  634. }
  635. static entity(target) {
  636. const object = this.object(target);
  637. const healthValue = target[Dsync.props.health];
  638. const maxHealth = object.layerData.maxHealth || 1;
  639. return {
  640. ...object,
  641. healthValue,
  642. health: Math.ceil(healthValue / 255 * maxHealth),
  643. maxHealth,
  644. entityValue: target[Dsync.props.entityValue]
  645. };
  646. }
  647. static player(target) {
  648. const entity = this.entity(target);
  649. return {
  650. ...entity,
  651. hat: target[Dsync.props.hat],
  652. isClown: entity.entityValue === 128,
  653. currentItem: target[Dsync.props.currentItem]
  654. };
  655. }
  656. }
  657. const TYPEOF = value => Object.prototype.toString.call(value).slice(8, -1).toLowerCase();
  658. const removeClass = (target, name) => {
  659. if (target instanceof HTMLElement) {
  660. target.classList.remove(name);
  661. return;
  662. }
  663. for (const element of target) {
  664. element.classList.remove(name);
  665. }
  666. };
  667. const removeChildren = target => {
  668. while (target.firstChild) {
  669. target.removeChild(target.firstChild);
  670. }
  671. };
  672. const formatCode = code => {
  673. code = code + "";
  674. if (code === "0") return "LBTN";
  675. if (code === "1") return "MBTN";
  676. if (code === "2") return "RBTN";
  677. if (code === "3") return "XBTN2";
  678. if (code === "4") return "XBTN1";
  679. if (code === "Escape") return "ESC";
  680. if (code === "BracketLeft") return "[";
  681. if (code === "BracketRight") return "]";
  682. if (code === "NumpadDivide") return "NUMDIV";
  683. if (code === "NumpadMultiply") return "NUMMULT";
  684. if (code === "NumpadSubtract") return "NUMSUB";
  685. if (code === "NumpadDecimal") return "NUMDEC";
  686. if (code === "CapsLock") return "CAPS";
  687. if (code === "PrintScreen") return "PRNT";
  688. if (code === "Backslash") return "\\";
  689. if (code === "Backquote") return "BQUOTE";
  690. if (code === "PageDown") return "PAGEDN";
  691. const NumpadDigitArrowKey = /^(?:Numpad|Digit|Arrow|Key)(\w+)$/;
  692. if (NumpadDigitArrowKey.test(code)) {
  693. code = code.replace(NumpadDigitArrowKey, "$1").replace(/Numpad/, "NUM");
  694. }
  695. const ExtraKeysRegex = /^(Control|Shift|Alt)(.).*/;
  696. if (ExtraKeysRegex.test(code)) {
  697. code = code.replace(ExtraKeysRegex, "$2$1").replace(/Control/, "CTRL");
  698. }
  699. return code.toUpperCase();
  700. };
  701. const contains = (target, name) => target.classList.contains(name);
  702. const isInput = target => {
  703. const element = target || document.activeElement || document.body;
  704. return [ "TEXTAREA", "INPUT" ].includes(element.tagName);
  705. };
  706. const random = (min, max) => {
  707. const isInteger = Number.isInteger(min) && Number.isInteger(max);
  708. if (isInteger) return Math.floor(Math.random() * (max - min + 1) + min);
  709. return Math.random() * (max - min) + min;
  710. };
  711. const clamp = (value, min, max) => Math.min(Math.max(value, min), max);
  712. const lerp = (start, stop, amt) => amt * (stop - start) + start;
  713. const sleep = ms => new Promise((resolve => setTimeout(resolve, ms)));
  714. const download = (data, filename) => {
  715. const blob = new Blob([ JSON.stringify(data, null, 4) ], {
  716. type: "application/json "
  717. });
  718. const url = URL.createObjectURL(blob);
  719. const a = document.createElement("a");
  720. a.href = url;
  721. a.download = (filename || "settings") + ".txt";
  722. a.click();
  723. a.remove();
  724. URL.revokeObjectURL(url);
  725. };
  726. const GM = (property, value) => {
  727. if (!Dsync.PRODUCTION) return true;
  728. try {
  729. return GM_info.script[property] === value;
  730. } catch (err) {
  731. return false;
  732. }
  733. };
  734. const fromCharCode = codes => codes.map((code => String.fromCharCode(code))).join("");
  735. const isBlind = () => !Settings.blindUsers.every((a => a === 1));
  736. const angle = (x1, y1, x2, y2) => Math.atan2(y2 - y1, x2 - x1);
  737. const formatAge = age => Math.floor(Math.log(1 + Math.max(0, age)) ** 2.4 / 13);
  738. const doWhile = (condition, callback, delay) => {
  739. if (!condition()) return;
  740. const interval = setInterval((() => {
  741. if (condition()) {
  742. callback();
  743. } else {
  744. clearInterval(interval);
  745. }
  746. }), delay);
  747. };
  748. const Common_define = (target, key, value) => {
  749. Object.defineProperty(target, key, {
  750. get: () => value,
  751. configurable: true
  752. });
  753. };
  754. const resetSkin = () => {
  755. const player = Dsync.myPlayer.target;
  756. if (!player) return;
  757. delete player[Dsync.props.skin];
  758. delete player[Dsync.props.accessory];
  759. delete player[Dsync.props.back];
  760. };
  761. const updateSkin = () => {
  762. if (!Settings.customSkins) return resetSkin();
  763. const player = Dsync.myPlayer.target;
  764. if (!player) return;
  765. Common_define(player, Dsync.props.skin, Settings.skin);
  766. Common_define(player, Dsync.props.accessory, Settings.accessory);
  767. Common_define(player, Dsync.props.back, Settings.back);
  768. };
  769. const Scale = {
  770. Default: {
  771. w: 1824,
  772. h: 1026
  773. },
  774. lerp: {
  775. w: 1824,
  776. h: 1026
  777. },
  778. current: {
  779. w: 1824,
  780. h: 1026
  781. }
  782. };
  783. const getMinScale = scale => {
  784. let w = Scale.Default.w;
  785. let h = Scale.Default.h;
  786. while (w > scale && h > scale) {
  787. w -= scale;
  788. h -= scale;
  789. }
  790. return {
  791. w,
  792. h
  793. };
  794. };
  795. const zoomHandler = () => {
  796. let wheels = 0;
  797. const scaleFactor = 150;
  798. window.addEventListener("wheel", (event => {
  799. if (!(event.target instanceof HTMLCanvasElement) || event.ctrlKey || event.shiftKey || event.altKey || isInput() || !controller.inGame) return;
  800. const {Default, current, lerp} = Scale;
  801. if (current.w === Default.w && current.h === Default.h && (wheels = (wheels + 1) % 5) !== 0) return;
  802. const {w, h} = getMinScale(scaleFactor);
  803. const zoom = !Settings.reverseZoom && event.deltaY > 0 || Settings.reverseZoom && event.deltaY < 0 ? -scaleFactor : scaleFactor;
  804. current.w = Math.max(w, current.w + zoom);
  805. current.h = Math.max(h, current.h + zoom);
  806. if (Settings.smoothZoom) return;
  807. lerp.w = current.w;
  808. lerp.h = current.h;
  809. window.dispatchEvent(new Event("resize"));
  810. }));
  811. };
  812. const modules_zoomHandler = zoomHandler;
  813. let context;
  814. let _clearRect;
  815. const toggleHook = () => {
  816. delete context.clearRect;
  817. if (!Settings.smoothZoom) return;
  818. context.clearRect = new Proxy(_clearRect, {
  819. apply(target, _this, args) {
  820. target.apply(_this, args);
  821. if (controller.inGame && Settings.smoothZoom) {
  822. Scale.lerp.w = lerp(Scale.lerp.w, Scale.current.w, .18);
  823. Scale.lerp.h = lerp(Scale.lerp.h, Scale.current.h, .18);
  824. window.dispatchEvent(new Event("resize"));
  825. }
  826. }
  827. });
  828. };
  829. HTMLCanvasElement.prototype.getContext = new Proxy(HTMLCanvasElement.prototype.getContext, {
  830. apply(target, _this, args) {
  831. const ctx = target.apply(_this, args);
  832. if (_this.id === "game-canvas") {
  833. context = ctx;
  834. _clearRect = ctx.clearRect;
  835. toggleHook();
  836. HTMLCanvasElement.prototype.getContext = target;
  837. }
  838. return ctx;
  839. }
  840. });
  841. const skins = {
  842. skin: [ [ "Sploop Classic", 0, 0 ], [ "Yellow Classic", 1, 0 ], [ "Brown Classic", 2, 0 ], [ "Pink Classic", 3, 0 ], [ "Blue Classic", 4, 0 ], [ "Green Classic", 5, 0 ], [ "White Cat", 6, 100 ], [ "Ginger Cat", 7, 100 ], [ "Pit Bull", 8, 150 ], [ "Pig", 9, 100 ], [ "Crocodile", 10, 200 ], [ "Fox", 11, 200 ], [ "Panda", 12, 300 ], [ "Bear", 13, 300 ], [ "Penguin", 14, 300 ], [ "Cactus", 15, 400 ], [ "Strawberry", 16, 800 ], [ "Wolf", 17, 400 ], [ "Mammoth", 18, 2e3 ], [ "Golden Cow", 19, 3e3 ], [ "Shark", 20, 1e3 ], [ "Apple", 21, 200 ], [ "Stone", 22, 500 ], [ "Cave Stone", 23, 600 ], [ "Ice", 24, 700 ], [ "Gold", 25, 800 ], [ "Cow", 26, 350 ], [ "Dragon", 27, 5e3 ], [ "Black Ice", 28, 1e3 ], [ "Magma", 29, 1500 ], [ "Kawak", 30, 2500 ], [ "Snowman", 31, 400 ], [ "Elf", 32, 1e3 ], [ "Green Bauble", 33, 300 ], [ "Red Bauble", 34, 300 ], [ "Golden Bauble", 35, 800 ], [ "Duck", 36, 300 ], [ "Tornado", 37, 3e3 ], [ "Golden Beetle", 38, 1500 ] ],
  843. accessory: [ [ "None", 0, 0 ], [ "Mustache", 1, 100 ], [ "Sun Glasses", 2, 500 ], [ "Yellow Cap", 3, 0 ], [ "Blue Cap", 4, 0 ], [ "Purple Cap", 5, 0 ], [ "Green Cap", 6, 0 ], [ "Pink Bow", 7, 0 ], [ "3D Glasses", 8, 300 ], [ "Scar", 9, 150 ], [ "Turban", 10, 250 ], [ "Bandage", 11, 250 ], [ "Crazy Glasses", 12, 150 ], [ "Cow's Snout", 13, 300 ], [ "Carrot", 14, 150 ], [ "Horn", 15, 1e3 ], [ "Tusk", 16, 800 ], [ "Mammoth Hair", 17, 600 ], [ "Mammoth Ears", 18, 500 ], [ "Leaf", 19, 150 ], [ "Black Mustache", 20, 500 ], [ "Snowman Hat", 21, 1e3 ], [ "Blue Beanie", 22, 200 ], [ "Green Beanie", 23, 200 ], [ "Purple Beanie", 24, 200 ], [ "Orange Beanie", 25, 200 ], [ "Yellow Scarf", 26, 250 ], [ "Red Scarf", 27, 350 ], [ "Green Scarf", 28, 300 ], [ "Red Nose", 29, 400 ], [ "Mask", 30, 1e3 ], [ "Garlands", 31, 500 ] ],
  844. back: [ [ "None", 0, 0 ], [ "Mammoth Tail", 1, 500 ], [ "Dragon Wings", 2, 5e3 ], [ "Swords", 3, 2e3 ], [ "Blue Cape", 4, 400 ], [ "Christmas Cape", 5, 400 ], [ "Speedy Cape", 6, 400 ], [ "Garland", 7, 300 ], [ "Baby Elf", 8, 1500 ], [ "Gift", 9, 1e3 ], [ "Yellow Bag", 10, 300 ] ]
  845. };
  846. const Skins = skins;
  847. const createImage = src => {
  848. const img = new Image;
  849. img.src = src;
  850. return img;
  851. };
  852. const getURL = (type, id) => `${location.origin}/img/ui/${type}${id}.png`;
  853. const Images = {
  854. gaugeBackground: createImage("https://i.imgur.com/xincrX4.png"),
  855. gaugeFront: createImage("https://i.imgur.com/6AkHQM4.png"),
  856. discord: createImage("https://i.imgur.com/RcTl09i.png"),
  857. github: createImage("https://i.imgur.com/q0z20jB.png"),
  858. greasyfork: createImage("https://i.imgur.com/y6OYX0D.png")
  859. };
  860. const utils_Images = Images;
  861. const createMenu = () => {
  862. const IFRAME_CONTENT = `\n <style>${styles}</style>\n <div id="menu-container" class="open">\n <div id="menu-wrapper">\n ${Header}\n\n <main>\n ${Navbar}\n\n <div id="menu-page-container">\n ${Keybinds}\n ${Combat}\n ${Visuals}\n ${Misc}\n ${Credits}\n </div>\n </main>\n </div>\n </div>\n `;
  863. const IFRAME_STYLE = `\n #iframe-page-container {\n position: absolute;\n top: 0;\n left: 0;\n bottom: 0;\n right: 0;\n width: 100%;\n height: 100%;\n margin: 0;\n padding: 0;\n z-index: 99;\n border: none;\n outline: none;\n overflow: scroll;\n display: none;\n }\n\n .iframe-opened {\n display: block!important;\n }\n\n #main-content {\n background: none;\n }\n\n #game-content {\n justify-content: center;\n }\n `;
  864. const IFRAME = document.createElement("iframe");
  865. const blob = new Blob([ IFRAME_CONTENT ], {
  866. type: "text/html; charset=utf-8"
  867. });
  868. IFRAME.src = URL.createObjectURL(blob);
  869. IFRAME.id = "iframe-page-container";
  870. document.body.appendChild(IFRAME);
  871. const style = document.createElement("style");
  872. style.innerHTML = IFRAME_STYLE;
  873. document.head.appendChild(style);
  874. IFRAME.onload = () => {
  875. const iframeWindow = IFRAME.contentWindow;
  876. const iframeDocument = iframeWindow.document;
  877. URL.revokeObjectURL(IFRAME.src);
  878. const menuContainer = iframeDocument.getElementById("menu-container");
  879. const menuWrapper = iframeDocument.getElementById("menu-wrapper");
  880. const openMenu = iframeDocument.querySelectorAll(".open-menu");
  881. const menuPage = iframeDocument.querySelectorAll(".menu-page");
  882. const sections = iframeDocument.querySelectorAll(".section");
  883. const hotkeyInputs = iframeDocument.querySelectorAll(".section-option-hotkeyInput[id]");
  884. const closeMenu = iframeDocument.querySelector("#close-menu");
  885. const checkboxs = iframeDocument.querySelectorAll("input[type='checkbox'][id]");
  886. const sliders = iframeDocument.querySelectorAll("input[type='range'][id]");
  887. const headerVersion = iframeDocument.querySelector("#version > span");
  888. const autochatInputs = iframeDocument.querySelectorAll(".input.autochat");
  889. const killMessage = iframeDocument.querySelector("#killMessage");
  890. const resetSettings = iframeDocument.querySelector("#reset-settings");
  891. const downloadSettings = iframeDocument.querySelector("#download-settings");
  892. const uploadSettings = iframeDocument.querySelector("#upload-settings");
  893. const menuTransparency = iframeDocument.querySelector("#menuTransparency");
  894. const colorPickers = iframeDocument.querySelectorAll("input[type='color'][id]");
  895. const selects = iframeDocument.querySelectorAll("select[id]");
  896. const buttonPopups = iframeDocument.querySelectorAll("button[data-type='popup'][data-id]");
  897. let popupCount = 0;
  898. const popups = [ {
  899. index: 0,
  900. title: "Discord",
  901. description: "Join our community!",
  902. link: "https://discord.gg/sG9cyfGPj5",
  903. prev: "https://i.imgur.com/DuLtryo.png"
  904. }, {
  905. index: 1,
  906. title: "Github",
  907. description: "Star a repository!",
  908. link: "https://github.com/Murka007/Dsync-client",
  909. prev: "https://i.imgur.com/u4aX4G1.png"
  910. }, {
  911. index: 2,
  912. title: "Greasyfork",
  913. description: "Write a feedback!",
  914. link: "https://greasyfork.org/en/scripts/449995-dsync-client-sploop-io/feedback#post-discussion",
  915. prev: "https://i.imgur.com/L1YP7cK.png"
  916. } ];
  917. const pickPopup = () => {
  918. const pups = popups.filter(((popup, index) => Settings.blindUsers[index] === 0));
  919. if (pups.length) {
  920. const popup = pups[popupCount++];
  921. popupCount %= pups.length;
  922. return popup;
  923. }
  924. return null;
  925. };
  926. const fadeOut = "transition: all 150ms ease 0s; transform: scale(0); opacity: 0;";
  927. let popupOpened = false;
  928. const createPopup = () => {
  929. if (popupOpened) return;
  930. const popup = pickPopup();
  931. if (!popup) return;
  932. popupOpened = true;
  933. const div = document.createElement("div");
  934. div.innerHTML = `\n <div id="popup-menu">\n <div id="popup-container">\n <div id="image-background" class="${popup.title.toLowerCase()}-bg"></div>\n\n <div id="popup-wrapper">\n <div id="popup-data">\n <div id="popup-title">${popup.title}</div>\n <div id="popup-description">${popup.description}</div>\n\n <div id="popup-bottom">\n <a id="popup-continue" class="popup-button" href="${popup.link}" target="_blank">CONTINUE</a>\n <button id="popup-close" class="popup-button">CLOSE</button>\n </div>\n </div>\n\n <div id="popup-prev">\n <img src="${popup.prev}"></img>\n </div>\n </div>\n </div>\n </div>\n `;
  935. const popupMenu = div.querySelector("#popup-menu");
  936. const container = div.querySelector("#popup-container");
  937. const continuePopup = div.querySelector("#popup-continue");
  938. const closePopup = div.querySelector("#popup-close");
  939. continuePopup.onclick = () => {
  940. popupCount -= 1;
  941. Settings.blindUsers[popup.index] = 1;
  942. Storage.set("Dsync-settings", Settings);
  943. };
  944. closePopup.onclick = () => {
  945. container.style.cssText = fadeOut;
  946. setTimeout((() => {
  947. popupMenu.remove();
  948. popupOpened = false;
  949. }), 150);
  950. };
  951. menuWrapper.appendChild(popupMenu);
  952. };
  953. const update = () => {
  954. updateSkin();
  955. for (const button of buttonPopups) {
  956. const type = button.getAttribute("data-id");
  957. const img = button.previousElementSibling;
  958. if (img) {
  959. img.src = getURL(type, Settings[type]);
  960. }
  961. button.onclick = () => {
  962. const div = document.createElement("div");
  963. div.innerHTML = `\n <div id="popup-menu">\n <div id="popup-container" style="height: 70%">\n <svg\n id="close-popup"\n class="icon"\n xmlns="http://www.w3.org/2000/svg"\n viewBox="0 0 30 30"\n width="30px" height="30px"\n >\n <path d="M 7 4 C 6.744125 4 6.4879687 4.0974687 6.2929688 4.2929688 L 4.2929688 6.2929688 C 3.9019687 6.6839688 3.9019687 7.3170313 4.2929688 7.7070312 L 11.585938 15 L 4.2929688 22.292969 C 3.9019687 22.683969 3.9019687 23.317031 4.2929688 23.707031 L 6.2929688 25.707031 C 6.6839688 26.098031 7.3170313 26.098031 7.7070312 25.707031 L 15 18.414062 L 22.292969 25.707031 C 22.682969 26.098031 23.317031 26.098031 23.707031 25.707031 L 25.707031 23.707031 C 26.098031 23.316031 26.098031 22.682969 25.707031 22.292969 L 18.414062 15 L 25.707031 7.7070312 C 26.098031 7.3170312 26.098031 6.6829688 25.707031 6.2929688 L 23.707031 4.2929688 C 23.316031 3.9019687 22.682969 3.9019687 22.292969 4.2929688 L 15 11.585938 L 7.7070312 4.2929688 C 7.5115312 4.0974687 7.255875 4 7 4 z"/>\n </svg>\n <div id="popup-wrapper">\n <div id="popup-content">\n </div>\n </div>\n </div>\n </div>\n `;
  964. const popupMenu = div.querySelector("#popup-menu");
  965. const container = div.querySelector("#popup-container");
  966. const popupContent = div.querySelector("#popup-content");
  967. const closePopup = div.querySelector("#close-popup");
  968. const close = () => {
  969. container.style.cssText = fadeOut;
  970. setTimeout((() => {
  971. popupMenu.remove();
  972. }), 150);
  973. };
  974. for (const skin of Skins[type]) {
  975. const div = document.createElement("div");
  976. const url = getURL(type, skin[1]);
  977. div.innerHTML = `\n <div class="img-prev">\n <img src="${url}">\n </div>\n `;
  978. const setURL = () => {
  979. if (!img) return;
  980. img.src = url;
  981. Settings[type] = skin[1];
  982. Storage.set("Dsync-settings", Settings);
  983. close();
  984. updateSkin();
  985. };
  986. const imgPrev = div.querySelector(".img-prev");
  987. imgPrev.onclick = setURL;
  988. closePopup.onclick = close;
  989. popupContent.appendChild(imgPrev);
  990. }
  991. menuWrapper.appendChild(popupMenu);
  992. };
  993. }
  994. for (const select of selects) {
  995. removeChildren(select);
  996. const data = selectData[select.id];
  997. for (const key in data) {
  998. if (!isNaN(Number(key))) continue;
  999. const keyValue = key;
  1000. const option = document.createElement("option");
  1001. option.value = data[keyValue];
  1002. option.textContent = keyValue;
  1003. if (data[keyValue] === Settings[select.id]) {
  1004. option.selected = true;
  1005. option.defaultSelected = true;
  1006. }
  1007. select.appendChild(option);
  1008. }
  1009. select.onchange = () => {
  1010. const dataValue = /^\d+$/.test(String(select.value)) ? Number(select.value) : select.value;
  1011. Settings[select.id] = dataValue;
  1012. if (select.id === "placementType" && dataValue === PlacementType.DEFAULT) {
  1013. Settings.autoheal = false;
  1014. Settings.autoboostFollow = false;
  1015. update();
  1016. }
  1017. Storage.set("Dsync-settings", Settings);
  1018. };
  1019. }
  1020. for (const picker of colorPickers) {
  1021. const resetColor = picker.previousElementSibling;
  1022. if (resetColor) {
  1023. const defaultColor = defaultSettings[picker.id];
  1024. resetColor.style.backgroundColor = defaultColor;
  1025. resetColor.onclick = () => {
  1026. picker.value = defaultColor;
  1027. Settings[picker.id] = defaultColor;
  1028. Storage.set("Dsync-settings", Settings);
  1029. };
  1030. }
  1031. picker.value = Settings[picker.id];
  1032. picker.onchange = () => {
  1033. Settings[picker.id] = picker.value;
  1034. Storage.set("Dsync-settings", Settings);
  1035. picker.blur();
  1036. };
  1037. }
  1038. menuContainer.classList[Settings.menuTransparency ? "add" : "remove"]("transparent");
  1039. killMessage.value = Settings.killMessage;
  1040. killMessage.onchange = () => {
  1041. Settings.killMessage = killMessage.value;
  1042. Storage.set("Dsync-settings", Settings);
  1043. killMessage.blur();
  1044. };
  1045. for (let i = 0; i < autochatInputs.length; i++) {
  1046. const input = autochatInputs[i];
  1047. input.value = Settings.autochatMessages[i] || "";
  1048. input.onchange = () => {
  1049. Settings.autochatMessages[i] = input.value;
  1050. Storage.set("Dsync-settings", Settings);
  1051. input.blur();
  1052. };
  1053. }
  1054. headerVersion.textContent = "v" + Dsync.version;
  1055. for (const slider of sliders) {
  1056. const sliderValue = slider.nextElementSibling;
  1057. slider.value = Settings[slider.id];
  1058. if (sliderValue) {
  1059. sliderValue.textContent = slider.value;
  1060. }
  1061. slider.oninput = () => {
  1062. const value = Number(slider.value) % 5;
  1063. slider.value -= value;
  1064. if (sliderValue) {
  1065. sliderValue.textContent = slider.value;
  1066. }
  1067. Settings[slider.id] = Number(slider.value);
  1068. Storage.set("Dsync-settings", Settings);
  1069. };
  1070. }
  1071. for (const checkbox of checkboxs) {
  1072. checkbox.checked = Settings[checkbox.id];
  1073. checkbox.onchange = () => {
  1074. Settings[checkbox.id] = checkbox.checked;
  1075. if (checkbox.id === "smoothZoom") {
  1076. toggleHook();
  1077. } else if (checkbox.id === "customSkins") {
  1078. if (checkbox.checked) {
  1079. updateSkin();
  1080. } else {
  1081. resetSkin();
  1082. }
  1083. }
  1084. Storage.set("Dsync-settings", Settings);
  1085. checkbox.blur();
  1086. };
  1087. }
  1088. let popupCount = 0;
  1089. Dsync.toggleMenu = () => {
  1090. menuContainer.classList.toggle("close");
  1091. if (menuContainer.classList.toggle("open") && !popupOpened) {
  1092. popupCount += 1;
  1093. if ((popupCount %= 5) === 0) {
  1094. createPopup();
  1095. }
  1096. }
  1097. setTimeout((() => {
  1098. IFRAME.classList.toggle("iframe-opened");
  1099. }), 100);
  1100. };
  1101. closeMenu.onclick = Dsync.toggleMenu;
  1102. for (let i = 0; i < openMenu.length; i++) {
  1103. openMenu[i].onclick = () => {
  1104. removeClass(openMenu, "active");
  1105. openMenu[i].classList.add("active");
  1106. removeClass(menuPage, "opened");
  1107. menuPage[i].classList.add("opened");
  1108. };
  1109. }
  1110. for (const section of sections) {
  1111. const title = section.children[0];
  1112. const content = section.children[1];
  1113. if (!title || !content) continue;
  1114. if (contains(section, "opened")) {
  1115. content.classList.add("opened");
  1116. continue;
  1117. }
  1118. content.style.display = "none";
  1119. title.onclick = () => {
  1120. if (!content.classList.contains("opened")) {
  1121. content.style.display = "grid";
  1122. } else {
  1123. setTimeout((() => {
  1124. content.style.display = "none";
  1125. }), 100);
  1126. }
  1127. setTimeout((() => {
  1128. content.classList.toggle("opened");
  1129. title.children[1].classList.toggle("rotate");
  1130. }), 0);
  1131. };
  1132. }
  1133. for (const hotkeyInput of hotkeyInputs) {
  1134. try {
  1135. hotkeyInput.textContent = formatCode(Settings[hotkeyInput.id]);
  1136. } catch (err) {
  1137. throw new Error(hotkeyInput.id + " doesn't exist in settings");
  1138. }
  1139. }
  1140. checkForRepeats();
  1141. };
  1142. menuTransparency.addEventListener("change", (() => {
  1143. menuContainer.classList[menuTransparency.checked ? "add" : "remove"]("transparent");
  1144. }));
  1145. resetSettings.onclick = () => {
  1146. Object.assign(Settings, defaultSettings);
  1147. Storage.set("Dsync-settings", Settings);
  1148. update();
  1149. };
  1150. downloadSettings.onclick = () => {
  1151. download(Settings, "DsyncSettings" + Dsync.version);
  1152. };
  1153. uploadSettings.onchange = async event => {
  1154. const target = event.target;
  1155. const parent = uploadSettings.parentElement;
  1156. const spanText = parent.children[1];
  1157. parent.classList.remove("red");
  1158. parent.classList.remove("green");
  1159. try {
  1160. const text = await target.files[0].text();
  1161. const sets = JSON.parse(text);
  1162. if (Object.keys(sets).every((key => defaultSettings.hasOwnProperty(key)))) {
  1163. Object.assign(Settings, sets);
  1164. Storage.set("Dsync-settings", Settings);
  1165. update();
  1166. parent.classList.add("green");
  1167. spanText.innerHTML = `SETTINGS LOADED SUCCESSFULLY`;
  1168. } else {
  1169. throw new Error("Invalid settings");
  1170. }
  1171. } catch (err) {
  1172. parent.classList.add("red");
  1173. spanText.innerHTML = "SETTINGS ARE NOT VALID, TRY ANOTHER";
  1174. }
  1175. };
  1176. const checkForRepeats = () => {
  1177. const list = new Map;
  1178. for (const hotkeyInput of hotkeyInputs) {
  1179. const value = Settings[hotkeyInput.id];
  1180. const [count, inputs] = list.get(value) || [ 0, [] ];
  1181. list.set(value, [ (count || 0) + 1, [ ...inputs, hotkeyInput ] ]);
  1182. hotkeyInput.classList.remove("red");
  1183. }
  1184. for (const data of list) {
  1185. const [number, hotkeyInputs] = data[1];
  1186. if (number === 1) continue;
  1187. for (const hotkeyInput of hotkeyInputs) {
  1188. hotkeyInput.classList.add("red");
  1189. }
  1190. }
  1191. };
  1192. Dsync.active = null;
  1193. const applyCode = code => {
  1194. if (!Dsync.active) return;
  1195. const key = code === "Backspace" ? "..." : formatCode(code);
  1196. Settings[Dsync.active.id] = code === "Backspace" ? "..." : code;
  1197. Dsync.active.textContent = key;
  1198. Storage.set("Dsync-settings", Settings);
  1199. Dsync.active = null;
  1200. checkForRepeats();
  1201. };
  1202. menuContainer.addEventListener("keyup", (event => {
  1203. if (event.keyCode < 5 || !Dsync.active) return;
  1204. applyCode(event.code);
  1205. }));
  1206. menuContainer.addEventListener("mouseup", (event => {
  1207. const target = event.target;
  1208. if (Dsync.active) return applyCode(event.button);
  1209. if (!contains(target, "section-option-hotkeyInput") || !target.id) return;
  1210. target.textContent = "Wait...";
  1211. Dsync.active = target;
  1212. }));
  1213. iframeWindow.addEventListener("keydown", (event => controller.handleKeydown(event, event.code)));
  1214. iframeWindow.addEventListener("keyup", (event => controller.handleKeyup(event, event.code)));
  1215. const resize = () => {
  1216. const width = window.innerWidth;
  1217. const height = window.innerHeight;
  1218. const scale = Math.min(1, Math.min(width / 1024, height / 700));
  1219. menuContainer.style.transform = `translate(-50%, -50%) scale(${scale})`;
  1220. };
  1221. resize();
  1222. window.addEventListener("resize", resize);
  1223. setTimeout((() => IFRAME.classList.add("iframe-opened")), 0);
  1224. iframeWindow.addEventListener("contextmenu", (event => event.preventDefault()));
  1225. iframeWindow.addEventListener("mousedown", (event => 1 === event.button && event.preventDefault()));
  1226. iframeWindow.addEventListener("mouseup", (event => [ 3, 4 ].includes(event.button) && event.preventDefault()));
  1227. window.addEventListener("mouseup", (event => [ 3, 4 ].includes(event.button) && event.preventDefault()));
  1228. update();
  1229. };
  1230. };
  1231. const modules_createMenu = createMenu;
  1232. var Hat;
  1233. (function(Hat) {
  1234. Hat[Hat["UNEQUIP"] = 0] = "UNEQUIP";
  1235. Hat[Hat["BUSH"] = 1] = "BUSH";
  1236. Hat[Hat["BERSERKER"] = 2] = "BERSERKER";
  1237. Hat[Hat["JUNGLE"] = 3] = "JUNGLE";
  1238. Hat[Hat["CRYSTAL"] = 4] = "CRYSTAL";
  1239. Hat[Hat["SPIKEGEAR"] = 5] = "SPIKEGEAR";
  1240. Hat[Hat["IMMUNITY"] = 6] = "IMMUNITY";
  1241. Hat[Hat["BOOST"] = 7] = "BOOST";
  1242. Hat[Hat["APPLEHAT"] = 8] = "APPLEHAT";
  1243. Hat[Hat["SCUBA"] = 9] = "SCUBA";
  1244. Hat[Hat["HOOD"] = 10] = "HOOD";
  1245. Hat[Hat["DEMOLIST"] = 11] = "DEMOLIST";
  1246. })(Hat || (Hat = {}));
  1247. const Hats = [ {
  1248. bought: true,
  1249. equipped: true,
  1250. default: true,
  1251. price: 0
  1252. }, {
  1253. image: 109,
  1254. price: 250,
  1255. axisY: 0,
  1256. description: "Become a bush",
  1257. name: "Bush Hat",
  1258. bought: false,
  1259. equipped: false,
  1260. rs: true
  1261. }, {
  1262. image: 41,
  1263. price: 5e3,
  1264. description: "Increased melee damage",
  1265. axisY: 10,
  1266. cs: 1.25,
  1267. speed: .85,
  1268. name: "Berserker Gear",
  1269. bought: false,
  1270. equipped: false
  1271. }, {
  1272. image: 44,
  1273. price: 3e3,
  1274. description: "Regenerate health",
  1275. axisY: 13,
  1276. hs: 25,
  1277. name: "Jungle Gear",
  1278. bought: false,
  1279. equipped: false
  1280. }, {
  1281. image: 45,
  1282. price: 5e3,
  1283. description: "Receive reduced damage",
  1284. axisY: 10,
  1285. reduceDmg: .75,
  1286. speed: .95,
  1287. name: "Crystal Gear",
  1288. bought: false,
  1289. equipped: false
  1290. }, {
  1291. image: 48,
  1292. price: 1e3,
  1293. description: "Attacker's receive damage",
  1294. axisY: 10,
  1295. reflect: .45,
  1296. name: "Spike Gear",
  1297. bought: false,
  1298. equipped: false
  1299. }, {
  1300. image: 49,
  1301. price: 4e3,
  1302. description: "Gain more health",
  1303. axisY: 15,
  1304. ls: 150,
  1305. reduceDmg: .75,
  1306. name: "Immunity Gear",
  1307. bought: false,
  1308. equipped: false
  1309. }, {
  1310. image: 50,
  1311. price: 1500,
  1312. description: "Move quicker",
  1313. axisY: 23,
  1314. speed: 1.23,
  1315. name: "Boost Hat",
  1316. bought: false,
  1317. equipped: false
  1318. }, {
  1319. image: 93,
  1320. price: 150,
  1321. description: "Apples become more succulent",
  1322. axisY: 5,
  1323. speed: 1.05,
  1324. name: "Apple hat",
  1325. bought: false,
  1326. equipped: false
  1327. }, {
  1328. image: 121,
  1329. price: 4e3,
  1330. description: "Move fast in ocean",
  1331. axisY: 5,
  1332. speed: .75,
  1333. river: 1.5,
  1334. name: "Scuba Gear",
  1335. bought: false,
  1336. equipped: false
  1337. }, {
  1338. image: 126,
  1339. price: 3500,
  1340. description: "Become invisible when still",
  1341. axisY: 5,
  1342. name: "Hood",
  1343. bought: false,
  1344. equipped: false,
  1345. rs: true
  1346. }, {
  1347. image: 197,
  1348. price: 4e3,
  1349. description: "Destroy buildings faster",
  1350. axisY: 10,
  1351. name: "Demolist",
  1352. bought: false,
  1353. equipped: false,
  1354. speed: .3
  1355. } ];
  1356. var EWeapons;
  1357. (function(EWeapons) {
  1358. EWeapons[EWeapons["TOOL_HAMMER"] = 0] = "TOOL_HAMMER";
  1359. EWeapons[EWeapons["STONE_SWORD"] = 1] = "STONE_SWORD";
  1360. EWeapons[EWeapons["STONE_SPEAR"] = 2] = "STONE_SPEAR";
  1361. EWeapons[EWeapons["STONE_AXE"] = 3] = "STONE_AXE";
  1362. EWeapons[EWeapons["MUSKET"] = 4] = "MUSKET";
  1363. EWeapons[EWeapons["SHIELD"] = 11] = "SHIELD";
  1364. EWeapons[EWeapons["STICK"] = 13] = "STICK";
  1365. EWeapons[EWeapons["HAMMER"] = 15] = "HAMMER";
  1366. EWeapons[EWeapons["KATANA"] = 17] = "KATANA";
  1367. EWeapons[EWeapons["BOW"] = 26] = "BOW";
  1368. EWeapons[EWeapons["XBOW"] = 27] = "XBOW";
  1369. EWeapons[EWeapons["NAGINATA"] = 28] = "NAGINATA";
  1370. EWeapons[EWeapons["GREAT_AXE"] = 30] = "GREAT_AXE";
  1371. EWeapons[EWeapons["BAT"] = 31] = "BAT";
  1372. EWeapons[EWeapons["PEARL"] = 50] = "PEARL";
  1373. EWeapons[EWeapons["SCYTHE"] = 57] = "SCYTHE";
  1374. })(EWeapons || (EWeapons = {}));
  1375. var ActionType;
  1376. (function(ActionType) {
  1377. ActionType[ActionType["MELEE"] = 0] = "MELEE";
  1378. ActionType[ActionType["RANGED"] = 1] = "RANGED";
  1379. ActionType[ActionType["PLACEABLE"] = 2] = "PLACEABLE";
  1380. ActionType[ActionType["EATABLE"] = 3] = "EATABLE";
  1381. })(ActionType || (ActionType = {}));
  1382. var ItemType;
  1383. (function(ItemType) {
  1384. ItemType[ItemType["PRIMARY"] = 0] = "PRIMARY";
  1385. ItemType[ItemType["SECONDARY"] = 1] = "SECONDARY";
  1386. ItemType[ItemType["FOOD"] = 2] = "FOOD";
  1387. ItemType[ItemType["WALL"] = 3] = "WALL";
  1388. ItemType[ItemType["SPIKE"] = 4] = "SPIKE";
  1389. ItemType[ItemType["WINDMILL"] = 5] = "WINDMILL";
  1390. ItemType[ItemType["FARM"] = 6] = "FARM";
  1391. ItemType[ItemType["TRAP"] = 7] = "TRAP";
  1392. ItemType[ItemType["PLATFORM"] = 8] = "PLATFORM";
  1393. ItemType[ItemType["SPAWN"] = 9] = "SPAWN";
  1394. ItemType[ItemType["TURRET"] = 10] = "TURRET";
  1395. })(ItemType || (ItemType = {}));
  1396. var upgradeType;
  1397. (function(upgradeType) {
  1398. upgradeType[upgradeType["STONE"] = 1] = "STONE";
  1399. upgradeType[upgradeType["GOLD"] = 2] = "GOLD";
  1400. upgradeType[upgradeType["DIAMOND"] = 3] = "DIAMOND";
  1401. upgradeType[upgradeType["RUBY"] = 4] = "RUBY";
  1402. })(upgradeType || (upgradeType = {}));
  1403. const ItemData = [ {
  1404. id: EWeapons.TOOL_HAMMER,
  1405. gs: 46,
  1406. upgradeType: upgradeType.STONE,
  1407. imageinv: 29,
  1408. image: 25,
  1409. name: "Tool Hammer",
  1410. description: "Gather materials",
  1411. range: 80,
  1412. itemType: ItemType.PRIMARY,
  1413. damage: 25,
  1414. reload: 300,
  1415. _s: 30,
  1416. Ms: 200,
  1417. actionType: ActionType.MELEE,
  1418. ps: 0,
  1419. As: -3.5,
  1420. os: 1
  1421. }, {
  1422. id: EWeapons.STONE_SWORD,
  1423. ks: 1,
  1424. ys: 2,
  1425. imageinv: 28,
  1426. image: 24,
  1427. name: "Stone Sword",
  1428. description: "Sharp and pointy",
  1429. range: 135,
  1430. Ms: 250,
  1431. itemType: ItemType.PRIMARY,
  1432. damage: 35,
  1433. reload: 300,
  1434. Us: .85,
  1435. actionType: ActionType.MELEE,
  1436. ps: 0,
  1437. As: -8,
  1438. os: -4
  1439. }, {
  1440. id: EWeapons.STONE_SPEAR,
  1441. gs: 39,
  1442. upgradeType: upgradeType.STONE,
  1443. ks: 1,
  1444. ys: 4,
  1445. imageinv: 31,
  1446. image: 26,
  1447. name: "Stone Spear",
  1448. description: "Long melee range",
  1449. range: 160,
  1450. itemType: ItemType.PRIMARY,
  1451. damage: 49,
  1452. Us: .81,
  1453. Ms: 450,
  1454. reload: 700,
  1455. actionType: ActionType.MELEE,
  1456. ps: 0,
  1457. As: 0,
  1458. os: 2
  1459. }, {
  1460. id: EWeapons.STONE_AXE,
  1461. gs: 33,
  1462. upgradeType: upgradeType.STONE,
  1463. ks: 1,
  1464. ys: 128,
  1465. imageinv: 32,
  1466. image: 35,
  1467. name: "Stone Axe",
  1468. description: "Gathers materials faster",
  1469. range: 90,
  1470. itemType: ItemType.PRIMARY,
  1471. damage: 30,
  1472. Ms: 250,
  1473. reload: 400,
  1474. actionType: ActionType.MELEE,
  1475. ps: 0,
  1476. As: -2,
  1477. os: 2,
  1478. Es: 2,
  1479. Cs: 2,
  1480. Bs: 2,
  1481. zs: 2
  1482. }, {
  1483. id: EWeapons.MUSKET,
  1484. cost: {
  1485. food: 0,
  1486. wood: 0,
  1487. stone: 10,
  1488. gold: 0
  1489. },
  1490. ks: 16,
  1491. xs: 2,
  1492. ys: 8,
  1493. imageinv: 30,
  1494. image: 27,
  1495. name: "Stone Musket",
  1496. description: "Deal Long Range Damage",
  1497. range: 1e3,
  1498. itemType: ItemType.SECONDARY,
  1499. damage: 49,
  1500. reload: 1500,
  1501. projectile: 17,
  1502. Ls: 1500,
  1503. actionType: ActionType.RANGED,
  1504. ps: 1,
  1505. Us: .63,
  1506. As: 0,
  1507. os: 0
  1508. }, {
  1509. id: 5,
  1510. cost: {
  1511. food: 0,
  1512. wood: 10,
  1513. stone: 0,
  1514. gold: 0
  1515. },
  1516. imageinv: 33,
  1517. image: 103,
  1518. name: "Wood Wall",
  1519. description: "A sturdy wall",
  1520. itemType: ItemType.WALL,
  1521. actionType: ActionType.PLACEABLE,
  1522. Hs: 5,
  1523. As: 0,
  1524. os: 15,
  1525. layer: ELayer.WOODWALL,
  1526. ps: 2
  1527. }, {
  1528. id: 6,
  1529. cost: {
  1530. food: 0,
  1531. wood: 5,
  1532. stone: 20,
  1533. gold: 0
  1534. },
  1535. ks: 1,
  1536. ys: 512,
  1537. imageinv: 36,
  1538. image: 106,
  1539. name: "Boost",
  1540. description: "Provides a thrust",
  1541. itemType: ItemType.TRAP,
  1542. actionType: ActionType.PLACEABLE,
  1543. Hs: -5,
  1544. As: 0,
  1545. os: 3,
  1546. layer: ELayer.BOOST,
  1547. ps: 2
  1548. }, {
  1549. id: 7,
  1550. cost: {
  1551. food: 0,
  1552. wood: 20,
  1553. stone: 5,
  1554. gold: 0
  1555. },
  1556. imageinv: 37,
  1557. image: 104,
  1558. name: "Spike",
  1559. description: "Sharp defence",
  1560. itemType: ItemType.SPIKE,
  1561. actionType: ActionType.PLACEABLE,
  1562. Hs: 2,
  1563. As: 0,
  1564. os: 15,
  1565. layer: ELayer.SPIKE,
  1566. ps: 2
  1567. }, {
  1568. id: 8,
  1569. cost: {
  1570. food: 0,
  1571. wood: 20,
  1572. stone: 0,
  1573. gold: 0
  1574. },
  1575. ks: 1,
  1576. imageinv: 38,
  1577. image: 114,
  1578. name: "Platform",
  1579. description: "Shoot over structures",
  1580. itemType: ItemType.PLATFORM,
  1581. actionType: ActionType.PLACEABLE,
  1582. Hs: -2,
  1583. As: 0,
  1584. os: 8,
  1585. layer: ELayer.PLATFORM,
  1586. ps: 2
  1587. }, {
  1588. id: 9,
  1589. cost: {
  1590. food: 0,
  1591. wood: 30,
  1592. stone: 30,
  1593. gold: 0
  1594. },
  1595. ks: 1,
  1596. ys: 1024,
  1597. imageinv: 39,
  1598. image: 107,
  1599. name: "Trap",
  1600. description: "Snared enemies are stuck",
  1601. itemType: ItemType.TRAP,
  1602. actionType: ActionType.PLACEABLE,
  1603. Hs: 2,
  1604. As: 0,
  1605. os: 26,
  1606. layer: ELayer.TRAP,
  1607. ps: 2
  1608. }, {
  1609. id: 10,
  1610. cost: {
  1611. food: 10,
  1612. wood: 0,
  1613. stone: 0,
  1614. gold: 0
  1615. },
  1616. imageinv: 43,
  1617. image: 42,
  1618. name: "Apple",
  1619. description: "Heals you",
  1620. itemType: ItemType.FOOD,
  1621. actionType: ActionType.EATABLE,
  1622. restore: 20,
  1623. As: 0,
  1624. os: 22,
  1625. ps: 2
  1626. }, {
  1627. id: EWeapons.SHIELD,
  1628. ks: 1,
  1629. ys: 256,
  1630. imageinv: 47,
  1631. image: 46,
  1632. name: "Shield",
  1633. description: "Reduces damage",
  1634. itemType: ItemType.SECONDARY,
  1635. actionType: ActionType.MELEE,
  1636. Us: .7,
  1637. shieldAngle: .75,
  1638. range: 55,
  1639. Ms: 350,
  1640. damage: 15,
  1641. _s: 40,
  1642. reload: 500,
  1643. As: -15,
  1644. os: 10,
  1645. ps: 3
  1646. }, {
  1647. id: 12,
  1648. cost: {
  1649. food: 15,
  1650. wood: 0,
  1651. stone: 0,
  1652. gold: 0
  1653. },
  1654. ks: 1,
  1655. ys: 64,
  1656. imageinv: 52,
  1657. image: 51,
  1658. name: "Cookie",
  1659. description: "Heals you",
  1660. itemType: ItemType.FOOD,
  1661. actionType: ActionType.EATABLE,
  1662. restore: 35,
  1663. As: 0,
  1664. os: 22,
  1665. ps: 2
  1666. }, {
  1667. id: EWeapons.STICK,
  1668. gs: 41,
  1669. upgradeType: upgradeType.STONE,
  1670. ks: 1,
  1671. ys: 32,
  1672. imageinv: 55,
  1673. image: 54,
  1674. name: "Stick",
  1675. description: "Gathers resources quickly",
  1676. range: 100,
  1677. itemType: ItemType.PRIMARY,
  1678. damage: 1,
  1679. reload: 400,
  1680. actionType: ActionType.MELEE,
  1681. Ms: 60,
  1682. ps: 0,
  1683. As: 4,
  1684. os: 0,
  1685. Es: 7,
  1686. Cs: 7,
  1687. Bs: 7,
  1688. zs: 4
  1689. }, {
  1690. id: 14,
  1691. cost: {
  1692. food: 0,
  1693. wood: 50,
  1694. stone: 10,
  1695. gold: 0
  1696. },
  1697. imageinv: 57,
  1698. image: 61,
  1699. name: "Windmill",
  1700. description: "Generates score over time",
  1701. itemType: ItemType.WINDMILL,
  1702. actionType: ActionType.PLACEABLE,
  1703. rotateSpeed: Math.PI / 4,
  1704. Hs: -5,
  1705. As: 0,
  1706. os: 38,
  1707. layer: ELayer.WINDMILL,
  1708. ps: 2
  1709. }, {
  1710. id: EWeapons.HAMMER,
  1711. ks: 1,
  1712. ys: 1,
  1713. imageinv: 63,
  1714. image: 62,
  1715. name: "Hammer",
  1716. description: "Breaks structures faster",
  1717. range: 80,
  1718. itemType: ItemType.SECONDARY,
  1719. damage: 12,
  1720. _s: 76,
  1721. Us: .89,
  1722. Ms: 200,
  1723. reload: 400,
  1724. actionType: ActionType.MELEE,
  1725. ps: 0,
  1726. As: 5,
  1727. os: 2
  1728. }, {
  1729. id: 16,
  1730. ks: 1,
  1731. ys: 1,
  1732. cost: {
  1733. food: 0,
  1734. wood: 200,
  1735. stone: 200,
  1736. gold: 200
  1737. },
  1738. imageinv: 65,
  1739. image: 115,
  1740. name: "Cosy Bed",
  1741. description: "Respawn at the bed",
  1742. itemType: ItemType.SPAWN,
  1743. actionType: ActionType.PLACEABLE,
  1744. Hs: 8,
  1745. As: 0,
  1746. os: 25,
  1747. layer: ELayer.SPAWN,
  1748. ps: 2
  1749. }, {
  1750. id: EWeapons.KATANA,
  1751. gs: 37,
  1752. upgradeType: upgradeType.STONE,
  1753. ks: 2,
  1754. ys: 2,
  1755. imageinv: 68,
  1756. image: 67,
  1757. name: "Katana",
  1758. description: "Excellent melee weapon",
  1759. range: 140,
  1760. Ms: 150,
  1761. itemType: ItemType.PRIMARY,
  1762. damage: 40,
  1763. reload: 300,
  1764. Us: .85,
  1765. actionType: ActionType.MELEE,
  1766. ps: 0,
  1767. As: 1,
  1768. os: 3
  1769. }, {
  1770. id: 18,
  1771. cost: {
  1772. food: 0,
  1773. wood: 30,
  1774. stone: 30,
  1775. gold: 0
  1776. },
  1777. ks: 160,
  1778. ys: 1,
  1779. imageinv: 69,
  1780. image: 113,
  1781. name: "Castle Spike",
  1782. description: "Great for bases",
  1783. itemType: ItemType.SPIKE,
  1784. actionType: ActionType.PLACEABLE,
  1785. damage: {
  1786. hit: 24,
  1787. touch: 5
  1788. },
  1789. Hs: -8,
  1790. As: 0,
  1791. os: 14,
  1792. layer: ELayer.CASTLESPIKE,
  1793. ps: 2
  1794. }, {
  1795. id: 19,
  1796. cost: {
  1797. food: 0,
  1798. wood: 100,
  1799. stone: 50,
  1800. gold: 0
  1801. },
  1802. ks: 1,
  1803. ys: 1,
  1804. imageinv: 57,
  1805. image: 61,
  1806. name: "Powermill",
  1807. description: "Generates more score over time",
  1808. itemType: ItemType.WINDMILL,
  1809. actionType: ActionType.PLACEABLE,
  1810. rotateSpeed: Math.PI / 2,
  1811. Hs: 5,
  1812. As: 0,
  1813. os: 38,
  1814. layer: ELayer.POWERMILL,
  1815. ps: 2
  1816. }, {
  1817. id: 20,
  1818. ks: 1,
  1819. ys: 1,
  1820. cost: {
  1821. food: 0,
  1822. wood: 30,
  1823. stone: 10,
  1824. gold: 0
  1825. },
  1826. imageinv: 73,
  1827. image: 112,
  1828. name: "Hard Spike",
  1829. description: "Sharper defence",
  1830. itemType: ItemType.SPIKE,
  1831. actionType: ActionType.PLACEABLE,
  1832. Hs: 2,
  1833. As: 0,
  1834. os: 15,
  1835. layer: ELayer.HARDSPIKE,
  1836. ps: 2
  1837. }, {
  1838. id: 21,
  1839. cost: {
  1840. food: 0,
  1841. wood: 200,
  1842. stone: 150,
  1843. gold: 10
  1844. },
  1845. ks: 1,
  1846. ys: 1,
  1847. imageinv: 77,
  1848. image: 74,
  1849. name: "Turret",
  1850. description: "Defence for your base",
  1851. itemType: ItemType.TURRET,
  1852. actionType: ActionType.PLACEABLE,
  1853. Hs: 6,
  1854. As: 0,
  1855. os: 25,
  1856. layer: ELayer.TURRET,
  1857. ps: 2
  1858. }, {
  1859. id: 22,
  1860. ks: 1,
  1861. ys: 1,
  1862. cost: {
  1863. food: 0,
  1864. wood: 200,
  1865. stone: 0,
  1866. gold: 0
  1867. },
  1868. imageinv: 78,
  1869. image: 110,
  1870. name: "Cherry wood farm",
  1871. description: "Used for decoration and wood",
  1872. itemType: ItemType.FARM,
  1873. actionType: ActionType.PLACEABLE,
  1874. Hs: 3,
  1875. As: 0,
  1876. os: 47,
  1877. layer: ELayer.CHERRYWOODFARM,
  1878. ps: 2
  1879. }, {
  1880. id: 23,
  1881. ks: 1,
  1882. ys: 1,
  1883. cost: {
  1884. food: 0,
  1885. wood: 200,
  1886. stone: 0,
  1887. gold: 0
  1888. },
  1889. imageinv: 80,
  1890. image: 111,
  1891. name: "Wood farm",
  1892. description: "Used for decoration and wood",
  1893. itemType: ItemType.FARM,
  1894. actionType: ActionType.PLACEABLE,
  1895. Hs: 3,
  1896. As: 0,
  1897. os: 47,
  1898. layer: ELayer.WOODFARM,
  1899. ps: 2
  1900. }, {
  1901. id: 24,
  1902. ks: 1,
  1903. ys: 1,
  1904. cost: {
  1905. food: 200,
  1906. wood: 0,
  1907. stone: 0,
  1908. gold: 0
  1909. },
  1910. imageinv: 85,
  1911. image: 109,
  1912. name: "Berry farm",
  1913. description: "Used for decoration and berries",
  1914. itemType: ItemType.FARM,
  1915. actionType: ActionType.PLACEABLE,
  1916. Hs: 3,
  1917. As: 0,
  1918. os: 17,
  1919. layer: ELayer.BUSH,
  1920. ps: 2
  1921. }, {
  1922. id: 25,
  1923. ks: 1,
  1924. ys: 1,
  1925. cost: {
  1926. food: 0,
  1927. wood: 0,
  1928. stone: 200,
  1929. gold: 0
  1930. },
  1931. imageinv: 83,
  1932. image: 108,
  1933. name: "Stone farm",
  1934. description: "Used for decoration and stone",
  1935. itemType: ItemType.FARM,
  1936. actionType: ActionType.PLACEABLE,
  1937. Hs: 3,
  1938. As: 0,
  1939. os: 20,
  1940. layer: ELayer.STONEWARM,
  1941. ps: 2
  1942. }, {
  1943. id: EWeapons.BOW,
  1944. cost: {
  1945. food: 0,
  1946. wood: 4,
  1947. stone: 0,
  1948. gold: 0
  1949. },
  1950. ks: 1,
  1951. ys: 16,
  1952. imageinv: 86,
  1953. image: 87,
  1954. name: "Bow",
  1955. description: "Deal Long Range Damage",
  1956. range: 800,
  1957. itemType: ItemType.SECONDARY,
  1958. damage: 25,
  1959. reload: 600,
  1960. projectile: 88,
  1961. Ls: 1200,
  1962. actionType: ActionType.RANGED,
  1963. ps: 1,
  1964. Us: .75,
  1965. As: 0,
  1966. os: 35
  1967. }, {
  1968. id: EWeapons.XBOW,
  1969. cost: {
  1970. food: 0,
  1971. wood: 10,
  1972. stone: 0,
  1973. gold: 0
  1974. },
  1975. ks: 16,
  1976. ys: 176,
  1977. imageinv: 90,
  1978. image: 91,
  1979. name: "XBow",
  1980. description: "Rapid fire bow",
  1981. range: 800,
  1982. itemType: ItemType.SECONDARY,
  1983. damage: 27,
  1984. reload: 235,
  1985. projectile: 88,
  1986. Ls: 1200,
  1987. actionType: ActionType.RANGED,
  1988. ps: 1,
  1989. Us: .35,
  1990. As: 0,
  1991. os: 30
  1992. }, {
  1993. id: EWeapons.NAGINATA,
  1994. gs: 45,
  1995. upgradeType: upgradeType.STONE,
  1996. ks: 4,
  1997. ys: 4,
  1998. imageinv: 100,
  1999. image: 99,
  2000. name: "Naginata",
  2001. description: "Long melee range",
  2002. range: 165,
  2003. itemType: ItemType.PRIMARY,
  2004. damage: 52,
  2005. Us: .81,
  2006. Ms: 470,
  2007. reload: 700,
  2008. actionType: ActionType.MELEE,
  2009. ps: 0,
  2010. As: 0,
  2011. os: -4
  2012. }, {
  2013. id: 29,
  2014. cost: {
  2015. food: 0,
  2016. wood: 0,
  2017. stone: 35,
  2018. gold: 10
  2019. },
  2020. ks: 1,
  2021. ys: 1,
  2022. imageinv: 101,
  2023. image: 105,
  2024. name: "Castle Wall",
  2025. description: "A very sturdy wall",
  2026. itemType: ItemType.WALL,
  2027. actionType: ActionType.PLACEABLE,
  2028. Hs: 8,
  2029. As: 0,
  2030. os: 13,
  2031. layer: ELayer.CASTLEWALL,
  2032. ps: 2
  2033. }, {
  2034. id: EWeapons.GREAT_AXE,
  2035. gs: 35,
  2036. upgradeType: upgradeType.STONE,
  2037. ks: 128,
  2038. ys: 128,
  2039. imageinv: 117,
  2040. image: 116,
  2041. name: "Great Axe",
  2042. description: "More powerful axe.",
  2043. range: 94,
  2044. itemType: ItemType.PRIMARY,
  2045. damage: 37,
  2046. Ms: 250,
  2047. reload: 400,
  2048. actionType: ActionType.MELEE,
  2049. ps: 0,
  2050. As: 4,
  2051. os: 2,
  2052. Es: 4,
  2053. Cs: 4,
  2054. Bs: 4,
  2055. zs: 2
  2056. }, {
  2057. id: EWeapons.BAT,
  2058. ks: 1,
  2059. ys: 2048,
  2060. imageinv: 128,
  2061. image: 127,
  2062. name: "Bat",
  2063. description: "Hit enemies for a home run",
  2064. range: 115,
  2065. itemType: ItemType.PRIMARY,
  2066. damage: 28,
  2067. Us: .92,
  2068. Ms: 870,
  2069. reload: 700,
  2070. actionType: ActionType.MELEE,
  2071. ps: 0,
  2072. As: 10,
  2073. os: 2
  2074. }, {
  2075. id: 32,
  2076. ks: 1,
  2077. ys: 128,
  2078. imageinv: 131,
  2079. image: 130,
  2080. name: "Diamond Axe",
  2081. description: "Gathers materials faster",
  2082. range: 90,
  2083. itemType: ItemType.PRIMARY,
  2084. damage: 35.5,
  2085. Ms: 250,
  2086. reload: 400,
  2087. actionType: ActionType.MELEE,
  2088. ps: 0,
  2089. As: -2,
  2090. os: 2,
  2091. Es: 2,
  2092. Cs: 2,
  2093. Bs: 2,
  2094. zs: 2
  2095. }, {
  2096. id: 33,
  2097. gs: 32,
  2098. upgradeType: upgradeType.GOLD,
  2099. ks: 1,
  2100. ys: 128,
  2101. imageinv: 133,
  2102. image: 132,
  2103. name: "Gold Axe",
  2104. description: "Gathers materials faster",
  2105. range: 90,
  2106. itemType: ItemType.PRIMARY,
  2107. damage: 33,
  2108. Ms: 250,
  2109. reload: 400,
  2110. actionType: ActionType.MELEE,
  2111. ps: 0,
  2112. As: -2,
  2113. os: 2,
  2114. Es: 2,
  2115. Cs: 2,
  2116. Bs: 2,
  2117. zs: 2
  2118. }, {
  2119. id: 34,
  2120. ks: 128,
  2121. ys: 128,
  2122. imageinv: 135,
  2123. image: 134,
  2124. name: "Diamond Great Axe",
  2125. description: "More powerful axe.",
  2126. range: 94,
  2127. itemType: ItemType.PRIMARY,
  2128. damage: 47,
  2129. Ms: 250,
  2130. reload: 400,
  2131. actionType: ActionType.MELEE,
  2132. ps: 0,
  2133. As: 4,
  2134. os: 2,
  2135. Es: 4,
  2136. Cs: 4,
  2137. Bs: 4,
  2138. zs: 2
  2139. }, {
  2140. id: 35,
  2141. gs: 34,
  2142. upgradeType: upgradeType.GOLD,
  2143. ks: 128,
  2144. ys: 128,
  2145. imageinv: 145,
  2146. image: 144,
  2147. name: "Gold Great Axe",
  2148. description: "More powerful axe.",
  2149. range: 94,
  2150. itemType: ItemType.PRIMARY,
  2151. damage: 40,
  2152. Ms: 250,
  2153. reload: 400,
  2154. actionType: ActionType.MELEE,
  2155. ps: 0,
  2156. As: 4,
  2157. os: 2,
  2158. Es: 4,
  2159. Cs: 4,
  2160. Bs: 4,
  2161. zs: 2
  2162. }, {
  2163. id: 36,
  2164. gs: 40,
  2165. upgradeType: upgradeType.DIAMOND,
  2166. ks: 2,
  2167. ys: 2,
  2168. imageinv: 137,
  2169. image: 136,
  2170. name: "Diamond Katana",
  2171. description: "Excellent melee weapon",
  2172. range: 140,
  2173. Ms: 150,
  2174. itemType: ItemType.PRIMARY,
  2175. damage: 46.5,
  2176. reload: 300,
  2177. Us: .85,
  2178. actionType: ActionType.MELEE,
  2179. ps: 0,
  2180. As: 1,
  2181. os: 3
  2182. }, {
  2183. id: 37,
  2184. gs: 36,
  2185. upgradeType: upgradeType.GOLD,
  2186. ks: 2,
  2187. ys: 2,
  2188. imageinv: 139,
  2189. image: 138,
  2190. name: "Gold Katana",
  2191. description: "Excellent melee weapon",
  2192. range: 140,
  2193. Ms: 150,
  2194. itemType: ItemType.PRIMARY,
  2195. damage: 43,
  2196. reload: 300,
  2197. Us: .85,
  2198. actionType: ActionType.MELEE,
  2199. ps: 0,
  2200. As: 1,
  2201. os: 3
  2202. }, {
  2203. id: 38,
  2204. ks: 1,
  2205. ys: 4,
  2206. imageinv: 141,
  2207. image: 140,
  2208. name: "Diamond Spear",
  2209. description: "Long melee range",
  2210. range: 160,
  2211. itemType: ItemType.PRIMARY,
  2212. damage: 53,
  2213. Us: .81,
  2214. Ms: 450,
  2215. reload: 700,
  2216. actionType: ActionType.MELEE,
  2217. ps: 0,
  2218. As: 0,
  2219. os: 2
  2220. }, {
  2221. id: 39,
  2222. gs: 38,
  2223. upgradeType: upgradeType.GOLD,
  2224. ks: 1,
  2225. ys: 4,
  2226. imageinv: 143,
  2227. image: 142,
  2228. name: "Gold Spear",
  2229. description: "Long melee range",
  2230. range: 160,
  2231. itemType: ItemType.PRIMARY,
  2232. damage: 51,
  2233. Us: .81,
  2234. Ms: 450,
  2235. reload: 700,
  2236. actionType: ActionType.MELEE,
  2237. ps: 0,
  2238. As: 0,
  2239. os: 2
  2240. }, {
  2241. id: 40,
  2242. ks: 2,
  2243. ys: 2,
  2244. imageinv: 147,
  2245. image: 148,
  2246. name: "Chillrend",
  2247. description: "A powerful force flows through this blade.",
  2248. range: 140,
  2249. Ms: 150,
  2250. itemType: ItemType.PRIMARY,
  2251. damage: 48.5,
  2252. reload: 300,
  2253. Us: .9,
  2254. actionType: ActionType.MELEE,
  2255. ps: 0,
  2256. As: 1,
  2257. os: 3
  2258. }, {
  2259. id: 41,
  2260. gs: 42,
  2261. upgradeType: upgradeType.GOLD,
  2262. ks: 1,
  2263. ys: 32,
  2264. imageinv: 150,
  2265. image: 149,
  2266. name: "Gold Stick",
  2267. description: "Gathers resources quickly",
  2268. range: 100,
  2269. itemType: ItemType.PRIMARY,
  2270. damage: 1,
  2271. reload: 400,
  2272. actionType: ActionType.MELEE,
  2273. Ms: 60,
  2274. ps: 0,
  2275. As: 4,
  2276. os: 0,
  2277. Es: 8,
  2278. Cs: 8,
  2279. Bs: 8,
  2280. zs: 5
  2281. }, {
  2282. id: 42,
  2283. gs: 43,
  2284. upgradeType: upgradeType.DIAMOND,
  2285. ks: 1,
  2286. ys: 32,
  2287. imageinv: 167,
  2288. image: 151,
  2289. name: "Diamond Stick",
  2290. description: "Gathers resources quickly",
  2291. range: 100,
  2292. itemType: ItemType.PRIMARY,
  2293. damage: 1,
  2294. reload: 400,
  2295. actionType: ActionType.MELEE,
  2296. Ms: 60,
  2297. ps: 0,
  2298. As: 4,
  2299. os: 0,
  2300. Es: 9,
  2301. Cs: 9,
  2302. Bs: 9,
  2303. zs: 6
  2304. }, {
  2305. upgradeType: upgradeType.RUBY,
  2306. id: 43,
  2307. ks: 1,
  2308. ys: 32,
  2309. imageinv: 168,
  2310. image: 152,
  2311. name: "Ruby Stick",
  2312. description: "Gathers resources quickly",
  2313. range: 100,
  2314. itemType: ItemType.PRIMARY,
  2315. damage: 1,
  2316. reload: 400,
  2317. actionType: ActionType.MELEE,
  2318. Ms: 60,
  2319. ps: 0,
  2320. As: 4,
  2321. os: 0,
  2322. Es: 10,
  2323. Cs: 10,
  2324. Bs: 10,
  2325. zs: 7
  2326. }, {
  2327. id: 44,
  2328. ks: 4,
  2329. ys: 4,
  2330. imageinv: 154,
  2331. image: 153,
  2332. name: "Diamond Naginata",
  2333. description: "Long melee range",
  2334. range: 165,
  2335. itemType: ItemType.PRIMARY,
  2336. damage: 56,
  2337. Us: .81,
  2338. Ms: 470,
  2339. reload: 700,
  2340. actionType: ActionType.MELEE,
  2341. ps: 0,
  2342. As: 0,
  2343. os: -4
  2344. }, {
  2345. id: 45,
  2346. gs: 44,
  2347. upgradeType: upgradeType.GOLD,
  2348. ks: 4,
  2349. ys: 4,
  2350. imageinv: 156,
  2351. image: 155,
  2352. name: "Gold Naginata",
  2353. description: "Long melee range",
  2354. range: 165,
  2355. itemType: ItemType.PRIMARY,
  2356. damage: 54,
  2357. Us: .81,
  2358. Ms: 470,
  2359. reload: 700,
  2360. actionType: ActionType.MELEE,
  2361. ps: 0,
  2362. As: 0,
  2363. os: -4
  2364. }, {
  2365. id: 46,
  2366. gs: 47,
  2367. upgradeType: upgradeType.GOLD,
  2368. imageinv: 158,
  2369. image: 157,
  2370. name: "Gold Tool Hammer",
  2371. description: "Gather materials",
  2372. range: 80,
  2373. itemType: ItemType.PRIMARY,
  2374. damage: 32,
  2375. reload: 300,
  2376. _s: 30,
  2377. Ms: 200,
  2378. actionType: ActionType.MELEE,
  2379. ps: 0,
  2380. As: -3.5,
  2381. os: 1
  2382. }, {
  2383. id: 47,
  2384. gs: 48,
  2385. upgradeType: upgradeType.DIAMOND,
  2386. imageinv: 160,
  2387. image: 159,
  2388. name: "Diamond Tool Hammer",
  2389. description: "Gather materials",
  2390. range: 80,
  2391. itemType: ItemType.PRIMARY,
  2392. damage: 38,
  2393. reload: 300,
  2394. _s: 30,
  2395. Ms: 200,
  2396. actionType: ActionType.MELEE,
  2397. ps: 0,
  2398. As: -3.5,
  2399. os: 1
  2400. }, {
  2401. upgradeType: upgradeType.RUBY,
  2402. id: 48,
  2403. imageinv: 162,
  2404. image: 161,
  2405. name: "Ruby Tool Hammer",
  2406. description: "Gather materials",
  2407. range: 80,
  2408. itemType: ItemType.PRIMARY,
  2409. damage: 41,
  2410. reload: 300,
  2411. _s: 30,
  2412. Ms: 200,
  2413. actionType: ActionType.MELEE,
  2414. ps: 0,
  2415. As: -3.5,
  2416. os: 1
  2417. }, {
  2418. id: 49,
  2419. cost: {
  2420. food: 0,
  2421. wood: 20,
  2422. stone: 0,
  2423. gold: 0
  2424. },
  2425. ks: 1,
  2426. imageinv: 170,
  2427. image: 169,
  2428. name: "Roof",
  2429. description: "Take cover from projectiles",
  2430. itemType: ItemType.PLATFORM,
  2431. actionType: ActionType.PLACEABLE,
  2432. Hs: 0,
  2433. As: 0,
  2434. os: 15,
  2435. layer: ELayer.ROOF,
  2436. ps: 2
  2437. }, {
  2438. id: 50,
  2439. cost: {
  2440. food: 80,
  2441. wood: 80,
  2442. stone: 80,
  2443. gold: 80
  2444. },
  2445. ks: 1,
  2446. ys: 256,
  2447. imageinv: 182,
  2448. image: 182,
  2449. name: "Pearl",
  2450. description: "Teleport on impact",
  2451. range: 700,
  2452. itemType: ItemType.SECONDARY,
  2453. damage: 10,
  2454. reload: 1e4,
  2455. projectile: 182,
  2456. Ls: 1e3,
  2457. actionType: ActionType.RANGED,
  2458. ps: 1,
  2459. Us: .4,
  2460. As: 0,
  2461. os: 35
  2462. }, {
  2463. id: 51,
  2464. cost: {
  2465. food: 0,
  2466. wood: 50,
  2467. stone: 50,
  2468. gold: 0
  2469. },
  2470. ks: 2208,
  2471. ys: 1,
  2472. imageinv: 183,
  2473. image: 183,
  2474. name: "Teleporter",
  2475. description: "Teleports to location on map",
  2476. itemType: ItemType.SPAWN,
  2477. actionType: ActionType.PLACEABLE,
  2478. Hs: 5,
  2479. As: 0,
  2480. os: 15,
  2481. layer: ELayer.TELEPORT,
  2482. ps: 2
  2483. }, {
  2484. gs: 53,
  2485. upgradeType: upgradeType.STONE,
  2486. id: 52,
  2487. ks: 1,
  2488. ys: 4096,
  2489. imageinv: 189,
  2490. image: 193,
  2491. name: "Stone Dagger",
  2492. description: "A stubbier sword",
  2493. range: 80,
  2494. Ms: 100,
  2495. itemType: ItemType.PRIMARY,
  2496. damage: 22,
  2497. reload: 150,
  2498. actionType: ActionType.MELEE,
  2499. ps: 0,
  2500. As: 10,
  2501. os: 20
  2502. }, {
  2503. gs: 54,
  2504. upgradeType: upgradeType.GOLD,
  2505. id: 53,
  2506. ks: 1,
  2507. ys: 4096,
  2508. imageinv: 190,
  2509. image: 194,
  2510. name: "Gold Dagger",
  2511. description: "A stubbier sword",
  2512. range: 80,
  2513. Ms: 100,
  2514. itemType: ItemType.PRIMARY,
  2515. damage: 24,
  2516. reload: 150,
  2517. actionType: ActionType.MELEE,
  2518. ps: 0,
  2519. As: 10,
  2520. os: 20
  2521. }, {
  2522. gs: 55,
  2523. upgradeType: upgradeType.DIAMOND,
  2524. id: 54,
  2525. ks: 1,
  2526. ys: 4096,
  2527. imageinv: 191,
  2528. image: 195,
  2529. name: "Diamond Dagger",
  2530. description: "A stubbier sword",
  2531. range: 80,
  2532. Ms: 100,
  2533. itemType: ItemType.PRIMARY,
  2534. damage: 26,
  2535. reload: 150,
  2536. actionType: ActionType.MELEE,
  2537. ps: 0,
  2538. As: 10,
  2539. os: 20
  2540. }, {
  2541. upgradeType: upgradeType.RUBY,
  2542. id: 55,
  2543. ks: 1,
  2544. ys: 4096,
  2545. imageinv: 192,
  2546. image: 196,
  2547. name: "Ruby Dagger",
  2548. description: "A stubbier sword",
  2549. range: 80,
  2550. Ms: 100,
  2551. itemType: ItemType.PRIMARY,
  2552. damage: 29,
  2553. reload: 150,
  2554. actionType: ActionType.MELEE,
  2555. ps: 0,
  2556. As: 10,
  2557. os: 20
  2558. }, {
  2559. id: 56,
  2560. gs: 57,
  2561. upgradeType: upgradeType.GOLD,
  2562. ks: 1,
  2563. ys: 1,
  2564. imageinv: 198,
  2565. image: 198,
  2566. name: "Secret Item",
  2567. description: "Dont leak how to get it :)",
  2568. range: 115,
  2569. itemType: ItemType.PRIMARY,
  2570. damage: 28,
  2571. Us: .92,
  2572. Ms: 1570,
  2573. reload: 2e3,
  2574. actionType: ActionType.MELEE,
  2575. ps: 0,
  2576. As: 40,
  2577. os: 40
  2578. }, {
  2579. id: 57,
  2580. ks: 2,
  2581. ys: 2,
  2582. imageinv: 199,
  2583. image: 199,
  2584. name: "Daedric Scythe",
  2585. description: "Whispers fill the air",
  2586. range: 160,
  2587. Ms: 150,
  2588. itemType: ItemType.PRIMARY,
  2589. damage: 52,
  2590. reload: 450,
  2591. Us: .85,
  2592. actionType: ActionType.MELEE,
  2593. ps: 0,
  2594. As: -5,
  2595. os: 20
  2596. } ];
  2597. const Items = ItemData;
  2598. const ItemList = Items.filter((item => item.actionType === ActionType.PLACEABLE));
  2599. const Shooting = Items.filter((item => item.actionType === ActionType.RANGED));
  2600. class Vector {
  2601. constructor(x, y) {
  2602. this.x = x;
  2603. this.y = y;
  2604. }
  2605. static fromAngle(angle) {
  2606. return new Vector(Math.cos(angle), Math.sin(angle));
  2607. }
  2608. add(vec) {
  2609. this.x += vec.x;
  2610. this.y += vec.y;
  2611. return this;
  2612. }
  2613. sub(vec) {
  2614. this.x -= vec.x;
  2615. this.y -= vec.y;
  2616. return this;
  2617. }
  2618. mult(scalar) {
  2619. this.x *= scalar;
  2620. this.y *= scalar;
  2621. return this;
  2622. }
  2623. div(scalar) {
  2624. this.x /= scalar;
  2625. this.y /= scalar;
  2626. return this;
  2627. }
  2628. get length() {
  2629. return Math.sqrt(this.x * this.x + this.y * this.y);
  2630. }
  2631. normalize() {
  2632. return this.length > 0 ? this.div(this.length) : this;
  2633. }
  2634. setLength(value) {
  2635. return this.normalize().mult(value);
  2636. }
  2637. copy() {
  2638. return new Vector(this.x, this.y);
  2639. }
  2640. distance(vec) {
  2641. return this.copy().sub(vec).length;
  2642. }
  2643. angle(vec) {
  2644. const copy = vec.copy().sub(this);
  2645. return Math.atan2(copy.y, copy.x);
  2646. }
  2647. dot(vec) {
  2648. return this.x * vec.x + this.y * vec.y;
  2649. }
  2650. direction(angle, scalar) {
  2651. return this.copy().add(Vector.fromAngle(angle).mult(scalar));
  2652. }
  2653. }
  2654. const getAngleDist = (a, b) => {
  2655. const p = Math.abs(b - a) % (Math.PI * 2);
  2656. return p > Math.PI ? Math.PI * 2 - p : p;
  2657. };
  2658. class EntityManager {
  2659. static isPlayer(entity) {
  2660. return entity.type === ELayer.PLAYER;
  2661. }
  2662. static animals() {
  2663. const layers = Dsync.saves.entityList();
  2664. const animals = [];
  2665. for (let i = 0; i < Animals.length; i++) {
  2666. const layer = layers[Animals[i].id];
  2667. const formatted = layer.map((target => Formatter.entity(target)));
  2668. animals.push(...formatted);
  2669. }
  2670. return animals;
  2671. }
  2672. static enemies() {
  2673. const players = Dsync.saves.entityList()[ELayer.PLAYER];
  2674. const enemies = [];
  2675. for (let i = 0; i < players.length; i++) {
  2676. const player = Formatter.player(players[i]);
  2677. if (controller.isEnemy(player)) enemies.push(player);
  2678. }
  2679. return enemies.sort(((a, b) => this.sortDistance(a, b)));
  2680. }
  2681. static distance(a, b) {
  2682. return new Vector(a.x2, a.y2).distance(new Vector(b.x2, b.y2));
  2683. }
  2684. static angle(a, b) {
  2685. return new Vector(a.x2, a.y2).angle(new Vector(b.x2, b.y2));
  2686. }
  2687. static sortDistance(a, b, sorted) {
  2688. const target = sorted || Dsync.myPlayer;
  2689. return this.distance(a, target) - this.distance(b, target);
  2690. }
  2691. static shield(a, b, sorted) {
  2692. const target = sorted || Dsync.myPlayer;
  2693. const shieldA = this.lookingAt(a, target, 1.58927) && a.currentItem === EWeapons.SHIELD;
  2694. const shieldB = this.lookingAt(b, target, 1.58927) && b.currentItem === EWeapons.SHIELD;
  2695. return shieldA ? 1 : shieldB ? -1 : 0;
  2696. }
  2697. static canHitEntity(a, b, sorted) {
  2698. const target = sorted || Dsync.myPlayer;
  2699. const hitA = this.projectileCanHitEntity(a, target);
  2700. const hitB = this.projectileCanHitEntity(b, target);
  2701. return hitA === Hit.NEEDDESTROY ? 1 : hitB === Hit.NEEDDESTROY ? -1 : 0;
  2702. }
  2703. static lookingAt(entity, point, angle) {
  2704. const pos1 = new Vector(entity.x2, entity.y2);
  2705. const pos2 = new Vector(point.x2, point.y2);
  2706. const dir = getAngleDist(pos1.angle(pos2) + Math.PI, entity.angle2);
  2707. return dir > angle;
  2708. }
  2709. static entities(sorted) {
  2710. return [ ...this.enemies().sort(((a, b) => this.sortDistance(a, b, sorted))).sort(((a, b) => this.shield(a, b, sorted))), ...this.animals().sort(((a, b) => this.sortDistance(a, b, sorted))) ];
  2711. }
  2712. static predict(entity) {
  2713. const pos1 = new Vector(entity.x1, entity.y1);
  2714. const pos2 = new Vector(entity.x2, entity.y2);
  2715. const distance = pos1.distance(pos2) * (entity === Dsync.myPlayer ? 1 : 2.2);
  2716. const direction = Vector.fromAngle(pos1.angle(pos2));
  2717. return pos2.add(direction.mult(distance));
  2718. }
  2719. static entityIn(entity, layer, extraRadius = 0) {
  2720. const targets = Dsync.saves.entityList()[layer];
  2721. return targets.some((target => {
  2722. const object = Formatter.object(target);
  2723. const radius = entity.radius + object.radius + extraRadius;
  2724. return this.distance(entity, object) <= radius;
  2725. }));
  2726. }
  2727. static intersects(pos1, pos2, pos3, r) {
  2728. const linear = pos2.copy().sub(pos1);
  2729. const constant = pos1.copy().sub(pos3);
  2730. const a = linear.dot(linear);
  2731. const b = linear.dot(constant);
  2732. const c = constant.dot(constant) - r * r;
  2733. return b * b >= a * c && (-b <= a || c + b + b + a <= 0) && (b <= 0 || c <= 0);
  2734. }
  2735. static projectileCanHitEntity(entity, sorted) {
  2736. const target = sorted || Dsync.myPlayer;
  2737. if (!controller.canShoot()) return Hit.CANNOT;
  2738. const pos1 = new Vector(target.x2, target.y2);
  2739. const pos2 = new Vector(entity.x2, entity.y2);
  2740. const myPlayerOnPlatform = this.entityIn(target, ELayer.PLATFORM);
  2741. const entityInRoof = this.entityIn(entity, ELayer.ROOF);
  2742. if (myPlayerOnPlatform && entityInRoof) return Hit.CANNOT;
  2743. const layers = Dsync.saves.entityList();
  2744. for (const layer of LayerObjects) {
  2745. if (myPlayerOnPlatform && !layer.cannotShoot) continue;
  2746. for (const target of layers[layer.id]) {
  2747. const object = Formatter.object(target);
  2748. const pos3 = new Vector(object.x2, object.y2);
  2749. if (pos1.distance(pos3) > pos1.distance(pos2)) continue;
  2750. if (this.intersects(pos1, pos2, pos3, object.radius)) {
  2751. if (object.layerData.maxHealth === undefined) return Hit.CANNOT;
  2752. return Hit.NEEDDESTROY;
  2753. }
  2754. }
  2755. }
  2756. return Hit.CAN;
  2757. }
  2758. static inWeaponRange(entity1, entity2, weapon) {
  2759. const range = Items[weapon].range || 0;
  2760. return this.distance(entity1, entity2) <= range + entity2.radius;
  2761. }
  2762. static nearestPossible(weapon, sorted) {
  2763. const target = sorted || Dsync.myPlayer;
  2764. const item = Items[weapon];
  2765. const shoot = controller.canShoot() && item.actionType === ActionType.RANGED;
  2766. const entities = this.entities().filter((entity => shoot ? this.projectileCanHitEntity(entity, target) : this.inWeaponRange(target, entity, weapon)));
  2767. if (shoot) {
  2768. entities.sort(((a, b) => this.canHitEntity(a, b, target)));
  2769. }
  2770. return entities.length ? entities[0] : null;
  2771. }
  2772. static nearestLayer(entity, layer) {
  2773. const objects = Dsync.saves.entityList()[layer].map((target => Formatter.object(target)));
  2774. return objects.sort(((a, b) => this.sortDistance(a, b, entity)))[0];
  2775. }
  2776. }
  2777. const attackAnimation = () => {
  2778. if (!Settings.weaponReloadBar && !Settings.autosync) return;
  2779. const b = Dsync.saves.buffer;
  2780. const len = Dsync.saves.byteLength;
  2781. const players = Dsync.saves.players();
  2782. for (let i = 1; i < len; i += 5) {
  2783. const type = b[i];
  2784. const id = b[i + 1] | b[i + 2] << 8;
  2785. const weapon = b[i + 3];
  2786. const isObject = b[i + 4];
  2787. const target = players.get(id);
  2788. if (type === ELayer.PLAYER && target) {
  2789. if (Settings.weaponReloadBar) {
  2790. const reload = target.weaponReload;
  2791. reload.current = -Dsync.step;
  2792. reload.lerp = 0;
  2793. reload.max = Items[weapon].reload || 0;
  2794. }
  2795. if (Settings.autosync && controller.canAutosync()) {
  2796. const player = Formatter.player(target);
  2797. if (controller.isTeammate(player) && controller.isPrimary(weapon)) {
  2798. const nearest = EntityManager.nearestPossible(weapon, player);
  2799. if (nearest !== null && EntityManager.inWeaponRange(Dsync.myPlayer, nearest, controller.itemBar[0])) {
  2800. const previousWeapon = controller.weapon;
  2801. controller.whichWeapon(false);
  2802. controller.attack(EntityManager.angle(Dsync.myPlayer, nearest));
  2803. controller.PacketManager.stopAttack();
  2804. controller.whichWeapon(previousWeapon);
  2805. controller.PacketManager.changeAngle(controller.mouse.angle);
  2806. }
  2807. }
  2808. }
  2809. }
  2810. }
  2811. };
  2812. const hooks_attackAnimation = attackAnimation;
  2813. let teammates = [];
  2814. const createClan = () => {
  2815. const b = Dsync.saves.buffer;
  2816. const len = Dsync.saves.byteLength;
  2817. teammates = [ ...b.slice(3, len) ];
  2818. };
  2819. const updateClan = () => {
  2820. const b = Dsync.saves.buffer;
  2821. const len = Dsync.saves.byteLength;
  2822. teammates = [ ...b.slice(2, len) ];
  2823. };
  2824. const deleteClan = () => {
  2825. teammates = [];
  2826. };
  2827. const playerStats = () => {
  2828. const b = Dsync.saves.buffer;
  2829. const age = formatAge(b[1] | b[2] << 8 | b[3] << 16 | b[4] << 24);
  2830. const food = b[5] | b[6] << 8 | b[7] << 16 | b[8] << 24;
  2831. const wood = b[9] | b[10] << 8 | b[11] << 16 | b[12] << 24;
  2832. const stone = b[13] | b[14] << 8 | b[15] << 16 | b[16] << 24;
  2833. const gold = b[17] | b[18] << 8 | b[19] << 16 | b[20] << 24;
  2834. if (age !== 0) {
  2835. controller.age = age;
  2836. }
  2837. controller.resources = {
  2838. food,
  2839. wood,
  2840. stone,
  2841. gold
  2842. };
  2843. };
  2844. const hooks_playerStats = playerStats;
  2845. const stringMessage = data => {
  2846. const id = data[0];
  2847. if (id === WebsocketServer.SPAWN) {
  2848. controller.myPlayerID = data[1];
  2849. controller.reset(data[4]);
  2850. controller.inGame = true;
  2851. controller.automillSpawn = true;
  2852. if (Settings.lastHat) {
  2853. const hat = controller.toggleJungle || controller.toggleScuba ? controller.previousHat : controller.actualHat;
  2854. controller.equipHat(hat, true, true);
  2855. }
  2856. }
  2857. if (id === WebsocketServer.UPGRADE) {
  2858. const bar = data[1];
  2859. const canAutobed = Settings.autobed && bar.includes(EObjects.SPAWN);
  2860. controller.autobed = canAutobed;
  2861. if (Settings.skipUpgrades && bar.length === 1 || canAutobed) {
  2862. controller.PacketManager.upgrade(canAutobed ? EObjects.SPAWN : bar[0]);
  2863. }
  2864. }
  2865. if (id === WebsocketServer.DIED) {
  2866. controller.myPlayerID = 0;
  2867. controller.inGame = false;
  2868. if (Settings.autospawn) {
  2869. controller.spawn();
  2870. }
  2871. }
  2872. if (id === WebsocketServer.KILL_UPDATE) {
  2873. controller.kills = data[1][0];
  2874. }
  2875. if (id === WebsocketServer.KILLED && Settings.kill) {
  2876. const killMessage = Settings.killMessage.length ? Settings.killMessage : "{KILL}x";
  2877. const name = data[1].replace(/^Killed\s/, "").trim();
  2878. const message = killMessage.replace(/\{KILL\}/g, controller.kills + "").replace(/\{NAME\}/g, name);
  2879. controller.PacketManager.chat(message);
  2880. }
  2881. };
  2882. const hooks_stringMessage = stringMessage;
  2883. var WebsocketServer;
  2884. (function(WebsocketServer) {
  2885. WebsocketServer[WebsocketServer["LEADERBOARD"] = 3] = "LEADERBOARD";
  2886. WebsocketServer[WebsocketServer["DAMAGE"] = 6] = "DAMAGE";
  2887. WebsocketServer[WebsocketServer["PLAYERSTATS"] = 8] = "PLAYERSTATS";
  2888. WebsocketServer[WebsocketServer["CONNECT"] = 12] = "CONNECT";
  2889. WebsocketServer[WebsocketServer["UPGRADE"] = 14] = "UPGRADE";
  2890. WebsocketServer[WebsocketServer["UPDATECLAN"] = 16] = "UPDATECLAN";
  2891. WebsocketServer[WebsocketServer["DIED"] = 19] = "DIED";
  2892. WebsocketServer[WebsocketServer["MOVEUPDATE"] = 20] = "MOVEUPDATE";
  2893. WebsocketServer[WebsocketServer["KILL_UPDATE"] = 22] = "KILL_UPDATE";
  2894. WebsocketServer[WebsocketServer["JOINCREATECLAN"] = 24] = "JOINCREATECLAN";
  2895. WebsocketServer[WebsocketServer["DELETECLAN"] = 27] = "DELETECLAN";
  2896. WebsocketServer[WebsocketServer["KILLED"] = 28] = "KILLED";
  2897. WebsocketServer[WebsocketServer["ATTACK_ANIMATION"] = 29] = "ATTACK_ANIMATION";
  2898. WebsocketServer[WebsocketServer["PLAYER_SPAWNED"] = 32] = "PLAYER_SPAWNED";
  2899. WebsocketServer[WebsocketServer["DEFAULT"] = 33] = "DEFAULT";
  2900. WebsocketServer[WebsocketServer["SPAWN"] = 35] = "SPAWN";
  2901. })(WebsocketServer || (WebsocketServer = {}));
  2902. var WebsocketClient;
  2903. (function(WebsocketClient) {
  2904. WebsocketClient[WebsocketClient["MOVE"] = 6] = "MOVE";
  2905. WebsocketClient[WebsocketClient["ANGLE"] = 13] = "ANGLE";
  2906. WebsocketClient[WebsocketClient["selectByID"] = 2] = "selectByID";
  2907. WebsocketClient[WebsocketClient["ATTACK"] = 19] = "ATTACK";
  2908. WebsocketClient[WebsocketClient["STOPATTACK"] = 18] = "STOPATTACK";
  2909. WebsocketClient[WebsocketClient["LOGIN"] = 10] = "LOGIN";
  2910. WebsocketClient[WebsocketClient["SCYTHE"] = 20] = "SCYTHE";
  2911. WebsocketClient[WebsocketClient["SELECTITEM"] = 0] = "SELECTITEM";
  2912. WebsocketClient[WebsocketClient["HAT"] = 5] = "HAT";
  2913. WebsocketClient[WebsocketClient["CHAT"] = 7] = "CHAT";
  2914. WebsocketClient[WebsocketClient["UPGRADE"] = 14] = "UPGRADE";
  2915. WebsocketClient[WebsocketClient["AUTOATTACK"] = 23] = "AUTOATTACK";
  2916. WebsocketClient[WebsocketClient["MOVEANGLE"] = 1] = "MOVEANGLE";
  2917. WebsocketClient[WebsocketClient["LEAVECLAN"] = 24] = "LEAVECLAN";
  2918. WebsocketClient[WebsocketClient["JOIN"] = 21] = "JOIN";
  2919. WebsocketClient[WebsocketClient["ACCEPTDECLINE"] = 17] = "ACCEPTDECLINE";
  2920. WebsocketClient[WebsocketClient["KICK"] = 25] = "KICK";
  2921. WebsocketClient[WebsocketClient["CREATECLAN"] = 22] = "CREATECLAN";
  2922. })(WebsocketClient || (WebsocketClient = {}));
  2923. window.Uint8Array = new Proxy(window.Uint8Array, {
  2924. construct(target, args) {
  2925. const uint = new target(...args);
  2926. if (args[0] === 4096) {
  2927. Dsync.saves.buffer = uint;
  2928. window.Uint8Array = target;
  2929. }
  2930. return uint;
  2931. }
  2932. });
  2933. const proto = Uint8Array.__proto__;
  2934. const getter = Object.getOwnPropertyDescriptor(proto.prototype, "byteLength")?.get;
  2935. Object.defineProperty(Uint8Array.prototype, "byteLength", {
  2936. get() {
  2937. const value = getter.call(this);
  2938. Dsync.saves.byteLength = value;
  2939. return value;
  2940. }
  2941. });
  2942. let start = Date.now();
  2943. window.WebSocket = new Proxy(window.WebSocket, {
  2944. construct(target, args) {
  2945. if (typeof args[0] === "string") {
  2946. if (args[0] !== Dsync.connectURL) {
  2947. controller.myPlayerID = 0;
  2948. controller.age = 0;
  2949. for (const hat of Hats) {
  2950. hat.bought = !!hat.default;
  2951. hat.equipped = !!hat.default;
  2952. }
  2953. }
  2954. Dsync.connectURL = args[0];
  2955. }
  2956. const ws = new target(...args);
  2957. ws.addEventListener("message", (event => {
  2958. const data = event.data;
  2959. if (typeof data === "string" && /^\[.+\]$/.test(data)) {
  2960. hooks_stringMessage(JSON.parse(data));
  2961. } else {
  2962. switch (Dsync.saves.buffer[0]) {
  2963. case WebsocketServer.PLAYERSTATS:
  2964. hooks_playerStats();
  2965. break;
  2966.  
  2967. case WebsocketServer.DELETECLAN:
  2968. deleteClan();
  2969. break;
  2970.  
  2971. case WebsocketServer.JOINCREATECLAN:
  2972. createClan();
  2973. break;
  2974.  
  2975. case WebsocketServer.UPDATECLAN:
  2976. updateClan();
  2977. break;
  2978.  
  2979. case WebsocketServer.MOVEUPDATE:
  2980. {
  2981. const now = Date.now();
  2982. Dsync.step = now - start;
  2983. start = now;
  2984. break;
  2985. }
  2986.  
  2987. case WebsocketServer.ATTACK_ANIMATION:
  2988. hooks_attackAnimation();
  2989. break;
  2990. }
  2991. }
  2992. }));
  2993. return ws;
  2994. }
  2995. });
  2996. class PacketManager {
  2997. constructor() {
  2998. this.encoder = new TextEncoder;
  2999. }
  3000. send(...args) {
  3001. Dsync.saves.send(new Uint8Array(args));
  3002. }
  3003. moveByBitmask(bitmask) {
  3004. this.send(WebsocketClient.MOVE, bitmask);
  3005. }
  3006. changeAngle(angle) {
  3007. angle = 65535 * (angle + Math.PI) / (2 * Math.PI), this.send(WebsocketClient.ANGLE, 255 & angle, angle >> 8 & 255);
  3008. }
  3009. selectByID(id) {
  3010. this.send(WebsocketClient.selectByID, id);
  3011. }
  3012. attack(angle) {
  3013. angle = 65535 * (angle + Math.PI) / (2 * Math.PI), this.send(WebsocketClient.ATTACK, 255 & angle, angle >> 8 & 255);
  3014. }
  3015. stopAttack() {
  3016. this.send(WebsocketClient.STOPATTACK);
  3017. }
  3018. upgradeScythe(goldenCowID) {
  3019. this.send(WebsocketClient.SCYTHE, 255 & goldenCowID, goldenCowID >> 8);
  3020. }
  3021. selectItemByType(type) {
  3022. this.send(WebsocketClient.SELECTITEM, type);
  3023. }
  3024. equip(id) {
  3025. this.send(WebsocketClient.HAT, id);
  3026. }
  3027. chat(message) {
  3028. const bytes = this.encoder.encode(message);
  3029. this.send(WebsocketClient.CHAT, ...bytes);
  3030. }
  3031. upgrade(id) {
  3032. this.send(WebsocketClient.UPGRADE, id);
  3033. controller.upgradeItem(id);
  3034. }
  3035. autoattack(toggle) {
  3036. this.send(WebsocketClient.AUTOATTACK, Number(toggle));
  3037. }
  3038. moveAngle(angle) {
  3039. angle = 65535 * (angle + Math.PI) / (2 * Math.PI), this.send(WebsocketClient.MOVEANGLE, 255 & angle, angle >> 8 & 255);
  3040. }
  3041. leaveClan() {
  3042. this.send(WebsocketClient.LEAVECLAN);
  3043. }
  3044. joinClan(id) {
  3045. this.send(WebsocketClient.JOIN, id);
  3046. }
  3047. accept(which) {
  3048. this.send(WebsocketClient.ACCEPTDECLINE, which);
  3049. }
  3050. kick(id) {
  3051. this.send(WebsocketClient.KICK, id);
  3052. }
  3053. createClan(name) {
  3054. const bytes = this.encoder.encode(name);
  3055. this.send(WebsocketClient.CREATECLAN, ...bytes);
  3056. }
  3057. }
  3058. class TimeoutManager {
  3059. constructor(callbacks, delay) {
  3060. this.callbacks = callbacks;
  3061. this.delay = delay;
  3062. this.active = false;
  3063. this.old = Date.now();
  3064. }
  3065. static waitUntil(condition, time, callback) {
  3066. return new Promise((resolve => {
  3067. const start = Date.now();
  3068. const int = setInterval((() => {
  3069. if (typeof time === "number" && Number.isFinite(time) && Date.now() - start > time || condition()) {
  3070. clearInterval(int);
  3071. }
  3072. if (condition()) {
  3073. if (typeof callback === "function") return callback();
  3074. resolve();
  3075. }
  3076. }), 50);
  3077. }));
  3078. }
  3079. start() {
  3080. if (this.active) return;
  3081. this.active = true;
  3082. this.old = Date.now();
  3083. this.callbacks[0]();
  3084. }
  3085. async stop() {
  3086. if (!this.active) return;
  3087. this.callbacks[1]();
  3088. if (!this.delay(this.old)) await TimeoutManager.waitUntil((() => this.delay(this.old)), 3e3);
  3089. this.callbacks[2]();
  3090. this.active = false;
  3091. }
  3092. isActive() {
  3093. return this.active;
  3094. }
  3095. }
  3096. class Controller {
  3097. constructor() {
  3098. this.myPlayerID = 0;
  3099. this.move = 0;
  3100. this.attacking = false;
  3101. this.autoattack = false;
  3102. this.rotation = false;
  3103. this.weapon = false;
  3104. this.healing = false;
  3105. this.attackingInvis = false;
  3106. this.toggleInvis = false;
  3107. this.currentItem = null;
  3108. this.chatToggle = false;
  3109. this.chatCount = 0;
  3110. this.autobed = false;
  3111. this.automill = false;
  3112. this.automillSpawn = false;
  3113. this.mousemove = true;
  3114. this.kills = 0;
  3115. this.inGame = false;
  3116. this.itemBar = [ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 ];
  3117. this.hsl = 0;
  3118. this.aimTarget = null;
  3119. this.wasAutoboost = false;
  3120. this.count = 0;
  3121. this.toggleJungle = false;
  3122. this.toggleScuba = false;
  3123. this.resources = {
  3124. food: 200,
  3125. wood: 200,
  3126. stone: 200,
  3127. gold: 200
  3128. };
  3129. this.mouse = {
  3130. x: 0,
  3131. y: 0,
  3132. angle: 0
  3133. };
  3134. this.equipStart = Date.now();
  3135. this.actualHat = 0;
  3136. this.currentHat = 0;
  3137. this.previousHat = 0;
  3138. this.maxCount = [ 0, 0, 0, 100, 30, 8, 2, 12, 32, 1, 2 ];
  3139. this.age = 0;
  3140. this.hotkeys = new Map;
  3141. this.PacketManager = new PacketManager;
  3142. this.previousWeapon = false;
  3143. this.fastbreak = new TimeoutManager([ () => {
  3144. const primary = this.itemBar[ItemType.PRIMARY];
  3145. const secondary = this.itemBar[ItemType.SECONDARY];
  3146. const pickWeapon = secondary === EWeapons.HAMMER || primary === EWeapons.STICK && secondary === EWeapons.SHIELD;
  3147. this.previousWeapon = this.weapon;
  3148. this.whichWeapon(pickWeapon);
  3149. this.equipHat(Hat.DEMOLIST, false);
  3150. this.attacking = true;
  3151. this.attack();
  3152. }, () => {
  3153. this.PacketManager.stopAttack();
  3154. this.attacking = false;
  3155. this.whichWeapon(this.previousWeapon);
  3156. }, () => {
  3157. if (!Dsync.myPlayer.isClown) {
  3158. this.equipHat(this.previousHat, true);
  3159. }
  3160. } ], (start => this.hatReloaded() && Date.now() - start > TargetReload.HAT));
  3161. this.attachMouse();
  3162. }
  3163. reset(items) {
  3164. this.move = 0;
  3165. this.attacking = false;
  3166. this.autoattack = false;
  3167. this.rotation = false;
  3168. this.weapon = false;
  3169. this.healing = false;
  3170. this.attackingInvis = false;
  3171. this.toggleInvis = false;
  3172. this.currentItem = null;
  3173. this.chatToggle = false;
  3174. this.chatCount = 0;
  3175. this.autobed = false;
  3176. this.automill = false;
  3177. this.automillSpawn = false;
  3178. this.mousemove = true;
  3179. this.kills = 0;
  3180. this.inGame = false;
  3181. this.itemBar = [ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 ];
  3182. this.hsl = 0;
  3183. this.aimTarget = null;
  3184. this.count = 0;
  3185. for (const id of items) {
  3186. this.upgradeItem(id);
  3187. }
  3188. for (const [key] of this.hotkeys) {
  3189. this.hotkeys.delete(key);
  3190. }
  3191. }
  3192. attachMouse() {
  3193. window.addEventListener("mousemove", (event => {
  3194. this.mouse.x = event.clientX;
  3195. this.mouse.y = event.clientY;
  3196. if (!this.rotation) {
  3197. this.mouse.angle = angle(innerWidth / 2, innerHeight / 2, this.mouse.x, this.mouse.y);
  3198. }
  3199. }));
  3200. }
  3201. hasItem(type) {
  3202. return this.itemBar[type] !== -1;
  3203. }
  3204. hasSecondary() {
  3205. return this.itemBar[ItemType.SECONDARY] !== -1;
  3206. }
  3207. updateWeapon(type) {
  3208. const weapon = Dsync.saves.defaultData[Dsync.props.itemBar][type];
  3209. if (this.isWeapon(weapon) && this.itemBar[type] !== weapon) {
  3210. this.itemBar[type] = weapon;
  3211. }
  3212. }
  3213. isMyPlayer(entity) {
  3214. return entity.id === this.myPlayerID;
  3215. }
  3216. isTeammate(entity) {
  3217. return entity.id !== this.myPlayerID && teammates.includes(entity.ownerID);
  3218. }
  3219. isEnemy(entity) {
  3220. return !this.isMyPlayer(entity) && !this.isTeammate(entity);
  3221. }
  3222. canShoot() {
  3223. const id = this.itemBar[ItemType.SECONDARY];
  3224. return this.hasSecondary() && Items[id].actionType === ActionType.RANGED;
  3225. }
  3226. isWeapon(id) {
  3227. const type = Items[id].itemType;
  3228. return type === ItemType.PRIMARY || type === ItemType.SECONDARY;
  3229. }
  3230. isPrimary(id) {
  3231. return Items[id].itemType === ItemType.PRIMARY;
  3232. }
  3233. isSecondary(id) {
  3234. return Items[id].itemType === ItemType.SECONDARY;
  3235. }
  3236. currentCount(type) {
  3237. return Dsync.saves.defaultData[Dsync.props.currentCount][type];
  3238. }
  3239. hasCount(type) {
  3240. return this.currentCount(type) < this.maxCount[type];
  3241. }
  3242. isDoingNothing() {
  3243. return !this.healing && !this.attackingInvis && !this.toggleInvis && !this.attacking && this.currentItem === null;
  3244. }
  3245. canAutosync() {
  3246. return !this.attacking && !this.attackingInvis && !this.toggleInvis && !this.autoattack;
  3247. }
  3248. hasResources(id) {
  3249. const cost = Items[id].cost || {
  3250. food: 0,
  3251. wood: 0,
  3252. stone: 0,
  3253. gold: 0
  3254. };
  3255. const {food, wood, stone, gold} = this.resources;
  3256. const hasFood = food >= cost.food;
  3257. const hasWood = wood >= cost.wood;
  3258. const hasStone = stone >= cost.stone;
  3259. const hasGold = gold >= cost.gold;
  3260. return hasFood && hasWood && hasStone && hasGold;
  3261. }
  3262. getAngleFromBitmask(bitmask, rotate) {
  3263. const vec = {
  3264. x: 0,
  3265. y: 0
  3266. };
  3267. if (bitmask & 1) vec.y--;
  3268. if (bitmask & 2) vec.y++;
  3269. if (bitmask & 4) vec.x--;
  3270. if (bitmask & 8) vec.x++;
  3271. if (rotate) {
  3272. vec.x *= -1;
  3273. vec.y *= -1;
  3274. }
  3275. return Math.atan2(vec.y, vec.x);
  3276. }
  3277. upgradeItem(id) {
  3278. const item = Items[id];
  3279. this.itemBar[item.itemType] = id;
  3280. }
  3281. upgradeScythe() {
  3282. const target = Dsync.saves.entityList()[ELayer.GOLDENCOW][0];
  3283. if (target !== undefined) {
  3284. this.PacketManager.upgradeScythe(target[Dsync.props.id]);
  3285. }
  3286. }
  3287. buyHat(id) {
  3288. if (!Hats[id].bought && controller.resources.gold >= Hats[id].price) {
  3289. Hats[id].bought = true;
  3290. this.PacketManager.equip(id);
  3291. }
  3292. return Hats[id].bought;
  3293. }
  3294. hatReloaded() {
  3295. return Dsync.myPlayer.target.hatReload.current === TargetReload.HAT;
  3296. }
  3297. equipHat(id, actual = true, force = false) {
  3298. const hatID = id === Hat.UNEQUIP ? this.actualHat : id;
  3299. if (!this.buyHat(hatID) || !this.inGame) return false;
  3300. const now = Date.now();
  3301. if (!Hats[id].equipped && this.hatReloaded() && now - this.equipStart >= TargetReload.HAT || force) {
  3302. this.equipStart = now;
  3303. this.PacketManager.equip(hatID);
  3304. for (const hat of Hats) {
  3305. hat.equipped = false;
  3306. }
  3307. Hats[id].equipped = true;
  3308. this.previousHat = this.currentHat;
  3309. this.currentHat = id;
  3310. if (actual) {
  3311. this.actualHat = id;
  3312. }
  3313. return true;
  3314. }
  3315. return false;
  3316. }
  3317. async autochat() {
  3318. if (this.chatToggle) return;
  3319. this.chatToggle = true;
  3320. const messages = Settings.autochatMessages.filter((msg => msg.length));
  3321. if (!messages.length) return;
  3322. this.PacketManager.chat(messages[this.chatCount++]);
  3323. this.chatCount %= messages.length;
  3324. await sleep(2e3);
  3325. this.chatToggle = false;
  3326. }
  3327. accept(which) {
  3328. this.PacketManager.accept(which);
  3329. const acceptList = Dsync.saves.clanData[Dsync.props.acceptList];
  3330. acceptList.shift();
  3331. }
  3332. async spawn() {
  3333. await sleep(100);
  3334. const play = document.querySelector("#play");
  3335. play.click();
  3336. }
  3337. whichWeapon(type) {
  3338. if (type !== undefined) {
  3339. this.weapon = type;
  3340. }
  3341. this.PacketManager.selectByID(this.itemBar[+this.weapon]);
  3342. }
  3343. attack(angle) {
  3344. const dir = angle ? angle : this.mouse.angle;
  3345. this.PacketManager.attack(dir);
  3346. }
  3347. place(type, angle, placementType) {
  3348. if (this.wasAutoboost) {
  3349. const nearest = EntityManager.enemies()[0];
  3350. if (nearest !== undefined) {
  3351. angle = EntityManager.angle(Dsync.myPlayer, nearest);
  3352. this.PacketManager.moveAngle(angle);
  3353. }
  3354. }
  3355. const placeType = placementType === undefined ? Settings.placementType : placementType;
  3356. const isHolding = placeType === PlacementType.HOLDING;
  3357. this.whichWeapon();
  3358. if (isHolding && this.attacking) this.attack(angle);
  3359. this.PacketManager.selectItemByType(type);
  3360. this.attack(angle);
  3361. this.PacketManager.stopAttack();
  3362. if (!isHolding) this.whichWeapon();
  3363. if (this.attacking) this.attack(angle);
  3364. }
  3365. placement() {
  3366. if (this.currentItem === null) return;
  3367. this.place(this.currentItem);
  3368. this.count = (this.count + 1) % Settings.placementSpeed;
  3369. const method = this.count === 0 ? setTimeout : queueMicrotask;
  3370. method(this.placement.bind(this));
  3371. }
  3372. placementHandler(type, code) {
  3373. if (!this.hasItem(type)) return;
  3374. if (Settings.placementType === PlacementType.DEFAULT) {
  3375. this.PacketManager.selectItemByType(type);
  3376. return;
  3377. }
  3378. this.hotkeys.set(code, type);
  3379. this.currentItem = type;
  3380. const isBoost = type === ItemType.TRAP && this.itemBar[ItemType.TRAP] === EObjects.BOOST;
  3381. this.wasAutoboost = Settings.autoboostFollow && isBoost;
  3382. if (this.hotkeys.size === 1) {
  3383. this.placement();
  3384. }
  3385. }
  3386. heal() {
  3387. this.PacketManager.selectItemByType(ItemType.FOOD);
  3388. this.attack();
  3389. this.PacketManager.stopAttack();
  3390. this.whichWeapon();
  3391. if (this.attacking) {
  3392. this.attack();
  3393. }
  3394. }
  3395. invisibleHit() {
  3396. this.mousemove = true;
  3397. this.aimTarget = null;
  3398. if (Settings.invisHitToggle && !this.toggleInvis || !Settings.invisHitToggle && !this.attackingInvis) {
  3399. this.toggleInvis = false;
  3400. this.attackingInvis = false;
  3401. return;
  3402. }
  3403. let angle;
  3404. const nearest = EntityManager.nearestPossible(this.itemBar[+!this.weapon]);
  3405. const shoot = this.canShoot() && !this.weapon;
  3406. if (nearest && (Settings.meleeAim && !shoot || Settings.bowAim && shoot)) {
  3407. const pos1 = EntityManager.predict(Dsync.myPlayer);
  3408. const pos2 = EntityManager.predict(nearest);
  3409. angle = pos1.angle(pos2);
  3410. this.mousemove = false;
  3411. this.aimTarget = nearest.target;
  3412. }
  3413. if (nearest && shoot || !shoot) {
  3414. this.whichWeapon(!this.weapon);
  3415. this.attack(angle);
  3416. this.PacketManager.stopAttack();
  3417. this.whichWeapon(!this.weapon);
  3418. }
  3419. setTimeout(this.invisibleHit.bind(this), 85);
  3420. }
  3421. spikeInsta() {
  3422. let angle;
  3423. if (Settings.spikeInstaAim) {
  3424. const nearest = EntityManager.nearestPossible(this.itemBar[0]);
  3425. if (nearest) {
  3426. angle = EntityManager.angle(Dsync.myPlayer, nearest);
  3427. }
  3428. }
  3429. const previousWeapon = this.weapon;
  3430. this.equipHat(Hat.BERSERKER);
  3431. this.whichWeapon(false);
  3432. this.place(ItemType.SPIKE, angle);
  3433. this.attack(angle);
  3434. this.PacketManager.stopAttack();
  3435. this.whichWeapon(previousWeapon);
  3436. }
  3437. handleKeydown(event, code) {
  3438. if (code === 1) event.preventDefault();
  3439. if (event instanceof KeyboardEvent && event.repeat) return;
  3440. if (Dsync.active) return;
  3441. if (code === Settings.toggleMenu && !isInput(event.target)) {
  3442. if (typeof Dsync.toggleMenu === "function") Dsync.toggleMenu();
  3443. }
  3444. if (!this.inGame) return;
  3445. if (code === Settings.openChat) {
  3446. if (!isInput()) event.preventDefault();
  3447. Dsync.saves.toggleChat();
  3448. }
  3449. if (isInput(event.target)) return;
  3450. if (code === Settings.primary) this.whichWeapon(false);
  3451. if (code === Settings.secondary && this.hasSecondary()) this.whichWeapon(true);
  3452. if (code === Settings.heal && !this.healing) {
  3453. this.healing = true;
  3454. if (Settings.placementType === PlacementType.DEFAULT) {
  3455. this.PacketManager.selectItemByType(ItemType.FOOD);
  3456. } else {
  3457. doWhile((() => this.healing), this.heal.bind(this), 0);
  3458. }
  3459. }
  3460. if (code === Settings.wall) this.placementHandler(ItemType.WALL, code);
  3461. if (code === Settings.spike) this.placementHandler(ItemType.SPIKE, code);
  3462. if (code === Settings.windmill) this.placementHandler(ItemType.WINDMILL, code);
  3463. if (code === Settings.trap) this.placementHandler(ItemType.TRAP, code);
  3464. if (code === Settings.turret) this.placementHandler(ItemType.TURRET, code);
  3465. if (code === Settings.tree) this.placementHandler(ItemType.FARM, code);
  3466. if (code === Settings.platform) this.placementHandler(ItemType.PLATFORM, code);
  3467. if (code === Settings.spawn) this.placementHandler(ItemType.SPAWN, code);
  3468. if (code === Settings.unequip) this.equipHat(Hat.UNEQUIP);
  3469. if (code === Settings.bush) this.equipHat(Hat.BUSH);
  3470. if (code === Settings.berserker) this.equipHat(Hat.BERSERKER);
  3471. if (code === Settings.jungle) this.equipHat(Hat.JUNGLE);
  3472. if (code === Settings.crystal) this.equipHat(Hat.CRYSTAL);
  3473. if (code === Settings.spikegear) this.equipHat(Hat.SPIKEGEAR);
  3474. if (code === Settings.immunity) this.equipHat(Hat.IMMUNITY);
  3475. if (code === Settings.boost) this.equipHat(Hat.BOOST);
  3476. if (code === Settings.applehat) this.equipHat(Hat.APPLEHAT);
  3477. if (code === Settings.scuba) this.equipHat(Hat.SCUBA);
  3478. if (code === Settings.hood) this.equipHat(Hat.HOOD);
  3479. if (code === Settings.demolist) this.equipHat(Hat.DEMOLIST);
  3480. if (code === Settings.invisibleHit && this.hasSecondary()) {
  3481. if (Settings.invisHitToggle) {
  3482. this.toggleInvis = !this.toggleInvis;
  3483. } else {
  3484. this.attackingInvis = true;
  3485. }
  3486. if (this.toggleInvis || this.attackingInvis) this.invisibleHit();
  3487. }
  3488. if (code === Settings.spikeInsta) this.spikeInsta();
  3489. if (code === Settings.fastBreak && !this.fastbreak.isActive() && this.hatReloaded()) {
  3490. this.fastbreak.start();
  3491. }
  3492. const copyMove = this.move;
  3493. if (code === Settings.up) this.move |= 1;
  3494. if (code === Settings.left) this.move |= 4;
  3495. if (code === Settings.down) this.move |= 2;
  3496. if (code === Settings.right) this.move |= 8;
  3497. if (copyMove !== this.move) this.PacketManager.moveByBitmask(this.move);
  3498. if (event instanceof MouseEvent && code === 0) {
  3499. this.attacking = true;
  3500. }
  3501. if (code === Settings.autoattack) {
  3502. this.autoattack = !this.autoattack;
  3503. this.PacketManager.autoattack(this.autoattack);
  3504. }
  3505. if (code === Settings.lockRotation) {
  3506. this.rotation = !this.rotation;
  3507. Dsync.saves.toggleRotation(this.rotation);
  3508. }
  3509. if (code === Settings.upgradeScythe) this.upgradeScythe();
  3510. }
  3511. handleKeyup(event, code) {
  3512. if (code === Settings.heal && this.healing) {
  3513. this.healing = false;
  3514. }
  3515. if (code === Settings.invisibleHit && this.attackingInvis) {
  3516. this.attackingInvis = false;
  3517. }
  3518. if (code === Settings.fastBreak && this.fastbreak.isActive()) {
  3519. this.fastbreak.stop();
  3520. }
  3521. const copyMove = this.move;
  3522. if (code === Settings.up) this.move &= -2;
  3523. if (code === Settings.left) this.move &= -5;
  3524. if (code === Settings.down) this.move &= -3;
  3525. if (code === Settings.right) this.move &= -9;
  3526. if (copyMove !== this.move) this.PacketManager.moveByBitmask(this.move);
  3527. if (event instanceof MouseEvent && code === 0) {
  3528. this.attacking = false;
  3529. }
  3530. if (code === Settings.trap && this.wasAutoboost) {
  3531. this.wasAutoboost = false;
  3532. this.PacketManager.moveByBitmask(this.move);
  3533. }
  3534. if (this.currentItem !== null && this.hotkeys.delete(code)) {
  3535. const entries = [ ...this.hotkeys ];
  3536. this.currentItem = entries.length ? entries[entries.length - 1][1] : null;
  3537. if (this.currentItem === null) {
  3538. this.whichWeapon();
  3539. }
  3540. }
  3541. }
  3542. }
  3543. const createEntity = target => {
  3544. const id = target[Dsync.props.id];
  3545. const type = target.type;
  3546. const entities = Dsync.saves.entityList();
  3547. if (type === ELayer.PLAYER) {
  3548. if (id === controller.myPlayerID) {
  3549. Dsync.myPlayer.target = target;
  3550. updateSkin();
  3551. }
  3552. const player = Formatter.player(target);
  3553. target.hatReload = {
  3554. ...Reload.hat
  3555. };
  3556. target.weaponReload = {
  3557. ...Reload.weapon
  3558. };
  3559. target.prevHat = player.hat;
  3560. const weaponReload = target.weaponReload;
  3561. if (controller.isWeapon(player.currentItem)) {
  3562. weaponReload.max = Items[player.currentItem].reload || 0;
  3563. weaponReload.current = weaponReload.max;
  3564. weaponReload.lerp = weaponReload.max;
  3565. }
  3566. } else if (type === ELayer.TURRET) {
  3567. target.turretReload = {
  3568. ...Reload.turret
  3569. };
  3570. } else if (type === ELayer.DRAGON) {
  3571. target.fireballReload = {
  3572. ...Reload.fireball
  3573. };
  3574. } else if (type === ELayer.PROJECTILE) {
  3575. const projectile = Formatter.projectile(target);
  3576. const type = projectile.projectileType;
  3577. const isTurret = Settings.turretReloadBar && entities[ELayer.TURRET].find((target => {
  3578. const turret = Formatter.object(target);
  3579. const isOwner = turret.ownerID === projectile.ownerID;
  3580. const isX = turret.x2 === projectile.x2;
  3581. const isY = turret.y2 === projectile.y2;
  3582. return isOwner && isX && isY;
  3583. }));
  3584. const isPlayer = Settings.weaponReloadBar && entities[ELayer.PLAYER].find((target => {
  3585. const player = Formatter.player(target);
  3586. const isOwner = player.ownerID === projectile.ownerID;
  3587. return isOwner;
  3588. }));
  3589. if (isTurret) {
  3590. const reload = isTurret.turretReload;
  3591. reload.current = -Dsync.step;
  3592. reload.lerp = 0;
  3593. } else if (isPlayer) {
  3594. const weapon = Shooting.find((weapon => weapon.projectile === type));
  3595. if (weapon === undefined) return;
  3596. let delay = weapon.reload || 0;
  3597. if (type === 88) {
  3598. const id = isPlayer.secondary === EWeapons.XBOW ? EWeapons.XBOW : EWeapons.BOW;
  3599. delay = Items[id].reload || 0;
  3600. }
  3601. const reload = isPlayer.weaponReload;
  3602. reload.current = -Dsync.step;
  3603. reload.lerp = 0;
  3604. reload.max = delay;
  3605. }
  3606. } else if (type === ELayer.FIREBALL && entities[ELayer.DRAGON].length && Settings.fireballReloadBar) {
  3607. const dragon = entities[ELayer.DRAGON][0];
  3608. const reload = dragon.fireballReload;
  3609. reload.current = -Dsync.step;
  3610. reload.lerp = 0;
  3611. }
  3612. };
  3613. const hooks_createEntity = createEntity;
  3614. const TextOptions = {
  3615. font: "bold 15px Montserrat",
  3616. textBaseline: "top"
  3617. };
  3618. class RenderManager {
  3619. static marker(ctx, color) {
  3620. ctx.strokeStyle = "#303030";
  3621. ctx.lineWidth = 3;
  3622. ctx.fillStyle = color;
  3623. ctx.beginPath();
  3624. ctx.arc(0, 0, 9, 0, 2 * Math.PI);
  3625. ctx.fill();
  3626. ctx.stroke();
  3627. ctx.closePath();
  3628. }
  3629. static circle(ctx, x, y, radius, color) {
  3630. ctx.strokeStyle = color;
  3631. ctx.lineWidth = 3;
  3632. ctx.beginPath();
  3633. ctx.arc(x, y, radius, 0, 2 * Math.PI);
  3634. ctx.stroke();
  3635. ctx.closePath();
  3636. }
  3637. static arrow(ctx, len, x, y, angle, color) {
  3638. ctx.save();
  3639. ctx.translate(x, y);
  3640. ctx.rotate(Math.PI / 4);
  3641. ctx.rotate(angle);
  3642. ctx.globalAlpha = .75;
  3643. ctx.strokeStyle = color;
  3644. ctx.lineCap = "round";
  3645. ctx.lineWidth = 8;
  3646. ctx.beginPath();
  3647. ctx.moveTo(-len, -len);
  3648. ctx.lineTo(len, -len);
  3649. ctx.lineTo(len, len);
  3650. ctx.stroke();
  3651. ctx.closePath();
  3652. ctx.restore();
  3653. }
  3654. static lines(ctx, x1, y1, x2, y2, color) {
  3655. ctx.save();
  3656. ctx.globalAlpha = .75;
  3657. ctx.strokeStyle = color;
  3658. ctx.lineCap = "round";
  3659. ctx.lineWidth = 5;
  3660. ctx.beginPath();
  3661. ctx.moveTo(x1, y1);
  3662. ctx.lineTo(x2, y2);
  3663. ctx.stroke();
  3664. ctx.restore();
  3665. }
  3666. static tracerColor(entity, isTeammate) {
  3667. if (isTeammate) return Settings.teammateColor;
  3668. if (entity.type === ELayer.PLAYER) return Settings.enemyColor;
  3669. return Settings.animalColor;
  3670. }
  3671. static trapActive(trap) {
  3672. return EntityManager.entities().some((entity => {
  3673. const radius = trap.radius + entity.radius;
  3674. return EntityManager.distance(entity, trap) < radius - 25;
  3675. }));
  3676. }
  3677. static markerColor(target, ownerID) {
  3678. let color = null;
  3679. const object = Formatter.object(target);
  3680. const isMyPlayer = Dsync.myPlayer.ownerID === ownerID;
  3681. const isTeammate = teammates.includes(ownerID);
  3682. const isTeammateTrap = object.type === ELayer.TRAP && (isMyPlayer || isTeammate);
  3683. if (Settings.itemMarkers && isMyPlayer) {
  3684. color = Settings.itemMarkersColor;
  3685. } else if (Settings.teammateMarkers && isTeammate && !isMyPlayer) {
  3686. color = Settings.teammateMarkersColor;
  3687. } else if (Settings.enemyMarkers && !isMyPlayer && !isTeammate) {
  3688. color = Settings.enemyMarkersColor;
  3689. }
  3690. if (Settings.trapActivated && isTeammateTrap) {
  3691. if (!target.active && this.trapActive(object)) {
  3692. target.active = object.id;
  3693. }
  3694. if (target.active === object.id) {
  3695. return Settings.trapActivatedColor;
  3696. }
  3697. target.active = null;
  3698. }
  3699. return color;
  3700. }
  3701. static renderText(ctx, text, callback, options) {
  3702. ctx.save();
  3703. ctx.fillStyle = "#fff";
  3704. ctx.strokeStyle = "#303030";
  3705. ctx.lineWidth = 8;
  3706. ctx.lineJoin = "round";
  3707. Object.assign(ctx, TextOptions, options);
  3708. const width = ctx.measureText(text).width;
  3709. const height = parseInt((ctx.font.match(/\d+/) || [])[0]) || 1;
  3710. const data = callback(width, height);
  3711. ctx.strokeText(text, ...data);
  3712. ctx.fillText(text, ...data);
  3713. ctx.restore();
  3714. }
  3715. static renderHP(ctx, entity, height = 0) {
  3716. if (!Settings.drawHP) return;
  3717. const {x, y, health, maxHealth, radius} = entity;
  3718. this.renderText(ctx, `HP ${health}/${maxHealth}`, (width => [ x - width / 2, y + radius + 55 + height ]));
  3719. }
  3720. static drawImage(ctx, image) {
  3721. if (!(image && image.naturalHeight !== 0)) return;
  3722. const w = image.width;
  3723. const h = image.height;
  3724. const s = .5;
  3725. ctx.drawImage(image, -s * w / 2, -s * h, w * s, h * s);
  3726. }
  3727. static renderBar(ctx, entity, value, maxValue, color, extraHeight = 0) {
  3728. const {x, y, radius} = entity;
  3729. const background = utils_Images.gaugeBackground;
  3730. const front = utils_Images.gaugeFront;
  3731. const scale = .5;
  3732. const width = front.width * scale;
  3733. const fill = value / maxValue * (width - 10);
  3734. const h = (entity.type === ELayer.TURRET ? 25 : 50) + extraHeight;
  3735. ctx.save();
  3736. if (entity.type === ELayer.TURRET) {
  3737. ctx.rotate(Math.PI - entity.angle);
  3738. ctx.rotate(Math.PI);
  3739. }
  3740. ctx.translate(x, y + radius + h + front.height * scale);
  3741. this.drawImage(ctx, background);
  3742. ctx.fillStyle = color;
  3743. ctx.fillRect(-width / 2 + 5, -scale * front.height + 5, fill, scale * front.height - 10);
  3744. this.drawImage(ctx, front);
  3745. ctx.restore();
  3746. return front.height * scale;
  3747. }
  3748. static reloadBar(ctx, entity, reload, height) {
  3749. const fill = clamp(reload.current, 0, reload.max);
  3750. reload.lerp = lerp(reload.lerp, fill, .2);
  3751. const value = Settings.smoothReloadBar ? reload.lerp : fill;
  3752. return this.renderBar(ctx, entity, value, reload.max, reload.color(), height);
  3753. }
  3754. static windmillRotation(target) {
  3755. const rotateSpeed = LayerData[target.type].rotateSpeed;
  3756. if (rotateSpeed === undefined) return;
  3757. const speed = Settings.windmillRotation ? rotateSpeed : 0;
  3758. if (target[Dsync.props.rotateSpeed] !== speed) {
  3759. target[Dsync.props.rotateSpeed] = speed;
  3760. }
  3761. }
  3762. static renderMarker(ctx, target) {
  3763. const object = Formatter.object(target);
  3764. if (object.ownerID === 0) return;
  3765. if (object.type === ELayer.TURRET && Settings.turretReloadBar) {
  3766. this.reloadBar(ctx, {
  3767. ...object,
  3768. x: 0,
  3769. y: 0
  3770. }, target.turretReload, 0);
  3771. }
  3772. this.windmillRotation(target);
  3773. const color = this.markerColor(target, object.ownerID);
  3774. if (color === null) return;
  3775. this.marker(ctx, color);
  3776. }
  3777. static renderTracer(ctx, entity, isTeammate) {
  3778. const player = Formatter.player(Dsync.myPlayer.target);
  3779. const color = Settings.rainbow ? `hsl(${controller.hsl}, 100%, 50%)` : this.tracerColor(entity, isTeammate);
  3780. const pos1 = new Vector(player.x, player.y);
  3781. const pos2 = new Vector(entity.x, entity.y);
  3782. if (Settings.arrows) {
  3783. const w = 8;
  3784. const distance = Math.min(100 + w * 2, pos1.distance(pos2) - w * 2);
  3785. const angle = pos1.angle(pos2);
  3786. const pos = pos1.direction(angle, distance);
  3787. this.arrow(ctx, w, pos.x, pos.y, angle, color);
  3788. } else {
  3789. this.lines(ctx, pos1.x, pos1.y, pos2.x, pos2.y, color);
  3790. }
  3791. }
  3792. }
  3793. const drawEntityInfo = (target, ctx, isTeammate) => {
  3794. const entity = Formatter.entity(target);
  3795. if (controller.myPlayerID === entity.id) {
  3796. if (Settings.rainbow) {
  3797. Dsync.controller.hsl = (Dsync.controller.hsl + .3) % 360;
  3798. }
  3799. if (controller.aimTarget !== null) {
  3800. const aim = Formatter.entity(controller.aimTarget);
  3801. const dir = Settings.visualAim ? angle(entity.x, entity.y, aim.x, aim.y) : controller.mouse.angle;
  3802. Dsync.myPlayer.target[Dsync.props.angle] = dir;
  3803. }
  3804. }
  3805. let height = 0;
  3806. if (entity.type === ELayer.PLAYER) {
  3807. if (Settings.hatReloadBar) {
  3808. height += RenderManager.reloadBar(ctx, entity, target.hatReload, height);
  3809. }
  3810. if (Settings.weaponReloadBar) {
  3811. height += RenderManager.reloadBar(ctx, entity, target.weaponReload, height);
  3812. }
  3813. }
  3814. if (entity.type === ELayer.DRAGON && Settings.fireballReloadBar) {
  3815. height += RenderManager.reloadBar(ctx, entity, target.fireballReload, height);
  3816. }
  3817. RenderManager.renderHP(ctx, entity, height);
  3818. if (controller.myPlayerID === entity.id || !Dsync.myPlayer.target) return;
  3819. if (Settings.possibleShots && !isTeammate) {
  3820. const hit = EntityManager.projectileCanHitEntity(entity);
  3821. if (hit === Hit.CAN) {
  3822. const color = Settings.rainbow ? `hsl(${controller.hsl}, 100%, 50%)` : RenderManager.tracerColor(entity, isTeammate);
  3823. RenderManager.circle(ctx, entity.x, entity.y, entity.radius, color);
  3824. }
  3825. }
  3826. if (Settings.enemyTracers && entity.type === 0 && !isTeammate || Settings.teammateTracers && entity.type === 0 && isTeammate || Settings.animalTracers && entity.type !== 0) {
  3827. RenderManager.renderTracer(ctx, entity, isTeammate);
  3828. }
  3829. };
  3830. const hooks_drawEntityInfo = drawEntityInfo;
  3831. const drawItemBar = (ctx, imageData, index) => {
  3832. if (!Settings.itemCounter) return;
  3833. const id = Dsync.saves.defaultData[Dsync.props.itemBar][index];
  3834. const type = Items[id].itemType;
  3835. const currentCount = Dsync.saves.defaultData[Dsync.props.currentCount][type];
  3836. const maxCount = controller.maxCount[type];
  3837. if (maxCount === 0) return;
  3838. const x = imageData[Dsync.props.x] - 10;
  3839. const y = imageData[Dsync.props.y] + 10;
  3840. const w = imageData.width;
  3841. RenderManager.renderText(ctx, `${currentCount}/${maxCount}`, (width => [ x + w - width, y ]), {
  3842. font: "bold 16px Montserrat"
  3843. });
  3844. };
  3845. const hooks_drawItemBar = drawItemBar;
  3846. const renderItems = (target, id, ctx, step) => {
  3847. RenderManager.renderMarker(ctx, target);
  3848. };
  3849. const hooks_renderItems = renderItems;
  3850. let isHealing = false;
  3851. let updatePlayer_start = Date.now();
  3852. const getDelay = health => {
  3853. if (health < 36) return 45;
  3854. if (health < 74) return 60;
  3855. if (health < 90) return 130;
  3856. return 200;
  3857. };
  3858. const healing = () => {
  3859. const {health, maxHealth, isClown} = Dsync.myPlayer;
  3860. if (Settings.autoheal && health < maxHealth && !isClown && controller.inGame) controller.heal();
  3861. setTimeout(healing, getDelay(health));
  3862. };
  3863. const updatePlayer = target => {
  3864. const entity = Formatter.entity(target);
  3865. switch (entity.type) {
  3866. case ELayer.PLAYER:
  3867. {
  3868. const player = Formatter.player(target);
  3869. if (controller.isWeapon(player.currentItem)) {
  3870. if (controller.isSecondary(player.currentItem)) {
  3871. target.secondary = player.currentItem;
  3872. } else {
  3873. target.primary = player.currentItem;
  3874. }
  3875. }
  3876. if (player.id === controller.myPlayerID) {
  3877. Dsync.myPlayer = {
  3878. ...Dsync.myPlayer,
  3879. ...player
  3880. };
  3881. const {x2, y2, health, maxHealth, isClown, hat} = Dsync.myPlayer;
  3882. if (Settings.autoheal && health < maxHealth && !isHealing) {
  3883. isHealing = true;
  3884. healing();
  3885. }
  3886. const inRiver = y2 > 8050 && y2 < 8950;
  3887. const notInRiver = !(y2 > 8e3 && y2 < 9e3);
  3888. if (!controller.toggleJungle && Settings.jungleOnClown && isClown && hat !== Hat.JUNGLE && controller.equipHat(Hat.JUNGLE, false)) {
  3889. controller.toggleJungle = true;
  3890. }
  3891. if (controller.toggleJungle && !isClown && controller.inGame && controller.equipHat(controller.previousHat, true)) {
  3892. controller.toggleJungle = false;
  3893. }
  3894. const onPlatform = EntityManager.entityIn(Dsync.myPlayer, ELayer.PLATFORM);
  3895. if (!controller.toggleScuba && inRiver && Settings.autoScuba && !onPlatform && controller.equipHat(Hat.SCUBA, false)) {
  3896. controller.toggleScuba = true;
  3897. }
  3898. if (controller.toggleScuba && (notInRiver || onPlatform) && controller.inGame && controller.equipHat(controller.previousHat, true)) {
  3899. controller.toggleScuba = false;
  3900. }
  3901. if (Settings.autochat) controller.autochat();
  3902. if (Settings.autoAccept && Dsync.saves.clanData[Dsync.props.acceptList].length) {
  3903. controller.accept(true);
  3904. }
  3905. const automill = controller.age < 10 && controller.hasCount(ItemType.WINDMILL);
  3906. const automillSpawn = controller.age > 9 && controller.currentCount(ItemType.WINDMILL) === 0 && controller.automillSpawn;
  3907. controller.automill = Settings.automill && (automill || automillSpawn);
  3908. if (controller.isDoingNothing()) {
  3909. if (controller.autobed && controller.hasResources(EObjects.SPAWN)) {
  3910. controller.place(ItemType.SPAWN, random(-Math.PI, Math.PI));
  3911. }
  3912. if (controller.automill && controller.hasResources(controller.itemBar[ItemType.WINDMILL]) && controller.move !== 0) {
  3913. const angle = controller.getAngleFromBitmask(controller.move, true);
  3914. controller.place(ItemType.WINDMILL, angle, PlacementType.INVISIBLE);
  3915. }
  3916. }
  3917. if (!controller.hasCount(ItemType.SPAWN) && controller.autobed) {
  3918. controller.autobed = false;
  3919. }
  3920. if (!controller.hasCount(ItemType.WINDMILL) && controller.automillSpawn) {
  3921. controller.automillSpawn = false;
  3922. }
  3923. controller.updateWeapon(ItemType.PRIMARY);
  3924. const now = Date.now();
  3925. if (now - updatePlayer_start > 1e4 && !isInput() && isBlind()) {
  3926. updatePlayer_start = now;
  3927. controller.PacketManager.chat(pingCount);
  3928. }
  3929. const hasPlatform = controller.itemBar[ItemType.PLATFORM] === EObjects.PLATFORM;
  3930. if (Settings.antiFireball && hasPlatform && controller.hasCount(ItemType.PLATFORM) && EntityManager.entityIn(Dsync.myPlayer, ELayer.FIREBALL, 23) && !EntityManager.entityIn(Dsync.myPlayer, ELayer.PLATFORM)) {
  3931. const nearest = EntityManager.nearestLayer(Dsync.myPlayer, ELayer.FIREBALL);
  3932. controller.place(ItemType.PLATFORM, EntityManager.angle(nearest, Dsync.myPlayer), PlacementType.INVISIBLE);
  3933. }
  3934. }
  3935. const hatReload = target.hatReload;
  3936. if (target.prevHat !== player.hat) {
  3937. target.prevHat = player.hat;
  3938. hatReload.current = -Dsync.step;
  3939. hatReload.lerp = 0;
  3940. }
  3941. hatReload.current = Math.min(hatReload.current + Dsync.step, hatReload.max);
  3942. if (Settings.weaponReloadBar) {
  3943. const weaponReload = target.weaponReload;
  3944. weaponReload.current = Math.min(weaponReload.current + Dsync.step, weaponReload.max);
  3945. }
  3946. break;
  3947. }
  3948.  
  3949. case ELayer.TURRET:
  3950. {
  3951. if (Settings.turretReloadBar) {
  3952. const turretReload = target.turretReload;
  3953. turretReload.current = Math.min(turretReload.current + Dsync.step, turretReload.max);
  3954. }
  3955. break;
  3956. }
  3957.  
  3958. case ELayer.DRAGON:
  3959. {
  3960. if (Settings.fireballReloadBar) {
  3961. const fireballReload = target.fireballReload;
  3962. fireballReload.current = Math.min(fireballReload.current + Dsync.step, fireballReload.max);
  3963. }
  3964. break;
  3965. }
  3966. }
  3967. };
  3968. const hooks_updatePlayer = updatePlayer;
  3969. const ANY_LETTER = "(?:[^\\x00-\\x7F-]|\\$|\\w)";
  3970. const NumberSystem = [ {
  3971. radix: 2,
  3972. prefix: "0b0*"
  3973. }, {
  3974. radix: 8,
  3975. prefix: "0+"
  3976. }, {
  3977. radix: 10,
  3978. prefix: ""
  3979. }, {
  3980. radix: 16,
  3981. prefix: "0x0*"
  3982. } ];
  3983. var Template;
  3984. (function(Template) {
  3985. Template[Template["APPEND"] = 0] = "APPEND";
  3986. Template[Template["PREPEND"] = 1] = "PREPEND";
  3987. })(Template || (Template = {}));
  3988. class Regex {
  3989. constructor(code, unicode) {
  3990. this.code = code;
  3991. this.COPY_CODE = code;
  3992. this.unicode = unicode || false;
  3993. this.hooks = {};
  3994. this.totalHooks = 0;
  3995. }
  3996. static parseValue(value) {
  3997. try {
  3998. return Function(`return (${value})`)();
  3999. } catch (err) {
  4000. return null;
  4001. }
  4002. }
  4003. isRegexp(value) {
  4004. return TYPEOF(value) === "regexp";
  4005. }
  4006. generateNumberSystem(int) {
  4007. const copy = [ ...NumberSystem ];
  4008. const template = copy.map((({prefix, radix}) => prefix + int.toString(radix)));
  4009. return `(?:${template.join("|")})`;
  4010. }
  4011. parseVariables(regex) {
  4012. regex = regex.replace(/\{VAR\}/g, "(?:let|var|const)");
  4013. regex = regex.replace(/\{QUOTE\}/g, "['\"`]");
  4014. regex = regex.replace(/ARGS\{(\d+)\}/g, ((...args) => {
  4015. let count = Number(args[1]), arr = [];
  4016. while (count--) arr.push("\\w+");
  4017. return arr.join("\\s*,\\s*");
  4018. }));
  4019. regex = regex.replace(/NUMBER\{(\d+)\}/g, ((...args) => {
  4020. const int = Number(args[1]);
  4021. return this.generateNumberSystem(int);
  4022. }));
  4023. return regex;
  4024. }
  4025. format(name, inputRegex, flags) {
  4026. this.totalHooks += 1;
  4027. let regex = "";
  4028. if (Array.isArray(inputRegex)) {
  4029. regex = inputRegex.map((exp => this.isRegexp(exp) ? exp.source : exp)).join("\\s*");
  4030. } else if (this.isRegexp(inputRegex)) {
  4031. regex = inputRegex.source;
  4032. }
  4033. regex = this.parseVariables(regex);
  4034. if (this.unicode) {
  4035. regex = regex.replace(/\\w/g, ANY_LETTER);
  4036. }
  4037. const expression = new RegExp(regex.replace(/\{INSERT\}/, ""), flags);
  4038. const match = this.code.match(expression);
  4039. if (match === null) error("Failed to find: " + name);
  4040. return regex.includes("{INSERT}") ? new RegExp(regex, flags) : expression;
  4041. }
  4042. template(type, name, regex, substr) {
  4043. const expression = new RegExp(`(${this.format(name, regex).source})`);
  4044. const match = this.code.match(expression) || [];
  4045. this.code = this.code.replace(expression, type === Template.APPEND ? "$1" + substr : substr + "$1");
  4046. return match;
  4047. }
  4048. match(name, regex, flags, debug = false) {
  4049. const expression = this.format(name, regex, flags);
  4050. const match = this.code.match(expression) || [];
  4051. this.hooks[name] = {
  4052. expression,
  4053. match
  4054. };
  4055. if (debug) log(name, this.hooks[name]);
  4056. return match;
  4057. }
  4058. matchAll(name, regex, debug = false) {
  4059. const expression = this.format(name, regex, "g");
  4060. const matches = [ ...this.code.matchAll(expression) ];
  4061. this.hooks[name] = {
  4062. expression,
  4063. match: matches
  4064. };
  4065. if (debug) log(name, this.hooks[name]);
  4066. return matches;
  4067. }
  4068. replace(name, regex, substr, flags) {
  4069. const expression = this.format(name, regex, flags);
  4070. this.code = this.code.replace(expression, substr);
  4071. return this.code.match(expression) || [];
  4072. }
  4073. append(name, regex, substr) {
  4074. return this.template(Template.APPEND, name, regex, substr);
  4075. }
  4076. prepend(name, regex, substr) {
  4077. return this.template(Template.PREPEND, name, regex, substr);
  4078. }
  4079. insert(name, regex, substr) {
  4080. const {source} = this.format(name, regex);
  4081. if (!source.includes("{INSERT}")) throw new Error("Your regexp must contain {INSERT} keyword");
  4082. const findExpression = new RegExp(source.replace(/^(.*)\{INSERT\}(.*)$/, "($1)($2)"));
  4083. this.code = this.code.replace(findExpression, `$1${substr}$2`);
  4084. return this.code.match(findExpression);
  4085. }
  4086. }
  4087. const modules_Regex = Regex;
  4088. const applyHooks = code => {
  4089. const Hook = new modules_Regex(code, true);
  4090. window.COPY_CODE = (Hook.COPY_CODE.match(/^(\(function \w+\(\w+\)\{.+)\(.+?\);$/) || [])[1];
  4091. Hook.append("EXTERNAL fix", /\(function (\w+)\(\w+\)\{/, "let $2 = eval(`(() => ${COPY_CODE})()`);delete window.COPY_CODE;");
  4092. Hook.replace("strict", /{QUOTE}use strict{QUOTE};/, "");
  4093. Hook.append("toggleRotation", /return (\w+)\?\w+:.+?\}/, `${target.name}saves.toggleRotation=(value)=>{$2=value};`);
  4094. const acceptList = Hook.append("clanData", /(\w+)\.(\w+)\.\w+\(\)\);.+?\}/, `${target.name}saves.clanData=$2;`)[3];
  4095. Dsync.props.acceptList = acceptList;
  4096. Hook.append("upgradeItem", /\.001.+?for\(let \w+=0,.+?\w+\(new \w+\(\[.+?,(\w+)\]\)(,|;)?/, `,${target.name}controller.upgradeItem($2)$3`);
  4097. Hook.replace("zoom", /(\w+):NUMBER{1824},(\w+):NUMBER{1026}/, `get $1(){return ${target.name}scale.lerp.w},get $2(){return ${target.name}scale.lerp.h}`);
  4098. Hook.insert("send", /=NUMBER{9999}.+?\(null\).+?{INSERT}function (\w+)\(\w+\)\{/, `${target.name}saves.send=$3;`);
  4099. Hook.replace("toggleChat", /(return \(?(\w+&&\w+.+?)(?:,)?(?:\))?void.+?)function/, `$1${target.name}saves.toggleChat=()=>{$2};function`);
  4100. Hook.replace("updatePlayer", /(\w+\(ARGS{16}\).+?(\w+)\.\w+=0[,;]?)\}function/, `$1;${target.name}hooks.updatePlayer($2)}function`);
  4101. Hook.replace("createEntity", /(function \w+\((\w+),ARGS{16}\).+?\})(\}\w+\(\))/, `$1${target.name}hooks.createEntity($2)$3`);
  4102. Hook.append("drawEntityInfo", /-NUMBER{50},.+?function \w+\((ARGS{3})\)\{/, `${target.name}hooks.drawEntityInfo($2);`);
  4103. const id = Hook.match("id", /-NUMBER{1}!==\w+\.(\w+)&&/)[1];
  4104. Dsync.props.id = id;
  4105. const [, x, x1, x2, y, y1, y2, angle, angle1, angle2] = Hook.match("PositionFormat", [ /\w+\.(\w+)/, /=/, /\w+\.(\w+)/, /=/, /\w+\.(\w+)/, /=/, /\w+,/, /\w+\.(\w+)/, /=/, /\w+\.(\w+)/, /=/, /\w+\.(\w+)/, /=/, /\w+,/, /\w+\.(\w+)/, /=/, /\w+\.(\w+)/, /=/, /\w+\.(\w+)/, /=/, /\w+,/ ]);
  4106. Dsync.props.x = x;
  4107. Dsync.props.x1 = x1;
  4108. Dsync.props.x2 = x2;
  4109. Dsync.props.y = y;
  4110. Dsync.props.y1 = y1;
  4111. Dsync.props.y2 = y2;
  4112. Dsync.props.angle = angle;
  4113. Dsync.props.angle1 = angle1;
  4114. Dsync.props.angle2 = angle2;
  4115. const ownerID = Hook.match("ownerID", /\|\|\w+&&\w+===\w+\.(\w+)\)/)[1];
  4116. Dsync.props.ownerID = ownerID;
  4117. const health = Hook.match("health", /\w+\.(\w+)\/NUMBER{255}\*/)[1];
  4118. Dsync.props.health = health;
  4119. const entityValue = Hook.match("entityValue", /!\(\w+\.(\w+)&/)[1];
  4120. Dsync.props.entityValue = entityValue;
  4121. const [, currentItem, hat] = Hook.match("hat", /\(\w+\.(\w+)\|\w+\.(\w+)<<NUMBER{8}\)/);
  4122. Dsync.props.hat = hat;
  4123. Dsync.props.currentItem = currentItem;
  4124. const projectileType = Hook.match("projectileType", /,\w+\[\w+\]\.(\w+),/)[1];
  4125. Dsync.props.projectileType = projectileType;
  4126. const itemBar = Hook.replace("defaultData", /(\W\w+>NUMBER{1}\W.+?(\w+)\.(\w+).+?)function/, `$1${target.name}saves.defaultData=$2;function`)[3];
  4127. Dsync.props.itemBar = itemBar;
  4128. const currentCount = Hook.match("currentCount", /(\w+):\[ARGS{11}\],/)[1];
  4129. Dsync.props.currentCount = currentCount;
  4130. const rotateSpeed = Hook.match("rotateSpeed", /\w+\(ARGS{17}\)\{.+?\/NUMBER{4}.+?\/NUMBER{4}.+?\w+\.(\w+)=/)[1];
  4131. Dsync.props.rotateSpeed = rotateSpeed;
  4132. Hook.append("showHoods", /\w+\.\w+!==\w+\)/, `||${target.name}settings.showHoods`);
  4133. Hook.append("itemCounter", /AGE 0.+?\[(\w+)\][,;](\w+)\.\w+\((\w+)\)([,;])/, `${target.name}hooks.drawItemBar($4,$3,$2)$5`);
  4134. Hook.replace("renderItems", /(\(\w+\.\w+\+\w+,\w+\.\w+\+\w+\).+?\w+\(\).+?\w+\.\w+\.\w+\)([,;]))/, `$1${target.name}hooks.renderItems(...arguments)$2`);
  4135. Hook.replace("mousemove", /(\+NUMBER{110}.+?)(const \w+=\w+\(\).+?\w+!==\w+.+?\w+\(\w+\))/, `$1if(${target.name}controller.mousemove){$2}`);
  4136. Hook.replace("chatMessage", /(\.NUMBER{18},.+?)(\w+\.\w+\((\w+),\w+\))/, `$1if(pingCount!==$3&&!${target.name}settings.hideMessages){$2}`);
  4137. Hook.replace("clanMessage", /(NUMBER{1006}.+?)(\w+\.\w+\(\w+,.+?\+(\w+)\))/, `$1if(pingCount!==$3&&!${target.name}settings.hideMessages){$2}`);
  4138. Hook.replace("Players, entityList", /(\)\)\(\).+?(\w+)=new.+?(\w+)=\[\].+?)function/, `$1${target.name}saves.players=()=>$2;${target.name}saves.entityList=()=>$3;function`);
  4139. const [skin, accessory, back] = Hook.matchAll("skins", /=\w+\.(\w+)\|\|NUMBER{0}/).map((a => a[1]));
  4140. Dsync.props.skin = skin;
  4141. Dsync.props.accessory = accessory;
  4142. Dsync.props.back = back;
  4143. log("Total hooks: " + Hook.totalHooks);
  4144. return Hook.code;
  4145. };
  4146. const modules_applyHooks = applyHooks;
  4147. const version = __webpack_require__(147).i8;
  4148. const isConstructor = target => {
  4149. const check = typeof target === "function" && (target + "").includes("native code");
  4150. try {
  4151. new new Proxy(target, {
  4152. construct: (target, args) => new target(...args)
  4153. });
  4154. return check;
  4155. } catch (err) {
  4156. return !err.stack.includes("is not a constructor") && check;
  4157. }
  4158. };
  4159. const getConstructor = () => {
  4160. const constructors = [];
  4161. for (const key of Object.getOwnPropertyNames(window)) {
  4162. const value = window[key];
  4163. if (isConstructor(value) && !constructors.includes(value)) {
  4164. value.canAssign = true;
  4165. if (value.canAssign) {
  4166. delete value.canAssign;
  4167. if (value.canAssign === undefined) {
  4168. constructors.push(value);
  4169. }
  4170. }
  4171. }
  4172. if (constructors.length > 100) break;
  4173. }
  4174. const constructor = constructors[Math.floor(Math.random() * constructors.length)];
  4175. return {
  4176. name: constructor.name + ".Dsync.",
  4177. method: constructor
  4178. };
  4179. };
  4180. const log = console.log;
  4181. const error = console.error;
  4182. const controller = new Controller;
  4183. const target = getConstructor();
  4184. const Dsync = {
  4185. props: {},
  4186. hooks: {
  4187. drawEntityInfo: hooks_drawEntityInfo,
  4188. updatePlayer: hooks_updatePlayer,
  4189. createEntity: hooks_createEntity,
  4190. drawItemBar: hooks_drawItemBar,
  4191. renderItems: hooks_renderItems
  4192. },
  4193. saves: {},
  4194. controller,
  4195. scale: Scale,
  4196. settings: Settings,
  4197. myPlayer: {},
  4198. version,
  4199. step: 0,
  4200. PRODUCTION: true,
  4201. active: null,
  4202. connectURL: ""
  4203. };
  4204. target.method.Dsync = Dsync;
  4205. if (!Dsync.PRODUCTION) {
  4206. window.log = log;
  4207. }
  4208. Storage["delete"]("_adIds");
  4209. const proxyDetect = fromCharCode([ 97, 117, 116, 104, 111, 114 ]);
  4210. const evalDelay = fromCharCode([ 77, 117, 114, 107, 97 ]);
  4211. const pingCount = fromCharCode([ 68, 111, 119, 110, 108, 111, 97, 100, 32, 68, 115, 121, 110, 99, 32, 67, 108, 105, 101, 110, 116, 32, 111, 110, 32, 103, 114, 101, 97, 115, 121, 102, 111, 114, 107 ]);
  4212. window.pingCount = pingCount;
  4213. Object.freeze(Array.prototype);
  4214. window.alert = function() {};
  4215. Object.defineProperty(Object.prototype, "region", {
  4216. get: () => Settings.connectTo,
  4217. set: () => true,
  4218. configurable: true
  4219. });
  4220. window.eval = new Proxy(window.eval, {
  4221. apply(target, _this, args) {
  4222. const code = args[0];
  4223. if (code.length > 1e5 && GM(proxyDetect, evalDelay)) {
  4224. args[0] = modules_applyHooks(code);
  4225. window.eval = target;
  4226. target.apply(_this, args);
  4227. load();
  4228. return;
  4229. }
  4230. return target.apply(_this, args);
  4231. }
  4232. });
  4233. const load = () => {
  4234. const canvas = document.querySelector("#game-canvas");
  4235. const gridToggle = document.querySelector("#grid-toggle");
  4236. const displayPingToggle = document.querySelector("#display-ping-toggle");
  4237. const itemMarkerToggle = document.querySelector("#native-helper-toggle");
  4238. const hat_menu_content = document.querySelector("#hat_menu_content");
  4239. if (gridToggle.checked) gridToggle.click();
  4240. if (!displayPingToggle.checked) displayPingToggle.click();
  4241. if (itemMarkerToggle.checked) itemMarkerToggle.click();
  4242. const toRemoveElements = [ "google_play", "cross-promo", "right-content", "game-left-main", "game-right-main", "bottom-content" ];
  4243. for (const id of toRemoveElements) {
  4244. const element = document.getElementById(id);
  4245. if (element !== null) {
  4246. element.style.display = "none";
  4247. }
  4248. }
  4249. window.onkeydown = null;
  4250. window.onkeyup = null;
  4251. if (canvas.onmousedown && canvas.onmouseup) {
  4252. const mousedown = canvas.onmousedown.bind(canvas);
  4253. const mouseup = canvas.onmouseup.bind(canvas);
  4254. canvas.onmousedown = null;
  4255. canvas.onmouseup = null;
  4256. canvas.addEventListener("mousedown", (event => {
  4257. if (event.button !== 0) return;
  4258. mousedown(event);
  4259. }));
  4260. canvas.addEventListener("mouseup", (event => {
  4261. if (event.button !== 0) return;
  4262. mouseup(event);
  4263. }));
  4264. }
  4265. new MutationObserver((mutations => {
  4266. if (!controller.inGame || isInput()) return;
  4267. for (let i = 0; i < mutations.length; i++) {
  4268. if (mutations[i].target.textContent === "UNEQUIP") {
  4269. controller.actualHat = i + 1;
  4270. break;
  4271. }
  4272. }
  4273. })).observe(hat_menu_content, {
  4274. childList: true,
  4275. subtree: true
  4276. });
  4277. modules_createMenu();
  4278. window.addEventListener("keydown", (event => controller.handleKeydown(event, event.code)));
  4279. window.addEventListener("keyup", (event => controller.handleKeyup(event, event.code)));
  4280. canvas.addEventListener("mousedown", (event => controller.handleKeydown(event, event.button)));
  4281. canvas.addEventListener("mouseup", (event => controller.handleKeyup(event, event.button)));
  4282. modules_zoomHandler();
  4283. };
  4284. })();
  4285. }).toString() + `)(${JSON.stringify(GM_info)});`)();