// ==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, LINK, LTC, NEO, STEAM, TRX, USDC, USDT, XEM, XRP, ZEC // @version 1.5.3 // @author satology // @namespace satology.onrender.com // @homepage https://satology.onrender.com/faucets/referrals // @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 AND // @note to roll Free-ethereum.io you need to add the following two lines to hCaptcha Solver script, right at the beginning of function getSynonyms(word) [line 232 on version 3.5]: // @note const WORDS_WITH_CYRILLIC = {'TBD': 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 - LAST UPDATES ---------------------------------------------------------------------------------------------------------------------------------------------------------------- // @note [@1.5.3] BUG Fixed: Timeout wasn't triggering if Keran/Bagi withdraw failed due to an Ad redirect. // @note [@1.5.1] BUG Fixed: sometimes new faucets weren't claiming due to URL error. // @note [@1.5 BETA RELEASE] Added Wallet to fill with your FaucetPay addresses [from the UI], promo codes suggestions [reusables] and Bagi & Keran faucets // @note Please don't activate ALL of the bagi/keran faucets. Consider the time it takes to roll them. This is a beta release as some modifications // @note will be added: needs refactor, might add priority to make sure certain faucets are rolled when available, etc. // @note Withdraw options: never, after each claim or every X hours (default). Can be configured @config var // @note Aggregate holds the sats you have at Keran/Bagi. Balance will accumulate the amount you withdraw to Faucet Pay. // @note You will see badges (timeouts/errors). Please don't report them unless they are labeled as 'ERROR'. // @note Faucets have referral links which are randomize. It has my ref links and of some users who have contributed with the // @note coding (thanks nat & karl) // @note [@1.4.0] Added Free-Litecoin.com & Free-Ethereum.io // @note [IMPORTANT 1]: Free-Ethereum.io has an annoying issue in the hCaptcha (at least on my end). Here's the problem and my way of 'fixing' it: // @note > Problem: The hCaptcha (despite being in English) displays what you need to look for with a character of the cyrillic unicode table // @note in the word. For example: instead of train, it says trаin. Looks the same, but it's not. The 'a' is different. // @note (CTRL+F and look for train and you'll see it won't match the latter. So this makes the hCaptcha Solver script fail. // @note > Solution/Workaround: Add the following 2 lines to the hCaptcha script, right after function getSynonyms(word) { // @note const WORDS_WITH_CYRILLIC = {'TBD': 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 As you can see, I couldn't get an AIRPLANE, so I don't know which character is replaced in that word. You can come up with a more solid // @note solution and share it. This is enough for me for now. It maps the word with the special character to the correct word. // @note [IMPORTANT 2]: Free-Ethereum.io is flagged as a phishing site by MetaMask. So you can just not use it or use it at your own risk as I do. // @note Just remember that if you use it, at least the first time after reopening Chrome, you'll get the MetaMask warning and you have to // @note bypass/'accept the risk' manually. Just in case, use a unique password for that site. // @note [@1.3] Added FaucetPay PTC. It runs on focus every 5 hs aprox (set by hoursBetweenRuns in config) // @note [@1.2] UI Changes // @note [@1.1] Added Freebitco.in and autologin for @cryptosfaucets // @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 config object 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_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://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/* // @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 }; 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 }; //TODO: add to UI let config = { defaults: { timeout: 4, // Use -1 to disable the timeout functionality. In minutes. Max time the monitor will wait for a result/roll. // After timeout is reached, the Manager/Monitor will assume something is wrong // (usually faucet tab being accidentally closed or failed to connect) postponeMinutes: 65, // Minutes to wait before retrying a faucet that timed out focusTab: false // If false the faucets will be opened in the background }, cf: { autologin: false, credentials: { mode: 1, // POSSIBLE VALUES: // 1: Use email/password saved through the script // 2: Waits for the credentials to be added manually or by a third party software/extension. // Useful if you use different email/password combinations on each faucet email: 'YOUR@EMAIL.com', password: 'YOURPASSWORD' } }, fb: { // FreeBitco.in activateRPBonus: false // will try to activate the highest RP Roll Bonus available for the account (100, 50 25, ... points per roll), }, fp: { // FaucetPay.io hoursBetweenRuns: 5, // how many hours to wait between each FaucetPay PTC run maxTimeInMinutes: 10, // max time it will stay working on each run }, bagikeran: { // Bagi.co.in & keran.co withdrawMode: 1, // POSSIBLE VALUES: // 0: Disables auto withdraw // 1: Withdraws once every 'hoursBetweenWithdraws' hours // 2: Withdraw after each successful claim hoursBetweenWithdraws: 6 } } // let persistence, shared, manager, ui, CFPromotions, interactions, SGProcessor, CFProcessor, CFHistory, FBProcessor, FPProcessor, FreeLitecoinProcessor, FreeGenericFaucetProcessor; let persistence, shared, manager, ui, CFPromotions, interactions, CFHistory, SiteProcessor; let helpers = { cleanString: function(input) { var output = ""; for (var i=0; i enm[key] === value); }, 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); }, addMilliseconds: function(date, ms) { return date.setMilliseconds(date.getMilliseconds() + ms); }, getRandomMillisecondsFromMinutesRange(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; function devlog(value) { let log; if(value) { log = persistence.load('devlog', true); log = log ?? []; log.push(value); } else { log = []; } persistence.save('devlog', log, true); }; function isOpenedByManager(currentHost) { loadFlowControl(); if(!flowControl) { return false; } let millisecondsDistance = new Date() - flowControl.requestedTime; if((flowControl.type != WebType.FAUCETPAY && flowControl.type != WebType.BAGIKERAN && flowControl.opened) || (flowControl.host != currentHost && !flowControl.expectedHosts.includes(currentHost)) || millisecondsDistance > 120000) { return false; } return true; }; function setFlowControl(id, url, webType, expectedHosts, params = null) { flowControl = { id: id, url: url, host: url.host, type: webType, requestedTime: new Date(), opened: false, expectedHosts: expectedHosts, error: false, result: {} }; if(params) { flowControl.params = params; } persistence.save('flowControl', flowControl, true); }; 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() { let current = {}; current.url = flowControl.url; current.host = flowControl.host; current.type = flowControl.type; if(flowControl.params) { current.params = flowControl.params; } return current; }; function saveAndclose(runDetails, delay = 0) { markAsVisited(runDetails); if(delay) { setTimeout(window.close, delay); } else { window.close(); } }; function loadFlowControl() { flowControl = persistence.load('flowControl', true); }; function markAsVisited(runDetails) { flowControl.opened = true; flowControl.result = runDetails; persistence.save('flowControl', flowControl, true); }; function closeWithError(errorType, errorMessage) { flowControl.error = true; flowControl.result.errorType = errorType; flowControl.result.errorMessage = errorMessage; persistence.save('flowControl', flowControl, true); window.close(); }; function clearFlowControl() { flowControl = {}; persistence.save('flowControl', flowControl, true); }; return { devlog: devlog, setFlowControl: setFlowControl, wasVisited: wasVisited, isOpenedByManager: isOpenedByManager, getCurrent: getCurrent, getResult: getResult, closeWindow: saveAndclose, closeWithError: closeWithError, updateWithoutClosing: markAsVisited, hasErrors: hasErrors, clearFlowControl: clearFlowControl }; }, 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=11748', '?ref=18976', '?ref=12487'], type: WebType.BAGIKERAN } ]; 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].focusTab = (element.id == '18' ? true : 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].focusTab = element.focusTab ?? webList[idx].focusTab; } }); } else { // helpers.shuffle(webList); } }; 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 = new Date().getTime(); persistence.save('timestamp', timestamp); }; function removeDisabledFaucets() { webList = webList.filter(x => x.enabled); }; return { initialize: initialize }; }(); function readUpdateValues(forceCheck = false) { readPromoCodeValues(); if(status == STATUS.IDLE || forceCheck) { let updateDataElement = $('#update-data')[0]; let updateValues = helpers.cleanString(updateDataElement.innerText); 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, idx, arr) { 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}`); } }); $('#faucets-display-status')[0].innerHTML = ''; ui.refresh(null, null, userWallet); saveUserWallet(); } if(updateObj.runAsap.changed || updateObj.editSingle.changed) { $('#faucets-display-status')[0].innerHTML = ''; update(true); process(); return; } } } if(forceCheck) { process(); } }; 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; } 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() < (new Date()).getTime()) { ui.log(`Opening ${webList[0].name}`); clearTimeout(processTimer); status = STATUS.CLAIMING; open(); } else { let timeUntilNext = webList[0].nextRoll.getTime() - (new Date()).getTime() + helpers.randomMs(1000, 2000); 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 expectedHosts = []; expectedHosts.push(navUrl.host); if(webList[0].type == WebType.STORMGAIN) { expectedHosts.push((new URL('https://www.google.com').host)); expectedHosts.push((new URL('https://www.recaptcha.net').host)); } let params = {}; if(webList[0].type == WebType.BAGIKERAN) { //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 } params.doWithdraw = getDoWithdraw(webList[0].lastWithdraw); } shared.setFlowControl(webList[0].id, navUrl, webList[0].type, expectedHosts, params); setTimeout(manager.resultReader, 15000); // Try to close old workingTab if still opened if (workingTab && !workingTab.closed) { try { workingTab.close(); } catch { } } workingTab = GM_openInTab(navUrl.href, { active: ((!webList[0].focusTab || webList[0].focusTab == USE_DEFAULT) ? config.defaults.focusTab : webList[0].focusTab) }); } catch(err) { ui.log(`Error opening tab: ${err}`) } }; function getDoWithdraw(lastWithdraw) { switch (config.bagikeran.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(config.bagikeran.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(config.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; } 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: ${webList[0].stats.errors.errorType} ${webList[0].stats.errors.errorMessage}`); } 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 moveNext() { let millisecondsDelay = helpers.getRandomMillisecondsFromMinutesRange(config.defaults.postponeMinutes, 5); webList[0].nextRoll = new Date(helpers.addMilliseconds(new Date(), millisecondsDelay)); shared.clearFlowControl(); update(true); timeWaiting = 0; readUpdateValues(true); } function hasTimedOut() { return config.defaults.timeout != -1 && (timeWaiting > (config.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 = 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 = $('#promo-code-new')[0]; let promoDataStr = helpers.cleanString(promoCodeElement.innerText); let promoDisplayStatus = $('#promo-display-status')[0]; 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 = ''; $('#promo-text-input').val(''); 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 = $('#rolls-span')[0]; 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; }; return{ init:start, process: process, resultReader: resultReader, getFaucetsForPromotion: getCFlist, readPromoCodeValues: readPromoCodeValues }; }, createUi: function() { let logLines = ['', '', '', '', '']; function init(cfFaucets) { appendCSS(); appendJavaScript(); appendHtml(); createPromoTable(cfFaucets); document.querySelector('.page-title h1').innerHTML = 'Auto Claim'; }; function appendCSS() { let css = ''; $('head').append(css); }; function appendJavaScript() { let js = ''; js += ''; $('head').append(js); }; function appendHtml() { let 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() ); }; 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 += `${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 refresh(scheduleData, promotionData, walletData) { if (scheduleData) { loadScheduleTable(scheduleData); } if (promotionData) { loadPromotionTable(promotionData); } if (walletData) { loadWalletTable(walletData); } }; function log(msg, elapsed = false) { 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) { return true; } else { return false; } return (timerSpans.length === 0); }; function activateMiner() { const activateButton = document.querySelector('.mb-8 .wrapper button'); if (activateButton) { activateButton.click(); setTimeout(processRunDetails, helpers.randomMs(10000, 20000)); } else { if(!is404Error()) { processRunDetails() } } }; function is404Error() { const h1 = document.getElementsByTagName('h1'); if (h1.length > 0 && h1[0].innerText.includes('404')) { window.location.reload(); return true; } return false; } 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(':'); if(timeLeft.length === 3) { mins = parseInt(timeLeft[0]) * 60 + parseInt(timeLeft[1]); } } catch (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 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) { $('#process-status')[0].innerHTML = 'Interacting'; timeWaiting = 0; interact(); } else { timeWaiting = -1; $('#process-status')[0].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 > config.defaults.timeout * 60) { shared.closeWithError('TIMEOUT', ''); return; } timeWaiting += 3000; setTimeout(findCountdownOrRollButton, helpers.randomMs(2000, 5000)); } }; function findLoginForm() { if ( $('div.login-wrapper').is(':visible') ) { //Other possible error is if recaptcha did not load yet... so maybe wait til the web is fully loaded for low connection issues if( $('.login-wrapper .error').length > 0 && $('.login-wrapper .error')[0].innerHTML != '') { let errorMessage = $('.login-wrapper .error').text(); shared.closeWithError('LOGIN_ERROR', errorMessage); return; } if(!loopingForErrors) { if(config.cf.credentials.mode == 1) { timeWaiting = 0; $('.login-wrapper input[name="email"]').val(config.cf.credentials.email); $('.login-wrapper input[name="password"]').val(config.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 > (config.defaults.timeout / 1.5) * 60) { shared.closeWithError('LOGIN_ERROR', 'No credentials were provided'); return; } } } } } if (timeWaiting/1000 > config.defaults.timeout * 60) { shared.closeWithError('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 { run: run, runPromotion: runPromotion, findPromotionTag: findPromotionTag, waitInteractions: waitInteractions, isFullyLoaded: isFullyLoaded, doLogin: doLogin }; }, 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 > config.defaults.timeout * 60) { shared.closeWithError('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 (config.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('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('ROLL_ERROR', $('.free_play_result_error')[0].innerHTML); return; } if($('#free_play_error').is(':visible')) { shared.closeWithError('ROLL_ERROR', $('.free_play_error')[0].innerHTML); return; } if ($(document.getElementById('same_ip_error')).is(':visible')) { shared.closeWithError('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 > config.defaults.timeout * 60) { shared.closeWithError('TIMEOUT', ''); return true; } timeWaiting += addMs; return false; } 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.addMilliseconds(new Date(), helpers.getRandomMillisecondsFromMinutesRange(config.fp.hoursBetweenRuns * 60, 2)); // Wait hoursBetweenRuns +/- 1% shared.updateWithoutClosing(result); } catch { } } } if ($('b:contains("Whoops!")').length) { result = shared.getResult(); result.nextRoll = helpers.addMilliseconds(new Date(), helpers.getRandomMillisecondsFromMinutesRange(config.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 (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(config.defaults.timeout)); } return { ptcList: ptcList, ptcSingle: ptcSingle }; }, // 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 > config.defaults.timeout * 60) { shared.closeWithError('TIMEOUT', ''); return true; } timeWaiting += addMs; return false; } 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 { selectElement.rollButton().click(); setTimeout(processRunDetails, helpers.randomMs(10000, 12000)); } catch (err) { shared.closeWithError('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 { run: run }; }, 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 > config.defaults.timeout * 60) { shared.closeWithError('TIMEOUT', ''); return true; } timeWaiting += addMs; return false; } function run() { readAlerts(); processIndex(); // setTimeout(processIndex, helpers.randomMs(1000, 3000)); }; function runCaptchaPage() { readAlerts(); processCaptchaPage(); // setTimeout(processCaptchaPage, helpers.randomMs(1000, 3000)); } function runWithdraw() { readAlerts(); processWithdraw(); // setTimeout(processWithdraw, helpers.randomMs(1000, 3000)); } 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('IP RESTRICTED', document.title + ' | ' + elm.innerText); return; } elements.errorDivs().forEach(function (elem) { if (elem) { if (elem.innerText.includes('VPN/Proxy/Tor')) { // "VPN/Proxy/Tor is not allowed on this faucet." ... shared.closeWithError('IP ERROR', elem.innerText); return; } else if (elem.innerText.includes('Claim not valid')) { // Claim not Valid, Please reClaim. Try again //might be a hcaptcha timeout (old hcaptcha solution). Maybe retry at least once shared.closeWithError('INVALID CLAIM', elem.innerText); return; } else if (elem.innerText.includes('look valid')) { // The Bitcoin Address doesn't look valid //invalid address shared.closeWithError('INVALID ADDRESS', elem.innerText); return; } else if (elem.innerText.includes('Login Not Valid')) { // Login Not Valid, Please reLogin // might be a login timeout (hCaptcha taking too long) shared.closeWithError('LOGIN TIMEOUT', elem.innerText); return; } else if (elem.innerText.includes('Claim Not Valid')) { // Claim not Valid, Please reClaim. Try again // might be a claim timeout (hCaptcha taking too long) shared.closeWithError('CLAIM TIMEOUT', elem.innerText); return; } else { // Unknown issue shared.closeWithError('ERROR', elem.innerText); return; } } }); } function processIndex() { if (elements.modal() && elements.addressInput() && elements.submitButton()) { // 2. Fill address & click Login elements.addressInput().value = shared.getCurrent().params.address; elements.submitButton().click(); // shoud redirect but check for timeout 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() { //weird 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 { run: run, runCaptchaPage: runCaptchaPage, runWithdraw: runWithdraw }; }, }; /** * Prevents alert popups to be able to reload the faucet if invisible captcha validation fails */ 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() { // TODO: Review for bagi/keran as it should consider the path too if(!shared.isOpenedByManager(window.location.host)) { return; } let currentFromManager = shared.getCurrent(); if (currentFromManager.type == WebType.STORMGAIN) { SiteProcessor = objectGenerator.createSGProcessor(); setTimeout(SiteProcessor.run, helpers.randomMs(10000, 20000)); return; } if (currentFromManager.type == WebType.CRYPTOSFAUCETS) { let expectedCfUrlType = helpers.cf.getUrlType(currentFromManager.url); let realCfUrlType = helpers.cf.getUrlType(window.location.href); switch(expectedCfUrlType) { case CFUrlType.FREE: switch(realCfUrlType) { 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); SiteProcessor = objectGenerator.createCFProcessor(); interactions = objectGenerator.createInteractions(); setTimeout(SiteProcessor.run, helpers.randomMs(1000, 3000)); break; case CFUrlType.CONTACTTWITTER: //TODO: mark as possibly banned break; case CFUrlType.HOME: if (config.cf.autologin) { addJS_Node (null, null, overrideSelectNativeJS_Functions); SiteProcessor = objectGenerator.createCFProcessor(); setTimeout(SiteProcessor.doLogin, helpers.randomMs(1000, 3000)); } else { shared.closeWithError('NEED_TO_LOGIN', ''); } break; default: break; } break; case CFUrlType.PROMOTION: SiteProcessor = objectGenerator.createCFProcessor(); interactions = objectGenerator.createInteractions(); setTimeout(SiteProcessor.runPromotion, helpers.randomMs(5000, 10000)); break; } return; } if (currentFromManager.type == WebType.FREEBITCOIN) { SiteProcessor = objectGenerator.createFBProcessor(); setTimeout(SiteProcessor.run, helpers.randomMs(2000, 5000)); return; } if (currentFromManager.type == WebType.FREELITECOIN) { SiteProcessor = objectGenerator.createGenericFaucetProcessor(currentFromManager.type); let url = new URL(window.location.href); if (url.pathname == '/') { setTimeout(SiteProcessor.run, helpers.randomMs(2000, 5000)); } else if (url.pathname.includes('/login')) { shared.closeWithError('NEED_TO_LOGIN', ''); } return; } if (currentFromManager.type == WebType.FREEETHEREUMIO) { SiteProcessor = objectGenerator.createGenericFaucetProcessor(currentFromManager.type); let url = new URL(window.location.href); if (url.pathname == '/free/') { setTimeout(SiteProcessor.run(), helpers.randomMs(2000, 5000)); } else if (url.pathname == '/') { shared.closeWithError('NEED_TO_LOGIN', ''); } return; } if (currentFromManager.type == WebType.BAGIKERAN) { SiteProcessor = objectGenerator.createBagiKeranProcessor(); let url = new URL(window.location.href); if (url.href.includes('captha.php')) { setTimeout(SiteProcessor.runCaptchaPage, helpers.randomMs(8000, 12000)); return; } else if (url.href.includes('withdraw.php')) { setTimeout(SiteProcessor.runWithdraw, helpers.randomMs(8000, 12000)); return; } else { setTimeout(SiteProcessor.run, helpers.randomMs(8000, 12000)); return; } return; } if (currentFromManager.type == WebType.FAUCETPAY) { SiteProcessor = objectGenerator.createFPProcessor(); let url = new URL(window.location.href); if(url.pathname.includes('ptc/view')) { setTimeout(SiteProcessor.ptcSingle, helpers.randomMs(2000, 5000)); } else if (url.pathname.includes('ptc')) { setTimeout(SiteProcessor.ptcList, helpers.randomMs(2000, 5000)); // } else if (url.pathname.includes('page/user-admin')) { // // Try to claim Reward Points } else if (url.href.includes('account/login')) { shared.closeWithError('NEED_TO_LOGIN', ''); } return; } } function init() { shared = objectGenerator.createShared(); persistence = objectGenerator.createPersistence(); if(window.location.host === 'satology.onrender.com') { manager = objectGenerator.createManager(); CFPromotions = objectGenerator.createCFPromotions(); ui = objectGenerator.createUi(); CFHistory = objectGenerator.createCFHistory(); manager.init(); } else { detectWeb(); } } init(); })();