steamfaucet / RS Captcha Cryptorotator

// ==UserScript==
// @name         RS Captcha Cryptorotator
// @namespace    RS Captcha Cryptorotator
// @version      0.2
// @description  RS Captcha Cryptorotator
// @author       steamfaucet
// @match        https://bithub.win/*
// @match        https://claimtrx.com/*
// @match        https://feyorra.top/*
// @match        https://spaceshooter.net/*
// @updateURL    https://openuserjs.org/meta/steamfaucet/RS_Captcha_Cryptorotator.meta.js
// @downloadURL  https://openuserjs.org/install/steamfaucet/RS_Captcha_Cryptorotator.user.js
// @copyright 2024, steamfaucet (https://openuserjs.org/users/steamfaucet)
// @license GPL-3.0-or-later
// @noframes
// @grant        none

// ==/UserScript==
(function () {

  'use strict';
  window.open = function () {};

  var count = 0;
  var clicked = false;

  //Enter your login and password below, if you like to Autologin. Be careful while providing passwords,
  //else you may get your accounts locked
  var websiteData = [{
      url: "https://bithub.win/ptc",
      login: "",
      password: ""
    },

    {
      url: "https://claimtrx.com/ptc",
      login: "",
      password: ""
    },

    {
      url: "https://feyorra.top/ptc",
      login: "",
      password: ""
    },

    {
      url: "https://spaceshooter.net/ptc",
      login: "",
      password: ""
    },

  ];

  //Check if a string is present in Array
  String.prototype.includesOneOf = function (arrayOfStrings) {

    //If this is not an Array, compare it as a String
    if (!Array.isArray(arrayOfStrings)) {
      return this.toLowerCase().includes(arrayOfStrings.toLowerCase());
    }

    for (var i = 0; i < arrayOfStrings.length; i++) {
      if (this.toLowerCase().includes(arrayOfStrings[i].toLowerCase())) {
        return true;
      }
    }
    return false;
  }

  var websiteMap = [{
    website: ["bithub.win", "claimtrx.com", "feyorra.top", "spaceshooter.net"],
    loginSelectors: ["input[type=email]", "input[type=password]", "button[type=submit]"],
    captchaButtonSubmitSelector: ["button[type=submit]"],
    additionalFunctions: ptcClick,
  }, ]

  var websiteDataValues = {};

  //Get selector details from the websiteMap
  for (let value of Object.values(websiteMap)) {
    if (window.location.href.includesOneOf(value.website)) {
      websiteDataValues.inputTextSelector = value.inputTextSelector;
      websiteDataValues.inputTextSelectorButton = value.inputTextSelectorButton;
      websiteDataValues.defaultButtonSelectors = value.defaultButtonSelectors;
      websiteDataValues.claimButtonSelector = value.claimButtonSelector;
      websiteDataValues.captchaButtonSubmitSelector = value.captchaButtonSubmitSelector;
      websiteDataValues.loginSelectors = value.loginSelectors;
      websiteDataValues.loginCaptcha = value.loginCaptcha;
      websiteDataValues.allMessageSelectors = value.allMessageSelectors;
      websiteDataValues.messagesToCheckBeforeMovingToNextUrl = value.messagesToCheckBeforeMovingToNextUrl;
      websiteDataValues.withdrawPageUrl = value.withdrawPageUrl;
      websiteDataValues.withdrawEnabled = value.withdrawEnabled;
      websiteDataValues.balanceSelector = value.balanceSelector;
      websiteDataValues.withdrawMinAmount = value.withdrawMinAmount;
      websiteDataValues.successMessageSelectors = value.successMessageSelectors;
      websiteDataValues.additionalFunctions = value.additionalFunctions;
      websiteDataValues.timeoutbeforeMovingToNextUrl = value.timeoutbeforeMovingToNextUrl;
      break;
    }
  }

  var login = "";
  var password = "";

  count = 0;
  var addressAssigned = false;
  for (let value of Object.values(websiteData)) {
    count = count + 1;
    if (window.location.href.includes("/" + value.regex)) {
      websiteDataValues.url = value.url;
      login = value.login;
      password = value.password;
      addressAssigned = true;
      break;
    }
  }

  //If URL does not have coin, check the default from the domain name
  if (!addressAssigned) {
    count = 0;
    for (let value of Object.values(websiteData)) {
      count = count + 1;
      if (value.url.includes(window.location.hostname)) {
        websiteDataValues.url = value.url;
        login = value.login;
        password = value.password;
        addressAssigned = true;
        break;
      }
    }
  }

  function ptcClick() {
    const regexArray = [
      /^visit for \d+ sec$/,
      /^go$/,
      /^view$/,
      /^view now$/,
      /^visit now$/,
      /^view ads/,
      /^view ad/,
      /^watch$/
    ];

    let ptcClicked = false;
    for (let i = 0; i < regexArray.length; i++) {
      let button = Array.from(document.querySelectorAll('button')).find(el => regexArray[i].test(el.textContent.toLowerCase().trim()));
      if (button && !isAncestorHidden(button)) {
        button?.click();
        ptcClicked = true;
        break;
      }
    }

    if (!ptcClicked && /ptc$/.test(window.location.href)) {
      goToNextUrl();
    }

  }

  function isAncestorHidden(element) {
    let parent = element;
    while (parent) {
      const display = getComputedStyle(parent).getPropertyValue('display');
      if (display === 'none') {
        return true;
      }
      parent = parent.parentElement;
    }
    return false;
  }

  //Get the next Url from the website data map
  async function getNextUrl() {

    //Go to the beginning if the end of the array is reached
    if (count >= websiteData.length) {
      websiteDataValues.nextUrl = websiteData[0].url;
    }
    else {
      websiteDataValues.nextUrl = websiteData[count].url;
    }

    //Use case for overrding next Url
    if (websiteDataValues.overrideNextUrl) {
      websiteDataValues.nextUrl = websiteDataValues.overrideNextUrl;
    }

  }

  async function delay(ms) {
    return new Promise(resolve => setTimeout(resolve, ms))
  }

  var movingToNextUrl = false;
  async function goToNextUrl() {
    if (!movingToNextUrl) {
      movingToNextUrl = true;
      getNextUrl();
      await delay(3000);
      window.location.href = websiteDataValues.nextUrl;
    }
  }

  //Default Setting: After 180 seconds go to next Url
  var delayBeforeMovingToNextUrl = 180000;
  if (websiteDataValues.timeoutbeforeMovingToNextUrl) {
    delayBeforeMovingToNextUrl = websiteDataValues.timeoutbeforeMovingToNextUrl;
  }

  setTimeout(function () {
    goToNextUrl();
  }, delayBeforeMovingToNextUrl);

  var stopSolvingCaptcha = false;

  function checkLoginSelectors() {

    if (websiteDataValues.loginSelectors) {
      //Check if all login selectors are present
      let count = 0;
      for (let i = 0; i < websiteDataValues.loginSelectors.length; i++) {
        if (document.querySelector(websiteDataValues.loginSelectors[i])) {
          count++;
        }

      }

      if (count == websiteDataValues.loginSelectors.length) {

        if (login.length > 0 && password.length > 0) {
          //Input Login
          document.querySelector(websiteDataValues.loginSelectors[0]).value = login;

          //Input Password
          document.querySelector(websiteDataValues.loginSelectors[1]).value = password;
        }
        else {
          stopSolvingCaptcha = true;
        }

      }
      else {
        stopSolvingCaptcha = true;
      }

    }
    else {
      stopSolvingCaptcha = true;
    }

  }

  setTimeout(function () {

    if (window.location.href.includes("/dashboard")) {
      window.location.href = "/ptc";
    }

    if (!window.location.href.includes("/ptc") && !window.location.href.includes("/dashboard") && !window.location.href.includes("/login")) {
      window.location.href = "/login";
    }

    checkLoginSelectors();

    if (websiteDataValues.additionalFunctions) {
      websiteDataValues.additionalFunctions();
    }

    //Check for all the default button selectors and click
    //This will only click the first selector found, so mention the selectors with parent element wherever required
    if (!movingToNextUrl && websiteDataValues.defaultButtonSelectors) {
      for (var i = 0; i < websiteDataValues.defaultButtonSelectors.length; i++) {
        if (document.querySelector(websiteDataValues.defaultButtonSelectors[i])) {
          document.querySelector(websiteDataValues.defaultButtonSelectors[i]).click();
          break;
        }
      }
    }

    //Input the address and click the login button
    if (!movingToNextUrl && document.querySelector(websiteDataValues.inputTextSelector)) {
      document.querySelector(websiteDataValues.inputTextSelector).value = websiteDataValues.address;
      setTimeout(function () {
        if (websiteDataValues.inputTextSelectorButton && document.querySelector(websiteDataValues.inputTextSelectorButton)) {
          document.querySelector(websiteDataValues.inputTextSelectorButton).click();
        }

      }, 5000);
    }

    //Click the form button after solving captcha
    //Works for both recaptcha and hcaptcha
    var clicked = false;
    var captchaInterval = setInterval(function () {
      if (!stopSolvingCaptcha || !window.location.href.includes("login")) {
        try {
          if (!clicked && document.querySelector("#captcha-solve > div")?.style?.display == '') {
            for (let i = 0; i < websiteDataValues.captchaButtonSubmitSelector.length; i++) {
              if (document.querySelector(websiteDataValues.captchaButtonSubmitSelector[i]) &&
                !isAncestorHidden(document.querySelector(websiteDataValues.captchaButtonSubmitSelector[i]))) {
                document.querySelector(websiteDataValues.captchaButtonSubmitSelector[i])?.click();
                clicked = true;
                clearInterval(captchaInterval);
              }
            }
          }

          if (!clicked && window?.grecaptcha?.getResponse?.()?.length > 0) {
            for (let i = 0; i < websiteDataValues.captchaButtonSubmitSelector.length; i++) {
              if (document.querySelector(websiteDataValues.captchaButtonSubmitSelector[i]) &&
                !isAncestorHidden(document.querySelector(websiteDataValues.captchaButtonSubmitSelector[i]))) {
                document.querySelector(websiteDataValues.captchaButtonSubmitSelector[i])?.click();
                clicked = true;
                clearInterval(captchaInterval);
              }
            }
          }
        }
        catch (e) {

        }

      }

    }, 5000);

  }, 5000);

})();