- // ==UserScript==
- // @name Void Coin FreeBitco
- // @namespace https://github.com/HaygoNunes/Script-FreeBTC
- // @namespace https://gf.qytechs.cn/en/users/1295753-hyago-nunes
- // @version 2.0
- // @description https://freebitco.in/?r=1393623
- // @author Sr.Fox / Hyago Nunes
- // @match https://freebitco.in/*
- // @match https://*/recaptcha/*
- // @match https://*.hcaptcha.com/*hcaptcha-challenge*
- // @match https://*.hcaptcha.com/*checkbox*
- // @match https://*.hcaptcha.com/*captcha*
- // @grant GM_getValue
- // @grant GM_setValue
- // @grant GM_registerMenuCommand
- // @grant GM_xmlhttpRequest
- // @update https://update.gf.qytechs.cn/scripts/493924/Void%20Coin%20FreeBitco.user.js
- // @license MIT
- // ==/UserScript==
-
- (function () {
- 'use strict';
-
- // UTILITÁRIOS BÁSICOS
- function qSelector(selector) { return document.querySelector(selector); }
- function isHidden(el) { return (el.offsetParent === null); }
- function random(min, max) { return min + (max - min) * Math.random(); }
-
- // CONFIGURAÇÃO
- const CONFIG = {
- tentativasMaximas: 7,
- intervaloCaptcha: 3000,
- rollDelay: 7000,
- playWithoutCaptchaDelay: 12000,
- secondRollDelay: 14000,
- intervaloVerificacao: 1000,
- intervaloBackground: 30000,
- // Seletores para captchas e botões
- hcCheckBox: "#checkbox",
- hcAriaChecked: "aria-checked",
- rcCheckBox: ".recaptcha-checkbox-border",
- rcStatus: "#recaptcha-accessible-status",
- rcDosCaptcha: ".rc-doscaptcha-body",
- rollButton: "#free_play_form_button",
- playWithoutCaptchaButton: "#play_without_captchas_button",
- timerElement: "#time_remaining",
- // Cloudflare Turnstile
- cfIframeSelector: 'iframe[src*="challenges.cloudflare.com"]',
- cfResponseInput: "#cf-chl-widget-a1bva_response",
- cfSuccessSelector: "#success-i > circle",
- // 2Captcha (para resolver o Turnstile, se necessário)
- use2Captcha: true,
- turnstileSitekey: "a1bva",
- apiKey2Captcha: "Sua KEY_API do 2captcha"
- };
-
- // ESTADO – persistência simples
- let state = {
- modoOperacao: 0, // 0 = Normal, 1 = Sem Captcha
- tentativas: 0,
- ultimaExecucao: 0
- };
-
- function carregarEstado() {
- try {
- const saved = GM_getValue('stateFreeBTC');
- if (saved) state = Object.assign(state, JSON.parse(saved));
- } catch (e) { console.error(e); }
- }
- function salvarEstado() {
- try {
- GM_setValue('stateFreeBTC', JSON.stringify(state));
- } catch (e) { console.error(e); }
- }
-
- // POPUP MANAGER
- const PopupManager = {
- fecharPopups() {
- ['.pushly_popover-container', '#onesignal-slidedown-container', '#notification_permission']
- .forEach(sel => { const el = qSelector(sel); if (el) el.style.display = 'none'; });
- }
- };
-
- // CAPTCHAS – Soluções para Hcaptcha, Recaptcha e Cloudflare Turnstile
- function resolverHcaptcha() {
- if (window.location.href.includes("hcaptcha")) {
- const interval = setInterval(() => {
- const checkbox = qSelector(CONFIG.hcCheckBox);
- if (!checkbox) return;
- if (checkbox.getAttribute(CONFIG.hcAriaChecked) === "true") {
- clearInterval(interval);
- console.log("Hcaptcha resolvido");
- } else if (!isHidden(checkbox) && checkbox.getAttribute(CONFIG.hcAriaChecked) === "false") {
- checkbox.click();
- clearInterval(interval);
- console.log("Hcaptcha: abrindo checkbox");
- }
- }, Number(CONFIG.intervaloCaptcha));
- }
- }
- function resolverRecaptcha() {
- if (window.location.href.includes("recaptcha")) {
- setTimeout(() => {
- let initialStatus = qSelector(CONFIG.rcStatus) ? qSelector(CONFIG.rcStatus).innerText : "";
- try {
- if (qSelector(CONFIG.rcCheckBox) && !isHidden(qSelector(CONFIG.rcCheckBox))) {
- qSelector(CONFIG.rcCheckBox).click();
- console.log("Recaptcha: abrindo checkbox");
- }
- if (qSelector(CONFIG.rcStatus) && qSelector(CONFIG.rcStatus).innerText !== initialStatus) {
- console.log("Recaptcha resolvido");
- }
- if (qSelector(CONFIG.rcDosCaptcha) && qSelector(CONFIG.rcDosCaptcha).innerText.length > 0) {
- console.log("Recaptcha: consulta automatizada detectada");
- }
- } catch (err) { console.error(err.message); }
- }, Number(CONFIG.intervaloCaptcha));
- }
- }
- function resolverTurnstileClique() {
- const cfIframe = qSelector(CONFIG.cfIframeSelector);
- if (cfIframe && cfIframe.contentDocument) {
- const checkbox = cfIframe.contentDocument.querySelector('.mark');
- if (checkbox && !isHidden(checkbox)) {
- if (simularCliqueHumano(checkbox)) {
- console.log("Turnstile resolvido via clique");
- return true;
- }
- }
- }
- return false;
- }
- function resolverTurnstile2Captcha(callback) {
- const reqUrl = `http://2captcha.com/in.php?key=${CONFIG.apiKey2Captcha}&method=turnstile&sitekey=${CONFIG.turnstileSitekey}&pageurl=${encodeURIComponent(window.location.href)}&json=1`;
- console.log("Enviando requisição 2Captcha para Turnstile");
- GM_xmlhttpRequest({
- method: "GET",
- url: reqUrl,
- onload: function(response) {
- try {
- const data = JSON.parse(response.responseText);
- if (data.status === 1) {
- pollToken(data.request, callback);
- } else {
- console.error("2Captcha Error: " + data.request);
- callback(false);
- }
- } catch (e) {
- console.error(e); callback(false);
- }
- },
- onerror: function(err) { console.error(err); callback(false); }
- });
- }
- function pollToken(captchaId, callback) {
- const pollUrl = `http://2captcha.com/res.php?key=${CONFIG.apiKey2Captcha}&action=get&id=${captchaId}&json=1`;
- let attempts = 0;
- const pollInterval = setInterval(() => {
- attempts++;
- GM_xmlhttpRequest({
- method: "GET",
- url: pollUrl,
- onload: function(response) {
- try {
- const data = JSON.parse(response.responseText);
- if (data.status === 1) {
- clearInterval(pollInterval);
- const token = data.request;
- const input = qSelector(CONFIG.cfResponseInput);
- if (input) {
- input.value = token;
- console.log("Turnstile resolvido via 2Captcha");
- callback(true);
- } else {
- console.error("Input para Turnstile não encontrado");
- callback(false);
- }
- } else if (data.request !== "CAPCHA_NOT_READY") {
- clearInterval(pollInterval);
- console.error("Erro polling: " + data.request);
- callback(false);
- }
- } catch (e) { console.error(e); callback(false); }
- },
- onerror: function(err) { console.error(err); callback(false); }
- });
- if (attempts >= 24) {
- clearInterval(pollInterval);
- console.error("Timeout 2Captcha polling");
- callback(false);
- }
- }, 5000);
- }
-
- // FUNÇÃO PARA SIMULAR CLIQUE HUMANO
- function simularCliqueHumano(elemento) {
- if (!elemento) return false;
- let sucesso = false;
- try {
- const rect = elemento.getBoundingClientRect();
- const x = rect.left + rect.width / 2;
- const y = rect.top + rect.height / 2;
- elemento.dispatchEvent(new MouseEvent('mousedown', { bubbles: true, cancelable: true, clientX: x, clientY: y }));
- elemento.dispatchEvent(new MouseEvent('mouseup', { bubbles: true, cancelable: true, clientX: x, clientY: y }));
- elemento.click();
- console.info("Clique simulado com MouseEvents");
- sucesso = true;
- } catch (e) { console.warn("MouseEvents falharam:", e); }
- if (!sucesso) {
- try {
- const rect = elemento.getBoundingClientRect();
- const x = rect.left + rect.width / 2;
- const y = rect.top + rect.height / 2;
- elemento.dispatchEvent(new PointerEvent('pointerdown', { bubbles: true, cancelable: true, clientX: x, clientY: y }));
- elemento.dispatchEvent(new PointerEvent('pointerup', { bubbles: true, cancelable: true, clientX: x, clientY: y }));
- elemento.click();
- console.info("Clique simulado com PointerEvents");
- sucesso = true;
- } catch (e) { console.warn("PointerEvents falharam:", e); }
- }
- if (!sucesso) {
- try {
- elemento.focus();
- elemento.click();
- console.info("Clique simulado com Focus + Click");
- sucesso = true;
- } catch (e) { console.error("Focus + Click falharam:", e); }
- }
- return sucesso;
- }
-
- // GERENCIAMENTO DOS CAPTCHAS
- function gerenciarCaptcha() {
- if (window.location.href.includes("hcaptcha")) resolverHcaptcha();
- if (window.location.href.includes("recaptcha")) resolverRecaptcha();
- if (qSelector(CONFIG.cfIframeSelector)) {
- if (!resolverTurnstileClique() && CONFIG.use2Captcha) {
- resolverTurnstile2Captcha(function(success) {
- if (!success) console.error("Falha ao resolver Turnstile via 2Captcha");
- });
- }
- }
- }
-
- // ACIONAMENTO DOS BOTÕES PLAY/ROLL
- function acionarRoll() {
- const btn = qSelector(CONFIG.rollButton);
- if (btn && !isHidden(btn)) { btn.click(); console.log("ROLL acionado"); }
- else console.warn("Botão ROLL não encontrado");
- }
- function acionarPlayWithoutCaptcha() {
- const btn = qSelector(CONFIG.playWithoutCaptchaButton);
- if (btn && !isHidden(btn)) { btn.click(); console.log("PLAY WITHOUT CAPTCHA acionado"); }
- else console.warn("Botão PLAY WITHOUT CAPTCHA não encontrado");
- }
-
- // AÇÕES TEMPORIZADAS
- function iniciarAcoesTemporizadas() {
- setTimeout(acionarRoll, CONFIG.rollDelay);
- setTimeout(acionarPlayWithoutCaptcha, CONFIG.playWithoutCaptchaDelay);
- setTimeout(acionarRoll, CONFIG.secondRollDelay);
- }
-
- // MONITORAMENTO DO TIMER
- function monitorarTimer() {
- setInterval(() => {
- const timer = qSelector(CONFIG.timerElement);
- if (timer && timer.textContent.trim().includes("00:00:00")) {
- console.log("Timer zerado – acionar ações");
- gerenciarCaptcha();
- iniciarAcoesTemporizadas();
- }
- }, 1000);
- }
-
- // MONITORAMENTO VISUAL DO TIMER NO CONSOLE (formata com countdown_section se disponível)
- function monitorarTimerNoConsole() {
- let ultimoTempo = '';
- const formatarTempo = (elemento) => {
- const secoes = elemento.querySelectorAll('.countdown_section');
- if (secoes.length < 2) return null;
- const minutos = secoes[0].querySelector('.countdown_amount').textContent.padStart(2, '0');
- const segundos = secoes[1].querySelector('.countdown_amount').textContent.padStart(2, '0');
- return `${minutos}:${segundos}`;
- };
- const atualizarConsole = () => {
- const timer = qSelector(CONFIG.timerElement);
- if (timer && timer.offsetParent !== null) {
- const tempoFormatado = formatarTempo(timer);
- if (tempoFormatado && tempoFormatado !== ultimoTempo) {
- console.clear();
- console.log(`⏳ Timer: ${tempoFormatado}`);
- ultimoTempo = tempoFormatado;
- }
- } else {
- if (ultimoTempo !== 'oculto') {
- console.log(' Timer não visível');
- ultimoTempo = 'oculto';
- }
- }
- };
- setInterval(atualizarConsole, 1000);
- atualizarConsole();
- }
-
- // CONTROLE DE VISIBILIDADE
- function configurarVisibilidade() {
- document.addEventListener('visibilitychange', () => {
- if (!document.hidden) {
- console.log("Retomando operação em primeiro plano");
-
- } else {
- console.log("Modo segundo plano ativado");
- }
- });
- }
-
- // AJUSTE DO PRELOAD DO CLOUDFLARE
- function ajustarPreloadCloudflare() {
- try {
- const link = document.querySelector('link[rel="preload"][href*="challenges.cloudflare.com/cdn-cgi/challenge-platform/h/g/cmg/1"]');
- if (link) {
- link.setAttribute('as', 'script');
- console.info("Atributo 'as' ajustado para 'script' no link de preload");
- }
- } catch (e) { console.error(e); }
- }
-
- // HANDLERS GLOBAIS DE ERROS
- const IGNORED_PATTERNS = ["third-party cookies", "preloaded using link preload"];
- window.addEventListener('error', event => {
- try {
- if (event.message && IGNORED_PATTERNS.some(p => event.message.includes(p))) {
- event.preventDefault();
- return;
- }
- if (event.filename && event.filename.includes('challenges.cloudflare.com')) {
- console.warn("Erro do Cloudflare ignorado:", event.message);
- event.preventDefault();
- } else {
- console.error(event.message, event);
- }
- } catch (e) { console.error(e); }
- });
- window.addEventListener('unhandledrejection', event => {
- try {
- if (event.reason && event.reason.message && IGNORED_PATTERNS.some(p => event.reason.message.includes(p))) {
- event.preventDefault();
- return;
- }
- if (event.reason && event.reason.message && event.reason.message.includes('challenges.cloudflare.com')) {
- console.warn("Rejeição do Cloudflare ignorada:", event.reason.message);
- event.preventDefault();
- } else {
- console.error(event.reason);
- }
- } catch (e) { console.error(e); }
- });
-
- // Polyfill para GM_getValue/GM_setValue se necessário
- if (typeof GM_getValue === 'undefined') {
- window.GM_getValue = key => JSON.parse(localStorage.getItem(key));
- window.GM_setValue = (key, value) => localStorage.setItem(key, JSON.stringify(value));
- }
-
- // MENU DE CONTROLE
- GM_registerMenuCommand('Configurações do Script', () => {
- alert(`Modo: ${state.modoOperacao === 0 ? 'Normal' : 'Sem Captcha'}\nTentativas: ${state.tentativas}`);
- });
-
- // INICIALIZAÇÃO
- function init() {
- carregarEstado();
- PopupManager.fecharPopups();
- monitorarTimer();
- monitorarTimerNoConsole();
- configurarVisibilidade();
- gerenciarCaptcha();
- iniciarAcoesTemporizadas();
- console.log("Script iniciado no Freebitco.in");
- }
-
- window.addEventListener('load', () => {
- ajustarPreloadCloudflare();
- init();
- });
- })();