// ==UserScript== // @name [satology] Auto Claim Multiple Faucets with Monitor UI // @description Automatic rolls and claims for 50+ crypto faucets/PTC/miners (Freebitco.in BTC, auto promo code for 15 CryptosFaucet, FaucetPay, StormGain, etc) // @description Claim free ADA, BNB, BCH, BTC, DASH, DGB, DOGE, ETH, FEY, LINK, LTC, NEO, STEAM, TRX, USDC, USDT, XEM, XRP, ZEC // @version 1.8.2 // @author satology // @namespace satology.onrender.com // @homepage https://satology.onrender.com/faucets/referrals // @note @1.8.2 : Added Dutchy faucets: monthly coin (now is TRX) and DUTCHY (used as 'energy' at their autofaucet) // @note > At Dutchy, you need to set hCaptcha as default captcha. Once in a while it uses the text hCaptcha some it might timeout/take longer // @note > Adjustments to OurBitco process: checking faucets countdowns at dashboard to avoid opening all faucets when possible // @note > UI adjustments: added some single-faucet customization (overrides default values as open in background, timeout) More will be added // @note @1.8: Added OurBitco, BetFury BNB/BTC boxes, Free-doge.io // @note > Ourbitco & BetFury are set to run every 30 min aprox. These values are hardcoded/not editable through the UI yet // @note > Ourbitco rolls are done by solving the image captcha (not the recaptcha) // @note @1.7.4 : > Ok BCH removed/commented out as the site structure changed [0 mins wait but 1 to 10 sat payment] // @note > Some minor changes in Bagi/Keran to handle Cloudflare hCaptcha validation // @note > Bagi/Keran default/suggested withdraw mode => off/manual // @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 ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- // @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 // @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/* // @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/* // @match https://www.bestchange.com/* // @match https://bitking.biz/* // @match https://litking.biz/* // @match https://faucetok.net/* // @match https://ourbitco.in/dashboard* // @match https://betfury.io/boxes/all* // @match https://www.free-doge.io/ // @match https://www.free-doge.io/free/ // @match https://autofaucet.dutchycorp.space/roll.php // @match https://autofaucet.dutchycorp.space/coin_roll.php // @downloadURL none // ==/UserScript== (function() { 'use strict'; /*// nop@require https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js */ /** * 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 K = Object.freeze({ WebType: { CRYPTOSFAUCETS: 1, STORMGAIN: 2, FREEBITCOIN: 3, FAUCETPAY: 4, FREELITECOIN: 5, FREEETHEREUMIO: 6, BAGIKERAN: 7, OKFAUCET: 8, BIGBTC: 9, BESTCHANGE: 10, KINGBIZ: 11, OURBITCOIN: 12, BETFURYBOX: 13, FREEDOGEIO: 14, DUTCHYROLL: 15 }, CF: { UrlType: { HOME: 0, FREE: 1, CONTACTTWITTER: 2, PROMOTION: 3, STATS: 4, SETTINGS: 5, FREEROLLS: 6, IGNORE: 99 }, PromoStatus: { NOCODE: 0, PENDING: 1, ACCEPTED: 2, USEDBEFORE: 3, INVALID: 4, UNKNOWNERROR: 5, EXPIRED: 6 }, ReusableCodeSuggestions: ['55khv20st4', '90nq6mcmz2', 'lytovoap04', 'vmuph8j0c6', 'ykxlvmg9ja', 'd8fmqxjlma', 'rjnmzjs673'] }, RandomInteractionLevel: { NONE: 0, LOW: 1, MEDIUM: 2, HIGH: 3 }, Integers: { HS_26_IN_MILLISECONDS: 93600000, //Using 26 hs instead of 24hs HS_2_IN_MILLISECONDS: 7200000 //and 2hs gap retry when code is flagged as USEDBEFORE }, Use_Default: -1, 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, BTC: 1, LTC: 2 }, 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, VERIFY_EMAIL: 14, NO_ADDRESS: 15 }, CMC: { BTC: '1', BNB: '1839' } }); let persistence, shared, manager, ui, CFPromotions, interactions, CFHistory, SiteProcessor; Element.prototype.isVisible = function() { return !!(this.offsetWidth||this.offsetHeight||this.getClientRects().length); }; Element.prototype.isUserFriendly = function(selector) { let e = selector ? this.querySelector(selector) : this; return e && e.isVisible() ? e : null; }; HTMLDocument.prototype.isUserFriendly = Element.prototype.isUserFriendly; 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: function(minute, rangeDiffInPercentage) { // Now will be a random value between minute and minute + rangeDiffPercentage%; Example if minute = 30 and rangeDiffPercentage = 5 => random in the range [30, 31.5] const msMin = minute * 60 * 1000; const msMax = msMin + rangeDiffInPercentage/100 * msMin; return helpers.randomMs(msMin, msMax); }, hsToMs: function(hours) { return hours * 60 * 60 * 1000; }, minToMs: function(min) { return min * 60 * 1000; }, getEmojiForPromoStatus: function(promoStatus) { switch (promoStatus) { case K.CF.PromoStatus.NOCODE: return '⚪'; break; case K.CF.PromoStatus.PENDING: return '⏳'; break; case K.CF.PromoStatus.ACCEPTED: return '✔️'; break; case K.CF.PromoStatus.USEDBEFORE: return '🕙'; break; case K.CF.PromoStatus.INVALID: return '❌'; break; case K.CF.PromoStatus.EXPIRED: return '📅'; break; case K.CF.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 K.CF.UrlType.FREE; } if (url.includes('/promotion/')) { return K.CF.UrlType.PROMOTION; } if (url.endsWith('/contact-twitter')) { return K.CF.UrlType.CONTACTTWITTER; } if (url.endsWith('/free-rolls')) { return K.CF.UrlType.FREEROLLS; } if (url.endsWith('/settings')) { return K.CF.UrlType.SETTINGS; } if (url.endsWith('/stats')) { return K.CF.UrlType.STATS; } if (url.endsWith('/')) { url = url.slice(0, -1); if (url == helpers.getHost(url, true)) { return K.CF.UrlType.HOME; } } return K.CF.UrlType.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; //0: Random between min and max config['defaults.postponeMinutes.min'] = 65; config['defaults.postponeMinutes.max'] = 65; config['defaults.workInBackground'] = true; config['defaults.extraInterval'] = 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'] = "0"; config['bk.hoursBetweenWithdraws'] = 4; config['bk.sleepMinutesIfIpBan'] = 75; config['bestchange.address'] = '101'; config['bigbtc.postponeMinutes'] = '0'; 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 != K.WebType.FAUCETPAY && flowControl.type != K.WebType.BAGIKERAN && flowControl.type != K.WebType.OURBITCOIN) { //if(flowControl.opened && flowControl.type != K.WebType.FAUCETPAY && flowControl.type != K.WebType.BAGIKERAN) { return false; } if(flowControl.type == K.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; }; function setProp(key, val) { flowControl[key] = val; saveFlowControl(); }; function getProp(key) { return flowControl[key]; }; 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, setProp: setProp, getProp: getProp }; }, 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: K.WebType.CRYPTOSFAUCETS }, { id: '2', name: 'CF BNB', cmc: '1839', coinRef: 'BNB', url: new URL('https://freebinancecoin.com/free'), rf: '?ref=161127', type: K.WebType.CRYPTOSFAUCETS }, { id: '3', name: 'CF BTC', cmc: '1', coinRef: 'BTC', url: new URL('https://freebitcoin.io/free'), rf: '?ref=490252', type: K.WebType.CRYPTOSFAUCETS }, { id: '4', name: 'CF DASH', cmc: '131', coinRef: 'DASH', url: new URL('https://freedash.io/free'), rf: '?ref=124083', type: K.WebType.CRYPTOSFAUCETS }, { id: '5', name: 'CF ETH', cmc: '1027', coinRef: 'ETH', url: new URL('https://freeethereum.com/free'), rf: '?ref=204076', type: K.WebType.CRYPTOSFAUCETS }, { id: '6', name: 'CF LINK', cmc: '1975', coinRef: 'LINK', url: new URL('https://freechainlink.io/free'), rf: '?ref=78652', type: K.WebType.CRYPTOSFAUCETS }, { id: '7', name: 'CF LTC', cmc: '2', coinRef: 'LTC', url: new URL('https://free-ltc.com/free'), rf: '?ref=117042', type: K.WebType.CRYPTOSFAUCETS }, { id: '8', name: 'CF NEO', cmc: '1376', coinRef: 'NEO', url: new URL('https://freeneo.io/free'), rf: '?ref=100529', type: K.WebType.CRYPTOSFAUCETS }, { id: '9', name: 'CF STEAM', cmc: '1230', coinRef: 'STEEM', url: new URL('https://freesteam.io/free'), rf: '?ref=117686', type: K.WebType.CRYPTOSFAUCETS }, { id: '10', name: 'CF TRX', cmc: '1958', coinRef: 'TRX', url: new URL('https://free-tron.com/free'), rf: '?ref=145047', type: K.WebType.CRYPTOSFAUCETS }, { id: '12', name: 'CF USDT', cmc: '825', coinRef: 'USDT', url: new URL('https://freetether.com/free'), rf: '?ref=181230', type: K.WebType.CRYPTOSFAUCETS }, { id: '11', name: 'CF USDC', cmc: '3408', coinRef: 'USDC', url: new URL('https://freeusdcoin.com/free'), rf: '?ref=100434', type: K.WebType.CRYPTOSFAUCETS }, { id: '13', name: 'CF XEM', cmc: '873', coinRef: 'XEM', url: new URL('https://freenem.com/free'), rf: '?ref=295274', type: K.WebType.CRYPTOSFAUCETS }, { id: '14', name: 'CF XRP', cmc: '52', coinRef: 'XRP', url: new URL('https://coinfaucet.io/free'), rf: '?ref=808298', type: K.WebType.CRYPTOSFAUCETS }, { id: '15', name: 'StormGain', cmc: '1', url: new URL('https://app.stormgain.com/crypto-miner/'), rf: 'friend/BNS27140552', type: K.WebType.STORMGAIN }, { id: '16', name: 'CF DOGE', cmc: '74', coinRef: 'DOGE', url: new URL('https://free-doge.com/free'), rf: '?ref=97166', type: K.WebType.CRYPTOSFAUCETS }, { id: '17', name: 'FreeBitco.in', cmc: '1', url: new URL('https://freebitco.in/'), rf: '?r=41092365', type: K.WebType.FREEBITCOIN }, { id: '18', name: 'FaucetPay PTC', cmc: '1', url: new URL('https://faucetpay.io/ptc'), rf: '?r=41092365', type: K.WebType.FAUCETPAY }, { id: '19', name: 'Free-Litecoin.com', cmc: '2', url: new URL('https://free-litecoin.com/'), rf: 'login?referer=1332950', type: K.WebType.FREELITECOIN }, { id: '20', name: 'Free-Ethereum.io', cmc: '1027', url: new URL('https://www.free-ethereum.io/'), rf: '?referer=1064662', type: K.WebType.FREEETHEREUMIO }, { id: '21', name: 'Bagi BTC', cmc: '1', wallet: K.WalletType.FP_BTC, url: new URL('https://bagi.co.in/bitcoin/'), rf: ['?ref=53706', '?ref=63428', '?ref=54350'], type: K.WebType.BAGIKERAN }, { id: '22', name: 'Bagi BNB', cmc: '1839', wallet: K.WalletType.FP_BNB, url: new URL('https://bagi.co.in/binance/'), rf: ['?ref=12529', '?ref=23852', '?ref=13847'], type: K.WebType.BAGIKERAN }, { id: '23', name: 'Bagi BCH', cmc: '1831', wallet: K.WalletType.FP_BCH, url: new URL('https://bagi.co.in/bitcoincash/'), rf: ['?ref=44242', '?ref=50185', '?ref=41957'], type: K.WebType.BAGIKERAN }, { id: '24', name: 'Bagi DASH', cmc: '131', wallet: K.WalletType.FP_DASH, url: new URL('https://bagi.co.in/dash/'), rf: ['?ref=32724', '?ref=38540', '?ref=40441'], type: K.WebType.BAGIKERAN }, { id: '25', name: 'Bagi DGB', cmc: '109', wallet: K.WalletType.FP_DGB, url: new URL('https://bagi.co.in/digibyte/'), rf: ['?ref=22664', '?ref=27872', '?ref=29669'], type: K.WebType.BAGIKERAN }, { id: '26', name: 'Bagi DOGE', cmc: '74', wallet: K.WalletType.FP_DOGE, url: new URL('https://bagi.co.in/dogecoin/'), rf: ['?ref=45047', '?ref=54217', '?ref=45568'], type: K.WebType.BAGIKERAN }, { id: '27', name: 'Bagi ETH', cmc: '1027', wallet: K.WalletType.FP_ETH, url: new URL('https://bagi.co.in/ethereum/'), rf: ['?ref=24486', '?ref=27799', '?ref=24847'], type: K.WebType.BAGIKERAN }, { id: '28', name: 'Bagi FEY', cmc: '10361', wallet: K.WalletType.FP_FEY, url: new URL('https://bagi.co.in/feyorra/'), rf: ['?ref=5049', '?ref=7433', '?ref=5318'], type: K.WebType.BAGIKERAN }, { id: '29', name: 'Bagi LTC', cmc: '2', wallet: K.WalletType.FP_LTC, url: new URL('https://bagi.co.in/litecoin/'), rf: ['?ref=48335', '?ref=57196', '?ref=48878'], type: K.WebType.BAGIKERAN }, { id: '30', name: 'Bagi TRX', cmc: '1958', wallet: K.WalletType.FP_TRX, url: new URL('https://bagi.co.in/tron/'), rf: ['?ref=22622', '?ref=31272', '?ref=23075'], type: K.WebType.BAGIKERAN }, { id: '31', name: 'Bagi USDT', cmc: '825', wallet: K.WalletType.FP_USDT, url: new URL('https://bagi.co.in/tether/'), rf: ['?ref=25462', '?ref=32491', '?ref=25981'], type: K.WebType.BAGIKERAN }, { id: '32', name: 'Bagi ZEC', cmc: '1437', wallet: K.WalletType.FP_ZEC, url: new URL('https://bagi.co.in/zcash/'), rf: ['?ref=9181', '?ref=15120', '?ref=9878'], type: K.WebType.BAGIKERAN }, { id: '33', name: 'Keran BTC', cmc: '1', wallet: K.WalletType.FP_BTC, url: new URL('https://keran.co/BTC/'), rf: ['?ref=73729', '?ref=92353', '?ref=79321'], type: K.WebType.BAGIKERAN }, { id: '34', name: 'Keran BNB', cmc: '1839', wallet: K.WalletType.FP_BNB, url: new URL('https://keran.co/BNB/'), rf: ['?ref=19287', '?ref=31242', '?ref=20659'], type: K.WebType.BAGIKERAN }, { id: '35', name: 'Keran BCH', cmc: '1831', wallet: K.WalletType.FP_BCH, url: new URL('https://keran.co/BCH/'), rf: ['?ref=58232', '?ref=67326', '?ref=70759'], type: K.WebType.BAGIKERAN }, { id: '36', name: 'Keran DASH', cmc: '131', wallet: K.WalletType.FP_DASH, url: new URL('https://keran.co/DASH/'), rf: ['?ref=45229', '?ref=53041', '?ref=55716'], type: K.WebType.BAGIKERAN }, { id: '37', name: 'Keran DGB', cmc: '109', wallet: K.WalletType.FP_DGB, url: new URL('https://keran.co/DGB/'), rf: ['?ref=32788', '?ref=39527', '?ref=42014'], type: K.WebType.BAGIKERAN }, { id: '38', name: 'Keran DOGE', cmc: '74', wallet: K.WalletType.FP_DOGE, url: new URL('https://keran.co/DOGE/'), rf: ['?ref=73512', '?ref=85779', '?ref=89613'], type: K.WebType.BAGIKERAN }, { id: '39', name: 'Keran ETH', cmc: '1027', wallet: K.WalletType.FP_ETH, url: new URL('https://keran.co/ETH/'), rf: ['?ref=32226', '?ref=36427', '?ref=32676'], type: K.WebType.BAGIKERAN }, { id: '40', name: 'Keran FEY', cmc: '10361', wallet: K.WalletType.FP_FEY, url: new URL('https://keran.co/FEY/'), rf: ['?ref=6269', '?ref=9019', '?ref=6569'], type: K.WebType.BAGIKERAN }, { id: '41', name: 'Keran LTC', cmc: '2', wallet: K.WalletType.FP_LTC, url: new URL('https://keran.co/LTC/'), rf: ['?ref=69102', '?ref=80726', '?ref=84722'], type: K.WebType.BAGIKERAN }, { id: '42', name: 'Keran TRX', cmc: '1958', wallet: K.WalletType.FP_TRX, url: new URL('https://keran.co/TRX/'), rf: ['?ref=49686', '?ref=46544', '?ref=34485'], type: K.WebType.BAGIKERAN }, { id: '43', name: 'Keran USDT', cmc: '825', wallet: K.WalletType.FP_USDT, url: new URL('https://keran.co/USDT/'), rf: ['?ref=40582', '?ref=48907', '?ref=41009'], type: K.WebType.BAGIKERAN }, { id: '44', name: 'Keran ZEC', cmc: '1437', wallet: K.WalletType.FP_ZEC, url: new URL('https://keran.co/ZEC/'), rf: ['?ref=', '?ref=18976', '?ref=12487'], type: K.WebType.BAGIKERAN }, { id: '45', name: 'OK Btc', cmc: '1', wallet: K.WalletType.FP_BTC, url: new URL('https://btc-ok.net/'), rf: 'index.php?r=1QCD6cWJNVH4Cdnz85SQ2qtTkAwGr9fvUk', type: K.WebType.OKFAUCET }, { id: '46', name: 'OK Dash', cmc: '131', wallet: K.WalletType.FP_DASH, url: new URL('https://dash-ok.net/'), rf: 'index.php?r=Xbyi7Fk2NRmZ32SHpDhmpGHLa4NMokhmGR', type: K.WebType.OKFAUCET }, { id: '47', name: 'OK Dgb', cmc: '109', wallet: K.WalletType.FP_DGB, url: new URL('https://dgb-ok.net/'), rf: 'index.php?r=DSM93hgZuapnjeeDMe8spzwG9rMrw4sdua', type: K.WebType.OKFAUCET }, { id: '48', name: 'OK Doge', cmc: '74', wallet: K.WalletType.FP_DOGE, url: new URL('https://doge-ok.net/'), rf: 'index.php?r=DDaQWmD7vY1NhtK1M5Pno7sdccmgxNUfv1', type: K.WebType.OKFAUCET }, { id: '49', name: 'OK Eth', cmc: '1027', wallet: K.WalletType.FP_ETH, url: new URL('https://eth-ok.net/'), rf: 'index.php?r=0x7636f64a8241257b1edaf65ae943c66de87b1749', type: K.WebType.OKFAUCET }, { id: '50', name: 'OK Ltc', cmc: '2', wallet: K.WalletType.FP_LTC, url: new URL('https://ltc-ok.net/'), rf: 'index.php?r=MEmxLqYzZdMsEswUQkqL5aawT5UsqYwYgr', type: K.WebType.OKFAUCET }, { id: '51', name: 'OK Trx', cmc: '1958', wallet: K.WalletType.FP_TRX, url: new URL('https://trx-ok.net/'), rf: 'index.php?r=TSocuzJ6ADUoQ49v28BXN2jo3By6awwHvj', type: K.WebType.OKFAUCET }, { id: '52', name: 'BigBtc', cmc: '1', wallet: K.WalletType.FP_BTC, url: new URL('https://bigbtc.win/'), rf: '?id=39255652', type: K.WebType.BIGBTC }, { id: '53', name: 'BestChange', cmc: '1', wallet: K.WalletType.FP_BTC, url: new URL('https://www.bestchange.com/'), rf: ['index.php?nt=bonus&p=1QCD6cWJNVH4Cdnz85SQ2qtTkAwGr9fvUk', 'index.php?nt=bonus&p=365Z9xPiQA4iWg23kcxRAdrGfV9RGPhS5J'], type: K.WebType.BESTCHANGE }, { id: '54', name: 'Litking.biz', cmc: '2', url: new URL('https://litking.biz/'), rf: 'signup?r=159189', type: K.WebType.KINGBIZ }, { id: '55', name: 'Bitking.biz', cmc: '1', url: new URL('https://bitking.biz/'), rf: 'signup?r=90003', type: K.WebType.KINGBIZ }, // { id: '56', name: 'OK Bch', cmc: '1831', wallet: K.WalletType.FP_BCH, url: new URL('https://faucetok.net/bch/'), rf: '?r=qz742nf2c30ktehlmn0pg6quqe8yuwp3evd75y8c0k', type: K.WebType.OKFAUCET } { id: '57', name: 'OurBitco.in', cmc: '1', url: new URL('https://ourbitco.in/dashboard'), rf: '?r=gebcjvwpky', type: K.WebType.OURBITCOIN }, { id: '58', name: 'BetFury BTC', cmc: '1', url: new URL('https://betfury.io/boxes/all'), rf: ['?r=608c5cfcd91e762043540fd9'], type: K.WebType.BETFURYBOX }, { id: '59', name: 'BetFury BNB', cmc: '1839', url: new URL('https://betfury.io/boxes/all'), rf: ['?r=608c5cfcd91e762043540fd9'], type: K.WebType.BETFURYBOX }, { id: '60', name: 'Free-Doge.io', cmc: '74', url: new URL('https://www.free-doge.io/'), rf: '?referer=6695', type: K.WebType.FREEDOGEIO }, { id: '61', name: 'Dutchy', cmc: '-1', url: new URL('https://autofaucet.dutchycorp.space/roll.php'), rf: '?r=corecrafting', type: K.WebType.DUTCHYROLL }, { id: '62', name: 'Dutchy Monthly Coin', cmc: '-1', url: new URL('https://autofaucet.dutchycorp.space/coin_roll.php'), rf: '?r=corecrafting', type: K.WebType.DUTCHYROLL } ]; const wallet = [ { id: '101', name: 'FaucetPay BTC (Bitcoin)', type: K.WalletType.FP_BTC }, { id: '102', name: 'FaucetPay BNB (Binance Coin)', type: K.WalletType.FP_BNB }, { id: '103', name: 'FaucetPay BCH (Bitcoin Cash)', type: K.WalletType.FP_BCH }, { id: '104', name: 'FaucetPay DASH (Dash)', type: K.WalletType.FP_DASH }, { id: '105', name: 'FaucetPay DGB (DigiByte)', type: K.WalletType.FP_DGB }, { id: '106', name: 'FaucetPay DOGE (Dogecoin)', type: K.WalletType.FP_DOGE }, { id: '107', name: 'FaucetPay ETH (Ethereum)', type: K.WalletType.FP_ETH }, { id: '108', name: 'FaucetPay FEY (Feyorra)', type: K.WalletType.FP_FEY }, { id: '109', name: 'FaucetPay LTC (Litecoin)', type: K.WalletType.FP_LTC }, { id: '110', name: 'FaucetPay TRX (Tron)', type: K.WalletType.FP_TRX }, { id: '111', name: 'FaucetPay USDT (Tether TRC20)', type: K.WalletType.FP_USDT }, { id: '112', name: 'FaucetPay ZEC (Zcash)', type: K.WalletType.FP_ZEC }, { id: '1', name: 'BTC Alternative Address', type: K.WalletType.BTC } // { id: '2', name: 'LTC Address', type: K.WalletType.LTC } ]; 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)); // Set some defaults 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 : K.USE_DEFAULT); // deprecated // TODO: review if(arr[idx].type == K.WebType.BAGIKERAN) { arr[idx].lastWithdraw = new Date(); } if (element.id == '18') { //18: FPPTC arr[idx].params = {}; arr[idx].params['defaults.workInBackground.override'] = true; arr[idx].params['defaults.workInBackground'] = false; } //TODO: defaults, schedule, logics, queues //arr[idx].params = { logics: { nextRun: K.USE_DEFAULT, balance: K.USE_DEFAULT }, sleepSchedule: K.USE_DEFAULT, queue: K.USE_DEFAULT }; // if(arr[idx].type == K.WebType.BETFURYBOX) { // arr[idx].params.logics.nextRun = '30 minutes +/- 10%'; // } // if(arr[idx].type == K.WebType.OURBITCOIN) { // arr[idx].params.logics.nextRun = '32 minutes +/- 7% but RETRY NOW IF FORCE_CLOSED OR SOMETHING LIKE THAT'; // } }); }; 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; webList[idx].params = element.params ?? webList[idx].params; } }); } 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.site.changed) { // console.log(JSON.stringify(updateObj)); try { updateSite(updateObj.site.id, updateObj.site.items); } catch (err) { ui.log(`Error updating site: ${err}`); } document.getElementById('faucets-display-status').innerHTML = ''; } if(updateObj.runAsap.changed || updateObj.editSingle.changed || updateObj.site.changed) { document.getElementById('faucets-display-status').innerHTML = ''; update(true); process(); return; } } } if(forceCheck) { process(); } }; function updateSite(id, items) { let elm = webList.find(x => x.id == id); if (elm) { elm.params = elm.params || {}; items.forEach( function (item) { elm.params[item.prop] = item.value; }); shared.devlog(`Saving: ${JSON.stringify(elm)}`); ui.log(`Site ${elm.name} updated`); } } function readModalData() { if(document.getElementById('modal-spinner').isVisible()) { let targetObject = JSON.parse(document.getElementById('target-spinner').innerHTML); let target = targetObject.id; 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()); } else if (target == 'modal-site') { let site = webList.find(x => x.id == targetObject.siteId); ui.refresh(null, null, null, null, { site: site, config: 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 == K.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, params: x.params }; 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 == K.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 = webList[0].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 { shared.addError(K.ErrorType.NO_ADDRESS, 'You need to add your address to the wallet before claiming this faucet.'); ui.log(`Unable to launch ${webType[0].name}: Address not detected > add it to the wallet.`); moveNext(); return; } } if(webList[0].type == K.WebType.BESTCHANGE) { params.address = shared.getConfig()['bestchange.address'] == '1' ? userWallet.find(x => x.type == 1).address : params.address; } if(webList[0].type == K.WebType.BAGIKERAN) { params.doWithdraw = getDoWithdraw(webList[0].lastWithdraw); params.doSignOut = (webList[0].wallet == K.WalletType.FP_BCH ? true : false); params.trackUrl = webList[0].url; } params.cmc = webList[0].cmc; 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 == K.USE_DEFAULT ? !shared.getConfig()['defaults.workInBackground'] : !webList[0].workInBackground) }); workingTab = GM_openInTab(navUrl.href, { active: !getCustomOrDefaultVal('defaults.workInBackground', useOverride('defaults.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; } //TODO: review workingTab.closed as it's redirected @ OurBitco.in if ((webList[0].type == K.WebType.FAUCETPAY || webList[0].type == K.WebType.OURBITCOIN) && workingTab && !workingTab.closed //if (webList[0].type == K.WebType.FAUCETPAY && workingTab && !workingTab.closed && timeWaiting < shared.getConfig()['fp.maxTimeInMinutes'] * 60) { 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 == K.WebType.CRYPTOSFAUCETS) && ( (result.claimed) || (result.promoStatus && result.promoStatus != K.CF.PromoStatus.ACCEPTED) )) { let promoCode = CFPromotions.hasPromoAvailable(webList[0].id); if (promoCode) { timeWaiting = 0; update(false); open(promoCode); return; } } if ( webList[0].type == K.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(K.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(K.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 == K.ErrorType.IP_BAN && shared.getConfig()['cf.sleepHoursIfIpBan'] > 0) || ( (webList[0].stats.errors.errorType == K.ErrorType.IP_RESTRICTED || webList[0].stats.errors.errorType == K.ErrorType.IP_BAN) && shared.getConfig()['bk.sleepMinutesIfIpBan'] > 0) ) { if(webList[0].type == K.WebType.CRYPTOSFAUCETS) { webList.filter(x => x.enabled && x.type == K.WebType.CRYPTOSFAUCETS) .forEach( function(el) { el.nextRoll = new Date(helpers.addMs(new Date(), helpers.getRandomMs(shared.getConfig()['cf.sleepHoursIfIpBan'] * 60, 2))); }); } if(webList[0].type == K.WebType.BAGIKERAN) { webList.filter(x => x.enabled && x.type == K.WebType.BAGIKERAN && x.url.host == webList[0].url.host) .forEach( function(el) { el.nextRoll = new Date(helpers.addMs(new Date(), helpers.getRandomMs(shared.getConfig()['bk.sleepMinutesIfIpBan'], 2))); }); } shared.clearFlowControl(); update(true); timeWaiting = 0; readUpdateValues(true); return true; } return false; } function getCustomOrDefaultVal(param, useOverride = false) { let val; if (useOverride) { if (webList[0].params && webList[0].params.hasOwnProperty(param)) { val = webList[0].params[param]; if (val != -1) { return val; } } } return shared.getConfig()[param]; } function useOverride(param) { let overrideFlag = param + '.override'; return webList[0].params && webList[0].params[overrideFlag]; } function moveNext() { let userOverride = useOverride('defaults.postponeMinutes'); let mode = getCustomOrDefaultVal('defaults.postponeMinutes', useOverride); let min = getCustomOrDefaultVal('defaults.postponeMinutes.min', useOverride); let max = getCustomOrDefaultVal('defaults.postponeMinutes.max', useOverride); let minutes = (mode == 0) ? helpers.randomInt(min, max) : mode; let msDelay = helpers.getRandomMs(minutes, 5); webList[0].nextRoll = new Date(helpers.addMs(new Date(), msDelay)); shared.clearFlowControl(); update(true); timeWaiting = 0; readUpdateValues(true); } function hasTimedOut() { let val = getCustomOrDefaultVal('defaults.timeout', useOverride('defaults.timeout')) * 60; return (timeWaiting > val); // 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 === K.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 injectables = { managerJs: function () { window.myBarChart = null; window.sendErrorReport = function sendErrorReport() { try { let header = new Headers(); header.append("Content-Type", "application/json"); let description = document.getElementById("log-message").value; let log = document.getElementById("log-textarea").value.split('\n'); let content = {"description":description, "log":log}; let opt = { method: "POST", header, mode: "cors", body: JSON.stringify(content) }; fetch("https://1d0103ec5a621b87ea27ffed3c072796.m.pipedream.net", opt).then(response => { console.log(response); }).catch(err => { console.error("[error] " + err.message); }); } catch { } }; window.loadDlg = function loadDlg(id, siteId = null) { document.querySelectorAll(".modal-content").forEach(x => x.classList.add('d-none')); // $(".modal-content").addClass("d-none"); if (id == "modal-ereport" || id == "modal-config" || id == "modal-site") { document.getElementById("target-spinner").innerHTML = JSON.stringify({id: id, siteId: siteId}); document.getElementById("modal-spinner").classList.remove("d-none"); return; } else { document.getElementById(id).classList.remove("d-none"); } }; window.savePromoCode = function savePromoCode() { var promoText = document.getElementById("promo-text-input"); var promoCode = document.getElementById("promo-code-new"); var promoDisplayStatus = document.getElementById("promo-display-status"); var promoDaily = document.getElementById("promo-daily"); var promoObject = { action: "ADD", code: promoText.value.trim(), repeatDaily: promoDaily.checked }; promoCode.innerHTML =JSON.stringify(promoObject); promoDisplayStatus.innerHTML = "Adding  "" + promoObject.code + ""...
This could take around a minute. Please wait..." }; window.removePromoCode = function removePromoCode(id, code) { var promoCode = document.getElementById("promo-code-new"); var promoDisplayStatus = document.getElementById("promo-display-status"); var promoObject = { action: "REMOVE", id: id, code: code }; promoCode.innerHTML =JSON.stringify(promoObject); promoDisplayStatus.innerHTML = "Removing code  "" + code + ""...
This could take around a minute. Please wait..." }; window.getUpdateObject = function getUpdateObject() { let updateObject; var updateData = document.getElementById("update-data"); if (updateData.innerHTML != "") { updateObject = JSON.parse(updateData.innerHTML); } else { updateObject = { runAsap: { ids: [], changed: false}, editSingle: { changed: false, items: [] }, wallet: { changed: false, items: []}, config: { changed: false, items: []}, site: { changed: false, id: null, items: []} }; } return updateObject; }; window.editList = function editList() { document.querySelectorAll("#schedule-table-body td.em-input").forEach(function (x) { let val = x.innerHTML; x.innerHTML = ""; }); document.querySelectorAll("#schedule-table-body td.edit-status").forEach(function (x) { let activeSwitch = x.querySelector("input"); x.classList.remove("d-none"); }); document.querySelectorAll(".em-only").forEach(x => x.classList.remove("d-none")); document.querySelectorAll(".em-hide").forEach(x => x.classList.add("d-none")); }; window.editListSave = function editListSave() { let updateObject = getUpdateObject(); document.querySelectorAll("#schedule-table-body tr").forEach(function (row) { let textInputCell = row.querySelector(".em-input"); let textInput = textInputCell.querySelector("input"); let activeSwitch = row.querySelector("td.edit-status input"); let single = { id: row.dataset.id, displayName: textInput.dataset.original, enabled: activeSwitch.dataset.original }; textInputCell.innerHTML = textInput.value; if(textInput.dataset.original != textInput.value) { single.displayName = textInput.value; } if(activeSwitch.dataset.original != Boolean(activeSwitch.checked)) { single.enabled = Boolean(activeSwitch.checked); } if(textInput.dataset.original != textInput.value || activeSwitch.dataset.original != Boolean(activeSwitch.checked)) { updateObject.editSingle.items.push(single); updateObject.editSingle.changed = true; } }); if(updateObject.editSingle.changed) { document.getElementById("update-data").innerHTML = JSON.stringify(updateObject); document.getElementById("faucets-display-status").innerHTML = "Data will be updated as soon as possible..."; } document.querySelectorAll(".em-only").forEach(x => x.classList.add("d-none")); document.querySelectorAll(".em-hide").forEach(x => x.classList.remove("d-none")); }; window.editListCancel = function editListCancel() { document.querySelectorAll("#schedule-table-body td.em-input input").forEach(function(x) { x.parentNode.innerHTML = x.dataset.original; }); document.querySelectorAll(".em-only").forEach(x => x.classList.add("d-none")); document.querySelectorAll(".em-hide").forEach(x => x.classList.remove("d-none")); }; window.editWallet = { save: function() { let updateObject = getUpdateObject(); document.querySelectorAll("#wallet-table-body tr").forEach( function(row) { let textInput = row.querySelector(".em-input input"); if(textInput.dataset.original != textInput.value) { let single = { id: row.dataset.id, address: textInput.value.trim() }; updateObject.wallet.items.push(single); updateObject.wallet.changed = true; } }); if(updateObject.wallet.changed) { document.getElementById("update-data").innerHTML = JSON.stringify(updateObject); document.getElementById("faucets-display-status").innerHTML = "Wallet will be updated as soon as possible..."; } }, toggleJson: function(val) { if (document.querySelector('#wallet-json').isVisible()) { if(val != 'cancel') { editWallet.fromJson(); } } else { editWallet.toJson(); } document.querySelector('.footer-json').classList.toggle('d-none'); document.querySelector('.footer-table').classList.toggle('d-none'); document.querySelector('#wallet-table').classList.toggle('d-none'); document.querySelector('#wallet-json').classList.toggle('d-none'); }, toJson: function() { let j = []; document.querySelectorAll('#wallet-table-body tr').forEach(function (row) { j.push({ id: row.dataset.id, address: row.querySelector('.em-input input').value }); }); document.querySelector('#wallet-json').value = JSON.stringify(j); }, fromJson: function() { let j = JSON.parse(document.querySelector('#wallet-json').value); document.querySelectorAll('#wallet-table-body tr').forEach(function (row) { let element = j.find(x => x.id == row.dataset.id); if (element) { row.querySelector('.em-input input').value = element.address; } }); }, cancel: function() { document.querySelectorAll("#wallet-table-body .em-input input").forEach( function(x) { x.value = x.dataset.original; }); } }; window.editConfig = { save: function() { let updateObject = getUpdateObject(); document.querySelectorAll("#modal-config [data-original][data-prop]").forEach(function(elm) { let single = { prop: elm.dataset.prop, value: elm.dataset.value }; if(elm.dataset.original != elm.value && (elm.type == "select-one" || elm.type == "text" || elm.type == "password" || elm.type == "number") ) { single.value = elm.value; updateObject.config.items.push(single); updateObject.config.changed = true; } else if (elm.type == "checkbox" && ((elm.dataset.original == "0" && elm.checked) || (elm.dataset.original == "1" && !elm.checked)) ) { single.value = elm.checked; updateObject.config.items.push(single); updateObject.config.changed = true; } }); if(updateObject.config.changed) { document.getElementById("update-data").innerHTML = JSON.stringify(updateObject); document.getElementById("faucets-display-status").innerHTML = "Config will be updated as soon as possible..."; } }, cancel: function() { document.querySelectorAll("#modal-config [data-original][data-prop]").forEach(function(elm) { if(elm.type == "select-one" || elm.type == "text" || elm.type == "password" || elm.type == "number") { elm.value = elm.dataset.original; } else if (elm.type == "checkbox") { elm.checked = (elm.dataset.original == "1" ? true : false) } }); } }; window.editSite = { save: function() { let updateObject = getUpdateObject(); updateObject.site.id = document.querySelector("#faucet-name").dataset.id; document.querySelectorAll("#modal-site [data-original][data-site-prop]").forEach(function(elm) { let single = { prop: elm.dataset.siteProp, value: elm.dataset.value }; // console.log("For " + elm.dataset.siteProp + ": original is " + elm.dataset.original + ",value is " + elm.dataset.value + " and checked is " + elm.checked); if(elm.dataset.original != elm.value && (elm.type == "select-one" || elm.type == "text" || elm.type == "password" || elm.type == "number") ) { single.value = elm.value; updateObject.site.items.push(single); updateObject.site.changed = true; } else if (elm.type == "checkbox" && ((elm.dataset.original == "0" && elm.checked) || (elm.dataset.original == "1" && !elm.checked)) ) { single.value = elm.checked; updateObject.site.items.push(single); updateObject.site.changed = true; } }); // console.log("@updateObject.site.changed: " + updateObject.site.changed); if(updateObject.site.changed) { document.getElementById("update-data").innerHTML = JSON.stringify(updateObject); document.getElementById("faucets-display-status").innerHTML = "Site will be updated as soon as possible..."; } }, cancel: function() { document.querySelectorAll("#modal-site [data-original][data-site-prop]").forEach(function(elm) { if(elm.type == "select-one" || elm.type == "text" || elm.type == "password" || elm.type == "number") { elm.value = elm.dataset.original; } else if (elm.type == "checkbox") { elm.checked = (elm.dataset.original == "1" ? true : false) } }); } }; window.editEreport = { save: function() { sendErrorReport(); }, cancel: function() { } }; window.modalSave = function modalSave(content) { switch(content) { case "wallet": editWallet.save(); break; case "ereport": editEreport.save(); break; case "config": editConfig.save(); break; case "site": editSite.save(); break; } // if(content == "wallet") { // editWallet.save(); // } else if (content == "ereport") { // editEreport.save(); // } else if (content == "config") { // editConfig.save(); // } }; window.modalCancel = function modalCancel(content) { if(content == "wallet") { editWallet.cancel(); } else if ("ereport") { editEreport.cancel(); } document.querySelectorAll("modal-content").forEach(x => x.classList.add("d-none")); }; window.updateValues = function updateValues(type, values) { let updateObject = getUpdateObject(); if (type == "runAsap") { updateObject.runAsap.ids.push(values.id); updateObject.runAsap.changed = true; document.getElementById("update-data").innerHTML = JSON.stringify(updateObject); document.getElementById("faucets-display-status").innerHTML = "Faucet will be updated to run as soon as possible..."; } }; window.removeAllPromos = function removeAllPromos() { var promoCode = document.getElementById("promo-code-new"); var promoDisplayStatus = document.getElementById("promo-display-status"); var promoObject = { action: "REMOVEALLPROMOS" }; promoCode.innerHTML =JSON.stringify(promoObject); promoDisplayStatus.innerHTML = "Removing all promotion codes...
This could take around a minute. Please wait..." }; window.openStatsChart = function openStatsChart() { if(myBarChart) { myBarChart.destroy(); } let statsFragment = document.getElementById("stats-fragment"); if (statsFragment.style.display === "block") { statsFragment.style.display = "none"; document.getElementById("stats-button").innerText = "Lucky Number Stats"; } else { statsFragment.style.display = "block"; document.getElementById("stats-button").innerText = "Close Stats"; var canvas = document.getElementById("barChart"); var ctx = canvas.getContext("2d"); var dataSpan = document.getElementById("rolls-span"); var data = { labels: ["0000-9885", "9886-9985", "9986-9993", "9994-9997", "9998-9999", "10000"], datasets: [ { fill: false, backgroundColor: [ "#990000", "#660066", "#000099", "#ff8000", "#ffff00", "#00ff00"], data: dataSpan.innerText.split(",") } ] }; var options = { plugins: { legend: { display: false } }, title: { display: true, text: "Rolled Numbers", position: "top" }, rotation: -0.3 * Math.PI }; myBarChart = new Chart(ctx, { type: "pie", data: data, options: options }); } }; } }; 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() { addJS_Node (null, null, injectables.managerJs); }; function appendHtml() { let html =''; // html += '
'; // if (shared.getConfig()['devlog.enabled']) { // html += '
View Log
'; // } // html += '
Edit Config
'; // html += '
'; html += '