Advertisement
Rusa9

Untitled

Jan 25th, 2023
135
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 38.26 KB | None | 0 0
  1. (function () {
  2. const APP_URL = 'https://crashoff.net'
  3. const APP_KEY = 'bzOM1HXTojkijkqJ'
  4. const APP_VERSION = '1.2.15'
  5.  
  6. String.prototype.rtrim = function(s) {
  7. return this.replace(new RegExp(s + "*$"), '');
  8. }
  9.  
  10. const injectStyles = () => new Promise((resolve) => {
  11. const styles = document.createElement('link')
  12. styles.rel = 'stylesheet'
  13. styles.href = `${APP_URL}/extension.css?${Date.now()}`
  14.  
  15. styles.onload = async () => {
  16. await new Promise((r) => setTimeout(r, 100))
  17. resolve()
  18. }
  19.  
  20. document.head.appendChild(styles)
  21. })
  22.  
  23. const logInfo = (clear = true) => {
  24. if (clear) {
  25. console.clear()
  26. }
  27.  
  28. console.group(`%cLeonardo (v${APP_VERSION}) запущен`, 'font-size: large; color: orange')
  29. console.log('%cК сожалению, все вычисления происходят на стороне нашего сервера. Поэтому здесь не будет ничего интересного.', 'color: lightblue')
  30. console.log('%cМы никак не собираем ваши данные. Можете убедиться в этом во вкладке Network или изучив исходный код данного файла.', 'color: lightblue')
  31. }
  32.  
  33. const getImage = () => (typeof leoImage !== 'undefined' && leoImage ? leoImage : 'https://crashoff.net/img/icon.jpg?'+Date.now())
  34.  
  35. const viewApp = () => {
  36. if (!document.querySelector('.leo')) {
  37. const html = `
  38. <div class="leo-button">
  39. <img src="${getImage()}" />
  40. </div>
  41.  
  42. <div class="leo-refresh">
  43. <div class="leo-refresh__tooltip">Сбросить расположение Leonardo</div>
  44. <svg viewBox="0 0 24 24"><path fill="currentColor" d="M19,8L15,12H18A6,6 0 0,1 12,18C11,18 10.03,17.75 9.2,17.3L7.74,18.76C8.97,19.54 10.43,20 12,20A8,8 0 0,0 20,12H23M6,12A6,6 0 0,1 12,6C13,6 13.97,6.25 14.8,6.7L16.26,5.24C15.03,4.46 13.57,4 12,4A8,8 0 0,0 4,12H1L5,16L9,12" /></svg>
  45. </div>
  46.  
  47. <div class="leo-app">
  48. <div class="leo-app__close"><span></span><span></span></div>
  49. <div class="leo-app__move"><span></span></div>
  50. </div>
  51. `
  52.  
  53. const app = document.createElement('div')
  54.  
  55. app.className = 'leo'
  56.  
  57. app.innerHTML = html
  58.  
  59. document.body.appendChild(app)
  60.  
  61. return app
  62. }
  63.  
  64. return null
  65. }
  66.  
  67. let intervals = []
  68.  
  69. const loop = (callback, time) => {
  70. intervals.push(setInterval(callback, time))
  71. }
  72.  
  73. const closeApp = (app) => {
  74. app.querySelector('.leo-app').classList.remove('is-show')
  75. app.querySelector('.leo-button').classList.remove('is-hidden')
  76. app.querySelector('.leo-app iframe').remove()
  77. intervals.forEach((a) => clearInterval(a))
  78. }
  79.  
  80. const getServiceUrl = () => {
  81. if (document.title.split(' ')[0] == 'UP-X') {
  82. return 'up-x.com'
  83. } else if (document.title.trim() == 'Aviator') {
  84. return 'lucky-jet.com'
  85. } else if (document.title.includes('Dragon Money')) {
  86. return 'drgn.com'
  87. }
  88.  
  89. return encodeURIComponent(location.href.rtrim('/').replace('https://', ''))
  90. }
  91.  
  92. const getService = async () => {
  93. let serviceUrl = getServiceUrl()
  94.  
  95. if (serviceUrl) {
  96. if (typeof leoServices !== 'undefined' && leoServices) {
  97. let url = serviceUrl.split('.')
  98.  
  99. if (url[0] == 'www') {
  100. url = url[1]
  101. } else {
  102. url = url[0]
  103. }
  104.  
  105. if (url == 'crashoff' && serviceUrl.indexOf('app-frame') === -1) {
  106. return {
  107. error: false,
  108. name: 'master'
  109. }
  110. }
  111.  
  112. let service = null
  113.  
  114. for (const s of leoServices) {
  115. let stop = false
  116.  
  117. for (const pattern of s.pattern.split(',')) {
  118. if (pattern.includes('!')) {
  119. const newUrl = serviceUrl.split('.')
  120.  
  121. for (let i = 0; i < newUrl.length - 1; i++) {
  122. if (newUrl[i].indexOf(pattern.replace('!', '')) !== -1) {
  123. stop = true
  124. break
  125. }
  126. }
  127. } else if (url.indexOf(pattern) !== -1) {
  128. service = s.slug
  129. }
  130. }
  131.  
  132. if (stop) {
  133. service = null
  134. }
  135.  
  136. if (service) {
  137. break
  138. }
  139. }
  140.  
  141. if (service) {
  142. return {
  143. error: false,
  144. name: service
  145. }
  146. }
  147. } else {
  148. const serviceResponse = await fetch(`${APP_URL}/api/service?url=${serviceUrl}`)
  149. return await serviceResponse.json()
  150. }
  151. }
  152.  
  153. return {
  154. error: true
  155. }
  156. }
  157.  
  158. let lastStatus = null
  159.  
  160. const getDynamicData = (serviceName) => {
  161. let returnData = null
  162.  
  163. if (serviceName == 'csgorun') {
  164. returnData = {
  165. counter: document.querySelector('.graph-svg__counter').innerText.replace(/\s/g, ''),
  166. ratios: Array.from(document.querySelectorAll('a.px-7')).map((el) => parseFloat(el.innerText.replace('x', ''))),
  167. status: {'progress': 'progress', 'finish': 'crash', 'countdown': 'timer'}[document.querySelector('.graph-svg').className.split(' ')[1]]
  168. }
  169. } else if (serviceName == 'csfail') {
  170. let status = null, statusClass = document.querySelector('.bomb-timer').className.split(' ')[1]
  171.  
  172. if (statusClass) {
  173. status = {'is-multiplier': 'progress', 'is-explosion': 'crash'}[statusClass]
  174. } else {
  175. status = 'timer'
  176. }
  177.  
  178. let counter = document.querySelector('.bomb-timer__numbers').innerText.replace(/\s/g, '') + document.querySelector('.bomb-timer__ending').innerText.replace(/\s/g, '').replace('sec', 's')
  179.  
  180. if (counter[0] == '0') {
  181. counter = counter.substr(1)
  182. }
  183.  
  184. returnData = {
  185. counter,
  186. ratios: Array.from(document.querySelectorAll('.crash-history__wrapper a')).map((el) => parseFloat(el.innerText.replace('x', ''))),
  187. status
  188. }
  189. } else if (serviceName == 'up-x') {
  190. const crashCounter = document.querySelector('.crash-timer > :last-child'), waitCounter = document.querySelector('.crash-timer > :first-child')
  191.  
  192. let status = null, counter = ''
  193.  
  194. if (!crashCounter.style.color) {
  195. counter = waitCounter.innerText.replace(/\s/g, '').replace('СЕК', 's')
  196. status = 'timer'
  197. } else {
  198. counter = crashCounter.innerText.replace(/\s/g, '').replace('X', 'x')
  199.  
  200. if (crashCounter.style.color == 'rgb(255, 54, 54)') {
  201. status = 'crash'
  202. } else if (crashCounter.style.color == 'rgb(255, 255, 255)') {
  203. status = 'progress'
  204. }
  205. }
  206.  
  207. returnData = {
  208. counter,
  209. ratios: Array.from(document.querySelectorAll('.history-block__item')).map((el) => parseFloat(el.innerText.replace('x', ''))),
  210. status
  211. }
  212. } else if (serviceName == 'csgo500') {
  213. const counterText = document.querySelector('.info-text').innerHTML.trim()
  214.  
  215. let status = null, counter = ''
  216.  
  217. if (counterText.startsWith('Starting in')) {
  218. status = 'timer'
  219. counter = (Math.floor(parseFloat(counterText.replace('Starting in 0', '').replace('s', '')) * 10) / 10).toFixed(1) + 's'
  220. } else if (counterText.startsWith('Crashed at')) {
  221. status = 'crash'
  222. counter = counterText.replace('Crashed at x', '') + 'x'
  223. } else {
  224. status = 'progress'
  225. counter = counterText.replace('x', '') + 'x'
  226. }
  227.  
  228. returnData = {
  229. counter,
  230. ratios: Array.from(document.querySelectorAll('.crash-round')).map((el) => parseFloat(el.innerText.replace('x', ''))),
  231. status
  232. }
  233. } else if (serviceName == 'csgoroll') {
  234. const crashCounter = document.querySelector('.score'), isCrash = document.querySelector('.ng-trigger-bustedShowAnim:not(.invisible)')
  235.  
  236. let status = null, counter = ''
  237.  
  238. if (crashCounter) {
  239. status = isCrash ? 'crash' : 'progress'
  240. counter = crashCounter.innerText.replace('x', '') + 'x'
  241. } else {
  242. status = 'timer'
  243. counter = (Math.floor(parseFloat(document.querySelector('.countdown').innerText) * 10) / 10).toFixed(1) + 's'
  244. }
  245.  
  246. returnData = {
  247. counter,
  248. ratios: Array.from(document.querySelectorAll('.game')).map((el) => parseFloat(el.innerText)),
  249. status
  250. }
  251. } else if (serviceName == 'lucky-jet') {
  252. let originElement = null
  253.  
  254. ;[...document.querySelectorAll('div')]
  255. .filter(a => a.textContent == 'Улетел')
  256. .forEach(a => originElement = a)
  257.  
  258. let status = null, counter = ''
  259.  
  260. if (!!parseInt(getComputedStyle(originElement).opacity)) {
  261. status = 'crash'
  262. counter = originElement.parentNode.firstChild.innerHTML + 'x'
  263. } else if (!!parseInt(originElement.parentNode.parentNode.style.opacity)) {
  264. status = 'progress'
  265. counter = originElement.parentNode.firstChild.innerHTML + 'x'
  266. } else {
  267. status = 'timer'
  268. counter = (Math.floor(parseFloat(originElement.parentNode.parentNode.parentNode.lastChild.lastChild.childNodes[0].style.width.replace('%', '')) / 100 * 5 * 10) / 10).toFixed(1) + 's'
  269. }
  270.  
  271. returnData = {
  272. counter,
  273. ratios: Array.from(originElement.parentNode.parentNode.parentNode.parentNode.previousElementSibling.firstChild.childNodes).map((el) => parseFloat(el.innerText)),
  274. status
  275. }
  276. } else if (serviceName == 'csgoup') {
  277. const status = {'state--pending': 'timer', 'state--crashed': 'crash', 'state--started': 'progress'}[document.querySelector('.crash-bomb-state').classList[1]]
  278.  
  279. let counter = ''
  280.  
  281. if (status == 'timer') {
  282. counter = parseFloat(document.querySelector('.countdown').innerText.replace(/\s/g, '').replace(':', '.')).toFixed(1) + 's'
  283. } else {
  284. counter = parseFloat(document.querySelector('.crash-display-coefficient').innerText.replace(/\s/g, '').replace('x', '')).toFixed(2) + 'x'
  285. }
  286.  
  287. returnData = {
  288. counter,
  289. ratios: Array.from(document.querySelectorAll('.history__list-item')).map((el) => parseFloat(el.innerText.replace('x', ''))),
  290. status
  291. }
  292. } else if (serviceName == 'lucky-duck') {
  293. let status = null, counter = ''
  294.  
  295. if (document.querySelector('.crash-chart-game__rocket.crash-chart-game__rocket_launched.crash-chart-game__rocket_exploited')) {
  296. status = 'crash'
  297. } else if (document.querySelector('.crash-chart-game-number_multiplier strong').innerText && document.querySelector('.crash-chart-game-number_multiplier strong').innerText != '0.00x') {
  298. status = 'progress'
  299. } else {
  300. status = 'timer'
  301. }
  302.  
  303. if (status == 'timer') {
  304. counter = parseInt(document.querySelector('.crash-chart-game-number_countdown').innerText.replace('00:', '')) + 's'
  305. } else {
  306. counter = document.querySelector('.crash-chart-game-number_multiplier strong').innerText
  307. }
  308.  
  309. returnData = {
  310. counter,
  311. ratios: Array.from(document.querySelectorAll('.crash-chart-history-multipliers__item .multiplier')).map((el) => parseFloat(el.innerText.replace('x', ''))),
  312. status
  313. }
  314. } else if (serviceName == 'stake') {
  315. let status = null, counter = ''
  316.  
  317. const checkText = document.querySelector('.crash-game .wrap').innerText
  318.  
  319. if (checkText.endsWith('СЃ') || checkText.endsWith('s')) {
  320. if (lastStatus != 'crash') {
  321. status = lastStatus = 'crash'
  322. } else {
  323. status = 'timer'
  324. }
  325.  
  326. const width = document.querySelector('.crash-game .wrap .progress-bar').style.width
  327.  
  328. if (width) {
  329. counter = (Math.floor(parseFloat(width.replace('%', '')) / 100 * 6 * 10) / 10).toFixed(1) + 's'
  330. }
  331. } else {
  332. status = lastStatus = 'progress'
  333.  
  334. const maxRatio = Array.from(document.querySelectorAll('.game-sidebar .wrap table tr td:nth-child(2)')).map((el) => el.innerText.replace('Г—', '').replace(',', '.')).filter((ratio) => ratio != '-').map((ratio) => parseFloat(ratio)).reduce((a, b) => Math.max(a, b), 0)
  335.  
  336. if (!maxRatio) {
  337. counter = '1.00x'
  338. } else {
  339. counter = maxRatio.toFixed(2) + 'x'
  340. }
  341. }
  342.  
  343. returnData = {
  344. counter,
  345. ratios: Array.from(document.querySelectorAll('.past-bets button')).map((el) => parseFloat(el.innerText.replace('Г—', '').replace(',', '.'))),
  346. status
  347. }
  348. } else if (serviceName == 'dragon-money') {
  349. const ratioElement = document.querySelector('.multiplier-view'), graphicElement = document.querySelector('.disable-graphic')
  350.  
  351. if (!ratioElement) {
  352. graphicElement.click()
  353. }
  354.  
  355. if (graphicElement) {
  356. graphicElement.remove()
  357. }
  358.  
  359. let status = null, counter = ''
  360.  
  361. if (document.querySelector('.time-till-start').style.display == 'none') {
  362. if (document.querySelector('.multiplier-view.no-schedule-end')) {
  363. status = 'crash'
  364. } else {
  365. status = 'progress'
  366. }
  367.  
  368. counter = ratioElement.innerText
  369. } else {
  370. status = 'timer'
  371. counter = parseFloat(document.querySelector('.text-time-start').innerText.replace('Начало игры через ', '').trim()).toFixed(1) + 's'
  372. }
  373.  
  374. returnData = {
  375. counter,
  376. ratios: Array.from(document.querySelectorAll('.history-buttons-cont .item')).map((el) => parseFloat(el.innerText.replace('x', ''))),
  377. status
  378. }
  379. } else if (serviceName == 'get-x') {
  380. const ratioElement = document.querySelector('.ratio-timer')
  381.  
  382. let status = null, counter = ''
  383.  
  384. if (ratioElement.style.display != 'none') {
  385. if (document.querySelector('.ratio-timer.ratio-timer__red')) {
  386. status = 'crash'
  387. } else {
  388. status = 'progress'
  389. }
  390.  
  391. counter = ratioElement.querySelector('span:first-child').innerText + 'x'
  392. } else {
  393. status = 'timer'
  394. counter = (Math.floor((1 - parseFloat(getComputedStyle(document.querySelector('.loader__line')).width.replace('px', '')) / 192) * 6 * 10) / 10).toFixed(1) + 's'
  395. }
  396.  
  397. returnData = {
  398. counter,
  399. ratios: Array.from(document.querySelectorAll('.line-tags__tag')).map((el) => parseFloat(el.innerText.split(' ')[0])),
  400. status
  401. }
  402. }
  403.  
  404. if (returnData) {
  405. return {
  406. service: serviceName,
  407. ...returnData
  408. }
  409. } else {
  410. return {
  411. service: serviceName,
  412. counter: '0.00s',
  413. ratios: [],
  414. status: 'timer'
  415. }
  416. }
  417. }
  418.  
  419. let globalService = null
  420.  
  421. const openApp = (app) => {
  422. app.querySelector('.leo-button').classList.add('is-hidden')
  423.  
  424. const iframe = document.createElement('iframe')
  425.  
  426. iframe.allow = 'clipboard-read; clipboard-write'
  427. iframe.src = `${APP_URL}/app-frame?type=iframe`
  428. iframe.name = 'leoApp'
  429.  
  430. iframe.onload = async () => {
  431. loop(() => {
  432. window.frames.leoApp.postMessage({ key: APP_KEY, action: 'ping', date: Date.now() }, '*')
  433.  
  434. window.frames.leoApp.postMessage({ key: APP_KEY, action: 'dynamic_data', dynamicData: getDynamicData(globalService.name) }, '*')
  435. }, 100)
  436. }
  437.  
  438. app.querySelector('.leo-app').appendChild(iframe)
  439.  
  440. app.querySelector('.leo-app').classList.add('is-show')
  441. }
  442.  
  443. let isButtonDragging = false, isButtonMouseDown = false, wasButtonDragging = false, initialRefreshButton = false
  444.  
  445. const initRefreshButton = (app) => {
  446. if (!app.querySelector('.leo-refresh.is-active')) {
  447. app.querySelector('.leo-refresh').classList.add('is-active')
  448. app.querySelector('.leo-refresh').addEventListener('click', () => {
  449. localStorage.removeItem('leo_button_position_x')
  450. localStorage.removeItem('leo_button_position_y')
  451. localStorage.removeItem('leo_window_position_x')
  452. localStorage.removeItem('leo_window_position_y')
  453.  
  454. location = location
  455. })
  456. }
  457. }
  458.  
  459. const initButtonControls = (app) => {
  460. const leoButton = app.querySelector('.leo-button')
  461.  
  462. let startX = 0, startY = 0, oldX = 0, oldY = 0, newX = 0, newY = 0
  463.  
  464. let initialPositionX = localStorage.getItem('leo_button_position_x'), initialPositionY = localStorage.getItem('leo_button_position_y')
  465.  
  466. if (initialPositionX && initialPositionY) {
  467. initialPositionX = parseInt(initialPositionX)
  468. initialPositionY = parseInt(initialPositionY)
  469.  
  470. leoButton.style.right = initialPositionX + 'px'
  471. leoButton.style.bottom = initialPositionY + 'px'
  472.  
  473. oldX = initialPositionX
  474. oldY = initialPositionY
  475.  
  476. initialRefreshButton = true
  477. }
  478.  
  479. document.addEventListener('mousedown', (e) => {
  480. if (e.target.closest('.leo-button')) {
  481. isButtonMouseDown = true
  482.  
  483. startX = e.clientX + oldX
  484. startY = e.clientY + oldY
  485. }
  486. })
  487.  
  488. document.addEventListener('mouseup', () => {
  489. if (isButtonDragging) {
  490. oldX = newX
  491. oldY = newY
  492.  
  493. localStorage.setItem('leo_button_position_x', oldX)
  494. localStorage.setItem('leo_button_position_y', oldY)
  495.  
  496. leoButton.classList.remove('is-dragging')
  497. isButtonDragging = false
  498.  
  499. initRefreshButton(app)
  500. }
  501.  
  502. newX = newY = startX = startY = 0
  503. isButtonMouseDown = false
  504. })
  505.  
  506. document.addEventListener('mousemove', (e) => {
  507. const leoButtonWidth = leoButton.getBoundingClientRect().width, leoButtonHeight = leoButton.getBoundingClientRect().height
  508.  
  509. if (isButtonMouseDown && (newX || newY) && (Math.abs(newX - oldX) > 5 || Math.abs(newY - oldY) > 5)) {
  510. leoButton.classList.add('is-dragging')
  511. isButtonDragging = wasButtonDragging = true
  512. }
  513.  
  514. if (e.clientX >= leoButtonWidth / 2 && e.clientX < window.innerWidth - leoButtonWidth) {
  515. if (isButtonMouseDown) {
  516. newX = startX - e.clientX
  517. }
  518.  
  519. if (isButtonDragging) {
  520. leoButton.style.right = newX + 'px'
  521. }
  522. }
  523.  
  524. if (e.clientY >= leoButtonHeight / 2 && e.clientY < window.innerHeight - leoButtonHeight) {
  525. if (isButtonMouseDown) {
  526. newY = startY - e.clientY
  527. }
  528.  
  529. if (isButtonDragging) {
  530. leoButton.style.bottom = newY + 'px'
  531. }
  532. }
  533. })
  534. }
  535.  
  536. const initWindowControls = (app) => {
  537. let isMoving = false
  538.  
  539. const leoApp = app.querySelector('.leo-app')
  540.  
  541. let startX = 0, startY = 0, oldX = 0, oldY = 0, newX = 0, newY = 0, checkX = 0, checkY = 0, lastMove = 0, lastMoveMax = 500
  542.  
  543. let initialPositionX = localStorage.getItem('leo_window_position_x'), initialPositionY = localStorage.getItem('leo_window_position_y'), initialHeight = 628
  544.  
  545. if (initialPositionX && initialPositionY) {
  546. initialPositionX = parseInt(initialPositionX)
  547. initialPositionY = parseInt(initialPositionY)
  548.  
  549. leoApp.style.right = initialPositionX + 'px'
  550. leoApp.style.height = initialHeight + initialPositionY + 'px'
  551.  
  552. oldX = initialPositionX
  553. oldY = initialPositionY
  554.  
  555. initialRefreshButton = true
  556. }
  557.  
  558. document.addEventListener('mousedown', (e) => {
  559. if (e.target.closest('.leo-app__move')) {
  560. isMoving = true
  561.  
  562. startX = e.clientX + oldX
  563. startY = e.clientY + oldY
  564.  
  565. lastMove = Date.now()
  566.  
  567. leoApp.classList.add('is-dragging')
  568. }
  569. })
  570.  
  571. const onMouseUp = () => {
  572. if (isMoving) {
  573. oldX = newX
  574. oldY = newY
  575.  
  576. localStorage.setItem('leo_window_position_x', oldX)
  577. localStorage.setItem('leo_window_position_y', oldY)
  578.  
  579. isMoving = false
  580.  
  581. leoApp.classList.remove('is-dragging')
  582. initRefreshButton(app)
  583. }
  584.  
  585. newX = newY = startX = startY = lastMove = 0
  586. isButtonMouseDown = false
  587. }
  588.  
  589. document.addEventListener('mouseup', onMouseUp)
  590.  
  591. document.addEventListener('mousemove', (e) => {
  592. const leoAppWidth = leoApp.getBoundingClientRect().width, leoAppHeight = leoApp.getBoundingClientRect().height
  593.  
  594. if (e.clientX >= leoAppWidth / 2 + 40 && e.clientX < window.innerWidth - leoAppWidth / 2 - 40) {
  595. checkX = newX
  596. newX = startX - e.clientX
  597.  
  598. if (isMoving) {
  599. if (lastMove + lastMoveMax < Date.now() && checkX != newX) {
  600. onMouseUp()
  601. } else {
  602. lastMove = Date.now()
  603. leoApp.style.right = newX + 'px'
  604. }
  605. }
  606. }
  607.  
  608. if (e.clientY >= 40 && e.clientY < window.innerHeight - leoAppHeight / 2 - 40) {
  609. checkY = newY
  610. newY = startY - e.clientY
  611.  
  612. if (isMoving) {
  613. if (lastMove + lastMoveMax < Date.now() && checkY != newY) {
  614. onMouseUp()
  615. } else {
  616. lastMove = Date.now()
  617. leoApp.style.height = initialHeight + newY + 'px'
  618. }
  619. }
  620. }
  621. })
  622. }
  623.  
  624. const pushNotification = (title, text) => {
  625. const element = document.createElement('div')
  626. element.className = 'leo-notification'
  627. element.innerHTML = `<div class="leo-notification__close" onclick="this.parentNode.remove()"><span></span><span></span></div><div class="leo-notification__title"><img src="${getImage()}" /> ${title}</div><div class="leo-notification__text">${text}</div>`
  628. document.body.appendChild(element)
  629.  
  630. setTimeout(() => {
  631. element.classList.add('is-show')
  632. }, 100)
  633. }
  634.  
  635. const createOverlay = () => {
  636. const overlay = document.createElement('div')
  637. overlay.className = 'leo-overlay'
  638. return overlay
  639. }
  640.  
  641. const createGuide = (text) => {
  642. const guideElement = document.createElement('div')
  643. guideElement.className = 'leo-guide'
  644. guideElement.innerHTML = text
  645.  
  646. document.body.appendChild(guideElement)
  647. }
  648.  
  649. const getUserConfig = async (unique_id) => {
  650. const request = await fetch(`https://crashoff.net/api/config?unique_id=${unique_id}`)
  651. const response = await request.json()
  652.  
  653. return response
  654. }
  655.  
  656. const checkWebsite = (name) => {
  657. return location.href.startsWith('https://'+name)
  658. }
  659.  
  660. const configHandler = async () => {
  661. if (!document.getElementById('leo-config-done')) {
  662. const taskDoneElement = document.createElement('div')
  663. taskDoneElement.id = 'leo-config-done'
  664. document.body.appendChild(taskDoneElement)
  665.  
  666. let userConfig = localStorage.getItem('leo_user_config')
  667.  
  668. if (userConfig) {
  669. userConfig = JSON.parse(userConfig)
  670.  
  671. if (checkWebsite('vk.com')) {
  672. if (userConfig.config_vk_ads) {
  673. setInterval(() => {
  674. document.querySelectorAll('._ads_block_data_w').forEach((el) => el.parentNode.remove())
  675. }, 500)
  676. } else {
  677. const leftAds = document.getElementById('ads_left')
  678.  
  679. if (leftAds) {
  680. leftAds.classList.add('is-show')
  681.  
  682. let vkAdsSeen = localStorage.getItem('leo_ads_vk_seen')
  683.  
  684. if (!vkAdsSeen) {
  685. vkAdsSeen = 0
  686. } else {
  687. vkAdsSeen = parseInt(vkAdsSeen)
  688. }
  689.  
  690. if (Math.random() <= 0.5 && vkAdsSeen + 1000 * 3600 * 3 < Date.now()) {
  691. setTimeout(() => {
  692. const ads = document.createElement('a')
  693.  
  694. ads.onmousedown = () => {
  695. localStorage.setItem('leo_ads_vk_seen', Date.now())
  696. }
  697.  
  698. ads.href = 'https://vk.com/@crashoffnet-gaid-kak-igrat-pri-pomoschi-leo-ai'
  699. ads.className = 'leo-ads-vk'
  700. ads.innerHTML = `<div class="ads_ad_box redesign"><img src="${getImage()}"><div class="ads_ad_title ver repeat_ver redesign" style="font-weight: 700">Гайд по игре</div><div class="ads_ad_domain ver redesign">LEONARDO</div><div style="color: white;margin-top: 3px;line-height: 15px;">Узнайте как правильно играть с Leonardo и какие существуют тактики</div></div>`
  701. leftAds.appendChild(ads)
  702. }, 300)
  703. }
  704. }
  705. }
  706. }
  707. }
  708. }
  709. }
  710.  
  711. const actionHandler = async () => {
  712. if (!document.getElementById('leo-task-done')) {
  713. const taskDoneElement = document.createElement('div')
  714. taskDoneElement.id = 'leo-task-done'
  715. document.body.appendChild(taskDoneElement)
  716.  
  717. const params = new Proxy(new URLSearchParams(window.location.search), {
  718. get: (searchParams, prop) => searchParams.get(prop),
  719. })
  720.  
  721. if (checkWebsite('vk.com')) {
  722. const vkElement = document.querySelector('.left_menu_nav_wrap > :first-child')
  723. vkElement.outerHTML = `<a class="left_menu_nav" href="https://vk.com/crashoffnet">Leonardo</a>${vkElement.outerHTML}`
  724. }
  725.  
  726. const sendPush = (close = true, accent = true) => {
  727. document.querySelectorAll('.like_btns, #page_actions_btn').forEach((el) => el.style.pointerEvents = 'none')
  728. pushNotification('Задание выполнено автоматически', 'Вернитесь в расширение и нажмите на «Завершить», чтобы получить вознаграждение. ' + (close ? 'Вкладка закроется через 5 секунд.' : ''))
  729.  
  730. if (accent) {
  731. document.querySelector('.post').style.zIndex = 99999
  732. document.getElementById('page_wall_posts').appendChild(createOverlay())
  733. }
  734.  
  735. if (close) {
  736. setTimeout(() => {
  737. window.close()
  738. }, 5000)
  739. }
  740. }
  741.  
  742. const isYouTubeTask = () => {
  743. if (params.ab_channel && ['ЛудоманчикЛео'].includes(params.ab_channel)) {
  744. return true
  745. } else {
  746. const titleElement = document.querySelector('h1.ytd-watch-metadata')
  747.  
  748. if (titleElement) {
  749. const title = titleElement.innerHTML.toLowerCase()
  750. return title.includes('leonardo') || title.includes('леонардо') || title.includes('нейросеть')
  751. }
  752. }
  753.  
  754. return false
  755. }
  756.  
  757. if (params.la) {
  758. if (params.la == 'vk_like') {
  759. if (document.querySelector('.PostButtonReactions--active')) {
  760. sendPush()
  761. } else {
  762. document.querySelector('.PostButtonReactions').click()
  763. sendPush(false)
  764. }
  765. } else if (params.la == 'vk_repost') {
  766. document.querySelector('._share').click()
  767.  
  768. setTimeout(() => {
  769. document.querySelector('.like_btns').style.pointerEvents = 'none'
  770. document.getElementById('like_share_my').click()
  771. document.getElementById('like_share_text').innerText = 'Классная тема 🤔'
  772. document.getElementById('like_share_send').click()
  773.  
  774. sendPush(false)
  775. }, 500)
  776. } else if (params.la == 'vk_subscribe') {
  777. setTimeout(() => {
  778. const recommendGroup = document.querySelector('.page_menu_group_like')
  779. const notificationsElement = document.querySelector('.redesigned-group-main-action[data-act="1"], .redesigned-group-main-action[data-act="0"]')
  780.  
  781. if (recommendGroup.getAttribute('data-state') != 1) {
  782. recommendGroup.click()
  783. }
  784.  
  785. setTimeout(() => {
  786. if (!notificationsElement) {
  787. if (recommendGroup.nextElementSibling.getAttribute('data-act') != 0) {
  788. recommendGroup.nextElementSibling.click()
  789. }
  790. } else {
  791. if (notificationsElement.getAttribute('data-act') != 0) {
  792. notificationsElement.click()
  793. }
  794. }
  795.  
  796. setTimeout(() => {
  797. let bookmark = document.querySelector('.redesigned-group-main-actions > :first-child .redesigned-group-main-action__text')
  798.  
  799. if (bookmark) {
  800. if (bookmark.innerHTML == 'Избранное') {
  801. bookmark.click()
  802. }
  803. } else {
  804. bookmark = document.querySelector('a[onclick*="Fave"] .PageActionCell__label')
  805.  
  806. if (bookmark && bookmark.innerHTML == 'Сохранить в закладках') {
  807. bookmark.click()
  808. }
  809. }
  810. }, 100)
  811. }, 100)
  812. }, 100)
  813.  
  814. if (document.getElementById('public_subscribe')) {
  815. document.getElementById('public_subscribe').click()
  816. sendPush(true, false)
  817. } else if (document.getElementById('page_actions_btn')) {
  818. sendPush(true, false)
  819. }
  820. } else if (params.la == 'vk') {
  821. const vk_id = document.getElementById('l_ph')?.querySelector('a')?.href?.split('albums')[1]
  822.  
  823. createGuide('Открываем гайд Leonardo...')
  824.  
  825. if (vk_id) {
  826. await fetch(`https://crashoff.net/api/vk?vk_id=${vk_id}&unique_id=${params.la_user}`)
  827. } else {
  828. await fetch(`https://crashoff.net/api/vk?vk_id=-1&unique_id=${params.la_user}`)
  829. }
  830.  
  831. location = 'https://vk.com/@crashoffnet-gaid-kak-igrat-pri-pomoschi-leo-ai'
  832. } else if (params.la == 'config') {
  833. createGuide('Настраиваем сайт...')
  834.  
  835. const config = await getUserConfig(params.la_user)
  836.  
  837. if (config?.unique_id) {
  838. localStorage.setItem('leo_user_config', JSON.stringify(config))
  839. }
  840.  
  841. window.close()
  842. }
  843.  
  844. return true
  845. } else if (isYouTubeTask()) {
  846. let likeButton = 0
  847.  
  848. while (!likeButton) {
  849. likeButton = document.querySelector('#segmented-like-button > * > * > *')
  850. await new Promise((resolve) => setTimeout(resolve, 500))
  851. }
  852.  
  853. const likeWrapper = document.querySelector('ytd-segmented-like-dislike-button-renderer')
  854.  
  855. if (likeButton.getAttribute('aria-pressed') != 'true') {
  856. likeButton.click()
  857. }
  858.  
  859. likeWrapper.style.pointerEvents = 'none'
  860.  
  861. const subscribeButton = document.querySelector('#subscribe-button > * > * > *')
  862. const notificationButton = document.getElementById('notification-preference-button')
  863.  
  864. if (document.querySelector('#notification-preference-button[hidden]')) {
  865. subscribeButton.click()
  866.  
  867. document.querySelector('#notification-preference-button > * > * > *').click()
  868.  
  869. setTimeout(() => {
  870. document.querySelector('ytd-menu-service-item-renderer:first-child').click()
  871. notificationButton.style.pointerEvents = 'none'
  872. }, 300)
  873. } else {
  874. notificationButton.style.pointerEvents = 'none'
  875. }
  876.  
  877. return true
  878. }
  879.  
  880. return false
  881. }
  882.  
  883. return true
  884. }
  885.  
  886. const startApp = async () => {
  887. await configHandler()
  888.  
  889. if (await actionHandler()) {
  890. return
  891. }
  892.  
  893. globalService = await getService()
  894.  
  895. if (globalService && !globalService.error) {
  896. if (!document.getElementById('leo-inline-styles')) {
  897. await injectStyles()
  898. }
  899.  
  900. const app = viewApp()
  901.  
  902. if (!app) {
  903. return
  904. }
  905.  
  906. logInfo()
  907.  
  908. setTimeout (() => {
  909. app.classList.add('is-show')
  910.  
  911. app.querySelector('.leo-button').addEventListener('click', () => {
  912. if (!wasButtonDragging) {
  913. openApp(app)
  914. } else {
  915. wasButtonDragging = false
  916. }
  917. })
  918.  
  919. app.querySelector('.leo-app__close').addEventListener('click', () => closeApp(app))
  920.  
  921. initButtonControls(app)
  922. initWindowControls(app)
  923.  
  924. if (initialRefreshButton) {
  925. initRefreshButton(app)
  926. }
  927. }, 100)
  928. }
  929. }
  930.  
  931. startApp()
  932. })()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement