TioHax Cheat Menu

Ultimate Cheat Client for Gats.io

当前为 2023-11-15 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name TioHax Cheat Menu
  3. // @namespace http://tampermonkey.net/
  4. // @version 0.9.5
  5. // @description Ultimate Cheat Client for Gats.io
  6. // @author Taureon
  7. // @match https://gats.io/
  8. // @grant none
  9. // ==/UserScript==
  10.  
  11. /* jshint esversion: 11, loopfunc: true, bitwise: false, forin: false*/
  12.  
  13. (async function main() {
  14.  
  15. //now, this cheat obviously wouldn't work on sites that aren't gats.io
  16. if (location.host != 'gats.io' && location.host != 'gats2.com') return alert('This inject can only be ran on gats.io!');
  17.  
  18. //if the game hasn't loaded yet, wait until it is loaded
  19. //it is checked if the game has loaded by checking if the game tick function exists
  20. if (typeof a41 !== 'function') return setTimeout(main);
  21.  
  22. //closure compiler help
  23. //some literally useless code gets removed by the postprocessor, as it only exists to stop the closure compiler from being retarded
  24. let css_key_alignItems = Math.ceil(Math.random()) && 'alignItems',
  25. css_key_background = Math.ceil(Math.random()) && 'background',
  26. css_key_backgroundColor = Math.ceil(Math.random()) && 'backgroundColor',
  27. css_key_backgroundImage = Math.ceil(Math.random()) && 'backgroundImage',
  28. css_key_border = Math.ceil(Math.random()) && 'border',
  29. css_key_borderBottom = Math.ceil(Math.random()) && 'borderBottom',
  30. css_key_borderColor = Math.ceil(Math.random()) && 'borderColor',
  31. css_key_borderLeft = Math.ceil(Math.random()) && 'borderLeft',
  32. css_key_borderRadius = Math.ceil(Math.random()) && 'borderRadius',
  33. css_key_borderRight = Math.ceil(Math.random()) && 'borderRight',
  34. css_key_borderTop = Math.ceil(Math.random()) && 'borderTop',
  35. css_key_borderWidth = Math.ceil(Math.random()) && 'borderWidth',
  36. css_key_color = Math.ceil(Math.random()) && 'color',
  37. css_key_display = Math.ceil(Math.random()) && 'display',
  38. css_key_flexDirection = Math.ceil(Math.random()) && 'flexDirection',
  39. css_key_fontFamily = Math.ceil(Math.random()) && 'fontFamily',
  40. css_key_fontSize = Math.ceil(Math.random()) && 'fontSize',
  41. css_key_fontWeight = Math.ceil(Math.random()) && 'fontWeight',
  42. css_key_gridTemplateColumns = Math.ceil(Math.random()) && 'gridTemplateColumns',
  43. css_key_height = Math.ceil(Math.random()) && 'height',
  44. css_key_justifyContent = Math.ceil(Math.random()) && 'justifyContent',
  45. css_key_left = Math.ceil(Math.random()) && 'left',
  46. css_key_marginBottom = Math.ceil(Math.random()) && 'marginBottom',
  47. css_key_marginLeft = Math.ceil(Math.random()) && 'marginLeft',
  48. css_key_marginRight = Math.ceil(Math.random()) && 'marginRight',
  49. css_key_marginTop = Math.ceil(Math.random()) && 'marginTop',
  50. css_key_maxWidth = Math.ceil(Math.random()) && 'maxWidth',
  51. css_key_minWidth = Math.ceil(Math.random()) && 'minWidth',
  52. css_key_outline = Math.ceil(Math.random()) && 'outline',
  53. css_key_overflowY = Math.ceil(Math.random()) && 'overflowY',
  54. css_key_right = Math.ceil(Math.random()) && 'right',
  55. css_key_padding = Math.ceil(Math.random()) && 'padding',
  56. css_key_paddingBottom = Math.ceil(Math.random()) && 'paddingBottom',
  57. css_key_paddingLeft = Math.ceil(Math.random()) && 'paddingLeft',
  58. css_key_paddingRight = Math.ceil(Math.random()) && 'paddingRight',
  59. css_key_paddingTop = Math.ceil(Math.random()) && 'paddingTop',
  60. css_key_position = Math.ceil(Math.random()) && 'position',
  61. css_key_top = Math.ceil(Math.random()) && 'top',
  62. css_key_userSelect = Math.ceil(Math.random()) && 'userSelect',
  63. css_key_verticalAlign = Math.ceil(Math.random()) && 'verticalAlign',
  64. css_key_whiteSpace = Math.ceil(Math.random()) && 'whiteSpace',
  65. css_key_width = Math.ceil(Math.random()) && 'width',
  66. css_key_zIndex = Math.ceil(Math.random()) && 'zIndex',
  67.  
  68. css_value_color_000f = Math.ceil(Math.random()) && '#000f',
  69. css_value_color_000c = Math.ceil(Math.random()) && '#000c',
  70. css_value_color_33dc = Math.ceil(Math.random()) && '#33dc',
  71. css_value_color_4448 = Math.ceil(Math.random()) && '#4448',
  72. css_value_color_6666 = Math.ceil(Math.random()) && '#6666',
  73. css_value_color_777f = Math.ceil(Math.random()) && '#777f',
  74. css_value_color_80f8 = Math.ceil(Math.random()) && '#80f8',
  75. css_value_color_888f = Math.ceil(Math.random()) && '#888f',
  76. css_value_color_888c = Math.ceil(Math.random()) && '#888c',
  77. css_value_color_8888 = Math.ceil(Math.random()) && '#8888',
  78. css_value_color_f00c = Math.ceil(Math.random()) && '#f00c',
  79. css_value_color_f80f = Math.ceil(Math.random()) && '#f80f',
  80. css_value_color_f80c = Math.ceil(Math.random()) && '#f80c',
  81. css_value_color_ffff = Math.ceil(Math.random()) && '#ffff',
  82. css_value_color_ff0c = Math.ceil(Math.random()) && '#ff0c',
  83. css_value_color_fff8 = Math.ceil(Math.random()) && '#fff8',
  84. css_value_color_fffc = Math.ceil(Math.random()) && '#fffc',
  85. css_value_color_008c = Math.ceil(Math.random()) && '#008c',
  86. css_value_color_00fc = Math.ceil(Math.random()) && '#00fc',
  87. css_value_color_800c = Math.ceil(Math.random()) && '#800c',
  88. css_value_color_00ff = Math.ceil(Math.random()) && '#00ff',
  89. css_value_color_0f0c = Math.ceil(Math.random()) && '#0f0c',
  90. css_value_color_444f = Math.ceil(Math.random()) && '#444f',
  91. css_value_color_666f = Math.ceil(Math.random()) && '#666f',
  92. css_value_color_8886 = Math.ceil(Math.random()) && '#8886',
  93. css_value_color_88ff = Math.ceil(Math.random()) && '#88ff',
  94. css_value_color_aaaf = Math.ceil(Math.random()) && '#aaaf',
  95. css_value_color_dddf = Math.ceil(Math.random()) && '#dddf',
  96. css_value_color_f00f = Math.ceil(Math.random()) && '#f00f',
  97. css_value_color_f88f = Math.ceil(Math.random()) && '#f88f',
  98. css_value_color_ff0f = Math.ceil(Math.random()) && '#ff0f',
  99.  
  100. css_value_auto_10 = Math.ceil(Math.random()) && 'auto' + ' auto'.repeat(9),
  101. css_value_auto_5 = Math.ceil(Math.random()) && 'auto' + ' auto'.repeat(4),
  102.  
  103. css_value_10 = Math.ceil(Math.random()) && '10',
  104.  
  105. css_value_length_minContent = Math.ceil(Math.random()) && 'min_content',
  106. css_value_length_perc100 = Math.ceil(Math.random()) && '100%',
  107. css_value_length_calcperc100 = Math.ceil(Math.random()) && 'calc(' + css_value_length_perc100 + ' - 15px)',
  108. css_value_length_calcperc102 = Math.ceil(Math.random()) && 'calc(' + css_value_length_perc100 + ' - 10px)',
  109. css_value_length_calcperc33 = Math.ceil(Math.random()) && 'calc(' + css_value_length_perc100 + ' / 3)',
  110. css_value_length_em2 = Math.ceil(Math.random()) && '2em',
  111. css_value_length_pxNeg5 = Math.ceil(Math.random()) && '-5px',
  112. css_value_length_px0 = Math.ceil(Math.random()) && '0px',
  113. css_value_length_px1 = Math.ceil(Math.random()) && '1px',
  114. css_value_length_px2 = Math.ceil(Math.random()) && '2px',
  115. css_value_length_px3 = Math.ceil(Math.random()) && '3px',
  116. css_value_length_px3p5 = Math.ceil(Math.random()) && '3.5px',
  117. css_value_length_px4 = Math.ceil(Math.random()) && '4px',
  118. css_value_length_px5 = Math.ceil(Math.random()) && '5px',
  119. css_value_length_px7 = Math.ceil(Math.random()) && '7px',
  120. css_value_length_px8 = Math.ceil(Math.random()) && '8px',
  121. css_value_length_px10 = Math.ceil(Math.random()) && '10px',
  122. css_value_length_px12 = Math.ceil(Math.random()) && '12px',
  123. css_value_length_px14 = Math.ceil(Math.random()) && '14px',
  124. css_value_length_px15 = Math.ceil(Math.random()) && '15px',
  125. css_value_length_px16 = Math.ceil(Math.random()) && '16px',
  126. css_value_length_px20 = Math.ceil(Math.random()) && '20px',
  127. css_value_length_px25 = Math.ceil(Math.random()) && '25px',
  128. css_value_length_px26 = Math.ceil(Math.random()) && '26px',
  129. css_value_length_px28 = Math.ceil(Math.random()) && '28px',
  130. css_value_length_px30 = Math.ceil(Math.random()) && '30px',
  131. css_value_length_px34 = Math.ceil(Math.random()) && '34px',
  132. css_value_length_px38 = Math.ceil(Math.random()) && '38px',
  133. css_value_length_px40 = Math.ceil(Math.random()) && '40px',
  134. css_value_length_px43 = Math.ceil(Math.random()) && '43px',
  135. css_value_length_px45 = Math.ceil(Math.random()) && '45px',
  136. css_value_length_px50 = Math.ceil(Math.random()) && '50px',
  137. css_value_length_px55 = Math.ceil(Math.random()) && '55px',
  138. css_value_length_px60 = Math.ceil(Math.random()) && '60px',
  139. css_value_length_px70 = Math.ceil(Math.random()) && '70px',
  140. css_value_length_px80 = Math.ceil(Math.random()) && '80px',
  141. css_value_length_px250 = Math.ceil(Math.random()) && '250px',
  142. css_value_length_px300 = Math.ceil(Math.random()) && '300px',
  143. css_value_length_px350 = Math.ceil(Math.random()) && '350px',
  144. css_value_length_px520 = Math.ceil(Math.random()) && '520px',
  145.  
  146. css_value_gradient_redblue = Math.ceil(Math.random()) && 'linear-gradient(to bottom, ' + css_value_color_800c + ' 0%, ' + css_value_color_f00c + ' 40%, ' + css_value_color_00fc + ' 60%, ' + css_value_color_008c + ' ' + css_value_length_perc100 + ')',
  147. css_value_gradient_gray = Math.ceil(Math.random()) && 'linear-gradient(to bottom, ' + css_value_color_888c + ' 0%, ' + css_value_color_fffc + ' 50%, ' + css_value_color_888c + ' ' + css_value_length_perc100 + ')',
  148.  
  149. css_value_random_solid = Math.ceil(Math.random()) && ' solid ',
  150.  
  151. css_value_border_3pxffff = Math.ceil(Math.random()) && css_value_length_px3 + css_value_random_solid + css_value_color_ffff,
  152. css_value_border_4pxffff = Math.ceil(Math.random()) && css_value_length_px4 + css_value_random_solid + css_value_color_ffff,
  153. css_value_border_35px000f = Math.ceil(Math.random()) && css_value_length_px3p5 + css_value_random_solid + css_value_color_000f,
  154. css_value_border_1px000f = Math.ceil(Math.random()) && css_value_length_px1 + css_value_random_solid + css_value_color_000f,
  155. css_value_border_2px000f = Math.ceil(Math.random()) && css_value_length_px2 + css_value_random_solid + css_value_color_000f,
  156. css_value_border_3px000f = Math.ceil(Math.random()) && css_value_length_px3 + css_value_random_solid + css_value_color_000f,
  157. css_value_border_4px000f = Math.ceil(Math.random()) && css_value_length_px4 + css_value_random_solid + css_value_color_000f,
  158.  
  159. css_value_misc_absolute = Math.ceil(Math.random()) && 'absolute',
  160. css_value_misc_bold = Math.ceil(Math.random()) && 'bold',
  161. css_value_misc_block = Math.ceil(Math.random()) && 'block',
  162. css_value_misc_center = Math.ceil(Math.random()) && 'center',
  163. css_value_misc_Consolas = Math.ceil(Math.random()) && 'Consolas',
  164. css_value_misc_flex = Math.ceil(Math.random()) && 'flex',
  165. css_value_misc_flexEnd = Math.ceil(Math.random()) && 'flex-end',
  166. css_value_misc_grid = Math.ceil(Math.random()) && 'grid',
  167. css_value_misc_none = Math.ceil(Math.random()) && 'none',
  168. css_value_misc_relative = Math.ceil(Math.random()) && 'relative',
  169. css_value_misc_row = Math.ceil(Math.random()) && 'row',
  170. css_value_misc_preWrap = Math.ceil(Math.random()) && 'pre-wrap',
  171. css_value_misc_scroll = Math.ceil(Math.random()) && 'scroll',
  172. css_value_misc_spaceBetween = Math.ceil(Math.random()) && 'space-between',
  173. css_value_misc_text = Math.ceil(Math.random()) && 'text',
  174. css_value_misc_inlineBlock = Math.ceil(Math.random()) && 'inline-block',
  175.  
  176. MOUSEEVENT_LEFT = 1,
  177. MOUSEEVENT_MIDDLE = 2,
  178. MOUSEEVENT_RIGHT = 3,
  179.  
  180. KEYPRESS_KEY_LEFT = 0,
  181. KEYPRESS_KEY_RIGHT = 1,
  182. KEYPRESS_KEY_UP = 2,
  183. KEYPRESS_KEY_DOWN = 3,
  184. KEYPRESS_KEY_RELOAD = 4,
  185.  
  186. KEYPRESS_STATE_OFF = 0,
  187. KEYPRESS_STATE_ON = 1,
  188.  
  189. SHIELD_RANGE = 45,
  190.  
  191. enumsCharDict = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_$',
  192.  
  193. ATTRIBUTE_USERNAMEHASH = enumsCharDict[0],
  194. ATTRIBUTE_PREVACCX = enumsCharDict[1],
  195. ATTRIBUTE_PREVACCY = enumsCharDict[2],
  196. ATTRIBUTE_ACCX = enumsCharDict[3],
  197. ATTRIBUTE_ACCY = enumsCharDict[4],
  198. ATTRIBUTE_HITBOX = enumsCharDict[5],
  199. ATTRIBUTE_HITBOXOFFSET = enumsCharDict[6],
  200. ATTRIBUTE_HITBOXRADIUS = enumsCharDict[7],
  201. ATTRIBUTE_HITBOXFORWARDOFFSET = enumsCharDict[8],
  202. ATTRIBUTE_BULLETCOLLISIONS = enumsCharDict[9],
  203. ATTRIBUTE_WIDTH = enumsCharDict[10],
  204. ATTRIBUTE_HEIGHT = enumsCharDict[11],
  205. ATTRIBUTE_PINGS = enumsCharDict[12],
  206. ATTRIBUTE_AVERAGEPING = enumsCharDict[13],
  207. ATTRIBUTE_MINPING = enumsCharDict[14],
  208. ATTRIBUTE_MAXPING = enumsCharDict[15],
  209. ATTRIBUTE_TIMEALIVEEXTRA = enumsCharDict[16],
  210. ATTRIBUTE_ISFROMCHEAT = enumsCharDict[17],
  211. ATTRIBUTE_TAGGEDNAME = enumsCharDict[18],
  212. ATTRIBUTE_USERNAME = enumsCharDict[19],
  213. ATTRIBUTE_SANITIZEDNAME = enumsCharDict[20],
  214. ATTRIBUTE_USABLEACCX = enumsCharDict[21],
  215. ATTRIBUTE_USABLEACCY = enumsCharDict[22],
  216. ATTRIBUTE_ENEMYFRIENDS = enumsCharDict[23],
  217. ATTRIBUTE_ENEMIES = enumsCharDict[24],
  218. ATTRIBUTE_PREVSPDX = enumsCharDict[25],
  219. ATTRIBUTE_PREVSPDY = enumsCharDict[26],
  220. ATTRIBUTE_USABLESPDX = enumsCharDict[27],
  221. ATTRIBUTE_USABLESPDY = enumsCharDict[28],
  222. ATTRIBUTE_ENEMY = enumsCharDict[29],
  223. ATTRIBUTE_DISTANCE = enumsCharDict[30],
  224. ATTRIBUTE_RADIUS = enumsCharDict[31],
  225. ATTRIBUTE_UPDATE = enumsCharDict[32],
  226. ATTRIBUTE_HPRADIUS = enumsCharDict[33],
  227. ATTRIBUTE_FILLHITBOX = enumsCharDict[34],
  228. ATTRIBUTE_MAKEHITBOX = enumsCharDict[35],
  229. ATTRIBUTE_DRAW = enumsCharDict[36],
  230. ATTRIBUTE_DRAWBODY = enumsCharDict[37],
  231. ATTRIBUTE_DRAWGUN = enumsCharDict[38],
  232.  
  233. KEYCODE_ESC = enumsCharDict[0],
  234. KEYCODE_A = enumsCharDict[1],
  235. KEYCODE_E = enumsCharDict[2],
  236. KEYCODE_D = enumsCharDict[3],
  237. KEYCODE_R = enumsCharDict[4],
  238. KEYCODE_S = enumsCharDict[5],
  239. KEYCODE_T = enumsCharDict[6],
  240. KEYCODE_W = enumsCharDict[7],
  241. KEYCODE_Z = enumsCharDict[8],
  242. KEYCODE_ENTER = enumsCharDict[9],
  243. KEYCODE_SPACE = enumsCharDict[10],
  244. KEYCODE_ARROWLEFT = enumsCharDict[11],
  245. KEYCODE_ARROWRIGHT = enumsCharDict[12],
  246. KEYCODE_ARROWUP = enumsCharDict[13],
  247. KEYCODE_ARROWDOWN = enumsCharDict[14],
  248. KEYCODE_N = enumsCharDict[15],
  249. KEYCODE_SHIFT = enumsCharDict[16],
  250. KEYCODE_CTRL = enumsCharDict[17],
  251.  
  252. INSTANTCHAT_CHATBINDS = enumsCharDict[0],
  253. INSTANTCHAT_CHATBINDSTEXTS = enumsCharDict[1],
  254. INSTANTCHAT_ONKILL = enumsCharDict[2],
  255. INSTANTCHAT_ONKILLTEXT = enumsCharDict[3],
  256. INSTANTCHAT_ONDEATH = enumsCharDict[4],
  257. INSTANTCHAT_ONDEATHTEXT = enumsCharDict[5],
  258. INSTANTCHAT_AUTOTHANK = enumsCharDict[6],
  259. INSTANTCHAT_AUTOTHANKTEXT = enumsCharDict[7],
  260.  
  261. AIMBOT_ENABLE = enumsCharDict[0],
  262. AIMBOT_AIMSMOOTHING = enumsCharDict[1],
  263. AIMBOT_CURSORMODE = enumsCharDict[2],
  264. AIMBOT_USEACCELERATION = enumsCharDict[3],
  265. AIMBOT_IGNORECHATTING = enumsCharDict[4],
  266. AIMBOT_PINGCOMPENSATION = enumsCharDict[5],
  267. AIMBOT_TRIGGERBOT = enumsCharDict[6],
  268. AIMBOT_WALLCHECK = enumsCharDict[7],
  269. AIMBOT_USEAHEAD = enumsCharDict[8],
  270. AIMBOT_DISABLEWHENDASHING = enumsCharDict[9],
  271. AIMBOT_CURSORPROXCOSENESS = enumsCharDict[10],
  272. AIMBOT_TARGETMODE = enumsCharDict[11],
  273. AIMBOT_TRIGGERBOTWHENDOWN = enumsCharDict[12],
  274. AIMBOT_RIGHTCLICKFRIEND = enumsCharDict[13],
  275. AIMBOT_AUXCLICKTARGET = enumsCharDict[14],
  276. AIMBOT_DROPDOWN_GENERAL = enumsCharDict[15],
  277. AIMBOT_DROPDOWN_ENHANCED = enumsCharDict[16],
  278. AIMBOT_DROPDOWN_CURSORPROX = enumsCharDict[17],
  279. AIMBOT_DROPDOWN_SMART = enumsCharDict[18],
  280. AIMBOT_DROPDOWN_PRIORITY = enumsCharDict[19],
  281. AIMBOT_DROPDOWN_TRIGGERBOT = enumsCharDict[20],
  282. AIMBOT_TARGETSONLY = enumsCharDict[21],
  283. AIMBOT_AVOIDFRIENDS = enumsCharDict[22],
  284. AIMBOT_AHEADNESSDEPTH = enumsCharDict[23],
  285. AIMBOT_LEADERMODE = enumsCharDict[24],
  286. AIMBOT_ACCAPPLYMULTIPLIER = enumsCharDict[25],
  287. AIMBOT_ACCTIMEMULTIPLIER = enumsCharDict[26],
  288.  
  289. ESP_ZOOM = enumsCharDict[0],
  290. ESP_FIXCAMERA = enumsCharDict[1],
  291. ESP_TRACERSBODYENEMY = enumsCharDict[2],
  292. ESP_TRACERSCURSORENEMY = enumsCharDict[3],
  293. ESP_TRACERSWALLCHECK = enumsCharDict[4],
  294. ESP_TRACERSGUN = enumsCharDict[5],
  295. ESP_TRACERSGRENADES = enumsCharDict[6],
  296. ESP_SHOWINVIS = enumsCharDict[7],
  297. ESP_REVEALTEAMS = enumsCharDict[8],
  298. ESP_SHOWHEALTH = enumsCharDict[9],
  299. ESP_SHOWARMOR = enumsCharDict[10],
  300. ESP_SHOWMAGS = enumsCharDict[11],
  301. ESP_SHOWGUNRELOADSTATUS = enumsCharDict[12],
  302. ESP_CAMUSEREALPOSITION = enumsCharDict[13],
  303. ESP_INCLUDEYOU = enumsCharDict[14],
  304. ESP_DROPDOWN_CAMERA = enumsCharDict[15],
  305. ESP_DROPDOWN_TRACERS = enumsCharDict[16],
  306. ESP_DROPDOWN_PLAYERSTATS = enumsCharDict[17],
  307. ESP_DROPDOWN_OTHER = enumsCharDict[18],
  308. ESP_SHOWRANGE = enumsCharDict[19],
  309. ESP_SCROLLSENSITIVITY = enumsCharDict[20],
  310.  
  311. CHATSPAMMER_TEXT = enumsCharDict[0],
  312. CHATSPAMMER_WIDTH = enumsCharDict[1],
  313. CHATSPAMMER_INTERVAL = enumsCharDict[2],
  314. CHATSPAMMER_DIRECTION = enumsCharDict[3],
  315. CHATSPAMMER_SEPERATOR = enumsCharDict[4],
  316. CHATSPAMMER_INDEX = enumsCharDict[5],
  317. CHATSPAMMER_TIMEOUT = enumsCharDict[6],
  318. CHATSPAMMER_PAUSEPERIOD = enumsCharDict[7],
  319. CHATSPAMMER_VARIATION = enumsCharDict[8],
  320. CHATSPAMMER_PREFIX = enumsCharDict[9],
  321. CHATSPAMMER_SUFFIX = enumsCharDict[10],
  322.  
  323. ANTIAIM_RELOAD = enumsCharDict[0],
  324. ANTIAIM_SHOOT = enumsCharDict[1],
  325. ANTIAIM_IDLE = enumsCharDict[2],
  326. ANTIAIM_ANGLESTART = enumsCharDict[3],
  327. ANTIAIM_ANGLERANGE = enumsCharDict[4],
  328. ANTIAIM_SPINSPEED = enumsCharDict[5],
  329. ANTIAIM_DELAY = enumsCharDict[6],
  330. ANTIAIM_SAVEDX = enumsCharDict[7],
  331. ANTIAIM_SAVEDY = enumsCharDict[8],
  332. ANTIAIM_DRAWREALAIM = enumsCharDict[9],
  333.  
  334. RECORDER_ISRECORDING = enumsCharDict[0],
  335. RECORDER_CURRENT = enumsCharDict[1],
  336. RECORDER_SESSIONS = enumsCharDict[2],
  337. RECORDER_ISPLAYING = enumsCharDict[3],
  338. RECORDER_TIMEOUT = enumsCharDict[4],
  339. RECORDER_SESSIONTOPLAY = enumsCharDict[5],
  340.  
  341. MISC_AUTORELOAD = enumsCharDict[0],
  342. MISC_PINGDISPLAY = enumsCharDict[1],
  343. MISC_RENDERDISPLAY = enumsCharDict[2],
  344. MISC_STATICHUD = enumsCharDict[3],
  345. MISC_STATICHEALTH = enumsCharDict[4],
  346. MISC_DISABLECLOSEPOPUP = enumsCharDict[5],
  347. MISC_BETTERCRATEHP = enumsCharDict[6],
  348. MISC_HIDECHATTING = enumsCharDict[7],
  349. MISC_FFACLANDISPLAY = enumsCharDict[8],
  350. MISC_SHOWFEATURES = enumsCharDict[9],
  351. MISC_DROPDOWN_INGAME = enumsCharDict[10],
  352. MISC_DROPDOWN_DEBUG = enumsCharDict[11],
  353. MISC_DROPDOWN_HUD = enumsCharDict[12],
  354. MISC_DROPDOWN_OTHER = enumsCharDict[13],
  355. MISC_POSITION = enumsCharDict[14],
  356. MISC_LEADERBOARDBADGES = enumsCharDict[15],
  357.  
  358. THNET_SOCKET = enumsCharDict[0],
  359. THNET_ENABLE = enumsCharDict[1],
  360. THNET_DISCONNECT = enumsCharDict[2],
  361. THNET_MEMBERS = enumsCharDict[3],
  362. THNET_CHAT = enumsCharDict[4],
  363. THNET_DONATE = enumsCharDict[5],
  364. THNET_ENTEROPENCHAT = enumsCharDict[6],
  365. THNET_AUTH = enumsCharDict[7],
  366. THNET_CLOSEREASON = enumsCharDict[8],
  367. THNET_INFOSHARE = enumsCharDict[9],
  368. THNET_INFOSHARING = enumsCharDict[10],
  369. THNET_BROTHERS = enumsCharDict[11],
  370.  
  371. ADVANCED_PINGCOUNT = enumsCharDict[0],
  372. ADVANCED_AIMCONSTANT = enumsCharDict[1],
  373. ADVANCED_TPS = enumsCharDict[2],
  374. ADVANCED_OPTIMISEWALLCHECK = enumsCharDict[3],
  375. ADVANCED_PINGCOMP = enumsCharDict[4],
  376.  
  377. PERKHACKS_KNIFE = enumsCharDict[0],
  378. PERKHACKS_KNIFEMAXRANGE = enumsCharDict[1],
  379. PERKHACKS_TICK = enumsCharDict[2],
  380. PERKHACKS_SHIELD = enumsCharDict[3],
  381. PERKHACKS_SHIELDUPKEEP = enumsCharDict[4],
  382. PERKHACKS_STOREDANGLE = enumsCharDict[5],
  383. PERKHACKS_SHIELDMANUAL = enumsCharDict[6],
  384. PERKHACKS_CRATEPLACEVISION = enumsCharDict[7],
  385. PERKHACKS_SHIELDLOOKAHEAD = enumsCharDict[8],
  386. PERKHACKS_MEDKITSELFHEAL = enumsCharDict[9],
  387. PERKHACKS_MEDKITSELFHEALTHRESHOLD = enumsCharDict[10],
  388. PERKHACKS_SHIELDVISUALISER = enumsCharDict[11],
  389. PERKHACKS_SHIELDWALLCHECK = enumsCharDict[12],
  390.  
  391. WEIRD_CURSORMOVE = enumsCharDict[0],
  392.  
  393. DISCORDRPC_ENABLED = enumsCharDict[0],
  394. DISCORDRPC_STATE = enumsCharDict[1],
  395. DISCORDRPC_DETAILS = enumsCharDict[2],
  396. DISCORDRPC_UPDATEINTERVAL = enumsCharDict[3],
  397. DISCORDRPC_START = enumsCharDict[4],
  398. DISCORDRPC_TIMEOUT = enumsCharDict[5],
  399. DISCORDRPC_CONNECTION = enumsCharDict[6],
  400. DISCORDRPC_TRIES = enumsCharDict[7],
  401. DISCORDRPC_ACCESSTOKEN = enumsCharDict[8],
  402. DISCORDRPC_CLIENTID = enumsCharDict[9],
  403. DISCORDRPC_EXPECTING = enumsCharDict[10],
  404.  
  405. PAINT_GRID = enumsCharDict[0],
  406. PAINT_GRIDSPACEX = enumsCharDict[1],
  407. PAINT_GRIDSPACEY = enumsCharDict[2],
  408. PAINT_GRIDLINEWIDTHHORIZONTAL = enumsCharDict[3],
  409. PAINT_GRIDLINEWIDTHVERTICAL = enumsCharDict[4],
  410. PAINT_GRIDCOLOR = enumsCharDict[6],
  411. PAINT_CRATES = enumsCharDict[7],
  412. PAINT_CRATESQUARE = enumsCharDict[8],
  413. PAINT_CRATELONG = enumsCharDict[9],
  414. PAINT_CRATEUSER = enumsCharDict[10],
  415. PAINT_CRATEPREMIUM = enumsCharDict[11],
  416. PAINT_CRATESHOWHPMODE = enumsCharDict[12],
  417. PAINT_POINTS = enumsCharDict[13],
  418. PAINT_POINTSIDLE = enumsCharDict[14],
  419. PAINT_POINTSFFA = enumsCharDict[15],
  420. PAINT_POINTSBLU = enumsCharDict[16],
  421. PAINT_POINTSRED = enumsCharDict[17],
  422. PAINT_POINTEDGEWIDTH = enumsCharDict[18],
  423. PAINT_CRATECORPSE = enumsCharDict[19],
  424. PAINT_PRESETMANAGER = enumsCharDict[20],
  425. PAINT_PRESETS = enumsCharDict[21],
  426.  
  427. MULTIBOX_SELECTEDSOCKET = enumsCharDict[0],
  428. MULTIBOX_SPAWNCLONE = enumsCharDict[1],
  429. MULTIBOX_INSTANTRESPAWN = enumsCharDict[2],
  430.  
  431. //database of guide entries
  432. //very incomplete, missing a lot of information
  433. guide = [[
  434. 'Menu',
  435.  
  436. 'Navigation',
  437. 'You can select any menu from the main menu by clicking on the menu\'s name.',
  438.  
  439. 'Back Button',
  440. 'You can return to the menu selection screen by clicking the back button at the top left corner.',
  441.  
  442. 'Toggling',
  443. 'You can toggle the menu to make it vanish or reappear by pressing (T) on your keyboard at any particular time.',
  444.  
  445. 'Scrolling',
  446. 'You can scroll in some menus by either using your mouse wheel or moving the scroll bar at the right side of the menu.',
  447.  
  448. 'Moving',
  449. 'You can drag the menu around by holding the title element.'
  450. ],[
  451. 'Settings',
  452.  
  453. 'Toggles and Values',
  454. 'You can toggle On/Off settings by simply clicking on them. You can change Value settings by clicking the [+] or [-] buttons next to them or by using your scroll wheel on the value display. To know what a setting does, hover over the setting, since most controls have tooltips added.',
  455.  
  456. 'Special Controls',
  457. 'Some menus use custom controls like text inputs, perk selection and more. Though most of those special controls don\'t need an introduction (as I think it is self explanatory enough, correct me if i\'m wrong), but for Auto Upgrade, you can click a perk you have already selected to unselect it.',
  458.  
  459. 'Empty Menus',
  460. 'Some menus (Recorder) don\'t have menu contents, which means they will be eventually added, probably...',
  461.  
  462. 'Imperfect Features',
  463. 'Some features may decrease your effectiveness or may cause other issues, please report the issues if that is the case.',
  464.  
  465. 'Saving',
  466. 'When you change any setting, it gets saved, which means if you reload, the settings won\'t be lost!'
  467. ],[
  468. 'Contact',
  469.  
  470. 'Discord',
  471. 'We have a discord where you can talk with fellow TioHax users and even the Developer himself! https://discord.gg/CwWd5UKf6R'
  472. ]],
  473.  
  474. credits = [[
  475. 'Developing',
  476. 'Main Developer of this Cheat Software',
  477. 'Taureon',
  478. 'For helping with technical stuff',
  479. 'Vaakir & Nitrogem35',
  480. 'Providing an API for the FFA Clan Display feature',
  481. 'Nitrogem35'
  482. ],[
  483. 'Playtesting',
  484. 'Finding dumb bugs and general playtesting',
  485. 'Ravgo'
  486. ],[
  487. 'Inspiration',
  488. 'Making my own Cheat Client',
  489. 'Vaakir',
  490. 'Providing me with moral justifications',
  491. 'GodF4ther, cat421, CrimAnn, SHTURM, DeadForYears and pretty much the rest of the Gats.io Community, you toxic idiots'
  492. ],[
  493. 'Special Thanks',
  494. 'You!',
  495. 'For using this cheat! Thank you so much!'
  496. ]],
  497.  
  498. //if the current enviroment is tampermonkey
  499. //isUserscript = typeof GM === 'object' || typeof GM_info === 'object',
  500.  
  501. //make sure closure compiler deals with that aswell
  502. ctx = j58,
  503.  
  504. undefVar = Math.ceil(Math.random()) && undefined,
  505.  
  506. //used to make math easier to read
  507. {
  508. PI, abs, asin, atan2,
  509. ceil, cos, floor, max,
  510. min, random, round, sign,
  511. sin, sqrt, E
  512. } = Math,
  513. TAU = PI * 2,
  514. degToRad = TAU / 360,
  515. mathSin = sin(degToRad * 60),
  516. third = 1 / 3,
  517.  
  518. nullPos = {x: 0, y: 0},
  519.  
  520. idRefreshMenu = 0,
  521.  
  522. //hash of the developer's ign
  523. //this is 'TheS3xHaver' but hashed with hashString() function
  524. developerHash = -1599485949,
  525.  
  526. homeUrl = 's://cheats.gatsio.repl.co/',
  527.  
  528. //time it took to render a frame
  529. renderTime = 0,
  530.  
  531. //how many ticks the main function has ran for
  532. tickCount = 0,
  533.  
  534. chatBoxRandom,
  535.  
  536. //turning armor names into indexes
  537. armorMap = {
  538. noArmor: 0,
  539. lightArmor: 1,
  540. mediumArmor: 2,
  541. heavyArmor: 3
  542. },
  543.  
  544. //turning gun names to indexes
  545. gunMap = {
  546. pistol: 0,
  547. smg: 1,
  548. shotgun: 2,
  549. assault: 3,
  550. sniper: 4,
  551. lmg: 5,
  552. 'bolt-action-rifle': 4,
  553. 'machine-gun': 5
  554. },
  555.  
  556. //turning gun indexes into gun displaynames
  557. gunNames = ['Pistol', 'SMG', 'Shotgun', 'Assault', 'Sniper', 'LMG'],
  558.  
  559. //6 = knife
  560. //7 = shield
  561.  
  562. //bullet velocities of guns
  563. velocities = [24, 22, 24, 24, 30, 24, 7, Infinity],
  564.  
  565. //bullet spawn offsets based on gun lengths
  566. offsets = [44, 50, 55, 63, 75, 62, 0, 0],
  567.  
  568. //how far each bullet travels
  569. ranges = [18, 13, 10, 18, 22, 16, 32, Infinity],
  570.  
  571. //stupidness
  572. textBoxFocused = 0,
  573.  
  574. gunMinRange = 0,
  575.  
  576. //cursor position that is independent of the game
  577. cursor = {x: 0, y: 0, isPressed: 0, isShooting: 0},
  578.  
  579. highestZIndex = 3,
  580.  
  581. movableWindows = [],
  582.  
  583. clanTagCache = {},
  584.  
  585. menuNames = [
  586. '', 'Guide', 'Menu', 'Aimbot',
  587. 'ESP', 'Instant Chat', 'Misc', 'Player Manager',
  588. 'Auto Upgrades', 'Chat Spammer', 'Anti Aim', 'Perk Hacks',
  589. 'Paint', 'Recorder', 'Discord Rich Presence', 'THNet',
  590. 'Weird', 'Advanced', 'Credits'
  591. ],
  592.  
  593. aimbotLabel = {
  594. [AIMBOT_ENABLE]: [ 'Enable Aimbot', 'Automatically aims your weapon at enemies, toggleable with right click.'],
  595. [AIMBOT_AIMSMOOTHING]: [ 'Aim Smoothing', 'Makes aimbot\'s movement smoother.'],
  596. [AIMBOT_CURSORMODE]: [ 'Enable', 'Whichever is closest to your cursor.'],
  597. [AIMBOT_USEACCELERATION]: [ 'Use Acceleration', 'Tries to account for the enemy\'s velocity changes.'],
  598. [AIMBOT_IGNORECHATTING]: [ 'Ignore Chatting', 'Ignores players who are typing.'],
  599. [AIMBOT_PINGCOMPENSATION]: [ 'Ping Compensation', 'Tries to compensate for the internet connection.'],
  600. [AIMBOT_TRIGGERBOT]: [ 'Enable', 'Shoots automatically when possible, requires Wall Check to be enabled (not recommended with single fire weapons.)'],
  601. [AIMBOT_WALLCHECK]: [ 'Wall Check', 'Tries to not aim at enemies behind walls.'],
  602. [AIMBOT_USEAHEAD]: [ 'Use Ahead Check', 'Use the position of where the enemy will be for wall check instead of where they are right now.'],
  603. [AIMBOT_DISABLEWHENDASHING]: [ 'Dash Disable', 'Turns aimbot temporarily off when dashing.'],
  604. [AIMBOT_CURSORPROXCOSENESS]: [ 'Range', 'How close an enemy needs to be to be targetted by the aimbot when in Cursor Proximity mode.'],
  605. [AIMBOT_TARGETMODE]: [ 'Prioritise Targets', 'Prioritises targetted players over anything when applicable.'],
  606. [AIMBOT_TRIGGERBOTWHENDOWN]: [ 'When Mouse Down', 'Triggerbot fires only when you shoot, suppresses manual firing when this and Triggerbot is enabled.'],
  607. [AIMBOT_RIGHTCLICKFRIEND]: [ 'Rightclick Friend', 'When you Rightclick on someone, it adds them to the friends list.'],
  608. [AIMBOT_AUXCLICKTARGET]: [ 'Middleclick Target', 'When you Middleclick on someone (Mouse-wheel when you press on it), it adds them to the targets list.'],
  609. [AIMBOT_TARGETSONLY]: [ 'Targets Only', 'Ignores people you aren\'t targetting.'],
  610. [AIMBOT_AVOIDFRIENDS]: [ 'Avoid Friends (WIP)', 'Avoids shooting at an enemy if it would be too risky for a friend on the enemy team to get hit. THIS IS IN BETA, MAY RESULT IN UNINTENDED CONSEQUENCES.'],
  611. [AIMBOT_AHEADNESSDEPTH]: [ 'Ahead Calc Depth', 'The accuracy of the calculation that checks how far ahead the aimbot should aim.'],
  612. [AIMBOT_LEADERMODE]: [ 'Prioritise Leader', 'Prioritises the top scoring player if they are on the enemy team. This takes priority over the \'Prioritise Targets\' setting.'],
  613. [AIMBOT_DROPDOWN_GENERAL]: [ 'General', '' ],
  614. [AIMBOT_DROPDOWN_ENHANCED]: [ 'Enhancements', '' ],
  615. [AIMBOT_DROPDOWN_CURSORPROX]: [ 'Cursor Proximity', '' ],
  616. [AIMBOT_DROPDOWN_SMART]: [ 'Smarter Targeting', '' ],
  617. [AIMBOT_DROPDOWN_PRIORITY]: [ 'Priority', '' ],
  618. [AIMBOT_DROPDOWN_TRIGGERBOT]: [ 'Triggerbot', '' ]
  619. },
  620.  
  621. espLabel = {
  622. [ESP_ZOOM]: [ 'Extended View', 'Gives you maximum possible vision', ],
  623. [ESP_FIXCAMERA]: [ 'Fixed Camera', 'Stops the camera from moving', ],
  624. [ESP_TRACERSBODYENEMY]: [ 'Player Tracers', 'Draws a line from you to every player currently loaded in' ],
  625. [ESP_TRACERSCURSORENEMY]: [ 'CursorProx Tracers', 'When Cursor Proximity is enabled, draws lines from your cursor to your enemies' ],
  626. [ESP_TRACERSWALLCHECK]: [ 'Wall Check Tracers', 'Visualises the wall checking algorithm' ],
  627. [ESP_TRACERSGUN]: [ 'Gun Tracers', 'Draws the line a bullet would go if you shot your gun' ],
  628. [ESP_TRACERSGRENADES]: [ 'Grenade Tracers', 'Draws a line to where a grenade is to where the grenade will roughly land at' ],
  629. [ESP_SHOWINVIS]: [ 'Show Invisibles', 'Shows silencers, camo players and landmines', ],
  630. [ESP_REVEALTEAMS]: [ 'Reveal Teams', 'Reveals the team affiliations for grenades, landmines, gas and knifes', ],
  631. [ESP_SHOWHEALTH]: [ 'Healths', 'Shows every players\' current health', ],
  632. [ESP_SHOWARMOR]: [ 'Armors', 'Shows every players\' current armor', ],
  633. [ESP_SHOWMAGS]: [ 'Magazines', 'Shows every players\' current ammo counts', ],
  634. [ESP_SHOWGUNRELOADSTATUS]: [ 'Gun Reload', 'Shows every player\'s current gun reloading status with a percentage.', ],
  635. [ESP_SHOWRANGE]: [ 'Ranges', 'Shows how far players can shoot (may cause the game to look like a clusterfuck)' ],
  636. [ESP_CAMUSEREALPOSITION]: [ 'Camera Cursor Fix', 'When Aimbot is on, this makes the Camera follow your Cursor, and not where the Aimbot tells the game where the Cursor is' ],
  637. [ESP_INCLUDEYOU]: [ 'Self Attributes', 'Makes Player Healths, Player Armors, Player Magazines and Player Gun Status draw over you aswell' ],
  638. [ESP_SCROLLSENSITIVITY]: [ 'Zoom Sensitivity', 'When the \'Extended View\' mode is on \'Scroll\', this determines how much you zoom in and out when you use the scroll wheel' ],
  639. [ESP_DROPDOWN_CAMERA]: [ 'Camera', 'Various Camera Improvement Settings' ],
  640. [ESP_DROPDOWN_TRACERS]: [ 'Tracers', 'Some Lines and Circles' ],
  641. [ESP_DROPDOWN_PLAYERSTATS]: [ 'Player Attributes', 'Helpful Attributes of nearby Players' ],
  642. [ESP_DROPDOWN_OTHER]: [ 'Other', 'Other ESP Features' ]
  643. },
  644.  
  645. autoUpgradesLabel = [
  646. [ 'Auto Upgrade', 'Automatically upgrades specified perks for you' ],
  647. 'No Perk Selected'
  648. ],
  649.  
  650. scrollerLabel = {
  651. 0: [ 'Toggle Scroller', 'Turn the Chat Scroller either On or Off' ],
  652. [CHATSPAMMER_WIDTH]: [ 'Text Width', 'Maximum width of the scrolled text' ],
  653. [CHATSPAMMER_DIRECTION]: [ 'Direction', 'In which direction the text scrolls (- = left, + = right)' ],
  654. [CHATSPAMMER_INTERVAL]: [ 'Interval', 'The interval it takes for the text to shift' ],
  655. [CHATSPAMMER_PAUSEPERIOD]: [ 'Pause Period', 'When something besides the Scroller has said something in chat, for how long it should wait before it should scroll again' ],
  656. [CHATSPAMMER_TEXT]: [ 'Text', 'The Text to scroll in Chat' ],
  657. [CHATSPAMMER_SEPERATOR]: [ 'Seperator', 'The Seperator so it does not look like \'hello worldhello worldhello world\'' ],
  658. [CHATSPAMMER_PREFIX]: [ 'Prefix', 'Static text to add in front of your chat message' ],
  659. [CHATSPAMMER_SUFFIX]: [ 'Sufffix', 'Static text to add after your chat message' ]
  660. },
  661.  
  662. instantchatLabel = {
  663. 0: 'Change the text you say when you press a key',
  664. [INSTANTCHAT_CHATBINDS]: [ 'Chat Binds', 'Press buttons to make the cheat instantly say something in chat for you', ],
  665. [INSTANTCHAT_CHATBINDSTEXTS]: [ 'Edit Binds', 'Select a button on your keyboard to make the cheat say LITERALLY ANYTHING for you' ],
  666. [INSTANTCHAT_ONKILL]: [ 'On Kill Chat Msg', 'Say something when you kill someone', ],
  667. [INSTANTCHAT_ONKILLTEXT]: [ '', 'Change the text you say when you kill someone' ],
  668. [INSTANTCHAT_ONDEATH]: [ 'On Death Chat Msg', 'Say something when you die', ],
  669. [INSTANTCHAT_ONDEATHTEXT]: [ '', 'Change the text you say when you die' ],
  670. [INSTANTCHAT_AUTOTHANK]: [ 'Auto Medkit Thank', 'Instantly say thanks when you get healed', ],
  671. [INSTANTCHAT_AUTOTHANKTEXT]: [ '', 'Change the text you say when you get healed' ]
  672. },
  673.  
  674. antiAimLabel = {
  675. [ANTIAIM_RELOAD]: [ 'While Reloading', 'To hide aim while reloading your gun' ],
  676. [ANTIAIM_SHOOT]: [ 'While Shooting', 'To hide aim while shooting your gun' ],
  677. [ANTIAIM_IDLE]: [ 'While Idle', 'To hide wim while neither shooting or reloading your gun (not recommended with single fire weapons)' ],
  678. [ANTIAIM_ANGLESTART]: [ 'Min Angle', 'Minimum Angle where it starts off' ],
  679. [ANTIAIM_ANGLERANGE]: [ 'Angle Range', 'Random additional angle from 0 to the angle range which gets added on the Minimum Angle' ],
  680. [ANTIAIM_SPINSPEED]: [ 'Spin Speed', 'How fast it spins. Accepts negative numbers if you want it to spin the other direction' ],
  681. [ANTIAIM_DELAY]: [ 'Interval', 'The amount of time (in game ticks) at which it picks another position to aim at' ],
  682. [ANTIAIM_DRAWREALAIM]: [ 'Draw Real Aim', 'Draws the gun a second time as if Anti Aim wasn\'t enabled' ]
  683. },
  684.  
  685. miscLabel = {
  686. [MISC_AUTORELOAD]: [ 'Auto Reload', 'Automatically reloads when there are no enemies nearby', ],
  687. [MISC_PINGDISPLAY]: [ 'Ping Display', 'Displays the latency to the server', ],
  688. [MISC_RENDERDISPLAY]: [ 'FPS & Render Time', 'Displays your current FPS and how long it took to render the last frame', ],
  689. [MISC_STATICHUD]: [ 'Static Hud', 'Disables hud animations', ],
  690. [MISC_STATICHEALTH]: [ 'Static Health', 'Disables the hp moving animations on players when they take damage', ],
  691. [MISC_DISABLECLOSEPOPUP]: [ 'No Unload Popup', 'Disable the unload popup when you leave or reload the game' ],
  692. [MISC_BETTERCRATEHP]: [ 'Better Crate HP', 'Makes the health display pick colors better instead of just picking one of 5 colors' ],
  693. [MISC_HIDECHATTING]: [ 'Hide Chatbox', 'Others won\'t see that you\'re typing, they\'ll just see you not move' ],
  694. [MISC_FFACLANDISPLAY]: [ 'FFA Clan Tags', 'Shows clan tags next to names in FFA Mode' ],
  695. [MISC_SHOWFEATURES]: [ 'Feature Display', 'Shows what main features are enabled in the bottom right corner' ],
  696. [MISC_POSITION]: [ 'Coordinates', 'Shows your coordinates, velocity and acceleration' ],
  697. [MISC_LEADERBOARDBADGES]: [ 'Leaderboard Badges', 'Shows Friends, Targets, THNet members and the dev with badges next to their leaderboard' ],
  698. [MISC_DROPDOWN_INGAME]: [ 'In Game', 'Gameplay related settings' ],
  699. [MISC_DROPDOWN_DEBUG]: [ 'Debug', 'Special Technical Information' ],
  700. [MISC_DROPDOWN_HUD]: [ 'Heads Up Display', 'HUD-related settings' ],
  701. [MISC_DROPDOWN_OTHER]: [ 'Other', 'Settings that have no category of their own' ]
  702. },
  703.  
  704. playerManagerLabel = [[
  705. 'Friends',
  706. 'Switch to the list of ignored enemies'
  707. ],[
  708. 'Targets',
  709. 'Switch to the list of prioritised targets'
  710. ],[
  711. 'Muted',
  712. 'Switch to the list of muted players'
  713. ],[
  714. 'Add a friend',
  715. 'Add a target',
  716. 'Mute someone'
  717. ]],
  718.  
  719. advancedLabel = {
  720. 0: [ 'Disconnect', 'Disconnect from the current server' ],
  721. 1: [ 'Clear Bootloader', 'Clears the stored code and version of the bootloader' ],
  722. 2: [ 'Clear TioHax', 'Clears the settings and configutations, and resets them to factory defaults.' ],
  723. [ADVANCED_PINGCOUNT]: [ 'Ping Cache', 'How many recent ping times it stores' ],
  724. [ADVANCED_AIMCONSTANT]: [ 'Aim Constant', 'Lower = Aimbot aims further ahead' ],
  725. [ADVANCED_PINGCOMP]: [ 'Account for ping', 'How far the aimbot aims ahead depending on the ping. lower = further' ],
  726. [ADVANCED_TPS]: [ 'Sync TPS with Server', 'Makes the game run at 25 ticks per second instead of 62.5' ],
  727. [ADVANCED_OPTIMISEWALLCHECK]: [ 'Optimise Wallcheck', 'Optimises the checking for the wall checking algorithm' ]
  728. },
  729.  
  730. perkHacksLabel = {
  731. 0: [ 'KnifeBot (WIP)', 'Automatically shoots a knife at very near enemies' ],
  732. 1: [ 'ShieldBot (WIP)', 'Automatically blocks nearby bullets' ],
  733. 2: [ 'Medkit and Build (WIP)', 'Gives tools for using Medkit and Build perks' ],
  734.  
  735. [PERKHACKS_KNIFE]: [ 'Enable', 'Automatically shoots a knife at a close enemy' ],
  736. [PERKHACKS_KNIFEMAXRANGE]: [ 'Range', 'How close an enemy needs to be to be knifed' ],
  737.  
  738. [PERKHACKS_SHIELD]: [ 'Enable', 'Automatically block nearby bullets' ],
  739. [PERKHACKS_SHIELDUPKEEP]: [ 'Takedown delay', 'How long (in ticks) the shield should be up for even when the bullet is deflected' ],
  740. [PERKHACKS_SHIELDMANUAL]: [ 'Manual Ability', 'Does not take control over your ability to use the shield, but still aims torwards close bullets for you' ],
  741. [PERKHACKS_SHIELDLOOKAHEAD]: [ 'Lookahead', 'Tries to block incoming bullets earlier the higher this value is' ],
  742. [PERKHACKS_SHIELDVISUALISER]: [ 'Visualiser', 'For debugging purposes, visualises the check that the ShieldBot does.' ],
  743. [PERKHACKS_SHIELDWALLCHECK]: [ 'Wall Check', 'Only tries to block bullets that would have to go through crates.' ],
  744.  
  745. [PERKHACKS_CRATEPLACEVISION]: [ 'Placement Vision', 'Where exactly the build block or medkit will be placed when Build or Medkit is used' ],
  746. [PERKHACKS_MEDKITSELFHEAL]: [ 'Auto Self Heal', 'Automatically puts the Medkit in front of you if you\'re below a certain health threshold' ],
  747. [PERKHACKS_MEDKITSELFHEALTHRESHOLD]: [ 'Threshold', 'The health threshold that says when to heal yourself. If your health is lower, it heals' ]
  748. },
  749.  
  750. THNetLabel = {
  751. 0: [ 'THNet Rules', 'Rules you have to follow when using THNet' ],
  752. 1: [
  753. 'Don\'t kill other THNet members, the point is to make THNet work with each other.',
  754. 'Don\'t spam THNet Chat with garbage, else it drowns out good messages.',
  755. 'Don\'t be mean to others in THNet Chat, it does not make you a good person.'
  756. ],
  757. [THNET_ENABLE]: [ 'Connect', 'Connects to THNet when you join a server, bringing a variety of features' ],
  758. [THNET_DISCONNECT]: [ 'Disconnect', 'Disconnect from THNet, your Aimbot will shoot at them but their Aimbots will also shoot you' ],
  759. [THNET_MEMBERS]: [ 'THNet Members', 'The List of THNet Members in your current lobby' ],
  760. [THNET_CHAT]: [ 'Serverwide Chat', 'Chat with all other THNet members in your current server without needing to be close' ],
  761. [THNET_DONATE]: [ 'Donate Connection', 'Donate an unused Game Connection to Taureon for a Botnet which will assist you' ],
  762. [THNET_AUTH]: [ 'THNet Admin Authentication', 'Authentication Code Input Box for THNet Administrators' ],
  763. [THNET_INFOSHARE]: [ 'Share Gameplay Info', 'Shares health, position, ammo count and class with other members' ]
  764. },
  765.  
  766. weirdLabel = {
  767. [WEIRD_CURSORMOVE]: [ 'Move with Cursor', 'You will move to where your cursor is' ]
  768. },
  769.  
  770. discordRPCLabel = {
  771. [DISCORDRPC_ENABLED]: [ 'Enable', 'Makes the Rich Presence show up on your Discord Profile' ],
  772. [DISCORDRPC_STATE]: [ 'State', 'First line below the Presence Title' ],
  773. [DISCORDRPC_DETAILS]: [ 'Details', 'Line below the State Line' ],
  774. [DISCORDRPC_UPDATEINTERVAL]: [ 'Update Interval', 'In seconds, how often it updates' ]
  775. },
  776.  
  777. paintLabel = {
  778. 0: [ 'Reset Colors/Values', 'Resets every change back to default'],
  779. 1: [ 'ARE YOU SURE that you want to reset everything you have changed in Paint?', 'Type exactly \'yes\' if yes' ],
  780.  
  781. [PAINT_GRID]: [ 'Grid', 'Change the look of the floor' ],
  782. [PAINT_POINTS]: [ 'Capture Points', 'Change the look of capture points' ],
  783. [PAINT_CRATES]: [ 'Crates', 'Change the look of crates on the map' ],
  784.  
  785. [PAINT_GRIDSPACEX]: [ 'Horiz. Space', 'The horizontal space between the grid lines' ],
  786. [PAINT_GRIDSPACEY]: [ 'Vert. Space', 'The vertical space between the grid lines' ],
  787. [PAINT_GRIDLINEWIDTHHORIZONTAL]: [ 'Hori. Line Width', 'Width of the lines that go horizontally' ],
  788. [PAINT_GRIDLINEWIDTHVERTICAL]: [ 'Vert. Line Width', 'Width of the lines that go vertically' ],
  789. [PAINT_GRIDCOLOR]: [ 'Grid Color', 'The color of the Grid' ],
  790.  
  791. [PAINT_POINTSIDLE]: [ 'No One Capturing', 'The color if no one is capturing the point' ],
  792. [PAINT_POINTSFFA]: [ 'FFA You Capturing', 'The color if you are capturing the point' ],
  793. [PAINT_POINTSBLU]: [ 'Blue Capturing', 'The color if the blue team is capturing the point' ],
  794. [PAINT_POINTSRED]: [ 'Red Capturing', 'The color if the red team is capturing the point' ],
  795. [PAINT_POINTEDGEWIDTH]: [ 'Edge Width', 'How wide the edges of the capture points should be' ],
  796.  
  797. [PAINT_CRATESHOWHPMODE]: [ 'Health Display', 'Change which parts should turn white when build crates get damaged' ],
  798. [PAINT_CRATESQUARE]: [ 'Square Crates', 'The large square-shaped crates' ],
  799. [PAINT_CRATELONG]: [ 'Long Crates', 'The smaller rectangle-shaped crates' ],
  800. [PAINT_CRATEUSER]: [ 'Build Crates', 'The crates made with the Build perk' ],
  801. [PAINT_CRATEPREMIUM]: [ 'Premium Crates', 'Build crates but built by Premium Users' ],
  802. [PAINT_CRATECORPSE]: [ 'Crate Corpses', 'The colors the crate takes on as its Health decreases' ],
  803.  
  804. [PAINT_PRESETMANAGER]: [ 'Preset Manager', 'Manage Paint Presets. Save, Load, Export, Import and Name Presets' ]
  805. },
  806.  
  807. controlDropdownOptions = [
  808. [
  809. [ 'Normal', 'Normal Game View' ],
  810. [ 'Scroll', 'Use your scroll wheel to change how much you can see' ],
  811. [ 'Static', 'Automatically zooms out to the most possible you can see' ]
  812. ], [
  813. [ 'None', 'Crate colors do not change' ],
  814. [ 'Edges', 'Only the crate\'s edge changes' ],
  815. [ 'Inside', 'Only the inside of the crate changes' ],
  816. [ 'Both', 'Entire crate changes' ]
  817. ], [
  818. [ 'Disabled', 'No Display for what Main Features are enabled' ],
  819. [ 'Enabled', 'Main Features get displayed in the bottom right corner' ],
  820. [ 'Graytext', 'Subsettings are shown in Gray Colors instead of Rainbow' ]
  821. ], [
  822. [ 'None', 'No ShieldBot check visualisers' ],
  823. [ 'Closeness', 'The circle inside a bullet needs to be in' ],
  824. [ 'Bullets', 'Draws small arrows to see how far ahead it predicts the bullets to be' ],
  825. [ 'Both', 'Shows both Bullets and Closeness' ]
  826. ]
  827. ],
  828.  
  829. menuLabel = [
  830. 'Minimise the Menu, can be reopened by pressing T',
  831. 'Return back to the previous menu',
  832. 'Close THNet chat, can be reopened by pressing CTRL',
  833. 'TioHax Cheat Menu',
  834. 'THNet Serverwide Chat'
  835. ],
  836.  
  837. loadedLocalisation = {},
  838.  
  839. //for if the player has made friends on the enemy team
  840. friends = [],
  841.  
  842. //for if the player wants to really kill someone
  843. targets = [],
  844.  
  845. //muted players who you don't want to hear text from
  846. muted = [],
  847.  
  848. //0 = friends
  849. playermanagerSelectedMenu = 0,
  850.  
  851. //the divs that make up the cheat menu
  852. divs = {
  853. menu: 0,
  854. title: 0,
  855. chatbox: 0,
  856. content: 0,
  857. chatwrap: 0,
  858. chatinput: 0,
  859. backbutton: 0
  860. },
  861.  
  862. //selected perk slot for auto upgrade menu
  863. selectedPerkSlot = 1,
  864.  
  865. //alternate chat bind messages so we don't get kicked for spam
  866. lastMessageLength = 0,
  867.  
  868. //key code map
  869. // http://www.foreui.com/articles/Key_Code_Table.htm
  870. keyCodeMap = {
  871. [KEYCODE_ESC]: 27, [KEYCODE_A]: 65, [KEYCODE_E]: 69,
  872. [KEYCODE_D]: 68, [KEYCODE_R]: 82, [KEYCODE_S]: 83,
  873. [KEYCODE_T]: 84, [KEYCODE_W]: 87, [KEYCODE_Z]: 90,
  874. [KEYCODE_ENTER]: 13, [KEYCODE_SPACE]: 32, [KEYCODE_ARROWLEFT]: 37,
  875. [KEYCODE_ARROWRIGHT]: 39, [KEYCODE_ARROWUP]: 38, [KEYCODE_ARROWDOWN]: 40,
  876. [KEYCODE_N]: 78, [KEYCODE_SHIFT]: 16, [KEYCODE_CTRL]: 17,
  877. },
  878.  
  879. autoUpgrades = [0, '', '', ''],
  880.  
  881. perks = [
  882. 'bipod', 'optics', 'thermal',
  883. 'armorPiercing', 'extended', 'grip',
  884. 'silencer', 'lightweight', 'longRange',
  885. 'thickSkin'
  886. ],
  887. abilities = [
  888. 'shield', 'firstAid', 'grenade',
  889. 'knife', 'engineer', 'ghillie',
  890. 'dash', 'gasGrenade', 'landMine',
  891. 'fragGrenade'
  892. ],
  893.  
  894. perkNames = {
  895. 'bipod': 'No Recoil',
  896. 'optics': 'Binoculars',
  897. 'thermal': 'Thermal',
  898. 'armorPiercing': 'Damage',
  899. 'extended': 'Large Mags',
  900. 'grip': '+Accuracy',
  901. 'silencer': 'Silencer',
  902. 'lightweight': 'Speed',
  903. 'longRange': 'Range',
  904. 'thickSkin': 'Kevlar',
  905. 'shield': 'Shield',
  906. 'firstAid': 'Medkit',
  907. 'grenade': 'Grenade',
  908. 'knife': 'Knife',
  909. 'engineer': 'Build',
  910. 'ghillie': 'Camo',
  911. 'dash': 'Dash',
  912. 'gasGrenade': 'Gas',
  913. 'landMine': 'Landmine',
  914. 'fragGrenade': 'Frag'
  915. },
  916.  
  917. aimbot = {
  918. [AIMBOT_ENABLE]: 0,
  919. [AIMBOT_AIMSMOOTHING]: 0,
  920. [AIMBOT_CURSORMODE]: 0,
  921. [AIMBOT_CURSORPROXCOSENESS]: 200,
  922. [AIMBOT_USEACCELERATION]: 0,
  923. [AIMBOT_IGNORECHATTING]: 0,
  924. [AIMBOT_PINGCOMPENSATION]: 0,
  925. [AIMBOT_WALLCHECK]: 0,
  926. [AIMBOT_USEAHEAD]: 0,
  927. [AIMBOT_DISABLEWHENDASHING]: 0,
  928. [AIMBOT_TRIGGERBOT]: 0,
  929. [AIMBOT_TRIGGERBOTWHENDOWN]: 0,
  930. [AIMBOT_TARGETMODE]: 0,
  931. [AIMBOT_RIGHTCLICKFRIEND]: 1,
  932. [AIMBOT_AUXCLICKTARGET]: 1,
  933. [AIMBOT_AVOIDFRIENDS]: 0,
  934. [AIMBOT_AHEADNESSDEPTH]: 0,
  935. [AIMBOT_LEADERMODE]: 0
  936. },
  937.  
  938. esp = {
  939. [ESP_ZOOM]: 0,
  940. [ESP_FIXCAMERA]: 0,
  941. [ESP_CAMUSEREALPOSITION]: 0,
  942. [ESP_TRACERSBODYENEMY]: 0,
  943. [ESP_TRACERSCURSORENEMY]: 0,
  944. [ESP_TRACERSWALLCHECK]: 0,
  945. [ESP_TRACERSGUN]: 0,
  946. [ESP_TRACERSGRENADES]: 0,
  947. [ESP_SHOWINVIS]: 0,
  948. [ESP_REVEALTEAMS]: 0,
  949. [ESP_SHOWHEALTH]: 0,
  950. [ESP_SHOWARMOR]: 0,
  951. [ESP_SHOWMAGS]: 0,
  952. [ESP_SHOWGUNRELOADSTATUS]: 0,
  953. [ESP_SHOWRANGE]: 0,
  954. [ESP_INCLUDEYOU]: 0,
  955. [ESP_SCROLLSENSITIVITY]: 1.1
  956. },
  957.  
  958. chatSpam = {
  959. [CHATSPAMMER_TEXT]: 'TioHax on top! http' + homeUrl,
  960. [CHATSPAMMER_INDEX]: 0,
  961. [CHATSPAMMER_WIDTH]: 30,
  962. [CHATSPAMMER_TIMEOUT]: 0,
  963. [CHATSPAMMER_INTERVAL]: 100,
  964. [CHATSPAMMER_VARIATION]: 0,
  965. [CHATSPAMMER_DIRECTION]: 1,
  966. [CHATSPAMMER_SEPERATOR]: ' # ',
  967. [CHATSPAMMER_PAUSEPERIOD]: 3000,
  968. [CHATSPAMMER_PREFIX]: '',
  969. [CHATSPAMMER_SUFFIX]: ''
  970. },
  971.  
  972. instantchat = {
  973. [INSTANTCHAT_ONKILL]: 0,
  974. [INSTANTCHAT_ONKILLTEXT]: '[[ENEMY]] just died to TioHax!',
  975. [INSTANTCHAT_ONDEATH]: 0,
  976. [INSTANTCHAT_ONDEATHTEXT]: '[[ENEMY]] = god awful',
  977. [INSTANTCHAT_AUTOTHANK]: 0,
  978. [INSTANTCHAT_AUTOTHANKTEXT]: 'I have been healed! Thank you!',
  979. [INSTANTCHAT_CHATBINDS]: 0,
  980. [INSTANTCHAT_CHATBINDSTEXTS]: {
  981. [keyCodeMap[KEYCODE_E]]: 'I need a medic!' ,
  982. [keyCodeMap[KEYCODE_Z]]: 'Put Build Blocks here!'
  983. }
  984. },
  985.  
  986. antiAim = {
  987. [ANTIAIM_RELOAD]: 0,
  988. [ANTIAIM_SHOOT]: 0,
  989. [ANTIAIM_IDLE]: 0,
  990. [ANTIAIM_ANGLESTART]: 0,
  991. [ANTIAIM_ANGLERANGE]: 0,
  992. [ANTIAIM_SPINSPEED]: 0,
  993. [ANTIAIM_DELAY]: 1,
  994. [ANTIAIM_SAVEDX]: 0,
  995. [ANTIAIM_SAVEDY]: 0
  996. },
  997.  
  998. recorder = {
  999. [RECORDER_ISRECORDING]: 0,
  1000. [RECORDER_ISPLAYING]: 0,
  1001. [RECORDER_CURRENT]: [],
  1002. [RECORDER_SESSIONS]: [],
  1003. [RECORDER_TIMEOUT]: 0,
  1004. [RECORDER_SESSIONTOPLAY]: -1
  1005. },
  1006.  
  1007. misc = {
  1008. [MISC_AUTORELOAD]: 0,
  1009. [MISC_PINGDISPLAY]: 0,
  1010. [MISC_RENDERDISPLAY]: 0,
  1011. [MISC_STATICHUD]: 0,
  1012. [MISC_STATICHEALTH]: 0,
  1013. [MISC_DISABLECLOSEPOPUP]: 0,
  1014. [MISC_BETTERCRATEHP]: 0,
  1015. [MISC_HIDECHATTING]: 0,
  1016. [MISC_FFACLANDISPLAY]: 0,
  1017. [MISC_SHOWFEATURES]: 0,
  1018. [MISC_POSITION]: 0,
  1019. [MISC_LEADERBOARDBADGES]: 0
  1020. },
  1021.  
  1022. advanced = {
  1023. [ADVANCED_PINGCOUNT]: 10,
  1024. [ADVANCED_AIMCONSTANT]: 1,
  1025. [ADVANCED_TPS]: 2.5,
  1026. [ADVANCED_OPTIMISEWALLCHECK]: 1,
  1027. [ADVANCED_PINGCOMP]: 25 // originally 40 because the server updates once every 40 ms, though 25 is a better number
  1028. },
  1029.  
  1030. perkHacks = {
  1031. [PERKHACKS_TICK]: 0,
  1032. [PERKHACKS_KNIFE]: 0,
  1033. [PERKHACKS_KNIFEMAXRANGE]: 100,
  1034. [PERKHACKS_SHIELD]: 0,
  1035. [PERKHACKS_SHIELDUPKEEP]: 5,
  1036. [PERKHACKS_STOREDANGLE]: 0,
  1037. [PERKHACKS_SHIELDMANUAL]: 0,
  1038. [PERKHACKS_SHIELDLOOKAHEAD]: 0,
  1039. [PERKHACKS_CRATEPLACEVISION]: 0,
  1040. [PERKHACKS_MEDKITSELFHEAL]: 0,
  1041. [PERKHACKS_MEDKITSELFHEALTHRESHOLD]: 50,
  1042. [PERKHACKS_SHIELDVISUALISER]: 0,
  1043. [PERKHACKS_SHIELDWALLCHECK]: 0
  1044. },
  1045.  
  1046. thnet = {
  1047. [THNET_ENABLE]: 1,
  1048. [THNET_SOCKET]: 0,
  1049. [THNET_CHAT]: 0,
  1050. [THNET_DONATE]: 0,
  1051. [THNET_CLOSEREASON]: '',
  1052. [THNET_AUTH]: '',
  1053. [THNET_BROTHERS]: [],
  1054. [THNET_INFOSHARE]: 0,
  1055. [THNET_INFOSHARING]: {},
  1056. [THNET_ENTEROPENCHAT]: 0
  1057. },
  1058.  
  1059. weird = {
  1060. [WEIRD_CURSORMOVE]: 0
  1061. },
  1062.  
  1063. discordRPC = {
  1064. [DISCORDRPC_ENABLED]: 0,
  1065. [DISCORDRPC_STATE]: 'State',
  1066. [DISCORDRPC_DETAILS]: 'Details',
  1067. [DISCORDRPC_UPDATEINTERVAL]: 30,
  1068. // ^^ = configurable | vv = internal
  1069. [DISCORDRPC_START]: Date.now(),
  1070. [DISCORDRPC_TIMEOUT]: 0,
  1071. [DISCORDRPC_CONNECTION]: 0,
  1072. [DISCORDRPC_CLIENTID]: '1050361019609927690',
  1073. [DISCORDRPC_TRIES]: 0,
  1074. [DISCORDRPC_ACCESSTOKEN]: '',
  1075. [DISCORDRPC_EXPECTING]: []
  1076. },
  1077.  
  1078. paint = {
  1079. [PAINT_GRIDSPACEX]: 20,
  1080. [PAINT_GRIDSPACEY]: 20,
  1081. [PAINT_GRIDLINEWIDTHHORIZONTAL]: 1,
  1082. [PAINT_GRIDLINEWIDTHVERTICAL]: 1,
  1083. [PAINT_GRIDCOLOR]: ['#e3e3e8', '#efeff5'],
  1084.  
  1085. [PAINT_POINTSIDLE]: ['#aaaaaa', '#f9f9f9'],
  1086. [PAINT_POINTSFFA]: ['#00cc66', '#f9f9f9'],
  1087. [PAINT_POINTSBLU]: ['#8dd8f8', '#f9f9f9'],
  1088. [PAINT_POINTSRED]: ['#f26740', '#f9f9f9'],
  1089. [PAINT_POINTEDGEWIDTH]: 4,
  1090.  
  1091. [PAINT_CRATESHOWHPMODE]: 2,
  1092. [PAINT_CRATESQUARE]: ['#808080', '#dfbf9f'],
  1093. [PAINT_CRATELONG]: ['#808080', '#bec8dd'],
  1094. [PAINT_CRATEUSER]: ['#808080', '#53c68c'],
  1095. [PAINT_CRATEPREMIUM]: ['#2e2d2d', '#f0ba37'],
  1096. [PAINT_CRATECORPSE]: ['#ffffff', '#ffffff'],
  1097.  
  1098. [PAINT_PRESETS]: [
  1099. [ 'Default' , 'Dygn' , 20, 20, 1, 1, ['#e3e3e8', '#efeff5'], ['#aaaaaa', '#f9f9f9'], ['#00cc66', '#f9f9f9'], ['#8dd8f8', '#f9f9f9'], ['#f26740', '#f9f9f9'], 4 , 2, ['#808080', '#dfbf9f'], ['#808080', '#bec8dd'], ['#808080', '#53c68c'], ['#2e2d2d', '#f0ba37'], ['#ffffff', '#ffffff'] ],
  1100. [ 'Vaakir Style' , 'Vaakir' , 20, 20, 1, 1, ['#e3e3e8', '#efeff5'], ['#aaaaaa', '#f9f9f9'], ['#00cc66', '#f9f9f9'], ['#8dd8f8', '#f9f9f9'], ['#f26740', '#f9f9f9'], 4 , 2, ['#4dd8f0', '#b1e9f9'], ['#303030', '#646464'], ['#808080', '#53c68c'], ['#2e2d2d', '#f0ba37'], ['#ffffff', '#ffffff'] ],
  1101. [ 'Drawn on Paper', 'Taureon', 40, 40, 1, 0, ["#a0a0a0", "#ffffff"], ["#808080", "#c4c4c4"], ["#00cc66", "#8fff91"], ["#00b3ff", "#94d1ff"], ["#f26740", "#ffa680"], 10, 2, ["#ff0000", "#ff9494"], ["#2b00ff", "#94b6ff"], ["#00ff04", "#7cfebd"], ["#ff8800", "#ffd470"], ["#ffffff", "#ffffff"] ]
  1102. ]
  1103. },
  1104.  
  1105. multiBox = {
  1106. [MULTIBOX_SELECTEDSOCKET]: 0,
  1107. [MULTIBOX_SPAWNCLONE]: 0,
  1108. [MULTIBOX_INSTANTRESPAWN]: 0
  1109. },
  1110.  
  1111. renderFunctions = [],
  1112.  
  1113. //this really doesnt need to exist but idc
  1114. pInt = parseInt,
  1115.  
  1116. getElementById = x => x && document.getElementById(x),
  1117.  
  1118. keyPress = (socketId, inputId, state) => RF.list[socketId]?.send(a59('key-press', {inputId, state: state * 1})),
  1119.  
  1120. startGunfire = socketId => keyPress(socketId, 6, cursor.isShooting = 1),
  1121. stopGunfire = socketId => keyPress(socketId, 6, cursor.isShooting = 0),
  1122.  
  1123. startActivePerk = socketId => keyPress(socketId, 5, 1),
  1124. stopActivePerk = socketId => keyPress(socketId, 5, 0),
  1125.  
  1126. startReloading = socketId => keyPress(socketId, 4, 1),
  1127. stopReloading = socketId => keyPress(socketId, 4, 0),
  1128.  
  1129. getPlayerHoveringOverOnLeaderboard = mouseEvent => {
  1130. if (j3 < 1 && j3 > 2.6) return '';
  1131. let offset = 0.03,
  1132. x = 1.7 * j13;
  1133. for (let entry of j38.current) {
  1134. if (!entry.userId) continue;
  1135. let y = (0.05 + offset) * j14;
  1136. offset += 0.045;
  1137. if (mouseEvent.x > x && mouseEvent.y > y && mouseEvent.x < x + 0.295 * j13 && mouseEvent.y < y + 0.04 * j14) {
  1138. return sanitiseName(entry.userId);
  1139. }
  1140. }
  1141. },
  1142.  
  1143. getPlayerHoveringOverInGame = mouseEvent => {
  1144. let me = RD.pool[c3],
  1145. x = c2.x + mouseEvent.x / j6,
  1146. y = c2.y + mouseEvent.y / j5;
  1147. for (let player of getPool(RD)) {
  1148. if (player.activated && player.id != me.id && getDistanceSquared(player, {x, y}, nullPos) <= (player[ATTRIBUTE_RADIUS] + 2 ) ** 2) {
  1149. return player[ATTRIBUTE_SANITIZEDNAME];
  1150. }
  1151. }
  1152. },
  1153.  
  1154. nonLeftClickPressHandler = (player, primaryList, secondaryList, enumClickToggle, enumSettingToggle) => {
  1155. if (player && aimbot[enumClickToggle]) {
  1156. toggleUsernameInlist(primaryList, player);
  1157. if (includesInArray(secondaryList, player)) toggleUsernameInlist(secondaryList, player);
  1158. } else {
  1159. aimbot[enumSettingToggle] = 1 - aimbot[enumSettingToggle];
  1160. saveSettings();
  1161. }
  1162. },
  1163.  
  1164. gameMouseUp = mouseEvent => {
  1165. if (!j17 && c3 && mouseEvent.which == MOUSEEVENT_LEFT) {
  1166. cursor.isPressed = 0;
  1167. stopGunfire(multiBox[MULTIBOX_SELECTEDSOCKET]);
  1168. }
  1169. j18 = {x: 0, y: 0};
  1170. },
  1171.  
  1172. gameMouseDown = mouseEvent => {
  1173. if ($('#loginModal' ).is(':visible') ||
  1174. $('#registerModal' ).is(':visible') ||
  1175. $('#aboutModal' ).is(':visible') ||
  1176. $('#privacyModal' ).is(':visible')) return;
  1177.  
  1178. j18 = {x: mouseEvent.clientX, y: mouseEvent.clientY};
  1179.  
  1180. if (j17 || c3 == null) return;
  1181.  
  1182. let playerHover = '';
  1183. if (mouseEvent.which !== MOUSEEVENT_LEFT && (aimbot[AIMBOT_RIGHTCLICKFRIEND] || aimbot[AIMBOT_AUXCLICKTARGET])) {
  1184. playerHover = getPlayerHoveringOverOnLeaderboard(mouseEvent) || getPlayerHoveringOverInGame(mouseEvent);
  1185. }
  1186.  
  1187. switch (mouseEvent.which) {
  1188. case MOUSEEVENT_LEFT:
  1189. if (aimbot[AIMBOT_TRIGGERBOTWHENDOWN] || !aimbot[AIMBOT_ENABLE] || !aimbot[AIMBOT_TRIGGERBOT]) startGunfire(multiBox[MULTIBOX_SELECTEDSOCKET]);
  1190. cursor.isPressed = 1;
  1191. break;
  1192.  
  1193. case MOUSEEVENT_MIDDLE:
  1194. nonLeftClickPressHandler(playerHover, targets, friends, AIMBOT_RIGHTCLICKFRIEND, AIMBOT_TARGETSONLY);
  1195. break;
  1196.  
  1197. case MOUSEEVENT_RIGHT:
  1198. nonLeftClickPressHandler(playerHover, friends, targets, AIMBOT_AUXCLICKTARGET, AIMBOT_ENABLE);
  1199. break;
  1200. }
  1201.  
  1202. //reset aiming direction to the cursor
  1203. if (aimbot[AIMBOT_ENABLE]) return;
  1204. aimMeAt({ clientX: cursor.x, clientY: cursor.y });
  1205. sendMousePositionToServer(multiBox[MULTIBOX_SELECTEDSOCKET]);
  1206. },
  1207.  
  1208. hashString = str => {
  1209. let hash = 0, i;
  1210. for (i = 0; i < str.length; i++) hash = (((hash << 5) - hash) + str.charCodeAt(i)) | 0;
  1211. return hash;
  1212. },
  1213.  
  1214. fetchFromServer = path => new Promise(Resolve => fetch('http' + homeUrl + path).then(res => res.text()).then(Resolve)),
  1215.  
  1216. // https://stackoverflow.com/questions/3977792/how-to-convert-keycode-to-character-using-javascript
  1217. keyCodeToLetter = key => String.fromCharCode((96 <= key && key <= 105) ? key - 48 : key),
  1218.  
  1219. clamp = (minVal, val, maxVal) => isNaN(val) ? minVal : min(maxVal, max(minVal, val)),
  1220.  
  1221. lerp = (a, b, t) => a + t * (b - a),
  1222.  
  1223. lerpR = (a, b, t) => round(lerp(a, b, t)),
  1224.  
  1225. spacePadding = (val, minLength = 3) => {
  1226. val = val.toString();
  1227. while (val.length < minLength) val = ' ' + val;
  1228. return val;
  1229. },
  1230.  
  1231. percentify = a => round(a * 100) + '%',
  1232.  
  1233. pressKey = keyCode => document.onkeydown({keyCode, [ATTRIBUTE_ISFROMCHEAT]: 1, preventDefault: ()=>{}}),
  1234. releaseKey = keyCode => document.onkeyup({keyCode, [ATTRIBUTE_ISFROMCHEAT]: 1, preventDefault: ()=>{}}),
  1235.  
  1236. sendChatMessage = (socketId, message, dontpause) => {
  1237. if (!dontpause) pauseChatScrolling();
  1238. lastMessageLength = message.length;
  1239. RF.list[socketId].send(a59('message', {message: message.replace(/,/g, '~')}));
  1240. },
  1241.  
  1242. //remove clan tags in tdm and dom
  1243. sanitiseName = username => username.replace(/\[[\d\w]{1,4}\] /, ''),
  1244.  
  1245. indexOfInArray = (arr, target) => {
  1246. for (let i = 0; i < arr.length; i++) if (arr[i] == target) return i;
  1247. return -1;
  1248. },
  1249.  
  1250. includesInArray = (arr, target) => {
  1251. for (let i = 0; i < arr.length; i++) if (arr[i] == target) return 1;
  1252. return 0;
  1253. },
  1254.  
  1255. getPool = R => {
  1256. if (!R) return;
  1257. return Object.values(R.pool);
  1258. },
  1259.  
  1260. discordRPCConnect = onConnected => {
  1261. const port = 6463 + (discordRPC[DISCORDRPC_TRIES]++ % 10);
  1262. discordRPC[DISCORDRPC_CONNECTION] = applyAttrbutes(new WebSocket('ws://127.0.0.1:' + port + '/?v=1&client_id=' + discordRPC[DISCORDRPC_CLIENTID]), {
  1263. 'onopen': onConnected,
  1264. 'onmessage': event => {
  1265. let message = JSON.parse(event.data),
  1266. nonce = message.nonce;
  1267. if (message.cmd === 'DISPATCH' && message.evt === 'READY') {
  1268. onConnected();
  1269. } else if (nonce in discordRPC[DISCORDRPC_EXPECTING]) {
  1270. const { y, n } = discordRPC[DISCORDRPC_EXPECTING][nonce];
  1271. if (message.evt === 'ERROR') {
  1272. const e = new Error(message.data.message);
  1273. e.code = message.data.code;
  1274. e.data = message.data;
  1275. n(e);
  1276. } else {
  1277. y(message.data);
  1278. }
  1279. delete discordRPC[DISCORDRPC_EXPECTING][nonce];
  1280. }
  1281. },
  1282. 'onerror': event => {
  1283. try {
  1284. discordRPC[DISCORDRPC_CONNECTION].close();
  1285. } catch {}
  1286. if (discordRPC[DISCORDRPC_TRIES] > 20) {
  1287. //TODO: handle error of there being no discord client
  1288. } else {
  1289. setTimeout(discordRPCConnect, 250);
  1290. }
  1291. },
  1292. 'onclose': event => {
  1293. if (event.wasClean) for (let e of discordRPC[DISCORDRPC_EXPECTING]) e.n(new Error('connection closed'));
  1294. discordRPC[DISCORDRPC_CONNECTION] = 0;
  1295. }
  1296. });
  1297. },
  1298.  
  1299. discordRPCStart = () => {
  1300. let discordRPCUpdate = () => discordRPCActivitySet(discordRPC[DISCORDRPC_TIMEOUT] = setTimeout(discordRPCUpdate, discordRPC[DISCORDRPC_UPDATEINTERVAL] * 1e3));
  1301. discordRPCConnect(discordRPCUpdate);
  1302. },
  1303.  
  1304. discordRPCRequest = (cmd, args, evt) => {
  1305. return new Promise((y, n) => {
  1306. let nonce = random() + ''; //good enough
  1307. if (discordRPC[DISCORDRPC_CONNECTION].readyState == 'OPEN') discordRPC[DISCORDRPC_CONNECTION].send(JSON.stringify({ cmd, args, evt, nonce }));
  1308. discordRPC[DISCORDRPC_EXPECTING][nonce] = { y, n };
  1309. });
  1310. },
  1311.  
  1312. discordRPCActivitySet = () => {
  1313. discordRPCRequest('SET_ACTIVITY', {
  1314. pid: null,
  1315. activity: {
  1316. state: discordRPC[DISCORDRPC_STATE],
  1317. details: discordRPC[DISCORDRPC_DETAILS],
  1318. timestamps: { start: discordRPC[DISCORDRPC_START], end: undefVar },
  1319. assets: { large_image: 'tiohax_icon', large_text: 'TioHax Cheat Menu', small_image: 'gatsio_favicon', small_text: 'On Gats.io' },
  1320. buttons: undefVar,
  1321. instance: false,
  1322. },
  1323. });
  1324. },
  1325.  
  1326. discordRPCActivityClear = () => discordRPCRequest('SET_ACTIVITY', { pid: null }),
  1327.  
  1328. saveSettings = () => {
  1329. //TODO: multibox stop fire on everything
  1330. stopGunfire(multiBox[MULTIBOX_SELECTEDSOCKET]);
  1331. for (let func of renderFunctions) func();
  1332. localStorage.setItem('TioHax_settings', JSON.stringify([
  1333. friends.filter(x => !x.startsWith('Guest ')),
  1334. targets.filter(x => !x.startsWith('Guest ')),
  1335. autoUpgrades,
  1336. [
  1337. aimbot[AIMBOT_ENABLE],
  1338. aimbot[AIMBOT_AIMSMOOTHING],
  1339. aimbot[AIMBOT_CURSORMODE],
  1340. aimbot[AIMBOT_USEACCELERATION],
  1341. aimbot[AIMBOT_IGNORECHATTING],
  1342. aimbot[AIMBOT_PINGCOMPENSATION],
  1343. aimbot[AIMBOT_TRIGGERBOT],
  1344. aimbot[AIMBOT_WALLCHECK],
  1345. aimbot[AIMBOT_USEAHEAD],
  1346. aimbot[AIMBOT_DISABLEWHENDASHING],
  1347. aimbot[AIMBOT_CURSORPROXCOSENESS],
  1348. aimbot[AIMBOT_TARGETMODE],
  1349. aimbot[AIMBOT_TRIGGERBOTWHENDOWN],
  1350. aimbot[AIMBOT_RIGHTCLICKFRIEND],
  1351. aimbot[AIMBOT_AUXCLICKTARGET],
  1352. aimbot[AIMBOT_TARGETSONLY],
  1353. aimbot[AIMBOT_AVOIDFRIENDS],
  1354. aimbot[AIMBOT_AHEADNESSDEPTH],
  1355. aimbot[AIMBOT_LEADERMODE]
  1356. ],[
  1357. esp[ESP_ZOOM],
  1358. esp[ESP_FIXCAMERA],
  1359. esp[ESP_TRACERSBODYENEMY],
  1360. esp[ESP_TRACERSCURSORENEMY],
  1361. esp[ESP_TRACERSWALLCHECK],
  1362. esp[ESP_TRACERSGUN],
  1363. esp[ESP_TRACERSGRENADES],
  1364. esp[ESP_SHOWINVIS],
  1365. esp[ESP_REVEALTEAMS],
  1366. esp[ESP_SHOWHEALTH],
  1367. esp[ESP_SHOWARMOR],
  1368. esp[ESP_SHOWMAGS],
  1369. esp[ESP_SHOWGUNRELOADSTATUS],
  1370. esp[ESP_CAMUSEREALPOSITION],
  1371. esp[ESP_INCLUDEYOU],
  1372. esp[ESP_SHOWRANGE],
  1373. esp[ESP_SCROLLSENSITIVITY]
  1374. ],[
  1375. chatSpam[CHATSPAMMER_TEXT],
  1376. chatSpam[CHATSPAMMER_WIDTH],
  1377. chatSpam[CHATSPAMMER_INTERVAL],
  1378. chatSpam[CHATSPAMMER_DIRECTION],
  1379. chatSpam[CHATSPAMMER_SEPERATOR],
  1380. chatSpam[CHATSPAMMER_PREFIX],
  1381. chatSpam[CHATSPAMMER_SUFFIX]
  1382. ],[
  1383. antiAim[ANTIAIM_RELOAD],
  1384. antiAim[ANTIAIM_SHOOT],
  1385. antiAim[ANTIAIM_IDLE],
  1386. antiAim[ANTIAIM_ANGLESTART],
  1387. antiAim[ANTIAIM_ANGLERANGE],
  1388. antiAim[ANTIAIM_SPINSPEED],
  1389. antiAim[ANTIAIM_DELAY],
  1390. antiAim[ANTIAIM_DRAWREALAIM]
  1391. ],[
  1392. instantchat[INSTANTCHAT_CHATBINDS],
  1393. instantchat[INSTANTCHAT_CHATBINDSTEXTS],
  1394. instantchat[INSTANTCHAT_ONKILL],
  1395. instantchat[INSTANTCHAT_ONKILLTEXT],
  1396. instantchat[INSTANTCHAT_ONDEATH],
  1397. instantchat[INSTANTCHAT_ONDEATHTEXT],
  1398. instantchat[INSTANTCHAT_AUTOTHANK],
  1399. instantchat[INSTANTCHAT_AUTOTHANKTEXT]
  1400. ],[
  1401. misc[MISC_AUTORELOAD],
  1402. misc[MISC_PINGDISPLAY],
  1403. misc[MISC_RENDERDISPLAY],
  1404. misc[MISC_STATICHUD],
  1405. misc[MISC_STATICHEALTH],
  1406. misc[MISC_DISABLECLOSEPOPUP],
  1407. misc[MISC_BETTERCRATEHP],
  1408. misc[MISC_HIDECHATTING],
  1409. misc[MISC_FFACLANDISPLAY],
  1410. misc[MISC_SHOWFEATURES],
  1411. misc[MISC_POSITION],
  1412. misc[MISC_LEADERBOARDBADGES]
  1413. ],[
  1414. advanced[ADVANCED_PINGCOUNT],
  1415. advanced[ADVANCED_AIMCONSTANT],
  1416. advanced[ADVANCED_OPTIMISEWALLCHECK],
  1417. advanced[ADVANCED_TPS],
  1418. advanced[ADVANCED_PINGCOMP]
  1419. ],[
  1420. thnet[THNET_ENABLE],
  1421. thnet[THNET_CHAT],
  1422. thnet[THNET_DONATE],
  1423. thnet[THNET_INFOSHARE]
  1424. ],
  1425. muted.filter(x => !x.startsWith('Guest ')),
  1426. [
  1427. perkHacks[PERKHACKS_KNIFE],
  1428. perkHacks[PERKHACKS_KNIFEMAXRANGE],
  1429. perkHacks[PERKHACKS_SHIELD],
  1430. perkHacks[PERKHACKS_SHIELDUPKEEP],
  1431. perkHacks[PERKHACKS_SHIELDMANUAL],
  1432. perkHacks[PERKHACKS_CRATEPLACEVISION],
  1433. perkHacks[PERKHACKS_SHIELDLOOKAHEAD],
  1434. perkHacks[PERKHACKS_MEDKITSELFHEAL],
  1435. perkHacks[PERKHACKS_MEDKITSELFHEALTHRESHOLD],
  1436. perkHacks[PERKHACKS_SHIELDVISUALISER],
  1437. perkHacks[PERKHACKS_SHIELDWALLCHECK]
  1438. ],[
  1439. // discordRPC[DISCORDRPC_ENABLED],
  1440. // discordRPC[DISCORDRPC_STATE],
  1441. // discordRPC[DISCORDRPC_DETAILS],
  1442. // discordRPC[DISCORDRPC_UPDATEINTERVAL]
  1443. ],[
  1444. paint[PAINT_GRIDSPACEX],
  1445. paint[PAINT_GRIDSPACEY],
  1446. paint[PAINT_GRIDLINEWIDTHHORIZONTAL],
  1447. paint[PAINT_GRIDLINEWIDTHVERTICAL],
  1448. paint[PAINT_GRIDCOLOR],
  1449. paint[PAINT_POINTSIDLE],
  1450. paint[PAINT_POINTSFFA],
  1451. paint[PAINT_POINTSBLU],
  1452. paint[PAINT_POINTSRED],
  1453. paint[PAINT_POINTEDGEWIDTH],
  1454. paint[PAINT_CRATESHOWHPMODE],
  1455. paint[PAINT_CRATESQUARE],
  1456. paint[PAINT_CRATELONG],
  1457. paint[PAINT_CRATEUSER],
  1458. paint[PAINT_CRATEPREMIUM],
  1459. paint[PAINT_CRATECORPSE],
  1460. paint[PAINT_PRESETS]
  1461. ],[
  1462. multiBox[MULTIBOX_SELECTEDSOCKET],
  1463. multiBox[MULTIBOX_SPAWNCLONE],
  1464. multiBox[MULTIBOX_INSTANTRESPAWN]
  1465. ]
  1466. ]));
  1467. },
  1468.  
  1469. /*
  1470. '[["nekoarc1941","BLACKOUTTTT","uncutegirl","zapster","USHOOTlSHOOT","PICC4pArTy","ZasDiablo","CY3RFOX","bublik12","NoBoDy7494","GoDSp33D","vMonst3r","SlimShady01","F1rp00","DOGGER","Nitrogem35","DasDr4gon","PyroSensei","mazicarnage","khanhdz","HENEEDMILK","VaakirYoutu2","VaakirYoutu3","VaakirYoutu4","VaakirYoutu5","ponchik12","Anyaaaa","NotADr4gon","TomatoG","evan85","SJX666","BlastkidGame","heheuwu","CrAdLeSFBR36","Happlefoot","Timofeith","BlockA","ShadowOfMars","XpBall005","xxProGamerxY","ANTOVEGAIT2","ya1emu","DrounedGhos","1994","kyoji","NewNo0b","OnlyMed1c","GIRLCAT","NoKill1234","DImaBull","aterminators","FuzZzy","GhostmaneNIH","milllynoob","NatikEdm","brainz786","XAceSniperX","TERJI","TwinyN1","doge0bread","TheAiry","lShowSpeedd","Flickshoter","PICCILOking","M1sAnY","excusernamed","0u0Hearless","TimeToYEET","procancanpro","rllycmon","renat","SikenSBS","XxOnlySoloxX","Zed25","SizPazzed","bmon","AidenTheGod1","ItsStorm123","ShieldNUB","TheFoxUwU","nandhu255","Black5heep","BreadCrust","xXSAITAMAXx","BOOSK48lvl","medictoo","samilp","xXDynamiteXx","hackcolo2022","SoulFLY4","soldier2253","boom01","DarkyFighter","Legend126","ilmar","Azural","MeowFighter","doodlebanger","ImaNewGod","MrMP","NoRecovery","RADIATION","JuzT","slai1zik","xUltra0","peemer","Kepfin","SuperSaiyan6","1887","NewAimBot","AA63","Sn1pey","Anubable","Mucus","Warden","AxyennoKrut","RussianKing","Igotya","INeverShoot","111111111112","COBRO","darinagirl","SANYI","PotatoG","nandhuSOLO","BuilderEU","chosen1","KingSniper1","AlfaRomeo","germankuba","HoneyNachos","ThirdMoon","Xnes","Libreville","Arino4ka","idationsYTYL","ThePussiLika","Stalee","CoRTeZza","Snowyday","LeoH4iK","Rusich","6AAABBB9","R0ss3W","cars","Usernamer","nitrous","4ltF4","sniper3003","Yorichi","MasterSnaiI","nologin","Wh1teSh33p","Party4Life","EQb","Gats24K","mskelgaard","essence1","xBqka","TheBuilder1","Otterr","Egomeister","AKMANTIS","MuteMan","Mixi","na555TURK","uncuteboy","TKSximed","SteelRanger","mamahoilol","DRAGONdue123","UuhhBruh","CreaterSG","DeathsCIawka","KingOfGatss","alg","menssidali","ADHKGuard","Ynvojo","MrP","WardenPet1","iME4NnoH4RM","humunukuapua","shotgnfriend","XXwishXX","BogdanZele","OrangeSlz","humantrap","RoRo222","ZenithZzzTop","Null900","blueredmedic","Flame232","Tryhard1337","tutku","onlyLOVE","Grintman","Pxtryq","TOKKOT","Meko","IGodkekel","Claw","ZeIensky","masterov2011","av0id","B0bDaBu1lder","Lunarz","berkaytuc","Repeat","XXXantacion","NewChronix","Latea15","chronix2nd","SmilePrime","datBoI6446","NoobTeamok23","EzKill17","darkVortex","tw0ysTrax","1vs7","FazeTfue5","ElvenWarrior","Vilka","Plex","BuilderZarc","xPeace","MucusGuard","WardenSOLO","ADHKJunior","SniperPro100","AHDKJunior","Me1Me","DeadForYears","blackheart5","DeathsClawk","Sn0wMan","GodzilIa","sunylemon","GodF4ther","WlZZ","Alforomeo","Armenia003","Mrsinnrush","builder1917","1SnIpEr4YoU","lmFlakilm","Ashwinn","Nevergive11","G4SP","Luxer3d","jimmymcjim","EnEgMat1k","iBuffed","Winstyyyy","jawbre4ker","KikiOna","Medic121","tv0ysTrax","Free8MedKit","Djerwoow","GoldNight","ggxxSOL","cocomelon10","Wistow","quandale1","LifeTaker","IVYK1","Nathanyes","TUX","breat0air","xXOWENX","UglyDuck","Ardaca2332","f0rgotten","arsemikov27","DoctorDeath2","TheFoxSOLO","DARKBULLETS","xixo123321","ZAY3","V918","FortKeeper","XXantacionXX","LyRz55","liarza","D9D9dz","TheVoid","Tyrizz","Anton84","RaidProtocol","nirou","FullWolf","raydslayer","Anubistrap","itscool","XyLiGaN","WinterMan","chickenwingz","RavgoYT","Leafer","darkey543","ImFluffy","Berkoooo","wardenpet69","three13","ZasHunter","nomnom54","ShadowBomb13","Redrosa1","Kiril22888","SEMBOB1010","bublik11","Dakness","N4RUT0","7heFUNhaver","SusPlayer","Null900Solo","TROL1ER","Panzer1Tank","FSBrelict","SLaYFusion","Snegyro4ka","Bot269168","KotikProfi","ShadowSon","SleepDiff","mrCatto","halfelonious","iSlaySimps11","unlegendary1","D3molish","Hanate","AfricanNaz1","Prawn","Sz4bszkaya","firebreker","cookiedoge","Sh4d0wD34th","WarShipXXX","ForMyBrother","toxixca","VGC","FxF","HornyDad","axe12REVENGE","kakatV420","iguana8","TheFriction","RuZza","nightwlker","RUNORDIE6969","JaviZgamer07","chessboifr","STERVIX0","BlasMir99","TheFate","FazeManFan1","xRAVx","Vekaaa5","liittle","B0BdaD3stRoy","axe12","AGEmilO","MasterSnail","Axe12Duo","ThePretzel","xYvProx","vedrogovna","BloodyKnife","YashaRUS","Chinder","IXRI","ZzKraskAzZ","BeHa","RUNORDIE666","SoMeBoDy456"],["Niggaclapper","Smoy4kk","crashere","Fable","HighNiggaPie","XDeathWishX","trtt1223","BlackAlpha","PeleIsBetter","Len1n","g1g2g4g6gcgb","TheNGC3132","PineappleG","RusPatriot","ImShieldRiot","F3ather","tk700","SHTURM","4Reich","vlad10","Innquisitor","AHDK","ErdemKralPro","egor4ikontop","giovigianni","HackerFr","appall","hunter7888"],[1,"lightweight","shield","thickSkin"],[1,0,0,0,0,1,1,1,1,0,0,1,0,1,1,0,0,1,null],[2,1,100,1," # ",1,1,1,1,1,1,1,1,1,1,1,null],["SOME VERY COOL SHIT",30,75,1," ","[[[ "," ]]]"],[1,1,1,0,360,0,1,1],[1,{"48":"Vaakir aimbot bad, use TioHax!","56":"YOUR GUN DOES NOTHING","57":"cheats.gatsio.repl.co","69":"I need a medic!","90":"Put Build Blocks here!"},1,"ACCESS DENIED, [[ENEMY]]",1,"[[ENEMY]] committed murder!",1,"I have been healed! Thank you!"],[1,1,1,1,1,1,1,1,0,1,1,1],[10,1,0,2.5,25],[true,1,null,1],[],[0,100,1,5,0,1,0,1,50,3],[],[40,40,1,0,["#a0a0a0","#ffffff"],["#808080","#c4c4c4"],["#00cc66","#8fff91"],["#00b3ff","#94d1ff"],["#f26740","#ffa680"],10,2,["#ff0000","#ff9494"],["#2b00ff","#94b6ff"],["#00ff04","#7cfebd"],["#ff8800","#ffd470"]],[0,null]]'
  1471. */
  1472.  
  1473. loadSettings = () => {
  1474. let data = JSON.parse(localStorage.getItem('TioHax_settings') || '{}'),
  1475. stuffToLoad = [
  1476. [friends
  1477. ],
  1478. [targets
  1479. ],
  1480. [autoUpgrades
  1481. ],
  1482. [aimbot,
  1483. AIMBOT_ENABLE + AIMBOT_AIMSMOOTHING + AIMBOT_CURSORMODE + AIMBOT_USEACCELERATION +
  1484. AIMBOT_IGNORECHATTING + AIMBOT_PINGCOMPENSATION + AIMBOT_TRIGGERBOT + AIMBOT_WALLCHECK +
  1485. AIMBOT_USEAHEAD + AIMBOT_DISABLEWHENDASHING + AIMBOT_CURSORPROXCOSENESS + AIMBOT_TARGETMODE +
  1486. AIMBOT_TRIGGERBOTWHENDOWN + AIMBOT_RIGHTCLICKFRIEND + AIMBOT_AUXCLICKTARGET + AIMBOT_TARGETSONLY +
  1487. AIMBOT_AVOIDFRIENDS + AIMBOT_AHEADNESSDEPTH + AIMBOT_LEADERMODE
  1488. ],
  1489. [esp,
  1490. ESP_ZOOM + ESP_FIXCAMERA + ESP_TRACERSBODYENEMY + ESP_TRACERSCURSORENEMY +
  1491. ESP_TRACERSWALLCHECK + ESP_TRACERSGUN + ESP_TRACERSGRENADES + ESP_SHOWINVIS +
  1492. ESP_REVEALTEAMS + ESP_SHOWHEALTH + ESP_SHOWARMOR + ESP_SHOWMAGS +
  1493. ESP_SHOWGUNRELOADSTATUS + ESP_CAMUSEREALPOSITION + ESP_INCLUDEYOU + ESP_SHOWRANGE +
  1494. ESP_SCROLLSENSITIVITY],
  1495. [chatSpam,
  1496. CHATSPAMMER_TEXT + CHATSPAMMER_WIDTH + CHATSPAMMER_INTERVAL + CHATSPAMMER_DIRECTION +
  1497. CHATSPAMMER_SEPERATOR + CHATSPAMMER_PREFIX + CHATSPAMMER_SUFFIX
  1498. ],
  1499. [antiAim,
  1500. ANTIAIM_RELOAD + ANTIAIM_SHOOT + ANTIAIM_IDLE + ANTIAIM_ANGLESTART +
  1501. ANTIAIM_ANGLERANGE + ANTIAIM_SPINSPEED + ANTIAIM_DELAY + ANTIAIM_DRAWREALAIM
  1502. ],
  1503. [instantchat,
  1504. INSTANTCHAT_CHATBINDS + INSTANTCHAT_CHATBINDSTEXTS + INSTANTCHAT_ONKILL + INSTANTCHAT_ONKILLTEXT +
  1505. INSTANTCHAT_ONDEATH + INSTANTCHAT_ONDEATHTEXT + INSTANTCHAT_AUTOTHANK + INSTANTCHAT_AUTOTHANKTEXT
  1506. ],
  1507. [misc,
  1508. MISC_AUTORELOAD + MISC_PINGDISPLAY + MISC_RENDERDISPLAY + MISC_STATICHUD +
  1509. MISC_STATICHEALTH + MISC_DISABLECLOSEPOPUP + MISC_BETTERCRATEHP + MISC_HIDECHATTING +
  1510. MISC_FFACLANDISPLAY + MISC_SHOWFEATURES + MISC_POSITION + MISC_LEADERBOARDBADGES
  1511. ],
  1512. [advanced,
  1513. ADVANCED_PINGCOUNT + ADVANCED_AIMCONSTANT + ADVANCED_OPTIMISEWALLCHECK + ADVANCED_TPS +
  1514. ADVANCED_PINGCOMP
  1515. ],
  1516. [thnet,
  1517. THNET_ENABLE + THNET_CHAT + THNET_DONATE + THNET_INFOSHARE
  1518. ],
  1519. [muted
  1520. ],
  1521. [perkHacks,
  1522. PERKHACKS_KNIFE + PERKHACKS_KNIFEMAXRANGE + PERKHACKS_SHIELD + PERKHACKS_SHIELDUPKEEP +
  1523. PERKHACKS_SHIELDMANUAL + PERKHACKS_CRATEPLACEVISION + PERKHACKS_SHIELDLOOKAHEAD + PERKHACKS_MEDKITSELFHEAL +
  1524. PERKHACKS_MEDKITSELFHEALTHRESHOLD + PERKHACKS_SHIELDVISUALISER + PERKHACKS_SHIELDWALLCHECK
  1525. ],
  1526. [discordRPC,
  1527. DISCORDRPC_ENABLED + DISCORDRPC_STATE + DISCORDRPC_DETAILS + DISCORDRPC_UPDATEINTERVAL
  1528. ],
  1529. [paint,
  1530. PAINT_GRIDSPACEX + PAINT_GRIDSPACEY + PAINT_GRIDLINEWIDTHHORIZONTAL + PAINT_GRIDLINEWIDTHVERTICAL +
  1531. PAINT_GRIDCOLOR + PAINT_POINTSIDLE + PAINT_POINTSFFA + PAINT_POINTSBLU +
  1532. PAINT_POINTSRED + PAINT_POINTEDGEWIDTH + PAINT_CRATESHOWHPMODE + PAINT_CRATESQUARE +
  1533. PAINT_CRATELONG + PAINT_CRATEUSER + PAINT_CRATEPREMIUM + PAINT_CRATECORPSE +
  1534. PAINT_PRESETS
  1535. ],
  1536. [multiBox,
  1537. MULTIBOX_SELECTEDSOCKET + MULTIBOX_SPAWNCLONE + MULTIBOX_INSTANTRESPAWN
  1538. ]
  1539. ];
  1540. for (let i = 0; i < stuffToLoad.length; i++) if (undefVar != data[i]) {
  1541. let renameThisLater = stuffToLoad[i],
  1542. [settingStorageObject, keystring] = renameThisLater;
  1543. if (keystring) {
  1544. for (let j = 0; j < keystring.length; j++) {
  1545. if (undefVar == data[i][j]) continue;
  1546. settingStorageObject[keystring[j]] = data[i][j];
  1547. }
  1548. } else {
  1549. settingStorageObject.length = 0; //this clears arrays because then the array class forgets that there were elements in it
  1550. settingStorageObject.push(...data[i]);
  1551. }
  1552. }
  1553. },
  1554.  
  1555. drawLineWrap = (x1, y1, x2, y2, w, c) => {
  1556. ctx.strokeStyle = c;
  1557. ctx.lineWidth = w;
  1558. ctx.beginPath();
  1559. ctx.moveTo(x1, y1);
  1560. ctx.lineTo(x2, y2);
  1561. ctx.stroke();
  1562. },
  1563.  
  1564. drawLine = (start, entity, offset, width, color) => drawLineWrap(
  1565. start.x, start.y,
  1566. entity.x + offset.x, entity.y + offset.y,
  1567. width,
  1568. color || getColor(entity)
  1569. ),
  1570.  
  1571. drawLine2 = (entity, end, offset, width, color) => drawLineWrap(
  1572. entity.x + offset.x,
  1573. entity.y + offset.y,
  1574. entity.x + offset.x + end.x,
  1575. entity.y + offset.y + end.y,
  1576. width,
  1577. color || getColor(entity)
  1578. ),
  1579.  
  1580. drawCircle = (entity, offset, radius, width, color) => {
  1581. ctx.strokeStyle = color || getColor(entity);
  1582. ctx.lineWidth = width;
  1583. ctx.beginPath();
  1584. ctx.moveTo(entity.x + offset.x + radius, entity.y + offset.y);
  1585. ctx.arc(entity.x + offset.x, entity.y + offset.y, radius, 0, TAU);
  1586. ctx.stroke();
  1587. },
  1588.  
  1589. drawCircle2 = (entity, offset, radius, width, color) => {
  1590. for (let i = 0; i < 3; i++) {
  1591. ctx.globalAlpha /= 2;
  1592. drawCircle(entity, offset, radius - width * i, width, color);
  1593. }
  1594. },
  1595.  
  1596. //text drawer wrapper
  1597. drawText = (x, y, text, color) => {
  1598. ctx.fillStyle = color;
  1599. ctx.lineWidth = 1;
  1600. ctx.strokeStyle = '#000';
  1601. ctx.fillText(text, x, y);
  1602. ctx.strokeText(text, x, y);
  1603. },
  1604.  
  1605. CLLonSegment = (p0, p1, q0, q1, r0, r1) => q0 <= max(p0, r0) && q0 >= min(p0, r0) && q1 <= max(p1, r1) && q1 >= min(p1, r1),
  1606.  
  1607. CLLorientation = (p0, p1, q0, q1, r0, r1) => {
  1608.  
  1609. // See https://www.geeksforgeeks.org/orientation-3-ordered-points/
  1610. // for details of below formula.
  1611. let v = (q1 - p1) * (r0 - q0) - (q0 - p0) * (r1 - q1);
  1612.  
  1613. return !v ? 0 : // collinear
  1614. v > 0 ? 1 : 2; // clock or counterclock wise
  1615. },
  1616.  
  1617. collisionLineLine = (p10, p11, q10, q11, p20, p21, q20, q21) => {
  1618.  
  1619. // Find the four orientations needed for general and
  1620. // special cases
  1621. let o1 = CLLorientation(p10, p11, q10, q11, p20, p21),
  1622. o2 = CLLorientation(p10, p11, q10, q11, q20, q21),
  1623. o3 = CLLorientation(p20, p21, q20, q21, p10, p11),
  1624. o4 = CLLorientation(p20, p21, q20, q21, q10, q11);
  1625. // General case
  1626. if (o1 != o2 && o3 != o4) return 1;
  1627. // Special Cases
  1628. return (
  1629. (o1 == 0 && CLLonSegment(p10, p11, p20, p21, q10, q11)) ||
  1630. (o2 == 0 && CLLonSegment(p10, p11, q20, q21, q10, q11)) ||
  1631. (o3 == 0 && CLLonSegment(p20, p21, p10, p11, q20, q21)) ||
  1632. (o4 == 0 && CLLonSegment(p20, p21, q10, q11, q20, q21))
  1633. );
  1634. },
  1635.  
  1636. // https://stackoverflow.com/a/1968345/10793061 but a comment by the god called cortijon
  1637. intersectionPointLineLine = (p0_x, p0_y, p1_x, p1_y, p2_x, p2_y, p3_x, p3_y) => {
  1638. let s1_x = p1_x - p0_x,
  1639. s1_y = p1_y - p0_y,
  1640. s2_x = p3_x - p2_x,
  1641. s2_y = p3_y - p2_y,
  1642. s = (-s1_y * (p0_x - p2_x) + s1_x * (p0_y - p2_y)) / (-s2_x * s1_y + s1_x * s2_y),
  1643. t = (s2_x * (p0_y - p2_y) - s2_y * (p0_x - p2_x)) / (-s2_x * s1_y + s1_x * s2_y);
  1644. if (s >= 0 && s <= 1 && t >= 0 && t <= 1) {
  1645. return {
  1646. x: p0_x + t * s1_x,
  1647. y: p0_y + t * s1_y
  1648. };
  1649. }
  1650. },
  1651.  
  1652. distanceSquaredBetweenPoints = (Ax, Ay, Bx, By) => (Ax - Bx) ** 2 + (Ay - By) ** 2,
  1653.  
  1654. //https://stackoverflow.com/questions/849211/shortest-distance-between-a-point-and-a-line-segment
  1655. distanceSquaredLinePoint = (Ax, Ay, Bx, By, Cx, Cy) => {
  1656. if (Ax === Bx && Ay === By) return distanceSquaredBetweenPoints(Cx, Cy, Ax, Ay);
  1657. let t = max(0, min(1, ((Cx - Ax) * (Bx - Ax) + (Cy - Ay) * (By - Ay)) / distanceSquaredBetweenPoints(Cx, Cy, Ax, Ay)));
  1658. return distanceSquaredBetweenPoints(Cx, Cy, Ax + t * (Bx - Ax), Ay + t * (By - Ay));
  1659. },
  1660.  
  1661. upgradePerk = (socketId, upgrade, upgradeLevel) => {
  1662. o3[upgradeLevel] = upgrade;
  1663. RF.list[socketId].send(a59('upgrade', {upgrade, upgradeLevel}));
  1664. c8[upgradeLevel] = 0;
  1665. },
  1666.  
  1667. autoUpgrade = (socketId, me) => {
  1668. if ((me.score >= c33 || c10 >= 1) && !o3[1] && autoUpgrades[1]) upgradePerk(socketId, autoUpgrades[1], 1);
  1669. if ((me.score >= c34 || c10 >= 2) && !o3[2] && autoUpgrades[2]) upgradePerk(socketId, autoUpgrades[2], 2);
  1670. if ((me.score >= c35 || c10 >= 3) && !o3[3] && autoUpgrades[3]) upgradePerk(socketId, autoUpgrades[3], 3);
  1671. },
  1672.  
  1673. /*gets the color of an enemy by its team affiliation
  1674. -FFA player colors-
  1675. red: {a: '#f26740', b: '#fcd9cf'}
  1676. orange: {a: '#f6803c', b: '#fddfce'}
  1677. yellow: {a: '#fff133', b: '#fffccc'}
  1678. green: {a: '#92cd8b', b: '#ddf0db'}
  1679. blue: {a: '#8dd8f8', b: '#cfeefc'}
  1680. pink: {a: '#f7b0c2', b: '#fde8ed'}
  1681. */
  1682. getColor = entity => {
  1683. //fix for FFA
  1684. if (entity.ownerId && !entity.teamCode) return RD.pool[c3].id == entity.ownerId ? 'green' : 'red';
  1685.  
  1686. return entity.teamCode == 2 ? 'blue' : entity.teamCode == 1 ? 'red' : {
  1687. '#f26740': 'red',
  1688. '#f6803c': 'orange',
  1689. '#fff133': 'yellow',
  1690. '#92cd8b': 'green',
  1691. '#8dd8f8': 'blue',
  1692. '#f7b0c2': 'hotpink'
  1693. }[entity.color.a];
  1694. },
  1695.  
  1696. //either add them or remove them from the friends list depending on if they are already in it or not
  1697. toggleUsernameInlist = (list, username) => {
  1698. username = sanitiseName(username);
  1699. let index = indexOfInArray(list, username);
  1700.  
  1701. //if the player doesnt exist in the list, add them
  1702. if (index == -1) {
  1703. list.push(username);
  1704.  
  1705. //if the player does exist, delete them from the list
  1706. } else if (index == list.length - 1){
  1707. list.pop();
  1708. } else {
  1709. list[index] = list.pop();
  1710. }
  1711.  
  1712. saveSettings();
  1713. },
  1714.  
  1715. applyAttrbutes = (object, attributes) => {
  1716. for (let key in attributes) object[key] = attributes[key];
  1717. return object;
  1718. },
  1719.  
  1720. applyStyle = (element, style) => applyAttrbutes(element.style, style),
  1721.  
  1722. make = (type, style = {}, attributes = {}, babies = []) => {
  1723. let element = document.createElement(type);
  1724. applyStyle(element, style);
  1725. applyAttrbutes(element, attributes);
  1726. for (let baby of babies) element.append(baby);
  1727. return element;
  1728. },
  1729.  
  1730. //note: elements cannot be placed at two places at once
  1731. dupeImg = img => {
  1732. let element = make('canvas', {
  1733. [css_key_width]: css_value_length_perc100,
  1734. [css_key_height]: css_value_length_perc100
  1735. }, {
  1736. [css_key_width]: img.width,
  1737. [css_key_height]: img.height
  1738. });
  1739. element.getContext('2d').drawImage(img, 0, 0, img.width, img.height);
  1740. return element;
  1741. },
  1742.  
  1743. //if a menu requires a canvas for whatever reason
  1744. //this function would later be re-defined in a menu
  1745. updateMenuCanvas = () => {},
  1746.  
  1747. stopChatScrolling = () => {
  1748. //surprisingly, clearTimeout doesn't throw an error if the argument is zero...
  1749. clearTimeout(chatSpam[CHATSPAMMER_TIMEOUT]);
  1750. chatSpam[CHATSPAMMER_TIMEOUT] = 0;
  1751. },
  1752.  
  1753. startChatScrolling = socketId => {
  1754. stopChatScrolling();
  1755. let chatSpamLoop = () => {
  1756. let text = chatSpam[CHATSPAMMER_TEXT] + chatSpam[CHATSPAMMER_SEPERATOR],
  1757. index = chatSpam[CHATSPAMMER_INDEX],
  1758. width = chatSpam[CHATSPAMMER_WIDTH] - (chatSpam[CHATSPAMMER_PREFIX].length + chatSpam[CHATSPAMMER_SUFFIX].length),
  1759. msg = text.length ? '' : ' ',
  1760. pad = ' '.repeat(chatSpam[CHATSPAMMER_VARIATION]);
  1761.  
  1762. if (!msg) for (let i = 0; i < width; i++) msg += text[(index + i) % text.length];
  1763. //the padding exists because the game kicks you for sending messages with the same length often
  1764. sendChatMessage(socketId, pad + chatSpam[CHATSPAMMER_PREFIX] + msg + chatSpam[CHATSPAMMER_SUFFIX] + pad, 1);
  1765.  
  1766. chatSpam[CHATSPAMMER_INDEX] = (index + chatSpam[CHATSPAMMER_DIRECTION] + text.length) % text.length;
  1767. chatSpam[CHATSPAMMER_VARIATION] = (chatSpam[CHATSPAMMER_VARIATION] + 1) % 3;
  1768. chatSpam[CHATSPAMMER_TIMEOUT] = setTimeout(chatSpamLoop, chatSpam[CHATSPAMMER_INTERVAL]);
  1769. };
  1770. chatSpamLoop();
  1771. },
  1772.  
  1773. pauseChatScrolling = socketId => {
  1774. if (!chatSpam[CHATSPAMMER_TIMEOUT]) return;
  1775. stopChatScrolling(socketId);
  1776. //to not conflict if this function was called another time
  1777. let localRandom = random();
  1778. chatBoxRandom = localRandom;
  1779. setTimeout(() => chatBoxRandom == localRandom && startChatScrolling(socketId), chatSpam[CHATSPAMMER_PAUSEPERIOD]);
  1780. },
  1781.  
  1782. removeChildren = element => {
  1783. while (element.hasChildNodes()) element.removeChild(element.lastChild);
  1784. },
  1785.  
  1786. checkScrollable = (bool, element, style) => {
  1787. bool = divs.content.scrollHeight > divs.content.clientHeight;
  1788. element = divs.content.lastChild;
  1789. style = element.style;
  1790. applyStyle(element, {
  1791. [css_key_borderBottom]: bool ? css_value_length_px0 : css_value_border_2px000f,
  1792. [css_key_height]: (pInt(style.height) - (4 - 2 * pInt(style.borderBottom || style.border))) + 'px'
  1793. });
  1794. },
  1795.  
  1796. loadLocalisationFile = fileStr => {
  1797. loadedLocalisation = {};
  1798. let entries = fileStr.split('\n');
  1799. for (let i = 0; i < entries.length; i++) {
  1800. let entry = entries[i],
  1801. index = indexOfInArray(entry, '=');
  1802. if (index == -1) continue;
  1803. let key = entry.slice(0, index),
  1804. value = entry.slice(index + 1, entry.length);
  1805. loadedLocalisation[key] = value;
  1806. }
  1807. },
  1808.  
  1809. getLocal = localisationEntry => loadedLocalisation[localisationEntry] ?? localisationEntry,
  1810.  
  1811. createControlBase = (label, controlSetting) => label && make('div', {
  1812. [css_key_width]: css_value_length_perc100,
  1813. [css_key_height]: css_value_length_px40,
  1814. [css_key_display]: css_value_misc_flex,
  1815. [css_key_alignItems]: css_value_misc_center,
  1816. [css_key_paddingLeft]: css_value_length_px5,
  1817. [css_key_paddingRight]: css_value_length_px5,
  1818. [css_key_borderBottom]: css_value_border_2px000f,
  1819. [css_key_paddingBottom]: css_value_length_px0,
  1820. [css_key_justifyContent]: css_value_misc_spaceBetween
  1821. }, {
  1822. title: getLocal(label[1])
  1823. }, [
  1824. make('div', {}, {
  1825. innerText: getLocal(label[0])
  1826. }),
  1827. controlSetting
  1828. ]),
  1829.  
  1830. createControlButton = (label, doThing) => {
  1831. return createControlBase(label, make('div', {
  1832. [css_key_width]: css_value_length_px45,
  1833. [css_key_height]: css_value_length_px30,
  1834. [css_key_border]: css_value_border_4pxffff,
  1835. [css_key_position]: css_value_misc_relative,
  1836. [css_key_borderRadius]: css_value_length_px7,
  1837. [css_key_backgroundColor]: css_value_color_33dc
  1838. }, {
  1839. onclick: () => {
  1840. saveSettings();
  1841. doThing();
  1842. }
  1843. }));
  1844. },
  1845.  
  1846. createControlToggle = (label, toggle, render) => {
  1847. let controlButtonDiv = make('div', {
  1848. [css_key_width]: css_value_length_px60,
  1849. [css_key_height]: css_value_length_px30,
  1850. [css_key_border]: css_value_border_4pxffff,
  1851. [css_key_display]: css_value_misc_flex,
  1852. [css_key_position]: css_value_misc_relative,
  1853. [css_key_alignItems]: css_value_misc_center,
  1854. [css_key_borderRadius]: css_value_length_px7,
  1855. [css_key_justifyContent]: css_value_misc_center
  1856. }, {
  1857. onclick: () => {
  1858. toggle();
  1859. controlButtonDiv[ATTRIBUTE_UPDATE]();
  1860. saveSettings();
  1861. },
  1862. [ATTRIBUTE_UPDATE]: () => {
  1863. let bool = render();
  1864. controlButtonDiv.innerText = bool ? 'On' : 'Off';
  1865. applyStyle(controlButtonDiv, {
  1866. [css_key_backgroundColor]: bool ? css_value_color_0f0c : css_value_color_f00c
  1867. });
  1868. }
  1869. });
  1870. controlButtonDiv[ATTRIBUTE_UPDATE]();
  1871. renderFunctions.push(controlButtonDiv[ATTRIBUTE_UPDATE]);
  1872. return createControlBase(label, controlButtonDiv);
  1873. },
  1874.  
  1875. createControlValue = (label, update, render) => {
  1876. let style = {
  1877. [css_key_width]: css_value_length_px30,
  1878. [css_key_height]: css_value_length_px30,
  1879. [css_key_border]: css_value_border_3pxffff,
  1880. [css_key_display]: css_value_misc_flex,
  1881. [css_key_position]: css_value_misc_relative,
  1882. [css_key_fontWeight]: css_value_misc_bold,
  1883. [css_key_alignItems]: css_value_misc_center,
  1884. [css_key_borderRadius]: css_value_length_px5,
  1885. [css_key_justifyContent]: css_value_misc_center,
  1886. [css_key_backgroundColor]: css_value_color_ff0c
  1887. },
  1888. controlIndicatorDiv = make('div', {
  1889. [css_key_color]: css_value_color_000f,
  1890. [css_key_width]: css_value_length_px60,
  1891. [css_key_height]: css_value_length_px34,
  1892. [css_key_border]: css_value_border_4pxffff,
  1893. [css_key_display]: css_value_misc_flex,
  1894. [css_key_position]: css_value_misc_relative,
  1895. [css_key_alignItems]: css_value_misc_center,
  1896. [css_key_marginLeft]: css_value_length_px5,
  1897. [css_key_marginRight]: css_value_length_px5,
  1898. [css_key_borderRadius]: css_value_length_px5,
  1899. [css_key_justifyContent]: css_value_misc_center,
  1900. [css_key_backgroundColor]: css_value_color_fffc
  1901. }, {
  1902. //type: css_value_misc_text,
  1903. //maxlength: 64,
  1904. //onfocus: () => textBoxFocused = 1,
  1905. //onblur: () => textBoxFocused = 0,
  1906. //value: render(),
  1907. //oninput: () => {
  1908. // update(editAutoTextInput.value);
  1909. // controlIndicatorDiv[ATTRIBUTE_UPDATE]();
  1910. // saveSettings();
  1911. //},
  1912. onwheel: E => {
  1913. E.preventDefault();
  1914. update(sign(-E.deltaY));
  1915. controlIndicatorDiv[ATTRIBUTE_UPDATE](1);
  1916. },
  1917. [ATTRIBUTE_UPDATE]: shouldSave => {
  1918. controlIndicatorDiv.innerText = render();
  1919. if (shouldSave) saveSettings();
  1920. }
  1921. }),
  1922. controlButtonLeftDiv = make('div', style, {
  1923. innerText: '-',
  1924. onclick: () => {
  1925. update(-1);
  1926. controlIndicatorDiv[ATTRIBUTE_UPDATE](1);
  1927. }
  1928. }),
  1929. controlButtonRightDiv = make('div', style, {
  1930. innerText: '+',
  1931. onclick: () => {
  1932. update(1);
  1933. controlIndicatorDiv[ATTRIBUTE_UPDATE](1);
  1934. }
  1935. });
  1936. controlIndicatorDiv[ATTRIBUTE_UPDATE]();
  1937. renderFunctions.push(controlIndicatorDiv[ATTRIBUTE_UPDATE]);
  1938. return createControlBase(label, make('div', {
  1939. [css_key_display]: css_value_misc_flex,
  1940. [css_key_alignItems]: css_value_misc_center,
  1941. [css_key_flexDirection]: css_value_misc_row
  1942. }, {}, [controlButtonLeftDiv, controlIndicatorDiv, controlButtonRightDiv]));
  1943. },
  1944.  
  1945. createControlText = (label, update, render) => {
  1946. let editAutoTextInput = make('input', {
  1947. [css_key_color]: css_value_color_000f,
  1948. [css_key_width]: css_value_length_perc100,
  1949. [css_key_height]: css_value_length_px34,
  1950. [css_key_border]: css_value_border_4pxffff,
  1951. [css_key_display]: css_value_misc_flex,
  1952. [css_key_position]: css_value_misc_relative,
  1953. [css_key_alignItems]: css_value_misc_center,
  1954. [css_key_borderRadius]: css_value_length_px5,
  1955. [css_key_justifyContent]: css_value_misc_center,
  1956. [css_key_backgroundColor]: css_value_color_fffc
  1957. }, {
  1958. type: css_value_misc_text,
  1959. maxlength: 64,
  1960. onfocus: () => textBoxFocused = 1,
  1961. onblur: () => textBoxFocused = 0,
  1962. oninput: () => {
  1963. update(editAutoTextInput.value);
  1964. editAutoTextInput.value = render();
  1965. saveSettings();
  1966. },
  1967. value: render()
  1968. });
  1969. renderFunctions.push(() => editAutoTextInput.value = render());
  1970. return make('div', {
  1971. [css_key_width]: css_value_length_perc100,
  1972. [css_key_padding]: css_value_length_px5,
  1973. [css_key_paddingTop]: css_value_length_px0,
  1974. [css_key_borderBottom]: css_value_border_2px000f,
  1975. [css_key_paddingBottom]: css_value_length_px0,
  1976. [css_key_justifyContent]: css_value_misc_spaceBetween,
  1977. [css_key_height]: css_value_length_px80
  1978. }, {
  1979. title: getLocal(label[1])
  1980. }, [
  1981. make('div', {
  1982. [css_key_width]: css_value_length_perc100,
  1983. [css_key_display]: css_value_misc_flex,
  1984. [css_key_padding]: css_value_length_px5,
  1985. [css_key_justifyContent]: css_value_misc_spaceBetween,
  1986. [css_key_height]: css_value_length_px40
  1987. }, {
  1988. innerText: getLocal(label[0])
  1989. }),
  1990. editAutoTextInput
  1991. ]);
  1992. },
  1993.  
  1994. createControlDropdown = (label, options, update, render) => {
  1995. let longest = 0;
  1996. for (let optionValue in options) if (options[optionValue][0].length > longest) longest = options[optionValue][0].length;
  1997. longest = (longest + 4.5) + 'ch';
  1998.  
  1999. let i = render(),
  2000. optionCount = Object.keys(options).length;
  2001. if (!options[i]) update(i = 0);
  2002. let controlOptionsDiv = make('div', {
  2003. [css_key_width]: longest,
  2004. [css_key_maxWidth]: longest,
  2005. [css_key_border]: css_value_border_4pxffff,
  2006. [css_key_display]: css_value_misc_flex,
  2007. [css_key_borderRadius]: css_value_length_px7,
  2008. [css_key_paddingRight]: css_value_length_px10,
  2009. [css_key_justifyContent]: css_value_misc_flexEnd,
  2010. [css_key_backgroundColor]: css_value_color_80f8,
  2011. [css_key_zIndex]: css_value_10
  2012. }, {
  2013. hidden: 1,
  2014. onclick: () => {
  2015. update(++i % optionCount);
  2016. controlOptionsDiv[ATTRIBUTE_UPDATE]();
  2017. },
  2018. [ATTRIBUTE_UPDATE]: () => applyAttrbutes(controlOptionsDiv, {
  2019. innerText: getLocal(options[render()][0]) + ' ▼',
  2020. title: getLocal(options[render()][1])
  2021. })
  2022. });
  2023.  
  2024. controlOptionsDiv[ATTRIBUTE_UPDATE]();
  2025. renderFunctions.push(controlOptionsDiv[ATTRIBUTE_UPDATE]);
  2026. return createControlBase(label, controlOptionsDiv);
  2027. },
  2028.  
  2029. createControlColor = (label, color) => {
  2030. let style = {
  2031. }, opts = [];
  2032. for (let i in color) {
  2033. let colorControl = make('input', applyAttrbutes(style, {
  2034. [css_key_width]: css_value_length_px26,
  2035. [css_key_height]: css_value_length_px26,
  2036. [css_key_borderRadius]: css_value_length_px7,
  2037. [css_key_border]: css_value_border_1px000f,
  2038. [css_key_padding]: css_value_length_px0,
  2039. [css_key_outline]: css_value_border_4pxffff,
  2040. [css_key_marginLeft]: css_value_length_px7,
  2041. [css_key_marginRight]: css_value_length_px5
  2042. }), {
  2043. type: 'color',
  2044. value: color[i],
  2045. oninput: () => {
  2046. color[i] = opts[i].value;
  2047. saveSettings();
  2048. opts[i][ATTRIBUTE_UPDATE]();
  2049. },
  2050. [ATTRIBUTE_UPDATE]: () => applyStyle(colorControl, { [css_key_backgroundColor]: colorControl.value = color[i] })
  2051. });
  2052. if (!color[i]) {
  2053. colorControl.value = '#ffffff';
  2054. colorControl.oninput();
  2055. }
  2056. colorControl[ATTRIBUTE_UPDATE]();
  2057. opts[i] = colorControl;
  2058. }
  2059. return createControlBase(label, make('div', {
  2060. [css_key_display]: css_value_misc_flex
  2061. }, {}, opts));
  2062. },
  2063.  
  2064. createMenuDropdown = (label, subcontrols) => {
  2065. let controlNameDiv = make('div', {
  2066. [css_key_display]: css_value_misc_flex
  2067. }, {
  2068. innerText: getLocal(label[0])
  2069. }),
  2070. controlButtonDiv = make('div', {
  2071. [css_key_width]: css_value_length_px45,
  2072. [css_key_height]: css_value_length_px30,
  2073. [css_key_border]: css_value_border_4pxffff,
  2074. [css_key_display]: css_value_misc_flex,
  2075. [css_key_position]: css_value_misc_relative,
  2076. [css_key_alignItems]: css_value_misc_center,
  2077. [css_key_borderRadius]: css_value_length_px7,
  2078. [css_key_justifyContent]: css_value_misc_center,
  2079. [css_key_backgroundColor]: css_value_color_888f
  2080. }, {
  2081. innerText: '▼',
  2082. onclick: () => checkScrollable(controlButtonDiv.innerText = (subcontrolsDiv.hidden = !subcontrolsDiv.hidden) ? '▼' : '▲')
  2083. }),
  2084. controlDiv = make('div', {
  2085. [css_key_width]: css_value_length_perc100,
  2086. [css_key_padding]: css_value_length_px5,
  2087. [css_key_display]: css_value_misc_flex,
  2088. [css_key_paddingBottom]: css_value_length_px0,
  2089. [css_key_justifyContent]: css_value_misc_spaceBetween,
  2090. [css_key_backgroundColor]: css_value_color_6666,
  2091. [css_key_height]: css_value_length_px40
  2092. }, {
  2093. title: getLocal(label[1])
  2094. }, [controlNameDiv, controlButtonDiv]),
  2095. subcontrolsDiv = make('div', {
  2096. [css_key_borderTop]: css_value_border_2px000f,
  2097. [css_key_borderLeft]: css_value_border_4px000f,
  2098. [css_key_borderBottom]: css_value_border_4px000f
  2099. }, { hidden: 1 }, subcontrols);
  2100. return make('div', {
  2101. [css_key_borderBottom]: css_value_border_2px000f
  2102. }, {}, [controlDiv, subcontrolsDiv]);
  2103. },
  2104.  
  2105. refreshMenu = menuID => {
  2106. idRefreshMenu = 0;
  2107. updateMenuCanvas = () => {};
  2108. renderFunctions = [];
  2109. removeChildren(divs.content);
  2110. menus[menuID][1](x=>divs.content.append(x));
  2111. checkScrollable();
  2112. },
  2113.  
  2114. createWindow = (fullWidth, contentHeight, mainTitleLabel, minifyLabelTitle, backbuttonLabelTitle) => {
  2115. let movableWindow = {},
  2116. title, content, backbutton,
  2117. menu = make('div', {
  2118. [css_key_width]: "number" == typeof fullWidth ? fullWidth + 'px' : fullWidth,
  2119. [css_key_height]: css_value_length_minContent,
  2120. [css_key_color]: css_value_color_ffff,
  2121. [css_key_border]: css_value_border_2px000f,
  2122. [css_key_borderRadius]: css_value_length_px5,
  2123. [css_key_zIndex]: highestZIndex++,
  2124. [css_key_position]: css_value_misc_absolute,
  2125. [css_key_fontSize]: css_value_length_px20,
  2126. [css_key_fontFamily]: css_value_misc_Consolas,
  2127. [css_key_userSelect]: css_value_misc_none
  2128. }, {
  2129. hidden: 1
  2130. }, [
  2131. title = make('div', {
  2132. [css_key_width]: css_value_length_perc100,
  2133. [css_key_height]: css_value_length_px43,
  2134. [css_key_border]: css_value_border_2px000f,
  2135. [css_key_padding]: css_value_length_px5,
  2136. [css_key_display]: css_value_misc_flex,
  2137. [css_key_whiteSpace]: css_value_misc_preWrap,
  2138. [css_key_justifyContent]: css_value_misc_spaceBetween,
  2139. [css_key_backgroundImage]: css_value_gradient_redblue
  2140. }, {
  2141. innerText: mainTitleLabel,
  2142. onmousedown: e => {
  2143. let style = menu.style;
  2144. style[css_key_zIndex] = highestZIndex++;
  2145. if (style[css_key_right]) {
  2146. style[css_key_left] = (window.innerWidth - (pInt(style[css_key_right]) + pInt(style[css_key_width]))) + 'px';
  2147. style[css_key_right] = '';
  2148. }
  2149. movableWindow.offsetX = e.clientX - pInt(style[css_key_left]);
  2150. movableWindow.offsetY = e.clientY - pInt(style[css_key_top]);
  2151. movableWindow.enable = 1;
  2152. },
  2153. onmouseup: () => movableWindow.enable = 0
  2154. }, [
  2155. make('div', {
  2156. [css_key_color]: css_value_color_000f,
  2157. [css_key_width]: css_value_length_px28,
  2158. [css_key_height]: css_value_length_px28,
  2159. [css_key_border]: css_value_border_35px000f,
  2160. [css_key_display]: css_value_misc_flex,
  2161. [css_key_fontWeight]: css_value_misc_bold,
  2162. [css_key_alignItems]: css_value_misc_center,
  2163. [css_key_paddingTop]: css_value_length_pxNeg5,
  2164. [css_key_borderRadius]: css_value_length_px10,
  2165. [css_key_justifyContent]: css_value_misc_center,
  2166. [css_key_backgroundColor]: css_value_color_fff8
  2167. }, {
  2168. title: getLocal(minifyLabelTitle),
  2169. innerText: '_',
  2170. onclick: () => divs.menu.hidden = 1
  2171. })
  2172. ]),
  2173. content = make('div', {
  2174. [css_key_width]: css_value_length_perc100,
  2175. [css_key_height]: "number" == typeof contentHeight ? contentHeight + 'px' : contentHeight,
  2176. [css_key_border]: css_value_border_2px000f,
  2177. [css_key_overflowY]: css_value_misc_scroll,
  2178. [css_key_borderTop]: css_value_border_2px000f,
  2179. [css_key_borderLeft]: css_value_border_2px000f,
  2180. [css_key_backgroundColor]: css_value_color_000c
  2181. })
  2182. ]);
  2183.  
  2184. if (backbuttonLabelTitle) {
  2185. backbutton = make('div', {
  2186. [css_key_color]: css_value_color_000f,
  2187. [css_key_width]: css_value_length_px28,
  2188. [css_key_height]: css_value_length_px28,
  2189. [css_key_border]: css_value_border_35px000f,
  2190. [css_key_display]: css_value_misc_flex,
  2191. [css_key_alignItems]: css_value_misc_center,
  2192. [css_key_justifyContent]: css_value_misc_center,
  2193. [css_key_backgroundColor]: css_value_color_fff8,
  2194. [css_key_borderRadius]: css_value_length_px10
  2195. }, {
  2196. title: getLocal(backbuttonLabelTitle),
  2197. innerText: '<',
  2198. onclick: () => refreshMenu(0)
  2199. });
  2200.  
  2201. title.prepend(backbutton);
  2202. }
  2203. movableWindow.element = menu;
  2204. movableWindows.push(movableWindow);
  2205.  
  2206. return [menu, title, content, backbutton];
  2207. },
  2208.  
  2209. createMenu = () => {
  2210. //custom scrollbar
  2211. //i wish there were a better way...
  2212. let windowElements = createWindow(350, 522, menuLabel[3], menuLabel[0], menuLabel[1]),
  2213. someText = '}::-webkit-scrollbar';
  2214. windowElements[0].hidden = 0;
  2215. document.head.append(make('style', {}, {
  2216. textContent:
  2217. 'img{'+
  2218. css_key_width + ':' + css_value_length_perc100 + ';' +
  2219. css_key_height + ':' + css_value_length_perc100 +
  2220. someText + '{'+
  2221. css_key_width + ':' + css_value_length_px16 +
  2222. someText + '-track{'+
  2223. css_key_background + ':' + css_value_color_000f + ';'+
  2224. 'border-left:' + css_value_border_4px000f +
  2225. someText + '-thumb{'+
  2226. css_key_background + ':' + css_value_color_666f + ';'+
  2227. 'border-left:' + css_value_border_4px000f +
  2228. someText + '-thumb:hover{'+
  2229. css_key_background + ':' + css_value_color_888f +
  2230. '}'
  2231. }));
  2232.  
  2233.  
  2234. divs.menu = windowElements[0];
  2235. divs.title = windowElements[1];
  2236. divs.content = windowElements[2];
  2237. divs.backbutton = windowElements[3];
  2238.  
  2239. // if (isUserscript) divs.menu.append(make('div', {
  2240. // [css_key_color]: css_value_color_000f,
  2241. // [css_key_width]: css_value_length_perc100,
  2242. // [css_key_border]: css_value_border_2px000f,
  2243. // [css_key_alignItems]: css_value_misc_center,
  2244. // [css_key_paddingLeft]: css_value_length_px5,
  2245. // [css_key_justifyContent]: css_value_misc_center,
  2246. // [css_key_backgroundImage]: css_value_gradient_gray
  2247. // }, {
  2248. // onclick: () => window.open('http' + homeUrl, '_blank').focus(),
  2249. // innerHTML: 'You are using:<br><b style="color:red">TioHax Userscript Edition</b><br><span style="color:blue">Click here to get the standalone version!<br></span><span style="fontSize: 14px">(It gets frequently updated)<span>'
  2250. // }));
  2251.  
  2252. document.body.append(divs.menu);
  2253. refreshMenu(0);
  2254. createChatbox();
  2255.  
  2256. applyStyle(divs.menu, { [css_key_left]: css_value_length_px5 });
  2257. setTimeout(applyStyle(divs.menu, { [css_key_top]: floor(window.innerHeight - pInt(divs.content.style[css_key_height])) / 2 + 'px' }));
  2258. },
  2259.  
  2260. createChatbox = () => {
  2261. let thnetChatWindow = createWindow(300, 294, menuLabel[4], menuLabel[2]);
  2262. divs.chatinput = make('input', {
  2263. [css_key_color]: css_value_color_000f,
  2264. [css_key_width]: css_value_length_perc100,
  2265. [css_key_height]: css_value_length_px34,
  2266. [css_key_border]: css_value_border_4pxffff,
  2267. [css_key_display]: css_value_misc_flex,
  2268. [css_key_position]: css_value_misc_relative,
  2269. [css_key_alignItems]: css_value_misc_center,
  2270. [css_key_borderRadius]: css_value_length_px5,
  2271. [css_key_justifyContent]: css_value_misc_center,
  2272. [css_key_backgroundColor]: css_value_color_fffc
  2273. }, {
  2274. type: css_value_misc_text,
  2275. maxlength: 128,
  2276. onfocus: () => textBoxFocused = 1,
  2277. onblur: () => textBoxFocused = 0,
  2278. onchange: () => {
  2279. thnet[THNET_SOCKET]?.send('0 ' + divs.chatinput.value);
  2280. divs.chatinput.value = '';
  2281. divs.chatinput.blur();
  2282. },
  2283. value: ''
  2284. });
  2285.  
  2286. thnetChatWindow[2].append(divs.chatbox = make('div', {
  2287. [css_key_width]: css_value_length_perc100,
  2288. [css_key_height]: css_value_length_px250,
  2289. [css_key_border]: css_value_border_2px000f,
  2290. [css_key_fontSize]: css_value_length_px14,
  2291. [css_key_overflowY]: css_value_misc_scroll,
  2292. [css_key_borderTop]: css_value_border_2px000f,
  2293. [css_key_userSelect]: css_value_misc_text,
  2294. [css_key_borderLeft]: css_value_border_2px000f,
  2295. }));
  2296. thnetChatWindow[2].append(make('div', {
  2297. [css_key_width]: css_value_length_perc100,
  2298. [css_key_display]: css_value_misc_flex,
  2299. [css_key_padding]: css_value_length_px5,
  2300. [css_key_paddingTop]: css_value_length_px2,
  2301. [css_key_paddingBottom]: css_value_length_px0,
  2302. [css_key_justifyContent]: css_value_misc_spaceBetween,
  2303. [css_key_height]: css_value_length_px40
  2304. }, {}, [ divs.chatinput ]))
  2305. document.body.append(divs.chatwrap = thnetChatWindow[0]);
  2306.  
  2307. applyStyle(thnetChatWindow[2], { [css_key_overflowY]: '' });
  2308. applyStyle(divs.chatwrap, { [css_key_left]: '', [css_key_right]: css_value_length_px5 });
  2309. setTimeout(applyStyle(divs.chatwrap, { [css_key_top]: (window.innerHeight - pInt(divs.chatbox.style[css_key_height])) / 2 + 'px' }));
  2310. },
  2311.  
  2312. fixWindowPositions = () => {
  2313. for (let movableWindow of movableWindows) {
  2314. let element = movableWindow.element,
  2315. rect = element.getBoundingClientRect(),
  2316. style = element.style;
  2317. if (!style[css_key_right]) {
  2318. applyStyle(element, {
  2319. [css_key_left]: max(0, min(window.innerWidth - rect[css_key_width], pInt(style[css_key_left]))) + 'px',
  2320. [css_key_top]: max(0, min(window.innerHeight - rect[css_key_height], pInt(style[css_key_top]))) + 'px'
  2321. });
  2322. }
  2323. }
  2324. },
  2325.  
  2326. refreshMenuSelect = append => {
  2327. for (let i in menus) {
  2328. if (pInt(i)) {
  2329. let menuDiv = make('div', {
  2330. [css_key_width]: css_value_length_perc100,
  2331. [css_key_padding]: css_value_length_px5,
  2332. [css_key_alignItems]: css_value_misc_center,
  2333. [css_key_borderBottom]: css_value_border_2px000f,
  2334. [css_key_justifyContent]: css_value_misc_center,
  2335. [css_key_backgroundColor]: css_value_color_8888,
  2336. [css_key_height]: menus.length - 1 == i ? css_value_length_px38 : css_value_length_px40
  2337. }, {
  2338. innerText: getLocal(menus[i][0]),
  2339. onmouseover: () => menuDiv.style[css_key_backgroundColor] = css_value_color_888c,
  2340. onmouseout: () => menuDiv.style[css_key_backgroundColor] = css_value_color_8888,
  2341. onclick: () => refreshMenu(pInt(i)),
  2342. });
  2343.  
  2344. append(menuDiv);
  2345. }
  2346. }
  2347. },
  2348.  
  2349. //PEOPLE STILL DONT READ THIS FOR SOME REASON
  2350. refreshMenuGuide = append => {
  2351. //this was going to have submenus so it would be easier to navigate
  2352. //then the cheat controls menu would have submenus aswell so it isnt just one disorganized mess
  2353. for (let entry in guide) for (let i in guide[entry]) {
  2354. let bool = i == 0;
  2355. append(make('div', {
  2356. [css_key_fontSize]: bool ? css_value_length_px30 : i & 1 ? css_value_length_px25 : css_value_length_px20,
  2357. [css_key_borderTop]: (bool && entry * 1) ? css_value_border_4px000f : '',
  2358. [css_key_paddingTop]: bool ? css_value_length_px10 : '',
  2359. [css_key_paddingLeft]: css_value_length_px5,
  2360. [css_key_marginBottom]: bool ? css_value_length_px10 : i & 1 ? css_value_length_px15 : css_value_length_px5
  2361. }, {
  2362. innerText: guide[entry][i]
  2363. }));
  2364. }
  2365. },
  2366.  
  2367. refreshMenuMenu = append => {
  2368. append(make('div', {}, {innerText: 'Coming Soon'}));
  2369. },
  2370.  
  2371. refreshMenuAimbot = append => {
  2372. let dropdowns = {
  2373. [AIMBOT_DROPDOWN_GENERAL]: AIMBOT_ENABLE + AIMBOT_AIMSMOOTHING + AIMBOT_DISABLEWHENDASHING,
  2374. [AIMBOT_DROPDOWN_ENHANCED]: AIMBOT_USEACCELERATION + AIMBOT_PINGCOMPENSATION + AIMBOT_AHEADNESSDEPTH,
  2375. [AIMBOT_DROPDOWN_CURSORPROX]: AIMBOT_CURSORMODE + AIMBOT_CURSORPROXCOSENESS,
  2376. [AIMBOT_DROPDOWN_SMART]: AIMBOT_WALLCHECK + AIMBOT_USEAHEAD + AIMBOT_AVOIDFRIENDS,
  2377. [AIMBOT_DROPDOWN_PRIORITY]: AIMBOT_RIGHTCLICKFRIEND + AIMBOT_IGNORECHATTING + AIMBOT_TARGETMODE + AIMBOT_AUXCLICKTARGET + AIMBOT_TARGETSONLY + AIMBOT_LEADERMODE,
  2378. [AIMBOT_DROPDOWN_TRIGGERBOT]: AIMBOT_TRIGGERBOT + AIMBOT_TRIGGERBOTWHENDOWN
  2379. };
  2380.  
  2381. for (let dropdown in dropdowns) {
  2382. let controls = [];
  2383. for (let setting of dropdowns[dropdown]) {
  2384. controls.push(
  2385. setting == AIMBOT_CURSORPROXCOSENESS ?
  2386. createControlValue(aimbotLabel[setting], i => aimbot[setting] = clamp(0, aimbot[setting] + 50 * i, 500), () => aimbot[setting]) :
  2387. setting == AIMBOT_AHEADNESSDEPTH ?
  2388. createControlValue(aimbotLabel[setting], i => aimbot[setting] = clamp(0, aimbot[setting] + i, 4), () => aimbot[setting] + 1) :
  2389. createControlToggle(aimbotLabel[setting], () => aimbot[setting] = 1 - aimbot[setting], () => aimbot[setting])
  2390. );
  2391. }
  2392. append(createMenuDropdown(aimbotLabel[dropdown], controls));
  2393. }
  2394. },
  2395.  
  2396. refreshMenuESP = append => {
  2397. let dropdowns = {
  2398. [ESP_DROPDOWN_CAMERA]: ESP_ZOOM + ESP_FIXCAMERA + ESP_CAMUSEREALPOSITION + ESP_SCROLLSENSITIVITY,
  2399. [ESP_DROPDOWN_TRACERS]: ESP_TRACERSBODYENEMY + ESP_TRACERSCURSORENEMY + ESP_TRACERSWALLCHECK + ESP_TRACERSGUN + ESP_TRACERSGRENADES,
  2400. [ESP_DROPDOWN_PLAYERSTATS]: ESP_SHOWHEALTH + ESP_SHOWARMOR + ESP_SHOWMAGS + ESP_SHOWGUNRELOADSTATUS + ESP_SHOWRANGE + ESP_INCLUDEYOU,
  2401. [ESP_DROPDOWN_OTHER]: ESP_SHOWINVIS + ESP_REVEALTEAMS
  2402. };
  2403.  
  2404. for (let dropdown in dropdowns) {
  2405. let controls = [];
  2406. for (let setting of dropdowns[dropdown]) {
  2407. controls.push(
  2408. setting == ESP_ZOOM ?
  2409. createControlDropdown(espLabel[setting], controlDropdownOptions[0], i => esp[setting] = i, () => esp[setting] ) :
  2410. setting == ESP_SCROLLSENSITIVITY ?
  2411. createControlValue(espLabel[setting], i => esp[setting] = clamp(1, esp[setting] + i * 0.01, 2), () => round((esp[setting] - 1) * 100)) :
  2412. createControlToggle(espLabel[setting], () => esp[setting] = 1 - esp[setting], () => esp[setting])
  2413. );
  2414. }
  2415. append(createMenuDropdown(espLabel[dropdown], controls));
  2416. }
  2417. },
  2418.  
  2419. refreshMenuMisc = append => {
  2420. let dropdowns = {
  2421. [MISC_DROPDOWN_INGAME]: MISC_AUTORELOAD + MISC_STATICHEALTH + MISC_BETTERCRATEHP + MISC_HIDECHATTING + MISC_FFACLANDISPLAY,
  2422. [MISC_DROPDOWN_DEBUG]: MISC_PINGDISPLAY + MISC_RENDERDISPLAY + MISC_POSITION,
  2423. [MISC_DROPDOWN_HUD]: MISC_STATICHUD + MISC_SHOWFEATURES + MISC_LEADERBOARDBADGES,
  2424. [MISC_DROPDOWN_OTHER]: MISC_DISABLECLOSEPOPUP
  2425. };
  2426.  
  2427. for (let dropdown in dropdowns) {
  2428. let controls = [];
  2429. for (let setting of dropdowns[dropdown]) controls.push(
  2430. setting == MISC_SHOWFEATURES ?
  2431. createControlDropdown(miscLabel[setting], controlDropdownOptions[2], i => misc[setting] = i, () => misc[setting] ) :
  2432. createControlToggle(miscLabel[setting], () => misc[setting] = 1 - misc[setting], () => misc[setting])
  2433. );
  2434. append(createMenuDropdown(miscLabel[dropdown], controls));
  2435. }
  2436. },
  2437.  
  2438. refreshMenuInstantchat = append => {
  2439. for (let setting in instantchat) if (setting !== INSTANTCHAT_CHATBINDSTEXTS) {
  2440. if (includesInArray(INSTANTCHAT_ONKILLTEXT + INSTANTCHAT_ONDEATHTEXT + INSTANTCHAT_AUTOTHANKTEXT, setting)) {
  2441. let editAutoTextInput = make('input', {
  2442. [css_key_color]: css_value_color_000f,
  2443. [css_key_width]: css_value_length_perc100,
  2444. [css_key_height]: css_value_length_px34,
  2445. [css_key_border]: css_value_border_4pxffff,
  2446. [css_key_display]: css_value_misc_flex,
  2447. [css_key_position]: css_value_misc_relative,
  2448. [css_key_alignItems]: css_value_misc_center,
  2449. [css_key_borderRadius]: css_value_length_px5,
  2450. [css_key_justifyContent]: css_value_misc_center,
  2451. [css_key_backgroundColor]: css_value_color_fffc
  2452. }, {
  2453. type: css_value_misc_text,
  2454. maxlength: setting === INSTANTCHAT_AUTOTHANKTEXT ? 32 : 38,
  2455. onfocus: () => textBoxFocused = 1,
  2456. onblur: () => textBoxFocused = 0,
  2457. oninput: () => {
  2458. instantchat[setting] = editAutoTextInput.value;
  2459. saveSettings();
  2460. },
  2461. value: instantchat[setting]
  2462. });
  2463. append(make('div', {
  2464. [css_key_width]: css_value_length_perc100,
  2465. [css_key_display]: css_value_misc_flex,
  2466. [css_key_padding]: css_value_length_px5,
  2467. [css_key_paddingTop]: css_value_length_px0,
  2468. [css_key_borderBottom]: css_value_border_3px000f,
  2469. [css_key_paddingBottom]: css_value_length_px0,
  2470. [css_key_justifyContent]: css_value_misc_spaceBetween,
  2471. [css_key_height]: css_value_length_px40
  2472. }, { title: instantchatLabel[setting][1] }, [editAutoTextInput]));
  2473. } else {
  2474. append(createControlToggle(instantchatLabel[setting], () => instantchat[setting] = 1 - instantchat[setting], () => instantchat[setting]));
  2475. }
  2476. }
  2477. let editBindInput = make('input', {
  2478. [css_key_color]: css_value_color_000f,
  2479. [css_key_width]: css_value_length_perc100,
  2480. [css_key_height]: css_value_length_px34,
  2481. [css_key_border]: css_value_border_4pxffff,
  2482. [css_key_display]: css_value_misc_flex,
  2483. [css_key_position]: css_value_misc_relative,
  2484. [css_key_alignItems]: css_value_misc_center,
  2485. [css_key_borderRadius]: css_value_length_px5,
  2486. [css_key_justifyContent]: css_value_misc_center,
  2487. [css_key_backgroundColor]: css_value_color_fffc
  2488. }, {
  2489. type: css_value_misc_text,
  2490. maxlength: 32,
  2491. onfocus: () => textBoxFocused = 1,
  2492. onblur: () => textBoxFocused = 0,
  2493. oninput: () => {
  2494. //memory leak prevention
  2495. if (selectedKey && !(instantchat[INSTANTCHAT_CHATBINDSTEXTS][selectedKey] = editBindInput.value)) delete instantchat[INSTANTCHAT_CHATBINDSTEXTS][selectedKey];
  2496. },
  2497. value: ''
  2498. }),
  2499. editBindDiv = make('div', {
  2500. [css_key_width]: css_value_length_perc100,
  2501. [css_key_display]: css_value_misc_flex,
  2502. [css_key_padding]: css_value_length_px5,
  2503. [css_key_paddingTop]: css_value_length_px2,
  2504. [css_key_borderBottom]: css_value_border_3px000f,
  2505. [css_key_paddingBottom]: css_value_length_px0,
  2506. [css_key_backgroundColor]: css_value_color_8888,
  2507. [css_key_justifyContent]: css_value_misc_spaceBetween,
  2508. [css_key_height]: css_value_length_px40
  2509. }, { title: getLocal(instantchatLabel[0]) }, [editBindInput]),
  2510. bindSelectDiv = make('div', {
  2511. [css_key_width]: css_value_length_perc100,
  2512. [css_key_display]: css_value_misc_grid,
  2513. [css_key_gridTemplateColumns]: css_value_auto_10
  2514. }), selectedBindDiv, selectedKey = 0;
  2515. for (let validKey of [0, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 66, 67, 69, 70, 71, 72, 73, 74, 75, 76, 77, 79, 80, 81, 85, 86, 88, 89, 90]) {
  2516. let bindKeyDiv = make('div', {
  2517. [css_key_display]: css_value_misc_flex,
  2518. [css_key_height]: bindSelectDiv.width / 9,
  2519. [css_key_alignItems]: css_value_misc_center,
  2520. [css_key_justifyContent]: css_value_misc_center,
  2521. [css_key_backgroundColor]: css_value_color_f80f
  2522. }, {
  2523. innerText: validKey ? ' ' + keyCodeToLetter(validKey) : ' ',
  2524. onclick: () => {
  2525. let oldDiv = selectedBindDiv;
  2526. selectedBindDiv = bindKeyDiv;
  2527. selectedKey = validKey;
  2528. oldDiv[ATTRIBUTE_UPDATE]();
  2529. bindKeyDiv[ATTRIBUTE_UPDATE]();
  2530. editBindInput.value = instantchat[INSTANTCHAT_CHATBINDSTEXTS][validKey] || '';
  2531. },
  2532. //update
  2533. [ATTRIBUTE_UPDATE]: () => applyStyle(bindKeyDiv, {
  2534. [css_key_border]: css_value_length_px2 + css_value_random_solid + (selectedBindDiv === bindKeyDiv ? css_value_color_ff0f : css_value_color_000f)
  2535. })
  2536. });
  2537. if (!validKey) selectedBindDiv = bindKeyDiv;
  2538. bindKeyDiv[ATTRIBUTE_UPDATE]();
  2539. bindSelectDiv.append(bindKeyDiv);
  2540. }
  2541. append(bindSelectDiv);
  2542. append(editBindDiv);
  2543. },
  2544.  
  2545. refreshMenuPlayermanager = append => {
  2546. let refreshPlayerManager = () => refreshMenu(7),
  2547. list = [friends, targets, muted][playermanagerSelectedMenu],
  2548. otherList = playermanagerSelectedMenu ? friends : targets,
  2549. controlAddButton = make('div', {
  2550. [css_key_width]: css_value_length_px50,
  2551. [css_key_height]: css_value_length_px34,
  2552. [css_key_color]: css_value_color_ffff,
  2553. [css_key_border]: css_value_border_4pxffff,
  2554. [css_key_display]: css_value_misc_flex,
  2555. [css_key_position]: css_value_misc_relative,
  2556. [css_key_alignItems]: css_value_misc_center,
  2557. [css_key_justifyContent]: css_value_misc_center,
  2558. [css_key_backgroundColor]: css_value_color_f80c
  2559. }, {
  2560. innerText: 'Add',
  2561. onclick: () => {
  2562. let name = sanitiseName(controlAddName.value);
  2563. if (includesInArray(list, name)) return;
  2564. if (playermanagerSelectedMenu !== 2 && includesInArray(otherList, name)) toggleUsernameInlist(otherList, name);
  2565. saveSettings(checkScrollable(refreshPlayerManager(toggleUsernameInlist(list, name))));
  2566. }
  2567. }),
  2568. controlAddName = make('input', {
  2569. [css_key_width]: css_value_length_calcperc100,
  2570. [css_key_height]: css_value_length_px34,
  2571. [css_key_color]: css_value_color_000f,
  2572. [css_key_border]: css_value_border_4pxffff,
  2573. [css_key_display]: css_value_misc_flex,
  2574. [css_key_marginLeft]: css_value_length_px5,
  2575. [css_key_position]: css_value_misc_relative,
  2576. [css_key_alignItems]: css_value_misc_center,
  2577. [css_key_justifyContent]: css_value_misc_center,
  2578. [css_key_backgroundColor]: css_value_color_fffc
  2579. }, {
  2580. type: css_value_misc_text,
  2581. onfocus: () => textBoxFocused = 1,
  2582. onblur: () => textBoxFocused = 0,
  2583. oninput: () => controlAddName.value = controlAddName.value.replace(/[^0-9a-zA-Z ]/g, '').slice(0, 12),
  2584. value: ''
  2585. }),
  2586. controlAdd = make('div', {
  2587. [css_key_width]: css_value_length_perc100,
  2588. [css_key_display]: css_value_misc_flex,
  2589. [css_key_padding]: css_value_length_px5,
  2590. [css_key_paddingTop]: css_value_length_px2,
  2591. [css_key_borderBottom]: css_value_border_3px000f,
  2592. [css_key_paddingBottom]: css_value_length_px0,
  2593. [css_key_backgroundColor]: css_value_color_8888,
  2594. [css_key_justifyContent]: css_value_misc_spaceBetween,
  2595. [css_key_height]: css_value_length_px40
  2596. }, {
  2597. title: playerManagerLabel[3][playermanagerSelectedMenu]
  2598. }, [controlAddButton, controlAddName]),
  2599. submenus = [];
  2600. for (let i = 0; i < 3; i++) {
  2601. submenus[i] = make('div', {
  2602. [css_key_width]: css_value_length_calcperc33,
  2603. [css_key_padding]: css_value_length_px5,
  2604. [css_key_alignItems]: css_value_misc_center,
  2605. [css_key_borderBottom]: css_value_border_3px000f,
  2606. [css_key_borderRight]: (i == playerManagerLabel.length - 1) ? '' : css_value_border_3px000f,
  2607. [css_key_paddingBottom]: css_value_length_px0,
  2608. [css_key_paddingTop]: css_value_length_px0,
  2609. [css_key_justifyContent]: css_value_misc_center,
  2610. [css_key_backgroundColor]: css_value_color_8888,
  2611. [css_key_display]: css_value_misc_flex,
  2612. [css_key_position]: css_value_misc_relative,
  2613. [css_key_height]: css_value_length_px40
  2614. }, {
  2615. innerText: getLocal(playerManagerLabel[i][0]),
  2616. title: getLocal(playerManagerLabel[i][1]),
  2617. onclick: () => refreshPlayerManager(playermanagerSelectedMenu = i)
  2618. });
  2619. }
  2620. append(make('div', {}, {}, [make('div', {
  2621. [css_key_width]: css_value_length_perc100,
  2622. [css_key_display]: css_value_misc_flex
  2623. }, {}, submenus), controlAdd]));
  2624.  
  2625. for (let username of list) {
  2626. let entryNameDiv = make('div', {
  2627. [css_key_userSelect]: css_value_misc_text
  2628. }, {
  2629. innerText: username
  2630. }),
  2631. entryButtonDiv = make('div', {
  2632. [css_key_width]: css_value_length_px30,
  2633. [css_key_height]: css_value_length_px30,
  2634. [css_key_border]: css_value_border_4pxffff,
  2635. [css_key_display]: css_value_misc_flex,
  2636. [css_key_position]: css_value_misc_relative,
  2637. [css_key_alignItems]: css_value_misc_center,
  2638. [css_key_justifyContent]: css_value_misc_center,
  2639. [css_key_backgroundColor]: css_value_color_f00c
  2640. }, {
  2641. innerText: 'X',
  2642. onclick: () => refreshPlayerManager(toggleUsernameInlist(list, username))
  2643. }),
  2644. entryDiv = make('div', {
  2645. [css_key_width]: css_value_length_perc100,
  2646. [css_key_display]: css_value_misc_flex,
  2647. [css_key_padding]: css_value_length_px5,
  2648. [css_key_borderBottom]: css_value_border_2px000f,
  2649. [css_key_paddingBottom]: css_value_length_px0,
  2650. [css_key_justifyContent]: css_value_misc_spaceBetween,
  2651. [css_key_height]: css_value_length_px40
  2652. }, {}, [entryNameDiv, entryButtonDiv]);
  2653.  
  2654. append(entryDiv);
  2655. }
  2656. },
  2657.  
  2658. //this menu was a serious pain in the ass
  2659. refreshMenuUpgrades = append => {
  2660. append(createControlToggle(autoUpgradesLabel[0], () => autoUpgrades[0] = 1 - autoUpgrades[0], () => autoUpgrades[0]));
  2661.  
  2662. let upgradeslotsDivs = [],
  2663. perkSelectDiv = make('div', {
  2664. [css_key_width]: ' 100%',
  2665. [css_key_display]: css_value_misc_grid,
  2666. [css_key_gridTemplateColumns]: css_value_auto_5
  2667. });
  2668.  
  2669. for (let i = 1; i < 4; i++) {
  2670. let upgradeNameDiv = make('div'),
  2671. perkSlotImageDiv = make('div', {
  2672. [css_key_width]: css_value_length_px30,
  2673. [css_key_height]: css_value_length_px30,
  2674. [css_key_border]: css_value_border_2px000f,
  2675. [css_key_padding]: css_value_length_px0,
  2676. [css_key_verticalAlign]: css_value_length_px0,
  2677. [css_key_backgroundColor]: css_value_color_4448
  2678. }),
  2679. upgradeSlotDiv = make('div', {
  2680. [css_key_width]: css_value_length_perc100,
  2681. [css_key_padding]: css_value_length_px5,
  2682. [css_key_display]: css_value_misc_flex,
  2683. [css_key_borderBottom]: css_value_border_2px000f,
  2684. [css_key_paddingBottom]: css_value_length_px0,
  2685. [css_key_justifyContent]: css_value_misc_spaceBetween,
  2686. [css_key_height]: css_value_length_px40
  2687. }, {
  2688. onclick: () => {
  2689. perkSelectDiv.p(selectedPerkSlot = i);
  2690. for (let slot of upgradeslotsDivs) slot.f();
  2691. }
  2692. }, [upgradeNameDiv, perkSlotImageDiv]);
  2693.  
  2694. //b = update
  2695. //this is abstracted because closure compiler doesnt
  2696. upgradeSlotDiv.b = (perk, boolean) => {
  2697. upgradeNameDiv.innerText = perkNames[perk] || getLocal(autoUpgradesLabel[1]);
  2698. removeChildren(perkSlotImageDiv);
  2699. if (perk && j30[perk]) perkSlotImageDiv.append(dupeImg(j30[perk]));
  2700. };
  2701. upgradeSlotDiv.b(autoUpgrades[i], 1);
  2702.  
  2703. //f = update visually
  2704. //this is abstracted because closure compiler doesnt
  2705. upgradeSlotDiv.f = () => upgradeSlotDiv.style[css_key_backgroundColor] = i == selectedPerkSlot ? css_value_color_888c : css_value_color_8886;
  2706. upgradeSlotDiv.f();
  2707.  
  2708. upgradeslotsDivs.push(upgradeSlotDiv);
  2709. }
  2710.  
  2711. //p = update
  2712. //this is abstracted because closure compiler doesnt
  2713. perkSelectDiv.p = perkLevel => {
  2714. removeChildren(perkSelectDiv);
  2715. let perksToDisplay = perkLevel === 2 ? abilities : perks,
  2716. perkLevelOther = 4 - perkLevel;
  2717. for (let perk of perksToDisplay) {
  2718. let perkImageDiv = make('div', {
  2719. [css_key_border]: css_value_length_px2 + css_value_random_solid + (autoUpgrades[perkLevel] === perk ? css_value_color_ff0f : css_value_color_000f),
  2720. [css_key_height]: perkSelectDiv.width / 4
  2721. }, {
  2722. onclick: () => {
  2723. //if this perk is already set, clear it
  2724. upgradeslotsDivs[perkLevel - 1].b(autoUpgrades[perkLevel] = autoUpgrades[perkLevel] === perk ? '' : perk);
  2725.  
  2726. //if the other setting is equal, clear it
  2727. if (perkLevelOther !== 2 && autoUpgrades[perkLevel] && autoUpgrades[perkLevelOther] === autoUpgrades[perkLevel]) {
  2728. upgradeslotsDivs[perkLevelOther - 1].b(autoUpgrades[perkLevelOther] = '');
  2729. }
  2730.  
  2731. //alternatively you can update just the perk selects that actually change but this is easier to do soo...
  2732. perkSelectDiv.p(perkLevel);
  2733.  
  2734. saveSettings();
  2735. }
  2736. }, [j30[perk]]);
  2737. perkSelectDiv.append(perkImageDiv);
  2738. }
  2739. };
  2740. perkSelectDiv.p(selectedPerkSlot);
  2741. for (let div of upgradeslotsDivs) append(div);
  2742. append(perkSelectDiv);
  2743. },
  2744.  
  2745. refreshMenuSpammer = append => {
  2746. append(createControlToggle(scrollerLabel[0], () => {
  2747. if (!chatSpam[CHATSPAMMER_TIMEOUT]) {
  2748. startChatScrolling(multiBox[MULTIBOX_SELECTEDSOCKET]);
  2749. } else {
  2750. stopChatScrolling(multiBox[MULTIBOX_SELECTEDSOCKET]);
  2751. sendChatMessage(multiBox[MULTIBOX_SELECTEDSOCKET], ' ');
  2752. }
  2753. }, () => chatSpam[CHATSPAMMER_TIMEOUT]));
  2754.  
  2755. //makes sure the values don't go past a certain unsafe point
  2756. let maxLength = (str, max) => str.replace(/\n/g, '').slice(0, max),
  2757. clampValues = () => {
  2758. chatSpam[CHATSPAMMER_WIDTH] = clamp(5, chatSpam[CHATSPAMMER_WIDTH], 30);
  2759. chatSpam[CHATSPAMMER_DIRECTION] = clamp(-5, chatSpam[CHATSPAMMER_DIRECTION], 5);
  2760. chatSpam[CHATSPAMMER_INTERVAL] = clamp(25, chatSpam[CHATSPAMMER_INTERVAL], 1000);
  2761. chatSpam[CHATSPAMMER_SEPERATOR] = maxLength(chatSpam[CHATSPAMMER_SEPERATOR], 5);
  2762. chatSpam[CHATSPAMMER_TEXT] = maxLength(chatSpam[CHATSPAMMER_TEXT], 99999);
  2763. chatSpam[CHATSPAMMER_PAUSEPERIOD] = clamp(500, chatSpam[CHATSPAMMER_PAUSEPERIOD], 10000);
  2764. chatSpam[CHATSPAMMER_PREFIX] = maxLength(chatSpam[CHATSPAMMER_PREFIX], 25 - chatSpam[CHATSPAMMER_SUFFIX].length);
  2765. chatSpam[CHATSPAMMER_SUFFIX] = maxLength(chatSpam[CHATSPAMMER_SUFFIX], 25 - chatSpam[CHATSPAMMER_PREFIX].length);
  2766. saveSettings();
  2767. };
  2768. clampValues();
  2769.  
  2770. for (let attribute of CHATSPAMMER_WIDTH + CHATSPAMMER_DIRECTION + CHATSPAMMER_INTERVAL + CHATSPAMMER_PAUSEPERIOD) append(createControlValue(scrollerLabel[attribute],
  2771. i => clampValues(chatSpam[attribute] += (CHATSPAMMER_PAUSEPERIOD == attribute ? 500 : CHATSPAMMER_INTERVAL == attribute ? 25 : 1) * i),
  2772. () => chatSpam[attribute] / (attribute == CHATSPAMMER_PAUSEPERIOD ? 1000 : 1)
  2773. ));
  2774.  
  2775. for (let attribute of CHATSPAMMER_SEPERATOR + CHATSPAMMER_TEXT + CHATSPAMMER_PREFIX + CHATSPAMMER_SUFFIX) {
  2776. let controlTextNameDiv = make('div', {
  2777. [css_key_marginTop]: css_value_length_px3,
  2778. [css_key_marginRight]: css_value_length_px8,
  2779. [css_key_display]: css_value_misc_flex
  2780. }, { innerText: scrollerLabel[attribute][0]}),
  2781. controlTextInputDiv = make('input', {
  2782. [css_key_width]: attribute == CHATSPAMMER_TEXT ? css_value_length_calcperc102 : css_value_length_px70,
  2783. [css_key_height]: css_value_length_px34,
  2784. [css_key_color]: css_value_color_000f,
  2785. [css_key_border]: css_value_border_4pxffff,
  2786. [css_key_display]: css_value_misc_flex,
  2787. [css_key_position]: css_value_misc_relative,
  2788. [css_key_alignItems]: css_value_misc_center,
  2789. [css_key_justifyContent]: css_value_misc_center,
  2790. [css_key_backgroundColor]: css_value_color_fffc
  2791. }, {
  2792. type: css_value_misc_text,
  2793. oninput: () => {
  2794. chatSpam[attribute] = controlTextInputDiv.value;
  2795. clampValues();
  2796. controlTextInputDiv.value = chatSpam[attribute];
  2797. },
  2798. onfocus: () => textBoxFocused = 1,
  2799. onblur: () => textBoxFocused = 0,
  2800. value: chatSpam[attribute]
  2801. }),
  2802. controlTextDiv = make('div', {
  2803. [css_key_width]: css_value_length_perc100,
  2804. [css_key_display]: css_value_misc_flex,
  2805. [css_key_padding]: css_value_length_px5,
  2806. [css_key_paddingTop]: css_value_length_px2,
  2807. [css_key_borderBottom]: css_value_border_2px000f,
  2808. [css_key_paddingBottom]: css_value_length_px0,
  2809. [css_key_justifyContent]: css_value_misc_spaceBetween,
  2810. [css_key_height]: css_value_length_px40
  2811. }, { title: scrollerLabel[attribute][1] }, [controlTextNameDiv, controlTextInputDiv]);
  2812. append(controlTextDiv);
  2813. }
  2814. },
  2815.  
  2816. refreshMenuAntiAim = append => {
  2817. let clampValues = () => {
  2818. antiAim[ANTIAIM_ANGLESTART] = (360 + antiAim[ANTIAIM_ANGLESTART]) % 360;
  2819. antiAim[ANTIAIM_ANGLERANGE] = (365 + antiAim[ANTIAIM_ANGLERANGE]) % 365;
  2820. antiAim[ANTIAIM_SPINSPEED] = clamp(-180, antiAim[ANTIAIM_SPINSPEED], 180);
  2821. antiAim[ANTIAIM_DELAY] = clamp(1, antiAim[ANTIAIM_DELAY], 62);
  2822. };
  2823.  
  2824. //toggleable settings
  2825. for (let attribute of ANTIAIM_RELOAD + ANTIAIM_SHOOT + ANTIAIM_IDLE + ANTIAIM_DRAWREALAIM) append(createControlToggle(antiAimLabel[attribute], () => antiAim[attribute] = 1 - antiAim[attribute], () => antiAim[attribute]));
  2826.  
  2827. //number settings
  2828. for (let attribute of ANTIAIM_ANGLESTART + ANTIAIM_ANGLERANGE + ANTIAIM_SPINSPEED + ANTIAIM_DELAY) append(createControlValue(antiAimLabel[attribute], i => clampValues(antiAim[attribute] += (includesInArray(ANTIAIM_ANGLESTART + ANTIAIM_ANGLERANGE, attribute) ? 5 : 1) * i), () => antiAim[attribute]));
  2829.  
  2830. updateMenuCanvas = (me, offset, players, crates) => {
  2831. if (divs.menu.hidden) return;
  2832. let angle1 = (antiAim[ANTIAIM_ANGLESTART] + tickCount * antiAim[ANTIAIM_SPINSPEED]) * degToRad,
  2833. angle2 = angle1 + antiAim[ANTIAIM_ANGLERANGE] * degToRad,
  2834. length = me[ATTRIBUTE_RADIUS] * 1.5 + 20;
  2835. drawLine2(me, {
  2836. x: length * sin(angle1),
  2837. y: length * cos(angle1)
  2838. }, offset, 2, '#f00');
  2839. drawLine2(me, {
  2840. x: length * sin(angle2),
  2841. y: length * cos(angle2)
  2842. }, offset, 2, '#00f');
  2843. ctx.lineWidth = 1;
  2844. ctx.beginPath();
  2845. //fuck this shit
  2846. ctx.arc(me.x + offset.x, me.y + offset.y, length, -angle1 + TAU / 4, -angle2 + TAU / 4, true);
  2847. ctx.stroke();
  2848. };
  2849. },
  2850.  
  2851. refreshMenuPerkHacks = append => {
  2852. append(createMenuDropdown(perkHacksLabel[0], [
  2853. createControlToggle(perkHacksLabel[PERKHACKS_KNIFE], () => perkHacks[PERKHACKS_KNIFE] = 1 - perkHacks[PERKHACKS_KNIFE], () => perkHacks[PERKHACKS_KNIFE]),
  2854. createControlValue(perkHacksLabel[PERKHACKS_KNIFEMAXRANGE], i => perkHacks[PERKHACKS_KNIFEMAXRANGE] = clamp(20, perkHacks[PERKHACKS_KNIFEMAXRANGE] + 10 * i, 300), () => perkHacks[PERKHACKS_KNIFEMAXRANGE])
  2855. ]));
  2856. append(createMenuDropdown(perkHacksLabel[1], [
  2857. createControlToggle(perkHacksLabel[PERKHACKS_SHIELD], () => perkHacks[PERKHACKS_SHIELD] = 1 - perkHacks[PERKHACKS_SHIELD], () => perkHacks[PERKHACKS_SHIELD]),
  2858. createControlValue(perkHacksLabel[PERKHACKS_SHIELDUPKEEP], i => perkHacks[PERKHACKS_SHIELDUPKEEP] = clamp(0, perkHacks[PERKHACKS_SHIELDUPKEEP] + i, 50), () => perkHacks[PERKHACKS_SHIELDUPKEEP]),
  2859. createControlValue(perkHacksLabel[PERKHACKS_SHIELDLOOKAHEAD], i => perkHacks[PERKHACKS_SHIELDLOOKAHEAD] = clamp(0, perkHacks[PERKHACKS_SHIELDLOOKAHEAD] + i, 10), () => perkHacks[PERKHACKS_SHIELDLOOKAHEAD]),
  2860. createControlToggle(perkHacksLabel[PERKHACKS_SHIELDMANUAL], () => perkHacks[PERKHACKS_SHIELDMANUAL] = 1 - perkHacks[PERKHACKS_SHIELDMANUAL], () => perkHacks[PERKHACKS_SHIELDMANUAL]),
  2861. createControlDropdown(perkHacksLabel[PERKHACKS_SHIELDVISUALISER], controlDropdownOptions[3], i => perkHacks[PERKHACKS_SHIELDVISUALISER] = i, () => perkHacks[PERKHACKS_SHIELDVISUALISER]),
  2862. createControlToggle(perkHacksLabel[PERKHACKS_SHIELDWALLCHECK], () => perkHacks[PERKHACKS_SHIELDWALLCHECK] = 1 - perkHacks[PERKHACKS_SHIELDWALLCHECK], () => perkHacks[PERKHACKS_SHIELDWALLCHECK])
  2863. ]));
  2864. append(createMenuDropdown(perkHacksLabel[2], [
  2865. createControlToggle(perkHacksLabel[PERKHACKS_CRATEPLACEVISION], () => perkHacks[PERKHACKS_CRATEPLACEVISION] = 1 - perkHacks[PERKHACKS_CRATEPLACEVISION], () => perkHacks[PERKHACKS_CRATEPLACEVISION]),
  2866. //createControlToggle(perkHacksLabel[PERKHACKS_MEDKITSELFHEAL], () => perkHacks[PERKHACKS_MEDKITSELFHEAL] = 1 - perkHacks[PERKHACKS_MEDKITSELFHEAL], () => perkHacks[PERKHACKS_MEDKITSELFHEAL]),
  2867. //createControlValue(perkHacksLabel[PERKHACKS_MEDKITSELFHEALTHRESHOLD], i => perkHacks[PERKHACKS_MEDKITSELFHEALTHRESHOLD] = clamp(5, perkHacks[PERKHACKS_MEDKITSELFHEALTHRESHOLD] + i * 5, 100), () => perkHacks[PERKHACKS_MEDKITSELFHEALTHRESHOLD]),
  2868. ]));
  2869. },
  2870.  
  2871. refreshMenuPaint = append => {
  2872. let dropdowns = {
  2873. [PAINT_GRID]: PAINT_GRIDSPACEX + PAINT_GRIDSPACEY + PAINT_GRIDLINEWIDTHHORIZONTAL + PAINT_GRIDLINEWIDTHVERTICAL + PAINT_GRIDCOLOR,
  2874. [PAINT_POINTS]: PAINT_POINTSIDLE + PAINT_POINTSFFA + PAINT_POINTSBLU + PAINT_POINTSRED + PAINT_POINTEDGEWIDTH,
  2875. [PAINT_CRATES]: PAINT_CRATESHOWHPMODE + PAINT_CRATESQUARE + PAINT_CRATELONG + PAINT_CRATEUSER + PAINT_CRATEPREMIUM + PAINT_CRATECORPSE
  2876. };
  2877.  
  2878. for (let dropdown in dropdowns) {
  2879. let controls = [];
  2880. for (let setting of dropdowns[dropdown]) {
  2881. let control;
  2882. switch (setting) {
  2883. case PAINT_CRATESHOWHPMODE:
  2884. control = createControlDropdown(paintLabel[PAINT_CRATESHOWHPMODE],
  2885. controlDropdownOptions[1],
  2886. x => paint[PAINT_CRATESHOWHPMODE] = x,
  2887. () => paint[PAINT_CRATESHOWHPMODE]);
  2888. break;
  2889.  
  2890. case PAINT_POINTEDGEWIDTH:
  2891. control = createControlValue(paintLabel[PAINT_POINTEDGEWIDTH],
  2892. i => paint[PAINT_POINTEDGEWIDTH] = clamp(0, paint[PAINT_POINTEDGEWIDTH] + i, 20),
  2893. () => paint[PAINT_POINTEDGEWIDTH]
  2894. );
  2895. break;
  2896.  
  2897. case PAINT_GRIDLINEWIDTHHORIZONTAL:
  2898. control = createControlValue(paintLabel[PAINT_GRIDLINEWIDTHHORIZONTAL],
  2899. i => paint[PAINT_GRIDLINEWIDTHHORIZONTAL] = clamp(0, paint[PAINT_GRIDLINEWIDTHHORIZONTAL] + i, 10),
  2900. () => paint[PAINT_GRIDLINEWIDTHHORIZONTAL]
  2901. );
  2902. break;
  2903.  
  2904. case PAINT_GRIDLINEWIDTHVERTICAL:
  2905. control = createControlValue(paintLabel[PAINT_GRIDLINEWIDTHVERTICAL],
  2906. i => paint[PAINT_GRIDLINEWIDTHVERTICAL] = clamp(0, paint[PAINT_GRIDLINEWIDTHVERTICAL] + i, 10),
  2907. () => paint[PAINT_GRIDLINEWIDTHVERTICAL]
  2908. );
  2909. break;
  2910.  
  2911. case PAINT_GRIDSPACEX:
  2912. control = createControlValue(paintLabel[PAINT_GRIDSPACEX],
  2913. i => paint[PAINT_GRIDSPACEX] = clamp(2, paint[PAINT_GRIDSPACEX] + i, 500),
  2914. () => paint[PAINT_GRIDSPACEX]
  2915. );
  2916. break;
  2917.  
  2918. case PAINT_GRIDSPACEY:
  2919. control = createControlValue(paintLabel[PAINT_GRIDSPACEY],
  2920. i => paint[PAINT_GRIDSPACEY] = clamp(2, paint[PAINT_GRIDSPACEY] + i, 500),
  2921. () => paint[PAINT_GRIDSPACEY]
  2922. );
  2923. break;
  2924.  
  2925. default:
  2926. control = createControlColor(paintLabel[setting], paint[setting]);
  2927. }
  2928. controls.push(control);
  2929. }
  2930. append(createMenuDropdown(paintLabel[dropdown], controls));
  2931. }
  2932. append(createControlButton(paintLabel[0], () => {
  2933. if (prompt(paintLabel[0], paintLabel[1]) == 'yes') paint = {
  2934. [PAINT_GRIDSPACEX]: 20,
  2935. [PAINT_GRIDSPACEY]: 20,
  2936. [PAINT_GRIDLINEWIDTHHORIZONTAL]: 1,
  2937. [PAINT_GRIDLINEWIDTHVERTICAL]: 1,
  2938. [PAINT_GRIDCOLOR]: ['#e3e3e8', '#efeff5'],
  2939. [PAINT_POINTSIDLE]: ['#aaaaaa', '#f9f9f9'],
  2940. [PAINT_POINTSFFA]: ['#00cc66', '#f9f9f9'],
  2941. [PAINT_POINTSBLU]: ['#8dd8f8', '#f9f9f9'],
  2942. [PAINT_POINTSRED]: ['#f26740', '#f9f9f9'],
  2943. [PAINT_POINTEDGEWIDTH]: 4,
  2944. [PAINT_CRATESHOWHPMODE]: 2,
  2945. [PAINT_CRATESQUARE]: ['#808080', '#dfbf9f'],
  2946. [PAINT_CRATELONG]: ['#808080', '#bec8dd'],
  2947. [PAINT_CRATEUSER]: ['#808080', '#53c68c'],
  2948. [PAINT_CRATEPREMIUM]: ['#2e2d2d', '#f0ba37']
  2949. }
  2950. saveSettings();
  2951. }));
  2952. let presetElements = [];
  2953. for (let preset of paint[PAINT_PRESETS]) {
  2954.  
  2955. presetElements.push(createControlBase(preset, [make("div", {
  2956. [css_key_border]: css_value_border_3pxffff,
  2957. [css_key_backgroundColor]: css_value_color_00fc
  2958. //TODO: add css
  2959. }, {
  2960. innerText: '⇑', //TODO: find good character
  2961. onclick: () => {
  2962. if (paint[PAINT_CHANGEDSOMETHING] && prompt(paintLabel[0], paintLabel[1]) == 'yes') saveSettings(paint = {
  2963. [PAINT_GRIDSPACEX]: preset[ 2],
  2964. [PAINT_GRIDSPACEY]: preset[ 3],
  2965. [PAINT_GRIDLINEWIDTHHORIZONTAL]: preset[ 4],
  2966. [PAINT_GRIDLINEWIDTHVERTICAL]: preset[ 5],
  2967. [PAINT_GRIDCOLOR]: [ preset[ 6], preset[ 7] ],
  2968. [PAINT_POINTSIDLE]: [ preset[ 8], preset[ 9] ],
  2969. [PAINT_POINTSFFA]: [ preset[10], preset[11] ],
  2970. [PAINT_POINTSBLU]: [ preset[12], preset[13] ],
  2971. [PAINT_POINTSRED]: [ preset[14], preset[15] ],
  2972. [PAINT_POINTEDGEWIDTH]: preset[16],
  2973. [PAINT_CRATESHOWHPMODE]: preset[17],
  2974. [PAINT_CRATESQUARE]: [ preset[18], preset[19] ],
  2975. [PAINT_CRATELONG]: [ preset[20], preset[21] ],
  2976. [PAINT_CRATEUSER]: [ preset[22], preset[23] ],
  2977. [PAINT_CRATEPREMIUM]: [ preset[24], preset[25] ]
  2978. })
  2979. }
  2980. }, [])]));
  2981. }
  2982. append(createMenuDropdown(paintLabel[PAINT_PRESETMANAGER], [
  2983. createControlButton(paintLabel[PAINT_PRESETMANAGERSAVE]),
  2984. createControlButton(paintLabel[PAINT_PRESETMANAGERIMPORT]),
  2985. createControlButton(paintLabel[PAINT_PRESETMANAGEREXPORT]),
  2986. createMenuDropdown(paintLabel[PAINT_PRESETMANAGERPRESETS], presetElements)
  2987. ]));
  2988. },
  2989.  
  2990. refreshMenuRecorder = append => {
  2991. //a game recorder similar to nitrogem's recorder but it works offline and doesn't need an iframe to play
  2992. //it back since it just plays back server packets while making the game think it is connected to one
  2993. append(make('div', {}, {
  2994. innerText: 'Coming Soon'
  2995. }));
  2996. },
  2997.  
  2998. //L, find a solution that works
  2999. refreshMenuDiscordRPC = append => {
  3000. append(createControlToggle(discordRPCLabel[DISCORDRPC_ENABLED], () => {
  3001. discordRPC[DISCORDRPC_ENABLED] = !discordRPC[DISCORDRPC_ENABLED];
  3002. if (discordRPC[DISCORDRPC_ENABLED]) {
  3003. //TODO: login to discord rpc
  3004. discordRPCStart();
  3005. } else if (discordRPC[DISCORDRPC_CONNECTION]) {
  3006. discordRPCActivityClear();
  3007. discordRPC[DISCORDRPC_CONNECTION].close();
  3008. }
  3009. }, () => discordRPC[DISCORDRPC_ENABLED]));
  3010.  
  3011. append(createControlText(discordRPCLabel[DISCORDRPC_STATE], str => discordRPC[DISCORDRPC_STATE] = str, () => discordRPC[DISCORDRPC_STATE]));
  3012. append(createControlText(discordRPCLabel[DISCORDRPC_DETAILS], str => discordRPC[DISCORDRPC_DETAILS] = str, () => discordRPC[DISCORDRPC_DETAILS]));
  3013. append(createControlValue(discordRPCLabel[DISCORDRPC_UPDATEINTERVAL], i => discordRPC[DISCORDRPC_UPDATEINTERVAL] = clamp(15, discordRPC[DISCORDRPC_UPDATEINTERVAL] + i, 60), () => discordRPC[DISCORDRPC_UPDATEINTERVAL]));
  3014. },
  3015.  
  3016. refreshMenuTHNet = append => {
  3017. append(createControlToggle(THNetLabel[THNET_ENABLE], () => {
  3018. thnet[THNET_ENABLE] = !thnet[THNET_ENABLE];
  3019. if (c3 !== null) {
  3020. if (thnet[THNET_ENABLE]) {
  3021. connectToTHNet();
  3022. } else if (thnet[THNET_SOCKET]) {
  3023. thnet[THNET_CLOSEREASON] = 'Manual';
  3024. thnet[THNET_SOCKET].close();
  3025. }
  3026. }
  3027. }, () => thnet[THNET_ENABLE]));
  3028. append(createControlToggle(THNetLabel[THNET_INFOSHARE], () => (thnet[THNET_INFOSHARE] = 1 - thnet[THNET_INFOSHARE]) || thnet[THNET_SOCKET].send('1'), () => thnet[THNET_INFOSHARE]));
  3029. append(createControlToggle(THNetLabel[THNET_CHAT], () => thnet[THNET_CHAT] = 1 - (divs.chatwrap.hidden = 1 - divs.chatwrap.hidden), () => thnet[THNET_CHAT]));
  3030. let rules = [];
  3031. for (let i = 0; i < THNetLabel[1].length; i++) rules[i] = make('div', {
  3032. [css_key_paddingTop]: css_value_length_px5
  3033. }, {
  3034. innerText: THNetLabel[1][i]
  3035. });
  3036. append(createMenuDropdown(THNetLabel[0], rules));
  3037. },
  3038.  
  3039. refreshMenuWeird = append => {
  3040. for (let setting in weird) append(createControlToggle(weirdLabel[setting], () => weird[setting] = 1 - weird[setting], () => weird[setting]));
  3041. },
  3042.  
  3043. refreshMenuAdvanced = append => {
  3044. for (let setting in advanced) {
  3045. let control;
  3046. switch (setting) {
  3047. case ADVANCED_TPS:
  3048. control = createControlToggle(advancedLabel[setting], () => advanced[setting] = advanced[setting] === 2.5 ? 1 : 2.5, () => advanced[setting] === 1);
  3049. break;
  3050. case ADVANCED_OPTIMISEWALLCHECK:
  3051. control = createControlToggle(advancedLabel[setting], () => advanced[setting] = 1 - advanced[setting], () => advanced[setting]);
  3052. break;
  3053. case ADVANCED_PINGCOUNT:
  3054. control = createControlValue(advancedLabel[setting], i => advanced[setting] = clamp(1, advanced[setting] + i, 50), () => advanced[setting]);
  3055. break;
  3056. case ADVANCED_PINGCOMP:
  3057. control = createControlValue(advancedLabel[setting], i => advanced[setting] = clamp(1, advanced[setting] + i, 100), () => advanced[setting]);
  3058. break;
  3059. case ADVANCED_AIMCONSTANT:
  3060. control = createControlValue(advancedLabel[setting], i => advanced[setting] = parseFloat(clamp(0.5, advanced[setting] + 0.05 * i, 2.5).toFixed(2)), () => advanced[setting]);
  3061. }
  3062. append(control);
  3063. }
  3064. append(createControlButton(advancedLabel[0], () => {
  3065. for (let server of RF.list) server.socket.close();
  3066. }));
  3067. append(createControlButton(advancedLabel[1], () => localStorage.removeItem('TioHax_bootloader')));
  3068. append(createControlButton(advancedLabel[2], () => {
  3069. if (prompt("Are you sure that you want to clear all TioHax settings? This cannot be undone! Type 'yes' if you want to proceed:", "no") == 'yes' &&
  3070. prompt("ARE YOU ABSOLUTELY SURE that you want to clear ALL TioHax settings!? Your current settings will be lost forever if you do this!! Type 'yes' again if you absolutely want to proceed:", "no") == 'yes'
  3071. ) {
  3072. localStorage.removeItem('TioHax_settings');
  3073. location.reload();
  3074. }
  3075. }));
  3076. append(createControlText(THNetLabel[THNET_AUTH], str => thnet[THNET_AUTH] = str, () => thnet[THNET_AUTH]));
  3077. },
  3078.  
  3079. refreshMenuCredits = append => {
  3080. for (let entry of credits) for (let i in entry) {
  3081. let bool = i == 0;
  3082. append(make('div', {
  3083. [css_key_fontSize]: bool ? css_value_length_px30 : i & 1 ? css_value_length_px25 : css_value_length_px20,
  3084. [css_key_borderTop]: bool ? css_value_border_4px000f : '',
  3085. [css_key_marginTop]: bool ? css_value_length_px10 : i & 1 ? css_value_length_px15 : css_value_length_px5,
  3086. [css_key_paddingTop]: bool ? css_value_length_px10 : '',
  3087. [css_key_paddingLeft]: css_value_length_px5
  3088. }, { innerText: entry[i] }));
  3089. }
  3090. },
  3091.  
  3092. pingDisplay = () => {
  3093.  
  3094. //starts at 5 padding so it isn't directly on the screen's edge, looks nicer
  3095. let pingTextPadding = 5,
  3096. fallbackText = 'Not Connected',
  3097. pingSocket = RF.list[0] || {
  3098. currentPing: fallbackText,
  3099. [ATTRIBUTE_AVERAGEPING]: fallbackText,
  3100. [ATTRIBUTE_MAXPING]: fallbackText,
  3101. [ATTRIBUTE_MINPING]: fallbackText
  3102. },
  3103. pingTexts = [
  3104. 'Ping: ' + pingSocket.currentPing + ' ms',
  3105. 'Avg.: ' + round(pingSocket[ATTRIBUTE_AVERAGEPING]) + ' ms',
  3106. 'Max: ' + pingSocket[ATTRIBUTE_MAXPING] + ' ms',
  3107. 'Min: ' + pingSocket[ATTRIBUTE_MINPING] + ' ms'
  3108. ];
  3109.  
  3110. //if we're in a game or not
  3111. if (b21 || c28) {
  3112. pingTextPadding += 10;
  3113. //second padding for the VIP tag
  3114. if (selfPremiumMember) pingTextPadding += 35;
  3115.  
  3116. //second padding for the username text
  3117. if (b3 || b4) {
  3118. ctx.font = '14px Arial';
  3119. pingTextPadding += ceil(ctx.measureText((b3 ? 'Logged in' : 'Playing') + ' as ' + b4).width);
  3120. }
  3121. }
  3122. ctx.font = 'bold 16px consolas';
  3123.  
  3124. //draw the ping number
  3125. for (let i = 0; i < pingTexts.length; i++) drawText(pingTextPadding, 16 + (i * 17), pingTexts[i], '#fff');
  3126.  
  3127. //return the padding for the render time so we dont draw the render time text over server ping text
  3128. return pingTextPadding + ceil(ctx.measureText(pingTexts[2]).width);
  3129. },
  3130.  
  3131. renderDisplay = (renderDisplayPadding) => {
  3132. ctx.font = 'bold 16px consolas';
  3133. let texts = [
  3134. 'Render time: ' + renderTime + 'ms',
  3135. spacePadding('FPS: ', 13) + min(1000 / renderTime, 25 * advanced[ADVANCED_TPS]).toFixed(renderTime > 500 ? 2 : 1)
  3136.  
  3137. ];
  3138. drawText(renderDisplayPadding, 16, texts[0], '#fff');
  3139. drawText(renderDisplayPadding, 32, texts[1], '#fff');
  3140. return ceil(ctx.measureText(texts[0].length > texts[1].length ? texts[0] : texts[1]).width);
  3141. },
  3142.  
  3143. coordsDisplay = (renderDisplayPadding, me) => {
  3144. ctx.font = 'bold 16px consolas';
  3145. let texts = [
  3146. 'Pos: x:' + spacePadding(me.x, 7) + ' y: ' + spacePadding(me.y, 7),
  3147. 'Vel: x:' + spacePadding(me.spdX, 7) + ' y: ' + spacePadding(me.spdY, 7),
  3148. 'Acc: x:' + spacePadding(me[ATTRIBUTE_ACCX].toFixed(1), 7) + ' y: ' + spacePadding(me[ATTRIBUTE_ACCY].toFixed(1), 7)
  3149. ], y = 16, longest = '';
  3150. for (let text of texts) {
  3151. drawText(renderDisplayPadding, y, text, '#fff');
  3152. y += 17;
  3153. if (longest.length < text.length) longest = text;
  3154. }
  3155. return ceil(ctx.measureText(longest).width);
  3156. },
  3157.  
  3158. getEnemies = (me, players) => {
  3159.  
  3160. //enemies: enemy players which will be aimed at
  3161. //enemy friends: enemy players which are friended
  3162. let enemies = [], enemyFriends = [];
  3163.  
  3164. for (let player of players) {
  3165.  
  3166. //dont aimbot at invincible players or at team mates
  3167. if (player.invincible || (player.teamCode && player.teamCode == me.teamCode)) continue;
  3168.  
  3169. //dont aimbot at the developer of this cheat
  3170. if (player[ATTRIBUTE_USERNAMEHASH] === developerHash ||
  3171. //dont aimbot at chatting people if that setting is enabled
  3172. (aimbot[AIMBOT_IGNORECHATTING] && player.chatBoxOpen) ||
  3173. //dont aimbot at people the aimbot is not supposted to shoot at
  3174. includesInArray(friends, player[ATTRIBUTE_SANITIZEDNAME]) ||
  3175. //dont aimbot at other tiohax users
  3176. includesInArray(thnet[THNET_BROTHERS], player[ATTRIBUTE_USERNAMEHASH])
  3177. ) {
  3178. enemyFriends.push(player);
  3179. } else {
  3180. enemies.push(player);
  3181. }
  3182. }
  3183.  
  3184. return { [ATTRIBUTE_ENEMIES]: enemies, [ATTRIBUTE_ENEMYFRIENDS]: enemyFriends };
  3185. },
  3186.  
  3187. getDistanceSquared = (me, enemy, offset) => ((me.x - offset.x) - enemy.x) ** 2 + ((me.y - offset.y) - enemy.y) ** 2,
  3188.  
  3189. //calculate where someone will be with respect to how long it takes to get there
  3190. calcAheadness = (me, enemy, distance, gun, count = aimbot[AIMBOT_AHEADNESSDEPTH]) => {
  3191.  
  3192. if (count) distance = getDistanceSquared(me, calcAheadness(me, enemy, distance, gun, count - 1), nullPos);
  3193.  
  3194. let x = enemy.x,
  3195. y = enemy.y;
  3196.  
  3197. //mathematical
  3198. distance = (sqrt(distance) - offsets[gun]) / (velocities[gun] * advanced[ADVANCED_AIMCONSTANT]);
  3199.  
  3200. //aim a bit more ahead depending on the connection, since some server ticks may have happened during transport
  3201. if (aimbot[AIMBOT_PINGCOMPENSATION]) {
  3202. distance += ceil(RF.list[0][ATTRIBUTE_AVERAGEPING] / advanced[ADVANCED_PINGCOMP]);
  3203. }
  3204.  
  3205. //Formula for 'Pos + Vel + Acc + Time => New Pos': (np = new pos, p = pos, v = vel, t = time, a = acc) np = (p) + (v * t) + (0.5 * a * t²)
  3206. //https://math.stackexchange.com/questions/4538784/formula-for-predicting-next-position-does-not-include-maximum-velocity-is-there/4538831#4538831
  3207. //TODO: fix when a player just stops going in one direction that the bot thinks it is going in the opposite direction
  3208. if (aimbot[AIMBOT_USEACCELERATION]) {
  3209. let maxXvel = me[ATTRIBUTE_USABLEACCX] ? me[ATTRIBUTE_USABLEACCX] * 8 : me[ATTRIBUTE_USABLESPDX],
  3210. maxYvel = me[ATTRIBUTE_USABLEACCY] ? me[ATTRIBUTE_USABLEACCY] * 8 : me[ATTRIBUTE_USABLESPDY];
  3211. if (distance > (maxXvel - me[ATTRIBUTE_USABLESPDX]) / me[ATTRIBUTE_USABLEACCX]) {
  3212. x += maxXvel * distance - ((maxXvel - me[ATTRIBUTE_USABLESPDX]) ** 2) / (me[ATTRIBUTE_USABLEACCX] ? 2 * me[ATTRIBUTE_USABLEACCX] : Infinity);
  3213. x += maxYvel * distance - ((maxYvel - me[ATTRIBUTE_USABLESPDY]) ** 2) / (me[ATTRIBUTE_USABLEACCY] ? 2 * me[ATTRIBUTE_USABLEACCY] : Infinity);
  3214. } else {
  3215. x += enemy[ATTRIBUTE_USABLESPDX] * distance + 0.5 * me[ATTRIBUTE_USABLEACCX] * (distance ** 2);
  3216. x += enemy[ATTRIBUTE_USABLESPDY] * distance + 0.5 * me[ATTRIBUTE_USABLEACCY] * (distance ** 2);
  3217. }
  3218. } else {
  3219. x += enemy[ATTRIBUTE_USABLESPDX] * distance;
  3220. y += enemy[ATTRIBUTE_USABLESPDY] * distance;
  3221. }
  3222.  
  3223. return {x, y};
  3224. },
  3225.  
  3226. wouldHitWall = (me, enemy, crates, gun) => {
  3227.  
  3228. //TODO: move the MAAAAAAAAAAAAAATH to a function
  3229. let enemyPos = aimbot[AIMBOT_USEAHEAD] ? calcAheadness(me, enemy, getDistanceSquared(me, enemy, nullPos), gun) : enemy,
  3230. relPos = {
  3231. x: enemyPos.x - me.x,
  3232. y: enemyPos.y - me.y
  3233. },
  3234. possibleAngle = atan2(relPos.y, relPos.x) + asin(18 / sqrt(relPos.x ** 2 + relPos.y ** 2)),
  3235. handAngle = 0 - (TAU * 0.6 + possibleAngle),
  3236. gunOffset = offsets[gun] + velocities[gun] - 14,
  3237. gunAngle = 0 - (TAU * 0.75 + possibleAngle),
  3238. gunEnd = {
  3239. x: me.x + sin(handAngle) * me[ATTRIBUTE_RADIUS] + sin(gunAngle) * gunOffset,
  3240. y: me.y + cos(handAngle) * me[ATTRIBUTE_RADIUS] + cos(gunAngle) * gunOffset
  3241. },
  3242. inclusionBox = {
  3243. x: (gunEnd.x + enemyPos.x) / 2,
  3244. y: (gunEnd.y + enemyPos.y) / 2,
  3245. z: sqrt(getDistanceSquared(gunEnd.x, enemyPos.x, nullPos)) / 2
  3246. },
  3247. hitCrates = [[gunEnd, enemyPos]];
  3248.  
  3249. wallcheckoptimise: {
  3250. for (let i = 0; i < crates.length; i++) {
  3251. let crate = crates[i];
  3252.  
  3253. //avoid calculating collisions if it would just be a waste
  3254. if (!crate[ATTRIBUTE_BULLETCOLLISIONS] || getDistanceSquared(inclusionBox, crate, nullPos) > (inclusionBox.z + crate[ATTRIBUTE_HITBOXRADIUS]) ** 2) continue;
  3255.  
  3256. //if the crate intersects with the line, add them to the list of crates that have been hit
  3257. //works by checking if the line from the gun end to the enemy position collides with any line from the crate hitbox
  3258. for (let j = 0; j < crate[ATTRIBUTE_HITBOX].length; j++) {
  3259. if (collisionLineLine(
  3260. gunEnd.x, gunEnd.y,
  3261. enemyPos.x, enemyPos.y,
  3262. crate.x + crate[ATTRIBUTE_HITBOX][j][0], crate.y + crate[ATTRIBUTE_HITBOX][j][1],
  3263. crate.x + crate[ATTRIBUTE_HITBOX][j][2], crate.y + crate[ATTRIBUTE_HITBOX][j][3]
  3264. ) || collisionLineLine(
  3265. enemy.x, enemy.y,
  3266. enemyPos.x, enemyPos.y,
  3267. crate.x + crate[ATTRIBUTE_HITBOX][j][0], crate.y + crate[ATTRIBUTE_HITBOX][j][1],
  3268. crate.x + crate[ATTRIBUTE_HITBOX][j][2], crate.y + crate[ATTRIBUTE_HITBOX][j][3]
  3269. )) {
  3270. hitCrates.push(crate);
  3271. if (advanced[ADVANCED_OPTIMISEWALLCHECK]) break wallcheckoptimise;
  3272. break;
  3273. }
  3274. }
  3275. }
  3276. }
  3277. return hitCrates;
  3278. },
  3279.  
  3280. couldHitFriend = (me, enemy, enemyFriends, gun) => {
  3281.  
  3282. //TODO: move the MAAAAAAAAAAAAAATH to a function
  3283. let enemyPos = aimbot[AIMBOT_USEAHEAD] ? calcAheadness(me, enemy, getDistanceSquared(me, enemy, nullPos), gun) : enemy.getAttr(), //the onlytime this method is ever needed...
  3284. relPos = {
  3285. x: enemyPos.x - me.x,
  3286. y: enemyPos.y - me.y
  3287. },
  3288. possibleAngle = atan2(relPos.y, relPos.x) + asin(18 / sqrt(relPos.x ** 2 + relPos.y ** 2)),
  3289. handAngle = 0 - (TAU * 0.6 + possibleAngle),
  3290. gunOffset = offsets[gun] + velocities[gun] - 14,
  3291. gunAngle = 0 - (TAU * 0.75 + possibleAngle),
  3292. gunEnd = {
  3293. x: me.x + sin(handAngle) * me[ATTRIBUTE_RADIUS] + sin(gunAngle) * gunOffset,
  3294. y: me.y + cos(handAngle) * me[ATTRIBUTE_RADIUS] + cos(gunAngle) * gunOffset
  3295. },
  3296. factor = (gunOffset + ranges[gun] * velocities[gun]) / sqrt(getDistanceSquared(me, enemyPos, nullPos));
  3297. enemyPos.x *= factor;
  3298. enemyPos.y *= factor;
  3299.  
  3300. for (let i = 0; i < enemyFriends.length; i++) {
  3301. let friend = enemyFriends[i],
  3302. offset = {x: -c2.x, y: -c2.y},
  3303. //scale radius based on distance
  3304. //TODO: this is goofy af, add stuff for speed and acceleration, make sure it also knows how far bullets can even go with ranges[gun] * velocities[gun]
  3305. radius = friend[ATTRIBUTE_RADIUS] * sqrt(max(1, (getDistanceSquared(me, friend, nullPos) - getDistanceSquared(me, gunEnd, nullPos)) / (velocities[gun] * 2.5))),
  3306. canHit = distanceSquaredLinePoint(
  3307. gunEnd.x, gunEnd.y,
  3308. enemyPos.x, enemyPos.y,
  3309. friend.x, friend.y,
  3310. ) < radius ** 2;
  3311. drawCircle(friend, offset, radius, 2, canHit ? '#888' : '#aaa');
  3312. if (canHit) return 1;
  3313. }
  3314. },
  3315.  
  3316. //NOTE: all distances calculated here are left squared because it is not required for them to be square-rooted until later on
  3317. getTarget = (me, offset, enemies, enemyFriends, crates, minRange, maxRange, gun) => {
  3318.  
  3319. //two of those will be returned and one of those will be used in the distance check
  3320. let includeOnlyTargets = aimbot[AIMBOT_TARGETSONLY],
  3321. smallestDistanceToPoint = aimbot[AIMBOT_CURSORMODE] && aimbot[AIMBOT_CURSORPROXCOSENESS] ? aimbot[AIMBOT_CURSORPROXCOSENESS] ** 2 : Infinity,
  3322. distanceToMe, distanceToPoint, enemy, distance,
  3323. c = {x: j9[0], y: j9[1]};
  3324. for (let currentEnemy of enemies) {
  3325. //compare distances and check if the current enemy to check is closer
  3326. distanceToMe = getDistanceSquared(me, currentEnemy, nullPos);
  3327.  
  3328. //or closer to the mouse if that setting is enabled
  3329. if (aimbot[AIMBOT_CURSORMODE]) {
  3330. distanceToPoint = getDistanceSquared(c, currentEnemy, offset);
  3331.  
  3332. //draws lines from cursor to enemies
  3333. if (esp[ESP_TRACERSCURSORENEMY]) drawLine(c, currentEnemy, offset, 1, '#888');
  3334. } else {
  3335. distanceToPoint = distanceToMe;
  3336. }
  3337.  
  3338. if (aimbot[AIMBOT_WALLCHECK]) {
  3339. let hitCrates = wouldHitWall(me, currentEnemy, crates, gun);
  3340.  
  3341. if (esp[ESP_TRACERSWALLCHECK]) {
  3342. let pos = hitCrates[0];
  3343. ctx.globalAlpha = hitCrates.length > 1 ? 1 : 0.5;
  3344. drawLineWrap(
  3345. pos[0].x + offset.x, pos[0].y + offset.y,
  3346. pos[1].x + offset.x, pos[1].y + offset.y,
  3347. 2,
  3348. '#888'
  3349. );
  3350. ctx.globalAlpha = 0.5;
  3351. for (let i = 1; i < hitCrates.length; i++) hitCrates[i][ATTRIBUTE_FILLHITBOX]();
  3352. ctx.globalAlpha = 1;
  3353. }
  3354.  
  3355. //NOTE: first hitCrates element is not a crate, it is the raycast line
  3356. if (hitCrates.length > 1) continue;
  3357. }
  3358.  
  3359. //if the enemy is too close or far for the gun to hit, completely disregard them
  3360. if (distanceToMe < minRange || distanceToPoint > maxRange) continue;
  3361.  
  3362. let isATarget = includesInArray(targets, currentEnemy[ATTRIBUTE_SANITIZEDNAME]);
  3363.  
  3364. //if (aimbot[AIMBOT_LEADERMODE] && currentEnemy.isLeader) return {[ATTRIBUTE_ENEMY]: currentEnemy, [ATTRIBUTE_DISTANCE]: distanceToMe};
  3365. //if (aimbot[AIMBOT_LEADERMODE] && currentEnemy.isLeader) break;
  3366.  
  3367. if (includeOnlyTargets && !isATarget) continue;
  3368. if (aimbot[AIMBOT_TARGETMODE] && isATarget && !includeOnlyTargets) {
  3369. includeOnlyTargets = 1;
  3370. smallestDistanceToPoint = aimbot[AIMBOT_CURSORMODE] ? aimbot[AIMBOT_CURSORPROXCOSENESS] ** 2 : Infinity;
  3371. }
  3372.  
  3373. if (distanceToPoint > smallestDistanceToPoint) continue;
  3374. if (aimbot[AIMBOT_AVOIDFRIENDS] && couldHitFriend(me, currentEnemy, enemyFriends, gun)) continue;
  3375.  
  3376. smallestDistanceToPoint = distanceToPoint;
  3377. distance = distanceToMe;
  3378. enemy = currentEnemy;
  3379. }
  3380.  
  3381. //a visualiser so you know whats close to your cursor
  3382. if (aimbot[AIMBOT_CURSORMODE]) {
  3383. if (enemy) drawLine(c, enemy, offset, 2, '#888');
  3384. let radius = sqrt(smallestDistanceToPoint);
  3385. ctx.beginPath();
  3386. ctx.moveTo(c.x + radius, c.y);
  3387. ctx.arc(c.x, c.y, radius, 0, TAU);
  3388. ctx.stroke();
  3389. }
  3390.  
  3391. return {[ATTRIBUTE_ENEMY]: enemy, [ATTRIBUTE_DISTANCE]: distance};
  3392. },
  3393.  
  3394. aimTorwards = (me, enemy, offset, distance, gun) => {
  3395.  
  3396. //not accounting for velocity when the enemy is dashing is mostly a better idea
  3397. if (!enemy.dashing) enemy = calcAheadness(me, enemy, distance, gun);
  3398.  
  3399. //if too close to player move the position to aim at somewhat away so it doesnt break
  3400. distance = sqrt(getDistanceSquared(me, enemy, nullPos));
  3401. if (distance < 50) {
  3402. distance = 50 / distance;
  3403. enemy.x -= me.x;
  3404. enemy.y -= me.y;
  3405. enemy.x *= distance;
  3406. enemy.y *= distance;
  3407. enemy.x += me.x;
  3408. enemy.y += me.y;
  3409. }
  3410.  
  3411. //immitate mouse cursor movement
  3412. return {
  3413. clientX: enemy.x + offset.x,
  3414. clientY: enemy.y + offset.y
  3415. };
  3416. },
  3417.  
  3418. setNameVariations = (player, username) => {
  3419. player[ATTRIBUTE_USERNAMEHASH] = hashString(player[ATTRIBUTE_SANITIZEDNAME] = sanitiseName(player[ATTRIBUTE_TAGGEDNAME] = player[ATTRIBUTE_USERNAME] = username));
  3420. if (c22 == 'FFA' && !player[ATTRIBUTE_TAGGEDNAME].startsWith('Guest ')) {
  3421. if (player[ATTRIBUTE_USERNAME] in clanTagCache) {
  3422. if (clanTagCache[player[ATTRIBUTE_USERNAME]]) {
  3423. player[ATTRIBUTE_TAGGEDNAME] = '[' + clanTagCache[player[ATTRIBUTE_USERNAME]] + '] ' + player[ATTRIBUTE_TAGGEDNAME];
  3424. }
  3425. } else {
  3426. fetchFromServer('clanof/' + player[ATTRIBUTE_TAGGEDNAME])
  3427. .then(clanTag => {
  3428. clanTagCache[player[ATTRIBUTE_USERNAME]] = clanTag;
  3429. if (clanTag) player[ATTRIBUTE_TAGGEDNAME] = '[' + clanTag + '] ' + player[ATTRIBUTE_TAGGEDNAME];
  3430. });
  3431. }
  3432. }
  3433. },
  3434.  
  3435. doAimbotThings = (me, offset, enemies, enemyFriends, crates, gunMinRange, playerScreenPos, gun) => {
  3436. let target = {[ATTRIBUTE_ENEMY]: undefVar, [ATTRIBUTE_DISTANCE]: undefVar};
  3437. if (!aimbot[AIMBOT_ENABLE]) return target;
  3438.  
  3439. drawCircle(me, offset, 10, 2, '#000');
  3440. if (aimbot[AIMBOT_TARGETSONLY]) drawCircle(me, offset, 15, 2, 'gray');
  3441.  
  3442. if (me.dashing && aimbot[AIMBOT_DISABLEWHENDASHING]) return target;
  3443.  
  3444. target = getTarget(me, offset, enemies, enemyFriends, crates, gunMinRange, Infinity, gun);
  3445. if (target[ATTRIBUTE_ENEMY]) {
  3446. if (!perkHacks[PERKHACKS_TICK]) aimMeAt(aimTorwards(me, target[ATTRIBUTE_ENEMY], offset, target[ATTRIBUTE_DISTANCE], gun), 1);
  3447. if (esp[ESP_TRACERSBODYENEMY]) drawLine(playerScreenPos, target[ATTRIBUTE_ENEMY], offset, 3);
  3448. }
  3449.  
  3450. return target;
  3451. },
  3452.  
  3453. hideAim = (me, offset, animationSubtraction) => {
  3454. if (me.dashing) return;
  3455. if (!(
  3456. (antiAim[ANTIAIM_IDLE] && !(me.reloading || me.shooting || cursor.isShooting)) ||
  3457. (antiAim[ANTIAIM_RELOAD] && me.reloading && me.reloadingAnimation && (me.reloadingFrame < me.reloadingAnimation.length - animationSubtraction)) ||
  3458. (antiAim[ANTIAIM_SHOOT] && me.shooting && me.shootingAnimation && (me.shootingFrame < me.shootingAnimation.length - animationSubtraction))
  3459. )) return;
  3460. if (0 === tickCount % antiAim[ANTIAIM_DELAY]) {
  3461. let angle = (antiAim[ANTIAIM_ANGLESTART] + antiAim[ANTIAIM_ANGLERANGE] * random() + tickCount * antiAim[ANTIAIM_SPINSPEED]) * degToRad,
  3462. ahead = me[ATTRIBUTE_RADIUS] * 2;
  3463. antiAim[ANTIAIM_SAVEDX] = me.x + offset.x + ahead * sin(angle);
  3464. antiAim[ANTIAIM_SAVEDY] = me.y + offset.y + ahead * cos(angle);
  3465. }
  3466. aimMeAt({
  3467. clientX: antiAim[ANTIAIM_SAVEDX],
  3468. clientY: antiAim[ANTIAIM_SAVEDY]
  3469. }, 1, 1);
  3470. },
  3471.  
  3472. showFeatures = () => {
  3473. ctx.font = 'bold 20px consolas';
  3474. let maxX = j1 * 2 - 5,
  3475. maxY = c2 ? floor(1.725 * j2) : (j2 * 2 - 30),
  3476. tracers = esp[ESP_TRACERSBODYENEMY] || esp[ESP_TRACERSCURSORENEMY] || esp[ESP_TRACERSWALLCHECK] || esp[ESP_TRACERSGUN] || esp[ESP_TRACERSGRENADES],
  3477. playerAttribs = esp[ESP_SHOWHEALTH] || esp[ESP_SHOWARMOR] || esp[ESP_SHOWMAGS] || esp[ESP_SHOWGUNRELOADSTATUS] || esp[ESP_SHOWRANGE],
  3478. things = [
  3479. [
  3480. chatSpam[CHATSPAMMER_TIMEOUT],
  3481. 'Chat Spammer',
  3482. ],[
  3483. misc[MISC_FFACLANDISPLAY],
  3484. 'FFA Clan Display',
  3485. ],[
  3486. chatSpam[CHATSPAMMER_TIMEOUT],
  3487. 'Chat Scroller',
  3488. ],[
  3489. esp[ESP_SHOWINVIS] || esp[ESP_REVEALTEAMS],
  3490. 'Invis Reveal',
  3491. ],[
  3492. misc[MISC_AUTORELOAD],
  3493. 'Auto Reload',
  3494. ],[
  3495. perkHacks[PERKHACKS_KNIFE] || perkHacks[PERKHACKS_SHIELD] || perkHacks[PERKHACKS_CRATEPLACEVISION],
  3496. 'Perk Hacks',
  3497. perkHacks[PERKHACKS_KNIFE] ? 'KnifeBot' : '',
  3498. perkHacks[PERKHACKS_SHIELD] ? 'ShieldBot' : '',
  3499. perkHacks[PERKHACKS_CRATEPLACEVISION] ? 'Build & Medkit' : ''
  3500. ],[
  3501. antiAim[ANTIAIM_RELOAD] || antiAim[ANTIAIM_SHOOT] || antiAim[ANTIAIM_IDLE],
  3502. 'Anti Aim',
  3503. ],[
  3504. aimbot[AIMBOT_ENABLE],
  3505. 'Aimbot',
  3506. aimbot[AIMBOT_WALLCHECK] ? 'Wall Check' : '',
  3507. aimbot[AIMBOT_TARGETSONLY] ? 'Targets Only' : '',
  3508. aimbot[AIMBOT_CURSORMODE] ? 'Cursor Prox' : '',
  3509. aimbot[AIMBOT_TRIGGERBOT] ? 'Triggerbot' + (aimbot[AIMBOT_TRIGGERBOTWHENDOWN] ? ', Mouse Down' : '') : ''
  3510. ],[
  3511. esp[ESP_ZOOM] || esp[ESP_FIXCAMERA],
  3512. 'Camera',
  3513. esp[ESP_ZOOM] ? 'Zoom' : '',
  3514. esp[ESP_FIXCAMERA] ? 'Fix' : ''
  3515. ],[
  3516. tracers || playerAttribs,
  3517. 'ESP',
  3518. tracers ? 'Tracers' : '',
  3519. playerAttribs ? 'Player Attributes' : ''
  3520. ],[
  3521. thnet[THNET_ENABLE],
  3522. 'THNet',
  3523. thnet[THNET_SOCKET].readyState != WebSocket.OPEN ? 'Not Connected' : '',
  3524. thnet[THNET_INFOSHARE] ? 'Info Share' : ''
  3525. ]
  3526. ];
  3527. for (let [should, head, ...ext] of things) if (should) {
  3528. let rainbowText = head,
  3529. grayText = '',
  3530. pad = 0;
  3531. for (let e of ext) if (e) grayText += ' (' + e + ')';
  3532. if (misc[MISC_SHOWFEATURES] == 1) {
  3533. rainbowText += grayText;
  3534. grayText = '';
  3535. }
  3536. pad = ctx.measureText(grayText).width;
  3537. drawText(maxX - ctx.measureText(rainbowText).width - pad, maxY - 10, rainbowText, 'hsl(' + round(tickCount * third + (maxY - j7) / E) % 360 + ', 100%, 50%)');
  3538. drawText(maxX - ctx.measureText(grayText).width, maxY - 10, grayText, '#888');
  3539. maxY -= 20;
  3540. }
  3541. },
  3542.  
  3543. drawTracers = (players, playerScreenPos, offset, animationSubtraction) => {
  3544. for (let player of players) {
  3545.  
  3546. //if they have no bullets and they arent reloading, assume they have max bullets
  3547. //because the server doesnt send accurate currentbullets info unless the other players update their bullet count in any way
  3548. if (!player.reloading && player.currentBullets == 0) player.currentBullets = player.maxBullets;
  3549.  
  3550. //the tracer
  3551. if (esp[ESP_TRACERSBODYENEMY]) drawLine(playerScreenPos, player, offset, 1);
  3552.  
  3553. let ringColor;
  3554. //congrats, you're playing with the dev of this cheat
  3555. if (player[ATTRIBUTE_USERNAMEHASH] == developerHash) {
  3556. ctx.globalAlpha = third * 2;
  3557. ringColor = 'blue';
  3558.  
  3559. //make a light blue circle to signify fellow tiohax users
  3560. } else if (includesInArray(thnet[THNET_BROTHERS], player[ATTRIBUTE_USERNAMEHASH])) {
  3561. ctx.globalAlpha = third;
  3562. ringColor = 'blue';
  3563.  
  3564. //make a red circle to tell targets apart
  3565. } else if (includesInArray(targets, player[ATTRIBUTE_SANITIZEDNAME])) {
  3566. ctx.globalAlpha = third;
  3567. ringColor = 'red';
  3568.  
  3569. //make a dark circle to tell friends apart
  3570. } else if (includesInArray(friends, player[ATTRIBUTE_SANITIZEDNAME])) {
  3571. ctx.globalAlpha = third * 2;
  3572. ringColor = '#000';
  3573.  
  3574. //show that they wont be shot at because they are chatting and the ignorechatting option is enabled
  3575. } else if (aimbot[AIMBOT_IGNORECHATTING] && player.chatBoxOpen) {
  3576. ctx.globalAlpha = third;
  3577. ringColor = '#000';
  3578. }
  3579.  
  3580. if (ringColor) drawCircle(player, offset, player[ATTRIBUTE_RADIUS] * 1.4, 5, ringColor);
  3581.  
  3582. //dont make the health value text transparent
  3583. ctx.globalAlpha = 1;
  3584.  
  3585. //draw the health values (hp and armor) either above or below the player
  3586. //could be more elegant, but ehh
  3587. let x = player.x + offset.x - player[ATTRIBUTE_RADIUS],
  3588. y = player.y + offset.y - (player[ATTRIBUTE_RADIUS] + 6);
  3589.  
  3590. //move health text further down if the player is chatting and above the upper half of the screen
  3591. //figuring out the exact offset values took 2 whole days of trial and error for some reason.
  3592. if (esp[ESP_SHOWHEALTH]) {
  3593. drawText(x, y, player.hp, getColor(player)); //drawText(x, y, spacePadding(player.hp), getColor(player));
  3594. y -= 20;
  3595. }
  3596. if (esp[ESP_SHOWARMOR]) {
  3597. drawText(x, y, player.armorAmount, '#666'); //drawText(x, y, spacePadding(player.armorAmount), '#666');
  3598. y -= 20;
  3599. }
  3600. if (esp[ESP_SHOWMAGS]) {
  3601. drawText(x, y, player.currentBullets + '/' + player.maxBullets, '#000'); //drawText(x, y, spacePadding(player.currentBullets) + '/' + player.maxBullets, '#000');
  3602. y -= 20;
  3603. }
  3604. if (esp[ESP_SHOWGUNRELOADSTATUS] && player.reloading) drawText(x, y, 'RELOADING ' + spacePadding(percentify(player.reloadingAnimation ? player.reloadingFrame / (player.reloadingAnimation.length - animationSubtraction) : 0)), '#888');
  3605. if (esp[ESP_SHOWRANGE]) {
  3606. let gun = gunMap[player.class], range = ranges[gun] * velocities[gun];
  3607. ctx.globalAlpha = 1;
  3608. drawCircle2(player, offset, sqrt((range * mathSin) ** 2 + (range * 0.5 + player[ATTRIBUTE_RADIUS]) ** 2), 3);
  3609. ctx.globalAlpha = 1;
  3610. drawCircle2(player, offset, sqrt((range * 1.5 * mathSin) ** 2 + (range * 0.75 + player[ATTRIBUTE_RADIUS]) ** 2), 3);
  3611. ctx.globalAlpha = 1;
  3612. }
  3613. }
  3614. },
  3615.  
  3616. drawTeamAffiliations = offset => {
  3617. //draw team affiliations of various stuff
  3618. if (!esp[ESP_REVEALTEAMS]) return;
  3619. for (let item of getPool(RA)) {
  3620. if (!item.activated) continue;
  3621.  
  3622. //landmines
  3623. if (item.type == 'landMine') {
  3624. drawCircle(item, offset, 20, 2);
  3625. continue;
  3626. }
  3627. //gas
  3628. if (item.emitting) {
  3629. drawCircle(item, offset, item.emissionRadius, 2);
  3630. continue;
  3631. }
  3632. //grenades
  3633. drawCircle(item, offset, 10, 2);
  3634.  
  3635. if (!esp[ESP_TRACERSGRENADES] || item.timeAlive > item.travelTime) continue;
  3636.  
  3637. //a line from where they are to roughly where they will be
  3638. let factor = (item.travelTime - (item.timeAlive + item[ATTRIBUTE_TIMEALIVEEXTRA])) * advanced[ADVANCED_TPS];
  3639. item[ATTRIBUTE_TIMEALIVEEXTRA] += third;
  3640. drawLine2(item, {x: item.spdX * factor, y: item.spdY * factor}, offset, 1);
  3641. }
  3642.  
  3643. //reveal team affiliations of knifes
  3644. for (let knife of getPool(RC)) if (knife.activated && knife.isKnife) drawCircle(knife, offset, 5, 2);
  3645. },
  3646.  
  3647. perkHacksActionKnife = (me, socketId, offset, enemies, enemyFriends, crates) => {
  3648. if (!perkHacks[PERKHACKS_KNIFE]) return;
  3649.  
  3650. let range = me[ATTRIBUTE_RADIUS] + perkHacks[PERKHACKS_KNIFEMAXRANGE],
  3651. gun = 6, // 6 is knife
  3652. target = getTarget(me, offset, enemies, enemyFriends, crates, me[ATTRIBUTE_RADIUS] ** 2, range ** 2, gun);
  3653. drawCircle(me, offset, range, 3, '#f88');
  3654.  
  3655. if (target[ATTRIBUTE_ENEMY] && target[ATTRIBUTE_DISTANCE] < range ** 2) {
  3656. aimMeAt(aimTorwards(me, target[ATTRIBUTE_ENEMY], offset, target[ATTRIBUTE_DISTANCE], gun), 1, 1);
  3657. if (perkHacks[PERKHACKS_TICK]) {
  3658. startActivePerk(socketId);
  3659. } else {
  3660. stopActivePerk(socketId);
  3661. }
  3662. perkHacks[PERKHACKS_TICK] = 1;
  3663.  
  3664. } else {
  3665. perkHacks[PERKHACKS_TICK] = 0;
  3666. }
  3667. },
  3668.  
  3669. perkHacksActionShield = (me, socketId, playerScreenPos, offset, crates, animationSubtraction) => {
  3670. if (!perkHacks[PERKHACKS_SHIELD]) return;
  3671.  
  3672. let closestBullet = 0,
  3673. shortestDistance = SHIELD_RANGE ** 2,
  3674. chosenAngle = 0.,
  3675. factor = animationSubtraction + perkHacks[PERKHACKS_SHIELDLOOKAHEAD],
  3676. futurePos = calcAheadness(me, me, 0, 0);
  3677.  
  3678. futurePos.x = me.x + (me.x - futurePos.x);
  3679. futurePos.y = me.y + (me.y - futurePos.y);
  3680.  
  3681. if (perkHacks[PERKHACKS_SHIELDVISUALISER] & 1) {
  3682. drawCircle(futurePos, offset, SHIELD_RANGE, 2, '#000');
  3683. drawCircle(futurePos, offset, 30, 2, '#000');
  3684. }
  3685.  
  3686. //look for the best bullet to block
  3687. for (let bullet of getPool(RC)) {
  3688. if (bullet.ownerId === me.id || (bullet.teamCode && bullet.teamCode == me.teamCode) ||
  3689. getDistanceSquared(bullet, me, nullPos) < 30 ** 2
  3690. ) continue;
  3691. let lineEnd = {
  3692. x: bullet.spdX * factor + bullet.length * cos(bullet.angle * degToRad),
  3693. y: bullet.spdY * factor + bullet.length * sin(bullet.angle * degToRad)
  3694. },
  3695. distance = distanceSquaredLinePoint(
  3696. bullet.x, bullet.y,
  3697. bullet.x + lineEnd.x, bullet.y + lineEnd.y,
  3698. futurePos.x, futurePos.y
  3699. );
  3700.  
  3701. if (perkHacks[PERKHACKS_SHIELDVISUALISER] > 1) drawLine2(bullet, lineEnd, offset, 1, '#ddd');
  3702.  
  3703. //if closer than the current closest bullet
  3704. if (distance > shortestDistance) continue;
  3705.  
  3706. //ignore bullets that would have to go through a wall
  3707. if (perkHacks[PERKHACKS_SHIELDWALLCHECK]) {
  3708. let hasToHit = 0;
  3709. for (let i = 0; i < crates.length; i++) {
  3710. let crate = crates[i];
  3711.  
  3712. //avoid calculating collisions if it would just be a waste
  3713. if (!crate[ATTRIBUTE_BULLETCOLLISIONS] || getDistanceSquared(inclusionBox, crate, nullPos) > (inclusionBox.z + crate[ATTRIBUTE_HITBOXRADIUS]) ** 2) continue;
  3714.  
  3715. //if the crate intersects with the line, add them to the list of crates that have been hit
  3716. //works by checking if the line from the gun end to the enemy position collides with any line from the crate hitbox
  3717. let wallIntersect = 0;
  3718. for (let j = 0; j < crate[ATTRIBUTE_HITBOX].length; j++) {
  3719.  
  3720. //find out where the wall is currently intersecting
  3721. let currentIntersect = intersectionPointLineLine(
  3722. bullet.x, bullet.y,
  3723. bullet.x + lineEnd.x, bullet.y + lineEnd.y,
  3724. crate.x + crate[ATTRIBUTE_HITBOX][j][0], crate.y + crate[ATTRIBUTE_HITBOX][j][1],
  3725. crate.x + crate[ATTRIBUTE_HITBOX][j][2], crate.y + crate[ATTRIBUTE_HITBOX][j][3]
  3726. );
  3727.  
  3728. //if we are intersecting, we have hit something
  3729. if (currentIntersect) {
  3730. hasToHit = 1;
  3731.  
  3732. //get the intersection point that is closer to the bullet
  3733. if (wallIntersect) {
  3734. if (getDistanceSquared(currentIntersect, bullet, nullPos) > getDistanceSquared(wallIntersect, bullet, nullPos)) {
  3735. wallIntersect = currentIntersect;
  3736. }
  3737. } else {
  3738. wallIntersect = currentIntersect;
  3739. }
  3740. }
  3741. }
  3742. }
  3743.  
  3744. //
  3745.  
  3746. if (hasToHit) continue;
  3747. }
  3748.  
  3749. closestBullet = bullet;
  3750. shortestDistance = distance;
  3751. }
  3752.  
  3753. if (closestBullet) {
  3754. if (!perkHacks[PERKHACKS_SHIELDMANUAL]) startActivePerk(socketId);
  3755. perkHacks[PERKHACKS_TICK] = perkHacks[PERKHACKS_SHIELDUPKEEP] * 2.5;
  3756. chosenAngle = perkHacks[PERKHACKS_STOREDANGLE] = atan2(-closestBullet.spdY, -closestBullet.spdX);
  3757.  
  3758. } else if (perkHacks[PERKHACKS_TICK] > 0 && (perkHacks[PERKHACKS_TICK] -= 2.5 / advanced[ADVANCED_TPS])) {
  3759. chosenAngle = perkHacks[PERKHACKS_STOREDANGLE];
  3760. if (!perkHacks[PERKHACKS_SHIELDMANUAL]) startActivePerk(socketId);
  3761.  
  3762. } else {
  3763. if (!perkHacks[PERKHACKS_SHIELDMANUAL]) stopActivePerk(socketId);
  3764. perkHacks[PERKHACKS_TICK] = perkHacks[PERKHACKS_STOREDANGLE] = 0;
  3765. return;
  3766. }
  3767. aimMeAt({
  3768. clientX: playerScreenPos.x + 50 * cos(perkHacks[PERKHACKS_STOREDANGLE]),
  3769. clientY: playerScreenPos.y + 50 * sin(perkHacks[PERKHACKS_STOREDANGLE])
  3770. }, 1, 1);
  3771. },
  3772.  
  3773. perkHacksActionBuildMedkit = (me, socketId, offset) => {
  3774. if (perkHacks[PERKHACKS_CRATEPLACEVISION]) {
  3775. let box = {
  3776. x: 50 * cos(me.playerAngle * degToRad),
  3777. y: 50 * sin(me.playerAngle * degToRad)
  3778. };
  3779. ctx.strokeStyle = '#000';
  3780. ctx.lineWidth = 1;
  3781. ctx.strokeRect(me.x + offset.x + box.x - 20, me.y + offset.y + box.y - 20, 40, 40);
  3782. drawLine2(me, box, offset, 1, '#000');
  3783. }
  3784.  
  3785. // if medkit
  3786. if (false && o3[2] == abilities[1]) {
  3787. if (perkHacks[PERKHACKS_MEDKITSELFHEAL] && me.hp < perkHacks[PERKHACKS_MEDKITSELFHEALTHRESHOLD]) {
  3788. let futurePos
  3789. aimMeAt({
  3790. clientX: me.x + offset.x + me[ATTRIBUTE_USABLESPDX],
  3791. clientY: me.y + offset.y + me[ATTRIBUTE_USABLESPDY]
  3792. }, 1, 1);
  3793. if (perkHacks[PERKHACKS_TICK]) startActivePerk(socketId);
  3794. perkHacks[PERKHACKS_TICK] = 1;
  3795. } else {
  3796. stopActivePerk(socketId);
  3797. perkHacks[PERKHACKS_TICK] = 0;
  3798. }
  3799. return;
  3800. }
  3801. // if build
  3802. },
  3803.  
  3804. perkHacksAction = (me, socketId, playerScreenPos, offset, enemies, enemyFriends, crates, animationSubtraction) => {
  3805. if (c9.current - animationSubtraction > 0 || !o3[2]) {
  3806. perkHacks[PERKHACKS_TICK] = 0;
  3807. if ((perkHacks[PERKHACKS_KNIFE] || perkHacks[PERKHACKS_SHIELD]) &&
  3808. !(perkHacks[PERKHACKS_SHIELD] && abilities[0] == o3[2] && perkHacks[PERKHACKS_SHIELDMANUAL])
  3809. ) stopActivePerk(socketId);
  3810. return;
  3811. }
  3812.  
  3813. switch (o3[2]) {
  3814. case abilities[3]: //Knife
  3815. perkHacksActionKnife(me, socketId, offset, enemies, enemyFriends, crates);
  3816. break;
  3817.  
  3818. case abilities[0]: //Shield
  3819. perkHacksActionShield(me, socketId, playerScreenPos, offset, crates, animationSubtraction);
  3820. break;
  3821.  
  3822. case abilities[1]: //Medkit
  3823. case abilities[4]: //Build
  3824. perkHacksActionBuildMedkit(me, socketId, offset);
  3825. break;
  3826. }
  3827. },
  3828.  
  3829. thnetInfoShare = leaderboardLeft => {
  3830. ctx.font = 'bold 14px consolas';
  3831. for (let entryName in thnet[THNET_INFOSHARING]) {
  3832. let entry = thnet[THNET_INFOSHARING][entryName],
  3833. spacing = 5,
  3834. width = 160,
  3835. height = 160;
  3836. if (entry.length < 10) continue;
  3837. leaderboardLeft -= spacing + width;
  3838. ctx.strokeStyle = ctx.fillStyle = '#888';
  3839. ctx.globalAlpha = 0.5;
  3840. ctx.fillRect(leaderboardLeft, 5, width, height);
  3841. ctx.lineWidth = 3;
  3842. ctx.globalAlpha = 1;
  3843. ctx.strokeRect(leaderboardLeft, 5, width, height);
  3844. leaderboardLeft += 5;
  3845. let text = [
  3846. ' Name: ' + entry[0],
  3847. ' HP: ' + spacePadding(entry[1]) + '/' + entry[2],
  3848. 'Armor: ' + spacePadding(entry[3]) + '/' + entry[4],
  3849. ' Ammo: ' + spacePadding(entry[5]) + '/' + entry[6],
  3850. 'Class: ' + gunNames[entry[7]],
  3851. ' X: ' + spacePadding(round(entry[8]), 4) + ' Y: ' + spacePadding(round(entry[9]), 4)
  3852. ];
  3853. for (let i = 0; i < text.length; i++) {
  3854. drawText(leaderboardLeft, 20 + i * 17, text[i], '#000');
  3855. }
  3856. ctx.lineWidth = 2;
  3857. for (let i = 0; i < 3; i++) {
  3858. ctx.strokeRect(leaderboardLeft + 5 + i * 50, 115, 40, 40);
  3859. if (j30[entry[11 + i]]) {
  3860. ctx.drawImage(j30[entry[11 + i]], leaderboardLeft + 5 + i * 50, 115, 40, 40);
  3861. if (i == 1 && entry[14] > 0) {
  3862. j58.globalAlpha = 0.75;
  3863. j58.fillStyle = "#7a7a7a";
  3864. j58.fillRect(leaderboardLeft + 5 + i * 50, 115, 40 * entry[14], 40);
  3865. ctx.globalAlpha = 1;
  3866. }
  3867. }
  3868. }
  3869. //0: sanitisedname
  3870. //1: hp
  3871. //2: hpMax
  3872. //3: armorAmount
  3873. //4: armorMax
  3874. //5: currentBullets
  3875. //6: maxBullets
  3876. //7: gun
  3877. //8: x
  3878. //9: y
  3879. //a: color
  3880. //b: o3[1]
  3881. //c: o3[2]
  3882. //d: o3[3]
  3883. //e: c9.current / c9.total
  3884.  
  3885.  
  3886. //RD.prototype[ATTRIBUTE_DRAWBODY].call({});
  3887. //RD.prototype[ATTRIBUTE_DRAWGUN].call({});
  3888. leaderboardLeft -= 10;
  3889. }
  3890. },
  3891.  
  3892. goToSpotWithPackets = (socketId, me, goal) => {
  3893. //resets movement
  3894. for (let inputId of [KEYPRESS_KEY_LEFT, KEYPRESS_KEY_RIGHT, KEYPRESS_KEY_UP, KEYPRESS_KEY_DOWN]) keyPress(socketId, inputId, 0);
  3895.  
  3896. //sends the correct movement
  3897. for (let inputId of [
  3898. [KEYPRESS_KEY_RIGHT],
  3899. [KEYPRESS_KEY_RIGHT, KEYPRESS_KEY_DOWN],
  3900. [KEYPRESS_KEY_DOWN],
  3901. [KEYPRESS_KEY_DOWN, KEYPRESS_KEY_LEFT],
  3902. [KEYPRESS_KEY_LEFT],
  3903. [KEYPRESS_KEY_UP, KEYPRESS_KEY_LEFT],
  3904. [KEYPRESS_KEY_UP],
  3905. [KEYPRESS_KEY_UP, KEYPRESS_KEY_RIGHT]
  3906. ][ round(( atan2(me.y - goal.y, me.x - goal.x) / TAU ) * 8 + 4) % 8 ]) keyPress(socketId, inputId, 1);
  3907. },
  3908.  
  3909. //will i ever use this?
  3910. sanitizeMessage = message => make('p', {}, { innerText: message }).innerHTML,
  3911.  
  3912. makeChatMessage = args => {
  3913. let scrollback = divs.chatbox.scrollTop === divs.chatbox.scrollHeight - divs.chatbox.clientHeight, msgs = [];
  3914. for (let msg of args) {
  3915. msgs.push(make('div', {
  3916. color: msg[0],
  3917. whiteSpace: msg[2] ? 'pre' : 'normal'
  3918. }, { innerText: msg[1] }));
  3919. }
  3920. divs.chatbox.append(make('div', {
  3921. [css_key_paddingLeft]: css_value_length_px3,
  3922. [css_key_display]: css_value_misc_flex,
  3923. [css_key_minWidth]: css_value_length_em2
  3924. }, {}, msgs));
  3925. if (scrollback) divs.chatbox.scroll({ top: divs.chatbox.scrollHeight, behavior: 'instant' });
  3926. },
  3927.  
  3928. thnetOnMessage = event => {
  3929. let data = event.data.split(' ');
  3930. switch (pInt(data.shift())) {
  3931. case 0: //load new people into dict without dublicates
  3932. for (let user of data) {
  3933. user = pInt(user);
  3934. if (!includesInArray(thnet[THNET_BROTHERS], user)) thnet[THNET_BROTHERS].push(user);
  3935. }
  3936. break;
  3937.  
  3938. case 1: //remove a person from the dict
  3939. let i = indexOfInArray(thnet[THNET_BROTHERS], pInt(data[0]));
  3940. if (thnet[THNET_BROTHERS].length - 1 > i) {
  3941. thnet[THNET_BROTHERS][i] = thnet[THNET_BROTHERS].pop();
  3942. } else {
  3943. thnet[THNET_BROTHERS].pop();
  3944. }
  3945. break;
  3946.  
  3947. case 2: //serverwide chat
  3948. makeChatMessage([['#88f', data.shift().replace('_', ' ')], ['#fff', ': ', 1], ['#fff', data.join(' ')]]);
  3949. break;
  3950.  
  3951. case 3: //keepalive
  3952. thnet[THNET_SOCKET].send('');
  3953. if (thnet[THNET_INFOSHARE] && c3 !== null && thnet[THNET_SOCKET].readyState == WebSocket.OPEN) {
  3954. let me = RD.pool[c3];
  3955. thnet[THNET_SOCKET].send('1 ' + [
  3956. me.hp, me.hpMax,
  3957. me.armorAmount, armorMap[c1.armor] * 30,
  3958. me.currentBullets, me.maxBullets,
  3959. gunMap[me.class],
  3960. me.x, me.y, me.color.a,
  3961. o3[1], o3[2], o3[3], c9.current / c9.total
  3962. ].join(' '));
  3963. }
  3964. break;
  3965.  
  3966. case 4: //received close reason
  3967. thnet[THNET_CLOSEREASON] = data.join(' ');
  3968. break;
  3969.  
  3970. case 5:
  3971. makeChatMessage([['#f88', data.join(' ')]]);
  3972. break;
  3973.  
  3974. case 6:
  3975. let name = data[0].replace('_', ' ');
  3976. if (data.length < 2) {
  3977. delete thnet[THNET_INFOSHARING][name];
  3978. return;
  3979. }
  3980. data[0] = name;
  3981. thnet[THNET_INFOSHARING][name] = data;
  3982. }
  3983. },
  3984.  
  3985. connectToTHNet = () => thnet[THNET_SOCKET] = applyAttrbutes(new WebSocket('ws' + homeUrl + sanitiseName(b4) + '/' + encodeURIComponent(o4.server + '/' + c22) + '/' + thnet[THNET_AUTH]), {
  3986. onopen: event => {
  3987. divs.chatwrap.hidden = !thnet[THNET_CHAT];
  3988. makeChatMessage([['#ff0', 'Connected']]);
  3989. },
  3990. onmessage: thnetOnMessage,
  3991. onerror: event => thnet[THNET_CLOSEREASON] = 'Error',
  3992. onclose: event => {
  3993. thnet[THNET_BROTHERS] = [];
  3994. thnet[THNET_SOCKET] = 0;
  3995. makeChatMessage([['#ff0', 'Disconnected' + (thnet[THNET_CLOSEREASON] ? ' (' + thnet[THNET_CLOSEREASON] + ')' : '')]]);
  3996.  
  3997. }
  3998. }),
  3999.  
  4000. handleUncomplicatedKeypress = (keyEvent, msg) => {
  4001. switch (keyEvent.keyCode) {
  4002. case keyCodeMap[KEYCODE_A]:
  4003. case keyCodeMap[KEYCODE_ARROWLEFT]:
  4004. keyPress(multiBox[MULTIBOX_SELECTEDSOCKET], KEYPRESS_KEY_LEFT, KEYPRESS_STATE_ON);
  4005. keyPress(multiBox[MULTIBOX_SELECTEDSOCKET], KEYPRESS_KEY_RIGHT, KEYPRESS_STATE_OFF);
  4006. break;
  4007. case keyCodeMap[KEYCODE_D]:
  4008. case keyCodeMap[KEYCODE_ARROWRIGHT]:
  4009. keyPress(multiBox[MULTIBOX_SELECTEDSOCKET], KEYPRESS_KEY_RIGHT, KEYPRESS_STATE_ON);
  4010. keyPress(multiBox[MULTIBOX_SELECTEDSOCKET], KEYPRESS_KEY_LEFT, KEYPRESS_STATE_OFF);
  4011. break;
  4012. case keyCodeMap[KEYCODE_W]:
  4013. case keyCodeMap[KEYCODE_ARROWUP]:
  4014. keyPress(multiBox[MULTIBOX_SELECTEDSOCKET], KEYPRESS_KEY_UP, KEYPRESS_STATE_ON);
  4015. keyPress(multiBox[MULTIBOX_SELECTEDSOCKET], KEYPRESS_KEY_DOWN, KEYPRESS_STATE_OFF);
  4016. break;
  4017. case keyCodeMap[KEYCODE_S]:
  4018. case keyCodeMap[KEYCODE_ARROWDOWN]:
  4019. keyPress(multiBox[MULTIBOX_SELECTEDSOCKET], KEYPRESS_KEY_DOWN, KEYPRESS_STATE_ON);
  4020. keyPress(multiBox[MULTIBOX_SELECTEDSOCKET], KEYPRESS_KEY_UP, KEYPRESS_STATE_OFF);
  4021. break;
  4022. case keyCodeMap[KEYCODE_R]:
  4023. keyPress(multiBox[MULTIBOX_SELECTEDSOCKET], KEYPRESS_KEY_RELOAD, KEYPRESS_STATE_ON);
  4024. break;
  4025. case keyCodeMap[KEYCODE_SPACE]:
  4026. startActivePerk(multiBox[MULTIBOX_SELECTEDSOCKET]);
  4027. break;
  4028. case keyCodeMap[KEYCODE_N]:
  4029. o10.push({type: 8, content: c37 = !c37, initTime: Date.now()});
  4030. break;
  4031. case keyCodeMap[KEYCODE_T]:
  4032. divs.menu.hidden = !divs.menu.hidden;
  4033. break;
  4034. case keyCodeMap[KEYCODE_CTRL]:
  4035. divs.chatwrap.hidden = !divs.chatwrap.hidden;
  4036. break;
  4037. default:
  4038. if (!instantchat[INSTANTCHAT_CHATBINDS] || !msg) break;
  4039. let padding = ' '.repeat(lastMessageLength = (lastMessageLength + 1) & 1);
  4040. sendChatMessage(multiBox[MULTIBOX_SELECTEDSOCKET], padding + msg + padding);
  4041. }
  4042. },
  4043.  
  4044. handleEnterPress = (socket, { style: chatboxContainerStyle }, chatbox, shiftPressed) => {
  4045. if (shiftPressed) return divs.chatinput.focus();
  4046.  
  4047. //get chat input value
  4048. j47 = chatbox.value;
  4049.  
  4050. //if there is a chat input value, send it as a chat message
  4051. if (j46 && j47 != '') {
  4052. sendChatMessage(multiBox[MULTIBOX_SELECTEDSOCKET], j47.replace(/,/g, '~').substring(0, 30));
  4053. chatboxContainerStyle[css_key_display] = css_value_misc_none;
  4054. chatbox.value = j47 = '';
  4055.  
  4056. //if no chat input value, close the chat input
  4057. } else if (j46 && j47 == '') {
  4058. chatboxContainerStyle[css_key_display] = css_value_misc_none;
  4059. } else if (!j46) {
  4060. chatboxContainerStyle[css_key_display] = css_value_misc_inlineBlock;
  4061. chatbox.focus();
  4062. }
  4063. j46 = !j46;
  4064. keyPress(multiBox[MULTIBOX_SELECTEDSOCKET], 7, j46 * !misc[MISC_HIDECHATTING]);
  4065. socket.send(a59('focus'));
  4066. },
  4067.  
  4068. colorLerp = (color1, color2, percent) => {
  4069. color1 = [
  4070. pInt(color1.slice(1, 3), 16),
  4071. pInt(color1.slice(3, 5), 16),
  4072. pInt(color1.slice(5, 7), 16)
  4073. ];
  4074. color2 = [
  4075. pInt(color2.slice(1, 3), 16),
  4076. pInt(color2.slice(3, 5), 16),
  4077. pInt(color2.slice(5, 7), 16)
  4078. ];
  4079. let result = '#';
  4080. for (let i = 0; i < 3; i++) {
  4081. let chunk = lerpR(color2[i], color1[i], percent).toString(16);
  4082. result += chunk.length == 1 ? '0' + chunk : chunk;
  4083. }
  4084.  
  4085. return result;
  4086. },
  4087.  
  4088. onAFK = (me, socketId) => {
  4089. let horizontal = j11 / 2 - me.x,
  4090. vertical = j12 / 2 - me.y,
  4091. key = [[ KEYPRESS_KEY_LEFT, KEYPRESS_KEY_RIGHT ][ horizontal > 1 ], [ KEYPRESS_KEY_DOWN, KEYPRESS_KEY_UP ][ vertical > 1 ]][ abs(horizontal) > abs(vertical) ];
  4092. keyPress(socketId, key, KEYPRESS_STATE_OFF);
  4093. keyPress(socketId, key, KEYPRESS_STATE_ON);
  4094. },
  4095.  
  4096. replaceENEMYInText = (str, enemy) => str.replace('[[ENEMY]]', sanitiseName(enemy.replace('Guest ', ''))),
  4097.  
  4098. onKill = (socketId, victim) => instantchat[INSTANTCHAT_ONKILL] && sendChatMessage(socketId, replaceENEMYInText(instantchat[INSTANTCHAT_ONKILLTEXT], victim)),
  4099.  
  4100. onDeath = (socketId, killer) => instantchat[INSTANTCHAT_ONDEATH] && sendChatMessage(socketId, replaceENEMYInText(instantchat[INSTANTCHAT_ONDEATHTEXT], killer)),
  4101.  
  4102. onHeal = (socketId, geduldig) => instantchat[INSTANTCHAT_AUTOTHANK] && geduldig == c3 && sendChatMessage(socketId, instantchat[INSTANTCHAT_AUTOTHANKTEXT]),
  4103.  
  4104. drawMinimap = player => {
  4105. if (j43) return;
  4106. let baseWidth = 144,
  4107. baseHeight = 144,
  4108. scaledWidth = (100 / j11 - j31) * 0.01,
  4109. scaledHeight = (100 / j12 - j41) * 0.01,
  4110. widthOffset = baseWidth / 2 - scaledWidth,
  4111. heightOffset = baseHeight / 2 - scaledWidth,
  4112. width = baseWidth * (c24 / j11),
  4113. height = baseHeight * (c24 / j12),
  4114. baseX = (baseWidth - width) * 0.5,
  4115. baseY = (baseHeight - height) * 0.5;
  4116. ctx.globalAlpha = 0.5;
  4117. ctx.fillStyle = "#808080";
  4118. ctx.fillRect(5, 20, 150, 150);
  4119. ctx.fillStyle = "#7a7a7a";
  4120. ctx.fillRect(8, 23, baseWidth, baseHeight);
  4121. ctx.fillStyle = "#b5b5b5";
  4122. ctx.strokeStyle = "#d9d9d9";
  4123. ctx.lineWidth = 1;
  4124. ctx.fillRect(widthOffset + 8, heightOffset + 23, scaledWidth * 2, scaledHeight * 2);
  4125. if (c22 == "FFA" || c22 == "TDM") {
  4126. ctx.strokeStyle = "#d9d9d9";
  4127. j25(ctx, baseX + 8, baseY + 23, width, height);
  4128. } else if (c22 == "2TEAM" || c22 == "DOM") {
  4129. for (let i = 0; i < 4; i++) {
  4130. ctx.strokeStyle = [
  4131. "#d9d9d9", //light gray, neutral
  4132. "#f26740", //reddish orange, red capped
  4133. "#8dd8f8" //light blue, blue capped
  4134. ][j52[i + 1]];
  4135.  
  4136. let baseX = baseWidth * 0.5 - 20,
  4137. baseY = baseHeight * 0.5 - 20;
  4138. if (i & 1) baseX += 40 - width;
  4139. if (i > 1) baseY += 40 - height;
  4140.  
  4141. j25(ctx, baseX + 8, baseY + 23, width, height);
  4142. }
  4143. }
  4144. ctx.strokeStyle = "#666";
  4145. ctx.lineWidth = 0;
  4146. if (thnet[THNET_INFOSHARE]) for (let entryName in thnet[THNET_INFOSHARING]) if (entryName != player[ATTRIBUTE_SANITIZEDNAME]) {
  4147. let entry = thnet[THNET_INFOSHARING][entryName];
  4148. ctx.fillStyle = entry[10];
  4149. j22(ctx, baseWidth * (entry[8] / j11) + 8, baseHeight * (entry[9] / j12) + 23, 2);
  4150. ctx.fill();
  4151. }
  4152. if (player == null || player === undefVar) return;
  4153. ctx.fillStyle = player.color.a;
  4154. j22(ctx, baseWidth * (player.x / j11) + 8, baseHeight * (player.y / j12) + 23, 2);
  4155. ctx.fill();
  4156. ctx.globalAlpha = 1;
  4157. },
  4158.  
  4159. //send mouse position to server
  4160. sendMousePositionToServer = socketId => {
  4161. //thank you dygn for coding packet sending in such a weird way
  4162. let str = a60('mouse-move', {mouseX: j16[0], mouseY: j16[1], mouseAngle: j16[2]});
  4163.  
  4164. //convert string to bytes then send
  4165. //j15 isnt used anywhere so we can reuse it for whatever purpose
  4166. if (RF.list[socketId] !== undefVar && str !== j15) RF.list[socketId].send(a66(j15 = str));
  4167. },
  4168.  
  4169. //draw floor
  4170. drawFloor = (ctx, camera) => {
  4171. let relPos1 = {x: -camera.x , y: -camera.y},
  4172. relPos2 = {x: j11 - camera.x, y: j12 - camera.y},
  4173. playerPos = RD.pool[c3],
  4174. position = {x: relPos1.x + j11 / 2 - c24 / 2, y: relPos1.y + j12 / 2 - c24 / 2},
  4175. positionMap = [
  4176. {x: relPos1.x + j11 / 2 - 1000 , y: relPos1.y + j12 / 2 - 1000 },
  4177. {x: relPos1.x + j11 / 2 + 1000 - c24 , y: relPos1.y + j12 / 2 - 1000 },
  4178. {x: relPos1.x + j11 / 2 - 1000 , y: relPos1.y + j12 / 2 + 1000 - c24},
  4179. {x: relPos1.x + j11 / 2 + 1000 - c24 , y: relPos1.y + j12 / 2 + 1000 - c24}
  4180. ],
  4181. capturepointPos = { x: (j11 - c24) / 2, y: (j12 - c24) / 2 },
  4182. midPointColor = playerPos.x > capturepointPos.x && playerPos.x < capturepointPos.x + c24 && playerPos.y > capturepointPos.y && playerPos.y < capturepointPos.y + c24 ? paint[PAINT_POINTSFFA] : paint[PAINT_POINTSIDLE],
  4183. i = 0;
  4184.  
  4185. for (i = 0; i < 4; i++) positionMap[i].z = [paint[PAINT_POINTSIDLE], paint[PAINT_POINTSRED], paint[PAINT_POINTSBLU]][j52[i + 1]];
  4186.  
  4187. //background
  4188. ctx.fillStyle = paint[PAINT_GRIDCOLOR][1];
  4189. ctx.fillRect(0, 0, j7, j8);
  4190.  
  4191. //mid point
  4192. if (c22 == 'FFA' || c22 == 'TDM') {
  4193. ctx.fillStyle = midPointColor[1];
  4194. ctx.fillRect(position.x, position.y, c24, c24);
  4195. }
  4196. if (c22 == '2TEAM' || c22 == 'DOM') for (let i = 0; i < positionMap.length; i++) {
  4197. ctx.fillStyle = positionMap[i].z[1];
  4198. ctx.fillRect(positionMap[i].x, positionMap[i].y, c24, c24);
  4199. }
  4200.  
  4201. //hey whats up guys its gr1dical here today we are changing how the grid looks
  4202. ctx.strokeStyle = paint[PAINT_GRIDCOLOR][0];
  4203. for (i = 0; i <= j12; i += paint[PAINT_GRIDSPACEY]) if (relPos1.y + i > 0 && relPos1.y + i <= relPos2.y) j21(ctx, relPos1.x, relPos1.y + i, relPos2.x, relPos1.y + i, paint[PAINT_GRIDLINEWIDTHHORIZONTAL]);
  4204. for (i = 0; i <= j11; i += paint[PAINT_GRIDSPACEX]) if (relPos1.x + i > 0 && relPos1.x + i <= relPos2.x) j21(ctx, relPos1.x + i, relPos1.y, relPos1.x + i, relPos2.y, paint[PAINT_GRIDLINEWIDTHVERTICAL]);
  4205.  
  4206. //map border
  4207. ctx.strokeStyle = '#aaa';
  4208. ctx.lineWidth = 10;
  4209. ctx.strokeRect(relPos1.x, relPos1.y, j11, j12);
  4210.  
  4211. //if mid capture point is being capped
  4212. ctx.lineWidth = paint[PAINT_POINTEDGEWIDTH];
  4213. if (c22 == 'FFA' || c22 == 'TDM') {
  4214. ctx.strokeStyle = midPointColor[0];
  4215. ctx.strokeRect(position.x, position.y, c24, c24);
  4216.  
  4217. }
  4218. //if dom capture points are being capped
  4219. if (c22 == '2TEAM' || c22 == 'DOM') for (let i = 0; i < positionMap.length; i++) {
  4220. ctx.strokeStyle = positionMap[i].z[0];
  4221. ctx.strokeRect(positionMap[i].x, positionMap[i].y, c24, c24);
  4222. }
  4223. },
  4224.  
  4225. //draw leaderboard
  4226. drawLeaderBoard = (ctx, leaderboard) => {
  4227. leaderboard.current = leaderboard.new;
  4228. if (j3 < 1 || j3 > 2.6) return;
  4229. let offset = 0.03,
  4230. leftiest = 1.695 * j1;
  4231. ctx.fillStyle = '#609b68';
  4232. ctx.textAlign = css_value_misc_center;
  4233. ctx.font = 'bold 11px Arial';
  4234. ctx.fillText('Total Players Online: ' + c29, 1.845 * j1, 0.032 * j2);
  4235. ctx.fillStyle = '#4C4C4C';
  4236. if (leaderboard.current.length > 0) ctx.fillText('Leaderboard', 1.845 * j1, 0.07 * j2);
  4237. ctx.textAlign = 'start';
  4238. for (let entry of leaderboard.current) {
  4239. if (!entry.userId) continue;
  4240. let horizontalOffset = 1.695 * j1,
  4241. name = entry.userId,
  4242. nameHash = hashString(sanitiseName(name)),
  4243. selectedStyle = nameHash == developerHash ? '#00f' :
  4244. includesInArray(thnet[THNET_BROTHERS], nameHash) ? '#88f' :
  4245. includesInArray(targets, name) ? '#f00' :
  4246. includesInArray(friends, name) ? '#000' : 0,
  4247. label = {
  4248. '#00f': 'DEV',
  4249. '#88f': 'THnet',
  4250. '#f00': 'Target',
  4251. '#000': 'Friend'
  4252. }[selectedStyle];
  4253. ctx.globalAlpha = 0.5;
  4254. ctx.fillStyle = ['#808080', '#f26740', '#40b2e5'][pInt(entry.teamCode)];
  4255. ctx.fillRect(1.7 * j1, (0.05 + offset) * j2, 0.295 * j1, 0.04 * j2);
  4256. if (entry.isMember) {
  4257. ctx.globalAlpha = 0.65;
  4258. drawImage(j30.vip, 1.703 * j1, (0.055 + offset) * j2, 18, 10);
  4259. }
  4260. ctx.globalAlpha = 1;
  4261. ctx.fillStyle = 'white';
  4262. ctx.font = '10px Arial';
  4263. ctx.fillText(name + ': ' + entry.score, (entry.isMember ? 1.735 : 1.705) * j1, (0.0787 + offset) * j2);
  4264. ctx.textAlign = 'right';
  4265. ctx.fillText('Kills: ' + entry.kills, 1.99 * j1, (0.0795 + offset) * j2);
  4266. ctx.textAlign = 'start';
  4267. if (misc[MISC_LEADERBOARDBADGES] && selectedStyle) {
  4268. ctx.strokeStyle = ctx.fillStyle = selectedStyle;
  4269. ctx.font = 'bold 13px consolas';
  4270. let width = ctx.measureText(label).width + 8;
  4271. ctx.globalAlpha = 0.5;
  4272. ctx.fillRect(horizontalOffset - width, (0.05 + offset) * j2, width, 0.04 * j2);
  4273. ctx.globalAlpha = ctx.lineWidth = 1;
  4274. ctx.strokeRect(horizontalOffset - width, (0.05 + offset) * j2, width, 0.04 * j2);
  4275. ctx.fillStyle = '#ffffff';
  4276. ctx.fillText(label, horizontalOffset - width + 4, (0.0795 + offset) * j2);
  4277. horizontalOffset -= width;
  4278. }
  4279. leftiest = min(leftiest, horizontalOffset);
  4280. offset += 0.045;
  4281. }
  4282. ctx.textAlign = 'right';
  4283. ctx.fillStyle = '#4C4C4C';
  4284. ctx.font = 'bold 11px Arial';
  4285. ctx.fillText('Players in arena: ' + o4.currentPlayers, 1.99 * j1, (offset + 0.075) * j2);
  4286. ctx.textAlign = 'start';
  4287. return leftiest;
  4288. },
  4289.  
  4290. aimMeAt = (event, isBot, isAbility) => {
  4291. let me = RD.pool[c3],
  4292. relPos = {
  4293. x: (me.x - c2.x) * (isBot ? 1 : j6) - event.clientX,
  4294. y: (me.y - c2.y) * (isBot ? 1 : j5) - event.clientY
  4295. },
  4296. mouseAngle = atan2(relPos.y, relPos.x) / degToRad + 180,
  4297. playerAngle = mouseAngle + (isAbility ? 0 : asin(18 / sqrt(relPos.x ** 2 + relPos.y ** 2)) / degToRad);
  4298. j16 = [round(relPos.x), round(relPos.y), round(mouseAngle)];
  4299. if (!playerAngle && playerAngle !== 0) playerAngle = mouseAngle;
  4300. me.playerAngle = round(playerAngle);
  4301. j9 = [event.clientX, event.clientY];
  4302. if (esp[ESP_CAMUSEREALPOSITION]) {
  4303. relPos.x += event.clientX - cursor.x;
  4304. relPos.y += event.clientY - cursor.y;
  4305. mouseAngle = atan2(relPos.y, relPos.x) / degToRad + 180;
  4306. }
  4307. me.mouseAngle = round(mouseAngle);
  4308. j39 = sqrt(relPos.x ** 2 + relPos.y ** 2);
  4309. },
  4310.  
  4311. handleMessage = (socketId, wsMsgEvent) => {
  4312. if (wsMsgEvent.data === undefVar || RF.list[0] === undefVar) return;
  4313. var messageString = a67(wsMsgEvent.data);
  4314. if (messageString == ".") {
  4315. RF.list[socketId].a74();
  4316. RF.list[socketId].a76();
  4317. }
  4318. var messageStringFragments = messageString.split("|");
  4319. for (var i = 0; i < messageStringFragments.length; i++) {
  4320. var wsMessage = a61(messageStringFragments[i]);
  4321. if (wsMessage) switch (wsMessage.code) {
  4322. case "a":
  4323. a78();
  4324. a90();
  4325. c3 = wsMessage.id;
  4326. c2 = new RE(wsMessage.c2);
  4327. c2.trackingId = wsMessage.id;
  4328. a1(c2);
  4329. RD.pool[wsMessage.id].activate(wsMessage, 0);
  4330. c10 = 0;
  4331. c5 = wsMessage.hp;
  4332. c6 = wsMessage.armorAmount;
  4333. c4 = 1;
  4334. var me = RD.pool[c3];
  4335. if (me) {
  4336. c2.x = me.x - window.innerWidth / j6 / 2;
  4337. c2.y = me.y - window.innerHeight / j5 / 2;
  4338. }
  4339. b4 = wsMessage.username;
  4340. b38 = wsMessage.b38;
  4341. selfPremiumMember = wsMessage.isPremiumMember;
  4342. b11 = 0;
  4343. j43 = 0;
  4344. if (thnet[THNET_ENABLE] && !thnet[THNET_SOCKET]) connectToTHNet();
  4345. break;
  4346. case "b":
  4347. RD.pool[wsMessage.id].applyPrimaryUpdate(wsMessage);
  4348. break;
  4349. case "c":
  4350. RD.pool[wsMessage.id].applyAuxUpdate(wsMessage);
  4351. break;
  4352. case "d":
  4353. RD.pool[wsMessage.id].activate(wsMessage, 1);
  4354. break;
  4355. case "e":
  4356. RD.pool[wsMessage.id].deactivate();
  4357. break;
  4358. case "f":
  4359. if (c3) RD.pool[c3].applyFirstPersonUpdateData(wsMessage);
  4360. break;
  4361. case "g":
  4362. RC.pool[wsMessage.id].activate(wsMessage);
  4363. break;
  4364. case "h":
  4365. var bullet = RC.pool[wsMessage.id];
  4366. if (bullet) bullet.applyUpdate(wsMessage);
  4367. break;
  4368. case "i":
  4369. RC.pool[wsMessage.id].deactivate();
  4370. break;
  4371. case "j":
  4372. RB.pool[wsMessage.id].activate(wsMessage);
  4373. break;
  4374. case "k":
  4375. RB.pool[wsMessage.id].applyUpdate(wsMessage);
  4376. break;
  4377. case "l":
  4378. RB.pool[wsMessage.id].deactivate();
  4379. break;
  4380. case "m":
  4381. RA.pool[wsMessage.id].activate(wsMessage);
  4382. break;
  4383. case "n":
  4384. var thrown = RA.pool[wsMessage.id];
  4385. if (thrown) thrown.applyUpdate(wsMessage);
  4386. break;
  4387. case "o":
  4388. RA.pool[wsMessage.id].deactivate();
  4389. break;
  4390. case "p":
  4391. c10 = wsMessage.level;
  4392. break;
  4393. case "q":
  4394. j27.push({
  4395. x: wsMessage.x / 10,
  4396. y: wsMessage.y / 10,
  4397. c42: 0
  4398. });
  4399. break;
  4400. case "r":
  4401. let type = pInt(wsMessage.type),
  4402. content = wsMessage.content;
  4403. if (type == 1) onKill(socketId, content);
  4404. if (type == 2 || type == 9) onDeath(socketId, content);
  4405. if (type == 5) onAFK(socketId, RD.pool[c3]);
  4406. if (pInt(wsMessage.type) == 3) {
  4407. //hit damage notification
  4408. let notif = _.find(o10, {type: 3});
  4409. content = pInt(content);
  4410. if (!notif) {
  4411. o10.push({
  4412. type: type,
  4413. content: content,
  4414. initTime: Date.now()
  4415. });
  4416. break;
  4417. }
  4418. notif.content += content;
  4419. notif.initTime = Date.now();
  4420. break;
  4421. }
  4422. o10.push({
  4423. type: type,
  4424. content: content,
  4425. initTime: Date.now()
  4426. });
  4427. break;
  4428. case "s":
  4429. a4();
  4430. break;
  4431. case "t":
  4432. b11 = 1;
  4433. a45();
  4434. break;
  4435. case "v":
  4436. j38.new = wsMessage.j38;
  4437. o4.currentPlayers = wsMessage.currentPlayers;
  4438. break;
  4439. case "w":
  4440. b4 = wsMessage.username;
  4441. b38 = wsMessage.b38;
  4442. selfPremiumMember = wsMessage.isPremiumMember;
  4443. b3 = 1;
  4444. a111("registerModal");
  4445. a111("loginModal");
  4446. if (wsMessage.rememberCookie.length > 0) a2("remember_cookie", wsMessage.rememberCookie, 365);
  4447. if (selfPremiumMember) $("#hostServerTabLi").show();
  4448. b2 = 0;
  4449. a104();
  4450. a99();
  4451. b24();
  4452. break;
  4453. case "x":
  4454. a18(wsMessage);
  4455. b2 = 0;
  4456. a99();
  4457. break;
  4458. case "y":
  4459. a20(wsMessage);
  4460. break;
  4461. case "z":
  4462. if (wsMessage.status) {
  4463. b4 = "Mystery Creature";
  4464. b38 = "";
  4465. selfPremiumMember = 0;
  4466. b3 = 0;
  4467. $("#hostServerTabLi").hide();
  4468. }
  4469. a99();
  4470. a104();
  4471. break;
  4472. case "sq":
  4473. j52[1] = pInt(wsMessage.squareOneTeam);
  4474. j52[2] = pInt(wsMessage.squareTwoTeam);
  4475. j52[3] = pInt(wsMessage.squareThreeTeam);
  4476. j52[4] = pInt(wsMessage.squareFourTeam);
  4477. break;
  4478. case "sz":
  4479. j31 = pInt(wsMessage.newSize);
  4480. j41 = pInt(wsMessage.newSize);
  4481. break;
  4482. case "sta":
  4483. c27 = wsMessage;
  4484. break;
  4485. case "re":
  4486. j43 = 1;
  4487. a80("respawn");
  4488. break;
  4489. case "fr":
  4490. j43 = 1;
  4491. a80("respawn");
  4492. grecaptcha.execute("6LenZt4ZAAAAAF-2nPKzH9111gkjBlaJCEp8UsQV", {action: "connect"})
  4493. .then(function (grecaptchatoken) {
  4494. grecaptcha.LoToken = grecaptchatoken;
  4495. grecaptcha.LoTime = (new Date).getTime();
  4496. RF.list[socketId].send(new Uint8Array(a68("q," + grecaptcha.LoToken + "," + grecaptcha.LoTime + "")));
  4497. });
  4498. break;
  4499. case "reco":
  4500. b1 = 0;
  4501. b2 = 0;
  4502. servers = [];
  4503. b11 = 0;
  4504. c4 = 0;
  4505. a47();
  4506. break;
  4507. }
  4508. }
  4509. if (messageString == "+") {
  4510. RF.list[socketId].b12 = 1;
  4511. RF.list[socketId].send(new Uint8Array(a68("q," + grecaptcha.LoToken + "," + grecaptcha.LoTime + "")));
  4512. b17();
  4513. a91();
  4514. b15 = 0;
  4515. if (!b1) {
  4516. loginViaCookie();
  4517. b1 = 1;
  4518. }
  4519. } else if (messageString.substring(0, 7) == "version") {
  4520. var receivedVersion = b35(messageString.substr(8)),
  4521. clientVersion = b35(window.clientVersion),
  4522. latestVersion = b35(window.latestVersion);
  4523. if (receivedVersion.pat > clientVersion.pat
  4524. || receivedVersion.min != clientVersion.min
  4525. || receivedVersion.maj != clientVersion.maj
  4526. ) return b36(receivedVersion);
  4527. a2("clv", clientVersion.maj + "." + clientVersion.min + "." + clientVersion.pat);
  4528. b37();
  4529. } else if (messageString.substring(0, 10) == "highScores" && messageString.substr(11).length > 20) {
  4530. var highScorePackage = JSON.parse(messageString.substr(11));
  4531. getElementById("hscrs").style[css_key_display] = "block";
  4532. getElementById("highScoresHeading").innerHTML = "Top Scores Today";
  4533. var todayHighScores = getElementById("hsd");
  4534. todayHighScores.innerHTML = "";
  4535. for (var highScoreEntry in highScorePackage) {
  4536. if (!highScorePackage[highScoreEntry].score) continue;
  4537. var highScoreEntryMainContainer = document.createElement("div");
  4538. highScoreEntryMainContainer.className = "high-score-row";
  4539. var highScoreEntryVIPContainer = document.createElement("div");
  4540. highScoreEntryVIPContainer.className = "vip-image-div";
  4541. if (highScorePackage[highScoreEntry].is_member) {
  4542. var vipImg = document.createElement("img");
  4543. vipImg.src = "/img/vip.png";
  4544. vipImg.className = "vip-score-image";
  4545. highScoreEntryVIPContainer.appendChild(vipImg);
  4546. }
  4547. highScoreEntryMainContainer.appendChild(highScoreEntryVIPContainer);
  4548. var nameContainer = document.createElement("div");
  4549. nameContainer.className = "high-scores-text";
  4550. nameContainer.innerHTML = highScorePackage[highScoreEntry].username + ": " + highScorePackage[highScoreEntry].score.toLocaleString();
  4551. highScoreEntryMainContainer.appendChild(nameContainer);
  4552. todayHighScores.appendChild(highScoreEntryMainContainer);
  4553. }
  4554. } else if (messageString.substring(0, 8) == "c22") {
  4555. a103(a61(messageString).j50);
  4556. }
  4557. },
  4558.  
  4559. menus = [
  4560. [menuNames[ 0], refreshMenuSelect],
  4561. [menuNames[ 1], refreshMenuGuide],
  4562. [menuNames[ 2], refreshMenuMenu],
  4563. [menuNames[ 3], refreshMenuAimbot],
  4564. [menuNames[ 4], refreshMenuESP],
  4565. [menuNames[ 5], refreshMenuInstantchat],
  4566. [menuNames[ 6], refreshMenuMisc],
  4567. [menuNames[ 7], refreshMenuPlayermanager],
  4568. [menuNames[ 8], refreshMenuUpgrades],
  4569. [menuNames[ 9], refreshMenuSpammer],
  4570. [menuNames[10], refreshMenuAntiAim],
  4571. [menuNames[11], refreshMenuPerkHacks],
  4572. [menuNames[12], refreshMenuPaint],
  4573. [menuNames[13], refreshMenuRecorder],
  4574. //[menuNames[14], refreshMenuDiscordRPC],
  4575. [menuNames[15], refreshMenuTHNet],
  4576. [menuNames[16], refreshMenuWeird],
  4577. [menuNames[17], refreshMenuAdvanced],
  4578. [menuNames[18], refreshMenuCredits],
  4579. ];
  4580.  
  4581. /*
  4582. //handle stuff when other cheats are loaded aswell, since they can cause issues
  4583. if (//getElementById('box2') || //vaakir
  4584. //getElementById('m2') || //dewey's spammer
  4585. //getElementById('scrollerGUI') //nitro's spammer
  4586. false) {
  4587. if (await new Promise(Resolve => {
  4588. let def = localStorage.getItem('TioHax_abortWhenRanWithOtherMods');
  4589. if (def) return Resolve(pInt(def));
  4590. document.body.append(make('div', {}))
  4591. Resolve();
  4592. })) return;
  4593. }*/
  4594.  
  4595. //this is the DRM!
  4596. setInterval(console.dir, 30000, 'GATS.io TioHax Menu\nMade by Taureon.\nhttp' + homeUrl + '\nhttps://discord.gg/CwWd5UKf6R');
  4597.  
  4598.  
  4599. /*
  4600. this is planned shit for an uktrakill-like style meter which would use the chat for the style level and the duration of the style
  4601. concept:
  4602. -------SSShitstorm-------
  4603. ------SSShitstorm------
  4604. -----SSShitstorm-----
  4605. ----SSShitstorm----
  4606. ---SSShitstorm---
  4607. -SSShitstorm-
  4608. SSShitstorm
  4609. when it ends it downgrades to the level before
  4610. if the user kills someone it levels up and resets the timer
  4611.  
  4612. (11) Destructive
  4613. ( 7) Chaotic
  4614. ( 6) Brutal
  4615. ( 8) Anarchic
  4616. ( 7) Supreme
  4617. ( 9) SSadistic
  4618. (11) SSShitstorm
  4619. ( 9) ULTRAKILL
  4620. 30 - 11 = 19 => 18
  4621. (30) jgihrehgioerhgiorehiogheriohge
  4622. */
  4623.  
  4624.  
  4625. RE = function(data) {
  4626. let that = this;
  4627. for (let prop of ['x', 'y', 'spdX', 'spdY', 'width', 'height']) {
  4628. that[prop] = pInt(data[prop]);
  4629. if (isNaN(that[prop])) that[prop] = 0;
  4630. }
  4631. that.update = that[ATTRIBUTE_UPDATE] = function(bool) {
  4632. let player = RD.pool[that.trackingId];
  4633. if (!player) return;
  4634. if (player.mouseAngle === undefVar) player.mouseAngle = 0;
  4635. if (esp[ESP_FIXCAMERA]) {
  4636. that.x = player.x + round(player.spdX / advanced[ADVANCED_TPS]) - j40.x;
  4637. that.y = player.y + round(player.spdY / advanced[ADVANCED_TPS]) - j40.y;
  4638. return;
  4639. }
  4640. if (!bool) {
  4641. that.spdX += sign(player.spdX - that.spdX) / 10;
  4642. that.spdY += sign(player.spdY - that.spdY) / 10;
  4643. if (that.spdX > -0.1 && that.spdX < 0.1) that.spdX = 0;
  4644. if (that.spdY > -0.1 && that.spdY < 0.1) that.spdY = 0;
  4645. that.spdX = round(that.spdX * 10) / 10;
  4646. that.spdY = round(that.spdY * 10) / 10;
  4647. }
  4648. let angleRad = player.mouseAngle * degToRad;
  4649. if (that.spdX > -22 && that.spdX < 22) that.x = j39 / 15 * cos(angleRad) + (player.x - j40.x) - that.spdX * 12;
  4650. if (that.spdY > -22 && that.spdY < 22) that.y = j39 / 15 * sin(angleRad) + (player.y - j40.y) - that.spdY * 12;
  4651. };
  4652. that.getRelPos = obj => ({ x: obj.x - that.x, y: obj.y - that.y });
  4653. that.getPos = () => ({ x: that.x, y: that.y });
  4654. that.getSize = () => ({ width: that.width, height: that.height });
  4655. };
  4656.  
  4657.  
  4658. //crates
  4659. RB.prototype[ATTRIBUTE_FILLHITBOX] = function () {
  4660. let relPos = { x: this.x - c2.x, y: this.y - c2.y };
  4661. ctx.beginPath();
  4662. ctx.moveTo(this[ATTRIBUTE_HITBOX][0][0] + relPos.x, this[ATTRIBUTE_HITBOX][0][1] + relPos.y);
  4663. for (let i = 1; i < 4; i++) ctx.lineTo(this[ATTRIBUTE_HITBOX][i][0] + relPos.x, this[ATTRIBUTE_HITBOX][i][1] + relPos.y);
  4664. ctx.closePath();
  4665. ctx.fill();
  4666. };
  4667.  
  4668. RB.prototype[ATTRIBUTE_MAKEHITBOX] = function () {
  4669.  
  4670. //`this.angle` is weird
  4671. let angle = 0 - (this.angle * degToRad - PI / 2),
  4672.  
  4673. hitboxOffset = {
  4674. x: this[ATTRIBUTE_HITBOXFORWARDOFFSET] * sin(angle),
  4675. y: this[ATTRIBUTE_HITBOXFORWARDOFFSET] * cos(angle)
  4676. },
  4677.  
  4678. //generate the relative corners
  4679. relativeCorners = [
  4680. atan2( this[ATTRIBUTE_WIDTH], this[ATTRIBUTE_HEIGHT]) + angle,
  4681. atan2(0 - this[ATTRIBUTE_WIDTH], this[ATTRIBUTE_HEIGHT]) + angle,
  4682. atan2(0 - this[ATTRIBUTE_WIDTH], 0 - this[ATTRIBUTE_HEIGHT]) + angle,
  4683. atan2( this[ATTRIBUTE_WIDTH], 0 - this[ATTRIBUTE_HEIGHT]) + angle
  4684. ],
  4685.  
  4686. distance = sqrt(this[ATTRIBUTE_WIDTH] ** 2 + this[ATTRIBUTE_HEIGHT] ** 2);
  4687.  
  4688. //ceonver 4 corners into 4 lines
  4689. for (let i = 0; i < 4; i++) relativeCorners[i] = {
  4690. x: hitboxOffset.x + distance * sin(relativeCorners[i]),
  4691. y: hitboxOffset.y + distance * cos(relativeCorners[i])
  4692. };
  4693. this[ATTRIBUTE_HITBOX] = [
  4694. [relativeCorners[0].x, relativeCorners[0].y, relativeCorners[1].x, relativeCorners[1].y],
  4695. [relativeCorners[1].x, relativeCorners[1].y, relativeCorners[2].x, relativeCorners[2].y],
  4696. [relativeCorners[2].x, relativeCorners[2].y, relativeCorners[3].x, relativeCorners[3].y],
  4697. [relativeCorners[3].x, relativeCorners[3].y, relativeCorners[0].x, relativeCorners[0].y]
  4698. ];
  4699.  
  4700. this[ATTRIBUTE_HITBOXOFFSET] = hitboxOffset;
  4701. this[ATTRIBUTE_HITBOXRADIUS] = distance;
  4702. };
  4703.  
  4704. RB.prototype.activate = function (data) {
  4705. this.parent = data.parentId;
  4706. this.type = data.type;
  4707. this.x = data.x / 10;
  4708. this.y = data.y / 10;
  4709. this.angle = data.angle;
  4710. this.maxHp = data.maxHp;
  4711. this.hp = data.hp;
  4712. this.isPremium = data.isPremium;
  4713. this.model = a11(this.type, this.isPremium);
  4714. this[ATTRIBUTE_WIDTH] = 0;
  4715. this[ATTRIBUTE_HEIGHT] = 0;
  4716. this[ATTRIBUTE_HITBOXFORWARDOFFSET] = 0;
  4717. this[ATTRIBUTE_BULLETCOLLISIONS] = 0;
  4718. switch (this.type) {
  4719. case 'crate':
  4720. this[ATTRIBUTE_WIDTH] = 45;
  4721. this[ATTRIBUTE_HEIGHT] = 45;
  4722. this[ATTRIBUTE_BULLETCOLLISIONS] = 1;
  4723. break;
  4724. case 'longCrate':
  4725. this[ATTRIBUTE_WIDTH] = 45;
  4726. this[ATTRIBUTE_HEIGHT] = 20;
  4727. this[ATTRIBUTE_BULLETCOLLISIONS] = 1;
  4728. break;
  4729. case 'userCrate':
  4730. case 'premiumCrate':
  4731. this[ATTRIBUTE_WIDTH] = 15;
  4732. this[ATTRIBUTE_HEIGHT] = 15;
  4733. this[ATTRIBUTE_BULLETCOLLISIONS] = 1;
  4734. break;
  4735. case 'shield':
  4736. this[ATTRIBUTE_WIDTH] = 30;
  4737. this[ATTRIBUTE_HEIGHT] = 10;
  4738. this[ATTRIBUTE_HITBOXFORWARDOFFSET] = 33;
  4739. this[ATTRIBUTE_BULLETCOLLISIONS] = 1;
  4740. break;
  4741. }
  4742. this.activated = 1;
  4743. this[ATTRIBUTE_MAKEHITBOX]();
  4744. };
  4745.  
  4746. RB.prototype[ATTRIBUTE_UPDATE] = function () {
  4747. if (this.model) this.animationFrame = (this.animationFrame + 1) % this.model.length;
  4748. if (this.type != 'shield') return;
  4749. let parent = RD.pool[this.parent];
  4750. if (!parent) return;
  4751. let angle = parent.playerAngle * degToRad;
  4752. this.x = parent.x + parent.spdX / advanced[ADVANCED_TPS] + cos(angle);
  4753. this.y = parent.y + parent.spdY / advanced[ADVANCED_TPS] + sin(angle);
  4754. this.angle = parent.playerAngle;
  4755. };
  4756.  
  4757. RB.prototype.applyUpdate = function (data) {
  4758. let bool = this.angle != data.angle;
  4759. this.x = data.x / 10;
  4760. this.y = data.y / 10;
  4761. this.angle = data.angle;
  4762. if (data.hp !== undefVar && data.hp != '') this.hp = pInt(data.hp);
  4763. if (bool) this[ATTRIBUTE_MAKEHITBOX]();
  4764. };
  4765.  
  4766. RB.prototype[ATTRIBUTE_DRAW] = function() {
  4767. if (!this.model) return;
  4768.  
  4769. let hpPercent = this.maxHp ? this.hp / this.maxHp : 1,
  4770. model = this.model[this.animationFrame],
  4771. color = {
  4772. 'crate': paint[PAINT_CRATESQUARE],
  4773. 'longCrate': paint[PAINT_CRATELONG],
  4774. 'userCrate': this.isPremium ? paint[PAINT_CRATEPREMIUM] : paint[PAINT_CRATEUSER]
  4775. }[this.type];
  4776.  
  4777. if (color) {
  4778. model[0][1][3] = color[0];
  4779. model[1][1][3] = color[1];
  4780. if (hpPercent < 0 || hpPercent > 1) hpPercent = 0;
  4781. if (!misc[MISC_BETTERCRATEHP]) hpPercent = ceil(hpPercent * 5) / 5;
  4782. if (paint[PAINT_CRATESHOWHPMODE] & 1) model[0][1][3] = colorLerp(color[0], paint[PAINT_CRATECORPSE][0], hpPercent);
  4783. if (paint[PAINT_CRATESHOWHPMODE] >> 1) model[1][1][3] = colorLerp(color[1], paint[PAINT_CRATECORPSE][1], hpPercent);
  4784. }
  4785. a38(ctx, c2, this, this.angle, model);
  4786. };
  4787.  
  4788.  
  4789. //bullets
  4790. RC.prototype[ATTRIBUTE_UPDATE] = function () {
  4791. if (this.model) this.animationFrame = (this.animationFrame + 1) % this.model.length;
  4792. this.x += this.spdX;
  4793. this.y += this.spdY;
  4794. };
  4795.  
  4796. RC.prototype[ATTRIBUTE_DRAW] = function() {
  4797. if (this.isKnife) return a38(ctx, c2, this, this.angle, this.model[this.animationFrame]);
  4798.  
  4799. ctx.strokeStyle = '#000';
  4800. if (this.silenced && !esp[ESP_SHOWINVIS]) {
  4801. ctx.strokeStyle = '#D3D3DA';
  4802. } else if (this.ownerId == c3 || (this.teamCode > 0 && this.teamCode == RD.pool[c3].teamCode)) {
  4803. ctx.strokeStyle = '#107a24';
  4804. } else if (RD.pool[c3].thermal) {
  4805. ctx.strokeStyle = '#f00';
  4806. }
  4807. let relPosX = this.x - c2.x,
  4808. relPosY = this.y - c2.y;
  4809. j21(ctx, relPosX, relPosY, relPosX + this.length * cos(this.angle * degToRad), relPosY + this.length * sin(this.angle * degToRad), this.width);
  4810. };
  4811.  
  4812.  
  4813. //players
  4814. RD.prototype.activate = async function(data, isMe) {
  4815. this.color = data.color;
  4816. this.x = parseFloat(data.x / 10);
  4817. this.y = parseFloat(data.y / 10);
  4818. this[ATTRIBUTE_PREVSPDX] = this[ATTRIBUTE_PREVSPDY] = this.spdY = this.spdX = this[ATTRIBUTE_PREVACCX] = this[ATTRIBUTE_PREVACCY] = this[ATTRIBUTE_ACCX] = this[ATTRIBUTE_ACCY] = 0;
  4819. this[ATTRIBUTE_RADIUS] = pInt(data.radius / 10);
  4820. this.playerAngle = pInt(data.playerAngle);
  4821. this.hp = pInt(data.hp);
  4822. this[ATTRIBUTE_HPRADIUS] = this.hp * this[ATTRIBUTE_RADIUS] / 100;
  4823. this.armorAmount = pInt(data.armorAmount);
  4824. this.shootingAnimation = a6('shooting', this.class = data.class);
  4825. this.ghillie = data.ghillie;
  4826. this.maxBullets = data.maxBullets;
  4827. this.invincible = data.invincible;
  4828. this.isLeader = pInt(data.isLeader);
  4829. this.isPremiumMember = pInt(data.isPremiumMember);
  4830. this.teamCode = pInt(data.teamCode);
  4831. this.chatBoxOpen = pInt(data.chatBoxOpen);
  4832. this.activated = 1;
  4833. if (!isMe) {
  4834. this.currentBullets = pInt(data.currentBullets);
  4835. this.maxBullets = pInt(data.maxBullets);
  4836. this.armor = data.armor;
  4837. this.c2 = data.c2;
  4838. this.hpMax = data.hpMax;
  4839. this.numExplosivesLeft = 3;
  4840. j31 = pInt(data.mapWidth) / 10;
  4841. j41 = pInt(data.mapHeight) / 10;
  4842. }
  4843. setNameVariations(this, formatUserName(data.username));
  4844. };
  4845.  
  4846. RD.prototype.applyFirstPersonUpdateData = function (data) {
  4847. if (data.currentBullets !== undefVar && data.currentBullets != '') this.currentBullets = pInt(data.currentBullets);
  4848. if (data.score !== undefVar && data.score != '') this.score = pInt(data.score);
  4849. if (data.kills !== undefVar && data.kills != '') this.kills = pInt(data.kills);
  4850. if (data.rechargeTimer !== undefVar) c9 = {current: pInt(data.rechargeTimer) * advanced[ADVANCED_TPS], total: pInt(data.rechargeTimer) * advanced[ADVANCED_TPS]};
  4851. if (data.maxBullets !== undefVar && data.maxBullets != '') this.maxBullets = pInt(data.maxBullets);
  4852. if (data.c2 !== undefVar && data.c2 != '') {
  4853. let c = data.c2.split('x');
  4854. c2.width = pInt(c[0]);
  4855. c2.height = pInt(c[1]);
  4856. }
  4857. if (data.thermal !== undefVar && data.thermal != '') this.thermal = pInt(data.thermal);
  4858. if (data.numExplosivesLeft !== undefVar && data.numExplosivesLeft != '') this.numExplosivesLeft = pInt(data.numExplosivesLeft);
  4859. };
  4860.  
  4861. RD.prototype[ATTRIBUTE_UPDATE] = function () {
  4862. let hpRadius = round((this.hp / 100) * (this[ATTRIBUTE_RADIUS] - this.armorAmount / 10 - 1));
  4863. if (misc[MISC_STATICHEALTH]) {
  4864. this[ATTRIBUTE_HPRADIUS] = hpRadius;
  4865.  
  4866. //if end user wants to keep health animations
  4867. } else {
  4868. if (this[ATTRIBUTE_HPRADIUS] > hpRadius - 0.5 && this[ATTRIBUTE_HPRADIUS] < hpRadius + 0.5) {
  4869. this[ATTRIBUTE_HPRADIUS] = hpRadius;
  4870. } else if (this[ATTRIBUTE_HPRADIUS] > hpRadius) {
  4871. this[ATTRIBUTE_HPRADIUS] = this[ATTRIBUTE_HPRADIUS] - 0.5;
  4872. } else if (this[ATTRIBUTE_HPRADIUS] < hpRadius) {
  4873. this[ATTRIBUTE_HPRADIUS] = this[ATTRIBUTE_HPRADIUS] + 0.5;
  4874. }
  4875. if (this[ATTRIBUTE_HPRADIUS] < 0) this[ATTRIBUTE_HPRADIUS] = 0;
  4876. }
  4877.  
  4878. if (this.hp > 0) {
  4879. this.x += round(this.spdX / advanced[ADVANCED_TPS]);
  4880. this.y += round(this.spdY / advanced[ADVANCED_TPS]);
  4881. }
  4882.  
  4883. //chat timer
  4884. if (this.j47Timer > 0) {
  4885. this.j47Timer -= 2.5 / advanced[ADVANCED_TPS];
  4886. if (this.j47Timer <= 0) this.j47 = "";
  4887. }
  4888.  
  4889. //animation handler
  4890. this.shootingAnimation = a6("shooting", this.class);
  4891. if (this.shooting) {
  4892. this.shootingFrame = (this.shootingFrame + 1) % this.shootingAnimation.length;
  4893. } else if (this.reloading && this.reloadingAnimation) {
  4894. this.reloadingFrame = (this.reloadingFrame + 1) % this.reloadingAnimation.length;
  4895. }
  4896. if (!this.shooting) this.shootingFrame = 0;
  4897. if (!this.reloading) this.reloadingFrame = 0;
  4898. };
  4899.  
  4900. RD.prototype.applyPrimaryUpdate = function(data) {
  4901. this.x = parseFloat(data.x / 10);
  4902. this.y = parseFloat(data.y / 10);
  4903. let spdX = parseFloat(data.spdX / 10);
  4904. let spdY = parseFloat(data.spdY / 10);
  4905. this[ATTRIBUTE_PREVACCX] = this[ATTRIBUTE_ACCX];
  4906. this[ATTRIBUTE_PREVACCY] = this[ATTRIBUTE_ACCY];
  4907. this[ATTRIBUTE_ACCX] = spdX - this.spdX;
  4908. this[ATTRIBUTE_ACCY] = spdY - this.spdY;
  4909. this[ATTRIBUTE_PREVSPDX] = this.spdX;
  4910. this[ATTRIBUTE_PREVSPDY] = this.spdY;
  4911. this.spdX = spdX;
  4912. this.spdY = spdY;
  4913. if (aimbot[AIMBOT_AIMSMOOTHING]) {
  4914. this[ATTRIBUTE_USABLESPDX] = (spdX + this[ATTRIBUTE_PREVSPDX]) / 2;
  4915. this[ATTRIBUTE_USABLESPDY] = (spdY + this[ATTRIBUTE_PREVSPDY]) / 2;
  4916. this[ATTRIBUTE_USABLEACCX] = (this[ATTRIBUTE_ACCX] + this[ATTRIBUTE_PREVACCX]) / 2;
  4917. this[ATTRIBUTE_USABLEACCY] = (this[ATTRIBUTE_ACCY] + this[ATTRIBUTE_PREVACCY]) / 2;
  4918. } else {
  4919. this[ATTRIBUTE_USABLESPDX] = spdX;
  4920. this[ATTRIBUTE_USABLESPDY] = spdY;
  4921. this[ATTRIBUTE_USABLEACCX] = this[ATTRIBUTE_ACCX];
  4922. this[ATTRIBUTE_USABLEACCY] = this[ATTRIBUTE_ACCY];
  4923. }
  4924. if (data.id != c3) this.playerAngle = pInt(data.playerAngle);
  4925. };
  4926.  
  4927. RD.prototype.applyAuxUpdate = function (data) {
  4928. if (!this.activated) return;
  4929. if (data.color !== undefVar && data.color != '') this.color = data.color;
  4930. if (data.radius !== undefVar && data.radius != '') this[ATTRIBUTE_RADIUS] = pInt(data.radius / 10);
  4931. if (data.dashing !== undefVar && data.dashing != '') this.dashing = pInt(data.dashing);
  4932. if (data.ghillie !== undefVar && data.ghillie != '') this.ghillie = pInt(data.ghillie);
  4933. if (data.shooting !== undefVar && data.shooting != '') this.shooting = pInt(data.shooting);
  4934. if (data.isLeader !== undefVar && data.isLeader != '') this.isLeader = pInt(data.isLeader);
  4935. if (data.reloading !== undefVar && data.reloading != '') this.reloading = pInt(data.reloading);
  4936. if (data.maxBullets !== undefVar && data.maxBullets != '') this.maxBullets = pInt(data.maxBullets);
  4937. if (data.invincible !== undefVar && data.invincible != '') this.invincible = pInt(data.invincible);
  4938. if (data.armorAmount !== undefVar && data.armorAmount != '') this.armorAmount = pInt(data.armorAmount);
  4939. if (data.chatBoxOpen !== undefVar && data.chatBoxOpen != '') this.chatBoxOpen = pInt(data.chatBoxOpen);
  4940. if (data.currentBullets !== undefVar && data.currentBullets != '') this.currentBullets = pInt(data.currentBullets);
  4941. if (data.hp !== undefVar && data.hp != '') {
  4942. let newHp = pInt(data.hp);
  4943. if (this.hp + 1 < newHp) onHeal(this.id);
  4944. this.hp = newHp;
  4945. }
  4946. if (data.beingHit !== undefVar && data.beingHit != '') {
  4947. if (data.id == c3) j37 = 6;
  4948. this.beingHit = pInt(data.beingHit);
  4949. }
  4950. if (data.j47 !== undefVar && data.j47 != '') {
  4951. this.j47 = data.j47.replace(/~/g, ',');
  4952. this.j47Timer = 200;
  4953. //if (!thnet[THNET_ENABLE] && this[ATTRIBUTE_USERNAMEHASH] == developerHash && this.j47 == ',revealRogues') sendChatMessage('I am rogue');
  4954. }
  4955. };
  4956.  
  4957. RD.prototype[ATTRIBUTE_DRAWBODY] = function() {
  4958. let relPos = {
  4959. x: this.x - c2.x,
  4960. y: this.y - c2.y
  4961. };
  4962. if (!(this.ghillie && !esp[ESP_SHOWINVIS]) || this.spdX != 0 || this.spdY != 0 || this.beingHit || this.shooting) {
  4963. if (this.isLeader) {
  4964. ctx.globalAlpha = 0.3;
  4965. ctx.strokeStyle = this.color.a;
  4966. ctx.lineWidth = 10;
  4967. j22(ctx, relPos.x, relPos.y, this[ATTRIBUTE_RADIUS] * 1.65);
  4968. }
  4969. ctx.globalAlpha = this.invincible ? 0.3 : 1;
  4970. ctx.lineWidth = 2;
  4971. ctx.strokeStyle = ctx.fillStyle = this.isPremiumMember ? '#000' : '#666';
  4972. j22(ctx, relPos.x, relPos.y, this[ATTRIBUTE_RADIUS] + 1);
  4973. ctx.fill();
  4974. ctx.lineWidth = 1;
  4975. ctx.strokeStyle = ctx.fillStyle = this.color.b;
  4976. j22(ctx, relPos.x, relPos.y, this[ATTRIBUTE_RADIUS] - this.armorAmount / 10);
  4977. ctx.fill();
  4978. if (this.dashing) {
  4979. ctx.strokeStyle = '#bababa';
  4980. j21(ctx, relPos.x , relPos.y , relPos.x - this.spdX * 5, relPos.y - this.spdY * 5, 1);
  4981. j21(ctx, relPos.x , relPos.y + 20, relPos.x - this.spdX * 5, relPos.y + 20 - this.spdY * 5, 1);
  4982. j21(ctx, relPos.x , relPos.y - 20, relPos.x - this.spdX * 5, relPos.y - 20 - this.spdY * 5, 1);
  4983. j21(ctx, relPos.x + 20, relPos.y , relPos.x + 20 - this.spdX * 5, relPos.y - this.spdY * 5, 1);
  4984. j21(ctx, relPos.x - 20, relPos.y , relPos.x - 20 - this.spdX * 5, relPos.y - this.spdY * 5, 1);
  4985. }
  4986. ctx.lineWidth = 1;
  4987. ctx.strokeStyle = ctx.fillStyle = this.color.a;
  4988. j22(ctx, relPos.x, relPos.y, this[ATTRIBUTE_HPRADIUS] + 1);
  4989. ctx.fill();
  4990. if (c37 && this.id != c3) {
  4991. ctx.fillStyle = this.isPremiumMember ? '#000' : '#666';
  4992. ctx.font = 'bold 12px Arial';
  4993. ctx.textAlign = 'center';
  4994. let usedName = misc[MISC_FFACLANDISPLAY] ? this[ATTRIBUTE_TAGGEDNAME] : this[ATTRIBUTE_USERNAME],
  4995. textWidth = ctx.measureText(usedName).width;
  4996. if (this.isPremiumMember) {
  4997. ctx.globalAlpha = 0.75;
  4998. ctx.fillText(usedName, relPos.x - 9, relPos.y + this[ATTRIBUTE_RADIUS] * 1.75);
  4999. drawImage(j30.vip, relPos.x + textWidth / 2 - 6, relPos.y + this[ATTRIBUTE_RADIUS] * 1.75 - 9, 18, 10);
  5000. ctx.globalAlpha = 1;
  5001. } else {
  5002. ctx.fillText(usedName, relPos.x, relPos.y + this[ATTRIBUTE_RADIUS] * 1.75);
  5003. }
  5004. ctx.textAlign = 'start';
  5005. }
  5006. ctx.globalAlpha = 1;
  5007. } else if (this.id != c3 && RD.pool[c3].thermal == 1) {
  5008. if (this.teamCode > 0 && this.teamCode == RD.pool[c3].teamCode) {
  5009. ctx.strokeStyle = '#107a24';
  5010. ctx.font = 'bold 12px Arial';
  5011. ctx.textAlign = 'center';
  5012. ctx.fillStyle = '#107a24';
  5013. ctx.fillText(this[ATTRIBUTE_USERNAME], relPos.x, relPos.y + this[ATTRIBUTE_RADIUS] * 1.75);
  5014. ctx.textAlign = 'start';
  5015. } else {
  5016. ctx.strokeStyle = '#f00';
  5017. }
  5018. } else {
  5019. ctx.strokeStyle = '#efeff5';
  5020. ctx.lineWidth = 2;
  5021. j22(ctx, relPos.x, relPos.y, this[ATTRIBUTE_RADIUS]);
  5022. ctx.fillStyle = '#efeff5';
  5023. ctx.fill();
  5024. }
  5025. if (!c37 || includesInArray(muted, this[ATTRIBUTE_SANITIZEDNAME])) return;
  5026. let chatMessage = this.j47;
  5027. if (chatMessage == '' && this.chatBoxOpen) chatMessage = '...';
  5028. if (chatMessage[chatMessage.length - 1] == ' ') chatMessage = chatMessage.substring(0, chatMessage.length - 1);
  5029. if (!chatMessage.length) return;
  5030. ctx.font = 'bold 12px Arial';
  5031. ctx.textAlign = 'center';
  5032. let textWidth = ctx.measureText(chatMessage).width;
  5033. ctx.globalAlpha = 0.7;
  5034. ctx.fillStyle = this.isPremiumMember ? '#000' : '#7a7a7a';
  5035. ctx.fillRect(relPos.x - textWidth / 2 - 3, relPos.y + this[ATTRIBUTE_RADIUS] * 2.7 - 13, textWidth + 6, 18);
  5036. ctx.globalAlpha = 1;
  5037. ctx.fillStyle = this.isPremiumMember ? '#deb34c' : '#fff';
  5038. ctx.fillText(chatMessage, relPos.x, relPos.y + this[ATTRIBUTE_RADIUS] * 2.7);
  5039. ctx.textAlign = 'start';
  5040. };
  5041.  
  5042. RD.prototype[ATTRIBUTE_DRAWGUN] = function () {
  5043. if (this.ghillie && !this.spdX && !this.spdY && !this.beingHit && !this.shooting) {
  5044. if (!RD.pool[c3].thermal || c3 == this.id) return;
  5045. let relPos = {
  5046. x: this.x - c2.x,
  5047. y: this.y - c2.y
  5048. };
  5049. ctx.strokeStyle = (this.teamCode > 0 && this.teamCode == RD.pool[c3].teamCode) ? "#107a24" : "#ff0000";
  5050. j21(ctx, relPos.x, relPos.y, relPos.x + cos(this.playerAngle * degToRad) * 20, relPos.y + sin(this.playerAngle * degToRad) * 20, 4);
  5051. return;
  5052. }
  5053.  
  5054. this.shootingAnimation = a6("shooting", this.class);
  5055. let animationFrameToDraw = this.shootingAnimation[this.shootingFrame],
  5056. what = 0;
  5057. if (this.beingHit) {
  5058. what = -1;
  5059. this.beingHit = 0;
  5060. }
  5061. if (this.reloading) {
  5062. this.reloadingAnimation = a6("reloading", this.class, this.maxBullets - this.currentBullets, !this.currentBullets);
  5063. animationFrameToDraw = this.reloadingAnimation[this.reloadingFrame];
  5064. }
  5065. if (this.invincible) ctx.globalAlpha = 0.3;
  5066. a38(ctx, c2, this.getAttr(), this.playerAngle, animationFrameToDraw, 4, null, what);
  5067. ctx.globalAlpha = 1;
  5068. };
  5069.  
  5070. //connections
  5071. RF.prototype.a74 = function () {
  5072. this.pingReceivedTime = Date.now();
  5073. this.currentPing = (this.pingReceivedTime - this.pingSentTime) >> 1; //divides by 2 and also rounds in the same operation!
  5074. ++this.numSuccessfulPings;
  5075.  
  5076. if (!this[ATTRIBUTE_PINGS]) this[ATTRIBUTE_PINGS] = [];
  5077. this[ATTRIBUTE_PINGS].push(this.currentPing);
  5078. if (this[ATTRIBUTE_PINGS].length > advanced[ADVANCED_PINGCOUNT]) this[ATTRIBUTE_PINGS].shift();
  5079.  
  5080. this[ATTRIBUTE_AVERAGEPING] = 0;
  5081. for (let ping of this[ATTRIBUTE_PINGS]) this[ATTRIBUTE_AVERAGEPING] += ping;
  5082. this[ATTRIBUTE_AVERAGEPING] /= this[ATTRIBUTE_PINGS].length;
  5083.  
  5084. this[ATTRIBUTE_MINPING] = min(...this[ATTRIBUTE_PINGS]);
  5085. this[ATTRIBUTE_MAXPING] = max(...this[ATTRIBUTE_PINGS]); //lag spikes? L
  5086. };
  5087.  
  5088. RF.prototype.createGameSocket = function () {
  5089. this.socket = new WebSocket(this.connectHostname);
  5090. this.socket.binaryType = 'arraybuffer';
  5091. this.pingSentTime = Date.now();
  5092. this.socket.onopen = () => {
  5093. if (this.socket == null) return;
  5094. let indexInList = indexOfInArray(RF.list, this);
  5095. this.socket.onmessage = wsMsgEvent => {
  5096. if (recorder[RECORDER_ISRECORDING]) recorder[RECORDER_CURRENT].push([Date.now(), wsMsgEvent.data]);
  5097. handleMessage(indexInList, wsMsgEvent);
  5098. };
  5099. };
  5100. this.socket.onclose = () => {
  5101. if (thnet[THNET_SOCKET]) thnet[THNET_SOCKET].close();
  5102. this.close();
  5103. a45();
  5104. };
  5105. };
  5106.  
  5107.  
  5108. //non-bullet projectiles
  5109. RA.prototype.applyUpdate = function(data) {
  5110. this.x = pInt(data.x / 10);
  5111. this.y = pInt(data.y / 10);
  5112. this.exploding = pInt(data.exploding);
  5113. this.emitting = pInt(data.emitting);
  5114. this.emissionRadius = pInt(data.emissionRadius / 10);
  5115. this[ATTRIBUTE_TIMEALIVEEXTRA] = 0;
  5116. this.timeAlive++;
  5117. };
  5118.  
  5119. RA.prototype[ATTRIBUTE_UPDATE] = function () {
  5120. if (this.type == "landMine" || this.emitting) return;
  5121. if (this.exploding) {
  5122. this.animationFrame++;
  5123. if (this.animationFrame < this.model.length) this.deactivate();
  5124. }
  5125. if (this.timeAlive < this.travelTime) {
  5126. this.x += this.spdX;
  5127. this.y += this.spdY;
  5128. }
  5129. this.angle = (this.angle + 7) % 360;
  5130. };
  5131.  
  5132. RA.prototype[ATTRIBUTE_DRAW] = function () {
  5133. if (!this.activated) return;
  5134. if (this.exploding) return a38(ctx, c2, this.getAttr(), this.angle, this.model[this.animationFrame]);
  5135. a38(ctx, c2, this.getAttr(), this.angle, this.model[0]);
  5136. if (this.type == "landMine" && RD.pool[c3].thermal == 1) {
  5137. let relPos = {
  5138. x: this.x - c2.x,
  5139. y: this.y - c2.y
  5140. };
  5141. ctx.strokeStyle = (this.ownerId == c3 || this.teamCode > 0 && this.teamCode == RD.pool[c3].teamCode) ? "#107a24" : "#ff0000";
  5142. j22(ctx, relPos.x, relPos.y, 20);
  5143. j22(ctx, relPos.x, relPos.y, 4);
  5144. }
  5145. };
  5146.  
  5147.  
  5148. //yes i could use addEventListener but I felt like doing it this way anyway
  5149. document.onkeydown = keyEvent => {
  5150.  
  5151. //prevents stupidness
  5152. if (textBoxFocused && !keyEvent[ATTRIBUTE_ISFROMCHEAT]) return;
  5153.  
  5154. let msg = instantchat[INSTANTCHAT_CHATBINDSTEXTS][keyEvent.keyCode],
  5155. socket = RF.list[multiBox[MULTIBOX_SELECTEDSOCKET]],
  5156. chatboxContainer = getElementById('chatboxContainer'),
  5157. chatbox = getElementById('chatbox');
  5158.  
  5159. //if the key code is the key code used to toggle the menu
  5160. if ((!(j46 || c4) && includesInArray([keyCodeMap[KEYCODE_T], keyCodeMap[KEYCODE_SHIFT]], keyEvent.keyCode)) ||
  5161. //if the chatbox is closed and if we are in a game
  5162. (c4 && !j46 && (msg || includesInArray(Object.values(keyCodeMap), keyEvent.keyCode)))
  5163. ) {
  5164. keyEvent.preventDefault();
  5165. handleUncomplicatedKeypress(keyEvent, msg);
  5166. }
  5167.  
  5168. //handle enter press
  5169. if (keyEvent.keyCode == keyCodeMap[KEYCODE_ENTER] && c4 && !c28) handleEnterPress(socket, chatboxContainer, chatbox, keyEvent.shiftKey);
  5170.  
  5171. //if ESC key pressed, simply close the chat input
  5172. if (keyEvent.keyCode == keyCodeMap[KEYCODE_ESC] && j46) {
  5173. divs.chatinput.blur();
  5174. chatboxContainer.style[css_key_display] = css_value_misc_none;
  5175. j46 = 0;
  5176. keyPress(multiBox[MULTIBOX_SELECTEDSOCKET], 7, 0);
  5177. }
  5178. };
  5179.  
  5180. document.onkeyup = function (keyEvent) {
  5181. if (!c4 || j46 || !includesInArray([68, 83, 65, 87, 82, 32, 45, 37, 38, 39, 40], keyEvent.keyCode)) return;
  5182. keyEvent.preventDefault();
  5183. switch (keyEvent.keyCode) {
  5184. case keyCodeMap[KEYCODE_A]:
  5185. case keyCodeMap[KEYCODE_ARROWLEFT]:
  5186. keyPress(multiBox[MULTIBOX_SELECTEDSOCKET], KEYPRESS_KEY_LEFT, KEYPRESS_STATE_OFF);
  5187. break;
  5188. case keyCodeMap[KEYCODE_D]:
  5189. case keyCodeMap[KEYCODE_ARROWRIGHT]:
  5190. keyPress(multiBox[MULTIBOX_SELECTEDSOCKET], KEYPRESS_KEY_RIGHT, KEYPRESS_STATE_OFF);
  5191. break;
  5192. case keyCodeMap[KEYCODE_W]:
  5193. case keyCodeMap[KEYCODE_ARROWUP]:
  5194. keyPress(multiBox[MULTIBOX_SELECTEDSOCKET], KEYPRESS_KEY_UP, KEYPRESS_STATE_OFF);
  5195. break;
  5196. case keyCodeMap[KEYCODE_S]:
  5197. case keyCodeMap[KEYCODE_ARROWDOWN]:
  5198. keyPress(multiBox[MULTIBOX_SELECTEDSOCKET], KEYPRESS_KEY_DOWN, KEYPRESS_STATE_OFF);
  5199. break;
  5200. case keyCodeMap[KEYCODE_R]:
  5201. stopReloading(multiBox[MULTIBOX_SELECTEDSOCKET]);
  5202. break;
  5203. case keyCodeMap[KEYCODE_SPACE]:
  5204. stopActivePerk(multiBox[MULTIBOX_SELECTEDSOCKET]);
  5205. break;
  5206. }
  5207. };
  5208.  
  5209. //game tick
  5210. a41 = () => {
  5211. let start = Date.now(),
  5212. renderDisplayPadding = 5,
  5213. leaderboardLeft;
  5214.  
  5215. //modified game loop tick
  5216. if (!c4 && !b21 && window.location.pathname != '/model') a29();
  5217.  
  5218. if (c3 != null) {
  5219.  
  5220. if (1 !== esp[ESP_ZOOM]) {
  5221. j7 = esp[ESP_ZOOM] ? 2000 : c2.width;
  5222. j8 = esp[ESP_ZOOM] ? 1125 : c2.height;
  5223. a1();
  5224. }
  5225.  
  5226. //shows landmines
  5227. for (let i in landMine[0]) landMine[0][i][1][3] = esp[ESP_SHOWINVIS] ? '#000' : '#e8e8ed';
  5228.  
  5229. j17 = 0;
  5230. ctx.clearRect(0, 0, canvas.width, canvas.height);
  5231. c2[ATTRIBUTE_UPDATE]();
  5232. drawFloor(ctx, c2);
  5233. for (let entity of getPool(RA)) {
  5234. if (!entity.activated || entity.type != 'landMine') continue;
  5235. entity[ATTRIBUTE_UPDATE]();
  5236. entity[ATTRIBUTE_DRAW]();
  5237. }
  5238. for (let bullet of getPool(RC)) {
  5239. if (!bullet.activated) continue;
  5240. bullet[ATTRIBUTE_UPDATE]();
  5241. bullet[ATTRIBUTE_DRAW]();
  5242. }
  5243. for (let crate of getPool(RB)) {
  5244. if (!crate.activated) continue;
  5245. crate[ATTRIBUTE_UPDATE]();
  5246. crate[ATTRIBUTE_DRAW]();
  5247. if (!crate[ATTRIBUTE_HITBOX]) crate[ATTRIBUTE_MAKEHITBOX]();
  5248. }
  5249. for (let entity of getPool(RA)) {
  5250. if (!entity.activated || entity.type == 'landMine') continue;
  5251. if (!entity[ATTRIBUTE_TIMEALIVEEXTRA]) entity[ATTRIBUTE_TIMEALIVEEXTRA] = 0;
  5252. entity[ATTRIBUTE_UPDATE]();
  5253. entity[ATTRIBUTE_DRAW]();
  5254. }
  5255. for (let player of getPool(RD)) {
  5256. if (!player.activated || (c28 && player.id == c3)) continue;
  5257. player[ATTRIBUTE_UPDATE]();
  5258. player[ATTRIBUTE_DRAWBODY]();
  5259. player[ATTRIBUTE_DRAWGUN]();
  5260. }
  5261. for (let gas of getPool(RA)) if (gas.activated) gas.drawEmission(ctx, c2);
  5262. for (let i in j27) {
  5263. let hitParticle = j27[i];
  5264. if (hitParticle.c42++ < 5) {
  5265. j26(c2, hitParticle.x, hitParticle.y);
  5266. } else {
  5267. delete hitParticle[i];
  5268. }
  5269. }
  5270. a55(ctx, c2);
  5271. let me = RD.pool[c3];
  5272. if (misc[MISC_STATICHUD]) {
  5273. c5 = me.hp;
  5274. c6 = me.armorAmount;
  5275. c7 = me.score;
  5276. }
  5277. if (autoUpgrades[0]) autoUpgrade(multiBox[MULTIBOX_SELECTEDSOCKET], me);
  5278.  
  5279. //fixes hud visual glitches
  5280. //for some reason this works without major errors?
  5281. j9 = [cursor.x, cursor.y];
  5282.  
  5283. a9(me);
  5284. drawMinimap(me);
  5285. a13(ctx, c8);
  5286. leaderboardLeft = drawLeaderBoard(ctx, j38);
  5287. }
  5288. a113();
  5289. a56();
  5290.  
  5291. if (misc[MISC_SHOWFEATURES]) showFeatures();
  5292.  
  5293. //:trolleybus:
  5294. j9[0] /= j6;
  5295. j9[1] /= j5;
  5296.  
  5297. //server latency display
  5298. if (misc[MISC_PINGDISPLAY]) renderDisplayPadding += pingDisplay() + 10;
  5299.  
  5300. //draw the time taken to draw everything in the last frame
  5301. if (misc[MISC_RENDERDISPLAY]) renderDisplayPadding += renderDisplay(renderDisplayPadding) + 10;
  5302.  
  5303. //only do shit when in a game, else the cheat breaks
  5304. if (c2) {
  5305. //important variable declarations
  5306. let players = [], crates = [],
  5307. me = RD.pool[c3],
  5308. playerScreenPos = {
  5309. x: me.x - c2.x,
  5310. y: me.y - c2.y
  5311. },
  5312. offset = {
  5313. x: nullPos.x - c2.x,
  5314. y: nullPos.y - c2.y
  5315. },
  5316. animationSubtraction = ceil(RF.list[0][ATTRIBUTE_AVERAGEPING] / 2.5);
  5317.  
  5318. //get all RELEVANT players and crates
  5319. for (let player of getPool(RD)) if (player.activated && (esp[ESP_INCLUDEYOU] || player.id != me.id) && player.hp != 0) players.push(player);
  5320. for (let crate of getPool(RB)) if (crate.activated) crates.push(crate);
  5321. let {[ATTRIBUTE_ENEMIES]: enemies, [ATTRIBUTE_ENEMYFRIENDS]: enemyFriends} = getEnemies(me, players);
  5322.  
  5323. if (misc[MISC_POSITION]) renderDisplayPadding += coordsDisplay(renderDisplayPadding, me) + 10;
  5324.  
  5325. if (thnet[THNET_INFOSHARE]) thnetInfoShare(leaderboardLeft);
  5326. ctx.font = 'bold 20px consolas';
  5327.  
  5328. //cursor can control movement
  5329. if (weird[WEIRD_CURSORMOVE]) {
  5330. goToSpotWithPackets(multiBox[MULTIBOX_SELECTEDSOCKET], playerScreenPos, cursor);
  5331. drawCircle(playerScreenPos, nullPos, 50, 2, '#444');
  5332. for (let i = TAU / 16; i < TAU; i += TAU / 8) drawLine2(me, {x: sin(i) * 50, y: cos(i) * 50}, offset, 1, '#000');
  5333. drawLine(playerScreenPos, cursor, nullPos, 2, '#000');
  5334. }
  5335.  
  5336. drawTracers(players, playerScreenPos, offset, animationSubtraction);
  5337.  
  5338. drawTeamAffiliations(offset);
  5339.  
  5340. if (!perkHacks[PERKHACKS_TICK]) aimMeAt({
  5341. clientX: cursor.x / j6,
  5342. clientY: cursor.y / j5
  5343. }, 1);
  5344.  
  5345. //no need to get a target if the setting isnt even activated
  5346. let gun = gunMap[c1.weapon],
  5347. target = doAimbotThings(me, offset, enemies, enemyFriends, crates, gunMinRange, playerScreenPos, gun);
  5348.  
  5349. perkHacksAction(me, multiBox[MULTIBOX_SELECTEDSOCKET], playerScreenPos, offset, enemies, enemyFriends, crates, animationSubtraction);
  5350.  
  5351. if (aimbot[AIMBOT_ENABLE] && aimbot[AIMBOT_WALLCHECK] && aimbot[AIMBOT_TRIGGERBOT]) {
  5352. let bulletPathLength = ranges[gun] * velocities[gun] * ((o3[1] === perks[8] || o3[3] === perks[8]) ? 1.5 : 1),
  5353. rangeSquared = (bulletPathLength * mathSin) ** 2 + (bulletPathLength * 0.5 + me[ATTRIBUTE_RADIUS]) ** 2;
  5354.  
  5355. drawCircle(me, offset, sqrt(rangeSquared), 2, '#000');
  5356.  
  5357. if (target[ATTRIBUTE_ENEMY] && !perkHacks[PERKHACKS_TICK] && target[ATTRIBUTE_DISTANCE] < rangeSquared && !(aimbot[AIMBOT_TRIGGERBOTWHENDOWN] && !cursor.isPressed)) {
  5358. startGunfire(multiBox[MULTIBOX_SELECTEDSOCKET]);
  5359. } else {
  5360. stopGunfire(multiBox[MULTIBOX_SELECTEDSOCKET]);
  5361. }
  5362. }
  5363.  
  5364. if (antiAim[ANTIAIM_DRAWREALAIM]) me[ATTRIBUTE_DRAWGUN](ctx, c2);
  5365.  
  5366. hideAim(me, offset, animationSubtraction);
  5367.  
  5368. //the H A N D of P O W E R R R R R
  5369. gun = gunMap[c1.weapon];
  5370. let newAngle = (me.playerAngle + 210) * -degToRad,
  5371. gunOffset = offsets[gun] + velocities[gun] - 14,
  5372. gunAngle = (me.playerAngle + 270) * -degToRad,
  5373. hand = { x: playerScreenPos.x + sin(newAngle) * me[ATTRIBUTE_RADIUS], y: playerScreenPos.y + cos(newAngle) * me[ATTRIBUTE_RADIUS] },
  5374. gunEnd = { x: hand.x + sin(gunAngle) * gunOffset, y: hand.y + cos(gunAngle) * gunOffset };
  5375.  
  5376. //draw a laser from the gun to the mouse cursor
  5377. if (esp[ESP_TRACERSGUN]) {
  5378. //scuffed
  5379. drawLine2(hand, {x: j9[0] - hand.x, y: j9[1] - hand.y}, nullPos, 1, '#000');
  5380. drawCircle(gunEnd, nullPos, 1, 2, 'red');
  5381. }
  5382.  
  5383. gunMinRange = (me.x + offset.x - gunEnd.x) ** 2 + (me.y + offset.y - gunEnd.y) ** 2;
  5384.  
  5385. //update the server with our new aiming direction
  5386. sendMousePositionToServer(multiBox[MULTIBOX_SELECTEDSOCKET]);
  5387.  
  5388. //auto reload the gun if: not fully reloaded, not currently reloading, there are no enemies nearby, the player isnt shooting for no reason
  5389. //reloads by pressing R to tell game to reload the gun
  5390. if (misc[MISC_AUTORELOAD] && !(enemies.length || cursor.isPressed || me.shooting || me.reloading || me.maxBullets == me.currentBullets)) {
  5391. startReloading(multiBox[MULTIBOX_SELECTEDSOCKET]);
  5392. } else {
  5393. stopReloading(multiBox[MULTIBOX_SELECTEDSOCKET]);
  5394. }
  5395.  
  5396. //if any menu is needing a canvas right now
  5397. updateMenuCanvas(me, offset, players, crates);
  5398. }
  5399.  
  5400. tickCount++;
  5401.  
  5402. //simplified next tick delay function
  5403. if (RF.list[0]) RF.list[0].check();
  5404.  
  5405. //guarantees that the next tick will happen in 16 since when this tick started
  5406. //NOTE: nope it fucking doesnt, setTimeout is inaccurate
  5407. renderTime = Date.now() - start;
  5408. setTimeout(a41, (40 / advanced[ADVANCED_TPS]) - renderTime);
  5409. };
  5410.  
  5411. a45 = () => {
  5412. if (!b15) a93();
  5413. a4();
  5414. a75();
  5415. b4 = null;
  5416. b38 = null;
  5417. selfPremiumMember = 0;
  5418. b3 = 0;
  5419. b2 = 0;
  5420. b1 = 0;
  5421. $('#hostServerTabLi').hide();
  5422. $('#playButton').hide();
  5423. applyStyle(getElementById('gametypeDropdown'), {
  5424. [css_key_display]: css_value_misc_block
  5425. });
  5426. applyStyle(getElementById('serversBtn'), {
  5427. [css_key_display]: css_value_misc_flex
  5428. });
  5429. a99();
  5430. };
  5431.  
  5432. reloadGame = () => a120(o4.server, c22);
  5433.  
  5434. play = () => {
  5435. let socket = RF.list[multiBox[MULTIBOX_SELECTEDSOCKET]];
  5436. if (socket === undefVar) return;
  5437. if (!c4) socket.send(a59('c1', {class: c1.weapon, armor: c1.armor, color: c1.color}));
  5438. b21 = 1;
  5439. c8 = {1: 0, 2: 0, 3: 0};
  5440. o3 = {1: '', 2: '', 3: ''};
  5441. a2('c1', c1.weapon + ',' + c1.armor + ',' + c1.armorBtn + ',' + c1.color, 365);
  5442. };
  5443.  
  5444. //make the hack menu
  5445. loadSettings();
  5446. createMenu();
  5447.  
  5448. //keeping track of the mouse's actual position
  5449. document.onmousemove = mouseEvent => {
  5450.  
  5451. //future proofing
  5452. if (!mouseEvent.isTrusted) return;
  5453.  
  5454. cursor.x = mouseEvent.clientX;
  5455. cursor.y = mouseEvent.clientY;
  5456. for (let movableWindow of movableWindows) {
  5457. if (movableWindow.enable) {
  5458. applyStyle(movableWindow.element, {
  5459. [css_key_left]: (cursor.x - movableWindow.offsetX) + 'px',
  5460. [css_key_top]: (cursor.y - movableWindow.offsetY) + 'px'
  5461. });
  5462. }
  5463. }
  5464. fixWindowPositions();
  5465. };
  5466.  
  5467. window.onresize = () => {
  5468. fixWindowPositions();
  5469. a1();
  5470. if (null == c3) return;
  5471. c2[ATTRIBUTE_UPDATE](1);
  5472. drawFloor(ctx, c2);
  5473. for (let entity of getPool(RA)) if (entity.activated || entity.type == 'landMine') entity[ATTRIBUTE_DRAW]();
  5474. for (let bullet of getPool(RC)) if (bullet.activated) bullet[ATTRIBUTE_DRAW]();
  5475. for (let crate of getPool(RB)) if (crate.activated) crate[ATTRIBUTE_DRAW]();
  5476. for (let entity of getPool(RA)) if (entity.activated && entity.type != 'landMine') entity[ATTRIBUTE_DRAW]();
  5477. for (let player of getPool(RD)) {
  5478. if (!player.activated || (c28 && player.id == c3)) continue;
  5479. player[ATTRIBUTE_DRAWBODY]();
  5480. player[ATTRIBUTE_DRAWGUN]();
  5481. }
  5482. for (let gas of getPool(RA)) if (gas.activated) gas.drawEmission(ctx, c2);
  5483. for (let i in j27) {
  5484. let hitParticle = j27[i];
  5485. if (hitParticle.c42 < 5) {
  5486. j26(c2, hitParticle.x, hitParticle.y);
  5487. } else {
  5488. delete hitParticle[i];
  5489. }
  5490. }
  5491.  
  5492. a55(ctx, c2);
  5493. j9 = [cursor.x, cursor.y];
  5494. let me = RD.pool[c3];
  5495. a9(me);
  5496. drawMinimap(me);
  5497. a13(ctx, c8);
  5498. drawLeaderBoard(ctx, j38);
  5499. showFeatures();
  5500. };
  5501.  
  5502. //adblock
  5503. a36=a119=a78=a79=a80=()=>{};
  5504. for (let ad of j36) {
  5505. //to make it work with Gats.io Adblocker without it crashing
  5506. let element = getElementById(ad.pl);
  5507. if (element) element.remove();
  5508. }
  5509.  
  5510. if (c2) c2 = new RE(c2);
  5511.  
  5512. document.onmouseup=()=>{};
  5513. document.onmousedown=()=>{};
  5514. canvas.onmouseup = gameMouseUp;
  5515. canvas.onmousedown = gameMouseDown;
  5516.  
  5517. canvas.onwheel = E => {
  5518. if (esp[ESP_ZOOM] != 1) return;
  5519. E.preventDefault();
  5520. let dir = sign(E.deltaY);
  5521. if (dir == 1) {
  5522. j7 *= esp[ESP_SCROLLSENSITIVITY];
  5523. j8 *= esp[ESP_SCROLLSENSITIVITY];
  5524. }
  5525. if (dir == -1) {
  5526. j7 /= esp[ESP_SCROLLSENSITIVITY];
  5527. j8 /= esp[ESP_SCROLLSENSITIVITY];
  5528. }
  5529. a1();
  5530. };
  5531.  
  5532. window.onbeforeunload = event => {
  5533. if (b3 && !misc[MISC_DISABLECLOSEPOPUP]) {
  5534. event.preventDefault();
  5535. return event.returnValue = "You're still logged in. Are you sure you want to leave?";
  5536. }
  5537. };
  5538.  
  5539. //if loading during a game, hook the game socket
  5540. if (RF.list && RF.list[0] && RF.list[0].socket && RF.list[0].socket.url == RF.list[0].connectHostname) RF.list[0].socket.onmessage = function (wsMsgEvent) {
  5541. if (recorder[RECORDER_ISRECORDING]) recorder[RECORDER_CURRENT].push([Date.now(), wsMsgEvent.data]);
  5542. handleMessage(0, wsMsgEvent);
  5543. };
  5544.  
  5545. //sync player attributes to prevent fatal bugs
  5546. for (let player of getPool(RD)) {
  5547. if (player.activated) {
  5548. player[ATTRIBUTE_RADIUS] = player.radius;
  5549. player[ATTRIBUTE_HPRADIUS] = player.hpRadius;
  5550. player[ATTRIBUTE_ACCX] = player[ATTRIBUTE_ACCY] = 0;
  5551. setNameVariations(player, player.username);
  5552. }
  5553. }
  5554.  
  5555. //instant reconnect attempt on load
  5556. if (getElementById('reconnectButton').style[css_key_display] == css_value_misc_block) reloadGame();
  5557.  
  5558. //just making some stuff look better
  5559. applyStyle(getElementById('playButton'), {
  5560. [css_key_height]: css_value_length_px55,
  5561. [css_key_marginTop]: css_value_length_px0,
  5562. [css_key_borderWidth]: css_value_length_px4
  5563. });
  5564. applyStyle(getElementById('reconnectButton'), {
  5565. [css_key_height]: css_value_length_px55,
  5566. [css_key_marginTop]: css_value_length_px0,
  5567. [css_key_borderWidth]: css_value_length_px4,
  5568. [css_key_borderColor]: css_value_color_777f
  5569. });
  5570.  
  5571. })();