// ==UserScript== // @name Rotator Speed // @namespace speed.satology // @version 1.1 // @author satology // @description Claim from SpeedSatoshi's faucets // @match https://*.speedsatoshi.com/faucet* // @match https://pepperlark.neocities.org/speedsatoshi.html // @match https://pepperlark.neocities.org/speedsatoshi.html/clearlog // @icon https://www.google.com/s2/favicons?sz=64&domain=speedsatoshi.com // @license MIT // @grant GM_setValue // @grant GM_getValue // @grant GM_addValueChangeListener // @downloadURL none // ==/UserScript== (function() { 'use strict'; const USE_LOG = true; // const TIMEOUT = 5 * 60 * 1000; const landing = 'https://pepperlark.neocities.org/speedsatoshi.html'; const wait = ms => new Promise(resolve => setTimeout(resolve, ms || 5000)); const btnSelector = '#claim'; let faucetList = [ { url: 'www.speedsatoshi.com' }, { url: 'ethereum.speedsatoshi.com' }, { url: 'binance-coin.speedsatoshi.com' }, { url: 'bitcoin-cash.speedsatoshi.com' }, { url: 'litecoin.speedsatoshi.com' }, { url: 'dogecoin.speedsatoshi.com' }, { url: 'tron.speedsatoshi.com' }, { url: 'digibyte.speedsatoshi.com' } ]; let scrolled = false; let sent = false; class Logger { static log; static listening; static async write(msg) { if (!USE_LOG) { return; } if (Logger.log == []) { await Logger.load(); } if(msg) { let last = { ts: 0, msg: '' }; try { last = Logger.log[Logger.log.length - 1]; } catch (err) { } if (!last || last.msg != msg || Date.now() - last.ts > 20000) { Logger.log.push({ ts: Date.now(), msg: msg }); Logger.save(); } } } static clear() { Logger.log = []; Logger.save(); } static refresh(name, old_value, new_value, remote) { if(remote) { Logger.log = JSON.parse(new_value); Logger.show(); } } static show() { if (!USE_LOG) { return; } if(!Logger.listening) { // document.querySelector('head').removeChild(document.querySelector('style')); let bodyElm = document.querySelector('body'); bodyElm.innerHTML = ''; let divElm = document.createElement('div'); divElm.innerHTML = '

Hi, welcome!

Click here to sign up

Click here to start the Script


Click here to clear the log (only when not claiming)


'; bodyElm.appendChild(divElm); GM_addValueChangeListener("devlog", Logger.refresh); Logger.listening = true; } let logElm = document.querySelector('#console-log'); logElm.innerHTML = Logger.log.map( function (x) { let date = new Date(x.ts); return `${date.readable()} - ${x.msg}` }).join('
'); logElm.scrollTop = logElm.scrollHeight; } static async load() { if (!USE_LOG) { return; } Logger.log = await GM_getValue('devlog'); if (Logger.log) { Logger.log = JSON.parse(Logger.log); } Logger.log = Logger.log ?? []; } static save() { GM_setValue('devlog', JSON.stringify(Logger.log)); } } function goNext() { let found = faucetList.findIndex( x => x.url == window.location.host ); let next = ( found + 1 == faucetList.length ? 0 : found + 1 ); let links = document.querySelectorAll('#full td span a'); if (links.length != 8) { //something changed Logger.write(`GOTO Link not found. Using url.`); window.location.href = linkFor(faucetList[next].url); } else { if (links.length >= found + 1) { links[next].click(); Logger.write(`GOTO Link clicked`); return; } } } function linkFor(host) { return 'https://' + host + '/faucet/manual'; } function claimedOk() { // let elms = [...document.querySelectorAll('p.alert.alert-info.alert-padded')]; if (elms.length > 0) { let found = elms.find( x => x.innerText.includes('Good job') ); if (found) { Logger.write(`claimedOk returning true: ${found.innerText}`); //save claimed return true; } } Logger.write(`claimedOk returning false`); return false; } function tokenError() { // let elms = [...document.querySelectorAll('p.alert.alert-danger')]; if (elms.length > 0) { let found = elms.find( x => x.innerText.includes('Invalid token. Refresh') ); if (found) { Logger.write(`tokenError returning true: ${found.innerText}`); return true; } } Logger.write(`tokenError returning false`); return false; } async function isSolved() { Logger.write(`Waiting for captcha`); return wait().then( () => { let elm = document.querySelector('.h-captcha > iframe'); if (elm && elm.hasAttribute('data-hcaptcha-response') && elm.getAttribute('data-hcaptcha-response').length > 0) { Logger.write(`Captcha solved`); return Promise.resolve(true); } return isSolved(); }); } function scrollTo(elm) { Logger.write(`Scrolling to button`); if (typeof(elm) == 'string') { document.querySelectorAll(elm)[0].scrollIntoView(false); } else { elm.scrollIntoView(false); } } let looper, adsHandler; Logger.load().then( () => { if (window.location.href == landing) { Number.prototype.padIt = function () { return this.toString().padStart(2, '0'); } Date.prototype.readable = function () { return `${this.getDate().padIt()}/${(this.getMonth()+1).padIt()} ${this.getHours().padIt()}:${this.getMinutes().padIt()}:${this.getSeconds().padIt()}`; } Logger.show(); //setInterval( () => { Logger.show(); }, 15000); } else if (window.location.href == landing + '/clearlog') { document.querySelector('body').innerHTML = 'Please wait...'; Logger.clear(); setTimeout( () => { window.location.href = 'https://pepperlark.neocities.org/speedsatoshi.html'; }, 10000); } else { looper = setInterval( () => { if (claimedOk()) { Logger.write(`Moving to next faucet`); //go to next faucet clearInterval(looper); setTimeout( () => { goNext(); }, 3000); return; } if (tokenError()) { //refresh clearInterval(looper); setTimeout( () => { window.location.reload(); }, 3000); return; } if(!scrolled) { if(document.querySelector(btnSelector)) { scrollTo(btnSelector); scrolled = true; } else { Logger.write(`Claim button not found yet`); // claim button not found yet return; } } if (!sent) { clearInterval(looper); isSolved().then( () => { Logger.write(`Submiting`); document.querySelector(btnSelector).parentElement.submit(); sent = true; }); } }, 3214); } adsHandler = setInterval( () => { let elm = null; elm = document.querySelector('div[data-name="stitialer"]'); if (elm) { elm.nextSibling.click(); } elm = document.querySelector('.ex-over-btn'); if (elm) { elm.click(); } }, 10000); }); })();