[KissAnime] Captcha Solver

Saves initial responses to KissAnime captcha and auto-selects images if it knows the answer. Compatible with any number of images in the captcha.

目前为 2018-07-01 提交的版本。查看 最新版本

// ==UserScript==
// @name         [KissAnime] Captcha Solver
// @namespace    https://greasyfork.org/en/users/193865-westleym
// @author       WestleyM
// @version      2018.06.30.2
// @icon         http://kissanime.ru/Content/images/favicon.ico
// @description  Saves initial responses to KissAnime captcha and auto-selects images if it knows the answer. Compatible with any number of images in the captcha.
// @grant        none
// @include      http://kissanime.ru/Special/AreYouHuman2*
// @require      http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js
// ==/UserScript==

/*
Author Notes:
This is a fork of a script made by user ankit16-19.  The original script can be found here: https://greasyfork.org/en/scripts/368595-kissanime-anime-captcha-solver
It should be noted that the initial solving of the captcha will take quite a long time due to the addition of numbers in the images.  My estimate is about 100 episodes.
4, 6, and 8 image captchas are fully supported.  In the future I may also include the captcha solutions in the code, I still haven't decided since it will take up a large chunk of the file.

If ankit16-19 would like this removed I will delete it.
*/


//Global variables
var words = [];
var undefinedWords = [];
var imageSrc = [];
var clickImage = [];
var count = 0;
var imageElements = $("#formVerify").find("img").toArray();  //All images under the "formVerify" form
var imageNumber = imageElements.length;  //How many images are in the captcha



//Custom HTML
$("#formVerify").append("<br>")

//Message box creation
var divs = $("#formVerify").find("div").toArray();  //Grabs all div elements in the "formVerify" element, selects the last one on the next line (named "mainBlock")
var mainBlock = divs[divs.length-1];
var alertBoxDiv = document.createElement("div");  //Creation of div element which will contain the below text element
alertBoxDiv.style.cssText = "background:#65A104; color:white; height:30px; width:100%; line-height:30px; textAlign:center;"

var alertBoxText = document.createElement("h3");  //Creation of text element which will say the descriptions of images the script doesn't know the answer to
alertBoxText.innerText = "Checking data. . . .";
alertBoxText.style.cssText = "background:#65A104; color:white; height:100%; width:100%; textAlign:center; font-size: 20px;"

alertBoxDiv.insertAdjacentElement("afterbegin", alertBoxText);  //Inserting "alertBoxText" into "alertBoxDiv" at the top
mainBlock.insertAdjacentElement("afterend", alertBoxDiv);  //Placing "alertBoxDiv" at the end of "mainBlock"

//Button creation
var i = 0, doc = document, docFrag = document.createDocumentFragment();
for (i; i < imageNumber; i++) {  //Creates several buttons in a document fragment
	var input = doc.createElement("input");
  var j = i+1;
	input.id = j.toString(); //Button IDs begin at 1 and end with how many images there are
	input.type="button";
	input.value="Image " + j.toString();
	input.onclick = function(){
	  if(!localStorage.getItem("helpword")){ //Saves the solution to local storage
	  	localStorage.setItem(localStorage.getItem("helpWord"),ProcessImages()[this.id-1])
	    localStorage.removeItem("helpword");
	  }
    
    var indexId = this.id-1;
    var indexId = indexId.toString();
    $("[indexValue='"+indexId+"']").click(); //Clicks the corresponding image for you after you select a button
    
	  if(unknownwords[1] !== undefined && count < 1){ //If there is a word that is not known it will ask for help.  This specific if statement will only activate after you've made your first selection and if the second is unknown.
	    askForHelp(unknownwords[1]);
	    count++;
	  }
	}
	input.setAttribute("style", "font-size:18px;");
  docFrag.appendChild(input); //Adds button to the document dragment
}
document.getElementById("formVerify").appendChild(docFrag); //Adds the document fragment to the bottom of the "formVerify" element



//Avoid conflicts
this.$ = this.jQuery = jQuery.noConflict(true);
$(document).ready(function()
{
 	unknownwords = UnknownWords();
  knownwords = KnownWords();
  console.log("Unknown words: " + unknownwords);
  console.log("Known words: " + knownwords);
  if(unknownwords[0] !== undefined){  //Ask for help with the first unknown word
  	askForHelp(unknownwords[0]);
  }
  knownwords.forEach(function(word){
    matchfound = 0;
    console.log("processing known word:" + word)
    ProcessImages().forEach(function(image,counter){  //Grabs known value from local storage and clicks the corresponding image
      console.log("counter: " + counter);
      if(localStorage.getItem(word) == image){
        console.log("found match for word " + word);
        matchfound = 1;
        $("[indexValue='"+counter+"']").click();
      }else if(counter === imageNumber-1 && matchfound === 0){  //Reloads the page if there was an issue with a known word
        console.log("There seems to be an issue with a known image.  Consider deleting entries.  The page will be reloaded.");
        location.reload();
      }
    })
    
  })  

});



function askForHelp(word){  //Asks you to select an answer when the script doesn't know.
  alertBoxText.innerText = "Please select the button matching: " + word;
  localStorage.setItem("helpWord",word);
}

function UnknownWords(){  //Finds the words that the script doesn't know the answer to
  var unknownwords = [];
  Words().forEach(function(word){
     if(!localStorage.getItem(word)){  //If the solution isn't found in the local storage, it will be added to the "unknownwords" array
       	unknownwords.push(word);
     }
  });
  return unknownwords;
}

function KnownWords(){  //Finds the words that the script knows the answer to
  var knownWords = [];
  Words().forEach(function(word){
     if(localStorage.getItem(word)){  //If solution is found in the local storage, it will be added to the "Knownwords" array
       	knownWords.push(word);
     }
  });
  return knownWords;
}

function SaveWord(word, dataurl){
  if(!localStorage.getItem(word)){
   		localStorage.removeItem(word);
    	localStorage.setItem(word, dataurl);
  }else {
   		localStorage.setItem(word,dataurl);
  }
}

function Words(){ //Grabs span elements that are children of the "formVerify" form.  This will include the "SKIP THIS (RapidVideo)" button and the two sections saying what to select.  Ex: "cat, glasses, 0"
    var words = $("#formVerify").find("span").toArray();
    var firstDesc = words[1].innerText; //Start at index 1 to skip the RapidVideo span element
    var secondDesc = words[2].innerText;
    return [firstDesc, secondDesc];
}

function Images(){
  return $("[indexValue]").toArray();
}

function ConvertToDataUrl(img) {
  var canvas = document.createElement("canvas");
  canvas.width = img.width;
  canvas.height = img.height;
  var ctx = canvas.getContext("2d");
  ctx.drawImage(img, 0, 0);
  var dataURL = canvas.toDataURL("image/png");
  return dataURL.replace(/^data:image\/(png|jpg);base64,/, "");
}

function MinimiseDataUrl(dataUrl,jump)
{
    var a = "";
    for(var i = 0; i < dataUrl.length; i=i+jump)
        a += dataUrl.charAt(i);
    return a;
}

function ProcessImages()
{
  var imagedata = [];
  Images().forEach(function(image, counter)
  {
    dataurl = ConvertToDataUrl(image)
    imagedata.push(MinimiseDataUrl(MinimiseDataUrl(MinimiseDataUrl(dataurl, 5), 4),3));
  })
  return imagedata
}