[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 提交的版本,檢視 最新版本

您需要先安裝使用者腳本管理器擴展,如 TampermonkeyGreasemonkeyViolentmonkey 之後才能安裝該腳本。

You will need to install an extension such as Tampermonkey to install this script.

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyUserscripts 後才能安裝該腳本。

你需要先安裝一款使用者腳本管理器擴展,比如 Tampermonkey,才能安裝此腳本

您需要先安裝使用者腳本管理器擴充功能後才能安裝該腳本。

(我已經安裝了使用者腳本管理器,讓我安裝!)

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

(我已經安裝了使用者樣式管理器,讓我安裝!)

// ==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
}