Last active
March 14, 2022 21:31
-
-
Save diego-mi/453fbfcc8307e682b4d9885efa354636 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ==UserScript== | |
// @name Zodiacs auto run race | |
// @namespace https://gist.github.com/diego-mi/453fbfcc8307e682b4d9885efa354636 | |
// @version 0.12 | |
// @description Zodiacs auto run race | |
// @author DiegoMi | |
// @match https://v2.zodiacs.me | |
// @grant none | |
// @run-at document-start | |
// ==/UserScript== | |
(function() { | |
'use strict'; | |
// Variaveis para guardar informacoes dos carros | |
const htmlElements = { | |
carListItemsElements: null | |
} | |
// Variaveis para encontrar elementos no html | |
const QuerySelector_CarList = '.car-list'; | |
const QuerySelector_CarItem = `${QuerySelector_CarList} .item`; | |
const QuerySelector_CarSelectedExpiredMessage = `.select-car .selected .text-red`; | |
const QuerySelector_CarSelectedStartRaceButton = `#root > section > section > div > div > div > div > div.selected.content.mb-1.text-center.p-3.shadowed > div > div.mt-3 > div.custom-btn.btn-green`; | |
const QuerySelector_CarSelectedStartRaceQuickRaceButton = `#root > section > section > div > div > div > div > div.selected.content.mb-1.text-center.p-3.shadowed > div > div.mt-3 > div.custom-btn.btn-yellow`; | |
const QuerySelector_CarSelectedStartCheckResultButton = `#root > section > section > div > div > div > div > div > div > div.mt-3 > div`; | |
const QuerySelector_CarSelectedStartCheckResultQuickRaceButton = `#root > section > section > div > div > div.ant-card.ant-card-bordered.select-car > div > div > div > div.mt-3 > div.custom-btn.btn-yellow.mt-3`; | |
const QuerySelector_CarSelectedRacesCounter = `#root > section > section > div > div > div > div > div.selected.content.mb-1.text-center.p-3.shadowed > div > div.d-flex.d-row > div:nth-child(2) > div:nth-child(4)`;; | |
const QuerySelector_CarSelectedStars = `#root > section > section > div > div > div.ant-card.ant-card-bordered.select-car > div > div > div > div.d-flex.d-row > div:nth-child(2) > div:nth-child(2) > span svg`; | |
const QuerySelector_ModalQuickRaceConfirmButton = `body > div:nth-child(7) > div > div.ant-modal-wrap.ant-modal-confirm-centered.ant-modal-centered > div > div.ant-modal-content > div > div > div.ant-modal-confirm-btns > button.ant-btn.ant-btn-success`; | |
const QuerySelector_ModalQuickRaceResultButton = `/html/body/div/section/section/div/div/div/div/div/div/div[4]/div`; | |
const QuerySelector_ModalResult = `body > div:nth-child(7) > div > div.ant-modal-wrap.ant-modal-confirm-centered.ant-modal-centered > div > div.ant-modal-content > div > div`; | |
const QuerySelector_ModalResultQuickRace = `body > div:nth-child(9) > div > div.ant-modal-wrap.ant-modal-confirm-centered.ant-modal-centered > div > div.ant-modal-content > div > div > div.ant-modal-confirm-btns > button`; | |
const QuerySelector_ModalResultClaimButton = `${QuerySelector_ModalResult} .ant-btn-success`; | |
const QuerySelector_ModalResultClaimQuickRaceButton = `body > div:nth-child(7) > div > div.ant-modal-wrap.ant-modal-confirm-centered.ant-modal-centered > div > div.ant-modal-content > div > div > div.ant-modal-confirm-btns > button > span`; | |
const QuerySelector_AmountCoin = `#root > section > header > div > div > div:nth-child(1) > span > b`; | |
let amountCoinInitial = 0; | |
let amountCoinInitialCurrentCar = 0; | |
let carsResult = []; | |
let currentCar = null; | |
const delayDefault = 50; | |
const delayDefaultRace = 28000; | |
let maxRacePerDay = 0; | |
const runAsQuickRace = true; | |
/** | |
* HELPERS | |
*/ | |
async function WaitForElement(selector) { | |
while (document.querySelector(selector) === null) { | |
await new Promise( resolve => requestAnimationFrame(resolve) ) | |
} | |
await new Promise(resolve => setTimeout(resolve, delayDefault)); | |
return document.querySelector(selector); | |
} | |
async function delay(time) { | |
return new Promise(resolve => setTimeout(resolve, time)); | |
} | |
function CarResult (carIndex, starsCar = 1) { | |
this.index = carIndex; | |
this.amountEarned = 0; | |
this.stars = starsCar; | |
this.races = 0; | |
this.expired = false; | |
this.raced = false; | |
this.addRace = () => this.races++; | |
this.setStars = function (stars) { this.stars = stars;} | |
this.setIndex = function (index) { this.index = index;} | |
this.setAmountEarned = function (amountEarned) { this.amountEarned = amountEarned;} | |
this.setAsExpired = function () { this.expired = true;} | |
this.setAsRaced = function () { this.raced = true;} | |
} | |
const GetRealIndex = (carIndex) => carIndex + 1; | |
/** | |
* END HELPERS | |
*/ | |
async function GetAmoutCoinInitial () { | |
await WaitForElement(QuerySelector_AmountCoin); | |
amountCoinInitial = document.querySelector(QuerySelector_AmountCoin).textContent; | |
} | |
async function GetAmoutCoinInitialCurrentCar (carIndex) { | |
await WaitForElement(QuerySelector_AmountCoin); | |
amountCoinInitialCurrentCar = document.querySelector(QuerySelector_AmountCoin).textContent; | |
} | |
async function GetAmoutCoinFinal () { | |
await WaitForElement(QuerySelector_AmountCoin); | |
const amount = document.querySelector(QuerySelector_AmountCoin).textContent; | |
alert(`Amount earned: ${amountCoinInitial - amount}`); | |
} | |
async function GetAmoutCoinFinalCurrentCar (carIndex) { | |
await WaitForElement(QuerySelector_AmountCoin); | |
const amount = document.querySelector(QuerySelector_AmountCoin).textContent; | |
const amountEarned = amount - amountCoinInitialCurrentCar; | |
currentCar.setAmountEarned(amountEarned); | |
} | |
async function GetStarsCarSelected () { | |
const stars = document.querySelectorAll(QuerySelector_CarSelectedStars); | |
currentCar.setStars(stars.length); | |
} | |
async function GetCars () { | |
await WaitForElement(QuerySelector_CarItem); | |
htmlElements.carListItemsElements = document.querySelectorAll(QuerySelector_CarItem); | |
if (htmlElements.carListItemsElements.length === 0) return console.log("Car Items not found"); | |
return console.log(`Car Items found: ${htmlElements.carListItemsElements.length}`); | |
} | |
async function DoRaces() { | |
for(let carIndex = 0; carIndex < htmlElements.carListItemsElements.length; carIndex++) { | |
currentCar = new CarResult(carIndex); | |
await selectCarListItemByIndex(carIndex); | |
await GetStarsCarSelected(); | |
await getMaxRaceCount(); | |
if (await isCarExpiredByIndex(carIndex)) { | |
currentCar.setAsExpired(); | |
} else { | |
await DoAllRacesOfCarByIndex(carIndex); | |
await delay(delayDefault); | |
} | |
await GetAmoutCoinFinalCurrentCar(); | |
carsResult.push(currentCar); | |
await AddHtml(); | |
} | |
} | |
async function getMaxRaceCount() { | |
const raceInformationText = document.querySelector(QuerySelector_CarSelectedRacesCounter).textContent; | |
const splitedString = raceInformationText.split('/'); | |
maxRacePerDay = splitedString[1]; | |
} | |
async function DoAllRacesOfCarByIndex(carIndex) { | |
await GetAmoutCoinInitialCurrentCar(carIndex); | |
const racesCount = runAsQuickRace ? 1 : maxRacePerDay; | |
for(let raceCount = 0; raceCount <= racesCount; raceCount++) { | |
if (await isCarRacedByIndex(carIndex)) { | |
currentCar.setAsRaced(); | |
await AddHtml(); | |
break; | |
} else { | |
await DoRaceByIndex(carIndex); | |
await GetCars(); | |
await selectCarListItemByIndex(carIndex); | |
} | |
} | |
console.log(`carsResult`, carsResult); | |
} | |
async function DoRaceByIndex(carIndex) { | |
await startRace(); | |
await waitForResult(); | |
await checkResult(); | |
await waitForModalResult(); | |
await claimResult(); | |
currentCar.addRace(); | |
await delay(delayDefault * 2); | |
} | |
async function selectCarListItemByIndex(carIndex) { | |
htmlElements.carListItemsElements[carIndex].click(); | |
await delay(delayDefault); | |
} | |
async function isCarExpiredByIndex(carIndex) { | |
return document.querySelector(QuerySelector_CarSelectedExpiredMessage) !== null; | |
} | |
async function isCarRacedByIndex() { | |
return document.querySelector(QuerySelector_CarSelectedRacesCounter).textContent.indexOf(`${maxRacePerDay}/${maxRacePerDay}`) > -1; | |
} | |
async function startRace() { | |
runAsQuickRace ? await startRaceQuickRace() : await startRaceDefault(); | |
} | |
async function startRaceDefault() { | |
document.querySelector(QuerySelector_CarSelectedStartRaceButton).click(); | |
} | |
async function startRaceQuickRace() { | |
console.log('startRaceQuickRace'); | |
document.querySelector(QuerySelector_CarSelectedStartRaceQuickRaceButton).click(); | |
await delay(300); | |
await WaitForElement(QuerySelector_ModalQuickRaceConfirmButton); | |
document.querySelector(QuerySelector_ModalQuickRaceConfirmButton).click(); | |
await delay(600); | |
} | |
async function waitForResult() { | |
await delay(300); | |
runAsQuickRace ? await waitForResultQuickRace() : await waitForResultDefault(); | |
await delay(300); | |
} | |
async function waitForResultDefault() { | |
await delay(delayDefaultRace); | |
await WaitForElement(QuerySelector_CarSelectedStartCheckResultButton); | |
} | |
async function waitForResultQuickRace() { | |
console.log('waitForResultQuickRace'); | |
await delay(600); | |
await WaitForElement(QuerySelector_CarSelectedStartCheckResultQuickRaceButton); | |
} | |
async function checkResult() { | |
runAsQuickRace ? await checkResultQuickRace() : await checkResultDefault(); | |
} | |
async function checkResultDefault() { | |
try { | |
await delay(delayDefault); | |
document.querySelector(QuerySelector_CarSelectedStartCheckResultButton).click(); | |
} catch(e) { | |
await waitForResult(); | |
await checkResult(); | |
} | |
} | |
async function checkResultQuickRace() { | |
console.log('checkResultQuickRace'); | |
try { | |
await delay(delayDefault * 2); | |
document.querySelector(QuerySelector_CarSelectedStartCheckResultQuickRaceButton).click(); | |
} catch(e) { | |
console.log('checkResultQuickRace error', e); | |
await waitForResult(); | |
await checkResult(); | |
} | |
} | |
async function waitForModalResult() { | |
runAsQuickRace ? await waitForModalResultQuickRace() : await waitForModalResultDefault(); | |
} | |
async function waitForModalResultDefault() { | |
await WaitForElement(QuerySelector_ModalResult); | |
} | |
async function waitForModalResultQuickRace() { | |
await WaitForElement(QuerySelector_ModalResultClaimQuickRaceButton); | |
} | |
async function claimResult() { | |
runAsQuickRace ? await claimResultQuickRace() : await claimResultDefault(); | |
} | |
async function claimResultDefault() { | |
await delay(delayDefault); | |
document.querySelector(QuerySelector_ModalResultClaimButton).click(); | |
} | |
async function claimResultQuickRace() { | |
console.log('claimResultQuickRace'); | |
await delay(300); | |
document.querySelector(QuerySelector_ModalResultClaimQuickRaceButton).click(); | |
await delay(delayDefault * 4); | |
console.log('claimedResultQuickRace'); | |
} | |
async function AddHtml() { | |
try { | |
var rowRemove = document.querySelector(".result-list"); | |
rowRemove.remove(); | |
} catch (e) { | |
} | |
const row = document.createElement('div'); | |
row.classList.add('ant-row', 'result-list'); | |
const rowTitle = document.createElement('h2'); | |
rowTitle.classList.add('text-orange','ant-col', 'ant-col-24'); | |
rowTitle.textContent = `Your Results`; | |
row.appendChild(rowTitle); | |
const div1 = document.createElement('div'); | |
div1.classList.add('ant-col','ant-col-10','p-3'); | |
const div2 = document.createElement('div'); | |
div2.classList.add('ant-card','ant-card-bordered','my-car','text-center'); | |
const div3 = document.createElement('div'); | |
div3.classList.add('ant-card-body'); | |
const div4 = document.createElement('div'); | |
div4.classList.add('user-car','text-center'); | |
const div5 = document.createElement('div'); | |
div5.classList.add('content','attrs','mt-3','shadowed'); | |
carsResult.forEach(async (item, index) => { | |
div5.appendChild(await AddText(`Car ${GetRealIndex(index)} ${item.stars}stars races ${item.races}/${maxRacePerDay} earned:`, `${parseFloat(item.amountEarned).toFixed(2)}`)); | |
}) | |
div4.appendChild(div5); | |
div3.appendChild(div4); | |
div2.appendChild(div3); | |
div1.appendChild(div2); | |
row.appendChild(div1); | |
document.querySelector('.main-content').prepend(row); | |
} | |
async function AddText(title, text) { | |
const divContent = document.createElement('div'); | |
divContent.classList.add('d-flex','justify-content-between'); | |
const spanTitle = document.createElement('span'); | |
spanTitle.innerHTML = title; | |
const spanText = document.createElement('span'); | |
spanText.textContent = text ; | |
divContent.appendChild(spanTitle); | |
divContent.appendChild(spanText); | |
return divContent; | |
} | |
/** | |
* INICIALIZACAO | |
*/ | |
async function Init() { | |
await GetCars(); | |
await GetAmoutCoinInitial(); | |
await DoRaces(); | |
await GetAmoutCoinFinal(); | |
console.log(`carsResult`, carsResult); | |
} | |
Init(); | |
})(); |
v0.4~v0.8
- Adicionado forma de mostrar os resultados por carros
- Melhorado gestao de espera de "aparecimento" de html na tela para diminuir o tempo total gasto
- Fix: bug que nao esperava a corrida acontecer e ja tentava verificar o resultado causando erro e para total do script
- Fix: atualizacao pos lançamento do quick race que confundia o bot pois o botao de quick race tem mesma .class do verificar resultado
v.10 adicionado quick-race como opção alterando a variavel runAsQuickRace
v.11
- fix bug de pular log do primeiro carro
- melhorado gestao de espera por elemento no quick-race
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
v0.3