// ==UserScript== // @name [satology] Auto Claim Multiple Faucets with Monitor UI // @description Freebitco.in, StormGain Miner, 15 Faucets with Promo Codes + Autologin, FaucetPay PTC, etc. // @description Automatic activation of StormGain Miner every 4 hours and hourly claim of free ADA, BNB, BCH, BTC, DASH, DGB, DOGE, ETH, FEY, LINK, LTC, NEO, STEAM, TRX, USDC, USDT, XEM, XRP, ZEC // @version 1.5.15 // @author satology // @namespace satology.onrender.com // @homepage https://satology.onrender.com/faucets/referrals // @note @1.5.13 : > Added 'Ok' (6 hourly faucets with direct payment to FP). Issue: they have popups. This script is not handling them. In case you need an ad blocker, I've created a simple script for this // @note specific case that you could use and adjust if you need to: (https://greasyfork.org/en/scripts/429739-closewindowbyname) // @note > Added BigBtc. It's set to run based on 'postponedMinutes' interval but it's a 5 min faucet. You can change the delay in the script if you want to. I wouldn't abuse it as it's easy for a // @note faucet admin to ban your address @ Fp. Also, it has manual payment (not implemented). // @note > Added signout at B/K BCH, to force login with address as the faucets have a bug (might use your ERC20 address if you previously claim TRX/USDT, instead of asking to login) // @note @1.5.12 : > Added some workarounds for those who don't like the script to be waiting when the sites are redirected to an Ad: // @note 1. Timer/interval that saves the timestamp every 10 seconds when processing/navigating a site. This should avoid waiting too long in case of ad redirects, // @note BUT it will consume more resources. You can enable it in the script, by setting useTimer to true (almost at the end of the script). // @note When enabled, it will be used only at B/K, Free-Litecoin and Free-Ethereum. // @note If a site is closed by this timer, it will display the error 'FORCE_CLOSED' at the schedule // @note 2. Added a retry logic for this faucets (when FORCE_CLOSED): whenever there's a time window (greater than timeout/2), it will try to run again the last one that failed // @note > Added ErrorType to a const/enum. Errors from previous versions of the script (were plain strings) will be displayed as '_ERR' // @note I'm not setting this stuff to be configured at the UI as I don't think it's worth it and might be confusing. // @note Same goes for enabling individual faucets to run on focus instead of background (as FP PTC does). I've added a line you can uncomment to do the same with StormGain // @note if you are having trouble with the auto activation when it's on the background (search for RUN STORMGAIN) // @note - IMPORTANT ------------------------------------------------------------------------------------------------------------------------------------------------------------------- // @note YOU MUST HAVE A hCaptcha solver INSTALLED to claim from the faucets // @note I recommend this script: https://greasyfork.org/en/scripts/425854-hcaptcha-solver-automatically-solves-hcaptcha-in-browser // @note At least until version 3.5 of the hCaptcha solver script, to roll Free-ethereum.io, you'd need to add the following two lines, right at the beginning of function getSynonyms(word) [line 232]: // @note const WORDS_WITH_CYRILLIC = {'аirplane': AIRPLANE, 'bіcycle': BICYCLE, 'bοat': BOAT, 'сar': CAR, 'mοtorbus': MOTORBUS, 'mοtorcycle': MOTORCYCLE, 'trаin': TRAIN, 'truсk': TRUCK }; // @note word = (encodeURIComponent(word).indexOf('%') > -1) ? WORDS_WITH_CYRILLIC[word] : word; // @note ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- // @note - MAIN FEATURES ------------------------------------------------------------------------------------------------------------------------------------------------ // @note > Automatic rolls and claims for faucets/PTCs/miners // @note > Accepts promotion codes (http://twitter.com/cryptosfaucets, free roll shortlinks) for CF 15 faucets // @note > Simple Monitor UI on top of a website to track progress (claims, next rolls, promo codes) // @note - IMPORTANT CONSIDERATIONS ------------------------------------------------------------------------------------------------------------------------------------- // @note 0. You need to enable popups on the Manager UI website to be able to open the faucets // @note 1. CF FAUCETS WEBSITES MUST OPEN IN ENGLISH TO BE ABLE TO RECOGNIZE IF THE PROMO CODE WAS ACCEPTED // @note In case you don't want to have them in English, you need to change the 3 strings the code uses for validation and change setToEnglish to false // @note (Search for localeStrings in the code) // @note 2. Autorolls will trigger ONLY when the faucet was opened by the Manager UI. // @note This is to allow users to navigate the websites to get the ShortLinks extra rolls, for example, // @note without having to stop the script. // @note 3. You can enable/disable faucets from the UI. By default they are all set to false. // @note It would be great if you could use my referral links listed below if you need an account. // @note To disable them, just set enabled: false in the webList array, save the script & refresh the manager // @note 4. You can change the configuration to enable autologin, RP free roll bonus, etc. // @note 5. All data stored for tracking and to be displayed is stored locally in your environment. Nothing is uploaded. // @note Always open to feedback. I'd be glad to hear from you if you find any bugs, have suggestions or new enhancements/features you'd like to see // @note ---------------------------------------------------------------------------------------------------------------------------------------------------------------- // @note DISCLAIMER: This script is shared to help. Use at your own discretion. I've being using it for months and works fine but I cannot // @note guarantee that the faucets won't ban your IP or account // @note ---------------------------------------------------------------------------------------------------------------------------------------------------------------- // @note ---------------------------------------------------------------------------------------------------------------------------------------------------------------- // @note If you wanna team up or just share some ideas, you can contact me at satology@protonmail.com // @note ---------------------------------------------------------------------------------------------------------------------------------------------------------------- // @grant GM_info // @grant GM_setValue // @grant GM_getValue // @grant window.close // @grant GM_openInTab // @icon https://www.google.com/s2/favicons?domain=stormgain.com // @require https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js // @match https://satology.onrender.com/faucets/referrals* // @match https://app.stormgain.com/crypto-miner/ // @match https://freecardano.com/* // @match https://freebinancecoin.com/* // @match https://freebitcoin.io/* // @match https://freedash.io/* // @match https://free-doge.com/* // @match https://freeethereum.com/* // @match https://freechainlink.io/* // @match https://free-ltc.com/* // @match https://freeneo.io/* // @match https://freesteam.io/* // @match https://free-tron.com/* // @match https://freeusdcoin.com/* // @match https://freetether.com/* // @match https://freenem.com/* // @match https://coinfaucet.io/* // @match https://freebitco.in/ // @match https://faucetpay.io/ptc // @match https://faucetpay.io/ptc* // @match https://faucetpay.io/account/login // @match https://faucetpay.io/account/login/not-logged-in // @match https://free-litecoin.com/* // @match https://www.free-ethereum.io/ // @match https://www.free-ethereum.io/free/ // @match https://bagi.co.in/* // @match https://keran.co/* // @match https://btc-ok.net/* // @match https://dash-ok.net/* // @match https://dgb-ok.net/* // @match https://doge-ok.net/* // @match https://eth-ok.net/* // @match https://ltc-ok.net/* // @match https://trx-ok.net/* // @match https://bigbtc.win/* // @downloadURL none // ==/UserScript== (function() { 'use strict'; /** * Specific string values to check if a promotion code was succesfully processed (used via indexOf). * Defaults are set for English. * If you want to view the faucets in another language, you will need to change the following values */ const localeConfig = { setToEnglish: true, // will set the faucets to English stringSearches: { promoCodeAccepted: 'roll', promoCodeUsed: 'already used', promoCodeInvalid: ['not found', 'only alphanumeric'], promoCodeExpired: ['ended'] } }; const WebType = { CRYPTOSFAUCETS: 1, STORMGAIN: 2, FREEBITCOIN: 3, FAUCETPAY: 4, FREELITECOIN: 5, FREEETHEREUMIO: 6, BAGIKERAN: 7, OKFAUCET: 8, BIGBTC: 9 }; const CFUrlType = { HOME: 0, FREE: 1, CONTACTTWITTER: 2, PROMOTION: 3, STATS: 4, SETTINGS: 5, FREEROLLS: 6, IGNORE: 99 }; const PromoStatus = { NOCODE: 0, PENDING: 1, ACCEPTED: 2, USEDBEFORE: 3, INVALID: 4, UNKNOWNERROR: 5, EXPIRED: 6 }; const RandomInteractionLevel = { NONE: 0, LOW: 1, MEDIUM: 2, HIGH: 3 }; const HS_26_IN_MILLISECONDS = 93600000; //Using 26 hs instead of 24hs const HS_2_IN_MILLISECONDS = 7200000; //and 2hs gap retry when code is flagged as USEDBEFORE const USE_DEFAULT = -1; const CFReusableCodesSuggestion = ['55khv20st4', '90nq6mcmz2', 'lytovoap04', 'vmuph8j0c6', 'ykxlvmg9ja', 'd8fmqxjlma', 'rjnmzjs673']; const WalletType = { FP_MAIL: 100, FP_BTC: 101, FP_BNB: 102, FP_BCH: 103, FP_DASH: 104, FP_DGB: 105, FP_DOGE: 106, FP_ETH: 107, FP_FEY: 108, FP_LTC: 109, FP_TRX: 110, FP_USDT: 111, FP_ZEC: 112 }; const ErrorType = { ERROR: 0, TIMEOUT: 1, NEED_TO_LOGIN: 2, ROLL_ERROR: 3, CLICK_ROLL_ERROR: 4, LOGIN_ERROR: 5, CLAIM_ERROR: 6, ADDRESS_ERROR: 7, MIN_WITHDRAW_ERROR: 8, IP_BAN: 9, IP_RESTRICTED: 10, IP_ERROR: 11, FORCE_CLOSED: 12, NO_FUNDS: 13 }; let persistence, shared, manager, ui, CFPromotions, interactions, CFHistory, SiteProcessor; //Extension methods Element.prototype.isVisible = function() { return !!(this.offsetWidth||this.offsetHeight||this.getClientRects().length); }; String.prototype.clean = function() { let output = ""; for (let i = 0; i < this.length; i++) { if (this.charCodeAt(i) <= 127) { output += this.charAt(i); } } return output; }; Array.prototype.shuffle = function () { let currentIndex = this.length, temporaryValue, randomIndex; while (0 !== currentIndex) { randomIndex = Math.floor(Math.random() * currentIndex); currentIndex -= 1; temporaryValue = this[currentIndex]; this[currentIndex] = this[randomIndex]; this[randomIndex] = temporaryValue; } return this; }; let helpers = { getPrintableTime: function (date = new Date()) { if (date == null) { return ''; } return ('0' + date.getHours()).slice(-2) + ':' + ('0' + date.getMinutes()).slice(-2) + ':' + ('0' + date.getSeconds()).slice(-2); }, getPrintableDateTime: function (date) { if (date != null) { return ('0' + date.getDate()).slice(-2) + '/' + ('0' + (date.getMonth() + 1)).slice(-2) + ' ' + ('0' + date.getHours()).slice(-2) + ':' + ('0' + date.getMinutes()).slice(-2); } else { return ''; } }, getEnumText: function (enm, value) { return Object.keys(enm).find(key => enm[key] === value) || '_ERR'; }, randomMs: function (a, b){ return a + (b - a) * Math.random(); }, addMinutes: function(date, mins) { return date.setMinutes(date.getMinutes() + parseInt(mins) + 1); }, randomInt: function(min, max) { return Math.floor(Math.random() * (max - min + 1) + min); }, addMs: function(date, ms) { return date.setMilliseconds(date.getMilliseconds() + ms); }, getRandomMs(minute, rangeDiffInPercentage) { const msCenter = minute * 60 * 1000; const msRangeDiff = Math.round(msCenter * rangeDiffInPercentage / 100); return helpers.randomMs(msCenter - msRangeDiff, msCenter + msRangeDiff); }, hsToMs: function(hours) { return hours * 60 * 60 * 1000; }, minToMs: function(min) { return min * 60 * 1000; }, getEmojiForPromoStatus: function(promoStatus) { switch (promoStatus) { case PromoStatus.NOCODE: return '⚪'; break; case PromoStatus.PENDING: return '⏳'; break; case PromoStatus.ACCEPTED: return '✔️'; break; case PromoStatus.USEDBEFORE: return '🕙'; break; case PromoStatus.INVALID: return '❌'; break; case PromoStatus.EXPIRED: return '📅'; break; case PromoStatus.UNKNOWNERROR: return '❗'; break; } }, getHost: function(url, withHttps = false) { if (url.includes('//')) { url = url.split('//')[1]; } url = url.split('/')[0]; return withHttps ? ('https://' + url) : url; }, cf: { getUrlType: function(url) { if (url.endsWith('/free')) { return CFUrlType.FREE; } if (url.includes('/promotion/')) { return CFUrlType.PROMOTION; } if (url.endsWith('/contact-twitter')) { return CFUrlType.CONTACTTWITTER; } if (url.endsWith('/free-rolls')) { return CFUrlType.FREEROLLS; } if (url.endsWith('/settings')) { return CFUrlType.SETTINGS; } if (url.endsWith('/stats')) { return CFUrlType.STATS; } if (url.endsWith('/')) { url = url.slice(0, -1); if (url == helpers.getHost(url, true)) { return CFUrlType.HOME; } } return CFUrlType.IGNORE; } } } let objectGenerator = { createPersistence: function() { const prefix = 'autoWeb_'; function save(key, value, parseIt = false) { GM_setValue(prefix + key, parseIt ? JSON.stringify(value) : value); }; function load(key, parseIt = false) { let value = GM_getValue(prefix + key); if(value && parseIt) { value = JSON.parse(value); } return value; }; return { save: save, load: load }; }, createShared: function() { let flowControl; let config = {}; function initializeConfig() { // Defaults: config['devlog.enabled'] = false; config['devlog.maxLines'] = 200; config['defaults.timeout'] = 4; config['defaults.postponeMinutes'] = 65; config['defaults.workInBackground'] = true; config['cf.autologin'] = false; config['cf.credentials.mode'] = 1; config['cf.credentials.email'] = 'YOUR@EMAIL.com'; config['cf.credentials.password'] = 'YOURPASSWORD'; config['cf.sleepHoursIfIpBan'] = 8; config['fb.activateRPBonus'] = true; config['fp.hoursBetweenRuns'] = 6; config['fp.maxTimeInMinutes'] = 15; config['bk.withdrawMode'] = "1"; config['bk.hoursBetweenWithdraws'] = 4; config['bk.sleepMinutesIfIpBan'] = 75; let storedData = persistence.load('config', true); if(storedData) { for (const prop in config) { if(storedData.hasOwnProperty(prop)) { config[prop] = storedData[prop]; } } } config.version = GM_info.script.version; }; function getConfig() { return config; }; function updateConfig(items) { items.forEach( function (item) { config[item.prop] = item.value; }); persistence.save('config', config, true); } function devlog(msg, elapsed = false, reset = false) { if(!config['devlog.enabled']) { return; } let log; if(reset) { log = [`${helpers.getPrintableTime()}|Log cleared`]; } else { log = persistence.load('devlog', true); log = log ?? []; } if(msg) { let previous; try { previous = log[log.length - 1].split('|')[1]; } catch {} if(elapsed && (previous == msg)) { log[log.length - 1] = `${helpers.getPrintableTime()}|${msg}|[Elapsed time: ${elapsed} seconds]`; } else { log.push(`${helpers.getPrintableTime()}|${msg}`); } } if(log.length > 200) { log.splice(0, log.length - 200); } persistence.save('devlog', log, true); }; function getDevLog() { let log; log = persistence.load('devlog', true); if(log) { return log; } }; function isOpenedByManager() { loadFlowControl(); if(!flowControl) { return false; } if(flowControl.host != window.location.host) { return false; } if(flowControl.opened && flowControl.type != WebType.FAUCETPAY && flowControl.type != WebType.BAGIKERAN) { return false; } if(flowControl.type == WebType.BAGIKERAN && !window.location.href.includes(flowControl.params.trackUrl)) { return false; } return true; }; function setFlowControl(id, url, webType, params = null) { flowControl = { id: id, changedAt: Date.now(), url: url, host: url.host, type: webType, opened: false, error: false, result: {} }; if(params) { flowControl.params = params; } saveFlowControl(); }; function wasVisited(expectedId) { loadFlowControl(); return flowControl.id == expectedId && flowControl.opened; }; function hasErrors(expectedId) { return flowControl.id == expectedId && flowControl.error; }; function getResult() { return flowControl.result; }; function getCurrent() { return flowControl; }; function saveAndclose(runDetails, delay = 0) { markAsVisited(runDetails); shared.devlog(`${window.location.href} closing`); if(delay) { setTimeout(window.close, delay); } else { window.close(); } }; function loadFlowControl() { flowControl = persistence.load('flowControl', true); }; function saveFlowControl() { persistence.save('flowControl', flowControl, true); }; function markAsVisited(runDetails) { flowControl.opened = true; flowControl.result = runDetails; saveFlowControl(); }; function addError(errorType, errorMessage) { flowControl.error = true; flowControl.result.errorType = errorType; flowControl.result.errorMessage = errorMessage; saveFlowControl(); }; function closeWithError(errorType, errorMessage) { addError(errorType, errorMessage); shared.devlog(`${window.location.href} closing with error msg`); window.close(); }; function clearFlowControl() { flowControl = {}; saveFlowControl(); }; function clearRetries() { loadFlowControl(); flowControl.retrying = false; saveFlowControl(); return false; }; function isRetrying() { if(flowControl.retrying) { return true; } flowControl.retrying = true; saveFlowControl(); return false; }; initializeConfig(); return { devlog: devlog, getDevLog: getDevLog, setFlowControl: setFlowControl, wasVisited: wasVisited, isOpenedByManager: isOpenedByManager, saveFlowControl: saveFlowControl, getCurrent: getCurrent, getResult: getResult, addError: addError, closeWindow: saveAndclose, closeWithError: closeWithError, updateWithoutClosing: markAsVisited, hasErrors: hasErrors, clearFlowControl: clearFlowControl, getConfig: getConfig, updateConfig: updateConfig, clearRetries: clearRetries, isRetrying: isRetrying }; }, createManager: function() { const STATUS = { INITIALIZING: 0, IDLE: 1, CLAIMING: 2 }; let timestamp = null; let timeWaiting = 0; let uiUpdatesInterval; let status = STATUS.INITIALIZING; let processTimer; let workingTab; let webList = []; let userWallet = []; const sites = [ { id: '1', name: 'CF ADA', cmc: '2010', coinRef: 'ADA', url: new URL('https://freecardano.com/free'), rf: '?ref=335463', type: WebType.CRYPTOSFAUCETS }, { id: '2', name: 'CF BNB', cmc: '1839', coinRef: 'BNB', url: new URL('https://freebinancecoin.com/free'), rf: '?ref=161127', type: WebType.CRYPTOSFAUCETS }, { id: '3', name: 'CF BTC', cmc: '1', coinRef: 'BTC', url: new URL('https://freebitcoin.io/free'), rf: '?ref=490252', type: WebType.CRYPTOSFAUCETS }, { id: '4', name: 'CF DASH', cmc: '131', coinRef: 'DASH', url: new URL('https://freedash.io/free'), rf: '?ref=124083', type: WebType.CRYPTOSFAUCETS }, { id: '5', name: 'CF ETH', cmc: '1027', coinRef: 'ETH', url: new URL('https://freeethereum.com/free'), rf: '?ref=204076', type: WebType.CRYPTOSFAUCETS }, { id: '6', name: 'CF LINK', cmc: '1975', coinRef: 'LINK', url: new URL('https://freechainlink.io/free'), rf: '?ref=78652', type: WebType.CRYPTOSFAUCETS }, { id: '7', name: 'CF LTC', cmc: '2', coinRef: 'LTC', url: new URL('https://free-ltc.com/free'), rf: '?ref=117042', type: WebType.CRYPTOSFAUCETS }, { id: '8', name: 'CF NEO', cmc: '1376', coinRef: 'NEO', url: new URL('https://freeneo.io/free'), rf: '?ref=100529', type: WebType.CRYPTOSFAUCETS }, { id: '9', name: 'CF STEAM', cmc: '1230', coinRef: 'STEEM', url: new URL('https://freesteam.io/free'), rf: '?ref=117686', type: WebType.CRYPTOSFAUCETS }, { id: '10', name: 'CF TRX', cmc: '1958', coinRef: 'TRX', url: new URL('https://free-tron.com/free'), rf: '?ref=145047', type: WebType.CRYPTOSFAUCETS }, { id: '11', name: 'CF USDC', cmc: '3408', coinRef: 'USDC', url: new URL('https://freeusdcoin.com/free'), rf: '?ref=100434', type: WebType.CRYPTOSFAUCETS }, { id: '12', name: 'CF USDT', cmc: '825', coinRef: 'USDT', url: new URL('https://freetether.com/free'), rf: '?ref=181230', type: WebType.CRYPTOSFAUCETS }, { id: '13', name: 'CF XEM', cmc: '873', coinRef: 'XEM', url: new URL('https://freenem.com/free'), rf: '?ref=295274', type: WebType.CRYPTOSFAUCETS }, { id: '14', name: 'CF XRP', cmc: '52', coinRef: 'XRP', url: new URL('https://coinfaucet.io/free'), rf: '?ref=808298', type: WebType.CRYPTOSFAUCETS }, { id: '15', name: 'StormGain', cmc: '1', url: new URL('https://app.stormgain.com/crypto-miner/'), rf: 'friend/BNS27140552', type: WebType.STORMGAIN }, { id: '16', name: 'CF DOGE', cmc: '74', coinRef: 'DOGE', url: new URL('https://free-doge.com/free'), rf: '?ref=97166', type: WebType.CRYPTOSFAUCETS }, { id: '17', name: 'FreeBitco.in', cmc: '1', url: new URL('https://freebitco.in/'), rf: '?r=41092365', type: WebType.FREEBITCOIN }, { id: '18', name: 'FaucetPay PTC', cmc: '1', url: new URL('https://faucetpay.io/ptc'), rf: '?r=41092365', type: WebType.FAUCETPAY }, { id: '19', name: 'Free-Litecoin.com', cmc: '2', url: new URL('https://free-litecoin.com/'), rf: 'login?referer=1332950', type: WebType.FREELITECOIN }, { id: '20', name: 'Free-Ethereum.io', cmc: '1027', url: new URL('https://www.free-ethereum.io/'), rf: '?referer=1064662', type: WebType.FREEETHEREUMIO }, { id: '21', name: 'Bagi BTC', cmc: '1', wallet: WalletType.FP_BTC, url: new URL('https://bagi.co.in/bitcoin/'), rf: ['?ref=53706', '?ref=63428', '?ref=54350'], type: WebType.BAGIKERAN }, { id: '22', name: 'Bagi BNB', cmc: '1839', wallet: WalletType.FP_BNB, url: new URL('https://bagi.co.in/binance/'), rf: ['?ref=12529', '?ref=23852', '?ref=13847'], type: WebType.BAGIKERAN }, { id: '23', name: 'Bagi BCH', cmc: '1831', wallet: WalletType.FP_BCH, url: new URL('https://bagi.co.in/bitcoincash/'), rf: ['?ref=44242', '?ref=50185', '?ref=41957'], type: WebType.BAGIKERAN }, { id: '24', name: 'Bagi DASH', cmc: '131', wallet: WalletType.FP_DASH, url: new URL('https://bagi.co.in/dash/'), rf: ['?ref=32724', '?ref=38540', '?ref=40441'], type: WebType.BAGIKERAN }, { id: '25', name: 'Bagi DGB', cmc: '109', wallet: WalletType.FP_DGB, url: new URL('https://bagi.co.in/digibyte/'), rf: ['?ref=22664', '?ref=27872', '?ref=29669'], type: WebType.BAGIKERAN }, { id: '26', name: 'Bagi DOGE', cmc: '74', wallet: WalletType.FP_DOGE, url: new URL('https://bagi.co.in/dogecoin/'), rf: ['?ref=45047', '?ref=54217', '?ref=45568'], type: WebType.BAGIKERAN }, { id: '27', name: 'Bagi ETH', cmc: '1027', wallet: WalletType.FP_ETH, url: new URL('https://bagi.co.in/ethereum/'), rf: ['?ref=24486', '?ref=27799', '?ref=24847'], type: WebType.BAGIKERAN }, { id: '28', name: 'Bagi FEY', cmc: '10361', wallet: WalletType.FP_FEY, url: new URL('https://bagi.co.in/feyorra/'), rf: ['?ref=5049', '?ref=7433', '?ref=5318'], type: WebType.BAGIKERAN }, { id: '29', name: 'Bagi LTC', cmc: '2', wallet: WalletType.FP_LTC, url: new URL('https://bagi.co.in/litecoin/'), rf: ['?ref=48335', '?ref=57196', '?ref=48878'], type: WebType.BAGIKERAN }, { id: '30', name: 'Bagi TRX', cmc: '1958', wallet: WalletType.FP_TRX, url: new URL('https://bagi.co.in/tron/'), rf: ['?ref=22622', '?ref=31272', '?ref=23075'], type: WebType.BAGIKERAN }, { id: '31', name: 'Bagi USDT', cmc: '825', wallet: WalletType.FP_USDT, url: new URL('https://bagi.co.in/tether/'), rf: ['?ref=25462', '?ref=32491', '?ref=25981'], type: WebType.BAGIKERAN }, { id: '32', name: 'Bagi ZEC', cmc: '1437', wallet: WalletType.FP_ZEC, url: new URL('https://bagi.co.in/zcash/'), rf: ['?ref=9181', '?ref=15120', '?ref=9878'], type: WebType.BAGIKERAN }, { id: '33', name: 'Keran BTC', cmc: '1', wallet: WalletType.FP_BTC, url: new URL('https://keran.co/BTC/'), rf: ['?ref=73729', '?ref=92353', '?ref=79321'], type: WebType.BAGIKERAN }, { id: '34', name: 'Keran BNB', cmc: '1839', wallet: WalletType.FP_BNB, url: new URL('https://keran.co/BNB/'), rf: ['?ref=19287', '?ref=31242', '?ref=20659'], type: WebType.BAGIKERAN }, { id: '35', name: 'Keran BCH', cmc: '1831', wallet: WalletType.FP_BCH, url: new URL('https://keran.co/BCH/'), rf: ['?ref=58232', '?ref=67326', '?ref=70759'], type: WebType.BAGIKERAN }, { id: '36', name: 'Keran DASH', cmc: '131', wallet: WalletType.FP_DASH, url: new URL('https://keran.co/DASH/'), rf: ['?ref=45229', '?ref=53041', '?ref=55716'], type: WebType.BAGIKERAN }, { id: '37', name: 'Keran DGB', cmc: '109', wallet: WalletType.FP_DGB, url: new URL('https://keran.co/DGB/'), rf: ['?ref=32788', '?ref=39527', '?ref=42014'], type: WebType.BAGIKERAN }, { id: '38', name: 'Keran DOGE', cmc: '74', wallet: WalletType.FP_DOGE, url: new URL('https://keran.co/DOGE/'), rf: ['?ref=73512', '?ref=85779', '?ref=89613'], type: WebType.BAGIKERAN }, { id: '39', name: 'Keran ETH', cmc: '1027', wallet: WalletType.FP_ETH, url: new URL('https://keran.co/ETH/'), rf: ['?ref=32226', '?ref=36427', '?ref=32676'], type: WebType.BAGIKERAN }, { id: '40', name: 'Keran FEY', cmc: '10361', wallet: WalletType.FP_FEY, url: new URL('https://keran.co/FEY/'), rf: ['?ref=6269', '?ref=9019', '?ref=6569'], type: WebType.BAGIKERAN }, { id: '41', name: 'Keran LTC', cmc: '2', wallet: WalletType.FP_LTC, url: new URL('https://keran.co/LTC/'), rf: ['?ref=69102', '?ref=80726', '?ref=84722'], type: WebType.BAGIKERAN }, { id: '42', name: 'Keran TRX', cmc: '1958', wallet: WalletType.FP_TRX, url: new URL('https://keran.co/TRX/'), rf: ['?ref=49686', '?ref=46544', '?ref=34485'], type: WebType.BAGIKERAN }, { id: '43', name: 'Keran USDT', cmc: '825', wallet: WalletType.FP_USDT, url: new URL('https://keran.co/USDT/'), rf: ['?ref=40582', '?ref=48907', '?ref=41009'], type: WebType.BAGIKERAN }, { id: '44', name: 'Keran ZEC', cmc: '1437', wallet: WalletType.FP_ZEC, url: new URL('https://keran.co/ZEC/'), rf: ['?ref=', '?ref=18976', '?ref=12487'], type: WebType.BAGIKERAN }, { id: '45', name: 'OK Btc', cmc: '1', wallet: WalletType.FP_BTC, url: new URL('https://btc-ok.net/'), rf: 'index.php?r=1QCD6cWJNVH4Cdnz85SQ2qtTkAwGr9fvUk', type: WebType.OKFAUCET }, { id: '46', name: 'OK Dash', cmc: '131', wallet: WalletType.FP_DASH, url: new URL('https://dash-ok.net/'), rf: 'index.php?r=Xbyi7Fk2NRmZ32SHpDhmpGHLa4NMokhmGR', type: WebType.OKFAUCET }, { id: '47', name: 'OK Dgb', cmc: '109', wallet: WalletType.FP_DGB, url: new URL('https://dgb-ok.net/'), rf: 'index.php?r=DSM93hgZuapnjeeDMe8spzwG9rMrw4sdua', type: WebType.OKFAUCET }, { id: '48', name: 'OK Doge', cmc: '74', wallet: WalletType.FP_DOGE, url: new URL('https://doge-ok.net/'), rf: 'index.php?r=DDaQWmD7vY1NhtK1M5Pno7sdccmgxNUfv1', type: WebType.OKFAUCET }, { id: '49', name: 'OK Eth', cmc: '1027', wallet: WalletType.FP_ETH, url: new URL('https://eth-ok.net/'), rf: 'index.php?r=0x7636f64a8241257b1edaf65ae943c66de87b1749', type: WebType.OKFAUCET }, { id: '50', name: 'OK Ltc', cmc: '2', wallet: WalletType.FP_LTC, url: new URL('https://ltc-ok.net/'), rf: 'index.php?r=MEmxLqYzZdMsEswUQkqL5aawT5UsqYwYgr', type: WebType.OKFAUCET }, { id: '51', name: 'OK Trx', cmc: '1958', wallet: WalletType.FP_TRX, url: new URL('https://trx-ok.net/'), rf: 'index.php?r=TSocuzJ6ADUoQ49v28BXN2jo3By6awwHvj', type: WebType.OKFAUCET }, { id: '52', name: 'BigBtc', cmc: '1', wallet: WalletType.FP_BTC, url: new URL('https://bigbtc.win/'), rf: '?id=39255652', type: WebType.BIGBTC } ]; const wallet = [ { id: '101', name: 'FaucetPay BTC (Bitcoin)', type: WalletType.FP_BTC }, { id: '102', name: 'FaucetPay BNB (Binance Coin)', type: WalletType.FP_BNB }, { id: '103', name: 'FaucetPay BCH (Bitcoin Cash)', type: WalletType.FP_BCH }, { id: '104', name: 'FaucetPay DASH (Dash)', type: WalletType.FP_DASH }, { id: '105', name: 'FaucetPay DGB (DigiByte)', type: WalletType.FP_DGB }, { id: '106', name: 'FaucetPay DOGE (Dogecoin)', type: WalletType.FP_DOGE }, { id: '107', name: 'FaucetPay ETH (Ethereum)', type: WalletType.FP_ETH }, { id: '108', name: 'FaucetPay FEY (Feyorra)', type: WalletType.FP_FEY }, { id: '109', name: 'FaucetPay LTC (Litecoin)', type: WalletType.FP_LTC }, { id: '110', name: 'FaucetPay TRX (Tron)', type: WalletType.FP_TRX }, { id: '111', name: 'FaucetPay USDT (Tether TRC20)', type: WalletType.FP_USDT }, { id: '112', name: 'FaucetPay ZEC (Zcash)', type: WalletType.FP_ZEC } ]; function start() { loader.initialize(); ui.init(getCFlist()); update(); ui.refresh(null, null, userWallet); uiUpdatesInterval = setInterval(readUpdateValues, 10000); processTimer = setTimeout(manager.process, 2000); }; let loader = function() { function initialize() { setTimestamp(); initializeWebList(); initializeUserWallet(); initializePromotions(); initializeHistory(); }; function initializeWebList() { addSites(); addStoredSitesData(); }; function addSites() { sites.forEach(x => webList.push(x)); webList.forEach(function (element, idx, arr) { arr[idx].enabled = false; arr[idx].lastClaim = 0; arr[idx].aggregate = 0; arr[idx].balance = 0; arr[idx].stats = {}; arr[idx].nextRoll = null; arr[idx].workInBackground = (element.id == '18' ? false : USE_DEFAULT); // UNCOMMENT THE FOLLOWING LINE TO RUN STORMGAIN WITH FOCUS INSTEAD OF BACKGROUND IF YOU ARE HAVING TROUBLE WITH IT'S ACTIVATION // arr[idx].workInBackground = ((element.id == '15' || element.id == '18') ? false : USE_DEFAULT); if(arr[idx].type == WebType.BAGIKERAN) { arr[idx].lastWithdraw = new Date(); } }); }; function addStoredSitesData() { let storedData = persistence.load('webList', true); if(storedData) { storedData.forEach( function (element) { let idx = webList.findIndex(x => x.id == element.id); if(idx != -1) { webList[idx].name = element.name ?? webList[idx].name; webList[idx].lastClaim = element.lastClaim ?? webList[idx].lastClaim; webList[idx].aggregate = element.aggregate ?? webList[idx].aggregate; webList[idx].balance = element.balance ?? webList[idx].balance; webList[idx].stats = element.stats ?? webList[idx].stats; webList[idx].enabled = element.enabled ?? webList[idx].enabled; if(!webList[idx].enabled) { webList[idx].nextRoll = null; } else { webList[idx].nextRoll = element.nextRoll ? new Date(element.nextRoll) : new Date(); } if(element.lastWithdraw) { webList[idx].lastWithdraw = new Date(element.lastWithdraw); } //webList[idx].workInBackground = element.workInBackground ?? webList[idx].workInBackground; } }); } else { // webList.shuffle(); } }; function initializeUserWallet() { addWallets(); addStoredWalletData(); }; function addWallets() { wallet.forEach(x => userWallet.push(x)); userWallet.forEach(function (element, idx, arr) { arr[idx].address = ''; }); }; function addStoredWalletData() { let storedData = persistence.load('userWallet', true); if(storedData) { storedData.forEach( function (element) { let idx = userWallet.findIndex(x => x.id == element.id); if(idx != -1) { userWallet[idx].address = element.address ?? webList[idx].address; } }); } }; function initializePromotions() { let storedData = persistence.load('CFPromotions', true); if (storedData) { storedData.forEach( function (element, idx, arr) { arr[idx].added = new Date(element.added); arr[idx].statusPerFaucet.forEach( function (el, i, a) { a[i].execTimeStamp = (el.execTimeStamp != null) ? new Date(el.execTimeStamp) : null; }); }); CFPromotions.load(storedData); } }; function initializeHistory() { CFHistory.initOrLoad(); }; function setTimestamp() { timestamp = Date.now(); persistence.save('timestamp', timestamp); }; function removeDisabledFaucets() { webList = webList.filter(x => x.enabled); }; return { initialize: initialize }; }(); function readUpdateValues(forceCheck = false) { readPromoCodeValues(); readModalData(); if(status == STATUS.IDLE || forceCheck) { let updateDataElement = document.getElementById('update-data'); let updateValues = updateDataElement.innerText.clean(); if (updateValues != '') { updateDataElement.innerText = ''; let updateObj = JSON.parse(updateValues); if(updateObj.runAsap.changed) { updateObj.runAsap.ids.forEach(function (element, idx, arr) { try { let itemIndex = webList.findIndex(x => x.id == element) webList[itemIndex].enabled = true; webList[itemIndex].nextRoll = new Date(754000 + idx); ui.log(`${webList[itemIndex].name} updated to run ASAP`); } catch (err) { ui.log(`Error setting faucet to run ASAP: ${err}`); } }); } if(updateObj.editSingle.changed) { updateObj.editSingle.items.forEach(function (element, idx, arr) { try { let itemIndex = webList.findIndex(x => x.id == element.id); webList[itemIndex].name = element.displayName; if (webList[itemIndex].enabled != element.enabled) { webList[itemIndex].enabled = element.enabled; if(webList[itemIndex].enabled) { webList[itemIndex].nextRoll = new Date(idx); } else { webList[itemIndex].nextRoll = null; } } ui.log(`Faucet updated. New name: ${element.displayName}. Active: ${element.enabled}`); } catch (err) { ui.log(`Error updating faucet data: ${err}`); } }); } if(updateObj.wallet.changed) { updateObj.wallet.items.forEach(function (element) { try { let itemIndex = userWallet.findIndex(x => x.id == element.id); userWallet[itemIndex].address = element.address; ui.log(`Wallet Address updated [${userWallet[itemIndex].name}]: ${userWallet[itemIndex].address}`); } catch (err) { ui.log(`Error updating wallet/address: ${err}`); } }); document.getElementById('faucets-display-status').innerHTML = ''; ui.refresh(null, null, userWallet); saveUserWallet(); } if(updateObj.config.changed) { try { shared.updateConfig(updateObj.config.items); ui.log(`Config updated. Reloading in a few seconds...`); window.location.reload(); return; } catch (err) { ui.log(`Error updating config: ${err}`); } document.getElementById('faucets-display-status').innerHTML = ''; } if(updateObj.runAsap.changed || updateObj.editSingle.changed) { document.getElementById('faucets-display-status').innerHTML = ''; update(true); process(); return; } } } if(forceCheck) { process(); } }; function readModalData() { if(document.getElementById('modal-spinner').isVisible()) { let target = document.getElementById('target-spinner').innerHTML; if (target == 'modal-ereport') { let temp = shared.getDevLog(); document.getElementById('log-textarea').value = temp.join('\n'); } else if (target == 'modal-config') { ui.refresh(null, null, null, shared.getConfig()); } document.getElementById('modal-spinner').classList.toggle('d-none'); document.getElementById(target).classList.toggle('d-none'); //$('#' + target).toggleClass('d-none'); document.getElementById('target-spinner').innerHTML = ''; } } function update(sortIt = true) { let updateRollStats = webList[0].type == WebType.CRYPTOSFAUCETS; if(sortIt) { webList.sort( function(a,b) { if (a === b) { return 0; } else if (a.nextRoll === null) { return 1; } else if (b.nextRoll === null) { return -1; } else { return a.nextRoll.getTime() < b.nextRoll.getTime() ? -1 : 1; } }); } saveWebList(); ui.refresh(webList, CFPromotions.getAll()); if(updateRollStats) { updateRollStatsSpan(); } }; function saveWebList() { const data = webList.map(function(x) { let ret = { id: x.id, name: x.name, lastClaim: x.lastClaim, aggregate: x.aggregate, balance: x.balance, stats: x.stats, nextRoll: x.nextRoll, enabled: x.enabled }; if (x.lastWithdraw) { ret.lastWithdraw = x.lastWithdraw; } return ret; }); persistence.save('webList', data, true); } function saveUserWallet() { const data = userWallet.map(x => { return { id: x.id, address: x.address };}); persistence.save('userWallet', data, true); } function process() { if(isObsolete()) { return; } timer.stopCheck(); if(webList[0].nextRoll == null) { ui.log(`All faucets are disabled. Click edit and select those you want to run...`); clearTimeout(processTimer); status = STATUS.IDLE; return; } if(webList[0].nextRoll.getTime() < Date.now()) { ui.log(`Opening ${webList[0].name}`); clearTimeout(processTimer); status = STATUS.CLAIMING; open(); } else { let timeUntilNext = webList[0].nextRoll.getTime() - Date.now() + helpers.randomMs(1000, 2000); // PROCESSING AGAIN LAST 'FORCE CLOSED' IN CASE WE HAVE A WINDOW OF TIME (MORE THAN TIMEOUT/2): if (timeUntilNext > (shared.getConfig()['defaults.timeout'] * 60 * 1000 / 2)) { let idx = -1; for (let i = webList.length - 1; i >= 0; i--) { if (webList[i].enabled && webList[i].stats && webList[i].stats.errors && webList[i].stats.errors.errorType == ErrorType.FORCE_CLOSED) { idx = i; break; } } if (idx > -1) { webList[idx].nextRoll = new Date(-20); update(true); process(); return; } } ui.log(`Waiting ${(timeUntilNext/1000/60).toFixed(2)} minutes...`); clearTimeout(processTimer); processTimer = setTimeout(manager.process, timeUntilNext); status = STATUS.IDLE; } }; function isObsolete() { let savedTimestamp = persistence.load('timestamp'); if (savedTimestamp && savedTimestamp > timestamp) { ui.log('STOPING EXECUTION! A new Manager UI window was opened. Process should continue there'); clearInterval(uiUpdatesInterval); return true; } return false; }; function open(promoCode) { let navUrl = webList[0].url; try { if(promoCode) { navUrl = new URL('promotion/' + promoCode, webList[0].url.origin); ui.log(`Opening ${webList[0].name} with Promo Code [${promoCode}]`); } if(Array.isArray(webList[0].rf)) { navUrl = new URL(navUrl.href + webList[0].rf[helpers.randomInt(0, webList[0].rf.length - 1)]); } let params = {}; if (webList[0].wallet) { //TODO: VALIDATE THAT ADDRESS EXISTS AND IS VALID!!! try { params.address = userWallet.find(x => x.type == webList[0].wallet).address; } catch { params.address = '123'; //not available @ wallet } } if(webList[0].type == WebType.BAGIKERAN) { params.doWithdraw = getDoWithdraw(webList[0].lastWithdraw); params.doSignOut = (webList[0].wallet == WalletType.FP_BCH ? true : false); params.trackUrl = webList[0].url; } shared.setFlowControl(webList[0].id, navUrl, webList[0].type, params); setTimeout(manager.resultReader, 15000); // Try to close old workingTab if still opened if (workingTab && !workingTab.closed) { try { shared.devlog(`Tab closed from Manager`); workingTab.close(); } catch { shared.devlog(`ERROR: unable to close tab from Manager`); } } else { shared.devlog(`No open tabs detected`); } timer.startCheck(webList[0].type); workingTab = GM_openInTab(navUrl.href, { active: (webList[0].workInBackground == USE_DEFAULT ? !shared.getConfig()['defaults.workInBackground'] : !webList[0].workInBackground) }); } catch(err) { ui.log(`Error opening tab: ${err}`) } }; function getDoWithdraw(lastWithdraw) { switch (shared.getConfig()['bk.withdrawMode']) { case "0": return false; break; case "2": return true; break; case "1": if(lastWithdraw == null) { return true; } return (lastWithdraw && ( (Date.now() - lastWithdraw.getTime()) > helpers.hsToMs(shared.getConfig()['bk.hoursBetweenWithdraws']))); break; default: return false; } return false; } // REFACTOR function resultReader() { if(isObsolete()) { return; } if (webList[0].type == WebType.FAUCETPAY && workingTab && !workingTab.closed && timeWaiting < helpers.minToMs(shared.getConfig()['fp.maxTimeInMinutes'])) { timeWaiting += 15; ui.log(`Waiting for ${webList[0].name} results...`, timeWaiting); setTimeout(manager.resultReader, 15000); return; } if(shared.wasVisited(webList[0].id)) { let result = shared.getResult(); if (result) { updateWebListItem(result); if ( (webList[0].type == WebType.CRYPTOSFAUCETS) && ( (result.claimed) || (result.promoStatus && result.promoStatus != PromoStatus.ACCEPTED) )) { let promoCode = CFPromotions.hasPromoAvailable(webList[0].id); if (promoCode) { timeWaiting = 0; update(false); open(promoCode); return; } } if ( webList[0].type == WebType.BAGIKERAN && shared.getCurrent().params.doWithdraw && !result.withdrawnAmount) { if(!result.withdrawing) { shared.updateWithoutClosing({ withdrawing: true }); update(false); timeWaiting = 0; } if (hasTimedOut()) { if(webList[0].stats.countTimeouts) { webList[0].stats.countTimeouts += 1; } else { webList[0].stats.countTimeouts = 1; } ui.log(`Waited too much time for ${webList[0].name} results: triggering timeout`); moveNext(); return; } if (shared.hasErrors(webList[0].id)) { webList[0].stats.errors = shared.getResult(); ui.log(`${webList[0].name} closed with error: ${helpers.getEnumText(ErrorType, webList[0].stats.errors.errorType)} ${webList[0].stats.errors.errorMessage}`); if(sleepIfBan()) { return; } moveNext(); return; } timeWaiting += 15; ui.log(`Waiting for ${webList[0].name} withdraw...`, timeWaiting); setTimeout(manager.resultReader, 15000); return; } } else { ui.log(`Unable to read last run result, for ID: ${webList[0].id} > ${webList[0].name}`); } timeWaiting = 0; update(true); readUpdateValues(true); return; } else { timeWaiting += 15; if (!shared.hasErrors(webList[0].id) && !hasTimedOut()) { ui.log(`Waiting for ${webList[0].name} results...`, timeWaiting); setTimeout(manager.resultReader, 15000); return; } if (shared.hasErrors(webList[0].id)) { webList[0].stats.errors = shared.getResult(); ui.log(`${webList[0].name} closed with error: ${helpers.getEnumText(ErrorType,webList[0].stats.errors.errorType)} ${webList[0].stats.errors.errorMessage}`); if(sleepIfBan()) { return; } } if (hasTimedOut()) { if(webList[0].stats.countTimeouts) { webList[0].stats.countTimeouts += 1; } else { webList[0].stats.countTimeouts = 1; } ui.log(`Waited too much time for ${webList[0].name} results: triggering timeout`); } moveNext(); return; } }; function sleepIfBan() { if( (webList[0].stats.errors.errorType == ErrorType.IP_BAN && shared.getConfig()['cf.sleepHoursIfIpBan'] > 0) || ( webList[0].stats.errors.errorType == ErrorType.IP_RESTRICTED && shared.getConfig()['bk.sleepMinutesIfIpBan'] > 0) ) { if(webList[0].type == WebType.CRYPTOSFAUCETS) { webList.filter(x => x.enabled && x.type == WebType.CRYPTOSFAUCETS) .forEach( function(el) { el.nextRoll = new Date(helpers.addMs(el.nextRoll, helpers.getRandomMs(shared.getConfig()['cf.sleepHoursIfIpBan'] * 60, 2))); }); } if(webList[0].type == WebType.BAGIKERAN) { webList.filter(x => x.enabled && x.type == WebType.BAGIKERAN && x.url.host == webList[0].url.host) .forEach( function(el) { el.nextRoll = new Date(helpers.addMs(el.nextRoll, helpers.getRandomMs(shared.getConfig()['bk.sleepMinutesIfIpBan'], 2))); }); } shared.clearFlowControl(); update(true); timeWaiting = 0; readUpdateValues(true); return true; } return false; } function moveNext() { let millisecondsDelay = helpers.getRandomMs(shared.getConfig()['defaults.postponeMinutes'], 5); webList[0].nextRoll = new Date(helpers.addMs(new Date(), millisecondsDelay)); shared.clearFlowControl(); update(true); timeWaiting = 0; readUpdateValues(true); } function hasTimedOut() { return shared.getConfig()['defaults.timeout'] != -1 && (timeWaiting > (shared.getConfig()['defaults.timeout'] * 60)); }; function updateWebListItem(result) { if (result.withdrawing) { return; } ui.log(`Updating data: ${JSON.stringify(result)}`); webList[0].stats.countTimeouts = 0; webList[0].stats.errors = null; if (result.withdrawnAmount && result.withdrawnAmount > 0) { webList[0].lastWithdraw = new Date(); webList[0].balance += result.withdrawnAmount; webList[0].lastClaim = 0; webList[0].aggregate = 0; return; } if (result.claimed) { try { result.claimed = parseFloat(result.claimed); } catch { } if(!isNaN(result.claimed)) { webList[0].lastClaim = result.claimed; webList[0].aggregate += result.claimed; // if (!result.balance) { // webList[0].balance = webList[0].aggregate; // } } } if(result.balance) { webList[0].balance = result.balance; } if(result.nextRoll) { webList[0].nextRoll = new Date(result.nextRoll); } if(result.promoStatus) { CFPromotions.updateFaucetForCode(result.promoCode, webList[0].id, result.promoStatus); } if(result.rolledNumber) { CFHistory.addRoll(result.rolledNumber); } }; function readPromoCodeValues() { let promoCodeElement = document.getElementById('promo-code-new'); let promoDataStr = promoCodeElement.innerText.clean(); let promoDisplayStatus = document.getElementById('promo-display-status'); if (promoDataStr == '') { promoDisplayStatus.innerHTML = ''; return; } let promoData = JSON.parse(promoDataStr); if(promoData.action) { switch (promoData.action) { case 'ADD': CFPromotions.addNew(promoData.code, promoData.repeatDaily); promoCodeElement.innerText = ''; document.getElementById('promo-text-input').value = ''; promoDisplayStatus.innerHTML = 'Code ' + promoData.code + ' added!'; ui.log(`Promo code ${promoData.code} added`); ui.refresh(null, CFPromotions.getAll()); break; case 'REMOVEALLPROMOS': CFPromotions.removeAll(); promoCodeElement.innerText = ''; promoDisplayStatus.innerHTML = 'Promo codes removed!'; ui.log(`Promo codes removed`); ui.refresh(null, CFPromotions.getAll()); break; case 'REMOVE': if(CFPromotions.remove(promoData.id, promoData.code) != -1) { ui.log(`Promo code ${promoData.code} removed`); } else { ui.log(`Unable to remove code ${promoData.code}`); } promoCodeElement.innerText = ''; ui.refresh(null, CFPromotions.getAll()); break; } } }; function updateRollStatsSpan() { let rollsSpanElement = document.getElementById('rolls-span'); rollsSpanElement.innerText = CFHistory.getRollsMeta().join(','); }; function getCFlist() { let items; items = webList.filter(f => f.type === WebType.CRYPTOSFAUCETS); items = items.map(x => { return { id: x.id, name: x.coinRef };}); items.sort((a, b) => (a.name > b.name) ? 1 : -1); return items; }; function closeWorkingTab() { workingTab.close(); }; return{ init:start, process: process, resultReader: resultReader, getFaucetsForPromotion: getCFlist, readPromoCodeValues: readPromoCodeValues, closeWorkingTab: closeWorkingTab }; }, createUi: function() { let logLines = ['', '', '', '', '']; function init(cfFaucets) { appendCSS(); appendJavaScript(); appendHtml(); createPromoTable(cfFaucets); document.querySelector('.page-title h1').innerHTML = 'Auto Claim'; }; function appendCSS() { let css = document.createElement('style'); css.innerHTML = ` td.em-input { padding-top: 0; padding-bottom: 0; } `; document.head.appendChild(css); }; function appendJavaScript() { // let js = document.createElement('script'); // js.setAttribute('language', 'text/javascript'); let js = '' // document.head.appendChild(js); $('head').append(js); }; function appendHtml() { let html =''; html += '
'; if (shared.getConfig()['devlog.enabled']) { html += '
Send Log
'; } html += '
Edit Config
'; html += '
'; html += ''; html += '
Loading...
'; html += '

Schedule

'; html += '
'; html += '
Save'; html += ' Cancel
'; html += ''; html += '
'; html += '
'; html += '
'; html += '
'; html +='
'; html +='

Promo Codes

'; html +='
'; html += ''; CFReusableCodesSuggestion.forEach( function(x) { html += '' }); html += ''; html +='
'; html +='
'; html +='
'; html +='
Remove All'; html +='
'; html +='
'; html += '
'; html += ''; html +='
'; $('#referral-table').before(html); $('#schedule-container').append( createScheduleTable() ); $(document.querySelector('.navbar-nav')).prepend('
discord
'); }; function createPromoTable(faucets) { let tableStructure = ''; tableStructure += ''; tableStructure += ''; tableStructure += ''; for (let i = 0, all = faucets.length; i < all; i++) { tableStructure += ''; } tableStructure += '
⏳ Pending ✔️ Accepted 🕙 Used Before ❌ Invalid code ❗ Unknown error ⚪ No code
CodeAdded' + faucets[i].name + '
'; $('#promo-container').append( tableStructure ); }; function createScheduleTable() { let tableStructure = ''; tableStructure += ''; tableStructure += ''; tableStructure += ''; tableStructure += '
Active#NameSiteLast ClaimAggregateBalanceFIATNext RollMsgsRun ASAP
'; return tableStructure; }; function loadScheduleTable(data) { let tableBody = ''; for(let i=0, all = data.length; i < all; i++) { tableBody += ''; tableBody +=''; tableBody +='' + (data[i].enabled ? (i + 1).toString() : '-') + ''; tableBody +='' + data[i].name + ''; tableBody +=''; if (Array.isArray(data[i].rf)) { tableBody +=' '; } else { tableBody +=' '; } tableBody += (data[i].type == WebType.BAGIKERAN ? data[i].url.host + data[i].url.pathname : data[i].url.host) + ''; tableBody +='' + data[i].lastClaim.toFixed(8) + ''; tableBody +='' + data[i].aggregate.toFixed(8) + ''; tableBody +=''; if (data[i].balance) { if(typeof data[i].balance == 'string') { tableBody += data[i].balance.split(' ')[0]; } else { tableBody += data[i].balance.toFixed(8); } } tableBody + ''; tableBody +=''; tableBody +='' + helpers.getPrintableTime(data[i].nextRoll) + ''; tableBody +='' + addBadges(data[i].stats) + ''; tableBody +=''; tableBody +=''; } $('#schedule-table-body').html(tableBody); location.href = 'javascript:convertToFiat();'; }; function addBadges(stats) { let consecutiveTimeout = stats.countTimeouts; let otherErrors = stats.errors; let html = ' '; if (consecutiveTimeout) { html += `${consecutiveTimeout}`; } if (otherErrors) { html += `${helpers.getEnumText(ErrorType, otherErrors.errorType)}`; } return html; } function loadPromotionTable(codes) { let tableBody = ''; for(let c=0; c < codes.length; c++) { let data = codes[c]; tableBody += ''; tableBody += ''; tableBody += ' '; tableBody += '' + data.code + ''; tableBody +='' + helpers.getPrintableDateTime(data.added) + ''; for(let i=0, all = data.statusPerFaucet.length; i < all; i++) { tableBody +='' + helpers.getEmojiForPromoStatus(data.statusPerFaucet[i].status ?? 0) + ''; } tableBody +=''; } $('#promo-table-body').html(tableBody); }; function loadWalletTable(data) { let tableBody = ''; for(let i=0, all = data.length; i < all; i++) { tableBody += ''; tableBody += '' + data[i].name + ''; tableBody += ''; tableBody += ''; } $('#wallet-table-body').html(tableBody); }; function loadConfigData(data) { for (const prop in data) { let element = document.querySelector('[data-prop="' + prop + '"]'); if(element) { if(element.type == 'select-one' || element.type == 'text' || element.type == 'password') { element.dataset.original = data[prop]; element.value = data[prop]; } else if (element.type == 'checkbox') { element.dataset.original = (data[prop] ? "1" : "0"); element.checked = data[prop]; } } } let elCredentialsAutologin = document.querySelector('[data-prop="cf.autologin"]'); let elCredentialsMode = document.querySelector('[data-prop="cf.credentials.mode"]'); let elCredentialsEmail = document.querySelector('[data-prop="cf.credentials.email"]'); let elCredentialsPassword = document.querySelector('[data-prop="cf.credentials.password"]'); let elWithdrawMode = document.querySelector('[data-prop="bk.withdrawMode"]'); let elHoursBetweenWithdraws = document.querySelector('[data-prop="bk.hoursBetweenWithdraws"]'); let elDevlogEnabled = document.querySelector('[data-prop="devlog.enabled"]'); let elDevlogMaxLines = document.querySelector('[data-prop="devlog.maxLines"]'); elCredentialsMode.disabled = !elCredentialsAutologin.checked; elCredentialsEmail.disabled = ( (!elCredentialsAutologin.checked || elCredentialsMode.value == "2") ? true : false); elCredentialsPassword.disabled = ( (!elCredentialsAutologin.checked || elCredentialsMode.value == "2") ? true : false); elHoursBetweenWithdraws.disabled = ( (elWithdrawMode.value == "0" || elWithdrawMode.value == "2") ? true : false); elDevlogMaxLines.disabled = !elDevlogEnabled.checked; elCredentialsAutologin.onchange = function (e) { document.querySelector('[data-prop="cf.credentials.mode"]').disabled = !e.target.checked; if (elCredentialsMode.value == "2") { document.querySelector('[data-prop="cf.credentials.email"]').disabled = true; document.querySelector('[data-prop="cf.credentials.password"]').disabled = true; } else { document.querySelector('[data-prop="cf.credentials.email"]').disabled = false; document.querySelector('[data-prop="cf.credentials.password"]').disabled = false; } } elCredentialsMode.onchange = function (e) { if (e.target.value == "2") { document.querySelector('[data-prop="cf.credentials.email"]').disabled = true; document.querySelector('[data-prop="cf.credentials.password"]').disabled = true; } else { document.querySelector('[data-prop="cf.credentials.email"]').disabled = false; document.querySelector('[data-prop="cf.credentials.password"]').disabled = false; } } elWithdrawMode.onchange = function (e) { if (e.target.value == "0" || e.target.value == "2") { document.querySelector('[data-prop="bk.hoursBetweenWithdraws"]').disabled = true; } else { document.querySelector('[data-prop="bk.hoursBetweenWithdraws"]').disabled = false; } } elDevlogEnabled.onchange = function (e) { document.querySelector('[data-prop="devlog.maxLines"]').disabled = !e.target.checked; } }; function refresh(scheduleData, promotionData, walletData, configData) { if (scheduleData) { loadScheduleTable(scheduleData); } if (promotionData) { loadPromotionTable(promotionData); } if (walletData) { loadWalletTable(walletData); } if (configData) { loadConfigData(configData); } }; function log(msg, elapsed = false) { if(shared.getConfig()['devlog.enabled']) { shared.devlog(msg, elapsed) }; if(msg) { let previous = logLines[0].split(' ')[1]; if(elapsed && (previous == msg)) { logLines[0] = helpers.getPrintableTime() + ' ' + msg + ' [Elapsed time: ' + elapsed + ' seconds]'; } else { logLines.pop(); logLines.unshift(helpers.getPrintableTime() + ' ' + msg); } $('#console-log').html(logLines.join('
')); } }; return { init: init, refresh: refresh, loadPromotionTable: loadPromotionTable, log: log } }, createCFPromotions: function() { let codes = []; function PromotionCode(id, code, repeatDaily = false) { this.id = id; this.code = code; this.added = new Date(); this.statusPerFaucet = []; this.repeatDaily = repeatDaily; this.lastExecTimeStamp = null; }; function getFaucetStatusInPromo(promo, faucetId) { let faucet = promo.statusPerFaucet.find(x => x.id == faucetId); if (faucet.status && promo.repeatDaily) { //Using 26 hs instead of 24hs, and 2hs gap retry when code is flagged as USEDBEFORE if((faucet.status == PromoStatus.ACCEPTED && (Date.now() - faucet.execTimeStamp.getTime()) > HS_26_IN_MILLISECONDS) || (faucet.status == PromoStatus.USEDBEFORE && (Date.now() - faucet.execTimeStamp.getTime()) > HS_2_IN_MILLISECONDS)) { faucet.status = PromoStatus.PENDING; } } return faucet.status ?? PromoStatus.NOCODE; }; function addNew(code, repeatDaily = false) { let newPromo = new PromotionCode(codes.length, code, repeatDaily); newPromo.statusPerFaucet = manager.getFaucetsForPromotion().map(x => { return { id: x.id, };}); newPromo.statusPerFaucet.forEach(function (element, idx, arr) { arr[idx].status = PromoStatus.PENDING; arr[idx].execTimeStamp = null; }); codes.push(newPromo); codes.sort((a, b) => (a.id < b.id) ? 1 : -1); save(); }; function getAll() { return codes; }; function updateFaucetForCode(code, faucetId, newStatus) { let promo = codes.find(x => x.code == code); let faucet = promo.statusPerFaucet.find(x => x.id == faucetId); if(faucet) { faucet.status = newStatus; faucet.execTimeStamp = new Date(); promo.lastExecTimeStamp = faucet.execTimeStamp; } save(); }; function hasPromoAvailable(faucetId) { let resp = false; codes.forEach(function (promotion, idx, arr) { let status = getFaucetStatusInPromo(promotion, faucetId); if (status == PromoStatus.PENDING) { resp = promotion.code; return; } }); return resp; }; function save() { persistence.save('CFPromotions', getAll(), true); }; function load(data) { codes = data; }; function removeAll() { codes = []; save(); }; function remove(id, code) { let idx = codes.findIndex(x => x.id == id && x.code == code); if(idx != -1) { codes.splice(idx, 1); save(); } return idx; }; return { addNew: addNew, removeAll: removeAll, remove: remove, getAll: getAll, load: load, updateFaucetForCode: updateFaucetForCode, hasPromoAvailable: hasPromoAvailable } }, createInteractions: function(){ let randomInteractionLevel = RandomInteractionLevel.MEDIUM; let maxActions = 0; let performedActions = -1; let selectableElements; let actions = { available: [ function() { $('html, body').animate({ scrollTop: helpers.randomInt(0, $('html, body').get(0).scrollHeight) }, { complete: setTimeout(interactions.addPerformed, helpers.randomMs(100, 3000)), duration: helpers.randomMs(100, 1500) }); }, function() { let element = interactions.selectableElements[helpers.randomInt(0, interactions.selectableElements.length - 1)]; try { if (document.body.createTextRange) { const range = document.body.createTextRange(); range.moveToElementText(element); range.select(); } else if (window.getSelection) { const selection = window.getSelection(); const range = document.createRange(); range.selectNodeContents(element); selection.removeAllRanges(); selection.addRange(range); } } catch (err) { } interactions.addPerformed(); } ] }; function start(selectableElements) { performedActions = 0; switch(randomInteractionLevel) { case RandomInteractionLevel.NONE: maxActions = 0; break; case RandomInteractionLevel.LOW: maxActions = helpers.randomInt(2, 4); break; case RandomInteractionLevel.MEDIUM: maxActions = helpers.randomInt(5, 8); break; case RandomInteractionLevel.HIGH: maxActions = helpers.randomInt(12, 16); break; } interactions.selectableElements = selectableElements; performActions(); } function performActions() { if(performedActions >= maxActions) { return; } let delay = 0; for(let i = 0; i < maxActions; i++) { delay += helpers.randomMs(350, 1500); setTimeout(actions.available[helpers.randomInt(0, actions.available.length - 1)], delay); } } function addPerformed() { performedActions++; } function completed() { return (performedActions >= maxActions); } return { start: start, completed: completed, addPerformed: addPerformed, selectableElements: selectableElements }; }, createSGProcessor: function() { let timerSpans; function run() { if(isLoading()) { setTimeout(run, helpers.randomMs(5000, 10000)); return; } else if (hasPopup()) { closePopup(); setTimeout(run, helpers.randomMs(5000, 10000)); } else { if(isMinerActive()) { processRunDetails(); } else { activateMiner(); } } }; function hasPopup() { return $('.wrapper.grid.min-h-0.md-min-h-1-2.md-relative.md-rounded-lg.md-bg-dark-4 svg circle').length > 0; }; function closePopup() { try { $('svg.flex.w-8.h-8.fill-current')[0].parentElement.click(); } catch { } }; function isLoading() { return $('#loader-logo').length; }; function isMinerActive() { timerSpans = $('.mb-8 .wrapper .mb-1 span'); if(timerSpans.length > 0) { shared.devlog(`SG: Miner is active`); return true; } else { shared.devlog(`SG: Miner is inactive`); return false; } return (timerSpans.length === 0); }; function activateMiner() { const activateButton = document.querySelector('.mb-8 .wrapper button'); if (activateButton) { activateButton.click(); shared.devlog(`SG: Activate miner clicked`); // setTimeout(processRunDetails, helpers.randomMs(10000, 20000)); setTimeout(run, helpers.randomMs(10000, 20000)); } else { processRunDetails() } }; function processRunDetails() { let result = {}; result.nextRoll = helpers.addMinutes(new Date(), readCountdown().toString()); result.balance = readBalance(); shared.closeWindow(result); }; function readCountdown() { let mins = 15; try { let timeLeft = timerSpans.last().text().split(':'); shared.devlog(`SG Countdown timeLeft spans:`); shared.devlog(timeLeft); if(timeLeft.length === 3) { mins = parseInt(timeLeft[0]) * 60 + parseInt(timeLeft[1]); } } catch (err) { shared.devlog(`SG Error reading countdown: ${err}`); } return mins; }; function readBalance() { let balance = ""; try { balance = $('span.text-accent').first().text() + " BTC"; } catch (err) { } return balance; }; return { run: run, processRunDetails: processRunDetails }; }, createCFProcessor: function() { const NavigationProcess = { ROLLING: 1, PROCESSING_PROMOTION: 2, LOGIN: 3 }; let navigationProcess; let countdown; let rollButton; let promotionTag; let timeWaiting= 0; let loopingForErrors = false; function init() { let urlType = helpers.cf.getUrlType(window.location.href); switch(urlType) { case CFUrlType.FREE: if(localeConfig.setToEnglish) { let refValue = $('.nav-item a')[4].innerHTML; if (refValue != 'Settings') { window.location.href = '/set-language/en'; } } addJS_Node (null, null, overrideSelectNativeJS_Functions); interactions = objectGenerator.createInteractions(); run(); break; case CFUrlType.PROMOTION: interactions = objectGenerator.createInteractions(); runPromotion(); break; case CFUrlType.HOME: if (shared.getConfig()['cf.autologin']) { addJS_Node (null, null, overrideSelectNativeJS_Functions); doLogin(); } else { shared.closeWithError(ErrorType.NEED_TO_LOGIN, ''); } break; case CFUrlType.CONTACTTWITTER: shared.closeWithError(ErrorType.IP_BAN, ''); break; default: break; } return; } function run() { navigationProcess = NavigationProcess.ROLLING; displayStatusUi(); setTimeout(findCountdownOrRollButton, helpers.randomMs(2000, 5000)); }; function doLogin() { navigationProcess = NavigationProcess.LOGIN; displayStatusUi(); setTimeout(findLoginForm, helpers.randomMs(2000, 5000)); }; function isFullyLoaded() { //Waits 55 seconds max if(document.readyState == 'complete' || timeWaiting == -1) { document.getElementById('process-status').innerHTML = 'Interacting'; timeWaiting = 0; interact(); } else { timeWaiting = -1; document.getElementById('process-status').innerHTML = 'Waiting for document fully loaded'; setTimeout(isFullyLoaded, helpers.randomMs(45000, 55000)); } }; function runPromotion() { navigationProcess = NavigationProcess.PROCESSING_PROMOTION displayStatusUi(); setTimeout(findPromotionTag, helpers.randomMs(1000, 3000)); }; function findCountdownOrRollButton() { if( isCountdownVisible() && !isRollButtonVisible() ) { timeWaiting = 0; processRunDetails(); } else if ( !isCountdownVisible() && isRollButtonVisible() ) { timeWaiting = 0; setTimeout(isFullyLoaded, helpers.randomMs(1000, 5000)); } else { if (timeWaiting/1000 > shared.getConfig()['defaults.timeout'] * 60) { shared.closeWithError(ErrorType.TIMEOUT, ''); return; } timeWaiting += 3000; setTimeout(findCountdownOrRollButton, helpers.randomMs(2000, 5000)); } }; function findLoginForm() { if ( document.getElementById('div.login-wrapper').isVisible() ) { //Other possible error is if recaptcha did not load yet... so maybe wait til the web is fully loaded for low connection issues let errElement = document.querySelector('.login-wrapper .error'); if( errElement && errElement.innerHTML != '') { let errorMessage = errElement.innerText; shared.closeWithError(ErrorType.LOGIN_ERROR, errorMessage); return; } if(!loopingForErrors) { if(shared.getConfig()['cf.credentials.mode'] == 1) { timeWaiting = 0; $('.login-wrapper input[name="email"]').val(shared.getConfig()['cf.credentials.email']); $('.login-wrapper input[name="password"]').val(shared.getConfig()['cf.credentials.password']); $('.login-wrapper button.login').click(); loopingForErrors = true; } else { if($('.login-wrapper input[name="email"]').val() != '' && $('.login-wrapper input[name="password"]').val() != '') { $('.login-wrapper button.login').click(); $('#process-status')[0].innerHTML = 'Processing'; loopingForErrors = true; } else { $('#process-status')[0].innerHTML = 'Waiting for credentials...'; if (timeWaiting/1000 > (shared.getConfig()['defaults.timeout'] / 1.5) * 60) { shared.closeWithError(ErrorType.LOGIN_ERROR, 'No credentials were provided'); return; } } } } } if (timeWaiting/1000 > shared.getConfig()['defaults.timeout'] * 60) { shared.closeWithError(ErrorType.TIMEOUT, ''); return; } timeWaiting += 3000; setTimeout(findLoginForm, helpers.randomMs(2000, 5000)); }; function interact() { let selectables = [] selectables = selectables.concat($('td').toArray()); selectables = selectables.concat($('p').toArray()); selectables = selectables.concat($('th').toArray()); interactions.start(selectables); setTimeout(waitInteractions, helpers.randomMs(2000, 4000)); } function waitInteractions() { if(interactions.completed()) { roll(); } else { setTimeout(waitInteractions, helpers.randomMs(2000, 4000)); } } function isCountdownVisible() { countdown = $('.timeout-wrapper'); return ($(countdown).length > 0 && $(countdown[0]).is(':visible')); }; function isRollButtonVisible() { rollButton = $('.main-button-2.roll-button.bg-2'); return ($(rollButton).length > 0 && $(rollButton[0]).is(':visible')); }; function roll() { $('#process-status')[0].innerHTML = 'Roll triggered'; $(rollButton[0]).click(); setTimeout(findCountdownOrRollButton, helpers.randomMs(2000, 3000)); } function isPromotionTagVisible() { let pTags = $('p'); if (pTags.length > 0) { promotionTag = $('p')[0]; return true; } return false; }; function findPromotionTag() { if( isPromotionTagVisible() ) { processRunDetails(); } else { setTimeout(cfProcessor.findPromotionTag, helpers.randomMs(2000, 5000)); } }; function processRunDetails() { let result = {}; if(navigationProcess == NavigationProcess.ROLLING) { result.nextRoll = readCountdown(); result.claimed = readClaimed(); result.balance = readBalance(); if(result.claimed != 0) { result.rolledNumber = readRolledNumber(); } result.balance = readBalance(); } else if (navigationProcess == NavigationProcess.PROCESSING_PROMOTION) { result.promoStatus = readPromoStatus(); result.promoCode = readPromoCode(); if (result.promoStatus == PromoStatus.ACCEPTED) { result.nextRoll = helpers.addMinutes(new Date(-20), "0"); } } shared.closeWindow(result); }; function readCountdown() { let minsElement = $('.timeout-container .minutes .digits'); let mins = "0"; if ($(minsElement).length > 0) { mins = $(minsElement)[0].innerHTML; } if (mins) { return helpers.addMinutes(new Date(), mins.toString()); } else { return null; } }; function readClaimed() { let claimed = 0; try { claimed = $('.result')[0].innerHTML; claimed = claimed.trim(); claimed = claimed.slice(claimed.lastIndexOf(" ") + 1); } catch(err) { } return claimed; }; function readRolledNumber() { let number = 0; try { number = $('.lucky-number').toArray().map(x => x.innerText).join(''); number = parseInt(number); } catch(err) { } return number; }; function readBalance() { let balance = ""; try { balance = $('.navbar-coins.bg-1 a').first().text(); } catch(err) { } return balance; }; function readPromoStatus() { let promoStatus = PromoStatus.UNKNOWNERROR; try { if(promotionTag.innerHTML.indexOf(localeConfig.stringSearches.promoCodeAccepted) > 0) { return PromoStatus.ACCEPTED; } else if(promotionTag.innerHTML.indexOf(localeConfig.stringSearches.promoCodeUsed) > 0) { return PromoStatus.USEDBEFORE; } else if(promotionTag.innerHTML.indexOf(localeConfig.stringSearches.promoCodeExpired) > 0) { return PromoStatus.EXPIRED; } else if(localeConfig.stringSearches.promoCodeInvalid.findIndex(x => promotionTag.innerHTML.indexOf(x) > -1) == -1) { return PromoStatus.INVALID; } } catch ( err ) { } return promoStatus; }; function validatePromoString() { }; function readPromoCode() { var urlSplit = window.location.href.split('/'); return urlSplit[urlSplit.length - 1]; }; function displayStatusUi() { $( 'body' ).prepend( '
⚙️ Processing
' ); }; return { init: init }; }, createCFHistory: function() { let rollsMeta = [ { id: 0, range: '0000-9885', count: 0 }, { id: 1, range: '9886-9985', count: 0 }, { id: 2, range: '9986-9993', count: 0 }, { id: 3, range: '9994-9997', count: 0 }, { id: 4, range: '9998-9999', count: 0 }, { id: 5, range: '10000', count: 0 } ]; function initOrLoad() { let storedData = persistence.load('CFHistory', true); if(storedData) { rollsMeta = storedData; } }; function addRoll(number) { switch(true) { case (number <= 9885): rollsMeta[0].count++; break; case (number <= 9985): rollsMeta[1].count++; break; case (number <= 9993): rollsMeta[2].count++; break; case (number <= 9997): rollsMeta[3].count++; break; case (number <= 9999): rollsMeta[4].count++; break; case (number == 10000): rollsMeta[5].count++; break; default: break; } save(); }; function getRollsMeta() { return rollsMeta.map(x => x.count); }; function save() { persistence.save('CFHistory', rollsMeta, true); }; return { initOrLoad: initOrLoad, addRoll: addRoll, getRollsMeta: getRollsMeta } }, createFBProcessor: function() { let countdownMinutes; let timeWaiting= 0; function timedOut(addMs) { if (timeWaiting/1000 > shared.getConfig()['defaults.timeout'] * 60) { shared.closeWithError(ErrorType.TIMEOUT, ''); return true; } timeWaiting += addMs; return false; } function run() { setTimeout(findCountdownOrRollButton, helpers.randomMs(12000, 15000)); }; function findCountdownOrRollButton() { if ( isCountdownVisible() ) { timeWaiting = 0; countdownMinutes = +document.querySelectorAll('.free_play_time_remaining.hasCountdown .countdown_amount')[0].innerHTML + 1; let result = {}; result.balance = readBalance(); result.nextRoll = helpers.addMinutes(new Date(), countdownMinutes.toString()); shared.closeWindow(result); return; } if ( isRollButtonVisible() ) { if (shared.getConfig()['fb.activateRPBonus']) { if (!document.getElementById('bonus_container_free_points')) { document.querySelector('a.rewards_link').click(); activateBonus(0); } } if (isHCaptchaVisible()) { waitForCaptcha(); } else { clickRoll(); } } else { setTimeout(findCountdownOrRollButton, helpers.randomMs(12000, 15000)); } }; function isCountdownVisible() { return document.querySelectorAll('.free_play_time_remaining.hasCountdown .countdown_amount').length > 0; }; function isHCaptchaVisible() { let hCaptchaFrame = document.querySelector('.h-captcha > iframe'); if (hCaptchaFrame && $(hCaptchaFrame).is(':visible')) { return true; } return false; }; function isRollButtonVisible() { return $(document.getElementById('free_play_form_button')).is(':visible'); }; function waitForCaptcha() { if ( document.querySelector('.h-captcha > iframe').getAttribute('data-hcaptcha-response').length > 0) { clickRoll(); } else { if (timedOut(10000)) { return; } setTimeout(waitForCaptcha, helpers.randomMs(10000, 12000)); } }; function clickRoll() { try { document.getElementById('free_play_form_button').click(); setTimeout(processRunDetails, helpers.randomMs(3000, 10000)); } catch (err) { shared.closeWithError(ErrorType.CLICK_ROLL_ERROR, err); } }; function processRunDetails() { if ($(document.getElementById('winnings')).is(':visible')) { closePopup(); let result = {}; result.claimed = readClaimed(); result.balance = readBalance(); if(result.claimed != 0) { result.rolledNumber = readRolledNumber(); result.nextRoll = helpers.addMinutes(new Date(), "60"); } shared.closeWindow(result); return; } if ($('.free_play_result_error').is(':visible')) { shared.closeWithError(ErrorType.ROLL_ERROR, $('.free_play_result_error')[0].innerHTML); return; } if($('#free_play_error').is(':visible')) { shared.closeWithError(ErrorType.ROLL_ERROR, $('.free_play_error')[0].innerHTML); return; } if ($(document.getElementById('same_ip_error')).is(':visible')) { shared.closeWithError(ErrorType.ROLL_ERROR, document.getElementById('same_ip_error').innerHTML); return; } if (timedOut(5000)) { return; } setTimeout(processRunDetails, helpers.randomMs(5000, 6000)); }; function closePopup() { let closePopupBtn = document.querySelector('.reveal-modal.open .close-reveal-modal'); if (closePopupBtn) { closePopupBtn.click(); } }; function readRolledNumber() { let rolled = 0; try { rolled = parseInt([... document.querySelectorAll('#free_play_digits span')].map( x => x.innerHTML).join('')); } catch { } return rolled; }; function readBalance() { let balance = 0; try { balance = document.getElementById('balance').innerHTML; } catch { } return balance; }; function readClaimed() { let claimed = 0; try { claimed = document.getElementById('winnings').innerHTML; } catch { } return claimed; }; function activateBonus(i) { if($(document.querySelector('#reward_point_redeem_result_container_div .reward_point_redeem_result_error')).is(':visible')) { let closeBtn = document.querySelector('#reward_point_redeem_result_container_div .reward_point_redeem_result_box_close') if ($(closeBtn).is(':visible')) { closeBtn.click(); } } else if ($(document.querySelector('#reward_point_redeem_result_container_div .reward_point_redeem_result_success')).is(':visible')) { let closeBtn = document.querySelector('#reward_point_redeem_result_container_div .reward_point_redeem_result_box_close') if ($(closeBtn).is(':visible')) { closeBtn.click(); document.querySelector('#free_play_link_li a').click(); setTimeout(findCountdownOrRollButton, helpers.randomMs(10000, 12000)); return; } } try { let redeemButtons = document.querySelectorAll('#free_points_rewards button'); redeemButtons[i].click(); i = i + 1; } catch (err) { } if(i > 4) { document.querySelector('#free_play_link_li a').click(); setTimeout(findCountdownOrRollButton, helpers.randomMs(10000, 12000)); return; } setTimeout(activateBonus.bind(null, i), 5000); }; return { run: run }; }, createFPProcessor: function() { let timeWaiting= 0; function timedOut(addMs) { if (timeWaiting/1000 > shared.getConfig()['defaults.timeout'] * 60) { shared.closeWithError(ErrorType.TIMEOUT, ''); return true; } timeWaiting += addMs; return false; } function init() { if(window.location.href.includes('ptc/view')) { ptcSingle(); } else if (window.location.href.includes('ptc')) { ptcList(); } else if (window.location.href.includes('account/login')) { shared.closeWithError(ErrorType.NEED_TO_LOGIN, ''); } return; } function ptcList() { let result; let runMsgDiv = document.querySelector('.alert.alert-info'); if (runMsgDiv) { let runMsg = runMsgDiv.innerHTML; if (runMsg.includes('invalid captcha')) { // Warn? Usually a error if ptcList is refreshed } else if (runMsg.includes('Good job')) { // "Good job! You have been credited with 0.00000001 BTC." try { let idx = runMsg.search(/\d/); let claimed = parseFloat(runMsg.slice(idx, idx + 10)); result = shared.getResult(); result.claimed = (result.claimed ?? 0) + claimed; result.nextRoll = helpers.addMs(new Date(), helpers.getRandomMs(shared.getConfig()['fp.hoursBetweenRuns'] * 60, 2)); // Wait hoursBetweenRuns +/- 1% shared.updateWithoutClosing(result); } catch { } } } if ($('b:contains("Whoops!")').length) { result = shared.getResult(); result.nextRoll = helpers.addMs(new Date(), helpers.getRandomMs(shared.getConfig()['fp.hoursBetweenRuns'] * 60, 2)); // Wait hoursBetweenRuns +/- 2% shared.closeWindow(result); return; } let adButtons = $('button').filter(function(idx) { return this.innerHTML.includes('VISIT AD FOR') > 0; }); if (adButtons.length > 0) { adButtons[0].click(); return; } if (timedOut(10000)) { return; } setTimeout(ptcList, helpers.randomMs(10000, 12000)); } function ptcSingle() { if($('input[name="complete"]').is(':visible')) { setTimeout(waitForCaptcha, 15000); } else if (document.querySelector('body').innerText.toLowerCase().includes('ad does not exist')) { window.location.href = 'https://faucetpay.io/ptc'; } else { if (timedOut(5000)) { return; } setTimeout(ptcSingle, helpers.randomMs(5000, 6000)); } } function waitForCaptcha() { if ( document.querySelector('.h-captcha > iframe').getAttribute('data-hcaptcha-response').length > 0 ) { clickClaim(); } else { if (timedOut(9000)) { return; } setTimeout(waitForCaptcha, helpers.randomMs(9000, 11000)); } } function clickClaim() { $('input[name="complete"]').focus(); $($('input[name="complete"]')[0]).attr("onclick", ""); $('input[name="complete"]').click(); //force close with timeout in case it's still opened setTimeout(shared.closeWithError.bind(null, 'TIMEOUT', 'Timed out after clicking a CLAIM button.'), helpers.minToMs(shared.getConfig()['defaults.timeout'])); } return { init: init }; }, // TODO: refactor to add more faucets to this processor: createGenericFaucetProcessor: function(wt) { let webType = wt; let countdownMinutes; let timeWaiting= 0; let selectElement = { rollButton: function() { switch (webType) { case WebType.FREELITECOIN: return document.getElementById('roll'); break; case WebType.FREEETHEREUMIO: return document.querySelector('#rollform button'); break; default: return; break; } }, balance: function() { switch (webType) { case WebType.FREELITECOIN: return document.getElementById('money'); break; case WebType.FREEETHEREUMIO: return document.getElementById('cryptovalue') break; default: return; break; } } }; function timedOut(addMs) { if (timeWaiting/1000 > shared.getConfig()['defaults.timeout'] * 60) { shared.closeWithError(ErrorType.TIMEOUT, ''); return true; } timeWaiting += addMs; return false; } function init() { let url = new URL(window.location.href); switch (webType) { case WebType.FREELITECOIN: if (url.pathname == '/') { run(); } else if (url.pathname.includes('/login')) { shared.closeWithError(ErrorType.NEED_TO_LOGIN, ''); } break; case WebType.FREEETHEREUMIO: if (url.pathname == '/free/') { run(); } else if (url.pathname == '/') { shared.closeWithError(ErrorType.NEED_TO_LOGIN, ''); } break; } return; } function run() { setTimeout(findCountdownOrRollButton, helpers.randomMs(12000, 15000)); }; function findCountdownOrRollButton() { if ( isCountdownVisible() ) { timeWaiting = 0; let countdownMinutes = document.getElementById('cislo1'); let result = {}; result.balance = readBalance(); result.nextRoll = helpers.addMinutes(new Date(), countdownMinutes.innerHTML.toString()); shared.closeWindow(result); return; } if ( isRollButtonVisible() ) { if (isHCaptchaVisible()) { waitForCaptcha(); } else { clickRoll(); } } else { setTimeout(findCountdownOrRollButton, helpers.randomMs(10000, 12000)); } }; function isCountdownVisible() { return $(document.getElementById('cislo1')).is(':visible') || $(document.getElementById('cislo2')).is(':visible'); }; function isHCaptchaVisible() { let hCaptchaFrame = document.querySelector('.h-captcha > iframe'); if (hCaptchaFrame && $(hCaptchaFrame).is(':visible')) { return true; } return false; }; function isRollButtonVisible() { let rollButton = selectElement.rollButton(); return rollButton && $(rollButton).is(':visible'); }; function waitForCaptcha() { if ( document.querySelector('.h-captcha > iframe').getAttribute('data-hcaptcha-response').length > 0) { clickRoll(); } else { if (timedOut(10000)) { return; } setTimeout(waitForCaptcha, helpers.randomMs(10000, 12000)); } }; function clickRoll() { try { shared.devlog('Clicking roll button'); selectElement.rollButton().click(); setTimeout(processRunDetails, helpers.randomMs(10000, 12000)); } catch (err) { shared.closeWithError(ErrorType.CLICK_ROLL_ERROR, err); } }; function processRunDetails() { let info = document.getElementById('info'); if (info && $(info).is(':visible')) { let result = {}; result.claimed = readClaimed(); result.balance = readBalance(); if(result.claimed != 0) { result.rolledNumber = readRolledNumber(); result.nextRoll = helpers.addMinutes(new Date(), "60"); } shared.closeWindow(result); return; } if (timedOut(5000)) { return; } setTimeout(processRunDetails, helpers.randomMs(5000, 6000)); }; function readRolledNumber() { let rolled = 0; try { rolled = parseInt(document.getElementById('numberroll').innerHTML); } catch { } return rolled; }; function readBalance() { let balance = 0; try { balance = selectElement.balance().innerHTML; } catch { } return balance; }; function readClaimed() { let claimed = 0; try { let info = document.getElementById('info').innerHTML; let idx = info.search(/0\./); claimed = parseFloat(info.slice(idx, idx + 10)); } catch { } return claimed; }; return { init: init }; }, createBagiKeranProcessor: function() { let timeWaiting= 0; let elements = { errorDivs: function() { return document.querySelectorAll('.alert.alert-danger'); }, warningDivs: function() { return document.querySelectorAll('.alert.alert-warning'); }, successDivs: function() { return document.querySelectorAll('.alert.alert-success'); }, errorCloudflare: function() { return document.querySelector('#cf-error-details p'); }, openLoginModalButton: function() { return document.getElementById('submit'); }, modal: function() { return document.querySelector('#myModal.show'); }, addressInput: function() { return document.querySelector('input[name="address"]'); }, submitButton: function() { return document.querySelector('#myModal button[type="submit"]'); }, openClaimModalButton: function() { return document.querySelector('form button[type="submit"]'); }, openWithdrawModal: function() { return document.getElementById('submit'); }, linkWithdrawMinNotReached: function() { return document.querySelector('a.btn.btn-primary.btn-block'); } }; function timedOut(addMs) { if (timeWaiting/1000 > shared.getConfig()['defaults.timeout'] * 60) { shared.closeWithError(ErrorType.TIMEOUT, ''); return true; } timeWaiting += addMs; return false; } function init() { if(shared.getCurrent().params.doSignOut) { // Unexpected behavior with BCH @ Bagi: seems it didn't login when the previous run was TRX/USDT so it saved the roll with that address and you couldn't withdraw: //Before you can receive payments at FaucetPay.io with this address you must link it to an account. Create an account at FaucetPay.io and link your address, then come back and claim again shared.devlog(`${window.location.href} signing out`); shared.getCurrent().params.doSignOut = false; shared.saveFlowControl(); window.location.href = (new URL('signout.php', window.location.href)).href;; return; } if (window.location.href.includes('captha.php')) { setTimeout(runCaptchaPage, helpers.randomMs(1000, 2000)); return; } else if (window.location.href.includes('withdraw.php')) { setTimeout(runWithdraw, helpers.randomMs(1000, 2000)); return; } else { setTimeout(run, helpers.randomMs(1000, 2000)); return; } } function run() { readAlerts(); processIndex(); }; function runCaptchaPage() { readAlerts(); shared.clearRetries(); processCaptchaPage(); } function runWithdraw() { readAlerts(); shared.clearRetries(); processWithdraw(); } function readAlerts() { let elm; elements.warningDivs().forEach(function (elem) { if (elem && elem.innerText.includes('already claimed')) { // "You have already claimed in the last 60 minutes.
You can claim again in 59 minutes.
" let result = {}; try { let mins = elem.innerText.split('\n')[1].replace(/\D/g, ''); result.nextRoll = helpers.addMinutes(new Date(), mins); } catch { result.nextRoll = helpers.addMinutes(new Date(), "60"); } if (shared.getCurrent().params.doWithdraw) { shared.updateWithoutClosing(result); window.location.href = (new URL('withdraw.php', window.location.href)).href; } else { shared.closeWindow(result); } return; } }); elements.successDivs().forEach(function (elem) { if (elem) { if (elem.innerText.includes('claimed successfully')) { // "You've claimed successfully 2 Satoshi BTC." ... let result = {}; result.nextRoll = helpers.addMinutes(new Date(), "60"); result.claimed = 0; try { let val = elem.innerText.split('\n')[0].replace(/\D/g, ''); if (typeof val == 'string') { val = +val; } if (Number.isInteger(val)) { val = val / 100000000; } result.claimed = val; } catch { } try { let mins = elem.innerText.split('\n')[1].replace(/\D/g, ''); result.nextRoll = helpers.addMinutes(new Date(), mins); } catch { } if (shared.getCurrent().params.doWithdraw) { shared.updateWithoutClosing(result); let link = elem.querySelector('a'); if (link && link.innerText.includes('withdraw')) { link.click(); return; } else { window.location.href = (new URL('withdraw.php', window.location.href)).href;; } } shared.closeWindow(result); return; } else if (elem.innerText.includes('was sent to')) { //2 satoshi was sent to your account at FaucetPay.io let result = {}; result.withdrawnAmount = 0; let val = elem.innerHTML.split(' ')[0]; if (typeof val == 'string') { val = +val; } if (Number.isInteger(val)) { val = val / 100000000; } result.withdrawnAmount = val; shared.closeWindow(result); return; } } }); elm = elements.errorCloudflare(); if (elm) { // "Access denied | bagi.co.in used Cloudflare to restrict access" @document.title shared.closeWithError(ErrorType.IP_RESTRICTED, document.title + ' | ' + elm.innerText); return; } elements.errorDivs().forEach(function (elem) { if (elem) { if (elem.innerText.toLowerCase().includes('vpn/proxy/tor')) { // "VPN/Proxy/Tor is not allowed on this faucet." ... shared.closeWithError(ErrorType.IP_ERROR, elem.innerText); return; } else if (elem.innerText.toLowerCase().includes('look valid')) { // The Bitcoin Address doesn't look valid //invalid address shared.closeWithError(ErrorType.ADDRESS_ERROR, elem.innerText); return; } else if (elem.innerText.toLowerCase().includes('login not valid')) { // Login Not Valid, Please reLogin // TODO: FIX => ITS NOT WORKING BECAUSE B/K REALOADS ITSELF TOO MANY TIMES // FORCE 1 RETRY as sometimes it might work if(shared.isRetrying()) { shared.devlog(`${window.location.href} login retry failed`); shared.closeWithError(ErrorType.LOGIN_ERROR, elem.innerText); } else { shared.devlog(`${window.location.href} will retry to login`); } return; } else if (elem.innerText.toLowerCase().includes('claim not valid')) { // Claim not Valid, Please reClaim. Try again // FORCE 1 RETRY if(shared.isRetrying()) { shared.devlog(`${window.location.href} claim retry failed`); shared.closeWithError(ErrorType.CLAIM_ERROR, elem.innerText); } else { shared.devlog(`${window.location.href} will retry to claim`); } return; } else { // Unknown issue shared.closeWithError(ErrorType.ERROR, elem.innerText); return; } } }); elm = elements.linkWithdrawMinNotReached(); if (elm) { if(elm.innerText.toLowerCase().includes('minimum withdraw')) { // Minimum Withdraw is ... shared.closeWithError(ErrorType.MIN_WITHDRAW_ERROR, elm.innerText); return; } } } function processIndex() { if (elements.modal() && elements.addressInput() && elements.submitButton()) { // 2. Fill address & click Login if(elements.addressInput().value != '') { shared.devlog('Clicking LOGIN'); elements.submitButton().click(); // shoud redirect but check for timeout } else { elements.addressInput().value = shared.getCurrent().params.address; } setTimeout(run, helpers.randomMs(2000, 4000)); return; } if (elements.openLoginModalButton()) { // 1. Click the Get Started Button elements.openLoginModalButton().click(); timeWaiting = 0; setTimeout(processIndex, helpers.randomMs(1000, 3000)); return; } if (elements.openClaimModalButton()) { // Claim Bitcoin Button elements.openClaimModalButton().click(); timeWaiting = 0; setTimeout(processIndex, helpers.randomMs(2000, 4000)); return; } setTimeout(run, helpers.randomMs(2000, 4000)); }; function processCaptchaPage() { if(elements.modal()) { setTimeout(waitForCaptcha, helpers.randomMs(2000, 4000)); return; } if (elements.openLoginModalButton()) { // 1. Click the Claim Button to open the modal w/the hCaptcha elements.openLoginModalButton().click(); timeWaiting = 0; setTimeout(processCaptchaPage, helpers.randomMs(1000, 3000)); return; } setTimeout(runCaptchaPage, helpers.randomMs(2000, 4000)); } function processWithdraw() { if(elements.modal()) { setTimeout(waitForCaptcha, helpers.randomMs(2000, 4000)); return; } if (elements.openWithdrawModal()) { // 1. Click the Withdraw to FaucetPay submit button to open the modal w/the hCaptcha elements.openWithdrawModal().click(); timeWaiting = 0; setTimeout(processWithdraw, helpers.randomMs(2000, 4000)); return; } setTimeout(runWithdraw, helpers.randomMs(2000, 4000)); } function waitForCaptcha() { let iframe = document.querySelector('.h-captcha > iframe'); if (!iframe) { iframe = document.querySelector('.g-recaptcha > iframe'); } if(iframe && iframe.getAttribute('data-hcaptcha-response').length > 0) { //claim after hCaptcha if(elements.submitButton()) { elements.submitButton().click(); // should redirect return; } } if (timedOut(5000)) { return; } setTimeout(waitForCaptcha, helpers.randomMs(5000, 6000)); }; return { init: init }; }, createOkFaucetProcessor: function() { let countdownMinutes; let timeWaiting= 0; let selectElement = { addressInput: function() { return document.querySelector('input[type="text"]'); }, rollButton: function() { return document.querySelector('input[type="submit"'); }, countdown: function() { // "You have to wait\n60 minutes" let successDivs = document.querySelectorAll(".alert.alert-success"); if(successDivs.length == 1 && successDivs[0].isVisible()) { return parseInt(successDivs[0].innerText.replace(/\D/g, '')); } return null; }, rolledNumber: function() { let successDivs = document.querySelectorAll(".alert.alert-success"); if(successDivs && successDivs.length > 1 && successDivs[0].isVisible()) { return parseInt(successDivs[0].innerText); } else { return null; } }, claimedAmount: function() { let successDivs = document.querySelectorAll(".alert.alert-success"); if(successDivs && successDivs.length > 1 && successDivs[0].isVisible()) { let val = parseInt(successDivs[1].innerText.replace(/\D/g, '')); if (Number.isInteger(val)) { val = val / 100000000; } return val; } else { return null; } }, error: function () { let errorDiv = document.querySelector(".alert.alert-danger"); if(errorDiv) { if (errorDiv.innerText.toLowerCase().includes('not have sufficient funds')) { shared.closeWithError(ErrorType.NO_FUNDS, errorDiv.innerText); } else { shared.closeWithError(ErrorType.ERROR, errorDiv.innerText); } } else { return null; } } }; function timedOut(addMs) { if (timeWaiting/1000 > shared.getConfig()['defaults.timeout'] * 60) { shared.closeWithError(ErrorType.TIMEOUT, ''); return true; } timeWaiting += addMs; return false; } function init() { run(); } function run() { try { setTimeout(findResultCountdownOrRollButton, helpers.randomMs(12000, 15000)); } catch (err) { shared.closeWithErrors(ErrorType.ERROR, err); } }; function findResultCountdownOrRollButton() { selectElement.error(); if ( selectElement.countdown() ) { shared.devlog(`Ok: countdown found`); timeWaiting = 0; let result = {}; result.nextRoll = helpers.addMinutes(new Date(), selectElement.countdown().toString()); shared.closeWindow(result); return; } if ( isRollButtonVisible() ) { startRoll(); return; } if (selectElement.claimedAmount()) { processRunDetails(); return; } setTimeout(findResultCountdownOrRollButton, helpers.randomMs(10000, 12000)); }; function startRoll() { shared.devlog(`Ok: rollbutton found`); let addressInput = selectElement.addressInput(); if (addressInput && addressInput.value != shared.getCurrent().params.address) { addressInput.value = shared.getCurrent().params.address; shared.devlog(`Ok: address filled`); } if (isHCaptchaVisible()) { waitForCaptcha(); } }; function isHCaptchaVisible() { let hCaptchaFrame = document.querySelector('.h-captcha > iframe'); if (hCaptchaFrame && hCaptchaFrame.isVisible()) { return true; } return false; }; function isRollButtonVisible() { let rollButton = selectElement.rollButton(); return rollButton && rollButton.isVisible(); }; function waitForCaptcha() { if ( document.querySelector('.h-captcha > iframe').getAttribute('data-hcaptcha-response').length > 0) { clickRoll(); } else { if (timedOut(10000)) { return; } setTimeout(waitForCaptcha, helpers.randomMs(10000, 12000)); } }; function clickRoll() { try { shared.devlog('Clicking roll button'); selectElement.rollButton().click(); return; } catch (err) { shared.closeWithError(ErrorType.CLICK_ROLL_ERROR, err); } }; function processRunDetails() { shared.devlog(`Ok: claimedAmount found`); let claimedAmount = selectElement.claimedAmount(); let rolledNumber = selectElement.rolledNumber(); if (claimedAmount && rolledNumber) { let result = {}; result.claimed = claimedAmount; result.rolledNumber = rolledNumber; result.nextRoll = helpers.addMinutes(new Date(), "60"); shared.closeWindow(result); return; } if (timedOut(5000)) { return; } setTimeout(processRunDetails, helpers.randomMs(5000, 6000)); }; return { init: init }; }, createBigBtcProcessor: function() { let countdownMinutes; let timeWaiting= 0; let selectElement = { loadingDiv: function() { let loading = document.querySelector('#loading'); if (loading && loading.isVisible()) { return true; } else { return false; } }, addressInput: function() { return document.querySelector('#login input[name="address"]'); }, loginButton: function() { return document.querySelector('#login input[type="submit"]'); }, claimButton: function() { return document.getElementById('claimbutn'); }, countdown: function() { // "You have to wait\n60 minutes" let cd = document.getElementById('countdown'); if(cd && cd.isVisible()) { return parseInt(cd.innerText); } return null; }, claimedAmount: function() { let elm = document.querySelector('.alert.alert-success.pulse'); //"Yuppie! You won 2 satoshi!" if(elm && elm.isVisible()) { let val = parseInt(elm.innerText.replace(/\D/g, '')); if (Number.isInteger(val)) { val = val / 100000000; } return val; } else { return null; } }, balance: function() { let elm = document.querySelector('a b'); if (elm && elm.isVisible()) { let val = parseInt(elm.innerText); if (Number.isInteger(val)) { val = val / 100000000; } return val; } else { return null; } }, error: function () { return null; } }; function timedOut(addMs) { if (timeWaiting/1000 > shared.getConfig()['defaults.timeout'] * 60) { shared.closeWithError(ErrorType.TIMEOUT, ''); return true; } timeWaiting += addMs; return false; } function init() { if (window.location.href.includes('/faucet')) { setTimeout(runFaucet, helpers.randomMs(12000, 14000)); return; } else { setTimeout(run, helpers.randomMs(3000, 5000)); return; } } function run() { try { setTimeout(waitIfLoading, helpers.randomMs(12000, 15000)); } catch (err) { shared.closeWithErrors(ErrorType.ERROR, err); } }; function doLogin() { let address = selectElement.addressInput(); if(address && address.value != shared.getCurrent().params.address) { address.value = shared.getCurrent().params.address; } else { selectElement.loginButton().click(); return; } setTimeout( doLogin , helpers.randomMs(1000, 2000)); }; function waitIfLoading() { if ( !selectElement.loadingDiv() ) { shared.devlog(`BigBtc: doing log in`); doLogin(); return; } else { shared.devlog(`BigBtc: waiting for login form`); if (timedOut(10000)) { return; } } setTimeout(waitIfLoading, helpers.randomMs(5000, 7000)); }; function runFaucet() { let claimedAmount = selectElement.claimedAmount(); if(claimedAmount) { processRunDetails(); return; } else if (selectElement.countdown()) { // need to wait let result = {}; result.nextRoll = helpers.addMinutes(new Date(), shared.getConfig()['defaults.postponeMinutes']); shared.closeWindow(result); } else { shared.devlog(`BigBtc: waiting for captcha`); setTimeout(waitForCaptcha, helpers.randomMs(4000, 8000)); } } function waitForCaptcha() { if ( document.querySelector('.h-captcha > iframe').getAttribute('data-hcaptcha-response').length > 0) { clickClaim(); } else { if (timedOut(10000)) { return; } setTimeout(waitForCaptcha, helpers.randomMs(10000, 12000)); } }; function clickClaim() { try { shared.devlog('Clicking roll button'); selectElement.claimButton().click(); return; } catch (err) { shared.closeWithError(ErrorType.CLICK_ROLL_ERROR, err); } }; function processRunDetails() { shared.devlog(`BigBtc: processing results`); let claimedAmount = selectElement.claimedAmount(); let balance = selectElement.balance(); let countdown = selectElement.countdown(); if (claimedAmount && balance) { let result = {}; result.claimed = claimedAmount; result.balance = balance; result.nextRoll = helpers.addMinutes(new Date(), shared.getConfig()['defaults.postponeMinutes']); shared.closeWindow(result); return; } if (timedOut(5000)) { return; } setTimeout(processRunDetails, helpers.randomMs(5000, 6000)); }; return { init: init }; } }; function overrideSelectNativeJS_Functions () { window.alert = function alert (message) { console.log (message); } } function addJS_Node (text, s_URL, funcToRun) { var scriptNode= document.createElement ('script'); scriptNode.type= "text/javascript"; if (text)scriptNode.textContent= text; if (s_URL)scriptNode.src= s_URL; if (funcToRun)scriptNode.textContent = '(' + funcToRun.toString() + ')()'; var element = document.getElementsByTagName ('head')[0] || document.body || document.documentElement; element.appendChild (scriptNode); } function detectWeb() { if(!shared.isOpenedByManager()) { shared.devlog(`${window.location.href} dismissed`); return; } shared.devlog(`${window.location.href} accepted`); let typeFromManager = shared.getCurrent().type; timer = new Timer(false, 10, typeFromManager); switch( typeFromManager ) { case WebType.STORMGAIN: SiteProcessor = objectGenerator.createSGProcessor(); setTimeout(SiteProcessor.run, helpers.randomMs(10000, 20000)); break; case WebType.CRYPTOSFAUCETS: SiteProcessor = objectGenerator.createCFProcessor(); setTimeout(SiteProcessor.init, helpers.randomMs(1000, 3000)); break; case WebType.FREEBITCOIN: SiteProcessor = objectGenerator.createFBProcessor(); setTimeout(SiteProcessor.run, helpers.randomMs(2000, 5000)); break; case WebType.FREELITECOIN: case WebType.FREEETHEREUMIO: SiteProcessor = objectGenerator.createGenericFaucetProcessor(typeFromManager); setTimeout(SiteProcessor.init, helpers.randomMs(2000, 5000)); break; case WebType.BAGIKERAN: SiteProcessor = objectGenerator.createBagiKeranProcessor(); setTimeout(SiteProcessor.init, helpers.randomMs(8000, 12000)); break; case WebType.FAUCETPAY: SiteProcessor = objectGenerator.createFPProcessor(); setTimeout(SiteProcessor.init, helpers.randomMs(2000, 5000)); break; case WebType.OKFAUCET: SiteProcessor = objectGenerator.createOkFaucetProcessor(); setTimeout(SiteProcessor.init, helpers.randomMs(4000, 6000)); break; case WebType.BIGBTC: SiteProcessor = objectGenerator.createBigBtcProcessor(); setTimeout(SiteProcessor.init, helpers.randomMs(4000, 6000)); break; default: break; } } class Timer { constructor(isManager, delaySeconds, webType) { if(!useTimer || (webType && !Timer.webTypes().includes(webType))) { return; } this.delay = delaySeconds * 1000; if(!isManager) { this.tick(); this.interval = setInterval( () => { this.tick() }, this.delay); } } static webTypes() { return [WebType.FREELITECOIN, WebType.FREEETHEREUMIO, WebType.BAGIKERAN, WebType.BIGBTC] }; startCheck(webType) { if(!useTimer || (webType && !Timer.webTypes().includes(webType))) { return; } persistence.save('lastAccess', Date.now()); this.interval = setInterval( () => { this.isAlive() }, this.delay); } stopCheck() { if(!useTimer) { return; } clearInterval(timer.interval); } tick() { if(!useTimer) { return; } persistence.save('lastAccess', Date.now()); } isAlive() { if(!useTimer) { return; } let now = Date.now(); let newAccess = persistence.load('lastAccess'); if(newAccess && (now - newAccess > this.delay)) { //Close working tab and force restart shared.devlog(`Timer is closing the working tab`); shared.addError(ErrorType.FORCE_CLOSED, 'Site was unresponsive or redirected'); manager.closeWorkingTab(); } } } let timer; let useTimer = false; // ENABLE/DISABLE TIMER HERE function init() { persistence = objectGenerator.createPersistence(); shared = objectGenerator.createShared(); if(window.location.host === 'satology.onrender.com') { timer = new Timer(true, 30); shared.devlog('Manager Reloaded'); manager = objectGenerator.createManager(); CFPromotions = objectGenerator.createCFPromotions(); ui = objectGenerator.createUi(); CFHistory = objectGenerator.createCFHistory(); manager.init(); } else { detectWeb(); } } init(); })();